Merge with git://www.denx.de/git/u-boot.git

This commit is contained in:
Stefan Roese 2007-04-12 14:06:54 +02:00
commit e8aac8e7bf
62 changed files with 4989 additions and 80 deletions

305
CHANGELOG
View File

@ -1,3 +1,276 @@
commit 51056dd9863e6a1bc363afbbe1775c58cd967418
Author: Wolfgang Denk <wd@denx.de>
Date: Wed Apr 11 17:22:55 2007 +0200
Update for SC3 board
* Make IDE timeout configurable through ide_reset_timeout variable.
* Use Newline as "password" string
* Use just a single partition in NAND flash
commit 31c98a88228021b314c89ebb8104fb6473da4471
Author: Wolfgang Denk <wd@denx.de>
Date: Wed Apr 4 02:09:30 2007 +0200
Minor coding style cleanup.
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 da6ebc1bc082cbe3b6bbde079cafe09f7ebbad4b
Author: Stefan Roese <sr@denx.de>
Date: Sat Mar 31 13:16:23 2007 +0200
ppc4xx: Update Katmai bootstrap command
Now the DDR2 frequency is also 2*PLB frequency when 166MHz PLB
is selected.
Signed-off-by: Stefan Roese <sr@denx.de>
commit cabee756a6532986729477c3cc1ea16ef8517ad2
Author: Stefan Roese <sr@denx.de>
Date: Sat Mar 31 13:15:06 2007 +0200
ppc4xx: Update 44x_spd_ddr2 code (440SP/440SPe)
Additional RAM information is now printed upon powerup, like
DDR2 frequency and CAS latency.
Signed-off-by: Stefan Roese <sr@denx.de>
commit 60723803431ac75cad085690789e433d5ab9174e
Author: Stefan Roese <sr@denx.de>
Date: Sat Mar 31 08:48:36 2007 +0200
ppc4xx: Change Yucca config file to support ECC
With the updated 44x DDR2 driver the Yucca board now supports
ECC generation and checking.
Signed-off-by: Stefan Roese <sr@denx.de>
commit 490e5730c674b20d708b783a2c5ffd7208f83873
Author: Stefan Roese <sr@denx.de>
Date: Sat Mar 31 08:47:34 2007 +0200
ppc4xx: Fix "bootstrap" command for Katmai board
The board specific "bootstrap" command is now fixed and can
be used for the AMCC Katmai board to configure different
CPU/PLB/OPB frequencies.
Signed-off-by: Stefan Roese <sr@denx.de>
commit 94f54703c3a776ec23e427ca2a16e0a79a5d50c1
Author: Stefan Roese <sr@denx.de>
Date: Sat Mar 31 08:46:08 2007 +0200
ppc4xx: Update 44x_spd_ddr2 code (440SP/440SPe)
Fix a bug in the auto calibration routine. This driver now runs
more reliable with the tested modules. It's also tested with
167MHz PLB frequency (667MHz DDR2 frequency) on the Katmai.
Signed-off-by: Stefan Roese <sr@denx.de>
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 430f1b0f9a670c2f13eaa52e66a10db96dd3647d
Author: Stefan Roese <sr@denx.de>
Date: Wed Mar 28 15:03:16 2007 +0200
Merge some AMCC make targets to keep the top-level Makefile smaller
Signed-off-by: Stefan Roese <sr@denx.de>
commit 0c75c9d84307a9f1cbe1ff0c4d8937ee3a96475e
Author: Stefan Roese <sr@denx.de>
Date: Wed Mar 28 14:52:12 2007 +0200
i2c: Enable "old" i2c commands even when CONFIG_I2C_CMD_TREE is defined
The "old" i2c commands (iprobe, imd...) are now compiled in again,
even when the i2c command tree is enabled via the CONFIG_I2C_CMD_TREE
config option.
Signed-off-by: Stefan Roese <sr@denx.de>
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 0d974d5297349504a2ddfa09314be573b5df320a
Author: Stefan Roese <sr@denx.de>
Date: Sat Mar 24 15:57:09 2007 +0100
[PATCH] Add 4xx GPIO functions
This patch adds some 4xx GPIO functions. It also moves some of the
common code and defines into a common 4xx GPIO header file.
Signed-off-by: Stefan Roese <sr@denx.de>
commit 2db633658bbf366ab0c8dad7a0727e1fb2ae6b11
Author: Stefan Roese <sr@denx.de>
Date: Sat Mar 24 15:55:58 2007 +0100
[PATCH] Small Sequoia cleanup
Signed-off-by: Stefan Roese <sr@denx.de>
commit 3cb86f3e40d2a80356177434a99f75bc8baa9caf
Author: Stefan Roese <sr@denx.de>
Date: Sat Mar 24 15:45:34 2007 +0100
[PATCH] Clean up 40EZ/Acadia support
This patch cleans up all the open issue of the preliminary
Acadia support.
Signed-off-by: Stefan Roese <sr@denx.de>
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 +421,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

View File

@ -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

View File

@ -564,6 +564,11 @@ Yasushi Shoji <yashi@atmark-techno.com>
SUZAKU MicroBlaze
Michal Simek <monstr@monstr.eu>
ML401 MicroBlaze
XUPV2P MicroBlaze
#########################################################################
# Coldfire Systems: #
# #

View File

@ -293,7 +293,7 @@ LIST_nios2=" \
#########################################################################
LIST_microblaze=" \
suzaku
suzaku ml401 xupv2p
"
#########################################################################

View File

@ -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
#########################################################################

33
README
View File

@ -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

View File

@ -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)
{

View File

@ -61,6 +61,7 @@ SECTIONS
{
__bss_start = .;
*(.bss)
__bss_start = .;
__bss_end = .;
}
__end = . ;
}

View File

@ -26,3 +26,8 @@
#
TEXT_BASE = 0xFE000000
#
# Additional board-specific libraries
#
BOARDLIBS = libfdt/libfdt.a

View File

@ -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

View File

@ -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)

View File

@ -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
#########################################################################

View File

@ -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

View File

@ -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;
}

View File

@ -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 = . ;
}

View File

@ -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

View File

@ -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);

View File

@ -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
#########################################################################

View File

@ -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

View File

@ -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 = . ;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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 \

View File

@ -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 */

View File

@ -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

874
common/cmd_fdt.c Normal file
View File

@ -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 */

View File

@ -513,9 +513,11 @@ void ide_init (void)
#endif
unsigned char c;
int i, bus;
#if defined(CONFIG_AMIGAONEG3SE) || defined(CONFIG_SC3)
unsigned int ata_reset_time;
#endif
#ifdef CONFIG_AMIGAONEG3SE
unsigned int max_bus_scan;
unsigned int ata_reset_time;
char *s;
#endif
#ifdef CONFIG_IDE_8xx_PCCARD
@ -617,10 +619,9 @@ void ide_init (void)
udelay (100000); /* 100 ms */
ide_outb (dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev));
udelay (100000); /* 100 ms */
#ifdef CONFIG_AMIGAONEG3SE
ata_reset_time = ATA_RESET_TIME;
s = getenv("ide_reset_timeout");
if (s) ata_reset_time = 2*simple_strtol(s, NULL, 10);
#if defined(CONFIG_AMIGAONEG3SE) || defined(CONFIG_SC3)
if ((s = getenv("ide_reset_timeout")) != NULL)
ata_reset_time = simple_strtol(s, NULL, 10);
#endif
i = 0;
do {
@ -628,7 +629,7 @@ void ide_init (void)
c = ide_inb (dev, ATA_STATUS);
i++;
#ifdef CONFIG_AMIGAONEG3SE
#if defined(CONFIG_AMIGAONEG3SE) || defined(CONFIG_SC3)
if (i > (ata_reset_time * 100)) {
#else
if (i > (ATA_RESET_TIME * 100)) {

View File

@ -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))

48
cpu/microblaze/cache.c Normal file
View File

@ -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

68
cpu/microblaze/dcache.S Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

69
cpu/microblaze/icache.S Normal file
View File

@ -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

View File

@ -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 */

165
cpu/microblaze/irq.S Normal file
View File

@ -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

View File

@ -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 */
#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

68
cpu/microblaze/timer.c Normal file
View File

@ -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

View File

@ -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)

View File

@ -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 */
};

View File

@ -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;

View File

@ -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

230
include/configs/ml401.h Normal file
View File

@ -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 */

View File

@ -133,8 +133,8 @@
#if 1 /* feel free to disable for development */
#define CONFIG_AUTOBOOT_KEYED /* Enable password protection */
#define CONFIG_AUTOBOOT_PROMPT "\nSC3 - booting... stop with S\n"
#define CONFIG_AUTOBOOT_DELAY_STR "S" /* 1st "password" */
#define CONFIG_AUTOBOOT_PROMPT "\nSC3 - booting... stop with ENTER\n"
#define CONFIG_AUTOBOOT_DELAY_STR "\n" /* 1st "password" */
#endif
/*
@ -416,11 +416,11 @@ extern unsigned long offsetOfEnvironment;
#define CONFIG_JFFS2_NAND 1 /* jffs2 on nand support */
/* No command line, one static partition Partition 3 contains jffs2 rootfs */
/* No command line, one static partition */
#undef CONFIG_JFFS2_CMDLINE
#define CONFIG_JFFS2_DEV "nand0"
#define CONFIG_JFFS2_PART_SIZE 0x00400000
#define CONFIG_JFFS2_PART_OFFSET 0x00c00000
#define CONFIG_JFFS2_PART_SIZE 0x01000000
#define CONFIG_JFFS2_PART_OFFSET 0x00000000
/*-----------------------------------------------------------------------
* Cache Configuration

View File

@ -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) */

174
include/configs/xupv2p.h Normal file
View File

@ -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 */

60
include/fdt.h Normal file
View File

@ -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 */

138
include/libfdt.h Normal file
View File

@ -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 */

16
include/libfdt_env.h Normal file
View File

@ -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 */

View File

@ -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 (;;) ;
}

View File

@ -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);
}

View File

@ -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)) ;
}

46
libfdt/Makefile Normal file
View File

@ -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
#########################################################################

23
libfdt/README Normal file
View File

@ -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

85
libfdt/fdt.c Normal file
View File

@ -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;
}

331
libfdt/fdt_ro.c Normal file
View File

@ -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;
}

293
libfdt/fdt_rw.c Normal file
View File

@ -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;
}

64
libfdt/fdt_strerror.c Normal file
View File

@ -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>";
}

226
libfdt/fdt_sw.c Normal file
View File

@ -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;
}

112
libfdt/fdt_wip.c Normal file
View File

@ -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;
}

40
libfdt/libfdt_internal.h Normal file
View File

@ -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 */

View File

@ -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