mirror of
https://github.com/Ysurac/openmptcprouter.git
synced 2025-03-09 15:40:20 +00:00
Add working ext4 support for BPI-R2, but dirty for now
This commit is contained in:
parent
3d9429ff7d
commit
b854992ef2
29 changed files with 4292 additions and 2 deletions
58
root/package/boot/uboot-mediatek/Makefile
Normal file
58
root/package/boot/uboot-mediatek/Makefile
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013-2019 OpenWrt.org
|
||||||
|
# Copyright (C) 2019 Alexey Loukianov
|
||||||
|
#
|
||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
# See /LICENSE for more information.
|
||||||
|
#
|
||||||
|
|
||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
include $(INCLUDE_DIR)/kernel.mk
|
||||||
|
|
||||||
|
PKG_VERSION:=2019.01
|
||||||
|
|
||||||
|
PKG_HASH:=50bd7e5a466ab828914d080d5f6a432345b500e8fba1ad3b7b61e95e60d51c22
|
||||||
|
|
||||||
|
PKG_MAINTAINER:=Alexey Loukianov <lx2@lexa2.ru>
|
||||||
|
|
||||||
|
include $(INCLUDE_DIR)/u-boot.mk
|
||||||
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
|
define U-Boot/Default
|
||||||
|
BUILD_TARGET:=mediatek
|
||||||
|
UBOOT_IMAGE:=u-boot.bin
|
||||||
|
UENV:=default
|
||||||
|
HIDDEN:=1
|
||||||
|
endef
|
||||||
|
|
||||||
|
define U-Boot/mt7623n_bpir2
|
||||||
|
BUILD_SUBTARGET:=mt7623
|
||||||
|
NAME:=Bannana PI R2 (mt7623)
|
||||||
|
BUILD_DEVICES:=7623n-bananapi-bpi-r2
|
||||||
|
endef
|
||||||
|
|
||||||
|
UBOOT_TARGETS := \
|
||||||
|
mt7623n_bpir2
|
||||||
|
|
||||||
|
UBOOT_CONFIGURE_VARS += USE_PRIVATE_LIBGCC=yes
|
||||||
|
|
||||||
|
UBOOT_MAKE_FLAGS = \
|
||||||
|
HOSTCC="$(HOSTCC)" \
|
||||||
|
HOSTCFLAGS="$(HOST_CFLAGS) $(HOST_CPPFLAGS) -std=gnu11" \
|
||||||
|
HOSTLDFLAGS="$(HOST_LDFLAGS)"
|
||||||
|
|
||||||
|
define Build/Prepare
|
||||||
|
$(call Build/Prepare/Default)
|
||||||
|
$(CP) uEnv-$(UENV).txt ${PKG_BUILD_DIR}/uEnv.txt
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/InstallDev
|
||||||
|
$(INSTALL_DIR) $(STAGING_DIR_IMAGE)
|
||||||
|
$(CP) $(PKG_BUILD_DIR)/$(UBOOT_IMAGE) $(STAGING_DIR_IMAGE)/$(BUILD_DEVICES)-uboot-mediatek.bin
|
||||||
|
$(CP) $(PKG_BUILD_DIR)/uEnv.txt $(STAGING_DIR_IMAGE)/$(BUILD_DEVICES)-uEnv.txt
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/u-boot/install/default
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call BuildPackage/U-Boot))
|
|
@ -0,0 +1,39 @@
|
||||||
|
diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig
|
||||||
|
index ae4fb280..74252cd0 100644
|
||||||
|
--- a/configs/mt7623n_bpir2_defconfig
|
||||||
|
+++ b/configs/mt7623n_bpir2_defconfig
|
||||||
|
@@ -3,6 +3,7 @@ CONFIG_SYS_THUMB_BUILD=y
|
||||||
|
CONFIG_ARCH_MEDIATEK=y
|
||||||
|
CONFIG_SYS_TEXT_BASE=0x81e00000
|
||||||
|
CONFIG_SYS_MALLOC_F_LEN=0x4000
|
||||||
|
+CONFIG_TARGET_MT7623=y
|
||||||
|
CONFIG_NR_DRAM_BANKS=1
|
||||||
|
CONFIG_FIT=y
|
||||||
|
CONFIG_FIT_VERBOSE=y
|
||||||
|
@@ -11,7 +12,7 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y
|
||||||
|
CONFIG_DEFAULT_FDT_FILE="mt7623n-bananapi-bpi-r2"
|
||||||
|
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||||
|
CONFIG_HUSH_PARSER=y
|
||||||
|
-CONFIG_SYS_PROMPT="U-Boot> "
|
||||||
|
+CONFIG_SYS_PROMPT="BPI-R2> "
|
||||||
|
CONFIG_CMD_BOOTMENU=y
|
||||||
|
# CONFIG_CMD_ELF is not set
|
||||||
|
# CONFIG_CMD_XIMG is not set
|
||||||
|
@@ -51,3 +52,14 @@ CONFIG_MTK_TIMER=y
|
||||||
|
CONFIG_WDT_MTK=y
|
||||||
|
CONFIG_LZMA=y
|
||||||
|
# CONFIG_EFI_LOADER is not set
|
||||||
|
+
|
||||||
|
+CONFIG_CMD_BOOTZ=y
|
||||||
|
+CONFIG_OF_LIBFDT_OVERLAY=y
|
||||||
|
+
|
||||||
|
+CONFIG_USE_DEFAULT_ENV_FILE=y
|
||||||
|
+CONFIG_DEFAULT_ENV_FILE="uEnv.txt"
|
||||||
|
+
|
||||||
|
+#enables savenenv-command
|
||||||
|
+CONFIG_ENV_IS_IN_MMC=y
|
||||||
|
+
|
||||||
|
+CONFIG_CMD_ASKENV=y
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
From 2a59134ba1d841cf1a7845017656b74b74412aaf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frank Wunderlich <frank-w@public-files.de>
|
||||||
|
Date: Mon, 3 Dec 2018 15:32:58 +0100
|
||||||
|
Subject: adding saveenv-command for bananapi r2
|
||||||
|
|
||||||
|
bananapi r2 can be booted from sd-card and emmc
|
||||||
|
saving the environment have to choose the storage
|
||||||
|
from which the device has booted
|
||||||
|
|
||||||
|
also the offset is set to 1MB-50Kb to make sure env is written
|
||||||
|
to block "user data area" between uboot and first partition
|
||||||
|
|
||||||
|
https://www.fw-web.de/dokuwiki/lib/exe/fetch.php?cache=&media=bpi-r2:boot-structure.png
|
||||||
|
|
||||||
|
v3: removed changes in defconfig (users choice)
|
||||||
|
v2: fixed bracket-style in if-else statement
|
||||||
|
|
||||||
|
Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
|
||||||
|
|
||||||
|
diff --git a/board/mediatek/mt7623/mt7623_rfb.c b/board/mediatek/mt7623/mt7623_rfb.c
|
||||||
|
index 08468b50..4ec27649 100644
|
||||||
|
--- a/board/mediatek/mt7623/mt7623_rfb.c
|
||||||
|
+++ b/board/mediatek/mt7623/mt7623_rfb.c
|
||||||
|
@@ -14,3 +14,22 @@ int board_init(void)
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+int mmc_get_boot_dev(void)
|
||||||
|
+{
|
||||||
|
+ int g_mmc_devid = -1;
|
||||||
|
+ char *uflag = (char *)0x81DFFFF0;
|
||||||
|
+ if (strncmp(uflag,"eMMC",4)==0) {
|
||||||
|
+ g_mmc_devid = 0;
|
||||||
|
+ printf("Boot From Emmc(id:%d)\n\n", g_mmc_devid);
|
||||||
|
+ } else {
|
||||||
|
+ g_mmc_devid = 1;
|
||||||
|
+ printf("Boot From SD(id:%d)\n\n", g_mmc_devid);
|
||||||
|
+ }
|
||||||
|
+ return g_mmc_devid;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int mmc_get_env_dev(void)
|
||||||
|
+{
|
||||||
|
+ return mmc_get_boot_dev();
|
||||||
|
+}
|
||||||
|
diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h
|
||||||
|
index ba763501..fb6ac073 100644
|
||||||
|
--- a/include/configs/mt7623.h
|
||||||
|
+++ b/include/configs/mt7623.h
|
||||||
|
@@ -53,4 +53,7 @@
|
||||||
|
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||||
|
FDT_HIGH
|
||||||
|
|
||||||
|
+#define CONFIG_SYS_MMC_ENV_DEV 0
|
||||||
|
+#define CONFIG_ENV_OFFSET 0xF3800
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,189 @@
|
||||||
|
From e4033f535d7f6f86f354d36037565a319c02c324 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Weijie Gao <weijie.gao@mediatek.com>
|
||||||
|
Date: Thu, 20 Dec 2018 16:12:51 +0800
|
||||||
|
Subject: reset: MedaiTek: add reset controller driver for MediaTek SoCs
|
||||||
|
|
||||||
|
This patch adds reset controller driver for MediaTek SoCs.
|
||||||
|
|
||||||
|
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
|
||||||
|
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
|
||||||
|
|
||||||
|
diff --git a/arch/arm/include/asm/arch-mediatek/reset.h b/arch/arm/include/asm/arch-mediatek/reset.h
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..9704666d
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/arm/include/asm/arch-mediatek/reset.h
|
||||||
|
@@ -0,0 +1,13 @@
|
||||||
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2018 MediaTek Inc.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef __MEDIATEK_RESET_H
|
||||||
|
+#define __MEDIATEK_RESET_H
|
||||||
|
+
|
||||||
|
+#include <dm.h>
|
||||||
|
+
|
||||||
|
+int mediatek_reset_bind(struct udevice *pdev, u32 regofs, u32 num_regs);
|
||||||
|
+
|
||||||
|
+#endif /* __MEDIATEK_RESET_H */
|
||||||
|
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
|
||||||
|
index 9c5208b7..3a6d61f4 100644
|
||||||
|
--- a/drivers/reset/Kconfig
|
||||||
|
+++ b/drivers/reset/Kconfig
|
||||||
|
@@ -106,4 +106,11 @@ config RESET_SOCFPGA
|
||||||
|
help
|
||||||
|
Support for reset controller on SoCFPGA platform.
|
||||||
|
|
||||||
|
+config RESET_MEDIATEK
|
||||||
|
+ bool "Reset controller driver for MediaTek SoCs"
|
||||||
|
+ depends on DM_RESET && ARCH_MEDIATEK && CLK
|
||||||
|
+ default y
|
||||||
|
+ help
|
||||||
|
+ Support for reset controller on MediaTek SoCs.
|
||||||
|
+
|
||||||
|
endmenu
|
||||||
|
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
|
||||||
|
index f4520878..8a4dcab8 100644
|
||||||
|
--- a/drivers/reset/Makefile
|
||||||
|
+++ b/drivers/reset/Makefile
|
||||||
|
@@ -17,3 +17,4 @@ obj-$(CONFIG_AST2500_RESET) += ast2500-reset.o
|
||||||
|
obj-$(CONFIG_RESET_ROCKCHIP) += reset-rockchip.o
|
||||||
|
obj-$(CONFIG_RESET_MESON) += reset-meson.o
|
||||||
|
obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
|
||||||
|
+obj-$(CONFIG_RESET_MEDIATEK) += reset-mediatek.o
|
||||||
|
diff --git a/drivers/reset/reset-mediatek.c b/drivers/reset/reset-mediatek.c
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..e3614e6e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/drivers/reset/reset-mediatek.c
|
||||||
|
@@ -0,0 +1,102 @@
|
||||||
|
+// SPDX-License-Identifier: GPL-2.0
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2018 MediaTek Inc.
|
||||||
|
+ *
|
||||||
|
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
|
||||||
|
+ * Weijie Gao <weijie.gao@mediatek.com>
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <common.h>
|
||||||
|
+#include <dm.h>
|
||||||
|
+#include <dm/lists.h>
|
||||||
|
+#include <regmap.h>
|
||||||
|
+#include <reset-uclass.h>
|
||||||
|
+#include <syscon.h>
|
||||||
|
+
|
||||||
|
+struct mediatek_reset_priv {
|
||||||
|
+ struct regmap *regmap;
|
||||||
|
+ u32 regofs;
|
||||||
|
+ u32 nr_resets;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int mediatek_reset_request(struct reset_ctl *reset_ctl)
|
||||||
|
+{
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int mediatek_reset_free(struct reset_ctl *reset_ctl)
|
||||||
|
+{
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int mediatek_reset_assert(struct reset_ctl *reset_ctl)
|
||||||
|
+{
|
||||||
|
+ struct mediatek_reset_priv *priv = dev_get_priv(reset_ctl->dev);
|
||||||
|
+ int id = reset_ctl->id;
|
||||||
|
+
|
||||||
|
+ if (id >= priv->nr_resets)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ return regmap_update_bits(priv->regmap,
|
||||||
|
+ priv->regofs + ((id / 32) << 2), BIT(id % 32), BIT(id % 32));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int mediatek_reset_deassert(struct reset_ctl *reset_ctl)
|
||||||
|
+{
|
||||||
|
+ struct mediatek_reset_priv *priv = dev_get_priv(reset_ctl->dev);
|
||||||
|
+ int id = reset_ctl->id;
|
||||||
|
+
|
||||||
|
+ if (id >= priv->nr_resets)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ return regmap_update_bits(priv->regmap,
|
||||||
|
+ priv->regofs + ((id / 32) << 2), BIT(id % 32), 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct reset_ops mediatek_reset_ops = {
|
||||||
|
+ .request = mediatek_reset_request,
|
||||||
|
+ .free = mediatek_reset_free,
|
||||||
|
+ .rst_assert = mediatek_reset_assert,
|
||||||
|
+ .rst_deassert = mediatek_reset_deassert,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int mediatek_reset_probe(struct udevice *dev)
|
||||||
|
+{
|
||||||
|
+ struct mediatek_reset_priv *priv = dev_get_priv(dev);
|
||||||
|
+
|
||||||
|
+ if (!priv->regofs && !priv->nr_resets)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ priv->regmap = syscon_node_to_regmap(dev_ofnode(dev));
|
||||||
|
+ if (IS_ERR(priv->regmap))
|
||||||
|
+ return PTR_ERR(priv->regmap);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int mediatek_reset_bind(struct udevice *pdev, u32 regofs, u32 num_regs)
|
||||||
|
+{
|
||||||
|
+ struct udevice *rst_dev;
|
||||||
|
+ struct mediatek_reset_priv *priv;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = device_bind_driver_to_node(pdev, "mediatek_reset", "reset",
|
||||||
|
+ dev_ofnode(pdev), &rst_dev);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ priv = malloc(sizeof(struct mediatek_reset_priv));
|
||||||
|
+ priv->regofs = regofs;
|
||||||
|
+ priv->nr_resets = num_regs * 32;
|
||||||
|
+ rst_dev->priv = priv;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+U_BOOT_DRIVER(mediatek_reset) = {
|
||||||
|
+ .name = "mediatek_reset",
|
||||||
|
+ .id = UCLASS_RESET,
|
||||||
|
+ .probe = mediatek_reset_probe,
|
||||||
|
+ .ops = &mediatek_reset_ops,
|
||||||
|
+ .priv_auto_alloc_size = sizeof(struct mediatek_reset_priv),
|
||||||
|
+};
|
||||||
|
diff --git a/include/dt-bindings/reset/mtk-reset.h b/include/dt-bindings/reset/mtk-reset.h
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..5f0a74f2
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/include/dt-bindings/reset/mtk-reset.h
|
||||||
|
@@ -0,0 +1,18 @@
|
||||||
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2018 MediaTek Inc.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef _DT_BINDINGS_MTK_RESET_H_
|
||||||
|
+#define _DT_BINDINGS_MTK_RESET_H_
|
||||||
|
+
|
||||||
|
+/* ETHSYS */
|
||||||
|
+#define ETHSYS_PPE_RST 31
|
||||||
|
+#define ETHSYS_EPHY_RST 24
|
||||||
|
+#define ETHSYS_GMAC_RST 23
|
||||||
|
+#define ETHSYS_ESW_RST 16
|
||||||
|
+#define ETHSYS_FE_RST 6
|
||||||
|
+#define ETHSYS_MCM_RST 2
|
||||||
|
+#define ETHSYS_SYS_RST 0
|
||||||
|
+
|
||||||
|
+#endif /* _DT_BINDINGS_MTK_RESET_H_ */
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
From ab7ad2d077ef18d6d853c8838bc116fbbd0ac154 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Weijie Gao <weijie.gao@mediatek.com>
|
||||||
|
Date: Thu, 20 Dec 2018 16:12:52 +0800
|
||||||
|
Subject: clk: MediaTek: bind ethsys reset controller
|
||||||
|
|
||||||
|
The ethsys contains not only the clock gating controller, but also the
|
||||||
|
reset controller for the whole ethernet subsystem and its components.
|
||||||
|
|
||||||
|
This patch adds binding of the reset controller so that the ethernet node
|
||||||
|
can have references on it.
|
||||||
|
|
||||||
|
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
|
||||||
|
|
||||||
|
diff --git a/drivers/clk/mediatek/clk-mt7623.c b/drivers/clk/mediatek/clk-mt7623.c
|
||||||
|
index c6b09d8e..87ad4f79 100644
|
||||||
|
--- a/drivers/clk/mediatek/clk-mt7623.c
|
||||||
|
+++ b/drivers/clk/mediatek/clk-mt7623.c
|
||||||
|
@@ -8,6 +8,7 @@
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
+#include <asm/arch-mediatek/reset.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <dt-bindings/clock/mt7623-clk.h>
|
||||||
|
|
||||||
|
@@ -782,6 +783,19 @@ static int mt7623_ethsys_probe(struct udevice *dev)
|
||||||
|
return mtk_common_clk_gate_init(dev, &mt7623_clk_tree, eth_cgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int mt7623_ethsys_bind(struct udevice *dev)
|
||||||
|
+{
|
||||||
|
+ int ret = 0;
|
||||||
|
+
|
||||||
|
+#if CONFIG_IS_ENABLED(RESET_MEDIATEK)
|
||||||
|
+ ret = mediatek_reset_bind(dev, ETHSYS_RST_CTRL_OFS, 1);
|
||||||
|
+ if (ret)
|
||||||
|
+ debug("Warning: failed to bind ethsys reset controller\n");
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static const struct udevice_id mt7623_apmixed_compat[] = {
|
||||||
|
{ .compatible = "mediatek,mt7623-apmixedsys" },
|
||||||
|
{ }
|
||||||
|
@@ -865,6 +879,7 @@ U_BOOT_DRIVER(mtk_clk_ethsys) = {
|
||||||
|
.id = UCLASS_CLK,
|
||||||
|
.of_match = mt7623_ethsys_compat,
|
||||||
|
.probe = mt7623_ethsys_probe,
|
||||||
|
+ .bind = mt7623_ethsys_bind,
|
||||||
|
.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
|
||||||
|
.ops = &mtk_clk_gate_ops,
|
||||||
|
};
|
||||||
|
diff --git a/drivers/clk/mediatek/clk-mt7629.c b/drivers/clk/mediatek/clk-mt7629.c
|
||||||
|
index 2601b6cf..6a9f6013 100644
|
||||||
|
--- a/drivers/clk/mediatek/clk-mt7629.c
|
||||||
|
+++ b/drivers/clk/mediatek/clk-mt7629.c
|
||||||
|
@@ -8,6 +8,7 @@
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
+#include <asm/arch-mediatek/reset.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <dt-bindings/clock/mt7629-clk.h>
|
||||||
|
|
||||||
|
@@ -602,6 +603,19 @@ static int mt7629_ethsys_probe(struct udevice *dev)
|
||||||
|
return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, eth_cgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int mt7629_ethsys_bind(struct udevice *dev)
|
||||||
|
+{
|
||||||
|
+ int ret = 0;
|
||||||
|
+
|
||||||
|
+#if CONFIG_IS_ENABLED(RESET_MEDIATEK)
|
||||||
|
+ ret = mediatek_reset_bind(dev, ETHSYS_RST_CTRL_OFS, 1);
|
||||||
|
+ if (ret)
|
||||||
|
+ debug("Warning: failed to bind ethsys reset controller\n");
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int mt7629_sgmiisys_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, sgmii_cgs);
|
||||||
|
@@ -695,6 +709,7 @@ U_BOOT_DRIVER(mtk_clk_ethsys) = {
|
||||||
|
.id = UCLASS_CLK,
|
||||||
|
.of_match = mt7629_ethsys_compat,
|
||||||
|
.probe = mt7629_ethsys_probe,
|
||||||
|
+ .bind = mt7629_ethsys_bind,
|
||||||
|
.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
|
||||||
|
.ops = &mtk_clk_gate_ops,
|
||||||
|
};
|
||||||
|
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
|
||||||
|
index 74152ed9..7847388b 100644
|
||||||
|
--- a/drivers/clk/mediatek/clk-mtk.h
|
||||||
|
+++ b/drivers/clk/mediatek/clk-mtk.h
|
||||||
|
@@ -23,6 +23,8 @@
|
||||||
|
#define CLK_PARENT_TOPCKGEN BIT(5)
|
||||||
|
#define CLK_PARENT_MASK GENMASK(5, 4)
|
||||||
|
|
||||||
|
+#define ETHSYS_RST_CTRL_OFS 0x34
|
||||||
|
+
|
||||||
|
/* struct mtk_pll_data - hardware-specific PLLs data */
|
||||||
|
struct mtk_pll_data {
|
||||||
|
const int id;
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,76 @@
|
||||||
|
From fbdf1c37235d4a5a50eaafff41cacff4fd3a6e9f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Weijie Gao <weijie.gao@mediatek.com>
|
||||||
|
Date: Thu, 20 Dec 2018 16:12:54 +0800
|
||||||
|
Subject: arm: dts: add ethernet related node for MT7623 SoC
|
||||||
|
|
||||||
|
This patch adds ethernet gmac node for MT7623 with MT7530 gigabit switch.
|
||||||
|
|
||||||
|
Signed-off-by: Mark Lee <Mark-MC.Lee@mediatek.com>
|
||||||
|
|
||||||
|
diff --git a/arch/arm/dts/mt7623.dtsi b/arch/arm/dts/mt7623.dtsi
|
||||||
|
index f50f4ef1..448d1d73 100644
|
||||||
|
--- a/arch/arm/dts/mt7623.dtsi
|
||||||
|
+++ b/arch/arm/dts/mt7623.dtsi
|
||||||
|
@@ -10,6 +10,7 @@
|
||||||
|
#include <dt-bindings/interrupt-controller/irq.h>
|
||||||
|
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||||
|
#include <dt-bindings/power/mt7623-power.h>
|
||||||
|
+#include <dt-bindings/reset/mtk-reset.h>
|
||||||
|
#include "skeleton.dtsi"
|
||||||
|
|
||||||
|
/ {
|
||||||
|
@@ -248,8 +249,26 @@
|
||||||
|
};
|
||||||
|
|
||||||
|
ethsys: syscon@1b000000 {
|
||||||
|
- compatible = "mediatek,mt7623-ethsys";
|
||||||
|
+ compatible = "mediatek,mt7623-ethsys", "syscon";
|
||||||
|
reg = <0x1b000000 0x1000>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
+ #reset-cells = <1>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ eth: ethernet@1b100000 {
|
||||||
|
+ compatible = "mediatek,mt7623-eth", "syscon";
|
||||||
|
+ reg = <0x1b100000 0x20000>;
|
||||||
|
+ clocks = <&topckgen CLK_TOP_ETHIF_SEL>,
|
||||||
|
+ <ðsys CLK_ETHSYS_ESW>,
|
||||||
|
+ <ðsys CLK_ETHSYS_GP1>,
|
||||||
|
+ <ðsys CLK_ETHSYS_GP2>,
|
||||||
|
+ <&apmixedsys CLK_APMIXED_TRGPLL>;
|
||||||
|
+ clock-names = "ethif", "esw", "gp1", "gp2", "trgpll";
|
||||||
|
+ power-domains = <&scpsys MT7623_POWER_DOMAIN_ETH>;
|
||||||
|
+ resets = <ðsys ETHSYS_FE_RST>,
|
||||||
|
+ <ðsys ETHSYS_MCM_RST>;
|
||||||
|
+ reset-names = "fe", "mcm";
|
||||||
|
+ mediatek,ethsys = <ðsys>;
|
||||||
|
+ status = "disabled";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
diff --git a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts
|
||||||
|
index 84a77fde..51628bb6 100644
|
||||||
|
--- a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts
|
||||||
|
+++ b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts
|
||||||
|
@@ -67,6 +67,19 @@
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
+ð {
|
||||||
|
+ status = "okay";
|
||||||
|
+ mediatek,gmac-id = <0>;
|
||||||
|
+ phy-mode = "rgmii";
|
||||||
|
+ mediatek,switch = "mt7530";
|
||||||
|
+ reset-gpios = <&gpio 33 GPIO_ACTIVE_HIGH>;
|
||||||
|
+
|
||||||
|
+ fixed-link {
|
||||||
|
+ speed = <1000>;
|
||||||
|
+ full-duplex;
|
||||||
|
+ };
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
&mmc0 {
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&mmc0_pins_default>;
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
From 038e3dc3801007f5025a2e57bb4b715c48b9590d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Weijie Gao <weijie.gao@mediatek.com>
|
||||||
|
Date: Thu, 20 Dec 2018 16:12:55 +0800
|
||||||
|
Subject: arm: dts: add ethernet related node for MT7629 SoC
|
||||||
|
|
||||||
|
This patch adds ethernet gmac node for MT7629 with internal gigabit phy.
|
||||||
|
|
||||||
|
Signed-off-by: Mark Lee <Mark-MC.Lee@mediatek.com>
|
||||||
|
|
||||||
|
diff --git a/arch/arm/dts/mt7629-rfb.dts b/arch/arm/dts/mt7629-rfb.dts
|
||||||
|
index a6d28a06..95d10aa6 100644
|
||||||
|
--- a/arch/arm/dts/mt7629-rfb.dts
|
||||||
|
+++ b/arch/arm/dts/mt7629-rfb.dts
|
||||||
|
@@ -22,6 +22,17 @@
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
+ð {
|
||||||
|
+ status = "okay";
|
||||||
|
+ mediatek,gmac-id = <1>;
|
||||||
|
+ phy-mode = "gmii";
|
||||||
|
+ phy-handle = <&phy0>;
|
||||||
|
+
|
||||||
|
+ phy0: ethernet-phy@0 {
|
||||||
|
+ reg = <0>;
|
||||||
|
+ };
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
&pinctrl {
|
||||||
|
qspi_pins: qspi-pins {
|
||||||
|
mux {
|
||||||
|
diff --git a/arch/arm/dts/mt7629.dtsi b/arch/arm/dts/mt7629.dtsi
|
||||||
|
index e6052bbd..c87115e0 100644
|
||||||
|
--- a/arch/arm/dts/mt7629.dtsi
|
||||||
|
+++ b/arch/arm/dts/mt7629.dtsi
|
||||||
|
@@ -10,6 +10,7 @@
|
||||||
|
#include <dt-bindings/interrupt-controller/irq.h>
|
||||||
|
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||||
|
#include <dt-bindings/power/mt7629-power.h>
|
||||||
|
+#include <dt-bindings/reset/mtk-reset.h>
|
||||||
|
#include "skeleton.dtsi"
|
||||||
|
|
||||||
|
/ {
|
||||||
|
@@ -228,6 +229,48 @@
|
||||||
|
compatible = "mediatek,mt7629-ethsys", "syscon";
|
||||||
|
reg = <0x1b000000 0x1000>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
+ #reset-cells = <1>;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ eth: ethernet@1b100000 {
|
||||||
|
+ compatible = "mediatek,mt7629-eth", "syscon";
|
||||||
|
+ reg = <0x1b100000 0x20000>;
|
||||||
|
+ clocks = <&topckgen CLK_TOP_ETH_SEL>,
|
||||||
|
+ <&topckgen CLK_TOP_F10M_REF_SEL>,
|
||||||
|
+ <ðsys CLK_ETH_ESW_EN>,
|
||||||
|
+ <ðsys CLK_ETH_GP0_EN>,
|
||||||
|
+ <ðsys CLK_ETH_GP1_EN>,
|
||||||
|
+ <ðsys CLK_ETH_GP2_EN>,
|
||||||
|
+ <ðsys CLK_ETH_FE_EN>,
|
||||||
|
+ <&sgmiisys0 CLK_SGMII_TX_EN>,
|
||||||
|
+ <&sgmiisys0 CLK_SGMII_RX_EN>,
|
||||||
|
+ <&sgmiisys0 CLK_SGMII_CDR_REF>,
|
||||||
|
+ <&sgmiisys0 CLK_SGMII_CDR_FB>,
|
||||||
|
+ <&sgmiisys1 CLK_SGMII_TX_EN>,
|
||||||
|
+ <&sgmiisys1 CLK_SGMII_RX_EN>,
|
||||||
|
+ <&sgmiisys1 CLK_SGMII_CDR_REF>,
|
||||||
|
+ <&sgmiisys1 CLK_SGMII_CDR_FB>,
|
||||||
|
+ <&apmixedsys CLK_APMIXED_SGMIPLL>,
|
||||||
|
+ <&apmixedsys CLK_APMIXED_ETH2PLL>;
|
||||||
|
+ clock-names = "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2",
|
||||||
|
+ "fe", "sgmii_tx250m", "sgmii_rx250m",
|
||||||
|
+ "sgmii_cdr_ref", "sgmii_cdr_fb",
|
||||||
|
+ "sgmii2_tx250m", "sgmii2_rx250m",
|
||||||
|
+ "sgmii2_cdr_ref", "sgmii2_cdr_fb",
|
||||||
|
+ "sgmii_ck", "eth2pll";
|
||||||
|
+ assigned-clocks = <&topckgen CLK_TOP_ETH_SEL>,
|
||||||
|
+ <&topckgen CLK_TOP_F10M_REF_SEL>;
|
||||||
|
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>,
|
||||||
|
+ <&topckgen CLK_TOP_SGMIIPLL_D2>;
|
||||||
|
+ power-domains = <&scpsys MT7629_POWER_DOMAIN_ETHSYS>;
|
||||||
|
+ resets = <ðsys ETHSYS_FE_RST>;
|
||||||
|
+ reset-names = "fe";
|
||||||
|
+ mediatek,ethsys = <ðsys>;
|
||||||
|
+ mediatek,sgmiisys = <&sgmiisys0>;
|
||||||
|
+ mediatek,infracfg = <&infracfg>;
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <0>;
|
||||||
|
+ status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
sgmiisys0: syscon@1b128000 {
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
From 8da1e0fd083f4c6a71f6735c06698e71250bcc07 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Weijie Gao <weijie.gao@mediatek.com>
|
||||||
|
Date: Thu, 20 Dec 2018 16:12:56 +0800
|
||||||
|
Subject: arm: MediaTek: add ethernet support for MT7623 boards
|
||||||
|
|
||||||
|
Enable ethernet related configs to mt7623n_bpir2_defconfig.
|
||||||
|
Add default IP addresses.
|
||||||
|
Enable noncached memory region required by ethernet driver.
|
||||||
|
|
||||||
|
Signed-off-by: Mark Lee <Mark-MC.Lee@mediatek.com>
|
||||||
|
|
||||||
|
diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig
|
||||||
|
index 74252cd0..bb67f328 100644
|
||||||
|
--- a/configs/mt7623n_bpir2_defconfig
|
||||||
|
+++ b/configs/mt7623n_bpir2_defconfig
|
||||||
|
@@ -29,6 +29,7 @@ CONFIG_CMD_FAT=y
|
||||||
|
CONFIG_CMD_FS_GENERIC=y
|
||||||
|
CONFIG_OF_EMBED=y
|
||||||
|
CONFIG_DEFAULT_DEVICE_TREE="mt7623n-bananapi-bpi-r2"
|
||||||
|
+CONFIG_NET_RANDOM_ETHADDR=y
|
||||||
|
CONFIG_REGMAP=y
|
||||||
|
CONFIG_SYSCON=y
|
||||||
|
# CONFIG_BLOCK_CACHE is not set
|
||||||
|
@@ -38,6 +39,11 @@ CONFIG_DM_MMC=y
|
||||||
|
# CONFIG_MMC_QUIRKS is not set
|
||||||
|
CONFIG_MMC_HS400_SUPPORT=y
|
||||||
|
CONFIG_MMC_MTK=y
|
||||||
|
+CONFIG_DM_RESET=y
|
||||||
|
+CONFIG_RESET_MEDIATEK=y
|
||||||
|
+CONFIG_PHY_FIXED=y
|
||||||
|
+CONFIG_DM_ETH=y
|
||||||
|
+CONFIG_MEDIATEK_ETH=y
|
||||||
|
CONFIG_PINCTRL=y
|
||||||
|
CONFIG_PINCONF=y
|
||||||
|
CONFIG_PINCTRL_MT7623=y
|
||||||
|
diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h
|
||||||
|
index fb6ac073..7d26debb 100644
|
||||||
|
--- a/include/configs/mt7623.h
|
||||||
|
+++ b/include/configs/mt7623.h
|
||||||
|
@@ -24,6 +24,7 @@
|
||||||
|
|
||||||
|
/* Size of malloc() pool */
|
||||||
|
#define CONFIG_SYS_MALLOC_LEN SZ_4M
|
||||||
|
+#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M
|
||||||
|
|
||||||
|
/* Environment */
|
||||||
|
#define CONFIG_ENV_SIZE SZ_4K
|
||||||
|
@@ -56,4 +57,8 @@
|
||||||
|
#define CONFIG_SYS_MMC_ENV_DEV 0
|
||||||
|
#define CONFIG_ENV_OFFSET 0x100000
|
||||||
|
|
||||||
|
+/* Ethernet */
|
||||||
|
+#define CONFIG_IPADDR 192.168.1.1
|
||||||
|
+#define CONFIG_SERVERIP 192.168.1.2
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
From 0fcb7ab842170e1ea7e9bf4d309af584b1e54388 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Weijie Gao <weijie.gao@mediatek.com>
|
||||||
|
Date: Thu, 20 Dec 2018 16:12:57 +0800
|
||||||
|
Subject: arm: MediaTek: add ethernet support for MT7629 boards
|
||||||
|
|
||||||
|
Enable ethernet related configs to mt7629_rfb_defconfig.
|
||||||
|
Add default IP addresses.
|
||||||
|
Enable noncached memory region required by ethernet driver.
|
||||||
|
|
||||||
|
Signed-off-by: Mark Lee <Mark-MC.Lee@mediatek.com>
|
||||||
|
|
||||||
|
diff --git a/configs/mt7629_rfb_defconfig b/configs/mt7629_rfb_defconfig
|
||||||
|
index 1729d13c..fdd5f575 100644
|
||||||
|
--- a/configs/mt7629_rfb_defconfig
|
||||||
|
+++ b/configs/mt7629_rfb_defconfig
|
||||||
|
@@ -32,6 +32,7 @@ CONFIG_CMD_PING=y
|
||||||
|
CONFIG_OF_EMBED=y
|
||||||
|
CONFIG_DEFAULT_DEVICE_TREE="mt7629-rfb"
|
||||||
|
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-parents"
|
||||||
|
+CONFIG_NET_RANDOM_ETHADDR=y
|
||||||
|
CONFIG_SPL_DM_SEQ_ALIAS=y
|
||||||
|
CONFIG_REGMAP=y
|
||||||
|
CONFIG_SPL_REGMAP=y
|
||||||
|
@@ -51,6 +52,10 @@ CONFIG_SPI_FLASH_MACRONIX=y
|
||||||
|
CONFIG_SPI_FLASH_SPANSION=y
|
||||||
|
CONFIG_SPI_FLASH_STMICRO=y
|
||||||
|
CONFIG_SPI_FLASH_WINBOND=y
|
||||||
|
+CONFIG_DM_RESET=y
|
||||||
|
+CONFIG_RESET_MEDIATEK=y
|
||||||
|
+CONFIG_DM_ETH=y
|
||||||
|
+CONFIG_MEDIATEK_ETH=y
|
||||||
|
CONFIG_PINCTRL=y
|
||||||
|
CONFIG_PINCONF=y
|
||||||
|
CONFIG_PINCTRL_MT7629=y
|
||||||
|
diff --git a/include/configs/mt7629.h b/include/configs/mt7629.h
|
||||||
|
index a665a5eb..9910d8c8 100644
|
||||||
|
--- a/include/configs/mt7629.h
|
||||||
|
+++ b/include/configs/mt7629.h
|
||||||
|
@@ -24,6 +24,7 @@
|
||||||
|
|
||||||
|
/* Size of malloc() pool */
|
||||||
|
#define CONFIG_SYS_MALLOC_LEN SZ_4M
|
||||||
|
+#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M
|
||||||
|
|
||||||
|
/* Environment */
|
||||||
|
#define CONFIG_ENV_SIZE SZ_4K
|
||||||
|
@@ -54,4 +55,8 @@
|
||||||
|
/* DRAM */
|
||||||
|
#define CONFIG_SYS_SDRAM_BASE 0x40000000
|
||||||
|
|
||||||
|
+/* Ethernet */
|
||||||
|
+#define CONFIG_IPADDR 192.168.1.1
|
||||||
|
+#define CONFIG_SERVERIP 192.168.1.2
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
From 31ca82655b5f623303e45508a820205b071df258 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Weijie Gao <weijie.gao@mediatek.com>
|
||||||
|
Date: Thu, 20 Dec 2018 16:12:58 +0800
|
||||||
|
Subject: MAINTAINERS: ARM MEDIATEK: update file entries
|
||||||
|
|
||||||
|
This patch adds new file entries for MediaTek SoCs
|
||||||
|
|
||||||
|
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
|
||||||
|
|
||||||
|
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||||
|
index f86fdf9c..e192db07 100644
|
||||||
|
--- a/MAINTAINERS
|
||||||
|
+++ b/MAINTAINERS
|
||||||
|
@@ -176,6 +176,8 @@ F: drivers/ram/mediatek/
|
||||||
|
F: drivers/spi/mtk_qspi.c
|
||||||
|
F: drivers/timer/mtk_timer.c
|
||||||
|
F: drivers/watchdog/mtk_wdt.c
|
||||||
|
+F: drivers/net/mtk_eth.c
|
||||||
|
+F: drivers/reset/reset-mediatek.c
|
||||||
|
F: tools/mtk_image.c
|
||||||
|
F: tools/mtk_image.h
|
||||||
|
N: mediatek
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
From d4b93c443372d651bd6f8b78070c54338ee35b91 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Weijie Gao <weijie.gao@mediatek.com>
|
||||||
|
Date: Thu, 20 Dec 2018 16:12:59 +0800
|
||||||
|
Subject: configs: MediaTek: use OF_SEPARATE instead of OF_EMBED
|
||||||
|
|
||||||
|
This patch replace OF_EMBED with OF_SEPARATE of defconfig files of
|
||||||
|
MediaTek boards because now OF_EMBED is only used for debugging purpose.
|
||||||
|
|
||||||
|
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
|
||||||
|
Reviewed-by: Simon Glass <sjg@chromium.org>
|
||||||
|
|
||||||
|
diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig
|
||||||
|
index bb67f328..a9f4506e 100644
|
||||||
|
--- a/configs/mt7623n_bpir2_defconfig
|
||||||
|
+++ b/configs/mt7623n_bpir2_defconfig
|
||||||
|
@@ -27,7 +27,7 @@ CONFIG_CMD_READ=y
|
||||||
|
CONFIG_CMD_PING=y
|
||||||
|
CONFIG_CMD_FAT=y
|
||||||
|
CONFIG_CMD_FS_GENERIC=y
|
||||||
|
-CONFIG_OF_EMBED=y
|
||||||
|
+CONFIG_OF_SEPARATE=y
|
||||||
|
CONFIG_DEFAULT_DEVICE_TREE="mt7623n-bananapi-bpi-r2"
|
||||||
|
CONFIG_NET_RANDOM_ETHADDR=y
|
||||||
|
CONFIG_REGMAP=y
|
||||||
|
diff --git a/configs/mt7629_rfb_defconfig b/configs/mt7629_rfb_defconfig
|
||||||
|
index fdd5f575..1da9932d 100644
|
||||||
|
--- a/configs/mt7629_rfb_defconfig
|
||||||
|
+++ b/configs/mt7629_rfb_defconfig
|
||||||
|
@@ -29,7 +29,7 @@ CONFIG_CMD_SF_TEST=y
|
||||||
|
# CONFIG_CMD_NFS is not set
|
||||||
|
CONFIG_CMD_PING=y
|
||||||
|
# CONFIG_PARTITIONS is not set
|
||||||
|
-CONFIG_OF_EMBED=y
|
||||||
|
+CONFIG_OF_SEPARATE=y
|
||||||
|
CONFIG_DEFAULT_DEVICE_TREE="mt7629-rfb"
|
||||||
|
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-parents"
|
||||||
|
CONFIG_NET_RANDOM_ETHADDR=y
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,326 @@
|
||||||
|
From d6755b9b0e59ea0193914e169f74df51d556fbb7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
Date: Mon, 14 Jan 2019 22:38:14 +0100
|
||||||
|
Subject: test: add test for lib/lmb.c
|
||||||
|
|
||||||
|
Add basic tests for the lmb memory allocation code used to reserve and
|
||||||
|
allocate memory during boot.
|
||||||
|
|
||||||
|
Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
Reviewed-by: Simon Glass <sjg@chromium.org>
|
||||||
|
|
||||||
|
diff --git a/test/lib/Makefile b/test/lib/Makefile
|
||||||
|
index ea68fae5..5a636aac 100644
|
||||||
|
--- a/test/lib/Makefile
|
||||||
|
+++ b/test/lib/Makefile
|
||||||
|
@@ -3,3 +3,4 @@
|
||||||
|
# (C) Copyright 2018
|
||||||
|
# Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
||||||
|
obj-y += hexdump.o
|
||||||
|
+obj-y += lmb.o
|
||||||
|
diff --git a/test/lib/lmb.c b/test/lib/lmb.c
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..dd7ba14b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/lib/lmb.c
|
||||||
|
@@ -0,0 +1,297 @@
|
||||||
|
+// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
+/*
|
||||||
|
+ * (C) Copyright 2018 Simon Goldschmidt
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <common.h>
|
||||||
|
+#include <lmb.h>
|
||||||
|
+#include <dm/test.h>
|
||||||
|
+#include <test/ut.h>
|
||||||
|
+
|
||||||
|
+static int check_lmb(struct unit_test_state *uts, struct lmb *lmb,
|
||||||
|
+ phys_addr_t ram_base, phys_size_t ram_size,
|
||||||
|
+ unsigned long num_reserved,
|
||||||
|
+ phys_addr_t base1, phys_size_t size1,
|
||||||
|
+ phys_addr_t base2, phys_size_t size2,
|
||||||
|
+ phys_addr_t base3, phys_size_t size3)
|
||||||
|
+{
|
||||||
|
+ ut_asserteq(lmb->memory.cnt, 1);
|
||||||
|
+ ut_asserteq(lmb->memory.region[0].base, ram_base);
|
||||||
|
+ ut_asserteq(lmb->memory.region[0].size, ram_size);
|
||||||
|
+
|
||||||
|
+ ut_asserteq(lmb->reserved.cnt, num_reserved);
|
||||||
|
+ if (num_reserved > 0) {
|
||||||
|
+ ut_asserteq(lmb->reserved.region[0].base, base1);
|
||||||
|
+ ut_asserteq(lmb->reserved.region[0].size, size1);
|
||||||
|
+ }
|
||||||
|
+ if (num_reserved > 1) {
|
||||||
|
+ ut_asserteq(lmb->reserved.region[1].base, base2);
|
||||||
|
+ ut_asserteq(lmb->reserved.region[1].size, size2);
|
||||||
|
+ }
|
||||||
|
+ if (num_reserved > 2) {
|
||||||
|
+ ut_asserteq(lmb->reserved.region[2].base, base3);
|
||||||
|
+ ut_asserteq(lmb->reserved.region[2].size, size3);
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define ASSERT_LMB(lmb, ram_base, ram_size, num_reserved, base1, size1, \
|
||||||
|
+ base2, size2, base3, size3) \
|
||||||
|
+ ut_assert(!check_lmb(uts, lmb, ram_base, ram_size, \
|
||||||
|
+ num_reserved, base1, size1, base2, size2, base3, \
|
||||||
|
+ size3))
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Test helper function that reserves 64 KiB somewhere in the simulated RAM and
|
||||||
|
+ * then does some alloc + free tests.
|
||||||
|
+ */
|
||||||
|
+static int test_multi_alloc(struct unit_test_state *uts,
|
||||||
|
+ const phys_addr_t ram, const phys_size_t ram_size,
|
||||||
|
+ const phys_addr_t alloc_64k_addr)
|
||||||
|
+{
|
||||||
|
+ const phys_addr_t ram_end = ram + ram_size;
|
||||||
|
+ const phys_addr_t alloc_64k_end = alloc_64k_addr + 0x10000;
|
||||||
|
+
|
||||||
|
+ struct lmb lmb;
|
||||||
|
+ long ret;
|
||||||
|
+ phys_addr_t a, a2, b, b2, c, d;
|
||||||
|
+
|
||||||
|
+ /* check for overflow */
|
||||||
|
+ ut_assert(ram_end == 0 || ram_end > ram);
|
||||||
|
+ ut_assert(alloc_64k_end > alloc_64k_addr);
|
||||||
|
+ /* check input addresses + size */
|
||||||
|
+ ut_assert(alloc_64k_addr >= ram + 8);
|
||||||
|
+ ut_assert(alloc_64k_end <= ram_end - 8);
|
||||||
|
+
|
||||||
|
+ lmb_init(&lmb);
|
||||||
|
+
|
||||||
|
+ ret = lmb_add(&lmb, ram, ram_size);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+
|
||||||
|
+ /* reserve 64KiB somewhere */
|
||||||
|
+ ret = lmb_reserve(&lmb, alloc_64k_addr, 0x10000);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+
|
||||||
|
+ /* allocate somewhere, should be at the end of RAM */
|
||||||
|
+ a = lmb_alloc(&lmb, 4, 1);
|
||||||
|
+ ut_asserteq(a, ram_end - 4);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 2, alloc_64k_addr, 0x10000,
|
||||||
|
+ ram_end - 4, 4, 0, 0);
|
||||||
|
+ /* alloc below end of reserved region -> below reserved region */
|
||||||
|
+ b = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end);
|
||||||
|
+ ut_asserteq(b, alloc_64k_addr - 4);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 2,
|
||||||
|
+ alloc_64k_addr - 4, 0x10000 + 4, ram_end - 4, 4, 0, 0);
|
||||||
|
+
|
||||||
|
+ /* 2nd time */
|
||||||
|
+ c = lmb_alloc(&lmb, 4, 1);
|
||||||
|
+ ut_asserteq(c, ram_end - 8);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 2,
|
||||||
|
+ alloc_64k_addr - 4, 0x10000 + 4, ram_end - 8, 8, 0, 0);
|
||||||
|
+ d = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end);
|
||||||
|
+ ut_asserteq(d, alloc_64k_addr - 8);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 2,
|
||||||
|
+ alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0);
|
||||||
|
+
|
||||||
|
+ ret = lmb_free(&lmb, a, 4);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 2,
|
||||||
|
+ alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
|
||||||
|
+ /* allocate again to ensure we get the same address */
|
||||||
|
+ a2 = lmb_alloc(&lmb, 4, 1);
|
||||||
|
+ ut_asserteq(a, a2);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 2,
|
||||||
|
+ alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0);
|
||||||
|
+ ret = lmb_free(&lmb, a2, 4);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 2,
|
||||||
|
+ alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
|
||||||
|
+
|
||||||
|
+ ret = lmb_free(&lmb, b, 4);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 3,
|
||||||
|
+ alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000,
|
||||||
|
+ ram_end - 8, 4);
|
||||||
|
+ /* allocate again to ensure we get the same address */
|
||||||
|
+ b2 = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end);
|
||||||
|
+ ut_asserteq(b, b2);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 2,
|
||||||
|
+ alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
|
||||||
|
+ ret = lmb_free(&lmb, b2, 4);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 3,
|
||||||
|
+ alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000,
|
||||||
|
+ ram_end - 8, 4);
|
||||||
|
+
|
||||||
|
+ ret = lmb_free(&lmb, c, 4);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 2,
|
||||||
|
+ alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, 0, 0);
|
||||||
|
+ ret = lmb_free(&lmb, d, 4);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int test_multi_alloc_512mb(struct unit_test_state *uts,
|
||||||
|
+ const phys_addr_t ram)
|
||||||
|
+{
|
||||||
|
+ return test_multi_alloc(uts, ram, 0x20000000, ram + 0x10000000);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Create a memory region with one reserved region and allocate */
|
||||||
|
+static int lib_test_lmb_simple(struct unit_test_state *uts)
|
||||||
|
+{
|
||||||
|
+ /* simulate 512 MiB RAM beginning at 1GiB */
|
||||||
|
+ return test_multi_alloc_512mb(uts, 0x40000000);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+DM_TEST(lib_test_lmb_simple, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
+
|
||||||
|
+/* Simulate 512 MiB RAM, allocate some blocks that fit/don't fit */
|
||||||
|
+static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram)
|
||||||
|
+{
|
||||||
|
+ const phys_size_t ram_size = 0x20000000;
|
||||||
|
+ const phys_size_t big_block_size = 0x10000000;
|
||||||
|
+ const phys_addr_t ram_end = ram + ram_size;
|
||||||
|
+ const phys_addr_t alloc_64k_addr = ram + 0x10000000;
|
||||||
|
+ struct lmb lmb;
|
||||||
|
+ long ret;
|
||||||
|
+ phys_addr_t a, b;
|
||||||
|
+
|
||||||
|
+ /* check for overflow */
|
||||||
|
+ ut_assert(ram_end == 0 || ram_end > ram);
|
||||||
|
+
|
||||||
|
+ lmb_init(&lmb);
|
||||||
|
+
|
||||||
|
+ ret = lmb_add(&lmb, ram, ram_size);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+
|
||||||
|
+ /* reserve 64KiB in the middle of RAM */
|
||||||
|
+ ret = lmb_reserve(&lmb, alloc_64k_addr, 0x10000);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+
|
||||||
|
+ /* allocate a big block, should be below reserved */
|
||||||
|
+ a = lmb_alloc(&lmb, big_block_size, 1);
|
||||||
|
+ ut_asserteq(a, ram);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, a,
|
||||||
|
+ big_block_size + 0x10000, 0, 0, 0, 0);
|
||||||
|
+ /* allocate 2nd big block */
|
||||||
|
+ /* This should fail, printing an error */
|
||||||
|
+ b = lmb_alloc(&lmb, big_block_size, 1);
|
||||||
|
+ ut_asserteq(b, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, a,
|
||||||
|
+ big_block_size + 0x10000, 0, 0, 0, 0);
|
||||||
|
+
|
||||||
|
+ ret = lmb_free(&lmb, a, big_block_size);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+
|
||||||
|
+ /* allocate too big block */
|
||||||
|
+ /* This should fail, printing an error */
|
||||||
|
+ a = lmb_alloc(&lmb, ram_size, 1);
|
||||||
|
+ ut_asserteq(a, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int lib_test_lmb_big(struct unit_test_state *uts)
|
||||||
|
+{
|
||||||
|
+ return test_bigblock(uts, 0x40000000);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+DM_TEST(lib_test_lmb_big, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
+
|
||||||
|
+/* Simulate 512 MiB RAM, allocate a block without previous reservation */
|
||||||
|
+static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram)
|
||||||
|
+{
|
||||||
|
+ const phys_size_t ram_size = 0x20000000;
|
||||||
|
+ const phys_addr_t ram_end = ram + ram_size;
|
||||||
|
+ struct lmb lmb;
|
||||||
|
+ long ret;
|
||||||
|
+ phys_addr_t a, b;
|
||||||
|
+
|
||||||
|
+ /* check for overflow */
|
||||||
|
+ ut_assert(ram_end == 0 || ram_end > ram);
|
||||||
|
+
|
||||||
|
+ lmb_init(&lmb);
|
||||||
|
+
|
||||||
|
+ ret = lmb_add(&lmb, ram, ram_size);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+
|
||||||
|
+ /* allocate a block */
|
||||||
|
+ a = lmb_alloc(&lmb, 4, 1);
|
||||||
|
+ ut_assert(a != 0);
|
||||||
|
+ /* and free it */
|
||||||
|
+ ret = lmb_free(&lmb, a, 4);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+
|
||||||
|
+ /* allocate a block with base*/
|
||||||
|
+ b = lmb_alloc_base(&lmb, 4, 1, ram_end);
|
||||||
|
+ ut_assert(a == b);
|
||||||
|
+ /* and free it */
|
||||||
|
+ ret = lmb_free(&lmb, b, 4);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int lib_test_lmb_noreserved(struct unit_test_state *uts)
|
||||||
|
+{
|
||||||
|
+ return test_noreserved(uts, 0x40000000);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+DM_TEST(lib_test_lmb_noreserved, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Simulate a RAM that starts at 0 and allocate down to address 0, which must
|
||||||
|
+ * fail as '0' means failure for the lmb_alloc functions.
|
||||||
|
+ */
|
||||||
|
+static int lib_test_lmb_at_0(struct unit_test_state *uts)
|
||||||
|
+{
|
||||||
|
+ const phys_addr_t ram = 0;
|
||||||
|
+ const phys_size_t ram_size = 0x20000000;
|
||||||
|
+ struct lmb lmb;
|
||||||
|
+ long ret;
|
||||||
|
+ phys_addr_t a, b;
|
||||||
|
+
|
||||||
|
+ lmb_init(&lmb);
|
||||||
|
+
|
||||||
|
+ ret = lmb_add(&lmb, ram, ram_size);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+
|
||||||
|
+ /* allocate nearly everything */
|
||||||
|
+ a = lmb_alloc(&lmb, ram_size - 4, 1);
|
||||||
|
+ ut_asserteq(a, ram + 4);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+ /* allocate the rest */
|
||||||
|
+ /* This should fail as the allocated address would be 0 */
|
||||||
|
+ b = lmb_alloc(&lmb, 4, 1);
|
||||||
|
+ ut_asserteq(b, 0);
|
||||||
|
+ /* check that this was an error by checking lmb */
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+ /* check that this was an error by freeing b */
|
||||||
|
+ ret = lmb_free(&lmb, b, 4);
|
||||||
|
+ ut_asserteq(ret, -1);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+
|
||||||
|
+ ret = lmb_free(&lmb, a, ram_size - 4);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+DM_TEST(lib_test_lmb_at_0, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
From 8d8854693b9a288c6dbcf5382e74e6ce05839b33 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
Date: Mon, 14 Jan 2019 22:38:15 +0100
|
||||||
|
Subject: lmb: fix allocation at end of address range
|
||||||
|
|
||||||
|
The lmb code fails if base + size of RAM overflows to zero.
|
||||||
|
|
||||||
|
Fix this by calculating end as 'base + size - 1' instead of 'base + size'
|
||||||
|
where appropriate.
|
||||||
|
|
||||||
|
Added tests to assert this is fixed.
|
||||||
|
|
||||||
|
Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
|
||||||
|
diff --git a/lib/lmb.c b/lib/lmb.c
|
||||||
|
index 17054173..6d3dcf4e 100644
|
||||||
|
--- a/lib/lmb.c
|
||||||
|
+++ b/lib/lmb.c
|
||||||
|
@@ -43,7 +43,10 @@ void lmb_dump_all(struct lmb *lmb)
|
||||||
|
static long lmb_addrs_overlap(phys_addr_t base1,
|
||||||
|
phys_size_t size1, phys_addr_t base2, phys_size_t size2)
|
||||||
|
{
|
||||||
|
- return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
|
||||||
|
+ const phys_addr_t base1_end = base1 + size1 - 1;
|
||||||
|
+ const phys_addr_t base2_end = base2 + size2 - 1;
|
||||||
|
+
|
||||||
|
+ return ((base1 <= base2_end) && (base2 <= base1_end));
|
||||||
|
}
|
||||||
|
|
||||||
|
static long lmb_addrs_adjacent(phys_addr_t base1, phys_size_t size1,
|
||||||
|
@@ -89,18 +92,9 @@ static void lmb_coalesce_regions(struct lmb_region *rgn,
|
||||||
|
|
||||||
|
void lmb_init(struct lmb *lmb)
|
||||||
|
{
|
||||||
|
- /* Create a dummy zero size LMB which will get coalesced away later.
|
||||||
|
- * This simplifies the lmb_add() code below...
|
||||||
|
- */
|
||||||
|
- lmb->memory.region[0].base = 0;
|
||||||
|
- lmb->memory.region[0].size = 0;
|
||||||
|
- lmb->memory.cnt = 1;
|
||||||
|
+ lmb->memory.cnt = 0;
|
||||||
|
lmb->memory.size = 0;
|
||||||
|
-
|
||||||
|
- /* Ditto. */
|
||||||
|
- lmb->reserved.region[0].base = 0;
|
||||||
|
- lmb->reserved.region[0].size = 0;
|
||||||
|
- lmb->reserved.cnt = 1;
|
||||||
|
+ lmb->reserved.cnt = 0;
|
||||||
|
lmb->reserved.size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -110,9 +104,10 @@ static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t
|
||||||
|
unsigned long coalesced = 0;
|
||||||
|
long adjacent, i;
|
||||||
|
|
||||||
|
- if ((rgn->cnt == 1) && (rgn->region[0].size == 0)) {
|
||||||
|
+ if (rgn->cnt == 0) {
|
||||||
|
rgn->region[0].base = base;
|
||||||
|
rgn->region[0].size = size;
|
||||||
|
+ rgn->cnt = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -183,7 +178,7 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size)
|
||||||
|
{
|
||||||
|
struct lmb_region *rgn = &(lmb->reserved);
|
||||||
|
phys_addr_t rgnbegin, rgnend;
|
||||||
|
- phys_addr_t end = base + size;
|
||||||
|
+ phys_addr_t end = base + size - 1;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
rgnbegin = rgnend = 0; /* supress gcc warnings */
|
||||||
|
@@ -191,7 +186,7 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size)
|
||||||
|
/* Find the region where (base, size) belongs to */
|
||||||
|
for (i=0; i < rgn->cnt; i++) {
|
||||||
|
rgnbegin = rgn->region[i].base;
|
||||||
|
- rgnend = rgnbegin + rgn->region[i].size;
|
||||||
|
+ rgnend = rgnbegin + rgn->region[i].size - 1;
|
||||||
|
|
||||||
|
if ((rgnbegin <= base) && (end <= rgnend))
|
||||||
|
break;
|
||||||
|
@@ -209,7 +204,7 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size)
|
||||||
|
|
||||||
|
/* Check to see if region is matching at the front */
|
||||||
|
if (rgnbegin == base) {
|
||||||
|
- rgn->region[i].base = end;
|
||||||
|
+ rgn->region[i].base = end + 1;
|
||||||
|
rgn->region[i].size -= size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -225,7 +220,7 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size)
|
||||||
|
* beginging of the hole and add the region after hole.
|
||||||
|
*/
|
||||||
|
rgn->region[i].size = base - rgn->region[i].base;
|
||||||
|
- return lmb_add_region(rgn, end, rgnend - end);
|
||||||
|
+ return lmb_add_region(rgn, end + 1, rgnend - end);
|
||||||
|
}
|
||||||
|
|
||||||
|
long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size)
|
||||||
|
diff --git a/test/lib/lmb.c b/test/lib/lmb.c
|
||||||
|
index dd7ba14b..fb7ca45e 100644
|
||||||
|
--- a/test/lib/lmb.c
|
||||||
|
+++ b/test/lib/lmb.c
|
||||||
|
@@ -146,8 +146,15 @@ static int test_multi_alloc_512mb(struct unit_test_state *uts,
|
||||||
|
/* Create a memory region with one reserved region and allocate */
|
||||||
|
static int lib_test_lmb_simple(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
/* simulate 512 MiB RAM beginning at 1GiB */
|
||||||
|
- return test_multi_alloc_512mb(uts, 0x40000000);
|
||||||
|
+ ret = test_multi_alloc_512mb(uts, 0x40000000);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ /* simulate 512 MiB RAM beginning at 1.5GiB */
|
||||||
|
+ return test_multi_alloc_512mb(uts, 0xE0000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
DM_TEST(lib_test_lmb_simple, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
@@ -206,7 +213,15 @@ static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram)
|
||||||
|
|
||||||
|
static int lib_test_lmb_big(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
- return test_bigblock(uts, 0x40000000);
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ /* simulate 512 MiB RAM beginning at 1GiB */
|
||||||
|
+ ret = test_bigblock(uts, 0x40000000);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ /* simulate 512 MiB RAM beginning at 1.5GiB */
|
||||||
|
+ return test_bigblock(uts, 0xE0000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
DM_TEST(lib_test_lmb_big, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
@@ -247,7 +262,15 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram)
|
||||||
|
|
||||||
|
static int lib_test_lmb_noreserved(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
- return test_noreserved(uts, 0x40000000);
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ /* simulate 512 MiB RAM beginning at 1GiB */
|
||||||
|
+ ret = test_noreserved(uts, 0x40000000);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ /* simulate 512 MiB RAM beginning at 1.5GiB */
|
||||||
|
+ return test_noreserved(uts, 0xE0000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
DM_TEST(lib_test_lmb_noreserved, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,208 @@
|
||||||
|
From 0b66765ffcdc995177753b7e6607be477593041e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
Date: Mon, 14 Jan 2019 22:38:16 +0100
|
||||||
|
Subject: lib: lmb: reserving overlapping regions should fail
|
||||||
|
|
||||||
|
lmb_add_region handles overlapping regions wrong: instead of merging
|
||||||
|
or rejecting to add a new reserved region that overlaps an existing
|
||||||
|
one, it just adds the new region.
|
||||||
|
|
||||||
|
Since internally the same function is used for lmb_alloc, change
|
||||||
|
lmb_add_region to reject overlapping regions.
|
||||||
|
|
||||||
|
Also, to keep reserved memory correct after 'free', reserved entries
|
||||||
|
created by allocating memory must not set their size to a multiple
|
||||||
|
of alignment but to the original size. This ensures the reserved
|
||||||
|
region is completely removed when the caller calls 'lmb_free', as
|
||||||
|
this one takes the same size as passed to 'lmb_alloc' etc.
|
||||||
|
|
||||||
|
Add test to assert this.
|
||||||
|
|
||||||
|
Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
|
||||||
|
diff --git a/lib/lmb.c b/lib/lmb.c
|
||||||
|
index 6d3dcf4e..cd297f82 100644
|
||||||
|
--- a/lib/lmb.c
|
||||||
|
+++ b/lib/lmb.c
|
||||||
|
@@ -131,6 +131,9 @@ static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t
|
||||||
|
rgn->region[i].size += size;
|
||||||
|
coalesced++;
|
||||||
|
break;
|
||||||
|
+ } else if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) {
|
||||||
|
+ /* regions overlap */
|
||||||
|
+ return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -269,11 +272,6 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size)
|
||||||
|
return addr & ~(size - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static phys_addr_t lmb_align_up(phys_addr_t addr, ulong size)
|
||||||
|
-{
|
||||||
|
- return (addr + (size - 1)) & ~(size - 1);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr)
|
||||||
|
{
|
||||||
|
long i, j;
|
||||||
|
@@ -302,8 +300,7 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phy
|
||||||
|
if (j < 0) {
|
||||||
|
/* This area isn't reserved, take it */
|
||||||
|
if (lmb_add_region(&lmb->reserved, base,
|
||||||
|
- lmb_align_up(size,
|
||||||
|
- align)) < 0)
|
||||||
|
+ size) < 0)
|
||||||
|
return 0;
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
diff --git a/test/lib/lmb.c b/test/lib/lmb.c
|
||||||
|
index fb7ca45e..e6acb70e 100644
|
||||||
|
--- a/test/lib/lmb.c
|
||||||
|
+++ b/test/lib/lmb.c
|
||||||
|
@@ -227,13 +227,16 @@ static int lib_test_lmb_big(struct unit_test_state *uts)
|
||||||
|
DM_TEST(lib_test_lmb_big, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
|
||||||
|
/* Simulate 512 MiB RAM, allocate a block without previous reservation */
|
||||||
|
-static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram)
|
||||||
|
+static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram,
|
||||||
|
+ const phys_addr_t alloc_size, const ulong align)
|
||||||
|
{
|
||||||
|
const phys_size_t ram_size = 0x20000000;
|
||||||
|
const phys_addr_t ram_end = ram + ram_size;
|
||||||
|
struct lmb lmb;
|
||||||
|
long ret;
|
||||||
|
phys_addr_t a, b;
|
||||||
|
+ const phys_addr_t alloc_size_aligned = (alloc_size + align - 1) &
|
||||||
|
+ ~(align - 1);
|
||||||
|
|
||||||
|
/* check for overflow */
|
||||||
|
ut_assert(ram_end == 0 || ram_end > ram);
|
||||||
|
@@ -242,20 +245,43 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram)
|
||||||
|
|
||||||
|
ret = lmb_add(&lmb, ram, ram_size);
|
||||||
|
ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
/* allocate a block */
|
||||||
|
- a = lmb_alloc(&lmb, 4, 1);
|
||||||
|
+ a = lmb_alloc(&lmb, alloc_size, align);
|
||||||
|
ut_assert(a != 0);
|
||||||
|
- /* and free it */
|
||||||
|
- ret = lmb_free(&lmb, a, 4);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned,
|
||||||
|
+ alloc_size, 0, 0, 0, 0);
|
||||||
|
+ /* allocate another block */
|
||||||
|
+ b = lmb_alloc(&lmb, alloc_size, align);
|
||||||
|
+ ut_assert(b != 0);
|
||||||
|
+ if (alloc_size == alloc_size_aligned) {
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size -
|
||||||
|
+ (alloc_size_aligned * 2), alloc_size * 2, 0, 0, 0,
|
||||||
|
+ 0);
|
||||||
|
+ } else {
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 2, ram + ram_size -
|
||||||
|
+ (alloc_size_aligned * 2), alloc_size, ram + ram_size
|
||||||
|
+ - alloc_size_aligned, alloc_size, 0, 0);
|
||||||
|
+ }
|
||||||
|
+ /* and free them */
|
||||||
|
+ ret = lmb_free(&lmb, b, alloc_size);
|
||||||
|
ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned,
|
||||||
|
+ alloc_size, 0, 0, 0, 0);
|
||||||
|
+ ret = lmb_free(&lmb, a, alloc_size);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
/* allocate a block with base*/
|
||||||
|
- b = lmb_alloc_base(&lmb, 4, 1, ram_end);
|
||||||
|
+ b = lmb_alloc_base(&lmb, alloc_size, align, ram_end);
|
||||||
|
ut_assert(a == b);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned,
|
||||||
|
+ alloc_size, 0, 0, 0, 0);
|
||||||
|
/* and free it */
|
||||||
|
- ret = lmb_free(&lmb, b, 4);
|
||||||
|
+ ret = lmb_free(&lmb, b, alloc_size);
|
||||||
|
ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -265,16 +291,30 @@ static int lib_test_lmb_noreserved(struct unit_test_state *uts)
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* simulate 512 MiB RAM beginning at 1GiB */
|
||||||
|
- ret = test_noreserved(uts, 0x40000000);
|
||||||
|
+ ret = test_noreserved(uts, 0x40000000, 4, 1);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* simulate 512 MiB RAM beginning at 1.5GiB */
|
||||||
|
- return test_noreserved(uts, 0xE0000000);
|
||||||
|
+ return test_noreserved(uts, 0xE0000000, 4, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
DM_TEST(lib_test_lmb_noreserved, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
|
||||||
|
+static int lib_test_lmb_unaligned_size(struct unit_test_state *uts)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ /* simulate 512 MiB RAM beginning at 1GiB */
|
||||||
|
+ ret = test_noreserved(uts, 0x40000000, 5, 8);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ /* simulate 512 MiB RAM beginning at 1.5GiB */
|
||||||
|
+ return test_noreserved(uts, 0xE0000000, 5, 8);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+DM_TEST(lib_test_lmb_unaligned_size, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
/*
|
||||||
|
* Simulate a RAM that starts at 0 and allocate down to address 0, which must
|
||||||
|
* fail as '0' means failure for the lmb_alloc functions.
|
||||||
|
@@ -318,3 +358,42 @@ static int lib_test_lmb_at_0(struct unit_test_state *uts)
|
||||||
|
}
|
||||||
|
|
||||||
|
DM_TEST(lib_test_lmb_at_0, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
+
|
||||||
|
+/* Check that calling lmb_reserve with overlapping regions fails. */
|
||||||
|
+static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts)
|
||||||
|
+{
|
||||||
|
+ const phys_addr_t ram = 0x40000000;
|
||||||
|
+ const phys_size_t ram_size = 0x20000000;
|
||||||
|
+ struct lmb lmb;
|
||||||
|
+ long ret;
|
||||||
|
+
|
||||||
|
+ lmb_init(&lmb);
|
||||||
|
+
|
||||||
|
+ ret = lmb_add(&lmb, ram, ram_size);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+
|
||||||
|
+ ret = lmb_reserve(&lmb, 0x40010000, 0x10000);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+ /* allocate overlapping region should fail */
|
||||||
|
+ ret = lmb_reserve(&lmb, 0x40011000, 0x10000);
|
||||||
|
+ ut_asserteq(ret, -1);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+ /* allocate 3nd region */
|
||||||
|
+ ret = lmb_reserve(&lmb, 0x40030000, 0x10000);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40010000, 0x10000,
|
||||||
|
+ 0x40030000, 0x10000, 0, 0);
|
||||||
|
+ /* allocate 2nd region */
|
||||||
|
+ ret = lmb_reserve(&lmb, 0x40020000, 0x10000);
|
||||||
|
+ ut_assert(ret >= 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x30000,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+DM_TEST(lib_test_lmb_overlapping_reserve,
|
||||||
|
+ DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
From 83dc6df2cff9e91e77890107c74d4858182e4b61 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
Date: Mon, 14 Jan 2019 22:38:17 +0100
|
||||||
|
Subject: fdt: parse "reserved-memory" for memory reservation
|
||||||
|
|
||||||
|
boot_fdt_add_mem_rsv_regions() adds reserved memory sections to an lmb
|
||||||
|
struct. Currently, it only parses regions described by /memreserve/
|
||||||
|
entries.
|
||||||
|
|
||||||
|
Extend this to the more commonly used scheme of the "reserved-memory"
|
||||||
|
node.
|
||||||
|
|
||||||
|
Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
Reviewed-by: Simon Glass <sjg@chromium.org>
|
||||||
|
|
||||||
|
diff --git a/common/image-fdt.c b/common/image-fdt.c
|
||||||
|
index 95748f0a..5c0d6db3 100644
|
||||||
|
--- a/common/image-fdt.c
|
||||||
|
+++ b/common/image-fdt.c
|
||||||
|
@@ -10,6 +10,7 @@
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <fdt_support.h>
|
||||||
|
+#include <fdtdec.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <image.h>
|
||||||
|
#include <linux/libfdt.h>
|
||||||
|
@@ -67,30 +68,66 @@ static const image_header_t *image_get_fdt(ulong fdt_addr)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+static void boot_fdt_reserve_region(struct lmb *lmb, uint64_t addr,
|
||||||
|
+ uint64_t size)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = lmb_reserve(lmb, addr, size);
|
||||||
|
+ if (!ret) {
|
||||||
|
+ debug(" reserving fdt memory region: addr=%llx size=%llx\n",
|
||||||
|
+ (unsigned long long)addr, (unsigned long long)size);
|
||||||
|
+ } else {
|
||||||
|
+ puts("ERROR: reserving fdt memory region failed ");
|
||||||
|
+ printf("(addr=%llx size=%llx)\n",
|
||||||
|
+ (unsigned long long)addr, (unsigned long long)size);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
- * boot_fdt_add_mem_rsv_regions - Mark the memreserve sections as unusable
|
||||||
|
+ * boot_fdt_add_mem_rsv_regions - Mark the memreserve and reserved-memory
|
||||||
|
+ * sections as unusable
|
||||||
|
* @lmb: pointer to lmb handle, will be used for memory mgmt
|
||||||
|
* @fdt_blob: pointer to fdt blob base address
|
||||||
|
*
|
||||||
|
- * Adds the memreserve regions in the dtb to the lmb block. Adding the
|
||||||
|
- * memreserve regions prevents u-boot from using them to store the initrd
|
||||||
|
- * or the fdt blob.
|
||||||
|
+ * Adds the and reserved-memorymemreserve regions in the dtb to the lmb block.
|
||||||
|
+ * Adding the memreserve regions prevents u-boot from using them to store the
|
||||||
|
+ * initrd or the fdt blob.
|
||||||
|
*/
|
||||||
|
void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob)
|
||||||
|
{
|
||||||
|
uint64_t addr, size;
|
||||||
|
- int i, total;
|
||||||
|
+ int i, total, ret;
|
||||||
|
+ int nodeoffset, subnode;
|
||||||
|
+ struct fdt_resource res;
|
||||||
|
|
||||||
|
if (fdt_check_header(fdt_blob) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
+ /* process memreserve sections */
|
||||||
|
total = fdt_num_mem_rsv(fdt_blob);
|
||||||
|
for (i = 0; i < total; i++) {
|
||||||
|
if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0)
|
||||||
|
continue;
|
||||||
|
- printf(" reserving fdt memory region: addr=%llx size=%llx\n",
|
||||||
|
- (unsigned long long)addr, (unsigned long long)size);
|
||||||
|
- lmb_reserve(lmb, addr, size);
|
||||||
|
+ boot_fdt_reserve_region(lmb, addr, size);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* process reserved-memory */
|
||||||
|
+ nodeoffset = fdt_subnode_offset(fdt_blob, 0, "reserved-memory");
|
||||||
|
+ if (nodeoffset >= 0) {
|
||||||
|
+ subnode = fdt_first_subnode(fdt_blob, nodeoffset);
|
||||||
|
+ while (subnode >= 0) {
|
||||||
|
+ /* check if this subnode has a reg property */
|
||||||
|
+ ret = fdt_get_resource(fdt_blob, subnode, "reg", 0,
|
||||||
|
+ &res);
|
||||||
|
+ if (!ret) {
|
||||||
|
+ addr = res.start;
|
||||||
|
+ size = res.end - res.start + 1;
|
||||||
|
+ boot_fdt_reserve_region(lmb, addr, size);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ subnode = fdt_next_subnode(fdt_blob, subnode);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/lib/Makefile b/lib/Makefile
|
||||||
|
index a6dd928a..358789ff 100644
|
||||||
|
--- a/lib/Makefile
|
||||||
|
+++ b/lib/Makefile
|
||||||
|
@@ -30,6 +30,7 @@ obj-y += crc7.o
|
||||||
|
obj-y += crc8.o
|
||||||
|
obj-y += crc16.o
|
||||||
|
obj-$(CONFIG_ERRNO_STR) += errno_str.o
|
||||||
|
+obj-$(CONFIG_OF_LIBFDT) += fdtdec.o
|
||||||
|
obj-$(CONFIG_FIT) += fdtdec_common.o
|
||||||
|
obj-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o
|
||||||
|
obj-$(CONFIG_GZIP_COMPRESSED) += gzip.o
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,312 @@
|
||||||
|
From 16448a9becefd10a64601a08bbcacea38075db70 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
Date: Mon, 14 Jan 2019 22:38:18 +0100
|
||||||
|
Subject: lib: lmb: extend lmb for checks at load time
|
||||||
|
|
||||||
|
This adds two new functions, lmb_alloc_addr and
|
||||||
|
lmb_get_unreserved_size.
|
||||||
|
|
||||||
|
lmb_alloc_addr behaves like lmb_alloc, but it tries to allocate a
|
||||||
|
pre-specified address range. Unlike lmb_reserve, this address range
|
||||||
|
must be inside one of the memory ranges that has been set up with
|
||||||
|
lmb_add.
|
||||||
|
|
||||||
|
lmb_get_unreserved_size returns the number of bytes that can be
|
||||||
|
used up to the next reserved region or the end of valid ram. This
|
||||||
|
can be 0 if the address passed is reserved.
|
||||||
|
|
||||||
|
Added test for these new functions.
|
||||||
|
|
||||||
|
Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
|
||||||
|
diff --git a/include/lmb.h b/include/lmb.h
|
||||||
|
index f04d0580..7d7e2a78 100644
|
||||||
|
--- a/include/lmb.h
|
||||||
|
+++ b/include/lmb.h
|
||||||
|
@@ -38,6 +38,9 @@ extern phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align
|
||||||
|
phys_addr_t max_addr);
|
||||||
|
extern phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align,
|
||||||
|
phys_addr_t max_addr);
|
||||||
|
+extern phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base,
|
||||||
|
+ phys_size_t size);
|
||||||
|
+extern phys_size_t lmb_get_unreserved_size(struct lmb *lmb, phys_addr_t addr);
|
||||||
|
extern int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr);
|
||||||
|
extern long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size);
|
||||||
|
|
||||||
|
diff --git a/lib/lmb.c b/lib/lmb.c
|
||||||
|
index cd297f82..e380a0a7 100644
|
||||||
|
--- a/lib/lmb.c
|
||||||
|
+++ b/lib/lmb.c
|
||||||
|
@@ -313,6 +313,59 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phy
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Try to allocate a specific address range: must be in defined memory but not
|
||||||
|
+ * reserved
|
||||||
|
+ */
|
||||||
|
+phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, phys_size_t size)
|
||||||
|
+{
|
||||||
|
+ long j;
|
||||||
|
+
|
||||||
|
+ /* Check if the requested address is in one of the memory regions */
|
||||||
|
+ j = lmb_overlaps_region(&lmb->memory, base, size);
|
||||||
|
+ if (j >= 0) {
|
||||||
|
+ /*
|
||||||
|
+ * Check if the requested end address is in the same memory
|
||||||
|
+ * region we found.
|
||||||
|
+ */
|
||||||
|
+ if (lmb_addrs_overlap(lmb->memory.region[j].base,
|
||||||
|
+ lmb->memory.region[j].size, base + size -
|
||||||
|
+ 1, 1)) {
|
||||||
|
+ /* ok, reserve the memory */
|
||||||
|
+ if (lmb_reserve(lmb, base, size) >= 0)
|
||||||
|
+ return base;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Return number of bytes from a given address that are free */
|
||||||
|
+phys_size_t lmb_get_unreserved_size(struct lmb *lmb, phys_addr_t addr)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+ long j;
|
||||||
|
+
|
||||||
|
+ /* check if the requested address is in the memory regions */
|
||||||
|
+ j = lmb_overlaps_region(&lmb->memory, addr, 1);
|
||||||
|
+ if (j >= 0) {
|
||||||
|
+ for (i = 0; i < lmb->reserved.cnt; i++) {
|
||||||
|
+ if (addr < lmb->reserved.region[i].base) {
|
||||||
|
+ /* first reserved range > requested address */
|
||||||
|
+ return lmb->reserved.region[i].base - addr;
|
||||||
|
+ }
|
||||||
|
+ if (lmb->reserved.region[i].base +
|
||||||
|
+ lmb->reserved.region[i].size > addr) {
|
||||||
|
+ /* requested addr is in this reserved range */
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ /* if we come here: no reserved ranges above requested addr */
|
||||||
|
+ return lmb->memory.region[lmb->memory.cnt - 1].base +
|
||||||
|
+ lmb->memory.region[lmb->memory.cnt - 1].size - addr;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
diff --git a/test/lib/lmb.c b/test/lib/lmb.c
|
||||||
|
index e6acb70e..058d3c33 100644
|
||||||
|
--- a/test/lib/lmb.c
|
||||||
|
+++ b/test/lib/lmb.c
|
||||||
|
@@ -397,3 +397,205 @@ static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts)
|
||||||
|
|
||||||
|
DM_TEST(lib_test_lmb_overlapping_reserve,
|
||||||
|
DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Simulate 512 MiB RAM, reserve 3 blocks, allocate addresses in between.
|
||||||
|
+ * Expect addresses outside the memory range to fail.
|
||||||
|
+ */
|
||||||
|
+static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
|
||||||
|
+{
|
||||||
|
+ const phys_size_t ram_size = 0x20000000;
|
||||||
|
+ const phys_addr_t ram_end = ram + ram_size;
|
||||||
|
+ const phys_size_t alloc_addr_a = ram + 0x8000000;
|
||||||
|
+ const phys_size_t alloc_addr_b = ram + 0x8000000 * 2;
|
||||||
|
+ const phys_size_t alloc_addr_c = ram + 0x8000000 * 3;
|
||||||
|
+ struct lmb lmb;
|
||||||
|
+ long ret;
|
||||||
|
+ phys_addr_t a, b, c, d, e;
|
||||||
|
+
|
||||||
|
+ /* check for overflow */
|
||||||
|
+ ut_assert(ram_end == 0 || ram_end > ram);
|
||||||
|
+
|
||||||
|
+ lmb_init(&lmb);
|
||||||
|
+
|
||||||
|
+ ret = lmb_add(&lmb, ram, ram_size);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+
|
||||||
|
+ /* reserve 3 blocks */
|
||||||
|
+ ret = lmb_reserve(&lmb, alloc_addr_a, 0x10000);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ret = lmb_reserve(&lmb, alloc_addr_b, 0x10000);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ret = lmb_reserve(&lmb, alloc_addr_c, 0x10000);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 3, alloc_addr_a, 0x10000,
|
||||||
|
+ alloc_addr_b, 0x10000, alloc_addr_c, 0x10000);
|
||||||
|
+
|
||||||
|
+ /* allocate blocks */
|
||||||
|
+ a = lmb_alloc_addr(&lmb, ram, alloc_addr_a - ram);
|
||||||
|
+ ut_asserteq(a, ram);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 3, ram, 0x8010000,
|
||||||
|
+ alloc_addr_b, 0x10000, alloc_addr_c, 0x10000);
|
||||||
|
+ b = lmb_alloc_addr(&lmb, alloc_addr_a + 0x10000,
|
||||||
|
+ alloc_addr_b - alloc_addr_a - 0x10000);
|
||||||
|
+ ut_asserteq(b, alloc_addr_a + 0x10000);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x10010000,
|
||||||
|
+ alloc_addr_c, 0x10000, 0, 0);
|
||||||
|
+ c = lmb_alloc_addr(&lmb, alloc_addr_b + 0x10000,
|
||||||
|
+ alloc_addr_c - alloc_addr_b - 0x10000);
|
||||||
|
+ ut_asserteq(c, alloc_addr_b + 0x10000);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+ d = lmb_alloc_addr(&lmb, alloc_addr_c + 0x10000,
|
||||||
|
+ ram_end - alloc_addr_c - 0x10000);
|
||||||
|
+ ut_asserteq(d, alloc_addr_c + 0x10000);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, ram_size,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+
|
||||||
|
+ /* allocating anything else should fail */
|
||||||
|
+ e = lmb_alloc(&lmb, 1, 1);
|
||||||
|
+ ut_asserteq(e, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, ram_size,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+
|
||||||
|
+ ret = lmb_free(&lmb, d, ram_end - alloc_addr_c - 0x10000);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+
|
||||||
|
+ /* allocate at 3 points in free range */
|
||||||
|
+
|
||||||
|
+ d = lmb_alloc_addr(&lmb, ram_end - 4, 4);
|
||||||
|
+ ut_asserteq(d, ram_end - 4);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x18010000,
|
||||||
|
+ d, 4, 0, 0);
|
||||||
|
+ ret = lmb_free(&lmb, d, 4);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+
|
||||||
|
+ d = lmb_alloc_addr(&lmb, ram_end - 128, 4);
|
||||||
|
+ ut_asserteq(d, ram_end - 128);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x18010000,
|
||||||
|
+ d, 4, 0, 0);
|
||||||
|
+ ret = lmb_free(&lmb, d, 4);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+
|
||||||
|
+ d = lmb_alloc_addr(&lmb, alloc_addr_c + 0x10000, 4);
|
||||||
|
+ ut_asserteq(d, alloc_addr_c + 0x10000);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010004,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+ ret = lmb_free(&lmb, d, 4);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+
|
||||||
|
+ /* allocate at the bottom */
|
||||||
|
+ ret = lmb_free(&lmb, a, alloc_addr_a - ram);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram + 0x8000000, 0x10010000,
|
||||||
|
+ 0, 0, 0, 0);
|
||||||
|
+ d = lmb_alloc_addr(&lmb, ram, 4);
|
||||||
|
+ ut_asserteq(d, ram);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 2, d, 4,
|
||||||
|
+ ram + 0x8000000, 0x10010000, 0, 0);
|
||||||
|
+
|
||||||
|
+ /* check that allocating outside memory fails */
|
||||||
|
+ if (ram_end != 0) {
|
||||||
|
+ ret = lmb_alloc_addr(&lmb, ram_end, 1);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ }
|
||||||
|
+ if (ram != 0) {
|
||||||
|
+ ret = lmb_alloc_addr(&lmb, ram - 1, 1);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int lib_test_lmb_alloc_addr(struct unit_test_state *uts)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ /* simulate 512 MiB RAM beginning at 1GiB */
|
||||||
|
+ ret = test_alloc_addr(uts, 0x40000000);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ /* simulate 512 MiB RAM beginning at 1.5GiB */
|
||||||
|
+ return test_alloc_addr(uts, 0xE0000000);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+DM_TEST(lib_test_lmb_alloc_addr, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
+
|
||||||
|
+/* Simulate 512 MiB RAM, reserve 3 blocks, check addresses in between */
|
||||||
|
+static int test_get_unreserved_size(struct unit_test_state *uts,
|
||||||
|
+ const phys_addr_t ram)
|
||||||
|
+{
|
||||||
|
+ const phys_size_t ram_size = 0x20000000;
|
||||||
|
+ const phys_addr_t ram_end = ram + ram_size;
|
||||||
|
+ const phys_size_t alloc_addr_a = ram + 0x8000000;
|
||||||
|
+ const phys_size_t alloc_addr_b = ram + 0x8000000 * 2;
|
||||||
|
+ const phys_size_t alloc_addr_c = ram + 0x8000000 * 3;
|
||||||
|
+ struct lmb lmb;
|
||||||
|
+ long ret;
|
||||||
|
+ phys_size_t s;
|
||||||
|
+
|
||||||
|
+ /* check for overflow */
|
||||||
|
+ ut_assert(ram_end == 0 || ram_end > ram);
|
||||||
|
+
|
||||||
|
+ lmb_init(&lmb);
|
||||||
|
+
|
||||||
|
+ ret = lmb_add(&lmb, ram, ram_size);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+
|
||||||
|
+ /* reserve 3 blocks */
|
||||||
|
+ ret = lmb_reserve(&lmb, alloc_addr_a, 0x10000);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ret = lmb_reserve(&lmb, alloc_addr_b, 0x10000);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ret = lmb_reserve(&lmb, alloc_addr_c, 0x10000);
|
||||||
|
+ ut_asserteq(ret, 0);
|
||||||
|
+ ASSERT_LMB(&lmb, ram, ram_size, 3, alloc_addr_a, 0x10000,
|
||||||
|
+ alloc_addr_b, 0x10000, alloc_addr_c, 0x10000);
|
||||||
|
+
|
||||||
|
+ /* check addresses in between blocks */
|
||||||
|
+ s = lmb_get_unreserved_size(&lmb, ram);
|
||||||
|
+ ut_asserteq(s, alloc_addr_a - ram);
|
||||||
|
+ s = lmb_get_unreserved_size(&lmb, ram + 0x10000);
|
||||||
|
+ ut_asserteq(s, alloc_addr_a - ram - 0x10000);
|
||||||
|
+ s = lmb_get_unreserved_size(&lmb, alloc_addr_a - 4);
|
||||||
|
+ ut_asserteq(s, 4);
|
||||||
|
+
|
||||||
|
+ s = lmb_get_unreserved_size(&lmb, alloc_addr_a + 0x10000);
|
||||||
|
+ ut_asserteq(s, alloc_addr_b - alloc_addr_a - 0x10000);
|
||||||
|
+ s = lmb_get_unreserved_size(&lmb, alloc_addr_a + 0x20000);
|
||||||
|
+ ut_asserteq(s, alloc_addr_b - alloc_addr_a - 0x20000);
|
||||||
|
+ s = lmb_get_unreserved_size(&lmb, alloc_addr_b - 4);
|
||||||
|
+ ut_asserteq(s, 4);
|
||||||
|
+
|
||||||
|
+ s = lmb_get_unreserved_size(&lmb, alloc_addr_c + 0x10000);
|
||||||
|
+ ut_asserteq(s, ram_end - alloc_addr_c - 0x10000);
|
||||||
|
+ s = lmb_get_unreserved_size(&lmb, alloc_addr_c + 0x20000);
|
||||||
|
+ ut_asserteq(s, ram_end - alloc_addr_c - 0x20000);
|
||||||
|
+ s = lmb_get_unreserved_size(&lmb, ram_end - 4);
|
||||||
|
+ ut_asserteq(s, 4);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int lib_test_lmb_get_unreserved_size(struct unit_test_state *uts)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ /* simulate 512 MiB RAM beginning at 1GiB */
|
||||||
|
+ ret = test_get_unreserved_size(uts, 0x40000000);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ /* simulate 512 MiB RAM beginning at 1.5GiB */
|
||||||
|
+ return test_get_unreserved_size(uts, 0xE0000000);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+DM_TEST(lib_test_lmb_get_unreserved_size,
|
||||||
|
+ DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
From 94e5a755db2a72b8bdaceb634b732ed59816b5ac Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
Date: Mon, 14 Jan 2019 22:38:19 +0100
|
||||||
|
Subject: fs: prevent overwriting reserved memory
|
||||||
|
|
||||||
|
This fixes CVE-2018-18440 ("insufficient boundary checks in filesystem
|
||||||
|
image load") by using lmb to check the load size of a file against
|
||||||
|
reserved memory addresses.
|
||||||
|
|
||||||
|
Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
Reviewed-by: Simon Glass <sjg@chromium.org>
|
||||||
|
|
||||||
|
diff --git a/fs/fs.c b/fs/fs.c
|
||||||
|
index cb265174..7fd22101 100644
|
||||||
|
--- a/fs/fs.c
|
||||||
|
+++ b/fs/fs.c
|
||||||
|
@@ -429,13 +429,57 @@ int fs_size(const char *filename, loff_t *size)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
|
||||||
|
- loff_t *actread)
|
||||||
|
+#ifdef CONFIG_LMB
|
||||||
|
+/* Check if a file may be read to the given address */
|
||||||
|
+static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset,
|
||||||
|
+ loff_t len, struct fstype_info *info)
|
||||||
|
+{
|
||||||
|
+ struct lmb lmb;
|
||||||
|
+ int ret;
|
||||||
|
+ loff_t size;
|
||||||
|
+ loff_t read_len;
|
||||||
|
+
|
||||||
|
+ /* get the actual size of the file */
|
||||||
|
+ ret = info->size(filename, &size);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+ if (offset >= size) {
|
||||||
|
+ /* offset >= EOF, no bytes will be written */
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ read_len = size - offset;
|
||||||
|
+
|
||||||
|
+ /* limit to 'len' if it is smaller */
|
||||||
|
+ if (len && len < read_len)
|
||||||
|
+ read_len = len;
|
||||||
|
+
|
||||||
|
+ lmb_init_and_reserve(&lmb, gd->bd->bi_dram[0].start,
|
||||||
|
+ gd->bd->bi_dram[0].size, (void *)gd->fdt_blob);
|
||||||
|
+ lmb_dump_all(&lmb);
|
||||||
|
+
|
||||||
|
+ if (lmb_alloc_addr(&lmb, addr, read_len) == addr)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ printf("** Reading file would overwrite reserved memory **\n");
|
||||||
|
+ return -ENOSPC;
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+static int _fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
|
||||||
|
+ int do_lmb_check, loff_t *actread)
|
||||||
|
{
|
||||||
|
struct fstype_info *info = fs_get_info(fs_type);
|
||||||
|
void *buf;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
+#ifdef CONFIG_LMB
|
||||||
|
+ if (do_lmb_check) {
|
||||||
|
+ ret = fs_read_lmb_check(filename, addr, offset, len, info);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* We don't actually know how many bytes are being read, since len==0
|
||||||
|
* means read the whole file.
|
||||||
|
@@ -452,6 +496,12 @@ int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
|
||||||
|
+ loff_t *actread)
|
||||||
|
+{
|
||||||
|
+ return _fs_read(filename, addr, offset, len, 0, actread);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len,
|
||||||
|
loff_t *actwrite)
|
||||||
|
{
|
||||||
|
@@ -622,7 +672,7 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
|
||||||
|
pos = 0;
|
||||||
|
|
||||||
|
time = get_timer(0);
|
||||||
|
- ret = fs_read(filename, addr, pos, bytes, &len_read);
|
||||||
|
+ ret = _fs_read(filename, addr, pos, bytes, 1, &len_read);
|
||||||
|
time = get_timer(time);
|
||||||
|
if (ret < 0)
|
||||||
|
return 1;
|
||||||
|
diff --git a/include/lmb.h b/include/lmb.h
|
||||||
|
index 7d7e2a78..62da85e7 100644
|
||||||
|
--- a/include/lmb.h
|
||||||
|
+++ b/include/lmb.h
|
||||||
|
@@ -31,6 +31,8 @@ struct lmb {
|
||||||
|
extern struct lmb lmb;
|
||||||
|
|
||||||
|
extern void lmb_init(struct lmb *lmb);
|
||||||
|
+extern void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base,
|
||||||
|
+ phys_size_t size, void *fdt_blob);
|
||||||
|
extern long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size);
|
||||||
|
extern long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size);
|
||||||
|
extern phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align);
|
||||||
|
diff --git a/lib/lmb.c b/lib/lmb.c
|
||||||
|
index e380a0a7..3407705f 100644
|
||||||
|
--- a/lib/lmb.c
|
||||||
|
+++ b/lib/lmb.c
|
||||||
|
@@ -98,6 +98,19 @@ void lmb_init(struct lmb *lmb)
|
||||||
|
lmb->reserved.size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Initialize the struct, add memory and call arch/board reserve functions */
|
||||||
|
+void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size,
|
||||||
|
+ void *fdt_blob)
|
||||||
|
+{
|
||||||
|
+ lmb_init(lmb);
|
||||||
|
+ lmb_add(lmb, base, size);
|
||||||
|
+ arch_lmb_reserve(lmb);
|
||||||
|
+ board_lmb_reserve(lmb);
|
||||||
|
+
|
||||||
|
+ if (IMAGE_ENABLE_OF_LIBFDT && fdt_blob)
|
||||||
|
+ boot_fdt_add_mem_rsv_regions(lmb, fdt_blob);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* This routine called with relocation disabled. */
|
||||||
|
static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t size)
|
||||||
|
{
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
From 2e3bdfbc449a5558ebbb55e36feee31f69fe32f7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
Date: Mon, 14 Jan 2019 22:38:20 +0100
|
||||||
|
Subject: bootm: use new common function lmb_init_and_reserve
|
||||||
|
|
||||||
|
This reduces duplicate code only.
|
||||||
|
|
||||||
|
Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
Reviewed-by: Simon Glass <sjg@chromium.org>
|
||||||
|
|
||||||
|
diff --git a/common/bootm.c b/common/bootm.c
|
||||||
|
index 8bf84ebc..31e4f0f7 100644
|
||||||
|
--- a/common/bootm.c
|
||||||
|
+++ b/common/bootm.c
|
||||||
|
@@ -56,15 +56,11 @@ static void boot_start_lmb(bootm_headers_t *images)
|
||||||
|
ulong mem_start;
|
||||||
|
phys_size_t mem_size;
|
||||||
|
|
||||||
|
- lmb_init(&images->lmb);
|
||||||
|
-
|
||||||
|
mem_start = env_get_bootm_low();
|
||||||
|
mem_size = env_get_bootm_size();
|
||||||
|
|
||||||
|
- lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size);
|
||||||
|
-
|
||||||
|
- arch_lmb_reserve(&images->lmb);
|
||||||
|
- board_lmb_reserve(&images->lmb);
|
||||||
|
+ lmb_init_and_reserve(&images->lmb, (phys_addr_t)mem_start, mem_size,
|
||||||
|
+ NULL);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define lmb_reserve(lmb, base, size)
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
From 8b554b62dcab25c0072c5b6880d0fcf079cc9d87 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
Date: Mon, 14 Jan 2019 22:38:21 +0100
|
||||||
|
Subject: lmb: remove unused extern declaration
|
||||||
|
|
||||||
|
lmb.h includes an extern declaration of "struct lmb lmb;" which
|
||||||
|
is not used anywhere, so remove it.
|
||||||
|
|
||||||
|
Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
|
||||||
|
diff --git a/include/lmb.h b/include/lmb.h
|
||||||
|
index 62da85e7..1bb003e3 100644
|
||||||
|
--- a/include/lmb.h
|
||||||
|
+++ b/include/lmb.h
|
||||||
|
@@ -28,8 +28,6 @@ struct lmb {
|
||||||
|
struct lmb_region reserved;
|
||||||
|
};
|
||||||
|
|
||||||
|
-extern struct lmb lmb;
|
||||||
|
-
|
||||||
|
extern void lmb_init(struct lmb *lmb);
|
||||||
|
extern void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base,
|
||||||
|
phys_size_t size, void *fdt_blob);
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,172 @@
|
||||||
|
From 2e972e30c0b07736fedcc4fad53cfe49249495a5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
Date: Mon, 14 Jan 2019 22:38:22 +0100
|
||||||
|
Subject: tftp: prevent overwriting reserved memory
|
||||||
|
|
||||||
|
This fixes CVE-2018-18439 ("insufficient boundary checks in network
|
||||||
|
image boot") by using lmb to check for a valid range to store
|
||||||
|
received blocks.
|
||||||
|
|
||||||
|
Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
|
||||||
|
|
||||||
|
diff --git a/net/tftp.c b/net/tftp.c
|
||||||
|
index 68ffd814..a9335b1b 100644
|
||||||
|
--- a/net/tftp.c
|
||||||
|
+++ b/net/tftp.c
|
||||||
|
@@ -17,6 +17,8 @@
|
||||||
|
#include <flash.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
+
|
||||||
|
/* Well known TFTP port # */
|
||||||
|
#define WELL_KNOWN_PORT 69
|
||||||
|
/* Millisecs to timeout for lost pkt */
|
||||||
|
@@ -81,6 +83,10 @@ static ulong tftp_block_wrap;
|
||||||
|
/* memory offset due to wrapping */
|
||||||
|
static ulong tftp_block_wrap_offset;
|
||||||
|
static int tftp_state;
|
||||||
|
+static ulong tftp_load_addr;
|
||||||
|
+#ifdef CONFIG_LMB
|
||||||
|
+static ulong tftp_load_size;
|
||||||
|
+#endif
|
||||||
|
#ifdef CONFIG_TFTP_TSIZE
|
||||||
|
/* The file size reported by the server */
|
||||||
|
static int tftp_tsize;
|
||||||
|
@@ -164,10 +170,11 @@ static void mcast_cleanup(void)
|
||||||
|
|
||||||
|
#endif /* CONFIG_MCAST_TFTP */
|
||||||
|
|
||||||
|
-static inline void store_block(int block, uchar *src, unsigned len)
|
||||||
|
+static inline int store_block(int block, uchar *src, unsigned int len)
|
||||||
|
{
|
||||||
|
ulong offset = block * tftp_block_size + tftp_block_wrap_offset;
|
||||||
|
ulong newsize = offset + len;
|
||||||
|
+ ulong store_addr = tftp_load_addr + offset;
|
||||||
|
#ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
|
||||||
|
int i, rc = 0;
|
||||||
|
|
||||||
|
@@ -175,24 +182,32 @@ static inline void store_block(int block, uchar *src, unsigned len)
|
||||||
|
/* start address in flash? */
|
||||||
|
if (flash_info[i].flash_id == FLASH_UNKNOWN)
|
||||||
|
continue;
|
||||||
|
- if (load_addr + offset >= flash_info[i].start[0]) {
|
||||||
|
+ if (store_addr >= flash_info[i].start[0]) {
|
||||||
|
rc = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc) { /* Flash is destination for this packet */
|
||||||
|
- rc = flash_write((char *)src, (ulong)(load_addr+offset), len);
|
||||||
|
+ rc = flash_write((char *)src, store_addr, len);
|
||||||
|
if (rc) {
|
||||||
|
flash_perror(rc);
|
||||||
|
- net_set_state(NETLOOP_FAIL);
|
||||||
|
- return;
|
||||||
|
+ return rc;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif /* CONFIG_SYS_DIRECT_FLASH_TFTP */
|
||||||
|
{
|
||||||
|
- void *ptr = map_sysmem(load_addr + offset, len);
|
||||||
|
-
|
||||||
|
+ void *ptr;
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_LMB
|
||||||
|
+ if (store_addr < tftp_load_addr ||
|
||||||
|
+ store_addr + len > tftp_load_addr + tftp_load_size) {
|
||||||
|
+ puts("\nTFTP error: ");
|
||||||
|
+ puts("trying to overwrite reserved memory...\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+ ptr = map_sysmem(store_addr, len);
|
||||||
|
memcpy(ptr, src, len);
|
||||||
|
unmap_sysmem(ptr);
|
||||||
|
}
|
||||||
|
@@ -203,6 +218,8 @@ static inline void store_block(int block, uchar *src, unsigned len)
|
||||||
|
|
||||||
|
if (net_boot_file_size < newsize)
|
||||||
|
net_boot_file_size = newsize;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear our state ready for a new transfer */
|
||||||
|
@@ -606,7 +623,11 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
||||||
|
timeout_count_max = tftp_timeout_count_max;
|
||||||
|
net_set_timeout_handler(timeout_ms, tftp_timeout_handler);
|
||||||
|
|
||||||
|
- store_block(tftp_cur_block - 1, pkt + 2, len);
|
||||||
|
+ if (store_block(tftp_cur_block - 1, pkt + 2, len)) {
|
||||||
|
+ eth_halt();
|
||||||
|
+ net_set_state(NETLOOP_FAIL);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Acknowledge the block just received, which will prompt
|
||||||
|
@@ -695,6 +716,25 @@ static void tftp_timeout_handler(void)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Initialize tftp_load_addr and tftp_load_size from load_addr and lmb */
|
||||||
|
+static int tftp_init_load_addr(void)
|
||||||
|
+{
|
||||||
|
+#ifdef CONFIG_LMB
|
||||||
|
+ struct lmb lmb;
|
||||||
|
+ phys_size_t max_size;
|
||||||
|
+
|
||||||
|
+ lmb_init_and_reserve(&lmb, gd->bd->bi_dram[0].start,
|
||||||
|
+ gd->bd->bi_dram[0].size, (void *)gd->fdt_blob);
|
||||||
|
+
|
||||||
|
+ max_size = lmb_get_unreserved_size(&lmb, load_addr);
|
||||||
|
+ if (!max_size)
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ tftp_load_size = max_size;
|
||||||
|
+#endif
|
||||||
|
+ tftp_load_addr = load_addr;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
|
||||||
|
void tftp_start(enum proto_t protocol)
|
||||||
|
{
|
||||||
|
@@ -791,7 +831,14 @@ void tftp_start(enum proto_t protocol)
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
- printf("Load address: 0x%lx\n", load_addr);
|
||||||
|
+ if (tftp_init_load_addr()) {
|
||||||
|
+ eth_halt();
|
||||||
|
+ net_set_state(NETLOOP_FAIL);
|
||||||
|
+ puts("\nTFTP error: ");
|
||||||
|
+ puts("trying to overwrite reserved memory...\n");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ printf("Load address: 0x%lx\n", tftp_load_addr);
|
||||||
|
puts("Loading: *\b");
|
||||||
|
tftp_state = STATE_SEND_RRQ;
|
||||||
|
#ifdef CONFIG_CMD_BOOTEFI
|
||||||
|
@@ -842,9 +889,15 @@ void tftp_start_server(void)
|
||||||
|
{
|
||||||
|
tftp_filename[0] = 0;
|
||||||
|
|
||||||
|
+ if (tftp_init_load_addr()) {
|
||||||
|
+ eth_halt();
|
||||||
|
+ net_set_state(NETLOOP_FAIL);
|
||||||
|
+ puts("\nTFTP error: trying to overwrite reserved memory...\n");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
printf("Using %s device\n", eth_get_name());
|
||||||
|
printf("Listening for TFTP transfer on %pI4\n", &net_ip);
|
||||||
|
- printf("Load address: 0x%lx\n", load_addr);
|
||||||
|
+ printf("Load address: 0x%lx\n", tftp_load_addr);
|
||||||
|
|
||||||
|
puts("Loading: *\b");
|
||||||
|
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
From 72bc6aa0bc7f034bd6966c872819f19af69f2b64 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
Date: Mon, 14 Jan 2019 22:38:23 +0100
|
||||||
|
Subject: arm: bootm: fix sp detection at end of address range
|
||||||
|
|
||||||
|
This fixes 'arch_lmb_reserve()' for ARM that tries to detect in which
|
||||||
|
DRAM bank 'sp' is in.
|
||||||
|
|
||||||
|
This code failed if a bank was at the end of physical address range
|
||||||
|
(i.e. size + length overflowed to 0).
|
||||||
|
|
||||||
|
To fix this, calculate 'bank_end' as 'size + length - 1' so that such
|
||||||
|
banks end at 0xffffffff, not 0.
|
||||||
|
|
||||||
|
Fixes: 15751403b6 ("ARM: bootm: don't assume sp is in DRAM bank 0")
|
||||||
|
Reported-by: Frank Wunderlich <frank-w@public-files.de>
|
||||||
|
Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
||||||
|
Reviewed-by: Stephen Warren <swarren@nvidia.com>
|
||||||
|
|
||||||
|
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
|
||||||
|
index c3c1d2fd..329f20c2 100644
|
||||||
|
--- a/arch/arm/lib/bootm.c
|
||||||
|
+++ b/arch/arm/lib/bootm.c
|
||||||
|
@@ -64,13 +64,15 @@ void arch_lmb_reserve(struct lmb *lmb)
|
||||||
|
/* adjust sp by 4K to be safe */
|
||||||
|
sp -= 4096;
|
||||||
|
for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
|
||||||
|
- if (sp < gd->bd->bi_dram[bank].start)
|
||||||
|
+ if (!gd->bd->bi_dram[bank].size ||
|
||||||
|
+ sp < gd->bd->bi_dram[bank].start)
|
||||||
|
continue;
|
||||||
|
+ /* Watch out for RAM at end of address space! */
|
||||||
|
bank_end = gd->bd->bi_dram[bank].start +
|
||||||
|
- gd->bd->bi_dram[bank].size;
|
||||||
|
- if (sp >= bank_end)
|
||||||
|
+ gd->bd->bi_dram[bank].size - 1;
|
||||||
|
+ if (sp > bank_end)
|
||||||
|
continue;
|
||||||
|
- lmb_reserve(lmb, sp, bank_end - sp);
|
||||||
|
+ lmb_reserve(lmb, sp, bank_end - sp + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
From 7b492a978a09fbc95340dbcdc1e14d604ac6ae76 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frank Wunderlich <frank-w@public-files.de>
|
||||||
|
Date: Wed, 23 Jan 2019 16:16:45 +0100
|
||||||
|
Subject: [defconfig] added strings and setenv used for lstftp
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig
|
||||||
|
index a9f4506e..bac45d11 100644
|
||||||
|
--- a/configs/mt7623n_bpir2_defconfig
|
||||||
|
+++ b/configs/mt7623n_bpir2_defconfig
|
||||||
|
@@ -22,7 +22,6 @@ CONFIG_CMD_GPT=y
|
||||||
|
CONFIG_CMD_MMC=y
|
||||||
|
CONFIG_CMD_PART=y
|
||||||
|
CONFIG_CMD_READ=y
|
||||||
|
-# CONFIG_CMD_SETEXPR is not set
|
||||||
|
# CONFIG_CMD_NFS is not set
|
||||||
|
CONFIG_CMD_PING=y
|
||||||
|
CONFIG_CMD_FAT=y
|
||||||
|
@@ -69,3 +68,5 @@ CONFIG_DEFAULT_ENV_FILE="uEnv.txt"
|
||||||
|
CONFIG_ENV_IS_IN_MMC=y
|
||||||
|
|
||||||
|
CONFIG_CMD_ASKENV=y
|
||||||
|
+CONFIG_CMD_STRINGS=y
|
||||||
|
+CONFIG_CMD_SETEXPR=y
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
From 0164e641d4a64dcff5d5394b168d612b174d83bd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frank Wunderlich <frank-w@public-files.de>
|
||||||
|
Date: Wed, 23 Jan 2019 16:30:39 +0100
|
||||||
|
Subject: increase size for environment 4k => 8k
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h
|
||||||
|
index 7d26debb..aa0314db 100644
|
||||||
|
--- a/include/configs/mt7623.h
|
||||||
|
+++ b/include/configs/mt7623.h
|
||||||
|
@@ -27,7 +27,7 @@
|
||||||
|
#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M
|
||||||
|
|
||||||
|
/* Environment */
|
||||||
|
-#define CONFIG_ENV_SIZE SZ_4K
|
||||||
|
+#define CONFIG_ENV_SIZE SZ_8K
|
||||||
|
/* Allow to overwrite serial and ethaddr */
|
||||||
|
#define CONFIG_ENV_OVERWRITE
|
||||||
|
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,216 @@
|
||||||
|
From 17843557032cc342117591939483d238e80bd169 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frank Wunderlich <frank-w@public-files.de>
|
||||||
|
Date: Fri, 28 Dec 2018 17:56:19 +0100
|
||||||
|
Subject: [bootmenu] added key-input (1-9,a-f)
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
|
||||||
|
index 7f88c1ed..0935fd40 100644
|
||||||
|
--- a/cmd/bootmenu.c
|
||||||
|
+++ b/cmd/bootmenu.c
|
||||||
|
@@ -39,7 +39,22 @@ struct bootmenu_data {
|
||||||
|
|
||||||
|
enum bootmenu_key {
|
||||||
|
KEY_NONE = 0,
|
||||||
|
- KEY_UP,
|
||||||
|
+ KEY_1,
|
||||||
|
+ KEY_2,
|
||||||
|
+ KEY_3,
|
||||||
|
+ KEY_4,
|
||||||
|
+ KEY_5,
|
||||||
|
+ KEY_6,
|
||||||
|
+ KEY_7,
|
||||||
|
+ KEY_8,
|
||||||
|
+ KEY_9,
|
||||||
|
+ KEY_a,
|
||||||
|
+ KEY_b,
|
||||||
|
+ KEY_c,
|
||||||
|
+ KEY_d,
|
||||||
|
+ KEY_e,
|
||||||
|
+ KEY_f,
|
||||||
|
+ KEY_UP = 20,
|
||||||
|
KEY_DOWN,
|
||||||
|
KEY_SELECT,
|
||||||
|
};
|
||||||
|
@@ -77,6 +92,23 @@ static void bootmenu_print_entry(void *data)
|
||||||
|
puts(ANSI_COLOR_RESET);
|
||||||
|
}
|
||||||
|
|
||||||
|
+bool get_bootmenu_key(enum bootmenu_key *key, int c)
|
||||||
|
+{
|
||||||
|
+ /* ANSI '1~9' - was pressed */
|
||||||
|
+ if (c <= '9' && c >= '1' )
|
||||||
|
+ {
|
||||||
|
+ *key = c-48;
|
||||||
|
+ return true;
|
||||||
|
+ }else
|
||||||
|
+ /* ANSI 'a~f' - was pressed */
|
||||||
|
+ if (c <= 'f' && c >= 'a' )
|
||||||
|
+ {
|
||||||
|
+ *key = c-87;
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void bootmenu_autoboot_loop(struct bootmenu_data *menu,
|
||||||
|
enum bootmenu_key *key, int *esc)
|
||||||
|
{
|
||||||
|
@@ -97,23 +129,23 @@ static void bootmenu_autoboot_loop(struct bootmenu_data *menu,
|
||||||
|
|
||||||
|
menu->delay = -1;
|
||||||
|
c = getc();
|
||||||
|
-
|
||||||
|
- switch (c) {
|
||||||
|
- case '\e':
|
||||||
|
- *esc = 1;
|
||||||
|
- *key = KEY_NONE;
|
||||||
|
- break;
|
||||||
|
- case '\r':
|
||||||
|
- *key = KEY_SELECT;
|
||||||
|
- break;
|
||||||
|
- default:
|
||||||
|
- *key = KEY_NONE;
|
||||||
|
- break;
|
||||||
|
+ if (!get_bootmenu_key(key,c))
|
||||||
|
+ {
|
||||||
|
+ switch (c) {
|
||||||
|
+ case '\e':
|
||||||
|
+ *esc = 1;
|
||||||
|
+ *key = KEY_NONE;
|
||||||
|
+ break;
|
||||||
|
+ case '\r':
|
||||||
|
+ *key = KEY_SELECT;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ *key = KEY_NONE;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
-
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
if (menu->delay < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
@@ -140,47 +172,49 @@ static void bootmenu_loop(struct bootmenu_data *menu,
|
||||||
|
|
||||||
|
c = getc();
|
||||||
|
|
||||||
|
- switch (*esc) {
|
||||||
|
- case 0:
|
||||||
|
- /* First char of ANSI escape sequence '\e' */
|
||||||
|
- if (c == '\e') {
|
||||||
|
- *esc = 1;
|
||||||
|
- *key = KEY_NONE;
|
||||||
|
- }
|
||||||
|
- break;
|
||||||
|
- case 1:
|
||||||
|
- /* Second char of ANSI '[' */
|
||||||
|
- if (c == '[') {
|
||||||
|
- *esc = 2;
|
||||||
|
- *key = KEY_NONE;
|
||||||
|
- } else {
|
||||||
|
- *esc = 0;
|
||||||
|
- }
|
||||||
|
- break;
|
||||||
|
- case 2:
|
||||||
|
- case 3:
|
||||||
|
- /* Third char of ANSI (number '1') - optional */
|
||||||
|
- if (*esc == 2 && c == '1') {
|
||||||
|
- *esc = 3;
|
||||||
|
+ if (!get_bootmenu_key(key,c))
|
||||||
|
+ {
|
||||||
|
+ switch (*esc) {
|
||||||
|
+ case 0:
|
||||||
|
+ /* First char of ANSI escape sequence '\e' */
|
||||||
|
+ if (c == '\e') {
|
||||||
|
+ *esc = 1;
|
||||||
|
+ *key = KEY_NONE;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case 1:
|
||||||
|
+ /* Second char of ANSI '[' */
|
||||||
|
+ if (c == '[') {
|
||||||
|
+ *esc = 2;
|
||||||
|
*key = KEY_NONE;
|
||||||
|
+ } else {
|
||||||
|
+ *esc = 0;
|
||||||
|
+ }
|
||||||
|
break;
|
||||||
|
- }
|
||||||
|
+ case 2:
|
||||||
|
+ case 3:
|
||||||
|
+ /* Third char of ANSI (number '1') - optional */
|
||||||
|
+ if (*esc == 2 && c == '1') {
|
||||||
|
+ *esc = 3;
|
||||||
|
+ *key = KEY_NONE;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- *esc = 0;
|
||||||
|
+ *esc = 0;
|
||||||
|
|
||||||
|
- /* ANSI 'A' - key up was pressed */
|
||||||
|
- if (c == 'A')
|
||||||
|
- *key = KEY_UP;
|
||||||
|
- /* ANSI 'B' - key down was pressed */
|
||||||
|
- else if (c == 'B')
|
||||||
|
- *key = KEY_DOWN;
|
||||||
|
- /* other key was pressed */
|
||||||
|
- else
|
||||||
|
- *key = KEY_NONE;
|
||||||
|
+ /* ANSI 'A' - key up was pressed */
|
||||||
|
+ if (c == 'A')
|
||||||
|
+ *key = KEY_UP;
|
||||||
|
+ /* ANSI 'B' - key down was pressed */
|
||||||
|
+ else if (c == 'B')
|
||||||
|
+ *key = KEY_DOWN;
|
||||||
|
+ /* other key was pressed */
|
||||||
|
+ else
|
||||||
|
+ *key = KEY_NONE;
|
||||||
|
|
||||||
|
- break;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
-
|
||||||
|
/* enter key was pressed */
|
||||||
|
if (c == '\r')
|
||||||
|
*key = KEY_SELECT;
|
||||||
|
@@ -203,6 +237,14 @@ static char *bootmenu_choice_entry(void *data)
|
||||||
|
bootmenu_loop(menu, &key, &esc);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (key < KEY_UP && key > KEY_NONE)
|
||||||
|
+ {
|
||||||
|
+ menu->active = key-1;
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+
|
||||||
|
switch (key) {
|
||||||
|
case KEY_UP:
|
||||||
|
if (menu->active > 0)
|
||||||
|
@@ -222,6 +264,7 @@ static char *bootmenu_choice_entry(void *data)
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* never happens */
|
||||||
|
@@ -466,7 +509,7 @@ void menu_display_statusline(struct menu *m)
|
||||||
|
printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
|
||||||
|
puts(ANSI_CLEAR_LINE);
|
||||||
|
printf(ANSI_CURSOR_POSITION, menu->count + 6, 1);
|
||||||
|
- puts(" Press UP/DOWN to move, ENTER to select");
|
||||||
|
+ puts(" Press UP/DOWN to move or Press 1~9,a~f to choose, ENTER to select");
|
||||||
|
puts(ANSI_CLEAR_LINE_TO_END);
|
||||||
|
printf(ANSI_CURSOR_POSITION, menu->count + 7, 1);
|
||||||
|
puts(ANSI_CLEAR_LINE);
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
91
root/package/boot/uboot-mediatek/uEnv-default.txt
Normal file
91
root/package/boot/uboot-mediatek/uEnv-default.txt
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
scriptaddr=0x83000000
|
||||||
|
device=mmc
|
||||||
|
bootenv=uEnv.txt
|
||||||
|
kernel=uImage
|
||||||
|
loadaddr=0x80200000
|
||||||
|
#default bootargs will be overidden by buildargs
|
||||||
|
bootargs=console=ttyS0,115200 root=/dev/mmcblk1p2 rw rootwait ip=dhcp
|
||||||
|
|
||||||
|
console=earlyprintk console=ttyS0,115200 console=tty1 fbcon=map:0
|
||||||
|
roottmpl=${rootdev} rootfstype=ext4 rootwait
|
||||||
|
prepsetroot=setenv setroot setenv root ${roottmpl}
|
||||||
|
bootopts=vmalloc=496M debug=7 initcall_debug=0
|
||||||
|
graphic=video=1920x1080 drm.debug=0x7
|
||||||
|
|
||||||
|
buildargs=setenv bootargs "console=${console} root=${root} ${bootopts} ${graphic}"
|
||||||
|
|
||||||
|
checkenv=test -e ${device} ${partition} ${bootenv}
|
||||||
|
importenv=env import -t ${scriptaddr} ${filesize}
|
||||||
|
loadbootenv=if fatload ${device} ${partition} ${scriptaddr} ${bootenv};then run importenv;else echo "fatload (${bootenv}) failed";fi
|
||||||
|
resetenv=env default -a;printenv;
|
||||||
|
|
||||||
|
# Here we assume that SD card id mmcblk1 and eMMC is mmcblk0 in linux. Swap them if your DTS define them in reverse order.
|
||||||
|
usesd=setenv partition 1:1; setenv rootdev /dev/mmcblk0p2; setenv bootdev SD; setenv swaproot 'run useemmc';
|
||||||
|
useemmc=setenv partition 0:1; setenv rootdev /dev/mmcblk1p2; setenv bootdev eMMC; setenv swaproot 'run usesd';
|
||||||
|
|
||||||
|
checkbootedfrom=if itest.l *81dffff0 == 434d4d65 ; then setenv bootedfrom eMMC; else setenv bootedfrom SD; fi;
|
||||||
|
|
||||||
|
checkroot=fatinfo ${device} ${partition}
|
||||||
|
checksd=fatinfo ${device} 1:1
|
||||||
|
checkmmc=fatinfo ${device} 0:1
|
||||||
|
|
||||||
|
reportbootedfrom=echo "Preloader/U-Boot loaded from ${bootedfrom}."; run validroot || echo "Both SD and eMMC pt#1 are not FAT, falling back to U-Boot shell."
|
||||||
|
reportvalidroot=run validroot || echo "Both SD and eMMC pt#1 are not FAT, falling back to U-Boot shell."
|
||||||
|
reportrootswapwarn=if test "${bootedfrom}" != "${bootdev}" ; then echo "Warning: Partition 1 on ${bootedfrom} is not FAT, failing back to ${bootdev}"; fi; true;
|
||||||
|
reportbootdev=echo "Booting from ${bootdev}."
|
||||||
|
reportboot=run reportbootedfrom reportvalidroot reportrootswapwarn reportbootdev
|
||||||
|
|
||||||
|
detectroot=run useemmc; run checkbootedfrom; if test "${bootedfrom}" == "SD"; then run usesd; fi; run validateroot;
|
||||||
|
validateroot=setenv validroot false; run checkroot || run swaproot; run checkroot && setenv validroot true || run swaproot;
|
||||||
|
|
||||||
|
newboot=run prepsetroot; run setroot;run buildargs;printenv bootargs;fatload ${device} ${partition} ${loadaddr} ${kernel}; bootm
|
||||||
|
|
||||||
|
reloadenv=run detectroot; if run validroot; then if run checkenv; then run loadbootenv; run detectroot; else echo uEnv.txt file not found on ${bootdev}; fi; fi;
|
||||||
|
reloadmenu=run reloadenv; run reportboot; if run validroot; then if run checkenv; then run loadbootenv; else echo uEnv.txt file not found on ${bootdev}; fi; bootmenu; fi;
|
||||||
|
|
||||||
|
lskernel=ls ${device} ${partition};
|
||||||
|
lsdtb=ls ${device} ${partition} dtb
|
||||||
|
askkernel=askenv kernelinput "enter uImage-name:";
|
||||||
|
askdtb=askenv dtbinput "enter dtb-name:";
|
||||||
|
|
||||||
|
#bootmenu
|
||||||
|
boot0=run lskernel;run askkernel;if printenv kernelinput ;then setenv kernel ${kernelinput};run lsdtb;run askdtb;if printenv dtbinput ;then setenv fdt ${dtbinput};fi; run newboot2; fi;
|
||||||
|
boot1=run newboot;
|
||||||
|
|
||||||
|
bootmenu_default=2
|
||||||
|
bootmenu_0=1. Enter kernel-name to boot from SD/EMMC.=run boot0
|
||||||
|
bootmenu_1=2. Boot kernel from TFTP.=run bootnet
|
||||||
|
bootmenu_2=3. Boot from SD/EMMC.=run boot1
|
||||||
|
bootmenu_3=4. Boot from eMMC.=run useemmc; run boot1
|
||||||
|
bootmenu_4=5. Boot from SD.=run usesd; run boot1
|
||||||
|
|
||||||
|
#Netboot
|
||||||
|
ipaddr=192.168.0.11
|
||||||
|
netmask=255.255.255.0
|
||||||
|
serverip=192.168.0.10
|
||||||
|
|
||||||
|
bootfile=uImage
|
||||||
|
netbootargs=console=ttyS0,115200 root=/dev/mmcblk1p2 rw rootwait
|
||||||
|
#ip=dhcp sets ip on eth0 instead of wan
|
||||||
|
|
||||||
|
lstftp=tftp ${loadaddr} ${serverip}:files.lst;setexpr listend ${loadaddr} + ${filesize};mw.b ${listend} 00 2;strings ${loadaddr};
|
||||||
|
#md.b ${loadaddr} 60;
|
||||||
|
|
||||||
|
bootnet=run lstftp;run askkernel;if printenv kernelinput ;then setenv bootfile "${kernelinput}"; fi;printenv; setenv bootargs ${netbootargs};tftp ${loadaddr} ${bootfile};bootm
|
||||||
|
|
||||||
|
#separate fdt+dto
|
||||||
|
dtaddr=0x83f00000
|
||||||
|
fdt_high=0xffffffff
|
||||||
|
|
||||||
|
loadfdt=fatload ${device} ${partition} ${dtaddr} dtb/${fdt}
|
||||||
|
loadkernel=echo "loading kernel ${kernel}...";fatload ${device} ${partition} ${loadaddr} ${kernel}
|
||||||
|
|
||||||
|
loaddto=echo "loaddto:${dto}";fdt addr ${dtaddr};fdt resize 8192; setexpr fdtovaddr ${dtaddr} + F000;fatload ${device} ${partition} ${fdtovaddr} dtb/${dto} && fdt apply ${fdtovaddr}
|
||||||
|
loaddtolist=for dto in ${dtolist} ; do run loaddto ; done
|
||||||
|
|
||||||
|
bootall=if printenv fdt; then run loadfdt; if printenv dtolist;then run loaddtolist;fi; bootm ${loadaddr} - ${dtaddr} ;else bootm; fi
|
||||||
|
newboot2=run prepsetroot; run setroot;run buildargs; printenv bootargs; run loadkernel; run bootall;
|
||||||
|
|
||||||
|
#automatic reload from sd/emmc
|
||||||
|
bootdelay=0
|
||||||
|
bootcmd=setenv bootdelay 3; run reloadmenu;
|
|
@ -8,6 +8,9 @@
|
||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
include $(INCLUDE_DIR)/image.mk
|
include $(INCLUDE_DIR)/image.mk
|
||||||
|
|
||||||
|
FAT32_BLOCK_SIZE=1024
|
||||||
|
FAT32_BLOCKS=$(shell echo $$((32*1024*1024/$(FAT32_BLOCK_SIZE))))
|
||||||
|
|
||||||
# for arm
|
# for arm
|
||||||
KERNEL_LOADADDR := 0x80008000
|
KERNEL_LOADADDR := 0x80008000
|
||||||
|
|
||||||
|
@ -16,6 +19,22 @@ ifeq ($(SUBTARGET),mt7622)
|
||||||
KERNEL_LOADADDR = 0x41080000
|
KERNEL_LOADADDR = 0x41080000
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
define Build/mediatek-sdcard
|
||||||
|
rm -f $@.boot
|
||||||
|
mkfs.fat $@.boot -C $(FAT32_BLOCKS)
|
||||||
|
|
||||||
|
mcopy -i $@.boot $(STAGING_DIR_IMAGE)/$(DEVICE_NAME)-uEnv.txt ::uEnv.txt
|
||||||
|
mcopy -i $@.boot $(IMAGE_KERNEL) ::uImage
|
||||||
|
./gen_mediatek_sdcard_img.sh $@ \
|
||||||
|
$(STAGING_DIR_IMAGE)/bpi-r2-preloader.bin \
|
||||||
|
$(STAGING_DIR_IMAGE)/$(DEVICE_NAME)-uboot-mediatek.bin \
|
||||||
|
$@.boot \
|
||||||
|
$(IMAGE_ROOTFS) \
|
||||||
|
32 \
|
||||||
|
$(CONFIG_TARGET_ROOTFS_PARTSIZE)
|
||||||
|
rm -f $@.boot
|
||||||
|
endef
|
||||||
|
|
||||||
define Build/sysupgrade-emmc
|
define Build/sysupgrade-emmc
|
||||||
rm -f $@.recovery
|
rm -f $@.recovery
|
||||||
mkfs.fat -C $@.recovery 3070
|
mkfs.fat -C $@.recovery 3070
|
||||||
|
@ -30,6 +49,7 @@ define Build/sysupgrade-bpi-r2-sd
|
||||||
dd bs="1024" if="$(STAGING_DIR_IMAGE)/mtk-bpi-r2-preloader-sd.bin" of="$@" seek="0"
|
dd bs="1024" if="$(STAGING_DIR_IMAGE)/mtk-bpi-r2-preloader-sd.bin" of="$@" seek="0"
|
||||||
dd bs="1024" if="$(STAGING_DIR_IMAGE)/mtk-bpi-r2-uboot.bin" of="$@" seek="320"
|
dd bs="1024" if="$(STAGING_DIR_IMAGE)/mtk-bpi-r2-uboot.bin" of="$@" seek="320"
|
||||||
dd bs="1024" if="$(IMAGE_KERNEL)" of="$@" seek="2048"
|
dd bs="1024" if="$(IMAGE_KERNEL)" of="$@" seek="2048"
|
||||||
|
#dd bs="1024" if="$(IMAGE_ROOTFS)" of="$@" seek="67584"
|
||||||
dd bs="1024" if="$(IMAGE_ROOTFS)" of="$@" seek="67584"
|
dd bs="1024" if="$(IMAGE_ROOTFS)" of="$@" seek="67584"
|
||||||
endef
|
endef
|
||||||
define Build/sysupgrade-bpi-r2-emmc
|
define Build/sysupgrade-bpi-r2-emmc
|
||||||
|
@ -48,9 +68,11 @@ define Device/Default
|
||||||
IMAGES := sysupgrade.bin
|
IMAGES := sysupgrade.bin
|
||||||
IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata
|
IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata
|
||||||
ifeq ($(SUBTARGET),mt7623)
|
ifeq ($(SUBTARGET),mt7623)
|
||||||
|
DEVICE_VARS := MEDIATEK_UBOOT
|
||||||
KERNEL_NAME := zImage
|
KERNEL_NAME := zImage
|
||||||
KERNEL := kernel-bin | append-dtb | uImage none
|
KERNEL := kernel-bin | append-dtb | uImage none
|
||||||
KERNEL_INITRAMFS := kernel-bin | append-dtb | uImage none
|
KERNEL_INITRAMFS := kernel-bin | append-dtb | uImage none
|
||||||
|
FILESYSTEMS += ext4
|
||||||
endif
|
endif
|
||||||
ifeq ($(SUBTARGET),mt7622)
|
ifeq ($(SUBTARGET),mt7622)
|
||||||
KERNEL_NAME := Image
|
KERNEL_NAME := Image
|
||||||
|
|
48
root/target/linux/mediatek/image/gen_mediatek_sdcard_img.sh
Executable file
48
root/target/linux/mediatek/image/gen_mediatek_sdcard_img.sh
Executable file
|
@ -0,0 +1,48 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 OpenWrt.org
|
||||||
|
#
|
||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
# See /LICENSE for more information.
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e
|
||||||
|
[ $# -eq 7 ] || {
|
||||||
|
echo "SYNTAX: $0 <file> <preloader image> <u-boot image> <bootfs image> <rootfs image> <bootfs size> <rootfs size>"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
OUTPUT="$1"
|
||||||
|
PRELOADER="$2"
|
||||||
|
UBOOT="$3"
|
||||||
|
BOOTFS="$4"
|
||||||
|
ROOTFS="$5"
|
||||||
|
BOOTFSSIZE="$6"
|
||||||
|
ROOTFSSIZE="$7"
|
||||||
|
|
||||||
|
head=4
|
||||||
|
sect=63
|
||||||
|
|
||||||
|
set `ptgen -o $OUTPUT -h $head -s $sect -l 1024 -t c -p ${BOOTFSSIZE}M -t 83 -p ${ROOTFSSIZE}M -a 0`
|
||||||
|
|
||||||
|
BOOT_OFFSET="$(($1 / 512))"
|
||||||
|
BOOT_SIZE="$(($2 / 512))"
|
||||||
|
ROOTFS_OFFSET="$(($3 / 512))"
|
||||||
|
ROOTFS_SIZE="$(($4 / 512))"
|
||||||
|
|
||||||
|
PRELOADER_OFFSET=2 # 2KB
|
||||||
|
UBOOT_OFFSET=320 # 320KB
|
||||||
|
|
||||||
|
SDMMC_BOOT="SDMMC_BOOT\x00\x00\x01\x00\x00\x00\x00\x02\x00\x00"
|
||||||
|
BRLYT="\
|
||||||
|
BRLYT\x00\x00\x00\x01\x00\x00\x00\x00\x08\x00\x00\
|
||||||
|
\x00\x08\x00\x00\x42\x42\x42\x42\x08\x00\x01\x00\x00\x08\x00\x00\
|
||||||
|
\x00\x08\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||||
|
|
||||||
|
echo -en "${SDMMC_BOOT}" | dd bs=1 of="${OUTPUT}" seek=0 conv=notrunc
|
||||||
|
echo -en "${BRLYT}" | dd bs=1 of="${OUTPUT}" seek=512 conv=notrunc
|
||||||
|
|
||||||
|
dd bs=1024 if="${PRELOADER}" of="${OUTPUT}" seek="${PRELOADER_OFFSET}" conv=notrunc
|
||||||
|
dd bs=1024 if="${UBOOT}" of="${OUTPUT}" seek="${UBOOT_OFFSET}" conv=notrunc
|
||||||
|
dd bs=512 if="${BOOTFS}" of="${OUTPUT}" seek="${BOOT_OFFSET}" conv=notrunc
|
||||||
|
dd bs=512 if="${ROOTFS}" of="${OUTPUT}" seek="${ROOTFS_OFFSET}" conv=notrunc
|
|
@ -13,12 +13,13 @@ define Device/7623n-bananapi-bpi-r2
|
||||||
DEVICE_TITLE := MTK7623n BananaPi R2
|
DEVICE_TITLE := MTK7623n BananaPi R2
|
||||||
DEVICE_DTS := mt7623n-bananapi-bpi-r2
|
DEVICE_DTS := mt7623n-bananapi-bpi-r2
|
||||||
# DEVICE_PACKAGES := wmt uboot-mtk-bpi-r2 kmod-crypto-hw-mtk kmod-nat-hw-mtk
|
# DEVICE_PACKAGES := wmt uboot-mtk-bpi-r2 kmod-crypto-hw-mtk kmod-nat-hw-mtk
|
||||||
DEVICE_PACKAGES := wmt uboot-mtk-bpi-r2 kmod-crypto-hw-mtk kmod-mt6625l-wlan-gen2
|
DEVICE_PACKAGES := wmt uboot-mtk-bpi-r2 kmod-crypto-hw-mtk kmod-mt6625l-wlan-gen2 kmod-usb-core kmod-ata-core kmod-usb3 kmod-usb2 kmod-usb-ohci mt7623n-preloader
|
||||||
SUPPORTED_DEVICES := bananapi,bpi-r2
|
SUPPORTED_DEVICES := bananapi,bpi-r2
|
||||||
IMAGES := sysupgrade.tar sysupgrade-sd.img.gz sysupgrade-emmc.img.gz
|
IMAGES := sysupgrade.tar sysupgrade-sd.img.gz sysupgrade-emmc.img.gz sdcard.img.gz
|
||||||
IMAGE/sysupgrade.tar := sysupgrade-tar | append-metadata
|
IMAGE/sysupgrade.tar := sysupgrade-tar | append-metadata
|
||||||
IMAGE/sysupgrade-sd.img.gz := sysupgrade-bpi-r2-sd | gzip | append-metadata
|
IMAGE/sysupgrade-sd.img.gz := sysupgrade-bpi-r2-sd | gzip | append-metadata
|
||||||
IMAGE/sysupgrade-emmc.img.gz := sysupgrade-bpi-r2-emmc | gzip | append-metadata
|
IMAGE/sysupgrade-emmc.img.gz := sysupgrade-bpi-r2-emmc | gzip | append-metadata
|
||||||
|
IMAGE/sdcard.img.gz := mediatek-sdcard | gzip | append-metadata
|
||||||
endef
|
endef
|
||||||
|
|
||||||
TARGET_DEVICES += 7623n-bananapi-bpi-r2
|
TARGET_DEVICES += 7623n-bananapi-bpi-r2
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue