summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Fleming <afleming@freescale.com>2008-09-09 21:16:20 (GMT)
committerAndrew Fleming-AFLEMING <afleming@freescale.com>2008-09-09 21:16:20 (GMT)
commit650a9e7abc44ce1ce73d6668eaf0ba2d6b8025e9 (patch)
tree30732e12d39390eda22338e98db7b8ab9025bf22
parent6cc64f9b5f69239c8b1969572b5a3a4aab7de5b9 (diff)
parent3b20fd83c73c22acfcb0c6663be747bd5c8b7011 (diff)
downloadu-boot-650a9e7abc44ce1ce73d6668eaf0ba2d6b8025e9.tar.xz
Merge branch 'denx'
-rw-r--r--CREDITS3
-rw-r--r--MAINTAINERS2
-rwxr-xr-xMAKEALL4
-rw-r--r--Makefile68
-rw-r--r--README15
-rw-r--r--board/atc/atc.c1
-rw-r--r--board/avnet/v5fx30teval/Makefile27
-rw-r--r--board/avnet/v5fx30teval/config.mk26
-rw-r--r--board/avnet/v5fx30teval/v5fx30teval.c28
-rw-r--r--board/avnet/v5fx30teval/xparameters.h33
-rw-r--r--board/cpu86/cpu86.c1
-rw-r--r--board/cpu87/cpu87.c1
-rw-r--r--board/esd/cpci405/config.mk16
-rw-r--r--board/esd/cpci405/u-boot.lds15
-rw-r--r--board/gen860t/gen860t.c2
-rw-r--r--board/integratorcp/integratorcp.c7
-rw-r--r--board/mcc200/mcc200.c1
-rw-r--r--board/mpl/common/common_util.c1
-rw-r--r--board/netstal/hcu5/sdram.c2
-rw-r--r--board/netta2/netta2.c14
-rw-r--r--board/pm520/pm520.c1
-rw-r--r--board/pm826/pm826.c1
-rw-r--r--board/pm828/pm828.c1
-rw-r--r--board/sc520_cdp/sc520_cdp.c10
-rw-r--r--board/stxxtc/stxxtc.c14
-rw-r--r--board/svm_sc8xx/svm_sc8xx.c1
-rw-r--r--board/trab/tsc2000.c10
-rw-r--r--board/xilinx/ml507/Makefile41
-rw-r--r--board/xilinx/ml507/config.mk11
-rw-r--r--board/xilinx/ml507/init.S53
-rw-r--r--board/xilinx/ml507/ml507.c21
-rw-r--r--board/xilinx/ml507/xparameters.h17
-rw-r--r--board/xilinx/ppc440-generic/Makefile62
-rw-r--r--board/xilinx/ppc440-generic/config.mk25
-rw-r--r--board/xilinx/ppc440-generic/init.S45
-rw-r--r--board/xilinx/ppc440-generic/u-boot-ram.lds (renamed from board/xilinx/ml507/u-boot-ram.lds)0
-rw-r--r--board/xilinx/ppc440-generic/u-boot-rom.lds (renamed from board/xilinx/ml507/u-boot-rom.lds)0
-rw-r--r--board/xilinx/ppc440-generic/xilinx_ppc440_generic.c52
-rw-r--r--board/xilinx/ppc440-generic/xparameters.h34
-rw-r--r--common/Makefile9
-rw-r--r--common/cmd_bootm.c109
-rw-r--r--common/image.c67
-rw-r--r--common/usb.c13
-rw-r--r--common/usb_kbd.c2
-rw-r--r--cpu/arm1176/s3c64xx/interrupts.c5
-rw-r--r--cpu/arm946es/config.mk7
-rw-r--r--cpu/arm_intcm/config.mk7
-rw-r--r--cpu/ppc4xx/44x_spd_ddr2.c158
-rw-r--r--cpu/ppc4xx/4xx_enet.c168
-rw-r--r--cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c1212
-rw-r--r--cpu/ppc4xx/Makefile3
-rw-r--r--cpu/ppc4xx/miiphy.c37
-rw-r--r--disk/part.c6
-rw-r--r--doc/uImage.FIT/source_file_format.txt2
-rw-r--r--drivers/mtd/mw_eeprom.c2
-rw-r--r--drivers/rtc/Makefile6
-rw-r--r--drivers/rtc/mk48t59.c2
-rw-r--r--drivers/rtc/rs5c372.c3
-rw-r--r--drivers/serial/Makefile6
-rw-r--r--drivers/serial/serial_pl011.c161
-rw-r--r--drivers/serial/serial_pl01x.c (renamed from drivers/serial/serial_pl010.c)88
-rw-r--r--drivers/serial/serial_pl01x.h (renamed from drivers/serial/serial_pl011.h)0
-rw-r--r--drivers/usb/usb_ohci.c4
-rw-r--r--examples/82559_eeprom.c16
-rw-r--r--include/asm-i386/byteorder.h4
-rw-r--r--include/asm-i386/global_data.h4
-rw-r--r--include/asm-i386/ic/ssi.h34
-rw-r--r--include/asm-i386/pci.h1
-rw-r--r--include/asm-i386/string.h2
-rw-r--r--include/asm-ppc/ppc4xx-sdram.h17
-rw-r--r--include/common.h3
-rw-r--r--include/configs/CPCI4052.h6
-rw-r--r--include/configs/CPCI405AB.h6
-rw-r--r--include/configs/NETPHONE.h2
-rw-r--r--include/configs/NETTA.h2
-rw-r--r--include/configs/NETTA2.h3
-rw-r--r--include/configs/NETVIA.h2
-rw-r--r--include/configs/PIP405.h1
-rw-r--r--include/configs/integratorap.h2
-rw-r--r--include/configs/integratorcp.h2
-rw-r--r--include/configs/kilauea.h19
-rw-r--r--include/configs/ml507.h91
-rw-r--r--include/configs/sc520_cdp.h24
-rw-r--r--include/configs/stxxtc.h1
-rw-r--r--include/configs/v5fx30teval.h49
-rw-r--r--include/configs/versatile.h2
-rw-r--r--include/configs/xilinx-ppc440-generic.h49
-rw-r--r--include/configs/xilinx-ppc440.h106
-rw-r--r--include/image.h2
-rw-r--r--include/onenand_uboot.h1
-rw-r--r--include/ppc440.h13
-rw-r--r--include/ppc4xx.h13
-rw-r--r--include/ppc4xx_enet.h3
-rw-r--r--lib_arm/bootm.c3
-rw-r--r--lib_i386/bios_setup.c6
-rw-r--r--lib_i386/board.c13
-rw-r--r--lib_i386/bootm.c2
-rw-r--r--lib_i386/video_bios.c3
-rw-r--r--lib_mips/Makefile4
-rw-r--r--lib_mips/bootm.c2
-rw-r--r--lib_mips/bootm_qemu_mips.c76
-rw-r--r--lib_ppc/interrupts.c7
-rw-r--r--tools/env/README6
-rw-r--r--tools/env/fw_env.c863
-rw-r--r--tools/env/fw_env.config6
105 files changed, 3228 insertions, 986 deletions
diff --git a/CREDITS b/CREDITS
index 4fe4e63..3767322 100644
--- a/CREDITS
+++ b/CREDITS
@@ -405,7 +405,8 @@ D: Atmel AT91CAP9ADK support
N: Ricardo Ribalda Delgado
E: ricardo.ribalda@uam.es
-D: PPC440x5 (Virtex5), ML507 Board, eeprom_simul, adt7460
+D: PPC440x5 (Virtex5), ML507 Board, eeprom_simul, adt7460, v5fx30teval
+D: Virtex ppc440 generic architecture
W: http://www.ii.uam.es/~rribalda
N: Stefan Roese
diff --git a/MAINTAINERS b/MAINTAINERS
index 3f16dab..64d8409 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -314,6 +314,8 @@ Daniel Poirot <dan.poirot@windriver.com>
Ricardo Ribalda <ricardo.ribalda@uam.es>
ml507 PPC440x5
+ v5fx30teval PPC440x5
+ xilinx-pp440-generic PPC440x5
Stefan Roese <sr@denx.de>
diff --git a/MAKEALL b/MAKEALL
index fbdcb42..9ccb9ac 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -230,12 +230,16 @@ LIST_4xx=" \
sequoia_nand \
taihu \
taishan \
+ v5fx30teval \
+ v5fx30teval_flash \
VOH405 \
VOM405 \
W7OLMC \
W7OLMG \
walnut \
WUH405 \
+ xilinx-ppc440-generic \
+ xilinx-ppc440-generic_flash \
XPEDITE1K \
yellowstone \
yosemite \
diff --git a/Makefile b/Makefile
index 8d82ef5..2e6dca3 100644
--- a/Makefile
+++ b/Makefile
@@ -295,7 +295,7 @@ $(obj)u-boot.hex: $(obj)u-boot
$(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@
$(obj)u-boot.srec: $(obj)u-boot
- $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@
+ $(OBJCOPY) -O srec $< $@
$(obj)u-boot.bin: $(obj)u-boot
$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
@@ -1242,12 +1242,15 @@ CMS700_config: unconfig
CPCI2DP_config: unconfig
@$(MKCONFIG) $(@:_config=) ppc ppc4xx cpci2dp esd
-CPCI405_config \
-CPCI4052_config \
+CPCI405_config: unconfig
+ @$(MKCONFIG) $(@:_config=) ppc ppc4xx cpci405 esd
+
+CPCI4052_config \
CPCI405DT_config \
CPCI405AB_config: unconfig
+ @mkdir -p $(obj)board/esd/cpci405
+ @echo "TEXT_BASE = 0xFFFC0000" > $(obj)board/esd/cpci405/config.tmp
@$(MKCONFIG) $(@:_config=) ppc ppc4xx cpci405 esd
- @echo "BOARD_REVISION = $(@:_config=)" >> $(obj)include/config.mk
CPCIISER4_config: unconfig
@$(MKCONFIG) $(@:_config=) ppc ppc4xx cpciiser4 esd
@@ -1356,16 +1359,23 @@ ML2_config: unconfig
ml300_config: unconfig
@$(MKCONFIG) $(@:_config=) ppc ppc4xx ml300 xilinx
-ml507_flash_config: unconfig
+ml507_flash_config: unconfig
+ @mkdir -p $(obj)include $(obj)board/xilinx/ppc440-generic
@mkdir -p $(obj)include $(obj)board/xilinx/ml507
- @cp $(obj)board/xilinx/ml507/u-boot-rom.lds $(obj)board/xilinx/ml507/u-boot.lds
- @echo "TEXT_BASE = 0xFE360000" > $(obj)board/xilinx/ml507/config.tmp
- @$(MKCONFIG) $(@:_flash_config=) ppc ppc4xx ml507 xilinx
-
-ml507_config: unconfig
+ @echo "LDSCRIPT:=$(SRCTREE)/board/xilinx/ppc440-generic/u-boot-rom.lds"\
+ > $(obj)board/xilinx/ml507/config.tmp
+ @echo "TEXT_BASE := 0xFE360000" \
+ >> $(obj)board/xilinx/ml507/config.tmp
+ @$(MKCONFIG) ml507 ppc ppc4xx ml507 xilinx
+
+ml507_config: unconfig
+ @mkdir -p $(obj)include $(obj)board/xilinx/ppc440-generic
@mkdir -p $(obj)include $(obj)board/xilinx/ml507
- @cp $(obj)board/xilinx/ml507/u-boot-ram.lds $(obj)board/xilinx/ml507/u-boot.lds
- @$(MKCONFIG) $(@:_config=) ppc ppc4xx ml507 xilinx
+ @echo "LDSCRIPT:=$(SRCTREE)/board/xilinx/ppc440-generic/u-boot-ram.lds"\
+ > $(obj)board/xilinx/ml507/config.tmp
+ @echo "TEXT_BASE := 0x04000000" \
+ >> $(obj)board/xilinx/ml507/config.tmp
+ @$(MKCONFIG) ml507 ppc ppc4xx ml507 xilinx
ocotea_config: unconfig
@$(MKCONFIG) $(@:_config=) ppc ppc4xx ocotea amcc
@@ -1461,6 +1471,24 @@ taihu_config: unconfig
taishan_config: unconfig
@$(MKCONFIG) $(@:_config=) ppc ppc4xx taishan amcc
+v5fx30teval_config: unconfig
+ @mkdir -p $(obj)include $(obj)board/xilinx/ppc440-generic
+ @mkdir -p $(obj)include $(obj)board/avnet/v5fx30teval
+ @echo "LDSCRIPT:=$(SRCTREE)/board/xilinx/ppc440-generic/u-boot-ram.lds"\
+ > $(obj)board/avnet/v5fx30teval/config.tmp
+ @echo "TEXT_BASE := 0x03000000" \
+ >> $(obj)board/avnet/v5fx30teval/config.tmp
+ @$(MKCONFIG) v5fx30teval ppc ppc4xx v5fx30teval avnet
+
+v5fx30teval_flash_config: unconfig
+ @mkdir -p $(obj)include $(obj)board/xilinx/ppc440-generic
+ @mkdir -p $(obj)include $(obj)board/avnet/v5fx30teval
+ @echo "LDSCRIPT:=$(SRCTREE)/board/xilinx/ppc440-generic/u-boot-rom.lds"\
+ > $(obj)/board/avnet/v5fx30teval/config.tmp
+ @echo "TEXT_BASE := 0xFF1C0000" \
+ >> $(obj)/board/avnet/v5fx30teval/config.tmp
+ @$(MKCONFIG) v5fx30teval ppc ppc4xx v5fx30teval avnet
+
VOH405_config: unconfig
@$(MKCONFIG) $(@:_config=) ppc ppc4xx voh405 esd
@@ -1479,6 +1507,22 @@ sycamore_config: unconfig
WUH405_config: unconfig
@$(MKCONFIG) $(@:_config=) ppc ppc4xx wuh405 esd
+xilinx-ppc440-generic_flash_config: unconfig
+ @mkdir -p $(obj)include $(obj)board/xilinx/ppc440-generic
+ @echo "LDSCRIPT:=$(SRCTREE)/board/xilinx/ppc440-generic/u-boot-rom.lds"\
+ > $(obj)board/xilinx/ppc440-generic/config.tmp
+ @echo "TEXT_BASE := 0xFE360000" \
+ >> $(obj)board/xilinx/ppc440-generic/config.tmp
+ @$(MKCONFIG) xilinx-ppc440-generic ppc ppc4xx ppc440-generic xilinx
+
+xilinx-ppc440-generic_config: unconfig
+ @mkdir -p $(obj)include $(obj)board/xilinx/ppc440-generic
+ @echo "LDSCRIPT:=$(SRCTREE)/board/xilinx/ppc440-generic/u-boot-ram.lds"\
+ > $(obj)board/xilinx/ppc440-generic/config.tmp
+ @echo "TEXT_BASE := 0x04000000" \
+ >> $(obj)board/xilinx/ppc440-generic/config.tmp
+ @$(MKCONFIG) xilinx-ppc440-generic ppc ppc4xx ppc440-generic xilinx
+
XPEDITE1K_config: unconfig
@$(MKCONFIG) $(@:_config=) ppc ppc4xx xpedite1k
diff --git a/README b/README
index 37449d1..b5e4086 100644
--- a/README
+++ b/README
@@ -380,11 +380,11 @@ The following options need to be configured:
param header, the default value is zero if undefined.
- Serial Ports:
- CFG_PL010_SERIAL
+ CONFIG_PL010_SERIAL
Define this if you want support for Amba PrimeCell PL010 UARTs.
- CFG_PL011_SERIAL
+ CONFIG_PL011_SERIAL
Define this if you want support for Amba PrimeCell PL011 UARTs.
@@ -3030,8 +3030,9 @@ 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,
- LynxOS, pSOS, QNX, RTEMS, ARTOS;
- Currently supported: Linux, NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS).
+ LynxOS, pSOS, QNX, RTEMS, INTEGRITY;
+ Currently supported: Linux, NetBSD, VxWorks, QNX, RTEMS, LynxOS,
+ INTEGRITY).
* Target CPU Architecture (Provisions for Alpha, ARM, AVR32, Intel x86,
IA64, MIPS, NIOS, PowerPC, IBM S390, SuperH, Sparc, Sparc 64 Bit;
Currently supported: ARM, AVR32, Intel x86, MIPS, NIOS, PowerPC).
@@ -3089,9 +3090,9 @@ But now you can ignore ALL boot loader code (in arch/ppc/mbxboot).
Just make sure your machine specific header file (for instance
include/asm-ppc/tqm8xx.h) includes the same definition of the Board
-Information structure as we define in include/u-boot.h, and make
-sure that your definition of IMAP_ADDR uses the same value as your
-U-Boot configuration in CFG_IMMR.
+Information structure as we define in include/asm-<arch>/u-boot.h,
+and make sure that your definition of IMAP_ADDR uses the same value
+as your U-Boot configuration in CFG_IMMR.
Configuring the Linux kernel:
diff --git a/board/atc/atc.c b/board/atc/atc.c
index 79527f4..b627c1c 100644
--- a/board/atc/atc.c
+++ b/board/atc/atc.c
@@ -380,7 +380,6 @@ phys_size_t initdram (int board_type)
}
#if defined(CONFIG_CMD_DOC)
-extern void doc_probe (ulong physadr);
void doc_init (void)
{
doc_probe (CFG_DOC_BASE);
diff --git a/board/avnet/v5fx30teval/Makefile b/board/avnet/v5fx30teval/Makefile
new file mode 100644
index 0000000..de23f29
--- /dev/null
+++ b/board/avnet/v5fx30teval/Makefile
@@ -0,0 +1,27 @@
+#
+# (C) Copyright 2008
+# Ricardo Ribalda,Universidad Autonoma de Madrid, ricardo.ribalda@uam.es
+# This work has been supported by: Qtechnology http://qtec.com/
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+COBJS += $(BOARD).o
+
+include $(SRCTREE)/board/xilinx/ppc440-generic/Makefile
diff --git a/board/avnet/v5fx30teval/config.mk b/board/avnet/v5fx30teval/config.mk
new file mode 100644
index 0000000..51448ce
--- /dev/null
+++ b/board/avnet/v5fx30teval/config.mk
@@ -0,0 +1,26 @@
+#
+# (C) Copyright 2008
+# Ricardo Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es
+# Work supported by Qtechnology http://www.qtec.com
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+
+sinclude $(SRCTREE)/board/xilinx/ppc440-generic/config.mk
diff --git a/board/avnet/v5fx30teval/v5fx30teval.c b/board/avnet/v5fx30teval/v5fx30teval.c
new file mode 100644
index 0000000..14a1d5d
--- /dev/null
+++ b/board/avnet/v5fx30teval/v5fx30teval.c
@@ -0,0 +1,28 @@
+/*
+ * (C) Copyright 2008
+ * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es
+ * This work has been supported by: QTechnology http://qtec.com/
+ * 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <config.h>
+#include <common.h>
+#include <asm/processor.h>
+
+
+int checkboard(void)
+{
+ puts("Avnet Virtex 5 FX30 Evaluation Board\n");
+ return 0;
+}
diff --git a/board/avnet/v5fx30teval/xparameters.h b/board/avnet/v5fx30teval/xparameters.h
new file mode 100644
index 0000000..bb657fc
--- /dev/null
+++ b/board/avnet/v5fx30teval/xparameters.h
@@ -0,0 +1,33 @@
+/*
+ * (C) Copyright 2008
+ * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es
+ * This work has been supported by: QTechnology http://qtec.com/
+ * based on xparameters.h by Xilinx
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef XPARAMETER_H
+#define XPARAMETER_H
+
+#define XPAR_DDR2_SDRAM_MEM_BASEADDR 0x00000000
+#define XPAR_INTC_0_BASEADDR 0x81800000
+#define XPAR_UARTLITE_0_BASEADDR 0x84000000
+#define XPAR_FLASH_MEM0_BASEADDR 0xFF000000
+#define XPAR_PLB_CLOCK_FREQ_HZ 100000000
+#define XPAR_CORE_CLOCK_FREQ_HZ 400000000
+#define XPAR_INTC_MAX_NUM_INTR_INPUTS 13
+#define XPAR_UARTLITE_0_BAUDRATE 9600
+
+#endif
diff --git a/board/cpu86/cpu86.c b/board/cpu86/cpu86.c
index 9e76c72..23ec283 100644
--- a/board/cpu86/cpu86.c
+++ b/board/cpu86/cpu86.c
@@ -313,7 +313,6 @@ phys_size_t initdram (int board_type)
}
#if defined(CONFIG_CMD_DOC)
-extern void doc_probe (ulong physadr);
void doc_init (void)
{
doc_probe (CFG_DOC_BASE);
diff --git a/board/cpu87/cpu87.c b/board/cpu87/cpu87.c
index 454987c..c7a96f9 100644
--- a/board/cpu87/cpu87.c
+++ b/board/cpu87/cpu87.c
@@ -323,7 +323,6 @@ phys_size_t initdram (int board_type)
}
#if defined(CONFIG_CMD_DOC)
-extern void doc_probe (ulong physadr);
void doc_init (void)
{
doc_probe (CFG_DOC_BASE);
diff --git a/board/esd/cpci405/config.mk b/board/esd/cpci405/config.mk
index 0be45c7..6cfb891 100644
--- a/board/esd/cpci405/config.mk
+++ b/board/esd/cpci405/config.mk
@@ -21,20 +21,8 @@
# MA 02111-1307 USA
#
-#
-# esd CPCI405 boards
-#
+sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp
-ifeq ($(BOARD_REVISION),CPCI4052)
-TEXT_BASE = 0xFFFC0000
-else
-ifeq ($(BOARD_REVISION),CPCI405DT)
-TEXT_BASE = 0xFFFC0000
-else
-ifeq ($(BOARD_REVISION),CPCI405AB)
-TEXT_BASE = 0xFFFC0000
-else
+ifndef TEXT_BASE
TEXT_BASE = 0xFFFD0000
endif
-endif
-endif
diff --git a/board/esd/cpci405/u-boot.lds b/board/esd/cpci405/u-boot.lds
index 21547ac..2a1fc31 100644
--- a/board/esd/cpci405/u-boot.lds
+++ b/board/esd/cpci405/u-boot.lds
@@ -57,22 +57,7 @@ SECTIONS
.plt : { *(.plt) }
.text :
{
- /* WARNING - the following is hand-optimized to fit within */
- /* the sector layout of our flash chips! XXX FIXME XXX */
-
cpu/ppc4xx/start.o (.text)
- cpu/ppc4xx/traps.o (.text)
- cpu/ppc4xx/interrupts.o (.text)
- cpu/ppc4xx/4xx_uart.o (.text)
- cpu/ppc4xx/cpu_init.o (.text)
- cpu/ppc4xx/speed.o (.text)
- common/dlmalloc.o (.text)
- lib_generic/crc32.o (.text)
- lib_ppc/extable.o (.text)
- lib_generic/zlib.o (.text)
-
-/* . = env_offset;*/
-/* common/environment.o(.text)*/
*(.text)
*(.fixup)
diff --git a/board/gen860t/gen860t.c b/board/gen860t/gen860t.c
index e3d0e43..5c497b6 100644
--- a/board/gen860t/gen860t.c
+++ b/board/gen860t/gen860t.c
@@ -223,8 +223,6 @@ phys_size_t initdram (int board_type)
* The DOC lives in the CS2* space
*/
#if defined(CONFIG_CMD_DOC)
-extern void doc_probe (ulong physadr);
-
void doc_init (void)
{
printf ("Probing at 0x%.8x: ", DOC_BASE);
diff --git a/board/integratorcp/integratorcp.c b/board/integratorcp/integratorcp.c
index d6d6e13..220513f 100644
--- a/board/integratorcp/integratorcp.c
+++ b/board/integratorcp/integratorcp.c
@@ -34,6 +34,7 @@
*/
#include <common.h>
+#include <div64.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -244,7 +245,11 @@ ulong get_timer_masked (void)
total_count += lastdec - now;
}
lastdec = now;
- timestamp = (ulong)(total_count/div_timer);
+
+ /* Reuse "now" */
+ now = total_count;
+ do_div(now, div_timer);
+ timestamp = now;
return timestamp;
}
diff --git a/board/mcc200/mcc200.c b/board/mcc200/mcc200.c
index 77ee3d7..4444650 100644
--- a/board/mcc200/mcc200.c
+++ b/board/mcc200/mcc200.c
@@ -323,7 +323,6 @@ void ide_set_reset (int idereset)
#endif
#if defined(CONFIG_CMD_DOC)
-extern void doc_probe (ulong physadr);
void doc_init (void)
{
doc_probe (CFG_DOC_BASE);
diff --git a/board/mpl/common/common_util.c b/board/mpl/common/common_util.c
index 24ce807..1f9a772 100644
--- a/board/mpl/common/common_util.c
+++ b/board/mpl/common/common_util.c
@@ -565,7 +565,6 @@ int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
#if defined(CONFIG_CMD_DOC)
-extern void doc_probe(ulong physadr);
void doc_init (void)
{
doc_probe(MULTI_PURPOSE_SOCKET_ADDR);
diff --git a/board/netstal/hcu5/sdram.c b/board/netstal/hcu5/sdram.c
index 66a958c..e5df62e 100644
--- a/board/netstal/hcu5/sdram.c
+++ b/board/netstal/hcu5/sdram.c
@@ -122,7 +122,7 @@ void sdram_panic(const char *reason)
}
#ifdef CONFIG_DDR_ECC
-static void blank_string(int size)
+void blank_string(int size)
{
int i;
diff --git a/board/netta2/netta2.c b/board/netta2/netta2.c
index a97c14c..1dbdde1 100644
--- a/board/netta2/netta2.c
+++ b/board/netta2/netta2.c
@@ -620,20 +620,6 @@ void hw_watchdog_reset(void)
#endif
-#ifdef CONFIG_SHOW_ACTIVITY
-
-/* called from timer interrupt every 1/CFG_HZ sec */
-void board_show_activity(ulong timestamp)
-{
-}
-
-/* called when looping */
-void show_activity(int arg)
-{
-}
-
-#endif
-
#if defined(CFG_CONSOLE_IS_IN_ENV) && defined(CFG_CONSOLE_OVERWRITE_ROUTINE)
int overwrite_console(void)
{
diff --git a/board/pm520/pm520.c b/board/pm520/pm520.c
index a9d63cc..6db93fb 100644
--- a/board/pm520/pm520.c
+++ b/board/pm520/pm520.c
@@ -316,7 +316,6 @@ void ide_set_reset (int idereset)
#endif
#if defined(CONFIG_CMD_DOC)
-extern void doc_probe (ulong physadr);
void doc_init (void)
{
doc_probe (CFG_DOC_BASE);
diff --git a/board/pm826/pm826.c b/board/pm826/pm826.c
index d8b0929..2304420 100644
--- a/board/pm826/pm826.c
+++ b/board/pm826/pm826.c
@@ -312,7 +312,6 @@ phys_size_t initdram (int board_type)
}
#if defined(CONFIG_CMD_DOC)
-extern void doc_probe (ulong physadr);
void doc_init (void)
{
doc_probe (CFG_DOC_BASE);
diff --git a/board/pm828/pm828.c b/board/pm828/pm828.c
index b163d5b..296a199 100644
--- a/board/pm828/pm828.c
+++ b/board/pm828/pm828.c
@@ -345,7 +345,6 @@ phys_size_t initdram (int board_type)
}
#if defined(CONFIG_CMD_DOC)
-extern void doc_probe (ulong physadr);
void doc_init (void)
{
doc_probe (CFG_DOC_BASE);
diff --git a/board/sc520_cdp/sc520_cdp.c b/board/sc520_cdp/sc520_cdp.c
index f21c730..99debde 100644
--- a/board/sc520_cdp/sc520_cdp.c
+++ b/board/sc520_cdp/sc520_cdp.c
@@ -114,7 +114,7 @@ static void irq_init(void)
}
-
+#ifdef CONFIG_PCI
/* PCI stuff */
static void pci_sc520_cdp_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
{
@@ -129,7 +129,7 @@ static void pci_sc520_cdp_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
};
static int next_irq_index=0;
- char tmp_pin;
+ uchar tmp_pin;
int pin;
pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_PIN, &tmp_pin);
@@ -193,7 +193,7 @@ void pci_init_board(void)
{
pci_sc520_init(&sc520_cdp_hose);
}
-
+#endif
static void silence_uart(int port)
{
@@ -563,12 +563,12 @@ void spi_eeprom_probe(int x)
{
}
-int spi_eeprom_read(int x, int offset, char *buffer, int len)
+int spi_eeprom_read(int x, int offset, uchar *buffer, int len)
{
return 0;
}
-int spi_eeprom_write(int x, int offset, char *buffer, int len)
+int spi_eeprom_write(int x, int offset, uchar *buffer, int len)
{
return 0;
}
diff --git a/board/stxxtc/stxxtc.c b/board/stxxtc/stxxtc.c
index a750374..4bb2d68 100644
--- a/board/stxxtc/stxxtc.c
+++ b/board/stxxtc/stxxtc.c
@@ -599,20 +599,6 @@ void hw_watchdog_reset(void)
#endif
-#ifdef CONFIG_SHOW_ACTIVITY
-
-/* called from timer interrupt every 1/CFG_HZ sec */
-void board_show_activity(ulong timestamp)
-{
-}
-
-/* called when looping */
-void show_activity(int arg)
-{
-}
-
-#endif
-
#if defined(CFG_CONSOLE_IS_IN_ENV) && defined(CFG_CONSOLE_OVERWRITE_ROUTINE)
int overwrite_console(void)
{
diff --git a/board/svm_sc8xx/svm_sc8xx.c b/board/svm_sc8xx/svm_sc8xx.c
index 06fb18b..48e05b8 100644
--- a/board/svm_sc8xx/svm_sc8xx.c
+++ b/board/svm_sc8xx/svm_sc8xx.c
@@ -154,7 +154,6 @@ phys_size_t initdram (int board_type)
}
#if defined(CONFIG_CMD_DOC)
-extern void doc_probe (ulong physadr);
void doc_init (void)
{
doc_probe (CFG_DOC_BASE);
diff --git a/board/trab/tsc2000.c b/board/trab/tsc2000.c
index 382a85b..f13a5a9 100644
--- a/board/trab/tsc2000.c
+++ b/board/trab/tsc2000.c
@@ -27,6 +27,7 @@
#include <common.h>
#include <s3c2400.h>
+#include <div64.h>
#include "tsc2000.h"
#include "Pt1000_temp_data.h"
@@ -332,6 +333,7 @@ void tsc2000_reg_init (void)
int tsc2000_interpolate(long value, long data[][2], long *result)
{
int i;
+ unsigned long long val;
/* the data is sorted and the first element is upper
* limit so we can easily check for out-of-band values
@@ -347,10 +349,10 @@ int tsc2000_interpolate(long value, long data[][2], long *result)
result in 'long long'.
*/
- *result = data[i-1][1] +
- ((unsigned long long)(data[i][1] - data[i-1][1])
- * (unsigned long long)(value - data[i-1][0]))
- / (data[i][0] - data[i-1][0]);
+ val = ((unsigned long long)(data[i][1] - data[i-1][1])
+ * (unsigned long long)(value - data[i-1][0]));
+ do_div(val, (data[i][0] - data[i-1][0]));
+ *result = data[i-1][1] + val;
return 0;
}
diff --git a/board/xilinx/ml507/Makefile b/board/xilinx/ml507/Makefile
index 7283704..de23f29 100644
--- a/board/xilinx/ml507/Makefile
+++ b/board/xilinx/ml507/Makefile
@@ -1,6 +1,7 @@
#
-# (C) Copyright 2000-2006
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+# (C) Copyright 2008
+# Ricardo Ribalda,Universidad Autonoma de Madrid, ricardo.ribalda@uam.es
+# This work has been supported by: Qtechnology http://qtec.com/
#
# See file CREDITS for list of people who contributed to this
# project.
@@ -21,38 +22,6 @@
# MA 02111-1307 USA
#
-include $(TOPDIR)/config.mk
-ifneq ($(OBJTREE),$(SRCTREE))
-endif
+COBJS += $(BOARD).o
-INCS :=
-CFLAGS += $(INCS)
-HOST_CFLAGS += $(INCS)
-
-LIB = $(obj)lib$(BOARD).a
-
-COBJS = $(BOARD).o
-
-SOBJS = init.o
-
-SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS := $(addprefix $(obj),$(COBJS))
-SOBJS := $(addprefix $(obj),$(SOBJS))
-
-$(LIB): $(OBJS) $(SOBJS)
- $(AR) $(ARFLAGS) $@ $^
-
-clean:
- rm -f $(SOBJS) $(OBJS)
-
-distclean: clean
- rm -f $(LIB) core *.bak .depend
-
-#########################################################################
-
-# defines $(obj).depend target
-include $(SRCTREE)/rules.mk
-
-sinclude $(obj).depend
-
-#########################################################################
+include $(SRCTREE)/board/xilinx/ppc440-generic/Makefile
diff --git a/board/xilinx/ml507/config.mk b/board/xilinx/ml507/config.mk
index e827e8a..51448ce 100644
--- a/board/xilinx/ml507/config.mk
+++ b/board/xilinx/ml507/config.mk
@@ -1,6 +1,7 @@
#
-# (C) Copyright 2000
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+# (C) Copyright 2008
+# Ricardo Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es
+# Work supported by Qtechnology http://www.qtec.com
#
# See file CREDITS for list of people who contributed to this
# project.
@@ -20,8 +21,6 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
-sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp
+#
-ifndef TEXT_BASE
-TEXT_BASE = 0x04000000
-endif
+sinclude $(SRCTREE)/board/xilinx/ppc440-generic/config.mk
diff --git a/board/xilinx/ml507/init.S b/board/xilinx/ml507/init.S
deleted file mode 100644
index 3228a65..0000000
--- a/board/xilinx/ml507/init.S
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * (C) Copyright 2008
- * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es
- * This work has been supported by: QTechnology http://qtec.com/
- *
- * 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <ppc_asm.tmpl>
-#include <config.h>
-#include <asm-ppc/mmu.h>
-
-.section .bootpg,"ax"
-.globl tlbtab
-
-tlbtab:
-tlbtab_start
- /* SDRAM */
-tlbentry(XPAR_DDR2_SDRAM_MEM_BASEADDR, SZ_256M, CFG_SDRAM_BASE, 0,
- AC_R | AC_W | AC_X | SA_G | SA_I)
- /* UART */
-tlbentry(XPAR_UARTLITE_0_BASEADDR, SZ_64K, XPAR_UARTLITE_0_BASEADDR, 0,
- AC_R | AC_W | SA_G | SA_I)
- /* PIC */
-tlbentry(XPAR_INTC_0_BASEADDR, SZ_64K, XPAR_INTC_0_BASEADDR, 0,
- AC_R | AC_W | SA_G | SA_I)
-#ifdef XPAR_IIC_EEPROM_BASEADDR
- /* I2C */
-tlbentry(XPAR_IIC_EEPROM_BASEADDR, SZ_64K, XPAR_IIC_EEPROM_BASEADDR, 0,
- AC_R | AC_W | SA_G | SA_I)
-#endif
-#ifdef XPAR_LLTEMAC_0_BASEADDR
- /* Net */
-tlbentry(XPAR_LLTEMAC_0_BASEADDR, SZ_64K, XPAR_LLTEMAC_0_BASEADDR, 0,
- AC_R | AC_W | SA_G | SA_I)
-#endif
-#ifdef XPAR_FLASH_MEM0_BASEADDR
- /*Flash*/
-tlbentry(XPAR_FLASH_MEM0_BASEADDR, SZ_256M, XPAR_FLASH_MEM0_BASEADDR, 0,
- AC_R | AC_W | AC_X | SA_G | SA_I)
-#endif
-tlbtab_end
diff --git a/board/xilinx/ml507/ml507.c b/board/xilinx/ml507/ml507.c
index d499303..f9789cf 100644
--- a/board/xilinx/ml507/ml507.c
+++ b/board/xilinx/ml507/ml507.c
@@ -20,28 +20,9 @@
#include <common.h>
#include <asm/processor.h>
-int board_pre_init(void)
-{
- return 0;
-}
int checkboard(void)
{
- puts("ML507 Board\n");
+ puts("Xilinx ML507 Board\n");
return 0;
}
-
-phys_size_t initdram(int board_type)
-{
- return get_ram_size(XPAR_DDR2_SDRAM_MEM_BASEADDR,
- CFG_SDRAM_SIZE_MB * 1024 * 1024);
-}
-
-void get_sys_info(sys_info_t * sysInfo)
-{
- sysInfo->freqProcessor = XPAR_CORE_CLOCK_FREQ_HZ;
- sysInfo->freqPLB = XPAR_PLB_CLOCK_FREQ_HZ;
- sysInfo->freqPCI = 0;
-
- return;
-}
diff --git a/board/xilinx/ml507/xparameters.h b/board/xilinx/ml507/xparameters.h
index 77d2ddf..1992fff 100644
--- a/board/xilinx/ml507/xparameters.h
+++ b/board/xilinx/ml507/xparameters.h
@@ -21,15 +21,14 @@
#ifndef XPARAMETER_H
#define XPARAMETER_H
-#define XPAR_DDR2_SDRAM_MEM_BASEADDR 0x00000000
-#define XPAR_IIC_EEPROM_BASEADDR 0x81600000
-#define XPAR_INTC_0_BASEADDR 0x81800000
-#define XPAR_LLTEMAC_0_BASEADDR 0x81C00000
-#define XPAR_UARTLITE_0_BASEADDR 0x84000000
-#define XPAR_FLASH_MEM0_BASEADDR 0xFE000000
-#define XPAR_PLB_CLOCK_FREQ_HZ 100000000
-#define XPAR_CORE_CLOCK_FREQ_HZ 400000000
-#define XPAR_INTC_MAX_NUM_INTR_INPUTS 13
+#define XPAR_DDR2_SDRAM_MEM_BASEADDR 0x00000000
+#define XPAR_IIC_EEPROM_BASEADDR 0x81600000
+#define XPAR_INTC_0_BASEADDR 0x81800000
+#define XPAR_UARTLITE_0_BASEADDR 0x84000000
+#define XPAR_FLASH_MEM0_BASEADDR 0xFE000000
+#define XPAR_PLB_CLOCK_FREQ_HZ 100000000
+#define XPAR_CORE_CLOCK_FREQ_HZ 400000000
+#define XPAR_INTC_MAX_NUM_INTR_INPUTS 13
#define XPAR_UARTLITE_0_BAUDRATE 9600
#endif
diff --git a/board/xilinx/ppc440-generic/Makefile b/board/xilinx/ppc440-generic/Makefile
new file mode 100644
index 0000000..bf0a6ba
--- /dev/null
+++ b/board/xilinx/ppc440-generic/Makefile
@@ -0,0 +1,62 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# (C) Copyright 2008
+# Ricardo Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es
+# Work supported by Qtechnology http://www.qtec.com
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+endif
+
+INCS :=
+CFLAGS += $(INCS)
+HOST_CFLAGS += $(INCS)
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS += ../../xilinx/ppc440-generic/xilinx_ppc440_generic.o
+
+SOBJS += ../../xilinx/ppc440-generic/init.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(OBJS) $(SOBJS)
+ $(AR) $(ARFLAGS) $@ $^
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/xilinx/ppc440-generic/config.mk b/board/xilinx/ppc440-generic/config.mk
new file mode 100644
index 0000000..8d220da
--- /dev/null
+++ b/board/xilinx/ppc440-generic/config.mk
@@ -0,0 +1,25 @@
+#
+# (C) Copyright 2008
+# Ricardo Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es
+# Work supported by Qtechnology http://www.qtec.com
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+sinclude $(obj)/board/$(BOARDDIR)/config.tmp
diff --git a/board/xilinx/ppc440-generic/init.S b/board/xilinx/ppc440-generic/init.S
new file mode 100644
index 0000000..1409467
--- /dev/null
+++ b/board/xilinx/ppc440-generic/init.S
@@ -0,0 +1,45 @@
+/*
+ * (C) Copyright 2008
+ * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es
+ * This work has been supported by: QTechnology http://qtec.com/
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <ppc_asm.tmpl>
+#include <config.h>
+#include <asm-ppc/mmu.h>
+
+.section .bootpg,"ax"
+.globl tlbtab
+
+tlbtab:
+tlbtab_start
+tlbentry(0x00000000, SZ_256M, 0x00000000, 0, AC_R | AC_W | AC_X | SA_G | SA_I)
+tlbentry(0x10000000, SZ_256M, 0x10000000, 0, AC_R | AC_W | AC_X | SA_G | SA_I)
+tlbentry(0x20000000, SZ_256M, 0x20000000, 0, AC_R | AC_W | AC_X | SA_G | SA_I)
+tlbentry(0x30000000, SZ_256M, 0x30000000, 0, AC_R | AC_W | AC_X | SA_G | SA_I)
+tlbentry(0x40000000, SZ_256M, 0x40000000, 0, AC_R | AC_W | AC_X | SA_G | SA_I)
+tlbentry(0x50000000, SZ_256M, 0x50000000, 0, AC_R | AC_W | AC_X | SA_G | SA_I)
+tlbentry(0x60000000, SZ_256M, 0x60000000, 0, AC_R | AC_W | AC_X | SA_G | SA_I)
+tlbentry(0x70000000, SZ_256M, 0x70000000, 0, AC_R | AC_W | AC_X | SA_G | SA_I)
+tlbentry(0x80000000, SZ_256M, 0x80000000, 0, AC_R | AC_W | AC_X | SA_G | SA_I)
+tlbentry(0x90000000, SZ_256M, 0x90000000, 0, AC_R | AC_W | AC_X | SA_G | SA_I)
+tlbentry(0xa0000000, SZ_256M, 0xa0000000, 0, AC_R | AC_W | AC_X | SA_G | SA_I)
+tlbentry(0xb0000000, SZ_256M, 0xb0000000, 0, AC_R | AC_W | AC_X | SA_G | SA_I)
+tlbentry(0xc0000000, SZ_256M, 0xc0000000, 0, AC_R | AC_W | AC_X | SA_G | SA_I)
+tlbentry(0xd0000000, SZ_256M, 0xd0000000, 0, AC_R | AC_W | AC_X | SA_G | SA_I)
+tlbentry(0xe0000000, SZ_256M, 0xe0000000, 0, AC_R | AC_W | AC_X | SA_G | SA_I)
+tlbentry(0xf0000000, SZ_256M, 0xf0000000, 0, AC_R | AC_W | AC_X | SA_G | SA_I)
+tlbtab_end
diff --git a/board/xilinx/ml507/u-boot-ram.lds b/board/xilinx/ppc440-generic/u-boot-ram.lds
index 2c98d27..2c98d27 100644
--- a/board/xilinx/ml507/u-boot-ram.lds
+++ b/board/xilinx/ppc440-generic/u-boot-ram.lds
diff --git a/board/xilinx/ml507/u-boot-rom.lds b/board/xilinx/ppc440-generic/u-boot-rom.lds
index d5da018..d5da018 100644
--- a/board/xilinx/ml507/u-boot-rom.lds
+++ b/board/xilinx/ppc440-generic/u-boot-rom.lds
diff --git a/board/xilinx/ppc440-generic/xilinx_ppc440_generic.c b/board/xilinx/ppc440-generic/xilinx_ppc440_generic.c
new file mode 100644
index 0000000..0867226
--- /dev/null
+++ b/board/xilinx/ppc440-generic/xilinx_ppc440_generic.c
@@ -0,0 +1,52 @@
+/*
+ * (C) Copyright 2008
+ * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es
+ * This work has been supported by: QTechnology http://qtec.com/
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <config.h>
+#include <common.h>
+#include <asm/processor.h>
+
+int __board_pre_init(void)
+{
+ return 0;
+}
+int board_pre_init(void) __attribute__((weak, alias("__board_pre_init")));
+
+int __checkboard(void)
+{
+ puts("Xilinx PPC440 Generic Board\n");
+ return 0;
+}
+int checkboard(void) __attribute__((weak, alias("__checkboard")));
+
+phys_size_t __initdram(int board_type)
+{
+ return get_ram_size(XPAR_DDR2_SDRAM_MEM_BASEADDR,
+ CFG_SDRAM_SIZE_MB * 1024 * 1024);
+}
+phys_size_t initdram(int) __attribute__((weak, alias("__initdram")));
+
+void __get_sys_info(sys_info_t *sysInfo)
+{
+ sysInfo->freqProcessor = XPAR_CORE_CLOCK_FREQ_HZ;
+ sysInfo->freqPLB = XPAR_PLB_CLOCK_FREQ_HZ;
+ sysInfo->freqPCI = 0;
+
+ return;
+}
+void get_sys_info(sys_info_t *) __attribute__((weak, alias("__get_sys_info")));
diff --git a/board/xilinx/ppc440-generic/xparameters.h b/board/xilinx/ppc440-generic/xparameters.h
new file mode 100644
index 0000000..1992fff
--- /dev/null
+++ b/board/xilinx/ppc440-generic/xparameters.h
@@ -0,0 +1,34 @@
+/*
+ * (C) Copyright 2008
+ * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es
+ * This work has been supported by: QTechnology http://qtec.com/
+ * based on xparameters-ml507.h by Xilinx
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef XPARAMETER_H
+#define XPARAMETER_H
+
+#define XPAR_DDR2_SDRAM_MEM_BASEADDR 0x00000000
+#define XPAR_IIC_EEPROM_BASEADDR 0x81600000
+#define XPAR_INTC_0_BASEADDR 0x81800000
+#define XPAR_UARTLITE_0_BASEADDR 0x84000000
+#define XPAR_FLASH_MEM0_BASEADDR 0xFE000000
+#define XPAR_PLB_CLOCK_FREQ_HZ 100000000
+#define XPAR_CORE_CLOCK_FREQ_HZ 400000000
+#define XPAR_INTC_MAX_NUM_INTR_INPUTS 13
+#define XPAR_UARTLITE_0_BAUDRATE 9600
+
+#endif
diff --git a/common/Makefile b/common/Makefile
index 0fe9c8b..8d4a426 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -56,7 +56,8 @@ COBJS-y += env_nowhere.o
# command
COBJS-$(CONFIG_CMD_AMBAPP) += cmd_ambapp.o
-COBJS-$(CONFIG_AUTOSCRIPT)$(CONFIG_CMD_AUTOSCRIPT) += cmd_autoscript.o
+COBJS-$(CONFIG_AUTOSCRIPT) += cmd_autoscript.o
+COBJS-$(CONFIG_CMD_AUTOSCRIPT) += cmd_autoscript.o
COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
COBJS-$(CONFIG_CMD_BEDBUG) += bedbug.o cmd_bedbug.o
COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o
@@ -110,7 +111,8 @@ COBJS-$(CONFIG_LOGBUFFER) += cmd_log.o
COBJS-y += cmd_mac.o
COBJS-y += cmd_mem.o
COBJS-$(CONFIG_CMD_MFSL) += cmd_mfsl.o
-COBJS-$(CONFIG_MII)$(CONFIG_CMD_MII) += miiphyutil.o
+COBJS-$(CONFIG_MII) += miiphyutil.o
+COBJS-$(CONFIG_CMD_MII) += miiphyutil.o
COBJS-$(CONFIG_CMD_MII) += cmd_mii.o
COBJS-$(CONFIG_CMD_MISC) += cmd_misc.o
COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o
@@ -151,8 +153,7 @@ COBJS-$(CONFIG_LYNXKDI) += lynxkdi.o
COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o
-COBJS-y += $(COBJS-yy)
-COBJS := $(COBJS-y)
+COBJS := $(sort $(COBJS-y))
SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS))
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 751f5b9..861712b 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -108,8 +108,8 @@ 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_fn do_bootm_artos;
+#if defined(CONFIG_INTEGRITY)
+static boot_os_fn do_bootm_integrity;
#endif
ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */
@@ -337,13 +337,13 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
return BOOTM_ERR_UNIMPLEMENTED;
}
puts ("OK\n");
- debug (" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, load_end);
+ debug (" kernel loaded at 0x%08lx, end = 0x%8p\n", load, load_end);
if (boot_progress)
show_boot_progress (7);
if ((load < blob_end) && (*load_end > blob_start)) {
debug ("images.os.start = 0x%lX, images.os.end = 0x%lx\n", blob_start, blob_end);
- debug ("images.os.load = 0x%lx, load_end = 0x%lx\n", load, load_end);
+ debug ("images.os.load = 0x%lx, load_end = 0x%p\n", load, load_end);
return BOOTM_ERR_OVERLAP;
}
@@ -455,9 +455,9 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
break;
#endif
-#ifdef CONFIG_ARTOS
- case IH_OS_ARTOS:
- do_bootm_artos (0, argc, argv, &images);
+#ifdef CONFIG_INTEGRITY
+ case IH_OS_INTEGRITY:
+ do_bootm_integrity (0, argc, argv, &images);
break;
#endif
}
@@ -854,6 +854,12 @@ static int image_info (ulong addr)
}
fit_print_contents (hdr);
+
+ if (!fit_all_image_check_hashes (hdr)) {
+ puts ("Bad hash in FIT image!\n");
+ return 1;
+ }
+
return 0;
#endif
default:
@@ -1153,92 +1159,31 @@ static int do_bootm_qnxelf(int flag, int argc, char *argv[],
}
#endif
-#if defined(CONFIG_ARTOS) && defined(CONFIG_PPC)
-static int do_bootm_artos (int flag, int argc, char *argv[],
+#ifdef CONFIG_INTEGRITY
+static int do_bootm_integrity (int flag, int argc, char *argv[],
bootm_headers_t *images)
{
- ulong top;
- char *s, *cmdline;
- char **fwenv, **ss;
- int i, j, nxt, len, envno, envsz;
- bd_t *kbd;
- void (*entry)(bd_t *bd, char *cmdline, char **fwenv, ulong top);
+ void (*entry_point)(void);
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
- fit_unsupported_reset ("ARTOS");
+ fit_unsupported_reset ("INTEGRITY");
return 1;
}
#endif
- /*
- * Booting an ARTOS kernel image + application
- */
+ entry_point = (void (*)(void))images->ep;
- /* this used to be the top of memory, but was wrong... */
-#ifdef CONFIG_PPC
- /* get stack pointer */
- asm volatile ("mr %0,1" : "=r"(top) );
-#endif
- debug ("## Current stack ends at 0x%08lX ", top);
-
- top -= 2048; /* just to be sure */
- if (top > CFG_BOOTMAPSZ)
- top = CFG_BOOTMAPSZ;
- top &= ~0xF;
-
- 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)
- s = "";
-
- /* get length of cmdline, and place it */
- len = strlen (s);
- top = (top - (len + 1)) & ~0xF;
- cmdline = (char *)top;
- debug ("## cmdline at 0x%08lX ", top);
- strcpy (cmdline, s);
-
- /* copy bdinfo */
- top = (top - sizeof (bd_t)) & ~0xF;
- debug ("## bd at 0x%08lX ", top);
- kbd = (bd_t *)top;
- 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)
- ;
- envno++;
- envsz += (nxt - i) + 1; /* plus trailing zero */
- }
- envno++; /* plus the terminating zero */
- debug ("## %u envvars total size %u ", envno, envsz);
-
- top = (top - sizeof (char **) * envno) & ~0xF;
- fwenv = (char **)top;
- debug ("## fwenv at 0x%08lX ", top);
-
- top = (top - envsz) & ~0xF;
- s = (char *)top;
- 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)
- ;
- *ss++ = s;
- for (j = i; j < nxt; ++j)
- *s++ = env_get_char (j);
- *s++ = '\0';
- }
- *ss++ = NULL; /* terminate */
+ printf ("## Transferring control to INTEGRITY (at address %08lx) ...\n",
+ (ulong)entry_point);
- entry = (void (*)(bd_t *, char *, char **, ulong))images->ep;
- (*entry) (kbd, cmdline, fwenv, top);
+ show_boot_progress (15);
+
+ /*
+ * INTEGRITY Parameters:
+ * None
+ */
+ (*entry_point)();
return 1;
}
diff --git a/common/image.c b/common/image.c
index 94f01ad..f7e8606 100644
--- a/common/image.c
+++ b/common/image.c
@@ -105,9 +105,6 @@ static table_entry_t uimage_arch[] = {
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", },
@@ -119,6 +116,9 @@ static table_entry_t uimage_os[] = {
{ IH_OS_QNX, "qnx", "QNX", },
{ IH_OS_VXWORKS, "vxworks", "VxWorks", },
#endif
+#if defined(CONFIG_INTEGRITY) || defined(USE_HOSTCC)
+ { IH_OS_INTEGRITY,"integrity", "INTEGRITY", },
+#endif
#ifdef USE_HOSTCC
{ IH_OS_4_4BSD, "4_4bsd", "4_4BSD", },
{ IH_OS_DELL, "dell", "Dell", },
@@ -2645,27 +2645,29 @@ int fit_image_check_hashes (const void *fit, int image_noffset)
continue;
if (fit_image_hash_get_algo (fit, noffset, &algo)) {
- err_msg = "Can't get hash algo property";
+ err_msg = " error!\nCan'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";
+ err_msg = " error!\nCan't get hash value "
+ "property";
goto error;
}
if (calculate_hash (data, size, algo, value, &value_len)) {
- err_msg = "Unsupported hash algorithm";
+ err_msg = " error!\nUnsupported hash algorithm";
goto error;
}
if (value_len != fit_value_len) {
- err_msg = "Bad hash value len";
+ err_msg = " error !\nBad hash value len";
goto error;
} else if (memcmp (value, fit_value, value_len) != 0) {
- err_msg = "Bad hash value";
+ err_msg = " error!\nBad hash value";
goto error;
}
printf ("+ ");
@@ -2682,6 +2684,55 @@ error:
}
/**
+ * fit_all_image_check_hashes - verify data intergity for all images
+ * @fit: pointer to the FIT format image header
+ *
+ * fit_all_image_check_hashes() goes over all images in the FIT and
+ * for every images checks if all it's hashes are valid.
+ *
+ * returns:
+ * 1, if all hashes of all images are valid
+ * 0, otherwise (or on error)
+ */
+int fit_all_image_check_hashes (const void *fit)
+{
+ int images_noffset;
+ int noffset;
+ int ndepth;
+ int count;
+
+ /* 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 0;
+ }
+
+ /* Process all image subnodes, check hashes for each */
+ printf ("## Checking hash(es) for FIT Image at %08lx ...\n",
+ (ulong)fit);
+ 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 (" Hash(es) for Image %u (%s): ", count++,
+ fit_get_name (fit, noffset, NULL));
+
+ if (!fit_image_check_hashes (fit, noffset))
+ return 0;
+ printf ("\n");
+ }
+ }
+ return 1;
+}
+
+/**
* 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
diff --git a/common/usb.c b/common/usb.c
index 9502f39..52e5964 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -126,10 +126,15 @@ int usb_init(void)
*/
int usb_stop(void)
{
- asynch_allowed=1;
- usb_started = 0;
- usb_hub_reset();
- return usb_lowlevel_stop();
+ int res = 0;
+
+ if (usb_started) {
+ asynch_allowed = 1;
+ usb_started = 0;
+ usb_hub_reset();
+ res = usb_lowlevel_stop();
+ }
+ return res;
}
/*
diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index 108bd60..920bb0f 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -162,6 +162,8 @@ int drv_usb_kbd_init(void)
/* scan all USB Devices */
for(i=0;i<USB_MAX_DEVICE;i++) {
dev=usb_get_dev_index(i); /* get device */
+ if(dev == NULL)
+ return -1;
if(dev->devnum!=-1) {
if(usb_kbd_probe(dev,0)==1) { /* Ok, we found a keyboard */
/* check, if it is already registered */
diff --git a/cpu/arm1176/s3c64xx/interrupts.c b/cpu/arm1176/s3c64xx/interrupts.c
index 8356ae4..e34369f 100644
--- a/cpu/arm1176/s3c64xx/interrupts.c
+++ b/cpu/arm1176/s3c64xx/interrupts.c
@@ -41,6 +41,7 @@
#include <common.h>
#include <asm/proc-armv/ptrace.h>
#include <s3c6400.h>
+#include <div64.h>
static ulong timer_load_val;
@@ -148,7 +149,9 @@ void reset_timer(void)
ulong get_timer_masked(void)
{
- return get_ticks() / (timer_load_val / (100 * CFG_HZ));
+ unsigned long long res = get_ticks();
+ do_div (res, (timer_load_val / (100 * CFG_HZ)));
+ return res;
}
ulong get_timer(ulong base)
diff --git a/cpu/arm946es/config.mk b/cpu/arm946es/config.mk
index 81ca288..f774c7e 100644
--- a/cpu/arm946es/config.mk
+++ b/cpu/arm946es/config.mk
@@ -25,3 +25,10 @@ PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
-msoft-float
PLATFORM_CPPFLAGS += -march=armv4
+# =========================================================================
+#
+# Supply options according to compiler version
+#
+# =========================================================================
+PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
+PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm_intcm/config.mk b/cpu/arm_intcm/config.mk
index 81ca288..f774c7e 100644
--- a/cpu/arm_intcm/config.mk
+++ b/cpu/arm_intcm/config.mk
@@ -25,3 +25,10 @@ PLATFORM_RELFLAGS += -fno-strict-aliasing -fno-common -ffixed-r8 \
-msoft-float
PLATFORM_CPPFLAGS += -march=armv4
+# =========================================================================
+#
+# Supply options according to compiler version
+#
+# =========================================================================
+PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
+PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c
index 15250d4..f1d7684 100644
--- a/cpu/ppc4xx/44x_spd_ddr2.c
+++ b/cpu/ppc4xx/44x_spd_ddr2.c
@@ -60,8 +60,6 @@
"SDRAM_" #mnemonic, SDRAM_##mnemonic, data); \
} while (0)
-static inline void ppc4xx_ibm_ddr2_register_dump(void);
-
#if defined(CONFIG_SPD_EEPROM)
/*-----------------------------------------------------------------------------+
@@ -260,62 +258,19 @@ static void program_ecc_addr(unsigned long start_address,
unsigned long num_bytes,
unsigned long tlb_word2_i_value);
#endif
+#if !defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
static void program_DQS_calibration(unsigned long *dimm_populated,
- unsigned char *iic0_dimm_addr,
- unsigned long num_dimm_banks);
+ unsigned char *iic0_dimm_addr,
+ unsigned long num_dimm_banks);
#ifdef HARD_CODED_DQS /* calibration test with hardvalues */
static void test(void);
#else
static void DQS_calibration_process(void);
#endif
+#endif
int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
void dcbz_area(u32 start_address, u32 num_bytes);
-static u32 mfdcr_any(u32 dcr)
-{
- u32 val;
-
- switch (dcr) {
- case SDRAM_R0BAS + 0:
- val = mfdcr(SDRAM_R0BAS + 0);
- break;
- case SDRAM_R0BAS + 1:
- val = mfdcr(SDRAM_R0BAS + 1);
- break;
- case SDRAM_R0BAS + 2:
- val = mfdcr(SDRAM_R0BAS + 2);
- break;
- case SDRAM_R0BAS + 3:
- val = mfdcr(SDRAM_R0BAS + 3);
- break;
- default:
- printf("DCR %d not defined in case statement!!!\n", dcr);
- val = 0; /* just to satisfy the compiler */
- }
-
- return val;
-}
-
-static void mtdcr_any(u32 dcr, u32 val)
-{
- switch (dcr) {
- case SDRAM_R0BAS + 0:
- mtdcr(SDRAM_R0BAS + 0, val);
- break;
- case SDRAM_R0BAS + 1:
- mtdcr(SDRAM_R0BAS + 1, val);
- break;
- case SDRAM_R0BAS + 2:
- mtdcr(SDRAM_R0BAS + 2, val);
- break;
- case SDRAM_R0BAS + 3:
- mtdcr(SDRAM_R0BAS + 3, val);
- break;
- default:
- printf("DCR %d not defined in case statement!!!\n", dcr);
- }
-}
-
static unsigned char spd_read(uchar chip, uint addr)
{
unsigned char data[2];
@@ -609,7 +564,11 @@ phys_size_t initdram(int board_type)
/*------------------------------------------------------------------
* DQS calibration.
*-----------------------------------------------------------------*/
+#if defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
+ DQS_autocalibration();
+#else
program_DQS_calibration(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+#endif
#ifdef CONFIG_DDR_ECC
/*------------------------------------------------------------------
@@ -2329,18 +2288,6 @@ static unsigned long is_ecc_enabled(void)
return ecc;
}
-static void blank_string(int size)
-{
- int i;
-
- for (i=0; i<size; i++)
- putc('\b');
- for (i=0; i<size; i++)
- putc(' ');
- for (i=0; i<size; i++)
- putc('\b');
-}
-
#ifdef CONFIG_DDR_ECC
/*-----------------------------------------------------------------------------+
* program_ecc.
@@ -2468,6 +2415,7 @@ static void program_ecc_addr(unsigned long start_address,
}
#endif
+#if !defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
/*-----------------------------------------------------------------------------+
* program_DQS_calibration.
*-----------------------------------------------------------------------------*/
@@ -3001,7 +2949,8 @@ static void test(void)
(ppcMfdcr_sdram(SDRAM_MCOPT1) & ~SDRAM_MCOPT1_MCHK_MASK)
| ecc_temp);
}
-#endif
+#endif /* !HARD_CODED_DQS */
+#endif /* !defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION) */
#else /* CONFIG_SPD_EEPROM */
@@ -3104,9 +3053,12 @@ phys_size_t initdram(int board_type)
/* Set Delay Control Registers */
mtsdram(SDRAM_DLCR, CFG_SDRAM0_DLCR);
+
+#if !defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
mtsdram(SDRAM_RDCC, CFG_SDRAM0_RDCC);
mtsdram(SDRAM_RQDC, CFG_SDRAM0_RQDC);
mtsdram(SDRAM_RFDC, CFG_SDRAM0_RFDC);
+#endif /* !CONFIG_PPC4xx_DDR_AUTOCALIBRATION */
/*
* Enable Controller by SDRAM0_MCOPT2[DCEN] = 1:
@@ -3115,18 +3067,98 @@ phys_size_t initdram(int board_type)
mfsdram(SDRAM_MCOPT2, val);
mtsdram(SDRAM_MCOPT2, val | SDRAM_MCOPT2_DCEN_ENABLE);
+#if defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
+#if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
+ /*------------------------------------------------------------------
+ | DQS calibration.
+ +-----------------------------------------------------------------*/
+ DQS_autocalibration();
+#endif /* !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) */
+#endif /* CONFIG_PPC4xx_DDR_AUTOCALIBRATION */
+
#if defined(CONFIG_DDR_ECC)
ecc_init(CFG_SDRAM_BASE, CFG_MBYTES_SDRAM << 20);
#endif /* defined(CONFIG_DDR_ECC) */
ppc4xx_ibm_ddr2_register_dump();
+
+#if defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
+ /*
+ * Clear potential errors resulting from auto-calibration.
+ * If not done, then we could get an interrupt later on when
+ * exceptions are enabled.
+ */
+ set_mcsr(get_mcsr());
+#endif /* CONFIG_PPC4xx_DDR_AUTOCALIBRATION */
+
#endif /* !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) */
return (CFG_MBYTES_SDRAM << 20);
}
#endif /* CONFIG_SPD_EEPROM */
-static inline void ppc4xx_ibm_ddr2_register_dump(void)
+#if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
+#if defined(CONFIG_440)
+u32 mfdcr_any(u32 dcr)
+{
+ u32 val;
+
+ switch (dcr) {
+ case SDRAM_R0BAS + 0:
+ val = mfdcr(SDRAM_R0BAS + 0);
+ break;
+ case SDRAM_R0BAS + 1:
+ val = mfdcr(SDRAM_R0BAS + 1);
+ break;
+ case SDRAM_R0BAS + 2:
+ val = mfdcr(SDRAM_R0BAS + 2);
+ break;
+ case SDRAM_R0BAS + 3:
+ val = mfdcr(SDRAM_R0BAS + 3);
+ break;
+ default:
+ printf("DCR %d not defined in case statement!!!\n", dcr);
+ val = 0; /* just to satisfy the compiler */
+ }
+
+ return val;
+}
+
+void mtdcr_any(u32 dcr, u32 val)
+{
+ switch (dcr) {
+ case SDRAM_R0BAS + 0:
+ mtdcr(SDRAM_R0BAS + 0, val);
+ break;
+ case SDRAM_R0BAS + 1:
+ mtdcr(SDRAM_R0BAS + 1, val);
+ break;
+ case SDRAM_R0BAS + 2:
+ mtdcr(SDRAM_R0BAS + 2, val);
+ break;
+ case SDRAM_R0BAS + 3:
+ mtdcr(SDRAM_R0BAS + 3, val);
+ break;
+ default:
+ printf("DCR %d not defined in case statement!!!\n", dcr);
+ }
+}
+#endif /* defined(CONFIG_440) */
+
+void blank_string(int size)
+{
+ int i;
+
+ for (i = 0; i < size; i++)
+ putc('\b');
+ for (i = 0; i < size; i++)
+ putc(' ');
+ for (i = 0; i < size; i++)
+ putc('\b');
+}
+#endif /* !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) */
+
+inline void ppc4xx_ibm_ddr2_register_dump(void)
{
#if defined(DEBUG)
printf("\nPPC4xx IBM DDR2 Register Dump:\n");
diff --git a/cpu/ppc4xx/4xx_enet.c b/cpu/ppc4xx/4xx_enet.c
index 8a38335..6d4d043 100644
--- a/cpu/ppc4xx/4xx_enet.c
+++ b/cpu/ppc4xx/4xx_enet.c
@@ -198,6 +198,7 @@
#define BI_PHYMODE_RMII 8
#endif
#endif
+#define BI_PHYMODE_SGMII 9
#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
@@ -216,6 +217,52 @@
#define MAL_RX_CHAN_MUL 1
#endif
+/*--------------------------------------------------------------------+
+ * Fixed PHY (PHY-less) support for Ethernet Ports.
+ *--------------------------------------------------------------------*/
+
+/*
+ * Some boards do not have a PHY for each ethernet port. These ports
+ * are known as Fixed PHY (or PHY-less) ports. For such ports, set
+ * the appropriate CONFIG_PHY_ADDR equal to CONFIG_FIXED_PHY and
+ * then define CFG_FIXED_PHY_PORTS to define what the speed and
+ * duplex should be for these ports in the board configuration
+ * file.
+ *
+ * For Example:
+ * #define CONFIG_FIXED_PHY 0xFFFFFFFF
+ *
+ * #define CONFIG_PHY_ADDR CONFIG_FIXED_PHY
+ * #define CONFIG_PHY1_ADDR 1
+ * #define CONFIG_PHY2_ADDR CONFIG_FIXED_PHY
+ * #define CONFIG_PHY3_ADDR 3
+ *
+ * #define CFG_FIXED_PHY_PORT(devnum,speed,duplex) \
+ * {devnum, speed, duplex},
+ *
+ * #define CFG_FIXED_PHY_PORTS \
+ * CFG_FIXED_PHY_PORT(0,1000,FULL) \
+ * CFG_FIXED_PHY_PORT(2,100,HALF)
+ */
+
+#ifndef CONFIG_FIXED_PHY
+#define CONFIG_FIXED_PHY 0xFFFFFFFF /* Fixed PHY (PHY-less) */
+#endif
+
+#ifndef CFG_FIXED_PHY_PORTS
+#define CFG_FIXED_PHY_PORTS /* default is an empty array */
+#endif
+
+struct fixed_phy_port {
+ unsigned int devnum; /* ethernet port */
+ unsigned int speed; /* specified speed 10,100 or 1000 */
+ unsigned int duplex; /* specified duplex FULL or HALF */
+};
+
+static const struct fixed_phy_port fixed_phy_port[] = {
+ CFG_FIXED_PHY_PORTS /* defined in board configuration file */
+};
+
/*-----------------------------------------------------------------------------+
* Global variables. TX and RX descriptors and buffers.
*-----------------------------------------------------------------------------*/
@@ -611,8 +658,17 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
#if defined(CONFIG_460EX)
mode = 9;
+ mfsdr(SDR0_ETH_CFG, eth_cfg);
+ if (((eth_cfg & SDR0_ETH_CFG_SGMII0_ENABLE) > 0) &&
+ ((eth_cfg & SDR0_ETH_CFG_SGMII1_ENABLE) > 0))
+ mode = 11; /* config SGMII */
#else
mode = 10;
+ mfsdr(SDR0_ETH_CFG, eth_cfg);
+ if (((eth_cfg & SDR0_ETH_CFG_SGMII0_ENABLE) > 0) &&
+ ((eth_cfg & SDR0_ETH_CFG_SGMII1_ENABLE) > 0) &&
+ ((eth_cfg & SDR0_ETH_CFG_SGMII2_ENABLE) > 0))
+ mode = 12; /* config SGMII */
#endif
/* TODO:
@@ -635,6 +691,8 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
/*
* Right now only 2*RGMII is supported. Please extend when needed.
* sr - 2008-02-19
+ * Add SGMII support.
+ * vg - 2008-07-28
*/
switch (mode) {
case 1:
@@ -761,6 +819,20 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
bis->bi_phymode[2] = BI_PHYMODE_RGMII;
bis->bi_phymode[3] = BI_PHYMODE_RGMII;
break;
+ case 11:
+ /* 2 SGMII - 460EX */
+ bis->bi_phymode[0] = BI_PHYMODE_SGMII;
+ bis->bi_phymode[1] = BI_PHYMODE_SGMII;
+ bis->bi_phymode[2] = BI_PHYMODE_NONE;
+ bis->bi_phymode[3] = BI_PHYMODE_NONE;
+ break;
+ case 12:
+ /* 3 SGMII - 460GT */
+ bis->bi_phymode[0] = BI_PHYMODE_SGMII;
+ bis->bi_phymode[1] = BI_PHYMODE_SGMII;
+ bis->bi_phymode[2] = BI_PHYMODE_SGMII;
+ bis->bi_phymode[3] = BI_PHYMODE_NONE;
+ break;
default:
break;
}
@@ -945,9 +1017,50 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
out_be32((void *)EMAC_M1 + hw_p->hw_addr, mode_reg);
#endif /* defined(CONFIG_440GX) || defined(CONFIG_440SP) */
+#if defined(CONFIG_GPCS_PHY_ADDR) || defined(CONFIG_GPCS_PHY1_ADDR) || \
+ defined(CONFIG_GPCS_PHY2_ADDR) || defined(CONFIG_GPCS_PHY3_ADDR)
+ if (bis->bi_phymode[devnum] == BI_PHYMODE_SGMII) {
+ /*
+ * In SGMII mode, GPCS access is needed for
+ * communication with the internal SGMII SerDes.
+ */
+ switch (devnum) {
+#if defined(CONFIG_GPCS_PHY_ADDR)
+ case 0:
+ reg = CONFIG_GPCS_PHY_ADDR;
+ break;
+#endif
+#if defined(CONFIG_GPCS_PHY1_ADDR)
+ case 1:
+ reg = CONFIG_GPCS_PHY1_ADDR;
+ break;
+#endif
+#if defined(CONFIG_GPCS_PHY2_ADDR)
+ case 2:
+ reg = CONFIG_GPCS_PHY2_ADDR;
+ break;
+#endif
+#if defined(CONFIG_GPCS_PHY3_ADDR)
+ case 3:
+ reg = CONFIG_GPCS_PHY3_ADDR;
+ break;
+#endif
+ }
+
+ mode_reg = in_be32((void *)EMAC_M1 + hw_p->hw_addr);
+ mode_reg |= EMAC_M1_MF_1000GPCS | EMAC_M1_IPPA_SET(reg);
+ out_be32((void *)EMAC_M1 + hw_p->hw_addr, mode_reg);
+
+ /* Configure GPCS interface to recommended setting for SGMII */
+ miiphy_reset(dev->name, reg);
+ miiphy_write(dev->name, reg, 0x04, 0x8120); /* AsymPause, FDX */
+ miiphy_write(dev->name, reg, 0x07, 0x2801); /* msg_pg, toggle */
+ miiphy_write(dev->name, reg, 0x00, 0x0140); /* 1Gbps, FDX */
+ }
+#endif /* defined(CONFIG_GPCS_PHY_ADDR) */
+
/* wait for PHY to complete auto negotiation */
reg_short = 0;
-#ifndef CONFIG_CS8952_PHY
switch (devnum) {
case 0:
reg = CONFIG_PHY_ADDR;
@@ -974,6 +1087,9 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
bis->bi_phynum[devnum] = reg;
+ if (reg == CONFIG_FIXED_PHY)
+ goto get_speed;
+
#if defined(CONFIG_PHY_RESET)
/*
* Reset the phy, only if its the first time through
@@ -986,6 +1102,27 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
miiphy_write (dev->name, reg, 0x09, 0x0e00);
miiphy_write (dev->name, reg, 0x04, 0x01e1);
#endif
+#if defined(CONFIG_M88E1112_PHY)
+ if (bis->bi_phymode[devnum] == BI_PHYMODE_SGMII) {
+ /*
+ * Marvell 88E1112 PHY needs to have the SGMII MAC
+ * interace (page 2) properly configured to
+ * communicate with the 460EX/GT GPCS interface.
+ */
+
+ /* Set access to Page 2 */
+ miiphy_write(dev->name, reg, 0x16, 0x0002);
+
+ miiphy_write(dev->name, reg, 0x00, 0x0040); /* 1Gbps */
+ miiphy_read(dev->name, reg, 0x1a, &reg_short);
+ reg_short |= 0x8000; /* bypass Auto-Negotiation */
+ miiphy_write(dev->name, reg, 0x1a, reg_short);
+ miiphy_reset(dev->name, reg); /* reset MAC interface */
+
+ /* Reset access to Page 0 */
+ miiphy_write(dev->name, reg, 0x16, 0x0000);
+ }
+#endif /* defined(CONFIG_M88E1112_PHY) */
miiphy_reset (dev->name, reg);
#if defined(CONFIG_440GX) || \
@@ -1022,7 +1159,7 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
miiphy_write (dev->name, reg, 0x1f, 0x0000);
/* end Vitesse/Cicada errata */
}
-#endif
+#endif /* defined(CONFIG_CIS8201_PHY) */
#if defined(CONFIG_ET1011C_PHY)
/*
@@ -1041,9 +1178,9 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
miiphy_write(dev->name, reg, 0x1c, 0x74f0);
}
-#endif
+#endif /* defined(CONFIG_ET1011C_PHY) */
-#endif
+#endif /* defined(CONFIG_440GX) ... */
/* Start/Restart autonegotiation */
phy_setup_aneg (dev->name, reg);
udelay (1000);
@@ -1073,15 +1210,30 @@ static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
}
udelay (1000); /* 1 ms */
miiphy_read (dev->name, reg, PHY_BMSR, &reg_short);
-
}
puts (" done\n");
udelay (500000); /* another 500 ms (results in faster booting) */
}
-#endif /* #ifndef CONFIG_CS8952_PHY */
- speed = miiphy_speed (dev->name, reg);
- duplex = miiphy_duplex (dev->name, reg);
+get_speed:
+ if (reg == CONFIG_FIXED_PHY) {
+ for (i = 0; i < ARRAY_SIZE(fixed_phy_port); i++) {
+ if (devnum == fixed_phy_port[i].devnum) {
+ speed = fixed_phy_port[i].speed;
+ duplex = fixed_phy_port[i].duplex;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(fixed_phy_port)) {
+ printf("ERROR: PHY (%s) not configured correctly!\n",
+ dev->name);
+ return -1;
+ }
+ } else {
+ speed = miiphy_speed(dev->name, reg);
+ duplex = miiphy_duplex(dev->name, reg);
+ }
if (hw_p->print_speed) {
hw_p->print_speed = 0;
diff --git a/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c b/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c
new file mode 100644
index 0000000..83b9883
--- /dev/null
+++ b/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c
@@ -0,0 +1,1212 @@
+/*
+ * cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c
+ * This SPD SDRAM detection code supports AMCC PPC44x cpu's with a
+ * DDR2 controller (non Denali Core). Those currently are:
+ *
+ * 405: 405EX
+ * 440/460: 440SP/440SPe/460EX/460GT/460SX
+ *
+ * (C) Copyright 2008 Applied Micro Circuits Corporation
+ * Adam Graham <agraham@amcc.com>
+ *
+ * (C) Copyright 2007-2008
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * COPYRIGHT AMCC CORPORATION 2004
+ *
+ * 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
+ *
+ */
+
+/* define DEBUG for debugging output (obviously ;-)) */
+#undef DEBUG
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+
+#if defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
+
+/*
+ * Only compile the DDR auto-calibration code for NOR boot and
+ * not for NAND boot (NAND SPL and NAND U-Boot - NUB)
+ */
+#if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
+
+#define MAXBXCF 4
+#define SDRAM_RXBAS_SHIFT_1M 20
+
+#if defined(CFG_DECREMENT_PATTERNS)
+#define NUMMEMTESTS 24
+#else
+#define NUMMEMTESTS 8
+#endif /* CFG_DECREMENT_PATTERNS */
+#define NUMLOOPS 1 /* configure as you deem approporiate */
+#define NUMMEMWORDS 16
+
+/* Private Structure Definitions */
+
+struct autocal_regs {
+ u32 rffd;
+ u32 rqfd;
+};
+
+struct ddrautocal {
+ u32 rffd;
+ u32 rffd_min;
+ u32 rffd_max;
+ u32 rffd_size;
+ u32 rqfd;
+ u32 rqfd_size;
+ u32 rdcc;
+ u32 flags;
+};
+
+struct sdram_timing {
+ u32 wrdtr;
+ u32 clktr;
+};
+
+struct sdram_timing_clks {
+ u32 wrdtr;
+ u32 clktr;
+ u32 rdcc;
+ u32 flags;
+};
+
+struct autocal_clks {
+ struct sdram_timing_clks clocks;
+ struct ddrautocal autocal;
+};
+
+/*--------------------------------------------------------------------------+
+ * Prototypes
+ *--------------------------------------------------------------------------*/
+#if defined(CONFIG_PPC4xx_DDR_METHOD_A)
+static u32 DQS_calibration_methodA(struct ddrautocal *);
+static u32 program_DQS_calibration_methodA(struct ddrautocal *);
+#else
+static u32 DQS_calibration_methodB(struct ddrautocal *);
+static u32 program_DQS_calibration_methodB(struct ddrautocal *);
+#endif
+static int short_mem_test(u32 *);
+
+/*
+ * To provide an interface for board specific config values in this common
+ * DDR setup code, we implement he "weak" default functions here. They return
+ * the default value back to the caller.
+ *
+ * Please see include/configs/yucca.h for an example fora board specific
+ * implementation.
+ */
+
+#if !defined(CONFIG_SPD_EEPROM)
+u32 __ddr_wrdtr(u32 default_val)
+{
+ return default_val;
+}
+u32 ddr_wrdtr(u32) __attribute__((weak, alias("__ddr_wrdtr")));
+
+u32 __ddr_clktr(u32 default_val)
+{
+ return default_val;
+}
+u32 ddr_clktr(u32) __attribute__((weak, alias("__ddr_clktr")));
+
+/*
+ * Board-specific Platform code can reimplement spd_ddr_init_hang () if needed
+ */
+void __spd_ddr_init_hang(void)
+{
+ hang();
+}
+void
+spd_ddr_init_hang(void) __attribute__((weak, alias("__spd_ddr_init_hang")));
+#endif /* defined(CONFIG_SPD_EEPROM) */
+
+ulong __ddr_scan_option(ulong default_val)
+{
+ return default_val;
+}
+ulong ddr_scan_option(ulong) __attribute__((weak, alias("__ddr_scan_option")));
+
+static u32 *get_membase(int bxcr_num)
+{
+ ulong bxcf;
+ u32 *membase;
+
+#if defined(SDRAM_R0BAS)
+ /* BAS from Memory Queue rank reg. */
+ membase =
+ (u32 *)(SDRAM_RXBAS_SDBA_DECODE(mfdcr_any(SDRAM_R0BAS+bxcr_num)));
+ bxcf = 0; /* just to satisfy the compiler */
+#else
+ /* BAS from SDRAM_MBxCF mem rank reg. */
+ mfsdram(SDRAM_MB0CF + (bxcr_num<<2), bxcf);
+ membase = (u32 *)((bxcf & 0xfff80000) << 3);
+#endif
+
+ return membase;
+}
+
+static inline void ecc_clear_status_reg(void)
+{
+ mtsdram(SDRAM_ECCCR, 0xffffffff);
+#if defined(SDRAM_R0BAS)
+ mtdcr(SDRAM_ERRSTATLL, 0xffffffff);
+#endif
+}
+
+static int ecc_check_status_reg(void)
+{
+ u32 ecc_status;
+
+ /*
+ * Compare suceeded, now check
+ * if got ecc error. If got an
+ * ecc error, then don't count
+ * this as a passing value
+ */
+ mfsdram(SDRAM_ECCCR, ecc_status);
+ if (ecc_status != 0x00000000) {
+ /* clear on error */
+ ecc_clear_status_reg();
+ /* ecc check failure */
+ return 0;
+ }
+ ecc_clear_status_reg();
+ sync();
+
+ return 1;
+}
+
+/* return 1 if passes, 0 if fail */
+static int short_mem_test(u32 *base_address)
+{
+ int i, j, l;
+ u32 ecc_mode = 0;
+
+ ulong test[NUMMEMTESTS][NUMMEMWORDS] = {
+ /* 0 */ {0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF},
+ /* 1 */ {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000},
+ /* 2 */ {0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
+ 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
+ 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
+ 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555},
+ /* 3 */ {0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
+ 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
+ 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
+ 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA},
+ /* 4 */ {0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
+ 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
+ 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
+ 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A},
+ /* 5 */ {0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
+ 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
+ 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
+ 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5},
+ /* 6 */ {0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
+ 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
+ 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
+ 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA},
+ /* 7 */ {0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
+ 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
+ 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
+ 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55},
+
+#if defined(CFG_DECREMENT_PATTERNS)
+ /* 8 */ {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff},
+ /* 9 */ {0xfffefffe, 0xfffefffe, 0xfffefffe, 0xfffefffe,
+ 0xfffefffe, 0xfffefffe, 0xfffefffe, 0xfffefffe,
+ 0xfffefffe, 0xfffefffe, 0xfffefffe, 0xfffefffe,
+ 0xfffefffe, 0xfffefffe, 0xfffefffe, 0xfffefffe},
+ /* 10 */{0xfffdfffd, 0xfffdfffd, 0xfffdffff, 0xfffdfffd,
+ 0xfffdfffd, 0xfffdfffd, 0xfffdffff, 0xfffdfffd,
+ 0xfffdfffd, 0xfffdfffd, 0xfffdffff, 0xfffdfffd,
+ 0xfffdfffd, 0xfffdfffd, 0xfffdffff, 0xfffdfffd},
+ /* 11 */{0xfffcfffc, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc,
+ 0xfffcfffc, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc,
+ 0xfffcfffc, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc,
+ 0xfffcfffc, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc},
+ /* 12 */{0xfffbfffb, 0xfffffffb, 0xfffffffb, 0xfffffffb,
+ 0xfffbfffb, 0xfffffffb, 0xfffffffb, 0xfffffffb,
+ 0xfffbfffb, 0xfffffffb, 0xfffffffb, 0xfffffffb,
+ 0xfffbfffb, 0xfffffffb, 0xfffffffb, 0xfffffffb},
+ /* 13 */{0xfffafffa, 0xfffafffa, 0xfffffffa, 0xfffafffa,
+ 0xfffafffa, 0xfffafffa, 0xfffafffa, 0xfffafffa,
+ 0xfffafffa, 0xfffafffa, 0xfffafffa, 0xfffafffa,
+ 0xfffafffa, 0xfffafffa, 0xfffafffa, 0xfffafffa},
+ /* 14 */{0xfff9fff9, 0xfff9fff9, 0xfff9fff9, 0xfff9fff9,
+ 0xfff9fff9, 0xfff9fff9, 0xfff9fff9, 0xfff9fff9,
+ 0xfff9fff9, 0xfff9fff9, 0xfff9fff9, 0xfff9fff9,
+ 0xfff9fff9, 0xfff9fff9, 0xfff9fff9, 0xfff9fff9},
+ /* 15 */{0xfff8fff8, 0xfff8fff8, 0xfff8fff8, 0xfff8fff8,
+ 0xfff8fff8, 0xfff8fff8, 0xfff8fff8, 0xfff8fff8,
+ 0xfff8fff8, 0xfff8fff8, 0xfff8fff8, 0xfff8fff8,
+ 0xfff8fff8, 0xfff8fff8, 0xfff8fff8, 0xfff8fff8},
+ /* 16 */{0xfff7fff7, 0xfff7ffff, 0xfff7fff7, 0xfff7fff7,
+ 0xfff7fff7, 0xfff7ffff, 0xfff7fff7, 0xfff7fff7,
+ 0xfff7fff7, 0xfff7ffff, 0xfff7fff7, 0xfff7fff7,
+ 0xfff7ffff, 0xfff7ffff, 0xfff7fff7, 0xfff7fff7},
+ /* 17 */{0xfff6fff5, 0xfff6ffff, 0xfff6fff6, 0xfff6fff7,
+ 0xfff6fff5, 0xfff6ffff, 0xfff6fff6, 0xfff6fff7,
+ 0xfff6fff5, 0xfff6ffff, 0xfff6fff6, 0xfff6fff7,
+ 0xfff6fff5, 0xfff6ffff, 0xfff6fff6, 0xfff6fff7},
+ /* 18 */{0xfff5fff4, 0xfff5ffff, 0xfff5fff5, 0xfff5fff5,
+ 0xfff5fff4, 0xfff5ffff, 0xfff5fff5, 0xfff5fff5,
+ 0xfff5fff4, 0xfff5ffff, 0xfff5fff5, 0xfff5fff5,
+ 0xfff5fff4, 0xfff5ffff, 0xfff5fff5, 0xfff5fff5},
+ /* 19 */{0xfff4fff3, 0xfff4ffff, 0xfff4fff4, 0xfff4fff4,
+ 0xfff4fff3, 0xfff4ffff, 0xfff4fff4, 0xfff4fff4,
+ 0xfff4fff3, 0xfff4ffff, 0xfff4fff4, 0xfff4fff4,
+ 0xfff4fff3, 0xfff4ffff, 0xfff4fff4, 0xfff4fff4},
+ /* 20 */{0xfff3fff2, 0xfff3ffff, 0xfff3fff3, 0xfff3fff3,
+ 0xfff3fff2, 0xfff3ffff, 0xfff3fff3, 0xfff3fff3,
+ 0xfff3fff2, 0xfff3ffff, 0xfff3fff3, 0xfff3fff3,
+ 0xfff3fff2, 0xfff3ffff, 0xfff3fff3, 0xfff3fff3},
+ /* 21 */{0xfff2ffff, 0xfff2ffff, 0xfff2fff2, 0xfff2fff2,
+ 0xfff2ffff, 0xfff2ffff, 0xfff2fff2, 0xfff2fff2,
+ 0xfff2ffff, 0xfff2ffff, 0xfff2fff2, 0xfff2fff2,
+ 0xfff2ffff, 0xfff2ffff, 0xfff2fff2, 0xfff2fff2},
+ /* 22 */{0xfff1ffff, 0xfff1ffff, 0xfff1fff1, 0xfff1fff1,
+ 0xfff1ffff, 0xfff1ffff, 0xfff1fff1, 0xfff1fff1,
+ 0xfff1ffff, 0xfff1ffff, 0xfff1fff1, 0xfff1fff1,
+ 0xfff1ffff, 0xfff1ffff, 0xfff1fff1, 0xfff1fff1},
+ /* 23 */{0xfff0fff0, 0xfff0fff0, 0xfff0fff0, 0xfff0fff0,
+ 0xfff0fff0, 0xfff0fff0, 0xfff0fff0, 0xfff0fff0,
+ 0xfff0fff0, 0xfff0fff0, 0xfff0fff0, 0xfff0fff0,
+ 0xfff0fff0, 0xfff0fffe, 0xfff0fff0, 0xfff0fff0},
+#endif /* CFG_DECREMENT_PATTERNS */
+ };
+
+ mfsdram(SDRAM_MCOPT1, ecc_mode);
+ if ((ecc_mode & SDRAM_MCOPT1_MCHK_CHK_REP) ==
+ SDRAM_MCOPT1_MCHK_CHK_REP) {
+ ecc_clear_status_reg();
+ sync();
+ ecc_mode = 1;
+ } else {
+ ecc_mode = 0;
+ }
+
+ /*
+ * Run the short memory test.
+ */
+ for (i = 0; i < NUMMEMTESTS; i++) {
+ for (j = 0; j < NUMMEMWORDS; j++) {
+ base_address[j] = test[i][j];
+ ppcDcbf((ulong)&(base_address[j]));
+ }
+ sync();
+ for (l = 0; l < NUMLOOPS; l++) {
+ for (j = 0; j < NUMMEMWORDS; j++) {
+ if (base_address[j] != test[i][j]) {
+ ppcDcbf((u32)&(base_address[j]));
+ return 0;
+ } else {
+ if (ecc_mode) {
+ if (!ecc_check_status_reg())
+ return 0;
+ }
+ }
+ ppcDcbf((u32)&(base_address[j]));
+ } /* for (j = 0; j < NUMMEMWORDS; j++) */
+ sync();
+ } /* for (l=0; l<NUMLOOPS; l++) */
+ }
+
+ return 1;
+}
+
+#if defined(CONFIG_PPC4xx_DDR_METHOD_A)
+/*-----------------------------------------------------------------------------+
+| program_DQS_calibration_methodA.
++-----------------------------------------------------------------------------*/
+static u32 program_DQS_calibration_methodA(struct ddrautocal *ddrcal)
+{
+ u32 pass_result = 0;
+
+#ifdef DEBUG
+ ulong temp;
+
+ mfsdram(SDRAM_RDCC, temp);
+ debug("<%s>SDRAM_RDCC=0x%08x\n", __func__, temp);
+#endif
+
+ pass_result = DQS_calibration_methodA(ddrcal);
+
+ return pass_result;
+}
+
+/*
+ * DQS_calibration_methodA()
+ *
+ * Autocalibration Method A
+ *
+ * ARRAY [Entire DQS Range] DQS_Valid_Window ; initialized to all zeros
+ * ARRAY [Entire FDBK Range] FDBK_Valid_Window; initialized to all zeros
+ * MEMWRITE(addr, expected_data);
+ * for (i = 0; i < Entire DQS Range; i++) { RQDC.RQFD
+ * for (j = 0; j < Entire FDBK Range; j++) { RFDC.RFFD
+ * MEMREAD(addr, actual_data);
+ * if (actual_data == expected_data) {
+ * DQS_Valid_Window[i] = 1; RQDC.RQFD
+ * FDBK_Valid_Window[i][j] = 1; RFDC.RFFD
+ * }
+ * }
+ * }
+ */
+static u32 DQS_calibration_methodA(struct ddrautocal *cal)
+{
+ ulong rfdc_reg;
+ ulong rffd;
+
+ ulong rqdc_reg;
+ ulong rqfd;
+
+ u32 *membase;
+ ulong bxcf;
+ int rqfd_average;
+ int bxcr_num;
+ int rffd_average;
+ int pass;
+ u32 passed = 0;
+
+ int in_window;
+ struct autocal_regs curr_win_min;
+ struct autocal_regs curr_win_max;
+ struct autocal_regs best_win_min;
+ struct autocal_regs best_win_max;
+ struct autocal_regs loop_win_min;
+ struct autocal_regs loop_win_max;
+
+#ifdef DEBUG
+ ulong temp;
+#endif
+ ulong rdcc;
+
+ char slash[] = "\\|/-\\|/-";
+ int loopi = 0;
+
+ /* start */
+ in_window = 0;
+
+ memset(&curr_win_min, 0, sizeof(curr_win_min));
+ memset(&curr_win_max, 0, sizeof(curr_win_max));
+ memset(&best_win_min, 0, sizeof(best_win_min));
+ memset(&best_win_max, 0, sizeof(best_win_max));
+ memset(&loop_win_min, 0, sizeof(loop_win_min));
+ memset(&loop_win_max, 0, sizeof(loop_win_max));
+
+ rdcc = 0;
+
+ /*
+ * Program RDCC register
+ * Read sample cycle auto-update enable
+ */
+ mtsdram(SDRAM_RDCC, SDRAM_RDCC_RDSS_T1 | SDRAM_RDCC_RSAE_ENABLE);
+
+#ifdef DEBUG
+ mfsdram(SDRAM_RDCC, temp);
+ debug("<%s>SDRAM_RDCC=0x%x\n", __func__, temp);
+ mfsdram(SDRAM_RTSR, temp);
+ debug("<%s>SDRAM_RTSR=0x%x\n", __func__, temp);
+ mfsdram(SDRAM_FCSR, temp);
+ debug("<%s>SDRAM_FCSR=0x%x\n", __func__, temp);
+#endif
+
+ /*
+ * Program RQDC register
+ * Internal DQS delay mechanism enable
+ */
+ mtsdram(SDRAM_RQDC,
+ SDRAM_RQDC_RQDE_ENABLE | SDRAM_RQDC_RQFD_ENCODE(0x00));
+
+#ifdef DEBUG
+ mfsdram(SDRAM_RQDC, temp);
+ debug("<%s>SDRAM_RQDC=0x%x\n", __func__, temp);
+#endif
+
+ /*
+ * Program RFDC register
+ * Set Feedback Fractional Oversample
+ * Auto-detect read sample cycle enable
+ */
+ mtsdram(SDRAM_RFDC, SDRAM_RFDC_ARSE_ENABLE |
+ SDRAM_RFDC_RFOS_ENCODE(0) | SDRAM_RFDC_RFFD_ENCODE(0));
+
+#ifdef DEBUG
+ mfsdram(SDRAM_RFDC, temp);
+ debug("<%s>SDRAM_RFDC=0x%x\n", __func__, temp);
+#endif
+
+ putc(' ');
+ for (rqfd = 0; rqfd <= SDRAM_RQDC_RQFD_MAX; rqfd++) {
+
+ mfsdram(SDRAM_RQDC, rqdc_reg);
+ rqdc_reg &= ~(SDRAM_RQDC_RQFD_MASK);
+ mtsdram(SDRAM_RQDC, rqdc_reg | SDRAM_RQDC_RQFD_ENCODE(rqfd));
+
+ putc('\b');
+ putc(slash[loopi++ % 8]);
+
+ curr_win_min.rffd = 0;
+ curr_win_max.rffd = 0;
+ in_window = 0;
+
+ for (rffd = 0, pass = 0; rffd <= SDRAM_RFDC_RFFD_MAX; rffd++) {
+ mfsdram(SDRAM_RFDC, rfdc_reg);
+ rfdc_reg &= ~(SDRAM_RFDC_RFFD_MASK);
+ mtsdram(SDRAM_RFDC,
+ rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd));
+
+ for (bxcr_num = 0; bxcr_num < MAXBXCF; bxcr_num++) {
+ mfsdram(SDRAM_MB0CF + (bxcr_num<<2), bxcf);
+
+ /* Banks enabled */
+ if (bxcf & SDRAM_BXCF_M_BE_MASK) {
+ /* Bank is enabled */
+ membase = get_membase(bxcr_num);
+ pass = short_mem_test(membase);
+ } /* if bank enabled */
+ } /* for bxcr_num */
+
+ /* If this value passed update RFFD windows */
+ if (pass && !in_window) { /* at the start of window */
+ in_window = 1;
+ curr_win_min.rffd = curr_win_max.rffd = rffd;
+ curr_win_min.rqfd = curr_win_max.rqfd = rqfd;
+ mfsdram(SDRAM_RDCC, rdcc); /*record this value*/
+ } else if (!pass && in_window) { /* at end of window */
+ in_window = 0;
+ } else if (pass && in_window) { /* within the window */
+ curr_win_max.rffd = rffd;
+ curr_win_max.rqfd = rqfd;
+ }
+ /* else if (!pass && !in_window)
+ skip - no pass, not currently in a window */
+
+ if (in_window) {
+ if ((curr_win_max.rffd - curr_win_min.rffd) >
+ (best_win_max.rffd - best_win_min.rffd)) {
+ best_win_min.rffd = curr_win_min.rffd;
+ best_win_max.rffd = curr_win_max.rffd;
+
+ best_win_min.rqfd = curr_win_min.rqfd;
+ best_win_max.rqfd = curr_win_max.rqfd;
+ cal->rdcc = rdcc;
+ }
+ passed = 1;
+ }
+ } /* RFDC.RFFD */
+
+ /*
+ * save-off the best window results of the RFDC.RFFD
+ * for this RQDC.RQFD setting
+ */
+ /*
+ * if (just ended RFDC.RFDC loop pass window) >
+ * (prior RFDC.RFFD loop pass window)
+ */
+ if ((best_win_max.rffd - best_win_min.rffd) >
+ (loop_win_max.rffd - loop_win_min.rffd)) {
+ loop_win_min.rffd = best_win_min.rffd;
+ loop_win_max.rffd = best_win_max.rffd;
+ loop_win_min.rqfd = rqfd;
+ loop_win_max.rqfd = rqfd;
+ debug("RQFD.min 0x%08x, RQFD.max 0x%08x, "
+ "RFFD.min 0x%08x, RFFD.max 0x%08x\n",
+ loop_win_min.rqfd, loop_win_max.rqfd,
+ loop_win_min.rffd, loop_win_max.rffd);
+ }
+ } /* RQDC.RQFD */
+
+ putc('\b');
+
+ debug("\n");
+
+ if ((loop_win_min.rffd == 0) && (loop_win_max.rffd == 0) &&
+ (best_win_min.rffd == 0) && (best_win_max.rffd == 0) &&
+ (best_win_min.rqfd == 0) && (best_win_max.rqfd == 0)) {
+ passed = 0;
+ }
+
+ /*
+ * Need to program RQDC before RFDC.
+ */
+ debug("<%s> RQFD Min: 0x%x\n", __func__, loop_win_min.rqfd);
+ debug("<%s> RQFD Max: 0x%x\n", __func__, loop_win_max.rqfd);
+ rqfd_average = loop_win_max.rqfd;
+
+ if (rqfd_average < 0)
+ rqfd_average = 0;
+
+ if (rqfd_average > SDRAM_RQDC_RQFD_MAX)
+ rqfd_average = SDRAM_RQDC_RQFD_MAX;
+
+ debug("<%s> RFFD average: 0x%08x\n", __func__, rqfd_average);
+ mtsdram(SDRAM_RQDC, (rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) |
+ SDRAM_RQDC_RQFD_ENCODE(rqfd_average));
+
+ debug("<%s> RFFD Min: 0x%08x\n", __func__, loop_win_min.rffd);
+ debug("<%s> RFFD Max: 0x%08x\n", __func__, loop_win_max.rffd);
+ rffd_average = ((loop_win_min.rffd + loop_win_max.rffd) / 2);
+
+ if (rffd_average < 0)
+ rffd_average = 0;
+
+ if (rffd_average > SDRAM_RFDC_RFFD_MAX)
+ rffd_average = SDRAM_RFDC_RFFD_MAX;
+
+ debug("<%s> RFFD average: 0x%08x\n", __func__, rffd_average);
+ mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd_average));
+
+ /* if something passed, then return the size of the largest window */
+ if (passed != 0) {
+ passed = loop_win_max.rffd - loop_win_min.rffd;
+ cal->rqfd = rqfd_average;
+ cal->rffd = rffd_average;
+ cal->rffd_min = loop_win_min.rffd;
+ cal->rffd_max = loop_win_max.rffd;
+ }
+
+ return (u32)passed;
+}
+
+#else /* !defined(CONFIG_PPC4xx_DDR_METHOD_A) */
+
+/*-----------------------------------------------------------------------------+
+| program_DQS_calibration_methodB.
++-----------------------------------------------------------------------------*/
+static u32 program_DQS_calibration_methodB(struct ddrautocal *ddrcal)
+{
+ u32 pass_result = 0;
+
+#ifdef DEBUG
+ ulong temp;
+#endif
+
+ /*
+ * Program RDCC register
+ * Read sample cycle auto-update enable
+ */
+ mtsdram(SDRAM_RDCC, SDRAM_RDCC_RDSS_T2 | SDRAM_RDCC_RSAE_ENABLE);
+
+#ifdef DEBUG
+ mfsdram(SDRAM_RDCC, temp);
+ debug("<%s>SDRAM_RDCC=0x%08x\n", __func__, temp);
+#endif
+
+ /*
+ * Program RQDC register
+ * Internal DQS delay mechanism enable
+ */
+ mtsdram(SDRAM_RQDC,
+#if defined(CONFIG_DDR_RQDC_START_VAL)
+ SDRAM_RQDC_RQDE_ENABLE |
+ SDRAM_RQDC_RQFD_ENCODE(CONFIG_DDR_RQDC_START_VAL));
+#else
+ SDRAM_RQDC_RQDE_ENABLE | SDRAM_RQDC_RQFD_ENCODE(0x38));
+#endif
+
+#ifdef DEBUG
+ mfsdram(SDRAM_RQDC, temp);
+ debug("<%s>SDRAM_RQDC=0x%08x\n", __func__, temp);
+#endif
+
+ /*
+ * Program RFDC register
+ * Set Feedback Fractional Oversample
+ * Auto-detect read sample cycle enable
+ */
+ mtsdram(SDRAM_RFDC, SDRAM_RFDC_ARSE_ENABLE |
+ SDRAM_RFDC_RFOS_ENCODE(0) |
+ SDRAM_RFDC_RFFD_ENCODE(0));
+
+#ifdef DEBUG
+ mfsdram(SDRAM_RFDC, temp);
+ debug("<%s>SDRAM_RFDC=0x%08x\n", __func__, temp);
+#endif
+
+ pass_result = DQS_calibration_methodB(ddrcal);
+
+ return pass_result;
+}
+
+/*
+ * DQS_calibration_methodB()
+ *
+ * Autocalibration Method B
+ *
+ * ARRAY [Entire DQS Range] DQS_Valid_Window ; initialized to all zeros
+ * ARRAY [Entire Feedback Range] FDBK_Valid_Window; initialized to all zeros
+ * MEMWRITE(addr, expected_data);
+ * Initialialize the DQS delay to 80 degrees (MCIF0_RRQDC[RQFD]=0x38).
+ *
+ * for (j = 0; j < Entire Feedback Range; j++) {
+ * MEMREAD(addr, actual_data);
+ * if (actual_data == expected_data) {
+ * FDBK_Valid_Window[j] = 1;
+ * }
+ * }
+ *
+ * Set MCIF0_RFDC[RFFD] to the middle of the FDBK_Valid_Window.
+ *
+ * for (i = 0; i < Entire DQS Range; i++) {
+ * MEMREAD(addr, actual_data);
+ * if (actual_data == expected_data) {
+ * DQS_Valid_Window[i] = 1;
+ * }
+ * }
+ *
+ * Set MCIF0_RRQDC[RQFD] to the middle of the DQS_Valid_Window.
+ */
+/*-----------------------------------------------------------------------------+
+| DQS_calibration_methodB.
++-----------------------------------------------------------------------------*/
+static u32 DQS_calibration_methodB(struct ddrautocal *cal)
+{
+ ulong rfdc_reg;
+ ulong rffd;
+
+ ulong rqdc_reg;
+ ulong rqfd;
+
+ ulong rdcc;
+
+ u32 *membase;
+ ulong bxcf;
+ int rqfd_average;
+ int bxcr_num;
+ int rffd_average;
+ int pass;
+ uint passed = 0;
+
+ int in_window;
+ u32 curr_win_min, curr_win_max;
+ u32 best_win_min, best_win_max;
+ u32 size = 0;
+
+ /*------------------------------------------------------------------
+ | Test to determine the best read clock delay tuning bits.
+ |
+ | Before the DDR controller can be used, the read clock delay needs to
+ | be set. This is SDRAM_RQDC[RQFD] and SDRAM_RFDC[RFFD].
+ | This value cannot be hardcoded into the program because it changes
+ | depending on the board's setup and environment.
+ | To do this, all delay values are tested to see if they
+ | work or not. By doing this, you get groups of fails with groups of
+ | passing values. The idea is to find the start and end of a passing
+ | window and take the center of it to use as the read clock delay.
+ |
+ | A failure has to be seen first so that when we hit a pass, we know
+ | that it is truely the start of the window. If we get passing values
+ | to start off with, we don't know if we are at the start of the window
+ |
+ | The code assumes that a failure will always be found.
+ | If a failure is not found, there is no easy way to get the middle
+ | of the passing window. I guess we can pretty much pick any value
+ | but some values will be better than others. Since the lowest speed
+ | we can clock the DDR interface at is 200 MHz (2x 100 MHz PLB speed),
+ | from experimentation it is safe to say you will always have a failure
+ +-----------------------------------------------------------------*/
+
+ debug("\n\n");
+
+ in_window = 0;
+ rdcc = 0;
+
+ curr_win_min = curr_win_max = 0;
+ best_win_min = best_win_max = 0;
+ for (rffd = 0; rffd <= SDRAM_RFDC_RFFD_MAX; rffd++) {
+ mfsdram(SDRAM_RFDC, rfdc_reg);
+ rfdc_reg &= ~(SDRAM_RFDC_RFFD_MASK);
+ mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd));
+
+ pass = 1;
+ for (bxcr_num = 0; bxcr_num < MAXBXCF; bxcr_num++) {
+ mfsdram(SDRAM_MB0CF + (bxcr_num<<2), bxcf);
+
+ /* Banks enabled */
+ if (bxcf & SDRAM_BXCF_M_BE_MASK) {
+ /* Bank is enabled */
+ membase = get_membase(bxcr_num);
+ pass &= short_mem_test(membase);
+ } /* if bank enabled */
+ } /* for bxcf_num */
+
+ /* If this value passed */
+ if (pass && !in_window) { /* start of passing window */
+ in_window = 1;
+ curr_win_min = curr_win_max = rffd;
+ mfsdram(SDRAM_RDCC, rdcc); /* record this value */
+ } else if (!pass && in_window) { /* end passing window */
+ in_window = 0;
+ } else if (pass && in_window) { /* within the passing window */
+ curr_win_max = rffd;
+ }
+
+ if (in_window) {
+ if ((curr_win_max - curr_win_min) >
+ (best_win_max - best_win_min)) {
+ best_win_min = curr_win_min;
+ best_win_max = curr_win_max;
+ cal->rdcc = rdcc;
+ }
+ passed = 1;
+ }
+ } /* for rffd */
+
+ if ((best_win_min == 0) && (best_win_max == 0))
+ passed = 0;
+ else
+ size = best_win_max - best_win_min;
+
+ debug("RFFD Min: 0x%x\n", best_win_min);
+ debug("RFFD Max: 0x%x\n", best_win_max);
+ rffd_average = ((best_win_min + best_win_max) / 2);
+
+ cal->rffd_min = best_win_min;
+ cal->rffd_max = best_win_max;
+
+ if (rffd_average < 0)
+ rffd_average = 0;
+
+ if (rffd_average > SDRAM_RFDC_RFFD_MAX)
+ rffd_average = SDRAM_RFDC_RFFD_MAX;
+
+ mtsdram(SDRAM_RFDC, rfdc_reg | SDRAM_RFDC_RFFD_ENCODE(rffd_average));
+
+ rffd = rffd_average;
+ in_window = 0;
+
+ curr_win_min = curr_win_max = 0;
+ best_win_min = best_win_max = 0;
+ for (rqfd = 0; rqfd <= SDRAM_RQDC_RQFD_MAX; rqfd++) {
+ mfsdram(SDRAM_RQDC, rqdc_reg);
+ rqdc_reg &= ~(SDRAM_RQDC_RQFD_MASK);
+ mtsdram(SDRAM_RQDC, rqdc_reg | SDRAM_RQDC_RQFD_ENCODE(rqfd));
+
+ pass = 1;
+ for (bxcr_num = 0; bxcr_num < MAXBXCF; bxcr_num++) {
+
+ mfsdram(SDRAM_MB0CF + (bxcr_num<<2), bxcf);
+
+ /* Banks enabled */
+ if (bxcf & SDRAM_BXCF_M_BE_MASK) {
+ /* Bank is enabled */
+ membase = get_membase(bxcr_num);
+ pass &= short_mem_test(membase);
+ } /* if bank enabled */
+ } /* for bxcf_num */
+
+ /* If this value passed */
+ if (pass && !in_window) {
+ in_window = 1;
+ curr_win_min = curr_win_max = rqfd;
+ } else if (!pass && in_window) {
+ in_window = 0;
+ } else if (pass && in_window) {
+ curr_win_max = rqfd;
+ }
+
+ if (in_window) {
+ if ((curr_win_max - curr_win_min) >
+ (best_win_max - best_win_min)) {
+ best_win_min = curr_win_min;
+ best_win_max = curr_win_max;
+ }
+ passed = 1;
+ }
+ } /* for rqfd */
+
+ if ((best_win_min == 0) && (best_win_max == 0))
+ passed = 0;
+
+ debug("RQFD Min: 0x%x\n", best_win_min);
+ debug("RQFD Max: 0x%x\n", best_win_max);
+ rqfd_average = ((best_win_min + best_win_max) / 2);
+
+ if (rqfd_average < 0)
+ rqfd_average = 0;
+
+ if (rqfd_average > SDRAM_RQDC_RQFD_MAX)
+ rqfd_average = SDRAM_RQDC_RQFD_MAX;
+
+ mtsdram(SDRAM_RQDC, (rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) |
+ SDRAM_RQDC_RQFD_ENCODE(rqfd_average));
+
+ mfsdram(SDRAM_RQDC, rqdc_reg);
+ mfsdram(SDRAM_RFDC, rfdc_reg);
+
+ /*
+ * Need to program RQDC before RFDC. The value is read above.
+ * That is the reason why auto cal not work.
+ * See, comments below.
+ */
+ mtsdram(SDRAM_RQDC, rqdc_reg);
+ mtsdram(SDRAM_RFDC, rfdc_reg);
+
+ debug("RQDC: 0x%08X\n", rqdc_reg);
+ debug("RFDC: 0x%08X\n", rfdc_reg);
+
+ /* if something passed, then return the size of the largest window */
+ if (passed != 0) {
+ passed = size;
+ cal->rqfd = rqfd_average;
+ cal->rffd = rffd_average;
+ }
+
+ return (uint)passed;
+}
+#endif /* defined(CONFIG_PPC4xx_DDR_METHOD_A) */
+
+/*
+ * Default table for DDR auto-calibration of all
+ * possible WRDTR and CLKTR values.
+ * Table format is:
+ * {SDRAM_WRDTR.[WDTR], SDRAM_CLKTR.[CKTR]}
+ *
+ * Table is terminated with {-1, -1} value pair.
+ *
+ * Board vendors can specify their own board specific subset of
+ * known working {SDRAM_WRDTR.[WDTR], SDRAM_CLKTR.[CKTR]} value
+ * pairs via a board defined ddr_scan_option() function.
+ */
+struct sdram_timing full_scan_options[] = {
+ {0, 0}, {0, 1}, {0, 2}, {0, 3},
+ {1, 0}, {1, 1}, {1, 2}, {1, 3},
+ {2, 0}, {2, 1}, {2, 2}, {2, 3},
+ {3, 0}, {3, 1}, {3, 2}, {3, 3},
+ {4, 0}, {4, 1}, {4, 2}, {4, 3},
+ {5, 0}, {5, 1}, {5, 2}, {5, 3},
+ {6, 0}, {6, 1}, {6, 2}, {6, 3},
+ {-1, -1}
+};
+
+/*---------------------------------------------------------------------------+
+| DQS_calibration.
++----------------------------------------------------------------------------*/
+u32 DQS_autocalibration(void)
+{
+ u32 wdtr;
+ u32 clkp;
+ u32 result = 0;
+ u32 best_result = 0;
+ u32 best_rdcc;
+ struct ddrautocal ddrcal;
+ struct autocal_clks tcal;
+ ulong rfdc_reg;
+ ulong rqdc_reg;
+ u32 val;
+ int verbose_lvl = 0;
+ char *str;
+ char slash[] = "\\|/-\\|/-";
+ int loopi = 0;
+ struct sdram_timing *scan_list;
+
+#if defined(DEBUG_PPC4xx_DDR_AUTOCALIBRATION)
+ int i;
+ char tmp[64]; /* long enough for environment variables */
+#endif
+
+ memset(&tcal, 0, sizeof(tcal));
+
+ ddr_scan_option((ulong)full_scan_options);
+
+ scan_list =
+ (struct sdram_timing *)ddr_scan_option((ulong)full_scan_options);
+
+ mfsdram(SDRAM_MCOPT1, val);
+ if ((val & SDRAM_MCOPT1_MCHK_CHK_REP) == SDRAM_MCOPT1_MCHK_CHK_REP)
+ str = "ECC Auto calibration -";
+ else
+ str = "Auto calibration -";
+
+ puts(str);
+
+#if defined(DEBUG_PPC4xx_DDR_AUTOCALIBRATION)
+ i = getenv_r("autocalib", tmp, sizeof(tmp));
+ if (i < 0)
+ strcpy(tmp, CONFIG_AUTOCALIB);
+
+ if (strcmp(tmp, "final") == 0) {
+ /* display the final autocalibration results only */
+ verbose_lvl = 1;
+ } else if (strcmp(tmp, "loop") == 0) {
+ /* display summary autocalibration info per iteration */
+ verbose_lvl = 2;
+ } else if (strcmp(tmp, "display") == 0) {
+ /* display full debug autocalibration window info. */
+ verbose_lvl = 3;
+ }
+#endif /* (DEBUG_PPC4xx_DDR_AUTOCALIBRATION) */
+
+ best_rdcc = (SDRAM_RDCC_RDSS_T4 >> 30);
+
+ while ((scan_list->wrdtr != -1) && (scan_list->clktr != -1)) {
+ wdtr = scan_list->wrdtr;
+ clkp = scan_list->clktr;
+
+ mfsdram(SDRAM_WRDTR, val);
+ val &= ~(SDRAM_WRDTR_LLWP_MASK | SDRAM_WRDTR_WTR_MASK);
+ mtsdram(SDRAM_WRDTR, (val |
+ ddr_wrdtr(SDRAM_WRDTR_LLWP_1_CYC | (wdtr << 25))));
+
+ mtsdram(SDRAM_CLKTR, clkp << 30);
+
+ putc('\b');
+ putc(slash[loopi++ % 8]);
+
+#ifdef DEBUG
+ debug("\n");
+ debug("*** --------------\n");
+ mfsdram(SDRAM_WRDTR, val);
+ debug("*** SDRAM_WRDTR set to 0x%08x\n", val);
+ mfsdram(SDRAM_CLKTR, val);
+ debug("*** SDRAM_CLKTR set to 0x%08x\n", val);
+#endif
+
+ debug("\n");
+ if (verbose_lvl > 2) {
+ printf("*** SDRAM_WRDTR (wdtr) set to %d\n", wdtr);
+ printf("*** SDRAM_CLKTR (clkp) set to %d\n", clkp);
+ }
+
+ memset(&ddrcal, 0, sizeof(ddrcal));
+
+ /*
+ * DQS calibration.
+ */
+ /*
+ * program_DQS_calibration_method[A|B]() returns 0 if no
+ * passing RFDC.[RFFD] window is found or returns the size
+ * of the best passing window; in the case of a found passing
+ * window, the ddrcal will contain the values of the best
+ * window RQDC.[RQFD] and RFDC.[RFFD].
+ */
+
+ /*
+ * Call PPC4xx SDRAM DDR autocalibration methodA or methodB.
+ * Default is methodB.
+ * Defined the autocalibration method in the board specific
+ * header file.
+ * Please see include/configs/kilauea.h for an example for
+ * a board specific implementation.
+ */
+#if defined(CONFIG_PPC4xx_DDR_METHOD_A)
+ result = program_DQS_calibration_methodA(&ddrcal);
+#else
+ result = program_DQS_calibration_methodB(&ddrcal);
+#endif
+
+ sync();
+
+ /*
+ * Clear potential errors resulting from auto-calibration.
+ * If not done, then we could get an interrupt later on when
+ * exceptions are enabled.
+ */
+ set_mcsr(get_mcsr());
+
+ val = ddrcal.rdcc; /* RDCC from the best passing window */
+
+ udelay(100);
+
+ if (verbose_lvl > 1) {
+ char *tstr;
+ switch ((val >> 30)) {
+ case 0:
+ if (result != 0)
+ tstr = "T1";
+ else
+ tstr = "N/A";
+ break;
+ case 1:
+ tstr = "T2";
+ break;
+ case 2:
+ tstr = "T3";
+ break;
+ case 3:
+ tstr = "T4";
+ break;
+ default:
+ tstr = "unknown";
+ break;
+ }
+ printf("** WRDTR(%d) CLKTR(%d), Wind (%d), best (%d), "
+ "max-min(0x%04x)(0x%04x), RDCC: %s\n",
+ wdtr, clkp, result, best_result,
+ ddrcal.rffd_min, ddrcal.rffd_max, tstr);
+ }
+
+ /*
+ * The DQS calibration "result" is either "0"
+ * if no passing window was found, or is the
+ * size of the RFFD passing window.
+ */
+ if (result != 0) {
+ tcal.autocal.flags = 1;
+ debug("*** (%d)(%d) result passed window size: 0x%08x, "
+ "rqfd = 0x%08x, rffd = 0x%08x, rdcc = 0x%08x\n",
+ wdtr, clkp, result, ddrcal.rqfd,
+ ddrcal.rffd, ddrcal.rdcc);
+ /*
+ * Save the SDRAM_WRDTR and SDRAM_CLKTR
+ * settings for the largest returned
+ * RFFD passing window size.
+ */
+ if (result > best_result) {
+ /*
+ * want the lowest Read Sample Cycle Select
+ */
+ val = (val & SDRAM_RDCC_RDSS_MASK) >> 30;
+ debug("*** (%d) (%d) current_rdcc, best_rdcc\n",
+ val, best_rdcc);
+ if (val <= best_rdcc) {
+ best_rdcc = val;
+ tcal.clocks.wrdtr = wdtr;
+ tcal.clocks.clktr = clkp;
+ tcal.clocks.rdcc = (val << 30);
+ tcal.autocal.rqfd = ddrcal.rqfd;
+ tcal.autocal.rffd = ddrcal.rffd;
+ best_result = result;
+
+ if (verbose_lvl > 2) {
+ printf("** (%d)(%d) "
+ "best result: 0x%04x\n",
+ wdtr, clkp,
+ best_result);
+ printf("** (%d)(%d) "
+ "best WRDTR: 0x%04x\n",
+ wdtr, clkp,
+ tcal.clocks.wrdtr);
+ printf("** (%d)(%d) "
+ "best CLKTR: 0x%04x\n",
+ wdtr, clkp,
+ tcal.clocks.clktr);
+ printf("** (%d)(%d) "
+ "best RQDC: 0x%04x\n",
+ wdtr, clkp,
+ tcal.autocal.rqfd);
+ printf("** (%d)(%d) "
+ "best RFDC: 0x%04x\n",
+ wdtr, clkp,
+ tcal.autocal.rffd);
+ printf("** (%d)(%d) "
+ "best RDCC: 0x%08x\n",
+ wdtr, clkp,
+ (u32)tcal.clocks.rdcc);
+ mfsdram(SDRAM_RTSR, val);
+ printf("** (%d)(%d) best "
+ "loop RTSR: 0x%08x\n",
+ wdtr, clkp, val);
+ mfsdram(SDRAM_FCSR, val);
+ printf("** (%d)(%d) best "
+ "loop FCSR: 0x%08x\n",
+ wdtr, clkp, val);
+ }
+ } /* if (val <= best_rdcc) */
+ } /* if (result >= best_result) */
+ } /* if (result != 0) */
+ scan_list++;
+ } /* while ((scan_list->wrdtr != -1) && (scan_list->clktr != -1)) */
+
+ if (tcal.autocal.flags == 1) {
+ if (verbose_lvl > 0) {
+ printf("*** --------------\n");
+ printf("*** best_result window size: %d\n",
+ best_result);
+ printf("*** best_result WRDTR: 0x%04x\n",
+ tcal.clocks.wrdtr);
+ printf("*** best_result CLKTR: 0x%04x\n",
+ tcal.clocks.clktr);
+ printf("*** best_result RQFD: 0x%04x\n",
+ tcal.autocal.rqfd);
+ printf("*** best_result RFFD: 0x%04x\n",
+ tcal.autocal.rffd);
+ printf("*** best_result RDCC: 0x%04x\n",
+ tcal.clocks.rdcc);
+ printf("*** --------------\n");
+ printf("\n");
+ }
+
+ /*
+ * if got best passing result window, then lock in the
+ * best CLKTR, WRDTR, RQFD, and RFFD values
+ */
+ mfsdram(SDRAM_WRDTR, val);
+ mtsdram(SDRAM_WRDTR, (val &
+ ~(SDRAM_WRDTR_LLWP_MASK | SDRAM_WRDTR_WTR_MASK)) |
+ ddr_wrdtr(SDRAM_WRDTR_LLWP_1_CYC |
+ (tcal.clocks.wrdtr << 25)));
+
+ mtsdram(SDRAM_CLKTR, tcal.clocks.clktr << 30);
+
+ mfsdram(SDRAM_RQDC, rqdc_reg);
+ rqdc_reg &= ~(SDRAM_RQDC_RQFD_MASK);
+ mtsdram(SDRAM_RQDC, rqdc_reg |
+ SDRAM_RQDC_RQFD_ENCODE(tcal.autocal.rqfd));
+
+ mfsdram(SDRAM_RQDC, rqdc_reg);
+ debug("*** best_result: read value SDRAM_RQDC 0x%08x\n",
+ rqdc_reg);
+
+ mfsdram(SDRAM_RFDC, rfdc_reg);
+ rfdc_reg &= ~(SDRAM_RFDC_RFFD_MASK);
+ mtsdram(SDRAM_RFDC, rfdc_reg |
+ SDRAM_RFDC_RFFD_ENCODE(tcal.autocal.rffd));
+
+ mfsdram(SDRAM_RFDC, rfdc_reg);
+ debug("*** best_result: read value SDRAM_RFDC 0x%08x\n",
+ rfdc_reg);
+ mfsdram(SDRAM_RDCC, val);
+ debug("*** SDRAM_RDCC 0x%08x\n", val);
+ } else {
+ /*
+ * no valid windows were found
+ */
+ printf("DQS memory calibration window can not be determined, "
+ "terminating u-boot.\n");
+ ppc4xx_ibm_ddr2_register_dump();
+ spd_ddr_init_hang();
+ }
+
+ blank_string(strlen(str));
+
+ return 0;
+}
+#else /* defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) */
+u32 DQS_autocalibration(void)
+{
+ return 0;
+}
+#endif /* !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) */
+#endif /* defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION) */
diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile
index c773400..463b575 100644
--- a/cpu/ppc4xx/Makefile
+++ b/cpu/ppc4xx/Makefile
@@ -35,6 +35,9 @@ SOBJS += kgdb.o
COBJS := 40x_spd_sdram.o
COBJS += 44x_spd_ddr.o
COBJS += 44x_spd_ddr2.o
+ifdef CONFIG_PPC4xx_DDR_AUTOCALIBRATION
+COBJS += 4xx_ibm_ddr2_autocalib.o
+endif
COBJS += 4xx_pci.o
COBJS += 4xx_pcie.o
COBJS += bedbug_405.o
diff --git a/cpu/ppc4xx/miiphy.c b/cpu/ppc4xx/miiphy.c
index c882720..84b1bbe 100644
--- a/cpu/ppc4xx/miiphy.c
+++ b/cpu/ppc4xx/miiphy.c
@@ -180,8 +180,10 @@ int phy_setup_aneg (char *devname, unsigned char addr)
*
* sr: Currently on 460EX only EMAC0 works with MDIO, so we always
* return EMAC0 offset here
+ * vg: For 460EX/460GT if internal GPCS PHY address is specified
+ * return appropriate EMAC offset
*/
-unsigned int miiphy_getemac_offset (void)
+unsigned int miiphy_getemac_offset(u8 addr)
{
#if (defined(CONFIG_440) && \
!defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
@@ -233,6 +235,35 @@ unsigned int miiphy_getemac_offset (void)
return 0x100;
#endif
+#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
+ u32 eoffset = 0;
+
+ switch (addr) {
+#if defined(CONFIG_HAS_ETH1) && defined(CONFIG_GPCS_PHY1_ADDR)
+ case CONFIG_GPCS_PHY1_ADDR:
+ if (addr == EMAC_M1_IPPA_GET(in_be32((void *)EMAC_M1 + 0x100)))
+ eoffset = 0x100;
+ break;
+#endif
+#if defined(CONFIG_HAS_ETH2) && defined(CONFIG_GPCS_PHY2_ADDR)
+ case CONFIG_GPCS_PHY2_ADDR:
+ if (addr == EMAC_M1_IPPA_GET(in_be32((void *)EMAC_M1 + 0x300)))
+ eoffset = 0x300;
+ break;
+#endif
+#if defined(CONFIG_HAS_ETH3) && defined(CONFIG_GPCS_PHY3_ADDR)
+ case CONFIG_GPCS_PHY3_ADDR:
+ if (addr == EMAC_M1_IPPA_GET(in_be32((void *)EMAC_M1 + 0x400)))
+ eoffset = 0x400;
+ break;
+#endif
+ default:
+ eoffset = 0;
+ break;
+ }
+ return eoffset;
+#endif
+
return 0;
#endif
}
@@ -262,7 +293,7 @@ static int emac_miiphy_command(u8 addr, u8 reg, int cmd, u16 value)
u32 emac_reg;
u32 sta_reg;
- emac_reg = miiphy_getemac_offset();
+ emac_reg = miiphy_getemac_offset(addr);
/* wait for completion */
if (emac_miiphy_wait(emac_reg) != 0)
@@ -311,7 +342,7 @@ int emac4xx_miiphy_read (char *devname, unsigned char addr, unsigned char reg,
unsigned long sta_reg;
unsigned long emac_reg;
- emac_reg = miiphy_getemac_offset ();
+ emac_reg = miiphy_getemac_offset(addr);
if (emac_miiphy_command(addr, reg, EMAC_STACR_READ, 0) != 0)
return -1;
diff --git a/disk/part.c b/disk/part.c
index 5c4bf6b..877e988 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -124,6 +124,12 @@ void dev_print (block_dev_desc_t *dev_desc)
dev_desc->revision,
dev_desc->product);
break;
+ case IF_TYPE_USB:
+ printf ("Vendor: %s Rev: %s Prod: %s\n",
+ dev_desc->vendor,
+ dev_desc->revision,
+ dev_desc->product);
+ break;
case IF_TYPE_UNKNOWN:
default:
puts ("not available\n");
diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt
index c1244fb..157936e 100644
--- a/doc/uImage.FIT/source_file_format.txt
+++ b/doc/uImage.FIT/source_file_format.txt
@@ -169,7 +169,7 @@ the '/images' node should have the following layout:
- 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".
+ "rtems", "unity", "integrity".
- 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",
diff --git a/drivers/mtd/mw_eeprom.c b/drivers/mtd/mw_eeprom.c
index f32ced4..f7791b51 100644
--- a/drivers/mtd/mw_eeprom.c
+++ b/drivers/mtd/mw_eeprom.c
@@ -1,7 +1,7 @@
/* Three-wire (MicroWire) serial eeprom driver (for 93C46 and compatibles) */
#include <common.h>
-#include <ssi.h>
+#include <asm/ic/ssi.h>
/*
* Serial EEPROM opcodes, including start bit
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index f41f33d..94bc518 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -32,8 +32,8 @@ COBJS-y += date.o
COBJS-$(CONFIG_RTC_DS12887) += ds12887.o
COBJS-$(CONFIG_RTC_DS1302) += ds1302.o
COBJS-$(CONFIG_RTC_DS1306) += ds1306.o
-COBJS-$(CONFIG_RTC_DS1307)$(CONFIG_RTC_DS1338) += ds1307.o
-COBJS-y += $(COBJS-yy)
+COBJS-$(CONFIG_RTC_DS1307) += ds1307.o
+COBJS-$(CONFIG_RTC_DS1338) += ds1307.o
COBJS-$(CONFIG_RTC_DS1337) += ds1337.o
COBJS-$(CONFIG_RTC_DS1374) += ds1374.o
COBJS-$(CONFIG_RTC_DS1556) += ds1556.o
@@ -59,7 +59,7 @@ COBJS-$(CONFIG_RTC_RX8025) += rx8025.o
COBJS-$(CONFIG_RTC_S3C24X0) += s3c24x0_rtc.o
COBJS-$(CONFIG_RTC_X1205) += x1205.o
-COBJS := $(COBJS-y)
+COBJS := $(sort $(COBJS-y))
SRCS := $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
diff --git a/drivers/rtc/mk48t59.c b/drivers/rtc/mk48t59.c
index b6c234e..dabf322 100644
--- a/drivers/rtc/mk48t59.c
+++ b/drivers/rtc/mk48t59.c
@@ -227,7 +227,7 @@ void rtc_reset (void)
rtc_write(RTC_CONTROLB, control_b);
}
-int rtc_set_watchdog(short multi, short res)
+void rtc_set_watchdog(short multi, short res)
{
uchar wd_value;
diff --git a/drivers/rtc/rs5c372.c b/drivers/rtc/rs5c372.c
index 34514d0..82dd969 100644
--- a/drivers/rtc/rs5c372.c
+++ b/drivers/rtc/rs5c372.c
@@ -195,8 +195,7 @@ rtc_get (struct rtc_time *tmp)
/*
* Set the RTC
*/
-void
-rtc_set (struct rtc_time *tmp)
+int rtc_set (struct rtc_time *tmp)
{
unsigned char buf[8], reg15;
int ret;
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index f30014d..eafe543 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -33,13 +33,13 @@ COBJS-$(CONFIG_DRIVER_S3C4510_UART) += s3c4510b_uart.o
COBJS-$(CONFIG_S3C64XX) += s3c64xx.o
COBJS-y += serial.o
COBJS-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o
-COBJS-y += serial_pl010.o
-COBJS-y += serial_pl011.o
+COBJS-$(CONFIG_PL010_SERIAL) += serial_pl01x.o
+COBJS-$(CONFIG_PL011_SERIAL) += serial_pl01x.o
COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o
COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o
COBJS-$(CONFIG_USB_TTY) += usbtty.o
-COBJS := $(COBJS-y)
+COBJS := $(sort $(COBJS-y))
SRCS := $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
diff --git a/drivers/serial/serial_pl011.c b/drivers/serial/serial_pl011.c
deleted file mode 100644
index 4d35fe5..0000000
--- a/drivers/serial/serial_pl011.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * (C) Copyright 2000
- * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
- *
- * (C) Copyright 2004
- * ARM Ltd.
- * Philippe Robin, <philippe.robin@arm.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/* Simple U-Boot driver for the PrimeCell PL011 UARTs on the IntegratorCP */
-/* Should be fairly simple to make it work with the PL010 as well */
-
-#include <common.h>
-
-#ifdef CFG_PL011_SERIAL
-
-#include "serial_pl011.h"
-
-#define IO_WRITE(addr, val) (*(volatile unsigned int *)(addr) = (val))
-#define IO_READ(addr) (*(volatile unsigned int *)(addr))
-
-/*
- * IntegratorCP has two UARTs, use the first one, at 38400-8-N-1
- * Versatile PB has four UARTs.
- */
-
-#define CONSOLE_PORT CONFIG_CONS_INDEX
-#define baudRate CONFIG_BAUDRATE
-static volatile unsigned char *const port[] = CONFIG_PL01x_PORTS;
-#define NUM_PORTS (sizeof(port)/sizeof(port[0]))
-
-static void pl011_putc (int portnum, char c);
-static int pl011_getc (int portnum);
-static int pl011_tstc (int portnum);
-
-
-int serial_init (void)
-{
- unsigned int temp;
- unsigned int divider;
- unsigned int remainder;
- unsigned int fraction;
-
- /*
- ** First, disable everything.
- */
- IO_WRITE (port[CONSOLE_PORT] + UART_PL011_CR, 0x0);
-
- /*
- ** Set baud rate
- **
- ** IBRD = UART_CLK / (16 * BAUD_RATE)
- ** FBRD = ROUND((64 * MOD(UART_CLK,(16 * BAUD_RATE))) / (16 * BAUD_RATE))
- */
- temp = 16 * baudRate;
- divider = CONFIG_PL011_CLOCK / temp;
- remainder = CONFIG_PL011_CLOCK % temp;
- temp = (8 * remainder) / baudRate;
- fraction = (temp >> 1) + (temp & 1);
-
- IO_WRITE (port[CONSOLE_PORT] + UART_PL011_IBRD, divider);
- IO_WRITE (port[CONSOLE_PORT] + UART_PL011_FBRD, fraction);
-
- /*
- ** Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled.
- */
- IO_WRITE (port[CONSOLE_PORT] + UART_PL011_LCRH,
- (UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN));
-
- /*
- ** Finally, enable the UART
- */
- IO_WRITE (port[CONSOLE_PORT] + UART_PL011_CR,
- (UART_PL011_CR_UARTEN | UART_PL011_CR_TXE |
- UART_PL011_CR_RXE));
-
- return 0;
-}
-
-void serial_putc (const char c)
-{
- if (c == '\n')
- pl011_putc (CONSOLE_PORT, '\r');
-
- pl011_putc (CONSOLE_PORT, c);
-}
-
-void serial_puts (const char *s)
-{
- while (*s) {
- serial_putc (*s++);
- }
-}
-
-int serial_getc (void)
-{
- return pl011_getc (CONSOLE_PORT);
-}
-
-int serial_tstc (void)
-{
- return pl011_tstc (CONSOLE_PORT);
-}
-
-void serial_setbrg (void)
-{
-}
-
-static void pl011_putc (int portnum, char c)
-{
- /* Wait until there is space in the FIFO */
- while (IO_READ (port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_TXFF);
-
- /* Send the character */
- IO_WRITE (port[portnum] + UART_PL01x_DR, c);
-}
-
-static int pl011_getc (int portnum)
-{
- unsigned int data;
-
- /* Wait until there is data in the FIFO */
- while (IO_READ (port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_RXFE);
-
- data = IO_READ (port[portnum] + UART_PL01x_DR);
-
- /* Check for an error flag */
- if (data & 0xFFFFFF00) {
- /* Clear the error */
- IO_WRITE (port[portnum] + UART_PL01x_ECR, 0xFFFFFFFF);
- return -1;
- }
-
- return (int) data;
-}
-
-static int pl011_tstc (int portnum)
-{
- return !(IO_READ (port[portnum] + UART_PL01x_FR) &
- UART_PL01x_FR_RXFE);
-}
-
-#endif
diff --git a/drivers/serial/serial_pl010.c b/drivers/serial/serial_pl01x.c
index 134ed09..c645cef 100644
--- a/drivers/serial/serial_pl010.c
+++ b/drivers/serial/serial_pl01x.c
@@ -25,30 +25,31 @@
* MA 02111-1307 USA
*/
-/* Simple U-Boot driver for the PrimeCell PL011 UARTs on the IntegratorCP */
-/* Should be fairly simple to make it work with the PL010 as well */
+/* Simple U-Boot driver for the PrimeCell PL010/PL011 UARTs */
#include <common.h>
#include <watchdog.h>
-#ifdef CFG_PL010_SERIAL
-
-#include "serial_pl011.h"
+#include "serial_pl01x.h"
#define IO_WRITE(addr, val) (*(volatile unsigned int *)(addr) = (val))
#define IO_READ(addr) (*(volatile unsigned int *)(addr))
-/* Integrator AP has two UARTs, we use the first one, at 38400-8-N-1 */
+/*
+ * Integrator AP has two UARTs, we use the first one, at 38400-8-N-1
+ * Integrator CP has two UARTs, use the first one, at 38400-8-N-1
+ * Versatile PB has four UARTs.
+ */
#define CONSOLE_PORT CONFIG_CONS_INDEX
#define baudRate CONFIG_BAUDRATE
static volatile unsigned char *const port[] = CONFIG_PL01x_PORTS;
#define NUM_PORTS (sizeof(port)/sizeof(port[0]))
+static void pl01x_putc (int portnum, char c);
+static int pl01x_getc (int portnum);
+static int pl01x_tstc (int portnum);
-static void pl010_putc (int portnum, char c);
-static int pl010_getc (int portnum);
-static int pl010_tstc (int portnum);
-
+#ifdef CONFIG_PL010_SERIAL
int serial_init (void)
{
@@ -103,15 +104,64 @@ int serial_init (void)
*/
IO_WRITE (port[CONSOLE_PORT] + UART_PL010_CR, (UART_PL010_CR_UARTEN));
- return (0);
+ return 0;
}
+#endif /* CONFIG_PL010_SERIAL */
+
+#ifdef CONFIG_PL011_SERIAL
+
+int serial_init (void)
+{
+ unsigned int temp;
+ unsigned int divider;
+ unsigned int remainder;
+ unsigned int fraction;
+
+ /*
+ ** First, disable everything.
+ */
+ IO_WRITE (port[CONSOLE_PORT] + UART_PL011_CR, 0x0);
+
+ /*
+ ** Set baud rate
+ **
+ ** IBRD = UART_CLK / (16 * BAUD_RATE)
+ ** FBRD = ROUND((64 * MOD(UART_CLK,(16 * BAUD_RATE))) / (16 * BAUD_RATE))
+ */
+ temp = 16 * baudRate;
+ divider = CONFIG_PL011_CLOCK / temp;
+ remainder = CONFIG_PL011_CLOCK % temp;
+ temp = (8 * remainder) / baudRate;
+ fraction = (temp >> 1) + (temp & 1);
+
+ IO_WRITE (port[CONSOLE_PORT] + UART_PL011_IBRD, divider);
+ IO_WRITE (port[CONSOLE_PORT] + UART_PL011_FBRD, fraction);
+
+ /*
+ ** Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled.
+ */
+ IO_WRITE (port[CONSOLE_PORT] + UART_PL011_LCRH,
+ (UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN));
+
+ /*
+ ** Finally, enable the UART
+ */
+ IO_WRITE (port[CONSOLE_PORT] + UART_PL011_CR,
+ (UART_PL011_CR_UARTEN | UART_PL011_CR_TXE |
+ UART_PL011_CR_RXE));
+
+ return 0;
+}
+
+#endif /* CONFIG_PL011_SERIAL */
+
void serial_putc (const char c)
{
if (c == '\n')
- pl010_putc (CONSOLE_PORT, '\r');
+ pl01x_putc (CONSOLE_PORT, '\r');
- pl010_putc (CONSOLE_PORT, c);
+ pl01x_putc (CONSOLE_PORT, c);
}
void serial_puts (const char *s)
@@ -123,19 +173,19 @@ void serial_puts (const char *s)
int serial_getc (void)
{
- return pl010_getc (CONSOLE_PORT);
+ return pl01x_getc (CONSOLE_PORT);
}
int serial_tstc (void)
{
- return pl010_tstc (CONSOLE_PORT);
+ return pl01x_tstc (CONSOLE_PORT);
}
void serial_setbrg (void)
{
}
-static void pl010_putc (int portnum, char c)
+static void pl01x_putc (int portnum, char c)
{
/* Wait until there is space in the FIFO */
while (IO_READ (port[portnum] + UART_PL01x_FR) & UART_PL01x_FR_TXFF)
@@ -145,7 +195,7 @@ static void pl010_putc (int portnum, char c)
IO_WRITE (port[portnum] + UART_PL01x_DR, c);
}
-static int pl010_getc (int portnum)
+static int pl01x_getc (int portnum)
{
unsigned int data;
@@ -165,11 +215,9 @@ static int pl010_getc (int portnum)
return (int) data;
}
-static int pl010_tstc (int portnum)
+static int pl01x_tstc (int portnum)
{
WATCHDOG_RESET();
return !(IO_READ (port[portnum] + UART_PL01x_FR) &
UART_PL01x_FR_RXFE);
}
-
-#endif
diff --git a/drivers/serial/serial_pl011.h b/drivers/serial/serial_pl01x.h
index 5f20fdd..5f20fdd 100644
--- a/drivers/serial/serial_pl011.h
+++ b/drivers/serial/serial_pl01x.h
diff --git a/drivers/usb/usb_ohci.c b/drivers/usb/usb_ohci.c
index fd5567f..da11ecb 100644
--- a/drivers/usb/usb_ohci.c
+++ b/drivers/usb/usb_ohci.c
@@ -1943,7 +1943,9 @@ int usb_lowlevel_stop(void)
if(usb_cpu_stop())
return -1;
#endif
-
+ /* This driver is no longer initialised. It needs a new low-level
+ * init (board/cpu) before it can be used again. */
+ ohci_inited = 0;
return 0;
}
#endif /* CONFIG_USB_OHCI_NEW */
diff --git a/examples/82559_eeprom.c b/examples/82559_eeprom.c
index 1a121d4..d99af26 100644
--- a/examples/82559_eeprom.c
+++ b/examples/82559_eeprom.c
@@ -51,13 +51,17 @@ static inline unsigned short swap16(unsigned short x)
}
-static inline void *memcpy(void *dst, const void *src, unsigned int len)
+void * memcpy(void * dest,const void *src,size_t count)
{
- void * ret = dst;
- while (len-- > 0) *((char *)dst)++ = *((char *)src)++;
- return ret;
+ char *tmp = (char *) dest, *s = (char *) src;
+
+ while (count--)
+ *tmp++ = *s++;
+
+ return dest;
}
+
/* The EEPROM commands include the alway-set leading bit. */
#define EE_WRITE_CMD (5)
#define EE_READ_CMD (6)
@@ -156,7 +160,7 @@ static int reset_eeprom(unsigned long ioaddr, unsigned char *hwaddr)
int size_test;
int i;
- printf("Resetting i82559 EEPROM @ 0x%08x ... ", ioaddr);
+ printf("Resetting i82559 EEPROM @ 0x%08lx ... ", ioaddr);
size_test = do_eeprom_cmd(ioaddr, (EE_READ_CMD << 8) << 16, 27);
eeprom_addr_size = (size_test & 0xffe0000) == 0xffe0000 ? 8 : 6;
@@ -305,7 +309,7 @@ write_config_word(int bus, int dev, int func, int reg, u16 data)
int main (int argc, char *argv[])
{
unsigned char *eth_addr;
- char buf[6];
+ uchar buf[6];
int instance;
app_startup(argv);
diff --git a/include/asm-i386/byteorder.h b/include/asm-i386/byteorder.h
index a9c69d5..7dfeb8b 100644
--- a/include/asm-i386/byteorder.h
+++ b/include/asm-i386/byteorder.h
@@ -6,7 +6,7 @@
#ifdef __GNUC__
-static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
+static __inline__ __u32 ___arch__swab32(__u32 x)
{
#ifdef CONFIG_X86_BSWAP
__asm__("bswap %0" : "=r" (x) : "0" (x));
@@ -20,7 +20,7 @@ static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
return x;
}
-static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
+static __inline__ __u16 ___arch__swab16(__u16 x)
{
__asm__("xchgb %b0,%h0" /* swap bytes */ \
: "=q" (x) \
diff --git a/include/asm-i386/global_data.h b/include/asm-i386/global_data.h
index 35bad23..cc30689 100644
--- a/include/asm-i386/global_data.h
+++ b/include/asm-i386/global_data.h
@@ -59,8 +59,8 @@ typedef struct {
#define GD_FLG_LOGINIT 0x00020 /* Log Buffer has been initialized */
#define GD_FLG_DISABLE_CONSOLE 0x00040 /* Disable console (in & out) */
-extern gd_t *global_data;
+extern gd_t *gd;
-#define DECLARE_GLOBAL_DATA_PTR gd_t *gd = global_data
+#define DECLARE_GLOBAL_DATA_PTR
#endif /* __ASM_GBL_DATA_H */
diff --git a/include/asm-i386/ic/ssi.h b/include/asm-i386/ic/ssi.h
new file mode 100644
index 0000000..bd48eab
--- /dev/null
+++ b/include/asm-i386/ic/ssi.h
@@ -0,0 +1,34 @@
+/*
+ * (C) Copyright 2008
+ * Graeme Russ <graeme.russ@gmail.com>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _ASM_IC_SSI_H_
+#define _ASM_IC_SSI_H_ 1
+
+int ssi_set_interface(int, int, int, int);
+void ssi_chip_select(int);
+u8 ssi_txrx_byte(u8);
+void ssi_tx_byte(u8);
+u8 ssi_rx_byte(void);
+
+
+#endif
diff --git a/include/asm-i386/pci.h b/include/asm-i386/pci.h
index bde9550..050a2bb 100644
--- a/include/asm-i386/pci.h
+++ b/include/asm-i386/pci.h
@@ -31,5 +31,4 @@ int pci_enable_legacy_video_ports(struct pci_controller* hose);
int pci_shadow_rom(pci_dev_t dev, unsigned char *dest);
void pci_remove_rom_window(struct pci_controller* hose, u32 addr);
u32 pci_get_rom_window(struct pci_controller* hose, int size);
-
#endif
diff --git a/include/asm-i386/string.h b/include/asm-i386/string.h
index 91a23f9..3643a79 100644
--- a/include/asm-i386/string.h
+++ b/include/asm-i386/string.h
@@ -5,6 +5,8 @@
* We don't do inline string functions, since the
* optimised inline asm versions are not small.
*/
+#undef __HAVE_ARCH_STRNCPY
+extern char *strncpy(char *__dest, __const__ char *__src, __kernel_size_t __n);
#undef __HAVE_ARCH_STRRCHR
extern char * strrchr(const char * s, int c);
diff --git a/include/asm-ppc/ppc4xx-sdram.h b/include/asm-ppc/ppc4xx-sdram.h
index 0174d62..8efa557 100644
--- a/include/asm-ppc/ppc4xx-sdram.h
+++ b/include/asm-ppc/ppc4xx-sdram.h
@@ -29,6 +29,7 @@
/*
* SDRAM Controller
*/
+
/*
* XXX - ToDo: Revisit file to change all these lower case defines into
* upper case. Also needs to be done in the controller setup code too
@@ -256,6 +257,7 @@
#define SDRAM_DLYCAL_DLCV_ENCODE(x) (((x)<<2) & SDRAM_DLYCAL_DLCV_MASK)
#define SDRAM_DLYCAL_DLCV_DECODE(x) (((x) & SDRAM_DLYCAL_DLCV_MASK)>>2)
+#if !defined(CONFIG_405EX)
/*
* Memory queue defines
*/
@@ -293,7 +295,6 @@
#define SDRAM_PLBADDUHB (SDRAMQ_DCR_BASE+0x10) /* PLB base address upper 32 LL */
-#if !defined(CONFIG_405EX)
/*
* Memory Bank 0-7 configuration
*/
@@ -1401,4 +1402,18 @@
#endif /* CONFIG_SDRAM_PPC4xx_DENALI_DDR2 */
+#ifndef __ASSEMBLY__
+/*
+ * Prototypes
+ */
+void inline blank_string(int size);
+inline void ppc4xx_ibm_ddr2_register_dump(void);
+u32 mfdcr_any(u32);
+void mtdcr_any(u32, u32);
+u32 ddr_wrdtr(u32);
+u32 ddr_clktr(u32);
+void spd_ddr_init_hang(void);
+u32 DQS_autocalibration(void);
+#endif /* __ASSEMBLY__ */
+
#endif /* _PPC4xx_SDRAM_H_ */
diff --git a/include/common.h b/include/common.h
index a394988..33c6e10 100644
--- a/include/common.h
+++ b/include/common.h
@@ -236,6 +236,9 @@ int autoscript (ulong addr, const char *fit_uname);
extern ulong load_addr; /* Default Load Address */
+/* common/cmd_doc.c */
+void doc_probe(unsigned long physadr);
+
/* common/cmd_nvedit.c */
int env_init (void);
void env_relocate (void);
diff --git a/include/configs/CPCI4052.h b/include/configs/CPCI4052.h
index fd49f56..9ec1721 100644
--- a/include/configs/CPCI4052.h
+++ b/include/configs/CPCI4052.h
@@ -146,6 +146,8 @@
#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+#define CONFIG_CMDLINE_EDITING /* add command line history */
+
#define CONFIG_LOOPW 1 /* enable loopw command */
#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */
@@ -219,6 +221,10 @@
* the maximum mapped by the Linux kernel during initialization.
*/
#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+
+#define CONFIG_OF_LIBFDT
+#define CONFIG_OF_BOARD_SETUP
+
/*-----------------------------------------------------------------------
* FLASH organization
*/
diff --git a/include/configs/CPCI405AB.h b/include/configs/CPCI405AB.h
index 55dd629..7899598 100644
--- a/include/configs/CPCI405AB.h
+++ b/include/configs/CPCI405AB.h
@@ -144,6 +144,8 @@
#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+#define CONFIG_CMDLINE_EDITING /* add command line history */
+
#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */
#define CONFIG_VERSION_VARIABLE 1 /* include version env variable */
@@ -215,6 +217,10 @@
* the maximum mapped by the Linux kernel during initialization.
*/
#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
+
+#define CONFIG_OF_LIBFDT
+#define CONFIG_OF_BOARD_SETUP
+
/*-----------------------------------------------------------------------
* FLASH organization
*/
diff --git a/include/configs/NETPHONE.h b/include/configs/NETPHONE.h
index 6c18b81..1494190 100644
--- a/include/configs/NETPHONE.h
+++ b/include/configs/NETPHONE.h
@@ -487,8 +487,6 @@
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
#define BOOTFLAG_WARM 0x02 /* Software reboot */
-#define CONFIG_ARTOS /* include ARTOS support */
-
#define CONFIG_LAST_STAGE_INIT /* needed to reset the damn phys */
/****************************************************************/
diff --git a/include/configs/NETTA.h b/include/configs/NETTA.h
index 1f1bc54..6480634 100644
--- a/include/configs/NETTA.h
+++ b/include/configs/NETTA.h
@@ -496,8 +496,6 @@
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
#define BOOTFLAG_WARM 0x02 /* Software reboot */
-#define CONFIG_ARTOS /* include ARTOS support */
-
#define CONFIG_LAST_STAGE_INIT /* needed to reset the damn phys */
/***********************************************************************************************************
diff --git a/include/configs/NETTA2.h b/include/configs/NETTA2.h
index 9a1f1d6..efa91e3 100644
--- a/include/configs/NETTA2.h
+++ b/include/configs/NETTA2.h
@@ -488,8 +488,6 @@
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */
#define BOOTFLAG_WARM 0x02 /* Software reboot */
-#define CONFIG_ARTOS /* include ARTOS support */
-
#define CONFIG_LAST_STAGE_INIT /* needed to reset the damn phys */
/****************************************************************/
@@ -745,7 +743,6 @@ typedef unsigned int led_id_t;
/* use board specific hardware */
#undef CONFIG_WATCHDOG /* watchdog disabled */
#define CONFIG_HW_WATCHDOG
-#define CONFIG_SHOW_ACTIVITY
/*************************************************************************************************/
diff --git a/include/configs/NETVIA.h b/include/configs/NETVIA.h
index c029594..40e09fb 100644
--- a/include/configs/NETVIA.h
+++ b/include/configs/NETVIA.h
@@ -357,8 +357,6 @@
/* Ethernet at SCC2 */
#define CONFIG_SCC2_ENET
-#define CONFIG_ARTOS /* include ARTOS support */
-
/****************************************************************/
#define DSP_SIZE 0x00010000 /* 64K */
diff --git a/include/configs/PIP405.h b/include/configs/PIP405.h
index 2ceda00..86ea6c6 100644
--- a/include/configs/PIP405.h
+++ b/include/configs/PIP405.h
@@ -281,7 +281,6 @@
***********************************************************/
#define CONFIG_MII 1 /* MII PHY management */
#define CONFIG_PHY_ADDR 1 /* PHY address */
-#define CONFIG_CS8952_PHY 1 /* its a CS8952 PHY */
/************************************************************
* RTC
***********************************************************/
diff --git a/include/configs/integratorap.h b/include/configs/integratorap.h
index 1452bf2..ba3c531 100644
--- a/include/configs/integratorap.h
+++ b/include/configs/integratorap.h
@@ -58,7 +58,7 @@
/*
* PL010 Configuration
*/
-#define CFG_PL010_SERIAL
+#define CONFIG_PL010_SERIAL
#define CONFIG_CONS_INDEX 0
#define CONFIG_BAUDRATE 38400
#define CONFIG_PL01x_PORTS { (void *) (CFG_SERIAL0), (void *) (CFG_SERIAL1) }
diff --git a/include/configs/integratorcp.h b/include/configs/integratorcp.h
index 347fa02..5340f7c 100644
--- a/include/configs/integratorcp.h
+++ b/include/configs/integratorcp.h
@@ -61,7 +61,7 @@
/*
* NS16550 Configuration
*/
-#define CFG_PL011_SERIAL
+#define CONFIG_PL011_SERIAL
#define CONFIG_PL011_CLOCK 14745600
#define CONFIG_PL01x_PORTS { (void *)CFG_SERIAL0, (void *)CFG_SERIAL1 }
#define CONFIG_CONS_INDEX 0
diff --git a/include/configs/kilauea.h b/include/configs/kilauea.h
index a475f97..f9eaa77 100644
--- a/include/configs/kilauea.h
+++ b/include/configs/kilauea.h
@@ -223,6 +223,22 @@
*----------------------------------------------------------------------*/
#define CFG_MBYTES_SDRAM (256) /* 256MB */
+/*
+ * CONFIG_PPC4xx_DDR_AUTOCALIBRATION
+ *
+ * Note: DDR Autocalibration Method_A scans the full range of possible PPC4xx
+ * SDRAM Controller DDR autocalibration values and takes a lot longer
+ * to run than Method_B.
+ * (See the Method_A and Method_B algorithm discription in the file:
+ * cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c)
+ * Define CONFIG_PPC4xx_DDR_METHOD_A to use DDR autocalibration Method_A
+ *
+ * DDR Autocalibration Method_B is the default.
+ */
+#define CONFIG_PPC4xx_DDR_AUTOCALIBRATION /* IBM DDR autocalibration */
+#define DEBUG_PPC4xx_DDR_AUTOCALIBRATION /* dynamic DDR autocal debug */
+#undef CONFIG_PPC4xx_DDR_METHOD_A
+
#define CFG_SDRAM0_MB0CF_BASE (( 0 << 20) + CFG_SDRAM_BASE)
/* DDR1/2 SDRAM Device Control Register Data Values */
@@ -386,6 +402,9 @@
#define CONFIG_HAS_ETH1 1 /* add support for "eth1addr" */
#define CONFIG_PHY1_ADDR 2
+/* Debug messages for the DDR autocalibration */
+#define CONFIG_AUTOCALIB "silent\0" /* default is non-verbose */
+
/*
* Default environment variables
*/
diff --git a/include/configs/ml507.h b/include/configs/ml507.h
index f8cd499..37d93bb 100644
--- a/include/configs/ml507.h
+++ b/include/configs/ml507.h
@@ -17,106 +17,33 @@
#ifndef __CONFIG_H
#define __CONFIG_H
-/*
-#define DEBUG
-#define ET_DEBUG
-*/
- /*CPU*/
-#define CONFIG_XILINX_ML507 1
-#define CONFIG_XILINX_440 1
+
+/*CPU*/
#define CONFIG_440 1
-#define CONFIG_4xx 1
+#define CONFIG_XILINX_ML507 1
#include "../board/xilinx/ml507/xparameters.h"
/*Mem Map*/
-#define CFG_SDRAM_BASE 0x0
#define CFG_SDRAM_SIZE_MB 256
-#define CFG_MONITOR_BASE TEXT_BASE
-#define CFG_MONITOR_LEN ( 192 * 1024 )
-#define CFG_MALLOC_LEN ( CFG_ENV_SIZE + 128 * 1024 )
-
-/*Uart*/
-#define CONFIG_XILINX_UARTLITE
-#define CONFIG_BAUDRATE XPAR_UARTLITE_0_BAUDRATE
-#define CFG_BAUDRATE_TABLE { XPAR_UARTLITE_0_BAUDRATE }
-#define CONFIG_SERIAL_BASE XPAR_UARTLITE_0_BASEADDR
-
-/*Cmd*/
-#include <config_cmd_default.h>
-#define CONFIG_CMD_ASKENV
-#define CONFIG_CMD_CACHE
-#define CONFIG_CMD_DIAG
-#define CONFIG_CMD_ELF
-#define CONFIG_CMD_IRQ
-#define CONFIG_CMD_REGINFO
-#define CONFIG_CMD_JFFS2
-#define CONFIG_JFFS2_CMDLINE
-#undef CONFIG_CMD_I2C
-#undef CONFIG_CMD_DTT
-#undef CONFIG_CMD_NET
-#undef CONFIG_CMD_PING
-#undef CONFIG_CMD_DHCP
-#undef CONFIG_CMD_EEPROM
-#undef CONFIG_CMD_IMLS
/*Env*/
-#define CFG_ENV_IS_IN_FLASH
+#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_SIZE 0x20000
#define CFG_ENV_SECT_SIZE 0x20000
-#define CFG_ENV_OFFSET 0x340000
-#define CFG_ENV_ADDR (XPAR_FLASH_MEM0_BASEADDR+CFG_ENV_OFFSET)
+#define CFG_ENV_OFFSET 0x340000
+#define CFG_ENV_ADDR (XPAR_FLASH_MEM0_BASEADDR+CFG_ENV_OFFSET)
/*Misc*/
-#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */
-#define CFG_LONGHELP /* undef to save memory */
-#define CFG_PROMPT "board:/# " /* Monitor Command Prompt */
-#if defined(CONFIG_CMD_KGDB)
-#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
-#else
-#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
-#endif
-#define CFG_PBSIZE ( CFG_CBSIZE + sizeof( CFG_PROMPT ) + 16 )
-#define CFG_MAXARGS 16 /* max number of command args */
-#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
-#define CFG_MEMTEST_START 0x00400000 /* memtest works on */
-#define CFG_MEMTEST_END 0x00C00000 /* 4 ... 12 MB in DRAM */
-#define CFG_LOAD_ADDR 0x00400000 /* default load address */
-#define CFG_EXTBDINFO 1 /* Extended board_into (bd_t) */
-#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
-#define CONFIG_CMDLINE_EDITING /* add command line history */
-#define CONFIG_AUTO_COMPLETE /* add autocompletion support */
-#define CONFIG_LOOPW /* enable loopw command */
-#define CONFIG_MX_CYCLIC /* enable mdc/mwc commands */
-#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */
-#define CONFIG_VERSION_VARIABLE /* include version env variable */
-#define CFG_CONSOLE_INFO_QUIET /* don't print console @ startup */
-#define CFG_HUSH_PARSER /* Use the HUSH parser */
-#define CFG_PROMPT_HUSH_PS2 "> "
-#define CONFIG_LOADS_ECHO /* echo on for serial download */
-#define CFG_LOADS_BAUD_CHANGE /* allow baudrate change */
-#define CFG_BOOTMAPSZ ( 8 << 20 ) /* Initial Memory map for Linux */
+#define CFG_PROMPT "ml507:/# " /* Monitor Command Prompt */
#define CONFIG_PREBOOT "echo U-Boot is up and runnining;"
-/*Stack*/
-#define CFG_INIT_RAM_ADDR 0x800000 /* Initial RAM address */
-#define CFG_INIT_RAM_END 0x2000 /* End of used area in RAM */
-#define CFG_GBL_DATA_SIZE 128 /* num bytes initial data */
-#define CFG_GBL_DATA_OFFSET ( CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE )
-#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
-/*Speed*/
-#define CONFIG_SYS_CLK_FREQ XPAR_CORE_CLOCK_FREQ_HZ
-
/*Flash*/
-#define CFG_FLASH_BASE XPAR_FLASH_MEM0_BASEADDR
#define CFG_FLASH_SIZE (32*1024*1024)
-#define CFG_FLASH_CFI 1
-#define CONFIG_FLASH_CFI_DRIVER 1
-#define CFG_FLASH_EMPTY_INFO 1
-#define CFG_MAX_FLASH_BANKS 1
#define CFG_MAX_FLASH_SECT 259
-#define CFG_FLASH_PROTECTION
#define MTDIDS_DEFAULT "nor0=ml507-flash"
#define MTDPARTS_DEFAULT "mtdparts=ml507-flash:-(user)"
+/*Generic Configs*/
+#include <configs/xilinx-ppc440.h>
#endif /* __CONFIG_H */
diff --git a/include/configs/sc520_cdp.h b/include/configs/sc520_cdp.h
index e29655e..dfe7b7d 100644
--- a/include/configs/sc520_cdp.h
+++ b/include/configs/sc520_cdp.h
@@ -28,6 +28,7 @@
#ifndef __CONFIG_H
#define __CONFIG_H
+#define GRUSS_TESTING
/*
* High Level Configuration Options
* (easy to change)
@@ -81,7 +82,11 @@
#include <config_cmd_default.h>
#define CONFIG_CMD_PCI
+#ifndef GRUSS_TESTING
#define CONFIG_CMD_SATA
+#else
+#undef CONFIG_CMD_SATA
+#endif
#define CONFIG_CMD_JFFS2
#define CONFIG_CMD_NET
#define CONFIG_CMD_EEPROM
@@ -175,10 +180,18 @@
/************************************************************
*SATA/Native Stuff
************************************************************/
+#ifndef GRUSS_TESTING
#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_MAX_DEVICE (CFG_SATA_MAXBUS* CFG_SATA_DEVS_PER_BUS)
#define CONFIG_ATA_PIIX 1 /*Supports ata_piix driver */
+#else
+#undef CFG_SATA_MAXBUS
+#undef CFG_SATA_DEVS_PER_BUS
+#undef CFG_SATA_MAX_DEVICE
+#undef CONFIG_ATA_PIIX
+#endif
+
/************************************************************
* DISK Partition support
@@ -190,7 +203,11 @@
/************************************************************
* Video/Keyboard support
************************************************************/
+#ifndef GRUSS_TESTING
#define CONFIG_VIDEO /* To enable video controller support */
+#else
+#undef CONFIG_VIDEO
+#endif
#define CONFIG_I8042_KBD
#define CFG_ISA_IO 0
@@ -203,6 +220,7 @@
/*
* PCI stuff
*/
+#ifndef GRUSS_TESTING
#define CONFIG_PCI /* include pci support */
#define CONFIG_PCI_PNP /* pci plug-and-play */
#define CONFIG_PCI_SCAN_SHOW
@@ -211,5 +229,11 @@
#define CFG_SECOND_PCI_IRQ 9
#define CFG_THIRD_PCI_IRQ 11
#define CFG_FORTH_PCI_IRQ 15
+#else
+#undef CONFIG_PCI
+#undef CONFIG_PCI_PNP
+#undef CONFIG_PCI_SCAN_SHOW
+#endif
+
#endif /* __CONFIG_H */
diff --git a/include/configs/stxxtc.h b/include/configs/stxxtc.h
index 37a52cf..0dc9f8a 100644
--- a/include/configs/stxxtc.h
+++ b/include/configs/stxxtc.h
@@ -580,7 +580,6 @@ typedef unsigned int led_id_t;
/* use board specific hardware */
#undef CONFIG_WATCHDOG /* watchdog disabled */
#define CONFIG_HW_WATCHDOG
-#define CONFIG_SHOW_ACTIVITY
/*****************************************************************************/
diff --git a/include/configs/v5fx30teval.h b/include/configs/v5fx30teval.h
new file mode 100644
index 0000000..67d8d7f
--- /dev/null
+++ b/include/configs/v5fx30teval.h
@@ -0,0 +1,49 @@
+/*
+ * (C) Copyright 2008
+ * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es
+ * This work has been supported by: QTechnology http://qtec.com/
+ * 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*CPU*/
+#define CONFIG_440 1
+#define CONFIG_XILINX_ML507 1
+#include "../board/avnet/v5fx30teval/xparameters.h"
+
+/*Mem Map*/
+#define CFG_SDRAM_SIZE_MB 64
+
+/*Env*/
+#define CFG_ENV_IS_IN_FLASH 1
+#define CFG_ENV_SIZE 0x20000
+#define CFG_ENV_SECT_SIZE 0x20000
+#define CFG_ENV_OFFSET 0x1A0000
+#define CFG_ENV_ADDR (XPAR_FLASH_MEM0_BASEADDR+CFG_ENV_OFFSET)
+
+/*Misc*/
+#define CFG_PROMPT "v5fx30t:/# " /* Monitor Command Prompt */
+#define CONFIG_PREBOOT "echo U-Boot is up and runnining;"
+
+/*Flash*/
+#define CFG_FLASH_SIZE (16*1024*1024)
+#define CFG_MAX_FLASH_SECT 131
+#define MTDIDS_DEFAULT "nor0=v5fx30t-flash"
+#define MTDPARTS_DEFAULT "mtdparts=v5fx30t-flash:-(user)"
+
+/*Generic Configs*/
+#include <configs/xilinx-ppc440.h>
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/versatile.h b/include/configs/versatile.h
index a88d356..c18a248 100644
--- a/include/configs/versatile.h
+++ b/include/configs/versatile.h
@@ -86,7 +86,7 @@
/*
* NS16550 Configuration
*/
-#define CFG_PL011_SERIAL
+#define CONFIG_PL011_SERIAL
#define CONFIG_PL011_CLOCK 24000000
#define CONFIG_PL01x_PORTS { (void *)CFG_SERIAL0, (void *)CFG_SERIAL1 }
#define CONFIG_CONS_INDEX 0
diff --git a/include/configs/xilinx-ppc440-generic.h b/include/configs/xilinx-ppc440-generic.h
new file mode 100644
index 0000000..4e8080b
--- /dev/null
+++ b/include/configs/xilinx-ppc440-generic.h
@@ -0,0 +1,49 @@
+/*
+ * (C) Copyright 2008
+ * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es
+ * This work has been supported by: QTechnology http://qtec.com/
+ * 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*CPU*/
+#define CONFIG_440 1
+#define CONFIG_XILINX_PPC440_GENERIC 1
+#include "../board/xilinx/ppc440-generic/xparameters.h"
+
+/*Mem Map*/
+#define CFG_SDRAM_SIZE_MB 256
+
+/*Env*/
+#define CFG_ENV_IS_IN_FLASH 1
+#define CFG_ENV_SIZE 0x20000
+#define CFG_ENV_SECT_SIZE 0x20000
+#define CFG_ENV_OFFSET 0x340000
+#define CFG_ENV_ADDR (XPAR_FLASH_MEM0_BASEADDR+CFG_ENV_OFFSET)
+
+/*Misc*/
+#define CFG_PROMPT "board:/# " /* Monitor Command Prompt */
+#define CONFIG_PREBOOT "echo U-Boot is up and runnining;"
+
+/*Flash*/
+#define CFG_FLASH_SIZE (32*1024*1024)
+#define CFG_MAX_FLASH_SECT 259
+#define MTDIDS_DEFAULT "nor0=ml507-flash"
+#define MTDPARTS_DEFAULT "mtdparts=ml507-flash:-(user)"
+
+/*Generic Configs*/
+#include <configs/xilinx-ppc440.h>
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/xilinx-ppc440.h b/include/configs/xilinx-ppc440.h
new file mode 100644
index 0000000..40293cd
--- /dev/null
+++ b/include/configs/xilinx-ppc440.h
@@ -0,0 +1,106 @@
+/*
+ * (C) Copyright 2008
+ * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es
+ * This work has been supported by: QTechnology http://qtec.com/
+ * 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __CONFIG_GEN_H
+#define __CONFIG_GEN_H
+/*
+#define DEBUG
+#define ET_DEBUG
+*/
+ /*CPU*/
+#define CONFIG_XILINX_440 1
+#define CONFIG_440 1
+#define CONFIG_4xx 1
+
+/*Mem Map*/
+#define CFG_SDRAM_BASE 0x0
+#define CFG_MONITOR_BASE TEXT_BASE
+#define CFG_MONITOR_LEN (192 * 1024)
+#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128 * 1024)
+
+/*Uart*/
+#define CONFIG_XILINX_UARTLITE
+#define CONFIG_BAUDRATE XPAR_UARTLITE_0_BAUDRATE
+#define CFG_BAUDRATE_TABLE { XPAR_UARTLITE_0_BAUDRATE }
+#define CONFIG_SERIAL_BASE XPAR_UARTLITE_0_BASEADDR
+
+/*Cmd*/
+#include <config_cmd_default.h>
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_ELF
+#define CONFIG_CMD_IRQ
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_JFFS2
+#define CONFIG_JFFS2_CMDLINE
+#undef CONFIG_CMD_SPI
+#undef CONFIG_CMD_I2C
+#undef CONFIG_CMD_DTT
+#undef CONFIG_CMD_NET
+#undef CONFIG_CMD_PING
+#undef CONFIG_CMD_DHCP
+#undef CONFIG_CMD_EEPROM
+#undef CONFIG_CMD_IMLS
+
+/*Misc*/
+#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */
+#define CFG_LONGHELP /* undef to save memory */
+#if defined(CONFIG_CMD_KGDB)
+#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */
+#else
+#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16)
+#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
+#define CFG_MEMTEST_START 0x00400000 /* memtest works on */
+#define CFG_MEMTEST_END 0x00C00000 /* 4 ... 12 MB in DRAM */
+#define CFG_LOAD_ADDR 0x00400000 /* default load address */
+#define CFG_EXTBDINFO 1 /* Extended board_into (bd_t) */
+#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */
+#define CONFIG_CMDLINE_EDITING /* add command line history */
+#define CONFIG_AUTO_COMPLETE /* add autocompletion support */
+#define CONFIG_LOOPW /* enable loopw command */
+#define CONFIG_MX_CYCLIC /* enable mdc/mwc commands */
+#define CONFIG_ZERO_BOOTDELAY_CHECK /* check for keypress on bootdelay==0 */
+#define CONFIG_VERSION_VARIABLE /* include version env variable */
+#define CFG_CONSOLE_INFO_QUIET /* don't print console @ startup */
+#define CFG_HUSH_PARSER /* Use the HUSH parser */
+#define CFG_PROMPT_HUSH_PS2 "> "
+#define CONFIG_LOADS_ECHO /* echo on for serial download */
+#define CFG_LOADS_BAUD_CHANGE /* allow baudrate change */
+#define CFG_BOOTMAPSZ (8 << 20)/* Initial Memory map for Linux */
+
+/*Stack*/
+#define CFG_INIT_RAM_ADDR 0x800000 /* Initial RAM address */
+#define CFG_INIT_RAM_END 0x2000 /* End of used area in RAM */
+#define CFG_GBL_DATA_SIZE 128 /* num bytes initial data */
+#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET
+/*Speed*/
+#define CONFIG_SYS_CLK_FREQ XPAR_CORE_CLOCK_FREQ_HZ
+
+/*Flash*/
+#define CFG_FLASH_BASE XPAR_FLASH_MEM0_BASEADDR
+#define CFG_FLASH_CFI 1
+#define CONFIG_FLASH_CFI_DRIVER 1
+#define CFG_FLASH_EMPTY_INFO 1
+#define CFG_MAX_FLASH_BANKS 1
+#define CFG_FLASH_PROTECTION
+
+#endif /* __CONFIG_H */
diff --git a/include/image.h b/include/image.h
index 9be806e..8c63686 100644
--- a/include/image.h
+++ b/include/image.h
@@ -85,6 +85,7 @@
#define IH_OS_RTEMS 18 /* RTEMS */
#define IH_OS_ARTOS 19 /* ARTOS */
#define IH_OS_UNITY 20 /* Unity OS */
+#define IH_OS_INTEGRITY 21 /* INTEGRITY */
/*
* CPU Architecture Codes (supported by Linux)
@@ -573,6 +574,7 @@ 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_all_image_check_hashes (const void *fit);
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);
diff --git a/include/onenand_uboot.h b/include/onenand_uboot.h
index 6605e4f..e960257 100644
--- a/include/onenand_uboot.h
+++ b/include/onenand_uboot.h
@@ -15,6 +15,7 @@
#define __UBOOT_ONENAND_H
#include <linux/types.h>
+#include <linux/mtd/mtd.h>
struct mtd_info;
struct erase_info;
diff --git a/include/ppc440.h b/include/ppc440.h
index 3584fd2..be8d3ff 100644
--- a/include/ppc440.h
+++ b/include/ppc440.h
@@ -2064,19 +2064,6 @@
#ifndef __ASSEMBLY__
-static inline u32 get_mcsr(void)
-{
- u32 val;
-
- asm volatile("mfspr %0, 0x23c" : "=r" (val) :);
- return val;
-}
-
-static inline void set_mcsr(u32 val)
-{
- asm volatile("mtspr 0x23c, %0" : "=r" (val) :);
-}
-
#endif /* _ASMLANGUAGE */
#endif /* __PPC440_H__ */
diff --git a/include/ppc4xx.h b/include/ppc4xx.h
index 59a3b06..e216663 100644
--- a/include/ppc4xx.h
+++ b/include/ppc4xx.h
@@ -203,6 +203,19 @@ typedef struct
unsigned long pllPlbDiv;
} PPC4xx_SYS_INFO;
+static inline u32 get_mcsr(void)
+{
+ u32 val;
+
+ asm volatile("mfspr %0, 0x23c" : "=r" (val) :);
+ return val;
+}
+
+static inline void set_mcsr(u32 val)
+{
+ asm volatile("mtspr 0x23c, %0" : "=r" (val) :);
+}
+
#endif /* __ASSEMBLY__ */
#endif /* __PPC4XX_H__ */
diff --git a/include/ppc4xx_enet.h b/include/ppc4xx_enet.h
index b74c6fc..00669a7 100644
--- a/include/ppc4xx_enet.h
+++ b/include/ppc4xx_enet.h
@@ -376,6 +376,7 @@ typedef struct emac_4xx_hw_st {
#define EMAC_M1_APP (0x08000000)
#define EMAC_M1_RSVD (0x06000000)
#define EMAC_M1_IST (0x01000000)
+#define EMAC_M1_MF_1000GPCS (0x00C00000)
#define EMAC_M1_MF_1000MBPS (0x00800000) /* 0's for 10MBPS */
#define EMAC_M1_MF_100MBPS (0x00400000)
#define EMAC_M1_RFS_MASK (0x00380000)
@@ -394,6 +395,8 @@ typedef struct emac_4xx_hw_st {
#define EMAC_M1_MWSW (0x00007000)
#define EMAC_M1_JUMBO_ENABLE (0x00000800)
#define EMAC_M1_IPPA (0x000007c0)
+#define EMAC_M1_IPPA_SET(id) (((id) & 0x1f) << 6)
+#define EMAC_M1_IPPA_GET(id) (((id) >> 6) & 0x1f)
#define EMAC_M1_OBCI_GT100 (0x00000020)
#define EMAC_M1_OBCI_100 (0x00000018)
#define EMAC_M1_OBCI_83 (0x00000010)
diff --git a/lib_arm/bootm.c b/lib_arm/bootm.c
index 6c2f37e..772fa7f 100644
--- a/lib_arm/bootm.c
+++ b/lib_arm/bootm.c
@@ -62,7 +62,6 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
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");
@@ -125,7 +124,7 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
theKernel (0, machid, bd->bi_boot_params);
/* does not return */
-error:
+
return 1;
}
diff --git a/lib_i386/bios_setup.c b/lib_i386/bios_setup.c
index 75f04a0..33c842c 100644
--- a/lib_i386/bios_setup.c
+++ b/lib_i386/bios_setup.c
@@ -140,8 +140,9 @@ int bios_setup(void)
{
static int done=0;
int vector;
+#ifdef CONFIG_PCI
struct pci_controller *pri_hose;
-
+#endif
if (done) {
return 0;
}
@@ -223,12 +224,13 @@ int bios_setup(void)
* (This, ofcause break on multi hose systems,
* but our PCI BIOS only support one hose anyway)
*/
+#ifdef CONFIG_PCI
pri_hose = pci_bus_to_hose(0);
if (NULL != pri_hose) {
/* fill in last pci bus number for use by the realmode
* PCI BIOS */
RELOC_16_BYTE(0xf000, pci_last_bus) = pri_hose->last_busno;
}
-
+#endif
return 0;
}
diff --git a/lib_i386/board.c b/lib_i386/board.c
index 55fa42a..f3da0a2 100644
--- a/lib_i386/board.c
+++ b/lib_i386/board.c
@@ -213,7 +213,7 @@ init_fnc_t *init_sequence[] = {
NULL,
};
-gd_t *global_data;
+gd_t *gd;
void start_i386boot (void)
{
@@ -226,7 +226,7 @@ void start_i386boot (void)
show_boot_progress(0x21);
- gd = global_data = &gd_data;
+ gd = &gd_data;
/* compiler optimization barrier needed for GCC >= 3.4 */
__asm__ __volatile__("": : :"memory");
@@ -266,7 +266,7 @@ void start_i386boot (void)
int i;
ulong reg;
char *s, *e;
- uchar tmp[64];
+ char tmp[64];
i = getenv_r ("ethaddr", tmp, sizeof (tmp));
s = (i > 0) ? tmp : NULL;
@@ -412,7 +412,10 @@ void hang (void)
unsigned long do_go_exec (ulong (*entry)(int, char *[]), int argc, char *argv[])
{
/*
- * Nios function pointers are address >> 1
+ * TODO: Test this function - changed to fix compiler error.
+ * Original code was:
+ * return (entry >> 1) (argc, argv);
+ * with a comment about Nios function pointers are address >> 1
*/
- return (entry >> 1) (argc, argv);
+ return (entry) (argc, argv);
}
diff --git a/lib_i386/bootm.c b/lib_i386/bootm.c
index 522d7ad..613e339 100644
--- a/lib_i386/bootm.c
+++ b/lib_i386/bootm.c
@@ -34,7 +34,7 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
void *base_ptr;
ulong os_data, os_len;
image_header_t *hdr;
- int ret;
+
#if defined(CONFIG_FIT)
const void *data;
size_t len;
diff --git a/lib_i386/video_bios.c b/lib_i386/video_bios.c
index 45f78e2..ce96a3e 100644
--- a/lib_i386/video_bios.c
+++ b/lib_i386/video_bios.c
@@ -136,6 +136,8 @@ static u32 probe_pci_video(void)
#endif
+#ifdef CONFIG_VIDEO
+
static int probe_isa_video(void)
{
u32 ptr;
@@ -217,3 +219,4 @@ int video_bios_init(void)
return 1;
}
+#endif
diff --git a/lib_mips/Makefile b/lib_mips/Makefile
index 8176437..7967e58 100644
--- a/lib_mips/Makefile
+++ b/lib_mips/Makefile
@@ -28,7 +28,11 @@ LIB = $(obj)lib$(ARCH).a
SOBJS-y +=
COBJS-y += board.o
+ifeq ($(CONFIG_QEMU_MIPS),y)
+COBJS-y += bootm_qemu_mips.o
+else
COBJS-y += bootm.o
+endif
COBJS-y += time.o
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
diff --git a/lib_mips/bootm.c b/lib_mips/bootm.c
index c1bf21e..dced28c 100644
--- a/lib_mips/bootm.c
+++ b/lib_mips/bootm.c
@@ -73,7 +73,7 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
linux_env_set ("memsize", env_buf);
sprintf (env_buf, "0x%08X", (uint) UNCACHED_SDRAM (images->rd_start));
- linux_env_set ("images->rd_start", env_buf);
+ linux_env_set ("initrd_start", env_buf);
sprintf (env_buf, "0x%X", (uint) (images->rd_end - images->rd_start));
linux_env_set ("initrd_size", env_buf);
diff --git a/lib_mips/bootm_qemu_mips.c b/lib_mips/bootm_qemu_mips.c
new file mode 100644
index 0000000..cc70fa9
--- /dev/null
+++ b/lib_mips/bootm_qemu_mips.c
@@ -0,0 +1,76 @@
+/*
+ * (C) Copyright 2008
+ * Jean-Christophe PLAGNIOL-VILLARD <jcplagniol@jcrosoft.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <image.h>
+#include <asm/byteorder.h>
+#include <asm/addrspace.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
+{
+ void (*theKernel) (int, char **, char **, int *);
+ char *bootargs = getenv ("bootargs");
+ char *start;
+ uint len;
+
+ /* find kernel entry point */
+ theKernel = (void (*)(int, char **, char **, int *))images->ep;
+
+ show_boot_progress (15);
+
+ debug ("## Transferring control to Linux (at address %08lx) ...\n",
+ (ulong) theKernel);
+
+ gd->bd->bi_boot_params = gd->bd->bi_memstart + (16 << 20) - 256;
+ debug ("%-12s= 0x%08lX\n", "boot_params", (ulong)gd->bd->bi_boot_params);
+
+ /* set Magic */
+ *(int32_t *)(gd->bd->bi_boot_params - 4) = 0x12345678;
+ /* set ram_size */
+ *(int32_t *)(gd->bd->bi_boot_params - 8) = gd->ram_size;
+
+ start = (char*)gd->bd->bi_boot_params;
+
+ len = strlen(bootargs);
+
+ strncpy(start, bootargs, len + 1);
+
+ start += len;
+
+ len = images->rd_end - images->rd_start;
+ if (len > 0) {
+ start += sprintf(start," rd_start=0x%08X rd_size=0x%0X",
+ (uint) UNCACHED_SDRAM (images->rd_start),
+ (uint) len);
+ }
+
+ /* we assume that the kernel is in place */
+ printf ("\nStarting kernel ...\n\n");
+
+ theKernel (0, NULL, NULL, 0);
+ /* does not return */
+ return 1;
+}
diff --git a/lib_ppc/interrupts.c b/lib_ppc/interrupts.c
index b803952..c5951e9 100644
--- a/lib_ppc/interrupts.c
+++ b/lib_ppc/interrupts.c
@@ -32,7 +32,12 @@
#endif
#ifdef CONFIG_SHOW_ACTIVITY
- extern void board_show_activity (ulong);
+void board_show_activity (ulong) __attribute__((weak, alias("__board_show_activity")));
+
+void __board_show_activity (ulong dummy)
+{
+ return;
+}
#endif /* CONFIG_SHOW_ACTIVITY */
#ifndef CFG_WATCHDOG_FREQ
diff --git a/tools/env/README b/tools/env/README
index f8a644e..91e679a 100644
--- a/tools/env/README
+++ b/tools/env/README
@@ -22,9 +22,11 @@ following lines are relevant:
#define DEVICE1_OFFSET 0x0000
#define ENV1_SIZE 0x4000
#define DEVICE1_ESIZE 0x4000
+#define DEVICE1_ENVSECTORS 2
#define DEVICE2_OFFSET 0x0000
#define ENV2_SIZE 0x4000
#define DEVICE2_ESIZE 0x4000
+#define DEVICE2_ENVSECTORS 2
Current configuration matches the environment layout of the TRAB
board.
@@ -46,3 +48,7 @@ then 1 sector.
DEVICEx_ESIZE defines the size of the first sector in the flash
partition where the environment resides.
+
+DEVICEx_ENVSECTORS defines the number of sectors that may be used for
+this environment instance. On NAND this is used to limit the range
+within which bad blocks are skipped, on NOR it is not used.
diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c
index e4fc02d..b6036c8 100644
--- a/tools/env/fw_env.c
+++ b/tools/env/fw_env.c
@@ -2,6 +2,9 @@
* (C) Copyright 2000-2008
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
+ * (C) Copyright 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, lg@denx.de.
+ *
* See file CREDITS for list of people who contributed to this
* project.
*
@@ -45,36 +48,75 @@
#define CMD_GETENV "fw_printenv"
#define CMD_SETENV "fw_setenv"
-typedef struct envdev_s {
+#define min(x, y) ({ \
+ typeof(x) _min1 = (x); \
+ typeof(y) _min2 = (y); \
+ (void) (&_min1 == &_min2); \
+ _min1 < _min2 ? _min1 : _min2; })
+
+struct envdev_s {
char devname[16]; /* Device name */
ulong devoff; /* Device offset */
ulong env_size; /* environment size */
ulong erase_size; /* device erase size */
-} envdev_t;
+ ulong env_sectors; /* number of environment sectors */
+ uint8_t mtd_type; /* type of the MTD device */
+};
-static envdev_t envdevices[2];
-static int curdev;
+static struct envdev_s envdevices[2] =
+{
+ {
+ .mtd_type = MTD_ABSENT,
+ }, {
+ .mtd_type = MTD_ABSENT,
+ },
+};
+static int dev_current;
#define DEVNAME(i) envdevices[(i)].devname
#define DEVOFFSET(i) envdevices[(i)].devoff
#define ENVSIZE(i) envdevices[(i)].env_size
#define DEVESIZE(i) envdevices[(i)].erase_size
+#define ENVSECTORS(i) envdevices[(i)].env_sectors
+#define DEVTYPE(i) envdevices[(i)].mtd_type
-#define CFG_ENV_SIZE ENVSIZE(curdev)
+#define CFG_ENV_SIZE ENVSIZE(dev_current)
#define ENV_SIZE getenvsize()
-typedef struct environment_s {
- ulong crc; /* CRC32 over data bytes */
- unsigned char flags; /* active or obsolete */
- char *data;
-} env_t;
+struct env_image_single {
+ uint32_t crc; /* CRC32 over data bytes */
+ char data[];
+};
-static env_t environment;
+struct env_image_redundant {
+ uint32_t crc; /* CRC32 over data bytes */
+ unsigned char flags; /* active or obsolete */
+ char data[];
+};
+
+enum flag_scheme {
+ FLAG_NONE,
+ FLAG_BOOLEAN,
+ FLAG_INCREMENTAL,
+};
+
+struct environment {
+ void *image;
+ uint32_t *crc;
+ unsigned char *flags;
+ char *data;
+ enum flag_scheme flag_scheme;
+};
+
+static struct environment environment = {
+ .flag_scheme = FLAG_NONE,
+};
static int HaveRedundEnv = 0;
static unsigned char active_flag = 1;
+/* obsolete_flag must be 0 to efficiently set it on NOR flash without erasing */
static unsigned char obsolete_flag = 0;
@@ -157,7 +199,7 @@ static char default_environment[] = {
#ifdef CONFIG_EXTRA_ENV_SETTINGS
CONFIG_EXTRA_ENV_SETTINGS
#endif
- "\0" /* Termimate env_t data with 2 NULs */
+ "\0" /* Termimate struct environment data with 2 NULs */
};
static int flash_io (int mode);
@@ -186,7 +228,7 @@ char *fw_getenv (char *name)
char *env, *nxt;
if (env_init ())
- return (NULL);
+ return NULL;
for (env = environment.data; *env; env = nxt + 1) {
char *val;
@@ -195,15 +237,15 @@ char *fw_getenv (char *name)
if (nxt >= &environment.data[ENV_SIZE]) {
fprintf (stderr, "## Error: "
"environment not terminated\n");
- return (NULL);
+ return NULL;
}
}
val = envmatch (name, env);
if (!val)
continue;
- return (val);
+ return val;
}
- return (NULL);
+ return NULL;
}
/*
@@ -217,7 +259,7 @@ int fw_printenv (int argc, char *argv[])
int rc = 0;
if (env_init ())
- return (-1);
+ return -1;
if (argc == 1) { /* Print all env variables */
for (env = environment.data; *env; env = nxt + 1) {
@@ -225,13 +267,13 @@ int fw_printenv (int argc, char *argv[])
if (nxt >= &environment.data[ENV_SIZE]) {
fprintf (stderr, "## Error: "
"environment not terminated\n");
- return (-1);
+ return -1;
}
}
printf ("%s\n", env);
}
- return (0);
+ return 0;
}
if (strcmp (argv[1], "-n") == 0) {
@@ -241,7 +283,7 @@ int fw_printenv (int argc, char *argv[])
if (argc != 2) {
fprintf (stderr, "## Error: "
"`-n' option requires exactly one argument\n");
- return (-1);
+ return -1;
}
} else {
n_flag = 0;
@@ -257,7 +299,7 @@ int fw_printenv (int argc, char *argv[])
if (nxt >= &environment.data[ENV_SIZE]) {
fprintf (stderr, "## Error: "
"environment not terminated\n");
- return (-1);
+ return -1;
}
}
val = envmatch (name, env);
@@ -276,11 +318,11 @@ int fw_printenv (int argc, char *argv[])
}
}
- return (rc);
+ return rc;
}
/*
- * Deletes or sets environment variables. Returns errno style error codes:
+ * Deletes or sets environment variables. Returns -1 and sets errno error codes:
* 0 - OK
* EINVAL - need at least 1 argument
* EROFS - certain variables ("ethaddr", "serial#") cannot be
@@ -295,11 +337,12 @@ int fw_setenv (int argc, char *argv[])
char *name;
if (argc < 2) {
- return (EINVAL);
+ errno = EINVAL;
+ return -1;
}
if (env_init ())
- return (errno);
+ return -1;
name = argv[1];
@@ -311,7 +354,8 @@ int fw_setenv (int argc, char *argv[])
if (nxt >= &environment.data[ENV_SIZE]) {
fprintf (stderr, "## Error: "
"environment not terminated\n");
- return (EINVAL);
+ errno = EINVAL;
+ return -1;
}
}
if ((oldval = envmatch (name, env)) != NULL)
@@ -328,7 +372,8 @@ int fw_setenv (int argc, char *argv[])
if ((strcmp (name, "ethaddr") == 0) ||
(strcmp (name, "serial#") == 0)) {
fprintf (stderr, "Can't overwrite \"%s\"\n", name);
- return (EROFS);
+ errno = EROFS;
+ return -1;
}
if (*++nxt == '\0') {
@@ -367,7 +412,7 @@ int fw_setenv (int argc, char *argv[])
fprintf (stderr,
"Error: environment overflow, \"%s\" deleted\n",
name);
- return (-1);
+ return -1;
}
while ((*env = *name++) != '\0')
env++;
@@ -383,195 +428,430 @@ int fw_setenv (int argc, char *argv[])
WRITE_FLASH:
- /* Update CRC */
- environment.crc = crc32 (0, (uint8_t*) environment.data, ENV_SIZE);
+ /*
+ * Update CRC
+ */
+ *environment.crc = crc32 (0, (uint8_t *) environment.data, ENV_SIZE);
/* write environment back to flash */
if (flash_io (O_RDWR)) {
fprintf (stderr, "Error: can't write fw_env to flash\n");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
-static int flash_io (int mode)
+/*
+ * Test for bad block on NAND, just returns 0 on NOR, on NAND:
+ * 0 - block is good
+ * > 0 - block is bad
+ * < 0 - failed to test
+ */
+static int flash_bad_block (int fd, uint8_t mtd_type, loff_t *blockstart)
{
- int fd, fdr, rc, otherdev, len, resid;
- struct erase_info_user erase;
- char *data = NULL;
+ if (mtd_type == MTD_NANDFLASH) {
+ int badblock = ioctl (fd, MEMGETBADBLOCK, blockstart);
- if ((fd = open (DEVNAME (curdev), mode)) < 0) {
- fprintf (stderr,
- "Can't open %s: %s\n",
- DEVNAME (curdev), strerror (errno));
- return (-1);
+ if (badblock < 0) {
+ perror ("Cannot read bad block mark");
+ return badblock;
+ }
+
+ if (badblock) {
+#ifdef DEBUG
+ fprintf (stderr, "Bad block at 0x%llx, "
+ "skipping\n", *blockstart);
+#endif
+ return badblock;
+ }
}
- len = sizeof (environment.crc);
- if (HaveRedundEnv) {
- len += sizeof (environment.flags);
+ return 0;
+}
+
+/*
+ * Read data from flash at an offset into a provided buffer. On NAND it skips
+ * bad blocks but makes sure it stays within ENVSECTORS (dev) starting from
+ * the DEVOFFSET (dev) block. On NOR the loop is only run once.
+ */
+static int flash_read_buf (int dev, int fd, void *buf, size_t count,
+ off_t offset, uint8_t mtd_type)
+{
+ size_t blocklen; /* erase / write length - one block on NAND,
+ 0 on NOR */
+ size_t processed = 0; /* progress counter */
+ size_t readlen = count; /* current read length */
+ off_t top_of_range; /* end of the last block we may use */
+ off_t block_seek; /* offset inside the current block to the start
+ of the data */
+ loff_t blockstart; /* running start of the current block -
+ MEMGETBADBLOCK needs 64 bits */
+ int rc;
+
+ /*
+ * Start of the first block to be read, relies on the fact, that
+ * erase sector size is always a power of 2
+ */
+ blockstart = offset & ~(DEVESIZE (dev) - 1);
+
+ /* Offset inside a block */
+ block_seek = offset - blockstart;
+
+ if (mtd_type == MTD_NANDFLASH) {
+ /*
+ * NAND: calculate which blocks we are reading. We have
+ * to read one block at a time to skip bad blocks.
+ */
+ blocklen = DEVESIZE (dev);
+
+ /*
+ * To calculate the top of the range, we have to use the
+ * global DEVOFFSET (dev), which can be different from offset
+ */
+ top_of_range = (DEVOFFSET (dev) & ~(blocklen - 1)) +
+ ENVSECTORS (dev) * blocklen;
+
+ /* Limit to one block for the first read */
+ if (readlen > blocklen - block_seek)
+ readlen = blocklen - block_seek;
+ } else {
+ blocklen = 0;
+ top_of_range = offset + count;
}
- if (mode == O_RDWR) {
- if (HaveRedundEnv) {
- /* switch to next partition for writing */
- otherdev = !curdev;
- if ((fdr = open (DEVNAME (otherdev), mode)) < 0) {
- fprintf (stderr,
- "Can't open %s: %s\n",
- DEVNAME (otherdev),
- strerror (errno));
- return (-1);
- }
- } else {
- otherdev = curdev;
- fdr = fd;
- }
- printf ("Unlocking flash...\n");
- erase.length = DEVESIZE (otherdev);
- erase.start = DEVOFFSET (otherdev);
- ioctl (fdr, MEMUNLOCK, &erase);
+ /* This only runs once on NOR flash */
+ while (processed < count) {
+ rc = flash_bad_block (fd, mtd_type, &blockstart);
+ if (rc < 0) /* block test failed */
+ return -1;
- if (HaveRedundEnv) {
- erase.length = DEVESIZE (curdev);
- erase.start = DEVOFFSET (curdev);
- ioctl (fd, MEMUNLOCK, &erase);
- environment.flags = active_flag;
+ if (blockstart + block_seek + readlen > top_of_range) {
+ /* End of range is reached */
+ fprintf (stderr,
+ "Too few good blocks within range\n");
+ return -1;
}
- printf ("Done\n");
- resid = DEVESIZE (otherdev) - CFG_ENV_SIZE;
- if (resid) {
- if ((data = malloc (resid)) == NULL) {
- fprintf (stderr,
- "Cannot malloc %d bytes: %s\n",
- resid,
- strerror (errno));
- return (-1);
- }
- if (lseek (fdr, DEVOFFSET (otherdev) + CFG_ENV_SIZE, SEEK_SET)
- == -1) {
- fprintf (stderr, "seek error on %s: %s\n",
- DEVNAME (otherdev),
- strerror (errno));
- return (-1);
- }
- if ((rc = read (fdr, data, resid)) != resid) {
- fprintf (stderr,
- "read error on %s: %s\n",
- DEVNAME (otherdev),
- strerror (errno));
- return (-1);
- }
+ if (rc) { /* block is bad */
+ blockstart += blocklen;
+ continue;
}
- printf ("Erasing old environment...\n");
+ /*
+ * If a block is bad, we retry in the next block at the same
+ * offset - see common/env_nand.c::writeenv()
+ */
+ lseek (fd, blockstart + block_seek, SEEK_SET);
- erase.length = DEVESIZE (otherdev);
- erase.start = DEVOFFSET (otherdev);
- if (ioctl (fdr, MEMERASE, &erase) != 0) {
- fprintf (stderr, "MTD erase error on %s: %s\n",
- DEVNAME (otherdev),
- strerror (errno));
- return (-1);
+ rc = read (fd, buf + processed, readlen);
+ if (rc != readlen) {
+ fprintf (stderr, "Read error on %s: %s\n",
+ DEVNAME (dev), strerror (errno));
+ return -1;
}
+#ifdef DEBUG
+ fprintf (stderr, "Read 0x%x bytes at 0x%llx\n",
+ rc, blockstart + block_seek);
+#endif
+ processed += readlen;
+ readlen = min (blocklen, count - processed);
+ block_seek = 0;
+ blockstart += blocklen;
+ }
+
+ return processed;
+}
+
+/*
+ * Write count bytes at offset, but stay within ENVSETCORS (dev) sectors of
+ * DEVOFFSET (dev). Similar to the read case above, on NOR we erase and write
+ * the whole data at once.
+ */
+static int flash_write_buf (int dev, int fd, void *buf, size_t count,
+ off_t offset, uint8_t mtd_type)
+{
+ void *data;
+ struct erase_info_user erase;
+ size_t blocklen; /* length of NAND block / NOR erase sector */
+ size_t erase_len; /* whole area that can be erased - may include
+ bad blocks */
+ size_t erasesize; /* erase / write length - one block on NAND,
+ whole area on NOR */
+ size_t processed = 0; /* progress counter */
+ size_t write_total; /* total size to actually write - excludinig
+ bad blocks */
+ off_t erase_offset; /* offset to the first erase block (aligned)
+ below offset */
+ off_t block_seek; /* offset inside the erase block to the start
+ of the data */
+ off_t top_of_range; /* end of the last block we may use */
+ loff_t blockstart; /* running start of the current block -
+ MEMGETBADBLOCK needs 64 bits */
+ int rc;
+
+ blocklen = DEVESIZE (dev);
+
+ /* Erase sector size is always a power of 2 */
+ top_of_range = (DEVOFFSET (dev) & ~(blocklen - 1)) +
+ ENVSECTORS (dev) * blocklen;
- printf ("Done\n");
+ erase_offset = offset & ~(blocklen - 1);
- printf ("Writing environment to %s...\n", DEVNAME (otherdev));
- if (lseek (fdr, DEVOFFSET (otherdev), SEEK_SET) == -1) {
+ /* Maximum area we may use */
+ erase_len = top_of_range - erase_offset;
+
+ blockstart = erase_offset;
+ /* Offset inside a block */
+ block_seek = offset - erase_offset;
+
+ /*
+ * Data size we actually have to write: from the start of the block
+ * to the start of the data, then count bytes of data, and to the
+ * end of the block
+ */
+ write_total = (block_seek + count + blocklen - 1) & ~(blocklen - 1);
+
+ /*
+ * Support data anywhere within erase sectors: read out the complete
+ * area to be erased, replace the environment image, write the whole
+ * block back again.
+ */
+ if (write_total > count) {
+ data = malloc (erase_len);
+ if (!data) {
fprintf (stderr,
- "seek error on %s: %s\n",
- DEVNAME (otherdev), strerror (errno));
- return (-1);
+ "Cannot malloc %u bytes: %s\n",
+ erase_len, strerror (errno));
+ return -1;
}
- if (write (fdr, &environment, len) != len) {
- fprintf (stderr,
- "CRC write error on %s: %s\n",
- DEVNAME (otherdev), strerror (errno));
- return (-1);
+
+ rc = flash_read_buf (dev, fd, data, write_total, erase_offset,
+ mtd_type);
+ if (write_total != rc)
+ return -1;
+
+ /* Overwrite the old environment */
+ memcpy (data + block_seek, buf, count);
+ } else {
+ /*
+ * We get here, iff offset is block-aligned and count is a
+ * multiple of blocklen - see write_total calculation above
+ */
+ data = buf;
+ }
+
+ if (mtd_type == MTD_NANDFLASH) {
+ /*
+ * NAND: calculate which blocks we are writing. We have
+ * to write one block at a time to skip bad blocks.
+ */
+ erasesize = blocklen;
+ } else {
+ erasesize = erase_len;
+ }
+
+ erase.length = erasesize;
+
+ /* This only runs once on NOR flash */
+ while (processed < write_total) {
+ rc = flash_bad_block (fd, mtd_type, &blockstart);
+ if (rc < 0) /* block test failed */
+ return rc;
+
+ if (blockstart + erasesize > top_of_range) {
+ fprintf (stderr, "End of range reached, aborting\n");
+ return -1;
}
- if (write (fdr, environment.data, ENV_SIZE) != ENV_SIZE) {
+
+ if (rc) { /* block is bad */
+ blockstart += blocklen;
+ continue;
+ }
+
+ erase.start = blockstart;
+ ioctl (fd, MEMUNLOCK, &erase);
+
+ if (ioctl (fd, MEMERASE, &erase) != 0) {
+ fprintf (stderr, "MTD erase error on %s: %s\n",
+ DEVNAME (dev),
+ strerror (errno));
+ return -1;
+ }
+
+ if (lseek (fd, blockstart, SEEK_SET) == -1) {
fprintf (stderr,
- "Write error on %s: %s\n",
- DEVNAME (otherdev), strerror (errno));
- return (-1);
+ "Seek error on %s: %s\n",
+ DEVNAME (dev), strerror (errno));
+ return -1;
}
- if (resid) {
- if (write (fdr, data, resid) != resid) {
- fprintf (stderr,
- "write error on %s: %s\n",
- DEVNAME (curdev), strerror (errno));
- return (-1);
- }
- free (data);
+
+#ifdef DEBUG
+ printf ("Write 0x%x bytes at 0x%llx\n", erasesize, blockstart);
+#endif
+ if (write (fd, data + processed, erasesize) != erasesize) {
+ fprintf (stderr, "Write error on %s: %s\n",
+ DEVNAME (dev), strerror (errno));
+ return -1;
}
+
+ ioctl (fd, MEMLOCK, &erase);
+
+ processed += blocklen;
+ block_seek = 0;
+ blockstart += blocklen;
+ }
+
+ if (write_total > count)
+ free (data);
+
+ return processed;
+}
+
+/*
+ * Set obsolete flag at offset - NOR flash only
+ */
+static int flash_flag_obsolete (int dev, int fd, off_t offset)
+{
+ int rc;
+
+ /* This relies on the fact, that obsolete_flag == 0 */
+ rc = lseek (fd, offset, SEEK_SET);
+ if (rc < 0) {
+ fprintf (stderr, "Cannot seek to set the flag on %s \n",
+ DEVNAME (dev));
+ return rc;
+ }
+ rc = write (fd, &obsolete_flag, sizeof (obsolete_flag));
+ if (rc < 0)
+ perror ("Could not set obsolete flag");
+
+ return rc;
+}
+
+static int flash_write (int fd_current, int fd_target, int dev_target)
+{
+ int rc;
+
+ switch (environment.flag_scheme) {
+ case FLAG_NONE:
+ break;
+ case FLAG_INCREMENTAL:
+ (*environment.flags)++;
+ break;
+ case FLAG_BOOLEAN:
+ *environment.flags = active_flag;
+ break;
+ default:
+ fprintf (stderr, "Unimplemented flash scheme %u \n",
+ environment.flag_scheme);
+ return -1;
+ }
+
+#ifdef DEBUG
+ printf ("Writing new environment at 0x%lx on %s\n",
+ DEVOFFSET (dev_target), DEVNAME (dev_target));
+#endif
+ rc = flash_write_buf (dev_target, fd_target, environment.image,
+ CFG_ENV_SIZE, DEVOFFSET (dev_target),
+ DEVTYPE(dev_target));
+ if (rc < 0)
+ return rc;
+
+ if (environment.flag_scheme == FLAG_BOOLEAN) {
+ /* Have to set obsolete flag */
+ off_t offset = DEVOFFSET (dev_current) +
+ offsetof (struct env_image_redundant, flags);
+#ifdef DEBUG
+ printf ("Setting obsolete flag in environment at 0x%lx on %s\n",
+ DEVOFFSET (dev_current), DEVNAME (dev_current));
+#endif
+ flash_flag_obsolete (dev_current, fd_current, offset);
+ }
+
+ return 0;
+}
+
+static int flash_read (int fd)
+{
+ struct mtd_info_user mtdinfo;
+ int rc;
+
+ rc = ioctl (fd, MEMGETINFO, &mtdinfo);
+ if (rc < 0) {
+ perror ("Cannot get MTD information");
+ return -1;
+ }
+
+ if (mtdinfo.type != MTD_NORFLASH && mtdinfo.type != MTD_NANDFLASH) {
+ fprintf (stderr, "Unsupported flash type %u\n", mtdinfo.type);
+ return -1;
+ }
+
+ DEVTYPE(dev_current) = mtdinfo.type;
+
+ rc = flash_read_buf (dev_current, fd, environment.image, CFG_ENV_SIZE,
+ DEVOFFSET (dev_current), mtdinfo.type);
+
+ return (rc != CFG_ENV_SIZE) ? -1 : 0;
+}
+
+static int flash_io (int mode)
+{
+ int fd_current, fd_target, rc, dev_target;
+
+ /* dev_current: fd_current, erase_current */
+ fd_current = open (DEVNAME (dev_current), mode);
+ if (fd_current < 0) {
+ fprintf (stderr,
+ "Can't open %s: %s\n",
+ DEVNAME (dev_current), strerror (errno));
+ return -1;
+ }
+
+ if (mode == O_RDWR) {
if (HaveRedundEnv) {
- /* change flag on current active env partition */
- if (lseek (fd, DEVOFFSET (curdev) + sizeof (ulong), SEEK_SET)
- == -1) {
- fprintf (stderr, "seek error on %s: %s\n",
- DEVNAME (curdev), strerror (errno));
- return (-1);
- }
- if (write (fd, &obsolete_flag, sizeof (obsolete_flag)) !=
- sizeof (obsolete_flag)) {
+ /* switch to next partition for writing */
+ dev_target = !dev_current;
+ /* dev_target: fd_target, erase_target */
+ fd_target = open (DEVNAME (dev_target), mode);
+ if (fd_target < 0) {
fprintf (stderr,
- "Write error on %s: %s\n",
- DEVNAME (curdev), strerror (errno));
- return (-1);
+ "Can't open %s: %s\n",
+ DEVNAME (dev_target),
+ strerror (errno));
+ rc = -1;
+ goto exit;
}
+ } else {
+ dev_target = dev_current;
+ fd_target = fd_current;
}
- printf ("Done\n");
- printf ("Locking ...\n");
- erase.length = DEVESIZE (otherdev);
- erase.start = DEVOFFSET (otherdev);
- ioctl (fdr, MEMLOCK, &erase);
+
+ rc = flash_write (fd_current, fd_target, dev_target);
+
if (HaveRedundEnv) {
- erase.length = DEVESIZE (curdev);
- erase.start = DEVOFFSET (curdev);
- ioctl (fd, MEMLOCK, &erase);
- if (close (fdr)) {
+ if (close (fd_target)) {
fprintf (stderr,
"I/O error on %s: %s\n",
- DEVNAME (otherdev),
+ DEVNAME (dev_target),
strerror (errno));
- return (-1);
+ rc = -1;
}
}
- printf ("Done\n");
} else {
-
- if (lseek (fd, DEVOFFSET (curdev), SEEK_SET) == -1) {
- fprintf (stderr,
- "seek error on %s: %s\n",
- DEVNAME (curdev), strerror (errno));
- return (-1);
- }
- if (read (fd, &environment, len) != len) {
- fprintf (stderr,
- "CRC read error on %s: %s\n",
- DEVNAME (curdev), strerror (errno));
- return (-1);
- }
- if ((rc = read (fd, environment.data, ENV_SIZE)) != ENV_SIZE) {
- fprintf (stderr,
- "Read error on %s: %s\n",
- DEVNAME (curdev), strerror (errno));
- return (-1);
- }
+ rc = flash_read (fd_current);
}
- if (close (fd)) {
+exit:
+ if (close (fd_current)) {
fprintf (stderr,
- "I/O error on %s: %s\n",
- DEVNAME (curdev), strerror (errno));
- return (-1);
+ "I/O error on %s: %s\n",
+ DEVNAME (dev_current), strerror (errno));
+ return -1;
}
- /* everything ok */
- return (0);
+ return rc;
}
/*
@@ -585,10 +865,10 @@ static char *envmatch (char * s1, char * s2)
while (*s1 == *s2++)
if (*s1++ == '=')
- return (s2);
+ return s2;
if (*s1 == '\0' && *(s2 - 1) == '=')
- return (s2);
- return (NULL);
+ return s2;
+ return NULL;
}
/*
@@ -596,108 +876,156 @@ static char *envmatch (char * s1, char * s2)
*/
static int env_init (void)
{
+ int crc0, crc0_ok;
+ char flag0;
+ void *addr0;
+
int crc1, crc1_ok;
- char *addr1;
+ char flag1;
+ void *addr1;
- int crc2, crc2_ok;
- char flag1, flag2, *addr2;
+ struct env_image_single *single;
+ struct env_image_redundant *redundant;
if (parse_config ()) /* should fill envdevices */
- return 1;
+ return -1;
- if ((addr1 = calloc (1, ENV_SIZE)) == NULL) {
+ addr0 = calloc (1, CFG_ENV_SIZE);
+ if (addr0 == NULL) {
fprintf (stderr,
"Not enough memory for environment (%ld bytes)\n",
- ENV_SIZE);
- return (errno);
+ CFG_ENV_SIZE);
+ return -1;
}
/* read environment from FLASH to local buffer */
- environment.data = addr1;
- curdev = 0;
- if (flash_io (O_RDONLY)) {
- return (errno);
+ environment.image = addr0;
+
+ if (HaveRedundEnv) {
+ redundant = addr0;
+ environment.crc = &redundant->crc;
+ environment.flags = &redundant->flags;
+ environment.data = redundant->data;
+ } else {
+ single = addr0;
+ environment.crc = &single->crc;
+ environment.flags = NULL;
+ environment.data = single->data;
}
- crc1_ok = ((crc1 = crc32 (0, (uint8_t *) environment.data, ENV_SIZE))
- == environment.crc);
+ dev_current = 0;
+ if (flash_io (O_RDONLY))
+ return -1;
+
+ crc0 = crc32 (0, (uint8_t *) environment.data, ENV_SIZE);
+ crc0_ok = (crc0 == *environment.crc);
if (!HaveRedundEnv) {
- if (!crc1_ok) {
+ if (!crc0_ok) {
fprintf (stderr,
"Warning: Bad CRC, using default environment\n");
memcpy(environment.data, default_environment, sizeof default_environment);
}
} else {
- flag1 = environment.flags;
+ flag0 = *environment.flags;
- curdev = 1;
- if ((addr2 = calloc (1, ENV_SIZE)) == NULL) {
+ dev_current = 1;
+ addr1 = calloc (1, CFG_ENV_SIZE);
+ if (addr1 == NULL) {
fprintf (stderr,
"Not enough memory for environment (%ld bytes)\n",
- ENV_SIZE);
- return (errno);
+ CFG_ENV_SIZE);
+ return -1;
}
- environment.data = addr2;
+ redundant = addr1;
- if (flash_io (O_RDONLY)) {
- return (errno);
+ /*
+ * have to set environment.image for flash_read(), careful -
+ * other pointers in environment still point inside addr0
+ */
+ environment.image = addr1;
+ if (flash_io (O_RDONLY))
+ return -1;
+
+ /* Check flag scheme compatibility */
+ if (DEVTYPE(dev_current) == MTD_NORFLASH &&
+ DEVTYPE(!dev_current) == MTD_NORFLASH) {
+ environment.flag_scheme = FLAG_BOOLEAN;
+ } else if (DEVTYPE(dev_current) == MTD_NANDFLASH &&
+ DEVTYPE(!dev_current) == MTD_NANDFLASH) {
+ environment.flag_scheme = FLAG_INCREMENTAL;
+ } else {
+ fprintf (stderr, "Incompatible flash types!\n");
+ return -1;
}
- crc2_ok = ((crc2 = crc32 (0, (uint8_t *) environment.data, ENV_SIZE))
- == environment.crc);
- flag2 = environment.flags;
-
- if (crc1_ok && !crc2_ok) {
- environment.data = addr1;
- environment.flags = flag1;
- environment.crc = crc1;
- curdev = 0;
- free (addr2);
- } else if (!crc1_ok && crc2_ok) {
- environment.data = addr2;
- environment.flags = flag2;
- environment.crc = crc2;
- curdev = 1;
- free (addr1);
- } else if (!crc1_ok && !crc2_ok) {
+ crc1 = crc32 (0, (uint8_t *) redundant->data, ENV_SIZE);
+ crc1_ok = (crc1 == redundant->crc);
+ flag1 = redundant->flags;
+
+ if (crc0_ok && !crc1_ok) {
+ dev_current = 0;
+ } else if (!crc0_ok && crc1_ok) {
+ dev_current = 1;
+ } else if (!crc0_ok && !crc1_ok) {
fprintf (stderr,
"Warning: Bad CRC, using default environment\n");
- memcpy(environment.data, default_environment, sizeof default_environment);
- curdev = 0;
- free (addr1);
- } else if (flag1 == active_flag && flag2 == obsolete_flag) {
- environment.data = addr1;
- environment.flags = flag1;
- environment.crc = crc1;
- curdev = 0;
- free (addr2);
- } else if (flag1 == obsolete_flag && flag2 == active_flag) {
- environment.data = addr2;
- environment.flags = flag2;
- environment.crc = crc2;
- curdev = 1;
- free (addr1);
- } else if (flag1 == flag2) {
- environment.data = addr1;
- environment.flags = flag1;
- environment.crc = crc1;
- curdev = 0;
- free (addr2);
- } else if (flag1 == 0xFF) {
- environment.data = addr1;
- environment.flags = flag1;
- environment.crc = crc1;
- curdev = 0;
- free (addr2);
- } else if (flag2 == 0xFF) {
- environment.data = addr2;
- environment.flags = flag2;
- environment.crc = crc2;
- curdev = 1;
+ memcpy (environment.data, default_environment,
+ sizeof default_environment);
+ dev_current = 0;
+ } else {
+ switch (environment.flag_scheme) {
+ case FLAG_BOOLEAN:
+ if (flag0 == active_flag &&
+ flag1 == obsolete_flag) {
+ dev_current = 0;
+ } else if (flag0 == obsolete_flag &&
+ flag1 == active_flag) {
+ dev_current = 1;
+ } else if (flag0 == flag1) {
+ dev_current = 0;
+ } else if (flag0 == 0xFF) {
+ dev_current = 0;
+ } else if (flag1 == 0xFF) {
+ dev_current = 1;
+ } else {
+ dev_current = 0;
+ }
+ break;
+ case FLAG_INCREMENTAL:
+ if ((flag0 == 255 && flag1 == 0) ||
+ flag1 > flag0)
+ dev_current = 1;
+ else if ((flag1 == 255 && flag0 == 0) ||
+ flag0 > flag1)
+ dev_current = 0;
+ else /* flags are equal - almost impossible */
+ dev_current = 0;
+ break;
+ default:
+ fprintf (stderr, "Unknown flag scheme %u \n",
+ environment.flag_scheme);
+ return -1;
+ }
+ }
+
+ /*
+ * If we are reading, we don't need the flag and the CRC any
+ * more, if we are writing, we will re-calculate CRC and update
+ * flags before writing out
+ */
+ if (dev_current) {
+ environment.image = addr1;
+ environment.crc = &redundant->crc;
+ environment.flags = &redundant->flags;
+ environment.data = redundant->data;
+ free (addr0);
+ } else {
+ environment.image = addr0;
+ /* Other pointers are already set */
free (addr1);
}
}
- return (0);
+ return 0;
}
@@ -710,18 +1038,20 @@ static int parse_config ()
if (get_config (CONFIG_FILE)) {
fprintf (stderr,
"Cannot parse config file: %s\n", strerror (errno));
- return 1;
+ return -1;
}
#else
strcpy (DEVNAME (0), DEVICE1_NAME);
DEVOFFSET (0) = DEVICE1_OFFSET;
ENVSIZE (0) = ENV1_SIZE;
DEVESIZE (0) = DEVICE1_ESIZE;
+ ENVSECTORS (0) = DEVICE1_ENVSECTORS;
#ifdef HAVE_REDUND
strcpy (DEVNAME (1), DEVICE2_NAME);
DEVOFFSET (1) = DEVICE2_OFFSET;
ENVSIZE (1) = ENV2_SIZE;
DEVESIZE (1) = DEVICE2_ESIZE;
+ ENVSECTORS (1) = DEVICE2_ENVSECTORS;
HaveRedundEnv = 1;
#endif
#endif
@@ -729,14 +1059,14 @@ static int parse_config ()
fprintf (stderr,
"Cannot access MTD device %s: %s\n",
DEVNAME (0), strerror (errno));
- return 1;
+ return -1;
}
if (HaveRedundEnv && stat (DEVNAME (1), &st)) {
fprintf (stderr,
"Cannot access MTD device %s: %s\n",
DEVNAME (1), strerror (errno));
- return 1;
+ return -1;
}
return 0;
}
@@ -749,21 +1079,28 @@ static int get_config (char *fname)
int rc;
char dump[128];
- if ((fp = fopen (fname, "r")) == NULL) {
- return 1;
- }
-
- while ((i < 2) && ((rc = fscanf (fp, "%s %lx %lx %lx",
- DEVNAME (i),
- &DEVOFFSET (i),
- &ENVSIZE (i),
- &DEVESIZE (i) )) != EOF)) {
+ fp = fopen (fname, "r");
+ if (fp == NULL)
+ return -1;
+ while (i < 2 && fgets (dump, sizeof (dump), fp)) {
/* Skip incomplete conversions and comment strings */
- if ((rc < 3) || (*DEVNAME (i) == '#')) {
- fgets (dump, sizeof (dump), fp); /* Consume till end */
+ if (dump[0] == '#')
continue;
- }
+
+ rc = sscanf (dump, "%s %lx %lx %lx %lx",
+ DEVNAME (i),
+ &DEVOFFSET (i),
+ &ENVSIZE (i),
+ &DEVESIZE (i),
+ &ENVSECTORS (i));
+
+ if (rc < 4)
+ continue;
+
+ if (rc < 5)
+ /* Default - 1 sector */
+ ENVSECTORS (i) = 1;
i++;
}
@@ -772,7 +1109,7 @@ static int get_config (char *fname)
HaveRedundEnv = i - 1;
if (!i) { /* No valid entries found */
errno = EINVAL;
- return 1;
+ return -1;
} else
return 0;
}
diff --git a/tools/env/fw_env.config b/tools/env/fw_env.config
index 2432bd8..0fe37c9 100644
--- a/tools/env/fw_env.config
+++ b/tools/env/fw_env.config
@@ -1,7 +1,11 @@
# Configuration file for fw_(printenv/saveenv) utility.
# Up to two entries are valid, in this case the redundand
# environment sector is assumed present.
+# Notice, that the "Number of sectors" is ignored on NOR.
-# MTD device name Device offset Env. size Flash sector size
+# MTD device name Device offset Env. size Flash sector size Number of sectors
/dev/mtd1 0x0000 0x4000 0x4000
/dev/mtd2 0x0000 0x4000 0x4000
+
+# NAND example
+#/dev/mtd0 0x4000 0x4000 0x20000 2