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 $(INCLUDE_DIR)/image.mk
|
||||
|
||||
FAT32_BLOCK_SIZE=1024
|
||||
FAT32_BLOCKS=$(shell echo $$((32*1024*1024/$(FAT32_BLOCK_SIZE))))
|
||||
|
||||
# for arm
|
||||
KERNEL_LOADADDR := 0x80008000
|
||||
|
||||
|
@ -16,6 +19,22 @@ ifeq ($(SUBTARGET),mt7622)
|
|||
KERNEL_LOADADDR = 0x41080000
|
||||
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
|
||||
rm -f $@.recovery
|
||||
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-uboot.bin" of="$@" seek="320"
|
||||
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"
|
||||
endef
|
||||
define Build/sysupgrade-bpi-r2-emmc
|
||||
|
@ -48,9 +68,11 @@ define Device/Default
|
|||
IMAGES := sysupgrade.bin
|
||||
IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata
|
||||
ifeq ($(SUBTARGET),mt7623)
|
||||
DEVICE_VARS := MEDIATEK_UBOOT
|
||||
KERNEL_NAME := zImage
|
||||
KERNEL := kernel-bin | append-dtb | uImage none
|
||||
KERNEL_INITRAMFS := kernel-bin | append-dtb | uImage none
|
||||
FILESYSTEMS += ext4
|
||||
endif
|
||||
ifeq ($(SUBTARGET),mt7622)
|
||||
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_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-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
|
||||
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-sd.img.gz := sysupgrade-bpi-r2-sd | 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
|
||||
|
||||
TARGET_DEVICES += 7623n-bananapi-bpi-r2
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue