diff --git a/CHANGELOG b/CHANGELOG index c0c7af69b..d5eae562a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,1340 @@ +commit fd0b1fe3c388a77e8fe00cdd930ca317a91198d4 +Author: Dave Liu +Date: Wed Mar 26 22:55:32 2008 +0800 + + drivers: add the support for Freescale SATA controller + + Add the Freescale on-chip SATA controller driver to u-boot, + The SATA controller is used on the 837x and 8315 targets, + The driver can be used to load kernel, fs and dtb. + + The features list: + - 1.5/3 Gbps link speed + - LBA48, LBA28 support + - DMA and FPDMA support + - Two ports support + + Signed-off-by: Dave Liu + +commit bede87f4c87c3ccd868cc60ebf792e0560c6d024 +Author: Dave Liu +Date: Wed Mar 26 22:54:44 2008 +0800 + + ata: add the readme for SATA command line + + Signed-off-by: Dave Liu + +commit cd54081cd479e542fc399b8a40651ff11a1ad849 +Author: Dave Liu +Date: Wed Mar 26 22:53:24 2008 +0800 + + ata: enable the sata initialize on boot up + + Signed-off-by: Dave Liu + +commit 69386383c5c2b323c66495b0b0cef6a9714d83bf +Author: Dave Liu +Date: Wed Mar 26 22:52:36 2008 +0800 + + ata: add the fis struct for SATA + + Signed-off-by: Dave Liu + +commit ffc664e80dfb2e17de0df5ad39e91a02e9c361bc +Author: Dave Liu +Date: Wed Mar 26 22:51:44 2008 +0800 + + ata: add the libata support + + add simple libata support in u-boot + + Signed-off-by: Dave Liu + +commit 8e9bb43429e50df55fa41932cbe65841ff579220 +Author: Dave Liu +Date: Wed Mar 26 22:50:45 2008 +0800 + + ata: make the ata_piix driver using new SATA framework + + original ata_piix driver is using IDE framework, not real + SATA framework. For now, the ata_piix driver is only used + by x86 sc520_cdp board. This patch makes the ata_piix driver + use the new SATA framework, so + + - remove the duplicated command stuff + - remove the CONFIG_CMD_IDE define in the sc520_cdp.h + - add the CONFIG_CMD_SATA define to sc520_cdp.h + + Signed-off-by: Dave Liu + +commit c7057b529c3c3cb9c0ac9060686a4068f1491bbe +Author: Dave Liu +Date: Wed Mar 26 22:49:44 2008 +0800 + + ata: add the support for SATA framework + + - add the SATA framework + - add the SATA command line + + Signed-off-by: Dave Liu + +commit 83c7f470a4ce94f33600f11ae85ce4dcf00aa90c +Author: Dave Liu +Date: Wed Mar 26 22:48:18 2008 +0800 + + ata: merge the header of ata_piix driver + + move the sata.h from include/ to drivers/block/ata_piix.h + + Signed-off-by: Dave Liu + +commit 9eef62804d9695425b24c87b46a61a7fa74afee0 +Author: Dave Liu +Date: Wed Mar 26 22:47:06 2008 +0800 + + ata: merge the ata_piix driver + + move the cmd_sata.c from common/ to drivers/ata_piix.c, + the cmd_sata.c have some part of ata_piix controller drivers. + consolidate the driver to have better framework. + + Signed-off-by: Dave Liu + +commit 5b5eb9ca5b778f763bcf332697b35cc1e747626e +Author: Wolfgang Denk +Date: Wed Mar 26 15:38:47 2008 +0100 + + Coding style cleanup. + + Signed-off-by: Wolfgang Denk + +commit da8808df7a9cef5a3d2ee286ef9ebf9de1780660 +Author: Joakim Tjernlund +Date: Wed Mar 26 13:02:13 2008 +0100 + + Add CFG_RTC_DS1337_NOOSC to turn off OSC output + + The default settings for RTC DS1337 keeps the OSC + output, 32,768 Hz, on. This add CFG_RTC_DS1337_NOOSC to + turn it off. + + Signed-off-by: Joakim Tjernlund + +commit 438a4c11260b4ea9805039b0b4f92f9df5306b02 +Author: Wolfgang Denk +Date: Wed Mar 26 11:48:46 2008 +0100 + + Cleanup coding style, update CHANGELOG + + Signed-off-by: Wolfgang Denk + +commit 218ca724c08ca8a649f0917cf201cf23d4b33f39 +Author: Wolfgang Denk +Date: Wed Mar 26 10:40:12 2008 +0100 + + README: update documentation (availability, links, etc.) + + Signed-off-by: Wolfgang Denk + +commit f6b44e0e4d18fe507833a0f76d24a9aa72c123f1 +Author: Aras Vaichas +Date: Tue Mar 25 12:09:07 2008 +1100 + + USB Storage, add meaningful return value + + This patch changes the "usb storage" command to return success if it + finds a USB storage device, otherwise it returns error. + + Signed-off-by: Markus Klotzbuecher + +commit 18e69a35efbb078403db0c0063986470dad7d082 +Author: Anton Vorontsov +Date: Fri Mar 14 23:20:18 2008 +0300 + + 83xx/fdt_support: let user specifiy FSL USB Dual-Role controller role + + Linux understands "host" (default), "peripheral" and "otg" (broken). + Though, U-Boot doesn't restrict dr_mode variable to these values (think + of renames in future). + + Signed-off-by: Anton Vorontsov + Signed-off-by: Kim Phillips + +commit c7604783b236e368f225efb7b3efb418fe20b404 +Author: Anton Vorontsov +Date: Fri Mar 14 23:20:30 2008 +0300 + + tsec: fix link detection for the RTL8211B PHY + + RTL8211B sets link state register after autonegotiation complete, + so with bootdelay=0 RTL8211B will report lack of the link. + + To fix this, we should wait for aneg to complete, even if the + link is currently down. + + Signed-off-by: Anton Vorontsov + Signed-off-by: Kim Phillips + +commit 7fa9cbb00dc83fcf175042b6f20c2c9bce9a15f4 +Author: Anton Vorontsov +Date: Mon Mar 24 20:47:09 2008 +0300 + + mpc83xx: add "fsl,soc" and "fsl,immr" compatible fixups + + device_type = "soc" is being deprecated, newer device trees will use + "fsl,soc" and/or "fsl,immr" for the soc nodes. + + This patch also adds clock-frequency property for soc nodes (the same + value as bus-frequency). + + Signed-off-by: Anton Vorontsov + +commit 507e2d79c91441a0bb2cd3d0c31c8bfe3f8cec07 +Author: Joe D'Abbraccio +Date: Mon Mar 24 13:00:59 2008 -0400 + + Modified the DDR SDRAM clock control register to delay MCK/MCK_B 3/4 clock + + With the original value of 1/2 clock cycle delay, the system ran relatively + stable except when we run benchmarks that are intensive users of memory. + When I run samba connected disk with a HDBENCH test, the system locks-up + or reboots sporadically. + + Signed-off by: Joe D'Abbraccio + +commit a7ba32d480a86db5db8dcd8ca66b21b4cadda923 +Author: Scott Wood +Date: Mon Mar 24 12:44:13 2008 -0500 + + mpc83xx: Set PCI I/O bus-address base to zero. + + The device trees for these boards describe PCI I/O as starting from + address zero from the device's perspective. + + Placing I/O elsewhere may cause problems with certain PCI boards, and may + cause problems with Linux. + + Signed-off-by: Scott Wood + +commit f700e7df7fecf2d3765ae568ce77ce788cde4f3e +Author: Anton Vorontsov +Date: Mon Mar 24 20:47:05 2008 +0300 + + mpc83xx: MPC8360E-RDK: use 33.3(3)MHz CLKIN/SYS_CLK + + At least on the "33MHz Pilot" board crystal is actually 33.3MHz. + This patch fixes "system time drifting" problem. + + Signed-off-by: Anton Vorontsov + +commit 3a0cfdd576dc9b16d1468d37339182607c697fb7 +Author: Anton Vorontsov +Date: Mon Mar 24 20:47:02 2008 +0300 + + mpc83xx: MPC8360E-RDK: define CONFIG_OF_STDOUT_VIA_ALIAS + + This is needed to update /choosen/linux,stdout-path properly. + + Signed-off-by: Anton Vorontsov + +commit 3419eb62f088d7a22f1d2a3cebf76b77e408b5b9 +Author: Anton Vorontsov +Date: Mon Mar 24 20:47:00 2008 +0300 + + mpc83xx: MPC8360E-RDK: add dhcp command + + Plus modify environment to use it and remove bootfile env variable, + it is internal and CONFIG_BOOTFILE is used for these purposes. + + Signed-off-by: Anton Vorontsov + +commit d892b2dbb4087a26778bfd42470c3ea7d0e2b6aa +Author: Anton Vorontsov +Date: Mon Mar 24 20:46:57 2008 +0300 + + mpc83xx: MPC8360E-RDK: rework ddr setup, enable ecc + + Current DDR setup easily causes memory corruption, this patch fixes it. + + Also fix TIMING_CFG0_MRS_CYC definition. + + Signed-off-by: Anton Vorontsov + +commit d47d49cc37a38f2719a3e1b9bbe08ac810cf2d9a +Author: Anton Vorontsov +Date: Mon Mar 24 20:46:53 2008 +0300 + + mpc83xx: MPC8360E-RDK: configure pario pins for AD7843 and FHCI + + This patch adds qe pario pins configuration for AD7843 ADC/Touchscreen + controller and FHCI (QE USB). + + Signed-off-by: Anton Vorontsov + +commit 7ad959490962e6842648d87d4bd795ea6cdcce67 +Author: Anton Vorontsov +Date: Mon Mar 24 20:46:51 2008 +0300 + + mpc83xx: MPC8360E-RDK: add support for NAND + + Signed-off-by: Anton Vorontsov + +commit 9a3e832aeb491861d029991241572ebdf4b5b61b +Author: Anton Vorontsov +Date: Mon Mar 24 20:46:46 2008 +0300 + + mpc83xx: MPC8360E-RDK: use RGMII_RXID interface mode + + This is needed for BCM PHYs to work on this board. + + Signed-off-by: Anton Vorontsov + +commit 300615dc5d9b0a2022fbc6af0c13159e33fd752e +Author: Anton Vorontsov +Date: Mon Mar 24 20:46:34 2008 +0300 + + uec: add support for Broadcom BCM5481 Gigabit PHY + + This patch adds basic support for Broadcom BCM5481 PHY. + + RXD-RXC delay quirk comes from MPC8360E-RDK BSP source, author is + Peter Barada . + + Signed-off-by: Anton Vorontsov + +commit 6a600c3a1876bc203445df4f0fd6b12648259666 +Author: Anton Vorontsov +Date: Mon Mar 24 20:46:28 2008 +0300 + + uec: add support for RGMII_RXID interface mode + + PHY drivers will use it to setup software delay between RXD and RXC + signals. + + Signed-off-by: Anton Vorontsov + +commit 91cdaa3a9d7562b869d96774e9c9ddf142c0848d +Author: Anton Vorontsov +Date: Mon Mar 24 20:46:24 2008 +0300 + + uec: add support for gbit mii status readings + + Signed-off-by: Anton Vorontsov + +commit aabce7fb505ffe55ebf3bf4dcafdae97a581558d +Author: Anton Vorontsov +Date: Mon Mar 24 17:40:47 2008 +0300 + + 83xx: define CONFIG_OF_STDOUT_VIA_ALIAS for the MPC837XERDB boards + + This is primarily for the early console support. + + Signed-off-by: Anton Vorontsov + +commit 2bd7460e9283ec98565189b3cdbcfb2bcdcdd635 +Author: Anton Vorontsov +Date: Mon Mar 24 17:40:43 2008 +0300 + + 83xx: initialize serdes for MPC837XRDB boards + + On the MPC8377ERDB: 2 SATA and 2 PCI-E. + On the MPC8378ERDB: 2 PCI-E + On the MPC8379ERDB: 4 SATA + + Signed-off-by: Anton Vorontsov + +commit 453316a2a19642d8afcbca7452e40a6b44a197b1 +Author: Anton Vorontsov +Date: Mon Mar 24 17:40:32 2008 +0300 + + 83xx: serdes setup routines + + This patch adds few routines to configure serdes on 837x targets. + + Signed-off-by: Anton Vorontsov + +commit a796cdf9c377cb4e5d61d1079a296608f8fbd903 +Author: Anton Vorontsov +Date: Mon Mar 24 17:40:27 2008 +0300 + + 83xx: split COBJS onto separate lines + + ..plus get rid of some #ifdefs in the .c files. + + Signed-off-by: Anton Vorontsov + +commit 46a3aeea73c13ab04ebf7a8739afb87ac5da94a3 +Author: Anton Vorontsov +Date: Mon Mar 24 17:40:23 2008 +0300 + + 83xx: nand support for MPC837XRDB boards + + Signed-off-by: Anton Vorontsov + +commit 82e45a204190593e8613145a928f998fb8c909c4 +Author: Jerry Van Baren +Date: Tue Mar 18 21:44:41 2008 -0400 + + Enable CONFIG_FLASH_SHOW_PROGRESS on the MPC8360EMDS. + + Signed-off-by: Gerald Van Baren + Signed-off-by: Kim Phillips + +commit 0fa7a1b4719e325fce332689fb8754ec166191ff +Author: Michael Barkowski +Date: Thu Mar 20 13:15:39 2008 -0400 + + mpc8323erdb: remove RTC and add EEPROM + + There's no on-board RTC on the MPC8323ERDB, but there is an EEPROM. + + Signed-off-by: Michael Barkowski + Acked-by: Kim Phillips + +commit 5bbeea86eb6afb872374cd23217cb3c1018443ed +Author: Michael Barkowski +Date: Thu Mar 20 13:15:34 2008 -0400 + + mpc8323erdb: Improve the system performance + + The following changes are based on kernel UCC ethernet performance: + + 1. Make the CSB bus pipeline depth as 4, and enable the repeat mode + 2. Optimize transactions between QE and CSB. Added CFG_SPCR_OPT + switch to enable this setting. + + The following changes are based on the App Note AN3369 and + verified to improve memory latency using LMbench: + + 3. CS0_CONFIG[AP_n_EN] is changed from 1 to 0 + 4. CS0_CONFIG[ODT_WR_CONFIG] set to 1. Was a reserved setting + previously. + 5. TIMING_CFG_1[WRREC] is changed from 3clks to 2clks (based on + Twr=15ns, and this was already the setting in DDR_MODE) + 6. TIMING_CFG_1[PRETOACT] is changed from 3clks to 2clks. (based on + Trp=15ns) + 7. TIMING_CFG_1[ACTTOPRE] is changed from 9clks to 6clks. (based on + Tras=40ns) + 8. TIMING_CFG_1[ACTTORW] is changed from 3clks to 2clks. (based on + Trcd=15ns) + 9. TIMING_CFG_1[REFREC] changed from 21 clks to 11clks. (based on + Trfc=75ns) + 10. TIMING_CFG_2[FOUR_ACT] is changed from 10 clks to 7clks. (based + on Tfaw=50ns) + 11. TIMING_CFG_2[ADD_LAT] and DDR_MODE[AL] changed from 0 to 1 (based + on CL=3 and WL=2). + + Signed-off-by: Michael Barkowski + Acked-by: Kim Phillips + +commit fc549c871f43933396a5b3e21d897023d4b31b8d +Author: Michael Barkowski +Date: Thu Mar 20 13:15:28 2008 -0400 + + mpc8323erdb: use readable DDR config macros + + Use available shift/mask macros to define DDR configuration. + + Signed-off-by: Michael Barkowski + Acked-by: Kim Phillips + +commit 89c7784ed90ba50301eec521144f95111e472906 +Author: Timur Tabi +Date: Fri Feb 8 13:15:55 2008 -0600 + + 83xx: Add Vitesse VSC7385 firmware uploading + + Update the MPC8349E-mITX, MPC8313E-RDB, and MPC837XE-RDB board files to upload + the Vitesse VSC7385 firmware. Changed CONFIG_VSC7385 to CONFIG_VSC7385_ENET. + Cleaned up the board header files to make selecting the VSC7385 easier to + control. + + Signed-off-by: Timur Tabi + Signed-off-by: Kim Phillips + +commit b55d98c6d5b8694e560a0e727b14cb6921d7cfcc +Author: Timur Tabi +Date: Fri Feb 8 13:15:54 2008 -0600 + + NET: Add Vitesse VSC7385 firmware uploading + + The Vitesse VSC7385 is a 5-port switch found on the Freescale MPC8349E-mITX + and other boards. A small firwmare must be uploaded to its on-board memory + before it can be enabled. This patch adds the code which uploads firmware + (but not the firmware itself). + + Previously, this feature was provided by a U-Boot application that was + made available only on Freescale BSPs. The VSC7385 firmware must still + be obtained separately, but at least there is no longer a need for a separate + application. + + Signed-off-by: Timur Tabi + Acked-by: Ben Warren + +commit aa6f6d171a1f9f46ee4f03ad6acb97a6bfb71855 +Author: Wolfgang Denk +Date: Wed Mar 26 00:52:10 2008 +0100 + + Coding Style cleanyp; update CHANGELOG + + Signed-off-by: Wolfgang Denk + +commit 43ddd9c820fec44816188f53346b464e20b3142d +Author: Jerry Van Baren +Date: Sat Mar 22 14:23:49 2008 -0400 + + Remove deprecated CONFIG_OF_HAS_UBOOT_ENV and CONFIG_OF_HAS_BD_T + + These defines embedded the u-boot env variables and/or the bd_t structure + in the fdt blob. The conclusion of discussion on the u-boot email list + was that embedding these in the fdt blob is not useful: there are better + ways of passing the data (in fact, the fdt blob itself replaces the + bd_t struct). + + The only board that enables these is the stxxtc and they don't appear + to be used by linux. + + Signed-off-by: Gerald Van Baren + Acked-by: Kim Phillips + +commit 22ed2285743359fd1fe73e411dff914b2256e68f +Author: Stefan Roese +Date: Mon Mar 17 10:49:25 2008 +0100 + + rtc: Remove 2nd reference to max6900.o in drivers/rtc/Makefile + + Signed-off-by: Stefan Roese + +commit 1bb707c39a0833e91d9f797dd862aaaaf4af264d +Author: Kyungmin Park +Date: Mon Mar 17 08:54:06 2008 +0900 + + Add Flex-OneNAND booting support + + Flex-OneNAND is a monolithic integrated circuit with a NAND Flash array + using a NOR Flash interface. This on-chip integration enables system designers + to reduce external system logic and use high-density NAND Flash + in applications that would otherwise have to use more NOR components. + + Flex-OneNAND enables users to configure to partition it into SLC and MLC areas + in more flexible way. While MLC area of Flex-OneNAND can be used to store data + that require low reliability and high density, SLC area of Flex-OneNAND + to store data that need high reliability and high performance. Flex-OneNAND + can let users take advantage of storing these two different types of data + into one chip, which is making Flex-OneNAND more cost- and space-effective. + + Signed-off-by: Kyungmin Park + +commit c512389cc4a10253249271ff6c887c6dab1f0db2 +Author: AndrĂ© Schwarz +Date: Thu Mar 13 13:50:52 2008 +0100 + + MPC5200: support setup without FEC + + Include FEC specific nodes in ft_cpu_setup only if CONFIG_MPC5xxx_FEC is + defined. Systems without FEC, i.e. no FEC node in DTB, should be possible. + + Signed-off-by: Andre Schwarz + Acked-by: Grant Likely + +commit aa3511e422946041ef626f80a05ae5e8bfc700e6 +Author: Jon Loeliger +Date: Wed Mar 5 18:05:46 2008 -0600 + + FSL: Move board/mpc8266ads under board/freescale + + Signed-off-by: Jon Loeliger + +commit 7f1d846e5c5754449c286587d099d85246062772 +Author: Jon Loeliger +Date: Wed Mar 5 18:05:47 2008 -0600 + + FSL: Move board/mpc7448hpc2 under board/freescale + + Signed-off-by: Jon Loeliger + +commit b7e24d283e34727c2a6cdfdac2e09a426c579b73 +Author: Jon Loeliger +Date: Wed Mar 5 18:05:45 2008 -0600 + + FSL: Move board/mpc8260ads under board/freescale + + Signed-off-by: Jon Loeliger + +commit 6a8a5dc4759867c45aa95580deb8bf26669a5d97 +Author: goda.yusuke +Date: Wed Mar 5 17:08:33 2008 +0900 + + net: Add support AX88796L ethernet device + + AX88796L is device of NE2000 compatible. + This patch support AX88796L ethernet device. + + Signed-off-by: Yusuke Goda + Acked-by: Nobuhiro Iwamatsu + +commit e0a6140dd381e1eed1ada2291166ef2616d8822b +Author: Wolfgang Denk +Date: Tue Mar 25 22:50:41 2008 +0100 + + ne2000 driver: change #ifdef to Makefile conditional compilation + + Signed-off-by: Wolfgang Denk + +commit e710185aae90c64d39c2d453e40e58ceefe4f250 +Author: goda.yusuke +Date: Wed Mar 5 17:08:20 2008 +0900 + + net: Divided code of NE2000 ethernet driver + + There are more devices of the NE2000 base. + A present code is difficult for us to support more devices. + To support more NE2000 clone devices, separated the function. + + Signed-off-by: Yusuke Goda + Acked-by: Nobuhiro Iwamatsu + +commit 395bce4f59a507a60a475f7ee46bed47de9482df +Author: Mike Frysinger +Date: Sun Feb 24 23:58:13 2008 -0500 + + net/Blackfin: move on-chip MAC driver into drivers/net/ + + The Blackfin on-chip MAC driver was being managed in the BF537-STAMP board + directory, but it is not board specific, so relocate it to the drivers dir + so that other Blackfin ports can utilize it. + + Signed-off-by: Mike Frysinger + +commit 8a30b4700942f37495d2e67f5998cdffb6e3ba8a +Author: Mike Frysinger +Date: Sun Feb 24 23:52:35 2008 -0500 + + smc91111: use SSYNC() rather than asm(ssync) for Blackfin + + Since the "ssync" instruction may have hardware anomalies associated with + it, have the smc91111 driver use the SSYNC macro rather than invoking it + directly. We workaround all the anomalies via this macro. + + Signed-off-by: Mike Frysinger + +commit 77ff7b7444ceb8022b46114f3d0b6d18e2fd1138 +Author: Bryan O'Donoghue +Date: Sun Feb 17 22:57:47 2008 +0000 + + 8xx: Update OF support on 8xx + + This patch does some shifting around of OF support on 8xx. + + Signed-off-by: Bryan O'Donoghue + +commit 9c666a7db0b2285a270c68810889ce7d5dba304b +Author: Kumar Gala +Date: Fri Feb 15 15:16:18 2008 -0600 + + ppc: Allow boards to specify how much memory they can map + + For historical reasons we limited the stack to 256M because some boards + could only map that much via BATS. However newer boards are capable of + mapping more memory (for example 85xx is capble of doing up to 2G). + + Signed-off-by: Kumar Gala + +commit a6f5f317cd074bbbfa2aab4fca05904c811c19fb +Author: Bryan O'Donoghue +Date: Fri Feb 15 01:05:58 2008 +0000 + + 8xx : Add OF support to Adder875 board port - resubmit + + Signed-off-by: Bryan O'Donoghue + +commit d058698fd2d9f769ff38ac53c8708b3fdd314f2d +Author: Kumar Gala +Date: Thu Feb 14 20:44:42 2008 -0600 + + Add setexpr command + + Add a simple expr style command that will set an env variable as the result + of the command. This allows us to do simple math in shell. The following + operations are supported: &, |, ^, +, -, *, /. + + Signed-off-by: Kumar Gala + +commit 3f105faa64b9826e088711fdfcaa70cb1230397a +Author: Jon Loeliger +Date: Wed Mar 5 17:27:48 2008 -0600 + + FSL: Move board/mpc7448hpc2 under board/freescale + + Signed-off-by: Jon Loeliger + +commit 449c703374a8868453425e15da7e2f76221b72e4 +Author: Jon Loeliger +Date: Wed Mar 5 17:21:43 2008 -0600 + + FSL: Move board/mpc8266ads under board/freescale + + Signed-off-by: Jon Loeliger + +commit 5863577989ad689427bb750107e9a75f1c1645d2 +Author: Jon Loeliger +Date: Wed Mar 5 16:41:41 2008 -0600 + + FSL: Move board/mpc8260ads under board/freescale + + Signed-off-by: Jon Loeliger + +commit 8a773983957ee6c4aa344469b742f29c7d26afbd +Author: Shinya Kuribayashi +Date: Tue Mar 25 21:30:08 2008 +0900 + + [MIPS] Move gth2_config from ARM section to MIPS + + Signed-off-by: Shinya Kuribayashi + +commit 373b16fc0c5ae34d28b9027f809ae3cbf45cdd15 +Author: Shinya Kuribayashi +Date: Tue Mar 25 21:30:07 2008 +0900 + + [MIPS] Extend MIPS_MAX_CACHE_SIZE upto 64kB + + Signed-off-by: Shinya Kuribayashi + +commit d98e348e2ed5aab8f7a6471ff628ab0688b8a459 +Author: Shinya Kuribayashi +Date: Tue Mar 25 21:30:07 2008 +0900 + + [MIPS] Fix dcache_status() + + You can't judge UNCACHED by Config.K0 LSB. + + Signed-off-by: Shinya Kuribayashi + +commit b0c66af53ec9385ac2d1cc2e5d7d1ecdc81caf34 +Author: Shinya Kuribayashi +Date: Tue Mar 25 21:30:07 2008 +0900 + + [MIPS] Introduce _machine_restart + + Handles machine specific functions by using weak functions. + + Signed-off-by: Shinya Kuribayashi + +commit decaba6f5cf386d569ac3997bebb871b966c6b18 +Author: Shinya Kuribayashi +Date: Tue Mar 25 21:30:07 2008 +0900 + + [MIPS] Cleanup CP0 Status initialization + + Add setup_c0_status from Linux. For the moment we disable interrupts, set + CU0, mark the kernel mode, and clear ERL and EXL. This is good enough for + reset-time configuration and will work well across most processors. + + Signed-off-by: Shinya Kuribayashi + +commit d43d43ef2845af309c25a64bb9c2c5fb3261bc23 +Author: Shinya Kuribayashi +Date: Tue Mar 25 21:30:07 2008 +0900 + + [MIPS] Initialize CP0 Cause before setting up CP0 Status register + + Without this change, we'll be suffering from deffered WATCH exception + once Status.EXL is cleared. Make sure Cause.WP is cleared. + + Signed-off-by: Shinya Kuribayashi + +commit 26138623230ca2bad3c78e05a65527ea70c8b688 +Author: Shinya Kuribayashi +Date: Tue Mar 25 21:30:07 2008 +0900 + + [MIPS] INCA-IP: Move watchdog init code from start.S to lowlevel_init() + + Move things to appropriate place. + + Signed-off-by: Shinya Kuribayashi + +commit ccf8f824ef67df028dedb29f8ea5d71a5a88d895 +Author: Shinya Kuribayashi +Date: Tue Mar 25 21:30:06 2008 +0900 + + [MIPS] Implement flush_cache() + + We do Hit_Writeback_Inv_D and Hit_Invalidate_I. You might think that you + don't need to do Hit_Invalidate_I, but flush_cache() needs it since this + function is used not only in U-Boot specfic programs but also at loading + target binaries. + + Signed-off-by: Shinya Kuribayashi + +commit 2e0e5271aac917812a76c72030a2b2c6f1d3387d +Author: Shinya Kuribayashi +Date: Tue Mar 25 21:30:06 2008 +0900 + + [MIPS] Fix I-/D-cache initialization loops + + Currently we do 1) Index_Store_Tag_I, 2) Fill and 3) Index_Store_Tag_I + again per a loop for I-cache initialization. But according to 'See MIPS + Run', we're encouraged to use three separate loops rather than combining + them *for both I- and D-cache*. This patch tries to fix this. + + In accordance with fixing above, mips_init_[id]cache are separated from + mips_cache_reset(), and rewrite cache loops are completely rewritten with + useful macros. + + Signed-off-by: Shinya Kuribayashi + +commit 1898840797c7f50799377bd5b285a8a93a82c419 +Author: Shinya Kuribayashi +Date: Tue Mar 25 21:30:06 2008 +0900 + + [MIPS] Replace memory clearance code with f_fill64 + + This routine fills memory with zero by 64 bytes, and is 64-bit capable. + + Signed-off-by: Shinya Kuribayashi + +commit 2f5d414ccb4024dd0992ff6b22561732dbc73590 +Author: Shinya Kuribayashi +Date: Tue Mar 25 21:30:06 2008 +0900 + + [MIPS] cpu/mips/cache.S: Introduce NESTED/LEAF/END macros + + This patch replaces the current function definitions with NESTED, LEAF + and END macro. They specify some more additional information about the + function; an alignment of symbol, type of symbol, stack frame usage, etc. + These information explicitly tells the assembler and the debugger about + the types of code we want to generate. + + Signed-off-by: Shinya Kuribayashi + +commit 282223a607c611425fa33f5428f8eae6636972bb +Author: Shinya Kuribayashi +Date: Tue Mar 25 11:43:17 2008 +0900 + + [MIPS] asm headers' updates + + Make some asm headers adjusted to the latest Linux kernel. + + Signed-off-by: Shinya Kuribayashi + +commit e1390801a3c1a2b6d12fa90be368efc19f5b9bfd +Author: Shinya Kuribayashi +Date: Tue Mar 25 11:39:29 2008 +0900 + + [MIPS] Request for the 'mips_cache_lock()' removal + + The initial intension of having mips_cache_lock() was to use the cache + as memory for temporary stack use so that a C environment can be set up + as early as possible. + + But now mips_cache_lock() follow lowlevel_init(). We've already have the + real memory initilaized at this point, therefore we could/should use it. + No reason to lock at all. + + Other problems: + + Cache locking is not consistent across MIPS implementaions. Some imple- + mentations don't support locking at all. The style of locking varies - + some support per line locking, others per way, etc. Some parts use bits + in status registers instead of cache ops. Current mips_cache_lock() is + not necessarily general-purpose. + + And this is worthy of special mention; once U-Boot/MIPS locks the lines, + they are never get unlocked, so the code relies on whatever gets loaded + after U-Boot to re-initialize the cache and clear the locks. We're sup- + posed to have CFG_INIT_RAM_LOCK and unlock_ram_in_cache() implemented, + but leave the situation as it is for a long time. + + For these reasons, I proposed the removal of mips_cache_lock() from the + global start-up code. + + This patch adds CFG_INIT_RAM_LOCK_MIPS to make existing users aware that + *things have changed*. If he wants the same behavior as before, he needs + to have CFG_INIT_RAM_LOCK_MIPS in his config file. + + If we don't have any regression report through several releases, then + we'll remove codes entirely. + + Signed-off-by: Shinya Kuribayashi + Acked-by: Andrew Dyer + +commit 0d48926c87ec96f974a6ac4034f4a2f2eab3255f +Author: Yuri Tikhonov +Date: Mon Mar 24 11:30:54 2008 +0100 + + lwmon5 SYSMON POST: fix backlight control + + If the LWMON5 config has SYSMON POST among CONFIG_POSTs which may be + run on the board, then the SYSMON POST controls the display backlight + (doesn't switch backlight ON if POST FAILED, and does switch the + backlight ON if PASSED). + + If not, then the video driver controls the display backlight (just + switch ON the backlight upon initialization). + + Signed-off-by: Yuri Tikhonov + +commit ff2bdfb2c1e073f65c065011f1e18d0a130bd3d8 +Author: Yuri Tikhonov +Date: Mon Mar 24 11:29:14 2008 +0100 + + lwmon5 SYSMON POST: fix handling of negative temperatures + + Fix errors in the LWMON5 Sysmon POST for negative temperatures. + + Signed-off-by: Yuri Tikhonov + +commit 55774b512fdf63c0516d441cc5da7c54bbffb7f2 +Author: Nobuhiro Iwamatsu +Date: Fri Mar 7 16:04:25 2008 +0900 + + pci: Add CONFIG_PCI_SKIP_HOST_BRIDGE config option + + In current source code, when the device number of PCI is 0, process PCI + bridge without fail. However, when the device number is 0, it is not PCI + always bridge. There are times when device of PCI allocates. + + When CONFIG_PCI_SKIP_HOST_BRIDGE is enable, this problem is solved when + use this patch. + + Signed-off-by: Nobuhiro Iwamatsu + Acked-by: Stefan Roese + +commit 86aea3eaefa248ffb9328e2b50c64720489cdbeb +Author: Yuri Tikhonov +Date: Fri Mar 21 09:18:40 2008 +0100 + + LWMON5: fix dsPIC POST + + Add test for DPIC_SYS_ERROR_REG to be zero in the LWMON5 dsPIC POST. + + Signed-off-by: Yuri Tikhonov --- + +commit 388b82fddc7c05596f3f615f190da0448227dc82 +Author: Bartlomiej Sieka +Date: Thu Mar 20 23:23:13 2008 +0100 + + [new uImage] Enable new uImage support for the pcs440ep board. + + Signed-off-by: Bartlomiej Sieka + +commit 95f4ec2b9c910c7261e6f060ea530d58b039692d +Author: Bartlomiej Sieka +Date: Thu Mar 20 23:23:13 2008 +0100 + + [new uImage] Do not compile new uImage format support by default + + Disable default building of new uImage format support in preparation + for merge with the master. Support for new format can be enabled on + a per-board basis, by defining the following in the board's config file: + + #define CONFIG_FIT 1 + #define CONFIG_OF_LIBFDT 1 + + This can be optionally defined to give more verbose output: + + #define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */ + + Signed-off-by: Bartlomiej Sieka + +commit dafaede8a46c7159310239e036c93e31c6374487 +Author: Bartlomiej Sieka +Date: Thu Mar 20 23:20:31 2008 +0100 + + [new uImage] Disable debuging output in preparation for merge with master + + Signed-off-by: Bartlomiej Sieka + +commit fbe7a155027beacebaee9b32e1ada781fe924bca +Author: Bartlomiej Sieka +Date: Thu Mar 20 19:38:45 2008 +0100 + + [new uImage] Compilation and new uImage handling fixes for imxtract + + Fix imxtract command not being compiled-in despite CONFIG_CMD_XIMG being in + include/config_cmd_default.h. Fix few warnings and handling of new format + images. + + Signed-off-by: Bartlomiej Sieka + +commit 36cc8cbb3379d5166f882641123521735c469f92 +Author: Bartlomiej Sieka +Date: Thu Mar 20 23:10:19 2008 +0100 + + [new uImage] Fix autoscr command used with new uImage format + + Signed-off-by: Bartlomiej Sieka + +commit 43142e817f0597be412e7cbe19413f5532eafa5d +Author: Bartlomiej Sieka +Date: Thu Mar 20 23:10:19 2008 +0100 + + [new uImage] Fix *.its files location in documentation + + Signed-off-by: Bartlomiej Sieka + +commit 81a0ac62ea29f8252d0a714709d0ecfdbba2a15e +Author: Wolfgang Denk +Date: Thu Mar 20 22:01:38 2008 +0100 + + lwmon5 POST: remove unreachable code + + plus some coding style cleanup + + Signed-off-by: Wolfgang Denk + +commit b73a19e1609d0f705cbab8014ca17aefe89e4c76 +Author: Yuri Tikhonov +Date: Thu Mar 20 17:56:04 2008 +0300 + + LWMON5: POST RTC fix + + Modify the RTC API to provide one a status for the time reported by + the rtc_get() function: + 0 - a reliable time is guaranteed, + < 0 - a reliable time isn't guaranteed (power fault, clock issues, + and so on). + + The RTC chip drivers are responsible for providing this info if the + corresponding chip supports such functionality. If not - always + report that the time is reliable. + + The POST RTC test was modified to detect the RTC faults utilizing + this new rtc_get() feature. + + Signed-off-by: Yuri Tikhonov + +commit a5cc5555ccee596908a7d8cf22a104f6b993bfd5 +Author: Martin Krause +Date: Wed Mar 19 14:25:14 2008 +0100 + + TQM5200B: update MTD partition layout + + - insert partition for dtb blob to TQM5200B MTD layout + - set env variables dependent on the configured board + (TQM5200 or TQM5200B) + + Signed-off-by: Martin Krause + +commit f0105727d132f56a21fa3ed8b162309cca6cac44 +Author: Stefan Roese +Date: Wed Mar 19 07:09:26 2008 +0100 + + CFI: Small cleanup for FLASH_SHOW_PROGRESS + + With this patch we don't need that many #ifdef's in the code. It moves + the subtraction into the macro and defines a NOP-macro when + CONFIG_FLASH_SHOW_PROGRESS is not defined. + + Signed-off-by: Stefan Roese + Acked-by: Gerald Van Baren + +commit 9a042e9ca512beaaa2cb450274313fc477141241 +Author: Jerry Van Baren +Date: Sat Mar 8 13:48:01 2008 -0500 + + Flash programming progress countdown. + + Signed-off-by: Gerald Van Baren + +commit 5e339fd9ed539a7d7fec59cfc88f0857ab26a53f +Author: Bartlomiej Sieka +Date: Wed Mar 19 10:00:06 2008 +0100 + + [new uImage] Fix style issue spotted by Wolfgang Denk + + Signed-off-by: Bartlomiej Sieka + +commit 11abe45c48ec3485a6c1a5168ce8d79c3288adc1 +Author: David Gibson +Date: Mon Feb 18 18:09:04 2008 +1100 + + libfdt: Remove no longer used code from fdt_node_offset_by_compatible() + + Since fdt_node_offset_by_compatible() was converted to the new + fdt_next_node() iterator, a chunk of initialization code became + redundant, but was not removed by oversight. This patch cleans it up. + + Signed-off-by: David Gibson + +commit d0ccb9b140b472039732de102fc14597eedb14df +Author: David Gibson +Date: Mon Feb 18 18:06:31 2008 +1100 + + libfdt: Trivial cleanup for CHECK_HEADER) + + Currently the CHECK_HEADER() macro is defined local to fdt_ro.c. + However, there are a handful of functions (fdt_move, rw_check_header, + fdt_open_into) from other files which could also use it (currently + they open-code something more-or-less identical). Therefore, this + patch moves CHECK_HEADER() to libfdt_internal.h and uses it in those + places. + + Signed-off-by: David Gibson + +commit fe30a354cdbb808b5f15366a935b151a4ccee74f +Author: Kumar Gala +Date: Wed Feb 20 14:32:36 2008 -0600 + + Fix fdt boardsetup command parsing + + The introduciton of the 'fdt bootcpu' broke parsing for 'fdt boardsetup'. + + Signed-off-by: Kumar Gala + +commit 804887e6001e2f00bea11431bf34d6d472512cda +Author: Kumar Gala +Date: Fri Feb 15 03:34:36 2008 -0600 + + Add sub-commands to fdt + + fdt header - Display header info + fdt bootcpu - Set boot cpuid + fdt memory - Add/Update memory node + fdt rsvmem print - Show current mem reserves + fdt rsvmem add - Add a mem reserve + fdt rsvmem delete - Delete a mem reserves + + Signed-off-by: Kumar Gala + +commit f84d65f9b085ffbed464d1d58e8aaa8f5a2efc07 +Author: David Gibson +Date: Thu Feb 14 16:50:34 2008 +1100 + + libfdt: Fix NOP handling bug in fdt_add_subnode_namelen() + + fdt_add_subnode_namelen() has a bug if asked to add a subnode to a + node which has NOP tags interspersed with its properties. In this + case fdt_add_subnode_namelen() will put the new subnode before the + first NOP tag, even if there are properties after it, which will + result in an invalid blob. + + This patch fixes the bug, and adds a testcase for it. + + Signed-off-by: David Gibson + +commit ae0b5908de3b9855f8931bc9b32c9fc4962df5a9 +Author: David Gibson +Date: Tue Feb 12 11:58:31 2008 +1100 + + libfdt: Add and use a node iteration helper function. + + This patch adds an fdt_next_node() function which can be used to + iterate through nodes of the tree while keeping track of depth. This + function is used to simplify the iteration code in a lot of other + functions, and is also exported for use by library users. + + Signed-off-by: David Gibson + +commit 9eaeb07a7185d852c7aa10735ecd4e9edf24fb5d +Author: David Gibson +Date: Fri Jan 11 14:55:05 2008 +1100 + + libfdt: Add fdt_set_name() function + + This patch adds an fdt_set_name() function to libfdt, mirroring + fdt_get_name(). This is a r/w function which alters the name of a + given device tree node. + + Signed-off-by: David Gibson + +commit 23e20aa6488e6c0622496549861bfdc74108debe +Author: Yuri Tikhonov +Date: Tue Mar 18 13:33:30 2008 +0100 + + lwmon5: Fix register test logic to match the specific GDC h/w. + + Signed-off-by: Dmitry Rakhchev + Signed-off-by: Yuri Tikhonov + +commit 46bc0a938779aa1d664b847d36b08aa00f22e539 +Author: Yuri Tikhonov +Date: Tue Mar 18 13:27:57 2008 +0100 + + Fix backlight in the lwmon5 POST. + + Backlight was switched on even when temperature was too low. + + Signed-off-by: Dmitry Rakhchev + Signed-off-by: Yuri Tikhonov + +commit 3d61018643a2cd38c145aa6dde53f3f5f1a0e9cf +Author: Yuri Tikhonov +Date: Wed Feb 6 18:48:36 2008 +0100 + + The patch introduces the alternative configuration of the log buffer for the lwmon5 board: the storage for the log-buffer itself is OCM(on-chip memory), the log-buffer header is moved to six GPT registers (PPC440EPX_GPT0_COMP1, ..., PPC440EPX_GPT0_COMP5). + + To enable this, alternative, configuration the U-Boot board configuration + file for lwmon5 includes the definitions of alternative addresses for header + (CONFIG_ALT_LH_ADDR) and buffer (CONFIG_ALT_LB_ADDR). + + The Linux shall be configured with the CONFIG_ALT_LB_LOCATION option set, + and has the BOARD_ALT_LH_ADDR and BOARD_ALT_LB_ADDR constants defined in the + lwmon5 board-specific header (arch/ppc/platforms/4xx/lwmon5.h). + + Signed-off-by: Yuri Tikhonov + +commit 0f009f781b5b88f25769e154ea4d42db13baf0c6 +Author: Yuri Tikhonov +Date: Mon Feb 4 17:11:53 2008 +0100 + + Add support for the lwmon5 board reset via GPIO58. + + Signed-off-by: Dmitry Rakhchev + Signed-off-by: Yuri Tikhonov + +commit f694e32f93565ec1fa8d0226c584d6b89e931ed9 +Author: Yuri Tikhonov +Date: Mon Feb 4 17:09:55 2008 +0100 + + Some fixes to dspic, fpga, and gdc post tests for lwmon5. Disable external watch-dog for now. + + Signed-off-by: Dmitry Rakhchev + Signed-off-by: Yuri Tikhonov + +commit b428f6a8c65c5303e5f96db8d24f2f699d94a98c +Author: Yuri Tikhonov +Date: Mon Feb 4 14:11:03 2008 +0100 + + The patch introduces the CRITICAL feature of POST tests. If the test marked as POST_CRITICAL fails then the alternative, post_critical, boot-command is used. If this command is not defined then U-Boot enters into interactive mode. + + Signed-off-by: Dmitry Rakhchev + Signed-off-by: Yuri Tikhonov + +commit 8f15d4addd49c956412e1e3bfc764a0c8b1f3184 +Author: Yuri Tikhonov +Date: Mon Feb 4 14:10:42 2008 +0100 + + The patch adds new POST tests for the Lwmon5 board. These are: + + * External Watchdog test; + * dsPIC tests; + * FPGA test; + * GDC test; + * Sysmon tests. + + Signed-off-by: Dmitry Rakhchev + Signed-off-by: Yuri Tikhonov + +commit c2ed33efbfff5767bca236828e021c55fd547b6c +Author: Yuri Tikhonov +Date: Mon Feb 4 14:10:01 2008 +0100 + + Enable CODEC POST with CFG_POST_CODEC rather than with CFG_POST_DSP. + + Signed-off-by: Dmitry Rakhchev + +commit 3515fd18d4e8e44f863ac7142b55e22b109e9af2 +Author: Wolfgang Denk +Date: Tue Mar 18 17:35:51 2008 +0100 + + HMI1001: fix compile problem. + + Signed-off-by: Wolfgang Denk + +commit 1f2a9970109cebf7446e0503b10b71f8673045ee +Author: Mike Frysinger +Date: Mon Feb 18 05:32:30 2008 -0500 + + Blackfin: BF537-stamp: drop board-specific flash driver for CFI + + The parallel flash on the BF537-STAMP is CFI compliant, so there is no need + for the board specific driver at all. Just use the common CFI driver. + + Signed-off-by: Mike Frysinger + +commit 5b22163fef865af2b6bfb6b75f1b7bf443ce170c +Author: Mike Frysinger +Date: Tue Feb 19 00:36:14 2008 -0500 + + Blackfin: add proper ELF markings to some assembly functions + + Signed-off-by: Mike Frysinger + +commit cf675d3b2b9c3511c1d99bc8f8f38fd2f08bfcaf +Author: Mike Frysinger +Date: Tue Feb 19 00:35:17 2008 -0500 + + Blackfin: new cplbinfo command for viewing cplb tables + + Signed-off-by: Mike Frysinger + +commit aadb72503cd1602349a5fe53356d5f55ecc1b900 +Author: Mike Frysinger +Date: Mon Feb 18 05:37:51 2008 -0500 + + Blackfin: update MAINTAINERS list + + Add maintainer information for the Blackfin boards. + + Signed-off-by: Mike Frysinger + +commit f7ce12cb65a30c6e152eecf26f0304b7d78cf39d +Author: Mike Frysinger +Date: Mon Feb 18 05:26:48 2008 -0500 + + Blackfin: convert BFIN_CPU to CONFIG_BFIN_CPU + + Stop tying things to the processor that should be tied to other defines and + change BFIN_CPU to CONFIG_BFIN_CPU so that it can be used in the build + system to select the -mcpu option. + + Signed-off-by: Mike Frysinger + +commit 86a20fb920bd198105acf7b1191117f566d637ed +Author: Mike Frysinger +Date: Sat Feb 16 07:40:36 2008 -0500 + + Blackfin: move bootldr command to common code + + This moves the Blackfin-common bootldr command out of the BF537-STAMP + specific board directory and into the common directory so that all Blackfin + boards may utilize it. + + Signed-off-by: Mike Frysinger + +commit decbe029b2a9d3333d02c433389b1c821eea96d7 +Author: Heiko Schocher +Date: Fri Mar 14 11:05:20 2008 +0100 + + mgcoge: update configuration + + Fix configuration for mgcoge board + + Signed-off-by: Heiko Schocher + +commit c136724cda0219c49f1d4b346f00da29b14fdf14 +Author: Wolfgang Denk +Date: Sun Mar 16 01:22:59 2008 +0100 + + drivers/rtc/Makefile: keep list sorted + + Signed-off-by: Wolfgang Denk + +commit 9536dfcce03e7be4ccbceb47a08d9ba07ada362f +Author: Tor Krill +Date: Sat Mar 15 15:40:26 2008 +0100 + + Add support for Intersil isl1208 RTC + + Signed-off-by: Tor Krill + +commit 0210cff3d079d97b2156b13685ee8de368e68a1a +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sat Mar 15 17:36:41 2008 +0100 + + cramfs: Fix ifdef + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit 0b8f2a27861a9fd06eb55a34f855ec9c5102aab4 +Author: Wolfgang Denk +Date: Sun Mar 16 01:12:58 2008 +0100 + + Conding style cleanup + + Signed-off-by: Wolfgang Denk + commit 41712b4e8c95dff23354bcd620e1f9477160c190 Author: Stefan Roese Date: Wed Mar 5 12:31:53 2008 +0100 @@ -226,6 +1563,25 @@ Date: Tue Mar 11 13:52:25 2008 +0100 Signed-off-by: Stefan Roese +commit 766529fccc860ecb9e955b4239dff69cd9e4ea09 +Author: Bartlomiej Sieka +Date: Fri Mar 14 16:22:34 2008 +0100 + + Add MD5 support to the new uImage format + + Signed-off-by: Bartlomiej Sieka + +commit 0ede0c383530a418cf98be9122371a86573cd0db +Author: Bartlomiej Sieka +Date: Fri Mar 14 16:22:34 2008 +0100 + + Add the MD5 algorithm + + MD5 supoprt is turned on by defining CONFIG_MD5, the digest can be then + calculated using the md5() function -- see include/md5.h for details. + + Signed-off-by: Bartlomiej Sieka + commit b8aa57b5d4d69e8f0810a5e632c0ce41c0f46ee0 Author: Wolfgang Denk Date: Fri Mar 14 16:04:54 2008 +0100 @@ -259,6 +1615,276 @@ Date: Thu Mar 13 14:29:49 2008 +0100 Signed-off-by: Wolfgang Denk +commit afe45c87e3c5d77bad76b1a57dccd20764d45b5d +Author: Marian Balakowicz +Date: Wed Mar 12 12:14:15 2008 +0100 + + [new uImage] Fix build issue on ARM + + ARM platforms don't have a bd->bi_memsize so use bd->bi_dram[0].size instead. + + Signed-off-by: Kumar Gala + +commit 3310c549a73a949430bfda90876df7552a1dab0c +Author: Marian Balakowicz +Date: Wed Mar 12 12:13:13 2008 +0100 + + [new uImage] Add new uImage format documentation and examples + + Create doc/uImage.FIT documentation directory with the following files: + - command_syntax_extensions.txt : extended command syntax description + - howto.txt : short usage howto + - source_file_format.txt : internal new uImage format description + + Add example image source files: + - kernel.its + - kernel_fdt.its + - multi.its + + Update README appropriately. + + Signed-off-by: Marian Balakowicz + Signed-off-by: Bartlomiej Sieka + +commit 1ec73761d2e247078f4520a265d463e8b73391a2 +Author: Marian Balakowicz +Date: Wed Mar 12 10:35:52 2008 +0100 + + [new uImage] Fix definition of common bootm_headers_t fields + + verify, autostart and lmb fields are used regardless of CONFIG_FIT + setting, move their definitions to common section. + + Signed-off-by: Marian Balakowicz + +commit 1d1cb4270edc6a99276834064069717f9782c491 +Author: Marian Balakowicz +Date: Wed Mar 12 10:35:51 2008 +0100 + + [new uImage] Fix build problems on trab board + + Signed-off-by: Marian Balakowicz + +commit f773bea8e11f4a11c388dcee956b2444203e6b65 +Author: Marian Balakowicz +Date: Wed Mar 12 10:35:46 2008 +0100 + + [new uImage] Add proper ramdisk/FDT handling when FIT configuration is used + + Save FIT configuration provied in the first bootm argument and use it + when to get ramdisk/FDT subimages when second and third (ramdisk/FDT) + arguments are not specified. + + Signed-off-by: Marian Balakowicz + +commit 2682ce8a4225f23d72bb7fed069e928dd39d34ae +Author: Marian Balakowicz +Date: Wed Mar 12 10:33:01 2008 +0100 + + [new uImage] More verbose kernel image uncompress error message + + Signed-off-by: Marian Balakowicz + +commit 1372cce2b9040fb640e5032b84e3a033a22d6ff0 +Author: Marian Balakowicz +Date: Wed Mar 12 10:33:01 2008 +0100 + + [new uImage] Use show_boot_progress() for new uImage format + + This patch allocates a set of show_boot_progress() IDs for new uImage format + and adds show_boot_progress() calls in new uImage format handling code. + + Signed-off-by: Marian Balakowicz + +commit c28c4d193dbfb20b2dd3a5447640fd6de7fd0720 +Author: Marian Balakowicz +Date: Wed Mar 12 10:33:01 2008 +0100 + + [new uImage] Add new uImage fromat support to fpga command + + Signed-off-by: Marian Balakowicz + +commit 09475f7527460e426c0e0628fc5b8f3754fbaa23 +Author: Marian Balakowicz +Date: Wed Mar 12 10:33:01 2008 +0100 + + [new uImage] Add new uImage format handling to other bootm related commands + + Updated commands: + + docboot - cmd_doc.c + fdcboot - cmd_fdc.c + diskboot - cmd_ide.c + nboot - cmd_nand.c + scsiboot - cmd_scsi.c + usbboot - cmd_usb.c + + Signed-off-by: Marian Balakowicz + +commit 1b7897f28d49a80d78d760ec6f6f11dc0f914338 +Author: Marian Balakowicz +Date: Wed Mar 12 10:33:00 2008 +0100 + + [new uImage] Add new uImage format support to imgextract command + + Signed-off-by: Marian Balakowicz + +commit 424c4abdd175d2c470510df8ce0e32d3f463ec16 +Author: Marian Balakowicz +Date: Wed Mar 12 10:33:00 2008 +0100 + + [new uImage] Add new uImage format support to autoscript routine + + autoscript() routine is updated to accept second argument, which + is only used for FIT images and provides a FIT subimage unit name. + + autoscript() routine callers must now pass two arguments. For + non-interactive use (like in cmd_load.c, cmd_net.c), new environment + variable 'autoscript_uname' is introduced and used as a FIT + subimage unit name source. + + autoscript command accepts extended syntax of the addr argument: + addr: + + Signed-off-by: Marian Balakowicz + +commit cd7c596e9f561dbbc17b717277438aee78cde14f +Author: Marian Balakowicz +Date: Wed Mar 12 10:33:00 2008 +0100 + + [new uImage] Add new uImage format support to arch specific do_bootm_linux() routines + + This patch updates architecture specific implementations of + do_bootm_linux() adding new uImage format handling for + operations like get kernel entry point address, get kernel + image data start address. + + Signed-off-by: Marian Balakowicz + +commit 3dfe110149311425919e6d6a14b561b4207498f1 +Author: Marian Balakowicz +Date: Wed Mar 12 10:32:59 2008 +0100 + + [new uImage] Add node offsets for FIT images listed in struct bootm_headers + + This patch adds new node offset fields to struct bootm_headers + and updates bootm_headers processing code to make use of them. + Saved node offsets allow to avoid repeating fit_image_get_node() calls. + + Signed-off-by: Marian Balakowicz + +commit bc8ed486b125452ba3bd8344f052f437329150c5 +Author: Marian Balakowicz +Date: Wed Mar 12 10:32:53 2008 +0100 + + [new uImage] ppc: Add new uImage format support to FDT handling routines + + Support for new (FIT) format uImages is added to powerpc specific + boot_get_fdt() routine which now recognizes, sanity checks FIT image + and is able to access data sections of the requested component image. + + Signed-off-by: Marian Balakowicz + +commit a44a269a905f924b420020506a4d7d7eedcc0eaf +Author: Marian Balakowicz +Date: Wed Mar 12 10:14:57 2008 +0100 + + [new uImage] Re-enable interrupts for non automatic booting + + Re-enable interrupts if we return from do_bootm_ and 'autostart' + environment variable is not set to 'yes'. + + Signed-off-by: Marian Balakowicz + +commit d985c8498c4e47095820da97aa722381d39172c5 +Author: Marian Balakowicz +Date: Wed Mar 12 10:14:38 2008 +0100 + + [new uImage] Remove unnecessary arguments passed to ramdisk routines + + boot_get_ramdisk() and image_get_ramdisk() do not need all + cmdtp, flag, argc and argv arguments. Simplify routines definition. + + Signed-off-by: Marian Balakowicz + +commit c87796483bc7c2900470dc747c367f602577608d +Author: Marian Balakowicz +Date: Wed Mar 12 10:12:37 2008 +0100 + + [new uImage] Add new uImage format support for ramdisk handling + + This patch updates boot_get_ramdisk() routine adding format + verification and handling for new (FIT) uImages. + + Signed-off-by: Marian Balakowicz + +commit 6986a385671749ecb3f60cf99e9cbae8e47bb50e +Author: Marian Balakowicz +Date: Wed Mar 12 10:01:05 2008 +0100 + + [new uImage] Add new uImage format support for kernel booting + + New format uImages are recognized by the bootm command, + validity of specified kernel component image is checked and + its data section located and used for further processing + (uncompress, load, etc.) + + Signed-off-by: Marian Balakowicz + +commit e32fea6adb620ecf2bd70acf2dd37e53df9d1547 +Author: Marian Balakowicz +Date: Tue Mar 11 12:35:20 2008 +0100 + + [new uImage] Add new uImage format support for imls and iminfo commands + + imls and iminfo can now recognize nad print out contents of the new (FIT) + format uImages. + + Signed-off-by: Marian Balakowicz + +commit 9d25438fe7d70cf35a8a293ea5e392fefc672613 +Author: Bartlomiej Sieka +Date: Tue Mar 11 12:34:47 2008 +0100 + + [new uImage] Add support for new uImage format to mkimage tool + + Support for the new uImage format (FIT) is added to mkimage tool. + Commandline syntax is appropriately extended: + + mkimage [-D dtc_options] -f fit-image.its fit-image + + mkimage (together with dtc) takes fit-image.its and referenced therein + binaries (like vmlinux.bin.gz) as inputs, and produces fit-image file -- the + final image that can be transferred to the target (e.g., via tftp) and then + booted using the bootm command in U-Boot. + + Signed-off-by: Bartlomiej Sieka + +commit eb6175edd6c120d8b89678243e5a2be362ee8e40 +Author: Marian Balakowicz +Date: Mon Mar 10 17:53:49 2008 +0100 + + [new uImage] Make node unit names const in struct bootm_headers + + Signed-off-by: Marian Balakowicz + +commit 5dfb52138688ccbf0146f62683fe6217b3ce1b05 +Author: Marian Balakowicz +Date: Fri Feb 29 21:24:06 2008 +0100 + + [new uImage] New uImage low-level API + + Add FDT-based functions for handling new format component images, + configurations, node operations, property get/set, etc. + + fit_ - routines handling global new format uImage operations + like get/set top level property, process all nodes, etc. + fit_image_ - routines handling component images subnodes + fit_conf_ - routines handling configurations node + + Signed-off-by: Bartlomiej Sieka + Signed-off-by: Marian Balakowicz + commit 30f1806f60978d707b0cff2d7bf89d141fc24290 Author: Wolfgang Denk Date: Sun Mar 9 16:20:02 2008 +0100 @@ -857,6 +2483,238 @@ Date: Sun Feb 24 11:44:29 2008 +0900 Signed-off-by: Shinya Kuribayashi +commit 05e07b1ea22844e946cfcf7d5e8a0199d18d2a95 +Author: Marian Balakowicz +Date: Fri Feb 29 22:22:46 2008 +0100 + + [new uImage] Fix FDT blob totalsize calculation in boot_relocate_fdt() + + Do not use global fdt blob pointer, calculate blob size from routine + argument blob pointer. + + Signed-off-by: Marian Balakowicz + +commit d1cc52879c8966507dad9fb575481e6d3985e64e +Author: David Gibson +Date: Tue Feb 12 00:58:31 2008 +1100 + + libfdt: Add and use a node iteration helper function. + + This patch adds an fdt_next_node() function which can be used to + iterate through nodes of the tree while keeping track of depth. This + function is used to simplify the iteration code in a lot of other + functions, and is also exported for use by library users. + + Signed-off-by: David Gibson + +commit 8cf30809a82902a471866d2f07725ce3b8a22291 +Author: Bartlomiej Sieka +Date: Fri Feb 29 16:00:24 2008 +0100 + + [new uImage] Add libfdt support to mkimage + + Signed-off-by: Bartlomiej Sieka + +commit a6e530f00d31a8494a0422799b2b9a692a9c0eb9 +Author: Bartlomiej Sieka +Date: Fri Feb 29 16:00:23 2008 +0100 + + [new uImage] Add sha1.o object to mkimage binary build + + Signed-off-by: Bartlomiej Sieka + +commit df6f1b895c997978f03afe04502ee76b7ba34ab9 +Author: Marian Balakowicz +Date: Fri Feb 29 16:00:06 2008 +0100 + + [new uImage] Fix component handling for legacy multi component images + + Use uint32_t when accessing size table in image_multi_count() and + image_multi_getimg() for multi component images. + + Add missing uimage_to_cpu() endianness conversion. + + Signed-off-by: Marian Balakowicz + +commit 570abb0ad120f6002bcaa3cf6f32bd4ca2e1b248 +Author: Marian Balakowicz +Date: Fri Feb 29 15:59:59 2008 +0100 + + [new uImage] Share common uImage code between mkimage and U-boot + + This patch adds the following common routines: + + 1) Dedicated mkimage print_header() is replaced with common + image_print_contents() + image_print_contents_noindent() + + 2) Common os/arch/type/comp fields name <--> id translation routines + genimg_get_os_name() + genimg_get_arch_name() + genimg_get_type_name() + genimg_get_comp_name() + genimg_get_os_id() + genimg_get_arch_id() + genimg_get_type_id() + genimg_get_comp_id() + + Signed-off-by: Marian Balakowicz + +commit 9a4daad0a35eb5143037eea9f786a3e9d672bdd6 +Author: Marian Balakowicz +Date: Fri Feb 29 14:58:34 2008 +0100 + + [new uImage] Update naming convention for bootm/uImage related code + + This patch introduces the following prefix convention for the + image format handling and bootm related code: + + genimg_ - dual format shared code + image_ - legacy uImage format specific code + fit_ - new uImage format specific code + boot_ - booting process related code + + Related routines are renamed and a few pieces of code are moved around and + re-grouped. + + Signed-off-by: Marian Balakowicz + +commit 75fa002c47171b73fb4c1f2c2fe4d6391c136276 +Author: Kumar Gala +Date: Wed Feb 27 21:51:51 2008 -0600 + + [new uImage] Respect autostart setting in linux bootm + + Signed-off-by: Kumar Gala + Acked-by: Marian Balakowicz + +commit d3f2fa0d278467b2232e4eb2372f905c3febfbeb +Author: Kumar Gala +Date: Wed Feb 27 21:51:50 2008 -0600 + + [new uImage] Provide ability to restrict region used for boot images + + Allow the user to set 'bootm_low' and 'bootm_size' env vars as a way + to restrict what memory range is used for bootm. + + Signed-off-by: Kumar Gala + Acked-by: Marian Balakowicz + +commit e822d7fc4dd4755d4d0a22f05e33f33d1a0481da +Author: Kumar Gala +Date: Wed Feb 27 21:51:49 2008 -0600 + + [new uImage] Use lmb for bootm allocations + + Convert generic ramdisk_high(), get_boot_cmdline(), get_boot_kbd() + functions over to using lmb for allocation of the ramdisk, command line + and kernel bd info. + + Convert PPC specific fdt_relocate() to use lmb for allocation of the device + tree. + + Provided a weak function that board code can call to do additional + lmb reserves if needed. + + Also introduce the concept of bootmap_base to specify the offset in + physical memory that the bootmap is located at. This is used for + allocations of the cmdline, kernel bd, and device tree as they should + be contained within bootmap_base and bootmap_base + CFG_BOOTMAPSZ. + + Signed-off-by: Kumar Gala + +commit f5614e7926863bf0225ec860d9b319741a9c4004 +Author: Kumar Gala +Date: Wed Feb 27 21:51:48 2008 -0600 + + [new uImage] Add autostart flag to bootm_headers structure + + The autostart env variable was dropped as part of the initial new uImage + cleanup. Add it back here so the arch specific code can decide if it + wants to really boot or not. + + Signed-off-by: Kumar Gala + Acked-by: Marian Balakowicz + +commit 4ed6552f715983bfc7d212c1199a1f796f1144ad +Author: Kumar Gala +Date: Wed Feb 27 21:51:47 2008 -0600 + + [new uImage] Introduce lmb from linux kernel for memory mgmt of boot images + + Introduce the LMB lib used on PPC in the kernel as a clean way to manage + the memory spaces used by various boot images and structures. This code + will allow us to simplify the code in bootm and its support functions. + + Signed-off-by: Kumar Gala + +commit 4648c2e7a173b0d7f17bef4adaa0623090c9e904 +Author: Kumar Gala +Date: Tue Feb 19 22:03:47 2008 -0600 + + [new uImage] ppc: Allow boards to specify effective amount of memory + + For historical reasons we limited the stack to 256M because some boards + could only map that much via BATS. However newer boards are capable of + mapping more memory (for example 85xx is capable of doing up to 2G). + + Signed-off-by: Kumar Gala + Acked-by: Marian Balakowicz + +commit 274cea2bddbca10cdad7daa518951b75c44ef6bc +Author: Kumar Gala +Date: Wed Feb 27 21:51:46 2008 -0600 + + [new uImage] rework error handling so common functions don't reset + + Changed image_get_ramdisk() to just return NULL on error and have + get_ramdisk() propogate that error to the caller. It's left to the + caller to call do_reset() if it wants to. + + Also moved calling do_reset() in get_fdt() and fdt_relocate() on ppc + to a common location. In the future we will change get_fdt() and + fdt_relocate() to return success/failure and not call do_reset() at all. + + Signed-off-by: Kumar Gala + Acked-by: Marian Balakowicz + +commit d2bc095a639672def11d5d043b5688d0dbd692ec +Author: Kumar Gala +Date: Wed Feb 27 21:51:45 2008 -0600 + + [new uImage] ppc: Re-order ramdisk/fdt handling sequence + + Doing the fdt before the ramdisk allows us to grow the fdt w/o concern + however it does mean we have to go in and fixup the initrd info since + we don't know where it will be. + + Signed-off-by: Kumar Gala + +commit 27953493ef025fb698d68c5dee39b36f01f4d530 +Author: Kumar Gala +Date: Wed Feb 27 21:51:44 2008 -0600 + + [new uImage] ppc: Determine if we are booting an OF style + + If we are bootin OF style than we can skip setting up some things + that are used for the old boot method. + + Signed-off-by: Kumar Gala + Acked-by: Marian Balakowicz + +commit a6612bdfe7ef37b9787b66800cf02aaded05fbeb +Author: Kumar Gala +Date: Wed Feb 27 21:51:43 2008 -0600 + + [new uImage] Don't pass kdb to ramdisk_high since we may not have one + + We don't actually need the kdb param as we are just using it to get + bd->bi_memsize which we can get from gd->bd->bi_memsize. Also, if we + boot via OF we might not actually fill out a kdb. + + Signed-off-by: Kumar Gala + Acked-by: Marian Balakowicz + commit 2b22fa4baee51e6b467c44ea1be0d1ecd86e8775 Author: Kumar Gala Date: Wed Feb 27 16:30:47 2008 -0600 @@ -917,6 +2775,98 @@ Date: Sun Feb 17 22:56:16 2008 +0100 Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD +commit 4efbe9dbb129f857f27856936112c8c02f016be6 +Author: Marian Balakowicz +Date: Wed Feb 27 11:02:26 2008 +0100 + + [new uImage] Correct raw FDT blob handlig when CONFIG_FIT is disabled + + Dual format image code must properly handle all three FDT passing methods: + - raw FDT blob passed + - FDT blob embedded in the legacy uImage + - FDT blob embedded in the new uImage + + This patch enables proper raw FDT handling when no FIT imaeg support + is compiled in. This is a bit tricky as we must dected FIT format even + when FIT uImage handling is not enabled as both FIT uImages and raw FDT + blobs use tha same low level format (libfdt). + + Signed-off-by: Marian Balakowicz + +commit ff0734cff0fb5397ce2f4602f4f3e5ec9c8a36e8 +Author: Marian Balakowicz +Date: Wed Feb 27 11:02:26 2008 +0100 + + [new uImage] POWERPC: Add image_get_fdt() routine + + FDT blob may be passed either: (1) raw (2) or embedded in the legacy uImage + (3) or embedded in the new uImage. For the (2) case embedding image must be + verified before we get FDT from it. This patch factors out legacy image + specific verification routine to the separate helper routine. + + Signed-off-by: Marian Balakowicz + Acked-by: Kumar Gala + +commit 1efd43601f90de21ec6c0ebb9880823e822927b1 +Author: Marian Balakowicz +Date: Wed Feb 27 11:02:07 2008 +0100 + + [new uImage] Add image_get_kernel() routine + + Legacy image specific verification is factored out to a separate helper + routine to keep get_kernel() generic and simple. + + Signed-off-by: Marian Balakowicz + Acked-by: Kumar Gala + +commit 8a5ea3e6168fe6a2780eeaf257a3b19f30dec658 +Author: Marian Balakowicz +Date: Wed Feb 27 11:01:04 2008 +0100 + + [new uImage] Move image verify flag to bootm_headers structure + + Do not pass image verification flag directly to related routines. + Simplify argument passing and move it to the bootm_header structure which + contains curently processed image specific data and is already being passed + on the argument list. + + Signed-off-by: Marian Balakowicz + Acked-by: Kumar Gala + +commit 823afe7cefe00dafefc6696c1cc7aa828c394234 +Author: Marian Balakowicz +Date: Wed Feb 27 11:00:47 2008 +0100 + + [Makefile] Sort COBJS in lib_ Makefiles + + Signed-off-by: Marian Balakowicz + +commit 6f0f9dfc4ee880fbf400a2ebe14238181a6c3f91 +Author: Marian Balakowicz +Date: Wed Feb 27 11:00:47 2008 +0100 + + [new uImage] Optimize gen_get_image() flow control + + When CONFIG_HAS_DATAFLASH is not defined gen_get_image() routine has nothing + to do, update its control flow to better reflect that simple case. + + Signed-off-by: Marian Balakowicz + Acked-by: Kumar Gala + +commit d2ced9eb19ec74f4a359949dbe353427fa6d55ca +Author: Marian Balakowicz +Date: Mon Feb 4 08:28:17 2008 +0100 + + [new uImage] POWERPC: Split get_fdt() into get and relocate routines + + PPC specific FDT blob handling code is divided into two separate routines: + + get_fdt() - find and verify a FDT blob (either raw or image embedded) + fdt_relocate() - move FDT blob to within BOOTMAP if needed + + Signed-off-by: Marian Balakowicz + Acked-by: Kumar Gala + commit 33fa5c0bfaf465de8ceb23fcd6b397f68b35a817 Author: Jon Loeliger Date: Mon Feb 25 13:13:37 2008 -0600 @@ -982,6 +2932,24 @@ Date: Sun Feb 24 23:03:10 2008 +0000 Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD +commit d5934ad7756f038a393a9cfab76a4fe306d9d930 +Author: Marian Balakowicz +Date: Mon Feb 4 08:28:09 2008 +0100 + + [new uImage] Add dual format uImage support framework + + This patch adds framework for dual format images. Format detection is added + and the bootm controll flow is updated to include cases for new FIT format + uImages. + + When the legacy (image_header based) format is detected appropriate + legacy specific handling is invoked. For the new (FIT based) format uImages + dual boot framework has a minial support, that will only print out a + corresponding debug messages. Implementation of the FIT specific handling will + be added in following patches. + + Signed-off-by: Marian Balakowicz + commit b29661fc1151077776454288051bc9a488351ce8 Author: Wolfgang Denk Date: Sun Feb 24 15:21:36 2008 +0100 @@ -1272,6 +3240,73 @@ Date: Sat Feb 16 02:12:37 2008 -0500 Signed-off-by: Mike Frysinger +commit 5583cbf736474ef754e128a54fb78632f57b48fd +Author: Marian Balakowicz +Date: Thu Feb 21 17:27:49 2008 +0100 + + [new uImage] Fix erroneous use of image_get_magic() in fdc/usb cmds + + Signed-off-by: Marian Balakowicz + +commit 2242f5369822bc7780db95c47985bb408ea9157b +Author: Marian Balakowicz +Date: Thu Feb 21 17:27:41 2008 +0100 + + [new uImage] Rename and move print_image_hdr() routine + + Signed-off-by: Marian Balakowicz + +commit f50433d670ec2ee9e96abac67cdc6e5e061a810d +Author: Marian Balakowicz +Date: Thu Feb 21 17:20:20 2008 +0100 + + [new uImage] Add fit_parse_conf() and fit_parse_subimage() routines + + Introducing routines for parsing new uImage format bootm arguments: + []# - configuration specification + []: - subimage specification + + New format images can contain multiple subimages of the same type. For example + a single new format image file can contain three kernels, two ramdisks and a + couple of FDT blobs. Subimage and configuration specifications are extensions + to bootm (and other image-related commands) arguments' syntax that allow to + specify which particular subimage should be operated on. + + Subimage specification is used to denote a particular subimage. Configurations + are a bit more complex -- they are used to define a particualr booting setup, + for example a (kernel, fdt blob) pair, or a (kernel, ramdisk, fdt blob) tuple, + etc. + + Signed-off-by: Marian Balakowicz + +commit fff888a1997ff7de9b29e24050fc4a0fd403ba16 +Author: Marian Balakowicz +Date: Thu Feb 21 17:20:19 2008 +0100 + + [new uImage] Add gen_get_image() routine + + This routine assures that image (whether legacy or FIT) is not + in a special dataflash storage. + + If image address is a dataflash address image is moved to system RAM. + + Signed-off-by: Marian Balakowicz + +commit 75d3e8fbd93c14d9929d024c75af2d742c76db70 +Author: Marian Balakowicz +Date: Thu Feb 21 17:20:18 2008 +0100 + + [new uImage] Pull in libfdt if CONFIG_FIT is enabled + + New uImage format (Flattened Image Tree) requires libfdt + functionality, print out error message if CONFIG_OF_LIBFDT + is not defined. + + New uImage support is enabled by defining CONFIG_FIT (and CONFIG_OF_LIBFDT). + This commit turns it on by default. + + Signed-off-by: Marian Balakowicz + commit 1ba639da5604a64b3ed884a2cbb1c5414a9fa728 Author: Michael Schwingen Date: Mon Feb 18 23:16:35 2008 +0100 @@ -2050,6 +4085,312 @@ Date: Thu Jan 17 08:25:45 2008 -0600 Signed-off-by: Kumar Gala +commit 5cf746c303710329f8040d9c62ee354313e3e91f +Author: Marian Balakowicz +Date: Thu Jan 31 13:59:09 2008 +0100 + + [new uImage] Move kernel data find code to get_kernel() routine + + Verification of the kernel image (in old format) and finding kernel + data is moved to a dedicated routine. The routine will also hold + support for, to be added, new image format. + + Signed-off-by: Marian Balakowicz + +commit 7b325454fd231d4273de3fe373850f777fb086bf +Author: Marian Balakowicz +Date: Thu Jan 31 13:58:20 2008 +0100 + + [new uImage] Cleanup FDT handling in PPC do_boot_linux() + + Move FDT blob finding and relocation to a dedicated + get_fdt() routine. It increases code readability and + will make adding support for new uImage format easier. + + Signed-off-by: Marian Balakowicz + +commit b6b0fe6460b7063ac60b9a3531ef210aedb31451 +Author: Marian Balakowicz +Date: Thu Jan 31 13:58:13 2008 +0100 + + [new uImage] Cleanup do_botm_linux() boot allocations + + This patch moves common pre-boot allocation steps shared between PPC + and M68K to a helper routines: + + common: + - get_boot_sp_limit() + - get_boot_cmline() + - get_boot_kbd() + + platform: + - set_clocks_in_mhz() + + Signed-off-by: Marian Balakowicz + +commit ceaed2b1e54ebf14d600e02fef016c8df5cc4d40 +Author: Marian Balakowicz +Date: Thu Jan 31 13:57:17 2008 +0100 + + [new uImage] Move ramdisk loading to a common routine + + Ramdisk loading code, including initrd_high variable handling, + was duplicated for PPC and M68K platforms. This patch creates + common helper routine that is being called from both platform + do_bootm_linux() routines. + + Signed-off-by: Marian Balakowicz + +commit 68d4f05e6b2383a442fb71f80f2a9fbb3d8def68 +Author: Marian Balakowicz +Date: Thu Jan 31 13:55:53 2008 +0100 + + [new uImage] Removed dead ramdisk code on microblaze architectures + + Microblaze do_bootm_linux() includes ramdisk processing code but + the ramdisk does not get used anywhere later on. + + Signed-off-by: Marian Balakowicz + +commit 5ad03eb3854c162684222a718b44c0716ea0db03 +Author: Marian Balakowicz +Date: Thu Jan 31 13:55:39 2008 +0100 + + [new uImage] Factor out common image_get_ramdisk() routine + + Architecture specific do_bootm_linux() routines share common + ramdisk image processing code. Move this code to a common + helper routine. + + Signed-off-by: Marian Balakowicz + +commit d3c5eb6dd1f4ed3c3388386cf1d1bf82aa51d56b +Author: Marian Balakowicz +Date: Thu Jan 31 13:20:08 2008 +0100 + + [new uImage] Move FDT error printing to common fdt_error() routine + + FDT error handling in PPC do_bootm_linux() shares the same message format. + This patch moves error message printing to a helper fdt_error() routine. + + Signed-off-by: Marian Balakowicz + Acked-by: Gerald Van Baren + +commit 42b73e8ee00d48004791dea64b8093fb974c57e1 +Author: Marian Balakowicz +Date: Thu Jan 31 13:20:07 2008 +0100 + + [new uImage] Factor out common routines for getting os/arch/type/comp names + + Move numeric-id to name translation for image os/arch/type/comp header + fields to a helper routines: image_get_os_name(), image_get_arch_name(), + image_get_type_name(), image_get_comp_name(). + + Signed-off-by: Marian Balakowicz + +commit e99c26694a384221d336f6448c06a57479c0baa4 +Author: Marian Balakowicz +Date: Thu Jan 31 13:20:07 2008 +0100 + + [new uImage] Remove standalone applications handling from boootm + + Standalone applications are supposed to be run using the "go" command. + This patch removes standalone images handling from the do_bootm(). + + Signed-off-by: Marian Balakowicz + +commit 4a2ad5ff6400698433dd7203d34939c3c9cc9bff +Author: Marian Balakowicz +Date: Thu Jan 31 13:20:07 2008 +0100 + + [new uImage] Remove OF_FLAT_TREE support from PPC bootm code + + Support for OF_FLAT_TREE is to be obsoleted in the near future, + remove related code from the bootm routines. + + Signed-off-by: Marian Balakowicz + +commit 82850f3d32a2661868ec6876bed7a22c55cef718 +Author: Marian Balakowicz +Date: Thu Jan 31 13:20:06 2008 +0100 + + [new uImage] Use image API in SH do_bootm_linux() routine + + Introduce image handling API for lately added Hitachi SH architecture. + + Signed-off-by: Marian Balakowicz + +commit 4a995edec1ac163d9326d143ffe2b47e7543407f +Author: Marian Balakowicz +Date: Thu Jan 31 13:20:06 2008 +0100 + + [new uImage] Rename architecture specific bootm code files + + Implementation of the do_bootm_linux() and other bootm helper routines is + architecture specific code. As such it resides in lib_ directories + in files named _linux.c + + This patch renames those files to a more clear and accurate + lib_/bootm.c form. + + List of the renamed files: + lib_arm/armlinux.c -> lib_arm/bootm.c + lib_avr32/avr32_linux.c -> lib_avr32/bootm.c + lib_blackfin/bf533_linux.c -> lib_blackfin/bootm.c + lib_i386/i386_linux.c -> lib_i386/bootm.c + lib_m68k/m68k_linux.c -> lib_m68k/bootm.c + lib_microblaze/microblaze_linux.c -> lib_microblaze/bootm.c + lib_mips/mips_linux.c -> lib_mips/bootm.c + lib_nios/nios_linux.c -> lib_nios/bootm.c + lib_nios2/nios_linux.c -> lib_nios2/bootm.c + lib_ppc/ppc_linux.c -> lib_ppc/bootm.c + lib_sh/sh_linux.c -> lib_sh/bootm.c + + Signed-off-by: Marian Balakowicz + +commit 7582438c285bf0cef82909d0f232de64ec567a8a +Author: Marian Balakowicz +Date: Thu Jan 31 13:20:06 2008 +0100 + + [new uImage] Return error on image move/uncompress overwrites + + Check for overwrites during image move/uncompress, return with error + when the original image gets corrupted. Report clear message to the user + and prevent further troubles when pointer to the corrupted images is passed + to do_bootm_linux routine. + + Signed-off-by: Marian Balakowicz + +commit f13e7b2e993c61fed1f607962501e051940d6e80 +Author: Marian Balakowicz +Date: Tue Jan 8 18:12:17 2008 +0100 + + [new uImage] Cleanup image header pointer use in bootm code + + - use single image header pointer instead of a set of auxilliary variables. + - add multi component image helper routines: get component size/data address + + Signed-off-by: Marian Balakowicz + +commit 1ee1180b6e93e56d0282ac8d943e448e9d0eab20 +Author: Marian Balakowicz +Date: Tue Jan 8 18:17:10 2008 +0100 + + [new uImage] Cleanup cmd_bootm.c + + - sort and cleanup headers, declarations, etc. + - group related routines + - cleanup indentation, white spaces + + Signed-off-by: Marian Balakowicz + +commit af13cdbc01eaf88880978bfb4f603e012818ba24 +Author: Marian Balakowicz +Date: Tue Jan 8 18:11:45 2008 +0100 + + [new uImage] Add memmove_wd() common routine + + Move common, watchdog sensible memmove code to a helper memmmove_wd() routine. + + Signed-off-by: Marian Balakowicz + +commit 958fc48abddeab513ea4847e34f22a2e9fe67fe1 +Author: Marian Balakowicz +Date: Tue Jan 8 18:11:44 2008 +0100 + + [new uImage] Fix FDT header verification in PPC do_boot_linux() routine + + Signed-off-by: Marian Balakowicz + +commit 15158971f49255ccef54f0979a942cfd3de2ae52 +Author: Marian Balakowicz +Date: Tue Jan 8 18:11:44 2008 +0100 + + [new uImage] Fix uImage header pointer use in i386 do_bootm_linux() + + Use image header copy instead of a (possibly corrupted) pointer to + a initial image location. + + Signed-off-by: Marian Balakowicz + +commit 261dcf4624b25f3c551efcf8634e9194fabba9c3 +Author: Marian Balakowicz +Date: Tue Jan 8 18:11:44 2008 +0100 + + [new uImage] Remove I386 uImage fake_header() routine + + I386 targets are not using a uImage format, instead fake header + is added to ram image before it is further processed by bootm. + + Remove this fixup and force proper uImage use for I386. + + Signed-off-by: Marian Balakowicz + +commit 559316faf7eae0614c91d77f509b57d6c4c091ba +Author: Marian Balakowicz +Date: Tue Jan 8 18:11:44 2008 +0100 + + [new uImage] Move CHUNKSZ definition to image.h + + CHUNKSZ defined for PPC and M68K is set to the same value of 64K, + move this definition to a common header. + + Signed-off-by: Marian Balakowicz + +commit 321359f20823e0b8c5ad38b64d007a6c48cda16e +Author: Marian Balakowicz +Date: Tue Jan 8 18:11:43 2008 +0100 + + [new uImage] Move gunzip() common code to common/gunzip.c + + Move gunzip(), zalloc() and zfree() to a separate file. + Share zalloc() and zfree() with cramfs uncompress routine. + + Signed-off-by: Marian Balakowicz + +commit d45d5a18b6b36688f2365623f9d550566c664b5b +Author: Marian Balakowicz +Date: Tue Jan 8 18:11:43 2008 +0100 + + [new uImage] Cleanup OF/FDT #if/#elif/#endif use in do_bootm_linux() + + Make CONFIG_OF_LIBFDT and CONFIG_OF_FLAT_TREE use more + readable in PPC variant of do_bootm_linux() routine. + + Signed-off-by: Marian Balakowicz + +commit 5d3cc55ecbae277e08f5ff771da20b1d6a36ec36 +Author: Marian Balakowicz +Date: Tue Jan 8 18:11:43 2008 +0100 + + [new uImage] Move PPC do_bootm_linux() to lib_ppc/ppc_linux.c + + PPC implementation of do_bootm_linux() routine is moved to + a dedicated file lib_ppc/ppc_linux.c + + Signed-off-by: Marian Balakowicz + +commit b97a2a0a21f279d66de8a9bdbfe21920968bcb1c +Author: Marian Balakowicz +Date: Tue Jan 8 18:14:09 2008 +0100 + + [new uImage] Define a API for image handling operations + + - Add inline helper macros for basic header processing + - Move common non inline code common/image.c + - Replace direct header access with the API routines + - Rename IH_CPU_* to IH_ARCH_* + + Signed-off-by: Marian Balakowicz + +commit ed29bc4e8142b46b626f67524207b36e43d9aad6 +Author: Marian Balakowicz +Date: Thu Jan 31 13:19:58 2008 +0100 + + Add missing cmd_ximg.o to common/Makefile + + Signed-off-by: Marian Balakowicz + commit 37e3c62fa07a823e7569c872e3a9395d227ed8e3 Author: Grzegorz Bernacki Date: Mon Jan 28 10:15:02 2008 +0100 diff --git a/Makefile b/Makefile index 4fde69967..4255cf5a0 100644 --- a/Makefile +++ b/Makefile @@ -339,10 +339,12 @@ $(U_BOOT_NAND): $(NAND_SPL) $(obj)u-boot.bin $(obj)include/autoconf.mk cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin $(ONENAND_IPL): $(VERSION_FILE) $(obj)include/autoconf.mk - $(MAKE) -C onenand_ipl/board/$(BOARDDIR) all + $(MAKE) -C $(obj)onenand_ipl/board/$(BOARDDIR) all $(U_BOOT_ONENAND): $(ONENAND_IPL) $(obj)u-boot.bin $(obj)include/autoconf.mk + $(MAKE) -C $(obj)onenand_ipl/board/$(BOARDDIR) all cat $(obj)onenand_ipl/onenand-ipl-2k.bin $(obj)u-boot.bin > $(obj)u-boot-onenand.bin + cat $(obj)onenand_ipl/onenand-ipl-4k.bin $(obj)u-boot.bin > $(obj)u-boot-flexonenand.bin $(VERSION_FILE): @( echo -n "#define U_BOOT_VERSION \"U-Boot " ; \ @@ -1609,7 +1611,7 @@ PQ2FADS-ZU_66MHz_config \ PQ2FADS-ZU_66MHz_lowboot_config \ : unconfig @mkdir -p $(obj)include - @mkdir -p $(obj)board/mpc8260ads + @mkdir -p $(obj)board/freescale/mpc8260ads $(if $(findstring PQ2FADS,$@), \ @echo "#define CONFIG_ADSTYPE CFG_PQ2FADS" > $(obj)include/config.h, \ @echo "#define CONFIG_ADSTYPE CFG_"$(subst MPC,,$(word 1,$(subst _, ,$@))) > $(obj)include/config.h) @@ -1618,13 +1620,13 @@ PQ2FADS-ZU_66MHz_lowboot_config \ $(if $(findstring VR,$@), \ @echo "#define CONFIG_8260_CLKIN 66000000" >> $(obj)include/config.h)) @[ -z "$(findstring lowboot_,$@)" ] || \ - { echo "TEXT_BASE = 0xFF800000" >$(obj)board/mpc8260ads/config.tmp ; \ + { echo "TEXT_BASE = 0xFF800000" >$(obj)board/freescale/mpc8260ads/config.tmp ; \ $(XECHO) "... with lowboot configuration" ; \ } - @$(MKCONFIG) -a MPC8260ADS ppc mpc8260 mpc8260ads + @$(MKCONFIG) -a MPC8260ADS ppc mpc8260 mpc8260ads freescale MPC8266ADS_config: unconfig - @$(MKCONFIG) $(@:_config=) ppc mpc8260 mpc8266ads + @$(MKCONFIG) $(@:_config=) ppc mpc8260 mpc8266ads freescale # PM825/PM826 default configuration: small (= 8 MB) Flash / boot from 64-bit flash PM825_config \ @@ -2243,7 +2245,7 @@ EVB64260_750CX_config: unconfig @$(MKCONFIG) EVB64260 ppc 74xx_7xx evb64260 mpc7448hpc2_config: unconfig - @$(MKCONFIG) $(@:_config=) ppc 74xx_7xx mpc7448hpc2 + @$(MKCONFIG) $(@:_config=) ppc 74xx_7xx mpc7448hpc2 freescale P3G4_config: unconfig @$(MKCONFIG) $(@:_config=) ppc 74xx_7xx evb64260 @@ -2470,11 +2472,6 @@ cm4008_config : unconfig cm41xx_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm920t cm41xx NULL ks8695 -gth2_config : unconfig - @mkdir -p $(obj)include - @echo "#define CONFIG_GTH2 1" >$(obj)include/config.h - @$(MKCONFIG) -a gth2 mips mips gth2 - ######################################################################### ## S3C44B0 Systems ######################################################################### @@ -2677,6 +2674,11 @@ pb1000_config : unconfig @echo "#define CONFIG_PB1000 1" >$(obj)include/config.h @$(MKCONFIG) -a pb1x00 mips mips pb1x00 +gth2_config: unconfig + @mkdir -p $(obj)include + @echo "#define CONFIG_GTH2 1" >$(obj)include/config.h + @$(MKCONFIG) -a gth2 mips mips gth2 + qemu_mips_config: unconfig @mkdir -p $(obj)include @echo "#define CONFIG_QEMU_MIPS 1" >$(obj)include/config.h @@ -2873,7 +2875,7 @@ clean: $(obj)board/{integratorap,integratorcp}/u-boot.lds \ $(obj)board/{bf533-ezkit,bf533-stamp,bf537-stamp,bf561-ezkit}/u-boot.lds @rm -f $(obj)include/bmp_logo.h $(obj)nand_spl/{u-boot-spl,u-boot-spl.map} - @rm -f $(obj)onenand_ipl/onenand-{ipl,ipl.bin,ipl-2k.bin,ipl.map} + @rm -f $(obj)onenand_ipl/onenand-{ipl,ipl.bin,ipl-2k.bin,ipl-4k.bin,ipl.map} @rm -f $(obj)api_examples/demo $(VERSION_FILE) @find $(OBJTREE) -type f \ \( -name 'core' -o -name '*.bak' -o -name '*~' \ @@ -2888,7 +2890,9 @@ clobber: clean @rm -f $(OBJS) $(obj)*.bak $(obj)ctags $(obj)etags $(obj)TAGS \ $(obj)cscope.* $(obj)*.*~ @rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL) - @rm -f $(obj)tools/{crc32.c,environment.c,env/crc32.c,sha1.c,inca-swap-bytes} + @rm -f $(obj)tools/{crc32.c,environment.c,env/crc32.c,md5.c,sha1.c,inca-swap-bytes} + @rm -f $(obj)tools/{image.c,fdt.c,fdt_ro.c,fdt_rw.c,fdt_strerror.c} + @rm -f $(obj)tools/{fdt_wip.c,libfdt_internal.h} @rm -f $(obj)cpu/mpc824x/bedbug_603e.c @rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm @[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -lname "*" -print | xargs rm -f diff --git a/README b/README index b230fde78..5cbe7c1e8 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ # -# (C) Copyright 2000 - 2005 +# (C) Copyright 2000 - 2008 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. # # See file CREDITS for list of people who contributed to this @@ -51,7 +51,8 @@ Makefile have been tested to some extent and can be considered "working". In fact, many of them are used in production systems. In case of problems see the CHANGELOG and CREDITS files to find out -who contributed the specific port. +who contributed the specific port. The MAINTAINERS file lists board +maintainers. Where to get help: @@ -65,6 +66,22 @@ before asking FAQ's. Please see http://lists.sourceforge.net/lists/listinfo/u-boot-users/ +Where to get source code: +========================= + +The U-Boot source code is maintained in the git repository at +git://www.denx.de/git/u-boot.git ; you can browse it online at +http://www.denx.de/cgi-bin/gitweb.cgi?p=u-boot.git;a=summary + +The "snapshot" links on this page allow you to download tarballs of +any version you might be interested in. Ofifcial releases are also +available for FTP download from the ftp://ftp.denx.de/pub/u-boot/ +directory. + +Pre-built (and tested) images are available from +ftp://ftp.denx.de/pub/u-boot/images/ + + Where we come from: =================== @@ -81,6 +98,7 @@ Where we come from: - create ARMBoot project (http://sourceforge.net/projects/armboot) - add other CPU families (starting with ARM) - create U-Boot project (http://sourceforge.net/projects/u-boot) +- current project page: see http://www.denx.de/wiki/UBoot Names and Spelling: @@ -168,7 +186,7 @@ Directory Hierarchy: - lib_mips Files generic to MIPS architecture - lib_nios Files generic to NIOS architecture - lib_ppc Files generic to PowerPC architecture -- libfdt Library files to support flattened device trees +- libfdt Library files to support flattened device trees - net Networking code - post Power On Self Test - rtc Real Time Clock drivers @@ -320,7 +338,7 @@ The following options need to be configured: converts clock data to MHZ before passing it to the Linux kernel. When CONFIG_CLOCKS_IN_MHZ is defined, a definition of - "clocks_in_mhz=1" is automatically included in the + "clocks_in_mhz=1" is automatically included in the default environment. CONFIG_MEMSIZE_IN_BYTES [relevant for MIPS only] @@ -671,6 +689,7 @@ The following options need to be configured: CONFIG_RTC_DS164x - use Dallas DS164x RTC CONFIG_RTC_ISL1208 - use Intersil ISL1208 RTC CONFIG_RTC_MAX6900 - use Maxim, Inc. MAX6900 RTC + CFG_RTC_DS1337_NOOSC - Turn off the OSC output for DS1337 Note that if the RTC uses I2C, then the I2C interface must also be configured. See I2C Support, below. @@ -686,9 +705,9 @@ The following options need to be configured: CONFIG_MAC_PARTITION and/or CONFIG_DOS_PARTITION and/or CONFIG_ISO_PARTITION - If IDE or SCSI support is enabled (CONFIG_CMD_IDE or - CONFIG_CMD_SCSI) you must configure support for at least - one partition type as well. + If IDE or SCSI support is enabled (CONFIG_CMD_IDE or + CONFIG_CMD_SCSI) you must configure support for at + least one partition type as well. - IDE Reset method: CONFIG_IDE_RESET_ROUTINE - this is defined in several @@ -1325,7 +1344,7 @@ The following options need to be configured: This option specifies a list of I2C devices that will be skipped when the 'i2c probe' command is issued (or 'iprobe' using the legacy command). If CONFIG_I2C_MULTI_BUS is set, specify a list of bus-device - pairs. Otherwise, specify a 1D array of device addresses + pairs. Otherwise, specify a 1D array of device addresses e.g. #undef CONFIG_I2C_MULTI_BUS @@ -1660,6 +1679,8 @@ The following options need to be configured: example, some LED's) on your board. At the moment, the following checkpoints are implemented: +Legacy uImage format: + Arg Where When 1 common/cmd_bootm.c before attempting to boot an image -1 common/cmd_bootm.c Image header has bad magic number @@ -1670,25 +1691,26 @@ The following options need to be configured: 4 common/cmd_bootm.c Image data has correct checksum -4 common/cmd_bootm.c Image is for unsupported architecture 5 common/cmd_bootm.c Architecture check OK - -5 common/cmd_bootm.c Wrong Image Type (not kernel, multi, standalone) + -5 common/cmd_bootm.c Wrong Image Type (not kernel, multi) 6 common/cmd_bootm.c Image Type check OK -6 common/cmd_bootm.c gunzip uncompression error -7 common/cmd_bootm.c Unimplemented compression type 7 common/cmd_bootm.c Uncompression OK - -8 common/cmd_bootm.c Wrong Image Type (not kernel, multi, standalone) - 8 common/cmd_bootm.c Image Type check OK + 8 common/cmd_bootm.c No uncompress/copy overwrite error -9 common/cmd_bootm.c Unsupported OS (not Linux, BSD, VxWorks, QNX) - 9 common/cmd_bootm.c Start initial ramdisk verification - -10 common/cmd_bootm.c Ramdisk header has bad magic number - -11 common/cmd_bootm.c Ramdisk header has bad checksum - 10 common/cmd_bootm.c Ramdisk header is OK - -12 common/cmd_bootm.c Ramdisk data has bad checksum - 11 common/cmd_bootm.c Ramdisk data has correct checksum - 12 common/cmd_bootm.c Ramdisk verification complete, start loading - -13 common/cmd_bootm.c Wrong Image Type (not PPC Linux Ramdisk) - 13 common/cmd_bootm.c Start multifile image verification - 14 common/cmd_bootm.c No initial ramdisk, no multifile, continue. - 15 common/cmd_bootm.c All preparation done, transferring control to OS + + 9 common/image.c Start initial ramdisk verification + -10 common/image.c Ramdisk header has bad magic number + -11 common/image.c Ramdisk header has bad checksum + 10 common/image.c Ramdisk header is OK + -12 common/image.c Ramdisk data has bad checksum + 11 common/image.c Ramdisk data has correct checksum + 12 common/image.c Ramdisk verification complete, start loading + -13 common/image.c Wrong Image Type (not PPC Linux Ramdisk) + 13 common/image.c Start multifile image verification + 14 common/image.c No initial ramdisk, no multifile, continue. + + 15 lib_/bootm.c All preparation done, transferring control to OS -30 lib_ppc/board.c Fatal error, hang the system -31 post/post.c POST test failed, detected by post_output_backlog() @@ -1758,6 +1780,59 @@ The following options need to be configured: -83 common/cmd_net.c some error in automatic boot or autoscript 84 common/cmd_net.c end without errors +FIT uImage format: + + Arg Where When + 100 common/cmd_bootm.c Kernel FIT Image has correct format + -100 common/cmd_bootm.c Kernel FIT Image has incorrect format + 101 common/cmd_bootm.c No Kernel subimage unit name, using configuration + -101 common/cmd_bootm.c Can't get configuration for kernel subimage + 102 common/cmd_bootm.c Kernel unit name specified + -103 common/cmd_bootm.c Can't get kernel subimage node offset + 103 common/cmd_bootm.c Found configuration node + 104 common/cmd_bootm.c Got kernel subimage node offset + -104 common/cmd_bootm.c Kernel subimage hash verification failed + 105 common/cmd_bootm.c Kernel subimage hash verification OK + -105 common/cmd_bootm.c Kernel subimage is for unsupported architecture + 106 common/cmd_bootm.c Architecture check OK + -106 common/cmd_bootm.c Kernel subimage has wrong typea + 107 common/cmd_bootm.c Kernel subimge type OK + -107 common/cmd_bootm.c Can't get kernel subimage data/size + 108 common/cmd_bootm.c Got kernel subimage data/size + -108 common/cmd_bootm.c Wrong image type (not legacy, FIT) + -109 common/cmd_bootm.c Can't get kernel subimage type + -110 common/cmd_bootm.c Can't get kernel subimage comp + -111 common/cmd_bootm.c Can't get kernel subimage os + -112 common/cmd_bootm.c Can't get kernel subimage load address + -113 common/cmd_bootm.c Image uncompress/copy overwrite error + + 120 common/image.c Start initial ramdisk verification + -120 common/image.c Ramdisk FIT image has incorrect format + 121 common/image.c Ramdisk FIT image has correct format + 122 common/image.c No Ramdisk subimage unit name, using configuration + -122 common/image.c Can't get configuration for ramdisk subimage + 123 common/image.c Ramdisk unit name specified + -124 common/image.c Can't get ramdisk subimage node offset + 125 common/image.c Got ramdisk subimage node offset + -125 common/image.c Ramdisk subimage hash verification failed + 126 common/image.c Ramdisk subimage hash verification OK + -126 common/image.c Ramdisk subimage for unsupported architecture + 127 common/image.c Architecture check OK + -127 common/image.c Can't get ramdisk subimage data/size + 128 common/image.c Got ramdisk subimage data/size + 129 common/image.c Can't get ramdisk load address + -129 common/image.c Got ramdisk load address + + -130 common/cmd_doc.c Icorrect FIT image format + 131 common/cmd_doc.c FIT image format OK + + -140 common/cmd_ide.c Icorrect FIT image format + 141 common/cmd_ide.c FIT image format OK + + -150 common/cmd_nand.c Icorrect FIT image format + 151 common/cmd_nand.c FIT image format OK + + Modem Support: -------------- @@ -1946,6 +2021,11 @@ Configuration Settings: is useful, if some of the configured banks are only optionally available. +- CONFIG_FLASH_SHOW_PROGRESS + If defined (must be an integer), print out countdown + digits and dots. Recommended value: 45 (9..1) for 80 + column displays, 15 (3..1) for 40 column displays. + - CFG_RX_ETH_BUFFER: Defines the number of ethernet receive buffers. On some ethernet controllers it is recommended to set this value @@ -2319,22 +2399,24 @@ Low Level (hardware related) configuration options: Overrides the default PCI memory map in cpu/mpc8260/pci.c if set. - CONFIG_SPD_EEPROM - Get DDR timing information from an I2C EEPROM. Common with pluggable - memory modules such as SODIMMs + Get DDR timing information from an I2C EEPROM. Common + with pluggable memory modules such as SODIMMs + SPD_EEPROM_ADDRESS I2C address of the SPD EEPROM - CFG_SPD_BUS_NUM - If SPD EEPROM is on an I2C bus other than the first one, specify here. - Note that the value must resolve to something your driver can deal with. + If SPD EEPROM is on an I2C bus other than the first + one, specify here. Note that the value must resolve + to something your driver can deal with. - CFG_83XX_DDR_USES_CS0 - Only for 83xx systems. If specified, then DDR should be configured - using CS0 and CS1 instead of CS2 and CS3. + Only for 83xx systems. If specified, then DDR should + be configured using CS0 and CS1 instead of CS2 and CS3. - CFG_83XX_DDR_USES_CS0 - Only for 83xx systems. If specified, then DDR should be configured - using CS0 and CS1 instead of CS2 and CS3. + Only for 83xx systems. If specified, then DDR should + be configured using CS0 and CS1 instead of CS2 and CS3. - CONFIG_ETHER_ON_FEC[12] Define to enable FEC[12] on a 8xx series processor. @@ -2400,29 +2482,30 @@ Low Level (hardware related) configuration options: Building the Software: ====================== -Building U-Boot has been tested in native PPC environments (on a -PowerBook G3 running LinuxPPC 2000) and in cross environments -(running RedHat 6.x and 7.x Linux on x86, Solaris 2.6 on a SPARC, and -NetBSD 1.5 on x86). +Building U-Boot has been tested in several native build environments +and in many different cross environments. Of course we cannot support +all possibly existing versions of cross development tools in all +(potentially obsolete) versions. In case of tool chain problems we +recommend to use the ELDK (see http://www.denx.de/wiki/DULG/ELDK) +which is extensively used to build and test U-Boot. -If you are not using a native PPC environment, it is assumed that you -have the GNU cross compiling tools available in your path and named -with a prefix of "powerpc-linux-". If this is not the case, (e.g. if -you are using Monta Vista's Hard Hat Linux CDK 1.2) you must change -the definition of CROSS_COMPILE in Makefile. For HHL on a 4xx CPU, -change it to: +If you are not using a native environment, it is assumed that you +have GNU cross compiling tools available in your path. In this case, +you must set the environment variable CROSS_COMPILE in your shell. +Note that no changes to the Makefile or any other source files are +necessary. For example using the ELDK on a 4xx CPU, please enter: - CROSS_COMPILE = ppc_4xx- + $ CROSS_COMPILE=ppc_4xx- + $ export CROSS_COMPILE - -U-Boot is intended to be simple to build. After installing the -sources you must configure U-Boot for one specific board type. This +U-Boot is intended to be simple to build. After installing the +sources you must configure U-Boot for one specific board type. This is done by typing: make NAME_config -where "NAME_config" is the name of one of the existing -configurations; see the main Makefile for supported names. +where "NAME_config" is the name of one of the existing configu- +rations; see the main Makefile for supported names. Note: for some board special configuration names may exist; check if additional information is available from the board vendor; for @@ -2498,20 +2581,20 @@ steps: Testing of U-Boot Modifications, Ports to New Hardware, etc.: ============================================================== -If you have modified U-Boot sources (for instance added a new board -or support for new devices, a new CPU, etc.) you are expected to +If you have modified U-Boot sources (for instance added a new board +or support for new devices, a new CPU, etc.) you are expected to provide feedback to the other developers. The feedback normally takes the form of a "patch", i. e. a context diff against a certain (latest -official or latest in CVS) version of U-Boot sources. +official or latest in the git repository) version of U-Boot sources. -But before you submit such a patch, please verify that your modifi- -cation did not break existing code. At least make sure that *ALL* of +But before you submit such a patch, please verify that your modifi- +cation did not break existing code. At least make sure that *ALL* of the supported boards compile WITHOUT ANY compiler warnings. To do so, just run the "MAKEALL" script, which will configure and build U-Boot -for ALL supported system. Be warned, this will take a while. You can -select which (cross) compiler to use by passing a `CROSS_COMPILE' -environment variable to the script, i. e. to use the cross tools from -MontaVista's Hard Hat Linux you can type +for ALL supported system. Be warned, this will take a while. You can +select which (cross) compiler to use by passing a `CROSS_COMPILE' +environment variable to the script, i. e. to use the ELDK cross tools +you can type CROSS_COMPILE=ppc_8xx- MAKEALL @@ -2519,20 +2602,21 @@ or to build on a native PowerPC system you can type CROSS_COMPILE=' ' MAKEALL -When using the MAKEALL script, the default behaviour is to build U-Boot -in the source directory. This location can be changed by setting the -BUILD_DIR environment variable. Also, for each target built, the MAKEALL -script saves two log files (.ERR and .MAKEALL) in the -/LOG directory. This default location can be changed by -setting the MAKEALL_LOGDIR environment variable. For example: +When using the MAKEALL script, the default behaviour is to build +U-Boot in the source directory. This location can be changed by +setting the BUILD_DIR environment variable. Also, for each target +built, the MAKEALL script saves two log files (.ERR and +.MAKEALL) in the /LOG directory. This default +location can be changed by setting the MAKEALL_LOGDIR environment +variable. For example: export BUILD_DIR=/tmp/build export MAKEALL_LOGDIR=/tmp/log CROSS_COMPILE=ppc_8xx- MAKEALL -With the above settings build objects are saved in the /tmp/build, log -files are saved in the /tmp/log and the source tree remains clean during -the whole build process. +With the above settings build objects are saved in the /tmp/build, +log files are saved in the /tmp/log and the source tree remains clean +during the whole build process. See also "U-Boot Porting Guide" below. @@ -2629,6 +2713,14 @@ Some configuration options can be set using Environment Variables: configuration from the BOOTP server, but not try to load any image using TFTP + autoscript - if set to "yes" commands like "loadb", "loady", + "bootp", "tftpb", "rarpboot" and "nfs" will attempt + to automatically run script images (by internally + calling "autoscript"). + + autoscript_uname - if script image is in a format (FIT) this + variable is used to get script subimage unit name. + autostart - if set to "yes", an image loaded using the "bootp", "rarpboot", "tftpboot" or "diskboot" commands will be automatically started (by internally calling @@ -2843,10 +2935,24 @@ o If neither SROM nor the environment contain a MAC address, an error Image Formats: ============== -The "boot" commands of this monitor operate on "image" files which -can be basicly anything, preceeded by a special header; see the -definitions in include/image.h for details; basicly, the header -defines the following image properties: +U-Boot is capable of booting (and performing other auxiliary operations on) +images in two formats: + +New uImage format (FIT) +----------------------- + +Flexible and powerful format based on Flattened Image Tree -- FIT (similar +to Flattened Device Tree). It allows the use of images with multiple +components (several kernels, ramdisks, etc.), with contents protected by +SHA1, MD5 or CRC32. More details are found in the doc/uImage.FIT directory. + + +Old uImage format +----------------- + +Old image format is based on binary files which can be basically anything, +preceded by a special header; see the definitions in include/image.h for +details; basically, the header defines the following image properties: * Target Operating System (Provisions for OpenBSD, NetBSD, FreeBSD, 4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, @@ -3088,7 +3194,7 @@ TQM8xxL is in the first Flash bank): You can check the success of the download using the 'iminfo' command; -this includes a checksum verification so you can be sure no data +this includes a checksum verification so you can be sure no data corruption happened: => imi 40100000 @@ -3433,7 +3539,7 @@ models provide on-chip memory (like the IMMR area on MPC8xx and MPC826x processors), on others (parts of) the data cache can be locked as (mis-) used as memory, etc. - Chris Hallinan posted a good summary of these issues to the + Chris Hallinan posted a good summary of these issues to the u-boot-users mailing list: Subject: RE: [U-Boot-Users] RE: More On Memory Bank x (nothingness)? @@ -3723,6 +3829,8 @@ may be rejected, even when they contain important and valuable stuff. Patches shall be sent to the u-boot-users mailing list. +Please see http://www.denx.de/wiki/UBoot/Patches for details. + When you send a patch, please include the following information with it: @@ -3743,18 +3851,23 @@ it: * If your patch adds new configuration options, don't forget to document these in the README file. -* The patch itself. If you are accessing the CVS repository use "cvs - update; cvs diff -puRN"; else, use "diff -purN OLD NEW". If your - version of diff does not support these options, then get the latest - version of GNU diff. +* The patch itself. If you are using git (which is *strongly* + recommended) you can easily generate the patch using the + "git-format-patch". If you then use "git-send-email" to send it to + the U-Boot mailing list, you will avoid most of the common problems + with some other mail clients. - The current directory when running this command shall be the top - level directory of the U-Boot source tree, or it's parent directory - (i. e. please make sure that your patch includes sufficient - directory information for the affected files). + If you cannot use git, use "diff -purN OLD NEW". If your version of + diff does not support these options, then get the latest version of + GNU diff. - We accept patches as plain text, MIME attachments or as uuencoded - gzipped text. + The current directory when running this command shall be the parent + directory of the U-Boot source tree (i. e. please make sure that + your patch includes sufficient directory information for the + affected files). + + We prefer patches as plain text. MIME attachments are discouraged, + and compressed attachments must not be used. * If one logical set of modifications affects or creates several files, all these changes shall be submitted in a SINGLE patch file. @@ -3781,4 +3894,6 @@ Notes: modification. * Remember that there is a size limit of 40 kB per message on the - u-boot-users mailing list. Compression may help. + u-boot-users mailing list. Bigger patches will be moderated. If + they are reasonable and not bigger than 100 kB, they will be + acknowledged. Even bigger patches should be avoided. diff --git a/board/adder/adder.c b/board/adder/adder.c index aa7815848..817c8649a 100644 --- a/board/adder/adder.c +++ b/board/adder/adder.c @@ -26,6 +26,9 @@ #include #include +#if defined(CONFIG_OF_LIBFDT) + #include +#endif /* * SDRAM is single Samsung K4S643232F-T70 chip (8MB) @@ -111,3 +114,11 @@ int checkboard( void ) return 0; } + +#if defined(CONFIG_OF_BOARD_SETUP) +void ft_board_setup(void *blob, bd_t *bd) +{ + ft_cpu_setup(blob, bd); + +} +#endif diff --git a/board/atum8548/tlb.c b/board/atum8548/tlb.c index bb6ce761a..1ef4de41e 100644 --- a/board/atum8548/tlb.c +++ b/board/atum8548/tlb.c @@ -82,7 +82,7 @@ struct fsl_e_tlb_entry tlb_table[] = { * 0xe210_0000 1M PCI2 IO * 0xe300_0000 1M PCIe IO */ - SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR, + SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 5, BOOKE_PAGESZ_64M, 1), }; diff --git a/board/bf537-stamp/Makefile b/board/bf537-stamp/Makefile index cdffc333e..5d2239337 100644 --- a/board/bf537-stamp/Makefile +++ b/board/bf537-stamp/Makefile @@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS := $(BOARD).o ether_bf537.o post-memory.o stm_m25p64.o cmd_bf537led.o nand.o +COBJS := $(BOARD).o post-memory.o stm_m25p64.o cmd_bf537led.o nand.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/cray/L1/L1.c b/board/cray/L1/L1.c index 5264bafd4..a72ba4620 100644 --- a/board/cray/L1/L1.c +++ b/board/cray/L1/L1.c @@ -139,8 +139,15 @@ int misc_init_r (void) struct rtc_time tm; char bootcmd[32]; - hdr = (image_header_t *) (CFG_MONITOR_BASE - sizeof (image_header_t)); - timestamp = (time_t) hdr->ih_time; + hdr = (image_header_t *) (CFG_MONITOR_BASE - image_get_header_size ()); +#if defined(CONFIG_FIT) + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + + timestamp = (time_t)image_get_time (hdr); to_tm (timestamp, &tm); printf ("Welcome to U-Boot on Cray L1. Compiled %4d-%02d-%02d %2d:%02d:%02d (UTC)\n", tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); diff --git a/board/esd/common/auto_update.c b/board/esd/common/auto_update.c index a76b00fe4..1bf81c699 100644 --- a/board/esd/common/auto_update.c +++ b/board/esd/common/auto_update.c @@ -89,24 +89,28 @@ extern block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE]; int au_check_cksum_valid(int i, long nbytes) { image_header_t *hdr; - unsigned long checksum; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif - if ((au_image[i].type == AU_FIRMWARE) && (au_image[i].size != ntohl(hdr->ih_size))) { + if ((au_image[i].type == AU_FIRMWARE) && + (au_image[i].size != image_get_data_size (hdr))) { printf ("Image %s has wrong size\n", au_image[i].name); return -1; } - if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size))) { + if (nbytes != (image_get_image_size (hdr))) { printf ("Image %s bad total SIZE\n", au_image[i].name); return -1; } - /* check the data CRC */ - checksum = ntohl(hdr->ih_dcrc); - if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size)) - != checksum) { + /* check the data CRC */ + if (!image_check_dcrc (hdr)) { printf ("Image %s bad data checksum\n", au_image[i].name); return -1; } @@ -120,51 +124,53 @@ int au_check_header_valid(int i, long nbytes) unsigned long checksum; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + /* check the easy ones first */ #undef CHECK_VALID_DEBUG #ifdef CHECK_VALID_DEBUG - printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC); - printf("arch %#x %#x ", hdr->ih_arch, IH_CPU_PPC); - printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes); - printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL); + printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC); + printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_PPC); + printf("size %#x %#lx ", image_get_data_size (hdr), nbytes); + printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL); #endif - if (nbytes < sizeof(*hdr)) + if (nbytes < image_get_header_size ()) { printf ("Image %s bad header SIZE\n", au_image[i].name); return -1; } - if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_PPC) + if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_PPC)) { printf ("Image %s bad MAGIC or ARCH\n", au_image[i].name); return -1; } - /* check the hdr CRC */ - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) { + if (!image_check_hcrc (hdr)) { printf ("Image %s bad header checksum\n", au_image[i].name); return -1; } - hdr->ih_hcrc = htonl(checksum); /* check the type - could do this all in one gigantic if() */ - if ((au_image[i].type == AU_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) { + if ((au_image[i].type == AU_FIRMWARE) && !image_check_type (hdr, IH_TYPE_FIRMWARE)) { printf ("Image %s wrong type\n", au_image[i].name); return -1; } - if ((au_image[i].type == AU_SCRIPT) && (hdr->ih_type != IH_TYPE_SCRIPT)) { + if ((au_image[i].type == AU_SCRIPT) && !image_check_type (hdr, IH_TYPE_SCRIPT)) { printf ("Image %s wrong type\n", au_image[i].name); return -1; } /* recycle checksum */ - checksum = ntohl(hdr->ih_size); + checksum = image_get_data_size (hdr); #if 0 /* test-only */ /* for kernel and app the image header must also fit into flash */ if (idx != IDX_DISK) - checksum += sizeof(*hdr); + checksum += image_get_header_size (); /* check the size does not exceed space in flash. HUSH scripts */ /* all have ausize[] set to 0 */ if ((ausize[idx] != 0) && (ausize[idx] < checksum)) { @@ -190,17 +196,23 @@ int au_do_update(int i, long sz) #endif hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif switch (au_image[i].type) { case AU_SCRIPT: printf("Executing script %s\n", au_image[i].name); /* execute a script */ - if (hdr->ih_type == IH_TYPE_SCRIPT) { - addr = (char *)((char *)hdr + sizeof(*hdr)); + if (image_check_type (hdr, IH_TYPE_SCRIPT)) { + addr = (char *)((char *)hdr + image_get_header_size ()); /* stick a NULL at the end of the script, otherwise */ /* parse_string_outer() runs off the end. */ - addr[ntohl(hdr->ih_size)] = 0; + addr[image_get_data_size (hdr)] = 0; addr += 8; /* @@ -231,8 +243,8 @@ int au_do_update(int i, long sz) */ if (au_image[i].type == AU_FIRMWARE) { char *orig = (char*)start; - char *new = (char *)((char *)hdr + sizeof(*hdr)); - nbytes = ntohl(hdr->ih_size); + char *new = (char *)((char *)hdr + image_get_header_size ()); + nbytes = image_get_data_size (hdr); while(--nbytes) { if (*orig++ != *new++) { @@ -272,12 +284,12 @@ int au_do_update(int i, long sz) /* strip the header - except for the kernel and ramdisk */ if (au_image[i].type != AU_FIRMWARE) { addr = (char *)hdr; - off = sizeof(*hdr); - nbytes = sizeof(*hdr) + ntohl(hdr->ih_size); + off = image_get_header_size (); + nbytes = image_get_image_size (hdr); } else { - addr = (char *)((char *)hdr + sizeof(*hdr)); + addr = (char *)((char *)hdr + image_get_header_size ()); off = 0; - nbytes = ntohl(hdr->ih_size); + nbytes = image_get_data_size (hdr); } /* @@ -305,15 +317,15 @@ int au_do_update(int i, long sz) * check the dcrc of the copy */ if (au_image[i].type != AU_NAND) { - rc = crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)); + rc = crc32 (0, (uchar *)(start + off), image_get_data_size (hdr)); } else { #if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY) rc = nand_legacy_rw(nand_dev_desc, NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP, start, nbytes, (size_t *)&total, (uchar *)addr); - rc = crc32 (0, (uchar *)(addr + off), ntohl(hdr->ih_size)); + rc = crc32 (0, (uchar *)(addr + off), image_get_data_size (hdr)); #endif } - if (rc != ntohl(hdr->ih_dcrc)) { + if (rc != image_get_dcrc (hdr)) { printf ("Image %s Bad Data Checksum After COPY\n", au_image[i].name); return -1; } @@ -497,10 +509,10 @@ int do_auto_update(void) printf("Reading %s ...", au_image[i].name); /* just read the header */ - sz = do_fat_read(au_image[i].name, LOAD_ADDR, sizeof(image_header_t), LS_NO); + sz = do_fat_read(au_image[i].name, LOAD_ADDR, image_get_header_size (), LS_NO); debug ("read %s sz %ld hdr %d\n", - au_image[i].name, sz, sizeof(image_header_t)); - if (sz <= 0 || sz < sizeof(image_header_t)) { + au_image[i].name, sz, image_get_header_size ()); + if (sz <= 0 || sz < image_get_header_size ()) { puts(" not found\n"); continue; } @@ -510,8 +522,8 @@ int do_auto_update(void) } sz = do_fat_read(au_image[i].name, LOAD_ADDR, MAX_LOADSZ, LS_NO); debug ("read %s sz %ld hdr %d\n", - au_image[i].name, sz, sizeof(image_header_t)); - if (sz <= 0 || sz <= sizeof(image_header_t)) { + au_image[i].name, sz, image_get_header_size ()); + if (sz <= 0 || sz <= image_get_header_size ()) { puts(" not found\n"); continue; } diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index 6665e7f7c..6340b418e 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -29,10 +29,18 @@ endif LIB = $(obj)lib$(VENDOR).a -COBJS-${CONFIG_PQ_MDS_PIB} += pq-mds-pib.o -COBJS-${CONFIG_ID_EEPROM} += sys_eeprom.o +COBJS-${CONFIG_FSL_CADMUS} += cadmus.o +COBJS-${CONFIG_FSL_CDS_EEPROM} += cds_eeprom.o +COBJS-${CONFIG_FSL_VIA} += cds_via.o COBJS-${CONFIG_FSL_DIU_FB} += fsl_diu_fb.o fsl_logo_bmp.o COBJS-${CONFIG_FSL_PIXIS} += pixis.o +COBJS-${CONFIG_PQ_MDS_PIB} += pq-mds-pib.o +COBJS-${CONFIG_ID_EEPROM} += sys_eeprom.o + +COBJS-${CONFIG_MPC8541CDS} += cds_pci_ft.o +COBJS-${CONFIG_MPC8548CDS} += cds_pci_ft.o +COBJS-${CONFIG_MPC8555CDS} += cds_pci_ft.o + SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(COBJS-y)) diff --git a/board/freescale/common/eeprom.c b/board/freescale/common/cds_eeprom.c similarity index 100% rename from board/freescale/common/eeprom.c rename to board/freescale/common/cds_eeprom.c diff --git a/board/freescale/common/ft_board.c b/board/freescale/common/cds_pci_ft.c similarity index 100% rename from board/freescale/common/ft_board.c rename to board/freescale/common/cds_pci_ft.c diff --git a/board/freescale/common/via.c b/board/freescale/common/cds_via.c similarity index 100% rename from board/freescale/common/via.c rename to board/freescale/common/cds_via.c diff --git a/board/mpc7448hpc2/Makefile b/board/freescale/mpc7448hpc2/Makefile similarity index 100% rename from board/mpc7448hpc2/Makefile rename to board/freescale/mpc7448hpc2/Makefile diff --git a/board/mpc7448hpc2/asm_init.S b/board/freescale/mpc7448hpc2/asm_init.S similarity index 100% rename from board/mpc7448hpc2/asm_init.S rename to board/freescale/mpc7448hpc2/asm_init.S diff --git a/board/mpc7448hpc2/config.mk b/board/freescale/mpc7448hpc2/config.mk similarity index 100% rename from board/mpc7448hpc2/config.mk rename to board/freescale/mpc7448hpc2/config.mk diff --git a/board/mpc7448hpc2/mpc7448hpc2.c b/board/freescale/mpc7448hpc2/mpc7448hpc2.c similarity index 100% rename from board/mpc7448hpc2/mpc7448hpc2.c rename to board/freescale/mpc7448hpc2/mpc7448hpc2.c diff --git a/board/mpc7448hpc2/tsi108_init.c b/board/freescale/mpc7448hpc2/tsi108_init.c similarity index 100% rename from board/mpc7448hpc2/tsi108_init.c rename to board/freescale/mpc7448hpc2/tsi108_init.c diff --git a/board/mpc7448hpc2/u-boot.lds b/board/freescale/mpc7448hpc2/u-boot.lds similarity index 100% rename from board/mpc7448hpc2/u-boot.lds rename to board/freescale/mpc7448hpc2/u-boot.lds diff --git a/board/mpc8260ads/Makefile b/board/freescale/mpc8260ads/Makefile similarity index 100% rename from board/mpc8260ads/Makefile rename to board/freescale/mpc8260ads/Makefile diff --git a/board/mpc8260ads/config.mk b/board/freescale/mpc8260ads/config.mk similarity index 100% rename from board/mpc8260ads/config.mk rename to board/freescale/mpc8260ads/config.mk diff --git a/board/mpc8260ads/flash.c b/board/freescale/mpc8260ads/flash.c similarity index 100% rename from board/mpc8260ads/flash.c rename to board/freescale/mpc8260ads/flash.c diff --git a/board/mpc8260ads/mpc8260ads.c b/board/freescale/mpc8260ads/mpc8260ads.c similarity index 100% rename from board/mpc8260ads/mpc8260ads.c rename to board/freescale/mpc8260ads/mpc8260ads.c diff --git a/board/mpc8266ads/Makefile b/board/freescale/mpc8266ads/Makefile similarity index 100% rename from board/mpc8266ads/Makefile rename to board/freescale/mpc8266ads/Makefile diff --git a/board/mpc8266ads/config.mk b/board/freescale/mpc8266ads/config.mk similarity index 100% rename from board/mpc8266ads/config.mk rename to board/freescale/mpc8266ads/config.mk diff --git a/board/mpc8266ads/flash.c b/board/freescale/mpc8266ads/flash.c similarity index 100% rename from board/mpc8266ads/flash.c rename to board/freescale/mpc8266ads/flash.c diff --git a/board/mpc8266ads/mpc8266ads.c b/board/freescale/mpc8266ads/mpc8266ads.c similarity index 100% rename from board/mpc8266ads/mpc8266ads.c rename to board/freescale/mpc8266ads/mpc8266ads.c diff --git a/board/freescale/mpc8313erdb/mpc8313erdb.c b/board/freescale/mpc8313erdb/mpc8313erdb.c index 42019fb80..7cbdb7bf3 100644 --- a/board/freescale/mpc8313erdb/mpc8313erdb.c +++ b/board/freescale/mpc8313erdb/mpc8313erdb.c @@ -28,6 +28,7 @@ #endif #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -98,6 +99,26 @@ void pci_init_board(void) mpc83xx_pci_init(1, reg, warmboot); } +/* + * Miscellaneous late-boot configurations + * + * If a VSC7385 microcode image is present, then upload it. +*/ +int misc_init_r(void) +{ + int rc = 0; + +#ifdef CONFIG_VSC7385_IMAGE + if (vsc7385_upload_firmware((void *) CONFIG_VSC7385_IMAGE, + CONFIG_VSC7385_IMAGE_SIZE)) { + puts("Failure uploading VSC7385 microcode.\n"); + rc = 1; + } +#endif + + return rc; +} + #if defined(CONFIG_OF_BOARD_SETUP) void ft_board_setup(void *blob, bd_t *bd) { diff --git a/board/freescale/mpc8349itx/mpc8349itx.c b/board/freescale/mpc8349itx/mpc8349itx.c index 972361fd6..704f9636b 100644 --- a/board/freescale/mpc8349itx/mpc8349itx.c +++ b/board/freescale/mpc8349itx/mpc8349itx.c @@ -25,6 +25,7 @@ #include #include #include +#include #ifdef CONFIG_PCI #include #include @@ -177,7 +178,7 @@ int checkboard(void) */ int misc_init_f(void) { -#ifdef CONFIG_VSC7385 +#ifdef CONFIG_VSC7385_ENET volatile u32 *vsc7385_cpuctrl; /* 0x1c0c0 is the VSC7385 CPU Control (CPUCTRL) Register. The power up @@ -239,6 +240,8 @@ int misc_init_f(void) } /* + * Miscellaneous late-boot configurations + * * Make sure the EEPROM has the HRCW correctly programmed. * Make sure the RTC is correctly programmed. * @@ -250,6 +253,8 @@ int misc_init_f(void) * * This function makes sure that the I2C EEPROM is programmed * correctly. + * + * If a VSC7385 microcode image is present, then upload it. */ int misc_init_r(void) { @@ -375,6 +380,14 @@ int misc_init_r(void) i2c_set_bus_num(orig_bus); #endif +#ifdef CONFIG_VSC7385_IMAGE + if (vsc7385_upload_firmware((void *) CONFIG_VSC7385_IMAGE, + CONFIG_VSC7385_IMAGE_SIZE)) { + puts("Failure uploading VSC7385 microcode.\n"); + rc = 1; + } +#endif + return rc; } diff --git a/board/freescale/mpc8360erdk/Makefile b/board/freescale/mpc8360erdk/Makefile index acc954488..53e0c4827 100644 --- a/board/freescale/mpc8360erdk/Makefile +++ b/board/freescale/mpc8360erdk/Makefile @@ -25,8 +25,10 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS := $(BOARD).o +COBJS-y += $(BOARD).o +COBJS-$(CONFIG_CMD_NAND) += nand.o +COBJS := $(COBJS-y) SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) SOBJS := $(addprefix $(obj),$(SOBJS)) diff --git a/board/freescale/mpc8360erdk/mpc8360erdk.c b/board/freescale/mpc8360erdk/mpc8360erdk.c index 8005a5053..3bcdda733 100644 --- a/board/freescale/mpc8360erdk/mpc8360erdk.c +++ b/board/freescale/mpc8360erdk/mpc8360erdk.c @@ -186,6 +186,23 @@ const qe_iop_conf_t qe_iop_conf_tab[] = { {1, 7, 1, 0, 0}, /* LVDS_BKLT_CTR */ {2, 16, 1, 0, 0}, /* LVDS_BKLT_EN */ + /* AD7843 ADC/Touchscreen controller */ + {4, 14, 1, 0, 0}, /* SPI_nCS0 */ + {4, 28, 3, 0, 3}, /* SPI_MOSI */ + {4, 29, 3, 0, 3}, /* SPI_MISO */ + {4, 30, 3, 0, 3}, /* SPI_CLK */ + + /* Freescale QUICC Engine USB Host Controller (FHCI) */ + {1, 2, 1, 0, 3}, /* USBOE */ + {1, 3, 1, 0, 3}, /* USBTP */ + {1, 8, 1, 0, 1}, /* USBTN */ + {1, 9, 2, 1, 3}, /* USBRP */ + {1, 10, 2, 0, 3}, /* USBRXD */ + {1, 11, 2, 1, 3}, /* USBRN */ + {2, 20, 2, 0, 1}, /* CLK21 */ + {4, 20, 1, 0, 0}, /* SPEED */ + {4, 21, 1, 0, 0}, /* SUSPND */ + /* END of table */ {0, 0, 0, 0, QE_IOP_TAB_END}, }; diff --git a/board/freescale/mpc8360erdk/nand.c b/board/freescale/mpc8360erdk/nand.c new file mode 100644 index 000000000..e1e790b34 --- /dev/null +++ b/board/freescale/mpc8360erdk/nand.c @@ -0,0 +1,72 @@ +/* + * MPC8360E-RDK support for the NAND on FSL UPM + * + * Copyright (C) 2007 MontaVista Software, Inc. + * Anton Vorontsov + * + * 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 +#include +#include +#include +#include +#include +#include + +static struct immap *im = (struct immap *)CFG_IMMR; + +static const u32 upm_array[] = { + 0x0ff03c30, 0x0ff03c30, 0x0ff03c34, 0x0ff33c30, /* Words 0 to 3 */ + 0xfff33c31, 0xfffffc30, 0xfffffc30, 0xfffffc30, /* Words 4 to 7 */ + 0x0faf3c30, 0x0faf3c30, 0x0faf3c30, 0x0fff3c34, /* Words 8 to 11 */ + 0xffff3c31, 0xfffffc30, 0xfffffc30, 0xfffffc30, /* Words 12 to 15 */ + 0x0fa3fc30, 0x0fa3fc30, 0x0fa3fc30, 0x0ff3fc34, /* Words 16 to 19 */ + 0xfff3fc31, 0xfffffc30, 0xfffffc30, 0xfffffc30, /* Words 20 to 23 */ + 0x0ff33c30, 0x0fa33c30, 0x0fa33c34, 0x0ff33c30, /* Words 24 to 27 */ + 0xfff33c31, 0xfff0fc30, 0xfff0fc30, 0xfff0fc30, /* Words 28 to 31 */ + 0xfff3fc30, 0xfff3fc30, 0xfff6fc30, 0xfffcfc30, /* Words 32 to 35 */ + 0xfffcfc30, 0xfffcfc30, 0xfffcfc30, 0xfffcfc30, /* Words 36 to 39 */ + 0xfffcfc30, 0xfffcfc30, 0xfffcfc30, 0xfffcfc30, /* Words 40 to 43 */ + 0xfffdfc30, 0xfffffc30, 0xfffffc30, 0xfffffc31, /* Words 44 to 47 */ + 0xfffffc30, 0xfffffc00, 0xfffffc00, 0xfffffc00, /* Words 48 to 51 */ + 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, /* Words 52 to 55 */ + 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, /* Words 56 to 59 */ + 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, /* Words 60 to 63 */ +}; + +static int dev_ready(void) +{ + if (in_be32(&im->qepio.ioport[4].pdat) & 0x00002000) { + debug("nand ready\n"); + return 1; + } + + debug("nand busy\n"); + return 0; +} + +static struct fsl_upm_nand fun = { + .upm = { + .array = upm_array, + .io_addr = (void *)CFG_NAND_BASE, + }, + .width = 1, + .upm_cmd_offset = 8, + .upm_addr_offset = 16, + .dev_ready = dev_ready, + .wait_pattern = 1, + .chip_delay = 50, +}; + +int board_nand_init(struct nand_chip *nand) +{ + fun.upm.mxmr = &im->lbus.mamr; + fun.upm.mdr = &im->lbus.mdr; + fun.upm.mar = &im->lbus.mar; + return fsl_upm_nand_init(nand, &fun); +} diff --git a/board/freescale/mpc837xerdb/mpc837xerdb.c b/board/freescale/mpc837xerdb/mpc837xerdb.c index bed0fc37e..83fb60da0 100644 --- a/board/freescale/mpc837xerdb/mpc837xerdb.c +++ b/board/freescale/mpc837xerdb/mpc837xerdb.c @@ -15,7 +15,10 @@ #include #include #include +#include #include +#include + #if defined(CFG_DRAM_TEST) int @@ -56,11 +59,6 @@ testdram(void) } #endif -int board_early_init_f(void) -{ - return 0; -} - #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC) void ddr_enable_ecc(unsigned int dram_size); #endif @@ -135,6 +133,62 @@ int checkboard(void) return 0; } +int board_early_init_f(void) +{ +#ifdef CONFIG_FSL_SERDES + immap_t *immr = (immap_t *)CFG_IMMR; + u32 spridr = in_be32(&immr->sysconf.spridr); + + /* we check only part num, and don't look for CPU revisions */ + switch (spridr >> 16) { + case SPR_8379E_REV10 >> 16: + case SPR_8379_REV10 >> 16: + fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SATA, + FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); + fsl_setup_serdes(CONFIG_FSL_SERDES2, FSL_SERDES_PROTO_SATA, + FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); + break; + case SPR_8378E_REV10 >> 16: + case SPR_8378_REV10 >> 16: + fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_PEX, + FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); + break; + case SPR_8377E_REV10 >> 16: + case SPR_8377_REV10 >> 16: + fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SATA, + FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); + fsl_setup_serdes(CONFIG_FSL_SERDES2, FSL_SERDES_PROTO_PEX, + FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V); + break; + default: + printf("serdes not configured: unknown CPU part number: " + "%04x\n", spridr >> 16); + break; + } +#endif /* CONFIG_FSL_SERDES */ + return 0; +} + +/* + * Miscellaneous late-boot configurations + * + * If a VSC7385 microcode image is present, then upload it. +*/ +int misc_init_r(void) +{ + int rc = 0; + +#ifdef CONFIG_VSC7385_IMAGE + if (vsc7385_upload_firmware((void *) CONFIG_VSC7385_IMAGE, + CONFIG_VSC7385_IMAGE_SIZE)) { + puts("Failure uploading VSC7385 microcode.\n"); + rc = 1; + } +#endif + + return rc; +} + #if defined(CONFIG_OF_BOARD_SETUP) void ft_board_setup(void *blob, bd_t *bd) @@ -143,5 +197,6 @@ void ft_board_setup(void *blob, bd_t *bd) ft_pci_setup(blob, bd); #endif ft_cpu_setup(blob, bd); + fdt_fixup_dr_usb(blob, bd); } #endif /* CONFIG_OF_BOARD_SETUP */ diff --git a/board/freescale/mpc8540ads/tlb.c b/board/freescale/mpc8540ads/tlb.c index 3eaff013f..4fe2862f7 100644 --- a/board/freescale/mpc8540ads/tlb.c +++ b/board/freescale/mpc8540ads/tlb.c @@ -87,7 +87,7 @@ struct fsl_e_tlb_entry tlb_table[] = { * 0xe000_0000 1M CCSRBAR * 0xe200_0000 16M PCI1 IO */ - SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR, + SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 5, BOOKE_PAGESZ_64M, 1), diff --git a/board/freescale/mpc8541cds/Makefile b/board/freescale/mpc8541cds/Makefile index d1a585ad6..3ae2e9757 100644 --- a/board/freescale/mpc8541cds/Makefile +++ b/board/freescale/mpc8541cds/Makefile @@ -23,21 +23,16 @@ # include $(TOPDIR)/config.mk -ifneq ($(OBJTREE),$(SRCTREE)) -$(shell mkdir -p $(obj)../common) -endif LIB = $(obj)lib$(BOARD).a -COBJS := $(BOARD).o law.o tlb.o \ - ../common/cadmus.o \ - ../common/eeprom.o \ - ../common/ft_board.o \ - ../common/via.o +COBJS-y += $(BOARD).o +COBJS-y += law.o +COBJS-y += tlb.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) -SOBJS := $(addprefix $(obj),$(SOBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS-y)) $(LIB): $(obj).depend $(OBJS) $(SOBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/board/freescale/mpc8541cds/tlb.c b/board/freescale/mpc8541cds/tlb.c index 92f759b31..c5434a069 100644 --- a/board/freescale/mpc8541cds/tlb.c +++ b/board/freescale/mpc8541cds/tlb.c @@ -88,7 +88,7 @@ struct fsl_e_tlb_entry tlb_table[] = { * 0xe200_0000 16M PCI1 IO * 0xe300_0000 16M PCI2 IO */ - SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR, + SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 5, BOOKE_PAGESZ_64M, 1), diff --git a/board/freescale/mpc8544ds/tlb.c b/board/freescale/mpc8544ds/tlb.c index 34cfb38f0..61fc60986 100644 --- a/board/freescale/mpc8544ds/tlb.c +++ b/board/freescale/mpc8544ds/tlb.c @@ -75,7 +75,7 @@ struct fsl_e_tlb_entry tlb_table[] = { * 0xe000_0000 1M CCSRBAR * 0xe100_0000 255M PCI IO range */ - SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR, + SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 4, BOOKE_PAGESZ_64M, 1), diff --git a/board/freescale/mpc8548cds/Makefile b/board/freescale/mpc8548cds/Makefile index d1a585ad6..3ae2e9757 100644 --- a/board/freescale/mpc8548cds/Makefile +++ b/board/freescale/mpc8548cds/Makefile @@ -23,21 +23,16 @@ # include $(TOPDIR)/config.mk -ifneq ($(OBJTREE),$(SRCTREE)) -$(shell mkdir -p $(obj)../common) -endif LIB = $(obj)lib$(BOARD).a -COBJS := $(BOARD).o law.o tlb.o \ - ../common/cadmus.o \ - ../common/eeprom.o \ - ../common/ft_board.o \ - ../common/via.o +COBJS-y += $(BOARD).o +COBJS-y += law.o +COBJS-y += tlb.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) -SOBJS := $(addprefix $(obj),$(SOBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS-y)) $(LIB): $(obj).depend $(OBJS) $(SOBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/board/freescale/mpc8548cds/tlb.c b/board/freescale/mpc8548cds/tlb.c index b21f71bd1..ab99af7e1 100644 --- a/board/freescale/mpc8548cds/tlb.c +++ b/board/freescale/mpc8548cds/tlb.c @@ -80,7 +80,7 @@ struct fsl_e_tlb_entry tlb_table[] = { * 0xe210_0000 1M PCI2 IO * 0xe300_0000 1M PCIe IO */ - SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR, + SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 5, BOOKE_PAGESZ_64M, 1), diff --git a/board/freescale/mpc8555cds/Makefile b/board/freescale/mpc8555cds/Makefile index d1a585ad6..3ae2e9757 100644 --- a/board/freescale/mpc8555cds/Makefile +++ b/board/freescale/mpc8555cds/Makefile @@ -23,21 +23,16 @@ # include $(TOPDIR)/config.mk -ifneq ($(OBJTREE),$(SRCTREE)) -$(shell mkdir -p $(obj)../common) -endif LIB = $(obj)lib$(BOARD).a -COBJS := $(BOARD).o law.o tlb.o \ - ../common/cadmus.o \ - ../common/eeprom.o \ - ../common/ft_board.o \ - ../common/via.o +COBJS-y += $(BOARD).o +COBJS-y += law.o +COBJS-y += tlb.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) -SOBJS := $(addprefix $(obj),$(SOBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS-y)) $(LIB): $(obj).depend $(OBJS) $(SOBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/board/freescale/mpc8555cds/tlb.c b/board/freescale/mpc8555cds/tlb.c index 92f759b31..c5434a069 100644 --- a/board/freescale/mpc8555cds/tlb.c +++ b/board/freescale/mpc8555cds/tlb.c @@ -88,7 +88,7 @@ struct fsl_e_tlb_entry tlb_table[] = { * 0xe200_0000 16M PCI1 IO * 0xe300_0000 16M PCI2 IO */ - SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR, + SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 5, BOOKE_PAGESZ_64M, 1), diff --git a/board/freescale/mpc8560ads/tlb.c b/board/freescale/mpc8560ads/tlb.c index 3eaff013f..4fe2862f7 100644 --- a/board/freescale/mpc8560ads/tlb.c +++ b/board/freescale/mpc8560ads/tlb.c @@ -87,7 +87,7 @@ struct fsl_e_tlb_entry tlb_table[] = { * 0xe000_0000 1M CCSRBAR * 0xe200_0000 16M PCI1 IO */ - SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR, + SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 5, BOOKE_PAGESZ_64M, 1), diff --git a/board/freescale/mpc8568mds/Makefile b/board/freescale/mpc8568mds/Makefile index d9f20f96f..8294d3bf4 100644 --- a/board/freescale/mpc8568mds/Makefile +++ b/board/freescale/mpc8568mds/Makefile @@ -23,9 +23,6 @@ # include $(TOPDIR)/config.mk -ifneq ($(OBJTREE),$(SRCTREE)) -$(shell mkdir -p $(obj)../common) -endif LIB = $(obj)lib$(BOARD).a diff --git a/board/freescale/mpc8568mds/tlb.c b/board/freescale/mpc8568mds/tlb.c index 225fc9465..a866c526c 100644 --- a/board/freescale/mpc8568mds/tlb.c +++ b/board/freescale/mpc8568mds/tlb.c @@ -74,7 +74,7 @@ struct fsl_e_tlb_entry tlb_table[] = { * 0xe200_0000 8M PCI1 IO * 0xe280_0000 8M PCIe IO */ - SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR, + SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 3, BOOKE_PAGESZ_64M, 1), diff --git a/board/freescale/mpc8610hpcd/Makefile b/board/freescale/mpc8610hpcd/Makefile index 489689e95..e17a9cb8e 100644 --- a/board/freescale/mpc8610hpcd/Makefile +++ b/board/freescale/mpc8610hpcd/Makefile @@ -21,10 +21,6 @@ include $(TOPDIR)/config.mk -ifneq ($(OBJTREE),$(SRCTREE)) -$(shell mkdir -p $(obj)../common) -endif - LIB = $(obj)lib$(BOARD).a COBJS := $(BOARD).o law.o diff --git a/board/incaip/incaip.c b/board/incaip/incaip.c index dbf0ecc5a..c624b3d82 100644 --- a/board/incaip/incaip.c +++ b/board/incaip/incaip.c @@ -26,9 +26,15 @@ #include #include #include +#include extern uint incaip_get_cpuclk(void); +void _machine_restart(void) +{ + *INCA_IP_WDT_RST_REQ = 0x3f; +} + static ulong max_sdram_size(void) { /* The only supported SDRAM data width is 16bit. diff --git a/board/incaip/lowlevel_init.S b/board/incaip/lowlevel_init.S index 14d738aa1..b39f93d43 100644 --- a/board/incaip/lowlevel_init.S +++ b/board/incaip/lowlevel_init.S @@ -276,6 +276,12 @@ __sdram_init: .ent lowlevel_init lowlevel_init: + /* Disable Watchdog. + */ + la t9, disable_incaip_wdt + jalr t9 + nop + /* EBU, CGU and SDRAM Initialization. */ li a0, CPU_CLOCK_RATE diff --git a/board/mcc200/auto_update.c b/board/mcc200/auto_update.c index 28e4c877b..5580c1188 100644 --- a/board/mcc200/auto_update.c +++ b/board/mcc200/auto_update.c @@ -141,18 +141,21 @@ extern void lcd_enable(void); int au_check_cksum_valid(int idx, long nbytes) { image_header_t *hdr; - unsigned long checksum; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif - if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size))) { + if (nbytes != image_get_image_size (hdr)) { printf ("Image %s bad total SIZE\n", aufile[idx]); return -1; } /* check the data CRC */ - checksum = ntohl(hdr->ih_dcrc); - - if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size)) != checksum) { + if (!image_check_dcrc (hdr)) { printf ("Image %s bad data checksum\n", aufile[idx]); return -1; } @@ -165,59 +168,62 @@ int au_check_header_valid(int idx, long nbytes) unsigned long checksum, fsize; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + /* check the easy ones first */ #undef CHECK_VALID_DEBUG #ifdef CHECK_VALID_DEBUG - printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC); - printf("arch %#x %#x ", hdr->ih_arch, IH_CPU_ARM); - printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes); - printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL); + printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC); + printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_ARM); + printf("size %#x %#lx ", image_get_data_size (hdr), nbytes); + printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL); #endif - if (nbytes < sizeof(*hdr)) { + if (nbytes < image_get_header_size ()) { printf ("Image %s bad header SIZE\n", aufile[idx]); ausize[idx] = 0; return -1; } - if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_PPC) { + if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_PPC)) { printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]); ausize[idx] = 0; return -1; } /* check the hdr CRC */ - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) { + if (!image_check_hcrc (hdr)) { printf ("Image %s bad header checksum\n", aufile[idx]); ausize[idx] = 0; return -1; } - hdr->ih_hcrc = htonl(checksum); /* check the type - could do this all in one gigantic if() */ - if ((idx == IDX_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) { + if ((idx == IDX_FIRMWARE) && !image_check_type (hdr, IH_TYPE_FIRMWARE)) { printf ("Image %s wrong type\n", aufile[idx]); ausize[idx] = 0; return -1; } - if ((idx == IDX_KERNEL) && (hdr->ih_type != IH_TYPE_KERNEL)) { + if ((idx == IDX_KERNEL) && !image_check_type (hdr, IH_TYPE_KERNEL)) { printf ("Image %s wrong type\n", aufile[idx]); ausize[idx] = 0; return -1; } if ((idx == IDX_ROOTFS) && - ( (hdr->ih_type != IH_TYPE_RAMDISK) && (hdr->ih_type != IH_TYPE_FILESYSTEM) ) - ) { + (!image_check_type (hdr, IH_TYPE_RAMDISK) && + !image_check_type (hdr, IH_TYPE_FILESYSTEM))) { printf ("Image %s wrong type\n", aufile[idx]); ausize[idx] = 0; return -1; } /* recycle checksum */ - checksum = ntohl(hdr->ih_size); + checksum = image_get_data_size (hdr); - fsize = checksum + sizeof(*hdr); + fsize = checksum + image_get_header_size (); /* for kernel and ramdisk the image header must also fit into flash */ - if (idx == IDX_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) - checksum += sizeof(*hdr); + if (idx == IDX_KERNEL || image_check_type (hdr, IH_TYPE_RAMDISK)) + checksum += image_get_header_size (); /* check the size does not exceed space in flash. HUSH scripts */ if ((ausize[idx] != 0) && (ausize[idx] < checksum)) { @@ -240,13 +246,19 @@ int au_do_update(int idx, long sz) uint nbytes; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif /* execute a script */ - if (hdr->ih_type == IH_TYPE_SCRIPT) { - addr = (char *)((char *)hdr + sizeof(*hdr)); + if (image_check_type (hdr, IH_TYPE_SCRIPT)) { + addr = (char *)((char *)hdr + image_get_header_size ()); /* stick a NULL at the end of the script, otherwise */ /* parse_string_outer() runs off the end. */ - addr[ntohl(hdr->ih_size)] = 0; + addr[image_get_data_size (hdr)] = 0; addr += 8; parse_string_outer(addr, FLAG_PARSE_SEMICOLON); return 0; @@ -278,19 +290,20 @@ int au_do_update(int idx, long sz) #endif /* strip the header - except for the kernel and ramdisk */ - if (hdr->ih_type == IH_TYPE_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) { + if (image_check_type (hdr, IH_TYPE_KERNEL) || + image_check_type (hdr, IH_TYPE_RAMDISK)) { addr = (char *)hdr; - off = sizeof(*hdr); - nbytes = sizeof(*hdr) + ntohl(hdr->ih_size); + off = image_get_header_size (); + nbytes = image_get_image_size (hdr); } else { - addr = (char *)((char *)hdr + sizeof(*hdr)); + addr = (char *)((char *)hdr + image_get_header_size ()); #ifdef AU_UPDATE_TEST /* copy it to where Linux goes */ if (idx == IDX_FIRMWARE) start = aufl_layout[1].start; #endif off = 0; - nbytes = ntohl(hdr->ih_size); + nbytes = image_get_data_size (hdr); } /* copy the data from RAM to FLASH */ @@ -306,7 +319,8 @@ int au_do_update(int idx, long sz) #endif /* check the data CRC of the copy */ - if (crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) { + if (crc32 (0, (uchar *)(start + off), image_get_data_size (hdr)) != + image_get_dcrc (hdr)) { printf ("Image %s Bad Data Checksum after COPY\n", aufile[idx]); return -1; } @@ -442,10 +456,10 @@ int do_auto_update(void) for (i = 0; i < AU_MAXFILES; i++) { ulong imsize; /* just read the header */ - sz = file_fat_read(aufile[i], LOAD_ADDR, sizeof(image_header_t)); + sz = file_fat_read(aufile[i], LOAD_ADDR, image_get_header_size ()); debug ("read %s sz %ld hdr %d\n", - aufile[i], sz, sizeof(image_header_t)); - if (sz <= 0 || sz < sizeof(image_header_t)) { + aufile[i], sz, image_get_header_size ()); + if (sz <= 0 || sz < image_get_header_size ()) { debug ("%s not found\n", aufile[i]); ausize[i] = 0; continue; @@ -474,14 +488,14 @@ int do_auto_update(void) sz = file_fat_read(aufile[i], LOAD_ADDR, ausize[i]); debug ("read %s sz %ld hdr %d\n", - aufile[i], sz, sizeof(image_header_t)); + aufile[i], sz, image_get_header_size ()); if (sz != ausize[i]) { printf ("%s: size %d read %d?\n", aufile[i], ausize[i], sz); continue; } - if (sz <= 0 || sz <= sizeof(image_header_t)) { + if (sz <= 0 || sz <= image_get_header_size ()) { debug ("%s not found\n", aufile[i]); continue; } diff --git a/board/mpc8540eval/tlb.c b/board/mpc8540eval/tlb.c index f04123636..1003bf613 100644 --- a/board/mpc8540eval/tlb.c +++ b/board/mpc8540eval/tlb.c @@ -27,7 +27,7 @@ #include struct fsl_e_tlb_entry tlb_table[] = { - SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR, + SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 1, BOOKE_PAGESZ_1M, 1), diff --git a/board/mpl/common/common_util.c b/board/mpl/common/common_util.c index 8d4cbe852..785d20469 100644 --- a/board/mpl/common/common_util.c +++ b/board/mpl/common/common_util.c @@ -57,9 +57,6 @@ extern int mem_test(ulong start, ulong ramsize, int quiet); extern flash_info_t flash_info[]; /* info for FLASH chips */ -static image_header_t header; - - static int mpl_prg(uchar *src, ulong size) { @@ -77,7 +74,7 @@ mpl_prg(uchar *src, ulong size) info = &flash_info[0]; #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI) - if (ntohl(magic[0]) != IH_MAGIC) { + if (uimage_to_cpu (magic[0]) != IH_MAGIC) { puts("Bad Magic number\n"); return -1; } @@ -179,44 +176,46 @@ mpl_prg(uchar *src, ulong size) static int mpl_prg_image(uchar *ld_addr) { - unsigned long len, checksum; + unsigned long len; uchar *data; - image_header_t *hdr = &header; + image_header_t *hdr = (image_header_t *)ld_addr; int rc; - /* Copy header so we can blank CRC field for re-calculation */ - memcpy (&header, (char *)ld_addr, sizeof(image_header_t)); - if (ntohl(hdr->ih_magic) != IH_MAGIC) { +#if defined(CONFIG_FIT) + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + + if (!image_check_magic (hdr)) { puts("Bad Magic Number\n"); return 1; } - print_image_hdr(hdr); - if (hdr->ih_os != IH_OS_U_BOOT) { + image_print_contents (hdr); + if (!image_check_os (hdr, IH_OS_U_BOOT)) { puts("No U-Boot Image\n"); return 1; } - if (hdr->ih_type != IH_TYPE_FIRMWARE) { + if (!image_check_type (hdr, IH_TYPE_FIRMWARE)) { puts("No Firmware Image\n"); return 1; } - data = (uchar *)&header; - len = sizeof(image_header_t); - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - if (crc32 (0, (uchar *)data, len) != checksum) { + if (!image_check_hcrc (hdr)) { puts("Bad Header Checksum\n"); return 1; } - data = ld_addr + sizeof(image_header_t); - len = ntohl(hdr->ih_size); puts("Verifying Checksum ... "); - if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) { + if (!image_check_dcrc (hdr)) { puts("Bad Data CRC\n"); return 1; } puts("OK\n"); - if (hdr->ih_comp != IH_COMP_NONE) { + data = (uchar *)image_get_data (hdr); + len = image_get_data_size (hdr); + + if (image_get_comp (hdr) != IH_COMP_NONE) { uchar *buf; /* reserve space for uncompressed image */ if ((buf = malloc(IMAGE_SIZE)) == NULL) { @@ -224,7 +223,7 @@ mpl_prg_image(uchar *ld_addr) return 1; } - switch (hdr->ih_comp) { + switch (image_get_comp (hdr)) { case IH_COMP_GZIP: puts("Uncompressing (GZIP) ... "); rc = gunzip ((void *)(buf), IMAGE_SIZE, data, &len); @@ -253,7 +252,8 @@ mpl_prg_image(uchar *ld_addr) break; #endif default: - printf ("Unimplemented compression type %d\n", hdr->ih_comp); + printf ("Unimplemented compression type %d\n", + image_get_comp (hdr)); free(buf); return 1; } diff --git a/board/pm854/tlb.c b/board/pm854/tlb.c index 5d8753798..a7f381350 100644 --- a/board/pm854/tlb.c +++ b/board/pm854/tlb.c @@ -87,7 +87,7 @@ struct fsl_e_tlb_entry tlb_table[] = { * 0xe000_0000 1M CCSRBAR * 0xe200_0000 16M PCI1 IO */ - SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR, + SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 5, BOOKE_PAGESZ_64M, 1), diff --git a/board/pm856/tlb.c b/board/pm856/tlb.c index 5d8753798..a7f381350 100644 --- a/board/pm856/tlb.c +++ b/board/pm856/tlb.c @@ -87,7 +87,7 @@ struct fsl_e_tlb_entry tlb_table[] = { * 0xe000_0000 1M CCSRBAR * 0xe200_0000 16M PCI1 IO */ - SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR, + SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 5, BOOKE_PAGESZ_64M, 1), diff --git a/board/pn62/cmd_pn62.c b/board/pn62/cmd_pn62.c index ffa20cde3..3f53e4b7c 100644 --- a/board/pn62/cmd_pn62.c +++ b/board/pn62/cmd_pn62.c @@ -157,8 +157,15 @@ int do_loadpci (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char *s; if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) { - printf("Running autoscript at addr 0x%08lX ...\n", load_addr); - rcode = autoscript (bd, load_addr); + printf ("Running autoscript at addr 0x%08lX", load_addr); + + s = getenv ("autoscript_uname"); + if (s) + printf (":%s ...\n", s); + else + puts (" ...\n"); + + rcode = autoscript (load_addr, s); } } #endif diff --git a/board/purple/purple.c b/board/purple/purple.c index 74718afb4..13a14556b 100644 --- a/board/purple/purple.c +++ b/board/purple/purple.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "sconsole.h" @@ -52,6 +53,13 @@ extern int asc_serial_getc (void); extern int asc_serial_tstc (void); extern void asc_serial_setbrg (void); +void _machine_restart(void) +{ + void (*f)(void) = (void *) 0xbfc00000; + + f(); +} + static void sdram_timing_init (ulong size) { register uint pass; diff --git a/board/sbc8548/tlb.c b/board/sbc8548/tlb.c index 8d6625e54..6314005ca 100644 --- a/board/sbc8548/tlb.c +++ b/board/sbc8548/tlb.c @@ -81,7 +81,7 @@ struct fsl_e_tlb_entry tlb_table[] = { * 0xe0000000 1M CCSRBAR * 0xe2000000 16M PCI1 IO */ - SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR, + SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 4, BOOKE_PAGESZ_64M, 1), diff --git a/board/sbc8560/tlb.c b/board/sbc8560/tlb.c index 155ff64bb..d07339960 100644 --- a/board/sbc8560/tlb.c +++ b/board/sbc8560/tlb.c @@ -28,7 +28,7 @@ struct fsl_e_tlb_entry tlb_table[] = { /* TLB for CCSRBAR (IMMR) */ - SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR, + SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 1, BOOKE_PAGESZ_1M, 1), diff --git a/board/siemens/common/fpga.c b/board/siemens/common/fpga.c index f022ed6d5..48c185082 100644 --- a/board/siemens/common/fpga.c +++ b/board/siemens/common/fpga.c @@ -131,45 +131,44 @@ static int fpga_reset (fpga_t* fpga) static int fpga_load (fpga_t* fpga, ulong addr, int checkall) { volatile uchar *fpga_addr = (volatile uchar *)fpga->conf_base; - image_header_t hdr; - ulong len, checksum; - uchar *data = (uchar *)&hdr; - char *s, msg[32]; + image_header_t *hdr = (image_header_t *)addr; + ulong len; + uchar *data; + char msg[32]; int verify, i; +#if defined(CONFIG_FIT) + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + /* * Check the image header and data of the net-list */ - memcpy (&hdr, (char *)addr, sizeof(image_header_t)); - - if (hdr.ih_magic != IH_MAGIC) { + if (!image_check_magic (hdr)) { strcpy (msg, "Bad Image Magic Number"); goto failure; } - len = sizeof(image_header_t); - - checksum = hdr.ih_hcrc; - hdr.ih_hcrc = 0; - - if (crc32 (0, data, len) != checksum) { + if (!image_check_hcrc (hdr)) { strcpy (msg, "Bad Image Header CRC"); goto failure; } - data = (uchar*)(addr + sizeof(image_header_t)); - len = hdr.ih_size; + data = (uchar*)image_get_data (hdr); + len = image_get_data_size (hdr); - s = getenv ("verify"); - verify = (s && (*s == 'n')) ? 0 : 1; + verify = getenv_verify (); if (verify) { - if (crc32 (0, data, len) != hdr.ih_dcrc) { + if (!image_check_dcrc (hdr)) { strcpy (msg, "Bad Image Data CRC"); goto failure; } } - if (checkall && fpga_get_version(fpga, (char *)(hdr.ih_name)) < 0) + if (checkall && fpga_get_version(fpga, image_get_name (hdr)) < 0) return 1; /* align length */ @@ -184,7 +183,7 @@ static int fpga_load (fpga_t* fpga, ulong addr, int checkall) goto failure; } - printf ("(%s)... ", hdr.ih_name); + printf ("(%s)... ", image_get_name (hdr)); /* * Copy data to FPGA */ @@ -341,7 +340,14 @@ int fpga_init (void) } hdr = (image_header_t *)addr; - if ((new_id = fpga_get_version(fpga, (char *)(hdr->ih_name))) == -1) +#if defined(CONFIG_FIT) + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + + if ((new_id = fpga_get_version(fpga, image_get_name (hdr))) == -1) return 1; do_load = 1; diff --git a/board/stxgp3/tlb.c b/board/stxgp3/tlb.c index 529f23042..d4104166a 100644 --- a/board/stxgp3/tlb.c +++ b/board/stxgp3/tlb.c @@ -87,7 +87,7 @@ struct fsl_e_tlb_entry tlb_table[] = { * 0xe000_0000 1M CCSRBAR * 0xe200_0000 16M PCI1 IO */ - SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR, + SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 5, BOOKE_PAGESZ_64M, 1), diff --git a/board/stxssa/tlb.c b/board/stxssa/tlb.c index 46b14406d..86cbd1127 100644 --- a/board/stxssa/tlb.c +++ b/board/stxssa/tlb.c @@ -88,7 +88,7 @@ struct fsl_e_tlb_entry tlb_table[] = { * 0xe200_0000 16M PCI1 IO * 0xe300_0000 16M PCI2 IO */ - SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR, + SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 5, BOOKE_PAGESZ_64M, 1), diff --git a/board/tb0229/tb0229.c b/board/tb0229/tb0229.c index 61c2e9bd3..d08b42245 100644 --- a/board/tb0229/tb0229.c +++ b/board/tb0229/tb0229.c @@ -12,10 +12,17 @@ #include #include #include -#include #include +#include #include +void _machine_restart(void) +{ + void (*f)(void) = (void *) 0xbfc00000; + + f(); +} + #if defined(CONFIG_PCI) static struct pci_controller hose; diff --git a/board/tqm85xx/tlb.c b/board/tqm85xx/tlb.c index a178cfef3..ad26caeea 100644 --- a/board/tqm85xx/tlb.c +++ b/board/tqm85xx/tlb.c @@ -91,7 +91,7 @@ struct fsl_e_tlb_entry tlb_table[] = { * 0xe000_0000 1M CCSRBAR * 0xe200_0000 16M PCI1 IO */ - SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR, + SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 6, BOOKE_PAGESZ_64M, 1), diff --git a/board/trab/auto_update.c b/board/trab/auto_update.c index 54d3645ff..46110cc76 100644 --- a/board/trab/auto_update.c +++ b/board/trab/auto_update.c @@ -209,21 +209,21 @@ int au_check_cksum_valid(int idx, long nbytes) { image_header_t *hdr; - unsigned long checksum; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif - if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size))) - { + if (nbytes != image_get_image_size (hdr)) { printf ("Image %s bad total SIZE\n", aufile[idx]); return -1; } /* check the data CRC */ - checksum = ntohl(hdr->ih_dcrc); - - if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size)) - != checksum) - { + if (!image_check_dcrc (hdr)) { printf ("Image %s bad data checksum\n", aufile[idx]); return -1; } @@ -238,54 +238,55 @@ au_check_header_valid(int idx, long nbytes) unsigned char buf[4]; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + /* check the easy ones first */ #undef CHECK_VALID_DEBUG #ifdef CHECK_VALID_DEBUG - printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC); - printf("arch %#x %#x ", hdr->ih_arch, IH_CPU_ARM); - printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes); - printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL); + printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC); + printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_ARM); + printf("size %#x %#lx ", image_get_data_size (hdr), nbytes); + printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL); #endif - if (nbytes < sizeof(*hdr)) - { + if (nbytes < image_get_header_size ()) { printf ("Image %s bad header SIZE\n", aufile[idx]); return -1; } - if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_ARM) - { + if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_ARM)) { printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]); return -1; } /* check the hdr CRC */ - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) { + if (!image_check_hcrc (hdr)) { printf ("Image %s bad header checksum\n", aufile[idx]); return -1; } - hdr->ih_hcrc = htonl(checksum); /* check the type - could do this all in one gigantic if() */ - if ((idx == IDX_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) { + if ((idx == IDX_FIRMWARE) && + !image_check_type (hdr, IH_TYPE_FIRMWARE)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } - if ((idx == IDX_KERNEL) && (hdr->ih_type != IH_TYPE_KERNEL)) { + if ((idx == IDX_KERNEL) && !image_check_type (hdr, IH_TYPE_KERNEL)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } - if ((idx == IDX_DISK) && (hdr->ih_type != IH_TYPE_FILESYSTEM)) { + if ((idx == IDX_DISK) && !image_check_type (hdr, IH_TYPE_FILESYSTEM)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } - if ((idx == IDX_APP) && (hdr->ih_type != IH_TYPE_RAMDISK) - && (hdr->ih_type != IH_TYPE_FILESYSTEM)) { + if ((idx == IDX_APP) && !image_check_type (hdr, IH_TYPE_RAMDISK) + && !image_check_type (hdr, IH_TYPE_FILESYSTEM)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } if ((idx == IDX_PREPARE || idx == IDX_PREINST || idx == IDX_POSTINST) - && (hdr->ih_type != IH_TYPE_SCRIPT)) - { + && !image_check_type (hdr, IH_TYPE_SCRIPT)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } @@ -293,10 +294,10 @@ au_check_header_valid(int idx, long nbytes) if (idx == IDX_PREPARE) return 0; /* recycle checksum */ - checksum = ntohl(hdr->ih_size); + checksum = image_get_data_size (hdr); /* for kernel and app the image header must also fit into flash */ if ((idx != IDX_DISK) && (idx != IDX_FIRMWARE)) - checksum += sizeof(*hdr); + checksum += image_get_header_size (); /* check the size does not exceed space in flash. HUSH scripts */ /* all have ausize[] set to 0 */ if ((ausize[idx] != 0) && (ausize[idx] < checksum)) { @@ -310,10 +311,10 @@ au_check_header_valid(int idx, long nbytes) printf ("buf[0] %#x buf[1] %#x buf[2] %#x buf[3] %#x " "as int %#x time %#x\n", buf[0], buf[1], buf[2], buf[3], - *((unsigned int *)buf), ntohl(hdr->ih_time)); + *((unsigned int *)buf), image_get_time (hdr)); #endif /* check it */ - if (*((unsigned int *)buf) >= ntohl(hdr->ih_time)) { + if (*((unsigned int *)buf) >= image_get_time (hdr)) { printf ("Image %s is too old\n", aufile[idx]); return -1; } @@ -335,16 +336,22 @@ au_do_update(int idx, long sz) uint nbytes; hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif /* disable the power switch */ *CPLD_VFD_BK |= POWER_OFF; /* execute a script */ - if (hdr->ih_type == IH_TYPE_SCRIPT) { - addr = (char *)((char *)hdr + sizeof(*hdr)); + if (image_check_type (hdr, IH_TYPE_SCRIPT)) { + addr = (char *)((char *)hdr + image_get_header_size ()); /* stick a NULL at the end of the script, otherwise */ /* parse_string_outer() runs off the end. */ - addr[ntohl(hdr->ih_size)] = 0; + addr[image_get_data_size (hdr)] = 0; addr += 8; parse_string_outer(addr, FLAG_PARSE_SEMICOLON); return 0; @@ -372,19 +379,20 @@ au_do_update(int idx, long sz) flash_sect_erase(start, end); wait_ms(100); /* strip the header - except for the kernel and ramdisk */ - if (hdr->ih_type == IH_TYPE_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) { + if (image_check_type (hdr, IH_TYPE_KERNEL) || + image_check_type (hdr, IH_TYPE_RAMDISK)) { addr = (char *)hdr; - off = sizeof(*hdr); - nbytes = sizeof(*hdr) + ntohl(hdr->ih_size); + off = image_get_header_size (); + nbytes = image_get_image_size (hdr); } else { - addr = (char *)((char *)hdr + sizeof(*hdr)); + addr = (char *)((char *)hdr + image_get_header_size ()); #ifdef AU_UPDATE_TEST /* copy it to where Linux goes */ if (idx == IDX_FIRMWARE) start = aufl_layout[1].start; #endif off = 0; - nbytes = ntohl(hdr->ih_size); + nbytes = image_get_data_size (hdr); } /* copy the data from RAM to FLASH */ @@ -396,7 +404,8 @@ au_do_update(int idx, long sz) } /* check the dcrc of the copy */ - if (crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) { + if (crc32 (0, (uchar *)(start + off), image_get_data_size (hdr)) != + image_get_dcrc (hdr)) { printf ("Image %s Bad Data Checksum After COPY\n", aufile[idx]); return -1; } @@ -423,17 +432,24 @@ au_update_eeprom(int idx) } hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) + if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { + puts ("Non legacy image format not supported\n"); + return -1; + } +#endif + /* write the time field into EEPROM */ off = auee_off[idx].time; - val = ntohl(hdr->ih_time); + val = image_get_time (hdr); i2c_write_multiple(0x54, off, 1, &val, sizeof(val)); /* write the size field into EEPROM */ off = auee_off[idx].size; - val = ntohl(hdr->ih_size); + val = image_get_data_size (hdr); i2c_write_multiple(0x54, off, 1, &val, sizeof(val)); /* write the dcrc field into EEPROM */ off = auee_off[idx].dcrc; - val = ntohl(hdr->ih_dcrc); + val = image_get_dcrc (hdr); i2c_write_multiple(0x54, off, 1, &val, sizeof(val)); /* enable the power switch */ *CPLD_VFD_BK &= ~POWER_OFF; @@ -577,10 +593,10 @@ do_auto_update(void) /* just loop thru all the possible files */ for (i = 0; i < AU_MAXFILES; i++) { /* just read the header */ - sz = file_fat_read(aufile[i], LOAD_ADDR, sizeof(image_header_t)); + sz = file_fat_read(aufile[i], LOAD_ADDR, image_get_header_size ()); debug ("read %s sz %ld hdr %d\n", - aufile[i], sz, sizeof(image_header_t)); - if (sz <= 0 || sz < sizeof(image_header_t)) { + aufile[i], sz, image_get_header_size ()); + if (sz <= 0 || sz < image_get_header_size ()) { debug ("%s not found\n", aufile[i]); continue; } @@ -590,8 +606,8 @@ do_auto_update(void) } sz = file_fat_read(aufile[i], LOAD_ADDR, MAX_LOADSZ); debug ("read %s sz %ld hdr %d\n", - aufile[i], sz, sizeof(image_header_t)); - if (sz <= 0 || sz <= sizeof(image_header_t)) { + aufile[i], sz, image_get_header_size ()); + if (sz <= 0 || sz <= image_get_header_size ()) { debug ("%s not found\n", aufile[i]); continue; } diff --git a/common/Makefile b/common/Makefile index 56d05819f..0d67337d2 100644 --- a/common/Makefile +++ b/common/Makefile @@ -36,6 +36,8 @@ COBJS-y += cmd_autoscript.o COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o COBJS-$(CONFIG_CMD_BEDBUG) += cmd_bedbug.o COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o +COBJS-y += image.o +COBJS-y += gunzip.o COBJS-y += cmd_boot.o COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o COBJS-y += cmd_bootm.o @@ -86,13 +88,15 @@ COBJS-y += cmd_pcmcia.o COBJS-$(CONFIG_CMD_PORTIO) += cmd_portio.o COBJS-$(CONFIG_CMD_REGINFO) += cmd_reginfo.o COBJS-$(CONFIG_CMD_REISER) += cmd_reiser.o -COBJS-y += cmd_sata.o +COBJS-$(CONFIG_CMD_SATA) += cmd_sata.o COBJS-$(CONFIG_CMD_SCSI) += cmd_scsi.o +COBJS-$(CONFIG_CMD_SETEXPR) += cmd_setexpr.o COBJS-$(CONFIG_CMD_SPI) += cmd_spi.o COBJS-$(CONFIG_CMD_STRINGS) += cmd_strings.o COBJS-$(CONFIG_CMD_TERMINAL) += cmd_terminal.o COBJS-$(CONFIG_CMD_UNIVERSE) += cmd_universe.o COBJS-$(CONFIG_CMD_USB) += cmd_usb.o +COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-y += cmd_vfd.o COBJS-y += command.o COBJS-y += console.o @@ -136,6 +140,7 @@ COBJS-y += crc16.o COBJS-y += xyzModem.o COBJS-y += cmd_mac.o COBJS-$(CONFIG_CMD_MFSL) += cmd_mfsl.o +COBJS-$(CONFIG_MP) += cmd_mp.o COBJS := $(COBJS-y) SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/common/cmd_autoscript.c b/common/cmd_autoscript.c index a6038a6ef..1a37b90d7 100644 --- a/common/cmd_autoscript.c +++ b/common/cmd_autoscript.c @@ -49,57 +49,110 @@ #if defined(CONFIG_AUTOSCRIPT) || defined(CONFIG_CMD_AUTOSCRIPT) -extern image_header_t header; /* from cmd_bootm.c */ int -autoscript (ulong addr) +autoscript (ulong addr, const char *fit_uname) { - ulong crc, data, len; - image_header_t *hdr = &header; - ulong *len_ptr; - char *cmd; - int rcode = 0; - int verify; + ulong len; + image_header_t *hdr; + ulong *data; + char *cmd; + int rcode = 0; + int verify; +#if defined(CONFIG_FIT) + const void* fit_hdr; + int noffset; + const void *fit_data; + size_t fit_len; +#endif - cmd = getenv ("verify"); - verify = (cmd && (*cmd == 'n')) ? 0 : 1; + verify = getenv_verify (); + switch (genimg_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - memmove (hdr, (char *)addr, sizeof(image_header_t)); - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - puts ("Bad magic number\n"); - return 1; - } - - crc = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - len = sizeof (image_header_t); - data = (ulong)hdr; - if (crc32(0, (uchar *)data, len) != crc) { - puts ("Bad header crc\n"); - return 1; - } - - data = addr + sizeof(image_header_t); - len = ntohl(hdr->ih_size); - - if (verify) { - if (crc32(0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) { - puts ("Bad data crc\n"); + if (!image_check_magic (hdr)) { + puts ("Bad magic number\n"); return 1; } - } - if (hdr->ih_type != IH_TYPE_SCRIPT) { - puts ("Bad image type\n"); - return 1; - } + if (!image_check_hcrc (hdr)) { + puts ("Bad header crc\n"); + return 1; + } - /* get length of script */ - len_ptr = (ulong *)data; + if (verify) { + if (!image_check_dcrc (hdr)) { + puts ("Bad data crc\n"); + return 1; + } + } - if ((len = ntohl(*len_ptr)) == 0) { - puts ("Empty Script\n"); + if (!image_check_type (hdr, IH_TYPE_SCRIPT)) { + puts ("Bad image type\n"); + return 1; + } + + /* get length of script */ + data = (ulong *)image_get_data (hdr); + + if ((len = uimage_to_cpu (*data)) == 0) { + puts ("Empty Script\n"); + return 1; + } + + /* + * scripts are just multi-image files with one component, seek + * past the zero-terminated sequence of image lengths to get + * to the actual image data + */ + while (*data++); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + if (fit_uname == NULL) { + puts ("No FIT subimage unit name\n"); + return 1; + } + + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + puts ("Bad FIT image format\n"); + return 1; + } + + /* get script component image node offset */ + noffset = fit_image_get_node (fit_hdr, fit_uname); + if (noffset < 0) { + printf ("Can't find '%s' FIT subimage\n", fit_uname); + return 1; + } + + if (!fit_image_check_type (fit_hdr, noffset, IH_TYPE_SCRIPT)) { + puts ("Not a image image\n"); + return 1; + } + + /* verify integrity */ + if (verify) { + if (!fit_image_check_hashes (fit_hdr, noffset)) { + puts ("Bad Data Hash\n"); + return 1; + } + } + + /* get script subimage data address and length */ + if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) { + puts ("Could not find script subimage data\n"); + return 1; + } + + data = (ulong *)fit_data; + len = (ulong)fit_len; + break; +#endif + default: + puts ("Wrong image format for autoscript\n"); return 1; } @@ -109,10 +162,8 @@ autoscript (ulong addr) return 1; } - while (*len_ptr++); - /* make sure cmd is null terminated */ - memmove (cmd, (char *)len_ptr, len); + memmove (cmd, (char *)data, len); *(cmd + len) = 0; #ifdef CFG_HUSH_PARSER /*?? */ @@ -158,25 +209,35 @@ do_autoscript (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong addr; int rcode; + const char *fit_uname = NULL; + /* Find script image */ if (argc < 2) { addr = CFG_LOAD_ADDR; + debug ("* autoscr: default load address = 0x%08lx\n", addr); +#if defined(CONFIG_FIT) + } else if (fit_parse_subimage (argv[1], load_addr, &addr, &fit_uname)) { + debug ("* autoscr: subimage '%s' from FIT image at 0x%08lx\n", + fit_uname, addr); +#endif } else { - addr = simple_strtoul (argv[1],0,16); + addr = simple_strtoul(argv[1], NULL, 16); + debug ("* autoscr: cmdline image address = 0x%08lx\n", addr); } - printf ("## Executing script at %08lx\n",addr); - rcode = autoscript (addr); + printf ("## Executing script at %08lx\n", addr); + rcode = autoscript (addr, fit_uname); return rcode; } -#if defined(CONFIG_CMD_AUTOSCRIPT) U_BOOT_CMD( autoscr, 2, 0, do_autoscript, "autoscr - run script from memory\n", "[addr] - run script starting at addr" " - A valid autoscr header must be present\n" +#if defined(CONFIG_FIT) + "For FIT format uImage addr must include subimage\n" + "unit name in the form of addr:\n" +#endif ); #endif - -#endif diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 9deb78190..9e5ce4b38 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -21,6 +21,7 @@ * MA 02111-1307 USA */ + /* * Boot support */ @@ -32,56 +33,24 @@ #include #include #include +#include #include -#if defined(CONFIG_OF_LIBFDT) -#include -#include -#include -#endif -#if defined(CONFIG_OF_FLAT_TREE) -#include -#endif - -DECLARE_GLOBAL_DATA_PTR; - -/*cmd_boot.c*/ -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - -#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) -#include -#endif - #ifdef CFG_HUSH_PARSER #include #endif -#ifdef CFG_INIT_RAM_LOCK -#include +DECLARE_GLOBAL_DATA_PTR; + +extern int gunzip (void *dst, int dstlen, unsigned char *src, unsigned long *lenp); +#ifndef CFG_BOOTM_LEN +#define CFG_BOOTM_LEN 0x800000 /* use 8MByte as default max gunzip size */ #endif -#ifdef CONFIG_LOGBUFFER -#include +#ifdef CONFIG_BZIP2 +extern void bz_internal_error(int); #endif -#ifdef CONFIG_HAS_DATAFLASH -#include -#endif - -/* - * Some systems (for example LWMON) have very short watchdog periods; - * we must make sure to split long operations like memmove() or - * crc32() into reasonable chunks. - */ -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) -# define CHUNKSZ (64 * 1024) -#endif - -int gunzip (void *, int, unsigned char *, unsigned long *); - -static void *zalloc(void *, unsigned, unsigned); -static void zfree(void *, void *, unsigned); - #if defined(CONFIG_CMD_IMI) static int image_info (unsigned long addr); #endif @@ -92,12 +61,19 @@ extern flash_info_t flash_info[]; /* info for FLASH chips */ static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #endif -static void print_type (image_header_t *hdr); - -#ifdef __I386__ -image_header_t *fake_header(image_header_t *hdr, void *ptr, int size); +#ifdef CONFIG_SILENT_CONSOLE +static void fixup_silent_linux (void); #endif +static image_header_t *image_get_kernel (ulong img_addr, int verify); +#if defined(CONFIG_FIT) +static int fit_check_kernel (const void *fit, int os_noffset, int verify); +#endif + +static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag,int argc, char *argv[], + bootm_headers_t *images, ulong *os_data, ulong *os_len); +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + /* * Continue booting an OS image; caller already has: * - copied image header to global variable `header' @@ -106,203 +82,135 @@ image_header_t *fake_header(image_header_t *hdr, void *ptr, int size); * - loaded (first part of) image to header load address, * - disabled interrupts. */ -typedef void boot_os_Fcn (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong addr, /* of image to boot */ - ulong *len_ptr, /* multi-file image length table */ - int verify); /* getenv("verify")[0] != 'n' */ +typedef void boot_os_fn (cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + bootm_headers_t *images); /* pointers to os/initrd/fdt */ -#ifdef DEBUG -extern int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +extern boot_os_fn do_bootm_linux; +static boot_os_fn do_bootm_netbsd; +#if defined(CONFIG_LYNXKDI) +static boot_os_fn do_bootm_lynxkdi; +extern void lynxkdi_boot (image_header_t *); #endif - -#ifdef CONFIG_PPC -static boot_os_Fcn do_bootm_linux; -#else -extern boot_os_Fcn do_bootm_linux; -#endif -#ifdef CONFIG_SILENT_CONSOLE -static void fixup_silent_linux (void); -#endif -static boot_os_Fcn do_bootm_netbsd; -static boot_os_Fcn do_bootm_rtems; +static boot_os_fn do_bootm_rtems; #if defined(CONFIG_CMD_ELF) -static boot_os_Fcn do_bootm_vxworks; -static boot_os_Fcn do_bootm_qnxelf; -int do_bootvx ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] ); -int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] ); +static boot_os_fn do_bootm_vxworks; +static boot_os_fn do_bootm_qnxelf; +int do_bootvx (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #endif #if defined(CONFIG_ARTOS) && defined(CONFIG_PPC) -static boot_os_Fcn do_bootm_artos; -#endif -#ifdef CONFIG_LYNXKDI -static boot_os_Fcn do_bootm_lynxkdi; -extern void lynxkdi_boot( image_header_t * ); +extern uchar (*env_get_char)(int); /* Returns a character from the environment */ +static boot_os_fn do_bootm_artos; #endif -#ifndef CFG_BOOTM_LEN -#define CFG_BOOTM_LEN 0x800000 /* use 8MByte as default max gunzip size */ -#endif +ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */ +static bootm_headers_t images; /* pointers to os/initrd/fdt images */ -image_header_t header; +void __board_lmb_reserve(struct lmb *lmb) +{ + /* please define platform specific board_lmb_reserve() */ +} +void board_lmb_reserve(struct lmb *lmb) __attribute__((weak, alias("__board_lmb_reserve"))); -ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */ +/*******************************************************************/ +/* bootm - boot application image from image in memory */ +/*******************************************************************/ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { - ulong iflag; - ulong addr; - ulong data, len, checksum; - ulong *len_ptr; - uint unc_len = CFG_BOOTM_LEN; - int i, verify; - char *name, *s; - int (*appl)(int, char *[]); - image_header_t *hdr = &header; + ulong iflag; + const char *type_name; + uint unc_len = CFG_BOOTM_LEN; + uint8_t comp, type, os; - s = getenv ("verify"); - verify = (s && (*s == 'n')) ? 0 : 1; + void *os_hdr; + ulong os_data, os_len; + ulong image_start, image_end; + ulong load_start, load_end; + ulong mem_start, mem_size; - if (argc < 2) { - addr = load_addr; - } else { - addr = simple_strtoul(argv[1], NULL, 16); - } + struct lmb lmb; - show_boot_progress (1); - printf ("## Booting image at %08lx ...\n", addr); + memset ((void *)&images, 0, sizeof (images)); + images.verify = getenv_verify(); + images.autostart = getenv_autostart(); + images.lmb = &lmb; - /* Copy header so we can blank CRC field for re-calculation */ -#ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash(addr)){ - read_dataflash(addr, sizeof(image_header_t), (char *)&header); - } else -#endif - memmove (&header, (char *)addr, sizeof(image_header_t)); + lmb_init(&lmb); - if (ntohl(hdr->ih_magic) != IH_MAGIC) { -#ifdef __I386__ /* correct image format not implemented yet - fake it */ - if (fake_header(hdr, (void*)addr, -1) != NULL) { - /* to compensate for the addition below */ - addr -= sizeof(image_header_t); - /* turnof verify, - * fake_header() does not fake the data crc - */ - verify = 0; - } else -#endif /* __I386__ */ - { - puts ("Bad Magic Number\n"); - show_boot_progress (-1); - return 1; - } - } - show_boot_progress (2); + mem_start = getenv_bootm_low(); + mem_size = getenv_bootm_size(); - data = (ulong)&header; - len = sizeof(image_header_t); + lmb_add(&lmb, mem_start, mem_size); - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; + board_lmb_reserve(&lmb); - if (crc32 (0, (uchar *)data, len) != checksum) { - puts ("Bad Header Checksum\n"); - show_boot_progress (-2); + /* get kernel image header, start address and length */ + os_hdr = boot_get_kernel (cmdtp, flag, argc, argv, + &images, &os_data, &os_len); + if (os_len == 0) { + puts ("ERROR: can't get kernel image!\n"); return 1; } - show_boot_progress (3); -#ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash(addr)){ - len = ntohl(hdr->ih_size) + sizeof(image_header_t); - read_dataflash(addr, len, (char *)CFG_LOAD_ADDR); - addr = CFG_LOAD_ADDR; - } -#endif + /* get image parameters */ + switch (genimg_get_format (os_hdr)) { + case IMAGE_FORMAT_LEGACY: + type = image_get_type (os_hdr); + comp = image_get_comp (os_hdr); + os = image_get_os (os_hdr); - - /* for multi-file images we need the data part, too */ - print_image_hdr ((image_header_t *)addr); - - data = addr + sizeof(image_header_t); - len = ntohl(hdr->ih_size); - - if (verify) { - puts (" Verifying Checksum ... "); - if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) { - printf ("Bad Data CRC\n"); - show_boot_progress (-3); + image_end = image_get_image_end (os_hdr); + load_start = image_get_load (os_hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + if (fit_image_get_type (images.fit_hdr_os, + images.fit_noffset_os, &type)) { + puts ("Can't get image type!\n"); + show_boot_progress (-109); return 1; } - puts ("OK\n"); - } - show_boot_progress (4); - len_ptr = (ulong *)data; + if (fit_image_get_comp (images.fit_hdr_os, + images.fit_noffset_os, &comp)) { + puts ("Can't get image compression!\n"); + show_boot_progress (-110); + return 1; + } -#if defined(__ARM__) - if (hdr->ih_arch != IH_CPU_ARM) -#elif defined(__avr32__) - if (hdr->ih_arch != IH_CPU_AVR32) -#elif defined(__bfin__) - if (hdr->ih_arch != IH_CPU_BLACKFIN) -#elif defined(__I386__) - if (hdr->ih_arch != IH_CPU_I386) -#elif defined(__M68K__) - if (hdr->ih_arch != IH_CPU_M68K) -#elif defined(__microblaze__) - if (hdr->ih_arch != IH_CPU_MICROBLAZE) -#elif defined(__mips__) - if (hdr->ih_arch != IH_CPU_MIPS) -#elif defined(__nios__) - if (hdr->ih_arch != IH_CPU_NIOS) -#elif defined(__nios2__) - if (hdr->ih_arch != IH_CPU_NIOS2) -#elif defined(__PPC__) - if (hdr->ih_arch != IH_CPU_PPC) -#elif defined(__sh__) - if (hdr->ih_arch != IH_CPU_SH) -#else -# error Unknown CPU type -#endif - { - printf ("Unsupported Architecture 0x%x\n", hdr->ih_arch); - show_boot_progress (-4); - return 1; - } - show_boot_progress (5); + if (fit_image_get_os (images.fit_hdr_os, + images.fit_noffset_os, &os)) { + puts ("Can't get image OS!\n"); + show_boot_progress (-111); + return 1; + } - switch (hdr->ih_type) { - case IH_TYPE_STANDALONE: - name = "Standalone Application"; - /* A second argument overwrites the load address */ - if (argc > 2) { - hdr->ih_load = htonl(simple_strtoul(argv[2], NULL, 16)); + image_end = fit_get_end (images.fit_hdr_os); + + if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os, + &load_start)) { + puts ("Can't get image load address!\n"); + show_boot_progress (-112); + return 1; } break; - case IH_TYPE_KERNEL: - name = "Kernel Image"; - break; - case IH_TYPE_MULTI: - name = "Multi-File Image"; - len = ntohl(len_ptr[0]); - /* OS kernel is always the first image */ - data += 8; /* kernel_len + terminator */ - for (i=1; len_ptr[i]; ++i) - data += 4; - break; - default: printf ("Wrong Image Type for %s command\n", cmdtp->name); - show_boot_progress (-5); +#endif + default: + puts ("ERROR: unknown image format type!\n"); return 1; } - show_boot_progress (6); + + image_start = (ulong)os_hdr; + load_end = 0; + type_name = genimg_get_type_name (type); /* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ - iflag = disable_interrupts(); #ifdef CONFIG_AMIGAONEG3SE @@ -316,138 +224,113 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) dcache_disable(); #endif - switch (hdr->ih_comp) { + switch (comp) { case IH_COMP_NONE: - if(ntohl(hdr->ih_load) == addr) { - printf (" XIP %s ... ", name); + if (load_start == (ulong)os_hdr) { + printf (" XIP %s ... ", type_name); } else { -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - size_t l = len; - void *to = (void *)ntohl(hdr->ih_load); - void *from = (void *)data; + printf (" Loading %s ... ", type_name); - printf (" Loading %s ... ", name); + memmove_wd ((void *)load_start, + (void *)os_data, os_len, CHUNKSZ); - while (l > 0) { - size_t tail = (l > CHUNKSZ) ? CHUNKSZ : l; - WATCHDOG_RESET(); - memmove (to, from, tail); - to += tail; - from += tail; - l -= tail; - } -#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ - memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len); -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ + load_end = load_start + os_len; + puts("OK\n"); } break; case IH_COMP_GZIP: - printf (" Uncompressing %s ... ", name); - if (gunzip ((void *)ntohl(hdr->ih_load), unc_len, - (uchar *)data, &len) != 0) { - puts ("GUNZIP ERROR - must RESET board to recover\n"); + printf (" Uncompressing %s ... ", type_name); + if (gunzip ((void *)load_start, unc_len, + (uchar *)os_data, &os_len) != 0) { + puts ("GUNZIP: uncompress or overwrite error " + "- must RESET board to recover\n"); show_boot_progress (-6); do_reset (cmdtp, flag, argc, argv); } + + load_end = load_start + os_len; break; #ifdef CONFIG_BZIP2 case IH_COMP_BZIP2: - printf (" Uncompressing %s ... ", name); + printf (" Uncompressing %s ... ", type_name); /* * If we've got less than 4 MB of malloc() space, * use slower decompression algorithm which requires * at most 2300 KB of memory. */ - i = BZ2_bzBuffToBuffDecompress ((char*)ntohl(hdr->ih_load), - &unc_len, (char *)data, len, - CFG_MALLOC_LEN < (4096 * 1024), 0); + int i = BZ2_bzBuffToBuffDecompress ((char*)load_start, + &unc_len, (char *)os_data, os_len, + CFG_MALLOC_LEN < (4096 * 1024), 0); if (i != BZ_OK) { - printf ("BUNZIP2 ERROR %d - must RESET board to recover\n", i); + printf ("BUNZIP2: uncompress or overwrite error %d " + "- must RESET board to recover\n", i); show_boot_progress (-6); do_reset (cmdtp, flag, argc, argv); } + + load_end = load_start + unc_len; break; #endif /* CONFIG_BZIP2 */ default: if (iflag) enable_interrupts(); - printf ("Unimplemented compression type %d\n", hdr->ih_comp); + printf ("Unimplemented compression type %d\n", comp); show_boot_progress (-7); return 1; } puts ("OK\n"); + debug (" kernel loaded at 0x%08lx, end = 0x%08lx\n", load_start, load_end); show_boot_progress (7); - switch (hdr->ih_type) { - case IH_TYPE_STANDALONE: - if (iflag) - enable_interrupts(); + if ((load_start < image_end) && (load_end > image_start)) { + debug ("image_start = 0x%lX, image_end = 0x%lx\n", image_start, image_end); + debug ("load_start = 0x%lx, load_end = 0x%lx\n", load_start, load_end); - /* load (and uncompress), but don't start if "autostart" - * is set to "no" - */ - if (((s = getenv("autostart")) != NULL) && (strcmp(s,"no") == 0)) { - char buf[32]; - sprintf(buf, "%lX", len); - setenv("filesize", buf); - return 0; - } - appl = (int (*)(int, char *[]))ntohl(hdr->ih_ep); - (*appl)(argc-1, &argv[1]); - return 0; - case IH_TYPE_KERNEL: - case IH_TYPE_MULTI: - /* handled below */ - break; - default: - if (iflag) - enable_interrupts(); - printf ("Can't boot image type %d\n", hdr->ih_type); - show_boot_progress (-8); - return 1; + puts ("ERROR: image overwritten - must RESET the board to recover.\n"); + show_boot_progress (-113); + do_reset (cmdtp, flag, argc, argv); } + show_boot_progress (8); - switch (hdr->ih_os) { + lmb_reserve(&lmb, load_start, (load_end - load_start)); + + switch (os) { default: /* handled by (original) Linux case */ case IH_OS_LINUX: #ifdef CONFIG_SILENT_CONSOLE fixup_silent_linux(); #endif - do_bootm_linux (cmdtp, flag, argc, argv, - addr, len_ptr, verify); + do_bootm_linux (cmdtp, flag, argc, argv, &images); break; + case IH_OS_NETBSD: - do_bootm_netbsd (cmdtp, flag, argc, argv, - addr, len_ptr, verify); + do_bootm_netbsd (cmdtp, flag, argc, argv, &images); break; #ifdef CONFIG_LYNXKDI case IH_OS_LYNXOS: - do_bootm_lynxkdi (cmdtp, flag, argc, argv, - addr, len_ptr, verify); + do_bootm_lynxkdi (cmdtp, flag, argc, argv, &images); break; #endif case IH_OS_RTEMS: - do_bootm_rtems (cmdtp, flag, argc, argv, - addr, len_ptr, verify); + do_bootm_rtems (cmdtp, flag, argc, argv, &images); break; #if defined(CONFIG_CMD_ELF) case IH_OS_VXWORKS: - do_bootm_vxworks (cmdtp, flag, argc, argv, - addr, len_ptr, verify); + do_bootm_vxworks (cmdtp, flag, argc, argv, &images); break; + case IH_OS_QNX: - do_bootm_qnxelf (cmdtp, flag, argc, argv, - addr, len_ptr, verify); + do_bootm_qnxelf (cmdtp, flag, argc, argv, &images); break; #endif + #ifdef CONFIG_ARTOS case IH_OS_ARTOS: - do_bootm_artos (cmdtp, flag, argc, argv, - addr, len_ptr, verify); + do_bootm_artos (cmdtp, flag, argc, argv, &images); break; #endif } @@ -455,29 +338,493 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) show_boot_progress (-9); #ifdef DEBUG puts ("\n## Control returned to monitor - resetting...\n"); - do_reset (cmdtp, flag, argc, argv); + if (images.autostart) + do_reset (cmdtp, flag, argc, argv); #endif + if (!images.autostart && iflag) + enable_interrupts(); + return 1; } +/** + * image_get_kernel - verify legacy format kernel image + * @img_addr: in RAM address of the legacy format image to be verified + * @verify: data CRC verification flag + * + * image_get_kernel() verifies legacy image integrity and returns pointer to + * legacy image header if image verification was completed successfully. + * + * returns: + * pointer to a legacy image header if valid image was found + * otherwise return NULL + */ +static image_header_t *image_get_kernel (ulong img_addr, int verify) +{ + image_header_t *hdr = (image_header_t *)img_addr; + + if (!image_check_magic(hdr)) { + puts ("Bad Magic Number\n"); + show_boot_progress (-1); + return NULL; + } + show_boot_progress (2); + + if (!image_check_hcrc (hdr)) { + puts ("Bad Header Checksum\n"); + show_boot_progress (-2); + return NULL; + } + + show_boot_progress (3); + image_print_contents (hdr); + + if (verify) { + puts (" Verifying Checksum ... "); + if (!image_check_dcrc (hdr)) { + printf ("Bad Data CRC\n"); + show_boot_progress (-3); + return NULL; + } + puts ("OK\n"); + } + show_boot_progress (4); + + if (!image_check_target_arch (hdr)) { + printf ("Unsupported Architecture 0x%x\n", image_get_arch (hdr)); + show_boot_progress (-4); + return NULL; + } + return hdr; +} + +/** + * fit_check_kernel - verify FIT format kernel subimage + * @fit_hdr: pointer to the FIT image header + * os_noffset: kernel subimage node offset within FIT image + * @verify: data CRC verification flag + * + * fit_check_kernel() verifies integrity of the kernel subimage and from + * specified FIT image. + * + * returns: + * 1, on success + * 0, on failure + */ +#if defined (CONFIG_FIT) +static int fit_check_kernel (const void *fit, int os_noffset, int verify) +{ + fit_image_print (fit, os_noffset, " "); + + if (verify) { + puts (" Verifying Hash Integrity ... "); + if (!fit_image_check_hashes (fit, os_noffset)) { + puts ("Bad Data Hash\n"); + show_boot_progress (-104); + return 0; + } + puts ("OK\n"); + } + show_boot_progress (105); + +#ifdef CONFIG_LOGBUFFER +#ifndef CONFIG_ALT_LB_ADDR + kbd=gd->bd; + /* Prevent initrd from overwriting logbuffer */ + if (initrd_high < (kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD)) + initrd_high = kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD; + debug ("## Logbuffer at 0x%08lX ", kbd->bi_memsize-LOGBUFF_LEN); +#else + debug ("## Logbuffer at 0x%08lX ", CONFIG_ALT_LB_ADDR); +#endif +#endif + if (!fit_image_check_target_arch (fit, os_noffset)) { + puts ("Unsupported Architecture\n"); + show_boot_progress (-105); + return 0; + } + + show_boot_progress (106); + if (!fit_image_check_type (fit, os_noffset, IH_TYPE_KERNEL)) { + puts ("Not a kernel image\n"); + show_boot_progress (-106); + return 0; + } + + show_boot_progress (107); + return 1; +} +#endif /* CONFIG_FIT */ + +/** + * boot_get_kernel - find kernel image + * @os_data: pointer to a ulong variable, will hold os data start address + * @os_len: pointer to a ulong variable, will hold os data length + * + * boot_get_kernel() tries to find a kernel image, verifies its integrity + * and locates kernel data. + * + * returns: + * pointer to image header if valid image was found, plus kernel start + * address and length, otherwise NULL + */ +static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + bootm_headers_t *images, ulong *os_data, ulong *os_len) +{ + image_header_t *hdr; + ulong img_addr; +#if defined(CONFIG_FIT) + void *fit_hdr; + const char *fit_uname_config = NULL; + const char *fit_uname_kernel = NULL; + const void *data; + size_t len; + int cfg_noffset; + int os_noffset; +#endif + + /* find out kernel image address */ + if (argc < 2) { + img_addr = load_addr; + debug ("* kernel: default image load address = 0x%08lx\n", + load_addr); +#if defined(CONFIG_FIT) + } else if (fit_parse_conf (argv[1], load_addr, &img_addr, + &fit_uname_config)) { + debug ("* kernel: config '%s' from image at 0x%08lx\n", + fit_uname_config, img_addr); + } else if (fit_parse_subimage (argv[1], load_addr, &img_addr, + &fit_uname_kernel)) { + debug ("* kernel: subimage '%s' from image at 0x%08lx\n", + fit_uname_kernel, img_addr); +#endif + } else { + img_addr = simple_strtoul(argv[1], NULL, 16); + debug ("* kernel: cmdline image address = 0x%08lx\n", img_addr); + } + + show_boot_progress (1); + + /* copy from dataflash if needed */ + img_addr = genimg_get_image (img_addr); + + /* check image type, for FIT images get FIT kernel node */ + *os_data = *os_len = 0; + switch (genimg_get_format ((void *)img_addr)) { + case IMAGE_FORMAT_LEGACY: + printf ("## Booting kernel from Legacy Image at %08lx ...\n", + img_addr); + hdr = image_get_kernel (img_addr, images->verify); + if (!hdr) + return NULL; + show_boot_progress (5); + + /* get os_data and os_len */ + switch (image_get_type (hdr)) { + case IH_TYPE_KERNEL: + *os_data = image_get_data (hdr); + *os_len = image_get_data_size (hdr); + break; + case IH_TYPE_MULTI: + image_multi_getimg (hdr, 0, os_data, os_len); + break; + default: + printf ("Wrong Image Type for %s command\n", cmdtp->name); + show_boot_progress (-5); + return NULL; + } + images->legacy_hdr_os = hdr; + images->legacy_hdr_valid = 1; + + show_boot_progress (6); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (void *)img_addr; + printf ("## Booting kernel from FIT Image at %08lx ...\n", + img_addr); + + if (!fit_check_format (fit_hdr)) { + puts ("Bad FIT kernel image format!\n"); + show_boot_progress (-100); + return NULL; + } + show_boot_progress (100); + + if (!fit_uname_kernel) { + /* + * no kernel image node unit name, try to get config + * node first. If config unit node name is NULL + * fit_conf_get_node() will try to find default config node + */ + show_boot_progress (101); + cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); + if (cfg_noffset < 0) { + show_boot_progress (-101); + return NULL; + } + /* save configuration uname provided in the first + * bootm argument + */ + images->fit_uname_cfg = fdt_get_name (fit_hdr, cfg_noffset, NULL); + printf (" Using '%s' configuration\n", images->fit_uname_cfg); + show_boot_progress (103); + + os_noffset = fit_conf_get_kernel_node (fit_hdr, cfg_noffset); + fit_uname_kernel = fit_get_name (fit_hdr, os_noffset, NULL); + } else { + /* get kernel component image node offset */ + show_boot_progress (102); + os_noffset = fit_image_get_node (fit_hdr, fit_uname_kernel); + } + if (os_noffset < 0) { + show_boot_progress (-103); + return NULL; + } + + printf (" Trying '%s' kernel subimage\n", fit_uname_kernel); + + show_boot_progress (104); + if (!fit_check_kernel (fit_hdr, os_noffset, images->verify)) + return NULL; + + /* get kernel image data address and length */ + if (fit_image_get_data (fit_hdr, os_noffset, &data, &len)) { + puts ("Could not find kernel subimage data!\n"); + show_boot_progress (-107); + return NULL; + } + show_boot_progress (108); + + *os_len = len; + *os_data = (ulong)data; + images->fit_hdr_os = fit_hdr; + images->fit_uname_os = fit_uname_kernel; + images->fit_noffset_os = os_noffset; + break; +#endif + default: + printf ("Wrong Image Format for %s command\n", cmdtp->name); + show_boot_progress (-108); + return NULL; + } + + debug (" kernel data at 0x%08lx, len = 0x%08lx (%d)\n", + *os_data, *os_len, *os_len); + + return (void *)img_addr; +} + U_BOOT_CMD( - bootm, CFG_MAXARGS, 1, do_bootm, - "bootm - boot application image from memory\n", - "[addr [arg ...]]\n - boot application image stored in memory\n" - "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n" - "\t'arg' can be the address of an initrd image\n" -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) + bootm, CFG_MAXARGS, 1, do_bootm, + "bootm - boot application image from memory\n", + "[addr [arg ...]]\n - boot application image stored in memory\n" + "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n" + "\t'arg' can be the address of an initrd image\n" +#if defined(CONFIG_OF_LIBFDT) "\tWhen booting a Linux kernel which requires a flat device-tree\n" "\ta third argument is required which is the address of the\n" "\tdevice-tree blob. To boot that kernel without an initrd image,\n" "\tuse a '-' for the second argument. If you do not pass a third\n" "\ta bd_info struct will be passed instead\n" #endif +#if defined(CONFIG_FIT) + "\t\nFor the new multi component uImage format (FIT) addresses\n" + "\tmust be extened to include component or configuration unit name:\n" + "\taddr: - direct component image specification\n" + "\taddr# - configuration specification\n" + "\tUse iminfo command to get the list of existing component\n" + "\timages and configurations.\n" +#endif ); +/*******************************************************************/ +/* bootd - boot default image */ +/*******************************************************************/ +#if defined(CONFIG_CMD_BOOTD) +int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int rcode = 0; + +#ifndef CFG_HUSH_PARSER + if (run_command (getenv ("bootcmd"), flag) < 0) + rcode = 1; +#else + if (parse_string_outer (getenv ("bootcmd"), + FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0) + rcode = 1; +#endif + return rcode; +} + +U_BOOT_CMD( + boot, 1, 1, do_bootd, + "boot - boot default, i.e., run 'bootcmd'\n", + NULL +); + +/* keep old command name "bootd" for backward compatibility */ +U_BOOT_CMD( + bootd, 1, 1, do_bootd, + "bootd - boot default, i.e., run 'bootcmd'\n", + NULL +); + +#endif + + +/*******************************************************************/ +/* iminfo - print header info for a requested image */ +/*******************************************************************/ +#if defined(CONFIG_CMD_IMI) +int do_iminfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int arg; + ulong addr; + int rcode = 0; + + if (argc < 2) { + return image_info (load_addr); + } + + for (arg = 1; arg < argc; ++arg) { + addr = simple_strtoul (argv[arg], NULL, 16); + if (image_info (addr) != 0) + rcode = 1; + } + return rcode; +} + +static int image_info (ulong addr) +{ + void *hdr = (void *)addr; + + printf ("\n## Checking Image at %08lx ...\n", addr); + + switch (genimg_get_format (hdr)) { + case IMAGE_FORMAT_LEGACY: + puts (" Legacy image found\n"); + if (!image_check_magic (hdr)) { + puts (" Bad Magic Number\n"); + return 1; + } + + if (!image_check_hcrc (hdr)) { + puts (" Bad Header Checksum\n"); + return 1; + } + + image_print_contents (hdr); + + puts (" Verifying Checksum ... "); + if (!image_check_dcrc (hdr)) { + puts (" Bad Data CRC\n"); + return 1; + } + puts ("OK\n"); + return 0; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + puts (" FIT image found\n"); + + if (!fit_check_format (hdr)) { + puts ("Bad FIT image format!\n"); + return 1; + } + + fit_print_contents (hdr); + return 0; +#endif + default: + puts ("Unknown image format!\n"); + break; + } + + return 1; +} + +U_BOOT_CMD( + iminfo, CFG_MAXARGS, 1, do_iminfo, + "iminfo - print header information for application image\n", + "addr [addr ...]\n" + " - print header information for application image starting at\n" + " address 'addr' in memory; this includes verification of the\n" + " image contents (magic number, header and payload checksums)\n" +); +#endif + + +/*******************************************************************/ +/* imls - list all images found in flash */ +/*******************************************************************/ +#if defined(CONFIG_CMD_IMLS) +int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + flash_info_t *info; + int i, j; + void *hdr; + + for (i = 0, info = &flash_info[0]; + i < CFG_MAX_FLASH_BANKS; ++i, ++info) { + + if (info->flash_id == FLASH_UNKNOWN) + goto next_bank; + for (j = 0; j < info->sector_count; ++j) { + + hdr = (void *)info->start[j]; + if (!hdr) + goto next_sector; + + switch (genimg_get_format (hdr)) { + case IMAGE_FORMAT_LEGACY: + if (!image_check_hcrc (hdr)) + goto next_sector; + + printf ("Legacy Image at %08lX:\n", (ulong)hdr); + image_print_contents (hdr); + + puts (" Verifying Checksum ... "); + if (!image_check_dcrc (hdr)) { + puts ("Bad Data CRC\n"); + } else { + puts ("OK\n"); + } + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + if (!fit_check_format (hdr)) + goto next_sector; + + printf ("FIT Image at %08lX:\n", (ulong)hdr); + fit_print_contents (hdr); + break; +#endif + default: + goto next_sector; + } + +next_sector: ; + } +next_bank: ; + } + + return (0); +} + +U_BOOT_CMD( + imls, 1, 1, do_imls, + "imls - list all images found in flash\n", + "\n" + " - Prints information about all images found at sector\n" + " boundaries in flash.\n" +); +#endif + +/*******************************************************************/ +/* helper routines */ +/*******************************************************************/ #ifdef CONFIG_SILENT_CONSOLE -static void -fixup_silent_linux () +static void fixup_silent_linux () { char buf[256], *start, *end; char *cmdline = getenv ("bootargs"); @@ -508,586 +855,28 @@ fixup_silent_linux () } #endif /* CONFIG_SILENT_CONSOLE */ -#ifdef CONFIG_PPC -static void __attribute__((noinline)) -do_bootm_linux (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong addr, - ulong *len_ptr, - int verify) + +/*******************************************************************/ +/* OS booting routines */ +/*******************************************************************/ + +static void do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + bootm_headers_t *images) { - ulong sp; - ulong len, checksum; - ulong initrd_start, initrd_end; - ulong cmd_start, cmd_end; - ulong initrd_high; - ulong data; - int initrd_copy_to_ram = 1; - char *cmdline; - char *s; - bd_t *kbd; - void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); - image_header_t *hdr = &header; -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) - char *of_flat_tree = NULL; - ulong of_data = 0; -#endif + void (*loader)(bd_t *, image_header_t *, char *, char *); + image_header_t *os_hdr, *hdr; + ulong kernel_data, kernel_len; + char *consdev; + char *cmdline; - if ((s = getenv ("initrd_high")) != NULL) { - /* a value of "no" or a similar string will act like 0, - * turning the "load high" feature off. This is intentional. - */ - initrd_high = simple_strtoul(s, NULL, 16); - if (initrd_high == ~0) - initrd_copy_to_ram = 0; - } else { /* not set, no restrictions to load high */ - initrd_high = ~0; - } - -#ifdef CONFIG_LOGBUFFER -#ifndef CONFIG_ALT_LB_ADDR - kbd=gd->bd; - /* Prevent initrd from overwriting logbuffer */ - if (initrd_high < (kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD)) - initrd_high = kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD; - debug ("## Logbuffer at 0x%08lX ", kbd->bi_memsize-LOGBUFF_LEN); -#else - debug ("## Logbuffer at 0x%08lX ", CONFIG_ALT_LB_ADDR); -#endif -#endif - - /* - * Booting a (Linux) kernel image - * - * Allocate space for command line and board info - the - * address should be as high as possible within the reach of - * the kernel (see CFG_BOOTMAPSZ settings), but in unused - * memory, which means far enough below the current stack - * pointer. - */ - - asm( "mr %0,1": "=r"(sp) : ); - - debug ("## Current stack ends at 0x%08lX ", sp); - - sp -= 2048; /* just to be sure */ - if (sp > CFG_BOOTMAPSZ) - sp = CFG_BOOTMAPSZ; - sp &= ~0xF; - - debug ("=> set upper limit to 0x%08lX\n", sp); - - cmdline = (char *)((sp - CFG_BARGSIZE) & ~0xF); - kbd = (bd_t *)(((ulong)cmdline - sizeof(bd_t)) & ~0xF); - - if ((s = getenv("bootargs")) == NULL) - s = ""; - - strcpy (cmdline, s); - - cmd_start = (ulong)&cmdline[0]; - cmd_end = cmd_start + strlen(cmdline); - - *kbd = *(gd->bd); - -#ifdef DEBUG - printf ("## cmdline at 0x%08lX ... 0x%08lX\n", cmd_start, cmd_end); - - do_bdinfo (NULL, 0, 0, NULL); -#endif - - if ((s = getenv ("clocks_in_mhz")) != NULL) { - /* convert all clock information to MHz */ - kbd->bi_intfreq /= 1000000L; - kbd->bi_busfreq /= 1000000L; -#if defined(CONFIG_MPC8220) - kbd->bi_inpfreq /= 1000000L; - kbd->bi_pcifreq /= 1000000L; - kbd->bi_pevfreq /= 1000000L; - kbd->bi_flbfreq /= 1000000L; - kbd->bi_vcofreq /= 1000000L; -#endif -#if defined(CONFIG_CPM2) - kbd->bi_cpmfreq /= 1000000L; - kbd->bi_brgfreq /= 1000000L; - kbd->bi_sccfreq /= 1000000L; - kbd->bi_vco /= 1000000L; -#endif -#if defined(CONFIG_MPC5xxx) - kbd->bi_ipbfreq /= 1000000L; - kbd->bi_pcifreq /= 1000000L; -#endif /* CONFIG_MPC5xxx */ - } - - kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong)) ntohl(hdr->ih_ep); - - /* - * Check if there is an initrd image - */ - -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) - /* Look for a '-' which indicates to ignore the ramdisk argument */ - if (argc >= 3 && strcmp(argv[2], "-") == 0) { - debug ("Skipping initrd\n"); - len = data = 0; - } - else -#endif - if (argc >= 3) { - debug ("Not skipping initrd\n"); - show_boot_progress (9); - - addr = simple_strtoul(argv[2], NULL, 16); - - printf ("## Loading RAMDisk Image at %08lx ...\n", addr); - - /* Copy header so we can blank CRC field for re-calculation */ - memmove (&header, (char *)addr, sizeof(image_header_t)); - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - puts ("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset (cmdtp, flag, argc, argv); - } - - data = (ulong)&header; - len = sizeof(image_header_t); - - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)data, len) != checksum) { - puts ("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset (cmdtp, flag, argc, argv); - } - - show_boot_progress (10); - - print_image_hdr (hdr); - - data = addr + sizeof(image_header_t); - len = ntohl(hdr->ih_size); - - if (verify) { - ulong csum = 0; -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - ulong cdata = data, edata = cdata + len; -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ - - puts (" Verifying Checksum ... "); - -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - - while (cdata < edata) { - ulong chunk = edata - cdata; - - if (chunk > CHUNKSZ) - chunk = CHUNKSZ; - csum = crc32 (csum, (uchar *)cdata, chunk); - cdata += chunk; - - WATCHDOG_RESET(); - } -#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ - csum = crc32 (0, (uchar *)data, len); -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ - - if (csum != ntohl(hdr->ih_dcrc)) { - puts ("Bad Data CRC\n"); - show_boot_progress (-12); - do_reset (cmdtp, flag, argc, argv); - } - puts ("OK\n"); - } - - show_boot_progress (11); - - if ((hdr->ih_os != IH_OS_LINUX) || - (hdr->ih_arch != IH_CPU_PPC) || - (hdr->ih_type != IH_TYPE_RAMDISK) ) { - puts ("No Linux PPC Ramdisk Image\n"); - show_boot_progress (-13); - do_reset (cmdtp, flag, argc, argv); - } - - /* - * Now check if we have a multifile image - */ - } else if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1])) { - u_long tail = ntohl(len_ptr[0]) % 4; - int i; - - show_boot_progress (13); - - /* skip kernel length and terminator */ - data = (ulong)(&len_ptr[2]); - /* skip any additional image length fields */ - for (i=1; len_ptr[i]; ++i) - data += 4; - /* add kernel length, and align */ - data += ntohl(len_ptr[0]); - if (tail) { - data += 4 - tail; - } - - len = ntohl(len_ptr[1]); - - } else { - /* - * no initrd image - */ - show_boot_progress (14); - - len = data = 0; - } - -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) - if(argc > 3) { - of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16); - hdr = (image_header_t *)of_flat_tree; -#if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree + sizeof(image_header_t))) != OF_DT_HEADER) { -#else - if (fdt_check_header(of_flat_tree + sizeof(image_header_t)) != 0) { -#endif -#ifndef CFG_NO_FLASH - if (addr2info((ulong)of_flat_tree) != NULL) - of_data = (ulong)of_flat_tree; -#endif - } else if (ntohl(hdr->ih_magic) == IH_MAGIC) { - printf("## Flat Device Tree at %08lX\n", hdr); - print_image_hdr(hdr); - - if ((ntohl(hdr->ih_load) < ((unsigned long)hdr + ntohl(hdr->ih_size) + sizeof(hdr))) && - ((ntohl(hdr->ih_load) + ntohl(hdr->ih_size)) > (unsigned long)hdr)) { - puts ("ERROR: fdt overwritten - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - - puts (" Verifying Checksum ... "); - memmove (&header, (char *)hdr, sizeof(image_header_t)); - checksum = ntohl(header.ih_hcrc); - header.ih_hcrc = 0; - - if(checksum != crc32(0, (uchar *)&header, sizeof(image_header_t))) { - puts ("ERROR: fdt header checksum invalid - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - - checksum = ntohl(hdr->ih_dcrc); - addr = (ulong)((uchar *)(hdr) + sizeof(image_header_t)); - - if(checksum != crc32(0, (uchar *)addr, ntohl(hdr->ih_size))) { - puts ("ERROR: fdt checksum invalid - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - puts ("OK\n"); - - if (ntohl(hdr->ih_type) != IH_TYPE_FLATDT) { - puts ("ERROR: uImage is not a fdt - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - if (ntohl(hdr->ih_comp) != IH_COMP_NONE) { - puts ("ERROR: uImage is compressed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } -#if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree + sizeof(image_header_t))) != OF_DT_HEADER) { -#else - if (fdt_check_header(of_flat_tree + sizeof(image_header_t)) != 0) { -#endif - puts ("ERROR: uImage data is not a fdt - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - - memmove((void *)ntohl(hdr->ih_load), - (void *)(of_flat_tree + sizeof(image_header_t)), - ntohl(hdr->ih_size)); - of_flat_tree = (char *)ntohl(hdr->ih_load); - } else { - puts ("Did not find a flat Flat Device Tree.\n" - "Must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - printf (" Booting using the fdt at 0x%x\n", - of_flat_tree); - } else if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1]) && (len_ptr[2])) { - u_long tail = ntohl(len_ptr[0]) % 4; - int i; - - /* skip kernel length, initrd length, and terminator */ - of_flat_tree = (char *)(&len_ptr[3]); - /* skip any additional image length fields */ - for (i=2; len_ptr[i]; ++i) - of_flat_tree += 4; - /* add kernel length, and align */ - of_flat_tree += ntohl(len_ptr[0]); - if (tail) { - of_flat_tree += 4 - tail; - } - - /* add initrd length, and align */ - tail = ntohl(len_ptr[1]) % 4; - of_flat_tree += ntohl(len_ptr[1]); - if (tail) { - of_flat_tree += 4 - tail; - } - -#ifndef CFG_NO_FLASH - /* move the blob if it is in flash (set of_data to !null) */ - if (addr2info ((ulong)of_flat_tree) != NULL) - of_data = (ulong)of_flat_tree; -#endif - - -#if defined(CONFIG_OF_FLAT_TREE) - if (*((ulong *)(of_flat_tree)) != OF_DT_HEADER) { -#else - if (fdt_check_header (of_flat_tree) != 0) { -#endif - puts ("ERROR: image is not a fdt - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - -#if defined(CONFIG_OF_FLAT_TREE) - if (((struct boot_param_header *)of_flat_tree)->totalsize != - ntohl (len_ptr[2])) { -#else - if (be32_to_cpu (fdt_totalsize (of_flat_tree)) != - ntohl(len_ptr[2])) { -#endif - puts ("ERROR: fdt size != image size - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } +#if defined(CONFIG_FIT) + if (!images->legacy_hdr_valid) { + fit_unsupported_reset ("NetBSD"); + do_reset (cmdtp, flag, argc, argv); } #endif - if (!data) { - debug ("No initrd\n"); - } - - if (data) { - if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ - initrd_start = data; - initrd_end = initrd_start + len; - } else { - initrd_start = (ulong)kbd - len; - initrd_start &= ~(4096 - 1); /* align on page */ - - if (initrd_high) { - ulong nsp; - - /* - * the inital ramdisk does not need to be within - * CFG_BOOTMAPSZ as it is not accessed until after - * the mm system is initialised. - * - * do the stack bottom calculation again and see if - * the initrd will fit just below the monitor stack - * bottom without overwriting the area allocated - * above for command line args and board info. - */ - asm( "mr %0,1": "=r"(nsp) : ); - nsp -= 2048; /* just to be sure */ - nsp &= ~0xF; - if (nsp > initrd_high) /* limit as specified */ - nsp = initrd_high; - nsp -= len; - nsp &= ~(4096 - 1); /* align on page */ - if (nsp >= sp) - initrd_start = nsp; - } - - show_boot_progress (12); - - debug ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - data, data + len - 1, len, len); - - initrd_end = initrd_start + len; - printf (" Loading Ramdisk to %08lx, end %08lx ... ", - initrd_start, initrd_end); -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - { - size_t l = len; - void *to = (void *)initrd_start; - void *from = (void *)data; - - while (l > 0) { - size_t tail = (l > CHUNKSZ) ? CHUNKSZ : l; - WATCHDOG_RESET(); - memmove (to, from, tail); - to += tail; - from += tail; - l -= tail; - } - } -#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ - memmove ((void *)initrd_start, (void *)data, len); -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ - puts ("OK\n"); - } - } else { - initrd_start = 0; - initrd_end = 0; - } - -#if defined(CONFIG_OF_LIBFDT) - -#ifdef CFG_BOOTMAPSZ - /* - * The blob must be within CFG_BOOTMAPSZ, - * so we flag it to be copied if it is not. - */ - if (of_flat_tree >= (char *)CFG_BOOTMAPSZ) - of_data = (ulong)of_flat_tree; -#endif - - /* move of_flat_tree if needed */ - if (of_data) { - int err; - ulong of_start, of_len; - - of_len = be32_to_cpu(fdt_totalsize(of_data)); - - /* position on a 4K boundary before the kbd */ - of_start = (ulong)kbd - of_len; - of_start &= ~(4096 - 1); /* align on page */ - debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - of_data, of_data + of_len - 1, of_len, of_len); - - of_flat_tree = (char *)of_start; - printf (" Loading Device Tree to %08lx, end %08lx ... ", - of_start, of_start + of_len - 1); - err = fdt_open_into((void *)of_data, (void *)of_start, of_len); - if (err != 0) { - puts ("ERROR: fdt move failed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } - puts ("OK\n"); - } - /* - * Add the chosen node if it doesn't exist, add the env and bd_t - * if the user wants it (the logic is in the subroutines). - */ - if (of_flat_tree) { - if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { - puts ("ERROR: /chosen node create failed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } -#ifdef CONFIG_OF_HAS_UBOOT_ENV - if (fdt_env(of_flat_tree) < 0) { - puts ("ERROR: /u-boot-env node create failed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } -#endif -#ifdef CONFIG_OF_HAS_BD_T - if (fdt_bd_t(of_flat_tree) < 0) { - puts ("ERROR: /bd_t node create failed - " - "must RESET the board to recover.\n"); - do_reset (cmdtp, flag, argc, argv); - } -#endif -#ifdef CONFIG_OF_BOARD_SETUP - /* Call the board-specific fixup routine */ - ft_board_setup(of_flat_tree, gd->bd); -#endif - } -#endif /* CONFIG_OF_LIBFDT */ -#if defined(CONFIG_OF_FLAT_TREE) -#ifdef CFG_BOOTMAPSZ - /* - * The blob must be within CFG_BOOTMAPSZ, - * so we flag it to be copied if it is not. - */ - if (of_flat_tree >= (char *)CFG_BOOTMAPSZ) - of_data = (ulong)of_flat_tree; -#endif - - /* move of_flat_tree if needed */ - if (of_data) { - ulong of_start, of_len; - of_len = ((struct boot_param_header *)of_data)->totalsize; - - /* provide extra 8k pad */ - of_start = (ulong)kbd - of_len - 8192; - of_start &= ~(4096 - 1); /* align on page */ - debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - of_data, of_data + of_len - 1, of_len, of_len); - - of_flat_tree = (char *)of_start; - printf (" Loading Device Tree to %08lx, end %08lx ... ", - of_start, of_start + of_len - 1); - memmove ((void *)of_start, (void *)of_data, of_len); - puts ("OK\n"); - } - /* - * Create the /chosen node and modify the blob with board specific - * values as needed. - */ - ft_setup(of_flat_tree, kbd, initrd_start, initrd_end); - /* ft_dump_blob(of_flat_tree); */ -#endif - debug ("## Transferring control to Linux (at address %08lx) ...\n", - (ulong)kernel); - - show_boot_progress (15); - -#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500) - unlock_ram_in_cache(); -#endif - -#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) - if (of_flat_tree) { /* device tree; boot new style */ - /* - * Linux Kernel Parameters (passing device tree): - * r3: pointer to the fdt, followed by the board info data - * r4: physical pointer to the kernel itself - * r5: NULL - * r6: NULL - * r7: NULL - */ - (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0); - /* does not return */ - } -#endif - /* - * Linux Kernel Parameters (passing board info data): - * r3: ptr to board info data - * r4: initrd_start or 0 if no initrd - * r5: initrd_end - unused if r4 is 0 - * r6: Start of command line string - * r7: End of command line string - */ - (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); - /* does not return */ -} -#endif /* CONFIG_PPC */ - -static void -do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong addr, - ulong *len_ptr, - int verify) -{ - image_header_t *hdr = &header; - - void (*loader)(bd_t *, image_header_t *, char *, char *); - image_header_t *img_addr; - char *consdev; - char *cmdline; - + hdr = images->legacy_hdr_os; /* * Booting a (NetBSD) kernel image @@ -1100,11 +889,12 @@ do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, * line, the name of the console device, and (optionally) the * address of the original image header. */ - - img_addr = 0; - if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1])) - img_addr = (image_header_t *) addr; - + os_hdr = NULL; + if (image_check_type (hdr, IH_TYPE_MULTI)) { + image_multi_getimg (hdr, 1, &kernel_data, &kernel_len); + if (kernel_len) + os_hdr = hdr; + } consdev = ""; #if defined (CONFIG_8xx_CONS_SMC1) @@ -1121,21 +911,21 @@ do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, ulong len; int i; - for (i=2, len=0 ; i 2) cmdline[len++] = ' '; strcpy (&cmdline[len], argv[i]); len += strlen (argv[i]); } - } else if ((cmdline = getenv("bootargs")) == NULL) { + } else if ((cmdline = getenv ("bootargs")) == NULL) { cmdline = ""; } - loader = (void (*)(bd_t *, image_header_t *, char *, char *)) ntohl(hdr->ih_ep); + loader = (void (*)(bd_t *, image_header_t *, char *, char *))image_get_ep (hdr); printf ("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n", (ulong)loader); @@ -1149,20 +939,101 @@ do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag, * r5: console device * r6: boot args string */ - (*loader) (gd->bd, img_addr, consdev, cmdline); + (*loader) (gd->bd, os_hdr, consdev, cmdline); } +#ifdef CONFIG_LYNXKDI +static void do_bootm_lynxkdi (cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + bootm_headers_t *images) +{ + image_header_t *hdr = images->legacy_hdr_os; + +#if defined(CONFIG_FIT) + if (!images->legacy_hdr_valid) { + fit_unsupported_reset ("Lynx"); + do_reset (cmdtp, flag, argc, argv); + } +#endif + + lynxkdi_boot ((image_header_t *)hdr); +} +#endif /* CONFIG_LYNXKDI */ + +static void do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + bootm_headers_t *images) +{ + image_header_t *hdr = images->legacy_hdr_os; + void (*entry_point)(bd_t *); + +#if defined(CONFIG_FIT) + if (!images->legacy_hdr_valid) { + fit_unsupported_reset ("RTEMS"); + do_reset (cmdtp, flag, argc, argv); + } +#endif + + entry_point = (void (*)(bd_t *))image_get_ep (hdr); + + printf ("## Transferring control to RTEMS (at address %08lx) ...\n", + (ulong)entry_point); + + show_boot_progress (15); + + /* + * RTEMS Parameters: + * r3: ptr to board info data + */ + (*entry_point)(gd->bd); +} + +#if defined(CONFIG_CMD_ELF) +static void do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + bootm_headers_t *images) +{ + char str[80]; + image_header_t *hdr = images->legacy_hdr_os; + +#if defined(CONFIG_FIT) + if (hdr == NULL) { + fit_unsupported_reset ("VxWorks"); + do_reset (cmdtp, flag, argc, argv); + } +#endif + + sprintf(str, "%x", image_get_ep (hdr)); /* write entry-point into string */ + setenv("loadaddr", str); + do_bootvx(cmdtp, 0, 0, NULL); +} + +static void do_bootm_qnxelf(cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + bootm_headers_t *images) +{ + char *local_args[2]; + char str[16]; + image_header_t *hdr = images->legacy_hdr_os; + +#if defined(CONFIG_FIT) + if (!images->legacy_hdr_valid) { + fit_unsupported_reset ("QNX"); + do_reset (cmdtp, flag, argc, argv); + } +#endif + + sprintf(str, "%x", image_get_ep (hdr)); /* write entry-point into string */ + local_args[0] = argv[0]; + local_args[1] = str; /* and provide it via the arguments */ + do_bootelf(cmdtp, 0, 2, local_args); +} +#endif + #if defined(CONFIG_ARTOS) && defined(CONFIG_PPC) - -/* Function that returns a character from the environment */ -extern uchar (*env_get_char)(int); - -static void -do_bootm_artos (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong addr, - ulong *len_ptr, - int verify) +static void do_bootm_artos (cmd_tbl_t *cmdtp, int flag, + int argc, char *argv[], + bootm_headers_t *images) { ulong top; char *s, *cmdline; @@ -1170,7 +1041,14 @@ do_bootm_artos (cmd_tbl_t *cmdtp, int flag, int i, j, nxt, len, envno, envsz; bd_t *kbd; void (*entry)(bd_t *bd, char *cmdline, char **fwenv, ulong top); - image_header_t *hdr = &header; + image_header_t *hdr = images->legacy_hdr_os; + +#if defined(CONFIG_FIT) + if (!images->legacy_hdr_valid) { + fit_unsupported_reset ("ARTOS"); + do_reset (cmdtp, flag, argc, argv); + } +#endif /* * Booting an ARTOS kernel image + application @@ -1191,27 +1069,27 @@ do_bootm_artos (cmd_tbl_t *cmdtp, int flag, debug ("=> set upper limit to 0x%08lX\n", top); /* first check the artos specific boot args, then the linux args*/ - if ((s = getenv("abootargs")) == NULL && (s = getenv("bootargs")) == NULL) + if ((s = getenv( "abootargs")) == NULL && (s = getenv ("bootargs")) == NULL) s = ""; /* get length of cmdline, and place it */ - len = strlen(s); + len = strlen (s); top = (top - (len + 1)) & ~0xF; cmdline = (char *)top; debug ("## cmdline at 0x%08lX ", top); - strcpy(cmdline, s); + strcpy (cmdline, s); /* copy bdinfo */ - top = (top - sizeof(bd_t)) & ~0xF; + top = (top - sizeof (bd_t)) & ~0xF; debug ("## bd at 0x%08lX ", top); kbd = (bd_t *)top; - memcpy(kbd, gd->bd, sizeof(bd_t)); + memcpy (kbd, gd->bd, sizeof (bd_t)); /* first find number of env entries, and their size */ envno = 0; envsz = 0; - for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { - for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) + for (i = 0; env_get_char (i) != '\0'; i = nxt + 1) { + for (nxt = i; env_get_char (nxt) != '\0'; ++nxt) ; envno++; envsz += (nxt - i) + 1; /* plus trailing zero */ @@ -1219,7 +1097,7 @@ do_bootm_artos (cmd_tbl_t *cmdtp, int flag, envno++; /* plus the terminating zero */ debug ("## %u envvars total size %u ", envno, envsz); - top = (top - sizeof(char **)*envno) & ~0xF; + top = (top - sizeof (char **) * envno) & ~0xF; fwenv = (char **)top; debug ("## fwenv at 0x%08lX ", top); @@ -1228,428 +1106,17 @@ do_bootm_artos (cmd_tbl_t *cmdtp, int flag, ss = fwenv; /* now copy them */ - for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { - for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) + for (i = 0; env_get_char (i) != '\0'; i = nxt + 1) { + for (nxt = i; env_get_char (nxt) != '\0'; ++nxt) ; *ss++ = s; for (j = i; j < nxt; ++j) - *s++ = env_get_char(j); + *s++ = env_get_char (j); *s++ = '\0'; } *ss++ = NULL; /* terminate */ - entry = (void (*)(bd_t *, char *, char **, ulong))ntohl(hdr->ih_ep); - (*entry)(kbd, cmdline, fwenv, top); + entry = (void (*)(bd_t *, char *, char **, ulong))image_get_ep (hdr); + (*entry) (kbd, cmdline, fwenv, top); } #endif - - -#if defined(CONFIG_CMD_BOOTD) -int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - int rcode = 0; -#ifndef CFG_HUSH_PARSER - if (run_command (getenv ("bootcmd"), flag) < 0) rcode = 1; -#else - if (parse_string_outer(getenv("bootcmd"), - FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0 ) rcode = 1; -#endif - return rcode; -} - -U_BOOT_CMD( - boot, 1, 1, do_bootd, - "boot - boot default, i.e., run 'bootcmd'\n", - NULL -); - -/* keep old command name "bootd" for backward compatibility */ -U_BOOT_CMD( - bootd, 1, 1, do_bootd, - "bootd - boot default, i.e., run 'bootcmd'\n", - NULL -); - -#endif - -#if defined(CONFIG_CMD_IMI) -int do_iminfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - int arg; - ulong addr; - int rcode=0; - - if (argc < 2) { - return image_info (load_addr); - } - - for (arg=1; arg ih_magic) != IH_MAGIC) { - puts (" Bad Magic Number\n"); - return 1; - } - - data = (ulong)&header; - len = sizeof(image_header_t); - - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)data, len) != checksum) { - puts (" Bad Header Checksum\n"); - return 1; - } - - /* for multi-file images we need the data part, too */ - print_image_hdr ((image_header_t *)addr); - - data = addr + sizeof(image_header_t); - len = ntohl(hdr->ih_size); - - puts (" Verifying Checksum ... "); - if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) { - puts (" Bad Data CRC\n"); - return 1; - } - puts ("OK\n"); - return 0; -} - -U_BOOT_CMD( - iminfo, CFG_MAXARGS, 1, do_iminfo, - "iminfo - print header information for application image\n", - "addr [addr ...]\n" - " - print header information for application image starting at\n" - " address 'addr' in memory; this includes verification of the\n" - " image contents (magic number, header and payload checksums)\n" -); - -#endif - -#if defined(CONFIG_CMD_IMLS) -/*----------------------------------------------------------------------- - * List all images found in flash. - */ -int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - flash_info_t *info; - int i, j; - image_header_t *hdr; - ulong data, len, checksum; - - for (i=0, info=&flash_info[0]; iflash_id == FLASH_UNKNOWN) - goto next_bank; - for (j=0; jsector_count; ++j) { - - if (!(hdr=(image_header_t *)info->start[j]) || - (ntohl(hdr->ih_magic) != IH_MAGIC)) - goto next_sector; - - /* Copy header so we can blank CRC field for re-calculation */ - memmove (&header, (char *)hdr, sizeof(image_header_t)); - - checksum = ntohl(header.ih_hcrc); - header.ih_hcrc = 0; - - if (crc32 (0, (uchar *)&header, sizeof(image_header_t)) - != checksum) - goto next_sector; - - printf ("Image at %08lX:\n", (ulong)hdr); - print_image_hdr( hdr ); - - data = (ulong)hdr + sizeof(image_header_t); - len = ntohl(hdr->ih_size); - - puts (" Verifying Checksum ... "); - if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) { - puts (" Bad Data CRC\n"); - } - puts ("OK\n"); -next_sector: ; - } -next_bank: ; - } - - return (0); -} - -U_BOOT_CMD( - imls, 1, 1, do_imls, - "imls - list all images found in flash\n", - "\n" - " - Prints information about all images found at sector\n" - " boundaries in flash.\n" -); -#endif - -void -print_image_hdr (image_header_t *hdr) -{ -#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) - time_t timestamp = (time_t)ntohl(hdr->ih_time); - struct rtc_time tm; -#endif - - printf (" Image Name: %.*s\n", IH_NMLEN, hdr->ih_name); -#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) - to_tm (timestamp, &tm); - printf (" Created: %4d-%02d-%02d %2d:%02d:%02d UTC\n", - tm.tm_year, tm.tm_mon, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); -#endif - puts (" Image Type: "); print_type(hdr); - printf ("\n Data Size: %d Bytes = ", ntohl(hdr->ih_size)); - print_size (ntohl(hdr->ih_size), "\n"); - printf (" Load Address: %08x\n" - " Entry Point: %08x\n", - ntohl(hdr->ih_load), ntohl(hdr->ih_ep)); - - if (hdr->ih_type == IH_TYPE_MULTI) { - int i; - ulong len; - ulong *len_ptr = (ulong *)((ulong)hdr + sizeof(image_header_t)); - - puts (" Contents:\n"); - for (i=0; (len = ntohl(*len_ptr)); ++i, ++len_ptr) { - printf (" Image %d: %8ld Bytes = ", i, len); - print_size (len, "\n"); - } - } -} - - -static void -print_type (image_header_t *hdr) -{ - char *os, *arch, *type, *comp; - - switch (hdr->ih_os) { - case IH_OS_INVALID: os = "Invalid OS"; break; - case IH_OS_NETBSD: os = "NetBSD"; break; - case IH_OS_LINUX: os = "Linux"; break; - case IH_OS_VXWORKS: os = "VxWorks"; break; - case IH_OS_QNX: os = "QNX"; break; - case IH_OS_U_BOOT: os = "U-Boot"; break; - case IH_OS_RTEMS: os = "RTEMS"; break; -#ifdef CONFIG_ARTOS - case IH_OS_ARTOS: os = "ARTOS"; break; -#endif -#ifdef CONFIG_LYNXKDI - case IH_OS_LYNXOS: os = "LynxOS"; break; -#endif - default: os = "Unknown OS"; break; - } - - switch (hdr->ih_arch) { - case IH_CPU_INVALID: arch = "Invalid CPU"; break; - case IH_CPU_ALPHA: arch = "Alpha"; break; - case IH_CPU_ARM: arch = "ARM"; break; - case IH_CPU_AVR32: arch = "AVR32"; break; - case IH_CPU_BLACKFIN: arch = "Blackfin"; break; - case IH_CPU_I386: arch = "Intel x86"; break; - case IH_CPU_IA64: arch = "IA64"; break; - case IH_CPU_M68K: arch = "M68K"; break; - case IH_CPU_MICROBLAZE: arch = "Microblaze"; break; - case IH_CPU_MIPS64: arch = "MIPS 64 Bit"; break; - case IH_CPU_MIPS: arch = "MIPS"; break; - case IH_CPU_NIOS2: arch = "Nios-II"; break; - case IH_CPU_NIOS: arch = "Nios"; break; - case IH_CPU_PPC: arch = "PowerPC"; break; - case IH_CPU_S390: arch = "IBM S390"; break; - case IH_CPU_SH: arch = "SuperH"; break; - case IH_CPU_SPARC64: arch = "SPARC 64 Bit"; break; - case IH_CPU_SPARC: arch = "SPARC"; break; - default: arch = "Unknown Architecture"; break; - } - - switch (hdr->ih_type) { - case IH_TYPE_INVALID: type = "Invalid Image"; break; - case IH_TYPE_STANDALONE:type = "Standalone Program"; break; - case IH_TYPE_KERNEL: type = "Kernel Image"; break; - case IH_TYPE_RAMDISK: type = "RAMDisk Image"; break; - case IH_TYPE_MULTI: type = "Multi-File Image"; break; - case IH_TYPE_FIRMWARE: type = "Firmware"; break; - case IH_TYPE_SCRIPT: type = "Script"; break; - case IH_TYPE_FLATDT: type = "Flat Device Tree"; break; - default: type = "Unknown Image"; break; - } - - switch (hdr->ih_comp) { - case IH_COMP_NONE: comp = "uncompressed"; break; - case IH_COMP_GZIP: comp = "gzip compressed"; break; - case IH_COMP_BZIP2: comp = "bzip2 compressed"; break; - default: comp = "unknown compression"; break; - } - - printf ("%s %s %s (%s)", arch, os, type, comp); -} - -#define ZALLOC_ALIGNMENT 16 - -static void *zalloc(void *x, unsigned items, unsigned size) -{ - void *p; - - size *= items; - size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1); - - p = malloc (size); - - return (p); -} - -static void zfree(void *x, void *addr, unsigned nb) -{ - free (addr); -} - -#define HEAD_CRC 2 -#define EXTRA_FIELD 4 -#define ORIG_NAME 8 -#define COMMENT 0x10 -#define RESERVED 0xe0 - -#define DEFLATED 8 - -int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp) -{ - z_stream s; - int r, i, flags; - - /* skip header */ - i = 10; - flags = src[3]; - if (src[2] != DEFLATED || (flags & RESERVED) != 0) { - puts ("Error: Bad gzipped data\n"); - return (-1); - } - if ((flags & EXTRA_FIELD) != 0) - i = 12 + src[10] + (src[11] << 8); - if ((flags & ORIG_NAME) != 0) - while (src[i++] != 0) - ; - if ((flags & COMMENT) != 0) - while (src[i++] != 0) - ; - if ((flags & HEAD_CRC) != 0) - i += 2; - if (i >= *lenp) { - puts ("Error: gunzip out of data in header\n"); - return (-1); - } - - s.zalloc = zalloc; - s.zfree = zfree; -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - s.outcb = (cb_func)WATCHDOG_RESET; -#else - s.outcb = Z_NULL; -#endif /* CONFIG_HW_WATCHDOG */ - - r = inflateInit2(&s, -MAX_WBITS); - if (r != Z_OK) { - printf ("Error: inflateInit2() returned %d\n", r); - return (-1); - } - s.next_in = src + i; - s.avail_in = *lenp - i; - s.next_out = dst; - s.avail_out = dstlen; - r = inflate(&s, Z_FINISH); - if (r != Z_OK && r != Z_STREAM_END) { - printf ("Error: inflate() returned %d\n", r); - return (-1); - } - *lenp = s.next_out - (unsigned char *) dst; - inflateEnd(&s); - - return (0); -} - -#ifdef CONFIG_BZIP2 -void bz_internal_error(int errcode) -{ - printf ("BZIP2 internal error %d\n", errcode); -} -#endif /* CONFIG_BZIP2 */ - -static void -do_bootm_rtems (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) -{ - image_header_t *hdr = &header; - void (*entry_point)(bd_t *); - - entry_point = (void (*)(bd_t *)) ntohl(hdr->ih_ep); - - printf ("## Transferring control to RTEMS (at address %08lx) ...\n", - (ulong)entry_point); - - show_boot_progress (15); - - /* - * RTEMS Parameters: - * r3: ptr to board info data - */ - - (*entry_point ) ( gd->bd ); -} - -#if defined(CONFIG_CMD_ELF) -static void -do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) -{ - image_header_t *hdr = &header; - char str[80]; - - sprintf(str, "%x", ntohl(hdr->ih_ep)); /* write entry-point into string */ - setenv("loadaddr", str); - do_bootvx(cmdtp, 0, 0, NULL); -} - -static void -do_bootm_qnxelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) -{ - image_header_t *hdr = &header; - char *local_args[2]; - char str[16]; - - sprintf(str, "%x", ntohl(hdr->ih_ep)); /* write entry-point into string */ - local_args[0] = argv[0]; - local_args[1] = str; /* and provide it via the arguments */ - do_bootelf(cmdtp, 0, 2, local_args); -} -#endif - -#ifdef CONFIG_LYNXKDI -static void -do_bootm_lynxkdi (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong addr, - ulong *len_ptr, - int verify) -{ - lynxkdi_boot( &header ); -} - -#endif /* CONFIG_LYNXKDI */ diff --git a/common/cmd_doc.c b/common/cmd_doc.c index 3d717c039..83aba3744 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -205,6 +205,9 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong offset = 0; image_header_t *hdr; int rcode = 0; +#if defined(CONFIG_FIT) + const void *fit_hdr; +#endif show_boot_progress (34); switch (argc) { @@ -261,21 +264,36 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (38); - hdr = (image_header_t *)addr; + switch (genimg_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (hdr->ih_magic == IH_MAGIC) { + image_print_contents (hdr); - print_image_hdr (hdr); + cnt = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + show_boot_progress (-130); + puts ("** Bad FIT image format\n"); + return 1; + } + show_boot_progress (131); + puts ("Fit image detected...\n"); - cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); - cnt -= SECTORSIZE; - } else { - puts ("\n** Bad Magic Number **\n"); + cnt = fit_get_size (fit_hdr); + break; +#endif + default: show_boot_progress (-39); + puts ("** Unknown image type\n"); return 1; } show_boot_progress (39); + cnt -= SECTORSIZE; if (doc_rw (doc_dev_desc + dev, 1, offset + SECTORSIZE, cnt, NULL, (u_char *)(addr+SECTORSIZE))) { printf ("** Read error on %d\n", dev); @@ -284,6 +302,12 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (40); +#if defined(CONFIG_FIT) + /* This cannot be done earlier, we need complete FIT image in RAM first */ + if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) + fit_print_contents ((const void *)addr); +#endif + /* Loading ok, update default load address */ load_addr = addr; diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c index 7349412c7..bf283702d 100644 --- a/common/cmd_fdc.c +++ b/common/cmd_fdc.c @@ -788,6 +788,9 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) int i,nrofblk; char *ep; int rcode = 0; +#if defined(CONFIG_FIT) + const void *fit_hdr; +#endif switch (argc) { case 1: @@ -835,14 +838,31 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf("result%d: 0x%02X\n",i,pCMD->result[i]); return 1; } - hdr = (image_header_t *)addr; - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - printf ("Bad Magic Number\n"); + + switch (genimg_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; + image_print_contents (hdr); + + imsize = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + puts ("** Bad FIT image format\n"); + return 1; + } + puts ("Fit image detected...\n"); + + imsize = fit_get_size (fit_hdr); + break; +#endif + default: + puts ("** Unknown image type\n"); return 1; } - print_image_hdr(hdr); - imsize= ntohl(hdr->ih_size)+sizeof(image_header_t); nrofblk=imsize/512; if((imsize%512)>0) nrofblk++; @@ -858,23 +878,28 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf("OK %ld Bytes loaded.\n",imsize); flush_cache (addr, imsize); + +#if defined(CONFIG_FIT) + /* This cannot be done earlier, we need complete FIT image in RAM first */ + if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) + fit_print_contents ((const void *)addr); +#endif + /* Loading ok, update default load address */ - load_addr = addr; - if(hdr->ih_type == IH_TYPE_KERNEL) { - /* Check if we should attempt an auto-start */ - if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { - char *local_args[2]; - extern int do_bootm (cmd_tbl_t *, int, int, char *[]); - local_args[0] = argv[0]; - local_args[1] = NULL; + /* Check if we should attempt an auto-start */ + if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { + char *local_args[2]; + extern int do_bootm (cmd_tbl_t *, int, int, char *[]); - printf ("Automatic boot of image at addr 0x%08lX ...\n", addr); + local_args[0] = argv[0]; + local_args[1] = NULL; - do_bootm (cmdtp, 0, 1, local_args); - rcode ++; - } + printf ("Automatic boot of image at addr 0x%08lX ...\n", addr); + + do_bootm (cmdtp, 0, 1, local_args); + rcode ++; } return rcode; } diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index 14c3fa022..a52284e2f 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -410,17 +410,6 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) /* Create a chosen node */ else if (argv[1][0] == 'c') fdt_chosen(fdt, 0, 0, 1); - -#ifdef CONFIG_OF_HAS_UBOOT_ENV - /* Create a u-boot-env node */ - else if (argv[1][0] == 'e') - fdt_env(fdt); -#endif -#ifdef CONFIG_OF_HAS_BD_T - /* Create a bd_t node */ - else if (argv[1][0] == 'b') - fdt_bd_t(fdt); -#endif else { /* Unrecognized command */ printf ("Usage:\n%s\n", cmdtp->usage); @@ -801,12 +790,6 @@ U_BOOT_CMD( "fdt rsvmem add - Add a mem reserve\n" "fdt rsvmem delete - Delete a mem reserves\n" "fdt chosen - Add/update the /chosen branch in the tree\n" -#ifdef CONFIG_OF_HAS_UBOOT_ENV - "fdt env - Add/replace the /u-boot-env branch in the tree\n" -#endif -#ifdef CONFIG_OF_HAS_BD_T - "fdt bd_t - Add/replace the /bd_t branch in the tree\n" -#endif "NOTE: If the path or property you are setting/printing has a '#' character\n" " or spaces, you MUST escape it with a \\ character or quote it with \".\n" ); diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c index f55447ab1..9141dcce9 100644 --- a/common/cmd_fpga.c +++ b/common/cmd_fpga.c @@ -164,6 +164,10 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) char *devstr = getenv ("fpga"); char *datastr = getenv ("fpgadata"); int rc = FPGA_FAIL; +#if defined (CONFIG_FIT) + const char *fit_uname = NULL; + ulong fit_addr; +#endif if (devstr) dev = (int) simple_strtoul (devstr, NULL, 16); @@ -173,9 +177,22 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) switch (argc) { case 5: /* fpga */ data_size = simple_strtoul (argv[4], NULL, 16); + case 4: /* fpga */ - fpga_data = (void *) simple_strtoul (argv[3], NULL, 16); +#if defined(CONFIG_FIT) + if (fit_parse_subimage (argv[3], (ulong)fpga_data, + &fit_addr, &fit_uname)) { + fpga_data = (void *)fit_addr; + debug ("* fpga: subimage '%s' from FIT image at 0x%08lx\n", + fit_uname, fit_addr); + } else +#endif + { + fpga_data = (void *) simple_strtoul (argv[3], NULL, 16); + debug ("* fpga: cmdline image address = 0x%08lx\n", (ulong)fpga_data); + } PRINTF ("%s: fpga_data = 0x%x\n", __FUNCTION__, (uint) fpga_data); + case 3: /* fpga */ dev = (int) simple_strtoul (argv[2], NULL, 16); PRINTF ("%s: device = %d\n", __FUNCTION__, dev); @@ -183,14 +200,29 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if ((argc == 3) && (dev > fpga_count ())) { /* must be buffer ptr */ PRINTF ("%s: Assuming buffer pointer in arg 3\n", __FUNCTION__); - fpga_data = (void *) dev; + +#if defined(CONFIG_FIT) + if (fit_parse_subimage (argv[2], (ulong)fpga_data, + &fit_addr, &fit_uname)) { + fpga_data = (void *)fit_addr; + debug ("* fpga: subimage '%s' from FIT image at 0x%08lx\n", + fit_uname, fit_addr); + } else +#endif + { + fpga_data = (void *) dev; + debug ("* fpga: cmdline image address = 0x%08lx\n", (ulong)fpga_data); + } + PRINTF ("%s: fpga_data = 0x%x\n", __FUNCTION__, (uint) fpga_data); dev = FPGA_INVALID_DEVICE; /* reset device num */ } + case 2: /* fpga */ op = (int) fpga_get_op (argv[1]); break; + default: PRINTF ("%s: Too many or too few args (%d)\n", __FUNCTION__, argc); @@ -216,19 +248,61 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) break; case FPGA_LOADMK: - { - image_header_t header; - image_header_t *hdr = &header; - ulong data; + switch (genimg_get_format (fpga_data)) { + case IMAGE_FORMAT_LEGACY: + { + image_header_t *hdr = (image_header_t *)fpga_data; + ulong data; - memmove (&header, (char *)fpga_data, sizeof(image_header_t)); - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - puts ("Bad Magic Number\n"); - return 1; + data = (ulong)image_get_data (hdr); + data_size = image_get_data_size (hdr); + rc = fpga_load (dev, (void *)data, data_size); } - data = ((ulong)fpga_data + sizeof(image_header_t)); - data_size = ntohl(hdr->ih_size); - rc = fpga_load (dev, (void *)data, data_size); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + { + const void *fit_hdr = (const void *)fpga_data; + int noffset; + void *fit_data; + + if (fit_uname == NULL) { + puts ("No FIT subimage unit name\n"); + return 1; + } + + if (!fit_check_format (fit_hdr)) { + puts ("Bad FIT image format\n"); + return 1; + } + + /* get fpga component image node offset */ + noffset = fit_image_get_node (fit_hdr, fit_uname); + if (noffset < 0) { + printf ("Can't find '%s' FIT subimage\n", fit_uname); + return 1; + } + + /* verify integrity */ + if (!fit_image_check_hashes (fit_hdr, noffset)) { + puts ("Bad Data Hash\n"); + return 1; + } + + /* get fpga subimage data address and length */ + if (fit_image_get_data (fit_hdr, noffset, &fit_data, &data_size)) { + puts ("Could not find fpga subimage data\n"); + return 1; + } + + rc = fpga_load (dev, fit_data, data_size); + } + break; +#endif + default: + puts ("** Unknown image type\n"); + rc = FPGA_FAIL; + break; } break; @@ -283,4 +357,9 @@ U_BOOT_CMD (fpga, 6, 1, do_fpga, "\tload\tLoad device from memory buffer\n" "\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\n" "\tloadmk\tLoad device generated with mkimage\n" - "\tdump\tLoad device to memory buffer\n"); + "\tdump\tLoad device to memory buffer\n" +#if defined(CONFIG_FIT) + "\tFor loadmk operating on FIT format uImage address must include\n" + "\tsubimage unit name in the form of addr:\n" +#endif +); diff --git a/common/cmd_ide.c b/common/cmd_ide.c index c38be4f1a..8ace970c7 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -366,10 +366,13 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char *boot_device = NULL; char *ep; int dev, part = 0; - ulong addr, cnt, checksum; + ulong addr, cnt; disk_partition_t info; image_header_t *hdr; int rcode = 0; +#if defined(CONFIG_FIT) + const void *fit_hdr; +#endif show_boot_progress (41); switch (argc) { @@ -446,29 +449,43 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (48); - hdr = (image_header_t *)addr; + switch (genimg_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - printf("\n** Bad Magic Number **\n"); + show_boot_progress (49); + + if (!image_check_hcrc (hdr)) { + puts ("\n** Bad Header Checksum **\n"); + show_boot_progress (-50); + return 1; + } + show_boot_progress (50); + + image_print_contents (hdr); + + cnt = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + show_boot_progress (-140); + puts ("** Bad FIT image format\n"); + return 1; + } + show_boot_progress (141); + puts ("Fit image detected...\n"); + + cnt = fit_get_size (fit_hdr); + break; +#endif + default: show_boot_progress (-49); + puts ("** Unknown image type\n"); return 1; } - show_boot_progress (49); - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) { - puts ("\n** Bad Header Checksum **\n"); - show_boot_progress (-50); - return 1; - } - show_boot_progress (50); - hdr->ih_hcrc = htonl(checksum); /* restore checksum for later use */ - - print_image_hdr (hdr); - - cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); cnt += info.blksz - 1; cnt /= info.blksz; cnt -= 1; @@ -481,6 +498,11 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (51); +#if defined(CONFIG_FIT) + /* This cannot be done earlier, we need complete FIT image in RAM first */ + if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) + fit_print_contents ((const void *)addr); +#endif /* Loading ok, update default load address */ diff --git a/common/cmd_load.c b/common/cmd_load.c index 204c3ebf1..1b75a7b5e 100644 --- a/common/cmd_load.c +++ b/common/cmd_load.c @@ -521,8 +521,15 @@ int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char *s; if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) { - printf("Running autoscript at addr 0x%08lX ...\n", load_addr); - rcode = autoscript (load_addr); + printf ("Running autoscript at addr 0x%08lX", load_addr); + + s = getenv ("autoscript_uname"); + if (s) + printf (":%s ...\n", s); + else + puts (" ...\n"); + + rcode = autoscript (load_addr, s); } } #endif diff --git a/common/cmd_mp.c b/common/cmd_mp.c new file mode 100644 index 000000000..26a57c5e9 --- /dev/null +++ b/common/cmd_mp.c @@ -0,0 +1,93 @@ +/* + * Copyright 2008 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 +#include + +int +cpu_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + unsigned long cpuid; + + if (argc < 3) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + cpuid = simple_strtoul(argv[1], NULL, 10); + if (cpuid >= CONFIG_NR_CPUS) { + printf ("Core num: %d is out of range[0..%d]\n", + cpuid, CONFIG_NR_CPUS - 1); + return 1; + } + + + if (argc == 3) { + if (strncmp(argv[2], "reset", 5) == 0) { + cpu_reset(cpuid); + } else if (strncmp(argv[2], "status", 6) == 0) { + cpu_status(cpuid); + } else { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + return 0; + } + + /* 4 or greater, make sure its release */ + if (strncmp(argv[2], "release", 7) != 0) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + if (cpu_release(cpuid, argc - 3, argv + 3)) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + return 0; +} + +#ifdef CONFIG_PPC +#define CPU_ARCH_HELP \ + " [args] : \n" \ + " pir - processor id (if writeable)\n" \ + " r3 - value for gpr 3\n" \ + " r6 - value for gpr 6\n" \ + "\n" \ + " Use '-' for any arg if you want the default value.\n" \ + " Default for r3 is and r6 is 0\n" \ + "\n" \ + " When cpu is released r4 and r5 = 0.\n" \ + " r7 will contain the size of the initial mapped area\n" +#endif + +U_BOOT_CMD( + cpu, CFG_MAXARGS, 1, cpu_cmd, + "cpu - Multiprocessor CPU boot manipulation and release\n", + " reset - Reset cpu \n" + "cpu status - Status of cpu \n" + "cpu release [args] - Release cpu at with [args]\n" +#ifdef CPU_ARCH_HELP + CPU_ARCH_HELP +#endif + ); diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 8d6c95958..7b1f83046 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -484,6 +484,9 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, ulong cnt; image_header_t *hdr; int jffs2 = 0; +#if defined(CONFIG_FIT) + const void *fit_hdr; +#endif s = strchr(cmd, '.'); if (s != NULL && @@ -512,18 +515,35 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, } show_boot_progress (56); - hdr = (image_header_t *) addr; + switch (genimg_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic); + show_boot_progress (57); + image_print_contents (hdr); + + cnt = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + show_boot_progress (-150); + puts ("** Bad FIT image format\n"); + return 1; + } + show_boot_progress (151); + puts ("Fit image detected...\n"); + + cnt = fit_get_size (fit_hdr); + break; +#endif + default: show_boot_progress (-57); + puts ("** Unknown image type\n"); return 1; } - show_boot_progress (57); - print_image_hdr(hdr); - - cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t)); if (jffs2) { nand_read_options_t opts; memset(&opts, 0, sizeof(opts)); @@ -543,6 +563,12 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, } show_boot_progress (58); +#if defined(CONFIG_FIT) + /* This cannot be done earlier, we need complete FIT image in RAM first */ + if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) + fit_print_contents ((const void *)addr); +#endif + /* Loading ok, update default load address */ load_addr = addr; @@ -925,6 +951,10 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) ulong offset = 0; image_header_t *hdr; int rcode = 0; +#if defined(CONFIG_FIT) + const void *fit_hdr; +#endif + show_boot_progress (52); switch (argc) { case 1: @@ -980,17 +1010,31 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (56); - hdr = (image_header_t *)addr; + switch (genimg_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; + image_print_contents (hdr); - if (ntohl(hdr->ih_magic) == IH_MAGIC) { - - print_image_hdr (hdr); - - cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); + cnt = image_get_image_size (hdr); cnt -= SECTORSIZE; - } else { - printf ("\n** Bad Magic Number 0x%x **\n", ntohl(hdr->ih_magic)); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + show_boot_progress (-150); + puts ("** Bad FIT image format\n"); + return 1; + } + show_boot_progress (151); + puts ("Fit image detected...\n"); + + cnt = fit_get_size (fit_hdr); + break; +#endif + default: show_boot_progress (-57); + puts ("** Unknown image type\n"); return 1; } show_boot_progress (57); @@ -1004,6 +1048,12 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } show_boot_progress (58); +#if defined(CONFIG_FIT) + /* This cannot be done earlier, we need complete FIT image in RAM first */ + if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) + fit_print_contents ((const void *)addr); +#endif + /* Loading ok, update default load address */ load_addr = addr; diff --git a/common/cmd_net.c b/common/cmd_net.c index dbf6b861b..79e910c76 100644 --- a/common/cmd_net.c +++ b/common/cmd_net.c @@ -220,9 +220,16 @@ netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[]) #ifdef CONFIG_AUTOSCRIPT if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) { - printf("Running autoscript at addr 0x%08lX ...\n", load_addr); + printf ("Running autoscript at addr 0x%08lX", load_addr); + + s = getenv ("autoscript_uname"); + if (s) + printf (":%s ...\n", s); + else + puts (" ...\n"); + show_boot_progress (83); - rcode = autoscript (load_addr); + rcode = autoscript (load_addr, s); } #endif if (rcode < 0) diff --git a/common/cmd_sata.c b/common/cmd_sata.c index bd4c11fd9..79c2495d6 100644 --- a/common/cmd_sata.c +++ b/common/cmd_sata.c @@ -1,8 +1,11 @@ /* + * Copyright (C) 2000-2005, DENX Software Engineering + * Wolfgang Denk * Copyright (C) Procsys. All rights reserved. - * Author: Mushtaq Khan + * Mushtaq Khan * - * + * Copyright (C) 2008 Freescale Semiconductor, Inc. + * Dave Liu * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -11,702 +14,180 @@ * * 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 + * 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 - * - * with the reference to libata in kernel 2.4.32 - * */ -/* - * File contains SATA read-write and other utility functions. - */ #include -#include -#include #include -#include -#include -#include - -#ifdef CFG_SATA_SUPPORTED -/*For debug prints set macro DEBUG_SATA to 1 */ -#define DEBUG_SATA 0 -/*Macro for SATA library specific declarations */ -#define SATA_DECL +#include #include -#undef SATA_DECL -static u8 __inline__ -sata_inb (unsigned long ioaddr) -{ - return inb (ioaddr); -} - -static void __inline__ -sata_outb (unsigned char val, unsigned long ioaddr) -{ - outb (val, ioaddr); -} - -static void -output_data (struct sata_ioports *ioaddr, ulong * sect_buf, int words) -{ - outsw (ioaddr->data_addr, sect_buf, words << 1); -} - -static int -input_data (struct sata_ioports *ioaddr, ulong * sect_buf, int words) -{ - insw (ioaddr->data_addr, sect_buf, words << 1); - return 0; -} - -static void -sata_cpy (unsigned char *dst, unsigned char *src, unsigned int len) -{ - unsigned char *end, *last; - - last = dst; - end = src + len - 1; - - /* reserve space for '\0' */ - if (len < 2) - goto OUT; - - /* skip leading white space */ - while ((*src) && (src < end) && (*src == ' ')) - ++src; - - /* copy string, omitting trailing white space */ - while ((*src) && (src < end)) { - *dst++ = *src; - if (*src++ != ' ') - last = dst; - } - OUT: - *last = '\0'; -} - -int -sata_bus_softreset (int num) -{ - u8 dev = 0, status = 0, i; - - port[num].dev_mask = 0; - - for (i = 0; i < CFG_SATA_DEVS_PER_BUS; i++) { - if (!(sata_devchk (&port[num].ioaddr, i))) { - PRINTF ("dev_chk failed for dev#%d\n", i); - } else { - port[num].dev_mask |= (1 << i); - PRINTF ("dev_chk passed for dev#%d\n", i); - } - } - - if (!(port[num].dev_mask)) { - printf ("no devices on port%d\n", num); - return 1; - } - - dev_select (&port[num].ioaddr, dev); - - port[num].ctl_reg = 0x08; /*Default value of control reg */ - sata_outb (port[num].ctl_reg, port[num].ioaddr.ctl_addr); - udelay (10); - sata_outb (port[num].ctl_reg | ATA_SRST, port[num].ioaddr.ctl_addr); - udelay (10); - sata_outb (port[num].ctl_reg, port[num].ioaddr.ctl_addr); - - /* spec mandates ">= 2ms" before checking status. - * We wait 150ms, because that was the magic delay used for - * ATAPI devices in Hale Landis's ATADRVR, for the period of time - * between when the ATA command register is written, and then - * status is checked. Because waiting for "a while" before - * checking status is fine, post SRST, we perform this magic - * delay here as well. - */ - msleep (150); - status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 300); - while ((status & ATA_BUSY)) { - msleep (100); - status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 3); - } - - if (status & ATA_BUSY) - printf ("ata%u is slow to respond,plz be patient\n", port); - - while ((status & ATA_BUSY)) { - msleep (100); - status = sata_chk_status (&port[num].ioaddr); - } - - if (status & ATA_BUSY) { - printf ("ata%u failed to respond : ", port); - printf ("bus reset failed\n"); - return 1; - } - return 0; -} - -void -sata_identify (int num, int dev) -{ - u8 cmd = 0, status = 0, devno = num * CFG_SATA_DEVS_PER_BUS + dev; - u16 iobuf[ATA_SECT_SIZE]; - u64 n_sectors = 0; - u8 mask = 0; - - memset (iobuf, 0, sizeof (iobuf)); - hd_driveid_t *iop = (hd_driveid_t *) iobuf; - - if (dev == 0) - mask = 0x01; - else - mask = 0x02; - - if (!(port[num].dev_mask & mask)) { - printf ("dev%d is not present on port#%d\n", dev, num); - return; - } - - printf ("port=%d dev=%d\n", num, dev); - - dev_select (&port[num].ioaddr, dev); - - status = 0; - cmd = ATA_CMD_IDENT; /*Device Identify Command */ - sata_outb (cmd, port[num].ioaddr.command_addr); - sata_inb (port[num].ioaddr.altstatus_addr); - udelay (10); - - status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 1000); - if (status & ATA_ERR) { - printf ("\ndevice not responding\n"); - port[num].dev_mask &= ~mask; - return; - } - - input_data (&port[num].ioaddr, (ulong *) iobuf, ATA_SECTORWORDS); - - PRINTF ("\nata%u: dev %u cfg 49:%04x 82:%04x 83:%04x 84:%04x85:%04x" - "86:%04x" "87:%04x 88:%04x\n", num, dev, iobuf[49], - iobuf[82], iobuf[83], iobuf[84], iobuf[85], iobuf[86], - iobuf[87], iobuf[88]); - - /* we require LBA and DMA support (bits 8 & 9 of word 49) */ - if (!ata_id_has_dma (iobuf) || !ata_id_has_lba (iobuf)) { - PRINTF ("ata%u: no dma/lba\n", num); - } - ata_dump_id (iobuf); - - if (ata_id_has_lba48 (iobuf)) { - n_sectors = ata_id_u64 (iobuf, 100); - } else { - n_sectors = ata_id_u32 (iobuf, 60); - } - PRINTF ("no. of sectors %u\n", ata_id_u64 (iobuf, 100)); - PRINTF ("no. of sectors %u\n", ata_id_u32 (iobuf, 60)); - - if (n_sectors == 0) { - port[num].dev_mask &= ~mask; - return; - } - - sata_cpy (sata_dev_desc[devno].revision, iop->fw_rev, - sizeof (sata_dev_desc[devno].revision)); - sata_cpy (sata_dev_desc[devno].vendor, iop->model, - sizeof (sata_dev_desc[devno].vendor)); - sata_cpy (sata_dev_desc[devno].product, iop->serial_no, - sizeof (sata_dev_desc[devno].product)); - strswab (sata_dev_desc[devno].revision); - strswab (sata_dev_desc[devno].vendor); - - if ((iop->config & 0x0080) == 0x0080) { - sata_dev_desc[devno].removable = 1; - } else { - sata_dev_desc[devno].removable = 0; - } - - sata_dev_desc[devno].lba = iop->lba_capacity; - PRINTF ("lba=0x%x", sata_dev_desc[devno].lba); - -#ifdef CONFIG_LBA48 - if (iop->command_set_2 & 0x0400) { - sata_dev_desc[devno].lba48 = 1; - lba = (unsigned long long) iop->lba48_capacity[0] | - ((unsigned long long) iop->lba48_capacity[1] << 16) | - ((unsigned long long) iop->lba48_capacity[2] << 32) | - ((unsigned long long) iop->lba48_capacity[3] << 48); - } else { - sata_dev_desc[devno].lba48 = 0; - } -#endif - - /* assuming HD */ - sata_dev_desc[devno].type = DEV_TYPE_HARDDISK; - sata_dev_desc[devno].blksz = ATA_BLOCKSIZE; - sata_dev_desc[devno].lun = 0; /* just to fill something in... */ -} - -void -set_Feature_cmd (int num, int dev) -{ - u8 mask = 0x00, status = 0; - - if (dev == 0) - mask = 0x01; - else - mask = 0x02; - - if (!(port[num].dev_mask & mask)) { - PRINTF ("dev%d is not present on port#%d\n", dev, num); - return; - } - - dev_select (&port[num].ioaddr, dev); - - sata_outb (SETFEATURES_XFER, port[num].ioaddr.feature_addr); - sata_outb (XFER_PIO_4, port[num].ioaddr.nsect_addr); - sata_outb (0, port[num].ioaddr.lbal_addr); - sata_outb (0, port[num].ioaddr.lbam_addr); - sata_outb (0, port[num].ioaddr.lbah_addr); - - sata_outb (ATA_DEVICE_OBS, port[num].ioaddr.device_addr); - sata_outb (ATA_CMD_SETF, port[num].ioaddr.command_addr); - - udelay (50); - msleep (150); - - status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 5000); - if ((status & (ATA_STAT_BUSY | ATA_STAT_ERR))) { - printf ("Error : status 0x%02x\n", status); - port[num].dev_mask &= ~mask; - } -} - -void -sata_port (struct sata_ioports *ioport) -{ - ioport->data_addr = ioport->cmd_addr + ATA_REG_DATA; - ioport->error_addr = ioport->cmd_addr + ATA_REG_ERR; - ioport->feature_addr = ioport->cmd_addr + ATA_REG_FEATURE; - ioport->nsect_addr = ioport->cmd_addr + ATA_REG_NSECT; - ioport->lbal_addr = ioport->cmd_addr + ATA_REG_LBAL; - ioport->lbam_addr = ioport->cmd_addr + ATA_REG_LBAM; - ioport->lbah_addr = ioport->cmd_addr + ATA_REG_LBAH; - ioport->device_addr = ioport->cmd_addr + ATA_REG_DEVICE; - ioport->status_addr = ioport->cmd_addr + ATA_REG_STATUS; - ioport->command_addr = ioport->cmd_addr + ATA_REG_CMD; -} - -int -sata_devchk (struct sata_ioports *ioaddr, int dev) -{ - u8 nsect, lbal; - - dev_select (ioaddr, dev); - - sata_outb (0x55, ioaddr->nsect_addr); - sata_outb (0xaa, ioaddr->lbal_addr); - - sata_outb (0xaa, ioaddr->nsect_addr); - sata_outb (0x55, ioaddr->lbal_addr); - - sata_outb (0x55, ioaddr->nsect_addr); - sata_outb (0xaa, ioaddr->lbal_addr); - - nsect = sata_inb (ioaddr->nsect_addr); - lbal = sata_inb (ioaddr->lbal_addr); - - if ((nsect == 0x55) && (lbal == 0xaa)) - return 1; /* we found a device */ - else - return 0; /* nothing found */ -} - -void -dev_select (struct sata_ioports *ioaddr, int dev) -{ - u8 tmp = 0; - - if (dev == 0) - tmp = ATA_DEVICE_OBS; - else - tmp = ATA_DEVICE_OBS | ATA_DEV1; - - sata_outb (tmp, ioaddr->device_addr); - sata_inb (ioaddr->altstatus_addr); - udelay (5); -} - -u8 -sata_busy_wait (struct sata_ioports *ioaddr, int bits, unsigned int max) -{ - u8 status; - - do { - udelay (1000); - status = sata_chk_status (ioaddr); - max--; - } while ((status & bits) && (max > 0)); - - return status; -} - -u8 -sata_chk_status (struct sata_ioports * ioaddr) -{ - return sata_inb (ioaddr->status_addr); -} - -void -msleep (int count) +int curr_device = -1; +block_dev_desc_t sata_dev_desc[CFG_SATA_MAX_DEVICE]; + +int sata_initialize(void) { + int rc; int i; - for (i = 0; i < count; i++) - udelay (1000); + for (i = 0; i < CFG_SATA_MAX_DEVICE; i++) { + memset(&sata_dev_desc[i], 0, sizeof(struct block_dev_desc)); + sata_dev_desc[i].if_type = IF_TYPE_SATA; + sata_dev_desc[i].dev = i; + sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN; + sata_dev_desc[i].type = DEV_TYPE_HARDDISK; + sata_dev_desc[i].lba = 0; + sata_dev_desc[i].blksz = 512; + sata_dev_desc[i].block_read = sata_read; + sata_dev_desc[i].block_write = sata_write; + + rc = init_sata(i); + rc = scan_sata(i); + if ((sata_dev_desc[i].lba > 0) && (sata_dev_desc[i].blksz > 0)) + init_part(&sata_dev_desc[i]); + } + curr_device = 0; + return rc; } -ulong -sata_read (int device, ulong blknr,lbaint_t blkcnt, void * buff) +block_dev_desc_t *sata_get_dev(int dev) { - ulong n = 0, *buffer = (ulong *)buff; - u8 dev = 0, num = 0, mask = 0, status = 0; - -#ifdef CONFIG_LBA48 - unsigned char lba48 = 0; - - if (blknr & 0x0000fffff0000000) { - if (!sata_dev_desc[devno].lba48) { - printf ("Drive doesn't support 48-bit addressing\n"); - return 0; - } - /* more than 28 bits used, use 48bit mode */ - lba48 = 1; - } -#endif - /*Port Number */ - num = device / CFG_SATA_DEVS_PER_BUS; - /*dev on the port */ - if (device >= CFG_SATA_DEVS_PER_BUS) - dev = device - CFG_SATA_DEVS_PER_BUS; - else - dev = device; - - if (dev == 0) - mask = 0x01; - else - mask = 0x02; - - if (!(port[num].dev_mask & mask)) { - printf ("dev%d is not present on port#%d\n", dev, num); - return 0; - } - - /* Select device */ - dev_select (&port[num].ioaddr, dev); - - status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500); - if (status & ATA_BUSY) { - printf ("ata%u failed to respond\n", port[num].port_no); - return n; - } - while (blkcnt-- > 0) { - status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500); - if (status & ATA_BUSY) { - printf ("ata%u failed to respond\n", 0); - return n; - } -#ifdef CONFIG_LBA48 - if (lba48) { - /* write high bits */ - sata_outb (0, port[num].ioaddr.nsect_addr); - sata_outb ((blknr >> 24) & 0xFF, - port[num].ioaddr.lbal_addr); - sata_outb ((blknr >> 32) & 0xFF, - port[num].ioaddr.lbam_addr); - sata_outb ((blknr >> 40) & 0xFF, - port[num].ioaddr.lbah_addr); - } -#endif - sata_outb (1, port[num].ioaddr.nsect_addr); - sata_outb (((blknr) >> 0) & 0xFF, - port[num].ioaddr.lbal_addr); - sata_outb ((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr); - sata_outb ((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr); - -#ifdef CONFIG_LBA48 - if (lba48) { - sata_outb (ATA_LBA, port[num].ioaddr.device_addr); - sata_outb (ATA_CMD_READ_EXT, - port[num].ioaddr.command_addr); - } else -#endif - { - sata_outb (ATA_LBA | ((blknr >> 24) & 0xF), - port[num].ioaddr.device_addr); - sata_outb (ATA_CMD_READ, - port[num].ioaddr.command_addr); - } - - msleep (50); - /*may take up to 4 sec */ - status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 4000); - - if ((status & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) - != ATA_STAT_DRQ) { - u8 err = 0; - - printf ("Error no DRQ dev %d blk %ld: sts 0x%02x\n", - device, (ulong) blknr, status); - err = sata_inb (port[num].ioaddr.error_addr); - printf ("Error reg = 0x%x\n", err); - return (n); - } - input_data (&port[num].ioaddr, buffer, ATA_SECTORWORDS); - sata_inb (port[num].ioaddr.altstatus_addr); - udelay (50); - - ++n; - ++blknr; - buffer += ATA_SECTORWORDS; - } - return n; + return (dev < CFG_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL; } -ulong -sata_write (int device, ulong blknr,lbaint_t blkcnt, void * buff) -{ - ulong n = 0, *buffer = (ulong *)buff; - unsigned char status = 0, num = 0, dev = 0, mask = 0; - -#ifdef CONFIG_LBA48 - unsigned char lba48 = 0; - - if (blknr & 0x0000fffff0000000) { - if (!sata_dev_desc[devno].lba48) { - printf ("Drive doesn't support 48-bit addressing\n"); - return 0; - } - /* more than 28 bits used, use 48bit mode */ - lba48 = 1; - } -#endif - /*Port Number */ - num = device / CFG_SATA_DEVS_PER_BUS; - /*dev on the Port */ - if (device >= CFG_SATA_DEVS_PER_BUS) - dev = device - CFG_SATA_DEVS_PER_BUS; - else - dev = device; - - if (dev == 0) - mask = 0x01; - else - mask = 0x02; - - /* Select device */ - dev_select (&port[num].ioaddr, dev); - - status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500); - if (status & ATA_BUSY) { - printf ("ata%u failed to respond\n", port[num].port_no); - return n; - } - - while (blkcnt-- > 0) { - status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500); - if (status & ATA_BUSY) { - printf ("ata%u failed to respond\n", - port[num].port_no); - return n; - } -#ifdef CONFIG_LBA48 - if (lba48) { - /* write high bits */ - sata_outb (0, port[num].ioaddr.nsect_addr); - sata_outb ((blknr >> 24) & 0xFF, - port[num].ioaddr.lbal_addr); - sata_outb ((blknr >> 32) & 0xFF, - port[num].ioaddr.lbam_addr); - sata_outb ((blknr >> 40) & 0xFF, - port[num].ioaddr.lbah_addr); - } -#endif - sata_outb (1, port[num].ioaddr.nsect_addr); - sata_outb ((blknr >> 0) & 0xFF, port[num].ioaddr.lbal_addr); - sata_outb ((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr); - sata_outb ((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr); -#ifdef CONFIG_LBA48 - if (lba48) { - sata_outb (ATA_LBA, port[num].ioaddr.device_addr); - sata_outb (ATA_CMD_WRITE_EXT, - port[num].ioaddr.command_addr); - } else -#endif - { - sata_outb (ATA_LBA | ((blknr >> 24) & 0xF), - port[num].ioaddr.device_addr); - sata_outb (ATA_CMD_WRITE, - port[num].ioaddr.command_addr); - } - - msleep (50); - /*may take up to 4 sec */ - status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 4000); - if ((status & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) - != ATA_STAT_DRQ) { - printf ("Error no DRQ dev %d blk %ld: sts 0x%02x\n", - device, (ulong) blknr, status); - return (n); - } - - output_data (&port[num].ioaddr, buffer, ATA_SECTORWORDS); - sata_inb (port[num].ioaddr.altstatus_addr); - udelay (50); - - ++n; - ++blknr; - buffer += ATA_SECTORWORDS; - } - return n; -} - -block_dev_desc_t *sata_get_dev (int dev); - -block_dev_desc_t * -sata_get_dev (int dev) -{ - return ((block_dev_desc_t *) & sata_dev_desc[dev]); -} - -int -do_sata (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { + int rc = 0; switch (argc) { case 0: case 1: - printf ("Usage:\n%s\n", cmdtp->usage); + printf("Usage:\n%s\n", cmdtp->usage); return 1; case 2: - if (strncmp (argv[1], "init", 4) == 0) { - int rcode = 0; - - rcode = init_sata (); - if (rcode) - printf ("Sata initialization Failed\n"); - return rcode; - } else if (strncmp (argv[1], "inf", 3) == 0) { + if (strncmp(argv[1],"inf", 3) == 0) { int i; - - putc ('\n'); - for (i = 0; i < CFG_SATA_MAXDEVICES; ++i) { - /*List only known devices */ - if (sata_dev_desc[i].type == - DEV_TYPE_UNKNOWN) + putc('\n'); + for (i = 0; i < CFG_SATA_MAX_DEVICE; ++i) { + if (sata_dev_desc[i].type == DEV_TYPE_UNKNOWN) continue; - printf ("sata dev %d: ", i); - dev_print (&sata_dev_desc[i]); + printf ("SATA device %d: ", i); + dev_print(&sata_dev_desc[i]); } return 0; + } else if (strncmp(argv[1],"dev", 3) == 0) { + if ((curr_device < 0) || (curr_device >= CFG_SATA_MAX_DEVICE)) { + puts("\nno SATA devices available\n"); + return 1; + } + printf("\nSATA device %d: ", curr_device); + dev_print(&sata_dev_desc[curr_device]); + return 0; + } else if (strncmp(argv[1],"part",4) == 0) { + int dev, ok; + + for (ok = 0, dev = 0; dev < CFG_SATA_MAX_DEVICE; ++dev) { + if (sata_dev_desc[dev].part_type != PART_TYPE_UNKNOWN) { + ++ok; + if (dev) + putc ('\n'); + print_part(&sata_dev_desc[dev]); + } + } + if (!ok) { + puts("\nno SATA devices available\n"); + rc ++; + } + return rc; } - printf ("Usage:\n%s\n", cmdtp->usage); + printf("Usage:\n%s\n", cmdtp->usage); return 1; case 3: - if (strcmp (argv[1], "dev") == 0) { - int dev = (int) simple_strtoul (argv[2], NULL, 10); + if (strncmp(argv[1], "dev", 3) == 0) { + int dev = (int)simple_strtoul(argv[2], NULL, 10); - if (dev >= CFG_SATA_MAXDEVICES) { - printf ("\nSata dev %d not available\n", - dev); + printf("\nSATA device %d: ", dev); + if (dev >= CFG_SATA_MAX_DEVICE) { + puts ("unknown device\n"); return 1; } - printf ("\nSATA dev %d: ", dev); - dev_print (&sata_dev_desc[dev]); + dev_print(&sata_dev_desc[dev]); + if (sata_dev_desc[dev].type == DEV_TYPE_UNKNOWN) return 1; - curr_dev = dev; - return 0; - } else if (strcmp (argv[1], "part") == 0) { - int dev = (int) simple_strtoul (argv[2], NULL, 10); - if (dev >= CFG_SATA_MAXDEVICES) { - printf ("\nSata dev %d not available\n", - dev); - return 1; - } - PRINTF ("\nSATA dev %d: ", dev); - if (sata_dev_desc[dev].part_type != - PART_TYPE_UNKNOWN) { - print_part (&sata_dev_desc[dev]); - } else { - printf ("\nSata dev %d partition type " - "unknown\n", dev); - return 1; - } + curr_device = dev; + + puts("... is now current device\n"); + return 0; + } else if (strncmp(argv[1], "part", 4) == 0) { + int dev = (int)simple_strtoul(argv[2], NULL, 10); + + if (sata_dev_desc[dev].part_type != PART_TYPE_UNKNOWN) { + print_part(&sata_dev_desc[dev]); + } else { + printf("\nSATA device %d not available\n", dev); + rc = 1; + } + return rc; } printf ("Usage:\n%s\n", cmdtp->usage); return 1; - default: - if (argc < 5) { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - } - if (strcmp (argv[1], "read") == 0) { - ulong addr = simple_strtoul (argv[2], NULL, 16); - ulong cnt = simple_strtoul (argv[4], NULL, 16); - ulong n; - lbaint_t blk = simple_strtoul (argv[3], NULL, 16); - memset ((int *) addr, 0, cnt * 512); - printf ("\nSATA read: dev %d blk # %ld," - "count %ld ... ", curr_dev, blk, cnt); - n = sata_read (curr_dev, blk, cnt, (ulong *) addr); + default: /* at least 4 args */ + if (strcmp(argv[1], "read") == 0) { + ulong addr = simple_strtoul(argv[2], NULL, 16); + ulong cnt = simple_strtoul(argv[4], NULL, 16); + ulong n; + lbaint_t blk = simple_strtoul(argv[3], NULL, 16); + + printf("\nSATA read: device %d block # %ld, count %ld ... ", + curr_device, blk, cnt); + + n = sata_read(curr_device, blk, cnt, (u32 *)addr); + /* flush cache after read */ - flush_cache (addr, cnt * 512); - printf ("%ld blocks read: %s\n", n, - (n == cnt) ? "OK" : "ERR"); - if (n == cnt) - return 1; - else - return 0; - } else if (strcmp (argv[1], "write") == 0) { - ulong addr = simple_strtoul (argv[2], NULL, 16); - ulong cnt = simple_strtoul (argv[4], NULL, 16); - ulong n; - lbaint_t blk = simple_strtoul (argv[3], NULL, 16); + flush_cache(addr, cnt * sata_dev_desc[curr_device].blksz); - printf ("\nSata write: dev %d blk # %ld," - "count %ld ... ", curr_dev, blk, cnt); - n = sata_write (curr_dev, blk, cnt, (ulong *) addr); - printf ("%ld blocks written: %s\n", n, - (n == cnt) ? "OK" : "ERR"); - if (n == cnt) - return 1; - else - return 0; + printf("%ld blocks read: %s\n", + n, (n==cnt) ? "OK" : "ERROR"); + return (n == cnt) ? 0 : 1; + } else if (strcmp(argv[1], "write") == 0) { + ulong addr = simple_strtoul(argv[2], NULL, 16); + ulong cnt = simple_strtoul(argv[4], NULL, 16); + ulong n; + + lbaint_t blk = simple_strtoul(argv[3], NULL, 16); + + printf("\nSATA write: device %d block # %ld, count %ld ... ", + curr_device, blk, cnt); + + n = sata_write(curr_device, blk, cnt, (u32 *)addr); + + printf("%ld blocks written: %s\n", + n, (n == cnt) ? "OK" : "ERROR"); + return (n == cnt) ? 0 : 1; } else { - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; + printf("Usage:\n%s\n", cmdtp->usage); + rc = 1; } - } /*End OF SWITCH */ + + return rc; + } } -U_BOOT_CMD (sata, 5, 1, do_sata, - "sata init\n" - "sata info\n" - "sata part device\n" - "sata dev device\n" - "sata read addr blk# cnt\n" - "sata write addr blk# cnt\n", "cmd for init,rw and dev-info\n"); - -#endif +U_BOOT_CMD( + sata, 5, 1, do_sata, + "sata - SATA sub system\n", + "sata info - show available SATA devices\n" + "sata device [dev] - show or set current device\n" + "sata part [dev] - print partition table\n" + "sata read addr blk# cnt\n" + "sata write addr blk# cnt\n"); diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index 1cdec159f..f49531e96 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -207,10 +207,13 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char *boot_device = NULL; char *ep; int dev, part = 0; - ulong addr, cnt, checksum; + ulong addr, cnt; disk_partition_t info; image_header_t *hdr; int rcode = 0; +#if defined(CONFIG_FIT) + const void *fit_hdr; +#endif switch (argc) { case 1: @@ -273,24 +276,35 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - hdr = (image_header_t *)addr; + switch (genimg_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (ntohl(hdr->ih_magic) == IH_MAGIC) { - printf("\n** Bad Magic Number **\n"); + if (!image_check_hcrc (hdr)) { + puts ("\n** Bad Header Checksum **\n"); + return 1; + } + + image_print_contents (hdr); + cnt = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + puts ("** Bad FIT image format\n"); + return 1; + } + puts ("Fit image detected...\n"); + + cnt = fit_get_size (fit_hdr); + break; +#endif + default: + puts ("** Unknown image type\n"); return 1; } - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) { - puts ("\n** Bad Header Checksum **\n"); - return 1; - } - hdr->ih_hcrc = htonl(checksum); /* restore checksum for later use */ - - print_image_hdr (hdr); - cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); cnt += info.blksz - 1; cnt /= info.blksz; cnt -= 1; @@ -300,6 +314,13 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf ("** Read error on %d:%d\n", dev, part); return 1; } + +#if defined(CONFIG_FIT) + /* This cannot be done earlier, we need complete FIT image in RAM first */ + if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) + fit_print_contents ((const void *)addr); +#endif + /* Loading ok, update default load address */ load_addr = addr; diff --git a/common/cmd_setexpr.c b/common/cmd_setexpr.c new file mode 100644 index 000000000..2e49b6dd9 --- /dev/null +++ b/common/cmd_setexpr.c @@ -0,0 +1,70 @@ +/* + * Copyright 2008 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 + */ + +/* + * This file provides a shell like 'expr' function to return. + */ + +#include +#include +#include + +int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + ulong a, b; + char buf[16]; + + /* Validate arguments */ + if ((argc != 5) || (strlen(argv[3]) != 1)) { + printf("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + a = simple_strtoul(argv[2], NULL, 16); + b = simple_strtoul(argv[4], NULL, 16); + + switch (argv[3][0]) { + case '|': sprintf(buf, "%lx", (a | b)); break; + case '&': sprintf(buf, "%lx", (a & b)); break; + case '+': sprintf(buf, "%lx", (a + b)); break; + case '^': sprintf(buf, "%lx", (a ^ b)); break; + case '-': sprintf(buf, "%lx", (a - b)); break; + case '*': sprintf(buf, "%lx", (a * b)); break; + case '/': sprintf(buf, "%lx", (a / b)); break; + case '%': sprintf(buf, "%lx", (a % b)); break; + default: + printf("invalid op\n"); + return 1; + } + + setenv(argv[1], buf); + + return 0; +} + +U_BOOT_CMD( + setexpr, 5, 0, do_setexpr, + "setexpr - set environment variable as the result of eval expression\n", + "name value1 value2\n" + " - set environment variable 'name' to the result of the evaluated\n" + " express specified by . can be &, |, ^, +, -, *, /, %\n" +); diff --git a/common/cmd_usb.c b/common/cmd_usb.c index c6b17c2ab..23413b510 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -311,11 +311,13 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char *boot_device = NULL; char *ep; int dev, part=1, rcode; - ulong addr, cnt, checksum; + ulong addr, cnt; disk_partition_t info; image_header_t *hdr; block_dev_desc_t *stor_dev; - +#if defined(CONFIG_FIT) + const void *fit_hdr; +#endif switch (argc) { case 1: @@ -386,25 +388,36 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - hdr = (image_header_t *)addr; + switch (genimg_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - printf("\n** Bad Magic Number **\n"); + if (!image_check_hcrc (hdr)) { + puts ("\n** Bad Header Checksum **\n"); + return 1; + } + + image_print_contents (hdr); + + cnt = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + puts ("** Bad FIT image format\n"); + return 1; + } + puts ("Fit image detected...\n"); + + cnt = fit_get_size (fit_hdr); + break; +#endif + default: + puts ("** Unknown image type\n"); return 1; } - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) { - puts ("\n** Bad Header Checksum **\n"); - return 1; - } - hdr->ih_hcrc = htonl(checksum); /* restore checksum for later use */ - - print_image_hdr (hdr); - - cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); cnt += info.blksz - 1; cnt /= info.blksz; cnt -= 1; @@ -414,6 +427,13 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) printf ("\n** Read error on %d:%d\n", dev, part); return 1; } + +#if defined(CONFIG_FIT) + /* This cannot be done earlier, we need complete FIT image in RAM first */ + if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) + fit_print_contents ((const void *)addr); +#endif + /* Loading ok, update default load address */ load_addr = addr; @@ -529,8 +549,7 @@ int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } if (strncmp(argv[1], "stor", 4) == 0) { - usb_stor_info(); - return 0; + return usb_stor_info(); } if (strncmp(argv[1],"part",4) == 0) { diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c index 52e061449..7916fc197 100644 --- a/common/cmd_ximg.c +++ b/common/cmd_ximg.c @@ -24,7 +24,6 @@ * MA 02111-1307 USA */ -#if defined(CONFIG_CMD_XIMG) /* * Multi Image extract @@ -37,92 +36,136 @@ int do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { - ulong addr = load_addr, dest = 0; - ulong data, len, checksum; - ulong *len_ptr; - int i, verify, part = 0; - char pbuf[10], *s; - image_header_t header; + ulong addr = load_addr; + ulong dest = 0; + ulong data, len, count; + int verify; + int part = 0; + char pbuf[10]; + image_header_t *hdr; +#if defined(CONFIG_FIT) + const char *uname = NULL; + const void* fit_hdr; + int noffset; + const void *fit_data; + size_t fit_len; +#endif - s = getenv("verify"); - verify = (s && (*s == 'n')) ? 0 : 1; + verify = getenv_verify (); if (argc > 1) { addr = simple_strtoul(argv[1], NULL, 16); } if (argc > 2) { part = simple_strtoul(argv[2], NULL, 16); +#if defined(CONFIG_FIT) + uname = argv[2]; +#endif } if (argc > 3) { dest = simple_strtoul(argv[3], NULL, 16); } - printf("## Copying from image at %08lx ...\n", addr); + switch (genimg_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: - /* Copy header so we can blank CRC field for re-calculation */ - memmove(&header, (char *) addr, sizeof (image_header_t)); + printf("## Copying part %d from legacy image " + "at %08lx ...\n", part, addr); - if (ntohl(header.ih_magic) != IH_MAGIC) { - printf("Bad Magic Number\n"); - return 1; - } - - data = (ulong) & header; - len = sizeof (image_header_t); - - checksum = ntohl(header.ih_hcrc); - header.ih_hcrc = 0; - - if (crc32(0, (char *) data, len) != checksum) { - printf("Bad Header Checksum\n"); - return 1; - } -#ifdef DEBUG - print_image_hdr((image_header_t *) addr); -#endif - - data = addr + sizeof (image_header_t); - len = ntohl(header.ih_size); - - if (header.ih_type != IH_TYPE_MULTI) { - printf("Wrong Image Type for %s command\n", cmdtp->name); - return 1; - } - - if (header.ih_comp != IH_COMP_NONE) { - printf("Wrong Compression Type for %s command\n", cmdtp->name); - return 1; - } - - if (verify) { - printf(" Verifying Checksum ... "); - if (crc32(0, (char *) data, len) != ntohl(header.ih_dcrc)) { - printf("Bad Data CRC\n"); + hdr = (image_header_t *)addr; + if (!image_check_magic (hdr)) { + printf("Bad Magic Number\n"); return 1; } - printf("OK\n"); - } - len_ptr = (ulong *) data; + if (!image_check_hcrc (hdr)) { + printf("Bad Header Checksum\n"); + return 1; + } +#ifdef DEBUG + image_print_contents (hdr); +#endif - data += 4; /* terminator */ - for (i = 0; len_ptr[i]; ++i) { - data += 4; - if (argc > 2 && part > i) { - u_long tail; - len = ntohl(len_ptr[i]); - tail = len % 4; - data += len; - if (tail) { - data += 4 - tail; + if (!image_check_type (hdr, IH_TYPE_MULTI)) { + printf("Wrong Image Type for %s command\n", + cmdtp->name); + return 1; + } + + if (image_get_comp (hdr) != IH_COMP_NONE) { + printf("Wrong Compression Type for %s command\n", + cmdtp->name); + return 1; + } + + if (verify) { + printf(" Verifying Checksum ... "); + if (!image_check_dcrc (hdr)) { + printf("Bad Data CRC\n"); + return 1; + } + printf("OK\n"); + } + + count = image_multi_count (hdr); + if (part >= count) { + printf("Bad Image Part\n"); + return 1; + } + + image_multi_getimg (hdr, part, &data, &len); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + if (uname == NULL) { + puts ("No FIT subimage unit name\n"); + return 1; + } + + printf("## Copying '%s' subimage from FIT image " + "at %08lx ...\n", uname, addr); + + fit_hdr = (const void *)addr; + if (!fit_check_format (fit_hdr)) { + puts ("Bad FIT image format\n"); + return 1; + } + + /* get subimage node offset */ + noffset = fit_image_get_node (fit_hdr, uname); + if (noffset < 0) { + printf ("Can't find '%s' FIT subimage\n", uname); + return 1; + } + + if (fit_image_check_comp (fit_hdr, noffset, IH_COMP_NONE)) { + printf("Wrong Compression Type for %s command\n", + cmdtp->name); + return 1; + } + + /* verify integrity */ + if (verify) { + if (!fit_image_check_hashes (fit_hdr, noffset)) { + puts ("Bad Data Hash\n"); + return 1; } } - } - if (argc > 2 && part >= i) { - printf("Bad Image Part\n"); + + /* get subimage data address and length */ + if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) { + puts ("Could not find script subimage data\n"); + return 1; + } + + data = (ulong)fit_data; + len = (ulong)fit_len; + break; +#endif + default: + puts ("Invalid image type for imxtract\n"); return 1; } - len = ntohl(len_ptr[part]); if (argc > 3) { memcpy((char *) dest, (char *) data, len); @@ -139,6 +182,9 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) U_BOOT_CMD(imxtract, 4, 1, do_imgextract, "imxtract- extract a part of a multi-image\n", "addr part [dest]\n" - " - extract from image at and copy to \n"); - + " - extract from legacy image at and copy to \n" +#if defined(CONFIG_FIT) + "addr uname [dest]\n" + " - extract subimage from FIT image at and copy to \n" #endif +); diff --git a/common/fdt_support.c b/common/fdt_support.c index 69eb66795..75077442d 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -40,7 +40,6 @@ DECLARE_GLOBAL_DATA_PTR; */ struct fdt_header *fdt; -/********************************************************************/ /** * fdt_find_and_setprop: Find a node and set it's property @@ -218,198 +217,6 @@ int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force) return err; } -/********************************************************************/ - -#ifdef CONFIG_OF_HAS_UBOOT_ENV - -/* Function that returns a character from the environment */ -extern uchar(*env_get_char) (int); - - -int fdt_env(void *fdt) -{ - int nodeoffset; - int err; - int k, nxt; - int i; - static char tmpenv[256]; - - err = fdt_check_header(fdt); - if (err < 0) { - printf("fdt_env: %s\n", fdt_strerror(err)); - return err; - } - - /* - * See if we already have a "u-boot-env" node, delete it if so. - * Then create a new empty node. - */ - nodeoffset = fdt_path_offset (fdt, "/u-boot-env"); - if (nodeoffset >= 0) { - err = fdt_del_node(fdt, nodeoffset); - if (err < 0) { - printf("fdt_env: %s\n", fdt_strerror(err)); - return err; - } - } - /* - * Create a new node "/u-boot-env" (offset 0 is root level) - */ - nodeoffset = fdt_add_subnode(fdt, 0, "u-boot-env"); - if (nodeoffset < 0) { - printf("WARNING: could not create /u-boot-env %s.\n", - fdt_strerror(nodeoffset)); - return nodeoffset; - } - - for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { - char *s, *lval, *rval; - - /* - * Find the end of the name=definition - */ - for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) - ; - s = tmpenv; - for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k) - *s++ = env_get_char(k); - *s++ = '\0'; - lval = tmpenv; - /* - * Find the first '=': it separates the name from the value - */ - s = strchr(tmpenv, '='); - if (s != NULL) { - *s++ = '\0'; - rval = s; - } else - continue; - err = fdt_setprop(fdt, nodeoffset, lval, rval, strlen(rval)+1); - if (err < 0) { - printf("WARNING: could not set %s %s.\n", - lval, fdt_strerror(err)); - return err; - } - } - return 0; -} -#endif /* ifdef CONFIG_OF_HAS_UBOOT_ENV */ - -/********************************************************************/ - -#ifdef CONFIG_OF_HAS_BD_T - -#define BDM(x) { .name = #x, .offset = offsetof(bd_t, bi_ ##x ) } - -static const struct { - const char *name; - int offset; -} bd_map[] = { - BDM(memstart), - BDM(memsize), - BDM(flashstart), - BDM(flashsize), - BDM(flashoffset), - BDM(sramstart), - BDM(sramsize), -#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \ - || defined(CONFIG_E500) - BDM(immr_base), -#endif -#if defined(CONFIG_MPC5xxx) - BDM(mbar_base), -#endif -#if defined(CONFIG_MPC83XX) - BDM(immrbar), -#endif -#if defined(CONFIG_MPC8220) - BDM(mbar_base), - BDM(inpfreq), - BDM(pcifreq), - BDM(pevfreq), - BDM(flbfreq), - BDM(vcofreq), -#endif - BDM(bootflags), - BDM(ip_addr), - BDM(intfreq), - BDM(busfreq), -#ifdef CONFIG_CPM2 - BDM(cpmfreq), - BDM(brgfreq), - BDM(sccfreq), - BDM(vco), -#endif -#if defined(CONFIG_MPC5xxx) - BDM(ipbfreq), - BDM(pcifreq), -#endif - BDM(baudrate), -}; - - -int fdt_bd_t(void *fdt) -{ - bd_t *bd = gd->bd; - int nodeoffset; - int err; - u32 tmp; /* used to set 32 bit integer properties */ - int i; - - err = fdt_check_header(fdt); - if (err < 0) { - printf("fdt_bd_t: %s\n", fdt_strerror(err)); - return err; - } - - /* - * See if we already have a "bd_t" node, delete it if so. - * Then create a new empty node. - */ - nodeoffset = fdt_path_offset (fdt, "/bd_t"); - if (nodeoffset >= 0) { - err = fdt_del_node(fdt, nodeoffset); - if (err < 0) { - printf("fdt_bd_t: %s\n", fdt_strerror(err)); - return err; - } - } - /* - * Create a new node "/bd_t" (offset 0 is root level) - */ - nodeoffset = fdt_add_subnode(fdt, 0, "bd_t"); - if (nodeoffset < 0) { - printf("WARNING: could not create /bd_t %s.\n", - fdt_strerror(nodeoffset)); - printf("fdt_bd_t: %s\n", fdt_strerror(nodeoffset)); - return nodeoffset; - } - /* - * Use the string/pointer structure to create the entries... - */ - for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) { - tmp = cpu_to_be32(getenv("bootargs")); - err = fdt_setprop(fdt, nodeoffset, - bd_map[i].name, &tmp, sizeof(tmp)); - if (err < 0) - printf("WARNING: could not set %s %s.\n", - bd_map[i].name, fdt_strerror(err)); - } - /* - * Add a couple of oddball entries... - */ - err = fdt_setprop(fdt, nodeoffset, "enetaddr", &bd->bi_enetaddr, 6); - if (err < 0) - printf("WARNING: could not set enetaddr %s.\n", - fdt_strerror(err)); - err = fdt_setprop(fdt, nodeoffset, "ethspeed", &bd->bi_ethspeed, 4); - if (err < 0) - printf("WARNING: could not set ethspeed %s.\n", - fdt_strerror(err)); - return 0; -} -#endif /* ifdef CONFIG_OF_HAS_BD_T */ - void do_fixup_by_path(void *fdt, const char *path, const char *prop, const void *val, int len, int create) { @@ -615,3 +422,28 @@ void fdt_fixup_ethernet(void *fdt, bd_t *bd) } } #endif + +#ifdef CONFIG_HAS_FSL_DR_USB +void fdt_fixup_dr_usb(void *blob, bd_t *bd) +{ + char *mode; + const char *compat = "fsl-usb2-dr"; + const char *prop = "dr_mode"; + int node_offset; + int err; + + mode = getenv("usb_dr_mode"); + if (!mode) + return; + + node_offset = fdt_node_offset_by_compatible(blob, 0, compat); + if (node_offset < 0) + printf("WARNING: could not find compatible node %s: %s.\n", + compat, fdt_strerror(node_offset)); + + err = fdt_setprop(blob, node_offset, prop, mode, strlen(mode) + 1); + if (err < 0) + printf("WARNING: could not set %s for %s: %s.\n", + prop, compat, fdt_strerror(err)); +} +#endif /* CONFIG_HAS_FSL_DR_USB */ diff --git a/common/gunzip.c b/common/gunzip.c new file mode 100644 index 000000000..74f0bf9f3 --- /dev/null +++ b/common/gunzip.c @@ -0,0 +1,113 @@ +/* + * (C) Copyright 2000-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +#define ZALLOC_ALIGNMENT 16 +#define HEAD_CRC 2 +#define EXTRA_FIELD 4 +#define ORIG_NAME 8 +#define COMMENT 0x10 +#define RESERVED 0xe0 +#define DEFLATED 8 + +int gunzip(void *, int, unsigned char *, unsigned long *); +void *zalloc(void *, unsigned, unsigned); +void zfree(void *, void *, unsigned); + +void *zalloc(void *x, unsigned items, unsigned size) +{ + void *p; + + size *= items; + size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1); + + p = malloc (size); + + return (p); +} + +void zfree(void *x, void *addr, unsigned nb) +{ + free (addr); +} + +int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp) +{ + z_stream s; + int r, i, flags; + + /* skip header */ + i = 10; + flags = src[3]; + if (src[2] != DEFLATED || (flags & RESERVED) != 0) { + puts ("Error: Bad gzipped data\n"); + return (-1); + } + if ((flags & EXTRA_FIELD) != 0) + i = 12 + src[10] + (src[11] << 8); + if ((flags & ORIG_NAME) != 0) + while (src[i++] != 0) + ; + if ((flags & COMMENT) != 0) + while (src[i++] != 0) + ; + if ((flags & HEAD_CRC) != 0) + i += 2; + if (i >= *lenp) { + puts ("Error: gunzip out of data in header\n"); + return (-1); + } + + s.zalloc = zalloc; + s.zfree = zfree; +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) + s.outcb = (cb_func)WATCHDOG_RESET; +#else + s.outcb = Z_NULL; +#endif /* CONFIG_HW_WATCHDOG */ + + r = inflateInit2(&s, -MAX_WBITS); + if (r != Z_OK) { + printf ("Error: inflateInit2() returned %d\n", r); + return (-1); + } + s.next_in = src + i; + s.avail_in = *lenp - i; + s.next_out = dst; + s.avail_out = dstlen; + r = inflate(&s, Z_FINISH); + if (r != Z_OK && r != Z_STREAM_END) { + printf ("Error: inflate() returned %d\n", r); + return (-1); + } + *lenp = s.next_out - (unsigned char *) dst; + inflateEnd(&s); + + return (0); +} diff --git a/common/image.c b/common/image.c new file mode 100644 index 000000000..f04826a5c --- /dev/null +++ b/common/image.c @@ -0,0 +1,2541 @@ +/* + * (C) Copyright 2008 Semihalf + * + * (C) Copyright 2000-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#ifndef USE_HOSTCC +#include +#include + +#ifdef CONFIG_SHOW_BOOT_PROGRESS +#include +#endif + +#ifdef CONFIG_HAS_DATAFLASH +#include +#endif + +#ifdef CONFIG_LOGBUFFER +#include +#endif + +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) +#include +#endif + +#include + +#if defined(CONFIG_FIT) || defined (CONFIG_OF_LIBFDT) +#include +#include +#include +#endif + +#if defined(CONFIG_FIT) +#include +#include + +static int fit_check_ramdisk (const void *fit, int os_noffset, + uint8_t arch, int verify); +#endif + +#ifdef CONFIG_CMD_BDI +extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +#endif + +DECLARE_GLOBAL_DATA_PTR; + +static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch, + int verify); +#else +#include "mkimage.h" +#include +#include +#include +#endif /* !USE_HOSTCC*/ + +typedef struct table_entry { + int id; /* as defined in image.h */ + char *sname; /* short (input) name */ + char *lname; /* long (output) name */ +} table_entry_t; + +static table_entry_t uimage_arch[] = { + { IH_ARCH_INVALID, NULL, "Invalid ARCH", }, + { IH_ARCH_ALPHA, "alpha", "Alpha", }, + { IH_ARCH_ARM, "arm", "ARM", }, + { IH_ARCH_I386, "x86", "Intel x86", }, + { IH_ARCH_IA64, "ia64", "IA64", }, + { IH_ARCH_M68K, "m68k", "M68K", }, + { IH_ARCH_MICROBLAZE, "microblaze", "MicroBlaze", }, + { IH_ARCH_MIPS, "mips", "MIPS", }, + { IH_ARCH_MIPS64, "mips64", "MIPS 64 Bit", }, + { IH_ARCH_NIOS, "nios", "NIOS", }, + { IH_ARCH_NIOS2, "nios2", "NIOS II", }, + { IH_ARCH_PPC, "ppc", "PowerPC", }, + { IH_ARCH_S390, "s390", "IBM S390", }, + { IH_ARCH_SH, "sh", "SuperH", }, + { IH_ARCH_SPARC, "sparc", "SPARC", }, + { IH_ARCH_SPARC64, "sparc64", "SPARC 64 Bit", }, + { IH_ARCH_BLACKFIN, "blackfin", "Blackfin", }, + { IH_ARCH_AVR32, "avr32", "AVR32", }, + { -1, "", "", }, +}; + +static table_entry_t uimage_os[] = { + { IH_OS_INVALID, NULL, "Invalid OS", }, +#if defined(CONFIG_ARTOS) || defined(USE_HOSTCC) + { IH_OS_ARTOS, "artos", "ARTOS", }, +#endif + { IH_OS_LINUX, "linux", "Linux", }, +#if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC) + { IH_OS_LYNXOS, "lynxos", "LynxOS", }, +#endif + { IH_OS_NETBSD, "netbsd", "NetBSD", }, + { IH_OS_RTEMS, "rtems", "RTEMS", }, + { IH_OS_U_BOOT, "u-boot", "U-Boot", }, +#if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC) + { IH_OS_QNX, "qnx", "QNX", }, + { IH_OS_VXWORKS, "vxworks", "VxWorks", }, +#endif +#ifdef USE_HOSTCC + { IH_OS_4_4BSD, "4_4bsd", "4_4BSD", }, + { IH_OS_DELL, "dell", "Dell", }, + { IH_OS_ESIX, "esix", "Esix", }, + { IH_OS_FREEBSD, "freebsd", "FreeBSD", }, + { IH_OS_IRIX, "irix", "Irix", }, + { IH_OS_NCR, "ncr", "NCR", }, + { IH_OS_OPENBSD, "openbsd", "OpenBSD", }, + { IH_OS_PSOS, "psos", "pSOS", }, + { IH_OS_SCO, "sco", "SCO", }, + { IH_OS_SOLARIS, "solaris", "Solaris", }, + { IH_OS_SVR4, "svr4", "SVR4", }, +#endif + { -1, "", "", }, +}; + +static table_entry_t uimage_type[] = { + { IH_TYPE_INVALID, NULL, "Invalid Image", }, + { IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", }, + { IH_TYPE_FIRMWARE, "firmware", "Firmware", }, + { IH_TYPE_KERNEL, "kernel", "Kernel Image", }, + { IH_TYPE_MULTI, "multi", "Multi-File Image", }, + { IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", }, + { IH_TYPE_SCRIPT, "script", "Script", }, + { IH_TYPE_STANDALONE, "standalone", "Standalone Program", }, + { IH_TYPE_FLATDT, "flat_dt", "Flat Device Tree", }, + { -1, "", "", }, +}; + +static table_entry_t uimage_comp[] = { + { IH_COMP_NONE, "none", "uncompressed", }, + { IH_COMP_BZIP2, "bzip2", "bzip2 compressed", }, + { IH_COMP_GZIP, "gzip", "gzip compressed", }, + { -1, "", "", }, +}; + +unsigned long crc32 (unsigned long, const unsigned char *, unsigned int); +static void genimg_print_size (uint32_t size); +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) +static void genimg_print_time (time_t timestamp); +#endif + +/*****************************************************************************/ +/* Legacy format routines */ +/*****************************************************************************/ +int image_check_hcrc (image_header_t *hdr) +{ + ulong hcrc; + ulong len = image_get_header_size (); + image_header_t header; + + /* Copy header so we can blank CRC field for re-calculation */ + memmove (&header, (char *)hdr, image_get_header_size ()); + image_set_hcrc (&header, 0); + + hcrc = crc32 (0, (unsigned char *)&header, len); + + return (hcrc == image_get_hcrc (hdr)); +} + +int image_check_dcrc (image_header_t *hdr) +{ + ulong data = image_get_data (hdr); + ulong len = image_get_data_size (hdr); + ulong dcrc = crc32 (0, (unsigned char *)data, len); + + return (dcrc == image_get_dcrc (hdr)); +} + +#ifndef USE_HOSTCC +int image_check_dcrc_wd (image_header_t *hdr, ulong chunksz) +{ + ulong dcrc = 0; + ulong len = image_get_data_size (hdr); + ulong data = image_get_data (hdr); + +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) + ulong cdata = data; + ulong edata = cdata + len; + + while (cdata < edata) { + ulong chunk = edata - cdata; + + if (chunk > chunksz) + chunk = chunksz; + dcrc = crc32 (dcrc, (unsigned char *)cdata, chunk); + cdata += chunk; + + WATCHDOG_RESET (); + } +#else + dcrc = crc32 (0, (unsigned char *)data, len); +#endif + + return (dcrc == image_get_dcrc (hdr)); +} +#endif /* !USE_HOSTCC */ + +/** + * image_multi_count - get component (sub-image) count + * @hdr: pointer to the header of the multi component image + * + * image_multi_count() returns number of components in a multi + * component image. + * + * Note: no checking of the image type is done, caller must pass + * a valid multi component image. + * + * returns: + * number of components + */ +ulong image_multi_count (image_header_t *hdr) +{ + ulong i, count = 0; + uint32_t *size; + + /* get start of the image payload, which in case of multi + * component images that points to a table of component sizes */ + size = (uint32_t *)image_get_data (hdr); + + /* count non empty slots */ + for (i = 0; size[i]; ++i) + count++; + + return count; +} + +/** + * image_multi_getimg - get component data address and size + * @hdr: pointer to the header of the multi component image + * @idx: index of the requested component + * @data: pointer to a ulong variable, will hold component data address + * @len: pointer to a ulong variable, will hold component size + * + * image_multi_getimg() returns size and data address for the requested + * component in a multi component image. + * + * Note: no checking of the image type is done, caller must pass + * a valid multi component image. + * + * returns: + * data address and size of the component, if idx is valid + * 0 in data and len, if idx is out of range + */ +void image_multi_getimg (image_header_t *hdr, ulong idx, + ulong *data, ulong *len) +{ + int i; + uint32_t *size; + ulong offset, tail, count, img_data; + + /* get number of component */ + count = image_multi_count (hdr); + + /* get start of the image payload, which in case of multi + * component images that points to a table of component sizes */ + size = (uint32_t *)image_get_data (hdr); + + /* get address of the proper component data start, which means + * skipping sizes table (add 1 for last, null entry) */ + img_data = image_get_data (hdr) + (count + 1) * sizeof (uint32_t); + + if (idx < count) { + *len = uimage_to_cpu (size[idx]); + offset = 0; + tail = 0; + + /* go over all indices preceding requested component idx */ + for (i = 0; i < idx; i++) { + /* add up i-th component size */ + offset += uimage_to_cpu (size[i]); + + /* add up alignment for i-th component */ + tail += (4 - uimage_to_cpu (size[i]) % 4); + } + + /* calculate idx-th component data address */ + *data = img_data + offset + tail; + } else { + *len = 0; + *data = 0; + } +} + +static void image_print_type (image_header_t *hdr) +{ + const char *os, *arch, *type, *comp; + + os = genimg_get_os_name (image_get_os (hdr)); + arch = genimg_get_arch_name (image_get_arch (hdr)); + type = genimg_get_type_name (image_get_type (hdr)); + comp = genimg_get_comp_name (image_get_comp (hdr)); + + printf ("%s %s %s (%s)\n", arch, os, type, comp); +} + +/** + * __image_print_contents - prints out the contents of the legacy format image + * @hdr: pointer to the legacy format image header + * @p: pointer to prefix string + * + * __image_print_contents() formats a multi line legacy image contents description. + * The routine prints out all header fields followed by the size/offset data + * for MULTI/SCRIPT images. + * + * returns: + * no returned results + */ +static void __image_print_contents (image_header_t *hdr, const char *p) +{ + printf ("%sImage Name: %.*s\n", p, IH_NMLEN, image_get_name (hdr)); +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) + printf ("%sCreated: ", p); + genimg_print_time ((time_t)image_get_time (hdr)); +#endif + printf ("%sImage Type: ", p); + image_print_type (hdr); + printf ("%sData Size: ", p); + genimg_print_size (image_get_data_size (hdr)); + printf ("%sLoad Address: %08x\n", p, image_get_load (hdr)); + printf ("%sEntry Point: %08x\n", p, image_get_ep (hdr)); + + if (image_check_type (hdr, IH_TYPE_MULTI) || + image_check_type (hdr, IH_TYPE_SCRIPT)) { + int i; + ulong data, len; + ulong count = image_multi_count (hdr); + + printf ("%sContents:\n", p); + for (i = 0; i < count; i++) { + image_multi_getimg (hdr, i, &data, &len); + + printf ("%s Image %d: ", p, i); + genimg_print_size (len); + + if (image_check_type (hdr, IH_TYPE_SCRIPT) && i > 0) { + /* + * the user may need to know offsets + * if planning to do something with + * multiple files + */ + printf ("%s Offset = 0x%08lx\n", p, data); + } + } + } +} + +inline void image_print_contents (image_header_t *hdr) +{ + __image_print_contents (hdr, " "); +} + +inline void image_print_contents_noindent (image_header_t *hdr) +{ + __image_print_contents (hdr, ""); +} + +#ifndef USE_HOSTCC +/** + * image_get_ramdisk - get and verify ramdisk image + * @rd_addr: ramdisk image start address + * @arch: expected ramdisk architecture + * @verify: checksum verification flag + * + * image_get_ramdisk() returns a pointer to the verified ramdisk image + * header. Routine receives image start address and expected architecture + * flag. Verification done covers data and header integrity and os/type/arch + * fields checking. + * + * If dataflash support is enabled routine checks for dataflash addresses + * and handles required dataflash reads. + * + * returns: + * pointer to a ramdisk image header, if image was found and valid + * otherwise, return NULL + */ +static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch, + int verify) +{ + image_header_t *rd_hdr = (image_header_t *)rd_addr; + + if (!image_check_magic (rd_hdr)) { + puts ("Bad Magic Number\n"); + show_boot_progress (-10); + return NULL; + } + + if (!image_check_hcrc (rd_hdr)) { + puts ("Bad Header Checksum\n"); + show_boot_progress (-11); + return NULL; + } + + show_boot_progress (10); + image_print_contents (rd_hdr); + + if (verify) { + puts(" Verifying Checksum ... "); + if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) { + puts ("Bad Data CRC\n"); + show_boot_progress (-12); + return NULL; + } + puts("OK\n"); + } + + show_boot_progress (11); + + if (!image_check_os (rd_hdr, IH_OS_LINUX) || + !image_check_arch (rd_hdr, arch) || + !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) { + printf ("No Linux %s Ramdisk Image\n", + genimg_get_arch_name(arch)); + show_boot_progress (-13); + return NULL; + } + + return rd_hdr; +} +#endif /* !USE_HOSTCC */ + +/*****************************************************************************/ +/* Shared dual-format routines */ +/*****************************************************************************/ +#ifndef USE_HOSTCC +int getenv_verify (void) +{ + char *s = getenv ("verify"); + return (s && (*s == 'n')) ? 0 : 1; +} + +int getenv_autostart (void) +{ + char *s = getenv ("autostart"); + return (s && (*s == 'n')) ? 0 : 1; +} + +ulong getenv_bootm_low(void) +{ + char *s = getenv ("bootm_low"); + if (s) { + ulong tmp = simple_strtoul (s, NULL, 16); + return tmp; + } + +#if defined(CFG_SDRAM_BASE) + return CFG_SDRAM_BASE; +#elif defined(CONFIG_ARM) + return gd->bd->bi_dram[0].start; +#else + return 0; +#endif +} + +ulong getenv_bootm_size(void) +{ + char *s = getenv ("bootm_size"); + if (s) { + ulong tmp = simple_strtoul (s, NULL, 16); + return tmp; + } + +#if defined(CONFIG_ARM) + return gd->bd->bi_dram[0].size; +#else + return gd->bd->bi_memsize; +#endif +} + +void memmove_wd (void *to, void *from, size_t len, ulong chunksz) +{ +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) + while (len > 0) { + size_t tail = (len > chunksz) ? chunksz : len; + WATCHDOG_RESET (); + memmove (to, from, tail); + to += tail; + from += tail; + len -= tail; + } +#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ + memmove (to, from, len); +#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ +} +#endif /* !USE_HOSTCC */ + +static void genimg_print_size (uint32_t size) +{ +#ifndef USE_HOSTCC + printf ("%d Bytes = ", size); + print_size (size, "\n"); +#else + printf ("%d Bytes = %.2f kB = %.2f MB\n", + size, (double)size / 1.024e3, + (double)size / 1.048576e6); +#endif +} + +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) +static void genimg_print_time (time_t timestamp) +{ +#ifndef USE_HOSTCC + struct rtc_time tm; + + to_tm (timestamp, &tm); + printf ("%4d-%02d-%02d %2d:%02d:%02d UTC\n", + tm.tm_year, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); +#else + printf ("%s", ctime(×tamp)); +#endif +} +#endif /* CONFIG_TIMESTAMP || CONFIG_CMD_DATE || USE_HOSTCC */ + +/** + * get_table_entry_name - translate entry id to long name + * @table: pointer to a translation table for entries of a specific type + * @msg: message to be returned when translation fails + * @id: entry id to be translated + * + * get_table_entry_name() will go over translation table trying to find + * entry that matches given id. If matching entry is found, its long + * name is returned to the caller. + * + * returns: + * long entry name if translation succeeds + * msg otherwise + */ +static char *get_table_entry_name (table_entry_t *table, char *msg, int id) +{ + for (; table->id >= 0; ++table) { + if (table->id == id) + return (table->lname); + } + return (msg); +} + +const char *genimg_get_os_name (uint8_t os) +{ + return (get_table_entry_name (uimage_os, "Unknown OS", os)); +} + +const char *genimg_get_arch_name (uint8_t arch) +{ + return (get_table_entry_name (uimage_arch, "Unknown Architecture", arch)); +} + +const char *genimg_get_type_name (uint8_t type) +{ + return (get_table_entry_name (uimage_type, "Unknown Image", type)); +} + +const char *genimg_get_comp_name (uint8_t comp) +{ + return (get_table_entry_name (uimage_comp, "Unknown Compression", comp)); +} + +/** + * get_table_entry_id - translate short entry name to id + * @table: pointer to a translation table for entries of a specific type + * @table_name: to be used in case of error + * @name: entry short name to be translated + * + * get_table_entry_id() will go over translation table trying to find + * entry that matches given short name. If matching entry is found, + * its id returned to the caller. + * + * returns: + * entry id if translation succeeds + * -1 otherwise + */ +static int get_table_entry_id (table_entry_t *table, + const char *table_name, const char *name) +{ + table_entry_t *t; +#ifdef USE_HOSTCC + int first = 1; + + for (t = table; t->id >= 0; ++t) { + if (t->sname && strcasecmp(t->sname, name) == 0) + return (t->id); + } + + fprintf (stderr, "\nInvalid %s Type - valid names are", table_name); + for (t = table; t->id >= 0; ++t) { + if (t->sname == NULL) + continue; + fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname); + first = 0; + } + fprintf (stderr, "\n"); +#else + for (t = table; t->id >= 0; ++t) { + if (t->sname && strcmp(t->sname, name) == 0) + return (t->id); + } + debug ("Invalid %s Type: %s\n", table_name, name); +#endif /* USE_HOSTCC */ + return (-1); +} + +int genimg_get_os_id (const char *name) +{ + return (get_table_entry_id (uimage_os, "OS", name)); +} + +int genimg_get_arch_id (const char *name) +{ + return (get_table_entry_id (uimage_arch, "CPU", name)); +} + +int genimg_get_type_id (const char *name) +{ + return (get_table_entry_id (uimage_type, "Image", name)); +} + +int genimg_get_comp_id (const char *name) +{ + return (get_table_entry_id (uimage_comp, "Compression", name)); +} + +#ifndef USE_HOSTCC +/** + * genimg_get_format - get image format type + * @img_addr: image start address + * + * genimg_get_format() checks whether provided address points to a valid + * legacy or FIT image. + * + * New uImage format and FDT blob are based on a libfdt. FDT blob + * may be passed directly or embedded in a FIT image. In both situations + * genimg_get_format() must be able to dectect libfdt header. + * + * returns: + * image format type or IMAGE_FORMAT_INVALID if no image is present + */ +int genimg_get_format (void *img_addr) +{ + ulong format = IMAGE_FORMAT_INVALID; + image_header_t *hdr; +#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) + char *fit_hdr; +#endif + + hdr = (image_header_t *)img_addr; + if (image_check_magic(hdr)) + format = IMAGE_FORMAT_LEGACY; +#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT) + else { + fit_hdr = (char *)img_addr; + if (fdt_check_header (fit_hdr) == 0) + format = IMAGE_FORMAT_FIT; + } +#endif + + return format; +} + +/** + * genimg_get_image - get image from special storage (if necessary) + * @img_addr: image start address + * + * genimg_get_image() checks if provided image start adddress is located + * in a dataflash storage. If so, image is moved to a system RAM memory. + * + * returns: + * image start address after possible relocation from special storage + */ +ulong genimg_get_image (ulong img_addr) +{ + ulong ram_addr = img_addr; + +#ifdef CONFIG_HAS_DATAFLASH + ulong h_size, d_size; + + if (addr_dataflash (img_addr)){ + /* ger RAM address */ + ram_addr = CFG_LOAD_ADDR; + + /* get header size */ + h_size = image_get_header_size (); +#if defined(CONFIG_FIT) + if (sizeof(struct fdt_header) > h_size) + h_size = sizeof(struct fdt_header); +#endif + + /* read in header */ + debug (" Reading image header from dataflash address " + "%08lx to RAM address %08lx\n", img_addr, ram_addr); + + read_dataflash (img_addr, h_size, (char *)ram_addr); + + /* get data size */ + switch (genimg_get_format ((void *)ram_addr)) { + case IMAGE_FORMAT_LEGACY: + d_size = image_get_data_size ((image_header_t *)ram_addr); + debug (" Legacy format image found at 0x%08lx, size 0x%08lx\n", + ram_addr, d_size); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + d_size = fit_get_size ((const void *)ram_addr) - h_size; + debug (" FIT/FDT format image found at 0x%08lx, size 0x%08lx\n", + ram_addr, d_size); + break; +#endif + default: + printf (" No valid image found at 0x%08lx\n", img_addr); + return ram_addr; + } + + /* read in image data */ + debug (" Reading image remaining data from dataflash address " + "%08lx to RAM address %08lx\n", img_addr + h_size, + ram_addr + h_size); + + read_dataflash (img_addr + h_size, d_size, + (char *)(ram_addr + h_size)); + + } +#endif /* CONFIG_HAS_DATAFLASH */ + + return ram_addr; +} + +/** + * fit_has_config - check if there is a valid FIT configuration + * @images: pointer to the bootm command headers structure + * + * fit_has_config() checks if there is a FIT configuration in use + * (if FTI support is present). + * + * returns: + * 0, no FIT support or no configuration found + * 1, configuration found + */ +int genimg_has_config (bootm_headers_t *images) +{ +#if defined(CONFIG_FIT) + if (images->fit_uname_cfg) + return 1; +#endif + return 0; +} + +/** + * boot_get_ramdisk - main ramdisk handling routine + * @argc: command argument count + * @argv: command argument list + * @images: pointer to the bootm images structure + * @arch: expected ramdisk architecture + * @rd_start: pointer to a ulong variable, will hold ramdisk start address + * @rd_end: pointer to a ulong variable, will hold ramdisk end + * + * boot_get_ramdisk() is responsible for finding a valid ramdisk image. + * Curently supported are the following ramdisk sources: + * - multicomponent kernel/ramdisk image, + * - commandline provided address of decicated ramdisk image. + * + * returns: + * 0, if ramdisk image was found and valid, or skiped + * rd_start and rd_end are set to ramdisk start/end addresses if + * ramdisk image is found and valid + * + * 1, if ramdisk image is found but corrupted + * rd_start and rd_end are set to 0 if no ramdisk exists + */ +int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, + uint8_t arch, ulong *rd_start, ulong *rd_end) +{ + ulong rd_addr, rd_load; + ulong rd_data, rd_len; + image_header_t *rd_hdr; +#if defined(CONFIG_FIT) + void *fit_hdr; + const char *fit_uname_config = NULL; + const char *fit_uname_ramdisk = NULL; + ulong default_addr; + int rd_noffset; + int cfg_noffset; + const void *data; + size_t size; +#endif + + *rd_start = 0; + *rd_end = 0; + + /* + * Look for a '-' which indicates to ignore the + * ramdisk argument + */ + if ((argc >= 3) && (strcmp(argv[2], "-") == 0)) { + debug ("## Skipping init Ramdisk\n"); + rd_len = rd_data = 0; + } else if (argc >= 3 || genimg_has_config (images)) { +#if defined(CONFIG_FIT) + if (argc >= 3) { + /* + * If the init ramdisk comes from the FIT image and + * the FIT image address is omitted in the command + * line argument, try to use os FIT image address or + * default load address. + */ + if (images->fit_uname_os) + default_addr = (ulong)images->fit_hdr_os; + else + default_addr = load_addr; + + if (fit_parse_conf (argv[2], default_addr, + &rd_addr, &fit_uname_config)) { + debug ("* ramdisk: config '%s' from image at 0x%08lx\n", + fit_uname_config, rd_addr); + } else if (fit_parse_subimage (argv[2], default_addr, + &rd_addr, &fit_uname_ramdisk)) { + debug ("* ramdisk: subimage '%s' from image at 0x%08lx\n", + fit_uname_ramdisk, rd_addr); + } else +#endif + { + rd_addr = simple_strtoul(argv[2], NULL, 16); + debug ("* ramdisk: cmdline image address = 0x%08lx\n", + rd_addr); + } +#if defined(CONFIG_FIT) + } else { + /* use FIT configuration provided in first bootm + * command argument + */ + rd_addr = (ulong)images->fit_hdr_os; + fit_uname_config = images->fit_uname_cfg; + debug ("* ramdisk: using config '%s' from image at 0x%08lx\n", + fit_uname_config, rd_addr); + + /* + * Check whether configuration has ramdisk defined, + * if not, don't try to use it, quit silently. + */ + fit_hdr = (void *)rd_addr; + cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); + if (cfg_noffset < 0) { + debug ("* ramdisk: no such config\n"); + return 0; + } + + rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset); + if (rd_noffset < 0) { + debug ("* ramdisk: no ramdisk in config\n"); + return 0; + } + } +#endif + + /* copy from dataflash if needed */ + rd_addr = genimg_get_image (rd_addr); + + /* + * Check if there is an initrd image at the + * address provided in the second bootm argument + * check image type, for FIT images get FIT node. + */ + switch (genimg_get_format ((void *)rd_addr)) { + case IMAGE_FORMAT_LEGACY: + printf ("## Loading init Ramdisk from Legacy " + "Image at %08lx ...\n", rd_addr); + + show_boot_progress (9); + rd_hdr = image_get_ramdisk (rd_addr, arch, + images->verify); + + if (rd_hdr == NULL) + return 1; + + rd_data = image_get_data (rd_hdr); + rd_len = image_get_data_size (rd_hdr); + rd_load = image_get_load (rd_hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (void *)rd_addr; + printf ("## Loading init Ramdisk from FIT " + "Image at %08lx ...\n", rd_addr); + + show_boot_progress (120); + if (!fit_check_format (fit_hdr)) { + puts ("Bad FIT ramdisk image format!\n"); + show_boot_progress (-120); + return 0; + } + show_boot_progress (121); + + if (!fit_uname_ramdisk) { + /* + * no ramdisk image node unit name, try to get config + * node first. If config unit node name is NULL + * fit_conf_get_node() will try to find default config node + */ + show_boot_progress (122); + cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); + if (cfg_noffset < 0) { + puts ("Could not find configuration node\n"); + show_boot_progress (-122); + return 0; + } + fit_uname_config = fdt_get_name (fit_hdr, cfg_noffset, NULL); + printf (" Using '%s' configuration\n", fit_uname_config); + + rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset); + fit_uname_ramdisk = fit_get_name (fit_hdr, rd_noffset, NULL); + } else { + /* get ramdisk component image node offset */ + show_boot_progress (123); + rd_noffset = fit_image_get_node (fit_hdr, fit_uname_ramdisk); + } + if (rd_noffset < 0) { + puts ("Could not find subimage node\n"); + show_boot_progress (-124); + return 0; + } + + printf (" Trying '%s' ramdisk subimage\n", fit_uname_ramdisk); + + show_boot_progress (125); + if (!fit_check_ramdisk (fit_hdr, rd_noffset, arch, images->verify)) + return 0; + + /* get ramdisk image data address and length */ + if (fit_image_get_data (fit_hdr, rd_noffset, &data, &size)) { + puts ("Could not find ramdisk subimage data!\n"); + show_boot_progress (-127); + return 0; + } + show_boot_progress (128); + + rd_data = (ulong)data; + rd_len = size; + + if (fit_image_get_load (fit_hdr, rd_noffset, &rd_load)) { + puts ("Can't get ramdisk subimage load address!\n"); + show_boot_progress (-129); + return 0; + } + show_boot_progress (129); + + images->fit_hdr_rd = fit_hdr; + images->fit_uname_rd = fit_uname_ramdisk; + images->fit_noffset_rd = rd_noffset; + break; +#endif + default: + puts ("Wrong Ramdisk Image Format\n"); + rd_data = rd_len = rd_load = 0; + } + +#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO) + /* + * We need to copy the ramdisk to SRAM to let Linux boot + */ + if (rd_data) { + memmove ((void *)rd_load, (uchar *)rd_data, rd_len); + rd_data = rd_load; + } +#endif /* CONFIG_B2 || CONFIG_EVB4510 || CONFIG_ARMADILLO */ + + } else if (images->legacy_hdr_valid && + image_check_type (images->legacy_hdr_os, IH_TYPE_MULTI)) { + /* + * Now check if we have a legacy mult-component image, + * get second entry data start address and len. + */ + show_boot_progress (13); + printf ("## Loading init Ramdisk from multi component " + "Legacy Image at %08lx ...\n", + (ulong)images->legacy_hdr_os); + + image_multi_getimg (images->legacy_hdr_os, 1, &rd_data, &rd_len); + } else { + /* + * no initrd image + */ + show_boot_progress (14); + rd_len = rd_data = 0; + } + + if (!rd_data) { + debug ("## No init Ramdisk\n"); + } else { + *rd_start = rd_data; + *rd_end = rd_data + rd_len; + } + debug (" ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n", + *rd_start, *rd_end); + + return 0; +} + +#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +/** + * boot_ramdisk_high - relocate init ramdisk + * @lmb: pointer to lmb handle, will be used for memory mgmt + * @rd_data: ramdisk data start address + * @rd_len: ramdisk data length + * @initrd_start: pointer to a ulong variable, will hold final init ramdisk + * start address (after possible relocation) + * @initrd_end: pointer to a ulong variable, will hold final init ramdisk + * end address (after possible relocation) + * + * boot_ramdisk_high() takes a relocation hint from "initrd_high" environement + * variable and if requested ramdisk data is moved to a specified location. + * + * Initrd_start and initrd_end are set to final (after relocation) ramdisk + * start/end addresses if ramdisk image start and len were provided, + * otherwise set initrd_start and initrd_end set to zeros. + * + * returns: + * 0 - success + * -1 - failure + */ +int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, + ulong *initrd_start, ulong *initrd_end) +{ + char *s; + ulong initrd_high; + int initrd_copy_to_ram = 1; + + if ((s = getenv ("initrd_high")) != NULL) { + /* a value of "no" or a similar string will act like 0, + * turning the "load high" feature off. This is intentional. + */ + initrd_high = simple_strtoul (s, NULL, 16); + if (initrd_high == ~0) + initrd_copy_to_ram = 0; + } else { + /* not set, no restrictions to load high */ + initrd_high = ~0; + } + + debug ("## initrd_high = 0x%08lx, copy_to_ram = %d\n", + initrd_high, initrd_copy_to_ram); + + if (rd_data) { + if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ + debug (" in-place initrd\n"); + *initrd_start = rd_data; + *initrd_end = rd_data + rd_len; + lmb_reserve(lmb, rd_data, rd_len); + } else { + if (initrd_high) + *initrd_start = lmb_alloc_base (lmb, rd_len, 0x1000, initrd_high); + else + *initrd_start = lmb_alloc (lmb, rd_len, 0x1000); + + if (*initrd_start == 0) { + puts ("ramdisk - allocation error\n"); + goto error; + } + show_boot_progress (12); + + *initrd_end = *initrd_start + rd_len; + printf (" Loading Ramdisk to %08lx, end %08lx ... ", + *initrd_start, *initrd_end); + + memmove_wd ((void *)*initrd_start, + (void *)rd_data, rd_len, CHUNKSZ); + + puts ("OK\n"); + } + } else { + *initrd_start = 0; + *initrd_end = 0; + } + debug (" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n", + *initrd_start, *initrd_end); + + return 0; + +error: + return -1; +} + +/** + * boot_get_cmdline - allocate and initialize kernel cmdline + * @lmb: pointer to lmb handle, will be used for memory mgmt + * @cmd_start: pointer to a ulong variable, will hold cmdline start + * @cmd_end: pointer to a ulong variable, will hold cmdline end + * @bootmap_base: ulong variable, holds offset in physical memory to + * base of bootmap + * + * boot_get_cmdline() allocates space for kernel command line below + * BOOTMAPSZ + bootmap_base address. If "bootargs" U-boot environemnt + * variable is present its contents is copied to allocated kernel + * command line. + * + * returns: + * 0 - success + * -1 - failure + */ +int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, + ulong bootmap_base) +{ + char *cmdline; + char *s; + + cmdline = (char *)lmb_alloc_base(lmb, CFG_BARGSIZE, 0xf, + CFG_BOOTMAPSZ + bootmap_base); + + if (cmdline == NULL) + return -1; + + if ((s = getenv("bootargs")) == NULL) + s = ""; + + strcpy(cmdline, s); + + *cmd_start = (ulong) & cmdline[0]; + *cmd_end = *cmd_start + strlen(cmdline); + + debug ("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end); + + return 0; +} + +/** + * boot_get_kbd - allocate and initialize kernel copy of board info + * @lmb: pointer to lmb handle, will be used for memory mgmt + * @kbd: double pointer to board info data + * @bootmap_base: ulong variable, holds offset in physical memory to + * base of bootmap + * + * boot_get_kbd() allocates space for kernel copy of board info data below + * BOOTMAPSZ + bootmap_base address and kernel board info is initialized with + * the current u-boot board info data. + * + * returns: + * 0 - success + * -1 - failure + */ +int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base) +{ + *kbd = (bd_t *)lmb_alloc_base(lmb, sizeof(bd_t), 0xf, + CFG_BOOTMAPSZ + bootmap_base); + if (*kbd == NULL) + return -1; + + **kbd = *(gd->bd); + + debug ("## kernel board info at 0x%08lx\n", (ulong)*kbd); + +#if defined(DEBUG) && defined(CONFIG_CMD_BDI) + do_bdinfo(NULL, 0, 0, NULL); +#endif + + return 0; +} +#endif /* CONFIG_PPC || CONFIG_M68K */ +#endif /* !USE_HOSTCC */ + +#if defined(CONFIG_FIT) +/*****************************************************************************/ +/* New uImage format routines */ +/*****************************************************************************/ +#ifndef USE_HOSTCC +static int fit_parse_spec (const char *spec, char sepc, ulong addr_curr, + ulong *addr, const char **name) +{ + const char *sep; + + *addr = addr_curr; + *name = NULL; + + sep = strchr (spec, sepc); + if (sep) { + if (sep - spec > 0) + *addr = simple_strtoul (spec, NULL, 16); + + *name = sep + 1; + return 1; + } + + return 0; +} + +/** + * fit_parse_conf - parse FIT configuration spec + * @spec: input string, containing configuration spec + * @add_curr: current image address (to be used as a possible default) + * @addr: pointer to a ulong variable, will hold FIT image address of a given + * configuration + * @conf_name double pointer to a char, will hold pointer to a configuration + * unit name + * + * fit_parse_conf() expects configuration spec in the for of []#, + * where is a FIT image address that contains configuration + * with a unit name. + * + * Address part is optional, and if omitted default add_curr will + * be used instead. + * + * returns: + * 1 if spec is a valid configuration string, + * addr and conf_name are set accordingly + * 0 otherwise + */ +inline int fit_parse_conf (const char *spec, ulong addr_curr, + ulong *addr, const char **conf_name) +{ + return fit_parse_spec (spec, '#', addr_curr, addr, conf_name); +} + +/** + * fit_parse_subimage - parse FIT subimage spec + * @spec: input string, containing subimage spec + * @add_curr: current image address (to be used as a possible default) + * @addr: pointer to a ulong variable, will hold FIT image address of a given + * subimage + * @image_name: double pointer to a char, will hold pointer to a subimage name + * + * fit_parse_subimage() expects subimage spec in the for of + * []:, where is a FIT image address that contains + * subimage with a unit name. + * + * Address part is optional, and if omitted default add_curr will + * be used instead. + * + * returns: + * 1 if spec is a valid subimage string, + * addr and image_name are set accordingly + * 0 otherwise + */ +inline int fit_parse_subimage (const char *spec, ulong addr_curr, + ulong *addr, const char **image_name) +{ + return fit_parse_spec (spec, ':', addr_curr, addr, image_name); +} +#endif /* !USE_HOSTCC */ + +static void fit_get_debug (const void *fit, int noffset, + char *prop_name, int err) +{ + debug ("Can't get '%s' property from FIT 0x%08lx, " + "node: offset %d, name %s (%s)\n", + prop_name, (ulong)fit, noffset, + fit_get_name (fit, noffset, NULL), + fdt_strerror (err)); +} + +/** + * __fit_print_contents - prints out the contents of the FIT format image + * @fit: pointer to the FIT format image header + * @p: pointer to prefix string + * + * __fit_print_contents() formats a multi line FIT image contents description. + * The routine prints out FIT image properties (root node level) follwed by + * the details of each component image. + * + * returns: + * no returned results + */ +static void __fit_print_contents (const void *fit, const char *p) +{ + char *desc; + char *uname; + int images_noffset; + int confs_noffset; + int noffset; + int ndepth; + int count = 0; + int ret; +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) + time_t timestamp; +#endif + + /* Root node properties */ + ret = fit_get_desc (fit, 0, &desc); + printf ("%sFIT description: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("%s\n", desc); + +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) + ret = fit_get_timestamp (fit, 0, ×tamp); + printf ("%sCreated: ", p); + if (ret) + printf ("unavailable\n"); + else + genimg_print_time (timestamp); +#endif + + /* Find images parent node offset */ + images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH); + if (images_noffset < 0) { + printf ("Can't find images parent node '%s' (%s)\n", + FIT_IMAGES_PATH, fdt_strerror (images_noffset)); + return; + } + + /* Process its subnodes, print out component images details */ + for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* + * Direct child node of the images parent node, + * i.e. component image node. + */ + printf ("%s Image %u (%s)\n", p, count++, + fit_get_name(fit, noffset, NULL)); + + fit_image_print (fit, noffset, p); + } + } + + /* Find configurations parent node offset */ + confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH); + if (confs_noffset < 0) { + debug ("Can't get configurations parent node '%s' (%s)\n", + FIT_CONFS_PATH, fdt_strerror (confs_noffset)); + return; + } + + /* get default configuration unit name from default property */ + uname = (char *)fdt_getprop (fit, noffset, FIT_DEFAULT_PROP, NULL); + if (uname) + printf ("%s Default Configuration: '%s'\n", p, uname); + + /* Process its subnodes, print out configurations details */ + for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, confs_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* + * Direct child node of the configurations parent node, + * i.e. configuration node. + */ + printf ("%s Configuration %u (%s)\n", p, count++, + fit_get_name(fit, noffset, NULL)); + + fit_conf_print (fit, noffset, p); + } + } +} + +inline void fit_print_contents (const void *fit) +{ + __fit_print_contents (fit, " "); +} + +inline void fit_print_contents_noindent (const void *fit) +{ + __fit_print_contents (fit, ""); +} + +/** + * fit_image_print - prints out the FIT component image details + * @fit: pointer to the FIT format image header + * @image_noffset: offset of the component image node + * @p: pointer to prefix string + * + * fit_image_print() lists all mandatory properies for the processed component + * image. If present, hash nodes are printed out as well. + * + * returns: + * no returned results + */ +void fit_image_print (const void *fit, int image_noffset, const char *p) +{ + char *desc; + uint8_t type, arch, os, comp; + size_t size; + ulong load, entry; + const void *data; + int noffset; + int ndepth; + int ret; + + /* Mandatory properties */ + ret = fit_get_desc (fit, image_noffset, &desc); + printf ("%s Description: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("%s\n", desc); + + fit_image_get_type (fit, image_noffset, &type); + printf ("%s Type: %s\n", p, genimg_get_type_name (type)); + + fit_image_get_comp (fit, image_noffset, &comp); + printf ("%s Compression: %s\n", p, genimg_get_comp_name (comp)); + + ret = fit_image_get_data (fit, image_noffset, &data, &size); + +#ifndef USE_HOSTCC + printf ("%s Data Start: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("0x%08lx\n", (ulong)data); +#endif + + printf ("%s Data Size: ", p); + if (ret) + printf ("unavailable\n"); + else + genimg_print_size (size); + + /* Remaining, type dependent properties */ + if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || + (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) || + (type == IH_TYPE_FLATDT)) { + fit_image_get_arch (fit, image_noffset, &arch); + printf ("%s Architecture: %s\n", p, genimg_get_arch_name (arch)); + } + + if (type == IH_TYPE_KERNEL) { + fit_image_get_os (fit, image_noffset, &os); + printf ("%s OS: %s\n", p, genimg_get_os_name (os)); + } + + if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE)) { + ret = fit_image_get_load (fit, image_noffset, &load); + printf ("%s Load Address: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("0x%08lx\n", load); + + fit_image_get_entry (fit, image_noffset, &entry); + printf ("%s Entry Point: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("0x%08lx\n", entry); + } + + /* Process all hash subnodes of the component image node */ + for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* Direct child node of the component image node */ + fit_image_print_hash (fit, noffset, p); + } + } +} + +/** + * fit_image_print_hash - prints out the hash node details + * @fit: pointer to the FIT format image header + * @noffset: offset of the hash node + * @p: pointer to prefix string + * + * fit_image_print_hash() lists properies for the processed hash node + * + * returns: + * no returned results + */ +void fit_image_print_hash (const void *fit, int noffset, const char *p) +{ + char *algo; + uint8_t *value; + int value_len; + int i, ret; + + /* + * Check subnode name, must be equal to "hash". + * Multiple hash nodes require unique unit node + * names, e.g. hash@1, hash@2, etc. + */ + if (strncmp (fit_get_name(fit, noffset, NULL), + FIT_HASH_NODENAME, + strlen(FIT_HASH_NODENAME)) != 0) + return; + + debug ("%s Hash node: '%s'\n", p, + fit_get_name (fit, noffset, NULL)); + + printf ("%s Hash algo: ", p); + if (fit_image_hash_get_algo (fit, noffset, &algo)) { + printf ("invalid/unsupported\n"); + return; + } + printf ("%s\n", algo); + + ret = fit_image_hash_get_value (fit, noffset, &value, + &value_len); + printf ("%s Hash value: ", p); + if (ret) { + printf ("unavailable\n"); + } else { + for (i = 0; i < value_len; i++) + printf ("%02x", value[i]); + printf ("\n"); + } + + debug ("%s Hash len: %d\n", p, value_len); +} + +/** + * fit_get_desc - get node description property + * @fit: pointer to the FIT format image header + * @noffset: node offset + * @desc: double pointer to the char, will hold pointer to the descrption + * + * fit_get_desc() reads description property from a given node, if + * description is found pointer to it is returened in third call argument. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_get_desc (const void *fit, int noffset, char **desc) +{ + int len; + + *desc = (char *)fdt_getprop (fit, noffset, FIT_DESC_PROP, &len); + if (*desc == NULL) { + fit_get_debug (fit, noffset, FIT_DESC_PROP, len); + return -1; + } + + return 0; +} + +/** + * fit_get_timestamp - get node timestamp property + * @fit: pointer to the FIT format image header + * @noffset: node offset + * @timestamp: pointer to the time_t, will hold read timestamp + * + * fit_get_timestamp() reads timestamp poperty from given node, if timestamp + * is found and has a correct size its value is retured in third call + * argument. + * + * returns: + * 0, on success + * -1, on property read failure + * -2, on wrong timestamp size + */ +int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp) +{ + int len; + const void *data; + + data = fdt_getprop (fit, noffset, FIT_TIMESTAMP_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_TIMESTAMP_PROP, len); + return -1; + } + if (len != sizeof (uint32_t)) { + debug ("FIT timestamp with incorrect size of (%u)\n", len); + return -2; + } + + *timestamp = uimage_to_cpu (*((uint32_t *)data)); + return 0; +} + +/** + * fit_image_get_node - get node offset for component image of a given unit name + * @fit: pointer to the FIT format image header + * @image_uname: component image node unit name + * + * fit_image_get_node() finds a component image (withing the '/images' + * node) of a provided unit name. If image is found its node offset is + * returned to the caller. + * + * returns: + * image node offset when found (>=0) + * negative number on failure (FDT_ERR_* code) + */ +int fit_image_get_node (const void *fit, const char *image_uname) +{ + int noffset, images_noffset; + + images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH); + if (images_noffset < 0) { + debug ("Can't find images parent node '%s' (%s)\n", + FIT_IMAGES_PATH, fdt_strerror (images_noffset)); + return images_noffset; + } + + noffset = fdt_subnode_offset (fit, images_noffset, image_uname); + if (noffset < 0) { + debug ("Can't get node offset for image unit name: '%s' (%s)\n", + image_uname, fdt_strerror (noffset)); + } + + return noffset; +} + +/** + * fit_image_get_os - get os id for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @os: pointer to the uint8_t, will hold os numeric id + * + * fit_image_get_os() finds os property in a given component image node. + * If the property is found, its (string) value is translated to the numeric + * id which is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_os (const void *fit, int noffset, uint8_t *os) +{ + int len; + const void *data; + + /* Get OS name from property data */ + data = fdt_getprop (fit, noffset, FIT_OS_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_OS_PROP, len); + *os = -1; + return -1; + } + + /* Translate OS name to id */ + *os = genimg_get_os_id (data); + return 0; +} + +/** + * fit_image_get_arch - get arch id for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @arch: pointer to the uint8_t, will hold arch numeric id + * + * fit_image_get_arch() finds arch property in a given component image node. + * If the property is found, its (string) value is translated to the numeric + * id which is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch) +{ + int len; + const void *data; + + /* Get architecture name from property data */ + data = fdt_getprop (fit, noffset, FIT_ARCH_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_ARCH_PROP, len); + *arch = -1; + return -1; + } + + /* Translate architecture name to id */ + *arch = genimg_get_arch_id (data); + return 0; +} + +/** + * fit_image_get_type - get type id for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @type: pointer to the uint8_t, will hold type numeric id + * + * fit_image_get_type() finds type property in a given component image node. + * If the property is found, its (string) value is translated to the numeric + * id which is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_type (const void *fit, int noffset, uint8_t *type) +{ + int len; + const void *data; + + /* Get image type name from property data */ + data = fdt_getprop (fit, noffset, FIT_TYPE_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_TYPE_PROP, len); + *type = -1; + return -1; + } + + /* Translate image type name to id */ + *type = genimg_get_type_id (data); + return 0; +} + +/** + * fit_image_get_comp - get comp id for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @comp: pointer to the uint8_t, will hold comp numeric id + * + * fit_image_get_comp() finds comp property in a given component image node. + * If the property is found, its (string) value is translated to the numeric + * id which is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp) +{ + int len; + const void *data; + + /* Get compression name from property data */ + data = fdt_getprop (fit, noffset, FIT_COMP_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_COMP_PROP, len); + *comp = -1; + return -1; + } + + /* Translate compression name to id */ + *comp = genimg_get_comp_id (data); + return 0; +} + +/** + * fit_image_get_load - get load address property for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @load: pointer to the uint32_t, will hold load address + * + * fit_image_get_load() finds load address property in a given component image node. + * If the property is found, its value is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_load (const void *fit, int noffset, ulong *load) +{ + int len; + const uint32_t *data; + + data = fdt_getprop (fit, noffset, FIT_LOAD_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_LOAD_PROP, len); + return -1; + } + + *load = uimage_to_cpu (*data); + return 0; +} + +/** + * fit_image_get_entry - get entry point address property for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @entry: pointer to the uint32_t, will hold entry point address + * + * fit_image_get_entry() finds entry point address property in a given component image node. + * If the property is found, its value is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_entry (const void *fit, int noffset, ulong *entry) +{ + int len; + const uint32_t *data; + + data = fdt_getprop (fit, noffset, FIT_ENTRY_PROP, &len); + if (data == NULL) { + fit_get_debug (fit, noffset, FIT_ENTRY_PROP, len); + return -1; + } + + *entry = uimage_to_cpu (*data); + return 0; +} + +/** + * fit_image_get_data - get data property and its size for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @data: double pointer to void, will hold data property's data address + * @size: pointer to size_t, will hold data property's data size + * + * fit_image_get_data() finds data property in a given component image node. + * If the property is found its data start address and size are returned to + * the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_get_data (const void *fit, int noffset, + const void **data, size_t *size) +{ + int len; + + *data = fdt_getprop (fit, noffset, FIT_DATA_PROP, &len); + if (*data == NULL) { + fit_get_debug (fit, noffset, FIT_DATA_PROP, len); + *size = 0; + return -1; + } + + *size = len; + return 0; +} + +/** + * fit_image_hash_get_algo - get hash algorithm name + * @fit: pointer to the FIT format image header + * @noffset: hash node offset + * @algo: double pointer to char, will hold pointer to the algorithm name + * + * fit_image_hash_get_algo() finds hash algorithm property in a given hash node. + * If the property is found its data start address is returned to the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_hash_get_algo (const void *fit, int noffset, char **algo) +{ + int len; + + *algo = (char *)fdt_getprop (fit, noffset, FIT_ALGO_PROP, &len); + if (*algo == NULL) { + fit_get_debug (fit, noffset, FIT_ALGO_PROP, len); + return -1; + } + + return 0; +} + +/** + * fit_image_hash_get_value - get hash value and length + * @fit: pointer to the FIT format image header + * @noffset: hash node offset + * @value: double pointer to uint8_t, will hold address of a hash value data + * @value_len: pointer to an int, will hold hash data length + * + * fit_image_hash_get_value() finds hash value property in a given hash node. + * If the property is found its data start address and size are returned to + * the caller. + * + * returns: + * 0, on success + * -1, on failure + */ +int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value, + int *value_len) +{ + int len; + + *value = (uint8_t *)fdt_getprop (fit, noffset, FIT_VALUE_PROP, &len); + if (*value == NULL) { + fit_get_debug (fit, noffset, FIT_VALUE_PROP, len); + *value_len = 0; + return -1; + } + + *value_len = len; + return 0; +} + +/** + * fit_set_timestamp - set node timestamp property + * @fit: pointer to the FIT format image header + * @noffset: node offset + * @timestamp: timestamp value to be set + * + * fit_set_timestamp() attempts to set timestamp property in the requested + * node and returns operation status to the caller. + * + * returns: + * 0, on success + * -1, on property read failure + */ +int fit_set_timestamp (void *fit, int noffset, time_t timestamp) +{ + uint32_t t; + int ret; + + t = cpu_to_uimage (timestamp); + ret = fdt_setprop (fit, noffset, FIT_TIMESTAMP_PROP, &t, + sizeof (uint32_t)); + if (ret) { + printf ("Can't set '%s' property for '%s' node (%s)\n", + FIT_TIMESTAMP_PROP, fit_get_name (fit, noffset, NULL), + fdt_strerror (ret)); + return -1; + } + + return 0; +} + +/** + * calculate_hash - calculate and return hash for provided input data + * @data: pointer to the input data + * @data_len: data length + * @algo: requested hash algorithm + * @value: pointer to the char, will hold hash value data (caller must + * allocate enough free space) + * value_len: length of the calculated hash + * + * calculate_hash() computes input data hash according to the requested algorithm. + * Resulting hash value is placed in caller provided 'value' buffer, length + * of the calculated hash is returned via value_len pointer argument. + * + * returns: + * 0, on success + * -1, when algo is unsupported + */ +static int calculate_hash (const void *data, int data_len, const char *algo, + uint8_t *value, int *value_len) +{ + if (strcmp (algo, "crc32") == 0 ) { + *((uint32_t *)value) = crc32 (0, data, data_len); + *((uint32_t *)value) = cpu_to_uimage (*((uint32_t *)value)); + *value_len = 4; + } else if (strcmp (algo, "sha1") == 0 ) { + sha1_csum ((unsigned char *) data, data_len, + (unsigned char *) value); + *value_len = 20; + } else if (strcmp (algo, "md5") == 0 ) { + md5 ((unsigned char *)data, data_len, value); + *value_len = 16; + } else { + debug ("Unsupported hash alogrithm\n"); + return -1; + } + return 0; +} + +#ifdef USE_HOSTCC +/** + * fit_set_hashes - process FIT component image nodes and calculate hashes + * @fit: pointer to the FIT format image header + * + * fit_set_hashes() adds hash values for all component images in the FIT blob. + * Hashes are calculated for all component images which have hash subnodes + * with algorithm property set to one of the supported hash algorithms. + * + * returns + * 0, on success + * libfdt error code, on failure + */ +int fit_set_hashes (void *fit) +{ + int images_noffset; + int noffset; + int ndepth; + int ret; + + /* Find images parent node offset */ + images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH); + if (images_noffset < 0) { + printf ("Can't find images parent node '%s' (%s)\n", + FIT_IMAGES_PATH, fdt_strerror (images_noffset)); + return images_noffset; + } + + /* Process its subnodes, print out component images details */ + for (ndepth = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* + * Direct child node of the images parent node, + * i.e. component image node. + */ + ret = fit_image_set_hashes (fit, noffset); + if (ret) + return ret; + } + } + + return 0; +} + +/** + * fit_image_set_hashes - calculate/set hashes for given component image node + * @fit: pointer to the FIT format image header + * @image_noffset: requested component image node + * + * fit_image_set_hashes() adds hash values for an component image node. All + * existing hash subnodes are checked, if algorithm property is set to one of + * the supported hash algorithms, hash value is computed and corresponding + * hash node property is set, for example: + * + * Input component image node structure: + * + * o image@1 (at image_noffset) + * | - data = [binary data] + * o hash@1 + * |- algo = "sha1" + * + * Output component image node structure: + * + * o image@1 (at image_noffset) + * | - data = [binary data] + * o hash@1 + * |- algo = "sha1" + * |- value = sha1(data) + * + * returns: + * 0 on sucess + * <0 on failure + */ +int fit_image_set_hashes (void *fit, int image_noffset) +{ + const void *data; + size_t size; + char *algo; + uint8_t value[FIT_MAX_HASH_LEN]; + int value_len; + int noffset; + int ndepth; + + /* Get image data and data length */ + if (fit_image_get_data (fit, image_noffset, &data, &size)) { + printf ("Can't get image data/size\n"); + return -1; + } + + /* Process all hash subnodes of the component image node */ + for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* Direct child node of the component image node */ + + /* + * Check subnode name, must be equal to "hash". + * Multiple hash nodes require unique unit node + * names, e.g. hash@1, hash@2, etc. + */ + if (strncmp (fit_get_name(fit, noffset, NULL), + FIT_HASH_NODENAME, + strlen(FIT_HASH_NODENAME)) != 0) { + /* Not a hash subnode, skip it */ + continue; + } + + if (fit_image_hash_get_algo (fit, noffset, &algo)) { + printf ("Can't get hash algo property for " + "'%s' hash node in '%s' image node\n", + fit_get_name (fit, noffset, NULL), + fit_get_name (fit, image_noffset, NULL)); + return -1; + } + + if (calculate_hash (data, size, algo, value, &value_len)) { + printf ("Unsupported hash algorithm (%s) for " + "'%s' hash node in '%s' image node\n", + algo, fit_get_name (fit, noffset, NULL), + fit_get_name (fit, image_noffset, NULL)); + return -1; + } + + if (fit_image_hash_set_value (fit, noffset, value, + value_len)) { + printf ("Can't set hash value for " + "'%s' hash node in '%s' image node\n", + fit_get_name (fit, noffset, NULL), + fit_get_name (fit, image_noffset, NULL)); + return -1; + } + } + } + + return 0; +} + +/** + * fit_image_hash_set_value - set hash value in requested has node + * @fit: pointer to the FIT format image header + * @noffset: hash node offset + * @value: hash value to be set + * @value_len: hash value length + * + * fit_image_hash_set_value() attempts to set hash value in a node at offset + * given and returns operation status to the caller. + * + * returns + * 0, on success + * -1, on failure + */ +int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value, + int value_len) +{ + int ret; + + ret = fdt_setprop (fit, noffset, FIT_VALUE_PROP, value, value_len); + if (ret) { + printf ("Can't set hash '%s' property for '%s' node (%s)\n", + FIT_VALUE_PROP, fit_get_name (fit, noffset, NULL), + fdt_strerror (ret)); + return -1; + } + + return 0; +} +#endif /* USE_HOSTCC */ + +/** + * fit_image_check_hashes - verify data intergity + * @fit: pointer to the FIT format image header + * @image_noffset: component image node offset + * + * fit_image_check_hashes() goes over component image hash nodes, + * re-calculates each data hash and compares with the value stored in hash + * node. + * + * returns: + * 1, if all hashes are valid + * 0, otherwise (or on error) + */ +int fit_image_check_hashes (const void *fit, int image_noffset) +{ + const void *data; + size_t size; + char *algo; + uint8_t *fit_value; + int fit_value_len; + uint8_t value[FIT_MAX_HASH_LEN]; + int value_len; + int noffset; + int ndepth; + char *err_msg = ""; + + /* Get image data and data length */ + if (fit_image_get_data (fit, image_noffset, &data, &size)) { + printf ("Can't get image data/size\n"); + return 0; + } + + /* Process all hash subnodes of the component image node */ + for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node (fit, noffset, &ndepth)) { + if (ndepth == 1) { + /* Direct child node of the component image node */ + + /* + * Check subnode name, must be equal to "hash". + * Multiple hash nodes require unique unit node + * names, e.g. hash@1, hash@2, etc. + */ + if (strncmp (fit_get_name(fit, noffset, NULL), + FIT_HASH_NODENAME, + strlen(FIT_HASH_NODENAME)) != 0) + continue; + + if (fit_image_hash_get_algo (fit, noffset, &algo)) { + err_msg = "Can't get hash algo property"; + goto error; + } + printf ("%s", algo); + + if (fit_image_hash_get_value (fit, noffset, &fit_value, + &fit_value_len)) { + err_msg = "Can't get hash value property"; + goto error; + } + + if (calculate_hash (data, size, algo, value, &value_len)) { + err_msg = "Unsupported hash algorithm"; + goto error; + } + + if (value_len != fit_value_len) { + err_msg = "Bad hash value len"; + goto error; + } else if (memcmp (value, fit_value, value_len) != 0) { + err_msg = "Bad hash value"; + goto error; + } + printf ("+ "); + } + } + + return 1; + +error: + printf ("%s for '%s' hash node in '%s' image node\n", + err_msg, fit_get_name (fit, noffset, NULL), + fit_get_name (fit, image_noffset, NULL)); + return 0; +} + +/** + * fit_image_check_os - check whether image node is of a given os type + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @os: requested image os + * + * fit_image_check_os() reads image os property and compares its numeric + * id with the requested os. Comparison result is returned to the caller. + * + * returns: + * 1 if image is of given os type + * 0 otherwise (or on error) + */ +int fit_image_check_os (const void *fit, int noffset, uint8_t os) +{ + uint8_t image_os; + + if (fit_image_get_os (fit, noffset, &image_os)) + return 0; + return (os == image_os); +} + +/** + * fit_image_check_arch - check whether image node is of a given arch + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @arch: requested imagearch + * + * fit_image_check_arch() reads image arch property and compares its numeric + * id with the requested arch. Comparison result is returned to the caller. + * + * returns: + * 1 if image is of given arch + * 0 otherwise (or on error) + */ +int fit_image_check_arch (const void *fit, int noffset, uint8_t arch) +{ + uint8_t image_arch; + + if (fit_image_get_arch (fit, noffset, &image_arch)) + return 0; + return (arch == image_arch); +} + +/** + * fit_image_check_type - check whether image node is of a given type + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @type: requested image type + * + * fit_image_check_type() reads image type property and compares its numeric + * id with the requested type. Comparison result is returned to the caller. + * + * returns: + * 1 if image is of given type + * 0 otherwise (or on error) + */ +int fit_image_check_type (const void *fit, int noffset, uint8_t type) +{ + uint8_t image_type; + + if (fit_image_get_type (fit, noffset, &image_type)) + return 0; + return (type == image_type); +} + +/** + * fit_image_check_comp - check whether image node uses given compression + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @comp: requested image compression type + * + * fit_image_check_comp() reads image compression property and compares its + * numeric id with the requested compression type. Comparison result is + * returned to the caller. + * + * returns: + * 1 if image uses requested compression + * 0 otherwise (or on error) + */ +int fit_image_check_comp (const void *fit, int noffset, uint8_t comp) +{ + uint8_t image_comp; + + if (fit_image_get_comp (fit, noffset, &image_comp)) + return 0; + return (comp == image_comp); +} + +/** + * fit_check_format - sanity check FIT image format + * @fit: pointer to the FIT format image header + * + * fit_check_format() runs a basic sanity FIT image verification. + * Routine checks for mandatory properties, nodes, etc. + * + * returns: + * 1, on success + * 0, on failure + */ +int fit_check_format (const void *fit) +{ + /* mandatory / node 'description' property */ + if (fdt_getprop (fit, 0, FIT_DESC_PROP, NULL) == NULL) { + debug ("Wrong FIT format: no description\n"); + return 0; + } + +#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) + /* mandatory / node 'timestamp' property */ + if (fdt_getprop (fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) { + debug ("Wrong FIT format: no description\n"); + return 0; + } +#endif + + /* mandatory subimages parent '/images' node */ + if (fdt_path_offset (fit, FIT_IMAGES_PATH) < 0) { + debug ("Wrong FIT format: no images parent node\n"); + return 0; + } + + return 1; +} + +/** + * fit_conf_get_node - get node offset for configuration of a given unit name + * @fit: pointer to the FIT format image header + * @conf_uname: configuration node unit name + * + * fit_conf_get_node() finds a configuration (withing the '/configurations' + * parant node) of a provided unit name. If configuration is found its node offset + * is returned to the caller. + * + * When NULL is provided in second argument fit_conf_get_node() will search + * for a default configuration node instead. Default configuration node unit name + * is retrived from FIT_DEFAULT_PROP property of the '/configurations' node. + * + * returns: + * configuration node offset when found (>=0) + * negative number on failure (FDT_ERR_* code) + */ +int fit_conf_get_node (const void *fit, const char *conf_uname) +{ + int noffset, confs_noffset; + int len; + + confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH); + if (confs_noffset < 0) { + debug ("Can't find configurations parent node '%s' (%s)\n", + FIT_CONFS_PATH, fdt_strerror (confs_noffset)); + return confs_noffset; + } + + if (conf_uname == NULL) { + /* get configuration unit name from the default property */ + debug ("No configuration specified, trying default...\n"); + conf_uname = (char *)fdt_getprop (fit, confs_noffset, FIT_DEFAULT_PROP, &len); + if (conf_uname == NULL) { + fit_get_debug (fit, confs_noffset, FIT_DEFAULT_PROP, len); + return len; + } + debug ("Found default configuration: '%s'\n", conf_uname); + } + + noffset = fdt_subnode_offset (fit, confs_noffset, conf_uname); + if (noffset < 0) { + debug ("Can't get node offset for configuration unit name: '%s' (%s)\n", + conf_uname, fdt_strerror (noffset)); + } + + return noffset; +} + +static int __fit_conf_get_prop_node (const void *fit, int noffset, + const char *prop_name) +{ + char *uname; + int len; + + /* get kernel image unit name from configuration kernel property */ + uname = (char *)fdt_getprop (fit, noffset, prop_name, &len); + if (uname == NULL) + return len; + + return fit_image_get_node (fit, uname); +} + +/** + * fit_conf_get_kernel_node - get kernel image node offset that corresponds to + * a given configuration + * @fit: pointer to the FIT format image header + * @noffset: configuration node offset + * + * fit_conf_get_kernel_node() retrives kernel image node unit name from + * configuration FIT_KERNEL_PROP property and translates it to the node + * offset. + * + * returns: + * image node offset when found (>=0) + * negative number on failure (FDT_ERR_* code) + */ +int fit_conf_get_kernel_node (const void *fit, int noffset) +{ + return __fit_conf_get_prop_node (fit, noffset, FIT_KERNEL_PROP); +} + +/** + * fit_conf_get_ramdisk_node - get ramdisk image node offset that corresponds to + * a given configuration + * @fit: pointer to the FIT format image header + * @noffset: configuration node offset + * + * fit_conf_get_ramdisk_node() retrives ramdisk image node unit name from + * configuration FIT_KERNEL_PROP property and translates it to the node + * offset. + * + * returns: + * image node offset when found (>=0) + * negative number on failure (FDT_ERR_* code) + */ +int fit_conf_get_ramdisk_node (const void *fit, int noffset) +{ + return __fit_conf_get_prop_node (fit, noffset, FIT_RAMDISK_PROP); +} + +/** + * fit_conf_get_fdt_node - get fdt image node offset that corresponds to + * a given configuration + * @fit: pointer to the FIT format image header + * @noffset: configuration node offset + * + * fit_conf_get_fdt_node() retrives fdt image node unit name from + * configuration FIT_KERNEL_PROP property and translates it to the node + * offset. + * + * returns: + * image node offset when found (>=0) + * negative number on failure (FDT_ERR_* code) + */ +int fit_conf_get_fdt_node (const void *fit, int noffset) +{ + return __fit_conf_get_prop_node (fit, noffset, FIT_FDT_PROP); +} + +/** + * fit_conf_print - prints out the FIT configuration details + * @fit: pointer to the FIT format image header + * @noffset: offset of the configuration node + * @p: pointer to prefix string + * + * fit_conf_print() lists all mandatory properies for the processed + * configuration node. + * + * returns: + * no returned results + */ +void fit_conf_print (const void *fit, int noffset, const char *p) +{ + char *desc; + char *uname; + int ret; + + /* Mandatory properties */ + ret = fit_get_desc (fit, noffset, &desc); + printf ("%s Description: ", p); + if (ret) + printf ("unavailable\n"); + else + printf ("%s\n", desc); + + uname = (char *)fdt_getprop (fit, noffset, FIT_KERNEL_PROP, NULL); + printf ("%s Kernel: ", p); + if (uname == NULL) + printf ("unavailable\n"); + else + printf ("%s\n", uname); + + /* Optional properties */ + uname = (char *)fdt_getprop (fit, noffset, FIT_RAMDISK_PROP, NULL); + if (uname) + printf ("%s Init Ramdisk: %s\n", p, uname); + + uname = (char *)fdt_getprop (fit, noffset, FIT_FDT_PROP, NULL); + if (uname) + printf ("%s FDT: %s\n", p, uname); +} + +/** + * fit_check_ramdisk - verify FIT format ramdisk subimage + * @fit_hdr: pointer to the FIT ramdisk header + * @rd_noffset: ramdisk subimage node offset within FIT image + * @arch: requested ramdisk image architecture type + * @verify: data CRC verification flag + * + * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from + * specified FIT image. + * + * returns: + * 1, on success + * 0, on failure + */ +#ifndef USE_HOSTCC +static int fit_check_ramdisk (const void *fit, int rd_noffset, uint8_t arch, int verify) +{ + fit_image_print (fit, rd_noffset, " "); + + if (verify) { + puts (" Verifying Hash Integrity ... "); + if (!fit_image_check_hashes (fit, rd_noffset)) { + puts ("Bad Data Hash\n"); + show_boot_progress (-125); + return 0; + } + puts ("OK\n"); + } + + show_boot_progress (126); + if (!fit_image_check_os (fit, rd_noffset, IH_OS_LINUX) || + !fit_image_check_arch (fit, rd_noffset, arch) || + !fit_image_check_type (fit, rd_noffset, IH_TYPE_RAMDISK)) { + printf ("No Linux %s Ramdisk Image\n", + genimg_get_arch_name(arch)); + show_boot_progress (-126); + return 0; + } + + show_boot_progress (127); + return 1; +} +#endif /* USE_HOSTCC */ +#endif /* CONFIG_FIT */ diff --git a/common/lynxkdi.c b/common/lynxkdi.c index 76a271b96..a5dc88769 100644 --- a/common/lynxkdi.c +++ b/common/lynxkdi.c @@ -23,45 +23,45 @@ DECLARE_GLOBAL_DATA_PTR; #if defined(CONFIG_MPC8260) || defined(CONFIG_440EP) || defined(CONFIG_440GR) -void lynxkdi_boot ( image_header_t *hdr ) +void lynxkdi_boot (image_header_t *hdr) { - void (*lynxkdi)(void) = (void(*)(void)) ntohl(hdr->ih_ep); + void (*lynxkdi)(void) = (void(*)(void))image_get_ep (hdr); lynxos_bootparms_t *parms = (lynxos_bootparms_t *)0x0020; bd_t *kbd; - u32 *psz = (u32 *)(ntohl(hdr->ih_load) + 0x0204); + u32 *psz = (u32 *)(image_get_load (hdr) + 0x0204); - memset( parms, 0, sizeof(*parms)); + memset (parms, 0, sizeof(*parms)); kbd = gd->bd; parms->clock_ref = kbd->bi_busfreq; parms->dramsz = kbd->bi_memsize; - memcpy(parms->ethaddr, kbd->bi_enetaddr, 6); - mtspr(SPRN_SPRG2, 0x0020); + memcpy (parms->ethaddr, kbd->bi_enetaddr, 6); + mtspr (SPRN_SPRG2, 0x0020); /* Do a simple check for Bluecat so we can pass the * kernel command line parameters. */ - if( le32_to_cpu(*psz) == ntohl(hdr->ih_size) ){ /* FIXME: NOT SURE HERE ! */ - char *args; - char *cmdline = (char *)(ntohl(hdr->ih_load) + 0x020c); - int len; + if (le32_to_cpu (*psz) == image_get_data_size (hdr)) { /* FIXME: NOT SURE HERE ! */ + char *args; + char *cmdline = (char *)(image_get_load (hdr) + 0x020c); + int len; - printf("Booting Bluecat KDI ...\n"); - udelay(200*1000); /* Allow serial port to flush */ - if ((args = getenv("bootargs")) == NULL) - args = ""; - /* Prepend the cmdline */ - len = strlen(args); - if( len && (len + strlen(cmdline) + 2 < (0x0400 - 0x020c))) { - memmove( cmdline + strlen(args) + 1, cmdline, strlen(cmdline) ); - strcpy( cmdline, args ); - cmdline[len] = ' '; - } + printf ("Booting Bluecat KDI ...\n"); + udelay (200*1000); /* Allow serial port to flush */ + if ((args = getenv ("bootargs")) == NULL) + args = ""; + /* Prepend the cmdline */ + len = strlen (args); + if (len && (len + strlen (cmdline) + 2 < (0x0400 - 0x020c))) { + memmove (cmdline + strlen (args) + 1, cmdline, strlen (cmdline)); + strcpy (cmdline, args); + cmdline[len] = ' '; + } } else { - printf("Booting LynxOS KDI ...\n"); + printf ("Booting LynxOS KDI ...\n"); } - lynxkdi(); + lynxkdi (); } #else #error "Lynx KDI support not implemented for configured CPU" diff --git a/common/usb_storage.c b/common/usb_storage.c index 443d78574..d263b6c0d 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -188,17 +188,20 @@ void usb_show_progress(void) * show info on storage devices; 'usb start/init' must be invoked earlier * as we only retrieve structures populated during devices initialization */ -void usb_stor_info(void) +int usb_stor_info(void) { int i; - if (usb_max_devs > 0) + if (usb_max_devs > 0) { for (i = 0; i < usb_max_devs; i++) { printf (" Device %d: ", i); dev_print(&usb_dev_desc[i]); } - else - printf("No storage devices, perhaps not 'usb start'ed..?\n"); + return 0; + } + + printf("No storage devices, perhaps not 'usb start'ed..?\n"); + return 1; } /********************************************************************************* diff --git a/cpu/mips/cache.S b/cpu/mips/cache.S index 443240e54..89ada716c 100644 --- a/cpu/mips/cache.S +++ b/cpu/mips/cache.S @@ -1,5 +1,5 @@ /* - * Cache-handling routined for MIPS 4K CPUs + * Cache-handling routined for MIPS CPUs * * Copyright (c) 2003 Wolfgang Denk * @@ -24,15 +24,32 @@ #include #include +#include #include #include #include #include - /* 16KB is the maximum size of instruction and data caches on - * MIPS 4K. - */ -#define MIPS_MAX_CACHE_SIZE 0x4000 +#define RA t8 + +/* + * 16kB is the maximum size of instruction and data caches on MIPS 4K, + * 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience. + * + * Note that the above size is the maximum size of primary cache. U-Boot + * doesn't have L2 cache support for now. + */ +#define MIPS_MAX_CACHE_SIZE 0x10000 + +#define INDEX_BASE KSEG0 + + .macro cache_op op addr + .set push + .set noreorder + .set mips3 + cache \op, 0(\addr) + .set pop + .endm /* * cacheop macro to automate cache operations @@ -103,6 +120,77 @@ #define icacheop(kva, n, cacheSize, cacheLineSize, op) \ icacheopn(kva, n, cacheSize, cacheLineSize, 1, (op)) + .macro f_fill64 dst, offset, val + LONG_S \val, (\offset + 0 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 1 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 2 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 3 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 4 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 5 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 6 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 7 * LONGSIZE)(\dst) +#if LONGSIZE == 4 + LONG_S \val, (\offset + 8 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 9 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 10 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 11 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 12 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 13 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 14 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 15 * LONGSIZE)(\dst) +#endif + .endm + +/* + * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz) + */ +LEAF(mips_init_icache) + blez a1, 9f + mtc0 zero, CP0_TAGLO + /* clear tag to invalidate */ + PTR_LI t0, INDEX_BASE + PTR_ADDU t1, t0, a1 +1: cache_op Index_Store_Tag_I t0 + PTR_ADDU t0, a2 + bne t0, t1, 1b + /* fill once, so data field parity is correct */ + PTR_LI t0, INDEX_BASE +2: cache_op Fill t0 + PTR_ADDU t0, a2 + bne t0, t1, 2b + /* invalidate again - prudent but not strictly neccessary */ + PTR_LI t0, INDEX_BASE +1: cache_op Index_Store_Tag_I t0 + PTR_ADDU t0, a2 + bne t0, t1, 1b +9: jr ra + END(mips_init_icache) + +/* + * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz) + */ +LEAF(mips_init_dcache) + blez a1, 9f + mtc0 zero, CP0_TAGLO + /* clear all tags */ + PTR_LI t0, INDEX_BASE + PTR_ADDU t1, t0, a1 +1: cache_op Index_Store_Tag_D t0 + PTR_ADDU t0, a2 + bne t0, t1, 1b + /* load from each line (in cached space) */ + PTR_LI t0, INDEX_BASE +2: LONG_L zero, 0(t0) + PTR_ADDU t0, a2 + bne t0, t1, 2b + /* clear all tags */ + PTR_LI t0, INDEX_BASE +1: cache_op Index_Store_Tag_D t0 + PTR_ADDU t0, a2 + bne t0, t1, 1b +9: jr ra + END(mips_init_dcache) + /******************************************************************************* * * mips_cache_reset - low level initialisation of the primary caches @@ -119,10 +207,8 @@ * RETURNS: N/A * */ - .globl mips_cache_reset - .ent mips_cache_reset -mips_cache_reset: - +NESTED(mips_cache_reset, 0, ra) + move RA, ra li t2, CFG_ICACHE_SIZE li t3, CFG_DCACHE_SIZE li t4, CFG_CACHELINE_SIZE @@ -130,27 +216,14 @@ mips_cache_reset: li v0, MIPS_MAX_CACHE_SIZE - /* Now clear that much memory starting from zero. + /* + * Now clear that much memory starting from zero. */ - - li a0, KSEG1 - addu a1, a0, v0 -2: - sw zero, 0(a0) - sw zero, 4(a0) - sw zero, 8(a0) - sw zero, 12(a0) - sw zero, 16(a0) - sw zero, 20(a0) - sw zero, 24(a0) - sw zero, 28(a0) - addu a0, 32 - bltu a0, a1, 2b - - /* Set invalid tag. - */ - - mtc0 zero, CP0_TAGLO + PTR_LI a0, KSEG1 + PTR_ADDU a1, a0, v0 +2: PTR_ADDIU a0, 64 + f_fill64 a0, -64, zero + bne a0, a1, 2b /* * The caches are probably in an indeterminate state, @@ -158,48 +231,26 @@ mips_cache_reset: * invalidate, load/fill, invalidate for each line. */ - /* Assume bottom of RAM will generate good parity for the cache. + /* + * Assume bottom of RAM will generate good parity for the cache. */ - li a0, K0BASE - move a2, t2 # icacheSize - move a3, t4 # icacheLineSize - move a1, a2 - icacheopn(a0,a1,a2,a3,121,(Index_Store_Tag_I,Fill)) - - /* To support Orion/R4600, we initialise the data cache in 3 passes. + /* + * Initialize the I-cache first, */ + move a1, t2 + move a2, t4 + bal mips_init_icache - /* 1: initialise dcache tags. + /* + * then initialize D-cache. */ + move a1, t3 + move a2, t5 + bal mips_init_dcache - li a0, K0BASE - move a2, t3 # dcacheSize - move a3, t5 # dcacheLineSize - move a1, a2 - icacheop(a0,a1,a2,a3,Index_Store_Tag_D) - - /* 2: fill dcache. - */ - - li a0, K0BASE - move a2, t3 # dcacheSize - move a3, t5 # dcacheLineSize - move a1, a2 - icacheopn(a0,a1,a2,a3,1lw,(dummy)) - - /* 3: clear dcache tags. - */ - - li a0, K0BASE - move a2, t3 # dcacheSize - move a3, t5 # dcacheLineSize - move a1, a2 - icacheop(a0,a1,a2,a3,Index_Store_Tag_D) - - j ra - - .end mips_cache_reset + jr RA + END(mips_cache_reset) /******************************************************************************* * @@ -208,15 +259,15 @@ mips_cache_reset: * RETURNS: 0 - cache disabled; 1 - cache enabled * */ - .globl dcache_status - .ent dcache_status -dcache_status: - - mfc0 v0, CP0_CONFIG - andi v0, v0, 1 - j ra - - .end dcache_status +LEAF(dcache_status) + mfc0 t0, CP0_CONFIG + li t1, CONF_CM_UNCACHED + andi t0, t0, CONF_CM_CMASK + move v0, zero + beq t0, t1, 2f + li v0, 1 +2: jr ra + END(dcache_status) /******************************************************************************* * @@ -225,19 +276,16 @@ dcache_status: * RETURNS: N/A * */ - .globl dcache_disable - .ent dcache_disable -dcache_disable: - +LEAF(dcache_disable) mfc0 t0, CP0_CONFIG li t1, -8 and t0, t0, t1 ori t0, t0, CONF_CM_UNCACHED mtc0 t0, CP0_CONFIG j ra + END(dcache_disable) - .end dcache_disable - +#ifdef CFG_INIT_RAM_LOCK_MIPS /******************************************************************************* * * mips_cache_lock - lock RAM area pointed to by a0 in cache. @@ -263,3 +311,4 @@ mips_cache_lock: j ra .end mips_cache_lock +#endif /* CFG_INIT_RAM_LOCK_MIPS */ diff --git a/cpu/mips/cpu.c b/cpu/mips/cpu.c index 7559ac657..8b43d8eb3 100644 --- a/cpu/mips/cpu.c +++ b/cpu/mips/cpu.c @@ -23,24 +23,45 @@ #include #include -#include #include +#include +#include + +#define cache_op(op,addr) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3\n\t \n" \ + " cache %0, %1 \n" \ + " .set pop \n" \ + : \ + : "i" (op), "R" (*(unsigned char *)(addr))) + +void __attribute__((weak)) _machine_restart(void) +{ +} int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { -#if defined(CONFIG_INCA_IP) - *INCA_IP_WDT_RST_REQ = 0x3f; -#elif defined(CONFIG_PURPLE) || defined(CONFIG_TB0229) - void (*f)(void) = (void *) 0xbfc00000; + _machine_restart(); - f(); -#endif fprintf(stderr, "*** reset failed ***\n"); return 0; } void flush_cache(ulong start_addr, ulong size) { + unsigned long lsize = CFG_CACHELINE_SIZE; + unsigned long addr = start_addr & ~(lsize - 1); + unsigned long aend = (start_addr + size - 1) & ~(lsize - 1); + + while (1) { + cache_op(Hit_Writeback_Inv_D, start_addr); + cache_op(Hit_Invalidate_I, start_addr); + if (addr == aend) + break; + addr += lsize; + } } void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1) diff --git a/cpu/mips/start.S b/cpu/mips/start.S index c92b16278..baac2ceaf 100644 --- a/cpu/mips/start.S +++ b/cpu/mips/start.S @@ -27,6 +27,30 @@ #include #include + /* + * For the moment disable interrupts, mark the kernel mode and + * set ST0_KX so that the CPU does not spit fire when using + * 64-bit addresses. + */ + .macro setup_c0_status set clr + .set push + mfc0 t0, CP0_STATUS + or t0, ST0_CU0 | \set | 0x1f | \clr + xor t0, 0x1f | \clr + mtc0 t0, CP0_STATUS + .set noreorder + sll zero, 3 # ehb + .set pop + .endm + + .macro setup_c0_status_reset +#ifdef CONFIG_64BIT + setup_c0_status ST0_KX 0 +#else + setup_c0_status 0 0 +#endif + .endm + #define RVECENT(f,n) \ b f; nop #define XVECENT(f,bev) \ @@ -211,19 +235,11 @@ reset: mtc0 zero, CP0_WATCHLO mtc0 zero, CP0_WATCHHI - /* STATUS register */ -#ifdef CONFIG_TB0229 - li k0, ST0_CU0 -#else - mfc0 k0, CP0_STATUS -#endif - li k1, ~ST0_IE - and k0, k1 - mtc0 k0, CP0_STATUS - - /* CAUSE register */ + /* WP(Watch Pending), SW0/1 should be cleared. */ mtc0 zero, CP0_CAUSE + setup_c0_status_reset + /* Init Timer */ mtc0 zero, CP0_COUNT mtc0 zero, CP0_COMPARE @@ -240,14 +256,6 @@ reset: 1: lw gp, 0(ra) -#ifdef CONFIG_INCA_IP - /* Disable INCA-IP Watchdog. - */ - la t9, disable_incaip_wdt - jalr t9 - nop -#endif - /* Initialize any external memory. */ la t9, lowlevel_init @@ -267,10 +275,12 @@ reset: /* Set up temporary stack. */ +#ifdef CFG_INIT_RAM_LOCK_MIPS li a0, CFG_INIT_SP_OFFSET la t9, mips_cache_lock jalr t9 nop +#endif li t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET la sp, 0(t0) diff --git a/cpu/mpc5xxx/cpu.c b/cpu/mpc5xxx/cpu.c index e4d616822..ace16535f 100644 --- a/cpu/mpc5xxx/cpu.c +++ b/cpu/mpc5xxx/cpu.c @@ -114,12 +114,14 @@ unsigned long get_tbclk (void) /* ------------------------------------------------------------------------- */ -#ifdef CONFIG_OF_LIBFDT +#if defined(CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP) void ft_cpu_setup(void *blob, bd_t *bd) { int div = in_8((void*)CFG_MBAR + 0x204) & 0x0020 ? 8 : 4; char * cpu_path = "/cpus/" OF_CPU; +#ifdef CONFIG_MPC5xxx_FEC char * eth_path = "/" OF_SOC "/ethernet@3000"; +#endif do_fixup_by_path_u32(blob, cpu_path, "timebase-frequency", OF_TBCLK, 1); do_fixup_by_path_u32(blob, cpu_path, "bus-frequency", bd->bi_busfreq, 1); @@ -127,7 +129,9 @@ void ft_cpu_setup(void *blob, bd_t *bd) do_fixup_by_path_u32(blob, "/" OF_SOC, "bus-frequency", bd->bi_ipbfreq, 1); do_fixup_by_path_u32(blob, "/" OF_SOC, "system-frequency", bd->bi_busfreq*div, 1); +#ifdef CONFIG_MPC5xxx_FEC do_fixup_by_path(blob, eth_path, "mac-address", bd->bi_enetaddr, 6, 0); do_fixup_by_path(blob, eth_path, "local-mac-address", bd->bi_enetaddr, 6, 0); +#endif } #endif diff --git a/cpu/mpc8260/cpu.c b/cpu/mpc8260/cpu.c index 55e61a188..414759e74 100644 --- a/cpu/mpc8260/cpu.c +++ b/cpu/mpc8260/cpu.c @@ -300,7 +300,7 @@ void watchdog_reset (void) #endif /* CONFIG_WATCHDOG */ /* ------------------------------------------------------------------------- */ -#if defined(CONFIG_OF_LIBFDT) +#if defined(CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP) void ft_cpu_setup (void *blob, bd_t *bd) { char * cpu_path = "/cpus/" OF_CPU; diff --git a/cpu/mpc83xx/Makefile b/cpu/mpc83xx/Makefile index 94a3cb833..fcb6a5246 100644 --- a/cpu/mpc83xx/Makefile +++ b/cpu/mpc83xx/Makefile @@ -28,9 +28,20 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a START = start.o -COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \ - spd_sdram.o ecc.o qe_io.o pci.o fdt.o +COBJS-y += traps.o +COBJS-y += cpu.o +COBJS-y += cpu_init.o +COBJS-y += speed.o +COBJS-y += interrupts.o +COBJS-y += spd_sdram.o +COBJS-y += ecc.o +COBJS-$(CONFIG_QE) += qe_io.o +COBJS-$(CONFIG_FSL_SERDES) += serdes.o +COBJS-$(CONFIG_83XX_GENERIC_PCI) += pci.o +COBJS-$(CONFIG_OF_LIBFDT) += fdt.o + +COBJS := $(COBJS-y) SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) START := $(addprefix $(obj),$(START)) diff --git a/cpu/mpc83xx/cpu_init.c b/cpu/mpc83xx/cpu_init.c index e643037d2..fba5b02ec 100644 --- a/cpu/mpc83xx/cpu_init.c +++ b/cpu/mpc83xx/cpu_init.c @@ -79,6 +79,12 @@ void cpu_init_f (volatile immap_t * im) (CFG_ACR_RPTCNT << ACR_RPTCNT_SHIFT); #endif +#ifdef CFG_SPCR_OPT + /* Optimize transactions between CSB and other devices */ + im->sysconf.spcr = (im->sysconf.spcr & ~SPCR_OPT) | + (CFG_SPCR_OPT << SPCR_OPT_SHIFT); +#endif + #ifdef CFG_SPCR_TSECEP /* all eTSEC's Emergency priority */ im->sysconf.spcr = (im->sysconf.spcr & ~SPCR_TSECEP) | diff --git a/cpu/mpc83xx/fdt.c b/cpu/mpc83xx/fdt.c index 6f55932da..b39f678f1 100644 --- a/cpu/mpc83xx/fdt.c +++ b/cpu/mpc83xx/fdt.c @@ -24,9 +24,6 @@ */ #include - -#if defined(CONFIG_OF_LIBFDT) - #include #include @@ -49,6 +46,14 @@ void ft_cpu_setup(void *blob, bd_t *bd) "clock-frequency", gd->core_clk, 1); do_fixup_by_prop_u32(blob, "device_type", "soc", 4, "bus-frequency", bd->bi_busfreq, 1); + do_fixup_by_compat_u32(blob, "fsl,soc", + "bus-frequency", bd->bi_busfreq, 1); + do_fixup_by_compat_u32(blob, "fsl,soc", + "clock-frequency", bd->bi_busfreq, 1); + do_fixup_by_compat_u32(blob, "fsl,immr", + "bus-frequency", bd->bi_busfreq, 1); + do_fixup_by_compat_u32(blob, "fsl,immr", + "clock-frequency", bd->bi_busfreq, 1); #ifdef CONFIG_QE ft_qe_setup(blob); #endif @@ -68,4 +73,3 @@ void ft_cpu_setup(void *blob, bd_t *bd) fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); } -#endif /* CONFIG_OF_LIBFDT */ diff --git a/cpu/mpc83xx/pci.c b/cpu/mpc83xx/pci.c index 18558db53..adabf7aac 100644 --- a/cpu/mpc83xx/pci.c +++ b/cpu/mpc83xx/pci.c @@ -33,7 +33,6 @@ #include -#ifdef CONFIG_83XX_GENERIC_PCI #define MAX_BUSES 2 DECLARE_GLOBAL_DATA_PTR; @@ -209,4 +208,3 @@ void ft_pci_setup(void *blob, bd_t *bd) } } #endif /* CONFIG_OF_LIBFDT */ -#endif /* CONFIG_83XX_GENERIC_PCI */ diff --git a/cpu/mpc83xx/qe_io.c b/cpu/mpc83xx/qe_io.c index 8b3937aa9..ce91a07d7 100644 --- a/cpu/mpc83xx/qe_io.c +++ b/cpu/mpc83xx/qe_io.c @@ -25,7 +25,6 @@ #include "asm/io.h" #include "asm/immap_83xx.h" -#if defined(CONFIG_QE) #define NUM_OF_PINS 32 void qe_config_iopin(u8 port, u8 pin, int dir, int open_drain, int assign) { @@ -81,5 +80,3 @@ void qe_config_iopin(u8 port, u8 pin, int dir, int open_drain, int assign) out_be32(&par_io->ioport[port].ppar1, pin_2bit_assign | tmp_val); } } - -#endif /* CONFIG_QE */ diff --git a/cpu/mpc83xx/serdes.c b/cpu/mpc83xx/serdes.c new file mode 100644 index 000000000..020c4c8f9 --- /dev/null +++ b/cpu/mpc83xx/serdes.c @@ -0,0 +1,145 @@ +/* + * Freescale SerDes initialization routine + * + * Copyright (C) 2007 Freescale Semicondutor, Inc. All rights reserved. + * Copyright (C) 2008 MontaVista Software, Inc. All rights reserved. + * + * Author: Li Yang + * + * 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 +#include +#include +#include + +/* SerDes registers */ +#define FSL_SRDSCR0_OFFS 0x0 +#define FSL_SRDSCR0_DPP_1V2 0x00008800 +#define FSL_SRDSCR1_OFFS 0x4 +#define FSL_SRDSCR1_PLLBW 0x00000040 +#define FSL_SRDSCR2_OFFS 0x8 +#define FSL_SRDSCR2_VDD_1V2 0x00800000 +#define FSL_SRDSCR2_SEIC_MASK 0x00001c1c +#define FSL_SRDSCR2_SEIC_SATA 0x00001414 +#define FSL_SRDSCR2_SEIC_PEX 0x00001010 +#define FSL_SRDSCR2_SEIC_SGMII 0x00000101 +#define FSL_SRDSCR3_OFFS 0xc +#define FSL_SRDSCR3_KFR_SATA 0x10100000 +#define FSL_SRDSCR3_KPH_SATA 0x04040000 +#define FSL_SRDSCR3_SDFM_SATA_PEX 0x01010000 +#define FSL_SRDSCR3_SDTXL_SATA 0x00000505 +#define FSL_SRDSCR4_OFFS 0x10 +#define FSL_SRDSCR4_PROT_SATA 0x00000808 +#define FSL_SRDSCR4_PROT_PEX 0x00000101 +#define FSL_SRDSCR4_PROT_SGMII 0x00000505 +#define FSL_SRDSCR4_PLANE_X2 0x01000000 +#define FSL_SRDSRSTCTL_OFFS 0x20 +#define FSL_SRDSRSTCTL_RST 0x80000000 +#define FSL_SRDSRSTCTL_SATA_RESET 0xf + +void fsl_setup_serdes(u32 offset, char proto, char rfcks, char vdd) +{ + void *regs = (void *)CFG_IMMR + offset; + u32 tmp; + + /* 1.0V corevdd */ + if (vdd) { + /* DPPE/DPPA = 0 */ + tmp = in_be32(regs + FSL_SRDSCR0_OFFS); + tmp &= ~FSL_SRDSCR0_DPP_1V2; + out_be32(regs + FSL_SRDSCR0_OFFS, tmp); + + /* VDD = 0 */ + tmp = in_be32(regs + FSL_SRDSCR2_OFFS); + tmp &= ~FSL_SRDSCR2_VDD_1V2; + out_be32(regs + FSL_SRDSCR2_OFFS, tmp); + } + + /* protocol specific configuration */ + switch (proto) { + case FSL_SERDES_PROTO_SATA: + /* Set and clear reset bits */ + tmp = in_be32(regs + FSL_SRDSRSTCTL_OFFS); + tmp |= FSL_SRDSRSTCTL_SATA_RESET; + out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp); + udelay(1000); + tmp &= ~FSL_SRDSRSTCTL_SATA_RESET; + out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp); + + /* Configure SRDSCR1 */ + tmp = in_be32(regs + FSL_SRDSCR1_OFFS); + tmp &= ~FSL_SRDSCR1_PLLBW; + out_be32(regs + FSL_SRDSCR1_OFFS, tmp); + + /* Configure SRDSCR2 */ + tmp = in_be32(regs + FSL_SRDSCR2_OFFS); + tmp &= ~FSL_SRDSCR2_SEIC_MASK; + tmp |= FSL_SRDSCR2_SEIC_SATA; + out_be32(regs + FSL_SRDSCR2_OFFS, tmp); + + /* Configure SRDSCR3 */ + tmp = FSL_SRDSCR3_KFR_SATA | FSL_SRDSCR3_KPH_SATA | + FSL_SRDSCR3_SDFM_SATA_PEX | + FSL_SRDSCR3_SDTXL_SATA; + out_be32(regs + FSL_SRDSCR3_OFFS, tmp); + + /* Configure SRDSCR4 */ + tmp = rfcks | FSL_SRDSCR4_PROT_SATA; + out_be32(regs + FSL_SRDSCR4_OFFS, tmp); + break; + case FSL_SERDES_PROTO_PEX: + case FSL_SERDES_PROTO_PEX_X2: + /* Configure SRDSCR1 */ + tmp = in_be32(regs + FSL_SRDSCR1_OFFS); + tmp |= FSL_SRDSCR1_PLLBW; + out_be32(regs + FSL_SRDSCR1_OFFS, tmp); + + /* Configure SRDSCR2 */ + tmp = in_be32(regs + FSL_SRDSCR2_OFFS); + tmp &= ~FSL_SRDSCR2_SEIC_MASK; + tmp |= FSL_SRDSCR2_SEIC_PEX; + out_be32(regs + FSL_SRDSCR2_OFFS, tmp); + + /* Configure SRDSCR3 */ + tmp = FSL_SRDSCR3_SDFM_SATA_PEX; + out_be32(regs + FSL_SRDSCR3_OFFS, tmp); + + /* Configure SRDSCR4 */ + tmp = rfcks | FSL_SRDSCR4_PROT_PEX; + if (proto == FSL_SERDES_PROTO_PEX_X2) + tmp |= FSL_SRDSCR4_PLANE_X2; + out_be32(regs + FSL_SRDSCR4_OFFS, tmp); + break; + case FSL_SERDES_PROTO_SGMII: + /* Configure SRDSCR1 */ + tmp = in_be32(regs + FSL_SRDSCR1_OFFS); + tmp &= ~FSL_SRDSCR1_PLLBW; + out_be32(regs + FSL_SRDSCR1_OFFS, tmp); + + /* Configure SRDSCR2 */ + tmp = in_be32(regs + FSL_SRDSCR2_OFFS); + tmp &= ~FSL_SRDSCR2_SEIC_MASK; + tmp |= FSL_SRDSCR2_SEIC_SGMII; + out_be32(regs + FSL_SRDSCR2_OFFS, tmp); + + /* Configure SRDSCR3 */ + out_be32(regs + FSL_SRDSCR3_OFFS, 0); + + /* Configure SRDSCR4 */ + tmp = rfcks | FSL_SRDSCR4_PROT_SGMII; + out_be32(regs + FSL_SRDSCR4_OFFS, tmp); + break; + default: + return; + } + + /* Do a software reset */ + tmp = in_be32(regs + FSL_SRDSRSTCTL_OFFS); + tmp |= FSL_SRDSRSTCTL_RST; + out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp); +} diff --git a/cpu/mpc85xx/Makefile b/cpu/mpc85xx/Makefile index 2205dca02..adbc58582 100644 --- a/cpu/mpc85xx/Makefile +++ b/cpu/mpc85xx/Makefile @@ -29,6 +29,9 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a START = start.o resetvec.o +SOBJS-$(CONFIG_MP) += release.o +SOBJS = $(SOBJS-y) +COBJS-$(CONFIG_MP) += mp.o COBJS-$(CONFIG_OF_LIBFDT) += fdt.o COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o tlb.o \ pci.o serial_scc.o commproc.o ether_fcc.o spd_sdram.o qe_io.o \ diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c index ac8b018b0..dcd881737 100644 --- a/cpu/mpc85xx/cpu.c +++ b/cpu/mpc85xx/cpu.c @@ -1,5 +1,5 @@ /* - * Copyright 2004,2007 Freescale Semiconductor, Inc. + * Copyright 2004,2007,2008 Freescale Semiconductor, Inc. * (C) Copyright 2002, 2003 Motorola Inc. * Xianghua Xiao (X.Xiao@motorola.com) * @@ -30,6 +30,41 @@ #include #include +DECLARE_GLOBAL_DATA_PTR; + +struct cpu_type { + char name[15]; + u32 soc_ver; +}; + +#define CPU_TYPE_ENTRY(x) {#x, SVR_##x} + +struct cpu_type cpu_type_list [] = { + CPU_TYPE_ENTRY(8533), + CPU_TYPE_ENTRY(8533_E), + CPU_TYPE_ENTRY(8540), + CPU_TYPE_ENTRY(8541), + CPU_TYPE_ENTRY(8541_E), + CPU_TYPE_ENTRY(8543), + CPU_TYPE_ENTRY(8543_E), + CPU_TYPE_ENTRY(8544), + CPU_TYPE_ENTRY(8544_E), + CPU_TYPE_ENTRY(8545), + CPU_TYPE_ENTRY(8545_E), + CPU_TYPE_ENTRY(8547_E), + CPU_TYPE_ENTRY(8548), + CPU_TYPE_ENTRY(8548_E), + CPU_TYPE_ENTRY(8555), + CPU_TYPE_ENTRY(8555_E), + CPU_TYPE_ENTRY(8560), + CPU_TYPE_ENTRY(8567), + CPU_TYPE_ENTRY(8567_E), + CPU_TYPE_ENTRY(8568), + CPU_TYPE_ENTRY(8568_E), + CPU_TYPE_ENTRY(8572), + CPU_TYPE_ENTRY(8572_E), +}; + int checkcpu (void) { sys_info_t sysinfo; @@ -39,47 +74,26 @@ int checkcpu (void) uint fam; uint ver; uint major, minor; + int i; u32 ddr_ratio; volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR); svr = get_svr(); - ver = SVR_VER(svr); + ver = SVR_SOC_VER(svr); major = SVR_MAJ(svr); minor = SVR_MIN(svr); puts("CPU: "); - switch (ver) { - case SVR_8540: - puts("8540"); - break; - case SVR_8541: - puts("8541"); - break; - case SVR_8555: - puts("8555"); - break; - case SVR_8560: - puts("8560"); - break; - case SVR_8548: - puts("8548"); - break; - case SVR_8548_E: - puts("8548_E"); - break; - case SVR_8544: - puts("8544"); - break; - case SVR_8544_E: - puts("8544_E"); - break; - case SVR_8568_E: - puts("8568_E"); - break; - default: + + for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++) + if (cpu_type_list[i].soc_ver == ver) { + puts(cpu_type_list[i].name); + break; + } + + if (i == ARRAY_SIZE(cpu_type_list)) puts("Unknown"); - break; - } + printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr); pvr = get_pvr(); @@ -108,13 +122,16 @@ int checkcpu (void) ddr_ratio = ((gur->porpllsr) & 0x00003e00) >> 9; switch (ddr_ratio) { case 0x0: - printf(" DDR:%4lu MHz, ", sysinfo.freqDDRBus / 2000000); + printf(" DDR:%4lu MHz (%lu MT/s data rate), ", + sysinfo.freqDDRBus / 2000000, sysinfo.freqDDRBus / 1000000); break; case 0x7: - printf(" DDR:%4lu MHz (Synchronous), ", sysinfo.freqDDRBus / 2000000); + printf(" DDR:%4lu MHz (%lu MT/s data rate) (Synchronous), ", + sysinfo.freqDDRBus / 2000000, sysinfo.freqDDRBus / 1000000); break; default: - printf(" DDR:%4lu MHz (Asynchronous), ", sysinfo.freqDDRBus / 2000000); + printf(" DDR:%4lu MHz (%lu MT/s data rate) (Asynchronous), ", + sysinfo.freqDDRBus / 2000000, sysinfo.freqDDRBus / 1000000); break; } @@ -142,10 +159,9 @@ int checkcpu (void) printf("LBC: unknown (lcrr: 0x%08x)\n", lcrr); } - if (ver == SVR_8560) { - printf("CPM: %lu Mhz\n", - sysinfo.freqSystemBus / 1000000); - } +#ifdef CONFIG_CPM2 + printf("CPM: %lu Mhz\n", sysinfo.freqSystemBus / 1000000); +#endif puts("L1: D-cache 32 kB enabled\n I-cache 32 kB enabled\n"); @@ -190,11 +206,7 @@ int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) */ unsigned long get_tbclk (void) { - - sys_info_t sys_info; - - get_sys_info(&sys_info); - return ((sys_info.freqSystemBus + 7L) / 8L); + return (gd->bus_clk + 4UL)/8UL; } diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c index c0ff1d512..fce0c4805 100644 --- a/cpu/mpc85xx/cpu_init.c +++ b/cpu/mpc85xx/cpu_init.c @@ -33,6 +33,7 @@ #include #include #include +#include "mp.h" DECLARE_GLOBAL_DATA_PTR; @@ -127,12 +128,12 @@ void config_8560_ioports (volatile ccsr_cpm_t * cpm) /* We run cpu_init_early_f in AS = 1 */ void cpu_init_early_f(void) { - set_tlb(0, CFG_CCSRBAR, CFG_CCSRBAR, + set_tlb(0, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 1, 0, BOOKE_PAGESZ_4K, 0); /* set up CCSR if we want it moved */ -#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR) +#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR_PHYS) { u32 temp; @@ -141,7 +142,7 @@ void cpu_init_early_f(void) 1, 1, BOOKE_PAGESZ_4K, 0); temp = in_be32((volatile u32 *)CFG_CCSRBAR_DEFAULT); - out_be32((volatile u32 *)CFG_CCSRBAR_DEFAULT, CFG_CCSRBAR >> 12); + out_be32((volatile u32 *)CFG_CCSRBAR_DEFAULT, CFG_CCSRBAR_PHYS >> 12); temp = in_be32((volatile u32 *)CFG_CCSRBAR); } @@ -328,5 +329,8 @@ int cpu_init_r(void) qe_reset(); #endif +#if defined(CONFIG_MP) + setup_mp(); +#endif return 0; } diff --git a/cpu/mpc85xx/fdt.c b/cpu/mpc85xx/fdt.c index a6b014cec..bde6d1e96 100644 --- a/cpu/mpc85xx/fdt.c +++ b/cpu/mpc85xx/fdt.c @@ -28,6 +28,54 @@ #include extern void ft_qe_setup(void *blob); +#ifdef CONFIG_MP +#include "mp.h" +DECLARE_GLOBAL_DATA_PTR; + +void ft_fixup_cpu(void *blob, u64 memory_limit) +{ + int off; + ulong spin_tbl_addr = get_spin_addr(); + u32 bootpg, id = get_my_id(); + + /* if we have 4G or more of memory, put the boot page at 4Gb-4k */ + if ((u64)gd->ram_size > 0xfffff000) + bootpg = 0xfffff000; + else + bootpg = gd->ram_size - 4096; + + off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4); + while (off != -FDT_ERR_NOTFOUND) { + u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0); + + if (reg) { + if (*reg == id) { + fdt_setprop_string(blob, off, "status", "okay"); + } else { + u32 val = *reg * SIZE_BOOT_ENTRY + spin_tbl_addr; + val = cpu_to_fdt32(val); + fdt_setprop_string(blob, off, "status", + "disabled"); + fdt_setprop_string(blob, off, "enable-method", + "spin-table"); + fdt_setprop(blob, off, "cpu-release-addr", + &val, sizeof(val)); + } + } else { + printf ("cpu NULL\n"); + } + off = fdt_node_offset_by_prop_value(blob, off, + "device_type", "cpu", 4); + } + + /* Reserve the boot page so OSes dont use it */ + if ((u64)bootpg < memory_limit) { + off = fdt_add_mem_rsv(blob, bootpg, (u64)4096); + if (off < 0) + printf("%s: %s\n", __FUNCTION__, fdt_strerror(off)); + } +} +#endif void ft_cpu_setup(void *blob, bd_t *bd) { @@ -62,4 +110,8 @@ void ft_cpu_setup(void *blob, bd_t *bd) #endif fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); + +#ifdef CONFIG_MP + ft_fixup_cpu(blob, (u64)bd->bi_memstart + (u64)bd->bi_memsize); +#endif } diff --git a/cpu/mpc85xx/mp.c b/cpu/mpc85xx/mp.c new file mode 100644 index 000000000..7b10fba0a --- /dev/null +++ b/cpu/mpc85xx/mp.c @@ -0,0 +1,210 @@ +/* + * Copyright 2008 Freescale Semiconductor. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include "mp.h" + +DECLARE_GLOBAL_DATA_PTR; + +u32 get_my_id() +{ + return mfspr(SPRN_PIR); +} + +int cpu_reset(int nr) +{ + volatile ccsr_pic_t *pic = (void *)(CFG_MPC85xx_PIC_ADDR); + out_be32(&pic->pir, 1 << nr); + (void)in_be32(&pic->pir); + out_be32(&pic->pir, 0x0); + + return 0; +} + +int cpu_status(int nr) +{ + u32 *table, id = get_my_id(); + + if (nr == id) { + table = (u32 *)get_spin_addr(); + printf("table base @ 0x%08x\n", table); + } else { + table = (u32 *)get_spin_addr() + nr * NUM_BOOT_ENTRY; + printf("Running on cpu %d\n", id); + printf("\n"); + printf("table @ 0x%08x:\n", table); + printf(" addr - 0x%08x\n", table[BOOT_ENTRY_ADDR_LOWER]); + printf(" pir - 0x%08x\n", table[BOOT_ENTRY_PIR]); + printf(" r3 - 0x%08x\n", table[BOOT_ENTRY_R3_LOWER]); + printf(" r6 - 0x%08x\n", table[BOOT_ENTRY_R6_LOWER]); + } + + return 0; +} + +static u8 boot_entry_map[4] = { + 0, + BOOT_ENTRY_PIR, + BOOT_ENTRY_R3_LOWER, + BOOT_ENTRY_R6_LOWER, +}; + +int cpu_release(int nr, int argc, char *argv[]) +{ + u32 i, val, *table = (u32 *)get_spin_addr() + nr * NUM_BOOT_ENTRY; + u64 boot_addr; + + if (nr == get_my_id()) { + printf("Invalid to release the boot core.\n\n"); + return 1; + } + + if (argc != 4) { + printf("Invalid number of arguments to release.\n\n"); + return 1; + } + +#ifdef CFG_64BIT_STRTOUL + boot_addr = simple_strtoull(argv[0], NULL, 16); +#else + boot_addr = simple_strtoul(argv[0], NULL, 16); +#endif + + /* handle pir, r3, r6 */ + for (i = 1; i < 4; i++) { + if (argv[i][0] != '-') { + u8 entry = boot_entry_map[i]; + val = simple_strtoul(argv[i], NULL, 16); + table[entry] = val; + } + } + + table[BOOT_ENTRY_ADDR_UPPER] = (u32)(boot_addr >> 32); + table[BOOT_ENTRY_ADDR_LOWER] = (u32)(boot_addr & 0xffffffff); + + return 0; +} + +ulong get_spin_addr(void) +{ + extern ulong __secondary_start_page; + extern ulong __spin_table; + + ulong addr = + (ulong)&__spin_table - (ulong)&__secondary_start_page; + addr += 0xfffff000; + + return addr; +} + +static void pq3_mp_up(unsigned long bootpg) +{ + u32 up, cpu_up_mask, whoami; + u32 *table = (u32 *)get_spin_addr(); + volatile u32 bpcr; + volatile ccsr_local_ecm_t *ecm = (void *)(CFG_MPC85xx_ECM_ADDR); + volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR); + volatile ccsr_pic_t *pic = (void *)(CFG_MPC85xx_PIC_ADDR); + u32 devdisr; + int timeout = 10; + + whoami = in_be32(&pic->whoami); + out_be32(&ecm->bptr, 0x80000000 | (bootpg >> 12)); + + /* disable time base at the platform */ + devdisr = in_be32(&gur->devdisr); + if (whoami) + devdisr |= MPC85xx_DEVDISR_TB0; + else + devdisr |= MPC85xx_DEVDISR_TB1; + out_be32(&gur->devdisr, devdisr); + + /* release the hounds */ + up = ((1 << CONFIG_NR_CPUS) - 1); + bpcr = in_be32(&ecm->eebpcr); + bpcr |= (up << 24); + out_be32(&ecm->eebpcr, bpcr); + asm("sync; isync; msync"); + + cpu_up_mask = 1 << whoami; + /* wait for everyone */ + while (timeout) { + int i; + for (i = 1; i < CONFIG_NR_CPUS; i++) { + if (table[i * NUM_BOOT_ENTRY]) + cpu_up_mask |= (1 << i); + }; + + if ((cpu_up_mask & up) == up) + break; + + udelay(100); + timeout--; + } + + /* enable time base at the platform */ + if (whoami) + devdisr |= MPC85xx_DEVDISR_TB1; + else + devdisr |= MPC85xx_DEVDISR_TB0; + out_be32(&gur->devdisr, devdisr); + mtspr(SPRN_TBWU, 0); + mtspr(SPRN_TBWL, 0); + + devdisr &= ~(MPC85xx_DEVDISR_TB0 | MPC85xx_DEVDISR_TB1); + out_be32(&gur->devdisr, devdisr); +} + +void cpu_mp_lmb_reserve(struct lmb *lmb) +{ + u32 bootpg; + + /* if we have 4G or more of memory, put the boot page at 4Gb-4k */ + if ((u64)gd->ram_size > 0xfffff000) + bootpg = 0xfffff000; + else + bootpg = gd->ram_size - 4096; + + lmb_reserve(lmb, bootpg, 4096); +} + +void setup_mp(void) +{ + extern ulong __secondary_start_page; + ulong fixup = (ulong)&__secondary_start_page; + u32 bootpg; + + /* if we have 4G or more of memory, put the boot page at 4Gb-4k */ + if ((u64)gd->ram_size > 0xfffff000) + bootpg = 0xfffff000; + else + bootpg = gd->ram_size - 4096; + + memcpy((void *)bootpg, (void *)fixup, 4096); + flush_cache(bootpg, 4096); + + pq3_mp_up(bootpg); +} diff --git a/cpu/mpc85xx/mp.h b/cpu/mpc85xx/mp.h new file mode 100644 index 000000000..4329286f1 --- /dev/null +++ b/cpu/mpc85xx/mp.h @@ -0,0 +1,20 @@ +#ifndef __MPC85XX_MP_H_ +#define __MPC85XX_MP_H_ + +ulong get_spin_addr(void); +void setup_mp(void); +u32 get_my_id(void); +void cpu_mp_lmb_reserve(struct lmb *lmb); + +#define BOOT_ENTRY_ADDR_UPPER 0 +#define BOOT_ENTRY_ADDR_LOWER 1 +#define BOOT_ENTRY_R3_UPPER 2 +#define BOOT_ENTRY_R3_LOWER 3 +#define BOOT_ENTRY_RESV 4 +#define BOOT_ENTRY_PIR 5 +#define BOOT_ENTRY_R6_UPPER 6 +#define BOOT_ENTRY_R6_LOWER 7 +#define NUM_BOOT_ENTRY 8 +#define SIZE_BOOT_ENTRY (NUM_BOOT_ENTRY * sizeof(u32)) + +#endif diff --git a/cpu/mpc85xx/release.S b/cpu/mpc85xx/release.S new file mode 100644 index 000000000..3b7366ff6 --- /dev/null +++ b/cpu/mpc85xx/release.S @@ -0,0 +1,182 @@ +#include +#include +#include + +#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ + +#include +#include + +#include +#include + +/* To boot secondary cpus, we need a place for them to start up. + * Normally, they start at 0xfffffffc, but that's usually the + * firmware, and we don't want to have to run the firmware again. + * Instead, the primary cpu will set the BPTR to point here to + * this page. We then set up the core, and head to + * start_secondary. Note that this means that the code below + * must never exceed 1023 instructions (the branch at the end + * would then be the 1024th). + */ + .globl __secondary_start_page + .align 12 +__secondary_start_page: +/* First do some preliminary setup */ + lis r3, HID0_EMCP@h /* enable machine check */ + ori r3,r3,HID0_TBEN@l /* enable Timebase */ +#ifdef CONFIG_PHYS_64BIT + ori r3,r3,HID0_ENMAS7@l /* enable MAS7 updates */ +#endif + mtspr SPRN_HID0,r3 + + li r3,(HID1_ASTME|HID1_ABE)@l /* Addr streaming & broadcast */ + mtspr SPRN_HID1,r3 + + /* Enable branch prediction */ + li r3,0x201 + mtspr SPRN_BUCSR,r3 + + /* Enable/invalidate the I-Cache */ + mfspr r0,SPRN_L1CSR1 + ori r0,r0,(L1CSR1_ICFI|L1CSR1_ICE) + mtspr SPRN_L1CSR1,r0 + isync + + /* Enable/invalidate the D-Cache */ + mfspr r0,SPRN_L1CSR0 + ori r0,r0,(L1CSR0_DCFI|L1CSR0_DCE) + msync + isync + mtspr SPRN_L1CSR0,r0 + isync + +#define toreset(x) (x - __secondary_start_page + 0xfffff000) + + /* get our PIR to figure out our table entry */ + lis r3,toreset(__spin_table)@h + ori r3,r3,toreset(__spin_table)@l + + /* r10 has the base address for the entry */ + mfspr r0,SPRN_PIR + mr r4,r0 + slwi r8,r4,5 + add r10,r3,r8 + +#define EPAPR_MAGIC (0x45504150) +#define ENTRY_ADDR_UPPER 0 +#define ENTRY_ADDR_LOWER 4 +#define ENTRY_R3_UPPER 8 +#define ENTRY_R3_LOWER 12 +#define ENTRY_RESV 16 +#define ENTRY_PIR 20 +#define ENTRY_R6_UPPER 24 +#define ENTRY_R6_LOWER 28 +#define ENTRY_SIZE 32 + + /* setup the entry */ + li r3,0 + li r8,1 + stw r0,ENTRY_PIR(r10) + stw r3,ENTRY_ADDR_UPPER(r10) + stw r8,ENTRY_ADDR_LOWER(r10) + stw r3,ENTRY_R3_UPPER(r10) + stw r4,ENTRY_R3_LOWER(r10) + stw r3,ENTRY_R6_UPPER(r10) + stw r3,ENTRY_R6_LOWER(r10) + + /* setup mapping for AS = 1, and jump there */ + lis r11,(MAS0_TLBSEL(1)|MAS0_ESEL(1))@h + mtspr SPRN_MAS0,r11 + lis r11,(MAS1_VALID|MAS1_IPROT)@h + ori r11,r11,(MAS1_TS|MAS1_TSIZE(BOOKE_PAGESZ_4K))@l + mtspr SPRN_MAS1,r11 + lis r11,(0xfffff000|MAS2_I)@h + ori r11,r11,(0xfffff000|MAS2_I)@l + mtspr SPRN_MAS2,r11 + lis r11,(0xfffff000|MAS3_SX|MAS3_SW|MAS3_SR)@h + ori r11,r11,(0xfffff000|MAS3_SX|MAS3_SW|MAS3_SR)@l + mtspr SPRN_MAS3,r11 + tlbwe + + bl 1f +1: mflr r11 + addi r11,r11,28 + mfmsr r13 + ori r12,r13,MSR_IS|MSR_DS@l + + mtspr SPRN_SRR0,r11 + mtspr SPRN_SRR1,r12 + rfi + + /* spin waiting for addr */ +2: + lwz r4,ENTRY_ADDR_LOWER(r10) + andi. r11,r4,1 + bne 2b + + /* get the upper bits of the addr */ + lwz r11,ENTRY_ADDR_UPPER(r10) + + /* setup branch addr */ + mtspr SPRN_SRR0,r4 + + /* mark the entry as released */ + li r8,3 + stw r8,ENTRY_ADDR_LOWER(r10) + + /* mask by ~64M to setup our tlb we will jump to */ + rlwinm r12,r4,0,0,5 + + /* setup r3, r4, r5, r6, r7, r8, r9 */ + lwz r3,ENTRY_R3_LOWER(r10) + li r4,0 + li r5,0 + lwz r6,ENTRY_R6_LOWER(r10) + lis r7,(64*1024*1024)@h + li r8,0 + li r9,0 + + /* load up the pir */ + lwz r0,ENTRY_PIR(r10) + mtspr SPRN_PIR,r0 + mfspr r0,SPRN_PIR + stw r0,ENTRY_PIR(r10) + +/* + * Coming here, we know the cpu has one TLB mapping in TLB1[0] + * which maps 0xfffff000-0xffffffff one-to-one. We set up a + * second mapping that maps addr 1:1 for 64M, and then we jump to + * addr + */ + lis r10,(MAS0_TLBSEL(1)|MAS0_ESEL(0))@h + mtspr SPRN_MAS0,r10 + lis r10,(MAS1_VALID|MAS1_IPROT)@h + ori r10,r10,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l + mtspr SPRN_MAS1,r10 + /* WIMGE = 0b00000 for now */ + mtspr SPRN_MAS2,r12 + ori r12,r12,(MAS3_SX|MAS3_SW|MAS3_SR) + mtspr SPRN_MAS3,r12 +#ifdef CONFIG_ENABLE_36BIT_PHYS + mtspr SPRN_MAS7,r11 +#endif + tlbwe + +/* Now we have another mapping for this page, so we jump to that + * mapping + */ + mtspr SPRN_SRR1,r13 + rfi + + .align 3 + .globl __spin_table +__spin_table: + .space CONFIG_NR_CPUS*ENTRY_SIZE + + /* Fill in the empty space. The actual reset vector is + * the last word of the page */ +__secondary_start_code_end: + .space 4092 - (__secondary_start_code_end - __secondary_start_page) +__secondary_reset_vector: + b __secondary_start_page diff --git a/cpu/mpc85xx/speed.c b/cpu/mpc85xx/speed.c index 952f30cf3..d90d39767 100644 --- a/cpu/mpc85xx/speed.c +++ b/cpu/mpc85xx/speed.c @@ -48,6 +48,8 @@ void get_sys_info (sys_info_t * sysInfo) * overflow for processor speeds above 2GHz */ half_freqSystemBus = sysInfo->freqSystemBus/2; sysInfo->freqProcessor = e500_ratio*half_freqSystemBus; + + /* Note: freqDDRBus is the MCLK frequency, not the data rate. */ sysInfo->freqDDRBus = sysInfo->freqSystemBus; #ifdef CONFIG_DDR_CLK_FREQ @@ -75,6 +77,7 @@ int get_clocks (void) get_sys_info (&sys_info); gd->cpu_clk = sys_info.freqProcessor; gd->bus_clk = sys_info.freqSystemBus; + gd->mem_clk = sys_info.freqDDRBus; gd->i2c1_clk = sys_info.freqSystemBus; gd->i2c2_clk = sys_info.freqSystemBus; @@ -96,14 +99,7 @@ int get_clocks (void) *********************************************/ ulong get_bus_freq (ulong dummy) { - ulong val; - - sys_info_t sys_info; - - get_sys_info (&sys_info); - val = sys_info.freqSystemBus; - - return val; + return gd->bus_clk; } /******************************************** @@ -112,12 +108,5 @@ ulong get_bus_freq (ulong dummy) *********************************************/ ulong get_ddr_freq (ulong dummy) { - ulong val; - - sys_info_t sys_info; - - get_sys_info (&sys_info); - val = sys_info.freqDDRBus; - - return val; + return gd->mem_clk; } diff --git a/cpu/mpc86xx/cpu.c b/cpu/mpc86xx/cpu.c index bf4e651aa..3c7476445 100644 --- a/cpu/mpc86xx/cpu.c +++ b/cpu/mpc86xx/cpu.c @@ -69,7 +69,7 @@ checkcpu(void) printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr); svr = get_svr(); - ver = SVR_VER(svr); + ver = SVR_SOC_VER(svr); major = SVR_MAJ(svr); minor = SVR_MIN(svr); diff --git a/cpu/mpc8xx/Makefile b/cpu/mpc8xx/Makefile index 223b30cbc..dbdc2e061 100644 --- a/cpu/mpc8xx/Makefile +++ b/cpu/mpc8xx/Makefile @@ -29,7 +29,7 @@ LIB = $(obj)lib$(CPU).a START = start.o kgdb.o COBJS = bedbug_860.o commproc.o cpu.o cpu_init.o \ - fec.o i2c.o interrupts.o lcd.o scc.o \ + fec.o fdt.o i2c.o interrupts.o lcd.o scc.o \ serial.o speed.o spi.o \ traps.o upatch.o video.o SOBJS = plprcr_write.o diff --git a/cpu/mpc8xx/cpu.c b/cpu/mpc8xx/cpu.c index c87835251..ec6a3fd5d 100644 --- a/cpu/mpc8xx/cpu.c +++ b/cpu/mpc8xx/cpu.c @@ -634,17 +634,4 @@ void reset_8xx_watchdog (volatile immap_t * immr) immr->im_siu_conf.sc_swsr = 0xaa39; /* write magic2 */ # endif /* CONFIG_LWMON */ } - #endif /* CONFIG_WATCHDOG */ - -/* ------------------------------------------------------------------------- */ -#if defined(CONFIG_OF_LIBFDT) -void ft_cpu_setup (void *blob, bd_t *bd) -{ - char * cpu_path = "/cpus/" OF_CPU; - - do_fixup_by_path_u32(blob, cpu_path, "bus-frequency", bd->bi_busfreq, 1); - do_fixup_by_path_u32(blob, cpu_path, "timebase-frequency", OF_TBCLK, 1); - do_fixup_by_path_u32(blob, cpu_path, "clock-frequency", bd->bi_intfreq, 1); -} -#endif /* CONFIG_OF_LIBFDT */ diff --git a/cpu/mpc8xx/fdt.c b/cpu/mpc8xx/fdt.c new file mode 100644 index 000000000..567094a96 --- /dev/null +++ b/cpu/mpc8xx/fdt.c @@ -0,0 +1,46 @@ +/* + * Copyright 2008 (C) Bryan O'Donoghue + * + * Code copied & edited from Freescale mpc85xx stuff. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +void ft_cpu_setup(void *blob, bd_t *bd) +{ + do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, + "timebase-frequency", get_tbclk(), 1); + do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, + "bus-frequency", bd->bi_busfreq, 1); + do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, + "clock-frequency", bd->bi_intfreq, 1); + do_fixup_by_compat_u32(blob, "fsl,cpm-brg", "clock-frequency", + gd->brg_clk, 1); + + /* Fixup ethernet MAC addresses */ + fdt_fixup_ethernet(blob, bd); + + fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); +} diff --git a/cpu/mpc8xx/speed.c b/cpu/mpc8xx/speed.c index 11b089330..070babcc9 100644 --- a/cpu/mpc8xx/speed.c +++ b/cpu/mpc8xx/speed.c @@ -174,6 +174,27 @@ unsigned long measure_gclk(void) #endif +void get_brgclk(uint sccr) +{ + uint divider = 0; + + switch((sccr&SCCR_DFBRG11)>>11){ + case 0: + divider = 1; + break; + case 1: + divider = 4; + break; + case 2: + divider = 16; + break; + case 3: + divider = 64; + break; + } + gd->brg_clk = gd->cpu_clk/divider; +} + #if !defined(CONFIG_8xx_CPUCLK_DEFAULT) /* @@ -223,6 +244,8 @@ int get_clocks (void) gd->bus_clk = gd->cpu_clk / 2; } + get_brgclk(sccr); + return (0); } @@ -254,6 +277,8 @@ int get_clocks_866 (void) gd->cpu_clk = measure_gclk (); #endif + get_brgclk(immr->im_clkrst.car_sccr); + /* if cpu clock <= 66 MHz then set bus division factor to 1, * otherwise set it to 2 */ diff --git a/disk/part.c b/disk/part.c index 56b9427c2..3c71208a1 100644 --- a/disk/part.c +++ b/disk/part.c @@ -35,6 +35,7 @@ #endif #if (defined(CONFIG_CMD_IDE) || \ + defined(CONFIG_CMD_SATA) || \ defined(CONFIG_CMD_SCSI) || \ defined(CONFIG_CMD_USB) || \ defined(CONFIG_MMC) || \ @@ -49,6 +50,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_SATA) + {.name = "sata", .get_dev = sata_get_dev, }, +#endif #if defined(CONFIG_CMD_SCSI) { .name = "scsi", .get_dev = scsi_get_dev, }, #endif @@ -87,6 +91,7 @@ block_dev_desc_t *get_dev(char* ifname, int dev) #endif #if (defined(CONFIG_CMD_IDE) || \ + defined(CONFIG_CMD_SATA) || \ defined(CONFIG_CMD_SCSI) || \ defined(CONFIG_CMD_USB) || \ defined(CONFIG_MMC) || \ @@ -116,6 +121,12 @@ void dev_print (block_dev_desc_t *dev_desc) dev_desc->vendor, dev_desc->revision, dev_desc->product); + } + if (dev_desc->if_type==IF_TYPE_SATA) { + printf ("Model: %s Firm: %s Ser#: %s\n", + dev_desc->vendor, + dev_desc->revision, + dev_desc->product); } else { printf ("Vendor: %s Prod.: %s Rev: %s\n", dev_desc->vendor, @@ -177,6 +188,7 @@ void dev_print (block_dev_desc_t *dev_desc) #endif #if (defined(CONFIG_CMD_IDE) || \ + defined(CONFIG_CMD_SATA) || \ defined(CONFIG_CMD_SCSI) || \ defined(CONFIG_CMD_USB) || \ defined(CONFIG_MMC) || \ @@ -271,6 +283,8 @@ static void print_part_header (const char *type, block_dev_desc_t * dev_desc) switch (dev_desc->if_type) { case IF_TYPE_IDE: puts ("IDE"); break; + case IF_TYPE_SATA: puts ("SATA"); + break; case IF_TYPE_SCSI: puts ("SCSI"); break; case IF_TYPE_ATAPI: puts ("ATAPI"); diff --git a/disk/part_dos.c b/disk/part_dos.c index 4707f803d..4d778ec5b 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -36,6 +36,7 @@ #include "part_dos.h" #if (defined(CONFIG_CMD_IDE) || \ + defined(CONFIG_CMD_SATA) || \ defined(CONFIG_CMD_SCSI) || \ defined(CONFIG_CMD_USB) || \ defined(CONFIG_MMC) || \ @@ -194,6 +195,7 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part info->size = le32_to_int (pt->size4); switch(dev_desc->if_type) { case IF_TYPE_IDE: + case IF_TYPE_SATA: case IF_TYPE_ATAPI: sprintf ((char *)info->name, "hd%c%d\n", 'a' + dev_desc->dev, part_num); break; diff --git a/disk/part_iso.c b/disk/part_iso.c index 06dd75eff..489463079 100644 --- a/disk/part_iso.c +++ b/disk/part_iso.c @@ -27,6 +27,7 @@ #if (defined(CONFIG_CMD_IDE) || \ defined(CONFIG_CMD_SCSI) || \ + defined(CONFIG_CMD_SATA) || \ defined(CONFIG_CMD_USB) || \ defined(CONFIG_MMC) || \ defined(CONFIG_SYSTEMACE) ) && defined(CONFIG_ISO_PARTITION) @@ -157,6 +158,7 @@ int get_partition_info_iso_verb(block_dev_desc_t * dev_desc, int part_num, disk_ sprintf ((char *)info->type, "U-Boot"); switch(dev_desc->if_type) { case IF_TYPE_IDE: + case IF_TYPE_SATA: case IF_TYPE_ATAPI: sprintf ((char *)info->name, "hd%c%d\n", 'a' + dev_desc->dev, part_num); break; diff --git a/disk/part_mac.c b/disk/part_mac.c index d303a73f2..1922fe53a 100644 --- a/disk/part_mac.c +++ b/disk/part_mac.c @@ -36,6 +36,7 @@ #if (defined(CONFIG_CMD_IDE) || \ defined(CONFIG_CMD_SCSI) || \ + defined(CONFIG_CMD_SATA) || \ defined(CONFIG_CMD_USB) || \ defined(CONFIG_MMC) || \ defined(CONFIG_SYSTEMACE) ) && defined(CONFIG_MAC_PARTITION) diff --git a/doc/README.sata b/doc/README.sata new file mode 100644 index 000000000..168dc7f54 --- /dev/null +++ b/doc/README.sata @@ -0,0 +1,68 @@ +1. SATA usage in U-boot + + Two ways to operate the hard disk + + * Raw read/write block from/to SATA hard disk; + * ext2load read file from ext2 filesytem in hard disk + +1.0 How to know the information of SATA hard disk? + + => sata info + +SATA device 0: Model: ST3320620AS Firm: 3.AAD Ser#: 4QF01ZTN + Type: Hard Disk + Supports 48-bit addressing + Capacity: 305245.3 MB = 298.0 GB (625142448 x 512) + +1.1 How to save the kernel, filesystem, dtb to SATA hard disk with raw? + + Notes: 0x1000 sectors = 2 MBytes + + wirte kernel + => tftp 40000 /tftpboot/uImage.837x + => sata write 40000 0 2000 + + write ramdisk + => tftp 40000 /tftpboot/ramdisk.837x + => sata write 40000 2000 8000 + + write dtb + => tftp 40000 /tftpboot/mpc837xemds.dtb + => sata write 40000 a000 1000 + +1.2 How to read the kernel, filesystem, dtb from SATA hard disk with raw? + + load kernel + => sata read 200000 0 2000 + + load ramdisk + => sata read 1000000 2000 8000 + + load dtb + => sata read 2000000 a000 1000 + + boot + => bootm 200000 1000000 2000000 + +1.3 How to load image from ext2 filesystem in U-boot? + + U-boot doesn't support ext2 write to hard disk, so + you have to write the image to hard disk under Linux env, + before you load image from ext2 filesystem. + + => ext2ls sata 0:1 / + 4096 . + 4096 .. + 16384 lost+found + 1352023 uImage.837x + 3646377 ramdisk.837x + 12288 mpc837xemds.dtb + 12 hello.txt + + => ext2load sata 0:1 200000 /uImage.837x + + => ext2load sata 0:1 1000000 /ramdisk.837x + + => ext2load sata 0:1 2000000 /mpc837xemds.dtb + + => bootm 200000 1000000 2000000 diff --git a/doc/uImage.FIT/command_syntax_extensions.txt b/doc/uImage.FIT/command_syntax_extensions.txt new file mode 100644 index 000000000..6185cd838 --- /dev/null +++ b/doc/uImage.FIT/command_syntax_extensions.txt @@ -0,0 +1,191 @@ +Command syntax extensions for the new uImage format +=================================================== + +Author: Bartlomiej Sieka + +With the introduction of the new uImage format, bootm command (and other +commands as well) have to understand new syntax of the arguments. This is +necessary in order to specify objects contained in the new uImage, on which +bootm has to operate. This note attempts to first summarize bootm usage +scenarios, and then introduces new argument syntax. + + +bootm usage scenarios +--------------------- + +Below is a summary of bootm usage scenarios, focused on booting a PowerPC +Linux kernel. The purpose of the following list is to document a complete list +of supported bootm usages. + +Note: U-Boot supports two methods of booting a PowerPC Linux kernel: old way, +i.e., without passing the Flattened Device Tree (FDT), and new way, where the +kernel is passed a pointer to the FDT. The boot method is indicated for each +scenario. + + +1. bootm boot image at the current address, equivalent to 2,3,8 + +Old uImage: +2. bootm /* single image at */ +3. bootm /* multi-image at */ +4. bootm - /* multi-image at */ +5. bootm /* single image at */ +6. bootm /* single image at */ +7. bootm - /* single image at */ + +New uImage: +8. bootm +9. bootm []: +10. bootm []# +11. bootm []: []: +12. bootm []: []: []: +13. bootm []: []: +14. bootm []: - []: +15. bootm []: - + + +Ad. 1. This is equivalent to cases 2,3,8, depending on the type of image at +the current image address. +- boot method: see cases 2,3,8 + +Ad. 2. Boot kernel image located at . +- boot method: non-FDT + +Ad. 3. First and second components of the image at are assumed to be a +kernel and a ramdisk, respectively. The kernel is booted with initrd loaded +with the ramdisk from the image. +- boot method: depends on the number of components at , and on whether + U-Boot is compiled with OF support: + + | 2 components | 3 components | + | (kernel, initrd) | (kernel, initrd, fdt) | +--------------------------------------------------------------------- +#ifdef CONFIG_OF_* | non-FDT | FDT | +#ifndef CONFIG_OF_* | non-FDT | non-FDT | + +Ad. 4. Similar to case 3, but the kernel is booted without initrd. Second +component of the multi-image is irrelevant (it can be a dummy, 1-byte file). +- boot method: see case 3 + +Ad. 5. Boot kernel image located at with initrd loaded with ramdisk +from the image at . +- boot method: non-FDT + +Ad. 6. is the address of a kernel image, is the address of a +ramdisk image, and is the address of a FDT binary blob. Kernel is +booted with initrd loaded with ramdisk from the image at . +- boot method: FDT + +Ad. 7. is the address of a kernel image and is the address of +a FDT binary blob. Kernel is booted without initrd. +- boot method: FDT + +Ad. 8. Image at is assumed to contain a default configuration, which +is booted. +- boot method: FDT or non-FDT, depending on whether the default configuration + defines FDT + +Ad. 9. Similar to case 2: boot kernel stored in from the image at +address . +- boot method: non-FDT + +Ad. 10. Boot configuration from the image at . +- boot method: FDT or non-FDT, depending on whether the configuration given + defines FDT + +Ad. 11. Equivalent to case 5: boot kernel stored in from the image +at with initrd loaded with ramdisk from the image at +. +- boot method: non-FDT + +Ad. 12. Equivalent to case 6: boot kernel stored in from the image +at with initrd loaded with ramdisk from the image at +, and pass FDT blob from the image at . +- boot method: FDT + +Ad. 13. Similar to case 12, the difference being that is the address +of FDT binary blob that is to be passed to the kernel. +- boot method: FDT + +Ad. 14. Equivalent to case 7: boot kernel stored in from the image +at , without initrd, and pass FDT blob from the image at +. +- boot method: FDT + +Ad. 15. Similar to case 14, the difference being that is the address +of the FDT binary blob that is to be passed to the kernel. +- boot method: FDT + + +New uImage argument syntax +-------------------------- + +New uImage support introduces two new forms for bootm arguments, with the +following syntax: + +- new uImage sub-image specification +: + +- new uImage configuration specification +# + + +Examples: + +- boot kernel "kernel@1" stored in a new uImage located at 200000: +bootm 200000:kernel@1 + +- boot configuration "cfg@1" from a new uImage located at 200000: +bootm 200000#cfg@1 + +- boot "kernel@1" from a new uImage at 200000 with initrd "ramdisk@2" found in + some other new uImage stored at address 800000: +bootm 200000:kernel@1 800000:ramdisk@2 + +- boot "kernel@2" from a new uImage at 200000, with initrd "ramdisk@1" and FDT + "fdt@1", both stored in some other new uImage located at 800000: +bootm 200000:kernel@1 800000:ramdisk@1 800000:fdt@1 + +- boot kernel "kernel@2" with initrd "ramdisk@2", both stored in a new uImage + at address 200000, with a raw FDT blob stored at address 600000: +bootm 200000:kernel@2 200000:ramdisk@2 600000 + +- boot kernel "kernel@2" from new uImage at 200000 with FDT "fdt@1" from the + same new uImage: +bootm 200000:kernel@2 - 200000:fdt@1 + + +Note on current image address +----------------------------- + +When bootm is called without arguments, the image at current image address is +booted. The current image address is the address set most recently by a load +command, etc, and is by default equal to CFG_LOAD_ADDR. For example, consider +the following commands: + +tftp 200000 /tftpboot/kernel +bootm +Last command is equivalent to: +bootm 200000 + +In case of the new uImage argument syntax, the address portion of any argument +can be omitted. If is omitted, then it is assumed that image at + should be used. Similarly, when is omitted, is is assumed that +image at should be used. If is omitted, it is assumed that the +current image address is to be used. For example, consider the following +commands: + +tftp 200000 /tftpboot/uImage +bootm :kernel@1 +Last command is equivalent to: +bootm 200000:kernel@1 + +tftp 200000 /tftpboot/uImage +bootm 400000:kernel@1 :ramdisk@1 +Last command is equivalent to: +bootm 400000:kernel@1 400000:ramdisk@1 + +tftp 200000 /tftpboot/uImage +bootm :kernel@1 400000:ramdisk@1 :fdt@1 +Last command is equivalent to: +bootm 200000:kernel@1 400000:ramdisk@1 400000:fdt@1 diff --git a/doc/uImage.FIT/howto.txt b/doc/uImage.FIT/howto.txt new file mode 100644 index 000000000..8065e9e1d --- /dev/null +++ b/doc/uImage.FIT/howto.txt @@ -0,0 +1,297 @@ +How to use images in the new image format +========================================= + +Author: Bartlomiej Sieka + + +Overview +-------- + +The new uImage format allows more flexibility in handling images of various +types (kernel, ramdisk, etc.), it also enhances integrity protection of images +with sha1 and md5 checksums. + +Two auxiliary tools are needed on the development host system in order to +create an uImage in the new format: mkimage and dtc, although only one +(mkimage) is invoked directly. dtc is called from within mkimage and operates +behind the scenes, but needs to be present in the $PATH nevertheless. It is +important that the dtc used has support for binary includes -- refer to +www.jdl.com for its latest version. mkimage (together with dtc) takes as input +an image source file, which describes the contents of the image and defines +its various properties used during booting. By convention, image source file +has the ".its" extension, also, the details of its format are given in +doc/source_file_format.txt. The actual data that is to be included in the +uImage (kernel, ramdisk, etc.) is specified in the image source file in the +form of paths to appropriate data files. The outcome of the image creation +process is a binary file (by convention with the ".itb" extension) that +contains all the referenced data (kernel, ramdisk, etc.) and other information +needed by U-Boot to handle the uImage properly. The uImage file is then +transferred to the target (e.g., via tftp) and booted using the bootm command. + +To summarize the prerequisites needed for new uImage creation: +- mkimage +- dtc (with support for binary includes) +- image source file (*.its) +- image data file(s) + + +Here's a graphical overview of the image creation and booting process: + +image source file mkimage + dtc transfer to target + + ---------------> image file --------------------> bootm +image data files(s) + + +Example 1 -- old-style (non-FDT) kernel booting +----------------------------------------------- + +Consider a simple scenario, where a PPC Linux kernel built from sources on the +development host is to be booted old-style (non-FDT) by U-Boot on an embedded +target. Assume that the outcome of the build is vmlinux.bin.gz, a file which +contains a gzip-compressed PPC Linux kernel (the only data file in this case). +The uImage can be produced using the image source file +doc/uImage.FIT/kernel.its (note that kernel.its assumes that vmlinux.bin.gz is +in the current working directory; if desired, an alternative path can be +specified in the kernel.its file). Here's how to create the image and inspect +its contents: + +[on the host system] +$ mkimage -f kernel.its kernel.itb +DTC: dts->dtb on file "kernel.its" +$ +$ mkimage -l kernel.itb +FIT description: Simple image with single Linux kernel +Created: Tue Mar 11 17:26:15 2008 + Image 0 (kernel@1) + Description: Vanilla Linux kernel + Type: Kernel Image + Compression: gzip compressed + Data Size: 943347 Bytes = 921.24 kB = 0.90 MB + Architecture: PowerPC + OS: Linux + Load Address: 0x00000000 + Entry Point: 0x00000000 + Hash algo: crc32 + Hash value: 2ae2bb40 + Hash algo: sha1 + Hash value: 3c200f34e2c226ddc789240cca0c59fc54a67cf4 + Default Configuration: 'config@1' + Configuration 0 (config@1) + Description: Boot Linux kernel + Kernel: kernel@1 + + +The resulting image file kernel.itb can be now transferred to the target, +inspected and booted (note that first three U-Boot commands below are shown +for completeness -- they are part of the standard booting procedure and not +specific to the new image format). + +[on the target system] +=> print nfsargs +nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath} +=> print addip +addip=setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off panic=1 +=> run nfsargs addip +=> tftp 900000 /path/to/tftp/location/kernel.itb +Using FEC ETHERNET device +TFTP from server 192.168.1.1; our IP address is 192.168.160.5 +Filename '/path/to/tftp/location/kernel.itb'. +Load address: 0x900000 +Loading: ################################################################# +done +Bytes transferred = 944464 (e6950 hex) +=> iminfo + +## Checking Image at 00900000 ... + FIT image found + FIT description: Simple image with single Linux kernel + Created: 2008-03-11 16:26:15 UTC + Image 0 (kernel@1) + Description: Vanilla Linux kernel + Type: Kernel Image + Compression: gzip compressed + Data Start: 0x009000e0 + Data Size: 943347 Bytes = 921.2 kB + Architecture: PowerPC + OS: Linux + Load Address: 0x00000000 + Entry Point: 0x00000000 + Hash algo: crc32 + Hash value: 2ae2bb40 + Hash algo: sha1 + Hash value: 3c200f34e2c226ddc789240cca0c59fc54a67cf4 + Default Configuration: 'config@1' + Configuration 0 (config@1) + Description: Boot Linux kernel + Kernel: kernel@1 + +=> bootm +## Booting kernel from FIT Image at 00900000 ... + Using 'config@1' configuration + Trying 'kernel@1' kernel subimage + Description: Vanilla Linux kernel + Type: Kernel Image + Compression: gzip compressed + Data Start: 0x009000e0 + Data Size: 943347 Bytes = 921.2 kB + Architecture: PowerPC + OS: Linux + Load Address: 0x00000000 + Entry Point: 0x00000000 + Hash algo: crc32 + Hash value: 2ae2bb40 + Hash algo: sha1 + Hash value: 3c200f34e2c226ddc789240cca0c59fc54a67cf4 + Verifying Hash Integrity ... crc32+ sha1+ OK + Uncompressing Kernel Image ... OK +Memory BAT mapping: BAT2=256Mb, BAT3=0Mb, residual: 0Mb +Linux version 2.4.25 (m8@hekate) (gcc version 4.0.0 (DENX ELDK 4.0 4.0.0)) #2 czw lip 5 17:56:18 CEST 2007 +On node 0 totalpages: 65536 +zone(0): 65536 pages. +zone(1): 0 pages. +zone(2): 0 pages. +Kernel command line: root=/dev/nfs rw nfsroot=192.168.1.1:/opt/eldk-4.1/ppc_6xx ip=192.168.160.5:192.168.1.1::255.255.0.0:lite5200b:eth0:off panic=1 +Calibrating delay loop... 307.20 BogoMIPS + + +Example 2 -- new-style (FDT) kernel booting +------------------------------------------- + +Consider another simple scenario, where a PPC Linux kernel is to be booted +new-style, i.e., with a FDT blob. In this case there are two prerequisite data +files: vmlinux.bin.gz (Linux kernel) and target.dtb (FDT blob). The uImage can +be produced using image source file doc/uImage.FIT/kernel_fdt.its like this +(note again, that both prerequisite data files are assumed to be present in +the current working directory -- image source file kernel_fdt.its can be +modified to take the files from some other location if needed): + +[on the host system] +$ mkimage -f kernel_fdt.its kernel_fdt.itb +DTC: dts->dtb on file "kernel_fdt.its" +$ +$ mkimage -l kernel_fdt.itb +FIT description: Simple image with single Linux kernel and FDT blob +Created: Tue Mar 11 16:29:22 2008 + Image 0 (kernel@1) + Description: Vanilla Linux kernel + Type: Kernel Image + Compression: gzip compressed + Data Size: 1092037 Bytes = 1066.44 kB = 1.04 MB + Architecture: PowerPC + OS: Linux + Load Address: 0x00000000 + Entry Point: 0x00000000 + Hash algo: crc32 + Hash value: 2c0cc807 + Hash algo: sha1 + Hash value: 264b59935470e42c418744f83935d44cdf59a3bb + Image 1 (fdt@1) + Description: Flattened Device Tree blob + Type: Flat Device Tree + Compression: uncompressed + Data Size: 16384 Bytes = 16.00 kB = 0.02 MB + Architecture: PowerPC + Hash algo: crc32 + Hash value: 0d655d71 + Hash algo: sha1 + Hash value: 25ab4e15cd4b8a5144610394560d9c318ce52def + Default Configuration: 'conf@1' + Configuration 0 (conf@1) + Description: Boot Linux kernel with FDT blob + Kernel: kernel@1 + FDT: fdt@1 + + +The resulting image file kernel_fdt.itb can be now transferred to the target, +inspected and booted: + +[on the target system] +=> tftp 900000 /path/to/tftp/location/kernel_fdt.itb +Using FEC ETHERNET device +TFTP from server 192.168.1.1; our IP address is 192.168.160.5 +Filename '/path/to/tftp/location/kernel_fdt.itb'. +Load address: 0x900000 +Loading: ################################################################# + ########### +done +Bytes transferred = 1109776 (10ef10 hex) +=> iminfo + +## Checking Image at 00900000 ... + FIT image found + FIT description: Simple image with single Linux kernel and FDT blob + Created: 2008-03-11 15:29:22 UTC + Image 0 (kernel@1) + Description: Vanilla Linux kernel + Type: Kernel Image + Compression: gzip compressed + Data Start: 0x009000ec + Data Size: 1092037 Bytes = 1 MB + Architecture: PowerPC + OS: Linux + Load Address: 0x00000000 + Entry Point: 0x00000000 + Hash algo: crc32 + Hash value: 2c0cc807 + Hash algo: sha1 + Hash value: 264b59935470e42c418744f83935d44cdf59a3bb + Image 1 (fdt@1) + Description: Flattened Device Tree blob + Type: Flat Device Tree + Compression: uncompressed + Data Start: 0x00a0abdc + Data Size: 16384 Bytes = 16 kB + Architecture: PowerPC + Hash algo: crc32 + Hash value: 0d655d71 + Hash algo: sha1 + Hash value: 25ab4e15cd4b8a5144610394560d9c318ce52def + Default Configuration: 'conf@1' + Configuration 0 (conf@1) + Description: Boot Linux kernel with FDT blob + Kernel: kernel@1 + FDT: fdt@1 +=> bootm +## Booting kernel from FIT Image at 00900000 ... + Using 'conf@1' configuration + Trying 'kernel@1' kernel subimage + Description: Vanilla Linux kernel + Type: Kernel Image + Compression: gzip compressed + Data Start: 0x009000ec + Data Size: 1092037 Bytes = 1 MB + Architecture: PowerPC + OS: Linux + Load Address: 0x00000000 + Entry Point: 0x00000000 + Hash algo: crc32 + Hash value: 2c0cc807 + Hash algo: sha1 + Hash value: 264b59935470e42c418744f83935d44cdf59a3bb + Verifying Hash Integrity ... crc32+ sha1+ OK + Uncompressing Kernel Image ... OK +## Flattened Device Tree from FIT Image at 00900000 + Using 'conf@1' configuration + Trying 'fdt@1' FDT blob subimage + Description: Flattened Device Tree blob + Type: Flat Device Tree + Compression: uncompressed + Data Start: 0x00a0abdc + Data Size: 16384 Bytes = 16 kB + Architecture: PowerPC + Hash algo: crc32 + Hash value: 0d655d71 + Hash algo: sha1 + Hash value: 25ab4e15cd4b8a5144610394560d9c318ce52def + Verifying Hash Integrity ... crc32+ sha1+ OK + Booting using the fdt blob at 0xa0abdc + Loading Device Tree to 007fc000, end 007fffff ... OK +[ 0.000000] Using lite5200 machine description +[ 0.000000] Linux version 2.6.24-rc6-gaebecdfc (m8@hekate) (gcc version 4.0.0 (DENX ELDK 4.1 4.0.0)) #1 Sat Jan 12 15:38:48 CET 2008 + + +Example 3 -- advanced booting +----------------------------- + +Refer to doc/uImage.FIT/multi.its for an image source file that allows more +sophisticated booting scenarios (multiple kernels, ramdisks and fdt blobs). diff --git a/doc/uImage.FIT/kernel.its b/doc/uImage.FIT/kernel.its new file mode 100644 index 000000000..d1a593911 --- /dev/null +++ b/doc/uImage.FIT/kernel.its @@ -0,0 +1,34 @@ +/* + * Simple U-boot uImage source file containing a single kernel + */ +/ { + description = "Simple image with single Linux kernel"; + #address-cells = <1>; + + images { + kernel@1 { + description = "Vanilla Linux kernel"; + data = /incbin/("./vmlinux.bin.gz"); + type = "kernel"; + arch = "ppc"; + os = "linux"; + compression = "gzip"; + load = <00000000>; + entry = <00000000>; + hash@1 { + algo = "crc32"; + }; + hash@2 { + algo = "sha1"; + }; + }; + }; + + configurations { + default = "config@1"; + config@1 { + description = "Boot Linux kernel"; + kernel = "kernel@1"; + }; + }; +}; diff --git a/doc/uImage.FIT/kernel_fdt.its b/doc/uImage.FIT/kernel_fdt.its new file mode 100644 index 000000000..fd6dee257 --- /dev/null +++ b/doc/uImage.FIT/kernel_fdt.its @@ -0,0 +1,48 @@ +/* + * Simple U-boot uImage source file containing a single kernel and FDT blob + */ +/ { + description = "Simple image with single Linux kernel and FDT blob"; + #address-cells = <1>; + + images { + kernel@1 { + description = "Vanilla Linux kernel"; + data = /incbin/("./vmlinux.bin.gz"); + type = "kernel"; + arch = "ppc"; + os = "linux"; + compression = "gzip"; + load = <00000000>; + entry = <00000000>; + hash@1 { + algo = "crc32"; + }; + hash@2 { + algo = "sha1"; + }; + }; + fdt@1 { + description = "Flattened Device Tree blob"; + data = /incbin/("./target.dtb"); + type = "flat_dt"; + arch = "ppc"; + compression = "none"; + hash@1 { + algo = "crc32"; + }; + hash@2 { + algo = "sha1"; + }; + }; + }; + + configurations { + default = "conf@1"; + conf@1 { + description = "Boot Linux kernel with FDT blob"; + kernel = "kernel@1"; + fdt = "fdt@1"; + }; + }; +}; diff --git a/doc/uImage.FIT/multi.its b/doc/uImage.FIT/multi.its new file mode 100644 index 000000000..b9929623b --- /dev/null +++ b/doc/uImage.FIT/multi.its @@ -0,0 +1,124 @@ +/* + * U-boot uImage source file with multiple kernels, ramdisks and FDT blobs + */ +/ { + description = "Various kernels, ramdisks and FDT blobs"; + #address-cells = <1>; + + images { + kernel@1 { + description = "vanilla-2.6.23"; + data = /incbin/("./vmlinux.bin.gz"); + type = "kernel"; + arch = "ppc"; + os = "linux"; + compression = "gzip"; + load = <00000000>; + entry = <00000000>; + hash@1 { + algo = "md5"; + }; + hash@2 { + algo = "sha1"; + }; + }; + + kernel@2 { + description = "2.6.23-denx"; + data = /incbin/("./2.6.23-denx.bin.gz"); + type = "kernel"; + arch = "ppc"; + os = "linux"; + compression = "gzip"; + load = <00000000>; + entry = <00000000>; + hash@1 { + algo = "sha1"; + }; + }; + + kernel@3 { + description = "2.4.25-denx"; + data = /incbin/("./2.4.25-denx.bin.gz"); + type = "kernel"; + arch = "ppc"; + os = "linux"; + compression = "gzip"; + load = <00000000>; + entry = <00000000>; + hash@1 { + algo = "md5"; + }; + }; + + ramdisk@1 { + description = "eldk-4.2-ramdisk"; + data = /incbin/("./eldk-4.2-ramdisk"); + type = "ramdisk"; + arch = "ppc"; + compression = "gzip"; + hash@1 { + algo = "sha1"; + }; + }; + + ramdisk@2 { + description = "eldk-3.1-ramdisk"; + data = /incbin/("./eldk-3.1-ramdisk"); + type = "ramdisk"; + arch = "ppc"; + compression = "gzip"; + hash@1 { + algo = "crc32"; + }; + }; + + fdt@1 { + description = "tqm5200-fdt"; + data = /incbin/("./tqm5200.dtb"); + type = "flat_dt"; + arch = "ppc"; + compression = "none"; + hash@1 { + algo = "crc32"; + }; + }; + + fdt@2 { + description = "tqm5200s-fdt"; + data = /incbin/("./tqm5200s.dtb"); + type = "flat_dt"; + arch = "ppc"; + compression = "none"; + load = <00700000>; + hash@1 { + algo = "sha1"; + }; + }; + + }; + + configurations { + default = "config@1"; + + config@1 { + description = "tqm5200 vanilla-2.6.23 configuration"; + kernel = "kernel@1"; + ramdisk = "ramdisk@1"; + fdt = "fdt@1"; + }; + + config@2 { + description = "tqm5200s denx-2.6.23 configuration"; + kernel = "kernel@2"; + ramdisk = "ramdisk@1"; + fdt = "fdt@2"; + }; + + config@3 { + description = "tqm5200s denx-2.4.25 configuration"; + kernel = "kernel@3"; + ramdisk = "ramdisk@2"; + }; + }; +}; diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt new file mode 100644 index 000000000..c1244fbad --- /dev/null +++ b/doc/uImage.FIT/source_file_format.txt @@ -0,0 +1,262 @@ +U-boot new uImage source file format (bindings definition) +========================================================== + +Author: Marian Balakowicz + +1) Introduction +--------------- + +Evolution of the 2.6 Linux kernel for embedded PowerPC systems introduced new +booting method which requires that hardware description is available to the +kernel in the form of Flattened Device Tree. + +Booting with a Flattened Device Tree is much more flexible and is intended to +replace direct passing of 'struct bd_info' which was used to boot pre-FDT +kernels. + +However, U-boot needs to support both techniques to provide backward +compatibility for platforms which are not FDT ready. Number of elements +playing role in the booting process has increased and now includes the FDT +blob. Kernel image, FDT blob and possibly ramdisk image - all must be placed +in the system memory and passed to bootm as a arguments. Some of them may be +missing: FDT is not present for legacy platforms, ramdisk is always optional. +Additionally, old uImage format has been extended to support multi sub-images +but the support is limited by simple format of the legacy uImage structure. +Single binary header 'struct image_header' is not flexible enough to cover all +possible scenarios. + +All those factors combined clearly show that there is a need for new, more +flexible, multi component uImage format. + + +2) New uImage format assumptions +-------------------------------- + +a) Implementation + +Libfdt has been selected for the new uImage format implementation as (1) it +provides needed functionality, (2) is actively maintained and developed and +(3) increases code reuse as it is already part of the U-boot source tree. + +b) Terminology + +This document defines new uImage structure by providing FDT bindings for new +uImage internals. Bindings are defined from U-boot perspective, i.e. describe +final form of the uImage at the moment when it reaches U-boot. User +perspective may be simpler, as some of the properties (like timestamps and +hashes) will need to be filled in automatically by the U-boot mkimage tool. + +To avoid confusion with the kernel FDT the following naming convention is +proposed for the new uImage format related terms: + +FIT - Flattened uImage Tree + +FIT is formally a flattened device tree (in the libfdt meaning), which +conforms to bindings defined in this document. + +.its - image tree source +.itb - image tree blob + +c) Image building procedure + +The following picture shows how the new uImage is prepared. Input consists of +image source file (.its) and a set of data files. Image is created with the +help of standard U-boot mkimage tool which in turn uses dtc (device tree +compiler) to produce image tree blob (.itb). Resulting .itb file is is the +actual binary of a new uImage. + + +tqm5200.its ++ +vmlinux.bin.gz mkimage + dtc xfer to target +eldk-4.2-ramdisk --------------> tqm5200.itb --------------> bootm +tqm5200.dtb /|\ +... | + 'new uImage' + + - create .its file, automatically filled-in properties are omitted + - call mkimage tool on a .its file + - mkimage calls dtc to create .itb image and assures that + missing properties are added + - .itb (new uImage) is uploaded onto the target and used therein + + +d) Unique identifiers + +To identify FIT sub-nodes representing images, hashes, configurations (which +are defined in the following sections), the "unit name" of the given sub-node +is used as it's identifier as it assures uniqueness without additional +checking required. + + +3) Root node properties +----------------------- + +Root node of the uImage Tree should have the following layout: + +/ o image-tree + |- description = "image description" + |- timestamp = <12399321> + |- #address-cells = <1> + | + o images + | | + | o img@1 {...} + | o img@2 {...} + | ... + | + o configurations + |- default = "cfg@1" + | + o cfg@1 {...} + o cfg@2 {...} + ... + + + Optional property: + - description : Textual description of the uImage + + Mandatory property: + - timestamp : Last image modification time being counted in seconds since + 1970-01-01 00:00:00 - to be automatically calculated by mkimage tool. + + Conditionally mandatory property: + - #address-cells : Number of 32bit cells required to represent entry and + load addresses supplied within sub-image nodes. May be omitted when no + entry or load addresses are used. + + Mandatory node: + - images : This node contains a set of sub-nodes, each of them representing + single component sub-image (like kernel, ramdisk, etc.). At least one + sub-image is required. + + Optional node: + - configurations : Contains a set of available configuration nodes and + defines a default configuration. + + +4) '/images' node +----------------- + +This node is a container node for component sub-image nodes. Each sub-node of +the '/images' node should have the following layout: + + o image@1 + |- description = "component sub-image description" + |- data = /incbin/("path/to/data/file.bin") + |- type = "sub-image type name" + |- arch = "ARCH name" + |- os = "OS name" + |- compression = "compression name" + |- load = <00000000> + |- entry = <00000000> + | + o hash@1 {...} + o hash@2 {...} + ... + + Mandatory properties: + - description : Textual description of the component sub-image + - type : Name of component sub-image type, supported types are: + "standalone", "kernel", "ramdisk", "firmware", "script", "filesystem", + "fdt". + - data : Path to the external file which contains this node's binary data. + - compression : Compression used by included data. Supported compressions + are "gzip" and "bzip2". If no compression is used compression property + should be set to "none". + + Conditionally mandatory property: + - os : OS name, mandatory for type="kernel", valid OS names are: "openbsd", + "netbsd", "freebsd", "4_4bsd", "linux", "svr4", "esix", "solaris", "irix", + "sco", "dell", "ncr", "lynxos", "vxworks", "psos", "qnx", "u_boot", + "rtems", "artos", "unity". + - arch : Architecture name, mandatory for types: "standalone", "kernel", + "firmware", "ramdisk" and "fdt". Valid architecture names are: "alpha", + "arm", "i386", "ia64", "mips", "mips64", "ppc", "s390", "sh", "sparc", + "sparc64", "m68k", "nios", "microblaze", "nios2", "blackfin", "avr32", + "st200". + - entry : entry point address, address size is determined by + '#address-cells' property of the root node. Mandatory for for types: + "standalone" and "kernel". + - load : load address, address size is determined by '#address-cells' + property of the root node. Mandatory for types: "standalone" and "kernel". + + Optional nodes: + - hash@1 : Each hash sub-node represents separate hash or checksum + calculated for node's data according to specified algorithm. + + +5) Hash nodes +------------- + +o hash@1 + |- algo = "hash or checksum algorithm name" + |- value = [hash or checksum value] + + Mandatory properties: + - algo : Algorithm name, supported are "crc32", "md5" and "sha1". + - value : Actual checksum or hash value, correspondingly 4, 16 or 20 bytes + long. + + +6) '/configurations' node +------------------------- + +The 'configurations' node is optional. If present, it allows to create a +convenient, labeled boot configurations, which combine together kernel images +with their ramdisks and fdt blobs. + +The 'configurations' node has has the following structure: + +o configurations + |- default = "default configuration sub-node unit name" + | + o config@1 {...} + o config@2 {...} + ... + + + Optional property: + - default : Selects one of the configuration sub-nodes as a default + configuration. + + Mandatory nodes: + - configuration-sub-node-unit-name : At least one of the configuration + sub-nodes is required. + + +7) Configuration nodes +---------------------- + +Each configuration has the following structure: + +o config@1 + |- description = "configuration description" + |- kernel = "kernel sub-node unit name" + |- ramdisk = "ramdisk sub-node unit name" + |- fdt = "fdt sub-node unit-name" + + + Mandatory properties: + - description : Textual configuration description. + - kernel : Unit name of the corresponding kernel image (image sub-node of a + "kernel" type). + + Optional properties: + - ramdisk : Unit name of the corresponding ramdisk image (component image + node of a "ramdisk" type). + - fdt : Unit name of the corresponding fdt blob (component image node of a + "fdt type"). + +The FDT blob is required to properly boot FDT based kernel, so the minimal +configuration for 2.6 FDT kernel is (kernel, fdt) pair. + +Older, 2.4 kernel and 2.6 non-FDT kernel do not use FDT blob, in such cases +'struct bd_info' must be passed instead of FDT blob, thus fdt property *must +not* be specified in a configuration node. + + +8) Examples +----------- + +Please see doc/uImage.FIT/*.its for actual image source files. diff --git a/drivers/block/Makefile b/drivers/block/Makefile index e069969e6..dca354791 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -27,6 +27,8 @@ LIB := $(obj)libblock.a COBJS-y += ahci.o COBJS-y += ata_piix.o +COBJS-$(CONFIG_FSL_SATA) += fsl_sata.o +COBJS-$(CONFIG_LIBATA) += libata.o COBJS-y += sil680.o COBJS-y += sym53c8xx.o COBJS-y += systemace.o diff --git a/drivers/block/ata_piix.c b/drivers/block/ata_piix.c index 42456d7be..441a4dcd8 100644 --- a/drivers/block/ata_piix.c +++ b/drivers/block/ata_piix.c @@ -26,20 +26,25 @@ */ #include +#include #include #include #include #include +#include #include #include #ifdef CFG_ATA_PIIX /*ata_piix driver */ +extern block_dev_desc_t sata_dev_desc[CFG_SATA_MAX_DEVICE]; +extern int curr_device; + #define DEBUG_SATA 0 /*For debug prints set DEBUG_SATA to 1 */ +#define SATA_DECL #define DRV_DECL /*For file specific declarations */ -#include -#undef DRV_DECL +#include "ata_piix.h" /*Macros realted to PCI*/ #define PCI_SATA_BUS 0x00 @@ -142,19 +147,15 @@ sata_bus_probe (int port_no) } int -init_sata (void) +init_sata (int dev) { + static int done = 0; u8 i, rv = 0; - for (i = 0; i < CFG_SATA_MAXDEVICES; i++) { - sata_dev_desc[i].type = DEV_TYPE_UNKNOWN; - sata_dev_desc[i].if_type = IF_TYPE_IDE; - sata_dev_desc[i].dev = i; - sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN; - sata_dev_desc[i].blksz = 0; - sata_dev_desc[i].lba = 0; - sata_dev_desc[i].block_read = sata_read; - } + if (!done) + done = 1; + else + return 0; rv = pci_sata_init (); if (rv == 1) { @@ -205,12 +206,555 @@ init_sata (void) dev_print (&sata_dev_desc[devno]); /* initialize partition type */ init_part (&sata_dev_desc[devno]); - if (curr_dev < 0) - curr_dev = + if (curr_device < 0) + curr_device = i * CFG_SATA_DEVS_PER_BUS + j; } } } return 0; } + +static u8 __inline__ +sata_inb (unsigned long ioaddr) +{ + return inb (ioaddr); +} + +static void __inline__ +sata_outb (unsigned char val, unsigned long ioaddr) +{ + outb (val, ioaddr); +} + +static void +output_data (struct sata_ioports *ioaddr, ulong * sect_buf, int words) +{ + outsw (ioaddr->data_addr, sect_buf, words << 1); +} + +static int +input_data (struct sata_ioports *ioaddr, ulong * sect_buf, int words) +{ + insw (ioaddr->data_addr, sect_buf, words << 1); + return 0; +} + +static void +sata_cpy (unsigned char *dst, unsigned char *src, unsigned int len) +{ + unsigned char *end, *last; + + last = dst; + end = src + len - 1; + + /* reserve space for '\0' */ + if (len < 2) + goto OUT; + + /* skip leading white space */ + while ((*src) && (src < end) && (*src == ' ')) + ++src; + + /* copy string, omitting trailing white space */ + while ((*src) && (src < end)) { + *dst++ = *src; + if (*src++ != ' ') + last = dst; + } + OUT: + *last = '\0'; +} + +int +sata_bus_softreset (int num) +{ + u8 dev = 0, status = 0, i; + + port[num].dev_mask = 0; + + for (i = 0; i < CFG_SATA_DEVS_PER_BUS; i++) { + if (!(sata_devchk (&port[num].ioaddr, i))) { + PRINTF ("dev_chk failed for dev#%d\n", i); + } else { + port[num].dev_mask |= (1 << i); + PRINTF ("dev_chk passed for dev#%d\n", i); + } + } + + if (!(port[num].dev_mask)) { + printf ("no devices on port%d\n", num); + return 1; + } + + dev_select (&port[num].ioaddr, dev); + + port[num].ctl_reg = 0x08; /*Default value of control reg */ + sata_outb (port[num].ctl_reg, port[num].ioaddr.ctl_addr); + udelay (10); + sata_outb (port[num].ctl_reg | ATA_SRST, port[num].ioaddr.ctl_addr); + udelay (10); + sata_outb (port[num].ctl_reg, port[num].ioaddr.ctl_addr); + + /* spec mandates ">= 2ms" before checking status. + * We wait 150ms, because that was the magic delay used for + * ATAPI devices in Hale Landis's ATADRVR, for the period of time + * between when the ATA command register is written, and then + * status is checked. Because waiting for "a while" before + * checking status is fine, post SRST, we perform this magic + * delay here as well. + */ + msleep (150); + status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 300); + while ((status & ATA_BUSY)) { + msleep (100); + status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 3); + } + + if (status & ATA_BUSY) + printf ("ata%u is slow to respond,plz be patient\n", port); + + while ((status & ATA_BUSY)) { + msleep (100); + status = sata_chk_status (&port[num].ioaddr); + } + + if (status & ATA_BUSY) { + printf ("ata%u failed to respond : ", port); + printf ("bus reset failed\n"); + return 1; + } + return 0; +} + +void +sata_identify (int num, int dev) +{ + u8 cmd = 0, status = 0, devno = num * CFG_SATA_DEVS_PER_BUS + dev; + u16 iobuf[ATA_SECT_SIZE]; + u64 n_sectors = 0; + u8 mask = 0; + + memset (iobuf, 0, sizeof (iobuf)); + hd_driveid_t *iop = (hd_driveid_t *) iobuf; + + if (dev == 0) + mask = 0x01; + else + mask = 0x02; + + if (!(port[num].dev_mask & mask)) { + printf ("dev%d is not present on port#%d\n", dev, num); + return; + } + + printf ("port=%d dev=%d\n", num, dev); + + dev_select (&port[num].ioaddr, dev); + + status = 0; + cmd = ATA_CMD_IDENT; /*Device Identify Command */ + sata_outb (cmd, port[num].ioaddr.command_addr); + sata_inb (port[num].ioaddr.altstatus_addr); + udelay (10); + + status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 1000); + if (status & ATA_ERR) { + printf ("\ndevice not responding\n"); + port[num].dev_mask &= ~mask; + return; + } + + input_data (&port[num].ioaddr, (ulong *) iobuf, ATA_SECTORWORDS); + + PRINTF ("\nata%u: dev %u cfg 49:%04x 82:%04x 83:%04x 84:%04x85:%04x" + "86:%04x" "87:%04x 88:%04x\n", num, dev, iobuf[49], + iobuf[82], iobuf[83], iobuf[84], iobuf[85], iobuf[86], + iobuf[87], iobuf[88]); + + /* we require LBA and DMA support (bits 8 & 9 of word 49) */ + if (!ata_id_has_dma (iobuf) || !ata_id_has_lba (iobuf)) { + PRINTF ("ata%u: no dma/lba\n", num); + } + ata_dump_id (iobuf); + + if (ata_id_has_lba48 (iobuf)) { + n_sectors = ata_id_u64 (iobuf, 100); + } else { + n_sectors = ata_id_u32 (iobuf, 60); + } + PRINTF ("no. of sectors %u\n", ata_id_u64 (iobuf, 100)); + PRINTF ("no. of sectors %u\n", ata_id_u32 (iobuf, 60)); + + if (n_sectors == 0) { + port[num].dev_mask &= ~mask; + return; + } + + sata_cpy (sata_dev_desc[devno].revision, iop->fw_rev, + sizeof (sata_dev_desc[devno].revision)); + sata_cpy (sata_dev_desc[devno].vendor, iop->model, + sizeof (sata_dev_desc[devno].vendor)); + sata_cpy (sata_dev_desc[devno].product, iop->serial_no, + sizeof (sata_dev_desc[devno].product)); + strswab (sata_dev_desc[devno].revision); + strswab (sata_dev_desc[devno].vendor); + + if ((iop->config & 0x0080) == 0x0080) { + sata_dev_desc[devno].removable = 1; + } else { + sata_dev_desc[devno].removable = 0; + } + + sata_dev_desc[devno].lba = iop->lba_capacity; + PRINTF ("lba=0x%x", sata_dev_desc[devno].lba); + +#ifdef CONFIG_LBA48 + if (iop->command_set_2 & 0x0400) { + sata_dev_desc[devno].lba48 = 1; + lba = (unsigned long long) iop->lba48_capacity[0] | + ((unsigned long long) iop->lba48_capacity[1] << 16) | + ((unsigned long long) iop->lba48_capacity[2] << 32) | + ((unsigned long long) iop->lba48_capacity[3] << 48); + } else { + sata_dev_desc[devno].lba48 = 0; + } +#endif + + /* assuming HD */ + sata_dev_desc[devno].type = DEV_TYPE_HARDDISK; + sata_dev_desc[devno].blksz = ATA_BLOCKSIZE; + sata_dev_desc[devno].lun = 0; /* just to fill something in... */ +} + +void +set_Feature_cmd (int num, int dev) +{ + u8 mask = 0x00, status = 0; + + if (dev == 0) + mask = 0x01; + else + mask = 0x02; + + if (!(port[num].dev_mask & mask)) { + PRINTF ("dev%d is not present on port#%d\n", dev, num); + return; + } + + dev_select (&port[num].ioaddr, dev); + + sata_outb (SETFEATURES_XFER, port[num].ioaddr.feature_addr); + sata_outb (XFER_PIO_4, port[num].ioaddr.nsect_addr); + sata_outb (0, port[num].ioaddr.lbal_addr); + sata_outb (0, port[num].ioaddr.lbam_addr); + sata_outb (0, port[num].ioaddr.lbah_addr); + + sata_outb (ATA_DEVICE_OBS, port[num].ioaddr.device_addr); + sata_outb (ATA_CMD_SETF, port[num].ioaddr.command_addr); + + udelay (50); + msleep (150); + + status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 5000); + if ((status & (ATA_STAT_BUSY | ATA_STAT_ERR))) { + printf ("Error : status 0x%02x\n", status); + port[num].dev_mask &= ~mask; + } +} + +void +sata_port (struct sata_ioports *ioport) +{ + ioport->data_addr = ioport->cmd_addr + ATA_REG_DATA; + ioport->error_addr = ioport->cmd_addr + ATA_REG_ERR; + ioport->feature_addr = ioport->cmd_addr + ATA_REG_FEATURE; + ioport->nsect_addr = ioport->cmd_addr + ATA_REG_NSECT; + ioport->lbal_addr = ioport->cmd_addr + ATA_REG_LBAL; + ioport->lbam_addr = ioport->cmd_addr + ATA_REG_LBAM; + ioport->lbah_addr = ioport->cmd_addr + ATA_REG_LBAH; + ioport->device_addr = ioport->cmd_addr + ATA_REG_DEVICE; + ioport->status_addr = ioport->cmd_addr + ATA_REG_STATUS; + ioport->command_addr = ioport->cmd_addr + ATA_REG_CMD; +} + +int +sata_devchk (struct sata_ioports *ioaddr, int dev) +{ + u8 nsect, lbal; + + dev_select (ioaddr, dev); + + sata_outb (0x55, ioaddr->nsect_addr); + sata_outb (0xaa, ioaddr->lbal_addr); + + sata_outb (0xaa, ioaddr->nsect_addr); + sata_outb (0x55, ioaddr->lbal_addr); + + sata_outb (0x55, ioaddr->nsect_addr); + sata_outb (0xaa, ioaddr->lbal_addr); + + nsect = sata_inb (ioaddr->nsect_addr); + lbal = sata_inb (ioaddr->lbal_addr); + + if ((nsect == 0x55) && (lbal == 0xaa)) + return 1; /* we found a device */ + else + return 0; /* nothing found */ +} + +void +dev_select (struct sata_ioports *ioaddr, int dev) +{ + u8 tmp = 0; + + if (dev == 0) + tmp = ATA_DEVICE_OBS; + else + tmp = ATA_DEVICE_OBS | ATA_DEV1; + + sata_outb (tmp, ioaddr->device_addr); + sata_inb (ioaddr->altstatus_addr); + udelay (5); +} + +u8 +sata_busy_wait (struct sata_ioports *ioaddr, int bits, unsigned int max) +{ + u8 status; + + do { + udelay (1000); + status = sata_chk_status (ioaddr); + max--; + } while ((status & bits) && (max > 0)); + + return status; +} + +u8 +sata_chk_status (struct sata_ioports * ioaddr) +{ + return sata_inb (ioaddr->status_addr); +} + +void +msleep (int count) +{ + int i; + + for (i = 0; i < count; i++) + udelay (1000); +} + +ulong +sata_read (int device, ulong blknr,lbaint_t blkcnt, void * buff) +{ + ulong n = 0, *buffer = (ulong *)buff; + u8 dev = 0, num = 0, mask = 0, status = 0; + +#ifdef CONFIG_LBA48 + unsigned char lba48 = 0; + + if (blknr & 0x0000fffff0000000) { + if (!sata_dev_desc[devno].lba48) { + printf ("Drive doesn't support 48-bit addressing\n"); + return 0; + } + /* more than 28 bits used, use 48bit mode */ + lba48 = 1; + } +#endif + /*Port Number */ + num = device / CFG_SATA_DEVS_PER_BUS; + /*dev on the port */ + if (device >= CFG_SATA_DEVS_PER_BUS) + dev = device - CFG_SATA_DEVS_PER_BUS; + else + dev = device; + + if (dev == 0) + mask = 0x01; + else + mask = 0x02; + + if (!(port[num].dev_mask & mask)) { + printf ("dev%d is not present on port#%d\n", dev, num); + return 0; + } + + /* Select device */ + dev_select (&port[num].ioaddr, dev); + + status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500); + if (status & ATA_BUSY) { + printf ("ata%u failed to respond\n", port[num].port_no); + return n; + } + while (blkcnt-- > 0) { + status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500); + if (status & ATA_BUSY) { + printf ("ata%u failed to respond\n", 0); + return n; + } +#ifdef CONFIG_LBA48 + if (lba48) { + /* write high bits */ + sata_outb (0, port[num].ioaddr.nsect_addr); + sata_outb ((blknr >> 24) & 0xFF, + port[num].ioaddr.lbal_addr); + sata_outb ((blknr >> 32) & 0xFF, + port[num].ioaddr.lbam_addr); + sata_outb ((blknr >> 40) & 0xFF, + port[num].ioaddr.lbah_addr); + } +#endif + sata_outb (1, port[num].ioaddr.nsect_addr); + sata_outb (((blknr) >> 0) & 0xFF, + port[num].ioaddr.lbal_addr); + sata_outb ((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr); + sata_outb ((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr); + +#ifdef CONFIG_LBA48 + if (lba48) { + sata_outb (ATA_LBA, port[num].ioaddr.device_addr); + sata_outb (ATA_CMD_READ_EXT, + port[num].ioaddr.command_addr); + } else +#endif + { + sata_outb (ATA_LBA | ((blknr >> 24) & 0xF), + port[num].ioaddr.device_addr); + sata_outb (ATA_CMD_READ, + port[num].ioaddr.command_addr); + } + + msleep (50); + /*may take up to 4 sec */ + status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 4000); + + if ((status & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) + != ATA_STAT_DRQ) { + u8 err = 0; + + printf ("Error no DRQ dev %d blk %ld: sts 0x%02x\n", + device, (ulong) blknr, status); + err = sata_inb (port[num].ioaddr.error_addr); + printf ("Error reg = 0x%x\n", err); + return (n); + } + input_data (&port[num].ioaddr, buffer, ATA_SECTORWORDS); + sata_inb (port[num].ioaddr.altstatus_addr); + udelay (50); + + ++n; + ++blknr; + buffer += ATA_SECTORWORDS; + } + return n; +} + +ulong +sata_write (int device, ulong blknr,lbaint_t blkcnt, void * buff) +{ + ulong n = 0, *buffer = (ulong *)buff; + unsigned char status = 0, num = 0, dev = 0, mask = 0; + +#ifdef CONFIG_LBA48 + unsigned char lba48 = 0; + + if (blknr & 0x0000fffff0000000) { + if (!sata_dev_desc[devno].lba48) { + printf ("Drive doesn't support 48-bit addressing\n"); + return 0; + } + /* more than 28 bits used, use 48bit mode */ + lba48 = 1; + } +#endif + /*Port Number */ + num = device / CFG_SATA_DEVS_PER_BUS; + /*dev on the Port */ + if (device >= CFG_SATA_DEVS_PER_BUS) + dev = device - CFG_SATA_DEVS_PER_BUS; + else + dev = device; + + if (dev == 0) + mask = 0x01; + else + mask = 0x02; + + /* Select device */ + dev_select (&port[num].ioaddr, dev); + + status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500); + if (status & ATA_BUSY) { + printf ("ata%u failed to respond\n", port[num].port_no); + return n; + } + + while (blkcnt-- > 0) { + status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500); + if (status & ATA_BUSY) { + printf ("ata%u failed to respond\n", + port[num].port_no); + return n; + } +#ifdef CONFIG_LBA48 + if (lba48) { + /* write high bits */ + sata_outb (0, port[num].ioaddr.nsect_addr); + sata_outb ((blknr >> 24) & 0xFF, + port[num].ioaddr.lbal_addr); + sata_outb ((blknr >> 32) & 0xFF, + port[num].ioaddr.lbam_addr); + sata_outb ((blknr >> 40) & 0xFF, + port[num].ioaddr.lbah_addr); + } +#endif + sata_outb (1, port[num].ioaddr.nsect_addr); + sata_outb ((blknr >> 0) & 0xFF, port[num].ioaddr.lbal_addr); + sata_outb ((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr); + sata_outb ((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr); +#ifdef CONFIG_LBA48 + if (lba48) { + sata_outb (ATA_LBA, port[num].ioaddr.device_addr); + sata_outb (ATA_CMD_WRITE_EXT, + port[num].ioaddr.command_addr); + } else +#endif + { + sata_outb (ATA_LBA | ((blknr >> 24) & 0xF), + port[num].ioaddr.device_addr); + sata_outb (ATA_CMD_WRITE, + port[num].ioaddr.command_addr); + } + + msleep (50); + /*may take up to 4 sec */ + status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 4000); + if ((status & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) + != ATA_STAT_DRQ) { + printf ("Error no DRQ dev %d blk %ld: sts 0x%02x\n", + device, (ulong) blknr, status); + return (n); + } + + output_data (&port[num].ioaddr, buffer, ATA_SECTORWORDS); + sata_inb (port[num].ioaddr.altstatus_addr); + udelay (50); + + ++n; + ++blknr; + buffer += ATA_SECTORWORDS; + } + return n; +} + +int scan_sata(int dev) +{ + return 0; +} + #endif diff --git a/drivers/block/ata_piix.h b/drivers/block/ata_piix.h new file mode 100644 index 000000000..ed2e4d57d --- /dev/null +++ b/drivers/block/ata_piix.h @@ -0,0 +1,90 @@ + +#if (DEBUG_SATA) +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +struct sata_ioports { + unsigned long cmd_addr; + unsigned long data_addr; + unsigned long error_addr; + unsigned long feature_addr; + unsigned long nsect_addr; + unsigned long lbal_addr; + unsigned long lbam_addr; + unsigned long lbah_addr; + unsigned long device_addr; + unsigned long status_addr; + unsigned long command_addr; + unsigned long altstatus_addr; + unsigned long ctl_addr; + unsigned long bmdma_addr; + unsigned long scr_addr; +}; + +struct sata_port { + unsigned char port_no; /* primary=0, secondary=1 */ + struct sata_ioports ioaddr; /* ATA cmd/ctl/dma reg blks */ + unsigned char ctl_reg; + unsigned char last_ctl; + unsigned char port_state; /* 1-port is available and */ + /* 0-port is not available */ + unsigned char dev_mask; +}; + +/***********SATA LIBRARY SPECIFIC DEFINITIONS AND DECLARATIONS**************/ +#ifdef SATA_DECL /*SATA library specific declarations */ +#define ata_id_has_lba48(id) ((id)[83] & (1 << 10)) +#define ata_id_has_lba(id) ((id)[49] & (1 << 9)) +#define ata_id_has_dma(id) ((id)[49] & (1 << 8)) +#define ata_id_u32(id,n) \ + (((u32) (id)[(n) + 1] << 16) | ((u32) (id)[(n)])) +#define ata_id_u64(id,n) \ + (((u64) (id)[(n) + 3] << 48) | \ + ((u64) (id)[(n) + 2] << 32) | \ + ((u64) (id)[(n) + 1] << 16) | \ + ((u64) (id)[(n) + 0]) ) +#endif + +#ifdef SATA_DECL /*SATA library specific declarations */ +static inline void +ata_dump_id (u16 * id) +{ + PRINTF ("49==0x%04x " + "53==0x%04x " + "63==0x%04x " + "64==0x%04x " + "75==0x%04x \n", id[49], id[53], id[63], id[64], id[75]); + PRINTF ("80==0x%04x " + "81==0x%04x " + "82==0x%04x " + "83==0x%04x " + "84==0x%04x \n", id[80], id[81], id[82], id[83], id[84]); + PRINTF ("88==0x%04x " "93==0x%04x\n", id[88], id[93]); +} +#endif + +#ifdef SATA_DECL /*SATA library specific declarations */ +int sata_bus_softreset (int num); +void sata_identify (int num, int dev); +void sata_port (struct sata_ioports *ioport); +void set_Feature_cmd (int num, int dev); +int sata_devchk (struct sata_ioports *ioaddr, int dev); +void dev_select (struct sata_ioports *ioaddr, int dev); +u8 sata_busy_wait (struct sata_ioports *ioaddr, int bits, unsigned int max); +u8 sata_chk_status (struct sata_ioports *ioaddr); +ulong sata_read (int device, ulong blknr,lbaint_t blkcnt, void * buffer); +ulong sata_write (int device,ulong blknr, lbaint_t blkcnt, void * buffer); +void msleep (int count); +#endif + +/************DRIVER SPECIFIC DEFINITIONS AND DECLARATIONS**************/ + +#ifdef DRV_DECL /*Driver specific declaration */ +int init_sata (int dev); +#endif + +#ifdef DRV_DECL /*Defines Driver Specific variables */ +struct sata_port port[CFG_SATA_MAXBUS]; +#endif diff --git a/drivers/block/fsl_sata.c b/drivers/block/fsl_sata.c new file mode 100644 index 000000000..7436c4d08 --- /dev/null +++ b/drivers/block/fsl_sata.c @@ -0,0 +1,916 @@ +/* + * Copyright (C) 2008 Freescale Semiconductor, Inc. + * Dave Liu + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include "fsl_sata.h" + +extern block_dev_desc_t sata_dev_desc[CFG_SATA_MAX_DEVICE]; + +#ifndef CFG_SATA1_FLAGS + #define CFG_SATA1_FLAGS FLAGS_DMA +#endif +#ifndef CFG_SATA2_FLAGS + #define CFG_SATA2_FLAGS FLAGS_DMA +#endif + +static struct fsl_sata_info fsl_sata_info[] = { +#ifdef CONFIG_SATA1 + {CFG_SATA1, CFG_SATA1_FLAGS}, +#else + {0, 0}, +#endif +#ifdef CONFIG_SATA2 + {CFG_SATA2, CFG_SATA2_FLAGS}, +#else + {0, 0}, +#endif +}; + +static inline void mdelay(unsigned long msec) +{ + unsigned long i; + for (i = 0; i < msec; i++) + udelay(1000); +} + +static inline void sdelay(unsigned long sec) +{ + unsigned long i; + for (i = 0; i < sec; i++) + mdelay(1000); +} + +void dprint_buffer(unsigned char *buf, int len) +{ + int i, j; + + i = 0; + j = 0; + printf("\n\r"); + + for (i = 0; i < len; i++) { + printf("%02x ", *buf++); + j++; + if (j == 16) { + printf("\n\r"); + j = 0; + } + } + printf("\n\r"); +} + +static void fsl_sata_dump_sfis(struct sfis *s) +{ + printf("Status FIS dump:\n\r"); + printf("fis_type: %02x\n\r", s->fis_type); + printf("pm_port_i: %02x\n\r", s->pm_port_i); + printf("status: %02x\n\r", s->status); + printf("error: %02x\n\r", s->error); + printf("lba_low: %02x\n\r", s->lba_low); + printf("lba_mid: %02x\n\r", s->lba_mid); + printf("lba_high: %02x\n\r", s->lba_high); + printf("device: %02x\n\r", s->device); + printf("lba_low_exp: %02x\n\r", s->lba_low_exp); + printf("lba_mid_exp: %02x\n\r", s->lba_mid_exp); + printf("lba_high_exp: %02x\n\r", s->lba_high_exp); + printf("res1: %02x\n\r", s->res1); + printf("sector_count: %02x\n\r", s->sector_count); + printf("sector_count_exp: %02x\n\r", s->sector_count_exp); +} + +static int ata_wait_register(volatile unsigned *addr, u32 mask, + u32 val, u32 timeout_msec) +{ + int i; + u32 temp; + + for (i = 0; (((temp = in_le32(addr)) & mask) != val) + && i < timeout_msec; i++) + mdelay(1); + return (i < timeout_msec) ? 0 : -1; +} + +int init_sata(int dev) +{ + u32 length, align; + cmd_hdr_tbl_t *cmd_hdr; + u32 cda; + u32 val32; + fsl_sata_reg_t *reg; + u32 sig; + int i; + fsl_sata_t *sata; + + if (dev < 0 || dev > (CFG_SATA_MAX_DEVICE - 1)) { + printf("the sata index %d is out of ranges\n\r", dev); + return -1; + } + + /* Allocate SATA device driver struct */ + sata = (fsl_sata_t *)malloc(sizeof(fsl_sata_t)); + if (!sata) { + printf("alloc the sata device struct failed\n\r"); + return -1; + } + /* Zero all of the device driver struct */ + memset((void *)sata, 0, sizeof(fsl_sata_t)); + + /* Save the private struct to block device struct */ + sata_dev_desc[dev].priv = (void *)sata; + + sprintf(sata->name, "SATA%d", dev); + + /* Set the controller register base address to device struct */ + reg = (fsl_sata_reg_t *)(fsl_sata_info[dev].sata_reg_base); + sata->reg_base = reg; + + /* Allocate the command header table, 4 bytes aligned */ + length = sizeof(struct cmd_hdr_tbl); + align = SATA_HC_CMD_HDR_TBL_ALIGN; + sata->cmd_hdr_tbl_offset = (void *)malloc(length + align); + if (!sata) { + printf("alloc the command header failed\n\r"); + return -1; + } + + cmd_hdr = (cmd_hdr_tbl_t *)(((u32)sata->cmd_hdr_tbl_offset + align) + & ~(align - 1)); + sata->cmd_hdr = cmd_hdr; + + /* Zero all of the command header table */ + memset((void *)sata->cmd_hdr_tbl_offset, 0, length + align); + + /* Allocate command descriptor for all command */ + length = sizeof(struct cmd_desc) * SATA_HC_MAX_CMD; + align = SATA_HC_CMD_DESC_ALIGN; + sata->cmd_desc_offset = (void *)malloc(length + align); + if (!sata->cmd_desc_offset) { + printf("alloc the command descriptor failed\n\r"); + return -1; + } + sata->cmd_desc = (cmd_desc_t *)(((u32)sata->cmd_desc_offset + align) + & ~(align - 1)); + /* Zero all of command descriptor */ + memset((void *)sata->cmd_desc_offset, 0, length + align); + + /* Link the command descriptor to command header */ + for (i = 0; i < SATA_HC_MAX_CMD; i++) { + cda = ((u32)sata->cmd_desc + SATA_HC_CMD_DESC_SIZE * i) + & ~(CMD_HDR_CDA_ALIGN - 1); + cmd_hdr->cmd_slot[i].cda = cpu_to_le32(cda); + } + + /* To have safe state, force the controller offline */ + val32 = in_le32(®->hcontrol); + val32 &= ~HCONTROL_ONOFF; + val32 |= HCONTROL_FORCE_OFFLINE; + out_le32(®->hcontrol, val32); + + /* Wait the controller offline */ + ata_wait_register(®->hstatus, HSTATUS_ONOFF, 0, 1000); + + /* Set the command header base address to CHBA register to tell DMA */ + out_le32(®->chba, (u32)cmd_hdr & ~0x3); + + /* Snoop for the command header */ + val32 = in_le32(®->hcontrol); + val32 |= HCONTROL_HDR_SNOOP; + out_le32(®->hcontrol, val32); + + /* Disable all of interrupts */ + val32 = in_le32(®->hcontrol); + val32 &= ~HCONTROL_INT_EN_ALL; + out_le32(®->hcontrol, val32); + + /* Clear all of interrupts */ + val32 = in_le32(®->hstatus); + out_le32(®->hstatus, val32); + + /* Set the ICC, no interrupt coalescing */ + out_le32(®->icc, 0x01000000); + + /* No PM attatched, the SATA device direct connect */ + out_le32(®->cqpmp, 0); + + /* Clear SError register */ + val32 = in_le32(®->serror); + out_le32(®->serror, val32); + + /* Clear CER register */ + val32 = in_le32(®->cer); + out_le32(®->cer, val32); + + /* Clear DER register */ + val32 = in_le32(®->der); + out_le32(®->der, val32); + + /* No device detection or initialization action requested */ + out_le32(®->scontrol, 0x00000300); + + /* Configure the transport layer, default value */ + out_le32(®->transcfg, 0x08000016); + + /* Configure the link layer, default value */ + out_le32(®->linkcfg, 0x0000ff34); + + /* Bring the controller online */ + val32 = in_le32(®->hcontrol); + val32 |= HCONTROL_ONOFF; + out_le32(®->hcontrol, val32); + + mdelay(100); + + /* print sata device name */ + if (!dev) + printf("%s ", sata->name); + else + printf(" %s ", sata->name); + + /* Check PHYRDY */ + val32 = in_le32(®->hstatus); + if (val32 & HSTATUS_PHY_RDY) { + sata->link = 1; + } else { + sata->link = 0; + printf("(No RDY)\n\r"); + return -1; + } + + if (val32 & HSTATUS_SIGNATURE) { + sig = in_le32(®->sig); + debug("Signature updated, the sig =%08x\n\r", sig); + sata->ata_device_type = ata_dev_classify(sig); + } + + /* Check the speed */ + val32 = in_le32(®->sstatus); + if ((val32 & SSTATUS_SPD_MASK) == SSTATUS_SPD_GEN1) + printf("(1.5 Gbps)\n\r"); + else if ((val32 & SSTATUS_SPD_MASK) == SSTATUS_SPD_GEN2) + printf("(3 Gbps)\n\r"); + + return 0; +} + +/* Hardware reset, like Power-on and COMRESET */ +void fsl_sata_hardware_reset(u32 reg_base) +{ + fsl_sata_reg_t *reg = (fsl_sata_reg_t *)reg_base; + u32 scontrol; + + /* Disable the SATA interface and put PHY offline */ + scontrol = in_le32(®->scontrol); + scontrol = (scontrol & 0x0f0) | 0x304; + out_le32(®->scontrol, scontrol); + + /* No speed strict */ + scontrol = in_le32(®->scontrol); + scontrol = scontrol & ~0x0f0; + out_le32(®->scontrol, scontrol); + + /* Issue PHY wake/reset, Hardware_reset_asserted */ + scontrol = in_le32(®->scontrol); + scontrol = (scontrol & 0x0f0) | 0x301; + out_le32(®->scontrol, scontrol); + + mdelay(100); + + /* Resume PHY, COMRESET negated, the device initialize hardware + * and execute diagnostics, send good status-signature to host, + * which is D2H register FIS, and then the device enter idle state. + */ + scontrol = in_le32(®->scontrol); + scontrol = (scontrol & 0x0f0) | 0x300; + out_le32(®->scontrol, scontrol); + + mdelay(100); + return; +} + +static void fsl_sata_dump_regs(fsl_sata_reg_t *reg) +{ + printf("\n\rSATA: %08x\n\r", (u32)reg); + printf("CQR: %08x\n\r", in_le32(®->cqr)); + printf("CAR: %08x\n\r", in_le32(®->car)); + printf("CCR: %08x\n\r", in_le32(®->ccr)); + printf("CER: %08x\n\r", in_le32(®->cer)); + printf("CQR: %08x\n\r", in_le32(®->cqr)); + printf("DER: %08x\n\r", in_le32(®->der)); + printf("CHBA: %08x\n\r", in_le32(®->chba)); + printf("HStatus: %08x\n\r", in_le32(®->hstatus)); + printf("HControl: %08x\n\r", in_le32(®->hcontrol)); + printf("CQPMP: %08x\n\r", in_le32(®->cqpmp)); + printf("SIG: %08x\n\r", in_le32(®->sig)); + printf("ICC: %08x\n\r", in_le32(®->icc)); + printf("SStatus: %08x\n\r", in_le32(®->sstatus)); + printf("SError: %08x\n\r", in_le32(®->serror)); + printf("SControl: %08x\n\r", in_le32(®->scontrol)); + printf("SNotification: %08x\n\r", in_le32(®->snotification)); + printf("TransCfg: %08x\n\r", in_le32(®->transcfg)); + printf("TransStatus: %08x\n\r", in_le32(®->transstatus)); + printf("LinkCfg: %08x\n\r", in_le32(®->linkcfg)); + printf("LinkCfg1: %08x\n\r", in_le32(®->linkcfg1)); + printf("LinkCfg2: %08x\n\r", in_le32(®->linkcfg2)); + printf("LinkStatus: %08x\n\r", in_le32(®->linkstatus)); + printf("LinkStatus1: %08x\n\r", in_le32(®->linkstatus1)); + printf("PhyCtrlCfg: %08x\n\r", in_le32(®->phyctrlcfg)); + printf("SYSPR: %08x\n\r", in_be32(®->syspr)); +} + +static int fsl_ata_exec_ata_cmd(struct fsl_sata *sata, struct cfis *cfis, + int is_ncq, int tag, u8 *buffer, u32 len) +{ + cmd_hdr_entry_t *cmd_hdr; + cmd_desc_t *cmd_desc; + sata_fis_h2d_t *h2d; + prd_entry_t *prde; + u32 ext_c_ddc; + u32 prde_count; + u32 val32; + u32 ttl; + fsl_sata_reg_t *reg = sata->reg_base; + int i; + + /* Check xfer length */ + if (len > SATA_HC_MAX_XFER_LEN) { + printf("max transfer length is 64MB\n\r"); + return 0; + } + + /* Setup the command descriptor */ + cmd_desc = sata->cmd_desc + tag; + + /* Get the pointer cfis of command descriptor */ + h2d = (sata_fis_h2d_t *)cmd_desc->cfis; + + /* Zero the cfis of command descriptor */ + memset((void *)h2d, 0, SATA_HC_CMD_DESC_CFIS_SIZE); + + /* Copy the cfis from user to command descriptor */ + h2d->fis_type = cfis->fis_type; + h2d->pm_port_c = cfis->pm_port_c; + h2d->command = cfis->command; + + h2d->features = cfis->features; + h2d->features_exp = cfis->features_exp; + + h2d->lba_low = cfis->lba_low; + h2d->lba_mid = cfis->lba_mid; + h2d->lba_high = cfis->lba_high; + h2d->lba_low_exp = cfis->lba_low_exp; + h2d->lba_mid_exp = cfis->lba_mid_exp; + h2d->lba_high_exp = cfis->lba_high_exp; + + if (!is_ncq) { + h2d->sector_count = cfis->sector_count; + h2d->sector_count_exp = cfis->sector_count_exp; + } else { /* NCQ */ + h2d->sector_count = (u8)(tag << 3); + } + + h2d->device = cfis->device; + h2d->control = cfis->control; + + /* Setup the PRD table */ + prde = (prd_entry_t *)cmd_desc->prdt; + memset((void *)prde, 0, sizeof(struct prdt)); + + prde_count = 0; + ttl = len; + for (i = 0; i < SATA_HC_MAX_PRD_DIRECT; i++) { + if (!len) + break; + prde->dba = cpu_to_le32((u32)buffer & ~0x3); + debug("dba = %08x\n\r", (u32)buffer); + + if (len < PRD_ENTRY_MAX_XFER_SZ) { + ext_c_ddc = PRD_ENTRY_DATA_SNOOP | len; + debug("ext_c_ddc1 = %08x, len = %08x\n\r", ext_c_ddc, len); + prde->ext_c_ddc = cpu_to_le32(ext_c_ddc); + prde_count++; + prde++; + break; + } else { + ext_c_ddc = PRD_ENTRY_DATA_SNOOP; /* 4M bytes */ + debug("ext_c_ddc2 = %08x, len = %08x\n\r", ext_c_ddc, len); + prde->ext_c_ddc = cpu_to_le32(ext_c_ddc); + buffer += PRD_ENTRY_MAX_XFER_SZ; + len -= PRD_ENTRY_MAX_XFER_SZ; + prde_count++; + prde++; + } + } + + /* Setup the command slot of cmd hdr */ + cmd_hdr = (cmd_hdr_entry_t *)&sata->cmd_hdr->cmd_slot[tag]; + + cmd_hdr->cda = cpu_to_le32((u32)cmd_desc & ~0x3); + + val32 = prde_count << CMD_HDR_PRD_ENTRY_SHIFT; + val32 |= sizeof(sata_fis_h2d_t); + cmd_hdr->prde_fis_len = cpu_to_le32(val32); + + cmd_hdr->ttl = cpu_to_le32(ttl); + + if (!is_ncq) { + val32 = CMD_HDR_ATTR_RES | CMD_HDR_ATTR_SNOOP; + } else { + val32 = CMD_HDR_ATTR_RES | CMD_HDR_ATTR_SNOOP | CMD_HDR_ATTR_FPDMA; + } + + tag &= CMD_HDR_ATTR_TAG; + val32 |= tag; + + debug("attribute = %08x\n\r", val32); + cmd_hdr->attribute = cpu_to_le32(val32); + + /* Make sure cmd desc and cmd slot valid before commmand issue */ + sync(); + + /* PMP*/ + val32 = (u32)(h2d->pm_port_c & 0x0f); + out_le32(®->cqpmp, val32); + + /* Wait no active */ + if (ata_wait_register(®->car, (1 << tag), 0, 10000)) + printf("Wait no active time out\n\r"); + + /* Issue command */ + if (!(in_le32(®->cqr) & (1 << tag))) { + val32 = 1 << tag; + out_le32(®->cqr, val32); + } + + /* Wait command completed for 10s */ + if (ata_wait_register(®->ccr, (1 << tag), (1 << tag), 10000)) { + if (!is_ncq) + printf("Non-NCQ command time out\n\r"); + else + printf("NCQ command time out\n\r"); + } + + val32 = in_le32(®->cer); + + if (val32) { + u32 der; + fsl_sata_dump_sfis((struct sfis *)cmd_desc->sfis); + printf("CE at device\n\r"); + fsl_sata_dump_regs(reg); + der = in_le32(®->der); + out_le32(®->cer, val32); + out_le32(®->der, der); + } + + /* Clear complete flags */ + val32 = in_le32(®->ccr); + out_le32(®->ccr, val32); + + return len; +} + +static int fsl_ata_exec_reset_cmd(struct fsl_sata *sata, struct cfis *cfis, + int tag, u8 *buffer, u32 len) +{ + return 0; +} + +static int fsl_sata_exec_cmd(struct fsl_sata *sata, struct cfis *cfis, + enum cmd_type command_type, int tag, u8 *buffer, u32 len) +{ + int rc; + + if (tag > SATA_HC_MAX_CMD || tag < 0) { + printf("tag is out of range, tag=\n\r", tag); + return -1; + } + + switch (command_type) { + case CMD_ATA: + rc = fsl_ata_exec_ata_cmd(sata, cfis, 0, tag, buffer, len); + return rc; + case CMD_RESET: + rc = fsl_ata_exec_reset_cmd(sata, cfis, tag, buffer, len); + return rc; + case CMD_NCQ: + rc = fsl_ata_exec_ata_cmd(sata, cfis, 1, tag, buffer, len); + return rc; + case CMD_ATAPI: + case CMD_VENDOR_BIST: + case CMD_BIST: + printf("not support now\n\r"); + return -1; + default: + break; + } + + return -1; +} + +static void fsl_sata_identify(int dev, u16 *id) +{ + fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; + struct sata_fis_h2d h2d; + struct cfis *cfis; + + cfis = (struct cfis *)&h2d; + memset((void *)cfis, 0, sizeof(struct cfis)); + + cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D; + cfis->pm_port_c = 0x80; /* is command */ + cfis->command = ATA_CMD_ID_ATA; + + fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, (u8 *)id, ATA_ID_WORDS * 2); + ata_swap_buf_le16(id, ATA_ID_WORDS); +} + +static void fsl_sata_xfer_mode(int dev, u16 *id) +{ + fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; + + sata->pio = id[ATA_ID_PIO_MODES]; + sata->mwdma = id[ATA_ID_MWDMA_MODES]; + sata->udma = id[ATA_ID_UDMA_MODES]; + debug("pio %04x, mwdma %04x, udma %04x\n\r", sata->pio, sata->mwdma, sata->udma); +} + +static void fsl_sata_set_features(int dev) +{ + fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; + struct sata_fis_h2d h2d; + struct cfis *cfis; + u8 udma_cap; + + cfis = (struct cfis *)&h2d; + memset((void *)cfis, 0, sizeof(struct cfis)); + + cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D; + cfis->pm_port_c = 0x80; /* is command */ + cfis->command = ATA_CMD_SET_FEATURES; + cfis->features = SETFEATURES_XFER; + + /* First check the device capablity */ + udma_cap = (u8)(sata->udma & 0xff); + debug("udma_cap %02x\n\r", udma_cap); + + if (udma_cap == ATA_UDMA6) + cfis->sector_count = XFER_UDMA_6; + if (udma_cap == ATA_UDMA5) + cfis->sector_count = XFER_UDMA_5; + if (udma_cap == ATA_UDMA4) + cfis->sector_count = XFER_UDMA_4; + if (udma_cap == ATA_UDMA3) + cfis->sector_count = XFER_UDMA_3; + + fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, NULL, 0); +} + +static u32 fsl_sata_rw_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_write) +{ + fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; + struct sata_fis_h2d h2d; + struct cfis *cfis; + u32 block; + + block = start; + cfis = (struct cfis *)&h2d; + + memset((void *)cfis, 0, sizeof(struct cfis)); + + cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D; + cfis->pm_port_c = 0x80; /* is command */ + cfis->command = (is_write) ? ATA_CMD_WRITE_DMA : ATA_CMD_READ_DMA; + cfis->device = ATA_LBA; + + cfis->device |= (block >> 24) & 0xf; + cfis->lba_high = (block >> 16) & 0xff; + cfis->lba_mid = (block >> 8) & 0xff; + cfis->lba_low = block & 0xff; + cfis->sector_count = (u8)(blkcnt & 0xff); + + fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, buffer, ATA_SECT_SIZE * blkcnt); + return blkcnt; +} + +void fsl_sata_flush_cache(int dev) +{ + fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; + struct sata_fis_h2d h2d; + struct cfis *cfis; + + cfis = (struct cfis *)&h2d; + + memset((void *)cfis, 0, sizeof(struct cfis)); + + cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D; + cfis->pm_port_c = 0x80; /* is command */ + cfis->command = ATA_CMD_FLUSH_CACHE; + + fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, NULL, 0); +} + +static u32 fsl_sata_rw_cmd_ext(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_write) +{ + fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; + struct sata_fis_h2d h2d; + struct cfis *cfis; + u64 block; + + block = (u64)start; + cfis = (struct cfis *)&h2d; + + memset((void *)cfis, 0, sizeof(struct cfis)); + + cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D; + cfis->pm_port_c = 0x80; /* is command */ + + cfis->command = (is_write) ? ATA_CMD_WRITE_DMA_EXT + : ATA_CMD_READ_DMA_EXT; + + cfis->lba_high_exp = (block >> 40) & 0xff; + cfis->lba_mid_exp = (block >> 32) & 0xff; + cfis->lba_low_exp = (block >> 24) & 0xff; + cfis->lba_high = (block >> 16) & 0xff; + cfis->lba_mid = (block >> 8) & 0xff; + cfis->lba_low = block & 0xff; + cfis->device = ATA_LBA; + cfis->sector_count_exp = (blkcnt >> 8) & 0xff; + cfis->sector_count = blkcnt & 0xff; + + fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, buffer, ATA_SECT_SIZE * blkcnt); + return blkcnt; +} + +u32 fsl_sata_rw_ncq_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_write) +{ + fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; + struct sata_fis_h2d h2d; + struct cfis *cfis; + int ncq_channel; + u64 block; + + if (sata_dev_desc[dev].lba48 != 1) { + printf("execute FPDMA command on non-LBA48 hard disk\n\r"); + return -1; + } + + block = (u64)start; + cfis = (struct cfis *)&h2d; + + memset((void *)cfis, 0, sizeof(struct cfis)); + + cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D; + cfis->pm_port_c = 0x80; /* is command */ + + cfis->command = (is_write) ? ATA_CMD_WRITE_FPDMA_QUEUED + : ATA_CMD_READ_FPDMA_QUEUED; + + cfis->lba_high_exp = (block >> 40) & 0xff; + cfis->lba_mid_exp = (block >> 32) & 0xff; + cfis->lba_low_exp = (block >> 24) & 0xff; + cfis->lba_high = (block >> 16) & 0xff; + cfis->lba_mid = (block >> 8) & 0xff; + cfis->lba_low = block & 0xff; + + cfis->device = ATA_LBA; + cfis->features_exp = (blkcnt >> 8) & 0xff; + cfis->features = blkcnt & 0xff; + + if (sata->queue_depth >= SATA_HC_MAX_CMD) + ncq_channel = SATA_HC_MAX_CMD - 1; + else + ncq_channel = sata->queue_depth - 1; + + /* Use the latest queue */ + fsl_sata_exec_cmd(sata, cfis, CMD_NCQ, ncq_channel, buffer, ATA_SECT_SIZE * blkcnt); + return blkcnt; +} + +void fsl_sata_flush_cache_ext(int dev) +{ + fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; + struct sata_fis_h2d h2d; + struct cfis *cfis; + + cfis = (struct cfis *)&h2d; + + memset((void *)cfis, 0, sizeof(struct cfis)); + + cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D; + cfis->pm_port_c = 0x80; /* is command */ + cfis->command = ATA_CMD_FLUSH_CACHE_EXT; + + fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, NULL, 0); +} + +/* Software reset, set SRST of the Device Control register */ +void fsl_sata_software_reset(int dev) +{ + return; +} + +static void fsl_sata_init_wcache(int dev, u16 *id) +{ + fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; + + if (ata_id_has_wcache(id) && ata_id_wcache_enabled(id)) + sata->wcache = 1; + if (ata_id_has_flush(id)) + sata->flush = 1; + if (ata_id_has_flush_ext(id)) + sata->flush_ext = 1; +} + +static int fsl_sata_get_wcache(int dev) +{ + fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; + return sata->wcache; +} + +static int fsl_sata_get_flush(int dev) +{ + fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; + return sata->flush; +} + +static int fsl_sata_get_flush_ext(int dev) +{ + fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; + return sata->flush_ext; +} + +u32 ata_low_level_rw_lba48(int dev, u32 blknr, u32 blkcnt, void *buffer, int is_write) +{ + u32 start, blks; + u8 *addr; + int max_blks; + + start = blknr; + blks = blkcnt; + addr = (u8 *)buffer; + + max_blks = ATA_MAX_SECTORS_LBA48; + do { + if (blks > max_blks) { + if (fsl_sata_info[dev].flags != FLAGS_FPDMA) + fsl_sata_rw_cmd_ext(dev, start, max_blks, addr, is_write); + else + fsl_sata_rw_ncq_cmd(dev, start, max_blks, addr, is_write); + start += max_blks; + blks -= max_blks; + addr += ATA_SECT_SIZE * max_blks; + } else { + if (fsl_sata_info[dev].flags != FLAGS_FPDMA) + fsl_sata_rw_cmd_ext(dev, start, blks, addr, is_write); + else + fsl_sata_rw_ncq_cmd(dev, start, blks, addr, is_write); + start += blks; + blks = 0; + addr += ATA_SECT_SIZE * blks; + } + } while (blks != 0); + + return blkcnt; +} + +u32 ata_low_level_rw_lba28(int dev, u32 blknr, u32 blkcnt, void *buffer, int is_write) +{ + u32 start, blks; + u8 *addr; + int max_blks; + + start = blknr; + blks = blkcnt; + addr = (u8 *)buffer; + + max_blks = ATA_MAX_SECTORS; + do { + if (blks > max_blks) { + fsl_sata_rw_cmd(dev, start, max_blks, addr, is_write); + start += max_blks; + blks -= max_blks; + addr += ATA_SECT_SIZE * max_blks; + } else { + fsl_sata_rw_cmd(dev, start, blks, addr, is_write); + start += blks; + blks = 0; + addr += ATA_SECT_SIZE * blks; + } + } while (blks != 0); + + return blkcnt; +} + +/* + * SATA interface between low level driver and command layer + */ +ulong sata_read(int dev, u32 blknr, u32 blkcnt, void *buffer) +{ + u32 rc; + + if (sata_dev_desc[dev].lba48) + rc = ata_low_level_rw_lba48(dev, blknr, blkcnt, buffer, READ_CMD); + else + rc = ata_low_level_rw_lba28(dev, blknr, blkcnt, buffer, READ_CMD); + return rc; +} + +ulong sata_write(int dev, u32 blknr, u32 blkcnt, void *buffer) +{ + u32 rc; + + if (sata_dev_desc[dev].lba48) { + rc = ata_low_level_rw_lba48(dev, blknr, blkcnt, buffer, WRITE_CMD); + if (fsl_sata_get_wcache(dev) && fsl_sata_get_flush_ext(dev)) + fsl_sata_flush_cache_ext(dev); + } else { + rc = ata_low_level_rw_lba28(dev, blknr, blkcnt, buffer, WRITE_CMD); + if (fsl_sata_get_wcache(dev) && fsl_sata_get_flush(dev)) + fsl_sata_flush_cache(dev); + } + return rc; +} + +int scan_sata(int dev) +{ + fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv; + unsigned char serial[ATA_ID_SERNO_LEN + 1]; + unsigned char firmware[ATA_ID_FW_REV_LEN + 1]; + unsigned char product[ATA_ID_PROD_LEN + 1]; + u16 *id; + u64 n_sectors; + + /* if no detected link */ + if (!sata->link) + return -1; + + id = (u16 *)malloc(ATA_ID_WORDS * 2); + if (!id) { + printf("id malloc failed\n\r"); + return -1; + } + + /* Identify device to get information */ + fsl_sata_identify(dev, id); + + /* Serial number */ + ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial)); + memcpy(sata_dev_desc[dev].product, serial, sizeof(serial)); + + /* Firmware version */ + ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware)); + memcpy(sata_dev_desc[dev].revision, firmware, sizeof(firmware)); + + /* Product model */ + ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product)); + memcpy(sata_dev_desc[dev].vendor, product, sizeof(product)); + + /* Totoal sectors */ + n_sectors = ata_id_n_sectors(id); + sata_dev_desc[dev].lba = (u32)n_sectors; + + /* Check if support LBA48 */ + if (ata_id_has_lba48(id)) { + sata_dev_desc[dev].lba48 = 1; + debug("Device support LBA48\n\r"); + } + + /* Get the NCQ queue depth from device */ + sata->queue_depth = ata_id_queue_depth(id); + + /* Get the xfer mode from device */ + fsl_sata_xfer_mode(dev, id); + + /* Get the write cache status from device */ + fsl_sata_init_wcache(dev, id); + + /* Set the xfer mode to highest speed */ + fsl_sata_set_features(dev); +#ifdef DEBUG + fsl_sata_identify(dev, id); + ata_dump_id(id); +#endif + free((void *)id); + return 0; +} diff --git a/drivers/block/fsl_sata.h b/drivers/block/fsl_sata.h new file mode 100644 index 000000000..874c0dc74 --- /dev/null +++ b/drivers/block/fsl_sata.h @@ -0,0 +1,374 @@ +/* + * Copyright (C) 2007-2008 Freescale Semiconductor, Inc. + * Dave Liu + * + * 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 __FSL_SATA_H__ +#define __FSL_SATA_H__ + +#define SATA_HC_MAX_NUM 4 /* Max host controller numbers */ +#define SATA_HC_MAX_CMD 16 /* Max command queue depth per host controller */ +#define SATA_HC_MAX_PORT 16 /* Max port number per host controller */ + +/* +* SATA Host Controller Registers +*/ +typedef struct fsl_sata_reg { + /* SATA command registers */ + u32 cqr; /* Command queue register */ + u8 res1[0x4]; + u32 car; /* Command active register */ + u8 res2[0x4]; + u32 ccr; /* Command completed register */ + u8 res3[0x4]; + u32 cer; /* Command error register */ + u8 res4[0x4]; + u32 der; /* Device error register */ + u32 chba; /* Command header base address */ + u32 hstatus; /* Host status register */ + u32 hcontrol; /* Host control register */ + u32 cqpmp; /* Port number queue register */ + u32 sig; /* Signature register */ + u32 icc; /* Interrupt coalescing control register */ + u8 res5[0xc4]; + + /* SATA supperset registers */ + u32 sstatus; /* SATA interface status register */ + u32 serror; /* SATA interface error register */ + u32 scontrol; /* SATA interface control register */ + u32 snotification; /* SATA interface notification register */ + u8 res6[0x30]; + + /* SATA control status registers */ + u32 transcfg; /* Transport layer configuration */ + u32 transstatus; /* Transport layer status */ + u32 linkcfg; /* Link layer configuration */ + u32 linkcfg1; /* Link layer configuration1 */ + u32 linkcfg2; /* Link layer configuration2 */ + u32 linkstatus; /* Link layer status */ + u32 linkstatus1; /* Link layer status1 */ + u32 phyctrlcfg; /* PHY control configuration */ + u8 res7[0x2b0]; + + /* SATA system control registers */ + u32 syspr; /* System priority register - big endian */ + u8 res8[0xbec]; +} __attribute__ ((packed)) fsl_sata_reg_t; + +/* HStatus register +*/ +#define HSTATUS_ONOFF 0x80000000 /* Online/offline status */ +#define HSTATUS_FORCE_OFFLINE 0x40000000 /* In process going offline */ +#define HSTATUS_BIST_ERR 0x20000000 + +/* Fatal error */ +#define HSTATUS_MASTER_ERR 0x00004000 +#define HSTATUS_DATA_UNDERRUN 0x00002000 +#define HSTATUS_DATA_OVERRUN 0x00001000 +#define HSTATUS_CRC_ERR_TX 0x00000800 +#define HSTATUS_CRC_ERR_RX 0x00000400 +#define HSTATUS_FIFO_OVERFLOW_TX 0x00000200 +#define HSTATUS_FIFO_OVERFLOW_RX 0x00000100 +#define HSTATUS_FATAL_ERR_ALL (HSTATUS_MASTER_ERR | \ + HSTATUS_DATA_UNDERRUN | \ + HSTATUS_DATA_OVERRUN | \ + HSTATUS_CRC_ERR_TX | \ + HSTATUS_CRC_ERR_RX | \ + HSTATUS_FIFO_OVERFLOW_TX | \ + HSTATUS_FIFO_OVERFLOW_RX) +/* Interrupt status */ +#define HSTATUS_FATAL_ERR 0x00000020 +#define HSTATUS_PHY_RDY 0x00000010 +#define HSTATUS_SIGNATURE 0x00000008 +#define HSTATUS_SNOTIFY 0x00000004 +#define HSTATUS_DEVICE_ERR 0x00000002 +#define HSTATUS_CMD_COMPLETE 0x00000001 + +/* HControl register +*/ +#define HCONTROL_ONOFF 0x80000000 /* Online or offline request */ +#define HCONTROL_FORCE_OFFLINE 0x40000000 /* Force offline request */ +#define HCONTROL_HDR_SNOOP 0x00000400 /* Command header snoop */ +#define HCONTROL_PMP_ATTACHED 0x00000200 /* Port multiplier attached */ + +/* Interrupt enable */ +#define HCONTROL_FATAL_ERR 0x00000020 +#define HCONTROL_PHY_RDY 0x00000010 +#define HCONTROL_SIGNATURE 0x00000008 +#define HCONTROL_SNOTIFY 0x00000004 +#define HCONTROL_DEVICE_ERR 0x00000002 +#define HCONTROL_CMD_COMPLETE 0x00000001 + +#define HCONTROL_INT_EN_ALL (HCONTROL_FATAL_ERR | \ + HCONTROL_PHY_RDY | \ + HCONTROL_SIGNATURE | \ + HCONTROL_SNOTIFY | \ + HCONTROL_DEVICE_ERR | \ + HCONTROL_CMD_COMPLETE) + +/* SStatus register +*/ +#define SSTATUS_IPM_MASK 0x00000780 +#define SSTATUS_IPM_NOPRESENT 0x00000000 +#define SSTATUS_IPM_ACTIVE 0x00000080 +#define SSTATUS_IPM_PATIAL 0x00000100 +#define SSTATUS_IPM_SLUMBER 0x00000300 + +#define SSTATUS_SPD_MASK 0x000000f0 +#define SSTATUS_SPD_GEN1 0x00000010 +#define SSTATUS_SPD_GEN2 0x00000020 + +#define SSTATUS_DET_MASK 0x0000000f +#define SSTATUS_DET_NODEVICE 0x00000000 +#define SSTATUS_DET_DISCONNECT 0x00000001 +#define SSTATUS_DET_CONNECT 0x00000003 +#define SSTATUS_DET_PHY_OFFLINE 0x00000004 + +/* SControl register +*/ +#define SCONTROL_SPM_MASK 0x0000f000 +#define SCONTROL_SPM_GO_PARTIAL 0x00001000 +#define SCONTROL_SPM_GO_SLUMBER 0x00002000 +#define SCONTROL_SPM_GO_ACTIVE 0x00004000 + +#define SCONTROL_IPM_MASK 0x00000f00 +#define SCONTROL_IPM_NO_RESTRICT 0x00000000 +#define SCONTROL_IPM_PARTIAL 0x00000100 +#define SCONTROL_IPM_SLUMBER 0x00000200 +#define SCONTROL_IPM_PART_SLUM 0x00000300 + +#define SCONTROL_SPD_MASK 0x000000f0 +#define SCONTROL_SPD_NO_RESTRICT 0x00000000 +#define SCONTROL_SPD_GEN1 0x00000010 +#define SCONTROL_SPD_GEN2 0x00000020 + +#define SCONTROL_DET_MASK 0x0000000f +#define SCONTROL_DET_HRESET 0x00000001 +#define SCONTROL_DET_DISABLE 0x00000004 + +/* TransCfg register +*/ +#define TRANSCFG_DFIS_SIZE_SHIFT 16 +#define TRANSCFG_RX_WATER_MARK_MASK 0x0000001f + +/* PhyCtrlCfg register +*/ +#define PHYCTRLCFG_FPRFTI_MASK 0x00000018 +#define PHYCTRLCFG_LOOPBACK_MASK 0x0000000e + +/* +* Command Header Entry +*/ +typedef struct cmd_hdr_entry { + u32 cda; /* Command Descriptor Address, 4 bytes aligned */ + u32 prde_fis_len; /* Number of PRD entries and FIS length */ + u32 ttl; /* Total transfer length */ + u32 attribute; /* the attribute of command */ +} __attribute__ ((packed)) cmd_hdr_entry_t; + +#define SATA_HC_CMD_HDR_ENTRY_SIZE sizeof(struct cmd_hdr_entry) + +/* cda +*/ +#define CMD_HDR_CDA_ALIGN 4 + +/* prde_fis_len +*/ +#define CMD_HDR_PRD_ENTRY_SHIFT 16 +#define CMD_HDR_PRD_ENTRY_MASK 0x003f0000 +#define CMD_HDR_FIS_LEN_SHIFT 2 + +/* attribute +*/ +#define CMD_HDR_ATTR_RES 0x00000800 /* Reserved bit, should be 1 */ +#define CMD_HDR_ATTR_VBIST 0x00000400 /* Vendor BIST */ +#define CMD_HDR_ATTR_SNOOP 0x00000200 /* Snoop enable for all descriptor */ +#define CMD_HDR_ATTR_FPDMA 0x00000100 /* FPDMA queued command */ +#define CMD_HDR_ATTR_RESET 0x00000080 /* Reset - a SRST or device reset */ +#define CMD_HDR_ATTR_BIST 0x00000040 /* BIST - require the host to enter BIST mode */ +#define CMD_HDR_ATTR_ATAPI 0x00000020 /* ATAPI command */ +#define CMD_HDR_ATTR_TAG 0x0000001f /* TAG mask */ + +/* command type +*/ +enum cmd_type { + CMD_VENDOR_BIST, + CMD_BIST, + CMD_RESET, /* SRST or device reset */ + CMD_ATAPI, + CMD_NCQ, + CMD_ATA, /* None of all above */ +}; + +/* +* Command Header Table +*/ +typedef struct cmd_hdr_tbl { + cmd_hdr_entry_t cmd_slot[SATA_HC_MAX_CMD]; +} __attribute__ ((packed)) cmd_hdr_tbl_t; + +#define SATA_HC_CMD_HDR_TBL_SIZE sizeof(struct cmd_hdr_tbl) +#define SATA_HC_CMD_HDR_TBL_ALIGN 4 + +/* +* PRD entry - Physical Region Descriptor entry +*/ +typedef struct prd_entry { + u32 dba; /* Data base address, 4 bytes aligned */ + u32 res1; + u32 res2; + u32 ext_c_ddc; /* Indirect PRD flags, snoop and data word count */ +} __attribute__ ((packed)) prd_entry_t; + +#define SATA_HC_CMD_DESC_PRD_SIZE sizeof(struct prd_entry) + +/* dba +*/ +#define PRD_ENTRY_DBA_ALIGN 4 + +/* ext_c_ddc +*/ +#define PRD_ENTRY_EXT 0x80000000 /* extension flag or called indirect descriptor flag */ +#define PRD_ENTRY_DATA_SNOOP 0x00400000 /* Snoop enable for all data associated with the PRD entry */ +#define PRD_ENTRY_LEN_MASK 0x003fffff /* Data word count */ + +#define PRD_ENTRY_MAX_XFER_SZ (PRD_ENTRY_LEN_MASK + 1) + +/* + * This SATA host controller supports a max of 16 direct PRD entries, but if use + * chained indirect PRD entries, then the contollers supports upto a max of 63 + * entries including direct and indirect PRD entries. + * The PRDT is an array of 63 PRD entries contigiously, but the PRD entries#15 + * will be setup as an indirect descriptor, pointing to it's next (contigious) + * PRD entries#16. + */ +#define SATA_HC_MAX_PRD 63 /* Max PRD entry numbers per command */ +#define SATA_HC_MAX_PRD_DIRECT 16 /* Direct PRDT entries */ +#define SATA_HC_MAX_PRD_USABLE (SATA_HC_MAX_PRD - 1) +#define SATA_HC_MAX_XFER_LEN 0x4000000 + +/* +* PRDT - Physical Region Descriptor Table +*/ +typedef struct prdt { + prd_entry_t prdt[SATA_HC_MAX_PRD]; +} __attribute__ ((packed)) prdt_t; + +/* +* Command Descriptor +*/ +#define SATA_HC_CMD_DESC_CFIS_SIZE 32 /* bytes */ +#define SATA_HC_CMD_DESC_SFIS_SIZE 32 /* bytes */ +#define SATA_HC_CMD_DESC_ACMD_SIZE 16 /* bytes */ +#define SATA_HC_CMD_DESC_RES 16 /* bytes */ + +typedef struct cmd_desc { + u8 cfis[SATA_HC_CMD_DESC_CFIS_SIZE]; + u8 sfis[SATA_HC_CMD_DESC_SFIS_SIZE]; + u8 acmd[SATA_HC_CMD_DESC_ACMD_SIZE]; + u8 res[SATA_HC_CMD_DESC_RES]; + prd_entry_t prdt[SATA_HC_MAX_PRD]; +} __attribute__ ((packed)) cmd_desc_t; + +#define SATA_HC_CMD_DESC_SIZE sizeof(struct cmd_desc) +#define SATA_HC_CMD_DESC_ALIGN 4 + +/* +* CFIS - Command FIS, which is H2D register FIS, the struct defination +* of Non-Queued command is different than NCQ command. see them is sata2.h +*/ +typedef struct cfis { + u8 fis_type; + u8 pm_port_c; + u8 command; + u8 features; + u8 lba_low; + u8 lba_mid; + u8 lba_high; + u8 device; + u8 lba_low_exp; + u8 lba_mid_exp; + u8 lba_high_exp; + u8 features_exp; + u8 sector_count; + u8 sector_count_exp; + u8 res1; + u8 control; + u8 res2[4]; +} __attribute__ ((packed)) cfis_t; + +/* +* SFIS - Status FIS, which is D2H register FIS. +*/ +typedef struct sfis { + u8 fis_type; + u8 pm_port_i; + u8 status; + u8 error; + u8 lba_low; + u8 lba_mid; + u8 lba_high; + u8 device; + u8 lba_low_exp; + u8 lba_mid_exp; + u8 lba_high_exp; + u8 res1; + u8 sector_count; + u8 sector_count_exp; + u8 res2[2]; + u8 res3[4]; +} __attribute__ ((packed)) sfis_t; + +/* + * SATA device driver info + */ +typedef struct fsl_sata_info { + u32 sata_reg_base; + u32 flags; +} fsl_sata_info_t; + +#define FLAGS_DMA 0x00000000 +#define FLAGS_FPDMA 0x00000001 + +/* + * SATA device driver struct + */ +typedef struct fsl_sata { + char name[12]; + fsl_sata_reg_t *reg_base; /* the base address of controller register */ + void *cmd_hdr_tbl_offset; /* alloc address of command header table */ + cmd_hdr_tbl_t *cmd_hdr; /* aligned address of command header table */ + void *cmd_desc_offset; /* alloc address of command descriptor */ + cmd_desc_t *cmd_desc; /* aligned address of command descriptor */ + int link; /* PHY link status */ + /* device attribute */ + int ata_device_type; /* device type */ + int lba48; + int queue_depth; /* Max NCQ queue depth */ + u16 pio; + u16 mwdma; + u16 udma; + int wcache; + int flush; + int flush_ext; +} fsl_sata_t; + +#define READ_CMD 0 +#define WRITE_CMD 1 + +#endif /* __FSL_SATA_H__ */ diff --git a/drivers/block/libata.c b/drivers/block/libata.c new file mode 100644 index 000000000..bbe16a228 --- /dev/null +++ b/drivers/block/libata.c @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2008 Freescale Semiconductor, Inc. + * Dave Liu + * port from the libata of linux kernel + * + * 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 + +u64 ata_id_n_sectors(u16 *id) +{ + if (ata_id_has_lba(id)) { + if (ata_id_has_lba48(id)) + return ata_id_u64(id, ATA_ID_LBA48_SECTORS); + else + return ata_id_u32(id, ATA_ID_LBA_SECTORS); + } else { + return 0; + } +} + +u32 ata_dev_classify(u32 sig) +{ + u8 lbam, lbah; + + lbam = (sig >> 16) & 0xff; + lbah = (sig >> 24) & 0xff; + + if (((lbam == 0) && (lbah == 0)) || + ((lbam == 0x3c) && (lbah == 0xc3))) + return ATA_DEV_ATA; + + if ((lbam == 0x14) && (lbah == 0xeb)) + return ATA_DEV_ATAPI; + + if ((lbam == 0x69) && (lbah == 0x96)) + return ATA_DEV_PMP; + + return ATA_DEV_UNKNOWN; +} + +static void ata_id_string(const u16 *id, unsigned char *s, + unsigned int ofs, unsigned int len) +{ + unsigned int c; + + while (len > 0) { + c = id[ofs] >> 8; + *s = c; + s++; + + c = id[ofs] & 0xff; + *s = c; + s++; + + ofs++; + len -= 2; + } +} + +void ata_id_c_string(const u16 *id, unsigned char *s, + unsigned int ofs, unsigned int len) +{ + unsigned char *p; + + ata_id_string(id, s, ofs, len - 1); + + p = s + strnlen((char *)s, len - 1); + while (p > s && p[-1] == ' ') + p--; + *p = '\0'; +} + +void ata_dump_id(u16 *id) +{ + unsigned char serial[ATA_ID_SERNO_LEN + 1]; + unsigned char firmware[ATA_ID_FW_REV_LEN + 1]; + unsigned char product[ATA_ID_PROD_LEN + 1]; + u64 n_sectors; + + /* Serial number */ + ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial)); + printf("S/N: %s\n\r", serial); + + /* Firmware version */ + ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware)); + printf("Firmware version: %s\n\r", firmware); + + /* Product model */ + ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product)); + printf("Product model number: %s\n\r", product); + + /* Total sectors of device */ + n_sectors = ata_id_n_sectors(id); + printf("Capablity: %d sectors\n\r", n_sectors); + + printf ("id[49]: capabilities ==0x%04x\n" + "id[53]: field valid ==0x%04x\n" + "id[63]: mwdma ==0x%04x\n" + "id[64]: pio ==0x%04x\n" + "id[75]: queue depth ==0x%04x\n", + id[49], + id[53], + id[63], + id[64], + id[75]); + + printf ("id[76]: sata capablity ==0x%04x\n" + "id[78]: sata features supported ==0x%04x\n" + "id[79]: sata features enable ==0x%04x\n", + id[76], + id[78], + id[79]); + + printf ("id[80]: major version ==0x%04x\n" + "id[81]: minor version ==0x%04x\n" + "id[82]: command set supported 1 ==0x%04x\n" + "id[83]: command set supported 2 ==0x%04x\n" + "id[84]: command set extension ==0x%04x\n", + id[80], + id[81], + id[82], + id[83], + id[84]); + printf ("id[85]: command set enable 1 ==0x%04x\n" + "id[86]: command set enable 2 ==0x%04x\n" + "id[87]: command set default ==0x%04x\n" + "id[88]: udma ==0x%04x\n" + "id[93]: hardware reset result ==0x%04x\n", + id[85], + id[86], + id[87], + id[88], + id[93]); +} + +void ata_swap_buf_le16(u16 *buf, unsigned int buf_words) +{ + unsigned int i; + + for (i = 0; i < buf_words; i++) + buf[i] = le16_to_cpu(buf[i]); +} diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c index 22485ea91..dde057124 100644 --- a/drivers/i2c/fsl_i2c.c +++ b/drivers/i2c/fsl_i2c.c @@ -32,6 +32,8 @@ #define I2C_READ_BIT 1 #define I2C_WRITE_BIT 0 +DECLARE_GLOBAL_DATA_PTR; + /* Initialize the bus pointer to whatever one the SPD EEPROM is on. * Default is bus 0. This is necessary because the DDR initialization * runs from ROM, and we can't switch buses because we can't modify @@ -43,24 +45,111 @@ static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = CFG_SPD_BUS static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = 0; #endif -static volatile struct fsl_i2c *i2c_dev[2] = { +static unsigned int i2c_bus_speed[2] = {CFG_I2C_SPEED, CFG_I2C_SPEED}; + +static const struct fsl_i2c *i2c_dev[2] = { (struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET), #ifdef CFG_I2C2_OFFSET (struct fsl_i2c *) (CFG_IMMR + CFG_I2C2_OFFSET) #endif }; +/* I2C speed map for a DFSR value of 1 */ + +/* + * Map I2C frequency dividers to FDR and DFSR values + * + * This structure is used to define the elements of a table that maps I2C + * frequency divider (I2C clock rate divided by I2C bus speed) to a value to be + * programmed into the Frequency Divider Ratio (FDR) and Digital Filter + * Sampling Rate (DFSR) registers. + * + * The actual table should be defined in the board file, and it must be called + * fsl_i2c_speed_map[]. + * + * The last entry of the table must have a value of {-1, X}, where X is same + * FDR/DFSR values as the second-to-last entry. This guarantees that any + * search through the array will always find a match. + * + * The values of the divider must be in increasing numerical order, i.e. + * fsl_i2c_speed_map[x+1].divider > fsl_i2c_speed_map[x].divider. + * + * For this table, the values are based on a value of 1 for the DFSR + * register. See the application note AN2919 "Determining the I2C Frequency + * Divider Ratio for SCL" + */ +static const struct { + unsigned short divider; + u8 dfsr; + u8 fdr; +} fsl_i2c_speed_map[] = { + {160, 1, 32}, {192, 1, 33}, {224, 1, 34}, {256, 1, 35}, + {288, 1, 0}, {320, 1, 1}, {352, 6, 1}, {384, 1, 2}, {416, 6, 2}, + {448, 1, 38}, {480, 1, 3}, {512, 1, 39}, {544, 11, 3}, {576, 1, 4}, + {608, 22, 3}, {640, 1, 5}, {672, 32, 3}, {704, 11, 5}, {736, 43, 3}, + {768, 1, 6}, {800, 54, 3}, {832, 11, 6}, {896, 1, 42}, {960, 1, 7}, + {1024, 1, 43}, {1088, 22, 7}, {1152, 1, 8}, {1216, 43, 7}, {1280, 1, 9}, + {1408, 22, 9}, {1536, 1, 10}, {1664, 22, 10}, {1792, 1, 46}, + {1920, 1, 11}, {2048, 1, 47}, {2176, 43, 11}, {2304, 1, 12}, + {2560, 1, 13}, {2816, 43, 13}, {3072, 1, 14}, {3328, 43, 14}, + {3584, 1, 50}, {3840, 1, 15}, {4096, 1, 51}, {4608, 1, 16}, + {5120, 1, 17}, {6144, 1, 18}, {7168, 1, 54}, {7680, 1, 19}, + {8192, 1, 55}, {9216, 1, 20}, {10240, 1, 21}, {12288, 1, 22}, + {14336, 1, 58}, {15360, 1, 23}, {16384, 1, 59}, {18432, 1, 24}, + {20480, 1, 25}, {24576, 1, 26}, {28672, 1, 62}, {30720, 1, 27}, + {32768, 1, 63}, {36864, 1, 28}, {40960, 1, 29}, {49152, 1, 30}, + {61440, 1, 31}, {-1, 1, 31} +}; + +/** + * Set the I2C bus speed for a given I2C device + * + * @param dev: the I2C device + * @i2c_clk: I2C bus clock frequency + * @speed: the desired speed of the bus + * + * The I2C device must be stopped before calling this function. + * + * The return value is the actual bus speed that is set. + */ +static unsigned int set_i2c_bus_speed(const struct fsl_i2c *dev, + unsigned int i2c_clk, unsigned int speed) +{ + unsigned short divider = min(i2c_clk / speed, (unsigned short) -1); + unsigned int i; + u8 fdr, dfsr; + + /* + * We want to choose an FDR/DFSR that generates an I2C bus speed that + * is equal to or lower than the requested speed. That means that we + * want the first divider that is equal to or greater than the + * calculated divider. + */ + + for (i = 0; i < ARRAY_SIZE(fsl_i2c_speed_map); i++) + if (fsl_i2c_speed_map[i].divider >= divider) { + dfsr = fsl_i2c_speed_map[i].dfsr; + fdr = fsl_i2c_speed_map[i].fdr; + speed = i2c_clk / fsl_i2c_speed_map[i].divider; + break; + } + + writeb(fdr, &dev->fdr); /* set bus speed */ + writeb(dfsr, &dev->dfsrr); /* set default filter */ + + return speed; +} + void i2c_init(int speed, int slaveadd) { - volatile struct fsl_i2c *dev; + struct fsl_i2c *dev; dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET); writeb(0, &dev->cr); /* stop I2C controller */ udelay(5); /* let it shutdown in peace */ - writeb(0x3F, &dev->fdr); /* set bus speed */ - writeb(0x3F, &dev->dfsrr); /* set default filter */ + i2c_bus_speed[0] = set_i2c_bus_speed(dev, gd->i2c1_clk, speed); writeb(slaveadd << 1, &dev->adr); /* write slave address */ writeb(0x0, &dev->sr); /* clear status register */ writeb(I2C_CR_MEN, &dev->cr); /* start I2C controller */ @@ -70,12 +159,11 @@ i2c_init(int speed, int slaveadd) writeb(0, &dev->cr); /* stop I2C controller */ udelay(5); /* let it shutdown in peace */ - writeb(0x3F, &dev->fdr); /* set bus speed */ - writeb(0x3F, &dev->dfsrr); /* set default filter */ + i2c_bus_speed[1] = set_i2c_bus_speed(dev, gd->i2c2_clk, speed); writeb(slaveadd << 1, &dev->adr); /* write slave address */ writeb(0x0, &dev->sr); /* clear status register */ writeb(I2C_CR_MEN, &dev->cr); /* start I2C controller */ -#endif /* CFG_I2C2_OFFSET */ +#endif } static __inline__ int @@ -279,7 +367,14 @@ int i2c_set_bus_num(unsigned int bus) int i2c_set_bus_speed(unsigned int speed) { - return -1; + unsigned int i2c_clk = (i2c_bus_num == 1) ? gd->i2c2_clk : gd->i2c1_clk; + + writeb(0, &i2c_dev[i2c_bus_num]->cr); /* stop controller */ + i2c_bus_speed[i2c_bus_num] = + set_i2c_bus_speed(i2c_dev[i2c_bus_num], i2c_clk, speed); + writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr); /* start controller */ + + return 0; } unsigned int i2c_get_bus_num(void) @@ -289,7 +384,8 @@ unsigned int i2c_get_bus_num(void) unsigned int i2c_get_bus_speed(void) { - return 0; + return i2c_bus_speed[i2c_bus_num]; } + #endif /* CONFIG_HARD_I2C */ #endif /* CONFIG_FSL_I2C */ diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 439c950cf..f04c72d05 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -1179,6 +1179,27 @@ void flash_print_info (flash_info_t * info) return; } +/*----------------------------------------------------------------------- + * This is used in a few places in write_buf() to show programming + * progress. Making it a function is nasty because it needs to do side + * effect updates to digit and dots. Repeated code is nasty too, so + * we define it once here. + */ +#ifdef CONFIG_FLASH_SHOW_PROGRESS +#define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub) \ + dots -= dots_sub; \ + if ((scale > 0) && (dots <= 0)) { \ + if ((digit % 5) == 0) \ + printf ("%d", digit / 5); \ + else \ + putc ('.'); \ + digit--; \ + dots += scale; \ + } +#else +#define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub) +#endif + /*----------------------------------------------------------------------- * Copy memory to flash, returns: * 0 - OK @@ -1192,10 +1213,23 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) int aln; cfiword_t cword; int i, rc; - #ifdef CFG_FLASH_USE_BUFFER_WRITE int buffered_size; #endif +#ifdef CONFIG_FLASH_SHOW_PROGRESS + int digit = CONFIG_FLASH_SHOW_PROGRESS; + int scale = 0; + int dots = 0; + + /* + * Suppress if there are fewer than CONFIG_FLASH_SHOW_PROGRESS writes. + */ + if (cnt >= CONFIG_FLASH_SHOW_PROGRESS) { + scale = (int)((cnt + CONFIG_FLASH_SHOW_PROGRESS - 1) / + CONFIG_FLASH_SHOW_PROGRESS); + } +#endif + /* get lower aligned address */ wp = (addr & ~(info->portwidth - 1)); @@ -1219,6 +1253,7 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) return rc; wp += i; + FLASH_SHOW_PROGRESS(scale, dots, digit, i); } /* handle the aligned part */ @@ -1248,6 +1283,7 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) wp += i; src += i; cnt -= i; + FLASH_SHOW_PROGRESS(scale, dots, digit, i); } #else while (cnt >= info->portwidth) { @@ -1259,8 +1295,10 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) return rc; wp += info->portwidth; cnt -= info->portwidth; + FLASH_SHOW_PROGRESS(scale, dots, digit, info->portwidth); } #endif /* CFG_FLASH_USE_BUFFER_WRITE */ + if (cnt == 0) { return (0); } diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index d4003a20f..3b828fb62 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -1180,6 +1180,12 @@ static int onenand_probe(struct mtd_info *mtd) if (maf_id != bram_maf_id || dev_id != bram_dev_id) return -ENXIO; + /* FIXME : Current OneNAND MTD doesn't support Flex-OneNAND */ + if (dev_id & (1 << 9)) { + printk("Not yet support Flex-OneNAND\n"); + return -ENXIO; + } + /* Flash device information */ onenand_print_device_info(dev_id, 0); this->device_id = dev_id; diff --git a/drivers/net/Makefile b/drivers/net/Makefile index b9723fa78..320dc3eba 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -27,6 +27,7 @@ LIB := $(obj)libnet.a COBJS-y += 3c589.o COBJS-y += bcm570x.o bcm570x_autoneg.o 5701rls.o +COBJS-$(CONFIG_BFIN_MAC) += bfin_mac.o COBJS-y += cs8900.o COBJS-y += dc2114x.o COBJS-y += dm9000x.o @@ -40,7 +41,7 @@ COBJS-y += lan91c96.o COBJS-y += macb.o COBJS-y += mcffec.o COBJS-y += natsemi.o -COBJS-y += ne2000.o +COBJS-$(CONFIG_DRIVER_NE2000) += ne2000.o COBJS-y += netarm_eth.o COBJS-y += netconsole.o COBJS-y += ns7520_eth.o @@ -57,6 +58,7 @@ COBJS-y += tigon3.o COBJS-y += tsec.o COBJS-y += tsi108_eth.o COBJS-y += uli526x.o +COBJS-y += vsc7385.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/net/ax88796.h b/drivers/net/ax88796.h new file mode 100644 index 000000000..069ae80fa --- /dev/null +++ b/drivers/net/ax88796.h @@ -0,0 +1,217 @@ +/* + * AX88796L(NE2000) support + * + * (c) 2007 Nobuhiro Iwamatsu + * + * 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 __DRIVERS_AX88796L_H__ +#define __DRIVERS_AX88796L_H__ + +#define DP_DATA (0x10 << 1) +#define START_PG 0x40 /* First page of TX buffer */ +#define START_PG2 0x48 +#define STOP_PG 0x80 /* Last page +1 of RX ring */ +#define TX_PAGES 12 +#define RX_START (START_PG+TX_PAGES) +#define RX_END STOP_PG + +#define AX88796L_BASE_ADDRESS CONFIG_DRIVER_NE2000_BASE +#define AX88796L_BYTE_ACCESS 0x00001000 +#define AX88796L_OFFSET 0x00000400 +#define AX88796L_ADDRESS_BYTE AX88796L_BASE_ADDRESS + \ + AX88796L_BYTE_ACCESS + AX88796L_OFFSET +#define AX88796L_REG_MEMR AX88796L_ADDRESS_BYTE + (0x14<<1) +#define AX88796L_REG_CR AX88796L_ADDRESS_BYTE + (0x00<<1) + +#define AX88796L_CR (*(vu_short *)(AX88796L_REG_CR)) +#define AX88796L_MEMR (*(vu_short *)(AX88796L_REG_MEMR)) + +#define EECS_HIGH (AX88796L_MEMR |= 0x10) +#define EECS_LOW (AX88796L_MEMR &= 0xef) +#define EECLK_HIGH (AX88796L_MEMR |= 0x80) +#define EECLK_LOW (AX88796L_MEMR &= 0x7f) +#define EEDI_HIGH (AX88796L_MEMR |= 0x20) +#define EEDI_LOW (AX88796L_MEMR &= 0xdf) +#define EEDO ((AX88796L_MEMR & 0x40)>>6) + +#define PAGE0_SET (AX88796L_CR &= 0x3f) +#define PAGE1_SET (AX88796L_CR = (AX88796L_CR & 0x3f) | 0x40) + +#define BIT_DUMMY 0 +#define MAC_EEP_READ 1 +#define MAC_EEP_WRITE 2 +#define MAC_EEP_ERACE 3 +#define MAC_EEP_EWEN 4 +#define MAC_EEP_EWDS 5 + +/* R7780MP Specific code */ +#if defined(CONFIG_R7780MP) +#define ISA_OFFSET 0x1400 +#define DP_IN(_b_, _o_, _d_) (_d_) = \ + *( (vu_short *) ((_b_) + ((_o_) * 2) + ISA_OFFSET)) +#define DP_OUT(_b_, _o_, _d_) \ + *((vu_short *)((_b_) + ((_o_) * 2) + ISA_OFFSET)) = (_d_) +#define DP_IN_DATA(_b_, _d_) (_d_) = *( (vu_short *) ((_b_) + ISA_OFFSET)) +#define DP_OUT_DATA(_b_, _d_) *( (vu_short *) ((_b_)+ISA_OFFSET)) = (_d_) +#else +/* Please change for your target boards */ +#define ISA_OFFSET 0x0000 +#define DP_IN(_b_, _o_, _d_) (_d_) = *( (vu_short *)((_b_)+(_o_ )+ISA_OFFSET)) +#define DP_OUT(_b_, _o_, _d_) *((vu_short *)((_b_)+(_o_)+ISA_OFFSET)) = (_d_) +#define DP_IN_DATA(_b_, _d_) (_d_) = *( (vu_short *) ((_b_)+ISA_OFFSET)) +#define DP_OUT_DATA(_b_, _d_) *( (vu_short *) ((_b_)+ISA_OFFSET)) = (_d_) +#endif + + +/* + * Set 1 bit data + */ +static void ax88796_bitset(u32 bit) +{ + /* DATA1 */ + if( bit ) + EEDI_HIGH; + else + EEDI_LOW; + + EECLK_LOW; + udelay(1000); + EECLK_HIGH; + udelay(1000); + EEDI_LOW; +} + +/* + * Get 1 bit data + */ +static u8 ax88796_bitget(void) +{ + u8 bit; + + EECLK_LOW; + udelay(1000); + /* DATA */ + bit = EEDO; + EECLK_HIGH; + udelay(1000); + + return bit; +} + +/* + * Send COMMAND to EEPROM + */ +static void ax88796_eep_cmd(u8 cmd) +{ + ax88796_bitset(BIT_DUMMY); + switch(cmd){ + case MAC_EEP_READ: + ax88796_bitset(1); + ax88796_bitset(1); + ax88796_bitset(0); + break; + + case MAC_EEP_WRITE: + ax88796_bitset(1); + ax88796_bitset(0); + ax88796_bitset(1); + break; + + case MAC_EEP_ERACE: + ax88796_bitset(1); + ax88796_bitset(1); + ax88796_bitset(1); + break; + + case MAC_EEP_EWEN: + ax88796_bitset(1); + ax88796_bitset(0); + ax88796_bitset(0); + break; + + case MAC_EEP_EWDS: + ax88796_bitset(1); + ax88796_bitset(0); + ax88796_bitset(0); + break; + default: + break; + } +} + +static void ax88796_eep_setaddr(u16 addr) +{ + int i ; + for( i = 7 ; i >= 0 ; i-- ) + ax88796_bitset(addr & (1 << i)); +} + +/* + * Get data from EEPROM + */ +static u16 ax88796_eep_getdata(void) +{ + ushort data = 0; + int i; + + ax88796_bitget(); /* DUMMY */ + for( i = 0 ; i < 16 ; i++ ){ + data <<= 1; + data |= ax88796_bitget(); + } + return data; +} + +static void ax88796_mac_read(u8 *buff) +{ + int i ; + u16 data, addr = 0; + + for( i = 0 ; i < 3; i++ ) + { + EECS_HIGH; + EEDI_LOW; + udelay(1000); + /* READ COMMAND */ + ax88796_eep_cmd(MAC_EEP_READ); + /* ADDRESS */ + ax88796_eep_setaddr(addr++); + /* GET DATA */ + data = ax88796_eep_getdata(); + *buff++ = (uchar)(data & 0xff); + *buff++ = (uchar)((data >> 8) & 0xff); + EECLK_LOW; + EEDI_LOW; + EECS_LOW; + } +} + +int get_prom(u8* mac_addr) +{ + u8 prom[32]; + int i; + + ax88796_mac_read(prom); + for (i = 0; i < 6; i++){ + mac_addr[i] = prom[i]; + } + return 1; +} + +#endif /* __DRIVERS_AX88796L_H__ */ diff --git a/board/bf537-stamp/ether_bf537.c b/drivers/net/bfin_mac.c similarity index 77% rename from board/bf537-stamp/ether_bf537.c rename to drivers/net/bfin_mac.c index 6c514c660..afe122a33 100644 --- a/board/bf537-stamp/ether_bf537.c +++ b/drivers/net/bfin_mac.c @@ -1,39 +1,24 @@ /* - * ADI Blackfin 537 MAC Ethernet + * Driver for Blackfin On-Chip MAC device * - * Copyright (c) 2005 Analog Device, Inc. + * Copyright (c) 2005-2008 Analog Device, 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 + * Licensed under the GPL-2 or later. */ #include #include -#include #include #include #include -#include "ether_bf537.h" +#include #include #include #include +#include "bfin_mac.h" + #ifdef CONFIG_POST #include #endif @@ -41,66 +26,50 @@ #undef DEBUG_ETHERNET #ifdef DEBUG_ETHERNET -#define DEBUGF(fmt,args...) printf(fmt,##args) +#define DEBUGF(fmt, args...) printf(fmt, ##args) #else -#define DEBUGF(fmt,args...) +#define DEBUGF(fmt, args...) #endif -#if defined(CONFIG_CMD_NET) - #define RXBUF_BASE_ADDR 0xFF900000 #define TXBUF_BASE_ADDR 0xFF800000 #define TX_BUF_CNT 1 -#define TOUT_LOOP 1000000 +#define TOUT_LOOP 1000000 ADI_ETHER_BUFFER *txbuf[TX_BUF_CNT]; ADI_ETHER_BUFFER *rxbuf[PKTBUFSRX]; static u16 txIdx; /* index of the current RX buffer */ static u16 rxIdx; /* index of the current TX buffer */ -u8 SrcAddr[6]; u16 PHYregs[NO_PHY_REGS]; /* u16 PHYADDR; */ /* DMAx_CONFIG values at DMA Restart */ -const ADI_DMA_CONFIG_REG rxdmacfg = { 1, 1, 2, 0, 0, 0, 0, 5, 7 }; +const ADI_DMA_CONFIG_REG rxdmacfg = { + .b_DMA_EN = 1, /* enabled */ + .b_WNR = 1, /* write to memory */ + .b_WDSIZE = 2, /* wordsize is 32 bits */ + .b_DMA2D = 0, + .b_RESTART = 0, + .b_DI_SEL = 0, + .b_DI_EN = 0, /* no interrupt */ + .b_NDSIZE = 5, /* 5 half words is desc size */ + .b_FLOW = 7 /* large desc flow */ +}; -#if 0 - rxdmacfg.b_DMA_EN = 1; /* enabled */ - rxdmacfg.b_WNR = 1; /* write to memory */ - rxdmacfg.b_WDSIZE = 2; /* wordsize is 32 bits */ - rxdmacfg.b_DMA2D = 0; /* N/A */ - rxdmacfg.b_RESTART= 0; /* N/A */ - rxdmacfg.b_DI_SEL = 0; /* N/A */ - rxdmacfg.b_DI_EN = 0; /* no interrupt */ - rxdmacfg.b_NDSIZE = 5; /* 5 half words is desc size. */ - rxdmacfg.b_FLOW = 7; /* large desc flow */ -#endif +const ADI_DMA_CONFIG_REG txdmacfg = { + .b_DMA_EN = 1, /* enabled */ + .b_WNR = 0, /* read from memory */ + .b_WDSIZE = 2, /* wordsize is 32 bits */ + .b_DMA2D = 0, + .b_RESTART = 0, + .b_DI_SEL = 0, + .b_DI_EN = 0, /* no interrupt */ + .b_NDSIZE = 5, /* 5 half words is desc size */ + .b_FLOW = 7 /* large desc flow */ +}; -const ADI_DMA_CONFIG_REG txdmacfg = { 1, 0, 2, 0, 0, 0, 0, 5, 7 }; - -#if 0 - txdmacfg.b_DMA_EN = 1; /* enabled */ - txdmacfg.b_WNR = 0; /* read from memory */ - txdmacfg.b_WDSIZE = 2; /* wordsize is 32 bits */ - txdmacfg.b_DMA2D = 0; /* N/A */ - txdmacfg.b_RESTART= 0; /* N/A */ - txdmacfg.b_DI_SEL = 0; /* N/A */ - txdmacfg.b_DI_EN = 0; /* no interrupt */ - txdmacfg.b_NDSIZE = 5; /* 5 half words is desc size. */ - txdmacfg.b_FLOW = 7; /* large desc flow */ -#endif - -ADI_ETHER_BUFFER *SetupRxBuffer(int no); -ADI_ETHER_BUFFER *SetupTxBuffer(int no); - -static int bfin_EMAC_init(struct eth_device *dev, bd_t * bd); -static void bfin_EMAC_halt(struct eth_device *dev); -static int bfin_EMAC_send(struct eth_device *dev, volatile void *packet, - int length); -static int bfin_EMAC_recv(struct eth_device *dev); - -int bfin_EMAC_initialize(bd_t * bis) +int bfin_EMAC_initialize(bd_t *bis) { struct eth_device *dev; dev = (struct eth_device *)malloc(sizeof(*dev)); @@ -108,7 +77,7 @@ int bfin_EMAC_initialize(bd_t * bis) hang(); memset(dev, 0, sizeof(*dev)); - sprintf(dev->name, "BF537 ETHERNET"); + sprintf(dev->name, "Blackfin EMAC"); dev->iobase = 0; dev->priv = 0; @@ -165,7 +134,7 @@ static int bfin_EMAC_send(struct eth_device *dev, volatile void *packet, txIdx = 0; else txIdx++; - out: + out: DEBUGF("BFIN EMAC send: length = %d\n", length); return result; } @@ -212,7 +181,7 @@ static int bfin_EMAC_recv(struct eth_device *dev) * *************************************************************/ -static int bfin_EMAC_init(struct eth_device *dev, bd_t * bd) +static int bfin_EMAC_init(struct eth_device *dev, bd_t *bd) { u32 opmode; int dat; @@ -227,7 +196,7 @@ static int bfin_EMAC_init(struct eth_device *dev, bd_t * bd) return -1; /* Initialize EMAC address */ - SetupMacAddr(SrcAddr); + bfin_EMAC_setup_addr(bd); /* Initialize TX and RX buffer */ for (i = 0; i < PKTBUFSRX; i++) { @@ -289,37 +258,25 @@ static void bfin_EMAC_halt(struct eth_device *dev) } -void SetupMacAddr(u8 * MACaddr) +void bfin_EMAC_setup_addr(bd_t *bd) { - char *tmp, *end; - int i; - /* this depends on a little-endian machine */ - tmp = getenv("ethaddr"); - if (tmp) { - for (i = 0; i < 6; i++) { - MACaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0; - if (tmp) - tmp = (*end) ? end + 1 : end; - } - -#ifndef CONFIG_NETCONSOLE - printf("Using MAC Address %02X:%02X:%02X:%02X:%02X:%02X\n", - MACaddr[0], MACaddr[1], - MACaddr[2], MACaddr[3], MACaddr[4], MACaddr[5]); -#endif - *pEMAC_ADDRLO = MACaddr[0] | MACaddr[1] << 8 | - MACaddr[2] << 16 | MACaddr[3] << 24; - *pEMAC_ADDRHI = MACaddr[4] | MACaddr[5] << 8; - } + *pEMAC_ADDRLO = + bd->bi_enetaddr[0] | + bd->bi_enetaddr[1] << 8 | + bd->bi_enetaddr[2] << 16 | + bd->bi_enetaddr[3] << 24; + *pEMAC_ADDRHI = + bd->bi_enetaddr[4] | + bd->bi_enetaddr[5] << 8; } -void PollMdcDone(void) +static void PollMdcDone(void) { /* poll the STABUSY bit */ while (*pEMAC_STAADD & STABUSY) ; } -void WrPHYReg(u16 PHYAddr, u16 RegAddr, u16 Data) +static void WrPHYReg(u16 PHYAddr, u16 RegAddr, u16 Data) { PollMdcDone(); @@ -332,7 +289,7 @@ void WrPHYReg(u16 PHYAddr, u16 RegAddr, u16 Data) /********************************************************************************* * Read an off-chip register in a PHY through the MDC/MDIO port * *********************************************************************************/ -u16 RdPHYReg(u16 PHYAddr, u16 RegAddr) +static u16 RdPHYReg(u16 PHYAddr, u16 RegAddr) { u16 Data; @@ -350,7 +307,8 @@ u16 RdPHYReg(u16 PHYAddr, u16 RegAddr) return Data; } -void SoftResetPHY(void) +#if 0 /* dead code ? */ +static void SoftResetPHY(void) { u16 phydat; /* set the reset bit */ @@ -362,13 +320,30 @@ void SoftResetPHY(void) phydat = RdPHYReg(PHYADDR, PHY_MODECTL); } while ((phydat & PHY_RESET) != 0); } +#endif -int SetupSystemRegs(int *opmode) +static int SetupSystemRegs(int *opmode) { u16 sysctl, phydat; int count = 0; /* Enable PHY output */ *pVR_CTL |= CLKBUFOE; + /* Set all the pins to peripheral mode */ + +#ifndef CONFIG_BFIN_MAC_RMII + *pPORTH_FER = 0xFFFF; +#ifdef __ADSPBF52x__ + *pPORTH_MUX = PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2 | PORT_x_MUX_2_FUNC_2; +#endif +#else +#if defined(__ADSPBF536__) || defined(__ADSPBF537__) + *pPORTH_FER = 0xC373; +#endif +#ifdef __ADSPBF52x__ + *pPORTH_FER = 0x01FF; + *pPORTH_MUX = PORT_x_MUX_0_FUNC_2 | PORT_x_MUX_1_FUNC_2; +#endif +#endif /* MDC = 2.5 MHz */ sysctl = SET_MDCDIV(24); /* Odd word alignment for Receive Frame DMA word */ @@ -546,4 +521,3 @@ int ether_post_test(int flags) return 0; } #endif -#endif diff --git a/board/bf537-stamp/ether_bf537.h b/drivers/net/bfin_mac.h similarity index 70% rename from board/bf537-stamp/ether_bf537.h rename to drivers/net/bfin_mac.h index 22fc392dd..c8a94d0c9 100644 --- a/board/bf537-stamp/ether_bf537.h +++ b/drivers/net/bfin_mac.h @@ -1,3 +1,14 @@ +/* + * bfin_mac.h - some defines/structures for the Blackfin on-chip MAC. + * + * Copyright (c) 2005-2008 Analog Device, Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __BFIN_MAC_H__ +#define __BFIN_MAC_H__ + #define PHYADDR 0x01 #define NO_PHY_REGS 0x20 @@ -60,12 +71,19 @@ typedef struct adi_ether_buffer { } ADI_ETHER_BUFFER; /* 40 bytes/struct in 44 bytes */ -void SetupMacAddr(u8 * MACaddr); +static ADI_ETHER_BUFFER *SetupRxBuffer(int no); +static ADI_ETHER_BUFFER *SetupTxBuffer(int no); -void PollMdcDone(void); -void WrPHYReg(u16 PHYAddr, u16 RegAddr, u16 Data); -u16 RdPHYReg(u16 PHYAddr, u16 RegAddr); -void SoftResetPHY(void); -void DumpPHYRegs(void); +static int bfin_EMAC_init(struct eth_device *dev, bd_t *bd); +static void bfin_EMAC_halt(struct eth_device *dev); +static int bfin_EMAC_send(struct eth_device *dev, volatile void *packet, int length); +static int bfin_EMAC_recv(struct eth_device *dev); -int SetupSystemRegs(int *opmode); +static void PollMdcDone(void); +static void WrPHYReg(u16 PHYAddr, u16 RegAddr, u16 Data); +static u16 RdPHYReg(u16 PHYAddr, u16 RegAddr); +static int SetupSystemRegs(int *opmode); + +static void bfin_EMAC_setup_addr(bd_t *bd); + +#endif diff --git a/drivers/net/ne2000.c b/drivers/net/ne2000.c index b10065753..99baeea3e 100644 --- a/drivers/net/ne2000.c +++ b/drivers/net/ne2000.c @@ -5,7 +5,6 @@ Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world are GPL, so this is, of course, GPL. - ========================================================================== dev/if_dp83902a.c @@ -70,9 +69,7 @@ Add SNMP ####DESCRIPTIONEND#### - ========================================================================== - */ #include @@ -80,27 +77,11 @@ Add SNMP #include #include -#ifdef CONFIG_DRIVER_NE2000 - -/* wor around udelay resetting OCR */ -static void my_udelay(long us) { - long tmo; - - tmo = get_timer (0) + us * CFG_HZ / 1000000; /* will this be much greater than 0 ? */ - while (get_timer (0) < tmo); -} - -#define mdelay(n) my_udelay((n)*1000) - +#define mdelay(n) udelay((n)*1000) /* forward definition of function used for the uboot interface */ void uboot_push_packet_len(int len); void uboot_push_tx_done(int key, int val); -/* timeout for tx/rx in s */ -#define TOUT 5 - -#define ETHER_ADDR_LEN 6 - /* ------------------------------------------------------------------------ Debugging details @@ -118,17 +99,22 @@ void uboot_push_tx_done(int key, int val); #if DEBUG & 1 #define DEBUG_FUNCTION() do { printf("%s\n", __FUNCTION__); } while (0) #define DEBUG_LINE() do { printf("%d\n", __LINE__); } while (0) +#define PRINTK(args...) printf(args) #else #define DEBUG_FUNCTION() do {} while(0) #define DEBUG_LINE() do {} while(0) +#define PRINTK(args...) #endif -#include "ne2000.h" +/* NE2000 base header file */ +#include "ne2000_base.h" -#if DEBUG & 1 -#define PRINTK(args...) printf(args) +#if defined(CONFIG_DRIVER_AX88796L) +/* AX88796L support */ +#include "ax88796.h" #else -#define PRINTK(args...) +/* Basic NE2000 chip support */ +#include "ne2000.h" #endif static dp83902a_priv_data_t nic; /* just one instance of the card supported */ @@ -137,8 +123,7 @@ static bool dp83902a_init(void) { dp83902a_priv_data_t *dp = &nic; - cyg_uint8* base; - int i; + u8* base; DEBUG_FUNCTION(); @@ -147,6 +132,8 @@ dp83902a_init(void) DEBUG_LINE(); +#if defined(NE2000_BASIC_INIT) + /* AX88796L doesn't need */ /* Prepare ESA */ DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1); /* Select page 1 */ /* Use the address from the serial EEPROM */ @@ -163,6 +150,7 @@ dp83902a_init(void) dp->esa[4], dp->esa[5] ); +#endif /* NE2000_BASIC_INIT */ return true; } @@ -170,7 +158,7 @@ static void dp83902a_stop(void) { dp83902a_priv_data_t *dp = &nic; - cyg_uint8 *base = dp->base; + u8 *base = dp->base; DEBUG_FUNCTION(); @@ -188,10 +176,10 @@ dp83902a_stop(void) the hardware ready to send/receive packets. */ static void -dp83902a_start(unsigned char * enaddr) +dp83902a_start(u8 * enaddr) { dp83902a_priv_data_t *dp = &nic; - cyg_uint8 *base = dp->base; + u8 *base = dp->base; int i; DEBUG_FUNCTION(); @@ -206,15 +194,21 @@ dp83902a_start(unsigned char * enaddr) dp->tx1 = dp->tx2 = 0; dp->tx_next = dp->tx_buf1; dp->tx_started = false; + dp->running = true; DP_OUT(base, DP_PSTART, dp->rx_buf_start); /* Receive ring start page */ DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1); /* Receive ring boundary */ DP_OUT(base, DP_PSTOP, dp->rx_buf_end); /* Receive ring end page */ dp->rx_next = dp->rx_buf_start-1; + dp->running = true; DP_OUT(base, DP_ISR, 0xFF); /* Clear any pending interrupts */ DP_OUT(base, DP_IMR, DP_IMR_All); /* Enable all interrupts */ DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1 | DP_CR_STOP); /* Select page 1 */ DP_OUT(base, DP_P1_CURP, dp->rx_buf_start); /* Current page - next free page for Rx */ + dp->running = true; for (i = 0; i < ETHER_ADDR_LEN; i++) { + /* FIXME */ + /*((vu_short*)( base + ((DP_P1_PAR0 + i) * 2) + + * 0x1400)) = enaddr[i];*/ DP_OUT(base, DP_P1_PAR0+i, enaddr[i]); } /* Enable and start device */ @@ -234,7 +228,7 @@ static void dp83902a_start_xmit(int start_page, int len) { dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *) &nic; - cyg_uint8 *base = dp->base; + u8 *base = dp->base; DEBUG_FUNCTION(); @@ -259,10 +253,10 @@ dp83902a_start_xmit(int start_page, int len) that there is free buffer space (dp->tx_next). */ static void -dp83902a_send(unsigned char *data, int total_len, unsigned long key) +dp83902a_send(u8 *data, int total_len, u32 key) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; - cyg_uint8 *base = dp->base; + u8 *base = dp->base; int len, start_page, pkt_len, i, isr; #if DEBUG & 4 int dx; @@ -296,7 +290,7 @@ dp83902a_send(unsigned char *data, int total_len, unsigned long key) /* but the code is extended a bit to do what Hitachi's monitor */ /* does (i.e., also read data). */ - cyg_uint16 tmp; + u16 tmp; int len = 1; DP_OUT(base, DP_RSAL, 0x100-len); @@ -322,7 +316,7 @@ dp83902a_send(unsigned char *data, int total_len, unsigned long key) /* Put data into buffer */ #if DEBUG & 4 - printf(" sg buf %08lx len %08x\n ", (unsigned long) data, len); + printf(" sg buf %08lx len %08x\n ", (u32)data, len); dx = 0; #endif while (len > 0) { @@ -330,6 +324,7 @@ dp83902a_send(unsigned char *data, int total_len, unsigned long key) printf(" %02x", *data); if (0 == (++dx % 16)) printf("\n "); #endif + DP_OUT_DATA(dp->data, *data++); len--; } @@ -358,6 +353,7 @@ dp83902a_send(unsigned char *data, int total_len, unsigned long key) do { DP_IN(base, DP_ISR, isr); } while ((isr & DP_ISR_RDC) == 0); + /* Then disable DMA */ DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); @@ -383,9 +379,9 @@ static void dp83902a_RxEvent(void) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; - cyg_uint8 *base = dp->base; - unsigned char rsr; - unsigned char rcv_hdr[4]; + u8 *base = dp->base; + u8 rsr; + u8 rcv_hdr[4]; int i, len, pkt, cur; DEBUG_FUNCTION(); @@ -423,6 +419,7 @@ dp83902a_RxEvent(void) CYGACC_CALL_IF_DELAY_US(10); #endif + /* read header (get data size)*/ for (i = 0; i < sizeof(rcv_hdr);) { DP_IN_DATA(dp->data, rcv_hdr[i++]); } @@ -432,7 +429,10 @@ dp83902a_RxEvent(void) rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]); #endif len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr); + + /* data read */ uboot_push_packet_len(len); + if (rcv_hdr[1] == dp->rx_buf_start) DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1); else @@ -448,12 +448,12 @@ dp83902a_RxEvent(void) efficient processing in the upper layers of the stack. */ static void -dp83902a_recv(unsigned char *data, int len) +dp83902a_recv(u8 *data, int len) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; - cyg_uint8 *base = dp->base; + u8 *base = dp->base; int i, mlen; - cyg_uint8 saved_char = 0; + u8 saved_char = 0; bool saved; #if DEBUG & 4 int dx; @@ -482,7 +482,7 @@ dp83902a_recv(unsigned char *data, int len) if (data) { mlen = len; #if DEBUG & 4 - printf(" sg buf %08lx len %08x \n", (unsigned long) data, mlen); + printf(" sg buf %08lx len %08x \n", (u32) data, mlen); dx = 0; #endif while (0 < mlen) { @@ -495,7 +495,7 @@ dp83902a_recv(unsigned char *data, int len) } { - cyg_uint8 tmp; + u8 tmp; DP_IN_DATA(dp->data, tmp); #if DEBUG & 4 printf(" %02x", tmp); @@ -516,9 +516,9 @@ static void dp83902a_TxEvent(void) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; - cyg_uint8 *base = dp->base; - unsigned char tsr; - unsigned long key; + u8 *base = dp->base; + u8 tsr; + u32 key; DEBUG_FUNCTION(); @@ -551,8 +551,8 @@ static void dp83902a_ClearCounters(void) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; - cyg_uint8 *base = dp->base; - cyg_uint8 cnt1, cnt2, cnt3; + u8 *base = dp->base; + u8 cnt1, cnt2, cnt3; DP_IN(base, DP_FER, cnt1); DP_IN(base, DP_CER, cnt2); @@ -566,8 +566,8 @@ static void dp83902a_Overflow(void) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)&nic; - cyg_uint8 *base = dp->base; - cyg_uint8 isr; + u8 *base = dp->base; + u8 isr; /* Issue a stop command and wait 1.6ms for it to complete. */ DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA); @@ -603,8 +603,8 @@ static void dp83902a_poll(void) { struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; - cyg_uint8 *base = dp->base; - unsigned char isr; + u8 *base = dp->base; + u8 isr; DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0 | DP_CR_START); DP_IN(base, DP_ISR, isr); @@ -642,13 +642,13 @@ dp83902a_poll(void) /* find prom (taken from pc_net_cs.c from Linux) */ #include "8390.h" - +/* typedef struct hw_info_t { u_int offset; u_char a0, a1, a2; u_int flags; } hw_info_t; - +*/ #define DELAY_OUTPUT 0x01 #define HAS_MISC_REG 0x02 #define USE_BIG_BUF 0x04 @@ -731,102 +731,17 @@ static hw_info_t hw_info[] = { static hw_info_t default_info = { 0, 0, 0, 0, 0 }; -unsigned char dev_addr[6]; +u8 dev_addr[6]; #define PCNET_CMD 0x00 #define PCNET_DATAPORT 0x10 /* NatSemi-defined port window offset. */ #define PCNET_RESET 0x1f /* Issue a read to reset, a write to clear. */ #define PCNET_MISC 0x18 /* For IBM CCAE and Socket EA cards */ -unsigned long nic_base; - -static void pcnet_reset_8390(void) -{ - int i, r; - - PRINTK("nic base is %lx\n", nic_base); - - n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD); - PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD)); - n2k_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, E8390_CMD); - PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD)); - n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD); - PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD)); - n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD); - - n2k_outb(n2k_inb(PCNET_RESET), PCNET_RESET); - - for (i = 0; i < 100; i++) { - if ((r = (n2k_inb(EN0_ISR) & ENISR_RESET)) != 0) - break; - PRINTK("got %x in reset\n", r); - my_udelay(100); - } - n2k_outb(ENISR_RESET, EN0_ISR); /* Ack intr. */ - - if (i == 100) - printf("pcnet_reset_8390() did not complete.\n"); -} /* pcnet_reset_8390 */ - -static hw_info_t * get_prom(void ) { - unsigned char prom[32]; - int i, j; - struct { - u_char value, offset; - } program_seq[] = { - {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ - {0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */ - {0x00, EN0_RCNTLO}, /* Clear the count regs. */ - {0x00, EN0_RCNTHI}, - {0x00, EN0_IMR}, /* Mask completion irq. */ - {0xFF, EN0_ISR}, - {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ - {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ - {32, EN0_RCNTLO}, - {0x00, EN0_RCNTHI}, - {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ - {0x00, EN0_RSARHI}, - {E8390_RREAD+E8390_START, E8390_CMD}, - }; - - PRINTK("trying to get MAC via prom reading\n"); - - pcnet_reset_8390(); - - mdelay(10); - - for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) - n2k_outb(program_seq[i].value, program_seq[i].offset); - - PRINTK("PROM:"); - for (i = 0; i < 32; i++) { - prom[i] = n2k_inb(PCNET_DATAPORT); - PRINTK(" %02x", prom[i]); - } - PRINTK("\n"); - for (i = 0; i < NR_INFO; i++) { - if ((prom[0] == hw_info[i].a0) && - (prom[2] == hw_info[i].a1) && - (prom[4] == hw_info[i].a2)) { - PRINTK("matched board %d\n", i); - break; - } - } - if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) { - for (j = 0; j < 6; j++) - dev_addr[j] = prom[j<<1]; - PRINTK("on exit i is %d/%ld\n", i, NR_INFO); - PRINTK("MAC address is %02x:%02x:%02x:%02x:%02x:%02x\n", - dev_addr[0],dev_addr[1],dev_addr[2],dev_addr[3],dev_addr[4],dev_addr[5]); - return (i < NR_INFO) ? hw_info+i : &default_info; - } - return NULL; -} +u32 nic_base; /* U-boot specific routines */ - - -static unsigned char *pbuf = NULL; +static u8 *pbuf = NULL; static int pkey = -1; static int initialized=0; @@ -839,7 +754,7 @@ void uboot_push_packet_len(int len) { } dp83902a_recv(&pbuf[0], len); - /* Just pass it to the upper layer */ + /*Just pass it to the upper layer*/ NetReceive(&pbuf[0], len); } @@ -864,7 +779,7 @@ int eth_init(bd_t *bd) { #ifdef CONFIG_DRIVER_NE2000_CCR { - volatile unsigned char *p = (volatile unsigned char *) CONFIG_DRIVER_NE2000_CCR; + vu_char *p = (vu_char *) CONFIG_DRIVER_NE2000_CCR; PRINTK("CCR before is %x\n", *p); *p = CONFIG_DRIVER_NE2000_VAL; @@ -873,9 +788,9 @@ int eth_init(bd_t *bd) { #endif nic_base = CONFIG_DRIVER_NE2000_BASE; - nic.base = (cyg_uint8 *) CONFIG_DRIVER_NE2000_BASE; + nic.base = (u8 *) CONFIG_DRIVER_NE2000_BASE; - r = get_prom(); + r = get_prom(dev_addr); if (!r) return -1; @@ -886,22 +801,23 @@ int eth_init(bd_t *bd) { PRINTK("Set environment from HW MAC addr = \"%s\"\n", ethaddr); setenv ("ethaddr", ethaddr); - -#define DP_DATA 0x10 nic.data = nic.base + DP_DATA; - nic.tx_buf1 = 0x40; - nic.tx_buf2 = 0x48; - nic.rx_buf_start = 0x50; - nic.rx_buf_end = 0x80; + nic.tx_buf1 = START_PG; + nic.tx_buf2 = START_PG2; + nic.rx_buf_start = RX_START; + nic.rx_buf_end = RX_END; if (dp83902a_init() == false) return -1; + dp83902a_start(dev_addr); initialized=1; + return 0; } void eth_halt() { + PRINTK("### eth_halt\n"); if(initialized) dp83902a_stop(); @@ -920,7 +836,7 @@ int eth_send(volatile void *packet, int length) { pkey = -1; - dp83902a_send((unsigned char *) packet, length, 666); + dp83902a_send((u8 *) packet, length, 666); tmo = get_timer (0) + TOUT * CFG_HZ; while(1) { dp83902a_poll(); @@ -936,4 +852,3 @@ int eth_send(volatile void *packet, int length) { } return 0; } -#endif diff --git a/drivers/net/ne2000.h b/drivers/net/ne2000.h index c13d9f0bb..d324a0008 100644 --- a/drivers/net/ne2000.h +++ b/drivers/net/ne2000.h @@ -5,7 +5,6 @@ Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world are GPL, so this is, of course, GPL. - ========================================================================== dev/dp83902a.h @@ -67,213 +66,114 @@ are GPL, so this is, of course, GPL. ####DESCRIPTIONEND#### ========================================================================== - */ /* - ------------------------------------------------------------------------ - Macros for accessing DP registers - These can be overridden by the platform header -*/ + * NE2000 support header file. + * Created by Nobuhiro Iwamatsu + */ -#define DP_IN(_b_, _o_, _d_) (_d_) = *( (volatile unsigned char *) ((_b_)+(_o_))) -#define DP_OUT(_b_, _o_, _d_) *( (volatile unsigned char *) ((_b_)+(_o_))) = (_d_) +#ifndef __DRIVERS_NE2000_H__ +#define __DRIVERS_NE2000_H__ -#define DP_IN_DATA(_b_, _d_) (_d_) = *( (volatile unsigned char *) ((_b_))) -#define DP_OUT_DATA(_b_, _d_) *( (volatile unsigned char *) ((_b_))) = (_d_) +/* Enable NE2000 basic init function */ +#define NE2000_BASIC_INIT +#define DP_DATA 0x10 +#define START_PG 0x50 /* First page of TX buffer */ +#define STOP_PG 0x80 /* Last page +1 of RX ring */ -/* here is all the data */ +#define RX_START 0x50 +#define RX_END 0x80 -#define cyg_uint8 unsigned char -#define cyg_uint16 unsigned short -#define bool int +#define DP_IN(_b_, _o_, _d_) (_d_) = *( (vu_char *) ((_b_)+(_o_))) +#define DP_OUT(_b_, _o_, _d_) *( (vu_char *) ((_b_)+(_o_))) = (_d_) +#define DP_IN_DATA(_b_, _d_) (_d_) = *( (vu_char *) ((_b_))) +#define DP_OUT_DATA(_b_, _d_) *( (vu_char *) ((_b_))) = (_d_) -#define false 0 -#define true 1 +static void pcnet_reset_8390(void) +{ + int i, r; -#define CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA 1 -#define CYGACC_CALL_IF_DELAY_US(X) my_udelay(X) + PRINTK("nic base is %lx\n", nic_base); -typedef struct dp83902a_priv_data { - cyg_uint8* base; - cyg_uint8* data; - cyg_uint8* reset; - int tx_next; /* First free Tx page */ - int tx_int; /* Expecting interrupt from this buffer */ - int rx_next; /* First free Rx page */ - int tx1, tx2; /* Page numbers for Tx buffers */ - unsigned long tx1_key, tx2_key; /* Used to ack when packet sent */ - int tx1_len, tx2_len; - bool tx_started, running, hardwired_esa; - cyg_uint8 esa[6]; - void* plf_priv; + n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD); + PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD)); + n2k_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, E8390_CMD); + PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD)); + n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD); + PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD)); + n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD); - /* Buffer allocation */ - int tx_buf1, tx_buf2; - int rx_buf_start, rx_buf_end; -} dp83902a_priv_data_t; + n2k_outb(n2k_inb(PCNET_RESET), PCNET_RESET); -/* - ------------------------------------------------------------------------ - Some forward declarations -*/ -static void dp83902a_poll(void); + for (i = 0; i < 100; i++) { + if ((r = (n2k_inb(EN0_ISR) & ENISR_RESET)) != 0) + break; + PRINTK("got %x in reset\n", r); + udelay(100); + } + n2k_outb(ENISR_RESET, EN0_ISR); /* Ack intr. */ -/* ------------------------------------------------------------------------ */ -/* Register offsets */ + if (i == 100) + printf("pcnet_reset_8390() did not complete.\n"); +} /* pcnet_reset_8390 */ -#define DP_CR 0x00 -#define DP_CLDA0 0x01 -#define DP_PSTART 0x01 /* write */ -#define DP_CLDA1 0x02 -#define DP_PSTOP 0x02 /* write */ -#define DP_BNDRY 0x03 -#define DP_TSR 0x04 -#define DP_TPSR 0x04 /* write */ -#define DP_NCR 0x05 -#define DP_TBCL 0x05 /* write */ -#define DP_FIFO 0x06 -#define DP_TBCH 0x06 /* write */ -#define DP_ISR 0x07 -#define DP_CRDA0 0x08 -#define DP_RSAL 0x08 /* write */ -#define DP_CRDA1 0x09 -#define DP_RSAH 0x09 /* write */ -#define DP_RBCL 0x0a /* write */ -#define DP_RBCH 0x0b /* write */ -#define DP_RSR 0x0c -#define DP_RCR 0x0c /* write */ -#define DP_FER 0x0d -#define DP_TCR 0x0d /* write */ -#define DP_CER 0x0e -#define DP_DCR 0x0e /* write */ -#define DP_MISSED 0x0f -#define DP_IMR 0x0f /* write */ -#define DP_DATAPORT 0x10 /* "eprom" data port */ +int get_prom(u8* mac_addr) +{ + u8 prom[32]; + int i, j; + struct { + u_char value, offset; + } program_seq[] = { + {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ + {0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */ + {0x00, EN0_RCNTLO}, /* Clear the count regs. */ + {0x00, EN0_RCNTHI}, + {0x00, EN0_IMR}, /* Mask completion irq. */ + {0xFF, EN0_ISR}, + {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ + {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ + {32, EN0_RCNTLO}, + {0x00, EN0_RCNTHI}, + {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ + {0x00, EN0_RSARHI}, + {E8390_RREAD+E8390_START, E8390_CMD}, + }; -#define DP_P1_CR 0x00 -#define DP_P1_PAR0 0x01 -#define DP_P1_PAR1 0x02 -#define DP_P1_PAR2 0x03 -#define DP_P1_PAR3 0x04 -#define DP_P1_PAR4 0x05 -#define DP_P1_PAR5 0x06 -#define DP_P1_CURP 0x07 -#define DP_P1_MAR0 0x08 -#define DP_P1_MAR1 0x09 -#define DP_P1_MAR2 0x0a -#define DP_P1_MAR3 0x0b -#define DP_P1_MAR4 0x0c -#define DP_P1_MAR5 0x0d -#define DP_P1_MAR6 0x0e -#define DP_P1_MAR7 0x0f + PRINTK ("trying to get MAC via prom reading\n"); -#define DP_P2_CR 0x00 -#define DP_P2_PSTART 0x01 -#define DP_P2_CLDA0 0x01 /* write */ -#define DP_P2_PSTOP 0x02 -#define DP_P2_CLDA1 0x02 /* write */ -#define DP_P2_RNPP 0x03 -#define DP_P2_TPSR 0x04 -#define DP_P2_LNPP 0x05 -#define DP_P2_ACH 0x06 -#define DP_P2_ACL 0x07 -#define DP_P2_RCR 0x0c -#define DP_P2_TCR 0x0d -#define DP_P2_DCR 0x0e -#define DP_P2_IMR 0x0f + pcnet_reset_8390 (); -/* Command register - common to all pages */ + mdelay (10); -#define DP_CR_STOP 0x01 /* Stop: software reset */ -#define DP_CR_START 0x02 /* Start: initialize device */ -#define DP_CR_TXPKT 0x04 /* Transmit packet */ -#define DP_CR_RDMA 0x08 /* Read DMA (recv data from device) */ -#define DP_CR_WDMA 0x10 /* Write DMA (send data to device) */ -#define DP_CR_SEND 0x18 /* Send packet */ -#define DP_CR_NODMA 0x20 /* Remote (or no) DMA */ -#define DP_CR_PAGE0 0x00 /* Page select */ -#define DP_CR_PAGE1 0x40 -#define DP_CR_PAGE2 0x80 -#define DP_CR_PAGEMSK 0x3F /* Used to mask out page bits */ + for (i = 0; i < sizeof (program_seq) / sizeof (program_seq[0]); i++) + n2k_outb (program_seq[i].value, program_seq[i].offset); -/* Data configuration register */ - -#define DP_DCR_WTS 0x01 /* 1=16 bit word transfers */ -#define DP_DCR_BOS 0x02 /* 1=Little Endian */ -#define DP_DCR_LAS 0x04 /* 1=Single 32 bit DMA mode */ -#define DP_DCR_LS 0x08 /* 1=normal mode, 0=loopback */ -#define DP_DCR_ARM 0x10 /* 0=no send command (program I/O) */ -#define DP_DCR_FIFO_1 0x00 /* FIFO threshold */ -#define DP_DCR_FIFO_2 0x20 -#define DP_DCR_FIFO_4 0x40 -#define DP_DCR_FIFO_6 0x60 - -#define DP_DCR_INIT (DP_DCR_LS|DP_DCR_FIFO_4) - -/* Interrupt status register */ - -#define DP_ISR_RxP 0x01 /* Packet received */ -#define DP_ISR_TxP 0x02 /* Packet transmitted */ -#define DP_ISR_RxE 0x04 /* Receive error */ -#define DP_ISR_TxE 0x08 /* Transmit error */ -#define DP_ISR_OFLW 0x10 /* Receive overflow */ -#define DP_ISR_CNT 0x20 /* Tally counters need emptying */ -#define DP_ISR_RDC 0x40 /* Remote DMA complete */ -#define DP_ISR_RESET 0x80 /* Device has reset (shutdown, error) */ - -/* Interrupt mask register */ - -#define DP_IMR_RxP 0x01 /* Packet received */ -#define DP_IMR_TxP 0x02 /* Packet transmitted */ -#define DP_IMR_RxE 0x04 /* Receive error */ -#define DP_IMR_TxE 0x08 /* Transmit error */ -#define DP_IMR_OFLW 0x10 /* Receive overflow */ -#define DP_IMR_CNT 0x20 /* Tall counters need emptying */ -#define DP_IMR_RDC 0x40 /* Remote DMA complete */ - -#define DP_IMR_All 0x3F /* Everything but remote DMA */ - -/* Receiver control register */ - -#define DP_RCR_SEP 0x01 /* Save bad(error) packets */ -#define DP_RCR_AR 0x02 /* Accept runt packets */ -#define DP_RCR_AB 0x04 /* Accept broadcast packets */ -#define DP_RCR_AM 0x08 /* Accept multicast packets */ -#define DP_RCR_PROM 0x10 /* Promiscuous mode */ -#define DP_RCR_MON 0x20 /* Monitor mode - 1=accept no packets */ - -/* Receiver status register */ - -#define DP_RSR_RxP 0x01 /* Packet received */ -#define DP_RSR_CRC 0x02 /* CRC error */ -#define DP_RSR_FRAME 0x04 /* Framing error */ -#define DP_RSR_FO 0x08 /* FIFO overrun */ -#define DP_RSR_MISS 0x10 /* Missed packet */ -#define DP_RSR_PHY 0x20 /* 0=pad match, 1=mad match */ -#define DP_RSR_DIS 0x40 /* Receiver disabled */ -#define DP_RSR_DFR 0x80 /* Receiver processing deferred */ - -/* Transmitter control register */ - -#define DP_TCR_NOCRC 0x01 /* 1=inhibit CRC */ -#define DP_TCR_NORMAL 0x00 /* Normal transmitter operation */ -#define DP_TCR_LOCAL 0x02 /* Internal NIC loopback */ -#define DP_TCR_INLOOP 0x04 /* Full internal loopback */ -#define DP_TCR_OUTLOOP 0x08 /* External loopback */ -#define DP_TCR_ATD 0x10 /* Auto transmit disable */ -#define DP_TCR_OFFSET 0x20 /* Collision offset adjust */ - -/* Transmit status register */ - -#define DP_TSR_TxP 0x01 /* Packet transmitted */ -#define DP_TSR_COL 0x04 /* Collision (at least one) */ -#define DP_TSR_ABT 0x08 /* Aborted because of too many collisions */ -#define DP_TSR_CRS 0x10 /* Lost carrier */ -#define DP_TSR_FU 0x20 /* FIFO underrun */ -#define DP_TSR_CDH 0x40 /* Collision Detect Heartbeat */ -#define DP_TSR_OWC 0x80 /* Collision outside normal window */ - -#define IEEE_8023_MAX_FRAME 1518 /* Largest possible ethernet frame */ -#define IEEE_8023_MIN_FRAME 64 /* Smallest possible ethernet frame */ + PRINTK ("PROM:"); + for (i = 0; i < 32; i++) { + prom[i] = n2k_inb (PCNET_DATAPORT); + PRINTK (" %02x", prom[i]); + } + PRINTK ("\n"); + for (i = 0; i < NR_INFO; i++) { + if ((prom[0] == hw_info[i].a0) && + (prom[2] == hw_info[i].a1) && + (prom[4] == hw_info[i].a2)) { + PRINTK ("matched board %d\n", i); + break; + } + } + if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) { + PRINTK ("on exit i is %d/%ld\n", i, NR_INFO); + PRINTK ("MAC address is "); + for (j = 0; j < 6; j++) { + mac_addr[j] = prom[j << 1]; + PRINTK ("%02x:", mac_addr[i]); + } + PRINTK ("\n"); + return (i < NR_INFO) ? i : 0; + } + return NULL; +} +#endif /* __DRIVERS_NE2000_H__ */ diff --git a/drivers/net/ne2000_base.h b/drivers/net/ne2000_base.h new file mode 100644 index 000000000..1badf62bf --- /dev/null +++ b/drivers/net/ne2000_base.h @@ -0,0 +1,282 @@ +/* +Ported to U-Boot by Christian Pellegrin + +Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and +eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world +are GPL, so this is, of course, GPL. + + +========================================================================== + + dev/dp83902a.h + + National Semiconductor DP83902a ethernet chip + +========================================================================== +####ECOSGPLCOPYRIGHTBEGIN#### + ------------------------------------------- + This file is part of eCos, the Embedded Configurable Operating System. + Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + + eCos 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. + + eCos 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 eCos; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + As a special exception, if other files instantiate templates or use macros + or inline functions from this file, or you compile this file and link it + with other works to produce a work based on this file, this file does not + by itself cause the resulting work to be covered by the GNU General Public + License. However the source code for this file must still be made available + in accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work based on + this file might be covered by the GNU General Public License. + + Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. + at http://sources.redhat.com/ecos/ecos-license/ + ------------------------------------------- +####ECOSGPLCOPYRIGHTEND#### +####BSDCOPYRIGHTBEGIN#### + + ------------------------------------------- + + Portions of this software may have been derived from OpenBSD or other sources, + and are covered by the appropriate copyright disclaimers included herein. + + ------------------------------------------- + +####BSDCOPYRIGHTEND#### +========================================================================== +#####DESCRIPTIONBEGIN#### + + Author(s): gthomas + Contributors: gthomas, jskov + Date: 2001-06-13 + Purpose: + Description: + +####DESCRIPTIONEND#### + +========================================================================== + +*/ + +/* + ------------------------------------------------------------------------ + Macros for accessing DP registers + These can be overridden by the platform header +*/ + +#define bool int + +#define false 0 +#define true 1 + +/* timeout for tx/rx in s */ +#define TOUT 5 +/* Ether MAC address size */ +#define ETHER_ADDR_LEN 6 + + +#define CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA 1 +#define CYGACC_CALL_IF_DELAY_US(X) udelay(X) + +/* H/W infomation struct */ +typedef struct hw_info_t { + u32 offset; + u8 a0, a1, a2; + u32 flags; +} hw_info_t; + +typedef struct dp83902a_priv_data { + u8* base; + u8* data; + u8* reset; + int tx_next; /* First free Tx page */ + int tx_int; /* Expecting interrupt from this buffer */ + int rx_next; /* First free Rx page */ + int tx1, tx2; /* Page numbers for Tx buffers */ + u32 tx1_key, tx2_key; /* Used to ack when packet sent */ + int tx1_len, tx2_len; + bool tx_started, running, hardwired_esa; + u8 esa[6]; + void* plf_priv; + + /* Buffer allocation */ + int tx_buf1, tx_buf2; + int rx_buf_start, rx_buf_end; +} dp83902a_priv_data_t; + +/* + ------------------------------------------------------------------------ + Some forward declarations +*/ +int get_prom( u8* mac_addr); +static void dp83902a_poll(void); + +/* ------------------------------------------------------------------------ */ +/* Register offsets */ + +#define DP_CR 0x00 +#define DP_CLDA0 0x01 +#define DP_PSTART 0x01 /* write */ +#define DP_CLDA1 0x02 +#define DP_PSTOP 0x02 /* write */ +#define DP_BNDRY 0x03 +#define DP_TSR 0x04 +#define DP_TPSR 0x04 /* write */ +#define DP_NCR 0x05 +#define DP_TBCL 0x05 /* write */ +#define DP_FIFO 0x06 +#define DP_TBCH 0x06 /* write */ +#define DP_ISR 0x07 +#define DP_CRDA0 0x08 +#define DP_RSAL 0x08 /* write */ +#define DP_CRDA1 0x09 +#define DP_RSAH 0x09 /* write */ +#define DP_RBCL 0x0a /* write */ +#define DP_RBCH 0x0b /* write */ +#define DP_RSR 0x0c +#define DP_RCR 0x0c /* write */ +#define DP_FER 0x0d +#define DP_TCR 0x0d /* write */ +#define DP_CER 0x0e +#define DP_DCR 0x0e /* write */ +#define DP_MISSED 0x0f +#define DP_IMR 0x0f /* write */ +#define DP_DATAPORT 0x10 /* "eprom" data port */ + +#define DP_P1_CR 0x00 +#define DP_P1_PAR0 0x01 +#define DP_P1_PAR1 0x02 +#define DP_P1_PAR2 0x03 +#define DP_P1_PAR3 0x04 +#define DP_P1_PAR4 0x05 +#define DP_P1_PAR5 0x06 +#define DP_P1_CURP 0x07 +#define DP_P1_MAR0 0x08 +#define DP_P1_MAR1 0x09 +#define DP_P1_MAR2 0x0a +#define DP_P1_MAR3 0x0b +#define DP_P1_MAR4 0x0c +#define DP_P1_MAR5 0x0d +#define DP_P1_MAR6 0x0e +#define DP_P1_MAR7 0x0f + +#define DP_P2_CR 0x00 +#define DP_P2_PSTART 0x01 +#define DP_P2_CLDA0 0x01 /* write */ +#define DP_P2_PSTOP 0x02 +#define DP_P2_CLDA1 0x02 /* write */ +#define DP_P2_RNPP 0x03 +#define DP_P2_TPSR 0x04 +#define DP_P2_LNPP 0x05 +#define DP_P2_ACH 0x06 +#define DP_P2_ACL 0x07 +#define DP_P2_RCR 0x0c +#define DP_P2_TCR 0x0d +#define DP_P2_DCR 0x0e +#define DP_P2_IMR 0x0f + +/* Command register - common to all pages */ + +#define DP_CR_STOP 0x01 /* Stop: software reset */ +#define DP_CR_START 0x02 /* Start: initialize device */ +#define DP_CR_TXPKT 0x04 /* Transmit packet */ +#define DP_CR_RDMA 0x08 /* Read DMA (recv data from device) */ +#define DP_CR_WDMA 0x10 /* Write DMA (send data to device) */ +#define DP_CR_SEND 0x18 /* Send packet */ +#define DP_CR_NODMA 0x20 /* Remote (or no) DMA */ +#define DP_CR_PAGE0 0x00 /* Page select */ +#define DP_CR_PAGE1 0x40 +#define DP_CR_PAGE2 0x80 +#define DP_CR_PAGEMSK 0x3F /* Used to mask out page bits */ + +/* Data configuration register */ + +#define DP_DCR_WTS 0x01 /* 1=16 bit word transfers */ +#define DP_DCR_BOS 0x02 /* 1=Little Endian */ +#define DP_DCR_LAS 0x04 /* 1=Single 32 bit DMA mode */ +#define DP_DCR_LS 0x08 /* 1=normal mode, 0=loopback */ +#define DP_DCR_ARM 0x10 /* 0=no send command (program I/O) */ +#define DP_DCR_FIFO_1 0x00 /* FIFO threshold */ +#define DP_DCR_FIFO_2 0x20 +#define DP_DCR_FIFO_4 0x40 +#define DP_DCR_FIFO_6 0x60 + +#define DP_DCR_INIT (DP_DCR_LS|DP_DCR_FIFO_4) + +/* Interrupt status register */ + +#define DP_ISR_RxP 0x01 /* Packet received */ +#define DP_ISR_TxP 0x02 /* Packet transmitted */ +#define DP_ISR_RxE 0x04 /* Receive error */ +#define DP_ISR_TxE 0x08 /* Transmit error */ +#define DP_ISR_OFLW 0x10 /* Receive overflow */ +#define DP_ISR_CNT 0x20 /* Tally counters need emptying */ +#define DP_ISR_RDC 0x40 /* Remote DMA complete */ +#define DP_ISR_RESET 0x80 /* Device has reset (shutdown, error) */ + +/* Interrupt mask register */ + +#define DP_IMR_RxP 0x01 /* Packet received */ +#define DP_IMR_TxP 0x02 /* Packet transmitted */ +#define DP_IMR_RxE 0x04 /* Receive error */ +#define DP_IMR_TxE 0x08 /* Transmit error */ +#define DP_IMR_OFLW 0x10 /* Receive overflow */ +#define DP_IMR_CNT 0x20 /* Tall counters need emptying */ +#define DP_IMR_RDC 0x40 /* Remote DMA complete */ + +#define DP_IMR_All 0x3F /* Everything but remote DMA */ + +/* Receiver control register */ + +#define DP_RCR_SEP 0x01 /* Save bad(error) packets */ +#define DP_RCR_AR 0x02 /* Accept runt packets */ +#define DP_RCR_AB 0x04 /* Accept broadcast packets */ +#define DP_RCR_AM 0x08 /* Accept multicast packets */ +#define DP_RCR_PROM 0x10 /* Promiscuous mode */ +#define DP_RCR_MON 0x20 /* Monitor mode - 1=accept no packets */ + +/* Receiver status register */ + +#define DP_RSR_RxP 0x01 /* Packet received */ +#define DP_RSR_CRC 0x02 /* CRC error */ +#define DP_RSR_FRAME 0x04 /* Framing error */ +#define DP_RSR_FO 0x08 /* FIFO overrun */ +#define DP_RSR_MISS 0x10 /* Missed packet */ +#define DP_RSR_PHY 0x20 /* 0=pad match, 1=mad match */ +#define DP_RSR_DIS 0x40 /* Receiver disabled */ +#define DP_RSR_DFR 0x80 /* Receiver processing deferred */ + +/* Transmitter control register */ + +#define DP_TCR_NOCRC 0x01 /* 1=inhibit CRC */ +#define DP_TCR_NORMAL 0x00 /* Normal transmitter operation */ +#define DP_TCR_LOCAL 0x02 /* Internal NIC loopback */ +#define DP_TCR_INLOOP 0x04 /* Full internal loopback */ +#define DP_TCR_OUTLOOP 0x08 /* External loopback */ +#define DP_TCR_ATD 0x10 /* Auto transmit disable */ +#define DP_TCR_OFFSET 0x20 /* Collision offset adjust */ + +/* Transmit status register */ + +#define DP_TSR_TxP 0x01 /* Packet transmitted */ +#define DP_TSR_COL 0x04 /* Collision (at least one) */ +#define DP_TSR_ABT 0x08 /* Aborted because of too many collisions */ +#define DP_TSR_CRS 0x10 /* Lost carrier */ +#define DP_TSR_FU 0x20 /* FIFO underrun */ +#define DP_TSR_CDH 0x40 /* Collision Detect Heartbeat */ +#define DP_TSR_OWC 0x80 /* Collision outside normal window */ + +#define IEEE_8023_MAX_FRAME 1518 /* Largest possible ethernet frame */ +#define IEEE_8023_MIN_FRAME 64 /* Smallest possible ethernet frame */ diff --git a/drivers/net/smc91111.h b/drivers/net/smc91111.h index d03cbc320..8dcbb3e2a 100644 --- a/drivers/net/smc91111.h +++ b/drivers/net/smc91111.h @@ -186,7 +186,7 @@ typedef unsigned long int dword; #ifdef CONFIG_ADNPESC1 #define SMC_inw(r) (*((volatile word *)(SMC_BASE_ADDRESS+((r)<<1)))) #elif CONFIG_BLACKFIN -#define SMC_inw(r) ({ word __v = (*((volatile word *)(SMC_BASE_ADDRESS+(r)))); asm("ssync;"); __v;}) +#define SMC_inw(r) ({ word __v = (*((volatile word *)(SMC_BASE_ADDRESS+(r)))); SSYNC(); __v;}) #else #define SMC_inw(r) (*((volatile word *)(SMC_BASE_ADDRESS+(r)))) #endif @@ -195,7 +195,7 @@ typedef unsigned long int dword; #ifdef CONFIG_ADNPESC1 #define SMC_outw(d,r) (*((volatile word *)(SMC_BASE_ADDRESS+((r)<<1))) = d) #elif CONFIG_BLACKFIN -#define SMC_outw(d,r) {(*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d);asm("ssync;");} +#define SMC_outw(d,r) {(*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d); SSYNC();} #else #define SMC_outw(d,r) (*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d) #endif diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index e91d9eadc..431a8d2f2 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -583,10 +583,11 @@ uint mii_parse_RTL8211B_sr(uint mii_reg, struct tsec_private * priv) uint speed; mii_reg = read_phy_reg(priv, MIIM_RTL8211B_PHY_STATUS); - if ((mii_reg & MIIM_RTL8211B_PHYSTAT_LINK) && - !(mii_reg & MIIM_RTL8211B_PHYSTAT_SPDDONE)) { + if (!(mii_reg & MIIM_RTL8211B_PHYSTAT_SPDDONE)) { int i = 0; + /* in case of timeout ->link is cleared */ + priv->link = 1; puts("Waiting for PHY realtime link"); while (!(mii_reg & MIIM_RTL8211B_PHYSTAT_SPDDONE)) { /* Timeout reached ? */ diff --git a/drivers/net/vsc7385.c b/drivers/net/vsc7385.c new file mode 100644 index 000000000..4095bce5b --- /dev/null +++ b/drivers/net/vsc7385.c @@ -0,0 +1,101 @@ +/* + * Vitesse 7385 Switch Firmware Upload + * + * Author: Timur Tabi + * + * Copyright 2008 Freescale Semiconductor, Inc. This file is licensed + * under the terms of the GNU General Public License version 2. This + * program is licensed "as is" without any warranty of any kind, whether + * express or implied. + * + * This module uploads proprietary firmware for the Vitesse VSC7385 5-port + * switch. + */ + +#include + +#ifdef CONFIG_VSC7385_ENET + +#include +#include +#include + +/* + * Upload a Vitesse VSC7385 firmware image to the hardware + * + * This function takes a pointer to a VSC7385 firmware image and a size, and + * uploads that firmware to the VSC7385. + * + * This firmware is typically located at a board-specific flash address, + * and the size is typically 8KB. + * + * The firmware is Vitesse proprietary. + * + * Further details on the register information can be obtained from Vitesse. + */ +int vsc7385_upload_firmware(void *firmware, unsigned int size) +{ + u8 *fw = firmware; + unsigned int i; + + u32 *gloreset = (u32 *) (CFG_VSC7385_BASE + 0x1c050); + u32 *icpu_ctrl = (u32 *) (CFG_VSC7385_BASE + 0x1c040); + u32 *icpu_addr = (u32 *) (CFG_VSC7385_BASE + 0x1c044); + u32 *icpu_data = (u32 *) (CFG_VSC7385_BASE + 0x1c048); + u32 *icpu_rom_map = (u32 *) (CFG_VSC7385_BASE + 0x1c070); +#ifdef DEBUG + u32 *chipid = (u32 *) (CFG_VSC7385_BASE + 0x1c060); +#endif + + out_be32(gloreset, 3); + udelay(200); + + out_be32(icpu_ctrl, 0x8E); + udelay(20); + + out_be32(icpu_rom_map, 1); + udelay(20); + + /* Write the firmware to I-RAM */ + out_be32(icpu_addr, 0); + udelay(20); + + for (i = 0; i < size; i++) { + out_be32(icpu_data, fw[i]); + udelay(20); + if (ctrlc()) + return -EINTR; + } + + /* Read back and compare */ + out_be32(icpu_addr, 0); + udelay(20); + + for (i = 0; i < size; i++) { + u8 value; + + value = (u8) in_be32(icpu_data); + udelay(20); + if (value != fw[i]) { + debug("VSC7385: Upload mismatch: address 0x%x, " + "read value 0x%x, image value 0x%x\n", + i, value, fw[i]); + + return -EIO; + } + if (ctrlc()) + break; + } + + out_be32(icpu_ctrl, 0x0B); + udelay(20); + +#ifdef DEBUG + printf("VSC7385: Chip ID is %08x\n", in_be32(chipid)); + udelay(20); +#endif + + return 0; +} + +#endif diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 50ca6b0ba..7944b6684 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -425,6 +425,9 @@ int pci_hose_scan_bus(struct pci_controller *hose, int bus) dev < PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1); dev += PCI_BDF(0,0,1)) { + + /* Bus 0 is not necessarily PCI bridge. */ +#if defined(CONFIG_PCI_SKIP_HOST_BRIDGE) /* Skip our host bridge */ if ( dev == PCI_BDF(hose->first_busno,0,0) ) { #if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */ @@ -434,10 +437,11 @@ int pci_hose_scan_bus(struct pci_controller *hose, int bus) if (getenv("pciconfighost") == NULL) { continue; /* Skip our host bridge */ } -#else +#else /* CONFIG_PCI_CONFIG_HOST_BRIDGE */ continue; /* Skip our host bridge */ -#endif +#endif /* CONFIG_PCI_CONFIG_HOST_BRIDGE */ } +#endif /* CONFIG_PCI_SKIP_HOST_BRIDGE */ if (PCI_FUNC(dev) && !found_multi) continue; @@ -473,8 +477,11 @@ int pci_hose_scan_bus(struct pci_controller *hose, int bus) hose->fixup_irq(hose, dev); #ifdef CONFIG_PCI_SCAN_SHOW +#if defined(CONFIG_PCI_SKIP_HOST_BRIDGE) /* Skip our host bridge */ - if ( dev != PCI_BDF(hose->first_busno,0,0) ) { + if ( dev != PCI_BDF(hose->first_busno,0,0) ) +#endif + { unsigned char int_line; pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_LINE, diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c index 55f37cb55..d34430c65 100644 --- a/drivers/qe/uec.c +++ b/drivers/qe/uec.c @@ -417,6 +417,7 @@ static int uec_set_mac_if_mode(uec_private_t *uec, enet_interface_e if_mode) maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE; upsmr |= (UPSMR_RPM | UPSMR_TBIM); break; + case ENET_1000_RGMII_RXID: case ENET_1000_RGMII: maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE; upsmr |= UPSMR_RPM; diff --git a/drivers/qe/uec.h b/drivers/qe/uec.h index c384055ce..7762de6a8 100644 --- a/drivers/qe/uec.h +++ b/drivers/qe/uec.h @@ -642,6 +642,7 @@ typedef enum enet_interface { ENET_100_RGMII, ENET_1000_GMII, ENET_1000_RGMII, + ENET_1000_RGMII_RXID, ENET_1000_TBI, ENET_1000_RTBI } enet_interface_e; diff --git a/drivers/qe/uec_phy.c b/drivers/qe/uec_phy.c index a42701c59..423ba789e 100644 --- a/drivers/qe/uec_phy.c +++ b/drivers/qe/uec_phy.c @@ -318,16 +318,26 @@ static int genmii_read_status (struct uec_mii_info *mii_info) return err; if (mii_info->autoneg) { - status = phy_read (mii_info, PHY_ANLPAR); + status = phy_read(mii_info, MII_1000BASETSTATUS); - if (status & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) - mii_info->duplex = DUPLEX_FULL; - else - mii_info->duplex = DUPLEX_HALF; - if (status & (PHY_ANLPAR_TXFD | PHY_ANLPAR_TX)) - mii_info->speed = SPEED_100; - else - mii_info->speed = SPEED_10; + if (status & (LPA_1000FULL | LPA_1000HALF)) { + mii_info->speed = SPEED_1000; + if (status & LPA_1000FULL) + mii_info->duplex = DUPLEX_FULL; + else + mii_info->duplex = DUPLEX_HALF; + } else { + status = phy_read(mii_info, PHY_ANLPAR); + + if (status & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) + mii_info->duplex = DUPLEX_FULL; + else + mii_info->duplex = DUPLEX_HALF; + if (status & (PHY_ANLPAR_TXFD | PHY_ANLPAR_TX)) + mii_info->speed = SPEED_100; + else + mii_info->speed = SPEED_10; + } mii_info->pause = 0; } /* On non-aneg, we assume what we put in BMCR is the speed, @@ -337,6 +347,37 @@ static int genmii_read_status (struct uec_mii_info *mii_info) return 0; } +static int bcm_init(struct uec_mii_info *mii_info) +{ + struct eth_device *edev = mii_info->dev; + uec_private_t *uec = edev->priv; + + gbit_config_aneg(mii_info); + + if (uec->uec_info->enet_interface == ENET_1000_RGMII_RXID) { + u16 val; + int cnt = 50; + + /* Wait for aneg to complete. */ + do + val = phy_read(mii_info, PHY_BMSR); + while (--cnt && !(val & PHY_BMSR_AUTN_COMP)); + + /* Set RDX clk delay. */ + phy_write(mii_info, 0x18, 0x7 | (7 << 12)); + + val = phy_read(mii_info, 0x18); + /* Set RDX-RXC skew. */ + val |= (1 << 8); + val |= (7 | (7 << 12)); + /* Write bits 14:0. */ + val |= (1 << 15); + phy_write(mii_info, 0x18, val); + } + + return 0; +} + static int marvell_read_status (struct uec_mii_info *mii_info) { u16 status; @@ -505,6 +546,15 @@ static struct phy_info phy_info_marvell = { .config_intr = &marvell_config_intr, }; +static struct phy_info phy_info_bcm5481 = { + .phy_id = 0x0143bca0, + .phy_id_mask = 0xffffff0, + .name = "Broadcom 5481", + .features = MII_GBIT_FEATURES, + .read_status = genmii_read_status, + .init = bcm_init, +}; + static struct phy_info phy_info_genmii = { .phy_id = 0x00000000, .phy_id_mask = 0x00000000, @@ -518,6 +568,7 @@ static struct phy_info *phy_info[] = { &phy_info_dm9161, &phy_info_dm9161a, &phy_info_marvell, + &phy_info_bcm5481, &phy_info_genmii, NULL }; diff --git a/drivers/qe/uec_phy.h b/drivers/qe/uec_phy.h index e59a940e0..6f769fb50 100644 --- a/drivers/qe/uec_phy.h +++ b/drivers/qe/uec_phy.h @@ -29,6 +29,11 @@ #define MII_1000BASETCONTROL_FULLDUPLEXCAP 0x0200 #define MII_1000BASETCONTROL_HALFDUPLEXCAP 0x0100 +/* 1000BT status */ +#define MII_1000BASETSTATUS 0x0a +#define LPA_1000FULL 0x0400 +#define LPA_1000HALF 0x0200 + /* Cicada Extended Control Register 1 */ #define MII_CIS8201_EXT_CON1 0x17 #define MII_CIS8201_EXTCON1_INIT 0x0000 diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 9be2130e1..800ab9934 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -43,7 +43,6 @@ COBJS-$(CONFIG_RTC_ISL1208) += isl1208.o COBJS-y += m41t11.o COBJS-y += m41t60.o COBJS-$(CONFIG_RTC_M41T62) += m41t62.o -COBJS-y += max6900.o COBJS-y += m48t35ax.o COBJS-y += max6900.o COBJS-y += mc146818.o diff --git a/drivers/rtc/ds1337.c b/drivers/rtc/ds1337.c index 50ab44690..e908749ef 100644 --- a/drivers/rtc/ds1337.c +++ b/drivers/rtc/ds1337.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2001, 2002 + * (C) Copyright 2001-2008 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * Keith Outwater, keith_outwater@mvis.com` * @@ -60,19 +60,19 @@ /* * RTC control register bits */ -#define RTC_CTL_BIT_A1IE 0x1 /* Alarm 1 interrupt enable */ -#define RTC_CTL_BIT_A2IE 0x2 /* Alarm 2 interrupt enable */ -#define RTC_CTL_BIT_INTCN 0x4 /* Interrupt control */ -#define RTC_CTL_BIT_RS1 0x8 /* Rate select 1 */ -#define RTC_CTL_BIT_RS2 0x10 /* Rate select 2 */ -#define RTC_CTL_BIT_DOSC 0x80 /* Disable Oscillator */ +#define RTC_CTL_BIT_A1IE 0x1 /* Alarm 1 interrupt enable */ +#define RTC_CTL_BIT_A2IE 0x2 /* Alarm 2 interrupt enable */ +#define RTC_CTL_BIT_INTCN 0x4 /* Interrupt control */ +#define RTC_CTL_BIT_RS1 0x8 /* Rate select 1 */ +#define RTC_CTL_BIT_RS2 0x10 /* Rate select 2 */ +#define RTC_CTL_BIT_DOSC 0x80 /* Disable Oscillator */ /* * RTC status register bits */ -#define RTC_STAT_BIT_A1F 0x1 /* Alarm 1 flag */ -#define RTC_STAT_BIT_A2F 0x2 /* Alarm 2 flag */ -#define RTC_STAT_BIT_OSF 0x80 /* Oscillator stop flag */ +#define RTC_STAT_BIT_A1F 0x1 /* Alarm 1 flag */ +#define RTC_STAT_BIT_A2F 0x2 /* Alarm 2 flag */ +#define RTC_STAT_BIT_OSF 0x80 /* Oscillator stop flag */ static uchar rtc_read (uchar reg); @@ -158,11 +158,18 @@ void rtc_set (struct rtc_time *tmp) * SQW/INTB* pin and program it for 32,768 Hz output. Note that * according to the datasheet, turning on the square wave output * increases the current drain on the backup battery from about - * 600 nA to 2uA. + * 600 nA to 2uA. Define CFG_RTC_DS1337_NOOSC if you wish to turn + * off the OSC output. */ +#ifdef CFG_RTC_DS1337_NOOSC + #define RTC_DS1337_RESET_VAL \ + (RTC_CTL_BIT_INTCN | RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2) +#else + #define RTC_DS1337_RESET_VAL (RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2) +#endif void rtc_reset (void) { - rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2); + rtc_write (RTC_CTL_REG_ADDR, RTC_DS1337_RESET_VAL); } diff --git a/drivers/video/mb862xx.c b/drivers/video/mb862xx.c index bfb057f51..9684cf3b7 100644 --- a/drivers/video/mb862xx.c +++ b/drivers/video/mb862xx.c @@ -36,6 +36,9 @@ #include "videomodes.h" #include +#if defined(CONFIG_POST) +#include +#endif /* * Graphic Device */ @@ -354,7 +357,7 @@ void *video_hw_init (void) board_disp_init(); #endif -#if defined(CONFIG_LWMON5) +#if defined(CONFIG_LWMON5) && !(CONFIG_POST & CFG_POST_SYSMON) /* Lamp on */ board_backlight_switch (1); #endif diff --git a/examples/eepro100_eeprom.c b/examples/eepro100_eeprom.c index a52e68d4e..2b15d05ad 100644 --- a/examples/eepro100_eeprom.c +++ b/examples/eepro100_eeprom.c @@ -17,8 +17,9 @@ * and release the resulting code under the GPL. */ -#define _PPC_STRING_H_ /* avoid unnecessary str/mem functions */ -#define _LINUX_STRING_H_ /* avoid unnecessary str/mem functions */ +/* avoid unnecessary memcpy function */ +#define __HAVE_ARCH_MEMCPY +#define _PPC_STRING_H_ #include #include diff --git a/fs/cramfs/uncompress.c b/fs/cramfs/uncompress.c index a9c0b7d46..cf6796790 100644 --- a/fs/cramfs/uncompress.c +++ b/fs/cramfs/uncompress.c @@ -29,24 +29,8 @@ static z_stream stream; -#define ZALLOC_ALIGNMENT 16 - -static void *zalloc (void *x, unsigned items, unsigned size) -{ - void *p; - - size *= items; - size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1); - - p = malloc (size); - - return (p); -} - -static void zfree (void *x, void *addr, unsigned nb) -{ - free (addr); -} +void *zalloc(void *, unsigned, unsigned); +void zfree(void *, void *, unsigned); /* Returns length of decompressed data. */ int cramfs_uncompress_block (void *dst, void *src, int srclen) diff --git a/include/asm-i386/zimage.h b/include/asm-i386/zimage.h index c7103b1f3..b6266e456 100644 --- a/include/asm-i386/zimage.h +++ b/include/asm-i386/zimage.h @@ -70,6 +70,5 @@ void *load_zimage(char *image, unsigned long kernel_size, int auto_boot); void boot_zimage(void *setup_base); -image_header_t *fake_zimage_header(image_header_t *hdr, void *ptr, int size); #endif diff --git a/include/asm-mips/asm.h b/include/asm-mips/asm.h new file mode 100644 index 000000000..608cfcfbb --- /dev/null +++ b/include/asm-mips/asm.h @@ -0,0 +1,409 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle + * Copyright (C) 1999 by Silicon Graphics, Inc. + * Copyright (C) 2001 MIPS Technologies, Inc. + * Copyright (C) 2002 Maciej W. Rozycki + * + * Some useful macros for MIPS assembler code + * + * Some of the routines below contain useless nops that will be optimized + * away by gas in -O mode. These nops are however required to fill delay + * slots in noreorder mode. + */ +#ifndef __ASM_ASM_H +#define __ASM_ASM_H + +#include + +#ifndef CAT +#ifdef __STDC__ +#define __CAT(str1, str2) str1##str2 +#else +#define __CAT(str1, str2) str1/**/str2 +#endif +#define CAT(str1, str2) __CAT(str1, str2) +#endif + +/* + * PIC specific declarations + * Not used for the kernel but here seems to be the right place. + */ +#ifdef __PIC__ +#define CPRESTORE(register) \ + .cprestore register +#define CPADD(register) \ + .cpadd register +#define CPLOAD(register) \ + .cpload register +#else +#define CPRESTORE(register) +#define CPADD(register) +#define CPLOAD(register) +#endif + +/* + * LEAF - declare leaf routine + */ +#define LEAF(symbol) \ + .globl symbol; \ + .align 2; \ + .type symbol, @function; \ + .ent symbol, 0; \ +symbol: .frame sp, 0, ra + +/* + * NESTED - declare nested routine entry point + */ +#define NESTED(symbol, framesize, rpc) \ + .globl symbol; \ + .align 2; \ + .type symbol, @function; \ + .ent symbol, 0; \ +symbol: .frame sp, framesize, rpc + +/* + * END - mark end of function + */ +#define END(function) \ + .end function; \ + .size function, .-function + +/* + * EXPORT - export definition of symbol + */ +#define EXPORT(symbol) \ + .globl symbol; \ +symbol: + +/* + * FEXPORT - export definition of a function symbol + */ +#define FEXPORT(symbol) \ + .globl symbol; \ + .type symbol, @function; \ +symbol: + +/* + * ABS - export absolute symbol + */ +#define ABS(symbol,value) \ + .globl symbol; \ +symbol = value + +#define PANIC(msg) \ + .set push; \ + .set reorder; \ + PTR_LA a0, 8f; \ + jal panic; \ +9: b 9b; \ + .set pop; \ + TEXT(msg) + +/* + * Print formatted string + */ +#ifdef CONFIG_PRINTK +#define PRINT(string) \ + .set push; \ + .set reorder; \ + PTR_LA a0, 8f; \ + jal printk; \ + .set pop; \ + TEXT(string) +#else +#define PRINT(string) +#endif + +#define TEXT(msg) \ + .pushsection .data; \ +8: .asciiz msg; \ + .popsection; + +/* + * Build text tables + */ +#define TTABLE(string) \ + .pushsection .text; \ + .word 1f; \ + .popsection \ + .pushsection .data; \ +1: .asciiz string; \ + .popsection + +/* + * MIPS IV pref instruction. + * Use with .set noreorder only! + * + * MIPS IV implementations are free to treat this as a nop. The R5000 + * is one of them. So we should have an option not to use this instruction. + */ +#ifdef CONFIG_CPU_HAS_PREFETCH + +#define PREF(hint,addr) \ + .set push; \ + .set mips4; \ + pref hint, addr; \ + .set pop + +#define PREFX(hint,addr) \ + .set push; \ + .set mips4; \ + prefx hint, addr; \ + .set pop + +#else /* !CONFIG_CPU_HAS_PREFETCH */ + +#define PREF(hint, addr) +#define PREFX(hint, addr) + +#endif /* !CONFIG_CPU_HAS_PREFETCH */ + +/* + * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs. + */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) +#define MOVN(rd, rs, rt) \ + .set push; \ + .set reorder; \ + beqz rt, 9f; \ + move rd, rs; \ + .set pop; \ +9: +#define MOVZ(rd, rs, rt) \ + .set push; \ + .set reorder; \ + bnez rt, 9f; \ + move rd, rs; \ + .set pop; \ +9: +#endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) +#define MOVN(rd, rs, rt) \ + .set push; \ + .set noreorder; \ + bnezl rt, 9f; \ + move rd, rs; \ + .set pop; \ +9: +#define MOVZ(rd, rs, rt) \ + .set push; \ + .set noreorder; \ + beqzl rt, 9f; \ + move rd, rs; \ + .set pop; \ +9: +#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ + (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) +#define MOVN(rd, rs, rt) \ + movn rd, rs, rt +#define MOVZ(rd, rs, rt) \ + movz rd, rs, rt +#endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */ + +/* + * Stack alignment + */ +#if (_MIPS_SIM == _MIPS_SIM_ABI32) +#define ALSZ 7 +#define ALMASK ~7 +#endif +#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) +#define ALSZ 15 +#define ALMASK ~15 +#endif + +/* + * Macros to handle different pointer/register sizes for 32/64-bit code + */ + +/* + * Size of a register + */ +#ifdef __mips64 +#define SZREG 8 +#else +#define SZREG 4 +#endif + +/* + * Use the following macros in assemblercode to load/store registers, + * pointers etc. + */ +#if (_MIPS_SIM == _MIPS_SIM_ABI32) +#define REG_S sw +#define REG_L lw +#define REG_SUBU subu +#define REG_ADDU addu +#endif +#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) +#define REG_S sd +#define REG_L ld +#define REG_SUBU dsubu +#define REG_ADDU daddu +#endif + +/* + * How to add/sub/load/store/shift C int variables. + */ +#if (_MIPS_SZINT == 32) +#define INT_ADD add +#define INT_ADDU addu +#define INT_ADDI addi +#define INT_ADDIU addiu +#define INT_SUB sub +#define INT_SUBU subu +#define INT_L lw +#define INT_S sw +#define INT_SLL sll +#define INT_SLLV sllv +#define INT_SRL srl +#define INT_SRLV srlv +#define INT_SRA sra +#define INT_SRAV srav +#endif + +#if (_MIPS_SZINT == 64) +#define INT_ADD dadd +#define INT_ADDU daddu +#define INT_ADDI daddi +#define INT_ADDIU daddiu +#define INT_SUB dsub +#define INT_SUBU dsubu +#define INT_L ld +#define INT_S sd +#define INT_SLL dsll +#define INT_SLLV dsllv +#define INT_SRL dsrl +#define INT_SRLV dsrlv +#define INT_SRA dsra +#define INT_SRAV dsrav +#endif + +/* + * How to add/sub/load/store/shift C long variables. + */ +#if (_MIPS_SZLONG == 32) +#define LONG_ADD add +#define LONG_ADDU addu +#define LONG_ADDI addi +#define LONG_ADDIU addiu +#define LONG_SUB sub +#define LONG_SUBU subu +#define LONG_L lw +#define LONG_S sw +#define LONG_SLL sll +#define LONG_SLLV sllv +#define LONG_SRL srl +#define LONG_SRLV srlv +#define LONG_SRA sra +#define LONG_SRAV srav + +#define LONG .word +#define LONGSIZE 4 +#define LONGMASK 3 +#define LONGLOG 2 +#endif + +#if (_MIPS_SZLONG == 64) +#define LONG_ADD dadd +#define LONG_ADDU daddu +#define LONG_ADDI daddi +#define LONG_ADDIU daddiu +#define LONG_SUB dsub +#define LONG_SUBU dsubu +#define LONG_L ld +#define LONG_S sd +#define LONG_SLL dsll +#define LONG_SLLV dsllv +#define LONG_SRL dsrl +#define LONG_SRLV dsrlv +#define LONG_SRA dsra +#define LONG_SRAV dsrav + +#define LONG .dword +#define LONGSIZE 8 +#define LONGMASK 7 +#define LONGLOG 3 +#endif + +/* + * How to add/sub/load/store/shift pointers. + */ +#if (_MIPS_SZPTR == 32) +#define PTR_ADD add +#define PTR_ADDU addu +#define PTR_ADDI addi +#define PTR_ADDIU addiu +#define PTR_SUB sub +#define PTR_SUBU subu +#define PTR_L lw +#define PTR_S sw +#define PTR_LA la +#define PTR_LI li +#define PTR_SLL sll +#define PTR_SLLV sllv +#define PTR_SRL srl +#define PTR_SRLV srlv +#define PTR_SRA sra +#define PTR_SRAV srav + +#define PTR_SCALESHIFT 2 + +#define PTR .word +#define PTRSIZE 4 +#define PTRLOG 2 +#endif + +#if (_MIPS_SZPTR == 64) +#define PTR_ADD dadd +#define PTR_ADDU daddu +#define PTR_ADDI daddi +#define PTR_ADDIU daddiu +#define PTR_SUB dsub +#define PTR_SUBU dsubu +#define PTR_L ld +#define PTR_S sd +#define PTR_LA dla +#define PTR_LI dli +#define PTR_SLL dsll +#define PTR_SLLV dsllv +#define PTR_SRL dsrl +#define PTR_SRLV dsrlv +#define PTR_SRA dsra +#define PTR_SRAV dsrav + +#define PTR_SCALESHIFT 3 + +#define PTR .dword +#define PTRSIZE 8 +#define PTRLOG 3 +#endif + +/* + * Some cp0 registers were extended to 64bit for MIPS III. + */ +#if (_MIPS_SIM == _MIPS_SIM_ABI32) +#define MFC0 mfc0 +#define MTC0 mtc0 +#endif +#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) +#define MFC0 dmfc0 +#define MTC0 dmtc0 +#endif + +#define SSNOP sll zero, zero, 1 + +#ifdef CONFIG_SGI_IP28 +/* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ +#include +#define R10KCBARRIER(addr) cache Cache_Barrier, addr; +#else +#define R10KCBARRIER(addr) +#endif + +#endif /* __ASM_ASM_H */ diff --git a/include/asm-mips/byteorder.h b/include/asm-mips/byteorder.h index b9604cf20..b5e685feb 100644 --- a/include/asm-mips/byteorder.h +++ b/include/asm-mips/byteorder.h @@ -1,18 +1,62 @@ -/* $Id: byteorder.h,v 1.8 1998/11/02 09:29:32 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) by Ralf Baechle + * Copyright (C) 1996, 99, 2003 by Ralf Baechle */ -#ifndef _MIPS_BYTEORDER_H -#define _MIPS_BYTEORDER_H +#ifndef _ASM_BYTEORDER_H +#define _ASM_BYTEORDER_H #include #ifdef __GNUC__ +#ifdef CONFIG_CPU_MIPSR2 + +static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x) +{ + __asm__( + " wsbh %0, %1 \n" + : "=r" (x) + : "r" (x)); + + return x; +} +#define __arch__swab16(x) ___arch__swab16(x) + +static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) +{ + __asm__( + " wsbh %0, %1 \n" + " rotr %0, %0, 16 \n" + : "=r" (x) + : "r" (x)); + + return x; +} +#define __arch__swab32(x) ___arch__swab32(x) + +#ifdef CONFIG_CPU_MIPS64_R2 + +static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x) +{ + __asm__( + " dsbh %0, %1 \n" + " dshd %0, %0 \n" + " drotr %0, %0, 32 \n" + : "=r" (x) + : "r" (x)); + + return x; +} + +#define __arch__swab64(x) ___arch__swab64(x) + +#endif /* CONFIG_CPU_MIPS64_R2 */ + +#endif /* CONFIG_CPU_MIPSR2 */ + #if !defined(__STRICT_ANSI__) || defined(__KERNEL__) # define __BYTEORDER_HAS_U64__ # define __SWAB_64_THRU_32__ @@ -20,12 +64,12 @@ #endif /* __GNUC__ */ -#if defined (__MIPSEB__) +#if defined(__MIPSEB__) # include -#elif defined (__MIPSEL__) +#elif defined(__MIPSEL__) # include #else # error "MIPS, but neither __MIPSEB__, nor __MIPSEL__???" #endif -#endif /* _MIPS_BYTEORDER_H */ +#endif /* _ASM_BYTEORDER_H */ diff --git a/include/asm-mips/cachectl.h b/include/asm-mips/cachectl.h index 9cc2b8721..f3ce72186 100644 --- a/include/asm-mips/cachectl.h +++ b/include/asm-mips/cachectl.h @@ -1,10 +1,12 @@ /* - * cachectl.h -- defines for MIPS cache control system calls + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. * * Copyright (C) 1994, 1995, 1996 by Ralf Baechle */ -#ifndef __ASM_MIPS_CACHECTL -#define __ASM_MIPS_CACHECTL +#ifndef _ASM_CACHECTL +#define _ASM_CACHECTL /* * Options for cacheflush system call @@ -21,4 +23,4 @@ #define CACHEABLE 0 /* make pages cacheable */ #define UNCACHEABLE 1 /* make pages uncacheable */ -#endif /* __ASM_MIPS_CACHECTL */ +#endif /* _ASM_CACHECTL */ diff --git a/include/asm-mips/cacheops.h b/include/asm-mips/cacheops.h index 66b0b361f..256ad2cc6 100644 --- a/include/asm-mips/cacheops.h +++ b/include/asm-mips/cacheops.h @@ -5,43 +5,81 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * (C) Copyright 1996, 1997 by Ralf Baechle + * (C) Copyright 1996, 97, 99, 2002, 03 Ralf Baechle + * (C) Copyright 1999 Silicon Graphics, Inc. */ -#ifndef __ASM_MIPS_CACHEOPS_H -#define __ASM_MIPS_CACHEOPS_H +#ifndef __ASM_CACHEOPS_H +#define __ASM_CACHEOPS_H /* - * Cache Operations + * Cache Operations available on all MIPS processors with R4000-style caches */ #define Index_Invalidate_I 0x00 #define Index_Writeback_Inv_D 0x01 -#define Index_Invalidate_SI 0x02 -#define Index_Writeback_Inv_SD 0x03 #define Index_Load_Tag_I 0x04 #define Index_Load_Tag_D 0x05 -#define Index_Load_Tag_SI 0x06 -#define Index_Load_Tag_SD 0x07 #define Index_Store_Tag_I 0x08 #define Index_Store_Tag_D 0x09 -#define Index_Store_Tag_SI 0x0A -#define Index_Store_Tag_SD 0x0B -#define Create_Dirty_Excl_D 0x0d -#define Create_Dirty_Excl_SD 0x0f +#if defined(CONFIG_CPU_LOONGSON2) +#define Hit_Invalidate_I 0x00 +#else #define Hit_Invalidate_I 0x10 +#endif #define Hit_Invalidate_D 0x11 -#define Hit_Invalidate_SI 0x12 -#define Hit_Invalidate_SD 0x13 -#define Fill 0x14 #define Hit_Writeback_Inv_D 0x15 - /* 0x16 is unused */ -#define Hit_Writeback_Inv_SD 0x17 + +/* + * R4000-specific cacheops + */ +#define Create_Dirty_Excl_D 0x0d +#define Fill 0x14 #define Hit_Writeback_I 0x18 #define Hit_Writeback_D 0x19 - /* 0x1a is unused */ + +/* + * R4000SC and R4400SC-specific cacheops + */ +#define Index_Invalidate_SI 0x02 +#define Index_Writeback_Inv_SD 0x03 +#define Index_Load_Tag_SI 0x06 +#define Index_Load_Tag_SD 0x07 +#define Index_Store_Tag_SI 0x0A +#define Index_Store_Tag_SD 0x0B +#define Create_Dirty_Excl_SD 0x0f +#define Hit_Invalidate_SI 0x12 +#define Hit_Invalidate_SD 0x13 +#define Hit_Writeback_Inv_SD 0x17 #define Hit_Writeback_SD 0x1b - /* 0x1c is unused */ - /* 0x1e is unused */ #define Hit_Set_Virtual_SI 0x1e #define Hit_Set_Virtual_SD 0x1f -#endif /* __ASM_MIPS_CACHEOPS_H */ +/* + * R5000-specific cacheops + */ +#define R5K_Page_Invalidate_S 0x17 + +/* + * RM7000-specific cacheops + */ +#define Page_Invalidate_T 0x16 + +/* + * R10000-specific cacheops + * + * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused. + * Most of the _S cacheops are identical to the R4000SC _SD cacheops. + */ +#define Index_Writeback_Inv_S 0x03 +#define Index_Load_Tag_S 0x07 +#define Index_Store_Tag_S 0x0B +#define Hit_Invalidate_S 0x13 +#define Cache_Barrier 0x14 +#define Hit_Writeback_Inv_S 0x17 +#define Index_Load_Data_I 0x18 +#define Index_Load_Data_D 0x19 +#define Index_Load_Data_S 0x1b +#define Index_Store_Data_I 0x1c +#define Index_Store_Data_D 0x1d +#define Index_Store_Data_S 0x1f + +#endif /* __ASM_CACHEOPS_H */ diff --git a/include/asm-mips/isadep.h b/include/asm-mips/isadep.h index 3cd1eb8eb..24c6cda79 100644 --- a/include/asm-mips/isadep.h +++ b/include/asm-mips/isadep.h @@ -1,16 +1,15 @@ /* - * Various ISA level dependant constants. + * Various ISA level dependent constants. * Most of the following constants reflect the different layout * of Coprocessor 0 registers. * * Copyright (c) 1998 Harald Koerfgen */ -#include #ifndef __ASM_ISADEP_H #define __ASM_ISADEP_H -#if defined(CONFIG_CPU_R3000) +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) /* * R2000 or R3000 */ diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index 6838aee98..24858ddda 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -4,9 +4,9 @@ * for more details. * * Copyright (C) 1994 Waldorf GMBH - * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001 Ralf Baechle + * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003 Ralf Baechle * Copyright (C) 1996 Paul M. Antoine - * Copyright (C) 1999 Silicon Graphics, Inc. + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ #ifndef _ASM_PROCESSOR_H #define _ASM_PROCESSOR_H @@ -15,92 +15,26 @@ #include -/* - * Default implementation of macro that returns current - * instruction pointer ("program counter"). - */ -#define current_text_addr() ({ __label__ _l; _l: &&_l;}) - -#if !defined (_LANGUAGE_ASSEMBLY) -#if 0 -#include -#endif #include #include #include #include -struct mips_cpuinfo { - unsigned long udelay_val; - unsigned long *pgd_quick; - unsigned long *pte_quick; - unsigned long pgtable_cache_sz; -}; +/* + * Return current * instruction pointer ("program counter"). + */ +#define current_text_addr() ({ __label__ _l; _l: &&_l;}) /* * System setup and hardware flags.. - * XXX: Should go into mips_cpuinfo. */ -extern void (*cpu_wait)(void); /* only available on R4[26]00 and R3081 */ -extern void r3081_wait(void); -extern void r4k_wait(void); -extern char cyclecounter_available; /* only available from R4000 upwards. */ +extern void (*cpu_wait)(void); -extern struct mips_cpuinfo boot_cpu_data; extern unsigned int vced_count, vcei_count; -#ifdef CONFIG_SMP -extern struct mips_cpuinfo cpu_data[]; -#define current_cpu_data cpu_data[smp_processor_id()] -#else -#define cpu_data &boot_cpu_data -#define current_cpu_data boot_cpu_data -#endif - -/* - * Bus types (default is ISA, but people can check others with these..) - * MCA_bus hardcoded to 0 for now. - * - * This needs to be extended since MIPS systems are being delivered with - * numerous different types of bus systems. - */ -extern int EISA_bus; -#define MCA_bus 0 -#define MCA_bus__is_a_macro /* for versions in ksyms.c */ - -/* - * MIPS has no problems with write protection - */ -#define wp_works_ok 1 -#define wp_works_ok__is_a_macro /* for versions in ksyms.c */ - -/* Lazy FPU handling on uni-processor */ -extern struct task_struct *last_task_used_math; - -/* - * User space process size: 2GB. This is hardcoded into a few places, - * so don't change it unless you know what you are doing. TASK_SIZE - * for a 64 bit kernel expandable to 8192EB, of which the current MIPS - * implementations will "only" be able to use 1TB ... - */ -#define TASK_SIZE (0x7fff8000UL) - -/* This decides where the kernel will search for a free chunk of vm - * space during mmap's. - */ -#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) - -/* - * Size of io_bitmap in longwords: 32 is ports 0-0x3ff. - */ -#define IO_BITMAP_SIZE 32 - #define NUM_FPU_REGS 32 -struct mips_fpu_hard_struct { - double fp_regs[NUM_FPU_REGS]; - unsigned int control; -}; +typedef __u64 fpureg_t; /* * It would be nice to add some more fields for emulator statistics, but there @@ -108,25 +42,29 @@ struct mips_fpu_hard_struct { * be recalculated by hand. So the additional information will be private to * the FPU emulator for now. See asm-mips/fpu_emulator.h. */ -typedef u64 fpureg_t; -struct mips_fpu_soft_struct { - fpureg_t regs[NUM_FPU_REGS]; - unsigned int sr; + +struct mips_fpu_struct { + fpureg_t fpr[NUM_FPU_REGS]; + unsigned int fcr31; }; -union mips_fpu_union { - struct mips_fpu_hard_struct hard; - struct mips_fpu_soft_struct soft; -}; +#define NUM_DSP_REGS 6 -#define INIT_FPU { \ - {{0,},} \ -} +typedef __u32 dspreg_t; + +struct mips_dsp_state { + dspreg_t dspr[NUM_DSP_REGS]; + unsigned int dspcontrol; +}; typedef struct { unsigned long seg; } mm_segment_t; +#define ARCH_MIN_TASKALIGN 8 + +struct mips_abi; + /* * If you change thread_struct remember to change the #defines below too! */ @@ -140,131 +78,36 @@ struct thread_struct { unsigned long cp0_status; /* Saved fpu/fpu emulator stuff. */ - union mips_fpu_union fpu; + struct mips_fpu_struct fpu; +#ifdef CONFIG_MIPS_MT_FPAFF + /* Emulated instruction count */ + unsigned long emulated_fp; + /* Saved per-thread scheduler affinity mask */ + cpumask_t user_cpus_allowed; +#endif /* CONFIG_MIPS_MT_FPAFF */ + + /* Saved state of the DSP ASE, if available. */ + struct mips_dsp_state dsp; /* Other stuff associated with the thread. */ unsigned long cp0_badvaddr; /* Last user fault */ unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */ unsigned long error_code; unsigned long trap_no; -#define MF_FIXADE 1 /* Fix address errors in software */ -#define MF_LOGADE 2 /* Log address errors to syslog */ - unsigned long mflags; - mm_segment_t current_ds; unsigned long irix_trampoline; /* Wheee... */ unsigned long irix_oldctx; - - /* - * These are really only needed if the full FPU emulator is configured. - * Would be made conditional on MIPS_FPU_EMULATOR if it weren't for the - * fact that having offset.h rebuilt differently for different config - * options would be asking for trouble. - * - * Saved EPC during delay-slot emulation (see math-emu/cp1emu.c) - */ - unsigned long dsemul_epc; - - /* - * Pointer to instruction used to induce address error - */ - unsigned long dsemul_aerpc; + struct mips_abi *abi; }; -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ - -#define INIT_THREAD { \ - /* \ - * saved main processor registers \ - */ \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, \ - /* \ - * saved cp0 stuff \ - */ \ - 0, \ - /* \ - * saved fpu/fpu emulator stuff \ - */ \ - INIT_FPU, \ - /* \ - * Other stuff associated with the process \ - */ \ - 0, 0, 0, 0, \ - /* \ - * For now the default is to fix address errors \ - */ \ - MF_FIXADE, { 0 }, 0, 0, \ - /* \ - * dsemul_epc and dsemul_aerpc should never be used uninitialized, \ - * but... \ - */ \ - 0 ,0 \ -} - -#ifdef __KERNEL__ - -#define KERNEL_STACK_SIZE 8192 - -#if !defined (_LANGUAGE_ASSEMBLY) +struct task_struct; /* Free all resources held by a thread. */ #define release_thread(thread) do { } while(0) -extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); +/* Prepare to copy thread state - unlazy all lazy status */ +#define prepare_to_copy(tsk) do { } while (0) -/* Copy and release all segment info associated with a VM */ -#define copy_segments(p, mm) do { } while(0) -#define release_segments(mm) do { } while(0) - -/* - * Return saved PC of a blocked thread. - */ -extern inline unsigned long thread_saved_pc(struct thread_struct *t) -{ - extern void ret_from_fork(void); - - /* New born processes are a special case */ - if (t->reg31 == (unsigned long) ret_from_fork) - return t->reg31; - - return ((unsigned long *)t->reg29)[10]; -} - -/* - * Do necessary setup to start up a newly executed thread. - */ -#define start_thread(regs, new_pc, new_sp) do { \ - /* New thread looses kernel privileges. */ \ - regs->cp0_status = (regs->cp0_status & ~(ST0_CU0|ST0_KSU)) | KU_USER;\ - regs->cp0_epc = new_pc; \ - regs->regs[29] = new_sp; \ - current->thread.current_ds = USER_DS; \ -} while (0) - -unsigned long get_wchan(struct task_struct *p); - -#define __PT_REG(reg) ((long)&((struct pt_regs *)0)->reg - sizeof(struct pt_regs)) -#define __KSTK_TOS(tsk) ((unsigned long)(tsk) + KERNEL_STACK_SIZE - 32) -#define KSTK_EIP(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(cp0_epc))) -#define KSTK_ESP(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(regs[29]))) - -/* Allocation and freeing of basic task resources. */ -/* - * NOTE! The task struct and the stack go together - */ -#define THREAD_SIZE (2*PAGE_SIZE) -#define alloc_task_struct() \ - ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) -#define free_task_struct(p) free_pages((unsigned long)(p),1) -#define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count) - -#define init_task (init_task_union.task) -#define init_stack (init_task_union.stack) - -#define cpu_relax() do { } while (0) - -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ -#endif /* __KERNEL__ */ +#define cpu_relax() barrier() /* * Return_address is a replacement for __builtin_return_address(count) @@ -280,4 +123,20 @@ unsigned long get_wchan(struct task_struct *p); */ #define return_address() ({__asm__ __volatile__("":::"$31");__builtin_return_address(0);}) +#ifdef CONFIG_CPU_HAS_PREFETCH + +#define ARCH_HAS_PREFETCH + +static inline void prefetch(const void *addr) +{ + __asm__ __volatile__( + " .set mips4 \n" + " pref %0, (%1) \n" + " .set mips0 \n" + : + : "i" (Pref_Load), "r" (addr)); +} + +#endif + #endif /* _ASM_PROCESSOR_H */ diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h index 2517adb2a..5659c0c87 100644 --- a/include/asm-mips/ptrace.h +++ b/include/asm-mips/ptrace.h @@ -3,17 +3,12 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000 by Ralf Baechle - * - * Machine dependent structs and defines to help the user use - * the ptrace system call. + * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000 by Ralf Baechle + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ #ifndef _ASM_PTRACE_H #define _ASM_PTRACE_H -#include -#include - /* 0 - 31 are integer registers, 32 - 63 are fp registers. */ #define FPR_BASE 32 #define PC 64 @@ -23,63 +18,69 @@ #define MMLO 68 #define FPC_CSR 69 #define FPC_EIR 70 +#define DSP_BASE 71 /* 3 more hi / lo register pairs */ +#define DSP_CONTROL 77 +#define ACX 78 -#ifndef _LANGUAGE_ASSEMBLY /* * This struct defines the way the registers are stored on the stack during a * system call/exception. As usual the registers k0/k1 aren't being saved. */ struct pt_regs { +#ifdef CONFIG_32BIT /* Pad bytes for argument save space on the stack. */ unsigned long pad0[6]; +#endif /* Saved main processor registers. */ unsigned long regs[32]; - /* Other saved registers. */ - unsigned long lo; - unsigned long hi; - - /* - * saved cp0 registers - */ - unsigned long cp0_epc; - unsigned long cp0_badvaddr; + /* Saved special registers. */ unsigned long cp0_status; + unsigned long hi; + unsigned long lo; +#ifdef CONFIG_CPU_HAS_SMARTMIPS + unsigned long acx; +#endif + unsigned long cp0_badvaddr; unsigned long cp0_cause; -}; - -#endif /* !(_LANGUAGE_ASSEMBLY) */ + unsigned long cp0_epc; +#ifdef CONFIG_MIPS_MT_SMTC + unsigned long cp0_tcstatus; +#endif /* CONFIG_MIPS_MT_SMTC */ +} __attribute__ ((aligned (8))); /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ -/* #define PTRACE_GETREGS 12 */ -/* #define PTRACE_SETREGS 13 */ -/* #define PTRACE_GETFPREGS 14 */ -/* #define PTRACE_SETFPREGS 15 */ +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 /* #define PTRACE_GETFPXREGS 18 */ /* #define PTRACE_SETFPXREGS 19 */ -#define PTRACE_SETOPTIONS 21 +#define PTRACE_OLDSETOPTIONS 21 -/* options set using PTRACE_SETOPTIONS */ -#define PTRACE_O_TRACESYSGOOD 0x00000001 +#define PTRACE_GET_THREAD_AREA 25 +#define PTRACE_SET_THREAD_AREA 26 -#if 0 /* def _LANGUAGE_ASSEMBLY */ -#include -#endif +/* Calls to trace a 64bit program from a 32bit program. */ +#define PTRACE_PEEKTEXT_3264 0xc0 +#define PTRACE_PEEKDATA_3264 0xc1 +#define PTRACE_POKETEXT_3264 0xc2 +#define PTRACE_POKEDATA_3264 0xc3 +#define PTRACE_GET_THREAD_AREA_3264 0xc4 #ifdef __KERNEL__ -#ifndef _LANGUAGE_ASSEMBLY +#include + /* * Does the process account for user or for system time? */ #define user_mode(regs) (((regs)->cp0_status & KU_MASK) == KU_USER) #define instruction_pointer(regs) ((regs)->cp0_epc) - -extern void show_regs(struct pt_regs *); -#endif /* !(_LANGUAGE_ASSEMBLY) */ +#define profile_pc(regs) instruction_pointer(regs) #endif diff --git a/include/asm-mips/reboot.h b/include/asm-mips/reboot.h new file mode 100644 index 000000000..978d20681 --- /dev/null +++ b/include/asm-mips/reboot.h @@ -0,0 +1,14 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1997, 1999, 2001, 06 by Ralf Baechle + * Copyright (C) 2001 MIPS Technologies, Inc. + */ +#ifndef _ASM_REBOOT_H +#define _ASM_REBOOT_H + +extern void _machine_restart(void); + +#endif /* _ASM_REBOOT_H */ diff --git a/include/asm-mips/reg.h b/include/asm-mips/reg.h index 35505b70f..fc6bc0c16 100644 --- a/include/asm-mips/reg.h +++ b/include/asm-mips/reg.h @@ -7,48 +7,50 @@ * for more details. * * Copyright (C) 1995, 1999 by Ralf Baechle + * Copyright (C) 1995, 1999 Silicon Graphics */ #ifndef __ASM_MIPS_REG_H #define __ASM_MIPS_REG_H -/* - * This defines/structures correspond to the register layout on stack - - * if the order here is changed, it needs to be updated in - * include/asm-mips/stackframe.h - */ -#define EF_REG0 6 -#define EF_REG1 7 -#define EF_REG2 8 -#define EF_REG3 9 -#define EF_REG4 10 -#define EF_REG5 11 -#define EF_REG6 12 -#define EF_REG7 13 -#define EF_REG8 14 -#define EF_REG9 15 -#define EF_REG10 16 -#define EF_REG11 17 -#define EF_REG12 18 -#define EF_REG13 19 -#define EF_REG14 20 -#define EF_REG15 21 -#define EF_REG16 22 -#define EF_REG17 23 -#define EF_REG18 24 -#define EF_REG19 25 -#define EF_REG20 26 -#define EF_REG21 27 -#define EF_REG22 28 -#define EF_REG23 29 -#define EF_REG24 30 -#define EF_REG25 31 +#if defined(CONFIG_32BIT) || defined(WANT_COMPAT_REG_H) + +#define EF_R0 6 +#define EF_R1 7 +#define EF_R2 8 +#define EF_R3 9 +#define EF_R4 10 +#define EF_R5 11 +#define EF_R6 12 +#define EF_R7 13 +#define EF_R8 14 +#define EF_R9 15 +#define EF_R10 16 +#define EF_R11 17 +#define EF_R12 18 +#define EF_R13 19 +#define EF_R14 20 +#define EF_R15 21 +#define EF_R16 22 +#define EF_R17 23 +#define EF_R18 24 +#define EF_R19 25 +#define EF_R20 26 +#define EF_R21 27 +#define EF_R22 28 +#define EF_R23 29 +#define EF_R24 30 +#define EF_R25 31 + /* * k0/k1 unsaved */ -#define EF_REG28 34 -#define EF_REG29 35 -#define EF_REG30 36 -#define EF_REG31 37 +#define EF_R26 32 +#define EF_R27 33 + +#define EF_R28 34 +#define EF_R29 35 +#define EF_R30 36 +#define EF_R31 37 /* * Saved special registers @@ -59,8 +61,66 @@ #define EF_CP0_EPC 40 #define EF_CP0_BADVADDR 41 #define EF_CP0_STATUS 42 -#define EF_CP0_CAUSE 44 +#define EF_CP0_CAUSE 43 +#define EF_UNUSED0 44 -#define EF_SIZE 180 /* size in bytes */ +#define EF_SIZE 180 + +#endif + +#ifdef CONFIG_64BIT + +#define EF_R0 0 +#define EF_R1 1 +#define EF_R2 2 +#define EF_R3 3 +#define EF_R4 4 +#define EF_R5 5 +#define EF_R6 6 +#define EF_R7 7 +#define EF_R8 8 +#define EF_R9 9 +#define EF_R10 10 +#define EF_R11 11 +#define EF_R12 12 +#define EF_R13 13 +#define EF_R14 14 +#define EF_R15 15 +#define EF_R16 16 +#define EF_R17 17 +#define EF_R18 18 +#define EF_R19 19 +#define EF_R20 20 +#define EF_R21 21 +#define EF_R22 22 +#define EF_R23 23 +#define EF_R24 24 +#define EF_R25 25 + +/* + * k0/k1 unsaved + */ +#define EF_R26 26 +#define EF_R27 27 + +#define EF_R28 28 +#define EF_R29 29 +#define EF_R30 30 +#define EF_R31 31 + +/* + * Saved special registers + */ +#define EF_LO 32 +#define EF_HI 33 + +#define EF_CP0_EPC 34 +#define EF_CP0_BADVADDR 35 +#define EF_CP0_STATUS 36 +#define EF_CP0_CAUSE 37 + +#define EF_SIZE 304 /* size in bytes */ + +#endif /* CONFIG_64BIT */ #endif /* __ASM_MIPS_REG_H */ diff --git a/include/asm-mips/regdef.h b/include/asm-mips/regdef.h index 691d047b6..2e65cc3c4 100644 --- a/include/asm-mips/regdef.h +++ b/include/asm-mips/regdef.h @@ -1,52 +1,100 @@ /* - * include/asm-mips/regdefs.h - * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994, 1995 by Ralf Baechle + * Copyright (C) 1985 MIPS Computer Systems, Inc. + * Copyright (C) 1994, 95, 99, 2003 by Ralf Baechle + * Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc. */ +#ifndef _ASM_REGDEF_H +#define _ASM_REGDEF_H -#ifndef __ASM_MIPS_REGDEF_H -#define __ASM_MIPS_REGDEF_H +#include + +#if _MIPS_SIM == _MIPS_SIM_ABI32 /* * Symbolic register names for 32 bit ABI */ -#define zero $0 /* wired zero */ -#define AT $1 /* assembler temp - uppercase because of ".set at" */ -#define v0 $2 /* return value */ -#define v1 $3 -#define a0 $4 /* argument registers */ -#define a1 $5 -#define a2 $6 -#define a3 $7 -#define t0 $8 /* caller saved */ -#define t1 $9 -#define t2 $10 -#define t3 $11 -#define t4 $12 -#define t5 $13 -#define t6 $14 -#define t7 $15 -#define s0 $16 /* callee saved */ -#define s1 $17 -#define s2 $18 -#define s3 $19 -#define s4 $20 -#define s5 $21 -#define s6 $22 -#define s7 $23 -#define t8 $24 /* caller saved */ -#define t9 $25 -#define jp $25 /* PIC jump register */ -#define k0 $26 /* kernel scratch */ -#define k1 $27 -#define gp $28 /* global pointer */ -#define sp $29 /* stack pointer */ -#define fp $30 /* frame pointer */ +#define zero $0 /* wired zero */ +#define AT $1 /* assembler temp - uppercase because of ".set at" */ +#define v0 $2 /* return value */ +#define v1 $3 +#define a0 $4 /* argument registers */ +#define a1 $5 +#define a2 $6 +#define a3 $7 +#define t0 $8 /* caller saved */ +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 +#define s0 $16 /* callee saved */ +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 +#define t8 $24 /* caller saved */ +#define t9 $25 +#define jp $25 /* PIC jump register */ +#define k0 $26 /* kernel scratch */ +#define k1 $27 +#define gp $28 /* global pointer */ +#define sp $29 /* stack pointer */ +#define fp $30 /* frame pointer */ #define s8 $30 /* same like fp! */ -#define ra $31 /* return address */ +#define ra $31 /* return address */ -#endif /* __ASM_MIPS_REGDEF_H */ +#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ + +#if _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 + +#define zero $0 /* wired zero */ +#define AT $at /* assembler temp - uppercase because of ".set at" */ +#define v0 $2 /* return value - caller saved */ +#define v1 $3 +#define a0 $4 /* argument registers */ +#define a1 $5 +#define a2 $6 +#define a3 $7 +#define a4 $8 /* arg reg 64 bit; caller saved in 32 bit */ +#define ta0 $8 +#define a5 $9 +#define ta1 $9 +#define a6 $10 +#define ta2 $10 +#define a7 $11 +#define ta3 $11 +#define t0 $12 /* caller saved */ +#define t1 $13 +#define t2 $14 +#define t3 $15 +#define s0 $16 /* callee saved */ +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 +#define t8 $24 /* caller saved */ +#define t9 $25 /* callee address for PIC/temp */ +#define jp $25 /* PIC jump register */ +#define k0 $26 /* kernel temporary */ +#define k1 $27 +#define gp $28 /* global pointer - caller saved for PIC */ +#define sp $29 /* stack pointer */ +#define fp $30 /* frame pointer */ +#define s8 $30 /* callee saved */ +#define ra $31 /* return address */ + +#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */ + +#endif /* _ASM_REGDEF_H */ diff --git a/include/asm-mips/types.h b/include/asm-mips/types.h index 707cbf42d..f49a2176a 100644 --- a/include/asm-mips/types.h +++ b/include/asm-mips/types.h @@ -1,5 +1,4 @@ -/* $Id: types.h,v 1.3 1999/08/18 23:37:50 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -10,6 +9,8 @@ #ifndef _ASM_TYPES_H #define _ASM_TYPES_H +#ifndef __ASSEMBLY__ + typedef unsigned short umode_t; /* @@ -40,11 +41,17 @@ __extension__ typedef unsigned long long __u64; #endif +#endif /* __ASSEMBLY__ */ + /* * These aren't exported outside the kernel to avoid name space clashes */ #ifdef __KERNEL__ +#define BITS_PER_LONG _MIPS_SZLONG + +#ifndef __ASSEMBLY__ + typedef __signed char s8; typedef unsigned char u8; @@ -68,9 +75,24 @@ typedef unsigned long long u64; #endif -#define BITS_PER_LONG _MIPS_SZLONG +#if (defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) \ + || defined(CONFIG_64BIT) +typedef u64 dma_addr_t; +#else +typedef u32 dma_addr_t; +#endif +typedef u64 dma64_addr_t; -typedef unsigned long dma_addr_t; +/* + * Don't use phys_t. You've been warned. + */ +#ifdef CONFIG_64BIT_PHYS_ADDR +typedef unsigned long long phys_t; +#else +typedef unsigned long phys_t; +#endif + +#endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/fsl_serdes.h b/include/asm-ppc/fsl_serdes.h new file mode 100644 index 000000000..733f919cf --- /dev/null +++ b/include/asm-ppc/fsl_serdes.h @@ -0,0 +1,21 @@ +#ifndef __FSL_SERDES_H +#define __FSL_SERDES_H + +#include + +#define FSL_SERDES_CLK_100 0 +#define FSL_SERDES_CLK_125 1 +#define FSL_SERDES_CLK_150 3 +#define FSL_SERDES_PROTO_SATA 0 +#define FSL_SERDES_PROTO_PEX 1 +#define FSL_SERDES_PROTO_PEX_X2 2 +#define FSL_SERDES_PROTO_SGMII 3 +#define FSL_SERDES_VDD_1V 1 + +#ifdef CONFIG_FSL_SERDES +extern void fsl_setup_serdes(u32 offset, char proto, char rfcks, char vdd); +#else +static void fsl_setup_serdes(u32 offset, char proto, char rfcks, char vdd) {} +#endif /* CONFIG_FSL_SERDES */ + +#endif /* __FSL_SERDES_H */ diff --git a/include/asm-ppc/global_data.h b/include/asm-ppc/global_data.h index e07092baa..b43dba335 100644 --- a/include/asm-ppc/global_data.h +++ b/include/asm-ppc/global_data.h @@ -40,8 +40,11 @@ typedef struct global_data { bd_t *bd; unsigned long flags; unsigned long baudrate; - unsigned long cpu_clk; /* CPU clock in Hz! */ + unsigned long cpu_clk; /* CPU clock in Hz! */ unsigned long bus_clk; +#if defined(CONFIG_8xx) + unsigned long brg_clk; +#endif #if defined(CONFIG_CPM2) /* There are many clocks on the MPC8260 - see page 9-5 */ unsigned long vco_out; @@ -49,9 +52,7 @@ typedef struct global_data { unsigned long scc_clk; unsigned long brg_clk; #endif -#if defined(CONFIG_MPC7448HPC2) unsigned long mem_clk; -#endif #if defined(CONFIG_MPC83XX) /* There are other clocks in the MPC83XX */ u32 csb_clk; diff --git a/include/asm-ppc/immap_85xx.h b/include/asm-ppc/immap_85xx.h index d769d7012..3506aec5e 100644 --- a/include/asm-ppc/immap_85xx.h +++ b/include/asm-ppc/immap_85xx.h @@ -57,7 +57,7 @@ typedef struct ccsr_local_ecm { uint lawbar7; /* 0xce8 - Local Access Window 7 Base Address Register */ char res19[4]; uint lawar7; /* 0xcf0 - Local Access Window 7 Attributes Register */ - char res20[780]; + char res20[780]; // XXX: LAW 8, LAW9 for 8572 uint eebacr; /* 0x1000 - ECM CCB Address Configuration Register */ char res21[12]; uint eebpcr; /* 0x1010 - ECM CCB Port Configuration Register */ @@ -86,7 +86,12 @@ typedef struct ccsr_ddr { uint cs1_config; /* 0x2084 - DDR Chip Select Configuration */ uint cs2_config; /* 0x2088 - DDR Chip Select Configuration */ uint cs3_config; /* 0x208c - DDR Chip Select Configuration */ - char res5[112]; + char res4a[48]; + uint cs0_config_2; /* 0x20c0 - DDR Chip Select Configuration 2 */ + uint cs1_config_2; /* 0x20c4 - DDR Chip Select Configuration 2 */ + uint cs2_config_2; /* 0x20c8 - DDR Chip Select Configuration 2 */ + uint cs3_config_2; /* 0x20cc - DDR Chip Select Configuration 2 */ + char res5[48]; uint ext_refrec; /* 0x2100 - DDR SDRAM Extended Refresh Recovery */ uint timing_cfg_0; /* 0x2104 - DDR SDRAM Timing Configuration Register 0 */ uint timing_cfg_1; /* 0x2108 - DDR SDRAM Timing Configuration Register 1 */ @@ -103,7 +108,17 @@ typedef struct ccsr_ddr { char res7[20]; uint init_address; /* 0x2148 - DDR training initialization address */ uint init_ext_address; /* 0x214C - DDR training initialization extended address */ - char res8_1[2728]; + char res8_1[16]; + uint timing_cfg_4; /* 0x2160 - DDR SDRAM Timing Configuration Register 4 */ + uint timing_cfg_5; /* 0x2164 - DDR SDRAM Timing Configuration Register 5 */ + char reg8_1a[8]; + uint ddr_zq_cntl; /* 0x2170 - DDR ZQ calibration control*/ + uint ddr_wrlvl_cntl; /* 0x2174 - DDR write leveling control*/ + uint ddr_pd_cntl; /* 0x2178 - DDR pre-drive conditioning control*/ + uint ddr_sr_cntr; /* 0x217C - DDR self refresh counter */ + uint ddr_sdram_rcw_1; /* 0x2180 - DDR Register Control Words 1 */ + uint ddr_sdram_rcw_2; /* 0x2184 - DDR Register Control Words 2 */ + char res8_1b[2672]; uint ip_rev1; /* 0x2BF8 - DDR IP Block Revision 1 */ uint ip_rev2; /* 0x2BFC - DDR IP Block Revision 2 */ char res8_2[512]; @@ -217,7 +232,7 @@ typedef struct ccsr_lbc { char res7[12]; uint lbcr; /* 0x50d0 - LBC Configuration Register */ uint lcrr; /* 0x50d4 - LBC Clock Ratio Register */ - char res8[12072]; + char res8[3880]; } ccsr_lbc_t; /* @@ -1578,7 +1593,11 @@ typedef struct ccsr_gur { #define MPC85xx_DEVDISR_RMSG 0x00040000 #define MPC85xx_DEVDISR_DDR 0x00010000 #define MPC85xx_DEVDISR_CPU 0x00008000 +#define MPC85xx_DEVDISR_CPU0 MPC85xx_DEVDISR_CPU #define MPC85xx_DEVDISR_TB 0x00004000 +#define MPC85xx_DEVDISR_TB0 MPC85xx_DEVDISR_TB +#define MPC85xx_DEVDISR_CPU1 0x00002000 +#define MPC85xx_DEVDISR_TB1 0x00001000 #define MPC85xx_DEVDISR_DMA 0x00000400 #define MPC85xx_DEVDISR_TSEC1 0x00000080 #define MPC85xx_DEVDISR_TSEC2 0x00000040 @@ -1624,6 +1643,8 @@ typedef struct ccsr_gur { #define CFG_MPC85xx_ECM_ADDR (CFG_IMMR + CFG_MPC85xx_ECM_OFFSET) #define CFG_MPC85xx_DDR_OFFSET (0x2000) #define CFG_MPC85xx_DDR_ADDR (CFG_IMMR + CFG_MPC85xx_DDR_OFFSET) +#define CFG_MPC85xx_DDR2_OFFSET (0x6000) +#define CFG_MPC85xx_DDR2_ADDR (CFG_IMMR + CFG_MPC85xx_DDR2_OFFSET) #define CFG_MPC85xx_LBC_OFFSET (0x5000) #define CFG_MPC85xx_LBC_ADDR (CFG_IMMR + CFG_MPC85xx_LBC_OFFSET) #define CFG_MPC85xx_PCIX_OFFSET (0x8000) diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index b7a5b2880..544cc010d 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -879,22 +879,42 @@ #define SVR_MAJ(svr) (((svr) >> 4) & 0xF) /* Major revision field*/ #define SVR_MIN(svr) (((svr) >> 0) & 0xF) /* Minor revision field*/ +/* Some parts define SVR[0:23] as the SOC version */ +#define SVR_SOC_VER(svr) (((svr) >> 8) & 0xFFFFFF) /* SOC Version fields */ + /* - * SVR_VER() Version Values + * SVR_SOC_VER() Version Values */ -#define SVR_8540 0x8030 -#define SVR_8560 0x8070 -#define SVR_8555 0x8079 -#define SVR_8541 0x807A -#define SVR_8544 0x8034 -#define SVR_8544_E 0x803C -#define SVR_8548 0x8031 -#define SVR_8548_E 0x8039 -#define SVR_8610 0x80A0 -#define SVR_8641 0x8090 -#define SVR_8568_E 0x807D +#define SVR_8533 0x803400 +#define SVR_8533_E 0x803C00 +#define SVR_8540 0x803000 +#define SVR_8541 0x807200 +#define SVR_8541_E 0x807A00 +#define SVR_8543 0x803200 +#define SVR_8543_E 0x803A00 +#define SVR_8544 0x803401 +#define SVR_8544_E 0x803C01 +#define SVR_8545 0x803102 +#define SVR_8545_E 0x803902 +#define SVR_8547_E 0x803901 +#define SVR_8548 0x803100 +#define SVR_8548_E 0x803900 +#define SVR_8555 0x807100 +#define SVR_8555_E 0x807900 +#define SVR_8560 0x807000 +#define SVR_8567 0x807600 +#define SVR_8567_E 0x807E00 +#define SVR_8568 0x807500 +#define SVR_8568_E 0x807D00 +#define SVR_8572 0x80E000 +#define SVR_8572_E 0x80E800 + +#define SVR_8610 0x80A000 +#define SVR_8641 0x809000 +#define SVR_8641D 0x809001 + /* I am just adding a single entry for 8260 boards. I think we may be diff --git a/include/common.h b/include/common.h index 673afdd15..39bcd307b 100644 --- a/include/common.h +++ b/include/common.h @@ -222,10 +222,7 @@ int mac_read_from_eeprom(void); void flash_perror (int); /* common/cmd_autoscript.c */ -int autoscript (ulong addr); - -/* common/cmd_bootm.c */ -void print_image_hdr (image_header_t *hdr); +int autoscript (ulong addr, const char *fit_uname); extern ulong load_addr; /* Default Load Address */ @@ -672,4 +669,11 @@ void inline show_boot_progress (int val); #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +/* Multicore arch functions */ +#ifdef CONFIG_MP +int cpu_status(int nr); +int cpu_reset(int nr); +int cpu_release(int nr, int argc, char *argv[]); +#endif + #endif /* __COMMON_H_ */ diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h index f3965efe9..69276a389 100644 --- a/include/config_cmd_all.h +++ b/include/config_cmd_all.h @@ -70,6 +70,7 @@ #define CONFIG_CMD_SAVES /* save S record dump */ #define CONFIG_CMD_SCSI /* SCSI Support */ #define CONFIG_CMD_SDRAM /* SDRAM DIMM SPD info printout */ +#define CONFIG_CMD_SETEXPR /* setexpr support */ #define CONFIG_CMD_SETGETDCR /* DCR support on 4xx */ #define CONFIG_CMD_SNTP /* SNTP support */ #define CONFIG_CMD_SPI /* SPI utility */ diff --git a/include/configs/ATUM8548.h b/include/configs/ATUM8548.h index c14376e7f..0d644da7a 100644 --- a/include/configs/ATUM8548.h +++ b/include/configs/ATUM8548.h @@ -96,6 +96,7 @@ */ #define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ #define CFG_CCSRBAR 0xe0000000 /* relocated CCSRBAR */ +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR /* physical addr of CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ #define PCI_SPEED 33333000 /* CPLD currenlty does not have PCI setup info */ diff --git a/include/configs/Adder.h b/include/configs/Adder.h index 4304ecca7..79199912d 100644 --- a/include/configs/Adder.h +++ b/include/configs/Adder.h @@ -37,6 +37,8 @@ #define CONFIG_ETHER_ON_FEC1 #define CONFIG_ETHER_ON_FEC2 +#define CONFIG_HAS_ETH0 +#define CONFIG_HAS_ETH1 #if defined(CONFIG_ETHER_ON_FEC1) || defined(CONFIG_ETHER_ON_FEC2) #define CFG_DISCOVER_PHY @@ -212,4 +214,8 @@ #define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from flash */ #define BOOTFLAG_WARM 0x02 /* Software reboot */ +/* pass open firmware flat tree */ +#define CONFIG_OF_LIBFDT 1 +#define CONFIG_OF_BOARD_SETUP 1 + #endif /* __CONFIG_H */ diff --git a/include/configs/MPC8313ERDB.h b/include/configs/MPC8313ERDB.h index f12a3e605..9576fa59e 100644 --- a/include/configs/MPC8313ERDB.h +++ b/include/configs/MPC8313ERDB.h @@ -38,6 +38,14 @@ #define CONFIG_PCI #define CONFIG_83XX_GENERIC_PCI +#define CONFIG_MISC_INIT_R + +/* + * On-board devices + */ +#define CONFIG_VSC7385_ENET + + #ifdef CFG_66MHZ #define CONFIG_83XX_CLKIN 66666667 /* in Hz */ #elif defined(CFG_33MHZ) @@ -64,6 +72,22 @@ #define CFG_ACR_PIPE_DEP 3 /* Arbiter pipeline depth (0-3) */ #define CFG_ACR_RPTCNT 3 /* Arbiter repeat count (0-7) */ +/* + * Device configurations + */ + +/* Vitesse 7385 */ + +#ifdef CONFIG_VSC7385_ENET + +#define CONFIG_TSEC2 + +/* The flash address and size of the VSC7385 firmware image */ +#define CONFIG_VSC7385_IMAGE 0xFE7FE000 +#define CONFIG_VSC7385_IMAGE_SIZE 8192 + +#endif + /* * DDR Setup */ @@ -214,20 +238,25 @@ #define CFG_LBLAWBAR1_PRELIM CFG_NAND_BASE #define CFG_LBLAWAR1_PRELIM 0x8000000E /* 32KB */ -#define CFG_VSC7385_BASE 0xF0000000 - -#define CONFIG_VSC7385_ENET /* VSC7385 ethernet support */ -#define CFG_BR2_PRELIM 0xf0000801 /* VSC7385 Base address */ -#define CFG_OR2_PRELIM 0xfffe09ff /* VSC7385, 128K bytes*/ -#define CFG_LBLAWBAR2_PRELIM CFG_VSC7385_BASE/* Access window base at VSC7385 base */ -#define CFG_LBLAWAR2_PRELIM 0x80000010 /* Access window size 128K */ - /* local bus read write buffer mapping */ #define CFG_BR3_PRELIM 0xFA000801 /* map at 0xFA000000 */ #define CFG_OR3_PRELIM 0xFFFF8FF7 /* 32kB */ #define CFG_LBLAWBAR3_PRELIM 0xFA000000 #define CFG_LBLAWAR3_PRELIM 0x8000000E /* 32KB */ +/* Vitesse 7385 */ + +#define CFG_VSC7385_BASE 0xF0000000 + +#ifdef CONFIG_VSC7385_ENET + +#define CFG_BR2_PRELIM 0xf0000801 /* VSC7385 Base address */ +#define CFG_OR2_PRELIM 0xfffe09ff /* VSC7385, 128K bytes*/ +#define CFG_LBLAWBAR2_PRELIM CFG_VSC7385_BASE/* Access window base at VSC7385 base */ +#define CFG_LBLAWAR2_PRELIM 0x80000010 /* Access window size 128K */ + +#endif + /* pass open firmware flat tree */ #define CONFIG_OF_LIBFDT 1 #define CONFIG_OF_BOARD_SETUP 1 @@ -263,13 +292,6 @@ #define CFG_I2C_OFFSET 0x3000 #define CFG_I2C2_OFFSET 0x3100 -/* TSEC */ -#define CFG_TSEC1_OFFSET 0x24000 -#define CFG_TSEC1 (CFG_IMMR+CFG_TSEC1_OFFSET) -#define CFG_TSEC2_OFFSET 0x25000 -#define CFG_TSEC2 (CFG_IMMR+CFG_TSEC2_OFFSET) -#define CONFIG_NET_MULTI - /* * General PCI * Addresses are mapped 1-1. @@ -288,26 +310,31 @@ #define CFG_PCI_SUBSYS_VENDORID 0x1057 /* Motorola */ /* - * TSEC configuration + * TSEC */ #define CONFIG_TSEC_ENET /* TSEC ethernet support */ -#ifndef CONFIG_NET_MULTI -#define CONFIG_NET_MULTI 1 +#define CONFIG_NET_MULTI +#define CONFIG_GMII /* MII PHY management */ + +#ifdef CONFIG_TSEC1 +#define CONFIG_HAS_ETH0 +#define CONFIG_TSEC1_NAME "TSEC0" +#define CFG_TSEC1_OFFSET 0x24000 +#define TSEC1_PHY_ADDR 0x1c +#define TSEC1_FLAGS TSEC_GIGABIT +#define TSEC1_PHYIDX 0 #endif -#define CONFIG_GMII 1 /* MII PHY management */ -#define CONFIG_TSEC1 1 - -#define CONFIG_TSEC1_NAME "TSEC0" -#define CONFIG_TSEC2 1 +#ifdef CONFIG_TSEC2 +#define CONFIG_HAS_ETH1 #define CONFIG_TSEC2_NAME "TSEC1" -#define TSEC1_PHY_ADDR 0x1c -#define TSEC2_PHY_ADDR 4 -#define TSEC1_FLAGS TSEC_GIGABIT -#define TSEC2_FLAGS TSEC_GIGABIT -#define TSEC1_PHYIDX 0 -#define TSEC2_PHYIDX 0 +#define CFG_TSEC2_OFFSET 0x25000 +#define TSEC2_PHY_ADDR 4 +#define TSEC2_FLAGS TSEC_GIGABIT +#define TSEC2_PHYIDX 0 +#endif + /* Options are: TSEC[0-1] */ #define CONFIG_ETHPRIME "TSEC1" @@ -496,10 +523,13 @@ */ #define CONFIG_ENV_OVERWRITE +#ifdef CONFIG_HAS_ETH0 #define CONFIG_ETHADDR 00:E0:0C:00:95:01 -#define CONFIG_HAS_ETH1 -#define CONFIG_HAS_ETH0 +#endif + +#ifdef CONFIG_HAS_ETH1 #define CONFIG_ETH1ADDR 00:E0:0C:00:95:02 +#endif #define CONFIG_IPADDR 10.0.0.2 #define CONFIG_SERVERIP 10.0.0.1 diff --git a/include/configs/MPC8315ERDB.h b/include/configs/MPC8315ERDB.h index ff7101f24..af7872628 100644 --- a/include/configs/MPC8315ERDB.h +++ b/include/configs/MPC8315ERDB.h @@ -299,7 +299,7 @@ #define CFG_PCI_MMIO_BASE 0x90000000 #define CFG_PCI_MMIO_PHYS CFG_PCI_MMIO_BASE #define CFG_PCI_MMIO_SIZE 0x10000000 /* 256M */ -#define CFG_PCI_IO_BASE 0xE0300000 +#define CFG_PCI_IO_BASE 0x00000000 #define CFG_PCI_IO_PHYS 0xE0300000 #define CFG_PCI_IO_SIZE 0x100000 /* 1M */ diff --git a/include/configs/MPC8323ERDB.h b/include/configs/MPC8323ERDB.h index bf5ef4b59..94c4c6b04 100644 --- a/include/configs/MPC8323ERDB.h +++ b/include/configs/MPC8323ERDB.h @@ -65,6 +65,13 @@ */ #define CFG_IMMR 0xE0000000 +/* + * System performance + */ +#define CFG_ACR_PIPE_DEP 3 /* Arbiter pipeline depth (0-3) */ +#define CFG_ACR_RPTCNT 3 /* Arbiter repeat count (0-7) */ +#define CFG_SPCR_OPT 1 /* (0-1) Optimize transactions between CSB and the SEC and QUICC Engine block */ + /* * DDR Setup */ @@ -82,17 +89,51 @@ /* Manually set up DDR parameters */ #define CFG_DDR_SIZE 64 /* MB */ -#define CFG_DDR_CS0_CONFIG 0x80840101 -#define CFG_DDR_TIMING_0 0x00220802 -#define CFG_DDR_TIMING_1 0x3935d322 -#define CFG_DDR_TIMING_2 0x0f9048ca +#define CFG_DDR_CS0_CONFIG ( CSCONFIG_EN \ + | CSCONFIG_ODT_WR_ACS \ + | CSCONFIG_ROW_BIT_13 | CSCONFIG_COL_BIT_9 ) + /* 0x80010101 */ +#define CFG_DDR_TIMING_0 ( ( 0 << TIMING_CFG0_RWT_SHIFT ) \ + | ( 0 << TIMING_CFG0_WRT_SHIFT ) \ + | ( 0 << TIMING_CFG0_RRT_SHIFT ) \ + | ( 0 << TIMING_CFG0_WWT_SHIFT ) \ + | ( 2 << TIMING_CFG0_ACT_PD_EXIT_SHIFT ) \ + | ( 2 << TIMING_CFG0_PRE_PD_EXIT_SHIFT ) \ + | ( 8 << TIMING_CFG0_ODT_PD_EXIT_SHIFT ) \ + | ( 2 << TIMING_CFG0_MRS_CYC_SHIFT ) ) + /* 0x00220802 */ +#define CFG_DDR_TIMING_1 ( ( 2 << TIMING_CFG1_PRETOACT_SHIFT ) \ + | ( 6 << TIMING_CFG1_ACTTOPRE_SHIFT ) \ + | ( 2 << TIMING_CFG1_ACTTORW_SHIFT ) \ + | ( 5 << TIMING_CFG1_CASLAT_SHIFT ) \ + | ( 3 << TIMING_CFG1_REFREC_SHIFT ) \ + | ( 2 << TIMING_CFG1_WRREC_SHIFT ) \ + | ( 2 << TIMING_CFG1_ACTTOACT_SHIFT ) \ + | ( 2 << TIMING_CFG1_WRTORD_SHIFT ) ) + /* 0x26253222 */ +#define CFG_DDR_TIMING_2 ( ( 1 << TIMING_CFG2_ADD_LAT_SHIFT ) \ + | (31 << TIMING_CFG2_CPO_SHIFT ) \ + | ( 2 << TIMING_CFG2_WR_LAT_DELAY_SHIFT ) \ + | ( 2 << TIMING_CFG2_RD_TO_PRE_SHIFT ) \ + | ( 2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT ) \ + | ( 3 << TIMING_CFG2_CKE_PLS_SHIFT ) \ + | ( 7 << TIMING_CFG2_FOUR_ACT_SHIFT) ) + /* 0x1f9048c7 */ #define CFG_DDR_TIMING_3 0x00000000 -#define CFG_DDR_CLK_CNTL 0x02000000 -#define CFG_DDR_MODE 0x44400232 +#define CFG_DDR_CLK_CNTL DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05 + /* 0x02000000 */ +#define CFG_DDR_MODE ( ( 0x4448 << SDRAM_MODE_ESD_SHIFT ) \ + | ( 0x0232 << SDRAM_MODE_SD_SHIFT ) ) + /* 0x44480232 */ #define CFG_DDR_MODE2 0x8000c000 -#define CFG_DDR_INTERVAL 0x03200064 +#define CFG_DDR_INTERVAL ( ( 800 << SDRAM_INTERVAL_REFINT_SHIFT ) \ + | ( 100 << SDRAM_INTERVAL_BSTOPRE_SHIFT ) ) + /* 0x03200064 */ #define CFG_DDR_CS0_BNDS 0x00000003 -#define CFG_DDR_SDRAM_CFG 0x43080000 +#define CFG_DDR_SDRAM_CFG ( SDRAM_CFG_SREN \ + | SDRAM_CFG_SDRAM_TYPE_DDR2 \ + | SDRAM_CFG_32_BE ) + /* 0x43080000 */ #define CFG_DDR_SDRAM_CFG2 0x00401000 #endif @@ -280,10 +321,10 @@ #define CFG_I2C_OFFSET 0x3000 /* - * Config on-board RTC + * Config on-board EEPROM */ -#define CONFIG_RTC_DS1374 /* use ds1374 rtc via i2c */ -#define CFG_I2C_RTC_ADDR 0x68 /* at address 0x68 */ +#define CFG_I2C_EEPROM_ADDR 0x50 +#define CFG_I2C_EEPROM_ADDR_LEN 2 /* * General PCI @@ -376,6 +417,7 @@ #define CONFIG_CMD_PING #define CONFIG_CMD_I2C +#define CONFIG_CMD_EEPROM #define CONFIG_CMD_ASKENV #if defined(CONFIG_PCI) diff --git a/include/configs/MPC832XEMDS.h b/include/configs/MPC832XEMDS.h index f32c4f70c..be2ab4558 100644 --- a/include/configs/MPC832XEMDS.h +++ b/include/configs/MPC832XEMDS.h @@ -346,7 +346,7 @@ #define CFG_PCI_MMIO_BASE 0x90000000 #define CFG_PCI_MMIO_PHYS CFG_PCI_MMIO_BASE #define CFG_PCI_MMIO_SIZE 0x10000000 /* 256M */ -#define CFG_PCI_IO_BASE 0xE0300000 +#define CFG_PCI_IO_BASE 0x00000000 #define CFG_PCI_IO_PHYS 0xE0300000 #define CFG_PCI_IO_SIZE 0x100000 /* 1M */ diff --git a/include/configs/MPC8349ITX.h b/include/configs/MPC8349ITX.h index 48c2736fc..6b8b74dd9 100644 --- a/include/configs/MPC8349ITX.h +++ b/include/configs/MPC8349ITX.h @@ -68,12 +68,16 @@ #define CFG_IMMR 0xE0000000 /* The IMMR is relocated to here */ +#define CONFIG_MISC_INIT_F +#define CONFIG_MISC_INIT_R -/* On-board devices */ +/* + * On-board devices + */ #ifdef CONFIG_MPC8349ITX #define CONFIG_COMPACT_FLASH /* The CF card interface on the back of the board */ -#define CONFIG_VSC7385 /* The Vitesse 7385 5-port switch */ +#define CONFIG_VSC7385_ENET /* VSC7385 ethernet support */ #endif #define CONFIG_PCI @@ -88,9 +92,6 @@ /* I2C */ #ifdef CONFIG_HARD_I2C -#define CONFIG_MISC_INIT_F -#define CONFIG_MISC_INIT_R - #define CONFIG_FSL_I2C #define CONFIG_I2C_MULTI_BUS #define CONFIG_I2C_CMD_TREE @@ -155,7 +156,7 @@ #define CFG_MEMTEST_END 0x2000 #define CFG_DDR_SDRAM_CLK_CNTL (DDR_SDRAM_CLK_CNTL_SS_EN | \ - DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05) + DDR_SDRAM_CLK_CNTL_CLK_ADJUST_075) #ifdef CONFIG_HARD_I2C #define CONFIG_SPD_EEPROM /* use SPD EEPROM for DDR setup*/ @@ -190,6 +191,18 @@ boards, we say we have two, but don't display a message if we find only one. */ #define CFG_FLASH_SIZE 16 /* FLASH size in MB */ #define CFG_FLASH_SIZE_SHIFT 4 /* log2 of the above value */ +/* Vitesse 7385 */ + +#ifdef CONFIG_VSC7385_ENET + +#define CONFIG_TSEC2 + +/* The flash address and size of the VSC7385 firmware image */ +#define CONFIG_VSC7385_IMAGE 0xFEFFE000 +#define CONFIG_VSC7385_IMAGE_SIZE 8192 + +#endif + /* * BRx, ORx, LBLAWBARx, and LBLAWARx */ @@ -205,10 +218,10 @@ boards, we say we have two, but don't display a message if we find only one. */ /* Vitesse 7385 */ -#ifdef CONFIG_VSC7385 - #define CFG_VSC7385_BASE 0xF8000000 +#ifdef CONFIG_VSC7385_ENET + #define CFG_BR1_PRELIM (CFG_VSC7385_BASE | BR_PS_8 | BR_V) #define CFG_OR1_PRELIM (OR_AM_128KB | OR_GPCM_CSNT | OR_GPCM_XACS | \ OR_GPCM_SCY_15 | OR_GPCM_SETA | OR_GPCM_TRLX | \ @@ -384,7 +397,7 @@ boards, we say we have two, but don't display a message if we find only one. */ #define CONFIG_HAS_ETH1 #define CONFIG_TSEC2_NAME "TSEC1" #define CFG_TSEC2_OFFSET 0x25000 -#define CONFIG_UNKNOWN_TSEC /* TSEC2 is proprietary */ + #define TSEC2_PHY_ADDR 4 #define TSEC2_PHYIDX 0 #define TSEC2_FLAGS TSEC_GIGABIT @@ -619,11 +632,11 @@ boards, we say we have two, but don't display a message if we find only one. */ */ #define CONFIG_ENV_OVERWRITE -#ifdef CONFIG_TSEC1 +#ifdef CONFIG_HAS_ETH0 #define CONFIG_ETHADDR 00:E0:0C:00:8C:01 #endif -#ifdef CONFIG_TSEC2 +#ifdef CONFIG_HAS_ETH1 #define CONFIG_ETH1ADDR 00:E0:0C:00:8C:02 #endif diff --git a/include/configs/MPC8360EMDS.h b/include/configs/MPC8360EMDS.h index c8dcbc628..46451c4c9 100644 --- a/include/configs/MPC8360EMDS.h +++ b/include/configs/MPC8360EMDS.h @@ -194,6 +194,7 @@ #define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ #define CFG_FLASH_BASE 0xFE000000 /* FLASH base address */ #define CFG_FLASH_SIZE 32 /* max FLASH size is 32M */ +#define CONFIG_FLASH_SHOW_PROGRESS 45 /* count down from 45/5: 9..1 */ #define CFG_LBLAWBAR0_PRELIM CFG_FLASH_BASE /* Window base at flash base */ #define CFG_LBLAWAR0_PRELIM 0x80000018 /* 32MB window size */ @@ -374,7 +375,7 @@ #define CFG_PCI_MMIO_BASE 0x90000000 #define CFG_PCI_MMIO_PHYS CFG_PCI_MMIO_BASE #define CFG_PCI_MMIO_SIZE 0x10000000 /* 256M */ -#define CFG_PCI_IO_BASE 0xE0300000 +#define CFG_PCI_IO_BASE 0x00000000 #define CFG_PCI_IO_PHYS 0xE0300000 #define CFG_PCI_IO_SIZE 0x100000 /* 1M */ diff --git a/include/configs/MPC8360ERDK.h b/include/configs/MPC8360ERDK.h index 27b037ad0..a4f6af673 100644 --- a/include/configs/MPC8360ERDK.h +++ b/include/configs/MPC8360ERDK.h @@ -30,8 +30,8 @@ * System Clock Setup */ #ifdef CONFIG_CLKIN_33MHZ -#define CONFIG_83XX_CLKIN 33000000 -#define CONFIG_SYS_CLK_FREQ 33000000 +#define CONFIG_83XX_CLKIN 33333333 +#define CONFIG_SYS_CLK_FREQ 33333333 #define PCI_33M 1 #define HRCWL_CSB_TO_CLKIN_MPC8360ERDK HRCWL_CSB_TO_CLKIN_10X1 #else @@ -89,8 +89,8 @@ #define CFG_83XX_DDR_USES_CS0 -#undef CONFIG_DDR_ECC /* support DDR ECC function */ -#undef CONFIG_DDR_ECC_CMD /* Use DDR ECC user commands */ +#define CONFIG_DDR_ECC /* support DDR ECC function */ +#define CONFIG_DDR_ECC_CMD /* Use DDR ECC user commands */ /* * DDRCDR - DDR Control Driver Register @@ -104,20 +104,44 @@ */ #define CONFIG_DDR_II #define CFG_DDR_SIZE 256 /* MB */ -#define CFG_DDRCDR 0x80080001 #define CFG_DDR_CS0_BNDS 0x0000000f #define CFG_DDR_CS0_CONFIG (CSCONFIG_EN | CSCONFIG_ROW_BIT_13 | \ - CSCONFIG_COL_BIT_10) -#define CFG_DDR_TIMING_0 0x00330903 -#define CFG_DDR_TIMING_1 0x3835a322 -#define CFG_DDR_TIMING_2 0x00104909 -#define CFG_DDR_TIMING_3 0x00000000 -#define CFG_DDR_CLK_CNTL 0x02000000 + CSCONFIG_COL_BIT_10 | CSCONFIG_ODT_WR_ACS) +#define CFG_DDR_SDRAM_CFG (SDRAM_CFG_SDRAM_TYPE_DDR2 | SDRAM_CFG_ECC_EN) +#define CFG_DDR_SDRAM_CFG2 0x00001000 +#define CFG_DDR_CLK_CNTL (DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05) +#define CFG_DDR_INTERVAL ((256 << SDRAM_INTERVAL_BSTOPRE_SHIFT) | \ + (1115 << SDRAM_INTERVAL_REFINT_SHIFT)) #define CFG_DDR_MODE 0x47800432 #define CFG_DDR_MODE2 0x8000c000 -#define CFG_DDR_INTERVAL 0x045b0100 -#define CFG_DDR_SDRAM_CFG 0x03000000 -#define CFG_DDR_SDRAM_CFG2 0x00001000 + +#define CFG_DDR_TIMING_0 ((2 << TIMING_CFG0_MRS_CYC_SHIFT) | \ + (9 << TIMING_CFG0_ODT_PD_EXIT_SHIFT) | \ + (3 << TIMING_CFG0_PRE_PD_EXIT_SHIFT) | \ + (3 << TIMING_CFG0_ACT_PD_EXIT_SHIFT) | \ + (0 << TIMING_CFG0_WWT_SHIFT) | \ + (0 << TIMING_CFG0_RRT_SHIFT) | \ + (0 << TIMING_CFG0_WRT_SHIFT) | \ + (0 << TIMING_CFG0_RWT_SHIFT)) + +#define CFG_DDR_TIMING_1 (( TIMING_CFG1_CASLAT_30) | \ + ( 2 << TIMING_CFG1_WRTORD_SHIFT) | \ + ( 2 << TIMING_CFG1_ACTTOACT_SHIFT) | \ + ( 3 << TIMING_CFG1_WRREC_SHIFT) | \ + (10 << TIMING_CFG1_REFREC_SHIFT) | \ + ( 3 << TIMING_CFG1_ACTTORW_SHIFT) | \ + ( 8 << TIMING_CFG1_ACTTOPRE_SHIFT) | \ + ( 3 << TIMING_CFG1_PRETOACT_SHIFT)) + +#define CFG_DDR_TIMING_2 ((9 << TIMING_CFG2_FOUR_ACT_SHIFT) | \ + (4 << TIMING_CFG2_CKE_PLS_SHIFT) | \ + (2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT) | \ + (2 << TIMING_CFG2_RD_TO_PRE_SHIFT) | \ + (2 << TIMING_CFG2_WR_LAT_DELAY_SHIFT) | \ + (0 << TIMING_CFG2_ADD_LAT_SHIFT) | \ + (0 << TIMING_CFG2_CPO_SHIFT)) + +#define CFG_DDR_TIMING_3 0x00000000 /* * Memory test @@ -184,6 +208,11 @@ * NAND flash on the local bus */ #define CFG_NAND_BASE 0x60000000 +#define CONFIG_CMD_NAND 1 +#define CONFIG_NAND_FSL_UPM 1 +#define CFG_MAX_NAND_DEVICE 1 +#define NAND_MAX_CHIPS 1 +#define CONFIG_MTD_NAND_VERIFY_WRITE #define CFG_LBLAWBAR1_PRELIM CFG_NAND_BASE #define CFG_LBLAWAR1_PRELIM 0x8000001b /* Access window size 4K */ @@ -230,6 +259,7 @@ /* Pass open firmware flat tree */ #define CONFIG_OF_LIBFDT 1 #define CONFIG_OF_BOARD_SETUP 1 +#define CONFIG_OF_STDOUT_VIA_ALIAS /* I2C */ #define CONFIG_HARD_I2C /* I2C with hardware support */ @@ -290,7 +320,7 @@ #define CFG_UEC1_TX_CLK QE_CLK9 #define CFG_UEC1_ETH_TYPE GIGA_ETH #define CFG_UEC1_PHY_ADDR 2 -#define CFG_UEC1_INTERFACE_MODE ENET_1000_GMII +#define CFG_UEC1_INTERFACE_MODE ENET_1000_RGMII_RXID #endif #define CONFIG_UEC_ETH2 /* GETH2 */ @@ -301,7 +331,7 @@ #define CFG_UEC2_TX_CLK QE_CLK4 #define CFG_UEC2_ETH_TYPE GIGA_ETH #define CFG_UEC2_PHY_ADDR 4 -#define CFG_UEC2_INTERFACE_MODE ENET_1000_GMII +#define CFG_UEC2_INTERFACE_MODE ENET_1000_RGMII_RXID #endif /* @@ -340,6 +370,7 @@ #define CONFIG_CMD_PING #define CONFIG_CMD_I2C #define CONFIG_CMD_ASKENV +#define CONFIG_CMD_DHCP #if defined(CONFIG_PCI) #define CONFIG_CMD_PCI @@ -499,27 +530,44 @@ "consoledev=ttyS0\0"\ "loadaddr=a00000\0"\ "fdtaddr=900000\0"\ - "bootfile=uImage\0"\ "fdtfile=dtb\0"\ "fsfile=fs\0"\ "ubootfile=u-boot.bin\0"\ + "mtdparts=mtdparts=60000000.nand-flash:4096k(kernel),128k(dtb),-(rootfs)\0"\ "setbootargs=setenv bootargs console=$consoledev,$baudrate "\ "$mtdparts panic=1\0"\ "adddhcpargs=setenv bootargs $bootargs ip=on\0"\ "addnfsargs=setenv bootargs $bootargs ip=$ipaddr:$serverip:"\ "$gatewayip:$netmask:$hostname:$netdev:off "\ "root=/dev/nfs rw nfsroot=$serverip:$rootpath\0"\ + "addnandargs=setenv bootargs $bootargs root=/dev/mtdblock3 "\ + "rootfstype=jffs2 rw\0"\ "tftp_get_uboot=tftp 100000 $ubootfile\0"\ "tftp_get_kernel=tftp $loadaddr $bootfile\0"\ "tftp_get_dtb=tftp $fdtaddr $fdtfile\0"\ "tftp_get_fs=tftp c00000 $fsfile\0"\ + "nand_erase_kernel=nand erase 0 400000\0"\ + "nand_erase_dtb=nand erase 400000 20000\0"\ + "nand_erase_fs=nand erase 420000 3be0000\0"\ + "nand_write_kernel=nand write.jffs2 $loadaddr 0 400000\0"\ + "nand_write_dtb=nand write.jffs2 $fdtaddr 400000 20000\0"\ + "nand_write_fs=nand write.jffs2 c00000 420000 $filesize\0"\ + "nand_read_kernel=nand read.jffs2 $loadaddr 0 400000\0"\ + "nand_read_dtb=nand read.jffs2 $fdtaddr 400000 20000\0"\ "nor_reflash=protect off ff800000 ff87ffff ; erase ff800000 ff87ffff ; "\ "cp.b 100000 ff800000 $filesize\0"\ + "nand_reflash_kernel=run tftp_get_kernel nand_erase_kernel "\ + "nand_write_kernel\0"\ + "nand_reflash_dtb=run tftp_get_dtb nand_erase_dtb nand_write_dtb\0"\ + "nand_reflash_fs=run tftp_get_fs nand_erase_fs nand_write_fs\0"\ + "nand_reflash=run nand_reflash_kernel nand_reflash_dtb "\ + "nand_reflash_fs\0"\ "boot_m=bootm $loadaddr - $fdtaddr\0"\ - "dhcpboot=run setbootargs adddhcpargs tftp_get_kernel tftp_get_dtb "\ - "boot_m\0"\ + "dhcpboot=dhcp ; run setbootargs adddhcpargs tftp_get_dtb boot_m\0"\ "nfsboot=run setbootargs addnfsargs tftp_get_kernel tftp_get_dtb "\ - "boot_m\0"\ + "boot_m\0"\ + "nandboot=run setbootargs addnandargs nand_read_kernel nand_read_dtb "\ + "boot_m\0"\ "" #define CONFIG_BOOTCOMMAND "run dhcpboot" diff --git a/include/configs/MPC837XEMDS.h b/include/configs/MPC837XEMDS.h index 5586533de..b307bf71e 100644 --- a/include/configs/MPC837XEMDS.h +++ b/include/configs/MPC837XEMDS.h @@ -338,7 +338,7 @@ #define CFG_PCI_MMIO_BASE 0x90000000 #define CFG_PCI_MMIO_PHYS CFG_PCI_MMIO_BASE #define CFG_PCI_MMIO_SIZE 0x10000000 /* 256M */ -#define CFG_PCI_IO_BASE 0xE0300000 +#define CFG_PCI_IO_BASE 0x00000000 #define CFG_PCI_IO_PHYS 0xE0300000 #define CFG_PCI_IO_SIZE 0x100000 /* 1M */ diff --git a/include/configs/MPC837XERDB.h b/include/configs/MPC837XERDB.h index 1964946ec..90812e92a 100644 --- a/include/configs/MPC837XERDB.h +++ b/include/configs/MPC837XERDB.h @@ -32,6 +32,15 @@ #define CONFIG_PCI 1 +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_MISC_INIT_R + +/* + * On-board devices + */ +#define CONFIG_TSEC_ENET /* TSEC Ethernet support */ +#define CONFIG_VSC7385_ENET + /* * System Clock Setup */ @@ -117,6 +126,22 @@ */ #define CFG_IMMR 0xE0000000 +/* + * Device configurations + */ + +/* Vitesse 7385 */ + +#ifdef CONFIG_VSC7385_ENET + +#define CONFIG_TSEC2 + +/* The flash address and size of the VSC7385 firmware image */ +#define CONFIG_VSC7385_IMAGE 0xFE7FE000 +#define CONFIG_VSC7385_IMAGE_SIZE 8192 + +#endif + /* * DDR Setup */ @@ -251,15 +276,38 @@ #define CFG_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */ #define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ +/* + * NAND Flash on the Local Bus + */ +#define CFG_NAND_BASE 0xE0600000 /* 0xE0600000 */ +#define CFG_BR1_PRELIM (CFG_NAND_BASE | \ + (2 << BR_DECC_SHIFT) | /* Use HW ECC */ \ + BR_PS_8 | /* Port Size = 8 bit */ \ + BR_MS_FCM | /* MSEL = FCM */ \ + BR_V) /* valid */ +#define CFG_OR1_PRELIM (0xFFFF8000 | /* length 32K */ \ + OR_FCM_CSCT | \ + OR_FCM_CST | \ + OR_FCM_CHT | \ + OR_FCM_SCY_1 | \ + OR_FCM_TRLX | \ + OR_FCM_EHTR) +#define CFG_LBLAWBAR1_PRELIM CFG_NAND_BASE +#define CFG_LBLAWAR1_PRELIM 0x8000000E /* 32KB */ + +/* Vitesse 7385 */ + #define CFG_VSC7385_BASE 0xF0000000 -/* VSC7385 Gigabit Switch support */ -#define CONFIG_VSC7385_ENET +#ifdef CONFIG_VSC7385_ENET + #define CFG_BR2_PRELIM 0xf0000801 /* Base address */ #define CFG_OR2_PRELIM 0xfffe09ff /* 128K bytes*/ #define CFG_LBLAWBAR2_PRELIM CFG_VSC7385_BASE /* Access Base */ #define CFG_LBLAWAR2_PRELIM 0x80000010 /* Access Size 128K */ +#endif + /* * Serial Port */ @@ -276,6 +324,11 @@ #define CFG_NS16550_COM1 (CFG_IMMR+0x4500) #define CFG_NS16550_COM2 (CFG_IMMR+0x4600) +/* SERDES */ +#define CONFIG_FSL_SERDES +#define CONFIG_FSL_SERDES1 0xe3000 +#define CONFIG_FSL_SERDES2 0xe3100 + /* Use the HUSH parser */ #define CFG_HUSH_PARSER #ifdef CFG_HUSH_PARSER @@ -285,6 +338,7 @@ /* Pass open firmware flat tree */ #define CONFIG_OF_LIBFDT 1 #define CONFIG_OF_BOARD_SETUP 1 +#define CONFIG_OF_STDOUT_VIA_ALIAS 1 /* I2C */ #define CONFIG_HARD_I2C /* I2C with hardware support */ @@ -312,7 +366,7 @@ #define CFG_PCI_MMIO_BASE 0x90000000 #define CFG_PCI_MMIO_PHYS CFG_PCI_MMIO_BASE #define CFG_PCI_MMIO_SIZE 0x10000000 /* 256M */ -#define CFG_PCI_IO_BASE 0xE0300000 +#define CFG_PCI_IO_BASE 0x00000000 #define CFG_PCI_IO_PHYS 0xE0300000 #define CFG_PCI_IO_SIZE 0x100000 /* 1M */ @@ -324,43 +378,43 @@ #define CONFIG_NET_MULTI #define CONFIG_PCI_PNP /* do pci plug-and-play */ -#undef CONFIG_EEPRO100 #undef CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ #define CFG_PCI_SUBSYS_VENDORID 0x1957 /* Freescale */ #endif /* CONFIG_PCI */ -#ifndef CONFIG_NET_MULTI -#define CONFIG_NET_MULTI 1 -#endif - /* * TSEC */ -#define CONFIG_TSEC_ENET /* TSEC ethernet support */ -#define CFG_TSEC1_OFFSET 0x24000 -#define CFG_TSEC1 (CFG_IMMR+CFG_TSEC1_OFFSET) -#define CFG_TSEC2_OFFSET 0x25000 -#define CFG_TSEC2 (CFG_IMMR+CFG_TSEC2_OFFSET) +#ifdef CONFIG_TSEC_ENET -/* - * TSEC ethernet configuration - */ -#define CONFIG_GMII 1 /* MII PHY management */ -#define CONFIG_TSEC1 1 +#define CONFIG_NET_MULTI +#define CONFIG_GMII /* MII PHY management */ + +#define CONFIG_TSEC1 + +#ifdef CONFIG_TSEC1 +#define CONFIG_HAS_ETH0 #define CONFIG_TSEC1_NAME "TSEC0" -#define CONFIG_TSEC2 1 -#define CONFIG_TSEC2_NAME "TSEC1" +#define CFG_TSEC1_OFFSET 0x24000 #define TSEC1_PHY_ADDR 2 -#define TSEC2_PHY_ADDR 0x1c #define TSEC1_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) -#define TSEC2_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) #define TSEC1_PHYIDX 0 -#define TSEC2_PHYIDX 0 +#endif +#ifdef CONFIG_TSEC2 +#define CONFIG_HAS_ETH1 +#define CONFIG_TSEC2_NAME "TSEC1" +#define CFG_TSEC2_OFFSET 0x25000 +#define TSEC2_PHY_ADDR 0x1c +#define TSEC2_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) +#define TSEC2_PHYIDX 0 +#endif /* Options are: TSEC[0-1] */ #define CONFIG_ETHPRIME "TSEC0" +#endif + /* * Environment */ @@ -529,10 +583,15 @@ */ #define CONFIG_ENV_OVERWRITE -#define CONFIG_HAS_ETH0 /* add support for "ethaddr" */ -#define CONFIG_ETHADDR 00:04:9f:ef:04:01 -#define CONFIG_HAS_ETH1 /* add support for "eth1addr" */ -#define CONFIG_ETH1ADDR 00:04:9f:ef:04:02 +#ifdef CONFIG_HAS_ETH0 +#define CONFIG_ETHADDR 00:04:9f:ef:04:01 +#endif + +#ifdef CONFIG_HAS_ETH1 +#define CONFIG_ETH1ADDR 00:04:9f:ef:04:02 +#endif + +#define CONFIG_HAS_FSL_DR_USB #define CONFIG_IPADDR 10.0.0.2 #define CONFIG_SERVERIP 10.0.0.1 diff --git a/include/configs/MPC8540ADS.h b/include/configs/MPC8540ADS.h index 5ea7b2504..85934d718 100644 --- a/include/configs/MPC8540ADS.h +++ b/include/configs/MPC8540ADS.h @@ -100,6 +100,7 @@ */ #define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ #define CFG_CCSRBAR 0xe0000000 /* relocated CCSRBAR */ +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR /* physical addr of CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ diff --git a/include/configs/MPC8540EVAL.h b/include/configs/MPC8540EVAL.h index 174215c2c..77eea7378 100644 --- a/include/configs/MPC8540EVAL.h +++ b/include/configs/MPC8540EVAL.h @@ -83,6 +83,7 @@ */ #define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ #define CFG_CCSRBAR 0xe0000000 /* relocated CCSRBAR */ +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR /* physical addr of CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ #define CFG_DDR_SDRAM_BASE 0x00000000 /* DDR is system memory */ diff --git a/include/configs/MPC8541CDS.h b/include/configs/MPC8541CDS.h index 7334088b1..3f3f741ad 100644 --- a/include/configs/MPC8541CDS.h +++ b/include/configs/MPC8541CDS.h @@ -49,6 +49,9 @@ #define CONFIG_FSL_LAW 1 /* Use common FSL init code */ +#define CONFIG_FSL_VIA +#define CONFIG_FSL_CDS_EEPROM + /* * When initializing flash, if we cannot find the manufacturer ID, * assume this is the AMD flash associated with the CDS board. @@ -82,6 +85,7 @@ extern unsigned long get_clock_freq(void); */ #define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ #define CFG_CCSRBAR 0xe0000000 /* relocated CCSRBAR */ +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR /* physical addr of CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ /* @@ -273,6 +277,8 @@ extern unsigned long get_clock_freq(void); * 1111 1111 1111 0000 0000 1111 1111 0111 = fff00ff7 */ +#define CONFIG_FSL_CADMUS + #define CADMUS_BASE_ADDR 0xf8000000 #define CFG_BR3_PRELIM 0xf8000801 #define CFG_OR3_PRELIM 0xfff00ff7 diff --git a/include/configs/MPC8544DS.h b/include/configs/MPC8544DS.h index a8942095c..c83d9e25d 100644 --- a/include/configs/MPC8544DS.h +++ b/include/configs/MPC8544DS.h @@ -98,6 +98,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); */ #define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ #define CFG_CCSRBAR 0xe0000000 /* relocated CCSRBAR */ +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR /* physical addr of CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ #define CFG_PCI1_ADDR (CFG_CCSRBAR+0x8000) diff --git a/include/configs/MPC8548CDS.h b/include/configs/MPC8548CDS.h index a3db9f445..fc8ad8813 100644 --- a/include/configs/MPC8548CDS.h +++ b/include/configs/MPC8548CDS.h @@ -57,6 +57,9 @@ #define CONFIG_FSL_LAW 1 /* Use common FSL init code */ +#define CONFIG_FSL_VIA +#define CONFIG_FSL_CDS_EEPROM + /* * When initializing flash, if we cannot find the manufacturer ID, * assume this is the AMD flash associated with the CDS board. @@ -96,6 +99,7 @@ extern unsigned long get_clock_freq(void); */ #define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ #define CFG_CCSRBAR 0xe0000000 /* relocated CCSRBAR */ +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR /* physical addr of CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ #define CFG_PCI1_ADDR (CFG_CCSRBAR+0x8000) @@ -296,6 +300,8 @@ extern unsigned long get_clock_freq(void); * 1111 1111 1111 0000 0000 1111 1111 0111 = fff00ff7 */ +#define CONFIG_FSL_CADMUS + #define CADMUS_BASE_ADDR 0xf8000000 #define CFG_BR3_PRELIM 0xf8000801 #define CFG_OR3_PRELIM 0xfff00ff7 diff --git a/include/configs/MPC8555CDS.h b/include/configs/MPC8555CDS.h index 93877aedb..500b57cec 100644 --- a/include/configs/MPC8555CDS.h +++ b/include/configs/MPC8555CDS.h @@ -49,6 +49,9 @@ #define CONFIG_FSL_LAW 1 /* Use common FSL init code */ +#define CONFIG_FSL_VIA +#define CONFIG_FSL_CDS_EEPROM + /* * When initializing flash, if we cannot find the manufacturer ID, * assume this is the AMD flash associated with the CDS board. @@ -82,6 +85,7 @@ extern unsigned long get_clock_freq(void); */ #define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ #define CFG_CCSRBAR 0xe0000000 /* relocated CCSRBAR */ +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR /* physical addr of CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ /* @@ -273,6 +277,8 @@ extern unsigned long get_clock_freq(void); * 1111 1111 1111 0000 0000 1111 1111 0111 = fff00ff7 */ +#define CONFIG_FSL_CADMUS + #define CADMUS_BASE_ADDR 0xf8000000 #define CFG_BR3_PRELIM 0xf8000801 #define CFG_OR3_PRELIM 0xfff00ff7 diff --git a/include/configs/MPC8560ADS.h b/include/configs/MPC8560ADS.h index 08884b36f..e30302c5d 100644 --- a/include/configs/MPC8560ADS.h +++ b/include/configs/MPC8560ADS.h @@ -95,6 +95,7 @@ */ #define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ #define CFG_CCSRBAR 0xe0000000 /* relocated CCSRBAR */ +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR /* physical addr of CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ diff --git a/include/configs/MPC8568MDS.h b/include/configs/MPC8568MDS.h index a12d193c7..7bb20e58c 100644 --- a/include/configs/MPC8568MDS.h +++ b/include/configs/MPC8568MDS.h @@ -90,6 +90,7 @@ extern unsigned long get_clock_freq(void); */ #define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ #define CFG_CCSRBAR 0xe0000000 /* relocated CCSRBAR */ +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR /* physical addr of CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ #define CFG_PCI1_ADDR (CFG_CCSRBAR+0x8000) diff --git a/include/configs/PM854.h b/include/configs/PM854.h index 819bee70a..bd058fc15 100644 --- a/include/configs/PM854.h +++ b/include/configs/PM854.h @@ -92,6 +92,7 @@ */ #define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ #define CFG_CCSRBAR 0xe0000000 /* relocated CCSRBAR */ +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR /* physical addr of CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ diff --git a/include/configs/PM856.h b/include/configs/PM856.h index 8902f42ff..38a26dc8a 100644 --- a/include/configs/PM856.h +++ b/include/configs/PM856.h @@ -94,6 +94,7 @@ */ #define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ #define CFG_CCSRBAR 0xe0000000 /* relocated CCSRBAR */ +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR /* physical addr of CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ diff --git a/include/configs/SBC8540.h b/include/configs/SBC8540.h index 2bbfe9aa6..946b3c2d8 100644 --- a/include/configs/SBC8540.h +++ b/include/configs/SBC8540.h @@ -99,6 +99,7 @@ #else #define CFG_CCSRBAR 0xff700000 /* default CCSRBAR */ #endif +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR /* physical addr of CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ #define CFG_DDR_SDRAM_BASE 0x00000000 /* DDR is system memory */ diff --git a/include/configs/TQM5200.h b/include/configs/TQM5200.h index 9a0e9b84a..b36c8264d 100644 --- a/include/configs/TQM5200.h +++ b/include/configs/TQM5200.h @@ -252,12 +252,22 @@ "setup=tftp 200000 cam5200/setup.img; autoscr 200000\0" #endif +#if defined(CONFIG_TQM5200_B) +#define ENV_FLASH_LAYOUT \ + "fdt_addr=FC100000\0" \ + "kernel_addr=FC140000\0" \ + "ramdisk_addr=FC600000\0" +#else /* !CONFIG_TQM5200_B */ +#define ENV_FLASH_LAYOUT \ + "fdt_addr=FC0A0000\0" \ + "kernel_addr=FC0C0000\0" \ + "ramdisk_addr=FC300000\0" +#endif + #define CONFIG_EXTRA_ENV_SETTINGS \ "netdev=eth0\0" \ "console=ttyPSC0\0" \ - "fdt_addr=FC0A0000\0" \ - "kernel_addr=FC0C0000\0" \ - "ramdisk_addr=FC300000\0" \ + ENV_FLASH_LAYOUT \ "kernel_addr_r=400000\0" \ "fdt_addr_r=600000\0" \ "rootpath=/opt/eldk/ppc_6xx\0" \ @@ -400,8 +410,9 @@ # if defined(CONFIG_TQM5200_B) # if defined(CFG_LOWBOOT) # define MTDPARTS_DEFAULT "mtdparts=TQM5200-0:1m(firmware)," \ - "1536k(kernel)," \ - "3584k(small-fs)," \ + "256k(dtb)," \ + "2304k(kernel)," \ + "2560k(small-fs)," \ "2m(initrd)," \ "8m(misc)," \ "16m(big-fs)" diff --git a/include/configs/TQM85xx.h b/include/configs/TQM85xx.h index 21e8bafc2..fca5f74df 100644 --- a/include/configs/TQM85xx.h +++ b/include/configs/TQM85xx.h @@ -89,6 +89,7 @@ */ #define CFG_CCSRBAR_DEFAULT 0xFF700000 /* CCSRBAR Default */ #define CFG_CCSRBAR 0xE0000000 /* relocated CCSRBAR */ +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR /* physical addr of CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ /* diff --git a/include/configs/pcs440ep.h b/include/configs/pcs440ep.h index 893924b4b..ba6d93224 100644 --- a/include/configs/pcs440ep.h +++ b/include/configs/pcs440ep.h @@ -27,6 +27,12 @@ #ifndef __CONFIG_H #define __CONFIG_H + +/* new uImage format support */ +#define CONFIG_FIT 1 +#define CONFIG_OF_LIBFDT 1 +#define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */ + /*----------------------------------------------------------------------- * High Level Configuration Options *----------------------------------------------------------------------*/ diff --git a/include/configs/sbc8548.h b/include/configs/sbc8548.h index 516203a5d..49a72347f 100644 --- a/include/configs/sbc8548.h +++ b/include/configs/sbc8548.h @@ -87,6 +87,7 @@ */ #define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ #define CFG_CCSRBAR 0xe0000000 /* relocated CCSRBAR */ +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR /* physical addr of CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ #define CFG_PCI1_ADDR (CFG_CCSRBAR+0x8000) diff --git a/include/configs/sbc8560.h b/include/configs/sbc8560.h index f9ede5f18..81a1e072c 100644 --- a/include/configs/sbc8560.h +++ b/include/configs/sbc8560.h @@ -93,6 +93,7 @@ #else #define CFG_CCSRBAR 0xff700000 /* default CCSRBAR */ #endif +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR /* physical addr of CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ #define CFG_DDR_SDRAM_BASE 0x00000000 /* DDR is system memory */ diff --git a/include/configs/sc520_cdp.h b/include/configs/sc520_cdp.h index 8491d97ae..4df461dd9 100644 --- a/include/configs/sc520_cdp.h +++ b/include/configs/sc520_cdp.h @@ -81,8 +81,8 @@ #include #define CONFIG_CMD_PCI +#define CONFIG_CMD_SATA #define CONFIG_CMD_JFFS2 -#define CONFIG_CMD_IDE #define CONFIG_CMD_NET #define CONFIG_CMD_EEPROM @@ -172,37 +172,14 @@ #define CONFIG_PCNET_79C975 #define PCNET_HAS_PROM 1 -/************************************************************ - * IDE/ATA stuff - ************************************************************/ -#define CFG_IDE_MAXBUS 1 /* max. 2 IDE busses */ -#define CFG_IDE_MAXDEVICE (CFG_IDE_MAXBUS*2) /* max. 2 drives per IDE bus */ - -#define CFG_ATA_IDE0_OFFSET 0x01F0 /* ide0 offste */ -/*#define CFG_ATA_IDE1_OFFSET 0x0170 /###* ide1 offset */ -#define CFG_ATA_DATA_OFFSET 0 /* data reg offset */ -#define CFG_ATA_REG_OFFSET 0 /* reg offset */ -#define CFG_ATA_ALT_OFFSET 0x200 /* alternate register offset */ -#define CFG_ATA_BASE_ADDR 0 - -#undef CONFIG_IDE_LED /* no led for ide supported */ -#undef CONFIG_IDE_RESET /* reset for ide unsupported... */ -#undef CONFIG_IDE_RESET_ROUTINE /* no special reset function */ - /************************************************************ *SATA/Native Stuff ************************************************************/ -#define CFG_SATA_SUPPORTED 1 #define CFG_SATA_MAXBUS 2 /*Max Sata buses supported */ #define CFG_SATA_DEVS_PER_BUS 2 /*Max no. of devices per bus/port */ -#define CFG_SATA_MAXDEVICES (CFG_SATA_MAXBUS* CFG_SATA_DEVS_PER_BUS) +#define CFG_SATA_MAX_DEVICE (CFG_SATA_MAXBUS* CFG_SATA_DEVS_PER_BUS) #define CFG_ATA_PIIX 1 /*Supports ata_piix driver */ -/************************************************************ - * ATAPI support (experimental) - ************************************************************/ -#define CONFIG_ATAPI /* enable ATAPI Support */ - /************************************************************ * DISK Partition support ************************************************************/ diff --git a/include/configs/stxgp3.h b/include/configs/stxgp3.h index 047e1cf99..fc5d0cc76 100644 --- a/include/configs/stxgp3.h +++ b/include/configs/stxgp3.h @@ -114,6 +114,7 @@ #define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ #endif #define CFG_CCSRBAR 0xfdf00000 /* relocated CCSRBAR */ +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR /* physical addr of CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ diff --git a/include/configs/stxssa.h b/include/configs/stxssa.h index e09dd7163..15f690af1 100644 --- a/include/configs/stxssa.h +++ b/include/configs/stxssa.h @@ -127,6 +127,7 @@ #define CFG_CCSRBAR_DEFAULT 0xff700000 /* CCSRBAR Default */ #endif #define CFG_CCSRBAR 0xe0000000 /* relocated CCSRBAR */ +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR /* physical addr of CCSRBAR */ #define CFG_IMMR CFG_CCSRBAR /* PQII uses CFG_IMMR */ diff --git a/include/configs/stxxtc.h b/include/configs/stxxtc.h index b035857dc..f12765d66 100644 --- a/include/configs/stxxtc.h +++ b/include/configs/stxxtc.h @@ -594,7 +594,5 @@ typedef unsigned int led_id_t; #define OF_CPU "PowerPC,MPC870@0" #define OF_TBCLK (MPC8XX_HZ / 16) -#define CONFIG_OF_HAS_BD_T 1 -#define CONFIG_OF_HAS_UBOOT_ENV 1 #endif /* __CONFIG_H */ diff --git a/include/fdt_support.h b/include/fdt_support.h index 7836f28cd..890993ff9 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -50,13 +50,11 @@ int fdt_find_and_setprop(void *fdt, const char *node, const char *prop, const void *val, int len, int create); void fdt_fixup_qe_firmware(void *fdt); -#ifdef CONFIG_OF_HAS_UBOOT_ENV -int fdt_env(void *fdt); -#endif - -#ifdef CONFIG_OF_HAS_BD_T -int fdt_bd_t(void *fdt); -#endif +#ifdef CONFIG_HAS_FSL_DR_USB +void fdt_fixup_dr_usb(void *blob, bd_t *bd); +#else +static inline void fdt_fixup_dr_usb(void *blob, bd_t *bd) {} +#endif /* CONFIG_HAS_FSL_DR_USB */ #ifdef CONFIG_OF_BOARD_SETUP void ft_board_setup(void *blob, bd_t *bd); diff --git a/include/fis.h b/include/fis.h new file mode 100644 index 000000000..2040b5095 --- /dev/null +++ b/include/fis.h @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2008 Freescale Semiconductor, Inc. + * Dave Liu + * + * 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 __FIS_H__ +#define __FIS_H__ +/* +* Register - Host to Device FIS +*/ +typedef struct sata_fis_h2d { + u8 fis_type; + u8 pm_port_c; + u8 command; + u8 features; + u8 lba_low; + u8 lba_mid; + u8 lba_high; + u8 device; + u8 lba_low_exp; + u8 lba_mid_exp; + u8 lba_high_exp; + u8 features_exp; + u8 sector_count; + u8 sector_count_exp; + u8 res1; + u8 control; + u8 res2[4]; +} __attribute__ ((packed)) sata_fis_h2d_t; + +/* +* Register - Host to Device FIS for read/write FPDMA queued +*/ +typedef struct sata_fis_h2d_ncq { + u8 fis_type; + u8 pm_port_c; + u8 command; + u8 sector_count_low; + u8 lba_low; + u8 lba_mid; + u8 lba_high; + u8 device; + u8 lba_low_exp; + u8 lba_mid_exp; + u8 lba_high_exp; + u8 sector_count_high; + u8 tag; + u8 res1; + u8 res2; + u8 control; + u8 res3[4]; +} __attribute__ ((packed)) sata_fis_h2d_ncq_t; + +/* +* Register - Device to Host FIS +*/ +typedef struct sata_fis_d2h { + u8 fis_type; + u8 pm_port_i; + u8 status; + u8 error; + u8 lba_low; + u8 lba_mid; + u8 lba_high; + u8 device; + u8 lba_low_exp; + u8 lba_mid_exp; + u8 lba_high_exp; + u8 res1; + u8 sector_count; + u8 sector_count_exp; + u8 res2[2]; + u8 res3[4]; +} __attribute__ ((packed)) sata_fis_d2h_t; + +/* +* DMA Setup - Device to Host or Host to Device FIS +*/ +typedef struct sata_fis_dma_setup { + u8 fis_type; + u8 pm_port_dir_int_act; + u8 res1; + u8 res2; + u32 dma_buffer_id_low; + u32 dma_buffer_id_high; + u32 res3; + u32 dma_buffer_offset; + u32 dma_transfer_count; + u32 res4; +} __attribute__ ((packed)) sata_fis_dma_setup_t; + +/* +* PIO Setup - Device to Host FIS +*/ +typedef struct sata_fis_pio_setup { + u8 fis_type; + u8 pm_port_dir_int; + u8 status; + u8 error; + u8 lba_low; + u8 lba_mid; + u8 lba_high; + u8 res1; + u8 lba_low_exp; + u8 lba_mid_exp; + u8 lba_high_exp; + u8 res2; + u8 sector_count; + u8 sector_count_exp; + u8 res3; + u8 e_status; + u16 transfer_count; + u16 res4; +} __attribute__ ((packed)) sata_fis_pio_setup_t; + +/* +* Data - Host to Device or Device to Host FIS +*/ +typedef struct sata_fis_data { + u8 fis_type; + u8 pm_port; + u8 res1; + u8 res2; + u32 data[2048]; +} __attribute__ ((packed)) sata_fis_data_t; + +/* fis_type - SATA FIS type + */ +enum sata_fis_type { + SATA_FIS_TYPE_REGISTER_H2D = 0x27, + SATA_FIS_TYPE_REGISTER_D2H = 0x34, + SATA_FIS_TYPE_DMA_ACT_D2H = 0x39, + SATA_FIS_TYPE_DMA_SETUP_BI = 0x41, + SATA_FIS_TYPE_DATA_BI = 0x46, + SATA_FIS_TYPE_BIST_ACT_BI = 0x58, + SATA_FIS_TYPE_PIO_SETUP_D2H = 0x5F, + SATA_FIS_TYPE_SET_DEVICE_BITS_D2H = 0xA1, +}; + +#endif /* __FIS_H__ */ diff --git a/include/image.h b/include/image.h index 432fa2239..36143e25a 100644 --- a/include/image.h +++ b/include/image.h @@ -1,4 +1,6 @@ /* + * (C) Copyright 2008 Semihalf + * * (C) Copyright 2000-2005 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * @@ -31,6 +33,34 @@ #ifndef __IMAGE_H__ #define __IMAGE_H__ +#include +#include + +#ifndef USE_HOSTCC +#include +#include +#include + +#else + +/* new uImage format support enabled on host */ +#define CONFIG_FIT 1 +#define CONFIG_OF_LIBFDT 1 +#define CONFIG_FIT_VERBOSE 1 /* enable fit_format_{error,warning}() */ + +#endif /* USE_HOSTCC */ + +#if defined(CONFIG_FIT) && !defined(CONFIG_OF_LIBFDT) +#error "CONFIG_OF_LIBFDT not enabled, required by CONFIG_FIT!" +#endif + +#if defined(CONFIG_FIT) +#include +#include +#include +#define CONFIG_MD5 /* FIT images need MD5 support */ +#endif + /* * Operating System Codes */ @@ -59,25 +89,25 @@ /* * CPU Architecture Codes (supported by Linux) */ -#define IH_CPU_INVALID 0 /* Invalid CPU */ -#define IH_CPU_ALPHA 1 /* Alpha */ -#define IH_CPU_ARM 2 /* ARM */ -#define IH_CPU_I386 3 /* Intel x86 */ -#define IH_CPU_IA64 4 /* IA64 */ -#define IH_CPU_MIPS 5 /* MIPS */ -#define IH_CPU_MIPS64 6 /* MIPS 64 Bit */ -#define IH_CPU_PPC 7 /* PowerPC */ -#define IH_CPU_S390 8 /* IBM S390 */ -#define IH_CPU_SH 9 /* SuperH */ -#define IH_CPU_SPARC 10 /* Sparc */ -#define IH_CPU_SPARC64 11 /* Sparc 64 Bit */ -#define IH_CPU_M68K 12 /* M68K */ -#define IH_CPU_NIOS 13 /* Nios-32 */ -#define IH_CPU_MICROBLAZE 14 /* MicroBlaze */ -#define IH_CPU_NIOS2 15 /* Nios-II */ -#define IH_CPU_BLACKFIN 16 /* Blackfin */ -#define IH_CPU_AVR32 17 /* AVR32 */ -#define IH_CPU_ST200 18 /* STMicroelectronics ST200 */ +#define IH_ARCH_INVALID 0 /* Invalid CPU */ +#define IH_ARCH_ALPHA 1 /* Alpha */ +#define IH_ARCH_ARM 2 /* ARM */ +#define IH_ARCH_I386 3 /* Intel x86 */ +#define IH_ARCH_IA64 4 /* IA64 */ +#define IH_ARCH_MIPS 5 /* MIPS */ +#define IH_ARCH_MIPS64 6 /* MIPS 64 Bit */ +#define IH_ARCH_PPC 7 /* PowerPC */ +#define IH_ARCH_S390 8 /* IBM S390 */ +#define IH_ARCH_SH 9 /* SuperH */ +#define IH_ARCH_SPARC 10 /* Sparc */ +#define IH_ARCH_SPARC64 11 /* Sparc 64 Bit */ +#define IH_ARCH_M68K 12 /* M68K */ +#define IH_ARCH_NIOS 13 /* Nios-32 */ +#define IH_ARCH_MICROBLAZE 14 /* MicroBlaze */ +#define IH_ARCH_NIOS2 15 /* Nios-II */ +#define IH_ARCH_BLACKFIN 16 /* Blackfin */ +#define IH_ARCH_AVR32 17 /* AVR32 */ +#define IH_ARCH_ST200 18 /* STMicroelectronics ST200 */ /* * Image Types @@ -139,9 +169,9 @@ #define IH_NMLEN 32 /* Image Name Length */ /* - * all data in network byte order (aka natural aka bigendian) + * Legacy format image header, + * all data in network byte order (aka natural aka bigendian). */ - typedef struct image_header { uint32_t ih_magic; /* Image Header Magic Number */ uint32_t ih_hcrc; /* Image Header CRC Checksum */ @@ -157,5 +187,412 @@ typedef struct image_header { uint8_t ih_name[IH_NMLEN]; /* Image Name */ } image_header_t; +/* + * Legacy and FIT format headers used by do_bootm() and do_bootm_() + * routines. + */ +typedef struct bootm_headers { + /* + * Legacy os image header, if it is a multi component image + * then boot_get_ramdisk() and get_fdt() will attempt to get + * data from second and third component accordingly. + */ + image_header_t *legacy_hdr_os; + ulong legacy_hdr_valid; + +#if defined(CONFIG_FIT) + const char *fit_uname_cfg; /* configuration node unit name */ + + void *fit_hdr_os; /* os FIT image header */ + const char *fit_uname_os; /* os subimage node unit name */ + int fit_noffset_os; /* os subimage node offset */ + + void *fit_hdr_rd; /* init ramdisk FIT image header */ + const char *fit_uname_rd; /* init ramdisk subimage node unit name */ + int fit_noffset_rd; /* init ramdisk subimage node offset */ + +#if defined(CONFIG_PPC) + void *fit_hdr_fdt; /* FDT blob FIT image header */ + const char *fit_uname_fdt; /* FDT blob subimage node unit name */ + int fit_noffset_fdt;/* FDT blob subimage node offset */ +#endif +#endif + + int verify; /* getenv("verify")[0] != 'n' */ + int autostart; /* getenv("autostart")[0] != 'n' */ + struct lmb *lmb; /* for memory mgmt */ +} bootm_headers_t; + +/* + * Some systems (for example LWMON) have very short watchdog periods; + * we must make sure to split long operations like memmove() or + * crc32() into reasonable chunks. + */ +#define CHUNKSZ (64 * 1024) + +#define uimage_to_cpu(x) ntohl(x) +#define cpu_to_uimage(x) htonl(x) + +const char *genimg_get_os_name (uint8_t os); +const char *genimg_get_arch_name (uint8_t arch); +const char *genimg_get_type_name (uint8_t type); +const char *genimg_get_comp_name (uint8_t comp); +int genimg_get_os_id (const char *name); +int genimg_get_arch_id (const char *name); +int genimg_get_type_id (const char *name); +int genimg_get_comp_id (const char *name); + +#ifndef USE_HOSTCC +/* Image format types, returned by _get_format() routine */ +#define IMAGE_FORMAT_INVALID 0x00 +#define IMAGE_FORMAT_LEGACY 0x01 /* legacy image_header based format */ +#define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */ + +int genimg_get_format (void *img_addr); +int genimg_has_config (bootm_headers_t *images); +ulong genimg_get_image (ulong img_addr); + +int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, + uint8_t arch, ulong *rd_start, ulong *rd_end); + +#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, + ulong *initrd_start, ulong *initrd_end); + +int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, + ulong bootmap_base); +int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base); +#endif /* CONFIG_PPC || CONFIG_M68K */ +#endif /* !USE_HOSTCC */ + +/*******************************************************************/ +/* Legacy format specific code (prefixed with image_) */ +/*******************************************************************/ +static inline uint32_t image_get_header_size (void) +{ + return (sizeof (image_header_t)); +} + +#define image_get_hdr_l(f) \ + static inline uint32_t image_get_##f(image_header_t *hdr) \ + { \ + return uimage_to_cpu (hdr->ih_##f); \ + } +image_get_hdr_l (magic); +image_get_hdr_l (hcrc); +image_get_hdr_l (time); +image_get_hdr_l (size); +image_get_hdr_l (load); +image_get_hdr_l (ep); +image_get_hdr_l (dcrc); + +#define image_get_hdr_b(f) \ + static inline uint8_t image_get_##f(image_header_t *hdr) \ + { \ + return hdr->ih_##f; \ + } +image_get_hdr_b (os); +image_get_hdr_b (arch); +image_get_hdr_b (type); +image_get_hdr_b (comp); + +static inline char *image_get_name (image_header_t *hdr) +{ + return (char *)hdr->ih_name; +} + +static inline uint32_t image_get_data_size (image_header_t *hdr) +{ + return image_get_size (hdr); +} + +/** + * image_get_data - get image payload start address + * @hdr: image header + * + * image_get_data() returns address of the image payload. For single + * component images it is image data start. For multi component + * images it points to the null terminated table of sub-images sizes. + * + * returns: + * image payload data start address + */ +static inline ulong image_get_data (image_header_t *hdr) +{ + return ((ulong)hdr + image_get_header_size ()); +} + +static inline uint32_t image_get_image_size (image_header_t *hdr) +{ + return (image_get_size (hdr) + image_get_header_size ()); +} +static inline ulong image_get_image_end (image_header_t *hdr) +{ + return ((ulong)hdr + image_get_image_size (hdr)); +} + +#define image_set_hdr_l(f) \ + static inline void image_set_##f(image_header_t *hdr, uint32_t val) \ + { \ + hdr->ih_##f = cpu_to_uimage (val); \ + } +image_set_hdr_l (magic); +image_set_hdr_l (hcrc); +image_set_hdr_l (time); +image_set_hdr_l (size); +image_set_hdr_l (load); +image_set_hdr_l (ep); +image_set_hdr_l (dcrc); + +#define image_set_hdr_b(f) \ + static inline void image_set_##f(image_header_t *hdr, uint8_t val) \ + { \ + hdr->ih_##f = val; \ + } +image_set_hdr_b (os); +image_set_hdr_b (arch); +image_set_hdr_b (type); +image_set_hdr_b (comp); + +static inline void image_set_name (image_header_t *hdr, const char *name) +{ + strncpy (image_get_name (hdr), name, IH_NMLEN); +} + +int image_check_hcrc (image_header_t *hdr); +int image_check_dcrc (image_header_t *hdr); +#ifndef USE_HOSTCC +int image_check_dcrc_wd (image_header_t *hdr, ulong chunksize); +int getenv_verify (void); +int getenv_autostart (void); +ulong getenv_bootm_low(void); +ulong getenv_bootm_size(void); +void memmove_wd (void *to, void *from, size_t len, ulong chunksz); +#endif + +static inline int image_check_magic (image_header_t *hdr) +{ + return (image_get_magic (hdr) == IH_MAGIC); +} +static inline int image_check_type (image_header_t *hdr, uint8_t type) +{ + return (image_get_type (hdr) == type); +} +static inline int image_check_arch (image_header_t *hdr, uint8_t arch) +{ + return (image_get_arch (hdr) == arch); +} +static inline int image_check_os (image_header_t *hdr, uint8_t os) +{ + return (image_get_os (hdr) == os); +} + +ulong image_multi_count (image_header_t *hdr); +void image_multi_getimg (image_header_t *hdr, ulong idx, + ulong *data, ulong *len); + +inline void image_print_contents (image_header_t *hdr); +inline void image_print_contents_noindent (image_header_t *hdr); + +#ifndef USE_HOSTCC +static inline int image_check_target_arch (image_header_t *hdr) +{ +#if defined(__ARM__) + if (!image_check_arch (hdr, IH_ARCH_ARM)) +#elif defined(__avr32__) + if (!image_check_arch (hdr, IH_ARCH_AVR32)) +#elif defined(__bfin__) + if (!image_check_arch (hdr, IH_ARCH_BLACKFIN)) +#elif defined(__I386__) + if (!image_check_arch (hdr, IH_ARCH_I386)) +#elif defined(__M68K__) + if (!image_check_arch (hdr, IH_ARCH_M68K)) +#elif defined(__microblaze__) + if (!image_check_arch (hdr, IH_ARCH_MICROBLAZE)) +#elif defined(__mips__) + if (!image_check_arch (hdr, IH_ARCH_MIPS)) +#elif defined(__nios__) + if (!image_check_arch (hdr, IH_ARCH_NIOS)) +#elif defined(__nios2__) + if (!image_check_arch (hdr, IH_ARCH_NIOS2)) +#elif defined(__PPC__) + if (!image_check_arch (hdr, IH_ARCH_PPC)) +#elif defined(__sh__) + if (!image_check_arch (hdr, IH_ARCH_SH)) +#else +# error Unknown CPU type +#endif + return 0; + + return 1; +} +#endif /* USE_HOSTCC */ + +/*******************************************************************/ +/* New uImage format specific code (prefixed with fit_) */ +/*******************************************************************/ +#if defined(CONFIG_FIT) + +#define FIT_IMAGES_PATH "/images" +#define FIT_CONFS_PATH "/configurations" + +/* hash node */ +#define FIT_HASH_NODENAME "hash" +#define FIT_ALGO_PROP "algo" +#define FIT_VALUE_PROP "value" + +/* image node */ +#define FIT_DATA_PROP "data" +#define FIT_TIMESTAMP_PROP "timestamp" +#define FIT_DESC_PROP "description" +#define FIT_ARCH_PROP "arch" +#define FIT_TYPE_PROP "type" +#define FIT_OS_PROP "os" +#define FIT_COMP_PROP "compression" +#define FIT_ENTRY_PROP "entry" +#define FIT_LOAD_PROP "load" + +/* configuration node */ +#define FIT_KERNEL_PROP "kernel" +#define FIT_RAMDISK_PROP "ramdisk" +#define FIT_FDT_PROP "fdt" +#define FIT_DEFAULT_PROP "default" + +#define FIT_MAX_HASH_LEN 20 /* max(crc32_len(4), sha1_len(20)) */ + +/* cmdline argument format parsing */ +inline int fit_parse_conf (const char *spec, ulong addr_curr, + ulong *addr, const char **conf_name); +inline int fit_parse_subimage (const char *spec, ulong addr_curr, + ulong *addr, const char **image_name); + +inline void fit_print_contents (const void *fit); +inline void fit_print_contents_noindent (const void *fit); +void fit_image_print (const void *fit, int noffset, const char *p); +void fit_image_print_hash (const void *fit, int noffset, const char *p); + +/** + * fit_get_end - get FIT image size + * @fit: pointer to the FIT format image header + * + * returns: + * size of the FIT image (blob) in memory + */ +static inline ulong fit_get_size (const void *fit) +{ + return fdt_totalsize (fit); +} + +/** + * fit_get_end - get FIT image end + * @fit: pointer to the FIT format image header + * + * returns: + * end address of the FIT image (blob) in memory + */ +static inline ulong fit_get_end (const void *fit) +{ + return (ulong)fit + fdt_totalsize (fit); +} + +/** + * fit_get_name - get FIT node name + * @fit: pointer to the FIT format image header + * + * returns: + * NULL, on error + * pointer to node name, on success + */ +static inline const char *fit_get_name (const void *fit_hdr, + int noffset, int *len) +{ + return fdt_get_name (fit_hdr, noffset, len); +} + +int fit_get_desc (const void *fit, int noffset, char **desc); +int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp); + +int fit_image_get_node (const void *fit, const char *image_uname); +int fit_image_get_os (const void *fit, int noffset, uint8_t *os); +int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch); +int fit_image_get_type (const void *fit, int noffset, uint8_t *type); +int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp); +int fit_image_get_load (const void *fit, int noffset, ulong *load); +int fit_image_get_entry (const void *fit, int noffset, ulong *entry); +int fit_image_get_data (const void *fit, int noffset, + const void **data, size_t *size); + +int fit_image_hash_get_algo (const void *fit, int noffset, char **algo); +int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value, + int *value_len); + +int fit_set_timestamp (void *fit, int noffset, time_t timestamp); +int fit_set_hashes (void *fit); +int fit_image_set_hashes (void *fit, int image_noffset); +int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value, + int value_len); + +int fit_image_check_hashes (const void *fit, int noffset); +int fit_image_check_os (const void *fit, int noffset, uint8_t os); +int fit_image_check_arch (const void *fit, int noffset, uint8_t arch); +int fit_image_check_type (const void *fit, int noffset, uint8_t type); +int fit_image_check_comp (const void *fit, int noffset, uint8_t comp); +int fit_check_format (const void *fit); + +int fit_conf_get_node (const void *fit, const char *conf_uname); +int fit_conf_get_kernel_node (const void *fit, int noffset); +int fit_conf_get_ramdisk_node (const void *fit, int noffset); +int fit_conf_get_fdt_node (const void *fit, int noffset); + +void fit_conf_print (const void *fit, int noffset, const char *p); + +#ifndef USE_HOSTCC +static inline int fit_image_check_target_arch (const void *fdt, int node) +{ +#if defined(__ARM__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_ARM)) +#elif defined(__avr32__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_AVR32)) +#elif defined(__bfin__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_BLACKFIN)) +#elif defined(__I386__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_I386)) +#elif defined(__M68K__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_M68K)) +#elif defined(__microblaze__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_MICROBLAZE)) +#elif defined(__mips__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_MIPS)) +#elif defined(__nios__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_NIOS)) +#elif defined(__nios2__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_NIOS2)) +#elif defined(__PPC__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_PPC)) +#elif defined(__sh__) + if (!fit_image_check_arch (fdt, node, IH_ARCH_SH)) +#else +# error Unknown CPU type +#endif + return 0; + + return 1; +} +#endif /* USE_HOSTCC */ + +#ifdef CONFIG_FIT_VERBOSE +#define fit_unsupported(msg) printf ("! %s:%d " \ + "FIT images not supported for '%s'\n", \ + __FILE__, __LINE__, (msg)) + +#define fit_unsupported_reset(msg) printf ("! %s:%d " \ + "FIT images not supported for '%s' " \ + "- must reset board to recover!\n", \ + __FILE__, __LINE__, (msg)) +#else +#define fit_unsupported(msg) +#define fit_unsupported_reset(msg) +#endif /* CONFIG_FIT_VERBOSE */ +#endif /* CONFIG_FIT */ #endif /* __IMAGE_H__ */ diff --git a/include/libata.h b/include/libata.h new file mode 100644 index 000000000..aedba743e --- /dev/null +++ b/include/libata.h @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2008 Freescale Semiconductor, Inc. + * Dave Liu + * port from libata of linux kernel + * + * 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 __LIBATA_H__ +#define __LIBATA_H__ + +#include + +/* command + */ +enum ata_cmd { + /* non-NCQ command */ + ATA_CMD_DEV_RESET = 0x08, /* ATAPI device reset */ + ATA_CMD_FLUSH_CACHE = 0xE7, + ATA_CMD_FLUSH_CACHE_EXT = 0xEA, + ATA_CMD_ID_ATA = 0xEC, + ATA_CMD_ID_ATAPI = 0xA1, + ATA_CMD_READ_DMA = 0xC8, + ATA_CMD_READ_DMA_EXT = 0x25, + ATA_CMD_WRITE_DMA = 0xCA, + ATA_CMD_WRITE_DMA_EXT = 0x35, + ATA_CMD_PIO_READ = 0x20, + ATA_CMD_PIO_READ_EXT = 0x24, + ATA_CMD_PIO_WRITE = 0x30, + ATA_CMD_PIO_WRITE_EXT = 0x34, + ATA_CMD_SET_FEATURES = 0xEF, + + /* NCQ command */ + ATA_CMD_READ_FPDMA_QUEUED = 0x60, + ATA_CMD_WRITE_FPDMA_QUEUED = 0x61, +}; + +/* SETFEATURES stuff + */ +enum ata_set_features { + /* SETFEATURES stuff */ + SETFEATURES_XFER = 0x03, + XFER_UDMA_7 = 0x47, + XFER_UDMA_6 = 0x46, + XFER_UDMA_5 = 0x45, + XFER_UDMA_4 = 0x44, + XFER_UDMA_3 = 0x43, + XFER_UDMA_2 = 0x42, + XFER_UDMA_1 = 0x41, + XFER_UDMA_0 = 0x40, + XFER_MW_DMA_4 = 0x24, /* CFA only */ + XFER_MW_DMA_3 = 0x23, /* CFA only */ + XFER_MW_DMA_2 = 0x22, + XFER_MW_DMA_1 = 0x21, + XFER_MW_DMA_0 = 0x20, + XFER_PIO_6 = 0x0E, /* CFA only */ + XFER_PIO_5 = 0x0D, /* CFA only */ + XFER_PIO_4 = 0x0C, + XFER_PIO_3 = 0x0B, + XFER_PIO_2 = 0x0A, + XFER_PIO_1 = 0x09, + XFER_PIO_0 = 0x08, + XFER_PIO_SLOW = 0x00, + + SETFEATURES_WC_ON = 0x02, /* Enable write cache */ + SETFEATURES_WC_OFF = 0x82, /* Disable write cache */ + + SETFEATURES_SPINUP = 0x07, /* Spin-up drive */ +}; + +enum ata_protocol { + ATA_PROT_UNKNOWN, /* unknown */ + ATA_PROT_NODATA, /* no data */ + ATA_PROT_PIO, /* PIO data xfer */ + ATA_PROT_DMA, /* DMA */ + ATA_PROT_NCQ, /* NCQ */ + ATA_PROT_ATAPI, /* packet command, PIO data xfer */ + ATA_PROT_ATAPI_NODATA, /* packet command, no data */ + ATA_PROT_ATAPI_DMA, /* packet command, DMA */ +}; + +enum ata_dev_typed { + ATA_DEV_ATA, /* ATA device */ + ATA_DEV_ATAPI, /* ATAPI device */ + ATA_DEV_PMP, /* Port Multiplier Port */ + ATA_DEV_UNKNOWN, /* unknown */ +}; + +enum { + ATA_SECT_SIZE = 512, + ATA_MAX_SECTORS_128 = 128, + ATA_MAX_SECTORS = 256, + ATA_MAX_SECTORS_LBA48 = 65535, + + /* bits in ATA command block registers */ + ATA_HOB = (1 << 7), /* LBA48 selector */ + ATA_NIEN = (1 << 1), /* disable-irq flag */ + ATA_LBA = (1 << 6), /* LBA28 selector */ + ATA_DEV1 = (1 << 4), /* Select Device 1 (slave) */ + ATA_BUSY = (1 << 7), /* BSY status bit */ + ATA_DRDY = (1 << 6), /* device ready */ + ATA_DF = (1 << 5), /* device fault */ + ATA_DRQ = (1 << 3), /* data request i/o */ + ATA_ERR = (1 << 0), /* have an error */ + ATA_SRST = (1 << 2), /* software reset */ + ATA_ICRC = (1 << 7), /* interface CRC error */ + ATA_UNC = (1 << 6), /* uncorrectable media error */ + ATA_IDNF = (1 << 4), /* ID not found */ + ATA_ABORTED = (1 << 2), /* command aborted */ + + ATA_ID_WORDS = 256, + ATA_ID_SERNO = 10, + ATA_ID_FW_REV = 23, + ATA_ID_PROD = 27, + ATA_ID_FIELD_VALID = 53, + ATA_ID_LBA_SECTORS = 60, + ATA_ID_MWDMA_MODES = 63, + ATA_ID_PIO_MODES = 64, + ATA_ID_QUEUE_DEPTH = 75, + ATA_ID_SATA_CAP = 76, + ATA_ID_SATA_FEATURES = 78, + ATA_ID_SATA_FEATURES_EN = 79, + ATA_ID_MAJOR_VER = 80, + ATA_ID_MINOR_VER = 81, + ATA_ID_UDMA_MODES = 88, + ATA_ID_LBA48_SECTORS = 100, + + ATA_ID_SERNO_LEN = 20, + ATA_ID_FW_REV_LEN = 8, + ATA_ID_PROD_LEN = 40, + + ATA_PIO3 = (1 << 0), + ATA_PIO4 = ATA_PIO3 | (1 << 1), + + ATA_UDMA0 = (1 << 0), + ATA_UDMA1 = ATA_UDMA0 | (1 << 1), + ATA_UDMA2 = ATA_UDMA1 | (1 << 2), + ATA_UDMA3 = ATA_UDMA2 | (1 << 3), + ATA_UDMA4 = ATA_UDMA3 | (1 << 4), + ATA_UDMA5 = ATA_UDMA4 | (1 << 5), + ATA_UDMA6 = ATA_UDMA5 | (1 << 6), + ATA_UDMA7 = ATA_UDMA6 | (1 << 7), +}; + +#define ata_id_is_ata(id) (((id)[0] & (1 << 15)) == 0) +#define ata_id_wcache_enabled(id) ((id)[85] & (1 << 5)) +#define ata_id_has_fua(id) ((id)[84] & (1 << 6)) +#define ata_id_has_flush(id) ((id)[83] & (1 << 12)) +#define ata_id_has_flush_ext(id) ((id)[83] & (1 << 13)) +#define ata_id_has_lba48(id) ((id)[83] & (1 << 10)) +#define ata_id_has_wcache(id) ((id)[82] & (1 << 5)) +#define ata_id_has_lba(id) ((id)[49] & (1 << 9)) +#define ata_id_has_dma(id) ((id)[49] & (1 << 8)) +#define ata_id_has_ncq(id) ((id)[76] & (1 << 8)) +#define ata_id_queue_depth(id) (((id)[75] & 0x1f) + 1) + +#define ata_id_u32(id,n) \ + (((u32) (id)[(n) + 1] << 16) | ((u32) (id)[(n)])) +#define ata_id_u64(id,n) \ + ( ((u64) (id)[(n) + 3] << 48) | \ + ((u64) (id)[(n) + 2] << 32) | \ + ((u64) (id)[(n) + 1] << 16) | \ + ((u64) (id)[(n) + 0]) ) + + +static inline unsigned int ata_id_major_version(const u16 *id) +{ + unsigned int mver; + + if (id[ATA_ID_MAJOR_VER] == 0xFFFF) + return 0; + + for (mver = 14; mver >= 1; mver--) + if (id[ATA_ID_MAJOR_VER] & (1 << mver)) + break; + return mver; +} + +static inline int ata_id_is_sata(const u16 *id) +{ + return ata_id_major_version(id) >= 5 && id[93] == 0; +} + +u64 ata_id_n_sectors(u16 *id); +u32 ata_dev_classify(u32 sig); +void ata_id_c_string(const u16 *id, unsigned char *s, + unsigned int ofs, unsigned int len); +void ata_dump_id(u16 *id); +void ata_swap_buf_le16(u16 *buf, unsigned int buf_words); + +#endif /* __LIBATA_H__ */ diff --git a/include/libfdt_env.h b/include/libfdt_env.h index 78f725830..ab5c3012d 100644 --- a/include/libfdt_env.h +++ b/include/libfdt_env.h @@ -21,11 +21,16 @@ #ifndef _LIBFDT_ENV_H #define _LIBFDT_ENV_H -#include -#include -#include +#ifdef USE_HOSTCC +#include +#include +#else #include +#include +#endif /* USE_HOSTCC */ +#include +#include extern struct fdt_header *fdt; /* Pointer to the working fdt */ #define fdt32_to_cpu(x) __be32_to_cpu(x) diff --git a/include/lmb.h b/include/lmb.h new file mode 100644 index 000000000..cc64cbbc7 --- /dev/null +++ b/include/lmb.h @@ -0,0 +1,54 @@ +#ifndef _LINUX_LMB_H +#define _LINUX_LMB_H +#ifdef __KERNEL__ + +#include +/* + * Logical memory blocks. + * + * Copyright (C) 2001 Peter Bergner, IBM Corp. + * + * 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. + */ + +#define MAX_LMB_REGIONS 8 + +struct lmb_property { + ulong base; + ulong size; +}; + +struct lmb_region { + unsigned long cnt; + ulong size; + struct lmb_property region[MAX_LMB_REGIONS+1]; +}; + +struct lmb { + struct lmb_region memory; + struct lmb_region reserved; +}; + +extern struct lmb lmb; + +extern void lmb_init(struct lmb *lmb); +extern long lmb_add(struct lmb *lmb, ulong base, ulong size); +extern long lmb_reserve(struct lmb *lmb, ulong base, ulong size); +extern ulong lmb_alloc(struct lmb *lmb, ulong size, ulong align); +extern ulong lmb_alloc_base(struct lmb *lmb, ulong size, ulong align, ulong max_addr); +extern ulong __lmb_alloc_base(struct lmb *lmb, ulong size, ulong align, ulong max_addr); +extern int lmb_is_reserved(struct lmb *lmb, ulong addr); + +extern void lmb_dump_all(struct lmb *lmb); + +static inline ulong +lmb_size_bytes(struct lmb_region *type, unsigned long region_nr) +{ + return type->region[region_nr].size; +} +#endif /* __KERNEL__ */ + +#endif /* _LINUX_LMB_H */ diff --git a/include/md5.h b/include/md5.h new file mode 100644 index 000000000..046d1eee7 --- /dev/null +++ b/include/md5.h @@ -0,0 +1,23 @@ +/* + * This file was transplanted with slight modifications from Linux sources + * (fs/cifs/md5.h) into U-Boot by Bartlomiej Sieka . + */ + +#ifndef _MD5_H +#define _MD5_H + +#include + +struct MD5Context { + __u32 buf[4]; + __u32 bits[2]; + unsigned char in[64]; +}; + +/* + * Calculate and store in 'output' the MD5 digest of 'len' bytes at + * 'input'. 'output' must have enough space to hold 16 bytes. + */ +void md5 (unsigned char *input, int len, unsigned char output[16]); + +#endif /* _MD5_H */ diff --git a/include/mpc83xx.h b/include/mpc83xx.h index df052e3d4..4ee38aafa 100644 --- a/include/mpc83xx.h +++ b/include/mpc83xx.h @@ -121,6 +121,7 @@ #define SPCR_PCIPR 0x03000000 /* PCI bridge system bus request priority */ #define SPCR_PCIPR_SHIFT (31-7) #define SPCR_OPT 0x00800000 /* Optimize */ +#define SPCR_OPT_SHIFT (31-8) #define SPCR_TBEN 0x00400000 /* E300 PowerPC core time base unit enable */ #define SPCR_TBEN_SHIFT (31-9) #define SPCR_COREPR 0x00300000 /* E300 PowerPC Core system bus request priority */ @@ -880,7 +881,7 @@ #define TIMING_CFG0_PRE_PD_EXIT_SHIFT 16 #define TIMING_CFG0_ODT_PD_EXIT 0x00000F00 #define TIMING_CFG0_ODT_PD_EXIT_SHIFT 8 -#define TIMING_CFG0_MRS_CYC 0x00000F00 +#define TIMING_CFG0_MRS_CYC 0x0000000F #define TIMING_CFG0_MRS_CYC_SHIFT 0 /* TIMING_CFG_1 - DDR SDRAM Timing Configuration 1 @@ -903,6 +904,7 @@ #define TIMING_CFG1_WRTORD_SHIFT 0 #define TIMING_CFG1_CASLAT_20 0x00030000 /* CAS latency = 2.0 */ #define TIMING_CFG1_CASLAT_25 0x00040000 /* CAS latency = 2.5 */ +#define TIMING_CFG1_CASLAT_30 0x00050000 /* CAS latency = 2.5 */ /* TIMING_CFG_2 - DDR SDRAM Timing Configuration 2 */ diff --git a/include/part.h b/include/part.h index 8407aa05d..b22a637dd 100644 --- a/include/part.h +++ b/include/part.h @@ -27,8 +27,8 @@ typedef struct block_dev_desc { int if_type; /* type of the interface */ - int dev; /* device number */ - unsigned char part_type; /* partition type */ + int dev; /* device number */ + unsigned char part_type; /* partition type */ unsigned char target; /* target SCSI ID */ unsigned char lun; /* target LUN */ unsigned char type; /* device type */ @@ -36,9 +36,9 @@ typedef struct block_dev_desc { #ifdef CONFIG_LBA48 unsigned char lba48; /* device can use 48bit addr (ATA/ATAPI v7) */ #endif - lbaint_t lba; /* number of blocks */ + lbaint_t lba; /* number of blocks */ unsigned long blksz; /* block size */ - char vendor [40+1]; /* IDE model, SCSI Vendor */ + char vendor [40+1]; /* IDE model, SCSI Vendor */ char product[20+1]; /* IDE Serial no, SCSI product */ char revision[8+1]; /* firmware revision */ unsigned long (*block_read)(int dev, @@ -49,6 +49,7 @@ typedef struct block_dev_desc { unsigned long start, lbaint_t blkcnt, const void *buffer); + void *priv; /* driver private struct pointer */ }block_dev_desc_t; /* Interface types: */ @@ -60,6 +61,7 @@ typedef struct block_dev_desc { #define IF_TYPE_DOC 5 #define IF_TYPE_MMC 6 #define IF_TYPE_SD 7 +#define IF_TYPE_SATA 8 /* Part types */ #define PART_TYPE_UNKNOWN 0x00 @@ -92,6 +94,7 @@ typedef struct disk_partition { /* Misc _get_dev functions */ block_dev_desc_t* get_dev(char* ifname, int dev); block_dev_desc_t* ide_get_dev(int dev); +block_dev_desc_t* sata_get_dev(int dev); block_dev_desc_t* scsi_get_dev(int dev); block_dev_desc_t* usb_stor_get_dev(int dev); block_dev_desc_t* mmc_get_dev(int dev); diff --git a/include/pci_ids.h b/include/pci_ids.h index 3b1045241..b0c1957ae 100644 --- a/include/pci_ids.h +++ b/include/pci_ids.h @@ -2050,3 +2050,26 @@ #define PCI_DEVICE_ID_MICROGATE_USC 0x0010 #define PCI_DEVICE_ID_MICROGATE_SCC 0x0020 #define PCI_DEVICE_ID_MICROGATE_SCA 0x0030 + +#define PCI_VENDOR_ID_FREESCALE 0x1957 +#define PCI_DEVICE_ID_MPC8548E 0x0012 +#define PCI_DEVICE_ID_MPC8548 0x0013 +#define PCI_DEVICE_ID_MPC8543E 0x0014 +#define PCI_DEVICE_ID_MPC8543 0x0015 +#define PCI_DEVICE_ID_MPC8547E 0x0018 +#define PCI_DEVICE_ID_MPC8545E 0x0019 +#define PCI_DEVICE_ID_MPC8545 0x001a +#define PCI_DEVICE_ID_MPC8568E 0x0020 +#define PCI_DEVICE_ID_MPC8568 0x0021 +#define PCI_DEVICE_ID_MPC8567E 0x0022 +#define PCI_DEVICE_ID_MPC8567 0x0023 +#define PCI_DEVICE_ID_MPC8533E 0x0030 +#define PCI_DEVICE_ID_MPC8533 0x0031 +#define PCI_DEVICE_ID_MPC8544E 0x0032 +#define PCI_DEVICE_ID_MPC8544 0x0033 +#define PCI_DEVICE_ID_MPC8572E 0x0040 +#define PCI_DEVICE_ID_MPC8572 0x0041 +#define PCI_DEVICE_ID_MPC8641 0x7010 +#define PCI_DEVICE_ID_MPC8641D 0x7011 +#define PCI_DEVICE_ID_MPC8610 0x7018 + diff --git a/include/sata.h b/include/sata.h index 165b471b2..b4b702903 100644 --- a/include/sata.h +++ b/include/sata.h @@ -1,108 +1,6 @@ +int init_sata(int dev); +int scan_sata(int dev); +ulong sata_read(int dev, ulong blknr, ulong blkcnt, void *buffer); +ulong sata_write(int dev, ulong blknr, ulong blkcnt, const void *buffer); -#if (DEBUG_SATA) -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -struct sata_ioports { - unsigned long cmd_addr; - unsigned long data_addr; - unsigned long error_addr; - unsigned long feature_addr; - unsigned long nsect_addr; - unsigned long lbal_addr; - unsigned long lbam_addr; - unsigned long lbah_addr; - unsigned long device_addr; - unsigned long status_addr; - unsigned long command_addr; - unsigned long altstatus_addr; - unsigned long ctl_addr; - unsigned long bmdma_addr; - unsigned long scr_addr; -}; - -struct sata_port { - unsigned char port_no; /* primary=0, secondary=1 */ - struct sata_ioports ioaddr; /* ATA cmd/ctl/dma reg blks */ - unsigned char ctl_reg; - unsigned char last_ctl; - unsigned char port_state; /* 1-port is available and */ - /* 0-port is not available */ - unsigned char dev_mask; -}; - -/***********SATA LIBRARY SPECIFIC DEFINITIONS AND DECLARATIONS**************/ -#ifdef SATA_DECL /*SATA library specific declarations */ -#define ata_id_has_lba48(id) ((id)[83] & (1 << 10)) -#define ata_id_has_lba(id) ((id)[49] & (1 << 9)) -#define ata_id_has_dma(id) ((id)[49] & (1 << 8)) -#define ata_id_u32(id,n) \ - (((u32) (id)[(n) + 1] << 16) | ((u32) (id)[(n)])) -#define ata_id_u64(id,n) \ - (((u64) (id)[(n) + 3] << 48) | \ - ((u64) (id)[(n) + 2] << 32) | \ - ((u64) (id)[(n) + 1] << 16) | \ - ((u64) (id)[(n) + 0]) ) -#endif - -#ifdef SATA_DECL /*SATA library specific declarations */ -static inline void -ata_dump_id (u16 * id) -{ - PRINTF ("49==0x%04x " - "53==0x%04x " - "63==0x%04x " - "64==0x%04x " - "75==0x%04x \n", id[49], id[53], id[63], id[64], id[75]); - PRINTF ("80==0x%04x " - "81==0x%04x " - "82==0x%04x " - "83==0x%04x " - "84==0x%04x \n", id[80], id[81], id[82], id[83], id[84]); - PRINTF ("88==0x%04x " "93==0x%04x\n", id[88], id[93]); -} -#endif - -#ifdef SATA_DECL /*SATA library specific declarations */ -int sata_bus_softreset (int num); -void sata_identify (int num, int dev); -void sata_port (struct sata_ioports *ioport); -void set_Feature_cmd (int num, int dev); -int sata_devchk (struct sata_ioports *ioaddr, int dev); -void dev_select (struct sata_ioports *ioaddr, int dev); -u8 sata_busy_wait (struct sata_ioports *ioaddr, int bits, unsigned int max); -u8 sata_chk_status (struct sata_ioports *ioaddr); -ulong sata_read (int device, ulong blknr,lbaint_t blkcnt, void * buffer); -ulong sata_write (int device,ulong blknr, lbaint_t blkcnt, void * buffer); -void msleep (int count); -#else -extern int sata_bus_softreset (int num); -extern void sata_identify (int num, int dev); -extern void sata_port (struct sata_ioports *ioport); -extern void set_Feature_cmd (int num, int dev); -extern ulong sata_read (int device, ulong blknr, - lbaint_t blkcnt, void * buffer); -extern ulong sata_write (int device, ulong blknr, - lbaint_t blkcnt, void * buffer); -extern void msleep (int count); -#endif - -/************DRIVER SPECIFIC DEFINITIONS AND DECLARATIONS**************/ - -#ifdef DRV_DECL /*Driver specific declaration */ -int init_sata (void); -#else -extern int init_sata (void); -#endif - -#ifdef DRV_DECL /*Defines Driver Specific variables */ -struct sata_port port[CFG_SATA_MAXBUS]; -block_dev_desc_t sata_dev_desc[CFG_SATA_MAXDEVICES]; -int curr_dev = -1; -#else -extern struct sata_port port[CFG_SATA_MAXBUS]; -extern block_dev_desc_t sata_dev_desc[CFG_SATA_MAXDEVICES]; -extern int curr_dev; -#endif +int sata_initialize(void); diff --git a/include/usb.h b/include/usb.h index 4e1539fa8..5a6ffddec 100644 --- a/include/usb.h +++ b/include/usb.h @@ -195,7 +195,7 @@ void usb_event_poll(void); #define USB_MAX_STOR_DEV 5 block_dev_desc_t *usb_stor_get_dev(int index); int usb_stor_scan(int mode); -void usb_stor_info(void); +int usb_stor_info(void); #endif diff --git a/include/vsc7385.h b/include/vsc7385.h new file mode 100644 index 000000000..fceb078fc --- /dev/null +++ b/include/vsc7385.h @@ -0,0 +1,12 @@ +/* + * Header file for vsc7385.c + * + * Author: Timur Tabi + * + * Copyright 2008 Freescale Semiconductor, Inc. This file is licensed + * under the terms of the GNU General Public License version 2. This + * program is licensed "as is" without any warranty of any kind, whether + * express or implied. + */ + +int vsc7385_upload_firmware(void *firmware, unsigned int size); diff --git a/lib_arm/Makefile b/lib_arm/Makefile index bfd5b0e6f..12a8748d1 100644 --- a/lib_arm/Makefile +++ b/lib_arm/Makefile @@ -25,13 +25,21 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = _ashldi3.o _ashrdi3.o _divsi3.o _modsi3.o _udivsi3.o _umodsi3.o +SOBJS-y += _ashldi3.o +SOBJS-y += _ashrdi3.o +SOBJS-y += _divsi3.o +SOBJS-y += _modsi3.o +SOBJS-y += _udivsi3.o +SOBJS-y += _umodsi3.o -COBJS = armlinux.o board.o \ - cache.o div0.o interrupts.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += cache.o +COBJS-y += div0.o +COBJS-y += interrupts.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_arm/armlinux.c b/lib_arm/bootm.c similarity index 68% rename from lib_arm/armlinux.c rename to lib_arm/bootm.c index 42098fcd6..c5e8cb3eb 100644 --- a/lib_arm/armlinux.c +++ b/lib_arm/bootm.c @@ -26,15 +26,9 @@ #include #include #include -#ifdef CONFIG_HAS_DATAFLASH -#include -#endif DECLARE_GLOBAL_DATA_PTR; -/*cmd_boot.c*/ -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - #if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ defined (CONFIG_INITRD_TAG) || \ @@ -62,30 +56,43 @@ static void setup_end_tag (bd_t *bd); static void setup_videolfb_tag (gd_t *gd); # endif - static struct tag *params; #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ -extern image_header_t header; /* from cmd_bootm.c */ - +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) + bootm_headers_t *images) { - ulong len = 0, checksum; - ulong initrd_start, initrd_end; - ulong data; - void (*theKernel)(int zero, int arch, uint params); - image_header_t *hdr = &header; - bd_t *bd = gd->bd; - int machid = bd->bi_arch_number; - char *s; + ulong initrd_start, initrd_end; + ulong ep = 0; + bd_t *bd = gd->bd; + char *s; + int machid = bd->bi_arch_number; + void (*theKernel)(int zero, int arch, uint params); + int ret; #ifdef CONFIG_CMDLINE_TAG char *commandline = getenv ("bootargs"); #endif - theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep); + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; + } +#endif + } else { + puts ("Could not find kernel entry point!\n"); + goto error; + } + theKernel = (void (*)(int, int, uint))ep; s = getenv ("machid"); if (s) { @@ -93,134 +100,10 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], printf ("Using machid 0x%x from environment\n", machid); } - /* - * Check if there is an initrd image - */ - if (argc >= 3) { - show_boot_progress (9); - - addr = simple_strtoul (argv[2], NULL, 16); - - printf ("## Loading Ramdisk Image at %08lx ...\n", addr); - - /* Copy header so we can blank CRC field for re-calculation */ -#ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash (addr)) { - read_dataflash (addr, sizeof (image_header_t), - (char *) &header); - } else -#endif - memcpy (&header, (char *) addr, - sizeof (image_header_t)); - - if (ntohl (hdr->ih_magic) != IH_MAGIC) { - printf ("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset (cmdtp, flag, argc, argv); - } - - data = (ulong) & header; - len = sizeof (image_header_t); - - checksum = ntohl (hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (unsigned char *) data, len) != checksum) { - printf ("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset (cmdtp, flag, argc, argv); - } - - show_boot_progress (10); - - print_image_hdr (hdr); - - data = addr + sizeof (image_header_t); - len = ntohl (hdr->ih_size); - -#ifdef CONFIG_HAS_DATAFLASH - if (addr_dataflash (addr)) { - read_dataflash (data, len, (char *) CFG_LOAD_ADDR); - data = CFG_LOAD_ADDR; - } -#endif - - if (verify) { - ulong csum = 0; - - printf (" Verifying Checksum ... "); - csum = crc32 (0, (unsigned char *) data, len); - if (csum != ntohl (hdr->ih_dcrc)) { - printf ("Bad Data CRC\n"); - show_boot_progress (-12); - do_reset (cmdtp, flag, argc, argv); - } - printf ("OK\n"); - } - - show_boot_progress (11); - - if ((hdr->ih_os != IH_OS_LINUX) || - (hdr->ih_arch != IH_CPU_ARM) || - (hdr->ih_type != IH_TYPE_RAMDISK)) { - printf ("No Linux ARM Ramdisk Image\n"); - show_boot_progress (-13); - do_reset (cmdtp, flag, argc, argv); - } - -#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || \ - defined(CONFIG_ARMADILLO) || defined(CONFIG_M501SK) - /* - *we need to copy the ramdisk to SRAM to let Linux boot - */ - memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len); - data = ntohl(hdr->ih_load); -#endif /* CONFIG_B2 || CONFIG_EVB4510 */ - - /* - * Now check if we have a multifile image - */ - } else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) { - ulong tail = ntohl (len_ptr[0]) % 4; - int i; - - show_boot_progress (13); - - /* skip kernel length and terminator */ - data = (ulong) (&len_ptr[2]); - /* skip any additional image length fields */ - for (i = 1; len_ptr[i]; ++i) - data += 4; - /* add kernel length, and align */ - data += ntohl (len_ptr[0]); - if (tail) { - data += 4 - tail; - } - - len = ntohl (len_ptr[1]); - - } else { - /* - * no initrd image - */ - show_boot_progress (14); - - len = data = 0; - } - -#ifdef DEBUG - if (!data) { - printf ("No initrd\n"); - } -#endif - - if (data) { - initrd_start = data; - initrd_end = initrd_start + len; - } else { - initrd_start = 0; - initrd_end = 0; - } + ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_ARM, + &initrd_start, &initrd_end); + if (ret) + goto error; show_boot_progress (15); @@ -257,6 +140,9 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], setup_end_tag (bd); #endif + if (!images->autostart) + return ; + /* we assume that the kernel is in place */ printf ("\nStarting kernel ...\n\n"); @@ -270,6 +156,13 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], cleanup_before_linux (); theKernel (0, machid, bd->bi_boot_params); + /* does not return */ + return; + +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return; } diff --git a/lib_avr32/Makefile b/lib_avr32/Makefile index bb2938fe5..37b80514f 100644 --- a/lib_avr32/Makefile +++ b/lib_avr32/Makefile @@ -27,12 +27,14 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = memset.o +SOBJS-y += memset.o -COBJS = board.o interrupts.o avr32_linux.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += interrupts.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_avr32/avr32_linux.c b/lib_avr32/bootm.c similarity index 65% rename from lib_avr32/avr32_linux.c rename to lib_avr32/bootm.c index 62afbd249..b1c651ab2 100644 --- a/lib_avr32/avr32_linux.c +++ b/lib_avr32/bootm.c @@ -31,12 +31,10 @@ DECLARE_GLOBAL_DATA_PTR; -extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - /* CPU-specific hook to allow flushing of caches, etc. */ extern void prepare_to_boot(void); -extern image_header_t header; /* from cmd_bootm.c */ +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); static struct tag *setup_start_tag(struct tag *params) { @@ -176,113 +174,37 @@ static void setup_end_tag(struct tag *params) } void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - unsigned long addr, unsigned long *len_ptr, int verify) + bootm_headers_t *images) { - unsigned long data, len = 0; - unsigned long initrd_start, initrd_end; - unsigned long image_start, image_end; - unsigned long checksum; - void (*theKernel)(int magic, void *tagtable); - image_header_t *hdr; - struct tag *params, *params_start; - char *commandline = getenv("bootargs"); + ulong initrd_start, initrd_end; + ulong ep = 0; + void (*theKernel)(int magic, void *tagtable); + struct tag *params, *params_start; + char *commandline = getenv("bootargs"); + int ret; - hdr = (image_header_t *)addr; - image_start = addr; - image_end = addr + hdr->ih_size; - - theKernel = (void *)ntohl(hdr->ih_ep); - - /* - * Check if there is an initrd image - */ - if (argc >= 3) { - show_boot_progress (9); - - addr = simple_strtoul(argv[2], NULL, 16); - - printf("## Loading RAMDISK image at %08lx ...\n", addr); - - memcpy(&header, (char *)addr, sizeof(header)); - hdr = &header; - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - puts("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset(cmdtp, flag, argc, argv); + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; } - - data = (unsigned long)hdr; - len = sizeof(*hdr); - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32(0, (unsigned char *)data, len) != checksum) { - puts("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset(cmdtp, flag, argc, argv); - } - - show_boot_progress (10); - - print_image_hdr(hdr); - - data = addr + sizeof(header); - len = ntohl(hdr->ih_size); - - if (verify) { - unsigned long csum = 0; - - puts(" Verifying Checksum ... "); - csum = crc32(0, (unsigned char *)data, len); - if (csum != ntohl(hdr->ih_dcrc)) { - puts("Bad Data CRC\n"); - show_boot_progress (-12); - do_reset(cmdtp, flag, argc, argv); - } - puts("OK\n"); - } - - show_boot_progress (11); - - if ((hdr->ih_os != IH_OS_LINUX) || - (hdr->ih_arch != IH_CPU_AVR32) || - (hdr->ih_type != IH_TYPE_RAMDISK)) { - puts("Not a Linux/AVR32 RAMDISK image\n"); - show_boot_progress (-13); - do_reset(cmdtp, flag, argc, argv); - } - } else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) { - ulong tail = ntohl (len_ptr[0]) % 4; - int i; - - show_boot_progress (13); - - /* skip kernel length and terminator */ - data = (ulong) (&len_ptr[2]); - /* skip any additional image length fields */ - for (i = 1; len_ptr[i]; ++i) - data += 4; - /* add kernel length, and align */ - data += ntohl (len_ptr[0]); - if (tail) { - data += 4 - tail; - } - - len = ntohl (len_ptr[1]); +#endif } else { - /* no initrd image */ - show_boot_progress (14); - len = data = 0; + puts ("Could not find kernel entry point!\n"); + goto error; } + theKernel = (void *)ep; - if (data) { - initrd_start = data; - initrd_end = initrd_start + len; - } else { - initrd_start = 0; - initrd_end = 0; - } + ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_AVR32, + &initrd_start, &initrd_end); + if (ret) + goto error; show_boot_progress (15); @@ -299,10 +221,20 @@ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], params = setup_ethernet_tags(params); setup_end_tag(params); + if (!images->autostart) + return ; + printf("\nStarting kernel at %p (params at %p)...\n\n", theKernel, params_start); prepare_to_boot(); theKernel(ATAG_MAGIC, params_start); + /* does not return */ + return; + +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return; } diff --git a/lib_blackfin/Makefile b/lib_blackfin/Makefile index a7aaef7a3..dfaed6d02 100644 --- a/lib_blackfin/Makefile +++ b/lib_blackfin/Makefile @@ -29,12 +29,21 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = memcpy.o memcmp.o memset.o memmove.o +SOBJS-y += memcmp.o +SOBJS-y += memcpy.o +SOBJS-y += memmove.o +SOBJS-y += memset.o -COBJS = post.o tests.o board.o bf533_linux.o bf533_string.o cache.o muldi3.o +COBJS-y += bf533_string.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += cache.o +COBJS-y += muldi3.o +COBJS-y += post.o +COBJS-y += tests.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_blackfin/bf533_linux.c b/lib_blackfin/bootm.c similarity index 74% rename from lib_blackfin/bf533_linux.c rename to lib_blackfin/bootm.c index 80a3dc7d6..1ea80f4e3 100644 --- a/lib_blackfin/bf533_linux.c +++ b/lib_blackfin/bootm.c @@ -42,22 +42,42 @@ extern void swap_to(int device_id); #endif -extern image_header_t header; extern void flush_instruction_cache(void); extern void flush_data_cache(void); static char *make_command_line(void); void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong * len_ptr, int verify) + bootm_headers_t *images) { - int (*appl) (char *cmdline); - char *cmdline; + int (*appl) (char *cmdline); + char *cmdline; + ulong ep = 0; + + if (!images->autostart) + return ; #ifdef SHARED_RESOURCES swap_to(FLASH); #endif - appl = (int (*)(char *))ntohl(header.ih_ep); + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + int ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; + } +#endif + } else { + puts ("Could not find kernel entry point!\n"); + goto error; + } + appl = (int (*)(char *))ep; + printf("Starting Kernel at = %x\n", appl); cmdline = make_command_line(); if (icache_status()) { @@ -69,6 +89,13 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], dcache_disable(); } (*appl) (cmdline); + /* does not return */ + return; + +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return; } char *make_command_line(void) diff --git a/lib_generic/Makefile b/lib_generic/Makefile index 9713353dd..abee19a2b 100644 --- a/lib_generic/Makefile +++ b/lib_generic/Makefile @@ -34,7 +34,9 @@ COBJS-y += crc32.o COBJS-y += ctype.o COBJS-y += display_options.o COBJS-y += div64.o +COBJS-y += lmb.o COBJS-y += ldiv.o +COBJS-$(CONFIG_MD5) += md5.o COBJS-y += sha1.o COBJS-y += string.o COBJS-y += vsprintf.o diff --git a/lib_generic/bzlib.c b/lib_generic/bzlib.c index 87e6a6eed..0d3f9c2d3 100644 --- a/lib_generic/bzlib.c +++ b/lib_generic/bzlib.c @@ -1592,6 +1592,10 @@ const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum) } #endif +void bz_internal_error(int errcode) +{ + printf ("BZIP2 internal error %d\n", errcode); +} /*-------------------------------------------------------------*/ /*--- end bzlib.c ---*/ diff --git a/lib_generic/lmb.c b/lib_generic/lmb.c new file mode 100644 index 000000000..3b8c805e8 --- /dev/null +++ b/lib_generic/lmb.c @@ -0,0 +1,280 @@ +/* + * Procedures for maintaining information about logical memory blocks. + * + * Peter Bergner, IBM Corp. June 2001. + * Copyright (C) 2001 Peter Bergner. + * + * 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 +#include + +#define LMB_ALLOC_ANYWHERE 0 + +void lmb_dump_all(struct lmb *lmb) +{ +#ifdef DEBUG + unsigned long i; + + debug("lmb_dump_all:\n"); + debug(" memory.cnt = 0x%lx\n", lmb->memory.cnt); + debug(" memory.size = 0x%08x\n", lmb->memory.size); + for (i=0; i < lmb->memory.cnt ;i++) { + debug(" memory.reg[0x%x].base = 0x%08x\n", i, + lmb->memory.region[i].base); + debug(" .size = 0x%08x\n", + lmb->memory.region[i].size); + } + + debug("\n reserved.cnt = 0x%lx\n", lmb->reserved.cnt); + debug(" reserved.size = 0x%08x\n", lmb->reserved.size); + for (i=0; i < lmb->reserved.cnt ;i++) { + debug(" reserved.reg[0x%x].base = 0x%08x\n", i, + lmb->reserved.region[i].base); + debug(" .size = 0x%08x\n", + lmb->reserved.region[i].size); + } +#endif /* DEBUG */ +} + +static unsigned long lmb_addrs_overlap(ulong base1, + ulong size1, ulong base2, ulong size2) +{ + return ((base1 < (base2+size2)) && (base2 < (base1+size1))); +} + +static long lmb_addrs_adjacent(ulong base1, ulong size1, + ulong base2, ulong size2) +{ + if (base2 == base1 + size1) + return 1; + else if (base1 == base2 + size2) + return -1; + + return 0; +} + +static long lmb_regions_adjacent(struct lmb_region *rgn, + unsigned long r1, unsigned long r2) +{ + ulong base1 = rgn->region[r1].base; + ulong size1 = rgn->region[r1].size; + ulong base2 = rgn->region[r2].base; + ulong size2 = rgn->region[r2].size; + + return lmb_addrs_adjacent(base1, size1, base2, size2); +} + +static void lmb_remove_region(struct lmb_region *rgn, unsigned long r) +{ + unsigned long i; + + for (i = r; i < rgn->cnt - 1; i++) { + rgn->region[i].base = rgn->region[i + 1].base; + rgn->region[i].size = rgn->region[i + 1].size; + } + rgn->cnt--; +} + +/* Assumption: base addr of region 1 < base addr of region 2 */ +static void lmb_coalesce_regions(struct lmb_region *rgn, + unsigned long r1, unsigned long r2) +{ + rgn->region[r1].size += rgn->region[r2].size; + lmb_remove_region(rgn, r2); +} + +void lmb_init(struct lmb *lmb) +{ + /* Create a dummy zero size LMB which will get coalesced away later. + * This simplifies the lmb_add() code below... + */ + lmb->memory.region[0].base = 0; + lmb->memory.region[0].size = 0; + lmb->memory.cnt = 1; + lmb->memory.size = 0; + + /* Ditto. */ + lmb->reserved.region[0].base = 0; + lmb->reserved.region[0].size = 0; + lmb->reserved.cnt = 1; + lmb->reserved.size = 0; +} + +/* This routine called with relocation disabled. */ +static long lmb_add_region(struct lmb_region *rgn, ulong base, ulong size) +{ + unsigned long coalesced = 0; + long adjacent, i; + + if ((rgn->cnt == 1) && (rgn->region[0].size == 0)) { + rgn->region[0].base = base; + rgn->region[0].size = size; + return 0; + } + + /* First try and coalesce this LMB with another. */ + for (i=0; i < rgn->cnt; i++) { + ulong rgnbase = rgn->region[i].base; + ulong rgnsize = rgn->region[i].size; + + if ((rgnbase == base) && (rgnsize == size)) + /* Already have this region, so we're done */ + return 0; + + adjacent = lmb_addrs_adjacent(base,size,rgnbase,rgnsize); + if ( adjacent > 0 ) { + rgn->region[i].base -= size; + rgn->region[i].size += size; + coalesced++; + break; + } + else if ( adjacent < 0 ) { + rgn->region[i].size += size; + coalesced++; + break; + } + } + + if ((i < rgn->cnt-1) && lmb_regions_adjacent(rgn, i, i+1) ) { + lmb_coalesce_regions(rgn, i, i+1); + coalesced++; + } + + if (coalesced) + return coalesced; + if (rgn->cnt >= MAX_LMB_REGIONS) + return -1; + + /* Couldn't coalesce the LMB, so add it to the sorted table. */ + for (i = rgn->cnt-1; i >= 0; i--) { + if (base < rgn->region[i].base) { + rgn->region[i+1].base = rgn->region[i].base; + rgn->region[i+1].size = rgn->region[i].size; + } else { + rgn->region[i+1].base = base; + rgn->region[i+1].size = size; + break; + } + } + + if (base < rgn->region[0].base) { + rgn->region[0].base = base; + rgn->region[0].size = size; + } + + rgn->cnt++; + + return 0; +} + +/* This routine may be called with relocation disabled. */ +long lmb_add(struct lmb *lmb, ulong base, ulong size) +{ + struct lmb_region *_rgn = &(lmb->memory); + + return lmb_add_region(_rgn, base, size); +} + +long lmb_reserve(struct lmb *lmb, ulong base, ulong size) +{ + struct lmb_region *_rgn = &(lmb->reserved); + + return lmb_add_region(_rgn, base, size); +} + +long lmb_overlaps_region(struct lmb_region *rgn, ulong base, + ulong size) +{ + unsigned long i; + + for (i=0; i < rgn->cnt; i++) { + ulong rgnbase = rgn->region[i].base; + ulong rgnsize = rgn->region[i].size; + if ( lmb_addrs_overlap(base,size,rgnbase,rgnsize) ) { + break; + } + } + + return (i < rgn->cnt) ? i : -1; +} + +ulong lmb_alloc(struct lmb *lmb, ulong size, ulong align) +{ + return lmb_alloc_base(lmb, size, align, LMB_ALLOC_ANYWHERE); +} + +ulong lmb_alloc_base(struct lmb *lmb, ulong size, ulong align, ulong max_addr) +{ + ulong alloc; + + alloc = __lmb_alloc_base(lmb, size, align, max_addr); + + if (alloc == 0) + printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", + size, max_addr); + + return alloc; +} + +static ulong lmb_align_down(ulong addr, ulong size) +{ + return addr & ~(size - 1); +} + +static ulong lmb_align_up(ulong addr, ulong size) +{ + return (addr + (size - 1)) & ~(size - 1); +} + +ulong __lmb_alloc_base(struct lmb *lmb, ulong size, ulong align, ulong max_addr) +{ + long i, j; + ulong base = 0; + + for (i = lmb->memory.cnt-1; i >= 0; i--) { + ulong lmbbase = lmb->memory.region[i].base; + ulong lmbsize = lmb->memory.region[i].size; + + if (max_addr == LMB_ALLOC_ANYWHERE) + base = lmb_align_down(lmbbase + lmbsize - size, align); + else if (lmbbase < max_addr) { + base = min(lmbbase + lmbsize, max_addr); + base = lmb_align_down(base - size, align); + } else + continue; + + while ((lmbbase <= base) && + ((j = lmb_overlaps_region(&(lmb->reserved), base, size)) >= 0) ) + base = lmb_align_down(lmb->reserved.region[j].base - size, + align); + + if ((base != 0) && (lmbbase <= base)) + break; + } + + if (i < 0) + return 0; + + if (lmb_add_region(&(lmb->reserved), base, lmb_align_up(size, align)) < 0) + return 0; + + return base; +} + +int lmb_is_reserved(struct lmb *lmb, ulong addr) +{ + int i; + + for (i = 0; i < lmb->reserved.cnt; i++) { + ulong upper = lmb->reserved.region[i].base + + lmb->reserved.region[i].size - 1; + if ((addr >= lmb->reserved.region[i].base) && (addr <= upper)) + return 1; + } + return 0; +} diff --git a/lib_generic/md5.c b/lib_generic/md5.c new file mode 100644 index 000000000..a51da451b --- /dev/null +++ b/lib_generic/md5.c @@ -0,0 +1,274 @@ +/* + * This file was transplanted with slight modifications from Linux sources + * (fs/cifs/md5.c) into U-Boot by Bartlomiej Sieka . + */ + +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ + +/* This code slightly modified to fit into Samba by + abartlet@samba.org Jun 2001 + and to fit the cifs vfs by + Steve French sfrench@us.ibm.com */ + +#include +#include +#include + +static void +MD5Transform(__u32 buf[4], __u32 const in[16]); + +/* + * Note: this code is harmless on little-endian machines. + */ +static void +byteReverse(unsigned char *buf, unsigned longs) +{ + __u32 t; + do { + t = (__u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | + ((unsigned) buf[1] << 8 | buf[0]); + *(__u32 *) buf = t; + buf += 4; + } while (--longs); +} + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +static void +MD5Init(struct MD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +static void +MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) +{ + register __u32 t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((__u32) len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if (t) { + unsigned char *p = (unsigned char *) ctx->in + t; + + t = 64 - t; + if (len < t) { + memmove(p, buf, len); + return; + } + memmove(p, buf, t); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (__u32 *) ctx->in); + buf += t; + len -= t; + } + /* Process data in 64-byte chunks */ + + while (len >= 64) { + memmove(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (__u32 *) ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + memmove(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +static void +MD5Final(unsigned char digest[16], struct MD5Context *ctx) +{ + unsigned int count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (__u32 *) ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + ((__u32 *) ctx->in)[14] = ctx->bits[0]; + ((__u32 *) ctx->in)[15] = ctx->bits[1]; + + MD5Transform(ctx->buf, (__u32 *) ctx->in); + byteReverse((unsigned char *) ctx->buf, 4); + memmove(digest, ctx->buf, 16); + memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ +} + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +static void +MD5Transform(__u32 buf[4], __u32 const in[16]) +{ + register __u32 a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +/* + * Calculate and store in 'output' the MD5 digest of 'len' bytes at + * 'input'. 'output' must have enough space to hold 16 bytes. + */ +void +md5 (unsigned char *input, int len, unsigned char output[16]) +{ + struct MD5Context context; + + MD5Init(&context); + MD5Update(&context, input, len); + MD5Final(output, &context); +} diff --git a/lib_i386/Makefile b/lib_i386/Makefile index e344da515..4cc29f432 100644 --- a/lib_i386/Makefile +++ b/lib_i386/Makefile @@ -25,13 +25,22 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = bios.o bios_pci.o realmode_switch.o +SOBJS-y += bios.o +SOBJS-y += bios_pci.o +SOBJS-y += realmode_switch.o -COBJS = board.o bios_setup.o i386_linux.o zimage.o realmode.o \ - pci_type1.o pci.o video_bios.o video.o +COBJS-y += bios_setup.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += pci.o +COBJS-y += pci_type1.o +COBJS-y += realmode.o +COBJS-y += video_bios.o +COBJS-y += video.o +COBJS-y += zimage.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_i386/bootm.c b/lib_i386/bootm.c new file mode 100644 index 000000000..107ebaaa6 --- /dev/null +++ b/lib_i386/bootm.c @@ -0,0 +1,107 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include + +/*cmd_boot.c*/ +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + +void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + bootm_headers_t *images) +{ + void *base_ptr; + ulong os_data, os_len; + ulong initrd_start, initrd_end; + ulong ep; + image_header_t *hdr; + int ret; +#if defined(CONFIG_FIT) + const void *data; + size_t len; +#endif + + ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_I386, + &initrd_start, &initrd_end); + if (ret) + goto error; + + if (images->legacy_hdr_valid) { + hdr = images->legacy_hdr_os; + if (image_check_type (hdr, IH_TYPE_MULTI)) { + /* if multi-part image, we need to get first subimage */ + image_multi_getimg (hdr, 0, &os_data, &os_len); + } else { + /* otherwise get image data */ + os_data = image_get_data (hdr); + os_len = image_get_data_size (hdr); + } +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + ret = fit_image_get_data (images->fit_hdr_os, + images->fit_noffset_os, &data, &len); + if (ret) { + puts ("Can't get image data/size!\n"); + goto error; + } + os_data = (ulong)data; + os_len = (ulong)len; +#endif + } else { + puts ("Could not find kernel image!\n"); + goto error; + } + + base_ptr = load_zimage ((void*)os_data, os_len, + initrd_start, initrd_end - initrd_start, 0); + + if (NULL == base_ptr) { + printf ("## Kernel loading failed ...\n"); + goto error; + + } + + if (!images->autostart) + return ; + +#ifdef DEBUG + printf ("## Transferring control to Linux (at address %08x) ...\n", + (u32)base_ptr); +#endif + + /* we assume that the kernel is in place */ + printf("\nStarting kernel ...\n\n"); + + boot_zimage(base_ptr); + /* does not return */ + return; + +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return; +} diff --git a/lib_i386/i386_linux.c b/lib_i386/i386_linux.c deleted file mode 100644 index b4a6f5a3c..000000000 --- a/lib_i386/i386_linux.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include - -/*cmd_boot.c*/ -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - -extern image_header_t header; /* from cmd_bootm.c */ - - -image_header_t *fake_header(image_header_t *hdr, void *ptr, int size) -{ - /* try each supported image type in order */ - if (NULL != fake_zimage_header(hdr, ptr, size)) { - return hdr; - } - - return NULL; -} - - -void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) -{ - void *base_ptr; - - ulong len = 0, checksum; - ulong initrd_start, initrd_end; - ulong data; - image_header_t *hdr = &header; - - /* - * Check if there is an initrd image - */ - if (argc >= 3) { - addr = simple_strtoul(argv[2], NULL, 16); - - printf ("## Loading Ramdisk Image at %08lx ...\n", addr); - - /* Copy header so we can blank CRC field for re-calculation */ - memcpy (&header, (char *)addr, sizeof(image_header_t)); - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - printf ("Bad Magic Number\n"); - do_reset (cmdtp, flag, argc, argv); - } - - data = (ulong)&header; - len = sizeof(image_header_t); - - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (char *)data, len) != checksum) { - printf ("Bad Header Checksum\n"); - do_reset (cmdtp, flag, argc, argv); - } - - print_image_hdr (hdr); - - data = addr + sizeof(image_header_t); - len = ntohl(hdr->ih_size); - - if (verify) { - ulong csum = 0; - - printf (" Verifying Checksum ... "); - csum = crc32 (0, (char *)data, len); - if (csum != ntohl(hdr->ih_dcrc)) { - printf ("Bad Data CRC\n"); - do_reset (cmdtp, flag, argc, argv); - } - printf ("OK\n"); - } - - if ((hdr->ih_os != IH_OS_LINUX) || - (hdr->ih_arch != IH_CPU_I386) || - (hdr->ih_type != IH_TYPE_RAMDISK) ) { - printf ("No Linux i386 Ramdisk Image\n"); - do_reset (cmdtp, flag, argc, argv); - } - - /* - * Now check if we have a multifile image - */ - } else if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1])) { - ulong tail = ntohl(len_ptr[0]) % 4; - int i; - - /* skip kernel length and terminator */ - data = (ulong)(&len_ptr[2]); - /* skip any additional image length fields */ - for (i=1; len_ptr[i]; ++i) - data += 4; - /* add kernel length, and align */ - data += ntohl(len_ptr[0]); - if (tail) { - data += 4 - tail; - } - - len = ntohl(len_ptr[1]); - - } else { - /* - * no initrd image - */ - data = 0; - } - -#ifdef DEBUG - if (!data) { - printf ("No initrd\n"); - } -#endif - - if (data) { - initrd_start = data; - initrd_end = initrd_start + len; - printf (" Loading Ramdisk to %08lx, end %08lx ... ", - initrd_start, initrd_end); - memmove ((void *)initrd_start, (void *)data, len); - printf ("OK\n"); - } else { - initrd_start = 0; - initrd_end = 0; - } - - /* if multi-part image, we need to advance base ptr */ - if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1])) { - int i; - for (i=0, addr+=sizeof(int); len_ptr[i++]; addr+=sizeof(int)); - } - - base_ptr = load_zimage((void*)addr + sizeof(image_header_t), ntohl(hdr->ih_size), - initrd_start, initrd_end-initrd_start, 0); - - if (NULL == base_ptr) { - printf ("## Kernel loading failed ...\n"); - do_reset(cmdtp, flag, argc, argv); - - } - -#ifdef DEBUG - printf ("## Transferring control to Linux (at address %08x) ...\n", - (u32)base_ptr); -#endif - - /* we assume that the kernel is in place */ - printf("\nStarting kernel ...\n\n"); - - boot_zimage(base_ptr); - -} diff --git a/lib_i386/zimage.c b/lib_i386/zimage.c index 3510f2fd6..c3b4e597a 100644 --- a/lib_i386/zimage.c +++ b/lib_i386/zimage.c @@ -212,7 +212,6 @@ void *load_zimage(char *image, unsigned long kernel_size, return setup_base; } - void boot_zimage(void *setup_base) { struct pt_regs regs; @@ -224,52 +223,3 @@ void boot_zimage(void *setup_base) regs.eflags = 0; enter_realmode(((u32)setup_base+SETUP_START_OFFSET)>>4, 0, ®s, ®s); } - - -image_header_t *fake_zimage_header(image_header_t *hdr, void *ptr, int size) -{ - /* There is no way to know the size of a zImage ... * - * so we assume that 2MB will be enough for now */ -#define ZIMAGE_SIZE 0x200000 - - /* load a 1MB, the loaded will have to be moved to its final - * position again later... */ -#define ZIMAGE_LOAD 0x100000 - - ulong checksum; - - if (KERNEL_MAGIC != *(u16*)(ptr + BOOT_FLAG_OFF)) { - /* not a zImage or bzImage */ - return NULL; - } - - if (-1 == size) { - size = ZIMAGE_SIZE; - } -#if 0 - checksum = crc32 (0, ptr, size); -#else - checksum = 0; -#endif - memset(hdr, 0, sizeof(image_header_t)); - - /* Build new header */ - hdr->ih_magic = htonl(IH_MAGIC); - hdr->ih_time = 0; - hdr->ih_size = htonl(size); - hdr->ih_load = htonl(ZIMAGE_LOAD); - hdr->ih_ep = 0; - hdr->ih_dcrc = htonl(checksum); - hdr->ih_os = IH_OS_LINUX; - hdr->ih_arch = IH_CPU_I386; - hdr->ih_type = IH_TYPE_KERNEL; - hdr->ih_comp = IH_COMP_NONE; - - strncpy((char *)hdr->ih_name, "(none)", IH_NMLEN); - - checksum = crc32(0,(const char *)hdr,sizeof(image_header_t)); - - hdr->ih_hcrc = htonl(checksum); - - return hdr; -} diff --git a/lib_m68k/Makefile b/lib_m68k/Makefile index 03784fd84..f6924cd0b 100644 --- a/lib_m68k/Makefile +++ b/lib_m68k/Makefile @@ -25,12 +25,17 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = +SOBJS-y += -COBJS = cache.o traps.o time.o interrupts.o board.o m68k_linux.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += cache.o +COBJS-y += interrupts.o +COBJS-y += time.o +COBJS-y += traps.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_m68k/bootm.c b/lib_m68k/bootm.c new file mode 100644 index 000000000..6f49c3161 --- /dev/null +++ b/lib_m68k/bootm.c @@ -0,0 +1,171 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SHOW_BOOT_PROGRESS +# include +#endif + +DECLARE_GLOBAL_DATA_PTR; + +#define PHYSADDR(x) x + +#define LINUX_MAX_ENVS 256 +#define LINUX_MAX_ARGS 256 + +static ulong get_sp (void); +static void set_clocks_in_mhz (bd_t *kbd); +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + +void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, + int argc, char *argv[], + bootm_headers_t *images) +{ + ulong sp; + + ulong rd_data_start, rd_data_end, rd_len; + ulong initrd_start, initrd_end; + int ret; + + ulong cmd_start, cmd_end; + ulong bootmap_base; + bd_t *kbd; + ulong ep = 0; + void (*kernel) (bd_t *, ulong, ulong, ulong, ulong); + struct lmb *lmb = images->lmb; + + bootmap_base = getenv_bootm_low(); + + /* + * Booting a (Linux) kernel image + * + * Allocate space for command line and board info - the + * address should be as high as possible within the reach of + * the kernel (see CFG_BOOTMAPSZ settings), but in unused + * memory, which means far enough below the current stack + * pointer. + */ + sp = get_sp(); + debug ("## Current stack ends at 0x%08lx ", sp); + + /* adjust sp by 1K to be safe */ + sp -= 1024; + lmb_reserve(lmb, sp, (CFG_SDRAM_BASE + gd->ram_size - sp)); + + /* allocate space and init command line */ + ret = boot_get_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base); + if (ret) { + puts("ERROR with allocation of cmdline\n"); + goto error; + } + + /* allocate space for kernel copy of board info */ + ret = boot_get_kbd (lmb, &kbd, bootmap_base); + if (ret) { + puts("ERROR with allocation of kernel bd\n"); + goto error; + } + set_clocks_in_mhz(kbd); + + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; + } +#endif + } else { + puts ("Could not find kernel entry point!\n"); + goto error; + } + kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; + + /* find ramdisk */ + ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_M68K, + &rd_data_start, &rd_data_end); + if (ret) + goto error; + + rd_len = rd_data_end - rd_data_start; + ret = boot_ramdisk_high (lmb, rd_data_start, rd_len, + &initrd_start, &initrd_end); + if (ret) + goto error; + + debug("## Transferring control to Linux (at address %08lx) ...\n", + (ulong) kernel); + + show_boot_progress (15); + + if (!images->autostart) + return; + /* + * Linux Kernel Parameters (passing board info data): + * r3: ptr to board info data + * r4: initrd_start or 0 if no initrd + * r5: initrd_end - unused if r4 is 0 + * r6: Start of command line string + * r7: End of command line string + */ + (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); + /* does not return */ + return ; + +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return ; +} + +static ulong get_sp (void) +{ + ulong sp; + + asm("movel %%a7, %%d0\n" + "movel %%d0, %0\n": "=d"(sp): :"%d0"); + + return sp; +} + +static void set_clocks_in_mhz (bd_t *kbd) +{ + char *s; + + if ((s = getenv("clocks_in_mhz")) != NULL) { + /* convert all clock information to MHz */ + kbd->bi_intfreq /= 1000000L; + kbd->bi_busfreq /= 1000000L; + } +} diff --git a/lib_m68k/m68k_linux.c b/lib_m68k/m68k_linux.c deleted file mode 100644 index cc974c2d6..000000000 --- a/lib_m68k/m68k_linux.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -#define PHYSADDR(x) x - -#define LINUX_MAX_ENVS 256 -#define LINUX_MAX_ARGS 256 - -#define CHUNKSZ (64 * 1024) - -#ifdef CONFIG_SHOW_BOOT_PROGRESS -# include -# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) -#else -# define SHOW_BOOT_PROGRESS(arg) -#endif - -extern image_header_t header; - -void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, - int argc, char *argv[], - ulong addr, ulong * len_ptr, int verify) -{ - ulong sp; - ulong len, checksum; - ulong initrd_start, initrd_end; - ulong cmd_start, cmd_end; - ulong initrd_high; - ulong data; - int initrd_copy_to_ram = 1; - char *cmdline; - char *s; - bd_t *kbd; - void (*kernel) (bd_t *, ulong, ulong, ulong, ulong); - image_header_t *hdr = &header; - - if ((s = getenv("initrd_high")) != NULL) { - /* a value of "no" or a similar string will act like 0, - * turning the "load high" feature off. This is intentional. - */ - initrd_high = simple_strtoul(s, NULL, 16); - if (initrd_high == ~0) - initrd_copy_to_ram = 0; - } else { /* not set, no restrictions to load high */ - initrd_high = ~0; - } - -#ifdef CONFIG_LOGBUFFER - kbd = gd->bd; - /* Prevent initrd from overwriting logbuffer */ - if (initrd_high < (kbd->bi_memsize - LOGBUFF_LEN - LOGBUFF_OVERHEAD)) - initrd_high = kbd->bi_memsize - LOGBUFF_LEN - LOGBUFF_OVERHEAD; - debug("## Logbuffer at 0x%08lX ", kbd->bi_memsize - LOGBUFF_LEN); -#endif - - /* - * Booting a (Linux) kernel image - * - * Allocate space for command line and board info - the - * address should be as high as possible within the reach of - * the kernel (see CFG_BOOTMAPSZ settings), but in unused - * memory, which means far enough below the current stack - * pointer. - */ - asm("movel %%a7, %%d0\n" - "movel %%d0, %0\n": "=d"(sp): :"%d0"); - - debug("## Current stack ends at 0x%08lX ", sp); - - sp -= 2048; /* just to be sure */ - if (sp > CFG_BOOTMAPSZ) - sp = CFG_BOOTMAPSZ; - sp &= ~0xF; - - debug("=> set upper limit to 0x%08lX\n", sp); - - cmdline = (char *)((sp - CFG_BARGSIZE) & ~0xF); - kbd = (bd_t *) (((ulong) cmdline - sizeof(bd_t)) & ~0xF); - - if ((s = getenv("bootargs")) == NULL) - s = ""; - - strcpy(cmdline, s); - - cmd_start = (ulong) & cmdline[0]; - cmd_end = cmd_start + strlen(cmdline); - - *kbd = *(gd->bd); - -#ifdef DEBUG - printf("## cmdline at 0x%08lX ... 0x%08lX\n", cmd_start, cmd_end); - - do_bdinfo(NULL, 0, 0, NULL); -#endif - - if ((s = getenv("clocks_in_mhz")) != NULL) { - /* convert all clock information to MHz */ - kbd->bi_intfreq /= 1000000L; - kbd->bi_busfreq /= 1000000L; - } - - kernel = - (void (*)(bd_t *, ulong, ulong, ulong, ulong))ntohl(hdr->ih_ep); - - /* - * Check if there is an initrd image - */ - - if (argc >= 3) { - debug("Not skipping initrd\n"); - SHOW_BOOT_PROGRESS(9); - - addr = simple_strtoul(argv[2], NULL, 16); - - printf("## Loading RAMDisk Image at %08lx ...\n", addr); - - /* Copy header so we can blank CRC field for re-calculation */ - memmove(&header, (char *)addr, sizeof(image_header_t)); - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - puts("Bad Magic Number\n"); - SHOW_BOOT_PROGRESS(-10); - do_reset(cmdtp, flag, argc, argv); - } - - data = (ulong) & header; - len = sizeof(image_header_t); - - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32(0, (uchar *) data, len) != checksum) { - puts("Bad Header Checksum\n"); - SHOW_BOOT_PROGRESS(-11); - do_reset(cmdtp, flag, argc, argv); - } - - SHOW_BOOT_PROGRESS(10); - - print_image_hdr(hdr); - - data = addr + sizeof(image_header_t); - len = ntohl(hdr->ih_size); - - if (verify) { - ulong csum = 0; -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - ulong cdata = data, edata = cdata + len; -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ - - puts(" Verifying Checksum ... "); - -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - - while (cdata < edata) { - ulong chunk = edata - cdata; - - if (chunk > CHUNKSZ) - chunk = CHUNKSZ; - csum = crc32(csum, (uchar *) cdata, chunk); - cdata += chunk; - - WATCHDOG_RESET(); - } -#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ - csum = crc32(0, (uchar *) data, len); -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ - - if (csum != ntohl(hdr->ih_dcrc)) { - puts("Bad Data CRC\n"); - SHOW_BOOT_PROGRESS(-12); - do_reset(cmdtp, flag, argc, argv); - } - puts("OK\n"); - } - - SHOW_BOOT_PROGRESS(11); - - if ((hdr->ih_os != IH_OS_LINUX) || - (hdr->ih_arch != IH_CPU_M68K) || - (hdr->ih_type != IH_TYPE_RAMDISK)) { - puts("No Linux ColdFire Ramdisk Image\n"); - SHOW_BOOT_PROGRESS(-13); - do_reset(cmdtp, flag, argc, argv); - } - - /* - * Now check if we have a multifile image - */ - } else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) { - u_long tail = ntohl(len_ptr[0]) % 4; - int i; - - SHOW_BOOT_PROGRESS(13); - - /* skip kernel length and terminator */ - data = (ulong) (&len_ptr[2]); - /* skip any additional image length fields */ - for (i = 1; len_ptr[i]; ++i) - data += 4; - /* add kernel length, and align */ - data += ntohl(len_ptr[0]); - if (tail) { - data += 4 - tail; - } - - len = ntohl(len_ptr[1]); - - } else { - /* - * no initrd image - */ - SHOW_BOOT_PROGRESS(14); - - len = data = 0; - } - - if (!data) { - debug("No initrd\n"); - } - - if (data) { - if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ - initrd_start = data; - initrd_end = initrd_start + len; - } else { - initrd_start = (ulong) kbd - len; - initrd_start &= ~(4096 - 1); /* align on page */ - - if (initrd_high) { - ulong nsp; - - /* - * the inital ramdisk does not need to be within - * CFG_BOOTMAPSZ as it is not accessed until after - * the mm system is initialised. - * - * do the stack bottom calculation again and see if - * the initrd will fit just below the monitor stack - * bottom without overwriting the area allocated - * above for command line args and board info. - */ - asm("movel %%a7, %%d0\n" - "movel %%d0, %0\n": "=d"(nsp): :"%d0"); - - nsp -= 2048; /* just to be sure */ - nsp &= ~0xF; - - if (nsp > initrd_high) /* limit as specified */ - nsp = initrd_high; - - nsp -= len; - nsp &= ~(4096 - 1); /* align on page */ - - if (nsp >= sp) - initrd_start = nsp; - } - - SHOW_BOOT_PROGRESS(12); - - debug - ("## initrd at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", - data, data + len - 1, len, len); - - initrd_end = initrd_start + len; - printf(" Loading Ramdisk to %08lx, end %08lx ... ", - initrd_start, initrd_end); -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - { - size_t l = len; - void *to = (void *)initrd_start; - void *from = (void *)data; - - while (l > 0) { - size_t tail = - (l > CHUNKSZ) ? CHUNKSZ : l; - WATCHDOG_RESET(); - memmove(to, from, tail); - to += tail; - from += tail; - l -= tail; - } - } -#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ - memmove((void *)initrd_start, (void *)data, len); -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ - puts("OK\n"); - } - } else { - initrd_start = 0; - initrd_end = 0; - } - - debug("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) kernel); - - SHOW_BOOT_PROGRESS(15); - - /* - * Linux Kernel Parameters (passing board info data): - * r3: ptr to board info data - * r4: initrd_start or 0 if no initrd - * r5: initrd_end - unused if r4 is 0 - * r6: Start of command line string - * r7: End of command line string - */ - (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); - /* does not return */ -} diff --git a/lib_microblaze/Makefile b/lib_microblaze/Makefile index 82b7beadb..141b08280 100644 --- a/lib_microblaze/Makefile +++ b/lib_microblaze/Makefile @@ -25,12 +25,15 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = +SOBJS-y += -COBJS = board.o microblaze_linux.o time.o cache.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += cache.o +COBJS-y += time.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_microblaze/bootm.c b/lib_microblaze/bootm.c new file mode 100644 index 000000000..fab4a5441 --- /dev/null +++ b/lib_microblaze/bootm.c @@ -0,0 +1,81 @@ +/* + * (C) Copyright 2007 Michal Simek + * (C) Copyright 2004 Atmark Techno, Inc. + * + * Michal SIMEK + * Yasushi SHOJI + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); + +void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], + bootm_headers_t *images) +{ + /* First parameter is mapped to $r5 for kernel boot args */ + void (*theKernel) (char *); + char *commandline = getenv ("bootargs"); + ulong ep = 0; + + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + int ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; + } +#endif + } else { + puts ("Could not find kernel entry point!\n"); + goto error; + } + theKernel = (void (*)(char *))ep; + + show_boot_progress (15); + +#ifdef DEBUG + printf ("## Transferring control to Linux (at address %08lx) ...\n", + (ulong) theKernel); +#endif + + if (!images->autostart) + return ; + + theKernel (commandline); + /* does not return */ + return; + +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return; +} diff --git a/lib_microblaze/microblaze_linux.c b/lib_microblaze/microblaze_linux.c deleted file mode 100644 index 68b58d4be..000000000 --- a/lib_microblaze/microblaze_linux.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * (C) Copyright 2007 Michal Simek - * (C) Copyright 2004 Atmark Techno, Inc. - * - * Michal SIMEK - * Yasushi SHOJI - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -extern image_header_t header; /* from cmd_bootm.c */ -/*cmd_boot.c*/ -extern int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]); - -void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong * len_ptr, int verify) -{ - ulong len = 0, checksum; - ulong initrd_start, initrd_end; - ulong data; - /* First parameter is mapped to $r5 for kernel boot args */ - void (*theKernel) (char *); - image_header_t *hdr = &header; - char *commandline = getenv ("bootargs"); - int i; - - theKernel = (void (*)(char *))ntohl (hdr->ih_ep); - - /* Check if there is an initrd image */ - if (argc >= 3) { - show_boot_progress (9); - - addr = simple_strtoul (argv[2], NULL, 16); - - printf ("## Loading Ramdisk Image at %08lx ...\n", addr); - - /* Copy header so we can blank CRC field for re-calculation */ - memcpy (&header, (char *)addr, sizeof (image_header_t)); - - if (ntohl (hdr->ih_magic) != IH_MAGIC) { - printf ("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset (cmdtp, flag, argc, argv); - } - - data = (ulong) & header; - len = sizeof (image_header_t); - - checksum = ntohl (hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (char *)data, len) != checksum) { - printf ("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset (cmdtp, flag, argc, argv); - } - - show_boot_progress (10); - - print_image_hdr (hdr); - - data = addr + sizeof (image_header_t); - len = ntohl (hdr->ih_size); - - if (verify) { - ulong csum = 0; - - printf (" Verifying Checksum ... "); - csum = crc32 (0, (char *)data, len); - if (csum != ntohl (hdr->ih_dcrc)) { - printf ("Bad Data CRC\n"); - show_boot_progress (-12); - do_reset (cmdtp, flag, argc, argv); - } - printf ("OK\n"); - } - - show_boot_progress (11); - - if ((hdr->ih_os != IH_OS_LINUX) || - (hdr->ih_arch != IH_CPU_MICROBLAZE) || - (hdr->ih_type != IH_TYPE_RAMDISK)) { - printf ("No Linux Microblaze Ramdisk Image\n"); - show_boot_progress (-13); - do_reset (cmdtp, flag, argc, argv); - } - - /* - * Now check if we have a multifile image - */ - } else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) { - ulong tail = ntohl (len_ptr[0]) % 4; - - show_boot_progress (13); - - /* skip kernel length and terminator */ - data = (ulong) (&len_ptr[2]); - /* skip any additional image length fields */ - for (i = 1; len_ptr[i]; ++i) - data += 4; - /* add kernel length, and align */ - data += ntohl (len_ptr[0]); - if (tail) { - data += 4 - tail; - } - - len = ntohl (len_ptr[1]); - - } else { - /* - * no initrd image - */ - show_boot_progress (14); - - data = 0; - } - -#ifdef DEBUG - if (!data) { - printf ("No initrd\n"); - } -#endif - - if (data) { - initrd_start = data; - initrd_end = initrd_start + len; - } else { - initrd_start = 0; - initrd_end = 0; - } - - show_boot_progress (15); - -#ifdef DEBUG - printf ("## Transferring control to Linux (at address %08lx) ...\n", - (ulong) theKernel); -#endif - - theKernel (commandline); -} diff --git a/lib_mips/Makefile b/lib_mips/Makefile index 3163f00e0..799eaf265 100644 --- a/lib_mips/Makefile +++ b/lib_mips/Makefile @@ -25,12 +25,14 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = +SOBJS-y += -COBJS = board.o time.o mips_linux.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += time.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_mips/mips_linux.c b/lib_mips/bootm.c similarity index 61% rename from lib_mips/mips_linux.c rename to lib_mips/bootm.c index 556b1804e..e4c139efa 100644 --- a/lib_mips/mips_linux.c +++ b/lib_mips/bootm.c @@ -33,10 +33,6 @@ DECLARE_GLOBAL_DATA_PTR; #define LINUX_MAX_ENVS 256 #define LINUX_MAX_ARGS 256 -extern image_header_t header; /* from cmd_bootm.c */ - -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); - static int linux_argc; static char ** linux_argv; @@ -47,126 +43,40 @@ static int linux_env_idx; static void linux_params_init (ulong start, char * commandline); static void linux_env_set (char * env_name, char * env_val); +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong * len_ptr, int verify) + bootm_headers_t *images) { - ulong len = 0, checksum; - ulong initrd_start, initrd_end; - ulong data; - void (*theKernel) (int, char **, char **, int *); - image_header_t *hdr = &header; - char *commandline = getenv ("bootargs"); - char env_buf[12]; + ulong initrd_start, initrd_end; + ulong ep = 0; + void (*theKernel) (int, char **, char **, int *); + char *commandline = getenv ("bootargs"); + char env_buf[12]; + int ret; - theKernel = - (void (*)(int, char **, char **, int *)) ntohl (hdr->ih_ep); - - /* - * Check if there is an initrd image - */ - if (argc >= 3) { - show_boot_progress (9); - - addr = simple_strtoul (argv[2], NULL, 16); - - printf ("## Loading Ramdisk Image at %08lx ...\n", addr); - - /* Copy header so we can blank CRC field for re-calculation */ - memcpy (&header, (char *) addr, sizeof (image_header_t)); - - if (ntohl (hdr->ih_magic) != IH_MAGIC) { - printf ("Bad Magic Number\n"); - show_boot_progress (-10); - do_reset (cmdtp, flag, argc, argv); + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; } - - data = (ulong) & header; - len = sizeof (image_header_t); - - checksum = ntohl (hdr->ih_hcrc); - hdr->ih_hcrc = 0; - - if (crc32 (0, (uchar *) data, len) != checksum) { - printf ("Bad Header Checksum\n"); - show_boot_progress (-11); - do_reset (cmdtp, flag, argc, argv); - } - - show_boot_progress (10); - - print_image_hdr (hdr); - - data = addr + sizeof (image_header_t); - len = ntohl (hdr->ih_size); - - if (verify) { - ulong csum = 0; - - printf (" Verifying Checksum ... "); - csum = crc32 (0, (uchar *) data, len); - if (csum != ntohl (hdr->ih_dcrc)) { - printf ("Bad Data CRC\n"); - show_boot_progress (-12); - do_reset (cmdtp, flag, argc, argv); - } - printf ("OK\n"); - } - - show_boot_progress (11); - - if ((hdr->ih_os != IH_OS_LINUX) || - (hdr->ih_arch != IH_CPU_MIPS) || - (hdr->ih_type != IH_TYPE_RAMDISK)) { - printf ("No Linux MIPS Ramdisk Image\n"); - show_boot_progress (-13); - do_reset (cmdtp, flag, argc, argv); - } - - /* - * Now check if we have a multifile image - */ - } else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) { - ulong tail = ntohl (len_ptr[0]) % 4; - int i; - - show_boot_progress (13); - - /* skip kernel length and terminator */ - data = (ulong) (&len_ptr[2]); - /* skip any additional image length fields */ - for (i = 1; len_ptr[i]; ++i) - data += 4; - /* add kernel length, and align */ - data += ntohl (len_ptr[0]); - if (tail) { - data += 4 - tail; - } - - len = ntohl (len_ptr[1]); - - } else { - /* - * no initrd image - */ - show_boot_progress (14); - - data = 0; - } - -#ifdef DEBUG - if (!data) { - printf ("No initrd\n"); - } #endif - - if (data) { - initrd_start = data; - initrd_end = initrd_start + len; } else { - initrd_start = 0; - initrd_end = 0; + puts ("Could not find kernel entry point!\n"); + goto error; } + theKernel = (void (*)(int, char **, char **, int *))ep; + + ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_MIPS, + &initrd_start, &initrd_end); + if (ret) + goto error; show_boot_progress (15); @@ -203,10 +113,20 @@ void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[], sprintf (env_buf, "0x%X", (uint) (gd->bd->bi_flashsize)); linux_env_set ("flash_size", env_buf); + if (!images->autostart) + return ; + /* we assume that the kernel is in place */ printf ("\nStarting kernel ...\n\n"); theKernel (linux_argc, linux_argv, linux_env, 0); + /* does not return */ + return; + +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return; } static void linux_params_init (ulong start, char *line) diff --git a/lib_nios/Makefile b/lib_nios/Makefile index 7c9d62cf7..c41d981a3 100644 --- a/lib_nios/Makefile +++ b/lib_nios/Makefile @@ -25,12 +25,17 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = +SOBJS-y += -COBJS = board.o cache.o divmod.o nios_linux.o mult.o time.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += cache.o +COBJS-y += divmod.o +COBJS-y += mult.o +COBJS-y += time.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_nios/nios_linux.c b/lib_nios/bootm.c similarity index 96% rename from lib_nios/nios_linux.c rename to lib_nios/bootm.c index eef17573f..fb2e9b520 100644 --- a/lib_nios/nios_linux.c +++ b/lib_nios/bootm.c @@ -29,6 +29,6 @@ * */ void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) + bootm_headers_t *images) { } diff --git a/lib_nios2/Makefile b/lib_nios2/Makefile index 1ff2f29bc..717aa9bfb 100644 --- a/lib_nios2/Makefile +++ b/lib_nios2/Makefile @@ -25,12 +25,16 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = cache.o +SOBJS-y += cache.o -COBJS = board.o divmod.o nios_linux.o mult.o time.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += divmod.o +COBJS-y += mult.o +COBJS-y += time.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_nios2/nios_linux.c b/lib_nios2/bootm.c similarity index 61% rename from lib_nios2/nios_linux.c rename to lib_nios2/bootm.c index 9eb34264d..0c89e9635 100644 --- a/lib_nios2/nios_linux.c +++ b/lib_nios2/bootm.c @@ -25,16 +25,43 @@ #include #include -extern image_header_t header; /* common/cmd_bootm.c */ +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) + bootm_headers_t *images) { - image_header_t *hdr = &header; - void (*kernel)(void) = (void (*)(void))ntohl (hdr->ih_ep); + ulong ep = 0; + + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + int ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; + } +#endif + } else { + puts ("Could not find kernel entry point!\n"); + goto error; + } + void (*kernel)(void) = (void (*)(void))ep; + + if (!images->autostart) + return ; /* For now we assume the Microtronix linux ... which only * needs to be called ;-) */ kernel (); + /* does not return */ + return; + +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return; } diff --git a/lib_ppc/Makefile b/lib_ppc/Makefile index afbd5caf5..3d76b700e 100644 --- a/lib_ppc/Makefile +++ b/lib_ppc/Makefile @@ -25,13 +25,21 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = ppccache.o ppcstring.o ticks.o +SOBJS-y += ppccache.o +SOBJS-y += ppcstring.o +SOBJS-y += ticks.o -COBJS = board.o \ - bat_rw.o cache.o extable.o kgdb.o time.o interrupts.o +COBJS-y += bat_rw.o +COBJS-y += board.o +COBJS-y += bootm.o +COBJS-y += cache.o +COBJS-y += extable.o +COBJS-y += interrupts.o +COBJS-y += kgdb.o +COBJS-y += time.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_ppc/board.c b/lib_ppc/board.c index ee0213e1a..30383027c 100644 --- a/lib_ppc/board.c +++ b/lib_ppc/board.c @@ -38,6 +38,9 @@ #if defined(CONFIG_CMD_IDE) #include #endif +#if defined(CONFIG_CMD_SATA) +#include +#endif #if defined(CONFIG_CMD_SCSI) #include #endif @@ -433,7 +436,18 @@ void board_init_f (ulong bootflag) */ len = (ulong)&_end - CFG_MONITOR_BASE; +#ifndef CONFIG_MAX_MEM_MAPPED +#define CONFIG_MAX_MEM_MAPPED (256 << 20) +#endif + +#ifndef CONFIG_VERY_BIG_RAM addr = CFG_SDRAM_BASE + get_effective_memsize(); +#else + /* only allow stack below 256M */ + addr = CFG_SDRAM_BASE + + (gd->ram_size > CONFIG_MAX_MEM_MAPPED) ? + CONFIG_MAX_MEM_MAPPED : get_effective_memsize(); +#endif #ifdef CONFIG_LOGBUFFER #ifndef CONFIG_ALT_LB_ADDR @@ -1093,6 +1107,11 @@ void board_init_r (gd_t *id, ulong dest_addr) #endif #endif +#if defined(CONFIG_CMD_SATA) + puts ("SATA: "); + sata_initialize (); +#endif + #ifdef CONFIG_LAST_STAGE_INIT WATCHDOG_RESET (); /* diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c new file mode 100644 index 000000000..b893146fc --- /dev/null +++ b/lib_ppc/bootm.c @@ -0,0 +1,774 @@ +/* + * (C) Copyright 2008 Semihalf + * + * (C) Copyright 2000-2006 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_OF_LIBFDT) +#include +#include +#include + +static void fdt_error (const char *msg); +static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + bootm_headers_t *images, char **of_flat_tree, ulong *of_size); +static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, + cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + char **of_flat_tree, ulong *of_size); +#endif + +#ifdef CFG_INIT_RAM_LOCK +#include +#endif + +DECLARE_GLOBAL_DATA_PTR; + +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +extern ulong get_effective_memsize(void); +static ulong get_sp (void); +static void set_clocks_in_mhz (bd_t *kbd); + +#ifndef CFG_LINUX_LOWMEM_MAX_SIZE +#define CFG_LINUX_LOWMEM_MAX_SIZE (768*1024*1024) +#endif + +void __attribute__((noinline)) +do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + bootm_headers_t *images) +{ + ulong sp; + + ulong initrd_start, initrd_end; + ulong rd_data_start, rd_data_end, rd_len; + ulong size; + + ulong cmd_start, cmd_end, bootmap_base; + bd_t *kbd; + ulong ep = 0; + void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); + int ret; + ulong of_size = 0; + struct lmb *lmb = images->lmb; + +#if defined(CONFIG_OF_LIBFDT) + char *of_flat_tree = NULL; +#endif + + bootmap_base = getenv_bootm_low(); + size = getenv_bootm_size(); + +#ifdef DEBUG + if (((u64)bootmap_base + size) > (CFG_SDRAM_BASE + (u64)gd->ram_size)) + puts("WARNING: bootm_low + bootm_size exceed total memory\n"); + if ((bootmap_base + size) > get_effective_memsize()) + puts("WARNING: bootm_low + bootm_size exceed eff. memory\n"); +#endif + + size = min(size, get_effective_memsize()); + size = min(size, CFG_LINUX_LOWMEM_MAX_SIZE); + + if (size < getenv_bootm_size()) { + ulong base = bootmap_base + size; + printf("WARNING: adjusting available memory to %x\n", size); + lmb_reserve(lmb, base, getenv_bootm_size() - size); + } + + /* + * Booting a (Linux) kernel image + * + * Allocate space for command line and board info - the + * address should be as high as possible within the reach of + * the kernel (see CFG_BOOTMAPSZ settings), but in unused + * memory, which means far enough below the current stack + * pointer. + */ + sp = get_sp(); + debug ("## Current stack ends at 0x%08lx\n", sp); + + /* adjust sp by 1K to be safe */ + sp -= 1024; + lmb_reserve(lmb, sp, (CFG_SDRAM_BASE + get_effective_memsize() - sp)); + +#if defined(CONFIG_OF_LIBFDT) + /* find flattened device tree */ + ret = boot_get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size); + + if (ret) + goto error; +#endif + + if (!of_size) { + /* allocate space and init command line */ + ret = boot_get_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base); + if (ret) { + puts("ERROR with allocation of cmdline\n"); + goto error; + } + + /* allocate space for kernel copy of board info */ + ret = boot_get_kbd (lmb, &kbd, bootmap_base); + if (ret) { + puts("ERROR with allocation of kernel bd\n"); + goto error; + } + set_clocks_in_mhz(kbd); + } + + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; + } +#endif + } else { + puts ("Could not find kernel entry point!\n"); + goto error; + } + kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ep; + + /* find ramdisk */ + ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_PPC, + &rd_data_start, &rd_data_end); + if (ret) + goto error; + + rd_len = rd_data_end - rd_data_start; + +#if defined(CONFIG_OF_LIBFDT) + ret = boot_relocate_fdt (lmb, bootmap_base, + cmdtp, flag, argc, argv, &of_flat_tree, &of_size); + + /* + * Add the chosen node if it doesn't exist, add the env and bd_t + * if the user wants it (the logic is in the subroutines). + */ + if (of_size) { + /* pass in dummy initrd info, we'll fix up later */ + if (fdt_chosen(of_flat_tree, rd_data_start, rd_data_end, 0) < 0) { + fdt_error ("/chosen node create failed"); + goto error; + } +#ifdef CONFIG_OF_HAS_UBOOT_ENV + if (fdt_env(of_flat_tree) < 0) { + fdt_error ("/u-boot-env node create failed"); + goto error; + } +#endif +#ifdef CONFIG_OF_HAS_BD_T + if (fdt_bd_t(of_flat_tree) < 0) { + fdt_error ("/bd_t node create failed"); + goto error; + } +#endif +#ifdef CONFIG_OF_BOARD_SETUP + /* Call the board-specific fixup routine */ + ft_board_setup(of_flat_tree, gd->bd); +#endif + } +#endif /* CONFIG_OF_LIBFDT */ + + ret = boot_ramdisk_high (lmb, rd_data_start, rd_len, &initrd_start, &initrd_end); + if (ret) + goto error; + +#if defined(CONFIG_OF_LIBFDT) + /* fixup the initrd now that we know where it should be */ + if ((of_flat_tree) && (initrd_start && initrd_end)) { + uint64_t addr, size; + int total = fdt_num_mem_rsv(of_flat_tree); + int j; + + /* Look for the dummy entry and delete it */ + for (j = 0; j < total; j++) { + fdt_get_mem_rsv(of_flat_tree, j, &addr, &size); + if (addr == rd_data_start) { + fdt_del_mem_rsv(of_flat_tree, j); + break; + } + } + + ret = fdt_add_mem_rsv(of_flat_tree, initrd_start, + initrd_end - initrd_start + 1); + if (ret < 0) { + printf("fdt_chosen: %s\n", fdt_strerror(ret)); + goto error; + } + + do_fixup_by_path_u32(of_flat_tree, "/chosen", + "linux,initrd-start", initrd_start, 0); + do_fixup_by_path_u32(of_flat_tree, "/chosen", + "linux,initrd-end", initrd_end, 0); + } +#endif + debug ("## Transferring control to Linux (at address %08lx) ...\n", + (ulong)kernel); + + show_boot_progress (15); + +#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500) + unlock_ram_in_cache(); +#endif + if (!images->autostart) + return ; + +#if defined(CONFIG_OF_LIBFDT) + if (of_flat_tree) { /* device tree; boot new style */ + /* + * Linux Kernel Parameters (passing device tree): + * r3: pointer to the fdt, followed by the board info data + * r4: physical pointer to the kernel itself + * r5: NULL + * r6: NULL + * r7: NULL + */ + debug (" Booting using OF flat tree...\n"); + (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0); + /* does not return */ + } else +#endif + { + /* + * Linux Kernel Parameters (passing board info data): + * r3: ptr to board info data + * r4: initrd_start or 0 if no initrd + * r5: initrd_end - unused if r4 is 0 + * r6: Start of command line string + * r7: End of command line string + */ + debug (" Booting using board info...\n"); + (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); + /* does not return */ + } + return ; + +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return ; +} + +static ulong get_sp (void) +{ + ulong sp; + + asm( "mr %0,1": "=r"(sp) : ); + return sp; +} + +static void set_clocks_in_mhz (bd_t *kbd) +{ + char *s; + + if ((s = getenv ("clocks_in_mhz")) != NULL) { + /* convert all clock information to MHz */ + kbd->bi_intfreq /= 1000000L; + kbd->bi_busfreq /= 1000000L; +#if defined(CONFIG_MPC8220) + kbd->bi_inpfreq /= 1000000L; + kbd->bi_pcifreq /= 1000000L; + kbd->bi_pevfreq /= 1000000L; + kbd->bi_flbfreq /= 1000000L; + kbd->bi_vcofreq /= 1000000L; +#endif +#if defined(CONFIG_CPM2) + kbd->bi_cpmfreq /= 1000000L; + kbd->bi_brgfreq /= 1000000L; + kbd->bi_sccfreq /= 1000000L; + kbd->bi_vco /= 1000000L; +#endif +#if defined(CONFIG_MPC5xxx) + kbd->bi_ipbfreq /= 1000000L; + kbd->bi_pcifreq /= 1000000L; +#endif /* CONFIG_MPC5xxx */ + } +} + +#if defined(CONFIG_OF_LIBFDT) +static void fdt_error (const char *msg) +{ + puts ("ERROR: "); + puts (msg); + puts (" - must RESET the board to recover.\n"); +} + +static image_header_t *image_get_fdt (ulong fdt_addr) +{ + image_header_t *fdt_hdr = (image_header_t *)fdt_addr; + + image_print_contents (fdt_hdr); + + puts (" Verifying Checksum ... "); + if (!image_check_hcrc (fdt_hdr)) { + fdt_error ("fdt header checksum invalid"); + return NULL; + } + + if (!image_check_dcrc (fdt_hdr)) { + fdt_error ("fdt checksum invalid"); + return NULL; + } + puts ("OK\n"); + + if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) { + fdt_error ("uImage is not a fdt"); + return NULL; + } + if (image_get_comp (fdt_hdr) != IH_COMP_NONE) { + fdt_error ("uImage is compressed"); + return NULL; + } + if (fdt_check_header ((char *)image_get_data (fdt_hdr)) != 0) { + fdt_error ("uImage data is not a fdt"); + return NULL; + } + return fdt_hdr; +} + +/** + * fit_check_fdt - verify FIT format FDT subimage + * @fit_hdr: pointer to the FIT header + * fdt_noffset: FDT subimage node offset within FIT image + * @verify: data CRC verification flag + * + * fit_check_fdt() verifies integrity of the FDT subimage and from + * specified FIT image. + * + * returns: + * 1, on success + * 0, on failure + */ +#if defined(CONFIG_FIT) +static int fit_check_fdt (const void *fit, int fdt_noffset, int verify) +{ + fit_image_print (fit, fdt_noffset, " "); + + if (verify) { + puts (" Verifying Hash Integrity ... "); + if (!fit_image_check_hashes (fit, fdt_noffset)) { + fdt_error ("Bad Data Hash"); + return 0; + } + puts ("OK\n"); + } + + if (!fit_image_check_type (fit, fdt_noffset, IH_TYPE_FLATDT)) { + fdt_error ("Not a FDT image"); + return 0; + } + + if (!fit_image_check_comp (fit, fdt_noffset, IH_COMP_NONE)) { + fdt_error ("FDT image is compressed"); + return 0; + } + + return 1; +} +#endif /* CONFIG_FIT */ + +static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + bootm_headers_t *images, char **of_flat_tree, ulong *of_size) +{ + ulong fdt_addr; + image_header_t *fdt_hdr; + char *fdt_blob = NULL; + ulong image_start, image_end; + ulong load_start, load_end; +#if defined(CONFIG_FIT) + void *fit_hdr; + const char *fit_uname_config = NULL; + const char *fit_uname_fdt = NULL; + ulong default_addr; + int cfg_noffset; + int fdt_noffset; + const void *data; + size_t size; +#endif + + *of_flat_tree = NULL; + *of_size = 0; + + if (argc > 3 || genimg_has_config (images)) { +#if defined(CONFIG_FIT) + if (argc > 3) { + /* + * If the FDT blob comes from the FIT image and the + * FIT image address is omitted in the command line + * argument, try to use ramdisk or os FIT image + * address or default load address. + */ + if (images->fit_uname_rd) + default_addr = (ulong)images->fit_hdr_rd; + else if (images->fit_uname_os) + default_addr = (ulong)images->fit_hdr_os; + else + default_addr = load_addr; + + if (fit_parse_conf (argv[3], default_addr, + &fdt_addr, &fit_uname_config)) { + debug ("* fdt: config '%s' from image at 0x%08lx\n", + fit_uname_config, fdt_addr); + } else if (fit_parse_subimage (argv[3], default_addr, + &fdt_addr, &fit_uname_fdt)) { + debug ("* fdt: subimage '%s' from image at 0x%08lx\n", + fit_uname_fdt, fdt_addr); + } else +#endif + { + fdt_addr = simple_strtoul(argv[3], NULL, 16); + debug ("* fdt: cmdline image address = 0x%08lx\n", + fdt_addr); + } +#if defined(CONFIG_FIT) + } else { + /* use FIT configuration provided in first bootm + * command argument + */ + fdt_addr = (ulong)images->fit_hdr_os; + fit_uname_config = images->fit_uname_cfg; + debug ("* fdt: using config '%s' from image at 0x%08lx\n", + fit_uname_config, fdt_addr); + + /* + * Check whether configuration has FDT blob defined, + * if not quit silently. + */ + fit_hdr = (void *)fdt_addr; + cfg_noffset = fit_conf_get_node (fit_hdr, + fit_uname_config); + if (cfg_noffset < 0) { + debug ("* fdt: no such config\n"); + return 0; + } + + fdt_noffset = fit_conf_get_fdt_node (fit_hdr, + cfg_noffset); + if (fdt_noffset < 0) { + debug ("* fdt: no fdt in config\n"); + return 0; + } + } +#endif + + debug ("## Checking for 'FDT'/'FDT Image' at %08lx\n", + fdt_addr); + + /* copy from dataflash if needed */ + fdt_addr = genimg_get_image (fdt_addr); + + /* + * Check if there is an FDT image at the + * address provided in the second bootm argument + * check image type, for FIT images get a FIT node. + */ + switch (genimg_get_format ((void *)fdt_addr)) { + case IMAGE_FORMAT_LEGACY: + /* verify fdt_addr points to a valid image header */ + printf ("## Flattened Device Tree from Legacy Image at %08lx\n", + fdt_addr); + fdt_hdr = image_get_fdt (fdt_addr); + if (!fdt_hdr) + goto error; + + /* + * move image data to the load address, + * make sure we don't overwrite initial image + */ + image_start = (ulong)fdt_hdr; + image_end = image_get_image_end (fdt_hdr); + + load_start = image_get_load (fdt_hdr); + load_end = load_start + image_get_data_size (fdt_hdr); + + if ((load_start < image_end) && (load_end > image_start)) { + fdt_error ("fdt overwritten"); + goto error; + } + + debug (" Loading FDT from 0x%08lx to 0x%08lx\n", + image_get_data (fdt_hdr), load_start); + + memmove ((void *)load_start, + (void *)image_get_data (fdt_hdr), + image_get_data_size (fdt_hdr)); + + fdt_blob = (char *)load_start; + break; + case IMAGE_FORMAT_FIT: + /* + * This case will catch both: new uImage format + * (libfdt based) and raw FDT blob (also libfdt + * based). + */ +#if defined(CONFIG_FIT) + /* check FDT blob vs FIT blob */ + if (fit_check_format ((const void *)fdt_addr)) { + /* + * FIT image + */ + fit_hdr = (void *)fdt_addr; + printf ("## Flattened Device Tree from FIT Image at %08lx\n", + fdt_addr); + + if (!fit_uname_fdt) { + /* + * no FDT blob image node unit name, + * try to get config node first. If + * config unit node name is NULL + * fit_conf_get_node() will try to + * find default config node + */ + cfg_noffset = fit_conf_get_node (fit_hdr, + fit_uname_config); + + if (cfg_noffset < 0) { + fdt_error ("Could not find configuration node\n"); + goto error; + } + + fit_uname_config = fdt_get_name (fit_hdr, + cfg_noffset, NULL); + printf (" Using '%s' configuration\n", + fit_uname_config); + + fdt_noffset = fit_conf_get_fdt_node (fit_hdr, + cfg_noffset); + fit_uname_fdt = fit_get_name (fit_hdr, + fdt_noffset, NULL); + } else { + /* get FDT component image node offset */ + fdt_noffset = fit_image_get_node (fit_hdr, + fit_uname_fdt); + } + if (fdt_noffset < 0) { + fdt_error ("Could not find subimage node\n"); + goto error; + } + + printf (" Trying '%s' FDT blob subimage\n", + fit_uname_fdt); + + if (!fit_check_fdt (fit_hdr, fdt_noffset, + images->verify)) + goto error; + + /* get ramdisk image data address and length */ + if (fit_image_get_data (fit_hdr, fdt_noffset, + &data, &size)) { + fdt_error ("Could not find FDT subimage data"); + goto error; + } + + /* verift that image data is a proper FDT blob */ + if (fdt_check_header ((char *)data) != 0) { + fdt_error ("Subimage data is not a FTD"); + goto error; + } + + /* + * move image data to the load address, + * make sure we don't overwrite initial image + */ + image_start = (ulong)fit_hdr; + image_end = fit_get_end (fit_hdr); + + if (fit_image_get_load (fit_hdr, fdt_noffset, + &load_start) == 0) { + load_end = load_start + size; + + if ((load_start < image_end) && + (load_end > image_start)) { + fdt_error ("FDT overwritten"); + goto error; + } + + printf (" Loading FDT from 0x%08lx to 0x%08lx\n", + (ulong)data, load_start); + + memmove ((void *)load_start, + (void *)data, size); + + fdt_blob = (char *)load_start; + } else { + fdt_blob = (char *)data; + } + + images->fit_hdr_fdt = fit_hdr; + images->fit_uname_fdt = fit_uname_fdt; + images->fit_noffset_fdt = fdt_noffset; + break; + } else +#endif + { + /* + * FDT blob + */ + debug ("* fdt: raw FDT blob\n"); + printf ("## Flattened Device Tree blob at %08lx\n", fdt_blob); + fdt_blob = (char *)fdt_addr; + } + break; + default: + fdt_error ("Did not find a cmdline Flattened Device Tree"); + goto error; + } + + printf (" Booting using the fdt blob at 0x%x\n", fdt_blob); + + } else if (images->legacy_hdr_valid && + image_check_type (images->legacy_hdr_os, IH_TYPE_MULTI)) { + + ulong fdt_data, fdt_len; + + /* + * Now check if we have a legacy multi-component image, + * get second entry data start address and len. + */ + printf ("## Flattened Device Tree from multi " + "component Image at %08lX\n", + (ulong)images->legacy_hdr_os); + + image_multi_getimg (images->legacy_hdr_os, 2, &fdt_data, &fdt_len); + if (fdt_len) { + + fdt_blob = (char *)fdt_data; + printf (" Booting using the fdt at 0x%x\n", fdt_blob); + + if (fdt_check_header (fdt_blob) != 0) { + fdt_error ("image is not a fdt"); + goto error; + } + + if (be32_to_cpu (fdt_totalsize (fdt_blob)) != fdt_len) { + fdt_error ("fdt size != image size"); + goto error; + } + } else { + fdt_error ("Did not find a Flattened Device Tree " + "in a legacy multi-component image"); + goto error; + } + } else { + debug ("## No Flattened Device Tree\n"); + return 0; + } + + *of_flat_tree = fdt_blob; + *of_size = be32_to_cpu (fdt_totalsize (fdt_blob)); + debug (" of_flat_tree at 0x%08lx size 0x%08lx\n", + *of_flat_tree, *of_size); + + return 0; + +error: + do_reset (cmdtp, flag, argc, argv); + return 1; +} + +static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, + cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], + char **of_flat_tree, ulong *of_size) +{ + char *fdt_blob = *of_flat_tree; + ulong relocate = 0; + ulong of_len = 0; + + /* nothing to do */ + if (*of_size == 0) + return 0; + + if (fdt_check_header (fdt_blob) != 0) { + fdt_error ("image is not a fdt"); + goto error; + } + +#ifndef CFG_NO_FLASH + /* move the blob if it is in flash (set relocate) */ + if (addr2info ((ulong)fdt_blob) != NULL) + relocate = 1; +#endif + + /* + * The blob must be within CFG_BOOTMAPSZ, + * so we flag it to be copied if it is not. + */ + if (fdt_blob >= (char *)CFG_BOOTMAPSZ) + relocate = 1; + + of_len = be32_to_cpu (fdt_totalsize (fdt_blob)); + + /* move flattend device tree if needed */ + if (relocate) { + int err; + ulong of_start; + + /* position on a 4K boundary before the alloc_current */ + of_start = lmb_alloc_base(lmb, of_len, 0x1000, + (CFG_BOOTMAPSZ + bootmap_base)); + + if (of_start == 0) { + puts("device tree - allocation error\n"); + goto error; + } + + debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n", + (ulong)fdt_blob, (ulong)fdt_blob + of_len - 1, + of_len, of_len); + + printf (" Loading Device Tree to %08lx, end %08lx ... ", + of_start, of_start + of_len - 1); + + err = fdt_open_into (fdt_blob, (void *)of_start, of_len); + if (err != 0) { + fdt_error ("fdt move failed"); + goto error; + } + puts ("OK\n"); + + *of_flat_tree = (char *)of_start; + } else { + *of_flat_tree = fdt_blob; + lmb_reserve(lmb, (ulong)fdt, of_len); + } + + return 0; + +error: + return 1; +} +#endif diff --git a/lib_sh/Makefile b/lib_sh/Makefile index cf127a826..a5772a013 100644 --- a/lib_sh/Makefile +++ b/lib_sh/Makefile @@ -22,12 +22,14 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).a -SOBJS = +SOBJS-y += -COBJS = board.o sh_linux.o # time.o +COBJS-y += board.o +COBJS-y += bootm.o +#COBJS-y += time.o -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) diff --git a/lib_sh/sh_linux.c b/lib_sh/bootm.c similarity index 69% rename from lib_sh/sh_linux.c rename to lib_sh/bootm.c index 14b6815cd..3d5c3bbc9 100644 --- a/lib_sh/sh_linux.c +++ b/lib_sh/bootm.c @@ -25,14 +25,12 @@ #include #include -extern image_header_t header; /* common/cmd_bootm.c */ - /* The SH kernel reads arguments from the empty zero page at location * 0 at the start of SDRAM. The following are copied from * arch/sh/kernel/setup.c and may require tweaking if the kernel sources * change. */ -#define PARAM ((unsigned char *)CFG_SDRAM_BASE + 0x1000) +#define PARAM ((unsigned char *)CFG_SDRAM_BASE + 0x1000) #define MOUNT_ROOT_RDONLY (*(unsigned long *) (PARAM+0x000)) #define RAMDISK_FLAGS (*(unsigned long *) (PARAM+0x004)) @@ -43,7 +41,9 @@ extern image_header_t header; /* common/cmd_bootm.c */ /* ... */ #define COMMAND_LINE ((char *) (PARAM+0x100)) -#define RAMDISK_IMAGE_START_MASK 0x07FF +#define RAMDISK_IMAGE_START_MASK 0x07FF + +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); #ifdef CFG_DEBUG static void hexdump (unsigned char *buf, int len) @@ -60,15 +60,42 @@ static void hexdump (unsigned char *buf, int len) #endif void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - ulong addr, ulong *len_ptr, int verify) + bootm_headers_t *images) { - image_header_t *hdr = &header; - char *bootargs = getenv("bootargs"); - void (*kernel) (void) = (void (*)(void)) ntohl (hdr->ih_ep); + ulong ep = 0; + char *bootargs = getenv("bootargs"); + + /* find kernel entry point */ + if (images->legacy_hdr_valid) { + ep = image_get_ep (images->legacy_hdr_os); +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + int ret = fit_image_get_entry (images->fit_hdr_os, + images->fit_noffset_os, &ep); + if (ret) { + puts ("Can't get entry point property!\n"); + goto error; + } +#endif + } else { + puts ("Could not find kernel entry point!\n"); + goto error; + } + void (*kernel) (void) = (void (*)(void))ep; + + if (!images->autostart) + return ; /* Setup parameters */ memset(PARAM, 0, 0x1000); /* Clear zero page */ strcpy(COMMAND_LINE, bootargs); kernel(); + /* does not return */ + return; + +error: + if (images->autostart) + do_reset (cmdtp, flag, argc, argv); + return; } diff --git a/libfdt/fdt.c b/libfdt/fdt.c index bd9171237..cfa1989d8 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -50,8 +50,12 @@ */ #include "libfdt_env.h" +#ifndef USE_HOSTCC #include #include +#else +#include "fdt_host.h" +#endif #include "libfdt_internal.h" diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 63fa1290b..11d80d2fa 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -50,8 +50,12 @@ */ #include "libfdt_env.h" +#ifndef USE_HOSTCC #include #include +#else +#include "fdt_host.h" +#endif #include "libfdt_internal.h" diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c index 0df472bc5..8609fa7d7 100644 --- a/libfdt/fdt_rw.c +++ b/libfdt/fdt_rw.c @@ -50,8 +50,12 @@ */ #include "libfdt_env.h" +#ifndef USE_HOSTCC #include #include +#else +#include "fdt_host.h" +#endif #include "libfdt_internal.h" diff --git a/libfdt/fdt_strerror.c b/libfdt/fdt_strerror.c index f9d32ef53..abf792e7d 100644 --- a/libfdt/fdt_strerror.c +++ b/libfdt/fdt_strerror.c @@ -50,8 +50,12 @@ */ #include "libfdt_env.h" +#ifndef USE_HOSTCC #include #include +#else +#include "fdt_host.h" +#endif #include "libfdt_internal.h" diff --git a/libfdt/fdt_wip.c b/libfdt/fdt_wip.c index 88e24b831..24e172495 100644 --- a/libfdt/fdt_wip.c +++ b/libfdt/fdt_wip.c @@ -50,8 +50,12 @@ */ #include "libfdt_env.h" +#ifndef USE_HOSTCC #include #include +#else +#include "fdt_host.h" +#endif #include "libfdt_internal.h" diff --git a/onenand_ipl/board/apollon/Makefile b/onenand_ipl/board/apollon/Makefile index 66a0959ee..f10ed0229 100644 --- a/onenand_ipl/board/apollon/Makefile +++ b/onenand_ipl/board/apollon/Makefile @@ -9,7 +9,7 @@ AFLAGS += -DCONFIG_ONENAND_IPL CFLAGS += -DCONFIG_ONENAND_IPL OBJCLFAGS += --gap-fill=0x00 -SOBJS = start.o low_levelinit.o # _memcpy32.o +SOBJS = start.o low_levelinit.o COBJS = apollon.o onenand_read.o onenand_boot.o SRCS := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c)) @@ -19,13 +19,16 @@ LNDIR := $(OBJTREE)/onenand_ipl/board/$(BOARDDIR) onenandobj := $(OBJTREE)/onenand_ipl/ -ALL = $(onenandobj)onenand-ipl $(onenandobj)onenand-ipl.bin $(onenandobj)onenand-ipl-2k.bin +ALL = $(onenandobj)onenand-ipl $(onenandobj)onenand-ipl.bin $(onenandobj)onenand-ipl-2k.bin $(onenandobj)onenand-ipl-4k.bin all: $(obj).depend $(ALL) $(onenandobj)onenand-ipl-2k.bin: $(onenandobj)onenand-ipl $(OBJCOPY) ${OBJCFLAGS} --pad-to=0x800 -O binary $< $@ +$(onenandobj)onenand-ipl-4k.bin: $(onenandobj)onenand-ipl + $(OBJCOPY) ${OBJCFLAGS} --pad-to=0x1000 -O binary $< $@ + $(onenandobj)onenand-ipl.bin: $(onenandobj)onenand-ipl $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ diff --git a/onenand_ipl/onenand_boot.c b/onenand_ipl/onenand_boot.c index f30deaeca..35668ac84 100644 --- a/onenand_ipl/onenand_boot.c +++ b/onenand_ipl/onenand_boot.c @@ -60,7 +60,7 @@ void start_oneboot(void) buf = (uchar *) CFG_LOAD_ADDR; - if (!onenand_read_block(buf, ONENAND_START_BLOCK)) + if (!onenand_read_block0(buf)) buf += ONENAND_BLOCK_SIZE; if (buf == (uchar *)CFG_LOAD_ADDR) diff --git a/onenand_ipl/onenand_ipl.h b/onenand_ipl/onenand_ipl.h index b9c6669a7..9188b9662 100644 --- a/onenand_ipl/onenand_ipl.h +++ b/onenand_ipl/onenand_ipl.h @@ -23,7 +23,6 @@ #include -#define ONENAND_START_BLOCK 0 #define ONENAND_BLOCK_SIZE 2048 #ifndef CFG_PRINTF @@ -40,5 +39,5 @@ #define ONENAND_PAGE_SIZE 2048 -extern int onenand_read_block(unsigned char *buf, ulong block); +extern int onenand_read_block0(unsigned char *buf); #endif diff --git a/onenand_ipl/onenand_read.c b/onenand_ipl/onenand_read.c index f55322023..669b1ef5f 100644 --- a/onenand_ipl/onenand_read.c +++ b/onenand_ipl/onenand_read.c @@ -33,8 +33,13 @@ #define onenand_buffer_address() ((1 << 3) << 8) #define onenand_bufferram_address(block) (0) +#ifdef __HAVE_ARCH_MEMCPY32 +extern void *memcpy32(void *dest, void *src, int size); +#endif + /* read a page with ECC */ -static inline int onenand_read_page(ulong block, ulong page, u_char *buf) +static inline int onenand_read_page(ulong block, ulong page, + u_char * buf, int pagesize) { unsigned long *base; @@ -46,15 +51,15 @@ static inline int onenand_read_page(ulong block, ulong page, u_char *buf) onenand_writew(onenand_block_address(block), THIS_ONENAND(ONENAND_REG_START_ADDRESS1)); + onenand_writew(onenand_bufferram_address(block), + THIS_ONENAND(ONENAND_REG_START_ADDRESS2)); + onenand_writew(onenand_sector_address(page), THIS_ONENAND(ONENAND_REG_START_ADDRESS8)); onenand_writew(onenand_buffer_address(), THIS_ONENAND(ONENAND_REG_START_BUFFER)); - onenand_writew(onenand_bufferram_address(block), - THIS_ONENAND(ONENAND_REG_START_ADDRESS2)); - onenand_writew(ONENAND_INT_CLEAR, THIS_ONENAND(ONENAND_REG_INTERRUPT)); onenand_writew(ONENAND_CMD_READ, THIS_ONENAND(ONENAND_REG_COMMAND)); @@ -69,9 +74,9 @@ static inline int onenand_read_page(ulong block, ulong page, u_char *buf) #ifdef __HAVE_ARCH_MEMCPY32 /* 32 bytes boundary memory copy */ - memcpy32(buf, base, ONENAND_PAGE_SIZE); + memcpy32(buf, base, pagesize); #else - for (offset = 0; offset < (ONENAND_PAGE_SIZE >> 2); offset++) { + for (offset = 0; offset < (pagesize >> 2); offset++) { value = *(base + offset); *p++ = value; } @@ -87,18 +92,22 @@ static inline int onenand_read_page(ulong block, ulong page, u_char *buf) * onenand_read_block - Read a block data to buf * @return 0 on success */ -int onenand_read_block(unsigned char *buf, ulong block) +int onenand_read_block0(unsigned char *buf) { int page, offset = 0; + int pagesize = ONENAND_PAGE_SIZE; + + /* MLC OneNAND has 4KiB page size */ + if (onenand_readw(THIS_ONENAND(ONENAND_REG_TECHNOLOGY))) + pagesize <<= 1; /* NOTE: you must read page from page 1 of block 0 */ /* read the block page by page*/ for (page = ONENAND_START_PAGE; page < ONENAND_PAGES_PER_BLOCK; page++) { - onenand_read_page(block, page, buf + offset); - - offset += ONENAND_PAGE_SIZE; + onenand_read_page(0, page, buf + offset, pagesize); + offset += pagesize; } return 0; diff --git a/post/board/lwmon5/dspic.c b/post/board/lwmon5/dspic.c index 65b96bcc2..fcbbc6031 100644 --- a/post/board/lwmon5/dspic.c +++ b/post/board/lwmon5/dspic.c @@ -59,25 +59,27 @@ int dspic_init_post_test(int flags) #if CONFIG_POST & CFG_POST_BSPEC2 /* Read a register from the dsPIC. */ -int dspic_read(ushort reg) +int dspic_read(ushort reg, ushort *data) { - uchar buf[2]; + uchar buf[sizeof(*data)]; + int rval; - if (i2c_read(CFG_I2C_DSPIC_IO_ADDR, reg, 2, buf, 2)) - return -1; + rval = i2c_read(CFG_I2C_DSPIC_IO_ADDR, reg, sizeof(reg), + buf, sizeof(*data)); - return (uint)((buf[0] << 8) | buf[1]); + *data = (buf[0] << 8) | buf[1]; + + return rval; } /* Verify error codes regs, display version */ int dspic_post_test(int flags) { - int data; + ushort data; int ret = 0; post_log("\n"); - data = dspic_read(DSPIC_VERSION_REG); - if (data == -1) { + if (dspic_read(DSPIC_VERSION_REG, &data)) { post_log("dsPIC : failed read version\n"); ret = 1; } else { @@ -85,20 +87,20 @@ int dspic_post_test(int flags) (data >> 8) & 0xFF, data & 0xFF); } - data = dspic_read(DSPIC_POST_ERROR_REG); - if (data != 0) ret = 1; - if (data == -1) { + if (dspic_read(DSPIC_POST_ERROR_REG, &data)) { post_log("dsPIC : failed read POST code\n"); } else { post_log("dsPIC POST code 0x%04X\n", data); } + if (data != 0) + ret = 1; - data = dspic_read(DSPIC_SYS_ERROR_REG); - if (data == -1) { + if (dspic_read(DSPIC_SYS_ERROR_REG, &data)) { post_log("dsPIC : failed read system error\n"); ret = 1; - } else { + } else if (data != 0) { post_log("dsPIC SYS-ERROR code: 0x%04X\n", data); + ret = 1; } return ret; diff --git a/post/board/lwmon5/sysmon.c b/post/board/lwmon5/sysmon.c index f7e51a3cf..0cf1cf2a2 100644 --- a/post/board/lwmon5/sysmon.c +++ b/post/board/lwmon5/sysmon.c @@ -34,9 +34,9 @@ * The test passes when all the following voltages and temperatures * are within allowed ranges: * - * Temperature -40 .. +85 C - * +5V +4.75 .. +5.25 V - * +5V standby +4.75 .. +5.25 V + * Temperature -40 .. +85 C + * +5V +4.75 .. +5.25 V + * +5V standby +4.75 .. +5.25 V * * LCD backlight is not enabled if temperature values are not within * allowed ranges (-30 .. + 80). The brightness of backlite can be @@ -58,7 +58,7 @@ DECLARE_GLOBAL_DATA_PTR; /* from dspic.c */ -extern int dspic_read(ushort reg); +extern int dspic_read(ushort reg, ushort *data); #define RELOC(x) if (x != NULL) x = (void *) ((ulong) (x) + gd->reloc_off) @@ -67,6 +67,7 @@ typedef struct sysmon_table_s sysmon_table_t; static void sysmon_dspic_init (sysmon_t * this); static int sysmon_dspic_read (sysmon_t * this, uint addr); +static int sysmon_dspic_read_sgn (sysmon_t * this, uint addr); static void sysmon_backlight_disable (sysmon_table_t * this); struct sysmon_s @@ -79,9 +80,13 @@ struct sysmon_s static sysmon_t sysmon_dspic = {CFG_I2C_DSPIC_IO_ADDR, sysmon_dspic_init, sysmon_dspic_read}; +static sysmon_t sysmon_dspic_sgn = + {CFG_I2C_DSPIC_IO_ADDR, sysmon_dspic_init, sysmon_dspic_read_sgn}; + static sysmon_t * sysmon_list[] = { &sysmon_dspic, + &sysmon_dspic_sgn, NULL }; @@ -109,17 +114,17 @@ struct sysmon_table_s static sysmon_table_t sysmon_table[] = { - {"Temperature", " C", &sysmon_dspic, NULL, sysmon_backlight_disable, + {"Temperature", " C", &sysmon_dspic_sgn, NULL, sysmon_backlight_disable, 1, 1, -32768, 32767, 0xFFFF, 0x8000-40, 0x8000+85, 0, - 0x8000-30, 0x8000+80, 0, 0x12BC}, + 0x8000-30, 0x8000+80, 0, 0x12BC}, {"+ 5 V", "V", &sysmon_dspic, NULL, NULL, - 100, 1000, -0x8000, 0x7FFF, 0xFFFF, 0x8000+4750, 0x8000+5250, 0, - 0x8000+4750, 0x8000+5250, 0, 0x12CA}, + 100, 1000, 0, 0xFFFF, 0xFFFF, 4750, 5250, 0, + 4750, 5250, 0, 0x12CA}, {"+ 5 V standby", "V", &sysmon_dspic, NULL, NULL, - 100, 1000, -0x8000, 0x7FFF, 0xFFFF, 0x8000+4750, 0x8000+5250, 0, - 0x8000+4750, 0x8000+5250, 0, 0x12C6}, + 100, 1000, 0, 0xFFFF, 0xFFFF, 4750, 5250, 0, + 4750, 5250, 0, 0x12C6}, }; static int sysmon_table_size = sizeof(sysmon_table) / sizeof(sysmon_table[0]); @@ -156,9 +161,7 @@ static char *sysmon_unit_value (sysmon_table_t *s, uint val) static char buf[32]; char *p, sign; int decimal, frac; - int unit_val; - - unit_val = + int unit_val = s->unit_min + (s->unit_max - s->unit_min) * val / s->val_mask; if (val == -1) @@ -194,10 +197,18 @@ static void sysmon_dspic_init (sysmon_t * this) static int sysmon_dspic_read (sysmon_t * this, uint addr) { - int res = dspic_read(addr); + ushort data; + + return (dspic_read(addr, &data)) ? -1 : data; +} + +static int sysmon_dspic_read_sgn (sysmon_t * this, uint addr) +{ + ushort data; /* To fit into the table range we should add 0x8000 */ - return (res == -1) ? -1 : (res + 0x8000); + return (dspic_read(addr, &data)) ? -1 : + (signed short)data + 0x8000; } static void sysmon_backlight_disable (sysmon_table_t * this) diff --git a/tools/.gitignore b/tools/.gitignore index c33679a9d..979f2dac0 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -4,6 +4,14 @@ /environment.c /gen_eth_addr /img2srec +/md5.c /mkimage /sha1.c /ubsha1 +/image.c +/fdt.c +/fdt_ro.c +/fdt_rw.c +/fdt_strerror.c +/fdt_wip.c +/libfdt_internal.h diff --git a/tools/Makefile b/tools/Makefile index af0de477c..8784a6d5c 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -23,7 +23,7 @@ BIN_FILES = img2srec$(SFX) mkimage$(SFX) envcrc$(SFX) ubsha1$(SFX) gen_eth_addr$(SFX) bmp_logo$(SFX) -OBJ_LINKS = environment.o crc32.o sha1.o +OBJ_LINKS = environment.o crc32.o md5.o sha1.o image.o OBJ_FILES = img2srec.o mkimage.o envcrc.o ubsha1.o gen_eth_addr.o bmp_logo.o ifeq ($(ARCH),mips) @@ -37,6 +37,8 @@ endif #OBJ_FILES += mpc86x_clk.o #endif +LIBFDT_OBJ_FILES = $(obj)fdt.o $(obj)fdt_ro.o $(obj)fdt_rw.o $(obj)fdt_strerror.o $(obj)fdt_wip.o + LOGO_H = $(OBJTREE)/include/bmp_logo.h ifeq ($(LOGO_BMP),) @@ -120,6 +122,10 @@ CPPFLAGS = -idirafter $(SRCTREE)/include \ -idirafter $(OBJTREE)/include \ -DTEXT_BASE=$(TEXT_BASE) -DUSE_HOSTCC CFLAGS = $(HOST_CFLAGS) $(CPPFLAGS) -O + +# No -pedantic switch to avoid libfdt compilation warnings +FIT_CFLAGS = -Wall $(CPPFLAGS) -O + AFLAGS = -D__ASSEMBLY__ $(CPPFLAGS) CC = $(HOSTCC) STRIP = $(HOSTSTRIP) @@ -137,7 +143,7 @@ $(obj)img2srec$(SFX): $(obj)img2srec.o $(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^ $(STRIP) $@ -$(obj)mkimage$(SFX): $(obj)mkimage.o $(obj)crc32.o +$(obj)mkimage$(SFX): $(obj)mkimage.o $(obj)crc32.o $(obj)image.o $(obj)md5.o $(obj)sha1.o $(LIBFDT_OBJ_FILES) $(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^ $(STRIP) $@ @@ -170,11 +176,17 @@ $(obj)ubsha1.o: $(src)ubsha1.c $(obj)crc32.o: $(obj)crc32.c $(CC) -g $(CFLAGS) -c -o $@ $< +$(obj)md5.o: $(obj)md5.c + $(CC) -g $(CFLAGS) -c -o $@ $< + $(obj)sha1.o: $(obj)sha1.c $(CC) -g $(CFLAGS) -c -o $@ $< +$(obj)image.o: $(obj)image.c + $(CC) -g $(FIT_CFLAGS) -c -o $@ $< + $(obj)mkimage.o: $(src)mkimage.c - $(CC) -g $(CFLAGS) -c -o $@ $< + $(CC) -g $(FIT_CFLAGS) -c -o $@ $< $(obj)ncb.o: $(src)ncb.c $(CC) -g $(CFLAGS) -c -o $@ $< @@ -188,6 +200,21 @@ $(obj)inca-swap-bytes.o: $(src)inca-swap-bytes.c $(obj)mpc86x_clk.o: $(src)mpc86x_clk.c $(CC) -g $(CFLAGS) -c -o $@ $< +$(obj)fdt.o: $(obj)fdt.c + $(CC) -g $(FIT_CFLAGS) -c -o $@ $< + +$(obj)fdt_ro.o: $(obj)fdt_ro.c + $(CC) -g $(FIT_CFLAGS) -c -o $@ $< + +$(obj)fdt_rw.o: $(obj)fdt_rw.c + $(CC) -g $(FIT_CFLAGS) -c -o $@ $< + +$(obj)fdt_strerror.o: $(obj)fdt_strerror.c + $(CC) -g $(FIT_CFLAGS) -c -o $@ $< + +$(obj)fdt_wip.o: $(obj)fdt_wip.c + $(CC) -g $(FIT_CFLAGS) -c -o $@ $< + subdirs: ifeq ($(TOOLSUBDIRS),) @: @@ -213,10 +240,48 @@ $(obj)crc32.c: @rm -f $(obj)crc32.c ln -s $(src)../lib_generic/crc32.c $(obj)crc32.c +$(obj)md5.c: + @rm -f $(obj)md5.c + ln -s $(src)../lib_generic/md5.c $(obj)md5.c + $(obj)sha1.c: @rm -f $(obj)sha1.c ln -s $(src)../lib_generic/sha1.c $(obj)sha1.c +$(obj)image.c: + @rm -f $(obj)image.c + ln -s $(src)../common/image.c $(obj)image.c + if [ ! -f $(obj)mkimage.h ] ; then \ + ln -s $(src)../tools/mkimage.h $(obj)mkimage.h; \ + fi + if [ ! -f $(obj)fdt_host.h ] ; then \ + ln -s $(src)../tools/fdt_host.h $(obj)fdt_host.h; \ + fi + +$(obj)fdt.c: $(obj)libfdt_internal.h + @rm -f $(obj)fdt.c + ln -s $(src)../libfdt/fdt.c $(obj)fdt.c + +$(obj)fdt_ro.c: $(obj)libfdt_internal.h + @rm -f $(obj)fdt_ro.c + ln -s $(src)../libfdt/fdt_ro.c $(obj)fdt_ro.c + +$(obj)fdt_rw.c: $(obj)libfdt_internal.h + @rm -f $(obj)fdt_rw.c + ln -s $(src)../libfdt/fdt_rw.c $(obj)fdt_rw.c + +$(obj)fdt_strerror.c: $(obj)libfdt_internal.h + @rm -f $(obj)fdt_strerror.c + ln -s $(src)../libfdt/fdt_strerror.c $(obj)fdt_strerror.c + +$(obj)fdt_wip.c: $(obj)libfdt_internal.h + @rm -f $(obj)fdt_wip.c + ln -s $(src)../libfdt/fdt_wip.c $(obj)fdt_wip.c + +$(obj)libfdt_internal.h: + @rm -f $(obj)libfdt_internal.h + ln -s $(src)../libfdt/libfdt_internal.h $(obj)libfdt_internal.h + $(LOGO_H): $(obj)bmp_logo $(LOGO_BMP) $(obj)./bmp_logo $(LOGO_BMP) >$@ diff --git a/tools/fdt_host.h b/tools/fdt_host.h new file mode 100644 index 000000000..085013e02 --- /dev/null +++ b/tools/fdt_host.h @@ -0,0 +1,28 @@ +/* + * (C) Copyright 2008 Semihalf + * + * 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 __FDT_HOST_H__ +#define __FDT_HOST_H__ + +/* Make sure to include u-boot version of libfdt include files */ +#include "../include/fdt.h" +#include "../include/libfdt.h" +#include "../include/fdt_support.h" + +#endif /* __FDT_HOST_H__ */ diff --git a/tools/mkimage.c b/tools/mkimage.c index 21251306a..6e1ff2b1e 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -1,4 +1,6 @@ /* + * (C) Copyright 2008 Semihalf + * * (C) Copyright 2000-2004 * DENX Software Engineering * Wolfgang Denk, wd@denx.de @@ -20,44 +22,7 @@ * MA 02111-1307 USA */ -#include -#include -#include -#include -#include -#ifndef __WIN32__ -#include /* for host / network byte order conversions */ -#endif -#include -#include -#include -#include - -#if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__) -#include -#endif - -#ifdef __WIN32__ -typedef unsigned int __u32; - -#define SWAP_LONG(x) \ - ((__u32)( \ - (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \ - (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \ - (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \ - (((__u32)(x) & (__u32)0xff000000UL) >> 24) )) -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; - -#define ntohl(a) SWAP_LONG(a) -#define htonl(a) SWAP_LONG(a) -#endif /* __WIN32__ */ - -#ifndef O_BINARY /* should be define'd on __WIN32__ */ -#define O_BINARY 0 -#endif - +#include "mkimage.h" #include extern int errno; @@ -66,110 +31,27 @@ extern int errno; #define MAP_FAILED (-1) #endif -char *cmdname; - -extern unsigned long crc32 (unsigned long crc, const char *buf, unsigned int len); - -typedef struct table_entry { - int val; /* as defined in image.h */ - char *sname; /* short (input) name */ - char *lname; /* long (output) name */ -} table_entry_t; - -table_entry_t arch_name[] = { - { IH_CPU_INVALID, NULL, "Invalid CPU", }, - { IH_CPU_ALPHA, "alpha", "Alpha", }, - { IH_CPU_ARM, "arm", "ARM", }, - { IH_CPU_I386, "x86", "Intel x86", }, - { IH_CPU_IA64, "ia64", "IA64", }, - { IH_CPU_M68K, "m68k", "MC68000", }, - { IH_CPU_MICROBLAZE, "microblaze", "MicroBlaze", }, - { IH_CPU_MIPS, "mips", "MIPS", }, - { IH_CPU_MIPS64, "mips64", "MIPS 64 Bit", }, - { IH_CPU_NIOS, "nios", "NIOS", }, - { IH_CPU_NIOS2, "nios2", "NIOS II", }, - { IH_CPU_PPC, "ppc", "PowerPC", }, - { IH_CPU_S390, "s390", "IBM S390", }, - { IH_CPU_SH, "sh", "SuperH", }, - { IH_CPU_SPARC, "sparc", "SPARC", }, - { IH_CPU_SPARC64, "sparc64", "SPARC 64 Bit", }, - { IH_CPU_BLACKFIN, "blackfin", "Blackfin", }, - { IH_CPU_AVR32, "avr32", "AVR32", }, - { -1, "", "", }, -}; - -table_entry_t os_name[] = { - { IH_OS_INVALID, NULL, "Invalid OS", }, - { IH_OS_4_4BSD, "4_4bsd", "4_4BSD", }, - { IH_OS_ARTOS, "artos", "ARTOS", }, - { IH_OS_DELL, "dell", "Dell", }, - { IH_OS_ESIX, "esix", "Esix", }, - { IH_OS_FREEBSD, "freebsd", "FreeBSD", }, - { IH_OS_IRIX, "irix", "Irix", }, - { IH_OS_LINUX, "linux", "Linux", }, - { IH_OS_LYNXOS, "lynxos", "LynxOS", }, - { IH_OS_NCR, "ncr", "NCR", }, - { IH_OS_NETBSD, "netbsd", "NetBSD", }, - { IH_OS_OPENBSD, "openbsd", "OpenBSD", }, - { IH_OS_PSOS, "psos", "pSOS", }, - { IH_OS_QNX, "qnx", "QNX", }, - { IH_OS_RTEMS, "rtems", "RTEMS", }, - { IH_OS_SCO, "sco", "SCO", }, - { IH_OS_SOLARIS, "solaris", "Solaris", }, - { IH_OS_SVR4, "svr4", "SVR4", }, - { IH_OS_U_BOOT, "u-boot", "U-Boot", }, - { IH_OS_VXWORKS, "vxworks", "VxWorks", }, - { -1, "", "", }, -}; - -table_entry_t type_name[] = { - { IH_TYPE_INVALID, NULL, "Invalid Image", }, - { IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", }, - { IH_TYPE_FIRMWARE, "firmware", "Firmware", }, - { IH_TYPE_KERNEL, "kernel", "Kernel Image", }, - { IH_TYPE_MULTI, "multi", "Multi-File Image", }, - { IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", }, - { IH_TYPE_SCRIPT, "script", "Script", }, - { IH_TYPE_STANDALONE, "standalone", "Standalone Program", }, - { IH_TYPE_FLATDT, "flat_dt", "Flat Device Tree", }, - { -1, "", "", }, -}; - -table_entry_t comp_name[] = { - { IH_COMP_NONE, "none", "uncompressed", }, - { IH_COMP_BZIP2, "bzip2", "bzip2 compressed", }, - { IH_COMP_GZIP, "gzip", "gzip compressed", }, - { -1, "", "", }, -}; - -static void copy_file (int, const char *, int); -static void usage (void); -static void print_header (image_header_t *); -static void print_type (image_header_t *); -static char *put_table_entry (table_entry_t *, char *, int); -static char *put_arch (int); -static char *put_type (int); -static char *put_os (int); -static char *put_comp (int); -static int get_table_entry (table_entry_t *, char *, char *); -static int get_arch(char *); -static int get_comp(char *); -static int get_os (char *); -static int get_type(char *); - +extern unsigned long crc32 (unsigned long crc, const char *buf, unsigned int len); +static void copy_file (int, const char *, int); +static void usage (void); +static void image_verify_header (char *, int); +static void fit_handle_file (void); char *datafile; char *imagefile; +char *cmdname; int dflag = 0; int eflag = 0; +int fflag = 0; int lflag = 0; int vflag = 0; int xflag = 0; int opt_os = IH_OS_LINUX; -int opt_arch = IH_CPU_PPC; +int opt_arch = IH_ARCH_PPC; int opt_type = IH_TYPE_KERNEL; int opt_comp = IH_COMP_GZIP; +char *opt_dtc = MKIMAGE_DEFAULT_DTC_OPTIONS; image_header_t header; image_header_t *hdr = &header; @@ -177,7 +59,7 @@ image_header_t *hdr = &header; int main (int argc, char **argv) { - int ifd; + int ifd = -1; uint32_t checksum; uint32_t addr; uint32_t ep; @@ -197,22 +79,28 @@ main (int argc, char **argv) break; case 'A': if ((--argc <= 0) || - (opt_arch = get_arch(*++argv)) < 0) + (opt_arch = genimg_get_arch_id (*++argv)) < 0) usage (); goto NXTARG; case 'C': if ((--argc <= 0) || - (opt_comp = get_comp(*++argv)) < 0) + (opt_comp = genimg_get_comp_id (*++argv)) < 0) usage (); goto NXTARG; + case 'D': + if (--argc <= 0) + usage (); + opt_dtc = *++argv; + goto NXTARG; + case 'O': if ((--argc <= 0) || - (opt_os = get_os(*++argv)) < 0) + (opt_os = genimg_get_os_id (*++argv)) < 0) usage (); goto NXTARG; case 'T': if ((--argc <= 0) || - (opt_type = get_type(*++argv)) < 0) + (opt_type = genimg_get_type_id (*++argv)) < 0) usage (); goto NXTARG; @@ -245,6 +133,12 @@ main (int argc, char **argv) } eflag = 1; goto NXTARG; + case 'f': + if (--argc <= 0) + usage (); + datafile = *++argv; + fflag = 1; + goto NXTARG; case 'n': if (--argc <= 0) usage (); @@ -263,14 +157,17 @@ main (int argc, char **argv) NXTARG: ; } - if ((argc != 1) || ((lflag ^ dflag) == 0)) + if ((argc != 1) || + (dflag && (fflag || lflag)) || + (fflag && (dflag || lflag)) || + (lflag && (dflag || fflag))) usage(); if (!eflag) { ep = addr; /* If XIP, entry point must be after the U-Boot header */ if (xflag) - ep += sizeof(image_header_t); + ep += image_get_header_size (); } /* @@ -278,32 +175,33 @@ NXTARG: ; * the size of the U-Boot header. */ if (xflag) { - if (ep != addr + sizeof(image_header_t)) { + if (ep != addr + image_get_header_size ()) { fprintf (stderr, "%s: For XIP, the entry point must be the load addr + %lu\n", cmdname, - (unsigned long)sizeof(image_header_t)); + (unsigned long)image_get_header_size ()); exit (EXIT_FAILURE); } } imagefile = *argv; - if (lflag) { - ifd = open(imagefile, O_RDONLY|O_BINARY); - } else { - ifd = open(imagefile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666); - } + if (!fflag){ + if (lflag) { + ifd = open (imagefile, O_RDONLY|O_BINARY); + } else { + ifd = open (imagefile, + O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666); + } - if (ifd < 0) { - fprintf (stderr, "%s: Can't open %s: %s\n", - cmdname, imagefile, strerror(errno)); - exit (EXIT_FAILURE); + if (ifd < 0) { + fprintf (stderr, "%s: Can't open %s: %s\n", + cmdname, imagefile, strerror(errno)); + exit (EXIT_FAILURE); + } } if (lflag) { - int len; - char *data; /* * list header information of existing image */ @@ -313,7 +211,7 @@ NXTARG: ; exit (EXIT_FAILURE); } - if ((unsigned)sbuf.st_size < sizeof(image_header_t)) { + if ((unsigned)sbuf.st_size < image_get_header_size ()) { fprintf (stderr, "%s: Bad size: \"%s\" is no valid image\n", cmdname, imagefile); @@ -328,49 +226,23 @@ NXTARG: ; exit (EXIT_FAILURE); } - /* - * create copy of header so that we can blank out the - * checksum field for checking - this can't be done - * on the PROT_READ mapped data. - */ - memcpy (hdr, ptr, sizeof(image_header_t)); - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - fprintf (stderr, - "%s: Bad Magic Number: \"%s\" is no valid image\n", - cmdname, imagefile); - exit (EXIT_FAILURE); + if (fdt_check_header (ptr)) { + /* old-style image */ + image_verify_header ((char *)ptr, sbuf.st_size); + image_print_contents_noindent ((image_header_t *)ptr); + } else { + /* FIT image */ + fit_print_contents_noindent (ptr); } - data = (char *)hdr; - len = sizeof(image_header_t); - - checksum = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = htonl(0); /* clear for re-calculation */ - - if (crc32 (0, data, len) != checksum) { - fprintf (stderr, - "%s: ERROR: \"%s\" has bad header checksum!\n", - cmdname, imagefile); - exit (EXIT_FAILURE); - } - - data = (char *)(ptr + sizeof(image_header_t)); - len = sbuf.st_size - sizeof(image_header_t) ; - - if (crc32 (0, data, len) != ntohl(hdr->ih_dcrc)) { - fprintf (stderr, - "%s: ERROR: \"%s\" has corrupted data!\n", - cmdname, imagefile); - exit (EXIT_FAILURE); - } - - /* for multi-file images we need the data part, too */ - print_header ((image_header_t *)ptr); - (void) munmap((void *)ptr, sbuf.st_size); (void) close (ifd); + exit (EXIT_SUCCESS); + } else if (fflag) { + /* Flattened Image Tree (FIT) format handling */ + debug ("FIT format handling\n"); + fit_handle_file (); exit (EXIT_SUCCESS); } @@ -379,9 +251,9 @@ NXTARG: ; * * write dummy header, to be fixed later */ - memset (hdr, 0, sizeof(image_header_t)); + memset (hdr, 0, image_get_header_size ()); - if (write(ifd, hdr, sizeof(image_header_t)) != sizeof(image_header_t)) { + if (write(ifd, hdr, image_get_header_size ()) != image_get_header_size ()) { fprintf (stderr, "%s: Write error on %s: %s\n", cmdname, imagefile, strerror(errno)); exit (EXIT_FAILURE); @@ -404,7 +276,7 @@ NXTARG: ; cmdname, file, strerror(errno)); exit (EXIT_FAILURE); } - size = htonl(sbuf.st_size); + size = cpu_to_uimage (sbuf.st_size); } else { size = 0; } @@ -469,29 +341,29 @@ NXTARG: ; hdr = (image_header_t *)ptr; checksum = crc32 (0, - (const char *)(ptr + sizeof(image_header_t)), - sbuf.st_size - sizeof(image_header_t) + (const char *)(ptr + image_get_header_size ()), + sbuf.st_size - image_get_header_size () ); /* Build new header */ - hdr->ih_magic = htonl(IH_MAGIC); - hdr->ih_time = htonl(sbuf.st_mtime); - hdr->ih_size = htonl(sbuf.st_size - sizeof(image_header_t)); - hdr->ih_load = htonl(addr); - hdr->ih_ep = htonl(ep); - hdr->ih_dcrc = htonl(checksum); - hdr->ih_os = opt_os; - hdr->ih_arch = opt_arch; - hdr->ih_type = opt_type; - hdr->ih_comp = opt_comp; + image_set_magic (hdr, IH_MAGIC); + image_set_time (hdr, sbuf.st_mtime); + image_set_size (hdr, sbuf.st_size - image_get_header_size ()); + image_set_load (hdr, addr); + image_set_ep (hdr, ep); + image_set_dcrc (hdr, checksum); + image_set_os (hdr, opt_os); + image_set_arch (hdr, opt_arch); + image_set_type (hdr, opt_type); + image_set_comp (hdr, opt_comp); - strncpy((char *)hdr->ih_name, name, IH_NMLEN); + image_set_name (hdr, name); - checksum = crc32(0,(const char *)hdr,sizeof(image_header_t)); + checksum = crc32 (0, (const char *)hdr, image_get_header_size ()); - hdr->ih_hcrc = htonl(checksum); + image_set_hcrc (hdr, checksum); - print_header (hdr); + image_print_contents_noindent (hdr); (void) munmap((void *)ptr, sbuf.st_size); @@ -554,14 +426,14 @@ copy_file (int ifd, const char *datafile, int pad) * reserved for it. */ - if ((unsigned)sbuf.st_size < sizeof(image_header_t)) { + if ((unsigned)sbuf.st_size < image_get_header_size ()) { fprintf (stderr, "%s: Bad size: \"%s\" is too small for XIP\n", cmdname, datafile); exit (EXIT_FAILURE); } - for (p=ptr; p < ptr+sizeof(image_header_t); p++) { + for (p = ptr; p < ptr + image_get_header_size (); p++) { if ( *p != 0xff ) { fprintf (stderr, "%s: Bad file: \"%s\" has invalid buffer for XIP\n", @@ -570,7 +442,7 @@ copy_file (int ifd, const char *datafile, int pad) } } - offset = sizeof(image_header_t); + offset = image_get_header_size (); } size = sbuf.st_size - offset; @@ -597,11 +469,11 @@ void usage () { fprintf (stderr, "Usage: %s -l image\n" - " -l ==> list image header information\n" - " %s [-x] -A arch -O os -T type -C comp " - "-a addr -e ep -n name -d data_file[:data_file...] image\n", - cmdname, cmdname); - fprintf (stderr, " -A ==> set architecture to 'arch'\n" + " -l ==> list image header information\n", + cmdname); + fprintf (stderr, " %s [-x] -A arch -O os -T type -C comp " + "-a addr -e ep -n name -d data_file[:data_file...] image\n" + " -A ==> set architecture to 'arch'\n" " -O ==> set operating system to 'os'\n" " -T ==> set image type to 'type'\n" " -C ==> set compression type 'comp'\n" @@ -609,143 +481,158 @@ usage () " -e ==> set entry point to 'ep' (hex)\n" " -n ==> set image name to 'name'\n" " -d ==> use image data from 'datafile'\n" - " -x ==> set XIP (execute in place)\n" - ); + " -x ==> set XIP (execute in place)\n", + cmdname); + fprintf (stderr, " %s [-D dtc_options] -f fit-image.its fit-image\n", + cmdname); + exit (EXIT_FAILURE); } static void -print_header (image_header_t *hdr) +image_verify_header (char *ptr, int image_size) { - time_t timestamp; - uint32_t size; + int len; + char *data; + uint32_t checksum; + image_header_t header; + image_header_t *hdr = &header; - timestamp = (time_t)ntohl(hdr->ih_time); - size = ntohl(hdr->ih_size); + /* + * create copy of header so that we can blank out the + * checksum field for checking - this can't be done + * on the PROT_READ mapped data. + */ + memcpy (hdr, ptr, sizeof(image_header_t)); - printf ("Image Name: %.*s\n", IH_NMLEN, hdr->ih_name); - printf ("Created: %s", ctime(×tamp)); - printf ("Image Type: "); print_type(hdr); - printf ("Data Size: %d Bytes = %.2f kB = %.2f MB\n", - size, (double)size / 1.024e3, (double)size / 1.048576e6 ); - printf ("Load Address: 0x%08X\n", ntohl(hdr->ih_load)); - printf ("Entry Point: 0x%08X\n", ntohl(hdr->ih_ep)); + if (ntohl(hdr->ih_magic) != IH_MAGIC) { + fprintf (stderr, + "%s: Bad Magic Number: \"%s\" is no valid image\n", + cmdname, imagefile); + exit (EXIT_FAILURE); + } - if (hdr->ih_type == IH_TYPE_MULTI || hdr->ih_type == IH_TYPE_SCRIPT) { - int i, ptrs; - uint32_t pos; - uint32_t *len_ptr = (uint32_t *) ( - (unsigned long)hdr + sizeof(image_header_t) - ); + data = (char *)hdr; + len = sizeof(image_header_t); - /* determine number of images first (to calculate image offsets) */ - for (i=0; len_ptr[i]; ++i) /* null pointer terminates list */ - ; - ptrs = i; /* null pointer terminates list */ + checksum = ntohl(hdr->ih_hcrc); + hdr->ih_hcrc = htonl(0); /* clear for re-calculation */ - pos = sizeof(image_header_t) + ptrs * sizeof(long); - printf ("Contents:\n"); - for (i=0; len_ptr[i]; ++i) { - size = ntohl(len_ptr[i]); + if (crc32 (0, data, len) != checksum) { + fprintf (stderr, + "%s: ERROR: \"%s\" has bad header checksum!\n", + cmdname, imagefile); + exit (EXIT_FAILURE); + } - printf (" Image %d: %8d Bytes = %4d kB = %d MB\n", - i, size, size>>10, size>>20); - if (hdr->ih_type == IH_TYPE_SCRIPT && i > 0) { - /* - * the user may need to know offsets - * if planning to do something with - * multiple files - */ - printf (" Offset = %08X\n", pos); - } - /* copy_file() will pad the first files to even word align */ - size += 3; - size &= ~3; - pos += size; - } + data = ptr + sizeof(image_header_t); + len = image_size - sizeof(image_header_t) ; + + if (crc32 (0, data, len) != ntohl(hdr->ih_dcrc)) { + fprintf (stderr, + "%s: ERROR: \"%s\" has corrupted data!\n", + cmdname, imagefile); + exit (EXIT_FAILURE); } } - -static void -print_type (image_header_t *hdr) +/** + * fit_handle_file - main FIT file processing function + * + * fit_handle_file() runs dtc to convert .its to .itb, includes + * binary data, updates timestamp property and calculates hashes. + * + * datafile - .its file + * imagefile - .itb file + * + * returns: + * only on success, otherwise calls exit (EXIT_FAILURE); + */ +static void fit_handle_file (void) { - printf ("%s %s %s (%s)\n", - put_arch (hdr->ih_arch), - put_os (hdr->ih_os ), - put_type (hdr->ih_type), - put_comp (hdr->ih_comp) - ); -} + char tmpfile[MKIMAGE_MAX_TMPFILE_LEN]; + char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN]; + int tfd; + struct stat sbuf; + unsigned char *ptr; -static char *put_arch (int arch) -{ - return (put_table_entry(arch_name, "Unknown Architecture", arch)); -} - -static char *put_os (int os) -{ - return (put_table_entry(os_name, "Unknown OS", os)); -} - -static char *put_type (int type) -{ - return (put_table_entry(type_name, "Unknown Image", type)); -} - -static char *put_comp (int comp) -{ - return (put_table_entry(comp_name, "Unknown Compression", comp)); -} - -static char *put_table_entry (table_entry_t *table, char *msg, int type) -{ - for (; table->val>=0; ++table) { - if (table->val == type) - return (table->lname); + /* call dtc to include binary properties into the tmp file */ + if (strlen (imagefile) + strlen (MKIMAGE_TMPFILE_SUFFIX) + 1 > + sizeof (tmpfile)) { + fprintf (stderr, "%s: Image file name (%s) too long, " + "can't create tmpfile", + imagefile, cmdname); + exit (EXIT_FAILURE); } - return (msg); -} + sprintf (tmpfile, "%s%s", imagefile, MKIMAGE_TMPFILE_SUFFIX); -static int get_arch(char *name) -{ - return (get_table_entry(arch_name, "CPU", name)); -} - - -static int get_comp(char *name) -{ - return (get_table_entry(comp_name, "Compression", name)); -} - - -static int get_os (char *name) -{ - return (get_table_entry(os_name, "OS", name)); -} - - -static int get_type(char *name) -{ - return (get_table_entry(type_name, "Image", name)); -} - -static int get_table_entry (table_entry_t *table, char *msg, char *name) -{ - table_entry_t *t; - int first = 1; - - for (t=table; t->val>=0; ++t) { - if (t->sname && strcasecmp(t->sname, name)==0) - return (t->val); + /* dtc -I dts -O -p 200 datafile > tmpfile */ + sprintf (cmd, "%s %s %s > %s", + MKIMAGE_DTC, opt_dtc, datafile, tmpfile); + debug ("Trying to execute \"%s\"\n", cmd); + if (system (cmd) == -1) { + fprintf (stderr, "%s: system(%s) failed: %s\n", + cmdname, cmd, strerror(errno)); + unlink (tmpfile); + exit (EXIT_FAILURE); } - fprintf (stderr, "\nInvalid %s Type - valid names are", msg); - for (t=table; t->val>=0; ++t) { - if (t->sname == NULL) - continue; - fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname); - first = 0; + + /* load FIT blob into memory */ + tfd = open (tmpfile, O_RDWR|O_BINARY); + + if (tfd < 0) { + fprintf (stderr, "%s: Can't open %s: %s\n", + cmdname, tmpfile, strerror(errno)); + unlink (tmpfile); + exit (EXIT_FAILURE); + } + + if (fstat (tfd, &sbuf) < 0) { + fprintf (stderr, "%s: Can't stat %s: %s\n", + cmdname, tmpfile, strerror(errno)); + unlink (tmpfile); + exit (EXIT_FAILURE); + } + + ptr = (unsigned char *)mmap (0, sbuf.st_size, + PROT_READ|PROT_WRITE, MAP_SHARED, tfd, 0); + if ((caddr_t)ptr == (caddr_t)-1) { + fprintf (stderr, "%s: Can't read %s: %s\n", + cmdname, tmpfile, strerror(errno)); + unlink (tmpfile); + exit (EXIT_FAILURE); + } + + /* check if ptr has a valid blob */ + if (fdt_check_header (ptr)) { + fprintf (stderr, "%s: Invalid FIT blob\n", cmdname); + unlink (tmpfile); + exit (EXIT_FAILURE); + } + + /* set hashes for images in the blob */ + if (fit_set_hashes (ptr)) { + fprintf (stderr, "%s Can't add hashes to FIT blob", cmdname); + unlink (tmpfile); + exit (EXIT_FAILURE); + } + + /* add a timestamp at offset 0 i.e., root */ + if (fit_set_timestamp (ptr, 0, sbuf.st_mtime)) { + fprintf (stderr, "%s: Can't add image timestamp\n", cmdname); + unlink (tmpfile); + exit (EXIT_FAILURE); + } + debug ("Added timestamp successfully\n"); + + munmap ((void *)ptr, sbuf.st_size); + close (tfd); + + if (rename (tmpfile, imagefile) == -1) { + fprintf (stderr, "%s: Can't rename %s to %s: %s\n", + cmdname, tmpfile, imagefile, strerror (errno)); + unlink (tmpfile); + unlink (imagefile); + exit (EXIT_FAILURE); } - fprintf (stderr, "\n"); - return (-1); } diff --git a/tools/mkimage.h b/tools/mkimage.h new file mode 100644 index 000000000..a2d524894 --- /dev/null +++ b/tools/mkimage.h @@ -0,0 +1,75 @@ +/* + * (C) Copyright 2000-2004 + * DENX Software Engineering + * Wolfgang Denk, wd@denx.de + * 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 + */ + +#include +#include +#include +#include +#include +#ifndef __WIN32__ +#include /* for host / network byte order conversions */ +#endif +#include +#include +#include +#include +#include +#include "fdt_host.h" + +#define MKIMAGE_DEBUG + +#ifdef MKIMAGE_DEBUG +#define debug(fmt,args...) printf (fmt ,##args) +#else +#define debug(fmt,args...) +#endif /* MKIMAGE_DEBUG */ + +#define MKIMAGE_TMPFILE_SUFFIX ".tmp" +#define MKIMAGE_MAX_TMPFILE_LEN 256 +#define MKIMAGE_DEFAULT_DTC_OPTIONS "-I dts -O dtb -p 500" +#define MKIMAGE_MAX_DTC_CMDLINE_LEN 512 +#define MKIMAGE_DTC "dtc" /* assume dtc is in $PATH */ + +#if defined(__BEOS__) || defined(__NetBSD__) || defined(__APPLE__) +#include +#endif + +#ifdef __WIN32__ +typedef unsigned int __u32; + +#define SWAP_LONG(x) \ + ((__u32)( \ + (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \ + (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \ + (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \ + (((__u32)(x) & (__u32)0xff000000UL) >> 24) )) +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; + +#define ntohl(a) SWAP_LONG(a) +#define htonl(a) SWAP_LONG(a) +#endif /* __WIN32__ */ + +#ifndef O_BINARY /* should be define'd on __WIN32__ */ +#define O_BINARY 0 +#endif