summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG182
-rw-r--r--CREDITS5
-rw-r--r--MAINTAINERS5
-rwxr-xr-xMAKEALL2
-rw-r--r--Makefile10
-rw-r--r--README33
-rw-r--r--board/AtmarkTechno/suzaku/suzaku.c2
-rw-r--r--board/AtmarkTechno/suzaku/u-boot.lds3
-rw-r--r--board/mpc8360emds/config.mk5
-rw-r--r--board/mpc8360emds/mpc8360emds.c30
-rw-r--r--board/mpc8360emds/pci.c20
-rw-r--r--board/xilinx/ml401/Makefile65
-rw-r--r--board/xilinx/ml401/config.mk32
-rw-r--r--board/xilinx/ml401/ml401.c49
-rw-r--r--board/xilinx/ml401/u-boot.lds (renamed from include/asm-microblaze/suzaku.h)46
-rw-r--r--board/xilinx/ml401/xparameters.h67
-rw-r--r--board/xilinx/xilinx_enet/emac_adapter.c4
-rw-r--r--board/xilinx/xupv2p/Makefile65
-rw-r--r--board/xilinx/xupv2p/config.mk32
-rw-r--r--board/xilinx/xupv2p/u-boot.lds67
-rw-r--r--board/xilinx/xupv2p/xparameters.h64
-rw-r--r--board/xilinx/xupv2p/xupv2p.c49
-rw-r--r--common/Makefile2
-rw-r--r--common/cmd_bdinfo.c26
-rw-r--r--common/cmd_bootm.c65
-rw-r--r--common/cmd_fdt.c874
-rw-r--r--cpu/microblaze/Makefile3
-rw-r--r--cpu/microblaze/cache.c48
-rw-r--r--cpu/microblaze/dcache.S68
-rw-r--r--cpu/microblaze/disable_int.S46
-rw-r--r--cpu/microblaze/enable_int.S (renamed from include/asm-microblaze/platform.h)25
-rw-r--r--cpu/microblaze/exception.c68
-rw-r--r--cpu/microblaze/icache.S69
-rw-r--r--cpu/microblaze/interrupts.c182
-rw-r--r--cpu/microblaze/irq.S165
-rw-r--r--cpu/microblaze/start.S91
-rw-r--r--cpu/microblaze/timer.c68
-rw-r--r--cpu/mpc83xx/cpu.c102
-rw-r--r--include/asm-microblaze/microblaze_intc.h40
-rw-r--r--include/asm-microblaze/microblaze_timer.h41
-rw-r--r--include/configs/MPC8360EMDS.h6
-rw-r--r--include/configs/ml401.h230
-rw-r--r--include/configs/suzaku.h7
-rw-r--r--include/configs/xupv2p.h174
-rw-r--r--include/fdt.h60
-rw-r--r--include/libfdt.h138
-rw-r--r--include/libfdt_env.h16
-rw-r--r--lib_microblaze/board.c95
-rw-r--r--lib_microblaze/microblaze_linux.c146
-rw-r--r--lib_microblaze/time.c9
-rw-r--r--libfdt/Makefile46
-rw-r--r--libfdt/README23
-rw-r--r--libfdt/fdt.c85
-rw-r--r--libfdt/fdt_ro.c331
-rw-r--r--libfdt/fdt_rw.c293
-rw-r--r--libfdt/fdt_strerror.c64
-rw-r--r--libfdt/fdt_sw.c226
-rw-r--r--libfdt/fdt_wip.c112
-rw-r--r--libfdt/libfdt_internal.h40
-rw-r--r--microblaze_config.mk2
60 files changed, 4854 insertions, 69 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 284ba76..7425ceb 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,153 @@
+commit 94abd7c0583ebe01e799b25f451201deeaab550d
+Author: Wolfgang Denk <wd@denx.de>
+Date: Wed Apr 4 01:49:15 2007 +0200
+
+ Minor cleanup.
+
+commit aea03c4e8c3a21ce43d3faf48a6e6d474c8bdf73
+Author: Gerald Van Baren <vanbaren@cideas.com>
+Date: Sat Mar 31 14:30:53 2007 -0400
+
+ Fix some minor whitespace violations.
+
+commit 213bf8c822de8eecaf69860684469cdaba2e9e6a
+Author: Gerald Van Baren <vanbaren@cideas.com>
+Date: Sat Mar 31 12:23:51 2007 -0400
+
+ Add a flattened device tree (fdt) command (2 of 2)
+
+ Modifications to the existing code to support the new fdt command.
+
+commit 781e09ee6e3e3e392ab362c1f0ef1068adc76e3e
+Author: Gerald Van Baren <vanbaren@cideas.com>
+Date: Sat Mar 31 12:22:10 2007 -0400
+
+ Add a flattened device tree (fdt) command (1 of 2)
+
+ The fdt command uses David Gibson's libfdt library to manipulate as well
+ as print the flattened device tree. This patch is the new command,
+ the second part is the modifications to the existing code.
+
+commit 3af0d587d93e0be5f96e1b30fa41e662f8b0803e
+Author: Gerald Van Baren <vanbaren@cideas.com>
+Date: Sat Mar 31 12:13:43 2007 -0400
+
+ libfdt: Enhanced and published fdt_next_tag()
+
+ Enhanced the formerly private function _fdt_next_tag() to allow stepping
+ through the tree, used to produce a human-readable dump, and made
+ it part of the published interface.
+ Also added some comments.
+
+commit fa3a74cec73dfd06a5ae35a9a3368200273aaa71
+Author: Gerald Van Baren <vanbaren@cideas.com>
+Date: Sat Mar 31 12:05:39 2007 -0400
+
+ libfdt: Customizations for use by u-boot.
+
+ Changes to David Gibson's original source to fit into u-boot's
+ environment. No functionality changes.
+
+commit 35748177c64a4a83a00057e93bb33e40278a2a96
+Author: Gerald Van Baren <vanbaren@cideas.com>
+Date: Sat Mar 31 12:00:56 2007 -0400
+
+ libfdt: Import libfdt source (2 of 2)
+
+ This adds the applicable libfdt source files (unmodified) and a README
+ to explain where the source came from.
+
+commit 7cd5da0fe877e7171a4cdd44880bce783132871a
+Author: Gerald Van Baren <vanbaren@cideas.com>
+Date: Sat Mar 31 11:59:59 2007 -0400
+
+ libfdt: Import libfdt source (1 of 2)
+
+ This adds the applicable libfdt source files (unmodified) and a README
+ to explain where the source came from.
+
+commit 342cd097be1e7affe82f42ab3da220959a699e64
+Author: Michal Simek <monstr@monstr.eu>
+Date: Fri Mar 30 22:52:09 2007 +0200
+
+ [PATCH] Clean include dependence
+
+commit 6f934210fb293fde2cfb4251c6d96fdc58b6a906
+Author: Michal Simek <monstr@monstr.eu>
+Date: Fri Mar 30 22:42:45 2007 +0200
+
+ [CLEAN] Remove inefficient Suzaku code
+
+commit 5da048adf44bea5e3b94080d02903c2e3fe7aa4a
+Author: Michal Simek <monstr@monstr.eu>
+Date: Tue Mar 27 00:32:16 2007 +0200
+
+ PATCH: Resolve GPL license problem
+
+commit 1798049522f594013aea29457d46794298c6ae15
+Author: Michal Simek <root@monstr.eu>
+Date: Mon Mar 26 01:39:07 2007 +0200
+
+ Support for XUPV2P board
+ Reset support
+ BSP autoconfig support
+
+commit 6eb1df835191d8ce4b81d5af40fa8e0fbe78e997
+Author: Jon Loeliger <jdl@freescale.com>
+Date: Tue Dec 12 11:02:20 2006 -0600
+
+ Fix 8641HPCN problem with ld version 2.16
+
+ (Dot outside sections problem).
+
+ This fix is in the spirit of 807d5d7319330e336ab34a5623c5e0d73b87d540.
+
+ Signed-off-by: Jon Loeliger <jdl@freescale.com>
+
+commit 9964a4dd0d4ef5a037febaebf1aa494b1a72991c
+Author: Haiying Wang <haiying.wang@freescale.com>
+Date: Thu Dec 7 10:35:55 2006 -0600
+
+ Set Rev 2.x 86xx PIC in mixed mode.
+
+ Prevent false interrupt from hanging Linux as MSR[EE] is set
+ to enable interrupts by changing the PIC out of the default
+ pass through mode into mixed mode.
+
+ Signed-off-by: Haiying Wang <haiying.wang@freescale.com>
+ Signed-off-by: Jon Loeliger <jdl@freescale.com>
+
+commit 5a58a73ceb0a4059c42ef64cedbc1a45e0aaa00e
+Author: Jason Jin <jason.jin@freescale.com>
+Date: Thu Dec 7 10:32:35 2006 -0600
+
+ Add flash cmd function to 8641HPCN ramboot
+
+ Also fixes some commmand for 8641 HPCN ramboot case.
+
+ Signed-off-by: Jason Jin <jason.jin@freescale.com>
+ Signed-off-by: Jon Loeliger <jdl@freescale.com>
+
+commit 2ccceacc04b009d923afb7c26189ba2f8a2a5d46
+Author: Ed Swarthout <ed.swarthout@freescale.com>
+Date: Thu Dec 7 10:34:14 2006 -0600
+
+ Add support for 8641 Rev 2 silicon.
+
+ Without this patch, I am unable to get to the prompt on rev 2 silicon.
+ Only set ddrioovcr for rev1.
+
+ Signed-off-by: Ed Swarthout<ed.swarthout@freescale.com>
+ Signed-off-by: Jon Loeliger <jdl@freescale.com>
+
+commit 44ba464b99001f8bd1c456a1e9d59726252f707a
+Author: Wolfgang Denk <wd@denx.de>
+Date: Thu Mar 22 00:13:12 2007 +0100
+
+ Code cleanup / re-insert previous Copyright entries.
+
+ Signed-off-by: Wolfgang Denk <wd@denx.de>
+
commit 2a8dfe08359a1b663418b2faa1da1d7bce34d302
Author: Wolfgang Denk <wd@denx.de>
Date: Wed Mar 21 23:26:15 2007 +0100
@@ -148,6 +298,38 @@ Date: Mon Mar 12 00:25:14 2007 +0800
[Blackfin][PATCH] code cleanup
+commit cfc67116a706fd18b8f6a9c11a16753c5626d689
+Author: Michal Simek <monstr@monstr.eu>
+Date: Sun Mar 11 13:48:24 2007 +0100
+
+ [Microblaze][PATCH] part 2
+ timer support
+ interrupt controller support
+ flash support
+ ethernet support
+ cache support
+ board information support
+ env support
+ booting image support
+
+ adding support for Xilinx ML401
+
+commit 76316a318de91f6184e7c22a10e02d275ade2441
+Author: Michal Simek <monstr@monstr.eu>
+Date: Sun Mar 11 13:42:58 2007 +0100
+
+ [Microblaze][PATCH]
+ timer support
+ interrupt controller support
+ flash support
+ ethernet support
+ cache support
+ board information support
+ env support
+ booting image support
+
+ adding support for Xilinx ML401
+
commit 8db13d63157811c839d15a313d9f2d2f5fd10af3
Author: Aubrey Li <aubrey.adi@gmail.com>
Date: Sat Mar 10 23:49:29 2007 +0800
diff --git a/CREDITS b/CREDITS
index 0099bd4..7af1b80 100644
--- a/CREDITS
+++ b/CREDITS
@@ -474,3 +474,8 @@ N: Timur Tabi
E: timur@freescale.com
D: Support for MPC8349E-mITX
W: www.freescale.com
+
+N: Michal Simek
+E: monstr@monstr.eu
+D: Support for Microblaze, ML401, XUPV2P board
+W: www.monstr.eu
diff --git a/MAINTAINERS b/MAINTAINERS
index 68233cf..2a43848 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -564,6 +564,11 @@ Yasushi Shoji <yashi@atmark-techno.com>
SUZAKU MicroBlaze
+Michal Simek <monstr@monstr.eu>
+
+ ML401 MicroBlaze
+ XUPV2P MicroBlaze
+
#########################################################################
# Coldfire Systems: #
# #
diff --git a/MAKEALL b/MAKEALL
index a02d8c1..47f2030 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -293,7 +293,7 @@ LIST_nios2=" \
#########################################################################
LIST_microblaze=" \
- suzaku
+ suzaku ml401 xupv2p
"
#########################################################################
diff --git a/Makefile b/Makefile
index 546960d..84b49fe 100644
--- a/Makefile
+++ b/Makefile
@@ -2346,6 +2346,16 @@ suzaku_config: unconfig
@echo "#define CONFIG_SUZAKU 1" >> $(obj)include/config.h
@$(MKCONFIG) -a $(@:_config=) microblaze microblaze suzaku AtmarkTechno
+ml401_config: unconfig
+ @ >include/config.h
+ @echo "#define CONFIG_ML401 1" >> include/config.h
+ @./mkconfig -a $(@:_config=) microblaze microblaze ml401 xilinx
+
+xupv2p_config: unconfig
+ @ >include/config.h
+ @echo "#define CONFIG_XUPV2P 1" >> include/config.h
+ @./mkconfig -a $(@:_config=) microblaze microblaze xupv2p xilinx
+
#########################################################################
## Blackfin
#########################################################################
diff --git a/README b/README
index 1542864..87d6d10 100644
--- a/README
+++ b/README
@@ -164,6 +164,7 @@ Directory Hierarchy:
- lib_mips Files generic to MIPS architecture
- lib_nios Files generic to NIOS architecture
- lib_ppc Files generic to PowerPC architecture
+- libfdt Library files to support flattened device trees
- net Networking code
- post Power On Self Test
- rtc Real Time Clock drivers
@@ -430,12 +431,23 @@ The following options need to be configured:
expect it to be in bytes, others in MB.
Define CONFIG_MEMSIZE_IN_BYTES to make it in bytes.
- CONFIG_OF_FLAT_TREE
+ CONFIG_OF_LIBFDT / CONFIG_OF_FLAT_TREE
New kernel versions are expecting firmware settings to be
- passed using flat open firmware trees.
- The environment variable "disable_of", when set, disables this
- functionality.
+ passed using flattened device trees (based on open firmware
+ concepts).
+
+ CONFIG_OF_LIBFDT
+ * New libfdt-based support
+ * Adds the "fdt" command
+ * The bootm command does _not_ modify the fdt
+
+ CONFIG_OF_FLAT_TREE
+ * Deprecated, see CONFIG_OF_LIBFDT
+ * Original ft_build.c-based support
+ * Automatically modifies the dft as part of the bootm command
+ * The environment variable "disable_of", when set,
+ disables this functionality.
CONFIG_OF_FLAT_TREE_MAX_SIZE
@@ -448,13 +460,16 @@ The following options need to be configured:
CONFIG_OF_HAS_BD_T
- The resulting flat device tree will have a copy of the bd_t.
- Space should be pre-allocated in the dts for the bd_t.
+ * CONFIG_OF_LIBFDT - enables the "fdt bd_t" command
+ * CONFIG_OF_FLAT_TREE - The resulting flat device tree
+ will have a copy of the bd_t. Space should be
+ pre-allocated in the dts for the bd_t.
CONFIG_OF_HAS_UBOOT_ENV
- The resulting flat device tree will have a copy of u-boot's
- environment variables
+ * CONFIG_OF_LIBFDT - enables the "fdt bd_t" command
+ * CONFIG_OF_FLAT_TREE - The resulting flat device tree
+ will have a copy of u-boot's environment variables
CONFIG_OF_BOARD_SETUP
@@ -721,6 +736,8 @@ The following options need to be configured:
#define CONFIG_COMMANDS (CFG_CMD_ALL & ~CFG_CMD_NET)
+ Other Commands:
+ fdt (flattened device tree) command: CONFIG_OF_LIBFDT
Note: Don't enable the "icache" and "dcache" commands
(configuration option CFG_CMD_CACHE) unless you know
diff --git a/board/AtmarkTechno/suzaku/suzaku.c b/board/AtmarkTechno/suzaku/suzaku.c
index afe124a..267c476 100644
--- a/board/AtmarkTechno/suzaku/suzaku.c
+++ b/board/AtmarkTechno/suzaku/suzaku.c
@@ -24,7 +24,7 @@
/* This is a board specific file. It's OK to include board specific
* header files */
-#include <asm/suzaku.h>
+#include <config.h>
void do_reset(void)
{
diff --git a/board/AtmarkTechno/suzaku/u-boot.lds b/board/AtmarkTechno/suzaku/u-boot.lds
index 00a8ef7..cb90854 100644
--- a/board/AtmarkTechno/suzaku/u-boot.lds
+++ b/board/AtmarkTechno/suzaku/u-boot.lds
@@ -61,6 +61,7 @@ SECTIONS
{
__bss_start = .;
*(.bss)
- __bss_start = .;
+ __bss_end = .;
}
+ __end = . ;
}
diff --git a/board/mpc8360emds/config.mk b/board/mpc8360emds/config.mk
index 9ace886..5801a5f 100644
--- a/board/mpc8360emds/config.mk
+++ b/board/mpc8360emds/config.mk
@@ -26,3 +26,8 @@
#
TEXT_BASE = 0xFE000000
+
+#
+# Additional board-specific libraries
+#
+BOARDLIBS = libfdt/libfdt.a
diff --git a/board/mpc8360emds/mpc8360emds.c b/board/mpc8360emds/mpc8360emds.c
index 535884c..deadb5f 100644
--- a/board/mpc8360emds/mpc8360emds.c
+++ b/board/mpc8360emds/mpc8360emds.c
@@ -31,6 +31,10 @@
#if defined(CONFIG_OF_FLAT_TREE)
#include <ft_build.h>
#endif
+#if defined(CONFIG_OF_LIBFDT)
+#include <libfdt.h>
+#include <libfdt_env.h>
+#endif
const qe_iop_conf_t qe_iop_conf_tab[] = {
/* GETH1 */
@@ -658,22 +662,36 @@ U_BOOT_CMD(ecc, 4, 0, do_ecc,
" - disables injects\n" " - re-inits memory");
#endif /* if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) */
-#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
+#if (defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)) \
+ && defined(CONFIG_OF_BOARD_SETUP)
void
ft_board_setup(void *blob, bd_t *bd)
{
+#if defined(CONFIG_OF_LIBFDT)
+ int nodeoffset;
+ int err;
+ int tmp[2];
+
+ nodeoffset = fdt_path_offset (fdt, "/memory");
+ if (nodeoffset >= 0) {
+ tmp[0] = cpu_to_be32(bd->bi_memstart);
+ tmp[1] = cpu_to_be32(bd->bi_memsize);
+ err = fdt_setprop(fdt, nodeoffset, "reg", tmp, sizeof(tmp));
+ }
+#else
u32 *p;
int len;
-#ifdef CONFIG_PCI
- ft_pci_setup(blob, bd);
-#endif
- ft_cpu_setup(blob, bd);
-
p = ft_get_prop(blob, "/memory/reg", &len);
if (p != NULL) {
*p++ = cpu_to_be32(bd->bi_memstart);
*p = cpu_to_be32(bd->bi_memsize);
}
+#endif
+
+#ifdef CONFIG_PCI
+ ft_pci_setup(blob, bd);
+#endif
+ ft_cpu_setup(blob, bd);
}
#endif
diff --git a/board/mpc8360emds/pci.c b/board/mpc8360emds/pci.c
index 67cd709..158effe 100644
--- a/board/mpc8360emds/pci.c
+++ b/board/mpc8360emds/pci.c
@@ -21,6 +21,10 @@
#if defined(CONFIG_OF_FLAT_TREE)
#include <ft_build.h>
#endif
+#if defined(CONFIG_OF_LIBFDT)
+#include <libfdt.h>
+#include <libfdt_env.h>
+#endif
#include <asm/fsl_i2c.h>
@@ -299,6 +303,22 @@ void pci_init_board(void)
}
#endif /* CONFIG_PCISLAVE */
+#if defined(CONFIG_OF_LIBFDT)
+void
+ft_pci_setup(void *blob, bd_t *bd)
+{
+ int nodeoffset;
+ int err;
+ int tmp[2];
+
+ nodeoffset = fdt_path_offset (fdt, "/" OF_SOC "/pci@8500");
+ if (nodeoffset >= 0) {
+ tmp[0] = cpu_to_be32(hose[0].first_busno);
+ tmp[1] = cpu_to_be32(hose[0].last_busno);
+ err = fdt_setprop(fdt, nodeoffset, "bus-range", tmp, sizeof(tmp));
+ }
+}
+#endif /* CONFIG_OF_LIBFDT */
#ifdef CONFIG_OF_FLAT_TREE
void
ft_pci_setup(void *blob, bd_t *bd)
diff --git a/board/xilinx/ml401/Makefile b/board/xilinx/ml401/Makefile
new file mode 100644
index 0000000..9ab5633
--- /dev/null
+++ b/board/xilinx/ml401/Makefile
@@ -0,0 +1,65 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)../common)
+$(shell mkdir -p $(obj)../xilinx_enet)
+endif
+
+INCS := -I../common -I../xilinx_enet
+CFLAGS += $(INCS)
+HOST_CFLAGS += $(INCS)
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS = $(BOARD).o \
+ ../xilinx_enet/emac_adapter.o ../xilinx_enet/xemac.o \
+ ../xilinx_enet/xemac_options.o ../xilinx_enet/xemac_polled.o \
+ ../xilinx_enet/xemac_intr.o ../xilinx_enet/xemac_g.o \
+ ../xilinx_enet/xemac_intr_dma.o ../common/xipif_v1_23_b.o \
+ ../common/xbasic_types.o ../common/xdma_channel.o \
+ ../common/xdma_channel_sg.o ../common/xpacket_fifo_v1_00_b.o \
+ ../common/xversion.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/ml401/config.mk b/board/xilinx/ml401/config.mk
new file mode 100644
index 0000000..807f169
--- /dev/null
+++ b/board/xilinx/ml401/config.mk
@@ -0,0 +1,32 @@
+#
+# (C) Copyright 2007 Michal Simek
+#
+# Michal SIMEK <monstr@monstr.eu>
+#
+# 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
+#
+# CAUTION: This file is automatically generated by libgen.
+# Version: Xilinx EDK 6.3 EDK_Gmm.12.3
+#
+
+TEXT_BASE = 0x12000000
+
+PLATFORM_CPPFLAGS += -mno-xl-soft-mul
+PLATFORM_CPPFLAGS += -mno-xl-soft-div
+PLATFORM_CPPFLAGS += -mxl-barrel-shift
diff --git a/board/xilinx/ml401/ml401.c b/board/xilinx/ml401/ml401.c
new file mode 100644
index 0000000..b48103f
--- /dev/null
+++ b/board/xilinx/ml401/ml401.c
@@ -0,0 +1,49 @@
+/*
+ * (C) Copyright 2007 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* This is a board specific file. It's OK to include board specific
+ * header files */
+
+#include <common.h>
+#include <config.h>
+
+void do_reset (void)
+{
+#ifdef CFG_GPIO_0
+ *((unsigned long *)(CFG_GPIO_0_ADDR)) =
+ ++(*((unsigned long *)(CFG_GPIO_0_ADDR)));
+#endif
+#ifdef CFG_RESET_ADDRESS
+ puts ("Reseting board\n");
+ asm ("bra r0");
+#endif
+}
+
+int gpio_init (void)
+{
+#ifdef CFG_GPIO_0
+ *((unsigned long *)(CFG_GPIO_0_ADDR)) = 0x0;
+#endif
+ return 0;
+}
diff --git a/include/asm-microblaze/suzaku.h b/board/xilinx/ml401/u-boot.lds
index c57a144..cb90854 100644
--- a/include/asm-microblaze/suzaku.h
+++ b/board/xilinx/ml401/u-boot.lds
@@ -22,6 +22,46 @@
* MA 02111-1307 USA
*/
-/* System Register (GPIO) */
-#define MICROBLAZE_SYSREG_BASE_ADDR 0xFFFFA000
-#define MICROBLAZE_SYSREG_RECONFIGURE (1 << 0)
+OUTPUT_ARCH(microblaze)
+ENTRY(_start)
+
+SECTIONS
+{
+ .text ALIGN(0x4):
+ {
+ __text_start = .;
+ cpu/microblaze/start.o (.text)
+ *(.text)
+ __text_end = .;
+ }
+
+ .rodata ALIGN(0x4):
+ {
+ __rodata_start = .;
+ *(.rodata)
+ __rodata_end = .;
+ }
+
+ .data ALIGN(0x4):
+ {
+ __data_start = .;
+ *(.data)
+ __data_end = .;
+ }
+
+ .u_boot_cmd ALIGN(0x4):
+ {
+ . = .;
+ __u_boot_cmd_start = .;
+ *(.u_boot_cmd)
+ __u_boot_cmd_end = .;
+ }
+
+ .bss ALIGN(0x4):
+ {
+ __bss_start = .;
+ *(.bss)
+ __bss_end = .;
+ }
+ __end = . ;
+}
diff --git a/board/xilinx/ml401/xparameters.h b/board/xilinx/ml401/xparameters.h
new file mode 100644
index 0000000..18d24f9
--- /dev/null
+++ b/board/xilinx/ml401/xparameters.h
@@ -0,0 +1,67 @@
+/*
+ * (C) Copyright 2007 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * 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
+ *
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 6.3 EDK_Gmm.12.3
+ */
+
+/* System Clock Frequency */
+#define XILINX_CLOCK_FREQ 66666667
+
+/* Interrupt controller is intc_0 */
+#define XILINX_INTC_BASEADDR 0xd1000fc0
+#define XILINX_INTC_NUM_INTR_INPUTS 12
+
+/* Timer pheriphery is opb_timer_0 */
+#define XILINX_TIMER_BASEADDR 0xa2000000
+#define XILINX_TIMER_IRQ 0
+
+/* Uart pheriphery is console_uart */
+#define XILINX_UART_BASEADDR 0xa0000000
+#define XILINX_UART_BAUDRATE 115200
+
+/* GPIO is opb_gpio_0*/
+#define XILINX_GPIO_BASEADDR 0x90000000
+
+/* Flash Memory is opb_emc_0 */
+#define XILINX_FLASH_START 0x28000000
+#define XILINX_FLASH_SIZE 0x00800000
+
+/* Main Memory is plb_ddr_0 */
+#define XILINX_RAM_START 0x10000000
+#define XILINX_RAM_SIZE 0x10000000
+
+/* Sysace Controller is opb_sysace_0 */
+#define XILINX_SYSACE_BASEADDR 0xCF000000
+#define XILINX_SYSACE_HIGHADDR 0xCF0001FF
+#define XILINX_SYSACE_MEM_WIDTH 16
+
+/* Ethernet controller is opb_ethernet_0 */
+#define XPAR_XEMAC_NUM_INSTANCES 1
+#define XPAR_OPB_ETHERNET_0_DEVICE_ID 0
+#define XPAR_OPB_ETHERNET_0_BASEADDR 0x60000000
+#define XPAR_OPB_ETHERNET_0_HIGHADDR 0x60003FFF
+#define XPAR_OPB_ETHERNET_0_DMA_PRESENT 1
+#define XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST 1
+#define XPAR_OPB_ETHERNET_0_MII_EXIST 1
diff --git a/board/xilinx/xilinx_enet/emac_adapter.c b/board/xilinx/xilinx_enet/emac_adapter.c
index f159cb6..d340303 100644
--- a/board/xilinx/xilinx_enet/emac_adapter.c
+++ b/board/xilinx/xilinx_enet/emac_adapter.c
@@ -147,7 +147,11 @@ eth_rx(void)
RecvFrameLength = PKTSIZE;
Result = XEmac_PollRecv(&Emac, (u8 *) etherrxbuff, &RecvFrameLength);
if (Result == XST_SUCCESS) {
+#ifndef CONFIG_EMACLITE
NetReceive((uchar *)etherrxbuff, RecvFrameLength);
+#else
+ NetReceive(etherrxbuff, RecvFrameLength);
+#endif
return (1);
} else {
return (0);
diff --git a/board/xilinx/xupv2p/Makefile b/board/xilinx/xupv2p/Makefile
new file mode 100644
index 0000000..9ab5633
--- /dev/null
+++ b/board/xilinx/xupv2p/Makefile
@@ -0,0 +1,65 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)../common)
+$(shell mkdir -p $(obj)../xilinx_enet)
+endif
+
+INCS := -I../common -I../xilinx_enet
+CFLAGS += $(INCS)
+HOST_CFLAGS += $(INCS)
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS = $(BOARD).o \
+ ../xilinx_enet/emac_adapter.o ../xilinx_enet/xemac.o \
+ ../xilinx_enet/xemac_options.o ../xilinx_enet/xemac_polled.o \
+ ../xilinx_enet/xemac_intr.o ../xilinx_enet/xemac_g.o \
+ ../xilinx_enet/xemac_intr_dma.o ../common/xipif_v1_23_b.o \
+ ../common/xbasic_types.o ../common/xdma_channel.o \
+ ../common/xdma_channel_sg.o ../common/xpacket_fifo_v1_00_b.o \
+ ../common/xversion.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/xupv2p/config.mk b/board/xilinx/xupv2p/config.mk
new file mode 100644
index 0000000..c07b0b3
--- /dev/null
+++ b/board/xilinx/xupv2p/config.mk
@@ -0,0 +1,32 @@
+#
+# (C) Copyright 2007 Michal Simek
+#
+# Michal SIMEK <monstr@monstr.eu>
+#
+# 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
+#
+# CAUTION: This file is automatically generated by libgen.
+# Version: Xilinx EDK 8.2.02 EDK_Im_Sp2.4
+#
+
+TEXT_BASE = 0x38000000
+
+PLATFORM_CPPFLAGS += -mno-xl-soft-mul
+PLATFORM_CPPFLAGS += -mno-xl-soft-div
+PLATFORM_CPPFLAGS += -mxl-barrel-shift
diff --git a/board/xilinx/xupv2p/u-boot.lds b/board/xilinx/xupv2p/u-boot.lds
new file mode 100644
index 0000000..cb90854
--- /dev/null
+++ b/board/xilinx/xupv2p/u-boot.lds
@@ -0,0 +1,67 @@
+/*
+ * (C) Copyright 2004 Atmark Techno, Inc.
+ *
+ * Yasushi SHOJI <yashi@atmark-techno.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
+ */
+
+OUTPUT_ARCH(microblaze)
+ENTRY(_start)
+
+SECTIONS
+{
+ .text ALIGN(0x4):
+ {
+ __text_start = .;
+ cpu/microblaze/start.o (.text)
+ *(.text)
+ __text_end = .;
+ }
+
+ .rodata ALIGN(0x4):
+ {
+ __rodata_start = .;
+ *(.rodata)
+ __rodata_end = .;
+ }
+
+ .data ALIGN(0x4):
+ {
+ __data_start = .;
+ *(.data)
+ __data_end = .;
+ }
+
+ .u_boot_cmd ALIGN(0x4):
+ {
+ . = .;
+ __u_boot_cmd_start = .;
+ *(.u_boot_cmd)
+ __u_boot_cmd_end = .;
+ }
+
+ .bss ALIGN(0x4):
+ {
+ __bss_start = .;
+ *(.bss)
+ __bss_end = .;
+ }
+ __end = . ;
+}
diff --git a/board/xilinx/xupv2p/xparameters.h b/board/xilinx/xupv2p/xparameters.h
new file mode 100644
index 0000000..a96c693
--- /dev/null
+++ b/board/xilinx/xupv2p/xparameters.h
@@ -0,0 +1,64 @@
+/*
+ * (C) Copyright 2007 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * 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
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 8.2.02 EDK_Im_Sp2.4
+ */
+
+/* System Clock Frequency */
+#define XILINX_CLOCK_FREQ 100000000
+
+/* Interrupt controller is opb_intc_0 */
+#define XILINX_INTC_BASEADDR 0x41200000
+#define XILINX_INTC_NUM_INTR_INPUTS 11
+
+/* Timer pheriphery is opb_timer_1 */
+#define XILINX_TIMER_BASEADDR 0x41c00000
+#define XILINX_TIMER_IRQ 1
+
+/* Uart pheriphery is RS232_Uart_1 */
+#define XILINX_UART_BASEADDR 0x40600000
+#define XILINX_UART_BAUDRATE 115200
+
+/* GPIO is LEDs_4Bit*/
+#define XILINX_GPIO_BASEADDR 0x40000000
+
+/* FLASH doesn't exist none */
+
+/* Main Memory is DDR_256MB_32MX64_rank1_row13_col10_cl2_5 */
+#define XILINX_RAM_START 0x30000000
+#define XILINX_RAM_SIZE 0x10000000
+
+/* Sysace Controller is SysACE_CompactFlash */
+#define XILINX_SYSACE_BASEADDR 0x41800000
+#define XILINX_SYSACE_HIGHADDR 0x4180ffff
+#define XILINX_SYSACE_MEM_WIDTH 16
+
+/* Ethernet controller is Ethernet_MAC */
+#define XPAR_XEMAC_NUM_INSTANCES 1
+#define XPAR_OPB_ETHERNET_0_DEVICE_ID 0
+#define XPAR_OPB_ETHERNET_0_BASEADDR 0x40c00000
+#define XPAR_OPB_ETHERNET_0_HIGHADDR 0x40c0ffff
+#define XPAR_OPB_ETHERNET_0_DMA_PRESENT 1
+#define XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST 1
+#define XPAR_OPB_ETHERNET_0_MII_EXIST 1
diff --git a/board/xilinx/xupv2p/xupv2p.c b/board/xilinx/xupv2p/xupv2p.c
new file mode 100644
index 0000000..b48103f
--- /dev/null
+++ b/board/xilinx/xupv2p/xupv2p.c
@@ -0,0 +1,49 @@
+/*
+ * (C) Copyright 2007 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* This is a board specific file. It's OK to include board specific
+ * header files */
+
+#include <common.h>
+#include <config.h>
+
+void do_reset (void)
+{
+#ifdef CFG_GPIO_0
+ *((unsigned long *)(CFG_GPIO_0_ADDR)) =
+ ++(*((unsigned long *)(CFG_GPIO_0_ADDR)));
+#endif
+#ifdef CFG_RESET_ADDRESS
+ puts ("Reseting board\n");
+ asm ("bra r0");
+#endif
+}
+
+int gpio_init (void)
+{
+#ifdef CFG_GPIO_0
+ *((unsigned long *)(CFG_GPIO_0_ADDR)) = 0x0;
+#endif
+ return 0;
+}
diff --git a/common/Makefile b/common/Makefile
index 6f81c4a..74a6af2 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -32,7 +32,7 @@ COBJS = main.o ACEX1K.o altera.o bedbug.o circbuf.o cmd_autoscript.o \
cmd_cache.o cmd_console.o \
cmd_date.o cmd_dcr.o cmd_diag.o cmd_display.o cmd_doc.o cmd_dtt.o \
cmd_eeprom.o cmd_elf.o cmd_ext2.o \
- cmd_fat.o cmd_fdc.o cmd_fdos.o cmd_flash.o cmd_fpga.o \
+ cmd_fat.o cmd_fdc.o cmd_fdt.o cmd_fdos.o cmd_flash.o cmd_fpga.o \
cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o \
cmd_load.o cmd_log.o \
cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \
diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c
index 70de795..d97c09e 100644
--- a/common/cmd_bdinfo.c
+++ b/common/cmd_bdinfo.c
@@ -180,6 +180,32 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
return 0;
}
+#elif defined(CONFIG_MICROBLAZE) /* ! PPC, which leaves Microblaze */
+
+int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ int i;
+ bd_t *bd = gd->bd;
+ print_num ("mem start ", (ulong)bd->bi_memstart);
+ print_num ("mem size ", (ulong)bd->bi_memsize);
+ print_num ("flash start ", (ulong)bd->bi_flashstart);
+ print_num ("flash size ", (ulong)bd->bi_flashsize);
+ print_num ("flash offset ", (ulong)bd->bi_flashoffset);
+#if defined(CFG_SRAM_BASE)
+ print_num ("sram start ", (ulong)bd->bi_sramstart);
+ print_num ("sram size ", (ulong)bd->bi_sramsize);
+#endif
+#if defined(CFG_CMD_NET)
+ puts ("ethaddr =");
+ for (i=0; i<6; ++i) {
+ printf ("%c%02X", i ? ':' : ' ', bd->bi_enetaddr[i]);
+ }
+ puts ("\nip_addr = ");
+ print_IPaddr (bd->bi_ip_addr);
+#endif
+ printf ("\nbaudrate = %d bps\n", (ulong)bd->bi_baudrate);
+ return 0;
+}
#else /* ! PPC, which leaves MIPS */
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index c0ed076..2721216b 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -34,7 +34,11 @@
#include <environment.h>
#include <asm/byteorder.h>
-#ifdef CONFIG_OF_FLAT_TREE
+#if defined(CONFIG_OF_LIBFDT)
+#include <fdt.h>
+#include <libfdt.h>
+#endif
+#if defined(CONFIG_OF_FLAT_TREE)
#include <ft_build.h>
#endif
@@ -467,7 +471,7 @@ U_BOOT_CMD(
"[addr [arg ...]]\n - boot application image stored in memory\n"
"\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
"\t'arg' can be the address of an initrd image\n"
-#ifdef CONFIG_OF_FLAT_TREE
+#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
"\tWhen booting a Linux kernel which requires a flat device-tree\n"
"\ta third argument is required which is the address of the of the\n"
"\tdevice-tree blob. To boot that kernel without an initrd image,\n"
@@ -529,7 +533,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
bd_t *kbd;
void (*kernel)(bd_t *, ulong, ulong, ulong, ulong);
image_header_t *hdr = &header;
-#ifdef CONFIG_OF_FLAT_TREE
+#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
char *of_flat_tree = NULL;
ulong of_data = 0;
#endif
@@ -622,7 +626,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
* Check if there is an initrd image
*/
-#ifdef CONFIG_OF_FLAT_TREE
+#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
/* Look for a '-' which indicates to ignore the ramdisk argument */
if (argc >= 3 && strcmp(argv[2], "-") == 0) {
debug ("Skipping initrd\n");
@@ -739,12 +743,15 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
len = data = 0;
}
-#ifdef CONFIG_OF_FLAT_TREE
+#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
if(argc > 3) {
of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16);
hdr = (image_header_t *)of_flat_tree;
-
- if (*(ulong *)of_flat_tree == OF_DT_HEADER) {
+#if defined(CONFIG_OF_LIBFDT)
+ if (be32_to_cpu(fdt_magic(of_flat_tree)) == FDT_MAGIC) {
+#else
+ if (*(ulong *)of_flat_tree == OF_DT_HEADER) {
+#endif
#ifndef CFG_NO_FLASH
if (addr2info((ulong)of_flat_tree) != NULL)
of_data = (ulong)of_flat_tree;
@@ -787,7 +794,11 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
printf("ERROR: uImage is not uncompressed\n");
return;
}
+#if defined(CONFIG_OF_LIBFDT)
+ if (be32_to_cpu(fdt_magic(of_flat_tree + sizeof(image_header_t))) != FDT_MAGIC) {
+#else
if (*((ulong *)(of_flat_tree + sizeof(image_header_t))) != OF_DT_HEADER) {
+#endif
printf ("ERROR: uImage data is not a flat device tree\n");
return;
}
@@ -824,12 +835,20 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
of_data += 4 - tail;
}
+#if defined(CONFIG_OF_LIBFDT)
+ if (be32_to_cpu(fdt_magic(of_data)) != FDT_MAGIC) {
+#else
if (((struct boot_param_header *)of_data)->magic != OF_DT_HEADER) {
+#endif
printf ("ERROR: image is not a flat device tree\n");
return;
}
+#if defined(CONFIG_OF_LIBFDT)
+ if (be32_to_cpu(fdt_totalsize(of_data)) != ntohl(len_ptr[2])) {
+#else
if (((struct boot_param_header *)of_data)->totalsize != ntohl(len_ptr[2])) {
+#endif
printf ("ERROR: flat device tree size does not agree with image\n");
return;
}
@@ -913,7 +932,31 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
unlock_ram_in_cache();
#endif
-#ifdef CONFIG_OF_FLAT_TREE
+#if defined(CONFIG_OF_LIBFDT)
+ /* move of_flat_tree if needed */
+ if (of_data) {
+ int err;
+ ulong of_start, of_len;
+ of_len = be32_to_cpu(fdt_totalsize(of_data));
+ /* provide extra 8k pad */
+ if (initrd_start)
+ of_start = initrd_start - of_len - 8192;
+ else
+ of_start = (ulong)kbd - of_len - 8192;
+ of_start &= ~(4096 - 1); /* align on page */
+ debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
+ of_data, of_data + of_len - 1, of_len, of_len);
+
+
+ printf (" Loading Device Tree to %08lx, end %08lx ... ",
+ of_start, of_start + of_len - 1);
+ err = fdt_open_into(of_start, of_data, of_len);
+ if (err != 0) {
+ printf ("libfdt: %s\n", fdt_strerror(err));
+ }
+ }
+#endif
+#if defined(CONFIG_OF_FLAT_TREE)
/* move of_flat_tree if needed */
if (of_data) {
ulong of_start, of_len;
@@ -942,13 +985,13 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
* r6: Start of command line string
* r7: End of command line string
*/
-#ifdef CONFIG_OF_FLAT_TREE
+#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
if (!of_flat_tree) /* no device tree; boot old style */
#endif
(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
/* does not return */
-#ifdef CONFIG_OF_FLAT_TREE
+#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT)
/*
* Linux Kernel Parameters (passing device tree):
* r3: ptr to OF flat tree, followed by the board info data
@@ -957,8 +1000,10 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
* r6: NULL
* r7: NULL
*/
+#if defined(CONFIG_OF_FLAT_TREE)
ft_setup(of_flat_tree, kbd, initrd_start, initrd_end);
/* ft_dump_blob(of_flat_tree); */
+#endif
(*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0);
#endif
diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c
new file mode 100644
index 0000000..968bade
--- /dev/null
+++ b/common/cmd_fdt.c
@@ -0,0 +1,874 @@
+/*
+ * (C) Copyright 2007
+ * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com
+ * Based on code written by:
+ * Pantelis Antoniou <pantelis.antoniou@gmail.com> and
+ * Matthew McClintock <msm@freescale.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 <linux/ctype.h>
+#include <linux/types.h>
+
+#ifdef CONFIG_OF_LIBFDT
+#include <asm/global_data.h>
+#include <fdt.h>
+#include <libfdt.h>
+
+#define MAX_LEVEL 32 /* how deeply nested we will go */
+#define SCRATCHPAD 1024 /* bytes of scratchpad memory */
+
+/*
+ * Global data (for the gd->bd)
+ */
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Scratchpad memory.
+ */
+static char data[SCRATCHPAD];
+
+
+/*
+ * Function prototypes/declarations.
+ */
+static int fdt_valid(void);
+static void print_data(const void *data, int len);
+static int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end);
+static int fdt_env(void *fdt);
+static int fdt_bd_t(void *fdt);
+
+
+/*
+ * Flattened Device Tree command, see the help for parameter definitions.
+ */
+int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ char op;
+
+ if (argc < 2) {
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
+ /*
+ * Figure out which subcommand was given
+ */
+ op = argv[1][0];
+ /********************************************************************
+ * Set the address of the fdt
+ ********************************************************************/
+ if (op == 'a') {
+ /*
+ * Set the address [and length] of the fdt.
+ */
+ fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16);
+
+ if (!fdt_valid()) {
+ return 1;
+ }
+
+ if (argc >= 4) {
+ int len;
+ int err;
+ /*
+ * Optional new length
+ */
+ len = simple_strtoul(argv[3], NULL, 16);
+ if (len < fdt_totalsize(fdt)) {
+ printf ("New length %d < existing length %d, ignoring.\n",
+ len, fdt_totalsize(fdt));
+ } else {
+ /*
+ * Open in place with a new length.
+ */
+ err = fdt_open_into(fdt, fdt, len);
+ if (err != 0) {
+ printf ("libfdt: %s\n", fdt_strerror(err));
+ }
+ }
+ }
+
+ /********************************************************************
+ * Move the fdt
+ ********************************************************************/
+ } else if (op == 'm') {
+ struct fdt_header *newaddr;
+ int len;
+ int err;
+
+ if (argc != 5) {
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
+ /*
+ * Set the address and length of the fdt.
+ */
+ fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16);
+ if (!fdt_valid()) {
+ return 1;
+ }
+
+ newaddr = (struct fdt_header *)simple_strtoul(argv[3], NULL, 16);
+ len = simple_strtoul(argv[4], NULL, 16);
+ if (len < fdt_totalsize(fdt)) {
+ printf ("New length %d < existing length %d, aborting.\n",
+ len, fdt_totalsize(fdt));
+ return 1;
+ }
+
+ /*
+ * Copy to the new location.
+ */
+ err = fdt_open_into(fdt, newaddr, len);
+ if (err != 0) {
+ printf ("libfdt: %s\n", fdt_strerror(err));
+ return 1;
+ }
+ fdt = newaddr;
+
+ /********************************************************************
+ * Set the value of a node in the fdt.
+ ********************************************************************/
+ } else if (op == 's') {
+ char *pathp; /* path */
+ char *prop; /* property */
+ struct fdt_property *nodep; /* node struct pointer */
+ char *newval; /* value from the user (as a string) */
+ char *vp; /* temporary value pointer */
+ char *cp; /* temporary char pointer */
+ int nodeoffset; /* node offset from libfdt */
+ int len; /* new length of the property */
+ int oldlen; /* original length of the property */
+ unsigned long tmp; /* holds converted values */
+ int ret; /* return value */
+
+ /*
+ * Parameters: Node path, property, value.
+ */
+ if (argc < 5) {
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
+ pathp = argv[2];
+ prop = argv[3];
+ newval = argv[4];
+
+ if (strcmp(pathp, "/") == 0) {
+ nodeoffset = 0;
+ } else {
+ nodeoffset = fdt_path_offset (fdt, pathp);
+ if (nodeoffset < 0) {
+ /*
+ * Not found or something else bad happened.
+ */
+ printf ("libfdt: %s\n", fdt_strerror(nodeoffset));
+ return 1;
+ }
+ }
+ nodep = fdt_getprop (fdt, nodeoffset, prop, &oldlen);
+ if (oldlen < 0) {
+ printf ("libfdt %s\n", fdt_strerror(oldlen));
+ return 1;
+ } else if (oldlen == 0) {
+ /*
+ * The specified property has no value
+ */
+ printf("%s has no value, cannot set one (yet).\n", prop);
+ return 1;
+ } else {
+ /*
+ * Convert the new property
+ */
+ vp = data;
+ if (*newval == '<') {
+ /*
+ * Bigger values than bytes.
+ */
+ len = 0;
+ newval++;
+ while ((*newval != '>') && (*newval != '\0')) {
+ cp = newval;
+ tmp = simple_strtoul(cp, &newval, 16);
+ if ((newval - cp) <= 2) {
+ *vp = tmp & 0xFF;
+ vp += 1;
+ len += 1;
+ } else if ((newval - cp) <= 4) {
+ *(uint16_t *)vp = __cpu_to_be16(tmp);
+ vp += 2;
+ len += 2;
+ } else if ((newval - cp) <= 8) {
+ *(uint32_t *)vp = __cpu_to_be32(tmp);
+ vp += 4;
+ len += 4;
+ } else {
+ printf("Sorry, I could not convert \"%s\"\n", cp);
+ return 1;
+ }
+ while (*newval == ' ')
+ newval++;
+ }
+ if (*newval != '>') {
+ printf("Unexpected character '%c'\n", *newval);
+ return 1;
+ }
+ } else if (*newval == '[') {
+ /*
+ * Byte stream. Convert the values.
+ */
+ len = 0;
+ newval++;
+ while ((*newval != ']') && (*newval != '\0')) {
+ tmp = simple_strtoul(newval, &newval, 16);
+ *vp++ = tmp & 0xFF;
+ len++;
+ while (*newval == ' ')
+ newval++;
+ }
+ if (*newval != ']') {
+ printf("Unexpected character '%c'\n", *newval);
+ return 1;
+ }
+ } else {
+ /*
+ * Assume it is a string. Copy it into our data area for
+ * convenience (including the terminating '\0').
+ */
+ len = strlen(newval) + 1;
+ strcpy(data, newval);
+ }
+
+ ret = fdt_setprop(fdt, nodeoffset, prop, data, len);
+ if (ret < 0) {
+ printf ("libfdt %s\n", fdt_strerror(ret));
+ return 1;
+ }
+ }
+
+ /********************************************************************
+ * Print (recursive) / List (single level)
+ ********************************************************************/
+ } else if ((op == 'p') || (op == 'l')) {
+ /*
+ * Recursively print (a portion of) the fdt.
+ */
+ static int offstack[MAX_LEVEL];
+ static char tabs[MAX_LEVEL+1] = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
+ int depth = MAX_LEVEL; /* how deep to print */
+ char *pathp; /* path */
+ char *prop; /* property */
+ void *nodep; /* property node pointer */
+ int nodeoffset; /* node offset from libfdt */
+ int nextoffset; /* next node offset from libfdt */
+ uint32_t tag; /* tag */
+ int len; /* length of the property */
+ int level = 0; /* keep track of nesting level */
+
+ /*
+ * list is an alias for print, but limited to 1 level
+ */
+ if (op == 'l') {
+ depth = 1;
+ }
+
+ /*
+ * Get the starting path. The root node is an oddball,
+ * the offset is zero and has no name.
+ */
+ pathp = argv[2];
+ if (argc > 3)
+ prop = argv[3];
+ else
+ prop = NULL;
+
+ if (strcmp(pathp, "/") == 0) {
+ nodeoffset = 0;
+ printf("/");
+ } else {
+ nodeoffset = fdt_path_offset (fdt, pathp);
+ if (nodeoffset < 0) {
+ /*
+ * Not found or something else bad happened.
+ */
+ printf ("libfdt %s\n", fdt_strerror(nodeoffset));
+ return 1;
+ }
+ }
+ /*
+ * The user passed in a property as well as node path. Print only
+ * the given property and then return.
+ */
+ if (prop) {
+ nodep = fdt_getprop (fdt, nodeoffset, prop, &len);
+ if (len == 0) {
+ printf("%s %s\n", pathp, prop); /* no property value */
+ return 0;
+ } else if (len > 0) {
+ printf("%s=", prop);
+ print_data (nodep, len);
+ printf("\n");
+ return 0;
+ } else {
+ printf ("libfdt %s\n", fdt_strerror(len));
+ return 1;
+ }
+ }
+
+ /*
+ * The user passed in a node path and no property, print the node
+ * and all subnodes.
+ */
+ offstack[0] = nodeoffset;
+
+ while(level >= 0) {
+ tag = fdt_next_tag(fdt, nodeoffset, &nextoffset, &pathp);
+ switch(tag) {
+ case FDT_BEGIN_NODE:
+ if(level <= depth)
+ printf("%s%s {\n", &tabs[MAX_LEVEL - level], pathp);
+ level++;
+ offstack[level] = nodeoffset;
+ if (level >= MAX_LEVEL) {
+ printf("Aaaiii <splat> nested too deep.\n");
+ return 1;
+ }
+ break;
+ case FDT_END_NODE:
+ level--;
+ if(level <= depth)
+ printf("%s};\n", &tabs[MAX_LEVEL - level]);
+ if (level == 0) {
+ level = -1; /* exit the loop */
+ }
+ break;
+ case FDT_PROP:
+ nodep = fdt_getprop (fdt, offstack[level], pathp, &len);
+ if (len < 0) {
+ printf ("libfdt %s\n", fdt_strerror(len));
+ return 1;
+ } else if (len == 0) {
+ /* the property has no value */
+ if(level <= depth)
+ printf("%s%s;\n", &tabs[MAX_LEVEL - level], pathp);
+ } else {
+ if(level <= depth) {
+ printf("%s%s=", &tabs[MAX_LEVEL - level], pathp);
+ print_data (nodep, len);
+ printf(";\n");
+ }
+ }
+ break;
+ case FDT_NOP:
+ break;
+ case FDT_END:
+ return 1;
+ default:
+ if(level <= depth)
+ printf("Unknown tag 0x%08X\n", tag);
+ return 1;
+ }
+ nodeoffset = nextoffset;
+ }
+
+ /********************************************************************
+ * Remove a property/node
+ ********************************************************************/
+ } else if (op == 'r') {
+ int nodeoffset; /* node offset from libfdt */
+ int err;
+
+ /*
+ * Get the path. The root node is an oddball, the offset
+ * is zero and has no name.
+ */
+ if (strcmp(argv[2], "/") == 0) {
+ nodeoffset = 0;
+ } else {
+ nodeoffset = fdt_path_offset (fdt, argv[2]);
+ if (nodeoffset < 0) {
+ /*
+ * Not found or something else bad happened.
+ */
+ printf ("libfdt %s\n", fdt_strerror(nodeoffset));
+ return 1;
+ }
+ }
+ /*
+ * Do the delete. A fourth parameter means delete a property,
+ * otherwise delete the node.
+ */
+ if (argc > 3) {
+ err = fdt_delprop(fdt, nodeoffset, argv[3]);
+ if (err < 0) {
+ printf("fdt_delprop libfdt: %s\n", fdt_strerror(err));
+ return err;
+ }
+ } else {
+ err = fdt_del_node(fdt, nodeoffset);
+ if (err < 0) {
+ printf("fdt_del_node libfdt: %s\n", fdt_strerror(err));
+ return err;
+ }
+ }
+
+ /********************************************************************
+ * Create a chosen node
+ ********************************************************************/
+ } else if (op == 'c') {
+ fdt_chosen(fdt, 0, 0);
+
+ /********************************************************************
+ * Create a u-boot-env node
+ ********************************************************************/
+ } else if (op == 'e') {
+ fdt_env(fdt);
+
+ /********************************************************************
+ * Create a bd_t node
+ ********************************************************************/
+ } else if (op == 'b') {
+ fdt_bd_t(fdt);
+
+ /********************************************************************
+ * Unrecognized command
+ ********************************************************************/
+ } else {
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
+ return 0;
+}
+
+/********************************************************************/
+
+static int fdt_valid(void)
+{
+ if (fdt == NULL) {
+ printf ("The address of the fdt is invalid.\n");
+ return 0;
+ }
+ if (!fdt || (fdt_magic(fdt) != FDT_MAGIC)) {
+ fdt = NULL;
+ printf ("Unrecognized fdt: bad magic\n");
+ return 0;
+ }
+ if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) {
+ printf ("Unsupported fdt version: $d < %d\n",
+ FDT_FIRST_SUPPORTED_VERSION, fdt_version(fdt));
+ fdt = NULL;
+ return 0;
+ }
+ if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) {
+ printf ("Unsupported fdt version: $d > %d\n",
+ fdt_version(fdt), FDT_LAST_SUPPORTED_VERSION);
+ fdt = NULL;
+ return 0;
+ }
+ return 1;
+}
+
+/********************************************************************/
+
+/*
+ * OF flat tree handling
+ * Written by: Pantelis Antoniou <pantelis.antoniou@gmail.com>
+ * Updated by: Matthew McClintock <msm@freescale.com>
+ * Converted to libfdt by: Gerald Van Baren <vanbaren@cideas.com>
+ */
+
+static int is_printable_string(const void *data, int len)
+{
+ const char *s = data;
+
+ /* zero length is not */
+ if (len == 0)
+ return 0;
+
+ /* must terminate with zero */
+ if (s[len - 1] != '\0')
+ return 0;
+
+ /* printable or a null byte (concatenated strings) */
+ while (((*s == '\0') || isprint(*s)) && (len > 0)) {
+ /*
+ * If we see a null, there are three possibilities:
+ * 1) If len == 1, it is the end of the string, printable
+ * 2) Next character also a null, not printable.
+ * 3) Next character not a null, continue to check.
+ */
+ if (s[0] == '\0') {
+ if (len == 1)
+ return 1;
+ if (s[1] == '\0')
+ return 0;
+ }
+ s++;
+ len--;
+ }
+
+ /* Not the null termination, or not done yet: not printable */
+ if (*s != '\0' || (len != 0))
+ return 0;
+
+ return 1;
+}
+
+static void print_data(const void *data, int len)
+{
+ int j;
+ const u8 *s;
+
+ /* no data, don't print */
+ if (len == 0)
+ return;
+
+ /*
+ * It is a string, but it may have multiple strings (embedded '\0's).
+ */
+ if (is_printable_string(data, len)) {
+ puts("\"");
+ j = 0;
+ while (j < len) {
+ if (j > 0)
+ puts("\", \"");
+ puts(data);
+ j += strlen(data) + 1;
+ data += strlen(data) + 1;
+ }
+ puts("\"");
+ return;
+ }
+
+ switch (len) {
+ case 1: /* byte */
+ printf("<%02x>", (*(u8 *) data) & 0xff);
+ break;
+ case 2: /* half-word */
+ printf("<%04x>", be16_to_cpu(*(u16 *) data) & 0xffff);
+ break;
+ case 4: /* word */
+ printf("<%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
+ break;
+ case 8: /* double-word */
+#if __WORDSIZE == 64
+ printf("<%016llx>", be64_to_cpu(*(uint64_t *) data));
+#else
+ printf("<%08x ", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
+ data += 4;
+ printf("%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
+#endif
+ break;
+ default: /* anything else... hexdump */
+ printf("[");
+ for (j = 0, s = data; j < len; j++)
+ printf("%02x%s", s[j], j < len - 1 ? " " : "");
+ printf("]");
+
+ break;
+ }
+}
+
+/********************************************************************/
+
+static int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end)
+{
+ bd_t *bd = gd->bd;
+ int nodeoffset;
+ int err;
+ u32 tmp; /* used to set 32 bit integer properties */
+ char *str; /* used to set string properties */
+ ulong clock;
+
+ if (initrd_start && initrd_end) {
+ err = fdt_add_reservemap_entry(fdt,
+ initrd_start, initrd_end - initrd_start + 1);
+ if (err < 0) {
+ printf("libfdt: %s\n", fdt_strerror(err));
+ return err;
+ }
+ }
+
+ /*
+ * See if we already have a "chosen" node, create it if not.
+ */
+ nodeoffset = fdt_path_offset (fdt, "/chosen");
+ if (nodeoffset < 0) {
+ /*
+ * Create a new node "/chosen" (offset 0 is root level)
+ */
+ nodeoffset = fdt_add_subnode(fdt, 0, "chosen");
+ if (nodeoffset < 0) {
+ printf("libfdt: %s\n", fdt_strerror(nodeoffset));
+ return nodeoffset;
+ }
+ }
+
+ str = getenv("bootargs");
+ if (str != NULL) {
+ err = fdt_setprop(fdt, nodeoffset, "bootargs", str, strlen(str)+1);
+ if (err < 0)
+ printf("libfdt: %s\n", fdt_strerror(err));
+ }
+ if (initrd_start && initrd_end) {
+ tmp = __cpu_to_be32(initrd_start);
+ err = fdt_setprop(fdt, nodeoffset, "linux,initrd-start", &tmp, sizeof(tmp));
+ if (err < 0)
+ printf("libfdt: %s\n", fdt_strerror(err));
+ tmp = __cpu_to_be32(initrd_end);
+ err = fdt_setprop(fdt, nodeoffset, "linux,initrd-end", &tmp, sizeof(tmp));
+ if (err < 0)
+ printf("libfdt: %s\n", fdt_strerror(err));
+ }
+#ifdef OF_STDOUT_PATH
+ err = fdt_setprop(fdt, nodeoffset, "linux,stdout-path", OF_STDOUT_PATH, strlen(OF_STDOUT_PATH)+1);
+ if (err < 0)
+ printf("libfdt: %s\n", fdt_strerror(err));
+#endif
+
+ nodeoffset = fdt_path_offset (fdt, "/cpus");
+ if (nodeoffset >= 0) {
+ clock = cpu_to_be32(bd->bi_intfreq);
+ err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4);
+ if (err < 0)
+ printf("libfdt: %s\n", fdt_strerror(err));
+ }
+#ifdef OF_TBCLK
+ nodeoffset = fdt_path_offset (fdt, "/cpus/" OF_CPU "/timebase-frequency");
+ if (nodeoffset >= 0) {
+ clock = cpu_to_be32(OF_TBCLK);
+ err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4);
+ if (err < 0)
+ printf("libfdt: %s\n", fdt_strerror(err));
+ }
+#endif
+}
+
+/********************************************************************/
+
+#ifdef CONFIG_OF_HAS_BD_T
+
+/* Function that returns a character from the environment */
+extern uchar(*env_get_char) (int);
+
+#define BDM(x) { .name = #x, .offset = offsetof(bd_t, bi_ ##x ) }
+
+static const struct {
+ const char *name;
+ int offset;
+} bd_map[] = {
+ BDM(memstart),
+ BDM(memsize),
+ BDM(flashstart),
+ BDM(flashsize),
+ BDM(flashoffset),
+ BDM(sramstart),
+ BDM(sramsize),
+#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \
+ || defined(CONFIG_E500)
+ BDM(immr_base),
+#endif
+#if defined(CONFIG_MPC5xxx)
+ BDM(mbar_base),
+#endif
+#if defined(CONFIG_MPC83XX)
+ BDM(immrbar),
+#endif
+#if defined(CONFIG_MPC8220)
+ BDM(mbar_base),
+ BDM(inpfreq),
+ BDM(pcifreq),
+ BDM(pevfreq),
+ BDM(flbfreq),
+ BDM(vcofreq),
+#endif
+ BDM(bootflags),
+ BDM(ip_addr),
+ BDM(intfreq),
+ BDM(busfreq),
+#ifdef CONFIG_CPM2
+ BDM(cpmfreq),
+ BDM(brgfreq),
+ BDM(sccfreq),
+ BDM(vco),
+#endif
+#if defined(CONFIG_MPC5xxx)
+ BDM(ipbfreq),
+ BDM(pcifreq),
+#endif
+ BDM(baudrate),
+};
+
+static int fdt_env(void *fdt)
+{
+ int nodeoffset;
+ int err;
+ int k, nxt;
+ int i;
+ static char tmpenv[256];
+
+ /*
+ * See if we already have a "u-boot-env" node, delete it if so.
+ * Then create a new empty node.
+ */
+ nodeoffset = fdt_path_offset (fdt, "/u-boot-env");
+ if (nodeoffset >= 0) {
+ err = fdt_del_node(fdt, nodeoffset);
+ if (err < 0) {
+ printf("libfdt: %s\n", fdt_strerror(err));
+ return err;
+ }
+ }
+ /*
+ * Create a new node "/u-boot-env" (offset 0 is root level)
+ */
+ nodeoffset = fdt_add_subnode(fdt, 0, "u-boot-env");
+ if (nodeoffset < 0) {
+ printf("libfdt: %s\n", fdt_strerror(nodeoffset));
+ return nodeoffset;
+ }
+
+ for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
+ char *s, *lval, *rval;
+
+ /*
+ * Find the end of the name=definition
+ */
+ for (nxt = i; env_get_char(nxt) != '\0'; ++nxt)
+ ;
+ s = tmpenv;
+ for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k)
+ *s++ = env_get_char(k);
+ *s++ = '\0';
+ lval = tmpenv;
+ /*
+ * Find the first '=': it separates the name from the value
+ */
+ s = strchr(tmpenv, '=');
+ if (s != NULL) {
+ *s++ = '\0';
+ rval = s;
+ } else
+ continue;
+ err = fdt_setprop(fdt, nodeoffset, lval, rval, strlen(rval)+1);
+ if (err < 0) {
+ printf("\"%s\" - libfdt: %s\n", lval, fdt_strerror(err));
+ return err;
+ }
+ }
+ return 0;
+}
+#endif /* CONFIG_OF_HAS_UBOOT_ENV */
+
+/********************************************************************/
+
+#ifdef CONFIG_OF_HAS_BD_T
+static int fdt_bd_t(void *fdt)
+{
+ bd_t *bd = gd->bd;
+ int nodeoffset;
+ int err;
+ u32 tmp; /* used to set 32 bit integer properties */
+ int i;
+
+ /*
+ * See if we already have a "bd_t" node, delete it if so.
+ * Then create a new empty node.
+ */
+ nodeoffset = fdt_path_offset (fdt, "/bd_t");
+ if (nodeoffset >= 0) {
+ err = fdt_del_node(fdt, nodeoffset);
+ if (err < 0) {
+ printf("libfdt: %s\n", fdt_strerror(err));
+ return err;
+ }
+ }
+ /*
+ * Create a new node "/bd_t" (offset 0 is root level)
+ */
+ nodeoffset = fdt_add_subnode(fdt, 0, "bd_t");
+ if (nodeoffset < 0) {
+ printf("libfdt: %s\n", fdt_strerror(nodeoffset));
+ return nodeoffset;
+ }
+ /*
+ * Use the string/pointer structure to create the entries...
+ */
+ for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) {
+ tmp = cpu_to_be32(getenv("bootargs"));
+ err = fdt_setprop(fdt, nodeoffset, bd_map[i].name, &tmp, sizeof(tmp));
+ if (err < 0)
+ printf("libfdt: %s\n", fdt_strerror(err));
+ }
+ /*
+ * Add a couple of oddball entries...
+ */
+ err = fdt_setprop(fdt, nodeoffset, "enetaddr", &bd->bi_enetaddr, 6);
+ if (err < 0)
+ printf("libfdt: %s\n", fdt_strerror(err));
+ err = fdt_setprop(fdt, nodeoffset, "ethspeed", &bd->bi_ethspeed, 4);
+ if (err < 0)
+ printf("libfdt: %s\n", fdt_strerror(err));
+
+#ifdef CONFIG_OF_BOARD_SETUP
+ ft_board_setup(fdt, bd);
+#endif
+
+ return 0;
+}
+#endif /* CONFIG_OF_HAS_BD_T */
+
+/********************************************************************/
+
+U_BOOT_CMD(
+ fdt, 5, 0, do_fdt,
+ "fdt - flattened device tree utility commands\n",
+ "addr <addr> [<length>] - Set the fdt location to <addr>\n"
+ "fdt move <fdt> <newaddr> <length> - Copy the fdt to <addr>\n"
+ "fdt print <path> [<prop>] - Recursive print starting at <path>\n"
+ "fdt list <path> [<prop>] - Print one level starting at <path>\n"
+ "fdt set <path> <prop> [<val>] - Set <property> [to <val>]\n"
+ "fdt mknode <path> <node> - Create a new node after <path>\n"
+ "fdt rm <path> [<prop>] - Delete the node or <property>\n"
+ "fdt chosen - Add/update the \"/chosen\" branch in the tree\n"
+#ifdef CONFIG_OF_HAS_UBOOT_ENV
+ "fdt env - Add/replace the \"/u-boot-env\" branch in the tree\n"
+#endif
+#ifdef CONFIG_OF_HAS_BD_T
+ "fdt bd_t - Add/replace the \"/bd_t\" branch in the tree\n"
+#endif
+ "Hints:\n"
+ " * Set a larger length with the fdt addr command to add to the blob.\n"
+ " * If the property you are setting/printing has a '#' character,\n"
+ " you MUST escape it with a \\ character or quote it with \" or\n"
+ " it will be ignored as a comment.\n"
+ " * If the value has spaces in it, you MUST escape the spaces with\n"
+ " \\ characters or quote it with \"\"\n"
+ "Examples: fdt print / # print the whole tree\n"
+ " fdt print /cpus \"#address-cells\"\n"
+ " fdt set /cpus \"#address-cells\" \"[00 00 00 01]\"\n"
+);
+
+#endif /* CONFIG_OF_FLAT_TREE */
diff --git a/cpu/microblaze/Makefile b/cpu/microblaze/Makefile
index fd54425..db1afa5 100644
--- a/cpu/microblaze/Makefile
+++ b/cpu/microblaze/Makefile
@@ -26,7 +26,8 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
START = start.o
-COBJS = cpu.o interrupts.o
+SOBJS = dcache.o icache.o irq.o disable_int.o enable_int.o
+COBJS = cpu.o interrupts.o cache.o exception.o timer.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/cpu/microblaze/cache.c b/cpu/microblaze/cache.c
new file mode 100644
index 0000000..fc388eb
--- /dev/null
+++ b/cpu/microblaze/cache.c
@@ -0,0 +1,48 @@
+/*
+ * (C) Copyright 2007 Michal Simek
+ *
+ * Michal SIMEK <moonstr@monstr.eu>
+ *
+ * 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>
+
+#if (CONFIG_COMMANDS & CFG_CMD_CACHE)
+
+int dcache_status (void)
+{
+ int i = 0;
+ int mask = 0x80;
+ __asm__ __volatile__ ("mfs %0,rmsr"::"r" (i):"memory");
+ /* i&=0x80 */
+ __asm__ __volatile__ ("and %0,%0,%1"::"r" (i), "r" (mask):"memory");
+ return i;
+}
+
+int icache_status (void)
+{
+ int i = 0;
+ int mask = 0x20;
+ __asm__ __volatile__ ("mfs %0,rmsr"::"r" (i):"memory");
+ /* i&=0x20 */
+ __asm__ __volatile__ ("and %0,%0,%1"::"r" (i), "r" (mask):"memory");
+ return i;
+}
+#endif
diff --git a/cpu/microblaze/dcache.S b/cpu/microblaze/dcache.S
new file mode 100644
index 0000000..eaf9671
--- /dev/null
+++ b/cpu/microblaze/dcache.S
@@ -0,0 +1,68 @@
+/*
+ * (C) Copyright 2007 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * 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
+ */
+ .text
+ .globl dcache_enable
+ .ent dcache_enable
+ .align 2
+dcache_enable:
+ /* Make space on stack for a temporary */
+ addi r1, r1, -4
+ /* Save register r12 */
+ swi r12, r1, 0
+ /* Read the MSR register */
+ mfs r12, rmsr
+ /* Set the instruction enable bit */
+ ori r12, r12, 0x80
+ /* Save the MSR register */
+ mts rmsr, r12
+ /* Load register r12 */
+ lwi r12, r1, 0
+ /* Return */
+ rtsd r15, 8
+ /* Update stack in the delay slot */
+ addi r1, r1, 4
+ .end dcache_enable
+
+ .text
+ .globl dcache_disable
+ .ent dcache_disable
+ .align 2
+dcache_disable:
+ /* Make space on stack for a temporary */
+ addi r1, r1, -4
+ /* Save register r12 */
+ swi r12, r1, 0
+ /* Read the MSR register */
+ mfs r12, rmsr
+ /* Clear the data cache enable bit */
+ andi r12, r12, ~0x80
+ /* Save the MSR register */
+ mts rmsr, r12
+ /* Load register r12 */
+ lwi r12, r1, 0
+ /* Return */
+ rtsd r15, 8
+ /* Update stack in the delay slot */
+ addi r1, r1, 4
+ .end dcache_disable
diff --git a/cpu/microblaze/disable_int.S b/cpu/microblaze/disable_int.S
new file mode 100644
index 0000000..aecd795
--- /dev/null
+++ b/cpu/microblaze/disable_int.S
@@ -0,0 +1,46 @@
+/*
+ * (C) Copyright 2007 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * 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
+ */
+
+ .text
+ .globl microblaze_disable_interrupts
+ .ent microblaze_disable_interrupts
+ .align 2
+microblaze_disable_interrupts:
+ #Make space on stack for a temporary
+ addi r1, r1, -4
+ #Save register r12
+ swi r12, r1, 0
+ #Read the MSR register
+ mfs r12, rmsr
+ #Clear the interrupt enable bit
+ andi r12, r12, ~2
+ #Save the MSR register
+ mts rmsr, r12
+ #Load register r12
+ lwi r12, r1, 0
+ #Return
+ rtsd r15, 8
+ #Update stack in the delay slot
+ addi r1, r1, 4
+ .end microblaze_disable_interrupts
diff --git a/include/asm-microblaze/platform.h b/cpu/microblaze/enable_int.S
index 2096cce..c096c6c 100644
--- a/include/asm-microblaze/platform.h
+++ b/cpu/microblaze/enable_int.S
@@ -1,7 +1,7 @@
/*
- * (C) Copyright 2004 Atmark Techno, Inc.
+ * (C) Copyright 2007 Michal Simek
*
- * Yasushi SHOJI <yashi@atmark-techno.com>
+ * Michal SIMEK <monstrmonstr.eu>
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -13,7 +13,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
@@ -22,8 +22,17 @@
* MA 02111-1307 USA
*/
-#include <config.h>
-
-#ifdef CONFIG_SUZAKU
-#include <asm/suzaku.h>
-#endif
+ .text
+ .globl microblaze_enable_interrupts
+ .ent microblaze_enable_interrupts
+ .align 2
+microblaze_enable_interrupts:
+ addi r1, r1, -4
+ swi r12, r1, 0
+ mfs r12, rmsr
+ ori r12, r12, 2
+ mts rmsr, r12
+ lwi r12, r1, 0
+ rtsd r15, 8
+ addi r1, r1, 4
+ .end microblaze_enable_interrupts
diff --git a/cpu/microblaze/exception.c b/cpu/microblaze/exception.c
new file mode 100644
index 0000000..b135acb
--- /dev/null
+++ b/cpu/microblaze/exception.c
@@ -0,0 +1,68 @@
+/*
+ * (C) Copyright 2007 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * 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>
+
+void _hw_exception_handler (void)
+{
+ int address = 0;
+ int state = 0;
+ /* loading address of exception EAR */
+ __asm__ __volatile ("mfs %0,rear"::"r" (address):"memory");
+ /* loading excetpion state register ESR */
+ __asm__ __volatile ("mfs %0,resr"::"r" (state):"memory");
+ printf ("Hardware exception at 0x%x address\n", address);
+ switch (state & 0x1f) { /* mask on exception cause */
+ case 0x1:
+ puts ("Unaligned data access exception\n");
+ break;
+ case 0x2:
+ puts ("Illegal op-code exception\n");
+ break;
+ case 0x3:
+ puts ("Instruction bus error exception\n");
+ break;
+ case 0x4:
+ puts ("Data bus error exception\n");
+ break;
+ case 0x5:
+ puts ("Divide by zero exception\n");
+ break;
+ default:
+ puts ("Undefined cause\n");
+ break;
+ }
+ printf ("Unaligned %sword access\n", ((state & 0x800) ? "" : "half"));
+ printf ("Unaligned %s access\n", ((state & 0x400) ? "store" : "load"));
+ printf ("Register R%x\n", (state & 0x3E) >> 5);
+ hang ();
+}
+
+#ifdef CFG_USR_EXCEP
+void _exception_handler (void)
+{
+ puts ("User vector_exception\n");
+ hang ();
+}
+#endif
diff --git a/cpu/microblaze/icache.S b/cpu/microblaze/icache.S
new file mode 100644
index 0000000..25940d1
--- /dev/null
+++ b/cpu/microblaze/icache.S
@@ -0,0 +1,69 @@
+/*
+ * (C) Copyright 2007 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * 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
+ */
+
+ .text
+ .globl icache_enable
+ .ent icache_enable
+ .align 2
+icache_enable:
+ /* Make space on stack for a temporary */
+ addi r1, r1, -4
+ /* Save register r12 */
+ swi r12, r1, 0
+ /* Read the MSR register */
+ mfs r12, rmsr
+ /* Set the instruction enable bit */
+ ori r12, r12, 0x20
+ /* Save the MSR register */
+ mts rmsr, r12
+ /* Load register r12 */
+ lwi r12, r1, 0
+ /* Return */
+ rtsd r15, 8
+ /* Update stack in the delay slot */
+ addi r1, r1, 4
+ .end icache_enable
+
+ .text
+ .globl icache_disable
+ .ent icache_disable
+ .align 2
+icache_disable:
+ /* Make space on stack for a temporary */
+ addi r1, r1, -4
+ /* Save register r12 */
+ swi r12, r1, 0
+ /* Read the MSR register */
+ mfs r12, rmsr
+ /* Clear the instruction enable bit */
+ andi r12, r12, ~0x20
+ /* Save the MSR register */
+ mts rmsr, r12
+ /* Load register r12 */
+ lwi r12, r1, 0
+ /* Return */
+ rtsd r15, 8
+ /* Update stack in the delay slot */
+ addi r1, r1, 4
+ .end icache_disable
diff --git a/cpu/microblaze/interrupts.c b/cpu/microblaze/interrupts.c
index ccf67e1..2db847c 100644
--- a/cpu/microblaze/interrupts.c
+++ b/cpu/microblaze/interrupts.c
@@ -1,6 +1,8 @@
/*
+ * (C) Copyright 2007 Michal Simek
* (C) Copyright 2004 Atmark Techno, Inc.
*
+ * Michal SIMEK <monstr@monstr.eu>
* Yasushi SHOJI <yashi@atmark-techno.com>
*
* See file CREDITS for list of people who contributed to this
@@ -13,7 +15,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
@@ -22,11 +24,185 @@
* MA 02111-1307 USA
*/
-void enable_interrupts(void)
+#include <common.h>
+#include <command.h>
+#include <asm/microblaze_intc.h>
+
+#undef DEBUG_INT
+
+extern void microblaze_disable_interrupts (void);
+extern void microblaze_enable_interrupts (void);
+
+void enable_interrupts (void)
{
+ microblaze_enable_interrupts ();
}
-int disable_interrupts(void)
+int disable_interrupts (void)
{
+ microblaze_disable_interrupts ();
return 0;
}
+
+#ifdef CFG_INTC_0
+#ifdef CFG_TIMER_0
+extern void timer_init (void);
+#endif
+
+static struct irq_action vecs[CFG_INTC_0_NUM];
+
+/* mapping structure to interrupt controller */
+microblaze_intc_t *intc = (microblaze_intc_t *) (CFG_INTC_0_ADDR);
+
+/* default handler */
+void def_hdlr (void)
+{
+ puts ("def_hdlr\n");
+}
+
+void enable_one_interrupt (int irq)
+{
+ int mask;
+ int offset = 1;
+ offset <<= irq;
+ mask = intc->ier;
+ intc->ier = (mask | offset);
+#ifdef DEBUG_INT
+ printf ("Enable one interrupt irq %x - mask %x,ier %x\n", offset, mask,
+ intc->ier);
+ printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier,
+ intc->iar, intc->mer);
+#endif
+}
+
+void disable_one_interrupt (int irq)
+{
+ int mask;
+ int offset = 1;
+ offset <<= irq;
+ mask = intc->ier;
+ intc->ier = (mask & ~offset);
+#ifdef DEBUG_INT
+ printf ("Disable one interrupt irq %x - mask %x,ier %x\n", irq, mask,
+ intc->ier);
+ printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier,
+ intc->iar, intc->mer);
+#endif
+}
+
+/* adding new handler for interrupt */
+void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, void *arg)
+{
+ struct irq_action *act;
+ /* irq out of range */
+ if ((irq < 0) || (irq > CFG_INTC_0_NUM)) {
+ puts ("IRQ out of range\n");
+ return;
+ }
+ act = &vecs[irq];
+ if (hdlr) { /* enable */
+ act->handler = hdlr;
+ act->arg = arg;
+ act->count = 0;
+ enable_one_interrupt (irq);
+ } else { /* disable */
+
+ act->handler = (interrupt_handler_t *) def_hdlr;
+ act->arg = (void *)irq;
+ disable_one_interrupt (irq);
+ }
+}
+
+/* initialization interrupt controller - hardware */
+void intc_init (void)
+{
+ intc->mer = 0;
+ intc->ier = 0;
+ intc->iar = 0xFFFFFFFF;
+ /* XIntc_Start - hw_interrupt enable and all interrupt enable */
+ intc->mer = 0x3;
+#ifdef DEBUG_INT
+ printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier,
+ intc->iar, intc->mer);
+#endif
+}
+
+int interrupts_init (void)
+{
+ int i;
+ /* initialize irq list */
+ for (i = 0; i < CFG_INTC_0_NUM; i++) {
+ vecs[i].handler = (interrupt_handler_t *) def_hdlr;
+ vecs[i].arg = (void *)i;
+ vecs[i].count = 0;
+ }
+ /* initialize intc controller */
+ intc_init ();
+#ifdef CFG_TIMER_0
+ timer_init ();
+#endif
+ enable_interrupts ();
+ return 0;
+}
+
+void interrupt_handler (void)
+{
+ int irqs;
+ irqs = (intc->isr & intc->ier); /* find active interrupt */
+
+#ifdef DEBUG_INT
+ printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier,
+ intc->iar, intc->mer);
+ printf ("Interrupt handler on %x line, r14 %x\n", irqs, value);
+#endif
+ struct irq_action *act = vecs;
+ while (irqs) {
+ if (irqs & 1) {
+#ifdef DEBUG_INT
+ printf
+ ("Jumping to interrupt handler rutine addr %x,count %x,arg %x\n",
+ act->handler, act->count, act->arg);
+#endif
+ act->handler (act->arg);
+ act->count++;
+ }
+ irqs >>= 1;
+ act++;
+ }
+ intc->iar = 0xFFFFFFFF; /* erase all events */
+#ifdef DEBUG
+ printf ("Dump INTC reg, isr %x, ier %x, iar %x, mer %x\n", intc->isr,
+ intc->ier, intc->iar, intc->mer);
+ printf ("Interrupt handler on %x line, r14\n", irqs);
+#endif
+}
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_IRQ)
+#ifdef CFG_INTC_0
+int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ int i;
+ struct irq_action *act = vecs;
+
+ puts ("\nInterrupt-Information:\n\n"
+ "Nr Routine Arg Count\n"
+ "-----------------------------\n");
+
+ for (i = 0; i < CFG_INTC_0_NUM; i++) {
+ if (act->handler != (interrupt_handler_t*) def_hdlr) {
+ printf ("%02d %08lx %08lx %d\n", i,
+ (int)act->handler, (int)act->arg, act->count);
+ }
+ act++;
+ }
+ puts ("\n");
+ return (0);
+}
+#else
+int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ puts ("Undefined interrupt controller\n");
+}
+#endif
+#endif /* CONFIG_COMMANDS & CFG_CMD_IRQ */
diff --git a/cpu/microblaze/irq.S b/cpu/microblaze/irq.S
new file mode 100644
index 0000000..a4e3fbf
--- /dev/null
+++ b/cpu/microblaze/irq.S
@@ -0,0 +1,165 @@
+/*
+ * (C) Copyright 2007 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * 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 <config.h>
+ .text
+ .global _interrupt_handler
+_interrupt_handler:
+ addi r1, r1, -4
+ swi r2, r1, 0
+ addi r1, r1, -4
+ swi r3, r1, 0
+ addi r1, r1, -4
+ swi r4, r1, 0
+ addi r1, r1, -4
+ swi r5, r1, 0
+ addi r1, r1, -4
+ swi r6, r1, 0
+ addi r1, r1, -4
+ swi r7, r1, 0
+ addi r1, r1, -4
+ swi r8, r1, 0
+ addi r1, r1, -4
+ swi r9, r1, 0
+ addi r1, r1, -4
+ swi r10, r1, 0
+ addi r1, r1, -4
+ swi r11, r1, 0
+ addi r1, r1, -4
+ swi r12, r1, 0
+ addi r1, r1, -4
+ swi r13, r1, 0
+ addi r1, r1, -4
+ swi r14, r1, 0
+ addi r1, r1, -4
+ swi r15, r1, 0
+ addi r1, r1, -4
+ swi r16, r1, 0
+ addi r1, r1, -4
+ swi r17, r1, 0
+ addi r1, r1, -4
+ swi r18, r1, 0
+ addi r1, r1, -4
+ swi r19, r1, 0
+ addi r1, r1, -4
+ swi r20, r1, 0
+ addi r1, r1, -4
+ swi r21, r1, 0
+ addi r1, r1, -4
+ swi r22, r1, 0
+ addi r1, r1, -4
+ swi r23, r1, 0
+ addi r1, r1, -4
+ swi r24, r1, 0
+ addi r1, r1, -4
+ swi r25, r1, 0
+ addi r1, r1, -4
+ swi r26, r1, 0
+ addi r1, r1, -4
+ swi r27, r1, 0
+ addi r1, r1, -4
+ swi r28, r1, 0
+ addi r1, r1, -4
+ swi r29, r1, 0
+ addi r1, r1, -4
+ swi r30, r1, 0
+ addi r1, r1, -4
+ swi r31, r1, 0
+ brlid r15, interrupt_handler
+ nop
+ nop
+ lwi r31, r1, 0
+ addi r1, r1, 4
+ lwi r30, r1, 0
+ addi r1, r1, 4
+ lwi r29, r1, 0
+ addi r1, r1, 4
+ lwi r28, r1, 0
+ addi r1, r1, 4
+ lwi r27, r1, 0
+ addi r1, r1, 4
+ lwi r26, r1, 0
+ addi r1, r1, 4
+ lwi r25, r1, 0
+ addi r1, r1, 4
+ lwi r24, r1, 0
+ addi r1, r1, 4
+ lwi r23, r1, 0
+ addi r1, r1, 4
+ lwi r22, r1, 0
+ addi r1, r1, 4
+ lwi r21, r1, 0
+ addi r1, r1, 4
+ lwi r20, r1, 0
+ addi r1, r1, 4
+ lwi r19, r1, 0
+ addi r1, r1, 4
+ lwi r18, r1, 0
+ addi r1, r1, 4
+ lwi r17, r1, 0
+ addi r1, r1, 4
+ lwi r16, r1, 0
+ addi r1, r1, 4
+ lwi r15, r1, 0
+ addi r1, r1, 4
+ lwi r14, r1, 0
+ addi r1, r1, 4
+ lwi r13, r1, 0
+ addi r1, r1, 4
+ lwi r12, r1, 0
+ addi r1, r1, 4
+ lwi r11, r1, 0
+ addi r1, r1, 4
+ lwi r10, r1, 0
+ addi r1, r1, 4
+ lwi r9, r1, 0
+ addi r1, r1, 4
+ lwi r8, r1, 0
+ addi r1, r1, 4
+ lwi r7, r1, 0
+ addi r1, r1, 4
+ lwi r6, r1, 0
+ addi r1, r1, 4
+ lwi r5, r1, 0
+ addi r1, r1, 4
+ lwi r4, r1, 0
+ addi r1, r1, 4
+ lwi r3, r1, 0
+ addi r1, r1, 4
+ lwi r2, r1, 0
+ addi r1, r1, 4
+
+ /* enable_interrupt */
+ addi r1, r1, -4
+ swi r12, r1, 0
+ mfs r12, rmsr
+ ori r12, r12, 2
+ mts rmsr, r12
+ lwi r12, r1, 0
+ addi r1, r1, 4
+ nop
+ bra r14
+ nop
+ nop
+ .size _interrupt_handler,.-_interrupt_handler
diff --git a/cpu/microblaze/start.S b/cpu/microblaze/start.S
index 7efdbb0..ca3befc 100644
--- a/cpu/microblaze/start.S
+++ b/cpu/microblaze/start.S
@@ -1,6 +1,8 @@
/*
+ * (C) Copyright 2007 Michal Simek
* (C) Copyright 2004 Atmark Techno, Inc.
*
+ * Michal SIMEK <monstr@monstr.eu>
* Yasushi SHOJI <yashi@atmark-techno.com>
*
* See file CREDITS for list of people who contributed to this
@@ -13,7 +15,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
@@ -27,10 +29,91 @@
.text
.global _start
_start:
+ mts rmsr, r0 /* disable cache */
+ addi r1, r0, CFG_INIT_SP_OFFSET
+ addi r1, r1, -4 /* Decrement SP to top of memory */
+ /* add opcode instruction for 32bit jump - 2 instruction imm & brai*/
+ addi r6, r0, 0xb000 /* hex b000 opcode imm */
+ bslli r6, r6, 16 /* shift */
+ swi r6, r0, 0x0 /* reset address */
+ swi r6, r0, 0x8 /* user vector exception */
+ swi r6, r0, 0x10 /* interrupt */
+ swi r6, r0, 0x20 /* hardware exception */
- addi r1, r0, CFG_SDRAM_BASE /* init stack pointer */
- addi r1, r1, CFG_SDRAM_SIZE /* set sp to high up */
+ addi r6, r0, 0xb808 /* hew b808 opcode brai*/
+ bslli r6, r6, 16
+ swi r6, r0, 0x4 /* reset address */
+ swi r6, r0, 0xC /* user vector exception */
+ swi r6, r0, 0x14 /* interrupt */
+ swi r6, r0, 0x24 /* hardware exception */
- brai board_init
+#ifdef CFG_RESET_ADDRESS
+ /* reset address */
+ addik r6, r0, CFG_RESET_ADDRESS
+ sw r6, r1, r0
+ lhu r7, r1, r0
+ shi r7, r0, 0x2
+ shi r6, r0, 0x6
+/*
+ * Copy U-Boot code to TEXT_BASE
+ * solve problem with sbrk_base
+ */
+#if (CFG_RESET_ADDRESS != TEXT_BASE)
+ addi r4, r0, __end
+ addi r5, r0, __text_start
+ rsub r4, r5, r4 /* size = __end - __text_start */
+ addi r6, r0, CFG_RESET_ADDRESS /* source address */
+ addi r7, r0, 0 /* counter */
+4:
+ lw r8, r6, r7
+ sw r8, r5, r7
+ addi r7, r7, 0x4
+ cmp r8, r4, r7
+ blti r8, 4b
+#endif
+#endif
+
+#ifdef CFG_USR_EXCEP
+ /* user_vector_exception */
+ addik r6, r0, _exception_handler
+ sw r6, r1, r0
+ lhu r7, r1, r0
+ shi r7, r0, 0xa
+ shi r6, r0, 0xe
+#endif
+#ifdef CFG_INTC_0
+ /* interrupt_handler */
+ addik r6, r0, _interrupt_handler
+ sw r6, r1, r0
+ lhu r7, r1, r0
+ shi r7, r0, 0x12
+ shi r6, r0, 0x16
+#endif
+
+ /* hardware exception */
+ addik r6, r0, _hw_exception_handler
+ sw r6, r1, r0
+ lhu r7, r1, r0
+ shi r7, r0, 0x22
+ shi r6, r0, 0x26
+
+ /* enable instruction and data cache */
+ mfs r12, rmsr
+ ori r12, r12, 0xa0
+ mts rmsr, r12
+
+clear_bss:
+ /* clear BSS segments */
+ addi r5, r0, __bss_start
+ addi r4, r0, __bss_end
+ cmp r6, r5, r4
+ beqi r6, 3f
+2:
+ swi r0, r5, 0 /* write zero to loc */
+ addi r5, r5, 4 /* increment to next loc */
+ cmp r6, r5, r4 /* check if we have reach the end */
+ bnei r6, 2b
+3: /* jumping to board_init */
+ brai board_init
1: bri 1b
diff --git a/cpu/microblaze/timer.c b/cpu/microblaze/timer.c
new file mode 100644
index 0000000..be4fd57
--- /dev/null
+++ b/cpu/microblaze/timer.c
@@ -0,0 +1,68 @@
+/*
+ * (C) Copyright 2007 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * 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 <asm/microblaze_timer.h>
+
+volatile int timestamp = 0;
+
+void reset_timer (void)
+{
+ timestamp = 0;
+}
+
+ulong get_timer (ulong base)
+{
+ return (timestamp - base);
+}
+
+void set_timer (ulong t)
+{
+ timestamp = t;
+}
+
+#ifdef CFG_INTC_0
+#ifdef CFG_TIMER_0
+extern void install_interrupt_handler (int irq, interrupt_handler_t * hdlr,
+ void *arg);
+
+microblaze_timer_t *tmr = (microblaze_timer_t *) (CFG_TIMER_0_ADDR);
+
+void timer_isr (void *arg)
+{
+ timestamp++;
+ tmr->control = tmr->control | TIMER_INTERRUPT;
+}
+
+void timer_init (void)
+{
+ tmr->loadreg = CFG_TIMER_0_PRELOAD;
+ tmr->control = TIMER_INTERRUPT | TIMER_RESET;
+ tmr->control =
+ TIMER_ENABLE | TIMER_ENABLE_INTR | TIMER_RELOAD | TIMER_DOWN_COUNT;
+ reset_timer ();
+ install_interrupt_handler (CFG_TIMER_0_IRQ, timer_isr, (void *)tmr);
+}
+#endif
+#endif
diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c
index e4bc405..21b1646 100644
--- a/cpu/mpc83xx/cpu.c
+++ b/cpu/mpc83xx/cpu.c
@@ -30,8 +30,14 @@
#include <watchdog.h>
#include <command.h>
#include <mpc83xx.h>
-#include <ft_build.h>
#include <asm/processor.h>
+#if defined(CONFIG_OF_FLAT_TREE)
+#include <ft_build.h>
+#endif
+#if defined(CONFIG_OF_LIBFDT)
+#include <libfdt.h>
+#include <libfdt_env.h>
+#endif
DECLARE_GLOBAL_DATA_PTR;
@@ -291,6 +297,100 @@ void watchdog_reset (void)
}
#endif
+#if defined(CONFIG_OF_LIBFDT)
+
+/*
+ * Fixups to the fdt. If "create" is TRUE, the node is created
+ * unconditionally. If "create" is FALSE, the node is updated
+ * only if it already exists.
+ */
+#define FT_UPDATE 0x00000000 /* update existing property only */
+#define FT_CREATE 0x00000001 /* create property if it doesn't exist */
+#define FT_BUSFREQ 0x00000002 /* source is bd->bi_busfreq */
+#define FT_ENETADDR 0x00000004 /* source is bd->bi_enetaddr */
+static const struct {
+ int createflags;
+ char *node;
+ char *prop;
+} fixup_props[] = {
+ { FT_CREATE | FT_BUSFREQ,
+ "/cpus/" OF_CPU,
+ "bus-frequency",
+ },
+ { FT_CREATE | FT_BUSFREQ,
+ "/cpus/" OF_SOC,
+ "bus-frequency"
+ },
+ { FT_CREATE | FT_BUSFREQ,
+ "/" OF_SOC "/serial@4500/",
+ "clock-frequency"
+ },
+ { FT_CREATE | FT_BUSFREQ,
+ "/" OF_SOC "/serial@4600/",
+ "clock-frequency"
+ },
+#ifdef CONFIG_MPC83XX_TSEC1
+ { FT_UPDATE | FT_ENETADDR,
+ "/" OF_SOC "/ethernet@24000,
+ "mac-address",
+ },
+ { FT_UPDATE | FT_ENETADDR,
+ "/" OF_SOC "/ethernet@24000,
+ "local-mac-address",
+ },
+#endif
+#ifdef CONFIG_MPC83XX_TSEC2
+ { FT_UPDATE | FT_ENETADDR,
+ "/" OF_SOC "/ethernet@25000,
+ "mac-address",
+ },
+ { FT_UPDATE | FT_ENETADDR,
+ "/" OF_SOC "/ethernet@25000,
+ "local-mac-address",
+ },
+#endif
+};
+
+void
+ft_cpu_setup(void *blob, bd_t *bd)
+{
+ int nodeoffset;
+ int err;
+ int j;
+
+ for (j = 0; j < (sizeof(fixup_props) / sizeof(fixup_props[0])); j++) {
+ nodeoffset = fdt_path_offset (fdt, fixup_props[j].node);
+ if (nodeoffset >= 0) {
+ /*
+ * If unconditional create or the property already exists...
+ */
+ if ((fixup_props[j].createflags & FT_CREATE) ||
+ (fdt_get_property(fdt, nodeoffset, fixup_props[j].prop, 0))) {
+ if (fixup_props[j].createflags & FT_BUSFREQ) {
+ u32 tmp;
+
+ tmp = cpu_to_be32(bd->bi_busfreq);
+ err = fdt_setprop(fdt, nodeoffset,
+ fixup_props[j].prop, &tmp, sizeof(tmp));
+ } else if (fixup_props[j].createflags & FT_ENETADDR) {
+ err = fdt_setprop(fdt, nodeoffset,
+ fixup_props[j].prop, bd->bi_enetaddr, 6);
+ } else {
+ printf("ft_cpu_setup: %s %s has no flag for the value to set\n",
+ fixup_props[j].node,
+ fixup_props[j].prop);
+ }
+ if (err < 0)
+ printf("libfdt: %s %s returned %s\n",
+ fixup_props[j].node,
+ fixup_props[j].prop,
+ fdt_strerror(err));
+ }
+ }
+ }
+}
+#endif
+
#if defined(CONFIG_OF_FLAT_TREE)
void
ft_cpu_setup(void *blob, bd_t *bd)
diff --git a/include/asm-microblaze/microblaze_intc.h b/include/asm-microblaze/microblaze_intc.h
new file mode 100644
index 0000000..6635aea
--- /dev/null
+++ b/include/asm-microblaze/microblaze_intc.h
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2007 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.cz>
+ *
+ * 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
+ */
+
+typedef volatile struct microblaze_intc_t {
+ int isr; /* interrupt status register */
+ int ipr; /* interrupt pending register */
+ int ier; /* interrupt enable register */
+ int iar; /* interrupt acknowledge register */
+ int sie; /* set interrupt enable bits */
+ int cie; /* clear interrupt enable bits */
+ int ivr; /* interrupt vector register */
+ int mer; /* master enable register */
+} microblaze_intc_t;
+
+struct irq_action {
+ interrupt_handler_t *handler; /* pointer to interrupt rutine */
+ void *arg;
+ int count; /* number of interrupt */
+};
diff --git a/include/asm-microblaze/microblaze_timer.h b/include/asm-microblaze/microblaze_timer.h
new file mode 100644
index 0000000..844c8db
--- /dev/null
+++ b/include/asm-microblaze/microblaze_timer.h
@@ -0,0 +1,41 @@
+/*
+ * (C) Copyright 2007 Michal Simek
+ *
+ * Michal SIMEK <monstr@monstr.cz>
+ *
+ * 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 TIMER_ENABLE_ALL 0x400 /* ENALL */
+#define TIMER_PWM 0x200 /* PWMA0 */
+#define TIMER_INTERRUPT 0x100 /* T0INT */
+#define TIMER_ENABLE 0x080 /* ENT0 */
+#define TIMER_ENABLE_INTR 0x040 /* ENIT0 */
+#define TIMER_RESET 0x020 /* LOAD0 */
+#define TIMER_RELOAD 0x010 /* ARHT0 */
+#define TIMER_EXT_CAPTURE 0x008 /* CAPT0 */
+#define TIMER_EXT_COMPARE 0x004 /* GENT0 */
+#define TIMER_DOWN_COUNT 0x002 /* UDT0 */
+#define TIMER_CAPTURE_MODE 0x001 /* MDT0 */
+
+typedef volatile struct microblaze_timer_t {
+ int control; /* control/statuc register TCSR */
+ int loadreg; /* load register TLR */
+ int counter; /* timer/counter register */
+} microblaze_timer_t;
diff --git a/include/configs/MPC8360EMDS.h b/include/configs/MPC8360EMDS.h
index d2af0e1..79937dc 100644
--- a/include/configs/MPC8360EMDS.h
+++ b/include/configs/MPC8360EMDS.h
@@ -342,8 +342,12 @@
#endif
/* pass open firmware flat tree */
-#define CONFIG_OF_FLAT_TREE 1
+#define CONFIG_OF_LIBFDT 1
+#undef CONFIG_OF_FLAT_TREE
#define CONFIG_OF_BOARD_SETUP 1
+#define CONFIG_OF_HAS_BD_T 1
+#define CONFIG_OF_HAS_UBOOT_ENV 1
+
/* maximum size of the flat tree (8K) */
#define OF_FLAT_TREE_MAX_SIZE 8192
diff --git a/include/configs/ml401.h b/include/configs/ml401.h
new file mode 100644
index 0000000..cb159e7
--- /dev/null
+++ b/include/configs/ml401.h
@@ -0,0 +1,230 @@
+/*
+ * (C) Copyright 2007 Czech Technical University.
+ *
+ * Michal SIMEK <monstr@seznam.cz>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include "../board/xilinx/ml401/xparameters.h"
+
+#define CONFIG_MICROBLAZE 1 /* MicroBlaze CPU */
+#define CONFIG_ML401 1 /* ML401 Board */
+
+/* uart */
+#define CONFIG_SERIAL_BASE XILINX_UART_BASEADDR
+#define CONFIG_BAUDRATE XILINX_UART_BAUDRATE
+#define CFG_BAUDRATE_TABLE { CONFIG_BAUDRATE }
+
+/* setting reset address */
+#define CFG_RESET_ADDRESS TEXT_BASE
+
+/* ethernet */
+#define CONFIG_EMACLITE 1
+#define XPAR_EMAC_0_DEVICE_ID XPAR_XEMAC_NUM_INSTANCES
+
+/* gpio */
+#define CFG_GPIO_0 1
+#define CFG_GPIO_0_ADDR XILINX_GPIO_BASEADDR
+
+/* interrupt controller */
+#define CFG_INTC_0 1
+#define CFG_INTC_0_ADDR XILINX_INTC_BASEADDR
+#define CFG_INTC_0_NUM XILINX_INTC_NUM_INTR_INPUTS
+
+/* timer */
+#define CFG_TIMER_0 1
+#define CFG_TIMER_0_ADDR XILINX_TIMER_BASEADDR
+#define CFG_TIMER_0_IRQ XILINX_TIMER_IRQ
+#define FREQUENCE XILINX_CLOCK_FREQ
+#define CFG_TIMER_0_PRELOAD ( FREQUENCE/1000 )
+
+/*
+ * memory layout - Example
+ * TEXT_BASE = 0x1200_0000;
+ * CFG_SRAM_BASE = 0x1000_0000;
+ * CFG_SRAM_SIZE = 0x0400_0000;
+ *
+ * CFG_GBL_DATA_OFFSET = 0x1000_0000 + 0x0400_0000 - 0x1000 = 0x13FF_F000
+ * CFG_MONITOR_BASE = 0x13FF_F000 - 0x40000 = 0x13FB_F000
+ * CFG_MALLOC_BASE = 0x13FB_F000 - 0x40000 = 0x13F7_F000
+ *
+ * 0x1000_0000 CFG_SDRAM_BASE
+ * FREE
+ * 0x1200_0000 TEXT_BASE
+ * U-BOOT code
+ * 0x1202_0000
+ * FREE
+ *
+ * STACK
+ * 0x13F7_F000 CFG_MALLOC_BASE
+ * MALLOC_AREA 256kB Alloc
+ * 0x11FB_F000 CFG_MONITOR_BASE
+ * MONITOR_CODE 256kB Env
+ * 0x13FF_F000 CFG_GBL_DATA_OFFSET
+ * GLOBAL_DATA 4kB bd, gd
+ * 0x1400_0000 CFG_SDRAM_BASE + CFG_SDRAM_SIZE
+ */
+
+/* ddr sdram - main memory */
+#define CFG_SDRAM_BASE XILINX_RAM_START
+#define CFG_SDRAM_SIZE XILINX_RAM_SIZE
+#define CFG_MEMTEST_START CFG_SDRAM_BASE
+#define CFG_MEMTEST_END (CFG_SDRAM_BASE + 0x1000)
+
+/* global pointer */
+#define CFG_GBL_DATA_SIZE 0x1000 /* size of global data */
+#define CFG_GBL_DATA_OFFSET (CFG_SDRAM_BASE + CFG_SDRAM_SIZE - CFG_GBL_DATA_SIZE) /* start of global data */
+
+/* monitor code */
+#define SIZE 0x40000
+#define CFG_MONITOR_LEN SIZE
+#define CFG_MONITOR_BASE (CFG_GBL_DATA_OFFSET - CFG_MONITOR_LEN)
+#define CFG_MONITOR_END (CFG_MONITOR_BASE + CFG_MONITOR_LEN)
+#define CFG_MALLOC_LEN SIZE
+#define CFG_MALLOC_BASE (CFG_MONITOR_BASE - CFG_MALLOC_LEN)
+
+/* stack */
+#define CFG_INIT_SP_OFFSET CFG_MONITOR_BASE
+
+/*#define RAMENV */
+#define FLASH
+
+#ifdef FLASH
+ #define CFG_FLASH_BASE XILINX_FLASH_START
+ #define CFG_FLASH_SIZE XILINX_FLASH_SIZE
+ #define CFG_FLASH_CFI 1
+ #define CFG_FLASH_CFI_DRIVER 1
+ #define CFG_FLASH_EMPTY_INFO 1 /* ?empty sector */
+ #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
+ #define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */
+
+ #ifdef RAMENV
+ #define CFG_ENV_IS_NOWHERE 1
+ #define CFG_ENV_SIZE 0x1000
+ #define CFG_ENV_ADDR (CFG_MONITOR_BASE - CFG_ENV_SIZE)
+
+ #else /* !RAMENV */
+ #define CFG_ENV_IS_IN_FLASH 1
+ #define CFG_ENV_ADDR 0x40000
+ #define CFG_ENV_SECT_SIZE 0x40000 /* 256K(one sector) for env */
+ #define CFG_ENV_SIZE 0x2000
+ #endif /* !RAMBOOT */
+#else /* !FLASH */
+ /* ENV in RAM */
+ #define CFG_NO_FLASH 1
+ #define CFG_ENV_IS_NOWHERE 1
+ #define CFG_ENV_SIZE 0x1000
+ #define CFG_ENV_ADDR (CFG_MONITOR_BASE - CFG_ENV_SIZE)
+#endif /* !FLASH */
+
+#ifdef FLASH
+ #ifdef RAMENV
+ #define CONFIG_COMMANDS (CONFIG__CMD_DFL |\
+ CFG_CMD_MEMORY |\
+ CFG_CMD_MISC |\
+ CFG_CMD_AUTOSCRIPT |\
+ CFG_CMD_IRQ |\
+ CFG_CMD_ASKENV |\
+ CFG_CMD_BDI |\
+ CFG_CMD_RUN |\
+ CFG_CMD_LOADS |\
+ CFG_CMD_LOADB |\
+ CFG_CMD_IMI |\
+ CFG_CMD_NET |\
+ CFG_CMD_CACHE |\
+ CFG_CMD_IMLS |\
+ CFG_CMD_FLASH |\
+ CFG_CMD_PING \
+ )
+ #else /* !RAMENV */
+ #define CONFIG_COMMANDS (CONFIG__CMD_DFL |\
+ CFG_CMD_MEMORY |\
+ CFG_CMD_MISC |\
+ CFG_CMD_AUTOSCRIPT |\
+ CFG_CMD_IRQ |\
+ CFG_CMD_ASKENV |\
+ CFG_CMD_BDI |\
+ CFG_CMD_RUN |\
+ CFG_CMD_LOADS |\
+ CFG_CMD_LOADB |\
+ CFG_CMD_IMI |\
+ CFG_CMD_NET |\
+ CFG_CMD_CACHE |\
+ CFG_CMD_IMLS |\
+ CFG_CMD_FLASH |\
+ CFG_CMD_PING |\
+ CFG_CMD_ENV |\
+ CFG_CMD_SAVES \
+ )
+
+ #endif
+
+#else /* !FLASH */
+ #define CONFIG_COMMANDS (CONFIG__CMD_DFL |\
+ CFG_CMD_MEMORY |\
+ CFG_CMD_MISC |\
+ CFG_CMD_AUTOSCRIPT |\
+ CFG_CMD_IRQ |\
+ CFG_CMD_ASKENV |\
+ CFG_CMD_BDI |\
+ CFG_CMD_RUN |\
+ CFG_CMD_LOADS |\
+ CFG_CMD_LOADB |\
+ CFG_CMD_IMI |\
+ CFG_CMD_NET |\
+ CFG_CMD_CACHE |\
+ CFG_CMD_PING \
+ )
+#endif /* !FLASH */
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/* Miscellaneous configurable options */
+#define CFG_PROMPT "U-Boot-mONStR> "
+#define CFG_CBSIZE 512 /* size of console buffer */
+#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) /* print buffer size */
+#define CFG_MAXARGS 15 /* max number of command args */
+#define CFG_LONGHELP
+#define CFG_LOAD_ADDR 0x12000000 /* default load address */
+
+#define CONFIG_BOOTDELAY 30
+#define CONFIG_BOOTARGS "root=romfs"
+#define CONFIG_HOSTNAME "ml401"
+#define CONFIG_BOOTCOMMAND "base 0;tftp 11000000 image.img;bootm"
+#define CONFIG_IPADDR 192.168.0.3
+#define CONFIG_SERVERIP 192.168.0.5
+#define CONFIG_GATEWAYIP 192.168.0.1
+#define CONFIG_ETHADDR 00:E0:0C:00:00:FD
+
+/* architecture dependent code */
+#define CFG_USR_EXCEP /* user exception */
+#define CFG_HZ 1000
+
+/* system ace */
+/*#define CONFIG_SYSTEMACE
+#define DEBUG_SYSTEMACE
+#define CFG_SYSTEMACE_BASE XILINX_SYSACE_BASEADDR
+#define CFG_SYSTEMACE_WIDTH XILINX_SYSACE_MEM_WIDTH
+#define CONFIG_DOS_PARTITION
+*/
+#endif /* __CONFIG_H */
diff --git a/include/configs/suzaku.h b/include/configs/suzaku.h
index 1ee6be1..8224555 100644
--- a/include/configs/suzaku.h
+++ b/include/configs/suzaku.h
@@ -44,12 +44,17 @@
#define CFG_FLASH_SIZE 0x00400000
#define CFG_RESET_ADDRESS 0xfff00100
#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */
-#define CFG_MONITOR_BASE (CFG_SDRAM_BASE + CFG_SDRAM_SIZE - (1024 * 1024))
+#define CFG_MONITOR_BASE (CFG_SDRAM_BASE + CFG_SDRAM_SIZE - (1024 * 1024))
#define CFG_MALLOC_LEN (256 << 10) /* Reserve 256 kB for malloc */
+#define CFG_MALLOC_BASE (CFG_MONITOR_BASE - (1024 * 1024))
#define CONFIG_BAUDRATE 115200
#define CFG_BAUDRATE_TABLE { 115200 }
+/* System Register (GPIO) */
+#define MICROBLAZE_SYSREG_BASE_ADDR 0xFFFFA000
+#define MICROBLAZE_SYSREG_RECONFIGURE (1 << 0)
+
#define CONFIG_COMMANDS (CONFIG__CMD_DFL)
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
diff --git a/include/configs/xupv2p.h b/include/configs/xupv2p.h
new file mode 100644
index 0000000..a2f4810
--- /dev/null
+++ b/include/configs/xupv2p.h
@@ -0,0 +1,174 @@
+/*
+ * (C) Copyright 2007 Czech Technical University.
+ *
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include "../board/xilinx/xupv2p/xparameters.h"
+
+#define CONFIG_MICROBLAZE 1 /* MicroBlaze CPU */
+#define CONFIG_XUPV2P 1
+
+/* uart */
+#define CONFIG_SERIAL_BASE XILINX_UART_BASEADDR
+#define CONFIG_BAUDRATE XILINX_UART_BAUDRATE
+#define CFG_BAUDRATE_TABLE { CONFIG_BAUDRATE }
+
+/* ethernet */
+#define CONFIG_EMAC 1
+#define XPAR_EMAC_0_DEVICE_ID XPAR_XEMAC_NUM_INSTANCES
+
+/*
+ * setting reset address
+ *
+ * TEXT_BASE is set to place, where the U-BOOT run in RAM, but
+ * if you want to store U-BOOT in flash, set CFG_RESET_ADDRESS
+ * to FLASH memory and after loading bitstream jump to FLASH.
+ * U-BOOT auto-relocate to TEXT_BASE. After RESET command Microblaze
+ * jump to CFG_RESET_ADDRESS where is the original U-BOOT code.
+ */
+#define CFG_RESET_ADDRESS 0x36000000
+
+/* gpio */
+#define CFG_GPIO_0 1
+#define CFG_GPIO_0_ADDR XILINX_GPIO_BASEADDR
+
+/* interrupt controller */
+#define CFG_INTC_0 1
+#define CFG_INTC_0_ADDR XILINX_INTC_BASEADDR
+#define CFG_INTC_0_NUM XILINX_INTC_NUM_INTR_INPUTS
+
+/* timer */
+#define CFG_TIMER_0 1
+#define CFG_TIMER_0_ADDR XILINX_TIMER_BASEADDR
+#define CFG_TIMER_0_IRQ XILINX_TIMER_IRQ
+#define FREQUENCE XILINX_CLOCK_FREQ
+#define CFG_TIMER_0_PRELOAD ( FREQUENCE/1000 )
+
+/*
+ * memory layout - Example
+ * TEXT_BASE = 0x3600_0000;
+ * CFG_SRAM_BASE = 0x3000_0000;
+ * CFG_SRAM_SIZE = 0x1000_0000;
+ *
+ * CFG_GBL_DATA_OFFSET = 0x3000_0000 + 0x1000_0000 - 0x1000 = 0x3FFF_F000
+ * CFG_MONITOR_BASE = 0x3FFF_F000 - 0x40000 = 0x3FFB_F000
+ * CFG_MALLOC_BASE = 0x3FFB_F000 - 0x40000 = 0x3FF7_F000
+ *
+ * 0x3000_0000 CFG_SDRAM_BASE
+ * FREE
+ * 0x3600_0000 TEXT_BASE
+ * U-BOOT code
+ * 0x3602_0000
+ * FREE
+ *
+ * STACK
+ * 0x3FF7_F000 CFG_MALLOC_BASE
+ * MALLOC_AREA 256kB Alloc
+ * 0x3FFB_F000 CFG_MONITOR_BASE
+ * MONITOR_CODE 256kB Env
+ * 0x3FFF_F000 CFG_GBL_DATA_OFFSET
+ * GLOBAL_DATA 4kB bd, gd
+ * 0x4000_0000 CFG_SDRAM_BASE + CFG_SDRAM_SIZE
+ */
+
+/* ddr sdram - main memory */
+#define CFG_SDRAM_BASE XILINX_RAM_START
+#define CFG_SDRAM_SIZE XILINX_RAM_SIZE
+#define CFG_MEMTEST_START CFG_SDRAM_BASE
+#define CFG_MEMTEST_END (CFG_SDRAM_BASE + 0x1000)
+
+/* global pointer */
+#define CFG_GBL_DATA_SIZE 0x1000 /* size of global data */
+#define CFG_GBL_DATA_OFFSET (CFG_SDRAM_BASE + CFG_SDRAM_SIZE - CFG_GBL_DATA_SIZE) /* start of global data */
+
+/* monitor code */
+#define SIZE 0x40000
+#define CFG_MONITOR_LEN SIZE
+#define CFG_MONITOR_BASE (CFG_GBL_DATA_OFFSET - CFG_MONITOR_LEN)
+#define CFG_MONITOR_END (CFG_MONITOR_BASE + CFG_MONITOR_LEN)
+#define CFG_MALLOC_LEN SIZE
+#define CFG_MALLOC_BASE (CFG_MONITOR_BASE - CFG_MALLOC_LEN)
+
+/* stack */
+#define CFG_INIT_SP_OFFSET CFG_MALLOC_BASE
+
+#define CFG_NO_FLASH 1
+#define CFG_ENV_IS_NOWHERE 1
+#define CFG_ENV_SIZE 0x1000
+#define CFG_ENV_ADDR (CFG_MONITOR_BASE - CFG_ENV_SIZE)
+#define CONFIG_COMMANDS (CONFIG__CMD_DFL |\
+ CFG_CMD_MEMORY |\
+ CFG_CMD_IRQ |\
+ CFG_CMD_BDI |\
+ CFG_CMD_NET |\
+ CFG_CMD_IMI |\
+ CFG_CMD_ECHO |\
+ CFG_CMD_CACHE |\
+ CFG_CMD_RUN |\
+ CFG_CMD_AUTOSCRIPT |\
+ CFG_CMD_ASKENV |\
+ CFG_CMD_LOADS |\
+ CFG_CMD_LOADB |\
+ CFG_CMD_MISC |\
+ CFG_CMD_PING \
+ )
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/* Miscellaneous configurable options */
+#define CFG_PROMPT "U-Boot-mONStR> "
+#define CFG_CBSIZE 512 /* size of console buffer */
+#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) /* print buffer size */
+#define CFG_MAXARGS 15 /* max number of command args */
+#define CFG_LONGHELP
+#define CFG_LOAD_ADDR 0x12000000 /* default load address */
+
+#define CONFIG_BOOTDELAY 30
+#define CONFIG_BOOTARGS "root=romfs"
+#define CONFIG_HOSTNAME "ml401"
+#define CONFIG_BOOTCOMMAND "base 0;tftp 11000000 image.img;bootm"
+#define CONFIG_IPADDR 192.168.0.3
+#define CONFIG_SERVERIP 192.168.0.5
+#define CONFIG_GATEWAYIP 192.168.0.1
+#define CONFIG_ETHADDR 00:E0:0C:00:00:FD
+
+/* architecture dependent code */
+#define CFG_USR_EXCEP /* user exception */
+#define CFG_HZ 1000
+
+#define CONFIG_PREBOOT "echo U-BOOT by mONStR;" \
+ "base 0;" \
+ "echo"
+
+
+/* system ace */
+/*#define CONFIG_SYSTEMACE
+#define DEBUG_SYSTEMACE
+#define CFG_SYSTEMACE_BASE 0xCF000000
+#define CFG_SYSTEMACE_WIDTH 16
+#define CONFIG_DOS_PARTITION*/
+
+#endif /* __CONFIG_H */
diff --git a/include/fdt.h b/include/fdt.h
new file mode 100644
index 0000000..48ccfd9
--- /dev/null
+++ b/include/fdt.h
@@ -0,0 +1,60 @@
+#ifndef _FDT_H
+#define _FDT_H
+
+#ifndef __ASSEMBLY__
+
+struct fdt_header {
+ uint32_t magic; /* magic word FDT_MAGIC */
+ uint32_t totalsize; /* total size of DT block */
+ uint32_t off_dt_struct; /* offset to structure */
+ uint32_t off_dt_strings; /* offset to strings */
+ uint32_t off_mem_rsvmap; /* offset to memory reserve map */
+ uint32_t version; /* format version */
+ uint32_t last_comp_version; /* last compatible version */
+
+ /* version 2 fields below */
+ uint32_t boot_cpuid_phys; /* Which physical CPU id we're
+ booting on */
+ /* version 3 fields below */
+ uint32_t size_dt_strings; /* size of the strings block */
+
+ /* version 17 fields below */
+ uint32_t size_dt_struct; /* size of the structure block */
+};
+
+struct fdt_reserve_entry {
+ uint64_t address;
+ uint64_t size;
+};
+
+struct fdt_node_header {
+ uint32_t tag;
+ char name[0];
+};
+
+struct fdt_property {
+ uint32_t tag;
+ uint32_t len;
+ uint32_t nameoff;
+ char data[0];
+};
+
+#endif /* !__ASSEMBLY */
+
+#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */
+#define FDT_TAGSIZE sizeof(uint32_t)
+
+#define FDT_BEGIN_NODE 0x1 /* Start node: full name */
+#define FDT_END_NODE 0x2 /* End node */
+#define FDT_PROP 0x3 /* Property: name off,
+ size, content */
+#define FDT_NOP 0x4 /* nop */
+#define FDT_END 0x9
+
+#define FDT_V1_SIZE (7*sizeof(uint32_t))
+#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(uint32_t))
+#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(uint32_t))
+#define FDT_V16_SIZE FDT_V3_SIZE
+#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(uint32_t))
+
+#endif /* _FDT_H */
diff --git a/include/libfdt.h b/include/libfdt.h
new file mode 100644
index 0000000..a0b4d55
--- /dev/null
+++ b/include/libfdt.h
@@ -0,0 +1,138 @@
+#ifndef _LIBFDT_H
+#define _LIBFDT_H
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <fdt.h>
+#include <libfdt_env.h>
+
+#define FDT_FIRST_SUPPORTED_VERSION 0x10
+#define FDT_LAST_SUPPORTED_VERSION 0x11
+
+/* Error codes: informative error codes */
+#define FDT_ERR_NOTFOUND 1
+#define FDT_ERR_EXISTS 2
+#define FDT_ERR_NOSPACE 3
+
+/* Error codes: codes for bad parameters */
+#define FDT_ERR_BADOFFSET 4
+#define FDT_ERR_BADPATH 5
+#define FDT_ERR_BADSTATE 6
+
+/* Error codes: codes for bad device tree blobs */
+#define FDT_ERR_TRUNCATED 7
+#define FDT_ERR_BADMAGIC 8
+#define FDT_ERR_BADVERSION 9
+#define FDT_ERR_BADSTRUCTURE 10
+#define FDT_ERR_BADLAYOUT 11
+
+#define FDT_ERR_MAX 11
+
+#define fdt_get_header(fdt, field) \
+ (fdt32_to_cpu(((struct fdt_header *)(fdt))->field))
+#define fdt_magic(fdt) (fdt_get_header(fdt, magic))
+#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))
+#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))
+#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings))
+#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap))
+#define fdt_version(fdt) (fdt_get_header(fdt, version))
+#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version))
+#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys))
+#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings))
+#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct))
+
+#define fdt_set_header(fdt, field, val) \
+ ((struct fdt_header *)(fdt))->field = cpu_to_fdt32(val)
+
+void *fdt_offset_ptr(const void *fdt, int offset, int checklen);
+
+#define fdt_offset_ptr_typed(fdt, offset, var) \
+ ((typeof(var))(fdt_offset_ptr((fdt), (offset), sizeof(*(var)))))
+
+int fdt_move(const void *fdt, void *buf, int bufsize);
+
+/* Read-only functions */
+char *fdt_string(const void *fdt, int stroffset);
+
+int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
+ const char *name, int namelen);
+int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
+
+int fdt_path_offset(const void *fdt, const char *path);
+
+struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
+ const char *name, int *lenp);
+void *fdt_getprop(const void *fdt, int nodeoffset,
+ const char *name, int *lenp);
+
+uint32_t fdt_next_tag(const void *fdt, int offset,
+ int *nextoffset, char **namep);
+
+/* Write-in-place functions */
+int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len);
+
+#define fdt_setprop_inplace_typed(fdt, nodeoffset, name, val) \
+ ({ \
+ typeof(val) x = val; \
+ fdt_setprop_inplace(fdt, nodeoffset, name, &x, sizeof(x)); \
+ })
+
+int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
+int fdt_nop_node(void *fdt, int nodeoffset);
+
+/* Sequential-write functions */
+int fdt_create(void *buf, int bufsize);
+int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
+int fdt_finish_reservemap(void *fdt);
+int fdt_begin_node(void *fdt, const char *name);
+int fdt_property(void *fdt, const char *name, const void *val, int len);
+#define fdt_property_typed(fdt, name, val) \
+ ({ \
+ typeof(val) x = (val); \
+ fdt_property((fdt), (name), &x, sizeof(x)); \
+ })
+#define fdt_property_string(fdt, name, str) \
+ fdt_property(fdt, name, str, strlen(str)+1)
+int fdt_end_node(void *fdt);
+int fdt_finish(void *fdt);
+
+/* Read-write functions */
+int fdt_open_into(void *fdt, void *buf, int bufsize);
+int fdt_pack(void *fdt);
+
+int fdt_setprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len);
+#define fdt_setprop_typed(fdt, nodeoffset, name, val) \
+ ({ \
+ typeof(val) x = (val); \
+ fdt_setprop((fdt), (nodeoffset), (name), &x, sizeof(x)); \
+ })
+#define fdt_setprop_string(fdt, nodeoffset, name, str) \
+ fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
+int fdt_delprop(void *fdt, int nodeoffset, const char *name);
+int fdt_add_subnode_namelen(void *fdt, int parentoffset,
+ const char *name, int namelen);
+int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
+int fdt_del_node(void *fdt, int nodeoffset);
+
+/* Extra functions */
+const char *fdt_strerror(int errval);
+
+#endif /* _LIBFDT_H */
diff --git a/include/libfdt_env.h b/include/libfdt_env.h
new file mode 100644
index 0000000..6c77852
--- /dev/null
+++ b/include/libfdt_env.h
@@ -0,0 +1,16 @@
+#ifndef _LIBFDT_ENV_H
+#define _LIBFDT_ENV_H
+
+#include <stddef.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <linux/string.h>
+
+struct fdt_header *fdt; /* Pointer to the working fdt */
+
+#define fdt32_to_cpu(x) __be32_to_cpu(x)
+#define cpu_to_fdt32(x) __cpu_to_be32(x)
+#define fdt64_to_cpu(x) __be64_to_cpu(x)
+#define cpu_to_fdt64(x) __cpu_to_be64(x)
+
+#endif /* _LIBFDT_ENV_H */
diff --git a/lib_microblaze/board.c b/lib_microblaze/board.c
index 026d247..c95125a 100644
--- a/lib_microblaze/board.c
+++ b/lib_microblaze/board.c
@@ -1,6 +1,8 @@
/*
+ * (C) Copyright 2007 Michal Simek
* (C) Copyright 2004 Atmark Techno, Inc.
*
+ * Michal SIMEK <monstr@monstr.eu>
* Yasushi SHOJI <yashi@atmark-techno.com>
*
* See file CREDITS for list of people who contributed to this
@@ -13,7 +15,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
@@ -30,8 +32,18 @@
DECLARE_GLOBAL_DATA_PTR;
-const char version_string[] =
- U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")";
+const char version_string[] = U_BOOT_VERSION " (" __DATE__ " - " __TIME__ ")";
+
+#ifdef CFG_GPIO_0
+extern int gpio_init (void);
+#endif
+#ifdef CFG_INTC_0
+extern int interrupts_init (void);
+#endif
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+extern int eth_init (bd_t * bis);
+extern int getenv_IPaddr (char *);
+#endif
/*
* Begin and End of memory area for malloc(), and current "brk"
@@ -40,6 +52,18 @@ static ulong mem_malloc_start;
static ulong mem_malloc_end;
static ulong mem_malloc_brk;
+/*
+ * The Malloc area is immediately below the monitor copy in DRAM
+ * aka CFG_MONITOR_BASE - Note there is no need for reloc_off
+ * as our monitory code is run from SDRAM
+ */
+static void mem_malloc_init (void)
+{
+ mem_malloc_end = (CFG_MALLOC_BASE + CFG_MALLOC_LEN);
+ mem_malloc_start = CFG_MALLOC_BASE;
+ mem_malloc_brk = mem_malloc_start;
+ memset ((void *)mem_malloc_start, 0, mem_malloc_end - mem_malloc_start);
+}
void *sbrk (ptrdiff_t increment)
{
@@ -50,7 +74,7 @@ void *sbrk (ptrdiff_t increment)
return (NULL);
}
mem_malloc_brk = new;
- return ((void *) old);
+ return ((void *)old);
}
/*
@@ -68,24 +92,36 @@ void *sbrk (ptrdiff_t increment)
typedef int (init_fnc_t) (void);
init_fnc_t *init_sequence[] = {
- serial_init, /* serial communications setup */
+ env_init,
+ serial_init,
+#ifdef CFG_GPIO_0
+ gpio_init,
+#endif
+#ifdef CFG_INTC_0
+ interrupts_init,
+#endif
NULL,
};
-void board_init(void)
+void board_init (void)
{
bd_t *bd;
init_fnc_t **init_fnc_ptr;
-
- /* Pointer is writable since we allocated a register for it. */
- gd = (gd_t *)CFG_GBL_DATA_OFFSET;
- memset((void *)gd, 0, CFG_GBL_DATA_SIZE);
-
- gd->bd = (bd_t *)(gd+1); /* At end of global data */
+ gd = (gd_t *) CFG_GBL_DATA_OFFSET;
+#if (CONFIG_COMMANDS & CFG_CMD_FLASH)
+ ulong flash_size = 0;
+#endif
+ asm ("nop"); /* FIXME gd is not initialize - wait */
+ memset ((void *)gd, 0, CFG_GBL_DATA_SIZE);
+ gd->bd = (bd_t *) (gd + 1); /* At end of global data */
gd->baudrate = CONFIG_BAUDRATE;
-
bd = gd->bd;
bd->bi_baudrate = CONFIG_BAUDRATE;
+ bd->bi_memstart = CFG_SDRAM_BASE;
+ bd->bi_memsize = CFG_SDRAM_SIZE;
+
+ /* Initialise malloc() area */
+ mem_malloc_init ();
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
WATCHDOG_RESET ();
@@ -94,6 +130,37 @@ void board_init(void)
}
}
+#if (CONFIG_COMMANDS & CFG_CMD_FLASH)
+ bd->bi_flashstart = CFG_FLASH_BASE;
+ if (0 < (flash_size = flash_init ())) {
+ bd->bi_flashsize = flash_size;
+ bd->bi_flashoffset = CFG_FLASH_BASE + flash_size;
+ } else {
+ puts ("Flash init FAILED");
+ bd->bi_flashstart = 0;
+ bd->bi_flashsize = 0;
+ bd->bi_flashoffset = 0;
+ }
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+ char *s, *e;
+ int i;
+ /* board MAC address */
+ s = getenv ("ethaddr");
+ for (i = 0; i < 6; ++i) {
+ bd->bi_enetaddr[i] = s ? simple_strtoul (s, &e, 16) : 0;
+ if (s)
+ s = (*e) ? e + 1 : e;
+ }
+ /* IP Address */
+ bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
+ eth_init (bd);
+#endif
+
+ /* relocate environment function pointers etc. */
+ env_relocate ();
+
/* main_loop */
for (;;) {
WATCHDOG_RESET ();
@@ -104,5 +171,5 @@ void board_init(void)
void hang (void)
{
puts ("### ERROR ### Please RESET the board ###\n");
- for (;;);
+ for (;;) ;
}
diff --git a/lib_microblaze/microblaze_linux.c b/lib_microblaze/microblaze_linux.c
index b3a0815..2c7885c 100644
--- a/lib_microblaze/microblaze_linux.c
+++ b/lib_microblaze/microblaze_linux.c
@@ -1,6 +1,8 @@
/*
+ * (C) Copyright 2007 Michal Simek
* (C) Copyright 2004 Atmark Techno, Inc.
*
+ * Michal SIMEK <monstr@monstr.eu>
* Yasushi SHOJI <yashi@atmark-techno.com>
*
* See file CREDITS for list of people who contributed to this
@@ -13,7 +15,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
@@ -24,8 +26,146 @@
#include <common.h>
#include <command.h>
+#include <image.h>
+#include <zlib.h>
+#include <asm/byteorder.h>
-void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
- ulong addr, ulong *len_ptr, int verify)
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+# include <status_led.h>
+# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
+#else
+# define SHOW_BOOT_PROGRESS(arg)
+#endif
+
+extern image_header_t header; /* from cmd_bootm.c */
+/*cmd_boot.c*/
+extern int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]);
+
+void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
+ ulong addr, ulong * len_ptr, int verify)
{
+ ulong len = 0, checksum;
+ ulong initrd_start, initrd_end;
+ ulong data;
+ /* First parameter is mapped to $r5 for kernel boot args */
+ void (*theKernel) (char *);
+ image_header_t *hdr = &header;
+ char *commandline = getenv ("bootargs");
+ int i;
+
+ theKernel = (void (*)(char *))ntohl (hdr->ih_ep);
+
+ /* Check if there is an initrd image */
+ if (argc >= 3) {
+ SHOW_BOOT_PROGRESS (9);
+
+ addr = simple_strtoul (argv[2], NULL, 16);
+
+ printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
+
+ /* Copy header so we can blank CRC field for re-calculation */
+ memcpy (&header, (char *)addr, sizeof (image_header_t));
+
+ if (ntohl (hdr->ih_magic) != IH_MAGIC) {
+ printf ("Bad Magic Number\n");
+ SHOW_BOOT_PROGRESS (-10);
+ do_reset (cmdtp, flag, argc, argv);
+ }
+
+ data = (ulong) & header;
+ len = sizeof (image_header_t);
+
+ checksum = ntohl (hdr->ih_hcrc);
+ hdr->ih_hcrc = 0;
+
+ if (crc32 (0, (char *)data, len) != checksum) {
+ printf ("Bad Header Checksum\n");
+ SHOW_BOOT_PROGRESS (-11);
+ do_reset (cmdtp, flag, argc, argv);
+ }
+
+ SHOW_BOOT_PROGRESS (10);
+
+ print_image_hdr (hdr);
+
+ data = addr + sizeof (image_header_t);
+ len = ntohl (hdr->ih_size);
+
+ if (verify) {
+ ulong csum = 0;
+
+ printf (" Verifying Checksum ... ");
+ csum = crc32 (0, (char *)data, len);
+ if (csum != ntohl (hdr->ih_dcrc)) {
+ printf ("Bad Data CRC\n");
+ SHOW_BOOT_PROGRESS (-12);
+ do_reset (cmdtp, flag, argc, argv);
+ }
+ printf ("OK\n");
+ }
+
+ SHOW_BOOT_PROGRESS (11);
+
+ if ((hdr->ih_os != IH_OS_LINUX) ||
+ (hdr->ih_arch != IH_CPU_MICROBLAZE) ||
+ (hdr->ih_type != IH_TYPE_RAMDISK)) {
+ printf ("No Linux Microblaze Ramdisk Image\n");
+ SHOW_BOOT_PROGRESS (-13);
+ do_reset (cmdtp, flag, argc, argv);
+ }
+
+ /*
+ * Now check if we have a multifile image
+ */
+ } else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) {
+ ulong tail = ntohl (len_ptr[0]) % 4;
+
+ SHOW_BOOT_PROGRESS (13);
+
+ /* skip kernel length and terminator */
+ data = (ulong) (&len_ptr[2]);
+ /* skip any additional image length fields */
+ for (i = 1; len_ptr[i]; ++i)
+ data += 4;
+ /* add kernel length, and align */
+ data += ntohl (len_ptr[0]);
+ if (tail) {
+ data += 4 - tail;
+ }
+
+ len = ntohl (len_ptr[1]);
+
+ } else {
+ /*
+ * no initrd image
+ */
+ SHOW_BOOT_PROGRESS (14);
+
+ data = 0;
+ }
+
+#ifdef DEBUG
+ if (!data) {
+ printf ("No initrd\n");
+ }
+#endif
+
+ if (data) {
+ initrd_start = data;
+ initrd_end = initrd_start + len;
+ } else {
+ initrd_start = 0;
+ initrd_end = 0;
+ }
+
+ SHOW_BOOT_PROGRESS (15);
+
+#ifdef DEBUG
+ printf ("## Transferring control to Linux (at address %08lx) ...\n",
+ (ulong) theKernel);
+#endif
+
+ theKernel (commandline);
}
diff --git a/lib_microblaze/time.c b/lib_microblaze/time.c
index 12e8488..3fa1b11 100644
--- a/lib_microblaze/time.c
+++ b/lib_microblaze/time.c
@@ -1,6 +1,8 @@
/*
+ * (C) Copyright 2007 Michal Simek
* (C) Copyright 2004 Atmark Techno, Inc.
*
+ * Michal SIMEK <monstr@monstr.eu>
* Yasushi SHOJI <yashi@atmark-techno.com>
*
* See file CREDITS for list of people who contributed to this
@@ -22,6 +24,11 @@
* MA 02111-1307 USA
*/
-void udelay(unsigned long usec)
+#include <common.h>
+
+void udelay (unsigned long usec)
{
+ int i;
+ i = get_timer (0);
+ while ((get_timer (0) - i) < (usec / 1000)) ;
}
diff --git a/libfdt/Makefile b/libfdt/Makefile
new file mode 100644
index 0000000..dc41137
--- /dev/null
+++ b/libfdt/Makefile
@@ -0,0 +1,46 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)libfdt.a
+
+SOBJS =
+
+COBJS = fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o
+
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+$(LIB): $(obj).depend $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/libfdt/README b/libfdt/README
new file mode 100644
index 0000000..f4cca34
--- /dev/null
+++ b/libfdt/README
@@ -0,0 +1,23 @@
+The libfdt functionality was written by David Gibson. The original
+source came from the git repository:
+
+URL: git://ozlabs.org/home/dgibson/git/libfdt.git
+
+author David Gibson <dgibson@sneetch.(none)>
+ Fri, 23 Mar 2007 04:16:54 +0000 (15:16 +1100)
+committer David Gibson <dgibson@sneetch.(none)>
+ Fri, 23 Mar 2007 04:16:54 +0000 (15:16 +1100)
+commit 857f54e79f74429af20c2b5ecc00ee98af6a3b8b
+tree 2f648f0f88225a51ded452968d28b4402df8ade0
+parent 07a12a08005f3b5cd9337900a6551e450c07b515
+
+To adapt for u-boot usage, only the applicable files were copied and
+imported into the u-boot git repository.
+Omitted:
+* GPL - u-boot comes with a copy of the GPL license
+* test subdirectory - not directly useful for u-boot
+
+After importing, other customizations were performed. See the git log
+for details.
+
+Jerry Van Baren
diff --git a/libfdt/fdt.c b/libfdt/fdt.c
new file mode 100644
index 0000000..4b1c8ab
--- /dev/null
+++ b/libfdt/fdt.c
@@ -0,0 +1,85 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+int _fdt_check_header(const void *fdt)
+{
+ if (fdt_magic(fdt) == FDT_MAGIC) {
+ /* Complete tree */
+ if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
+ return -FDT_ERR_BADVERSION;
+ if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
+ return -FDT_ERR_BADVERSION;
+ } else if (fdt_magic(fdt) == SW_MAGIC) {
+ /* Unfinished sequential-write blob */
+ if (fdt_size_dt_struct(fdt) == 0)
+ return -FDT_ERR_BADSTATE;
+ } else {
+ return -FDT_ERR_BADMAGIC;
+ }
+
+ return 0;
+}
+
+void *fdt_offset_ptr(const void *fdt, int offset, int len)
+{
+ void *p;
+
+ if (fdt_version(fdt) >= 0x11)
+ if (((offset + len) < offset)
+ || ((offset + len) > fdt_size_dt_struct(fdt)))
+ return NULL;
+
+ p = _fdt_offset_ptr(fdt, offset);
+
+ if (p + len < p)
+ return NULL;
+ return p;
+}
+
+const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
+{
+ int len = strlen(s) + 1;
+ const char *last = strtab + tabsize - len;
+ const char *p;
+
+ for (p = strtab; p <= last; p++)
+ if (memeq(p, s, len))
+ return p;
+ return NULL;
+}
+
+int fdt_move(const void *fdt, void *buf, int bufsize)
+{
+ int err = _fdt_check_header(fdt);
+
+ if (err)
+ return err;
+
+ if (fdt_totalsize(fdt) > bufsize)
+ return -FDT_ERR_NOSPACE;
+
+ memmove(buf, fdt, fdt_totalsize(fdt));
+ return 0;
+}
diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c
new file mode 100644
index 0000000..ce01dc7
--- /dev/null
+++ b/libfdt/fdt_ro.c
@@ -0,0 +1,331 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+#define CHECK_HEADER(fdt) { \
+ int err; \
+ if ((err = _fdt_check_header(fdt)) != 0) \
+ return err; \
+}
+
+static int offset_streq(const void *fdt, int offset,
+ const char *s, int len)
+{
+ const char *p = fdt_offset_ptr(fdt, offset, len+1);
+
+ if (! p)
+ /* short match */
+ return 0;
+
+ if (memcmp(p, s, len) != 0)
+ return 0;
+
+ if (p[len] != '\0')
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Return a pointer to the string at the given string offset.
+ */
+char *fdt_string(const void *fdt, int stroffset)
+{
+ return (char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
+}
+
+/*
+ * Return the node offset of the node specified by:
+ * parentoffset - starting place (0 to start at the root)
+ * name - name being searched for
+ * namelen - length of the name: typically strlen(name)
+ *
+ * Notes:
+ * If the start node has subnodes, the subnodes are _not_ searched for the
+ * requested name.
+ */
+int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
+ const char *name, int namelen)
+{
+ int level = 0;
+ uint32_t tag;
+ int offset, nextoffset;
+
+ CHECK_HEADER(fdt);
+
+ tag = fdt_next_tag(fdt, parentoffset, &nextoffset, NULL);
+ if (tag != FDT_BEGIN_NODE)
+ return -FDT_ERR_BADOFFSET;
+
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset, NULL);
+
+ switch (tag) {
+ case FDT_END:
+ return -FDT_ERR_TRUNCATED;
+
+ case FDT_BEGIN_NODE:
+ level++;
+ /*
+ * If we are nested down levels, ignore the strings
+ * until we get back to the proper level.
+ */
+ if (level != 1)
+ continue;
+
+ /* Return the offset if this is "our" string. */
+ if (offset_streq(fdt, offset+FDT_TAGSIZE, name, namelen))
+ return offset;
+ break;
+
+ case FDT_END_NODE:
+ level--;
+ break;
+
+ case FDT_PROP:
+ case FDT_NOP:
+ break;
+
+ default:
+ return -FDT_ERR_BADSTRUCTURE;
+ }
+ } while (level >= 0);
+
+ return -FDT_ERR_NOTFOUND;
+}
+
+/*
+ * See fdt_subnode_offset_namelen()
+ */
+int fdt_subnode_offset(const void *fdt, int parentoffset,
+ const char *name)
+{
+ return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));
+}
+
+/*
+ * Searches for the node corresponding to the given path and returns the
+ * offset of that node.
+ */
+int fdt_path_offset(const void *fdt, const char *path)
+{
+ const char *end = path + strlen(path);
+ const char *p = path;
+ int offset = 0;
+
+ CHECK_HEADER(fdt);
+
+ /* Paths must be absolute */
+ if (*path != '/')
+ return -FDT_ERR_BADPATH;
+
+ while (*p) {
+ const char *q;
+
+ /* Skip path separator(s) */
+ while (*p == '/')
+ p++;
+ if (! *p)
+ return -FDT_ERR_BADPATH;
+
+ /*
+ * Find the next path separator. The characters between
+ * p and q are the next segment of the the path to find.
+ */
+ q = strchr(p, '/');
+ if (! q)
+ q = end;
+
+ /*
+ * Find the offset corresponding to the this path segment.
+ */
+ offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);
+
+ /* Oops, error, abort abort abort */
+ if (offset < 0)
+ return offset;
+
+ p = q;
+ }
+
+ return offset;
+}
+
+/*
+ * Given the offset of a node and a name of a property in that node, return
+ * a pointer to the property struct.
+ */
+struct fdt_property *fdt_get_property(const void *fdt,
+ int nodeoffset,
+ const char *name, int *lenp)
+{
+ int level = 0;
+ uint32_t tag;
+ struct fdt_property *prop;
+ int namestroff;
+ int offset, nextoffset;
+ int err;
+
+ if ((err = _fdt_check_header(fdt)) != 0)
+ goto fail;
+
+ err = -FDT_ERR_BADOFFSET;
+ if (nodeoffset % FDT_TAGSIZE)
+ goto fail;
+
+ tag = fdt_next_tag(fdt, nodeoffset, &nextoffset, NULL);
+ if (tag != FDT_BEGIN_NODE)
+ goto fail;
+
+ do {
+ offset = nextoffset;
+
+ tag = fdt_next_tag(fdt, offset, &nextoffset, NULL);
+ switch (tag) {
+ case FDT_END:
+ err = -FDT_ERR_TRUNCATED;
+ goto fail;
+
+ case FDT_BEGIN_NODE:
+ level++;
+ break;
+
+ case FDT_END_NODE:
+ level--;
+ break;
+
+ case FDT_PROP:
+ /*
+ * If we are nested down levels, ignore the strings
+ * until we get back to the proper level.
+ */
+ if (level != 0)
+ continue;
+
+ err = -FDT_ERR_BADSTRUCTURE;
+ prop = fdt_offset_ptr_typed(fdt, offset, prop);
+ if (! prop)
+ goto fail;
+ namestroff = fdt32_to_cpu(prop->nameoff);
+ if (streq(fdt_string(fdt, namestroff), name)) {
+ /* Found it! */
+ int len = fdt32_to_cpu(prop->len);
+ prop = fdt_offset_ptr(fdt, offset,
+ sizeof(*prop)+len);
+ if (! prop)
+ goto fail;
+
+ if (lenp)
+ *lenp = len;
+
+ return prop;
+ }
+ break;
+
+ case FDT_NOP:
+ break;
+
+ default:
+ err = -FDT_ERR_BADSTRUCTURE;
+ goto fail;
+ }
+ } while (level >= 0);
+
+ err = -FDT_ERR_NOTFOUND;
+fail:
+ if (lenp)
+ *lenp = err;
+ return NULL;
+}
+
+/*
+ * Given the offset of a node and a name of a property in that node, return
+ * a pointer to the property data (ONLY).
+ */
+void *fdt_getprop(const void *fdt, int nodeoffset,
+ const char *name, int *lenp)
+{
+ const struct fdt_property *prop;
+
+ prop = fdt_get_property(fdt, nodeoffset, name, lenp);
+ if (! prop)
+ return NULL;
+
+ return (void *)prop->data;
+}
+
+
+uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset, char **namep)
+{
+ const uint32_t *tagp, *lenp;
+ uint32_t tag;
+ const char *p;
+
+ if (offset % FDT_TAGSIZE)
+ return -1;
+
+ tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
+ if (! tagp)
+ return FDT_END; /* premature end */
+ tag = fdt32_to_cpu(*tagp);
+ offset += FDT_TAGSIZE;
+
+ switch (tag) {
+ case FDT_BEGIN_NODE:
+ if(namep)
+ *namep = fdt_offset_ptr(fdt, offset, 1);
+
+ /* skip name */
+ do {
+ p = fdt_offset_ptr(fdt, offset++, 1);
+ } while (p && (*p != '\0'));
+ if (! p)
+ return FDT_END;
+ break;
+ case FDT_PROP:
+ lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
+ if (! lenp)
+ return FDT_END;
+ /*
+ * Get the property and set the namep to the name.
+ */
+ if(namep) {
+ struct fdt_property *prop;
+
+ prop = fdt_offset_ptr_typed(fdt, offset - FDT_TAGSIZE, prop);
+ if (! prop)
+ return -FDT_ERR_BADSTRUCTURE;
+ *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+ }
+ /* skip name offset, length and value */
+ offset += 2*FDT_TAGSIZE + fdt32_to_cpu(*lenp);
+ break;
+ }
+
+ if (nextoffset)
+ *nextoffset = ALIGN(offset, FDT_TAGSIZE);
+
+ return tag;
+}
diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c
new file mode 100644
index 0000000..b33fbf4
--- /dev/null
+++ b/libfdt/fdt_rw.c
@@ -0,0 +1,293 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+static int rw_check_header(void *fdt)
+{
+ int err;
+
+ if ((err = _fdt_check_header(fdt)))
+ return err;
+ if (fdt_version(fdt) < 0x11)
+ return -FDT_ERR_BADVERSION;
+ if (fdt_off_mem_rsvmap(fdt) < ALIGN(sizeof(struct fdt_header), 8))
+ return -FDT_ERR_BADLAYOUT;
+ if (fdt_off_dt_struct(fdt) <
+ (fdt_off_mem_rsvmap(fdt) + sizeof(struct fdt_reserve_entry)))
+ return -FDT_ERR_BADLAYOUT;
+ if (fdt_off_dt_strings(fdt) <
+ (fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt)))
+ return -FDT_ERR_BADLAYOUT;
+ if (fdt_totalsize(fdt) <
+ (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)))
+ return -FDT_ERR_BADLAYOUT;
+ return 0;
+}
+
+#define RW_CHECK_HEADER(fdt) \
+ { \
+ int err; \
+ if ((err = rw_check_header(fdt)) != 0) \
+ return err; \
+ }
+
+static inline int _blob_data_size(void *fdt)
+{
+ return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
+}
+
+static int _blob_splice(void *fdt, void *p, int oldlen, int newlen)
+{
+ void *end = fdt + _blob_data_size(fdt);
+
+ if (((p + oldlen) < p) || ((p + oldlen) > end))
+ return -FDT_ERR_BADOFFSET;
+ if ((end - oldlen + newlen) > (fdt + fdt_totalsize(fdt)))
+ return -FDT_ERR_NOSPACE;
+ memmove(p + newlen, p + oldlen, end - p - oldlen);
+ return 0;
+}
+
+static int _blob_splice_struct(void *fdt, void *p,
+ int oldlen, int newlen)
+{
+ int delta = newlen - oldlen;
+ int err;
+
+ if ((err = _blob_splice(fdt, p, oldlen, newlen)))
+ return err;
+
+ fdt_set_header(fdt, size_dt_struct, fdt_size_dt_struct(fdt) + delta);
+ fdt_set_header(fdt, off_dt_strings, fdt_off_dt_strings(fdt) + delta);
+ return 0;
+}
+
+static int _blob_splice_string(void *fdt, int newlen)
+{
+ void *p = fdt + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
+ int err;
+
+ if ((err = _blob_splice(fdt, p, 0, newlen)))
+ return err;
+
+ fdt_set_header(fdt, size_dt_strings, fdt_size_dt_strings(fdt) + newlen);
+ return 0;
+}
+
+static int _find_add_string(void *fdt, const char *s)
+{
+ char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
+ const char *p;
+ char *new;
+ int len = strlen(s) + 1;
+ int err;
+
+ p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s);
+ if (p)
+ /* found it */
+ return (p - strtab);
+
+ new = strtab + fdt_size_dt_strings(fdt);
+ err = _blob_splice_string(fdt, len);
+ if (err)
+ return err;
+
+ memcpy(new, s, len);
+ return (new - strtab);
+}
+
+static int _resize_property(void *fdt, int nodeoffset, const char *name, int len,
+ struct fdt_property **prop)
+{
+ int oldlen;
+ int err;
+
+ *prop = fdt_get_property(fdt, nodeoffset, name, &oldlen);
+ if (! (*prop))
+ return oldlen;
+
+ if ((err = _blob_splice_struct(fdt, (*prop)->data,
+ ALIGN(oldlen, FDT_TAGSIZE),
+ ALIGN(len, FDT_TAGSIZE))))
+ return err;
+
+ (*prop)->len = cpu_to_fdt32(len);
+ return 0;
+}
+
+static int _add_property(void *fdt, int nodeoffset, const char *name, int len,
+ struct fdt_property **prop)
+{
+ uint32_t tag;
+ int proplen;
+ int nextoffset;
+ int namestroff;
+ int err;
+
+ tag = fdt_next_tag(fdt, nodeoffset, &nextoffset, NULL);
+ if (tag != FDT_BEGIN_NODE)
+ return -FDT_ERR_BADOFFSET;
+
+ namestroff = _find_add_string(fdt, name);
+ if (namestroff < 0)
+ return namestroff;
+
+ *prop = _fdt_offset_ptr(fdt, nextoffset);
+ proplen = sizeof(**prop) + ALIGN(len, FDT_TAGSIZE);
+
+ err = _blob_splice_struct(fdt, *prop, 0, proplen);
+ if (err)
+ return err;
+
+ (*prop)->tag = cpu_to_fdt32(FDT_PROP);
+ (*prop)->nameoff = cpu_to_fdt32(namestroff);
+ (*prop)->len = cpu_to_fdt32(len);
+ return 0;
+}
+
+int fdt_setprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
+{
+ struct fdt_property *prop;
+ int err;
+
+ if ((err = rw_check_header(fdt)))
+ return err;
+
+ err = _resize_property(fdt, nodeoffset, name, len, &prop);
+ if (err == -FDT_ERR_NOTFOUND)
+ err = _add_property(fdt, nodeoffset, name, len, &prop);
+ if (err)
+ return err;
+
+ memcpy(prop->data, val, len);
+ return 0;
+}
+
+int fdt_delprop(void *fdt, int nodeoffset, const char *name)
+{
+ struct fdt_property *prop;
+ int len, proplen;
+
+ RW_CHECK_HEADER(fdt);
+
+ prop = fdt_get_property(fdt, nodeoffset, name, &len);
+ if (! prop)
+ return len;
+
+ proplen = sizeof(*prop) + ALIGN(len, FDT_TAGSIZE);
+ return _blob_splice_struct(fdt, prop, proplen, 0);
+}
+
+int fdt_add_subnode_namelen(void *fdt, int parentoffset,
+ const char *name, int namelen)
+{
+ struct fdt_node_header *nh;
+ int offset, nextoffset;
+ int nodelen;
+ int err;
+ uint32_t tag;
+ uint32_t *endtag;
+
+ RW_CHECK_HEADER(fdt);
+
+ offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
+ if (offset >= 0)
+ return -FDT_ERR_EXISTS;
+ else if (offset != -FDT_ERR_NOTFOUND)
+ return offset;
+
+ /* Try to place the new node after the parent's properties */
+ fdt_next_tag(fdt, parentoffset, &nextoffset, NULL); /* skip the BEGIN_NODE */
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset, NULL);
+ } while (tag == FDT_PROP);
+
+ nh = _fdt_offset_ptr(fdt, offset);
+ nodelen = sizeof(*nh) + ALIGN(namelen+1, FDT_TAGSIZE) + FDT_TAGSIZE;
+
+ err = _blob_splice_struct(fdt, nh, 0, nodelen);
+ if (err)
+ return err;
+
+ nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
+ memset(nh->name, 0, ALIGN(namelen+1, FDT_TAGSIZE));
+ memcpy(nh->name, name, namelen);
+ endtag = (uint32_t *)((void *)nh + nodelen - FDT_TAGSIZE);
+ *endtag = cpu_to_fdt32(FDT_END_NODE);
+
+ return offset;
+}
+
+int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
+{
+ return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
+}
+
+int fdt_del_node(void *fdt, int nodeoffset)
+{
+ int endoffset;
+
+ endoffset = _fdt_node_end_offset(fdt, nodeoffset);
+ if (endoffset < 0)
+ return endoffset;
+
+ return _blob_splice_struct(fdt, _fdt_offset_ptr(fdt, nodeoffset),
+ endoffset - nodeoffset, 0);
+}
+
+int fdt_open_into(void *fdt, void *buf, int bufsize)
+{
+ int err;
+
+ err = fdt_move(fdt, buf, bufsize);
+ if (err)
+ return err;
+
+ fdt = buf;
+
+ fdt_set_header(fdt, totalsize, bufsize);
+
+ /* FIXME: re-order if necessary */
+
+ err = rw_check_header(fdt);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+int fdt_pack(void *fdt)
+{
+ int err;
+
+ err = rw_check_header(fdt);
+ if (err)
+ return err;
+
+ /* FIXME: pack components */
+ fdt_set_header(fdt, totalsize, _blob_data_size(fdt));
+ return 0;
+}
diff --git a/libfdt/fdt_strerror.c b/libfdt/fdt_strerror.c
new file mode 100644
index 0000000..7f231ce
--- /dev/null
+++ b/libfdt/fdt_strerror.c
@@ -0,0 +1,64 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+struct errtabent {
+ const char *str;
+};
+
+#define ERRTABENT(val) \
+ [(val)] = { .str = #val, }
+
+static struct errtabent errtable[] = {
+ ERRTABENT(FDT_ERR_NOTFOUND),
+ ERRTABENT(FDT_ERR_EXISTS),
+ ERRTABENT(FDT_ERR_NOSPACE),
+
+ ERRTABENT(FDT_ERR_BADOFFSET),
+ ERRTABENT(FDT_ERR_BADPATH),
+ ERRTABENT(FDT_ERR_BADSTATE),
+
+ ERRTABENT(FDT_ERR_TRUNCATED),
+ ERRTABENT(FDT_ERR_BADMAGIC),
+ ERRTABENT(FDT_ERR_BADVERSION),
+ ERRTABENT(FDT_ERR_BADSTRUCTURE),
+ ERRTABENT(FDT_ERR_BADLAYOUT),
+};
+#define ERRTABSIZE (sizeof(errtable) / sizeof(errtable[0]))
+
+const char *fdt_strerror(int errval)
+{
+ if (errval > 0)
+ return "<valid offset/length>";
+ else if (errval == 0)
+ return "<no error>";
+ else if (errval > -ERRTABSIZE) {
+ const char *s = errtable[-errval].str;
+
+ if (s)
+ return s;
+ }
+
+ return "<unknown error>";
+}
diff --git a/libfdt/fdt_sw.c b/libfdt/fdt_sw.c
new file mode 100644
index 0000000..672f4dd
--- /dev/null
+++ b/libfdt/fdt_sw.c
@@ -0,0 +1,226 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+static int check_header_sw(void *fdt)
+{
+ if (fdt_magic(fdt) != SW_MAGIC)
+ return -FDT_ERR_BADMAGIC;
+ return 0;
+}
+
+static void *grab_space(void *fdt, int len)
+{
+ int offset = fdt_size_dt_struct(fdt);
+ int spaceleft;
+
+ spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
+ - fdt_size_dt_strings(fdt);
+
+ if ((offset + len < offset) || (offset + len > spaceleft))
+ return NULL;
+
+ fdt_set_header(fdt, size_dt_struct, offset + len);
+ return fdt_offset_ptr(fdt, offset, len);
+}
+
+int fdt_create(void *buf, int bufsize)
+{
+ void *fdt = buf;
+
+ if (bufsize < sizeof(struct fdt_header))
+ return -FDT_ERR_NOSPACE;
+
+ memset(buf, 0, bufsize);
+
+ fdt_set_header(fdt, magic, SW_MAGIC);
+ fdt_set_header(fdt, version, FDT_LAST_SUPPORTED_VERSION);
+ fdt_set_header(fdt, last_comp_version, FDT_FIRST_SUPPORTED_VERSION);
+ fdt_set_header(fdt, totalsize, bufsize);
+
+ fdt_set_header(fdt, off_mem_rsvmap, ALIGN(sizeof(struct fdt_header),
+ sizeof(struct fdt_reserve_entry)));
+ fdt_set_header(fdt, off_dt_struct, fdt_off_mem_rsvmap(fdt));
+ fdt_set_header(fdt, off_dt_strings, bufsize);
+
+ return 0;
+}
+
+int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
+{
+ struct fdt_reserve_entry *re;
+ int err = check_header_sw(fdt);
+ int offset;
+
+ if (err)
+ return err;
+ if (fdt_size_dt_struct(fdt))
+ return -FDT_ERR_BADSTATE;
+
+ offset = fdt_off_dt_struct(fdt);
+ if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
+ return -FDT_ERR_NOSPACE;
+
+ re = (struct fdt_reserve_entry *)((void *)fdt + offset);
+ re->address = cpu_to_fdt64(addr);
+ re->size = cpu_to_fdt64(size);
+
+ fdt_set_header(fdt, off_dt_struct, offset + sizeof(*re));
+
+ return 0;
+}
+
+int fdt_finish_reservemap(void *fdt)
+{
+ return fdt_add_reservemap_entry(fdt, 0, 0);
+}
+
+int fdt_begin_node(void *fdt, const char *name)
+{
+ struct fdt_node_header *nh;
+ int err = check_header_sw(fdt);
+ int namelen = strlen(name) + 1;
+
+ if (err)
+ return err;
+
+ nh = grab_space(fdt, sizeof(*nh) + ALIGN(namelen, FDT_TAGSIZE));
+ if (! nh)
+ return -FDT_ERR_NOSPACE;
+
+ nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
+ memcpy(nh->name, name, namelen);
+ return 0;
+}
+
+int fdt_end_node(void *fdt)
+{
+ uint32_t *en;
+ int err = check_header_sw(fdt);
+
+ if (err)
+ return err;
+
+ en = grab_space(fdt, FDT_TAGSIZE);
+ if (! en)
+ return -FDT_ERR_NOSPACE;
+
+ *en = cpu_to_fdt32(FDT_END_NODE);
+ return 0;
+}
+
+static int find_add_string(void *fdt, const char *s)
+{
+ char *strtab = (char *)fdt + fdt_totalsize(fdt);
+ const char *p;
+ int strtabsize = fdt_size_dt_strings(fdt);
+ int len = strlen(s) + 1;
+ int struct_top, offset;
+
+ p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
+ if (p)
+ return p - strtab;
+
+ /* Add it */
+ offset = -strtabsize - len;
+ struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
+ if (fdt_totalsize(fdt) + offset < struct_top)
+ return 0; /* no more room :( */
+
+ memcpy(strtab + offset, s, len);
+ fdt_set_header(fdt, size_dt_strings, strtabsize + len);
+ return offset;
+}
+
+int fdt_property(void *fdt, const char *name, const void *val, int len)
+{
+ struct fdt_property *prop;
+ int err = check_header_sw(fdt);
+ int nameoff;
+
+ if (err)
+ return err;
+
+ nameoff = find_add_string(fdt, name);
+ if (nameoff == 0)
+ return -FDT_ERR_NOSPACE;
+
+ prop = grab_space(fdt, sizeof(*prop) + ALIGN(len, FDT_TAGSIZE));
+ if (! prop)
+ return -FDT_ERR_NOSPACE;
+
+ prop->tag = cpu_to_fdt32(FDT_PROP);
+ prop->nameoff = cpu_to_fdt32(nameoff);
+ prop->len = cpu_to_fdt32(len);
+ memcpy(prop->data, val, len);
+ return 0;
+}
+
+int fdt_finish(void *fdt)
+{
+ int err = check_header_sw(fdt);
+ char *p = (char *)fdt;
+ uint32_t *end;
+ int oldstroffset, newstroffset;
+ uint32_t tag;
+ int offset, nextoffset;
+
+ if (err)
+ return err;
+
+ /* Add terminator */
+ end = grab_space(fdt, sizeof(*end));
+ if (! end)
+ return -FDT_ERR_NOSPACE;
+ *end = cpu_to_fdt32(FDT_END);
+
+ /* Relocate the string table */
+ oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
+ newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
+ memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
+ fdt_set_header(fdt, off_dt_strings, newstroffset);
+
+ /* Walk the structure, correcting string offsets */
+ offset = 0;
+ while ((tag = fdt_next_tag(fdt, offset, &nextoffset, NULL)) != FDT_END) {
+ if (tag == FDT_PROP) {
+ struct fdt_property *prop = fdt_offset_ptr(fdt, offset,
+ sizeof(*prop));
+ int nameoff;
+
+ if (! prop)
+ return -FDT_ERR_BADSTRUCTURE;
+
+ nameoff = fdt32_to_cpu(prop->nameoff);
+ nameoff += fdt_size_dt_strings(fdt);
+ prop->nameoff = cpu_to_fdt32(nameoff);
+ }
+ offset = nextoffset;
+ }
+
+ /* Finally, adjust the header */
+ fdt_set_header(fdt, totalsize, newstroffset + fdt_size_dt_strings(fdt));
+ fdt_set_header(fdt, magic, FDT_MAGIC);
+ return 0;
+}
diff --git a/libfdt/fdt_wip.c b/libfdt/fdt_wip.c
new file mode 100644
index 0000000..261b9b0
--- /dev/null
+++ b/libfdt/fdt_wip.c
@@ -0,0 +1,112 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
+{
+ void *propval;
+ int proplen;
+
+ propval = fdt_getprop(fdt, nodeoffset, name, &proplen);
+ if (! propval)
+ return proplen;
+
+ if (proplen != len)
+ return -FDT_ERR_NOSPACE;
+
+ memcpy(propval, val, len);
+ return 0;
+}
+
+static void nop_region(void *start, int len)
+{
+ uint32_t *p;
+
+ for (p = start; (void *)p < (start + len); p++)
+ *p = cpu_to_fdt32(FDT_NOP);
+}
+
+int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
+{
+ struct fdt_property *prop;
+ int len;
+
+ prop = fdt_get_property(fdt, nodeoffset, name, &len);
+ if (! prop)
+ return len;
+
+ nop_region(prop, len + sizeof(*prop));
+
+ return 0;
+}
+
+int _fdt_node_end_offset(void *fdt, int nodeoffset)
+{
+ int level = 0;
+ uint32_t tag;
+ int offset, nextoffset;
+
+ tag = fdt_next_tag(fdt, nodeoffset, &nextoffset, NULL);
+ if (tag != FDT_BEGIN_NODE)
+ return -FDT_ERR_BADOFFSET;
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset, NULL);
+
+ switch (tag) {
+ case FDT_END:
+ return offset;
+
+ case FDT_BEGIN_NODE:
+ level++;
+ break;
+
+ case FDT_END_NODE:
+ level--;
+ break;
+
+ case FDT_PROP:
+ case FDT_NOP:
+ break;
+
+ default:
+ return -FDT_ERR_BADSTRUCTURE;
+ }
+ } while (level >= 0);
+
+ return nextoffset;
+}
+
+int fdt_nop_node(void *fdt, int nodeoffset)
+{
+ int endoffset;
+
+ endoffset = _fdt_node_end_offset(fdt, nodeoffset);
+ if (endoffset < 0)
+ return endoffset;
+
+ nop_region(fdt_offset_ptr(fdt, nodeoffset, 0), endoffset - nodeoffset);
+ return 0;
+}
diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h
new file mode 100644
index 0000000..cc9633c
--- /dev/null
+++ b/libfdt/libfdt_internal.h
@@ -0,0 +1,40 @@
+#ifndef _LIBFDT_INTERNAL_H
+#define _LIBFDT_INTERNAL_H
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <fdt.h>
+
+#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
+#define PALIGN(p, a) ((void *)ALIGN((unsigned long)(p), (a)))
+
+#define memeq(p, q, n) (memcmp((p), (q), (n)) == 0)
+#define streq(p, q) (strcmp((p), (q)) == 0)
+
+int _fdt_check_header(const void *fdt);
+const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
+int _fdt_node_end_offset(void *fdt, int nodeoffset);
+
+static inline void *_fdt_offset_ptr(const struct fdt_header *fdt, int offset)
+{
+ return (void *)fdt + fdt_off_dt_struct(fdt) + offset;
+}
+
+#define SW_MAGIC (~FDT_MAGIC)
+
+#endif /* _LIBFDT_INTERNAL_H */
diff --git a/microblaze_config.mk b/microblaze_config.mk
index b3ac8e0..06ddefa 100644
--- a/microblaze_config.mk
+++ b/microblaze_config.mk
@@ -22,7 +22,7 @@
# MA 02111-1307 USA
#
-PLATFORM_CPPFLAGS += -ffixed-r31
+PLATFORM_CPPFLAGS += -ffixed-r31 -D__microblaze__
ifdef CONFIG_MICROBLAZE_HARD_MULT
PLATFORM_CPPFLAGS += -mno-xl-soft-mul