U-Boot
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
May 2012
- 175 participants
- 506 discussions

06 Oct '12
This series adds support for warm boot, allowing the device to suspend
and resume. U-Boot sets up some 'warm boot' code in a special area such
that the SOC can find it on a resume. This code is responsible for
setting up memory and clocked and then allowing the OS to continue
where it left off.
Also included here is support for the EMC, which allows setting the memory
timings correctly in U-Boot for maximum speed operation.
Note: sign-offs are needed from Jimmy Zhang, Wei Ni and Yen Lin.
Changes in v2:
- Add check of undocumented values in hidrev register
- Add debug() output to EMC
- Add new fdtdec_locate_array() function
- Add patch to find DVC bus number
- Check error return from pmu_set_nominal() in debug mode
- Move EMC tables to device tree
- Move structs shared between A9 and AVP into warmboot.h header file
- New patch to add low-level clock functions
- Rely on compiler to optimise out debug_print_vector()
- Remove unused crypto code
- Remove unused crypto code from crypto.c
- Removed check for nominal voltage (not needed as it is done just before)
- Split PMU code into separate TPS6586X driver
- Tidy SDRAM range check in warmboot_prepare_code()
- Tidy whitespace problems
- Use const for sbox arrays
- Use low-level clock functions in warmboot code instead of register access
Changes in v3:
- Add apb_misc.h header file in new patch
- Add better error reporting when EMC setup fails
- Add new fdtdec_next_compatible_subnode() patch
- Add new patch to put abs() in common.h
- Fix CONFIG_TEGRA_I2C define
- Move abs() macro into common.h
- Support nvidia,use-ram-code binding option for EMC
- Try to return a useful error code when EMC config fails
Jimmy Zhang (3):
tegra: Add EMC support for optimal memory timings
tegra: Add PMU to manage power supplies
tegra: Add EMC settings for Seaboard
Simon Glass (14):
fdt: Add function to locate an array in the device tree
fdt: Add function to return next compatible subnode
Add abs() macro to return absolute value
i2c: Add TPS6586X driver
tegra: Move ap20.h header into arch location
tegra: Add functions to access low-level Osc/PLL details
tegra: Add tegra_get_chip_type() to detect SKU
tegra: Add header file for APB_MISC register
tegra: Set up PMU for Nvidia boards
tegra: Set up warmboot code on Nvidia boards
fdt: tegra: Add EMC node to device tree
tegra: i2c: Add function to find DVC bus
tegra: fdt: Add EMC data for Tegra2 Seaboard
tegra: Enable LP0 on Seaboard
Wei Ni (1):
tegra: Turn off power detect in board init
Yen Lin (5):
Add AES crypto library
tegra: Add crypto library for warmboot code
tegra: Add flow, gp_padctl, fuse, sdram headers
tegra: Add warmboot implementation
tegra: Setup PMC scratch info from ap20 setup
arch/arm/cpu/armv7/tegra2/Makefile | 4 +
arch/arm/cpu/armv7/tegra2/ap20.c | 44 ++-
arch/arm/cpu/armv7/tegra2/board.c | 4 +-
arch/arm/cpu/armv7/tegra2/clock.c | 32 +
arch/arm/cpu/armv7/tegra2/crypto.c | 230 ++++++++
arch/arm/cpu/armv7/tegra2/crypto.h | 36 ++
arch/arm/cpu/armv7/tegra2/emc.c | 286 ++++++++++
arch/arm/cpu/armv7/tegra2/pmu.c | 70 +++
arch/arm/cpu/armv7/tegra2/warmboot.c | 382 +++++++++++++
arch/arm/cpu/armv7/tegra2/warmboot_avp.c | 250 ++++++++
arch/arm/cpu/armv7/tegra2/warmboot_avp.h | 81 +++
arch/arm/dts/tegra20.dtsi | 7 +
.../tegra2 => include/asm/arch-tegra2}/ap20.h | 7 +
arch/arm/include/asm/arch-tegra2/apb_misc.h | 36 ++
arch/arm/include/asm/arch-tegra2/clk_rst.h | 3 +
arch/arm/include/asm/arch-tegra2/clock.h | 22 +
arch/arm/include/asm/arch-tegra2/emc.h | 113 ++++
arch/arm/include/asm/arch-tegra2/flow.h | 36 ++
arch/arm/include/asm/arch-tegra2/fuse.h | 39 ++
arch/arm/include/asm/arch-tegra2/gp_padctrl.h | 73 +++
arch/arm/include/asm/arch-tegra2/pmu.h | 30 +
arch/arm/include/asm/arch-tegra2/sdram_param.h | 148 +++++
arch/arm/include/asm/arch-tegra2/tegra2.h | 25 +
arch/arm/include/asm/arch-tegra2/tegra_i2c.h | 7 +
arch/arm/include/asm/arch-tegra2/warmboot.h | 150 +++++
board/nvidia/common/Makefile | 1 +
board/nvidia/common/board.c | 41 ++-
board/nvidia/common/emc.c | 53 ++
board/nvidia/common/emc.h | 29 +
board/nvidia/dts/tegra2-seaboard.dts | 72 +++
drivers/i2c/tegra_i2c.c | 14 +
drivers/power/Makefile | 1 +
drivers/power/tps6586x.c | 280 +++++++++
include/aes.h | 70 +++
include/common.h | 13 +
include/configs/seaboard.h | 8 +
include/configs/tegra2-common.h | 17 +
include/fdtdec.h | 38 ++
include/tps6586x.h | 68 +++
lib/Makefile | 1 +
lib/aes.c | 598 ++++++++++++++++++++
lib/fdtdec.c | 28 +
42 files changed, 3443 insertions(+), 4 deletions(-)
create mode 100644 arch/arm/cpu/armv7/tegra2/crypto.c
create mode 100644 arch/arm/cpu/armv7/tegra2/crypto.h
create mode 100644 arch/arm/cpu/armv7/tegra2/emc.c
create mode 100644 arch/arm/cpu/armv7/tegra2/pmu.c
create mode 100644 arch/arm/cpu/armv7/tegra2/warmboot.c
create mode 100644 arch/arm/cpu/armv7/tegra2/warmboot_avp.c
create mode 100644 arch/arm/cpu/armv7/tegra2/warmboot_avp.h
rename arch/arm/{cpu/armv7/tegra2 => include/asm/arch-tegra2}/ap20.h (96%)
create mode 100644 arch/arm/include/asm/arch-tegra2/apb_misc.h
create mode 100644 arch/arm/include/asm/arch-tegra2/emc.h
create mode 100644 arch/arm/include/asm/arch-tegra2/flow.h
create mode 100644 arch/arm/include/asm/arch-tegra2/fuse.h
create mode 100644 arch/arm/include/asm/arch-tegra2/gp_padctrl.h
create mode 100644 arch/arm/include/asm/arch-tegra2/pmu.h
create mode 100644 arch/arm/include/asm/arch-tegra2/sdram_param.h
create mode 100644 arch/arm/include/asm/arch-tegra2/warmboot.h
create mode 100644 board/nvidia/common/emc.c
create mode 100644 board/nvidia/common/emc.h
create mode 100644 drivers/power/tps6586x.c
create mode 100644 include/aes.h
create mode 100644 include/tps6586x.h
create mode 100644 lib/aes.c
--
1.7.7.3
8
53

04 Oct '12
This patch adds support for the X600 SPEAr600 based board. Its also
the first SPEAr600 board that uses the newly introduced SPEAr600
SPL support. Xloader is not necessary any more. By using the new
"u-boot.spr" make target, one image will generated containing both,
U-Boot SPL (with mkimage header as needed by the SPEAr BootROM, and
the main U-Boot with mkimage header.
Signed-off-by: Stefan Roese <sr(a)denx.de>
Cc: Amit Virdi <amit.virdi(a)st.com>
Cc: Vipin Kumar <vipin.kumar(a)st.com>
---
v2:
- Add hush support
- Add bootcount & altbootcmd support
MAINTAINERS | 2 +
board/spear/x600/Makefile | 47 +++++++
board/spear/x600/fpga.c | 280 +++++++++++++++++++++++++++++++++++++
board/spear/x600/fpga.h | 23 +++
board/spear/x600/x600.c | 124 +++++++++++++++++
boards.cfg | 1 +
include/configs/x600.h | 339 +++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 816 insertions(+)
create mode 100644 board/spear/x600/Makefile
create mode 100644 board/spear/x600/fpga.c
create mode 100644 board/spear/x600/fpga.h
create mode 100644 board/spear/x600/x600.c
create mode 100644 include/configs/x600.h
diff --git a/MAINTAINERS b/MAINTAINERS
index f796872..c55faff 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -828,6 +828,8 @@ John Rigby <jcrigby(a)gmail.com>
Stefan Roese <sr(a)denx.de>
+ x600 ARM926EJS (spear600 Soc)
+
pdnb3 xscale/ixp
scpu xscale/ixp
diff --git a/board/spear/x600/Makefile b/board/spear/x600/Makefile
new file mode 100644
index 0000000..8c4e7e2
--- /dev/null
+++ b/board/spear/x600/Makefile
@@ -0,0 +1,47 @@
+#
+# (C) Copyright 2000-2004
+# Wolfgang Denk, DENX Software Engineering, wd(a)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)lib$(BOARD).o
+
+ifndef CONFIG_SPL_BUILD
+COBJS := fpga.o $(BOARD).o
+endif
+SOBJS :=
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/spear/x600/fpga.c b/board/spear/x600/fpga.c
new file mode 100644
index 0000000..85eb31b
--- /dev/null
+++ b/board/spear/x600/fpga.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2012 Stefan Roese <sr(a)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 <common.h>
+#include <spartan3.h>
+#include <command.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/spr_misc.h>
+#include <asm/arch/spr_ssp.h>
+
+/*
+ * FPGA program pin configuration on X600:
+ *
+ * Only PROG and DONE are connected to GPIOs. INIT is not connected to the
+ * SoC at all. And CLOCK and DATA are connected to the SSP2 port. We use
+ * 16bit serial writes via this SSP port to write the data bits into the
+ * FPGA.
+ */
+#define CONFIG_SYS_FPGA_PROG 2
+#define CONFIG_SYS_FPGA_DONE 3
+
+/*
+ * Set the active-low FPGA reset signal.
+ */
+static void fpga_reset(int assert)
+{
+ /*
+ * On x600 we have no means to toggle the FPGA reset signal
+ */
+ debug("%s:%d: RESET (%d)\n", __func__, __LINE__, assert);
+}
+
+/*
+ * Set the FPGA's active-low SelectMap program line to the specified level
+ */
+static int fpga_pgm_fn(int assert, int flush, int cookie)
+{
+ debug("%s:%d: FPGA PROG (%d)\n", __func__, __LINE__, assert);
+
+ gpio_set_value(CONFIG_SYS_FPGA_PROG, assert);
+
+ return assert;
+}
+
+/*
+ * Test the state of the active-low FPGA INIT line. Return 1 on INIT
+ * asserted (low).
+ */
+static int fpga_init_fn(int cookie)
+{
+ static int state;
+
+ debug("%s:%d: init (state=%d)\n", __func__, __LINE__, state);
+
+ /*
+ * On x600, the FPGA INIT signal is not connected to the SoC.
+ * We can't read the INIT status. Let's return the "correct"
+ * INIT signal state generated via a local state-machine.
+ */
+ if (++state == 1) {
+ return 1;
+ } else {
+ state = 0;
+ return 0;
+ }
+}
+
+/*
+ * Test the state of the active-high FPGA DONE pin
+ */
+static int fpga_done_fn(int cookie)
+{
+ struct ssp_regs *ssp = (struct ssp_regs *)CONFIG_SSP2_BASE;
+
+ /*
+ * Wait for Tx-FIFO to become empty before looking for DONE
+ */
+ while (!(readl(&ssp->sspsr) & SSPSR_TFE))
+ ;
+
+ if (gpio_get_value(CONFIG_SYS_FPGA_DONE))
+ return 1;
+ else
+ return 0;
+}
+
+/*
+ * FPGA pre-configuration function. Just make sure that
+ * FPGA reset is asserted to keep the FPGA from starting up after
+ * configuration.
+ */
+static int fpga_pre_config_fn(int cookie)
+{
+ debug("%s:%d: FPGA pre-configuration\n", __func__, __LINE__);
+ fpga_reset(TRUE);
+
+ return 0;
+}
+
+/*
+ * FPGA post configuration function. Blip the FPGA reset line and then see if
+ * the FPGA appears to be running.
+ */
+static int fpga_post_config_fn(int cookie)
+{
+ int rc = 0;
+
+ debug("%s:%d: FPGA post configuration\n", __func__, __LINE__);
+
+ fpga_reset(TRUE);
+ udelay(100);
+ fpga_reset(FALSE);
+ udelay(100);
+
+ return rc;
+}
+
+static int fpga_clk_fn(int assert_clk, int flush, int cookie)
+{
+ /*
+ * No dedicated clock signal on x600 (data & clock generated)
+ * in SSP interface. So we don't have to do anything here.
+ */
+ return assert_clk;
+}
+
+static int fpga_wr_fn(int assert_write, int flush, int cookie)
+{
+ struct ssp_regs *ssp = (struct ssp_regs *)CONFIG_SSP2_BASE;
+ static int count;
+ static u16 data;
+
+ /*
+ * First collect 16 bits of data
+ */
+ data = data << 1;
+ if (assert_write)
+ data |= 1;
+
+ /*
+ * If 16 bits are not available, return for more bits
+ */
+ count++;
+ if (count != 16)
+ return assert_write;
+
+ count = 0;
+
+ /*
+ * Wait for Tx-FIFO to become ready
+ */
+ while (!(readl(&ssp->sspsr) & SSPSR_TNF))
+ ;
+
+ /* Send 16 bits to FPGA via SSP bus */
+ writel(data, &ssp->sspdr);
+
+ return assert_write;
+}
+
+static Xilinx_Spartan3_Slave_Serial_fns x600_fpga_fns = {
+ fpga_pre_config_fn,
+ fpga_pgm_fn,
+ fpga_clk_fn,
+ fpga_init_fn,
+ fpga_done_fn,
+ fpga_wr_fn,
+ fpga_post_config_fn,
+};
+
+static Xilinx_desc fpga[CONFIG_FPGA_COUNT] = {
+ XILINX_XC3S1200E_DESC(slave_serial, &x600_fpga_fns, 0)
+};
+
+/*
+ * Initialize the SelectMap interface. We assume that the mode and the
+ * initial state of all of the port pins have already been set!
+ */
+static void fpga_serialslave_init(void)
+{
+ debug("%s:%d: Initialize serial slave interface\n", __func__, __LINE__);
+ fpga_pgm_fn(FALSE, FALSE, 0); /* make sure program pin is inactive */
+}
+
+static int expi_setup(int freq)
+{
+ struct misc_regs *misc = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+ int pll2_m, pll2_n, pll2_p, expi_x, expi_y;
+
+ pll2_m = (freq * 2) / 1000;
+ pll2_n = 15;
+ pll2_p = 1;
+ expi_x = 1;
+ expi_y = 2;
+
+ /*
+ * Disable reset, Low compression, Disable retiming, Enable Expi,
+ * Enable soft reset, DMA, PLL2, Internal
+ */
+ writel(EXPI_CLK_CFG_LOW_COMPR | EXPI_CLK_CFG_CLK_EN | EXPI_CLK_CFG_RST |
+ EXPI_CLK_SYNT_EN | EXPI_CLK_CFG_SEL_PLL2 |
+ EXPI_CLK_CFG_INT_CLK_EN | (expi_y << 16) | (expi_x << 24),
+ &misc->expi_clk_cfg);
+
+ /*
+ * 6 uA, Internal feedback, 1st order, Non-dithered, Sample Parameters,
+ * Enable PLL2, Disable reset
+ */
+ writel((pll2_m << 24) | (pll2_p << 8) | (pll2_n), &misc->pll2_frq);
+ writel(PLL2_CNTL_6UA | PLL2_CNTL_SAMPLE | PLL2_CNTL_ENABLE |
+ PLL2_CNTL_RESETN | PLL2_CNTL_LOCK, &misc->pll2_cntl);
+
+ /*
+ * Disable soft reset
+ */
+ clrbits_le32(&misc->expi_clk_cfg, EXPI_CLK_CFG_RST);
+
+ return 0;
+}
+
+/*
+ * Initialize the fpga
+ */
+int x600_init_fpga(void)
+{
+ struct ssp_regs *ssp = (struct ssp_regs *)CONFIG_SSP2_BASE;
+ struct misc_regs *misc = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+
+ /* Enable SSP2 clock */
+ writel(readl(&misc->periph1_clken) | MISC_SSP2ENB | MISC_GPIO4ENB,
+ &misc->periph1_clken);
+
+ /* Set EXPI clock to 45 MHz */
+ expi_setup(45000);
+
+ /* Configure GPIO directions */
+ gpio_direction_output(CONFIG_SYS_FPGA_PROG, 0);
+ gpio_direction_input(CONFIG_SYS_FPGA_DONE);
+
+ writel(SSPCR0_DSS_16BITS, &ssp->sspcr0);
+ writel(SSPCR1_SSE, &ssp->sspcr1);
+
+ /*
+ * Set lowest prescale divisor value (CPSDVSR) of 2 for max download
+ * speed.
+ *
+ * Actual data clock rate is: 80MHz / (CPSDVSR * (SCR + 1))
+ * With CPSDVSR at 2 and SCR at 0, the maximume clock rate is 40MHz.
+ */
+ writel(2, &ssp->sspcpsr);
+
+ fpga_init();
+ fpga_serialslave_init();
+
+ debug("%s:%d: Adding fpga 0\n", __func__, __LINE__);
+ fpga_add(fpga_xilinx, &fpga[0]);
+
+ return 0;
+}
diff --git a/board/spear/x600/fpga.h b/board/spear/x600/fpga.h
new file mode 100644
index 0000000..2b18557
--- /dev/null
+++ b/board/spear/x600/fpga.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2012 Stefan Roese <sr(a)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
+ */
+
+int x600_init_fpga(void);
diff --git a/board/spear/x600/x600.c b/board/spear/x600/x600.c
new file mode 100644
index 0000000..96ec0ad
--- /dev/null
+++ b/board/spear/x600/x600.c
@@ -0,0 +1,124 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar(a)st.com.
+ *
+ * Copyright (C) 2012 Stefan Roese <sr(a)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 <common.h>
+#include <nand.h>
+#include <netdev.h>
+#include <phy.h>
+#include <rtc.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/spr_defs.h>
+#include <asm/arch/spr_misc.h>
+#include <linux/mtd/fsmc_nand.h>
+#include "fpga.h"
+
+static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
+
+int board_init(void)
+{
+ /*
+ * X600 is equipped with an M41T82 RTC. This RTC has the
+ * HT bit (Halt Update), which needs to be cleared upon
+ * power-up. Otherwise the RTC is halted.
+ */
+ rtc_reset();
+
+ return spear_board_init(MACH_TYPE_SPEAR600);
+}
+
+int board_late_init(void)
+{
+ /*
+ * Monitor and env protection on by default
+ */
+ flash_protect(FLAG_PROTECT_SET,
+ CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE +
+ CONFIG_SYS_SPL_LEN + CONFIG_SYS_MONITOR_LEN +
+ 2 * CONFIG_ENV_SECT_SIZE - 1,
+ &flash_info[0]);
+
+ /* Init FPGA subsystem */
+ x600_init_fpga();
+
+ return 0;
+}
+
+/*
+ * board_nand_init - Board specific NAND initialization
+ * @nand: mtd private chip structure
+ *
+ * Called by nand_init_chip to initialize the board specific functions
+ */
+
+void board_nand_init(void)
+{
+ struct misc_regs *const misc_regs_p =
+ (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+ struct nand_chip *nand = &nand_chip[0];
+
+ if (!(readl(&misc_regs_p->auto_cfg_reg) & MISC_NANDDIS))
+ fsmc_nand_init(nand);
+}
+
+int designware_board_phy_init(struct eth_device *dev, int phy_addr,
+ int (*mii_write)(struct eth_device *, u8, u8, u16),
+ int dw_reset_phy(struct eth_device *))
+{
+ /* Extended PHY control 1, select GMII */
+ mii_write(dev, phy_addr, 23, 0x0020);
+
+ /* Software reset necessary after GMII mode selction */
+ dw_reset_phy(dev);
+
+ /* Enable extended page register access */
+ mii_write(dev, phy_addr, 31, 0x0001);
+
+ /* 17e: Enhanced LED behavior, needs to be written twice */
+ mii_write(dev, phy_addr, 17, 0x09ff);
+ mii_write(dev, phy_addr, 17, 0x09ff);
+
+ /* 16e: Enhanced LED method select */
+ mii_write(dev, phy_addr, 16, 0xe0ea);
+
+ /* Disable extended page register access */
+ mii_write(dev, phy_addr, 31, 0x0000);
+
+ /* Enable clock output pin */
+ mii_write(dev, phy_addr, 18, 0x0049);
+
+ return 0;
+}
+
+int board_eth_init(bd_t *bis)
+{
+ int ret = 0;
+
+ if (designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_PHY_ADDR,
+ PHY_INTERFACE_MODE_GMII) >= 0)
+ ret++;
+
+ return ret;
+}
diff --git a/boards.cfg b/boards.cfg
index 2a75880..89984d0 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -193,6 +193,7 @@ spear600 arm arm926ejs spear600 spear
spear600_nand arm arm926ejs spear600 spear spear spear6xx_evb:spear600,nand
spear600_usbtty arm arm926ejs spear600 spear spear spear6xx_evb:spear600,usbtty
spear600_usbtty_nand arm arm926ejs spear600 spear spear spear6xx_evb:spear600,usbtty,nand
+x600 arm arm926ejs - spear spear x600
versatileab arm arm926ejs versatile armltd versatile versatile:ARCH_VERSATILE_AB
versatilepb arm arm926ejs versatile armltd versatile versatile:ARCH_VERSATILE_PB
versatileqemu arm arm926ejs versatile armltd versatile versatile:ARCH_VERSATILE_QEMU,ARCH_VERSATILE_PB
diff --git a/include/configs/x600.h b/include/configs/x600.h
new file mode 100644
index 0000000..3082aaa
--- /dev/null
+++ b/include/configs/x600.h
@@ -0,0 +1,339 @@
+/*
+ * (C) Copyright 2009
+ * Vipin Kumar, STMicroelectronics, <vipin.kumar(a)st.com>
+ *
+ * Copyright (C) 2012 Stefan Roese <sr(a)denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_SPEAR600 /* SPEAr600 SoC */
+#define CONFIG_X600 /* on X600 board */
+
+#include <asm/arch/hardware.h>
+
+/* Timer, HZ specific defines */
+#define CONFIG_SYS_HZ 1000
+#define CONFIG_SYS_HZ_CLOCK 8300000
+
+#define CONFIG_SYS_TEXT_BASE 0x00800040
+#define CONFIG_SYS_FLASH_BASE 0xf8000000
+/* Reserve 8KiB for SPL */
+#define CONFIG_SPL_PAD_TO 8192 /* decimal for 'dd' */
+#define CONFIG_SYS_SPL_LEN CONFIG_SPL_PAD_TO
+#define CONFIG_SYS_UBOOT_BASE (CONFIG_SYS_FLASH_BASE + \
+ CONFIG_SYS_SPL_LEN)
+#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE
+#define CONFIG_SYS_MONITOR_LEN 0x60000
+
+#define CONFIG_ENV_IS_IN_FLASH
+
+/* Serial Configuration (PL011) */
+#define CONFIG_SYS_SERIAL0 0xD0000000
+#define CONFIG_SYS_SERIAL1 0xD0080000
+#define CONFIG_PL01x_PORTS { (void *)CONFIG_SYS_SERIAL0, \
+ (void *)CONFIG_SYS_SERIAL1 }
+#define CONFIG_PL011_SERIAL
+#define CONFIG_PL011_CLOCK (48 * 1000 * 1000)
+#define CONFIG_CONS_INDEX 0
+#define CONFIG_BAUDRATE 115200
+#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, \
+ 57600, 115200 }
+#define CONFIG_SYS_LOADS_BAUD_CHANGE
+
+/* NOR FLASH config options */
+#define CONFIG_ST_SMI
+#define CONFIG_SYS_MAX_FLASH_BANKS 1
+#define CONFIG_SYS_FLASH_BANK_SIZE 0x01000000
+#define CONFIG_SYS_FLASH_ADDR_BASE { CONFIG_SYS_FLASH_BASE }
+#define CONFIG_SYS_MAX_FLASH_SECT 128
+#define CONFIG_SYS_FLASH_EMPTY_INFO
+#define CONFIG_SYS_FLASH_ERASE_TOUT (3 * CONFIG_SYS_HZ)
+#define CONFIG_SYS_FLASH_WRITE_TOUT (3 * CONFIG_SYS_HZ)
+
+/* NAND FLASH config options */
+#define CONFIG_NAND_FSMC
+#define CONFIG_SYS_NAND_SELF_INIT
+#define CONFIG_SYS_MAX_NAND_DEVICE 1
+#define CONFIG_SYS_NAND_BASE CONFIG_FSMC_NAND_BASE
+#define CONFIG_MTD_ECC_SOFT
+#define CONFIG_SYS_FSMC_NAND_8BIT
+#define CONFIG_SYS_NAND_ONFI_DETECTION
+
+/* UBI/UBI config options */
+#define CONFIG_MTD_DEVICE
+#define CONFIG_MTD_PARTITIONS
+#define CONFIG_RBTREE
+
+/* Ethernet config options */
+#define CONFIG_MII
+#define CONFIG_DESIGNWARE_ETH
+#define CONFIG_DW_SEARCH_PHY
+#define CONFIG_NET_MULTI
+#define CONFIG_PHY_RESET_DELAY 10000 /* in usec */
+#define CONFIG_DW_AUTONEG
+#define CONFIG_PHY_ADDR 0 /* PHY address */
+#define CONFIG_PHY_GIGE /* Include GbE speed/duplex detection */
+
+#define CONFIG_SPEAR_GPIO
+
+/* I2C config options */
+#define CONFIG_HARD_I2C
+#define CONFIG_DW_I2C
+#define CONFIG_SYS_I2C_SPEED 400000
+#define CONFIG_SYS_I2C_SLAVE 0x02
+#define CONFIG_I2C_CHIPADDRESS 0x50
+
+#define CONFIG_RTC_M41T62 1
+#define CONFIG_SYS_I2C_RTC_ADDR 0x68
+
+/* FPGA config options */
+#define CONFIG_FPGA
+#define CONFIG_FPGA_XILINX
+#define CONFIG_FPGA_SPARTAN3
+#define CONFIG_FPGA_COUNT 1
+
+/*
+ * Command support defines
+ */
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_DATE
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_FPGA
+#define CONFIG_CMD_GPIO
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_MEMORY
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_CMD_NAND
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_RUN
+#define CONFIG_CMD_SAVES
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_UBIFS
+#define CONFIG_LZO
+
+/* This must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <config_cmd_default.h>
+
+#define CONFIG_BOOTDELAY 3
+
+#define CONFIG_SYS_HUSH_PARSER /* Use the HUSH parser */
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+
+/*
+ * U-Boot Environment placing definitions.
+ */
+#define CONFIG_ENV_SECT_SIZE 0x00010000
+#define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE + \
+ CONFIG_SYS_MONITOR_LEN)
+#define CONFIG_ENV_SIZE 0x02000
+#define CONFIG_ENV_ADDR_REDUND (CONFIG_ENV_ADDR + \
+ CONFIG_ENV_SECT_SIZE)
+#define CONFIG_ENV_SIZE_REDUND (CONFIG_ENV_SIZE)
+
+/* Miscellaneous configurable options */
+#define CONFIG_ARCH_CPU_INIT
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_BOOT_PARAMS_ADDR 0x00000100
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_OF_LIBFDT /* enable passing of devicetree */
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_MISC_INIT_R
+#define CONFIG_BOARD_LATE_INIT
+#define CONFIG_LOOPW /* enable loopw command */
+#define CONFIG_MX_CYCLIC /* enable mdc/mwc commands */
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+#define CONFIG_AUTOBOOT_KEYED
+#define CONFIG_AUTOBOOT_STOP_STR " "
+#define CONFIG_AUTOBOOT_PROMPT \
+ "Hit SPACE in %d seconds to stop autoboot.\n", bootdelay
+
+#define CONFIG_SYS_MEMTEST_START 0x00800000
+#define CONFIG_SYS_MEMTEST_END 0x04000000
+#define CONFIG_SYS_MALLOC_LEN (1024 * 1024)
+#define CONFIG_IDENT_STRING "-SPEAr"
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_PROMPT "X600> "
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_SYS_CBSIZE 256
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
+ sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS 16
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+#define CONFIG_SYS_LOAD_ADDR 0x00800000
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+#define CONFIG_SYS_64BIT_VSPRINTF
+
+/* Use last 2 lwords in internal SRAM for bootcounter */
+#define CONFIG_BOOTCOUNT_LIMIT
+#define CONFIG_SYS_BOOTCOUNT_ADDR 0xd2801ff8
+
+#define CONFIG_HOSTNAME x600
+#define CONFIG_UBI_PART ubi0
+#define CONFIG_UBIFS_VOLUME rootfs
+
+#define xstr(s) str(s)
+#define str(s) #s
+
+#define MTDIDS_DEFAULT "nand0=nand"
+#define MTDPARTS_DEFAULT "mtdparts=nand:64M(ubi0),64M(ubi1)"
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "u-boot_addr=1000000\0" \
+ "u-boot=" xstr(CONFIG_HOSTNAME) "/u-boot.spr\0" \
+ "load=tftp ${u-boot_addr} ${u-boot}\0" \
+ "update=protect off " xstr(CONFIG_SYS_MONITOR_BASE) " +${filesize};"\
+ "erase " xstr(CONFIG_SYS_MONITOR_BASE) " +${filesize};" \
+ "cp.b ${u-boot_addr} " xstr(CONFIG_SYS_MONITOR_BASE) \
+ " ${filesize};" \
+ "protect on " xstr(CONFIG_SYS_MONITOR_BASE) \
+ " +${filesize}\0" \
+ "upd=run load update\0" \
+ "ubifs=" xstr(CONFIG_HOSTNAME) "/ubifs.img\0" \
+ "part=" xstr(CONFIG_UBI_PART) "\0" \
+ "vol=" xstr(CONFIG_UBIFS_VOLUME) "\0" \
+ "load_ubifs=tftp ${kernel_addr} ${ubifs}\0" \
+ "update_ubifs=ubi part ${part};ubi write ${kernel_addr} ${vol}" \
+ " ${filesize}\0" \
+ "upd_ubifs=run load_ubifs update_ubifs\0" \
+ "init_ubifs=nand erase.part ubi0;ubi part ${part};" \
+ "ubi create ${vol} 4000000\0" \
+ "netdev=eth0\0" \
+ "rootpath=/opt/eldk-4.2/arm\0" \
+ "nfsargs=setenv bootargs root=/dev/nfs rw " \
+ "nfsroot=${serverip}:${rootpath}\0" \
+ "ramargs=setenv bootargs root=/dev/ram rw\0" \
+ "boot_part=0\0" \
+ "altbootcmd=if test $boot_part -eq 0;then " \
+ "echo Switching to partition 1!;" \
+ "setenv boot_part 1;" \
+ "else; " \
+ "echo Switching to partition 0!;" \
+ "setenv boot_part 0;" \
+ "fi;" \
+ "saveenv;boot\0" \
+ "ubifsargs=set bootargs ubi.mtd=ubi${boot_part} " \
+ "root=ubi0:rootfs rootfstype=ubifs\0" \
+ "kernel=" xstr(CONFIG_HOSTNAME) "/uImage\0" \
+ "kernel_fs=/boot/uImage \0" \
+ "kernel_addr=1000000\0" \
+ "dtb=" xstr(CONFIG_HOSTNAME) "/" xstr(CONFIG_HOSTNAME) ".dtb\0" \
+ "dtb_fs=/boot/" xstr(CONFIG_HOSTNAME) ".dtb\0" \
+ "dtb_addr=1800000\0" \
+ "load_kernel=tftp ${kernel_addr} ${kernel}\0" \
+ "load_dtb=tftp ${dtb_addr} ${dtb}\0" \
+ "addip=setenv bootargs ${bootargs} " \
+ "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}" \
+ ":${hostname}:${netdev}:off panic=1\0" \
+ "addcon=setenv bootargs ${bootargs} console=ttyAMA0," \
+ "${baudrate}\0" \
+ "addmtd=setenv bootargs ${bootargs} ${mtdparts}\0" \
+ "net_nfs=run load_dtb load_kernel; " \
+ "run nfsargs addip addcon addmtd addmisc;" \
+ "bootm ${kernel_addr} - ${dtb_addr}\0" \
+ "mtdids=" MTDIDS_DEFAULT "\0" \
+ "mtdparts=" MTDPARTS_DEFAULT "\0" \
+ "nand_ubifs=run ubifs_mount ubifs_load ubifsargs addip" \
+ " addcon addmisc addmtd;" \
+ "bootm ${kernel_addr} - ${dtb_addr}\0" \
+ "ubifs_mount=ubi part ubi${boot_part};ubifsmount rootfs\0" \
+ "ubifs_load=ubifsload ${kernel_addr} ${kernel_fs};" \
+ "ubifsload ${dtb_addr} ${dtb_fs};\0" \
+ "nand_ubifs=run ubifs_mount ubifs_load ubifsargs addip addcon " \
+ "addmtd addmisc;bootm ${kernel_addr} - ${dtb_addr}\0" \
+ "bootcmd=run nand_ubifs\0" \
+ "\0"
+
+/* Stack sizes */
+#define CONFIG_STACKSIZE (512 * 1024)
+
+/* Physical Memory Map */
+#define CONFIG_NR_DRAM_BANKS 1
+#define PHYS_SDRAM_1 0x00000000
+#define PHYS_SDRAM_1_MAXSIZE 0x40000000
+
+#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_RAM_ADDR 0xD2800000
+#define CONFIG_SYS_INIT_RAM_SIZE 0x2000
+
+#define CONFIG_SYS_INIT_SP_OFFSET \
+ (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
+
+#define CONFIG_SYS_INIT_SP_ADDR \
+ (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
+
+/*
+ * SPL related defines
+ */
+#define CONFIG_SPL
+#define CONFIG_SPL_TEXT_BASE 0xd2800b00
+#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/arm926ejs/spear"
+#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds"
+
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_LIBCOMMON_SUPPORT /* image.c */
+#define CONFIG_SPL_LIBGENERIC_SUPPORT /* string.c */
+#define CONFIG_SPL_NO_PRINTF
+
+/*
+ * Please select/define only one of the following
+ * Each definition corresponds to a supported DDR chip.
+ * DDR configuration is based on the following selection
+ */
+#define CONFIG_DDR_MT47H64M16 1
+#define CONFIG_DDR_MT47H32M16 0
+#define CONFIG_DDR_MT47H128M8 0
+
+/*
+ * Synchronous/Asynchronous operation of DDR
+ *
+ * Select CONFIG_DDR_2HCLK for DDR clk = 333MHz, synchronous operation
+ * Select CONFIG_DDR_HCLK for DDR clk = 166MHz, synchronous operation
+ * Select CONFIG_DDR_PLL2 for DDR clk = PLL2, asynchronous operation
+ */
+#define CONFIG_DDR_2HCLK 1
+#define CONFIG_DDR_HCLK 0
+#define CONFIG_DDR_PLL2 0
+
+/*
+ * xxx_BOOT_SUPPORTED macro defines whether a booting type is supported
+ * or not. Modify/Add to only these macros to define new boot types
+ */
+#define USB_BOOT_SUPPORTED 0
+#define PCIE_BOOT_SUPPORTED 0
+#define SNOR_BOOT_SUPPORTED 1
+#define NAND_BOOT_SUPPORTED 1
+#define PNOR_BOOT_SUPPORTED 0
+#define TFTP_BOOT_SUPPORTED 0
+#define UART_BOOT_SUPPORTED 0
+#define SPI_BOOT_SUPPORTED 0
+#define I2C_BOOT_SUPPORTED 0
+#define MMC_BOOT_SUPPORTED 0
+
+#endif /* __CONFIG_H */
--
1.7.10.3
4
5
>From the last time, I removed the patch about the PLL initialization because
it's board specific. I added a new patch for s3c440 gpio driver. Now in the
board file we have no more magic bloat.
>> +/*
>> + * When booting from NAND, it is impossible to access the lowest addresses
>> + * due to the SteppingStone being in the way. Luckily the NOR doesn't really
>> + * care about the highest 16 bits of address, so we set the controlers
>> + * registers to go and poke over there, instead.
>> + */
>> +#define PHYS_FLASH_1 0x0
>> +#define CONFIG_SYS_FLASH_BASE 0x0
>
>Urghh... this sounds very much like a serious design issue?
About this point, I ported it from the old version uboot as well. It may need
some investigation, but I remember it was a big problem with this board. In the
case of a NAND boot, we don't have access to NOR because the SteppingStone
(SRAM) is mapped at the same range.
Gabriel Huau (2):
Add GPIO Driver and IOMUX definition for S3C2440
Add support for MINI2440 (s3c2440).
MAINTAINERS | 4 +
arch/arm/include/asm/arch-s3c24x0/gpio.h | 183 +++++++++++++++++++++++++
arch/arm/include/asm/arch-s3c24x0/iomux.h | 197 +++++++++++++++++++++++++++
board/friendlyarm/mini2440/Makefile | 44 ++++++
board/friendlyarm/mini2440/mini2440.c | 135 +++++++++++++++++++
board/friendlyarm/mini2440/mini2440.h | 144 ++++++++++++++++++++
boards.cfg | 1 +
doc/README.mini2440 | 28 ++++
drivers/gpio/Makefile | 1 +
drivers/gpio/s3c2440_gpio.c | 74 ++++++++++
include/configs/mini2440.h | 209 +++++++++++++++++++++++++++++
11 files changed, 1020 insertions(+)
create mode 100644 arch/arm/include/asm/arch-s3c24x0/gpio.h
create mode 100644 arch/arm/include/asm/arch-s3c24x0/iomux.h
create mode 100644 board/friendlyarm/mini2440/Makefile
create mode 100644 board/friendlyarm/mini2440/mini2440.c
create mode 100644 board/friendlyarm/mini2440/mini2440.h
create mode 100644 doc/README.mini2440
create mode 100644 drivers/gpio/s3c2440_gpio.c
create mode 100644 include/configs/mini2440.h
--
1.7.9.5
6
48

[U-Boot] [PATCH 5/5] msm7x30: Add support for msm7630_surf board
by mohamed.haneefï¼ lntinfotech.com 03 Oct '12
by mohamed.haneefï¼ lntinfotech.com 03 Oct '12
03 Oct '12
From: Mohamed Haneef <mohamed.haneef(a)lntinfotech.com>
*Support for msm7630_surf board
Signed-off-by: Mohamed Haneef <mohamed.haneef(a)lntinfotech.com>
---
board/qcom/msm7630_surf/Makefile | 55 +++++++++++
board/qcom/msm7630_surf/msm7630_surf.c | 155 ++++++++++++++++++++++++++++++++
board/qcom/msm7630_surf/msm7630_surf.h | 30 ++++++
boards.cfg | 1 +
include/configs/msm7630_surf.h | 131 +++++++++++++++++++++++++++
5 files changed, 372 insertions(+), 0 deletions(-)
create mode 100644 board/qcom/msm7630_surf/Makefile
create mode 100644 board/qcom/msm7630_surf/msm7630_surf.c
create mode 100644 board/qcom/msm7630_surf/msm7630_surf.h
create mode 100644 include/configs/msm7630_surf.h
diff --git a/board/qcom/msm7630_surf/Makefile b/board/qcom/msm7630_surf/Makefile
new file mode 100644
index 0000000..f9dec32
--- /dev/null
+++ b/board/qcom/msm7630_surf/Makefile
@@ -0,0 +1,55 @@
+#
+# (C) Copyright 2012
+# LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+#
+# (C) Copyright 2010,2011
+# NVIDIA Corporation <www.nvidia.com>
+#
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)../../qcom/msm7630_surf/)
+endif
+
+LIB = $(obj)lib$(BOARD).o
+
+COBJS := $(BOARD).o
+SRCS := $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+
+$(LIB): $(obj).depend $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+clean:
+ rm -f $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/qcom/msm7630_surf/msm7630_surf.c b/board/qcom/msm7630_surf/msm7630_surf.c
new file mode 100644
index 0000000..eb941c7
--- /dev/null
+++ b/board/qcom/msm7630_surf/msm7630_surf.c
@@ -0,0 +1,155 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <asm/arch/iomap.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/gpio.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <asm/arch/mmc.h>
+#include <linux/string.h>
+#include <asm/mach-types.h>
+#include <asm/arch/proc_comm.h>
+#include "msm7630_surf.h"
+
+static struct msm_gpio uart2_gpio_table[] = {
+ {
+ .gpio_cfg = GPIO_CFG(49, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA),
+ .label = NULL,
+ },
+ {
+ .gpio_cfg = GPIO_CFG(50, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA),
+ .label = NULL,
+ },
+ {
+ .gpio_cfg = GPIO_CFG(51, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA),
+ .label = NULL,
+ },
+ {
+ .gpio_cfg = GPIO_CFG(52, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA),
+ .label = NULL,
+ },
+};
+
+
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void uart2_mux_init(void)
+{
+ platform_gpios_enable(uart2_gpio_table, ARRAY_SIZE(uart2_gpio_table));
+}
+
+#ifdef CONFIG_BOARD_EARLY_INIT_F
+int board_early_init_f()
+{
+ uart2_mux_init();
+ uart2_clock_init();
+ return 0;
+}
+#endif
+int board_init()
+{
+ unsigned long new_addr;
+ unsigned long offset;
+ offset = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
+ new_addr = CONFIG_SYS_TEXT_BASE + offset;
+ set_vector_base(new_addr);
+ bd_t *bd = gd->bd;
+ bd->bi_arch_number = MACH_TYPE_MSM7X30_SURF;
+ acpu_clock_init();
+ adm_enable_clock();
+ return 0;
+}
+
+#ifdef CONFIG_QC_MMC
+
+/* called during the scan of each mmc device */
+int qc_board_mmc_init(struct mmc *mmc)
+{
+
+ struct mmc_priv *sd = (struct mmc_priv *)mmc->priv;
+ u32 smem_val;
+ do {
+ smem_val = 0;
+ smem_val = readl(MSM_SHARED_BASE + 0x14);
+ } while (smem_val != 1);
+
+ if (sd->instance == 2 || sd->instance == 4) {
+ mmc_boot_main(mmc);
+ return 0;
+ } else
+ /* this board does not have an sd/mmc card on this interface. */
+ return 1;
+ }
+int board_mmc_init(bd_t *bis)
+{
+#ifdef QC_SD
+ struct mmc *mmc_4;
+ struct mmc_priv *sdcc_4;
+ mmc_4 = (struct mmc *) malloc(sizeof(struct mmc));
+ if (!mmc_4)
+ return 1;
+ sdcc_4 = (struct mmc_priv *) malloc(sizeof(struct mmc_priv));
+ if (!sdcc_4) {
+ free(mmc_4);
+ return 1;
+ }
+ sdcc_4->instance = 4;
+ sdcc_4->base = MSM_SDC4_BASE;
+ mmc_4->priv = sdcc_4;
+ mmc_4->send_cmd = mmc_boot_send_command_map;
+ mmc_4->set_ios = mmc_boot_set_ios;
+ mmc_4->init = qc_board_mmc_init;
+ mmc_4->voltages = MMC_VDD_29_30|MMC_VDD_165_195;
+ mmc_4->host_caps = MMC_MODE_4BIT|MMC_MODE_HS;
+ mmc_4->f_min = MMC_CLK_400KHZ;
+ mmc_4->f_max = MMC_CLK_48MHZ;
+ sprintf(mmc_4->name, "External_Card");
+ mmc_register(mmc_4);
+#else
+ struct mmc *mmc_2;
+ struct mmc_priv *sdcc_2;
+ mmc_2 = (struct mmc *) malloc(sizeof(struct mmc));
+ if (!mmc_2)
+ return 1;
+ sdcc_2 = (struct mmc_priv *) malloc(sizeof(struct mmc_priv));
+ if (!sdcc_2) {
+ free(mmc_2);
+ return 1;
+ }
+ sdcc_2->instance = 2;
+ sdcc_2->base = MSM_SDC2_BASE;
+ mmc_2->priv = sdcc_2;
+ mmc_2->send_cmd = mmc_boot_send_command_map;
+ mmc_2->set_ios = mmc_boot_set_ios;
+ mmc_2->init = qc_board_mmc_init;
+ mmc_2->voltages = MMC_VDD_29_30|MMC_VDD_165_195;
+ mmc_2->host_caps = MMC_MODE_4BIT|MMC_MODE_HS|MMC_MODE_8BIT|
+ MMC_MODE_HS_52MHz;
+ mmc_2->f_min = MMC_CLK_400KHZ;
+ mmc_2->f_max = MMC_CLK_48MHZ;
+ sprintf(mmc_2->name, "Internal_Card");
+ mmc_register(mmc_2);
+#endif
+ return 0;
+}
+#endif
diff --git a/board/qcom/msm7630_surf/msm7630_surf.h b/board/qcom/msm7630_surf/msm7630_surf.h
new file mode 100644
index 0000000..a3d4bde
--- /dev/null
+++ b/board/qcom/msm7630_surf/msm7630_surf.h
@@ -0,0 +1,30 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __MSM7630_SURF_H_
+#define __MSM7630_SURF_H_
+#include <asm/arch/gpio_hw.h>
+
+extern void set_vector_base(unsigned long);
+extern void adm_enable_clock(void);
+extern void acpu_clock_init(void);
+extern void uart2_clock_init(void);
+extern int platform_gpios_enable(const struct msm_gpio *table, int size);
+#endif
diff --git a/boards.cfg b/boards.cfg
index bf71a66..4ab9330 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -190,6 +190,7 @@ integratorcp_cm946es arm arm946es integrator armltd
ca9x4_ct_vxp arm armv7 vexpress armltd
am335x_evm arm armv7 am335x ti am33xx
highbank arm armv7 highbank - highbank
+msm7630_surf arm armv7 msm7630_surf qcom msm7630
efikamx arm armv7 efikamx - mx5 efikamx:MACH_TYPE=MACH_TYPE_MX51_EFIKAMX,IMX_CONFIG=board/efikamx/imximage_mx.cfg
efikasb arm armv7 efikamx - mx5 efikamx:MACH_TYPE=MACH_TYPE_MX51_EFIKASB,IMX_CONFIG=board/efikamx/imximage_sb.cfg
mx51evk arm armv7 mx51evk freescale mx5 mx51evk:IMX_CONFIG=board/freescale/mx51evk/imximage.cfg
diff --git a/include/configs/msm7630_surf.h b/include/configs/msm7630_surf.h
new file mode 100644
index 0000000..3356611
--- /dev/null
+++ b/include/configs/msm7630_surf.h
@@ -0,0 +1,131 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <asm/sizes.h>
+#define PLATFORM_MSM7X30 1
+#define CONFIG_MSM_UART
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_L2_OFF
+#define CONFIG_SKIP_LOWLEVEL_INIT
+/* Environment */
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE 0x20000 /* Total Size Environment */
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_MSM_PCOMM
+#define CONFIG_ARCH_CPU_INIT
+/*
+ * Size of malloc() pool
+ */
+#define CONFIG_SYS_MALLOC_LEN (4 * 1024) /* 4KB */
+#define CONFIG_MSM7630
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_CONS_INDEX 1
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_BAUDRATE 115200
+#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\
+ 115200}
+
+#include <config_cmd_default.h>
+
+/* remove unused commands */
+#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */
+#undef CONFIG_CMD_FPGA /* FPGA configuration support */
+#undef CONFIG_CMD_IMI
+#undef CONFIG_CMD_IMLS
+#undef CONFIG_CMD_NFS /* NFS support */
+#undef CONFIG_CMD_NET /* network support */
+#undef CONFIG_SYS_MAX_FLASH_SECT
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "console=ttyS0,115200n8\0" \
+
+#define CONFIG_BOOTDELAY 2 /* -1 to disable auto boot */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP /* undef to save memory */
+#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+#define V_PROMPT "(MSM 7x30) # "
+#define CONFIG_SYS_PROMPT V_PROMPT
+/*
+ * Increasing the size of the IO buffer as default nfsargs size is more
+ * than 256 and so it is not possible to edit it
+ */
+#define CONFIG_SYS_CBSIZE (256 * 2) /* Console I/O Buffer Size */
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
+ sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
+/* Boot Argument Buffer Size */
+#define CONFIG_SYS_BARGSIZE (CONFIG_SYS_CBSIZE)
+
+#define CONFIG_SYS_HZ 1000
+#define CONFIG_SYS_LOAD_ADDR 0x00208000
+#define CONFIG_SYS_MEMTEST_START 0x08008000
+#define CONFIG_SYS_MEMTEST_END 0x08008001
+
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MMC
+#define CONFIG_CMD_MMC
+
+#define CONFIG_GENERIC_MMC
+#define CONFIG_QC_MMC
+
+/*---------------------------------------------------------------------
+ * IRQ Settings
+ */
+
+#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
+
+/*-----------------------------------------------------------------------
+ * Physical Memory Map
+ */
+
+
+#define CONFIG_NR_DRAM_BANKS 2
+
+#define PHYS_SDRAM_1 0x00200000
+#define PHYS_SDRAM_1_SIZE (60*1024*1024) /* 512M */
+
+
+#define PHYS_SDRAM_2 0x07A00000
+#define PHYS_SDRAM_2_SIZE (134*1024*1024)
+
+#define CONFIG_SYS_TEXT_BASE 0x00000000
+#define CONFIG_SYS_INIT_RAM_ADDR 0x00000000
+#define CONFIG_SYS_INIT_RAM_SIZE 0x00100000
+
+
+#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \
+ CONFIG_SYS_INIT_RAM_SIZE - \
+ GENERATED_GBL_DATA_SIZE)
+
+#endif
--
1.7.1
The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
2
1

03 Oct '12
Signed-off-by: Stefan Kristiansson <stefan.kristiansson(a)saunalahti.fi>
---
arch/openrisc/include/asm/bitops.h | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/arch/openrisc/include/asm/bitops.h b/arch/openrisc/include/asm/bitops.h
index c001a5d..c76a409 100644
--- a/arch/openrisc/include/asm/bitops.h
+++ b/arch/openrisc/include/asm/bitops.h
@@ -25,4 +25,8 @@
#define PLATFORM_FFS
#include <asm/bitops/ffs.h>
+#define hweight32(x) generic_hweight32(x)
+#define hweight16(x) generic_hweight16(x)
+#define hweight8(x) generic_hweight8(x)
+
#endif /* __ASM_GENERIC_BITOPS_H */
--
1.7.5.4
5
8

29 Sep '12
From: Lei Wen <leiwen(a)marvell.com>
This patch set add zip command support for uboot.
The first two patches import deflate and trees functions from zlib 1.2.5
without any change. While the third patch did the necessary change to
make the import file could be built passed in uboot environment.
The fourth patch make us could zip the memory from 0 in the address space.
The latter fifth and sixth patch does the adding gzip lib function exporting
and zip command support.
Patch set test with zip&unzip and compared with original memory content.
Lei Wen (6):
lib: zlib: import deflate source file from 1.2.5
lib: zlib: import trees file from 1.2.5
lib: zlib: include deflate into zlib build
lib: zlib: remove the limitation for cannot using 0 as start
lib: add gzip lib function callback
common: add zip command support
common/Makefile | 1 +
common/cmd_zip.c | 60 ++
include/common.h | 7 +
include/u-boot/zlib.h | 40 +-
lib/Makefile | 1 +
lib/gzip.c | 143 ++++
lib/zlib/deflate.c | 1831 +++++++++++++++++++++++++++++++++++++++++++++++++
lib/zlib/deflate.h | 342 +++++++++
lib/zlib/trees.c | 1244 +++++++++++++++++++++++++++++++++
lib/zlib/trees.h | 128 ++++
lib/zlib/zlib.c | 8 +
lib/zlib/zutil.h | 4 +
12 files changed, 3804 insertions(+), 5 deletions(-)
create mode 100644 common/cmd_zip.c
create mode 100644 lib/gzip.c
create mode 100644 lib/zlib/deflate.c
create mode 100644 lib/zlib/deflate.h
create mode 100644 lib/zlib/trees.c
create mode 100644 lib/zlib/trees.h
--
1.7.5.4
8
40
Hi Stefan,
I address this question to you because one of your commits is connected to this
problem, but other hints from other readers are also welcome ;-) .
We have a kirkwood based board with a micron NAND flash. We have one ubi device
created on the NAND flash and inside the device we have one ubi volume were we
store our linux kernel. At startup we attach to the ubi device, to be able to
readout the kernel image. On our old u-boot branch which based on v2009.08 we
hadn't any problems. Now after upgrading to the newest u-boot version we saw in
some rarely cases our u-boot get stuck when we try to attach:
=> ubi part ubi0
Creating 1 MTD partitions on "nand0":
0x000000000000-0x000008000000 : "mtd=0"
UBI: attaching mtd1 to ubi0
UBI: physical eraseblock size: 131072 bytes (128 KiB)
UBI: logical eraseblock size: 129024 bytes
UBI: smallest flash I/O unit: 2048
UBI: sub-page size: 512
UBI: VID header offset: 512 (aligned 512)
UBI: data offset: 2048
UBI: fixable bit-flip detected at PEB 71
And after this u-boot gets stuck until the end of days and we have to force a
reboot, but the u-boot gets stuck again.
If I revert your commit:
commit 1b1f9a9d00447d9eab32ae5633f60a106196b75f
Author: Stefan Roese <sr(a)denx.de>
Date: Mon May 17 10:00:51 2010 +0200
UBI: Ensure that "background thread" operations are really executed
the u-boot don't get stuck:
=> ubi part ubi0
Creating 1 MTD partitions on "nand0":
0x000000000000-0x000008000000 : "mtd=0"
UBI: attaching mtd1 to ubi0
UBI: physical eraseblock size: 131072 bytes (128 KiB)
UBI: logical eraseblock size: 129024 bytes
UBI: smallest flash I/O unit: 2048
UBI: sub-page size: 512
UBI: VID header offset: 512 (aligned 512)
UBI: data offset: 2048
UBI: fixable bit-flip detected at PEB 71
UBI: attached mtd1 to ubi0
UBI: MTD device name: "mtd=0"
UBI: MTD device size: 128 MiB
UBI: number of good PEBs: 1024
UBI: number of bad PEBs: 0
UBI: max. allowed volumes: 128
UBI: wear-leveling threshold: 4096
UBI: number of internal volumes: 1
UBI: number of user volumes: 9
UBI: available PEBs: 623
UBI: total number of reserved PEBs: 401
UBI: number of PEBs reserved for bad PEB handling: 10
UBI: max/mean erase counter: 8193/3082
=>
This is the reason why our old u-boot works, because the background thread seems
to be not or not completely executed...
If I boot a recent linux kernel the kernel also reports an "fixable bit-flip
detected at PEB 71" but linux is able to really fix this bit flip and is able to
work as expceted, even u-boot is afterwards bootable because the bitflip is
corrected and gone.
Now I could revert your commit in my local branch and then it seems to work, but
I think this is not a good solution because I expect that the real error is
somewhere in the UBI layer in u-boot and already fixed in current linux. AFAIK
the ubi layer was initially copied from linux, but it seems that the bugfixes
are not backported in the last years. Any thoughts or ideas?
Best regards
Holger
3
10
From: Uma Shankar <uma.shankar(a)samsung.com>
Signed-off-by: Uma Shankar <uma.shankar(a)samsung.com>
Signed-off-by: Manjunatha C Achar <a.manjunatha(a)samsung.com>
Signed-off-by: Iqbal Shareef <iqbal.ams(a)samsung.com>
Signed-off-by: Hakgoo Lee <goodguy.lee(a)samsung.com>
---
Makefile | 2 +-
common/Makefile | 1 +
common/cmd_ext2.c | 1 +
common/cmd_ext4.c | 253 ++++++++++++++++++++++
fs/Makefile | 1 +
fs/ext2/dev.c | 1 +
fs/ext2/ext2fs.c | 340 +++---------------------------
fs/ext4/Makefile | 51 +++++
fs/ext4/ext4_common.c | 573 +++++++++++++++++++++++++++++++++++++++++++++++++
fs/ext4/ext4_common.h | 44 ++++
fs/ext4/ext4fs.c | 215 ++++++++++++++++++
include/ext2fs.h | 16 +-
include/ext4fs.h | 116 ++++++++++
include/ext_common.h | 199 +++++++++++++++++
14 files changed, 1489 insertions(+), 324 deletions(-)
create mode 100644 common/cmd_ext4.c
create mode 100644 fs/ext4/Makefile
create mode 100644 fs/ext4/ext4_common.c
create mode 100644 fs/ext4/ext4_common.h
create mode 100644 fs/ext4/ext4fs.c
create mode 100644 include/ext4fs.h
create mode 100644 include/ext_common.h
diff --git a/Makefile b/Makefile
index 5de7915..20cb941 100644
--- a/Makefile
+++ b/Makefile
@@ -235,7 +235,7 @@ LIBS += dts/libdts.o
endif
LIBS += arch/$(ARCH)/lib/lib$(ARCH).o
LIBS += fs/cramfs/libcramfs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o \
- fs/reiserfs/libreiserfs.o fs/ext2/libext2fs.o fs/yaffs2/libyaffs2.o \
+ fs/reiserfs/libreiserfs.o fs/ext2/libext2fs.o fs/ext4/libext4fs.o fs/yaffs2/libyaffs2.o \
fs/ubifs/libubifs.o
LIBS += net/libnet.o
LIBS += disk/libdisk.o
diff --git a/common/Makefile b/common/Makefile
index 2d9ae8c..d99cc31 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -87,6 +87,7 @@ COBJS-$(CONFIG_CMD_EEPROM) += cmd_eeprom.o
COBJS-$(CONFIG_CMD_ELF) += cmd_elf.o
COBJS-$(CONFIG_SYS_HUSH_PARSER) += cmd_exit.o
COBJS-$(CONFIG_CMD_EXT2) += cmd_ext2.o
+COBJS-$(CONFIG_CMD_EXT4) += cmd_ext4.o
COBJS-$(CONFIG_CMD_FAT) += cmd_fat.o
COBJS-$(CONFIG_CMD_FDC)$(CONFIG_CMD_FDOS) += cmd_fdc.o
COBJS-$(CONFIG_OF_LIBFDT) += cmd_fdt.o fdt_support.o
diff --git a/common/cmd_ext2.c b/common/cmd_ext2.c
index 35fb361..3ccc47e 100644
--- a/common/cmd_ext2.c
+++ b/common/cmd_ext2.c
@@ -40,6 +40,7 @@
#include <linux/ctype.h>
#include <asm/byteorder.h>
#include <ext2fs.h>
+#include <ext_common.h>
#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
#include <usb.h>
#endif
diff --git a/common/cmd_ext4.c b/common/cmd_ext4.c
new file mode 100644
index 0000000..7c2d541
--- /dev/null
+++ b/common/cmd_ext4.c
@@ -0,0 +1,253 @@
+/*
+ * (C) Copyright 2011 Samsung Electronics
+ * EXT4 filesystem implementation in Uboot by
+ * Uma Shankar <uma.shankar(a)samsung.com>
+ * Manjunatha C Achar <a.manjunatha(a)samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+/*
+ * Ext4fs support
+ * made from existing cmd_ext2.c file of Uboot
+ */
+#include <common.h>
+#include <part.h>
+#include <config.h>
+#include <command.h>
+#include <image.h>
+#include <linux/ctype.h>
+#include <asm/byteorder.h>
+#include <ext_common.h>
+#include <ext4fs.h>
+#include <linux/stat.h>
+#include <malloc.h>
+
+#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
+#include <usb.h>
+#endif
+
+#if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION)
+#error DOS or EFI partition support must be selected
+#endif
+
+uint64_t total_sector;
+uint64_t part_offset;
+
+#define DOS_PART_MAGIC_OFFSET 0x1fe
+#define DOS_FS_TYPE_OFFSET 0x36
+#define DOS_FS32_TYPE_OFFSET 0x52
+
+int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ char *filename = NULL;
+ char *ep;
+ int dev;
+ unsigned long part = 1;
+ ulong addr = 0, part_length;
+ int filelen;
+ disk_partition_t info;
+ struct ext_filesystem *fs;
+ char buf[12];
+ unsigned long count;
+ const char *addr_str;
+
+ switch (argc) {
+ case 3:
+ addr_str = getenv("loadaddr");
+ if (addr_str != NULL)
+ strict_strtoul(addr_str, 16, &addr);
+ else
+ addr = CONFIG_SYS_LOAD_ADDR;
+
+ filename = getenv("bootfile");
+ count = 0;
+ break;
+ case 4:
+ strict_strtoul(argv[3], 16, &addr);
+ filename = getenv("bootfile");
+ count = 0;
+ break;
+ case 5:
+ strict_strtoul(argv[3], 16, &addr);
+ filename = argv[4];
+ count = 0;
+ break;
+ case 6:
+ strict_strtoul(argv[3], 16, &addr);
+ filename = argv[4];
+ strict_strtoul(argv[5], 16, &count);
+ break;
+
+ default:
+ return cmd_usage(cmdtp);
+ }
+
+ if (!filename) {
+ puts("** No boot file defined **\n");
+ return 1;
+ }
+
+ dev = (int)simple_strtoul(argv[2], &ep, 16);
+ ext4_dev_desc = get_dev(argv[1], dev);
+ if (ext4_dev_desc == NULL) {
+ printf("** Block device %s %d not supported\n", argv[1], dev);
+ return 1;
+ }
+ if (init_fs(ext4_dev_desc))
+ return 1;
+
+ fs = get_fs();
+ if (*ep) {
+ if (*ep != ':') {
+ puts("** Invalid boot device, use `dev[:part]' **\n");
+ return 1;
+ }
+ (int)strict_strtoul(++ep, 16, &part);
+ }
+
+ if (part != 0) {
+ if (get_partition_info(fs->dev_desc, part, &info)) {
+ printf("** Bad partition %lu **\n", part);
+ return 1;
+ }
+
+ if (strncmp((char *)info.type, BOOT_PART_TYPE,
+ sizeof(info.type)) != 0) {
+ printf("** Invalid partition type \"%.32s\""
+ " (expect \"" BOOT_PART_TYPE "\")\n", info.type);
+ return 1;
+ }
+ printf("Loading file \"%s\" "
+ "from %s device %d:%lu (%.32s)\n",
+ filename, argv[1], dev, part, info.name);
+ } else {
+ printf("Loading file \"%s\" from %s device %d\n",
+ filename, argv[1], dev);
+ }
+
+ part_length = ext2fs_set_blk_dev(fs->dev_desc, part);
+ if (part_length == 0) {
+ printf("**Bad partition - %s %d:%lu **\n", argv[1], dev, part);
+ ext4fs_close();
+ return 1;
+ }
+
+ if (!ext4fs_mount(part_length)) {
+ printf("** Bad ext2 partition or disk - %s %d:%lu **\n",
+ argv[1], dev, part);
+ ext4fs_close();
+ return 1;
+ }
+
+ filelen = ext4fs_open(filename);
+ if (filelen < 0) {
+ printf("** File not found %s\n", filename);
+ ext4fs_close();
+ return 1;
+ }
+ if ((count < filelen) && (count != 0))
+ filelen = count;
+
+ if (ext4fs_read((char *)addr, filelen) != filelen) {
+ printf("** Unable to read \"%s\" from %s %d:%lu **\n",
+ filename, argv[1], dev, part);
+ ext4fs_close();
+ return 1;
+ }
+
+ ext4fs_close();
+ deinit_fs(fs->dev_desc);
+ /* Loading ok, update default load address */
+ load_addr = addr;
+
+ printf("%d bytes read\n", filelen);
+ sprintf(buf, "%X", filelen);
+ setenv("filesize", buf);
+
+ return 0;
+}
+
+int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ char *filename = "/";
+ int dev = 0;
+ unsigned long part = 1;
+ char *ep;
+ struct ext_filesystem *fs;
+ int part_length;
+
+ if (argc < 3)
+ return cmd_usage(cmdtp);
+
+ dev = (int)simple_strtoul(argv[2], &ep, 16);
+ ext4_dev_desc = get_dev(argv[1], dev);
+
+ if (ext4_dev_desc == NULL) {
+ printf("\n** Block device %s %d not supported\n", argv[1], dev);
+ return 1;
+ }
+
+ if (init_fs(ext4_dev_desc))
+ return 1;
+
+ fs = get_fs();
+ if (*ep) {
+ if (*ep != ':') {
+ puts("\n** Invalid boot device, use `dev[:part]' **\n");
+ return 1;
+ }
+ (int)strict_strtoul(++ep, 16, &part);
+ }
+
+ if (argc == 4)
+ filename = argv[3];
+
+ part_length = ext2fs_set_blk_dev(fs->dev_desc, part);
+ if (part_length == 0) {
+ printf("** Bad partition - %s %d:%lu **\n", argv[1], dev, part);
+ ext4fs_close();
+ return 1;
+ }
+
+ if (!ext4fs_mount(part_length)) {
+ printf("** Bad ext2 partition or disk - %s %d:%lu **\n",
+ argv[1], dev, part);
+ ext4fs_close();
+ return 1;
+ }
+ if (ext4fs_ls(filename)) {
+ printf("** Error ext2fs_ls() **\n");
+ ext4fs_close();
+ return 1;
+ };
+
+ ext4fs_close();
+ deinit_fs(fs->dev_desc);
+ return 0;
+}
+
+U_BOOT_CMD(ext4ls, 4, 1, do_ext4_ls,
+ "list files in a directory (default /)",
+ "<interface> <dev[:part]> [directory]\n"
+ " - list files from 'dev' on 'interface' in a 'directory'");
+
+U_BOOT_CMD(ext4load, 6, 0, do_ext4_load,
+ "load binary file from a Ext2 filesystem",
+ "<interface> <dev[:part]> [addr] [filename] [bytes]\n"
+ " - load binary file 'filename' from 'dev' on 'interface'\n"
+ " to address 'addr' from ext2 filesystem");
diff --git a/fs/Makefile b/fs/Makefile
index 22aad12..27330d4 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -24,6 +24,7 @@
subdirs-$(CONFIG_CMD_CRAMFS) := cramfs
subdirs-$(CONFIG_CMD_EXT2) += ext2
+subdirs-$(CONFIG_CMD_EXT4) += ext4
subdirs-$(CONFIG_CMD_FAT) += fat
subdirs-$(CONFIG_CMD_FDOS) += fdos
subdirs-$(CONFIG_CMD_JFFS2) += jffs2
diff --git a/fs/ext2/dev.c b/fs/ext2/dev.c
index 874e211..315ff53 100644
--- a/fs/ext2/dev.c
+++ b/fs/ext2/dev.c
@@ -27,6 +27,7 @@
#include <common.h>
#include <config.h>
#include <ext2fs.h>
+#include <ext_common.h>
static block_dev_desc_t *ext2fs_block_dev_desc;
static disk_partition_t part_info;
diff --git a/fs/ext2/ext2fs.c b/fs/ext2/ext2fs.c
index e119e13..df336b9 100644
--- a/fs/ext2/ext2fs.c
+++ b/fs/ext2/ext2fs.c
@@ -25,152 +25,12 @@
#include <common.h>
#include <ext2fs.h>
+#include <ext_common.h>
#include <malloc.h>
#include <asm/byteorder.h>
-extern int ext2fs_devread (int sector, int byte_offset, int byte_len,
- char *buf);
-
-/* Magic value used to identify an ext2 filesystem. */
-#define EXT2_MAGIC 0xEF53
-/* Amount of indirect blocks in an inode. */
-#define INDIRECT_BLOCKS 12
-/* Maximum lenght of a pathname. */
-#define EXT2_PATH_MAX 4096
-/* Maximum nesting of symlinks, used to prevent a loop. */
-#define EXT2_MAX_SYMLINKCNT 8
-
-/* Filetype used in directory entry. */
-#define FILETYPE_UNKNOWN 0
-#define FILETYPE_REG 1
-#define FILETYPE_DIRECTORY 2
-#define FILETYPE_SYMLINK 7
-
-/* Filetype information as used in inodes. */
-#define FILETYPE_INO_MASK 0170000
-#define FILETYPE_INO_REG 0100000
-#define FILETYPE_INO_DIRECTORY 0040000
-#define FILETYPE_INO_SYMLINK 0120000
-
-/* Bits used as offset in sector */
-#define DISK_SECTOR_BITS 9
-
-/* Log2 size of ext2 block in 512 blocks. */
-#define LOG2_EXT2_BLOCK_SIZE(data) (__le32_to_cpu (data->sblock.log2_block_size) + 1)
-
-/* Log2 size of ext2 block in bytes. */
-#define LOG2_BLOCK_SIZE(data) (__le32_to_cpu (data->sblock.log2_block_size) + 10)
-
-/* The size of an ext2 block in bytes. */
-#define EXT2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE(data))
-
-/* The ext2 superblock. */
-struct ext2_sblock {
- uint32_t total_inodes;
- uint32_t total_blocks;
- uint32_t reserved_blocks;
- uint32_t free_blocks;
- uint32_t free_inodes;
- uint32_t first_data_block;
- uint32_t log2_block_size;
- uint32_t log2_fragment_size;
- uint32_t blocks_per_group;
- uint32_t fragments_per_group;
- uint32_t inodes_per_group;
- uint32_t mtime;
- uint32_t utime;
- uint16_t mnt_count;
- uint16_t max_mnt_count;
- uint16_t magic;
- uint16_t fs_state;
- uint16_t error_handling;
- uint16_t minor_revision_level;
- uint32_t lastcheck;
- uint32_t checkinterval;
- uint32_t creator_os;
- uint32_t revision_level;
- uint16_t uid_reserved;
- uint16_t gid_reserved;
- uint32_t first_inode;
- uint16_t inode_size;
- uint16_t block_group_number;
- uint32_t feature_compatibility;
- uint32_t feature_incompat;
- uint32_t feature_ro_compat;
- uint32_t unique_id[4];
- char volume_name[16];
- char last_mounted_on[64];
- uint32_t compression_info;
-};
-
-/* The ext2 blockgroup. */
-struct ext2_block_group {
- uint32_t block_id;
- uint32_t inode_id;
- uint32_t inode_table_id;
- uint16_t free_blocks;
- uint16_t free_inodes;
- uint16_t used_dir_cnt;
- uint32_t reserved[3];
-};
-
-/* The ext2 inode. */
-struct ext2_inode {
- uint16_t mode;
- uint16_t uid;
- uint32_t size;
- uint32_t atime;
- uint32_t ctime;
- uint32_t mtime;
- uint32_t dtime;
- uint16_t gid;
- uint16_t nlinks;
- uint32_t blockcnt; /* Blocks of 512 bytes!! */
- uint32_t flags;
- uint32_t osd1;
- union {
- struct datablocks {
- uint32_t dir_blocks[INDIRECT_BLOCKS];
- uint32_t indir_block;
- uint32_t double_indir_block;
- uint32_t tripple_indir_block;
- } blocks;
- char symlink[60];
- } b;
- uint32_t version;
- uint32_t acl;
- uint32_t dir_acl;
- uint32_t fragment_addr;
- uint32_t osd2[3];
-};
-
-/* The header of an ext2 directory entry. */
-struct ext2_dirent {
- uint32_t inode;
- uint16_t direntlen;
- uint8_t namelen;
- uint8_t filetype;
-};
-
-struct ext2fs_node {
- struct ext2_data *data;
- struct ext2_inode inode;
- int ino;
- int inode_read;
-};
-
-/* Information about a "mounted" ext2 filesystem. */
-struct ext2_data {
- struct ext2_sblock sblock;
- struct ext2_inode *inode;
- struct ext2fs_node diropen;
-};
-
-
-typedef struct ext2fs_node *ext2fs_node_t;
-
-struct ext2_data *ext2fs_root = NULL;
-ext2fs_node_t ext2fs_file = NULL;
+struct ext2_data *ext2fs_root;
+struct ext2fs_node *ext2fs_file;
int symlinknest = 0;
uint32_t *indir1_block = NULL;
int indir1_size = 0;
@@ -178,8 +38,7 @@ int indir1_blkno = -1;
uint32_t *indir2_block = NULL;
int indir2_size = 0;
int indir2_blkno = -1;
-static unsigned int inode_size;
-
+unsigned int inode_size;
static int ext2fs_blockgroup
(struct ext2_data *data, int group, struct ext2_block_group *blkgrp) {
@@ -198,10 +57,8 @@ static int ext2fs_blockgroup
#endif
return (ext2fs_devread (blkno << LOG2_EXT2_BLOCK_SIZE(data),
blkoff, sizeof(struct ext2_block_group), (char *)blkgrp));
-
}
-
static int ext2fs_read_inode
(struct ext2_data *data, int ino, struct ext2_inode *inode) {
struct ext2_block_group blkgrp;
@@ -242,155 +99,16 @@ static int ext2fs_read_inode
return (1);
}
-
-void ext2fs_free_node (ext2fs_node_t node, ext2fs_node_t currroot) {
+void ext2fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot)
+{
if ((node != &ext2fs_root->diropen) && (node != currroot)) {
free (node);
}
}
-
-static int ext2fs_read_block (ext2fs_node_t node, int fileblock) {
- struct ext2_data *data = node->data;
- struct ext2_inode *inode = &node->inode;
- int blknr;
- int blksz = EXT2_BLOCK_SIZE (data);
- int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data);
- int status;
-
- /* Direct blocks. */
- if (fileblock < INDIRECT_BLOCKS) {
- blknr = __le32_to_cpu (inode->b.blocks.dir_blocks[fileblock]);
- }
- /* Indirect. */
- else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4))) {
- if (indir1_block == NULL) {
- indir1_block = (uint32_t *) malloc (blksz);
- if (indir1_block == NULL) {
- printf ("** ext2fs read block (indir 1) malloc failed. **\n");
- return (-1);
- }
- indir1_size = blksz;
- indir1_blkno = -1;
- }
- if (blksz != indir1_size) {
- free (indir1_block);
- indir1_block = NULL;
- indir1_size = 0;
- indir1_blkno = -1;
- indir1_block = (uint32_t *) malloc (blksz);
- if (indir1_block == NULL) {
- printf ("** ext2fs read block (indir 1) malloc failed. **\n");
- return (-1);
- }
- indir1_size = blksz;
- }
- if ((__le32_to_cpu (inode->b.blocks.indir_block) <<
- log2_blksz) != indir1_blkno) {
- status = ext2fs_devread (__le32_to_cpu(inode->b.blocks.indir_block) << log2_blksz,
- 0, blksz,
- (char *) indir1_block);
- if (status == 0) {
- printf ("** ext2fs read block (indir 1) failed. **\n");
- return (0);
- }
- indir1_blkno =
- __le32_to_cpu (inode->b.blocks.
- indir_block) << log2_blksz;
- }
- blknr = __le32_to_cpu (indir1_block
- [fileblock - INDIRECT_BLOCKS]);
- }
- /* Double indirect. */
- else if (fileblock <
- (INDIRECT_BLOCKS + (blksz / 4 * (blksz / 4 + 1)))) {
- unsigned int perblock = blksz / 4;
- unsigned int rblock = fileblock - (INDIRECT_BLOCKS
- + blksz / 4);
-
- if (indir1_block == NULL) {
- indir1_block = (uint32_t *) malloc (blksz);
- if (indir1_block == NULL) {
- printf ("** ext2fs read block (indir 2 1) malloc failed. **\n");
- return (-1);
- }
- indir1_size = blksz;
- indir1_blkno = -1;
- }
- if (blksz != indir1_size) {
- free (indir1_block);
- indir1_block = NULL;
- indir1_size = 0;
- indir1_blkno = -1;
- indir1_block = (uint32_t *) malloc (blksz);
- if (indir1_block == NULL) {
- printf ("** ext2fs read block (indir 2 1) malloc failed. **\n");
- return (-1);
- }
- indir1_size = blksz;
- }
- if ((__le32_to_cpu (inode->b.blocks.double_indir_block) <<
- log2_blksz) != indir1_blkno) {
- status = ext2fs_devread (__le32_to_cpu(inode->b.blocks.double_indir_block) << log2_blksz,
- 0, blksz,
- (char *) indir1_block);
- if (status == 0) {
- printf ("** ext2fs read block (indir 2 1) failed. **\n");
- return (-1);
- }
- indir1_blkno =
- __le32_to_cpu (inode->b.blocks.double_indir_block) << log2_blksz;
- }
-
- if (indir2_block == NULL) {
- indir2_block = (uint32_t *) malloc (blksz);
- if (indir2_block == NULL) {
- printf ("** ext2fs read block (indir 2 2) malloc failed. **\n");
- return (-1);
- }
- indir2_size = blksz;
- indir2_blkno = -1;
- }
- if (blksz != indir2_size) {
- free (indir2_block);
- indir2_block = NULL;
- indir2_size = 0;
- indir2_blkno = -1;
- indir2_block = (uint32_t *) malloc (blksz);
- if (indir2_block == NULL) {
- printf ("** ext2fs read block (indir 2 2) malloc failed. **\n");
- return (-1);
- }
- indir2_size = blksz;
- }
- if ((__le32_to_cpu (indir1_block[rblock / perblock]) <<
- log2_blksz) != indir2_blkno) {
- status = ext2fs_devread (__le32_to_cpu(indir1_block[rblock / perblock]) << log2_blksz,
- 0, blksz,
- (char *) indir2_block);
- if (status == 0) {
- printf ("** ext2fs read block (indir 2 2) failed. **\n");
- return (-1);
- }
- indir2_blkno =
- __le32_to_cpu (indir1_block[rblock / perblock]) << log2_blksz;
- }
- blknr = __le32_to_cpu (indir2_block[rblock % perblock]);
- }
- /* Tripple indirect. */
- else {
- printf ("** ext2fs doesn't support tripple indirect blocks. **\n");
- return (-1);
- }
-#ifdef DEBUG
- printf ("ext2fs_read_block %08x\n", blknr);
-#endif
- return (blknr);
-}
-
-
int ext2fs_read_file
- (ext2fs_node_t node, int pos, unsigned int len, char *buf) {
+ (struct ext2fs_node *node, int pos, unsigned int len, char *buf)
+{
int i;
int blockcnt;
int log2blocksize = LOG2_EXT2_BLOCK_SIZE (node->data);
@@ -409,8 +127,7 @@ int ext2fs_read_file
int blockend = blocksize;
int skipfirst = 0;
-
- blknr = ext2fs_read_block (node, i);
+ blknr = read_allocated_block(&(node->inode), i);
if (blknr < 0) {
return (-1);
}
@@ -449,8 +166,8 @@ int ext2fs_read_file
return (len);
}
-
-static int ext2fs_iterate_dir (ext2fs_node_t dir, char *name, ext2fs_node_t * fnode, int *ftype)
+int ext2fs_iterate_dir(struct ext2fs_node *dir, char *name,
+ struct ext2fs_node **fnode, int *ftype)
{
unsigned int fpos = 0;
int status;
@@ -479,7 +196,7 @@ static int ext2fs_iterate_dir (ext2fs_node_t dir, char *name, ext2fs_node_t * fn
}
if (dirent.namelen != 0) {
char filename[dirent.namelen + 1];
- ext2fs_node_t fdiro;
+ struct ext2fs_node *fdiro;
int type = FILETYPE_UNKNOWN;
status = ext2fs_read_file (diro,
@@ -581,8 +298,8 @@ static int ext2fs_iterate_dir (ext2fs_node_t dir, char *name, ext2fs_node_t * fn
return (0);
}
-
-static char *ext2fs_read_symlink (ext2fs_node_t node) {
+static char *ext2fs_read_symlink(struct ext2fs_node *node)
+{
char *symlink;
struct ext2fs_node *diro = node;
int status;
@@ -617,17 +334,17 @@ static char *ext2fs_read_symlink (ext2fs_node_t node) {
return (symlink);
}
-
int ext2fs_find_file1
- (const char *currpath,
- ext2fs_node_t currroot, ext2fs_node_t * currfound, int *foundtype) {
+ (const char *currpath, struct ext2fs_node *currroot,
+ struct ext2fs_node **currfound, int *foundtype)
+{
char fpath[strlen (currpath) + 1];
char *name = fpath;
char *next;
int status;
int type = FILETYPE_DIRECTORY;
- ext2fs_node_t currnode = currroot;
- ext2fs_node_t oldnode = currroot;
+ struct ext2fs_node *currnode = currroot;
+ struct ext2fs_node *oldnode = currroot;
strncpy (fpath, currpath, strlen (currpath) + 1);
@@ -721,14 +438,13 @@ int ext2fs_find_file1
return (-1);
}
-
int ext2fs_find_file
- (const char *path,
- ext2fs_node_t rootnode, ext2fs_node_t * foundnode, int expecttype) {
+ (const char *path, struct ext2fs_node *rootnode,
+ struct ext2fs_node **foundnode, int expecttype)
+{
int status;
int foundtype = FILETYPE_DIRECTORY;
-
symlinknest = 0;
if (!path) {
return (0);
@@ -748,9 +464,8 @@ int ext2fs_find_file
return (1);
}
-
int ext2fs_ls (const char *dirname) {
- ext2fs_node_t dirnode;
+ struct ext2fs_node *dirnode;
int status;
if (ext2fs_root == NULL) {
@@ -768,9 +483,8 @@ int ext2fs_ls (const char *dirname) {
return (0);
}
-
int ext2fs_open (const char *filename) {
- ext2fs_node_t fdiro = NULL;
+ struct ext2fs_node *fdiro = NULL;
int status;
int len;
@@ -799,7 +513,6 @@ fail:
return (-1);
}
-
int ext2fs_close (void
) {
if ((ext2fs_file != NULL) && (ext2fs_root != NULL)) {
@@ -825,7 +538,6 @@ int ext2fs_close (void
return (0);
}
-
int ext2fs_read (char *buf, unsigned len) {
int status;
@@ -836,12 +548,10 @@ int ext2fs_read (char *buf, unsigned len) {
if (ext2fs_file == NULL) {
return (0);
}
-
status = ext2fs_read_file (ext2fs_file, 0, len, buf);
return (status);
}
-
int ext2fs_mount (unsigned part_length) {
struct ext2_data *data;
int status;
@@ -880,7 +590,7 @@ int ext2fs_mount (unsigned part_length) {
}
ext2fs_root = data;
-
+ ext4fs_root = data;
return (1);
fail:
diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile
new file mode 100644
index 0000000..850f821
--- /dev/null
+++ b/fs/ext4/Makefile
@@ -0,0 +1,51 @@
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd(a)denx.de.
+#
+# (C) Copyright 2003
+# Pavel Bartusek, Sysgo Real-Time Solutions AG, pba(a)sysgo.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)libext4fs.o
+
+AOBJS =
+COBJS-$(CONFIG_CMD_EXT4) := ext4fs.o ext4_common.o
+
+SRCS := $(AOBJS:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS-y))
+
+
+all: $(LIB) $(AOBJS)
+
+$(LIB): $(obj).depend $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
new file mode 100644
index 0000000..6f9351c
--- /dev/null
+++ b/fs/ext4/ext4_common.c
@@ -0,0 +1,573 @@
+/*
+ * (C) Copyright 2011 Samsung Electronics
+ * EXT4 filesystem implementation in Uboot by
+ * Uma Shankar <uma.shankar(a)samsung.com>
+ * Manjunatha C Achar <a.manjunatha(a)samsung.com>
+ *
+ * Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * ext4load - based on code from GRUB2 fs/ext2.c
+*/
+#include <common.h>
+#include <ext_common.h>
+#include <ext4fs.h>
+#include <malloc.h>
+#include <asm/byteorder.h>
+#include <linux/stat.h>
+#include <linux/time.h>
+#include "ext4_common.h"
+
+struct ext2_data *ext4fs_root;
+struct ext2fs_node *ext4fs_file;
+uint32_t *ext4fs_indir1_block;
+int ext4fs_indir1_size;
+int ext4fs_indir1_blkno = -1;
+uint32_t *ext4fs_indir2_block;
+int ext4fs_indir2_size;
+int ext4fs_indir2_blkno = -1;
+
+uint32_t *ext4fs_indir3_block;
+int ext4fs_indir3_size;
+int ext4fs_indir3_blkno = -1;
+struct ext2_inode *g_parent_inode;
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+void *xmalloc(size_t size)
+{
+ void *ptr = malloc(size);
+ if (ptr == NULL && size != 0)
+ printf("bb_msg_memory_exhausted\n");
+ return ptr;
+}
+
+void *xzalloc(size_t size)
+{
+ void *ptr = xmalloc(size);
+ memset(ptr, 0, size);
+ return ptr;
+}
+
+static struct ext4_extent_header *ext4fs_find_leaf(struct ext2_data *data,
+ char *buf, struct ext4_extent_header *ext_block, uint32_t fileblock)
+{
+ struct ext4_extent_idx *index;
+ unsigned long long block;
+ int i;
+
+ while (1) {
+ index = (struct ext4_extent_idx *)(ext_block + 1);
+
+ if (le32_to_cpu(ext_block->magic) != EXT4_EXT_MAGIC)
+ return 0;
+
+ if (ext_block->depth == 0)
+ return ext_block;
+
+ for (i = 0; i < le32_to_cpu(ext_block->entries); i++) {
+ if (fileblock < le32_to_cpu(index[i].block))
+ break;
+ }
+
+ if (--i < 0)
+ return 0;
+
+ block = le32_to_cpu(index[i].leaf_hi);
+ block = (block << 32) + le32_to_cpu(index[i].leaf);
+
+ if (ext2fs_devread(block << LOG2_EXT2_BLOCK_SIZE(data),
+ 0, EXT2_BLOCK_SIZE(data), buf)) {
+ ext_block = (struct ext4_extent_header *)buf;
+ return ext_block;
+ } else
+ return 0;
+ }
+}
+
+static int ext4fs_blockgroup
+ (struct ext2_data *data, int group, struct ext2_block_group *blkgrp)
+{
+ long int blkno;
+ unsigned int blkoff, desc_per_blk;
+
+ desc_per_blk = EXT2_BLOCK_SIZE(data) / sizeof(struct ext2_block_group);
+
+ blkno = __le32_to_cpu(data->sblock.first_data_block) + 1
+ + group / desc_per_blk;
+ blkoff = (group % desc_per_blk) * sizeof(struct ext2_block_group);
+
+ debug("ext4fs read %d group descriptor (blkno %ld blkoff %u)\n",
+ group, blkno, blkoff);
+
+ return ext2fs_devread(blkno << LOG2_EXT2_BLOCK_SIZE(data),
+ blkoff, sizeof(struct ext2_block_group), (char *)blkgrp);
+}
+
+int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode)
+{
+ struct ext2_block_group blkgrp;
+ struct ext2_sblock *sblock = &data->sblock;
+ struct ext_filesystem *fs = get_fs();
+ int inodes_per_block, status;
+ long int blkno;
+ unsigned int blkoff;
+
+ /* It is easier to calculate if the first inode is 0. */
+ ino--;
+ status = ext4fs_blockgroup(data, ino / __le32_to_cpu
+ (sblock->inodes_per_group), &blkgrp);
+
+ if (status == 0)
+ return 0;
+
+ inodes_per_block = EXT2_BLOCK_SIZE(data) / fs->inodesz;
+
+ blkno = __le32_to_cpu(blkgrp.inode_table_id) +
+ (ino % __le32_to_cpu(sblock->inodes_per_group))
+ / inodes_per_block;
+ blkoff = (ino % inodes_per_block) * fs->inodesz;
+ /* Read the inode. */
+ status = ext2fs_devread(blkno << LOG2_EXT2_BLOCK_SIZE(data), blkoff,
+ sizeof(struct ext2_inode), (char *)inode);
+ if (status == 0)
+ return 0;
+
+ return 1;
+}
+
+long int read_allocated_block(struct ext2_inode *inode, int fileblock)
+{
+ long int blknr;
+ int blksz;
+ int log2_blksz;
+ int status;
+ long int rblock;
+ long int perblock_parent;
+ long int perblock_child;
+ unsigned long long start;
+ /*get the blocksize of the filesystem */
+ blksz = EXT2_BLOCK_SIZE(ext4fs_root);
+ log2_blksz = LOG2_EXT2_BLOCK_SIZE(ext4fs_root);
+
+ if (le32_to_cpu(inode->flags) & EXT4_EXTENTS_FLAG) {
+ char buf[EXT2_BLOCK_SIZE(ext4fs_root)];
+ struct ext4_extent_header *leaf;
+ struct ext4_extent *ext;
+ int i;
+
+ leaf = ext4fs_find_leaf(ext4fs_root, buf,
+ (struct ext4_extent_header *)inode->
+ b.blocks.dir_blocks, fileblock);
+ if (!leaf) {
+ printf("invalid extent\n");
+ return -1;
+ }
+
+ ext = (struct ext4_extent *)(leaf + 1);
+
+ for (i = 0; i < le32_to_cpu(leaf->entries); i++) {
+ if (fileblock < le32_to_cpu(ext[i].block))
+ break;
+ }
+
+ if (--i >= 0) {
+ fileblock -= le32_to_cpu(ext[i].block);
+ if (fileblock >= le32_to_cpu(ext[i].len)) {
+ return 0;
+ } else {
+ start = le32_to_cpu(ext[i].start_hi);
+ start = (start << 32) +
+ le32_to_cpu(ext[i].start);
+ return fileblock + start;
+ }
+ } else {
+ printf("something wrong with extent\n");
+ return -1;
+ }
+ }
+
+ /* Direct blocks. */
+ if (fileblock < INDIRECT_BLOCKS)
+ blknr = __le32_to_cpu(inode->b.blocks.dir_blocks[fileblock]);
+
+ /* Indirect. */
+ else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4))) {
+ if (ext4fs_indir1_block == NULL) {
+ ext4fs_indir1_block = (uint32_t *) malloc(blksz);
+ if (ext4fs_indir1_block == NULL) {
+ printf("** SI ext2fs read block (indir 1)"
+ "malloc failed. **\n");
+ return -1;
+ }
+ ext4fs_indir1_size = blksz;
+ ext4fs_indir1_blkno = -1;
+ }
+ if (blksz != ext4fs_indir1_size) {
+ free(ext4fs_indir1_block);
+ ext4fs_indir1_block = NULL;
+ ext4fs_indir1_size = 0;
+ ext4fs_indir1_blkno = -1;
+ ext4fs_indir1_block = (uint32_t *) malloc(blksz);
+ if (ext4fs_indir1_block == NULL) {
+ printf("** SI ext2fs read block (indir 1):"
+ "malloc failed. **\n");
+ return -1;
+ }
+ ext4fs_indir1_size = blksz;
+ }
+ if ((__le32_to_cpu(inode->b.blocks.indir_block) <<
+ log2_blksz) != ext4fs_indir1_blkno) {
+ status = ext2fs_devread(__le32_to_cpu(inode->b.blocks.
+ indir_block) << log2_blksz, 0, blksz,
+ (char *) ext4fs_indir1_block);
+ if (status == 0) {
+ printf("** SI ext2fs read block (indir 1)"
+ "failed. **\n");
+ return 0;
+ }
+ ext4fs_indir1_blkno =
+ __le32_to_cpu(inode->b.blocks.
+ indir_block) << log2_blksz;
+ }
+ blknr = __le32_to_cpu(ext4fs_indir1_block
+ [fileblock - INDIRECT_BLOCKS]);
+ }
+ /* Double indirect. */
+ else if (fileblock <
+ (INDIRECT_BLOCKS + (blksz / 4 * (blksz / 4 + 1)))) {
+
+ long int perblock = blksz / 4;
+ long int rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4);
+
+ if (ext4fs_indir1_block == NULL) {
+ ext4fs_indir1_block = (uint32_t *) malloc(blksz);
+ if (ext4fs_indir1_block == NULL) {
+ printf("** DI ext2fs read block (indir 2 1)"
+ "malloc failed. **\n");
+ return -1;
+ }
+ ext4fs_indir1_size = blksz;
+ ext4fs_indir1_blkno = -1;
+ }
+ if (blksz != ext4fs_indir1_size) {
+ free(ext4fs_indir1_block);
+ ext4fs_indir1_block = NULL;
+ ext4fs_indir1_size = 0;
+ ext4fs_indir1_blkno = -1;
+ ext4fs_indir1_block = (uint32_t *) malloc(blksz);
+ if (ext4fs_indir1_block == NULL) {
+ printf("** DI ext2fs read block (indir 2 1)"
+ "malloc failed. **\n");
+ return -1;
+ }
+ ext4fs_indir1_size = blksz;
+ }
+ if ((__le32_to_cpu(inode->b.blocks.double_indir_block) <<
+ log2_blksz) != ext4fs_indir1_blkno) {
+ status = ext2fs_devread(__le32_to_cpu(inode->b.blocks.
+ double_indir_block) << log2_blksz, 0, blksz,
+ (char *) ext4fs_indir1_block);
+ if (status == 0) {
+ printf("** DI ext2fs read block (indir 2 1)"
+ "failed. **\n");
+ return -1;
+ }
+ ext4fs_indir1_blkno =
+ __le32_to_cpu(inode->b.blocks.
+ double_indir_block) << log2_blksz;
+ }
+
+ if (ext4fs_indir2_block == NULL) {
+ ext4fs_indir2_block = (uint32_t *) malloc(blksz);
+ if (ext4fs_indir2_block == NULL) {
+ printf("** DI ext2fs read block (indir 2 2)"
+ "malloc failed. **\n");
+ return -1;
+ }
+ ext4fs_indir2_size = blksz;
+ ext4fs_indir2_blkno = -1;
+ }
+ if (blksz != ext4fs_indir2_size) {
+ free(ext4fs_indir2_block);
+ ext4fs_indir2_block = NULL;
+ ext4fs_indir2_size = 0;
+ ext4fs_indir2_blkno = -1;
+ ext4fs_indir2_block = (uint32_t *) malloc(blksz);
+ if (ext4fs_indir2_block == NULL) {
+ printf("** DI ext2fs read block (indir 2 2)"
+ "malloc failed. **\n");
+ return -1;
+ }
+ ext4fs_indir2_size = blksz;
+ }
+ if ((__le32_to_cpu(ext4fs_indir1_block[rblock / perblock]) <<
+ log2_blksz) != ext4fs_indir2_blkno) {
+ status = ext2fs_devread(__le32_to_cpu
+ (ext4fs_indir1_block
+ [rblock / perblock]) << log2_blksz,
+ 0, blksz, (char *) ext4fs_indir2_block);
+ if (status == 0) {
+ printf("** DI ext2fs read block (indir 2 2)"
+ "failed. **\n");
+ return -1;
+ }
+ ext4fs_indir2_blkno =
+ __le32_to_cpu(ext4fs_indir1_block[rblock
+ / perblock]) << log2_blksz;
+ }
+ blknr = __le32_to_cpu(ext4fs_indir2_block[rblock % perblock]);
+ }
+ /* Tripple indirect. */
+ else {
+ rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4 +
+ (blksz / 4 * blksz / 4));
+ perblock_child = blksz / 4;
+ perblock_parent = ((blksz / 4) * (blksz / 4));
+
+ if (ext4fs_indir1_block == NULL) {
+ ext4fs_indir1_block = (uint32_t *) malloc(blksz);
+ if (ext4fs_indir1_block == NULL) {
+ printf("** TI ext2fs read block (indir 2 1)"
+ "malloc failed. **\n");
+ return -1;
+ }
+ ext4fs_indir1_size = blksz;
+ ext4fs_indir1_blkno = -1;
+ }
+ if (blksz != ext4fs_indir1_size) {
+ free(ext4fs_indir1_block);
+ ext4fs_indir1_block = NULL;
+ ext4fs_indir1_size = 0;
+ ext4fs_indir1_blkno = -1;
+ ext4fs_indir1_block = (uint32_t *) malloc(blksz);
+ if (ext4fs_indir1_block == NULL) {
+ printf("** TI ext2fs read block (indir 2 1)"
+ "malloc failed. **\n");
+ return -1;
+ }
+ ext4fs_indir1_size = blksz;
+ }
+ if ((__le32_to_cpu(inode->b.blocks.tripple_indir_block) <<
+ log2_blksz) != ext4fs_indir1_blkno) {
+ status = ext2fs_devread
+ (__le32_to_cpu(inode->b.blocks.
+ tripple_indir_block) << log2_blksz,
+ 0, blksz, (char *) ext4fs_indir1_block);
+ if (status == 0) {
+ printf("** TI ext2fs read block (indir 2 1)"
+ "failed. **\n");
+ return -1;
+ }
+ ext4fs_indir1_blkno =
+ __le32_to_cpu(inode->b.blocks.
+ tripple_indir_block) << log2_blksz;
+ }
+
+ if (ext4fs_indir2_block == NULL) {
+ ext4fs_indir2_block = (uint32_t *) malloc(blksz);
+ if (ext4fs_indir2_block == NULL) {
+ printf("** TI ext2fs read block (indir 2 2)"
+ "malloc failed. **\n");
+ return -1;
+ }
+ ext4fs_indir2_size = blksz;
+ ext4fs_indir2_blkno = -1;
+ }
+ if (blksz != ext4fs_indir2_size) {
+ free(ext4fs_indir2_block);
+ ext4fs_indir2_block = NULL;
+ ext4fs_indir2_size = 0;
+ ext4fs_indir2_blkno = -1;
+ ext4fs_indir2_block = (uint32_t *) malloc(blksz);
+ if (ext4fs_indir2_block == NULL) {
+ printf("** TI ext2fs read block (indir 2 2)"
+ "malloc failed. **\n");
+ return -1;
+ }
+ ext4fs_indir2_size = blksz;
+ }
+ if ((__le32_to_cpu(ext4fs_indir1_block[rblock /
+ perblock_parent]) << log2_blksz)
+ != ext4fs_indir2_blkno) {
+ status = ext2fs_devread(__le32_to_cpu
+ (ext4fs_indir1_block
+ [rblock / perblock_parent]) << log2_blksz,
+ 0, blksz, (char *) ext4fs_indir2_block);
+ if (status == 0) {
+ printf("** TI ext2fs read block (indir 2 2)"
+ "failed. **\n");
+ return -1;
+ }
+ ext4fs_indir2_blkno =
+ __le32_to_cpu(ext4fs_indir1_block[rblock /
+ perblock_parent]) << log2_blksz;
+ }
+
+ if (ext4fs_indir3_block == NULL) {
+ ext4fs_indir3_block = (uint32_t *) malloc(blksz);
+ if (ext4fs_indir3_block == NULL) {
+ printf("** TI ext2fs read block (indir 2 2)"
+ "malloc failed. **\n");
+ return -1;
+ }
+ ext4fs_indir3_size = blksz;
+ ext4fs_indir3_blkno = -1;
+ }
+ if (blksz != ext4fs_indir3_size) {
+ free(ext4fs_indir3_block);
+ ext4fs_indir3_block = NULL;
+ ext4fs_indir3_size = 0;
+ ext4fs_indir3_blkno = -1;
+ ext4fs_indir3_block = (uint32_t *) malloc(blksz);
+ if (ext4fs_indir3_block == NULL) {
+ printf("** TI ext2fs read block (indir 2 2)"
+ "malloc failed. **\n");
+ return -1;
+ }
+ ext4fs_indir3_size = blksz;
+ }
+ if ((__le32_to_cpu(ext4fs_indir2_block[rblock
+ / perblock_child]) << log2_blksz) != ext4fs_indir3_blkno){
+ status = ext2fs_devread(__le32_to_cpu
+ (ext4fs_indir2_block[(rblock / perblock_child)
+ % (blksz / 4)]) << log2_blksz,
+ 0, blksz, (char *) ext4fs_indir3_block);
+ if (status == 0) {
+ printf("** TI ext2fs read block (indir 2 2)"
+ "failed. **\n");
+ return -1;
+ }
+ ext4fs_indir3_blkno =
+ __le32_to_cpu(ext4fs_indir2_block[(rblock /
+ perblock_child) % (blksz / 4)]) << log2_blksz;
+ }
+
+ blknr = __le32_to_cpu(ext4fs_indir3_block
+ [rblock % perblock_child]);
+ }
+ debug("ext4fs_read_block %ld\n", blknr);
+ return blknr;
+}
+
+int ext4fs_close(void)
+{
+ if ((ext4fs_file != NULL) && (ext4fs_root != NULL)) {
+ ext4fs_free_node(ext4fs_file, &ext4fs_root->diropen);
+ ext4fs_file = NULL;
+ }
+ if (ext4fs_root != NULL) {
+ free(ext4fs_root);
+ ext4fs_root = NULL;
+ }
+ if (ext4fs_indir1_block != NULL) {
+ free(ext4fs_indir1_block);
+ ext4fs_indir1_block = NULL;
+ ext4fs_indir1_size = 0;
+ ext4fs_indir1_blkno = -1;
+ }
+ if (ext4fs_indir2_block != NULL) {
+ free(ext4fs_indir2_block);
+ ext4fs_indir2_block = NULL;
+ ext4fs_indir2_size = 0;
+ ext4fs_indir2_blkno = -1;
+ }
+ return 0;
+}
+
+int ext4fs_open(const char *filename)
+{
+ struct ext2fs_node *fdiro = NULL;
+ int status;
+ int len;
+
+ if (ext4fs_root == NULL)
+ return -1;
+
+ ext4fs_file = NULL;
+ status = ext2fs_find_file(filename, &ext4fs_root->diropen, &fdiro,
+ FILETYPE_REG);
+ if (status == 0)
+ goto fail;
+
+ if (!fdiro->inode_read) {
+ status = ext4fs_read_inode(fdiro->data, fdiro->ino,
+ &fdiro->inode);
+ if (status == 0)
+ goto fail;
+ }
+ len = __le32_to_cpu(fdiro->inode.size);
+ ext4fs_file = fdiro;
+ return len;
+
+fail:
+ ext4fs_free_node(fdiro, &ext4fs_root->diropen);
+ return -1;
+}
+
+int ext4fs_mount(unsigned part_length)
+{
+ struct ext2_data *data;
+ int status;
+ struct ext_filesystem *fs = get_fs();
+ data = malloc(sizeof(struct ext2_data));
+ if (!data)
+ return 0;
+
+ /* Read the superblock. */
+ status = ext2fs_devread(1 * 2, 0, sizeof(struct ext2_sblock),
+ (char *)&data->sblock);
+
+ if (status == 0)
+ goto fail;
+
+ /* Make sure this is an ext2 filesystem. */
+ if (__le16_to_cpu(data->sblock.magic) != EXT2_MAGIC)
+ goto fail;
+
+ if (__le32_to_cpu(data->sblock.revision_level == 0))
+ fs->inodesz = 128;
+ else
+ fs->inodesz = __le16_to_cpu(data->sblock.inode_size);
+
+#ifdef DEBUG
+ printf("EXT2 rev %d, inode_size %d\n",
+ __le32_to_cpu(data->sblock.revision_level), fs->inodesz);
+#endif
+ data->diropen.data = data;
+ data->diropen.ino = 2;
+ data->diropen.inode_read = 1;
+ data->inode = &data->diropen.inode;
+
+ status = ext4fs_read_inode(data, 2, data->inode);
+ if (status == 0)
+ goto fail;
+
+ inode_size = fs->inodesz;
+ ext4fs_root = data;
+ ext2fs_root = data;
+ return 1;
+
+fail:
+ printf("Failed to mount ext2 filesystem...\n");
+ free(data);
+
+ ext4fs_root = NULL;
+ return 0;
+}
diff --git a/fs/ext4/ext4_common.h b/fs/ext4/ext4_common.h
new file mode 100644
index 0000000..73f218d
--- /dev/null
+++ b/fs/ext4/ext4_common.h
@@ -0,0 +1,44 @@
+/*
+ * (C) Copyright 2011 Samsung Electronics
+ * EXT4 filesystem implementation in Uboot by
+ * Uma Shankar <uma.shankar(a)samsung.com>
+ * Manjunatha C Achar <a.manjunatha(a)samsung.com>
+ *
+ * Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __EXT4_COMMON__
+#define __EXT4_COMMON__
+#include <ext_common.h>
+#include <ext4fs.h>
+
+#define YES 1
+#define NO 0
+#define TRUE 1
+#define FALSE 0
+#define RECOVER 1
+#define SCAN 0
+
+#define S_IFLNK 0120000 /* symbolic link */
+#define BLOCK_NO_ONE 1
+#define SUPERBLOCK_SECTOR 2
+#define SUPERBLOCK_SIZE 1024
+#define F_FILE 1
+
+extern unsigned long part_offset;
+int ext4fs_read_inode(struct ext2_data *data, int ino,
+ struct ext2_inode *inode);
+#endif
diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c
new file mode 100644
index 0000000..d4faa16
--- /dev/null
+++ b/fs/ext4/ext4fs.c
@@ -0,0 +1,215 @@
+/*
+ * (C) Copyright 2011 Samsung Electronics
+ * EXT4 filesystem implementation in Uboot by
+ * Uma Shankar <uma.shankar(a)samsung.com>
+ * Manjunatha C Achar <a.manjunatha(a)samsung.com>
+ *
+ * Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * ext4load - based on code from GRUB2 fs/ext2.c
+*/
+#include <common.h>
+#include <malloc.h>
+#include <asm/byteorder.h>
+#include <linux/stat.h>
+#include <linux/time.h>
+#include <ext_common.h>
+#include <ext4fs.h>
+#include "ext4_common.h"
+
+int ext4fs_symlinknest;
+block_dev_desc_t *ext4_dev_desc;
+
+struct ext_filesystem *get_fs(void)
+{
+ if (ext4_dev_desc == NULL || ext4_dev_desc->priv == NULL)
+ printf("Invalid Input Arguments %s\n", __func__);
+ return (struct ext_filesystem *)ext4_dev_desc->priv;
+}
+
+int init_fs(block_dev_desc_t *dev_desc)
+{
+ struct ext_filesystem *fs;
+ if (dev_desc == NULL) {
+ printf("Invalid Input Arguments %s\n", __func__);
+ return -1;
+ }
+
+ fs = (struct ext_filesystem *)xzalloc(sizeof(struct ext_filesystem));
+ if (fs == NULL) {
+ printf("malloc failed: %s\n", __func__);
+ return -1;
+ }
+
+ fs->dev_desc = dev_desc;
+ dev_desc->priv = fs;
+ return 0;
+}
+
+void deinit_fs(block_dev_desc_t *dev_desc)
+{
+ if (dev_desc == NULL) {
+ printf("Invalid Input Arguments %s\n", __func__);
+ return;
+ }
+ if (dev_desc->priv)
+ free(dev_desc->priv);
+ return;
+}
+
+void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot)
+{
+ if ((node != &ext4fs_root->diropen) && (node != currroot))
+ free(node);
+}
+
+/* Taken from openmoko-kernel mailing list: By Andy green
+* Optimized read file API : collects and defers contiguous sector
+* reads into one potentially more efficient larger sequential read action
+*/
+int ext4fs_read_file(struct ext2fs_node *node, int pos,
+ unsigned int len, char *buf)
+{
+ int i;
+ int blockcnt;
+ int log2blocksize = LOG2_EXT2_BLOCK_SIZE(node->data);
+ int blocksize = 1 << (log2blocksize + DISK_SECTOR_BITS);
+ unsigned int filesize = __le32_to_cpu(node->inode.size);
+ int previous_block_number = -1;
+ int delayed_start = 0;
+ int delayed_extent = 0;
+ int delayed_skipfirst = 0;
+ int delayed_next = 0;
+ char *delayed_buf = NULL;
+ short status;
+
+ /* Adjust len so it we can't read past the end of the file. */
+ if (len > filesize)
+ len = filesize;
+
+ blockcnt = ((len + pos) + blocksize - 1) / blocksize;
+
+ for (i = pos / blocksize; i < blockcnt; i++) {
+ int blknr;
+ int blockoff = pos % blocksize;
+ int blockend = blocksize;
+ int skipfirst = 0;
+ blknr = read_allocated_block(&(node->inode), i);
+ if (blknr < 0)
+ return -1;
+
+ blknr = blknr << log2blocksize;
+
+ /* Last block. */
+ if (i == blockcnt - 1) {
+ blockend = (len + pos) % blocksize;
+
+ /* The last portion is exactly blocksize. */
+ if (!blockend)
+ blockend = blocksize;
+ }
+
+ /* First block. */
+ if (i == pos / blocksize) {
+ skipfirst = blockoff;
+ blockend -= skipfirst;
+ }
+ if (blknr) {
+ int status;
+
+ if (previous_block_number != -1) {
+ if (delayed_next == blknr) {
+ delayed_extent += blockend;
+ delayed_next += blockend >> SECTOR_BITS;
+ } else { /* spill */
+ status = ext2fs_devread(delayed_start,
+ delayed_skipfirst,
+ delayed_extent,
+ delayed_buf);
+ if (status == 0)
+ return -1;
+ previous_block_number = blknr;
+ delayed_start = blknr;
+ delayed_extent = blockend;
+ delayed_skipfirst = skipfirst;
+ delayed_buf = buf;
+ delayed_next = blknr +
+ (blockend >> SECTOR_BITS);
+ }
+ } else {
+ previous_block_number = blknr;
+ delayed_start = blknr;
+ delayed_extent = blockend;
+ delayed_skipfirst = skipfirst;
+ delayed_buf = buf;
+ delayed_next = blknr +
+ (blockend >> SECTOR_BITS);
+ }
+ } else {
+ if (previous_block_number != -1) {
+ /* spill */
+ status = ext2fs_devread(delayed_start,
+ delayed_skipfirst,
+ delayed_extent,
+ delayed_buf);
+ if (status == 0)
+ return -1;
+ previous_block_number = -1;
+ }
+ memset(buf, 0, blocksize - skipfirst);
+ }
+ buf += blocksize - skipfirst;
+ }
+ if (previous_block_number != -1) {
+ /* spill */
+ status = ext2fs_devread(delayed_start,
+ delayed_skipfirst, delayed_extent,
+ delayed_buf);
+ if (status == 0)
+ return -1;
+ previous_block_number = -1;
+ }
+ return len;
+}
+
+int ext4fs_ls(const char *dirname)
+{
+ struct ext2fs_node *dirnode;
+ int status;
+
+ if (dirname == NULL)
+ return 0;
+
+ status = ext2fs_find_file(dirname, &ext4fs_root->diropen, &dirnode,
+ FILETYPE_DIRECTORY);
+ if (status != 1) {
+ printf("** Can not find directory. **\n");
+ return 1;
+ }
+
+ ext2fs_iterate_dir(dirnode, NULL, NULL, NULL);
+ ext4fs_free_node(dirnode, &ext4fs_root->diropen);
+ return 0;
+}
+
+int ext4fs_read(char *buf, unsigned len)
+{
+ if (ext4fs_root == NULL || ext4fs_file == NULL)
+ return 0;
+ return ext4fs_read_file(ext4fs_file, 0, len, buf);
+}
diff --git a/include/ext2fs.h b/include/ext2fs.h
index 163a9bb..7d4834c 100644
--- a/include/ext2fs.h
+++ b/include/ext2fs.h
@@ -25,6 +25,8 @@
* from the original ext2 fs code, as found in the linux kernel.
*/
+#ifndef __EXT2__
+#define __EXT2__
#define SECTOR_SIZE 0x200
#define SECTOR_BITS 9
@@ -68,14 +70,12 @@ typedef enum
ERR_DEV_NEED_INIT,
ERR_NO_DISK_SPACE,
ERR_NUMBER_OVERFLOW,
-
MAX_ERR_NUM
} ext2fs_error_t;
-
-extern int ext2fs_set_blk_dev(block_dev_desc_t *rbdd, int part);
-extern int ext2fs_ls (const char *dirname);
-extern int ext2fs_open (const char *filename);
-extern int ext2fs_read (char *buf, unsigned len);
-extern int ext2fs_mount (unsigned part_length);
-extern int ext2fs_close(void);
+int ext2fs_ls(const char *dirname);
+int ext2fs_open(const char *filename);
+int ext2fs_read(char *buf, unsigned len);
+int ext2fs_close(void);
+int ext2_register_device(block_dev_desc_t *dev_desc, int part_no);
+#endif
diff --git a/include/ext4fs.h b/include/ext4fs.h
new file mode 100644
index 0000000..fd7bd47
--- /dev/null
+++ b/include/ext4fs.h
@@ -0,0 +1,116 @@
+/*
+ * (C) Copyright 2011 Samsung Electronics
+ * EXT4 filesystem implementation in Uboot by
+ * Uma Shankar <uma.shankar(a)samsung.com>
+ * Manjunatha C Achar <a.manjunatha(a)samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Some parts of this code (mainly the structures and defines) are
+ * from the original ext4 fs code, as found in the linux kernel.
+ * Reference for ext4load and ls features have ben taken from GRUB
+ */
+
+#ifndef __EXT4__
+#define __EXT4__
+#include <ext_common.h>
+
+#define EXT4_EXTENTS_FLAG 0x80000
+#define EXT4_EXT_MAGIC 0xf30a
+#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010
+#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040
+#define EXT4_INDIRECT_BLOCKS 12
+
+#define EXT4_BG_INODE_UNINIT 0x0001
+#define EXT4_BG_BLOCK_UNINIT 0x0002
+#define EXT4_BG_INODE_ZEROED 0x0004
+
+struct ext4_extent_header {
+ uint16_t magic;
+ uint16_t entries;
+ uint16_t max;
+ uint16_t depth;
+ uint32_t generation;
+};
+
+struct ext4_extent {
+ uint32_t block;
+ uint16_t len;
+ uint16_t start_hi;
+ uint32_t start;
+};
+
+struct ext4_extent_idx {
+ uint32_t block;
+ uint32_t leaf;
+ uint16_t leaf_hi;
+ uint16_t unused;
+};
+
+struct ext_filesystem {
+ /*Total Sector of partition */
+ uint64_t total_sect;
+ /*Block size of partition */
+ uint32_t blksz;
+ /*Inode size of partition */
+ uint32_t inodesz;
+ /*Sectors per Block */
+ uint32_t sect_perblk;
+ /*Group Descriptor Block Number */
+ uint32_t gdtable_blkno;
+ /*Total block groups of partition */
+ uint32_t no_blkgrp;
+ /*No of blocks required for bgdtable */
+ uint32_t no_blk_pergdt;
+ /*superblock */
+ struct ext2_sblock *sb;
+ /*block group descritpor table */
+ struct ext2_block_group *gd;
+ char *gdtable;
+
+ /*Block Bitmap Related */
+ unsigned char **blk_bmaps;
+ long int curr_blkno;
+ uint16_t first_pass_bbmap;
+
+ /*Inode Bitmap Related */
+ unsigned char **inode_bmaps;
+ int curr_inode_no;
+ uint16_t first_pass_ibmap;
+
+ /*Journal Related */
+
+ /*Block Device Descriptor */
+ block_dev_desc_t *dev_desc;
+};
+
+/*############################*/
+extern block_dev_desc_t *ext4_dev_desc;
+/*#########################*/
+
+extern struct ext2_data *ext4fs_root;
+extern struct ext2fs_node *ext4fs_file;
+struct ext_filesystem *get_fs(void);
+int init_fs(block_dev_desc_t *);
+void deinit_fs(block_dev_desc_t *);
+int ext4fs_open(const char *filename);
+int ext4fs_read(char *buf, unsigned len);
+int ext4fs_mount(unsigned part_length);
+int ext4fs_close(void);
+int ext4fs_ls(const char *dirname);
+void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot);
+extern int ext2fs_devread(int sector, int byte_offset, int byte_len, char *buf);
+extern void *xzalloc(size_t size);
+#endif
diff --git a/include/ext_common.h b/include/ext_common.h
new file mode 100644
index 0000000..8b0474c
--- /dev/null
+++ b/include/ext_common.h
@@ -0,0 +1,199 @@
+/*
+ * (C) Copyright 2011 Samsung Electronics
+ * EXT4 filesystem implementation in Uboot by
+ * Uma Shankar <uma.shankar(a)samsung.com>
+ * Manjunatha C Achar <a.manjunatha(a)samsung.com>
+ *
+ * Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/* Some parts of this code (mainly the structures and defines) are
+ * from the original ext2 fs code, as found in the linux kernel.
+ */
+
+#ifndef __EXT_COMMON__
+#define __EXT_COMMON__
+
+#define SECTOR_SIZE 0x200
+#define SECTOR_BITS 9
+
+/* Magic value used to identify an ext2 filesystem. */
+#define EXT2_MAGIC 0xEF53
+/* Amount of indirect blocks in an inode. */
+#define INDIRECT_BLOCKS 12
+/* Maximum lenght of a pathname. */
+#define EXT2_PATH_MAX 4096
+/* Maximum nesting of symlinks, used to prevent a loop. */
+#define EXT2_MAX_SYMLINKCNT 8
+
+/* Filetype used in directory entry. */
+#define FILETYPE_UNKNOWN 0
+#define FILETYPE_REG 1
+#define FILETYPE_DIRECTORY 2
+#define FILETYPE_SYMLINK 7
+
+/* Filetype information as used in inodes. */
+#define FILETYPE_INO_MASK 0170000
+#define FILETYPE_INO_REG 0100000
+#define FILETYPE_INO_DIRECTORY 0040000
+#define FILETYPE_INO_SYMLINK 0120000
+#define EXT2_ROOT_INO 2 /* Root inode */
+
+/* Bits used as offset in sector */
+#define DISK_SECTOR_BITS 9
+/* The size of an ext2 block in bytes. */
+#define EXT2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE(data))
+
+/* Log2 size of ext2 block in 512 blocks. */
+#define LOG2_EXT2_BLOCK_SIZE(data) (__le32_to_cpu \
+ (data->sblock.log2_block_size) + 1)
+
+/* Log2 size of ext2 block in bytes. */
+#define LOG2_BLOCK_SIZE(data) (__le32_to_cpu \
+ (data->sblock.log2_block_size) + 10)
+#define INODE_SIZE_FILESYSTEM(data) (__le32_to_cpu \
+ (data->sblock.inode_size))
+
+#define EXT2_FT_DIR 2
+#define SUCCESS 1
+/*
+ * Macro-instructions used to manage several block sizes
+ */
+#define EXT2_MIN_BLOCK_LOG_SIZE 10 /* 1024 */
+#define EXT2_MAX_BLOCK_LOG_SIZE 16 /* 65536 */
+#define EXT2_MIN_BLOCK_SIZE (1 << EXT2_MIN_BLOCK_LOG_SIZE)
+#define EXT2_MAX_BLOCK_SIZE (1 << EXT2_MAX_BLOCK_LOG_SIZE)
+
+/* The ext2 superblock. */
+struct ext2_sblock {
+ uint32_t total_inodes;
+ uint32_t total_blocks;
+ uint32_t reserved_blocks;
+ uint32_t free_blocks;
+ uint32_t free_inodes;
+ uint32_t first_data_block;
+ uint32_t log2_block_size;
+ uint32_t log2_fragment_size;
+ uint32_t blocks_per_group;
+ uint32_t fragments_per_group;
+ uint32_t inodes_per_group;
+ uint32_t mtime;
+ uint32_t utime;
+ uint16_t mnt_count;
+ uint16_t max_mnt_count;
+ uint16_t magic;
+ uint16_t fs_state;
+ uint16_t error_handling;
+ uint16_t minor_revision_level;
+ uint32_t lastcheck;
+ uint32_t checkinterval;
+ uint32_t creator_os;
+ uint32_t revision_level;
+ uint16_t uid_reserved;
+ uint16_t gid_reserved;
+ uint32_t first_inode;
+ uint16_t inode_size;
+ uint16_t block_group_number;
+ uint32_t feature_compatibility;
+ uint32_t feature_incompat;
+ uint32_t feature_ro_compat;
+ uint32_t unique_id[4];
+ char volume_name[16];
+ char last_mounted_on[64];
+ uint32_t compression_info;
+};
+
+struct ext2_block_group {
+ __u32 block_id; /* Blocks bitmap block */
+ __u32 inode_id; /* Inodes bitmap block */
+ __u32 inode_table_id; /* Inodes table block */
+ __u16 free_blocks; /* Free blocks count */
+ __u16 free_inodes; /* Free inodes count */
+ __u16 used_dir_cnt; /* Directories count */
+ __u16 bg_flags;
+ __u32 bg_reserved[2];
+ __u16 bg_itable_unused; /* Unused inodes count */
+ __u16 bg_checksum; /* crc16(s_uuid+grouo_num+group_desc)*/
+};
+
+/* The ext2 inode. */
+struct ext2_inode {
+ uint16_t mode;
+ uint16_t uid;
+ uint32_t size;
+ uint32_t atime;
+ uint32_t ctime;
+ uint32_t mtime;
+ uint32_t dtime;
+ uint16_t gid;
+ uint16_t nlinks;
+ uint32_t blockcnt; /* Blocks of 512 bytes!! */
+ uint32_t flags;
+ uint32_t osd1;
+ union {
+ struct datablocks {
+ uint32_t dir_blocks[INDIRECT_BLOCKS];
+ uint32_t indir_block;
+ uint32_t double_indir_block;
+ uint32_t tripple_indir_block;
+ } blocks;
+ char symlink[60];
+ } b;
+ uint32_t version;
+ uint32_t acl;
+ uint32_t dir_acl;
+ uint32_t fragment_addr;
+ uint32_t osd2[3];
+};
+
+/* The header of an ext2 directory entry. */
+struct ext2_dirent {
+ uint32_t inode;
+ uint16_t direntlen;
+ uint8_t namelen;
+ uint8_t filetype;
+};
+
+struct ext2fs_node {
+ struct ext2_data *data;
+ struct ext2_inode inode;
+ int ino;
+ int inode_read;
+};
+
+/* Information about a "mounted" ext2 filesystem. */
+struct ext2_data {
+ struct ext2_sblock sblock;
+ struct ext2_inode *inode;
+ struct ext2fs_node diropen;
+};
+
+extern unsigned int inode_size;
+extern struct ext2_data *ext2fs_root;
+extern struct ext2_data *ext4fs_root;
+extern int ext2fs_iterate_dir(struct ext2fs_node *dir, char *name,
+ struct ext2fs_node **fnode, int *ftype);
+extern int ext2fs_find_file(const char *path, struct ext2fs_node *rootnode,
+ struct ext2fs_node **foundnode, int expecttype);
+extern int ext2fs_devread(int sector, int byte_offset, int byte_len, char *buf);
+int ext2fs_set_blk_dev(block_dev_desc_t *rbdd, int part);
+uint32_t div_roundup(uint32_t size, uint32_t n);
+long int read_allocated_block(struct ext2_inode *inode, int fileblock);
+int ext2fs_mount(unsigned part_length);
+void *xmalloc(size_t size);
+void *xzalloc(size_t size);
+#endif
--
1.7.0.4
9
27

19 Sep '12
Adjust the IPUv3 registers, so that the IPUv3 driver can be extended for mx6 as well.
Signed-off-by: Fabio Estevam <fabio.estevam(a)freescale.com>
---
This patch series apply against Anatolij's tree.
arch/arm/include/asm/arch-mx5/imx-regs.h | 2 --
arch/arm/include/asm/arch-mx6/imx-regs.h | 3 +++
drivers/video/ipu_regs.h | 12 +++++++++++-
3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/arch-mx5/imx-regs.h b/arch/arm/include/asm/arch-mx5/imx-regs.h
index 88fb7cb..8117f4f 100644
--- a/arch/arm/include/asm/arch-mx5/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx5/imx-regs.h
@@ -50,8 +50,6 @@
#error "CPU_TYPE not defined"
#endif
-#define IPU_CTRL_BASE_ADDR IPU_SOC_BASE_ADDR + IPU_SOC_OFFSET
-
#define IRAM_SIZE 0x00020000 /* 128 KB */
/*
diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h
index e165810..5d77603 100644
--- a/arch/arm/include/asm/arch-mx6/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx6/imx-regs.h
@@ -73,6 +73,9 @@
#define MMDC1_ARB_BASE_ADDR 0x80000000
#define MMDC1_ARB_END_ADDR 0xFFFFFFFF
+#define IPU_SOC_BASE_ADDR IPU1_ARB_BASE_ADDR
+#define IPU_SOC_OFFSET 0x00200000
+
/* Defines for Blocks connected via AIPS (SkyBlue) */
#define ATZ1_BASE_ADDR AIPS1_ARB_BASE_ADDR
#define ATZ2_BASE_ADDR AIPS2_ARB_BASE_ADDR
diff --git a/drivers/video/ipu_regs.h b/drivers/video/ipu_regs.h
index 93b195f..874e009 100644
--- a/drivers/video/ipu_regs.h
+++ b/drivers/video/ipu_regs.h
@@ -47,14 +47,24 @@
#define IPU_SMFC_REG_BASE 0x00050000
#define IPU_DC_REG_BASE 0x00058000
#define IPU_DMFC_REG_BASE 0x00060000
+#define IPU_VDI_REG_BASE 0x00680000
+#if defined(CONFIG_MX51) || defined(CONFIG_MX53)
#define IPU_CPMEM_REG_BASE 0x01000000
#define IPU_LUT_REG_BASE 0x01020000
#define IPU_SRM_REG_BASE 0x01040000
#define IPU_TPM_REG_BASE 0x01060000
#define IPU_DC_TMPL_REG_BASE 0x01080000
#define IPU_ISP_TBPR_REG_BASE 0x010C0000
-#define IPU_VDI_REG_BASE 0x00680000
+#elif defined(CONFIG_MX6Q)
+#define IPU_CPMEM_REG_BASE 0x00100000
+#define IPU_LUT_REG_BASE 0x00120000
+#define IPU_SRM_REG_BASE 0x00140000
+#define IPU_TPM_REG_BASE 0x00160000
+#define IPU_DC_TMPL_REG_BASE 0x00180000
+#define IPU_ISP_TBPR_REG_BASE 0x001C0000
+#endif
+#define IPU_CTRL_BASE_ADDR (IPU_SOC_BASE_ADDR + IPU_SOC_OFFSET)
extern u32 *ipu_dc_tmpl_reg;
--
1.7.1
8
45

[U-Boot] [PATCH v1 0/5] env: handle special variables and selective env default
by Gerlando Falauto 18 Sep '12
by Gerlando Falauto 18 Sep '12
18 Sep '12
This patchset modifies the handling of all the operations on the environment
(set/import/default) so to unify handling of special variables.
On top of that we implement a selective "env default".
A selective "env import" would imply a user API change and should therefore
be discussed separately.
Changes in the syntax (user API):
- "env default" -f: override write-once variables, -a means all
First patch is a cosmetic prerequisite to the second patch
which constifies serial_assign().
Changes from v0:
- checkpatch cleanup
- removed himport_ex()
- removed warning for serial_assign()
- env import NOT implemented here
Gerlando Falauto (5):
serial: cosmetic checkpatch compliance
serial: constify serial_assign()
env: unify logic to check and apply changes
env: check and apply changes on delete/destroy
env: make "env default" selective, check and apply
README | 2 +
common/cmd_nvedit.c | 209 +++++++++++++++++++++++++++++++---------------
common/env_common.c | 35 +++++++-
common/serial.c | 51 ++++++------
include/config_cmd_all.h | 1 +
include/environment.h | 12 +++
include/search.h | 23 +++++-
include/serial.h | 19 ++--
lib/hashtable.c | 61 ++++++++++++--
9 files changed, 300 insertions(+), 113 deletions(-)
8
103