mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 23:51:33 +00:00
Merge branch '2020-04-24-master-imports'
- Assorted minor bugfixes. - Resync fixdep with Linux v5.7-rc1 - Numerous changes to reduce SPL in various cases including when we have read-only env support. - Allow mkimage to align the header on FIT images to a specific size.
This commit is contained in:
commit
18b9c98024
53 changed files with 953 additions and 536 deletions
1
.mailmap
1
.mailmap
|
@ -36,6 +36,7 @@ Prabhakar Kushwaha <prabhakar@freescale.com>
|
|||
Rajeshwari Shinde <rajeshwari.s@samsung.com>
|
||||
Ricardo Ribalda <ricardo@ribalda.com> <ricardo.ribalda@uam.es>
|
||||
Ricardo Ribalda <ricardo@ribalda.com> <ricardo.ribalda@gmail.com>
|
||||
Ruchika Gupta <ruchika.gupta@nxp.com> <ruchika.gupta@freescale.com>
|
||||
Sandeep Paulraj <s-paulraj@ti.com>
|
||||
Shaohui Xie <Shaohui.Xie@freescale.com>
|
||||
Stefan Roese <stroese>
|
||||
|
|
|
@ -217,7 +217,8 @@ script:
|
|||
#
|
||||
# Build a selection of boards if TEST_PY_BD is empty
|
||||
- if [[ "${BUILDMAN}" != "" ]]; then
|
||||
tools/buildman/buildman -P -E -W ${BUILDMAN} ${OVERRIDE};
|
||||
ret=0
|
||||
tools/buildman/buildman -P -E -W ${BUILDMAN} ${OVERRIDE} || ret=$?;
|
||||
if [[ $ret -ne 0 ]]; then
|
||||
tools/buildman/buildman -seP ${BUILDMAN};
|
||||
exit $ret;
|
||||
|
|
2
Kconfig
2
Kconfig
|
@ -447,7 +447,7 @@ config SPL_FIT_SIGNATURE
|
|||
select SPL_FIT
|
||||
select SPL_RSA
|
||||
select SPL_RSA_VERIFY
|
||||
select IMAGE_SIGN_INFO
|
||||
select SPL_IMAGE_SIGN_INFO
|
||||
|
||||
config SPL_LOAD_FIT
|
||||
bool "Enable SPL loading U-Boot as a FIT (basic fitImage features)"
|
||||
|
|
16
Makefile
16
Makefile
|
@ -742,13 +742,15 @@ KBUILD_CFLAGS += $(KCFLAGS)
|
|||
# Use UBOOTINCLUDE when you must reference the include/ directory.
|
||||
# Needed to be compatible with the O= option
|
||||
UBOOTINCLUDE := \
|
||||
-Iinclude \
|
||||
$(if $(KBUILD_SRC), -I$(srctree)/include) \
|
||||
$(if $(CONFIG_$(SPL_)SYS_THUMB_BUILD), \
|
||||
$(if $(CONFIG_HAS_THUMB2),, \
|
||||
-I$(srctree)/arch/$(ARCH)/thumb1/include),) \
|
||||
-I$(srctree)/arch/$(ARCH)/include \
|
||||
-include $(srctree)/include/linux/kconfig.h
|
||||
-Iinclude \
|
||||
$(if $(KBUILD_SRC), -I$(srctree)/include) \
|
||||
$(if $(CONFIG_$(SPL_)SYS_THUMB_BUILD), \
|
||||
$(if $(CONFIG_HAS_THUMB2), \
|
||||
$(if $(CONFIG_CPU_V7M), \
|
||||
-I$(srctree)/arch/arm/thumb1/include), \
|
||||
-I$(srctree)/arch/arm/thumb1/include)) \
|
||||
-I$(srctree)/arch/$(ARCH)/include \
|
||||
-include $(srctree)/include/linux/kconfig.h
|
||||
|
||||
NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
|
||||
|
||||
|
|
10
README
10
README
|
@ -3186,16 +3186,6 @@ necessary. For example using the ELDK on a 4xx CPU, please enter:
|
|||
$ CROSS_COMPILE=ppc_4xx-
|
||||
$ export CROSS_COMPILE
|
||||
|
||||
Note: If you wish to generate Windows versions of the utilities in
|
||||
the tools directory you can use the MinGW toolchain
|
||||
(http://www.mingw.org). Set your HOST tools to the MinGW
|
||||
toolchain and execute 'make tools'. For example:
|
||||
|
||||
$ make HOSTCC=i586-mingw32msvc-gcc HOSTSTRIP=i586-mingw32msvc-strip tools
|
||||
|
||||
Binaries such as tools/mkimage.exe will be created which can
|
||||
be executed on computers running Windows.
|
||||
|
||||
U-Boot is intended to be simple to build. After installing the
|
||||
sources you must configure U-Boot for one specific board type. This
|
||||
is done by typing:
|
||||
|
|
|
@ -9,16 +9,20 @@ config SYS_BOARD
|
|||
config SYS_CONFIG_NAME
|
||||
default "qemu-arm"
|
||||
|
||||
endif
|
||||
choice
|
||||
prompt "QEMU ARM architecture"
|
||||
default TARGET_QEMU_ARM_64BIT
|
||||
|
||||
config TARGET_QEMU_ARM_32BIT
|
||||
bool "Support qemu_arm"
|
||||
depends on ARCH_QEMU
|
||||
bool "ARMv7-A, 32bit"
|
||||
select ARCH_SUPPORT_PSCI
|
||||
select CPU_V7A
|
||||
select SYS_ARCH_TIMER
|
||||
|
||||
config TARGET_QEMU_ARM_64BIT
|
||||
bool "Support qemu_arm64"
|
||||
depends on ARCH_QEMU
|
||||
bool "ARMv8, 64bit"
|
||||
select ARM64
|
||||
|
||||
endchoice
|
||||
|
||||
endif
|
||||
|
|
|
@ -1060,3 +1060,14 @@ config IMAGE_SIGN_INFO
|
|||
select SHA256
|
||||
help
|
||||
Enable image_sign_info helper functions.
|
||||
|
||||
if IMAGE_SIGN_INFO
|
||||
|
||||
config SPL_IMAGE_SIGN_INFO
|
||||
bool
|
||||
select SHA1
|
||||
select SHA256
|
||||
help
|
||||
Enable image_sign_info helper functions in SPL.
|
||||
|
||||
endif
|
||||
|
|
|
@ -112,7 +112,7 @@ obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o image-android-dt.o
|
|||
obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += image-fdt.o
|
||||
obj-$(CONFIG_$(SPL_TPL_)FIT) += image-fit.o
|
||||
obj-$(CONFIG_$(SPL_)MULTI_DTB_FIT) += boot_fit.o common_fit.o
|
||||
obj-$(CONFIG_IMAGE_SIGN_INFO) += image-sig.o
|
||||
obj-$(CONFIG_$(SPL_TPL_)IMAGE_SIGN_INFO) += image-sig.o
|
||||
obj-$(CONFIG_$(SPL_TPL_)FIT_SIGNATURE) += image-fit-sig.o
|
||||
obj-$(CONFIG_$(SPL_TPL_)FIT_CIPHER) += image-cipher.o
|
||||
obj-$(CONFIG_IO_TRACE) += iotrace.o
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <common.h>
|
||||
|
||||
#if defined(CONFIG_UNIT_TEST)
|
||||
#if CONFIG_IS_ENABLED(UNIT_TEST)
|
||||
#define DEBUG
|
||||
#endif
|
||||
|
||||
|
|
|
@ -508,12 +508,6 @@ config SPL_DMA
|
|||
the CPU moving the data. Enable this option to build the drivers
|
||||
in drivers/dma as part of an SPL build.
|
||||
|
||||
config SPL_DM_GPIO
|
||||
bool "Support Driver Model GPIO drivers"
|
||||
depends on SPL_GPIO_SUPPORT && DM_GPIO
|
||||
help
|
||||
Enable support for Driver Model based GPIO drivers in SPL.
|
||||
|
||||
config SPL_DRIVERS_MISC_SUPPORT
|
||||
bool "Support misc drivers"
|
||||
help
|
||||
|
|
|
@ -14,6 +14,8 @@ CONFIG_BOOTARGS="console=ttyAMA0 earlycon=pl011,0x1c090000 debug user_debug=31 l
|
|||
# CONFIG_DISPLAY_CPUINFO is not set
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_SYS_PROMPT="VExpress64# "
|
||||
CONFIG_ANDROID_BOOT_IMAGE=y
|
||||
CONFIG_CMD_ABOOTIMG=y
|
||||
# CONFIG_CMD_CONSOLE is not set
|
||||
# CONFIG_CMD_XIMG is not set
|
||||
# CONFIG_CMD_EDITENV is not set
|
||||
|
|
51
doc/README.bootcount
Normal file
51
doc/README.bootcount
Normal file
|
@ -0,0 +1,51 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
Boot Count Limit
|
||||
================
|
||||
|
||||
This allows to detect multiple failed attempts to boot Linux.
|
||||
|
||||
After a power-on reset, "bootcount" variable will be initialized with 1, and
|
||||
each reboot will increment the value by 1.
|
||||
|
||||
If, after a reboot, the new value of "bootcount" exceeds the value of
|
||||
"bootlimit", then instead of the standard boot action (executing the contents of
|
||||
"bootcmd") an alternate boot action will be performed, and the contents of
|
||||
"altbootcmd" will be executed.
|
||||
|
||||
If the variable "bootlimit" is not defined in the environment, the Boot Count
|
||||
Limit feature is disabled. If it is enabled, but "altbootcmd" is not defined,
|
||||
then U-Boot will drop into interactive mode and remain there.
|
||||
|
||||
It is the responsibility of some application code (typically a Linux
|
||||
application) to reset the variable "bootcount", thus allowing for more boot
|
||||
cycles.
|
||||
|
||||
BOOTCOUNT_EXT
|
||||
-------------
|
||||
|
||||
This adds support for maintaining boot count in a file on an EXT filesystem.
|
||||
The file to use is define by:
|
||||
|
||||
SYS_BOOTCOUNT_EXT_INTERFACE
|
||||
SYS_BOOTCOUNT_EXT_DEVPART
|
||||
SYS_BOOTCOUNT_EXT_NAME
|
||||
|
||||
The format of the file is:
|
||||
|
||||
==== =================
|
||||
type entry
|
||||
==== =================
|
||||
u8 magic
|
||||
u8 version
|
||||
u8 bootcount
|
||||
u8 upgrade_available
|
||||
==== =================
|
||||
|
||||
To prevent unattended usage of "altbootcmd" the "upgrade_available" variable is
|
||||
used.
|
||||
If "upgrade_available" is 0, "bootcount" is not saved, if "upgrade_available" is
|
||||
1 "bootcount" is save.
|
||||
So the Userspace Application must set the "upgrade_available" and "bootcount"
|
||||
variables to 0, if a boot was successfully.
|
||||
This also prevents writes on all reboots.
|
|
@ -37,7 +37,7 @@ needs_sphinx = '1.3'
|
|||
extensions = ['kerneldoc', 'rstFlatTable', 'kernel_include', 'cdomain', 'kfigure']
|
||||
|
||||
# The name of the math extension changed on Sphinx 1.4
|
||||
if major == 1 and minor > 3:
|
||||
if (major == 1 and minor > 3) or (major > 1):
|
||||
extensions.append("sphinx.ext.imgmath")
|
||||
else:
|
||||
extensions.append("sphinx.ext.pngmath")
|
||||
|
|
|
@ -53,8 +53,6 @@ from docutils.utils import SystemMessagePropagation
|
|||
# common globals
|
||||
# ==============================================================================
|
||||
|
||||
# The version numbering follows numbering of the specification
|
||||
# (doc/books/kernel-doc-HOWTO).
|
||||
__version__ = '1.0'
|
||||
|
||||
PY3 = sys.version_info[0] == 3
|
||||
|
|
|
@ -304,6 +304,11 @@ Normal kernel FIT image has data embedded within FIT structure. U-Boot image
|
|||
for SPL boot has external data. Existence of 'data-offset' can be used to
|
||||
identify which format is used.
|
||||
|
||||
For FIT image with external data, it would be better to align each blob of data
|
||||
to block(512 byte) for block device, so that we don't need to do the copy when
|
||||
read the image data in SPL. Pass '-B 0x200' to mkimage to align the FIT
|
||||
structure and data to 512 byte, other values available for other align size.
|
||||
|
||||
9) Examples
|
||||
-----------
|
||||
|
||||
|
|
|
@ -7,11 +7,21 @@
|
|||
#include <fs.h>
|
||||
#include <mapmem.h>
|
||||
|
||||
#define BC_MAGIC 0xbc
|
||||
#define BC_MAGIC 0xbd
|
||||
#define BC_VERSION 1
|
||||
|
||||
typedef struct {
|
||||
u8 magic;
|
||||
u8 version;
|
||||
u8 bootcount;
|
||||
u8 upgrade_available;
|
||||
} bootcount_ext_t;
|
||||
|
||||
static u8 upgrade_available = 1;
|
||||
|
||||
void bootcount_store(ulong a)
|
||||
{
|
||||
u8 *buf;
|
||||
bootcount_ext_t *buf;
|
||||
loff_t len;
|
||||
int ret;
|
||||
|
||||
|
@ -21,20 +31,27 @@ void bootcount_store(ulong a)
|
|||
return;
|
||||
}
|
||||
|
||||
buf = map_sysmem(CONFIG_SYS_BOOTCOUNT_ADDR, 2);
|
||||
buf[0] = BC_MAGIC;
|
||||
buf[1] = (a & 0xff);
|
||||
/* Only update bootcount during upgrade process */
|
||||
if (!upgrade_available)
|
||||
return;
|
||||
|
||||
buf = map_sysmem(CONFIG_SYS_BOOTCOUNT_ADDR, sizeof(bootcount_ext_t));
|
||||
buf->magic = BC_MAGIC;
|
||||
buf->version = BC_VERSION;
|
||||
buf->bootcount = (a & 0xff);
|
||||
buf->upgrade_available = upgrade_available;
|
||||
unmap_sysmem(buf);
|
||||
|
||||
ret = fs_write(CONFIG_SYS_BOOTCOUNT_EXT_NAME,
|
||||
CONFIG_SYS_BOOTCOUNT_ADDR, 0, 2, &len);
|
||||
CONFIG_SYS_BOOTCOUNT_ADDR, 0, sizeof(bootcount_ext_t),
|
||||
&len);
|
||||
if (ret != 0)
|
||||
puts("Error storing bootcount\n");
|
||||
}
|
||||
|
||||
ulong bootcount_load(void)
|
||||
{
|
||||
u8 *buf;
|
||||
bootcount_ext_t *buf;
|
||||
loff_t len_read;
|
||||
int ret;
|
||||
|
||||
|
@ -45,15 +62,20 @@ ulong bootcount_load(void)
|
|||
}
|
||||
|
||||
ret = fs_read(CONFIG_SYS_BOOTCOUNT_EXT_NAME, CONFIG_SYS_BOOTCOUNT_ADDR,
|
||||
0, 2, &len_read);
|
||||
if (ret != 0 || len_read != 2) {
|
||||
0, sizeof(bootcount_ext_t), &len_read);
|
||||
if (ret != 0 || len_read != sizeof(bootcount_ext_t)) {
|
||||
puts("Error loading bootcount\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
buf = map_sysmem(CONFIG_SYS_BOOTCOUNT_ADDR, 2);
|
||||
if (buf[0] == BC_MAGIC)
|
||||
ret = buf[1];
|
||||
buf = map_sysmem(CONFIG_SYS_BOOTCOUNT_ADDR, sizeof(bootcount_ext_t));
|
||||
if (buf->magic == BC_MAGIC && buf->version == BC_VERSION) {
|
||||
upgrade_available = buf->upgrade_available;
|
||||
if (upgrade_available)
|
||||
ret = buf->bootcount;
|
||||
} else {
|
||||
puts("Incorrect bootcount file\n");
|
||||
}
|
||||
|
||||
unmap_sysmem(buf);
|
||||
|
||||
|
|
|
@ -31,10 +31,12 @@
|
|||
#define RX_TOTAL_BUF_SIZE (NUM_RX_DESC * PKTSIZE_ALIGN)
|
||||
#define TOTAL_PKT_BUF_SIZE (TX_TOTAL_BUF_SIZE + RX_TOTAL_BUF_SIZE)
|
||||
|
||||
#define MT7530_NUM_PHYS 5
|
||||
#define MT7530_DFL_SMI_ADDR 31
|
||||
#define MT753X_NUM_PHYS 5
|
||||
#define MT753X_NUM_PORTS 7
|
||||
#define MT753X_DFL_SMI_ADDR 31
|
||||
#define MT753X_SMI_ADDR_MASK 0x1f
|
||||
|
||||
#define MT7530_PHY_ADDR(base, addr) \
|
||||
#define MT753X_PHY_ADDR(base, addr) \
|
||||
(((base) + (addr)) & 0x1f)
|
||||
|
||||
#define GDMA_FWD_TO_CPU \
|
||||
|
@ -132,7 +134,8 @@ struct pdma_txdesc {
|
|||
|
||||
enum mtk_switch {
|
||||
SW_NONE,
|
||||
SW_MT7530
|
||||
SW_MT7530,
|
||||
SW_MT7531
|
||||
};
|
||||
|
||||
enum mtk_soc {
|
||||
|
@ -174,8 +177,8 @@ struct mtk_eth_priv {
|
|||
|
||||
enum mtk_switch sw;
|
||||
int (*switch_init)(struct mtk_eth_priv *priv);
|
||||
u32 mt7530_smi_addr;
|
||||
u32 mt7530_phy_base;
|
||||
u32 mt753x_smi_addr;
|
||||
u32 mt753x_phy_base;
|
||||
|
||||
struct gpio_desc rst_gpio;
|
||||
int mcm;
|
||||
|
@ -350,6 +353,174 @@ static int mtk_mmd_ind_write(struct mtk_eth_priv *priv, u8 addr, u8 devad,
|
|||
return priv->mii_write(priv, addr, MII_MMD_ADDR_DATA_REG, val);
|
||||
}
|
||||
|
||||
/*
|
||||
* MT7530 Internal Register Address Bits
|
||||
* -------------------------------------------------------------------
|
||||
* | 15 14 13 12 11 10 9 8 7 6 | 5 4 3 2 | 1 0 |
|
||||
* |----------------------------------------|---------------|--------|
|
||||
* | Page Address | Reg Address | Unused |
|
||||
* -------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int mt753x_reg_read(struct mtk_eth_priv *priv, u32 reg, u32 *data)
|
||||
{
|
||||
int ret, low_word, high_word;
|
||||
|
||||
/* Write page address */
|
||||
ret = mtk_mii_write(priv, priv->mt753x_smi_addr, 0x1f, reg >> 6);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Read low word */
|
||||
low_word = mtk_mii_read(priv, priv->mt753x_smi_addr, (reg >> 2) & 0xf);
|
||||
if (low_word < 0)
|
||||
return low_word;
|
||||
|
||||
/* Read high word */
|
||||
high_word = mtk_mii_read(priv, priv->mt753x_smi_addr, 0x10);
|
||||
if (high_word < 0)
|
||||
return high_word;
|
||||
|
||||
if (data)
|
||||
*data = ((u32)high_word << 16) | (low_word & 0xffff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt753x_reg_write(struct mtk_eth_priv *priv, u32 reg, u32 data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Write page address */
|
||||
ret = mtk_mii_write(priv, priv->mt753x_smi_addr, 0x1f, reg >> 6);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Write low word */
|
||||
ret = mtk_mii_write(priv, priv->mt753x_smi_addr, (reg >> 2) & 0xf,
|
||||
data & 0xffff);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Write high word */
|
||||
return mtk_mii_write(priv, priv->mt753x_smi_addr, 0x10, data >> 16);
|
||||
}
|
||||
|
||||
static void mt753x_reg_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr,
|
||||
u32 set)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
mt753x_reg_read(priv, reg, &val);
|
||||
val &= ~clr;
|
||||
val |= set;
|
||||
mt753x_reg_write(priv, reg, val);
|
||||
}
|
||||
|
||||
/* Indirect MDIO clause 22/45 access */
|
||||
static int mt7531_mii_rw(struct mtk_eth_priv *priv, int phy, int reg, u16 data,
|
||||
u32 cmd, u32 st)
|
||||
{
|
||||
ulong timeout;
|
||||
u32 val, timeout_ms;
|
||||
int ret = 0;
|
||||
|
||||
val = (st << MDIO_ST_S) |
|
||||
((cmd << MDIO_CMD_S) & MDIO_CMD_M) |
|
||||
((phy << MDIO_PHY_ADDR_S) & MDIO_PHY_ADDR_M) |
|
||||
((reg << MDIO_REG_ADDR_S) & MDIO_REG_ADDR_M);
|
||||
|
||||
if (cmd == MDIO_CMD_WRITE || cmd == MDIO_CMD_ADDR)
|
||||
val |= data & MDIO_RW_DATA_M;
|
||||
|
||||
mt753x_reg_write(priv, MT7531_PHY_IAC, val | PHY_ACS_ST);
|
||||
|
||||
timeout_ms = 100;
|
||||
timeout = get_timer(0);
|
||||
while (1) {
|
||||
mt753x_reg_read(priv, MT7531_PHY_IAC, &val);
|
||||
|
||||
if ((val & PHY_ACS_ST) == 0)
|
||||
break;
|
||||
|
||||
if (get_timer(timeout) > timeout_ms)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
if (cmd == MDIO_CMD_READ || cmd == MDIO_CMD_READ_C45) {
|
||||
mt753x_reg_read(priv, MT7531_PHY_IAC, &val);
|
||||
ret = val & MDIO_RW_DATA_M;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mt7531_mii_ind_read(struct mtk_eth_priv *priv, u8 phy, u8 reg)
|
||||
{
|
||||
u8 phy_addr;
|
||||
|
||||
if (phy >= MT753X_NUM_PHYS)
|
||||
return -EINVAL;
|
||||
|
||||
phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, phy);
|
||||
|
||||
return mt7531_mii_rw(priv, phy_addr, reg, 0, MDIO_CMD_READ,
|
||||
MDIO_ST_C22);
|
||||
}
|
||||
|
||||
static int mt7531_mii_ind_write(struct mtk_eth_priv *priv, u8 phy, u8 reg,
|
||||
u16 val)
|
||||
{
|
||||
u8 phy_addr;
|
||||
|
||||
if (phy >= MT753X_NUM_PHYS)
|
||||
return -EINVAL;
|
||||
|
||||
phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, phy);
|
||||
|
||||
return mt7531_mii_rw(priv, phy_addr, reg, val, MDIO_CMD_WRITE,
|
||||
MDIO_ST_C22);
|
||||
}
|
||||
|
||||
int mt7531_mmd_ind_read(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg)
|
||||
{
|
||||
u8 phy_addr;
|
||||
int ret;
|
||||
|
||||
if (addr >= MT753X_NUM_PHYS)
|
||||
return -EINVAL;
|
||||
|
||||
phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, addr);
|
||||
|
||||
ret = mt7531_mii_rw(priv, phy_addr, devad, reg, MDIO_CMD_ADDR,
|
||||
MDIO_ST_C45);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return mt7531_mii_rw(priv, phy_addr, devad, 0, MDIO_CMD_READ_C45,
|
||||
MDIO_ST_C45);
|
||||
}
|
||||
|
||||
static int mt7531_mmd_ind_write(struct mtk_eth_priv *priv, u8 addr, u8 devad,
|
||||
u16 reg, u16 val)
|
||||
{
|
||||
u8 phy_addr;
|
||||
int ret;
|
||||
|
||||
if (addr >= MT753X_NUM_PHYS)
|
||||
return 0;
|
||||
|
||||
phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, addr);
|
||||
|
||||
ret = mt7531_mii_rw(priv, phy_addr, devad, reg, MDIO_CMD_ADDR,
|
||||
MDIO_ST_C45);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return mt7531_mii_rw(priv, phy_addr, devad, val, MDIO_CMD_WRITE,
|
||||
MDIO_ST_C45);
|
||||
}
|
||||
|
||||
static int mtk_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
|
||||
{
|
||||
struct mtk_eth_priv *priv = bus->priv;
|
||||
|
@ -388,6 +559,12 @@ static int mtk_mdio_register(struct udevice *dev)
|
|||
priv->mmd_read = mtk_mmd_ind_read;
|
||||
priv->mmd_write = mtk_mmd_ind_write;
|
||||
break;
|
||||
case SW_MT7531:
|
||||
priv->mii_read = mt7531_mii_ind_read;
|
||||
priv->mii_write = mt7531_mii_ind_write;
|
||||
priv->mmd_read = mt7531_mmd_ind_read;
|
||||
priv->mmd_write = mt7531_mmd_ind_write;
|
||||
break;
|
||||
default:
|
||||
priv->mii_read = mtk_mii_read;
|
||||
priv->mii_write = mtk_mii_write;
|
||||
|
@ -411,75 +588,18 @@ static int mtk_mdio_register(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* MT7530 Internal Register Address Bits
|
||||
* -------------------------------------------------------------------
|
||||
* | 15 14 13 12 11 10 9 8 7 6 | 5 4 3 2 | 1 0 |
|
||||
* |----------------------------------------|---------------|--------|
|
||||
* | Page Address | Reg Address | Unused |
|
||||
* -------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int mt7530_reg_read(struct mtk_eth_priv *priv, u32 reg, u32 *data)
|
||||
static int mt753x_core_reg_read(struct mtk_eth_priv *priv, u32 reg)
|
||||
{
|
||||
int ret, low_word, high_word;
|
||||
u8 phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, 0);
|
||||
|
||||
/* Write page address */
|
||||
ret = mtk_mii_write(priv, priv->mt7530_smi_addr, 0x1f, reg >> 6);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Read low word */
|
||||
low_word = mtk_mii_read(priv, priv->mt7530_smi_addr, (reg >> 2) & 0xf);
|
||||
if (low_word < 0)
|
||||
return low_word;
|
||||
|
||||
/* Read high word */
|
||||
high_word = mtk_mii_read(priv, priv->mt7530_smi_addr, 0x10);
|
||||
if (high_word < 0)
|
||||
return high_word;
|
||||
|
||||
if (data)
|
||||
*data = ((u32)high_word << 16) | (low_word & 0xffff);
|
||||
|
||||
return 0;
|
||||
return priv->mmd_read(priv, phy_addr, 0x1f, reg);
|
||||
}
|
||||
|
||||
static int mt7530_reg_write(struct mtk_eth_priv *priv, u32 reg, u32 data)
|
||||
static void mt753x_core_reg_write(struct mtk_eth_priv *priv, u32 reg, u32 val)
|
||||
{
|
||||
int ret;
|
||||
u8 phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, 0);
|
||||
|
||||
/* Write page address */
|
||||
ret = mtk_mii_write(priv, priv->mt7530_smi_addr, 0x1f, reg >> 6);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Write low word */
|
||||
ret = mtk_mii_write(priv, priv->mt7530_smi_addr, (reg >> 2) & 0xf,
|
||||
data & 0xffff);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Write high word */
|
||||
return mtk_mii_write(priv, priv->mt7530_smi_addr, 0x10, data >> 16);
|
||||
}
|
||||
|
||||
static void mt7530_reg_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr,
|
||||
u32 set)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
mt7530_reg_read(priv, reg, &val);
|
||||
val &= ~clr;
|
||||
val |= set;
|
||||
mt7530_reg_write(priv, reg, val);
|
||||
}
|
||||
|
||||
static void mt7530_core_reg_write(struct mtk_eth_priv *priv, u32 reg, u32 val)
|
||||
{
|
||||
u8 phy_addr = MT7530_PHY_ADDR(priv->mt7530_phy_base, 0);
|
||||
|
||||
mtk_mmd_ind_write(priv, phy_addr, 0x1f, reg, val);
|
||||
priv->mmd_write(priv, phy_addr, 0x1f, reg, val);
|
||||
}
|
||||
|
||||
static int mt7530_pad_clk_setup(struct mtk_eth_priv *priv, int mode)
|
||||
|
@ -497,46 +617,46 @@ static int mt7530_pad_clk_setup(struct mtk_eth_priv *priv, int mode)
|
|||
}
|
||||
|
||||
/* Disable MT7530 core clock */
|
||||
mt7530_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, 0);
|
||||
mt753x_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, 0);
|
||||
|
||||
/* Disable MT7530 PLL */
|
||||
mt7530_core_reg_write(priv, CORE_GSWPLL_GRP1,
|
||||
mt753x_core_reg_write(priv, CORE_GSWPLL_GRP1,
|
||||
(2 << RG_GSWPLL_POSDIV_200M_S) |
|
||||
(32 << RG_GSWPLL_FBKDIV_200M_S));
|
||||
|
||||
/* For MT7530 core clock = 500Mhz */
|
||||
mt7530_core_reg_write(priv, CORE_GSWPLL_GRP2,
|
||||
mt753x_core_reg_write(priv, CORE_GSWPLL_GRP2,
|
||||
(1 << RG_GSWPLL_POSDIV_500M_S) |
|
||||
(25 << RG_GSWPLL_FBKDIV_500M_S));
|
||||
|
||||
/* Enable MT7530 PLL */
|
||||
mt7530_core_reg_write(priv, CORE_GSWPLL_GRP1,
|
||||
mt753x_core_reg_write(priv, CORE_GSWPLL_GRP1,
|
||||
(2 << RG_GSWPLL_POSDIV_200M_S) |
|
||||
(32 << RG_GSWPLL_FBKDIV_200M_S) |
|
||||
RG_GSWPLL_EN_PRE);
|
||||
|
||||
udelay(20);
|
||||
|
||||
mt7530_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
|
||||
mt753x_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
|
||||
|
||||
/* Setup the MT7530 TRGMII Tx Clock */
|
||||
mt7530_core_reg_write(priv, CORE_PLL_GROUP5, ncpo1);
|
||||
mt7530_core_reg_write(priv, CORE_PLL_GROUP6, 0);
|
||||
mt7530_core_reg_write(priv, CORE_PLL_GROUP10, ssc_delta);
|
||||
mt7530_core_reg_write(priv, CORE_PLL_GROUP11, ssc_delta);
|
||||
mt7530_core_reg_write(priv, CORE_PLL_GROUP4, RG_SYSPLL_DDSFBK_EN |
|
||||
mt753x_core_reg_write(priv, CORE_PLL_GROUP5, ncpo1);
|
||||
mt753x_core_reg_write(priv, CORE_PLL_GROUP6, 0);
|
||||
mt753x_core_reg_write(priv, CORE_PLL_GROUP10, ssc_delta);
|
||||
mt753x_core_reg_write(priv, CORE_PLL_GROUP11, ssc_delta);
|
||||
mt753x_core_reg_write(priv, CORE_PLL_GROUP4, RG_SYSPLL_DDSFBK_EN |
|
||||
RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN);
|
||||
|
||||
mt7530_core_reg_write(priv, CORE_PLL_GROUP2,
|
||||
mt753x_core_reg_write(priv, CORE_PLL_GROUP2,
|
||||
RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN |
|
||||
(1 << RG_SYSPLL_POSDIV_S));
|
||||
|
||||
mt7530_core_reg_write(priv, CORE_PLL_GROUP7,
|
||||
mt753x_core_reg_write(priv, CORE_PLL_GROUP7,
|
||||
RG_LCDDS_PCW_NCPO_CHG | (3 << RG_LCCDS_C_S) |
|
||||
RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
|
||||
|
||||
/* Enable MT7530 core clock */
|
||||
mt7530_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG,
|
||||
mt753x_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG,
|
||||
REG_GSWCK_EN | REG_TRGMIICK_EN);
|
||||
|
||||
return 0;
|
||||
|
@ -552,6 +672,285 @@ static int mt7530_setup(struct mtk_eth_priv *priv)
|
|||
mtk_ethsys_rmw(priv, ETHSYS_CLKCFG0_REG,
|
||||
ETHSYS_TRGMII_CLK_SEL362_5, 0);
|
||||
|
||||
/* Modify HWTRAP first to allow direct access to internal PHYs */
|
||||
mt753x_reg_read(priv, HWTRAP_REG, &val);
|
||||
val |= CHG_TRAP;
|
||||
val &= ~C_MDIO_BPS;
|
||||
mt753x_reg_write(priv, MHWTRAP_REG, val);
|
||||
|
||||
/* Calculate the phy base address */
|
||||
val = ((val & SMI_ADDR_M) >> SMI_ADDR_S) << 3;
|
||||
priv->mt753x_phy_base = (val | 0x7) + 1;
|
||||
|
||||
/* Turn off PHYs */
|
||||
for (i = 0; i < MT753X_NUM_PHYS; i++) {
|
||||
phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i);
|
||||
phy_val = priv->mii_read(priv, phy_addr, MII_BMCR);
|
||||
phy_val |= BMCR_PDOWN;
|
||||
priv->mii_write(priv, phy_addr, MII_BMCR, phy_val);
|
||||
}
|
||||
|
||||
/* Force MAC link down before reset */
|
||||
mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE);
|
||||
mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE);
|
||||
|
||||
/* MT7530 reset */
|
||||
mt753x_reg_write(priv, SYS_CTRL_REG, SW_SYS_RST | SW_REG_RST);
|
||||
udelay(100);
|
||||
|
||||
val = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
|
||||
MAC_MODE | FORCE_MODE |
|
||||
MAC_TX_EN | MAC_RX_EN |
|
||||
BKOFF_EN | BACKPR_EN |
|
||||
(SPEED_1000M << FORCE_SPD_S) |
|
||||
FORCE_DPX | FORCE_LINK;
|
||||
|
||||
/* MT7530 Port6: Forced 1000M/FD, FC disabled */
|
||||
mt753x_reg_write(priv, PMCR_REG(6), val);
|
||||
|
||||
/* MT7530 Port5: Forced link down */
|
||||
mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE);
|
||||
|
||||
/* MT7530 Port6: Set to RGMII */
|
||||
mt753x_reg_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_M, P6_INTF_MODE_RGMII);
|
||||
|
||||
/* Hardware Trap: Enable Port6, Disable Port5 */
|
||||
mt753x_reg_read(priv, HWTRAP_REG, &val);
|
||||
val |= CHG_TRAP | LOOPDET_DIS | P5_INTF_DIS |
|
||||
(P5_INTF_SEL_GMAC5 << P5_INTF_SEL_S) |
|
||||
(P5_INTF_MODE_RGMII << P5_INTF_MODE_S);
|
||||
val &= ~(C_MDIO_BPS | P6_INTF_DIS);
|
||||
mt753x_reg_write(priv, MHWTRAP_REG, val);
|
||||
|
||||
/* Setup switch core pll */
|
||||
mt7530_pad_clk_setup(priv, priv->phy_interface);
|
||||
|
||||
/* Lower Tx Driving for TRGMII path */
|
||||
for (i = 0 ; i < NUM_TRGMII_CTRL ; i++)
|
||||
mt753x_reg_write(priv, MT7530_TRGMII_TD_ODT(i),
|
||||
(8 << TD_DM_DRVP_S) | (8 << TD_DM_DRVN_S));
|
||||
|
||||
for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
|
||||
mt753x_reg_rmw(priv, MT7530_TRGMII_RD(i), RD_TAP_M, 16);
|
||||
|
||||
/* Turn on PHYs */
|
||||
for (i = 0; i < MT753X_NUM_PHYS; i++) {
|
||||
phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i);
|
||||
phy_val = priv->mii_read(priv, phy_addr, MII_BMCR);
|
||||
phy_val &= ~BMCR_PDOWN;
|
||||
priv->mii_write(priv, phy_addr, MII_BMCR, phy_val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mt7531_core_pll_setup(struct mtk_eth_priv *priv, int mcm)
|
||||
{
|
||||
/* Step 1 : Disable MT7531 COREPLL */
|
||||
mt753x_reg_rmw(priv, MT7531_PLLGP_EN, EN_COREPLL, 0);
|
||||
|
||||
/* Step 2: switch to XTAL output */
|
||||
mt753x_reg_rmw(priv, MT7531_PLLGP_EN, SW_CLKSW, SW_CLKSW);
|
||||
|
||||
mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_EN, 0);
|
||||
|
||||
/* Step 3: disable PLLGP and enable program PLLGP */
|
||||
mt753x_reg_rmw(priv, MT7531_PLLGP_EN, SW_PLLGP, SW_PLLGP);
|
||||
|
||||
/* Step 4: program COREPLL output frequency to 500MHz */
|
||||
mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_POSDIV_M,
|
||||
2 << RG_COREPLL_POSDIV_S);
|
||||
udelay(25);
|
||||
|
||||
/* Currently, support XTAL 25Mhz only */
|
||||
mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_SDM_PCW_M,
|
||||
0x140000 << RG_COREPLL_SDM_PCW_S);
|
||||
|
||||
/* Set feedback divide ratio update signal to high */
|
||||
mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_SDM_PCW_CHG,
|
||||
RG_COREPLL_SDM_PCW_CHG);
|
||||
|
||||
/* Wait for at least 16 XTAL clocks */
|
||||
udelay(10);
|
||||
|
||||
/* Step 5: set feedback divide ratio update signal to low */
|
||||
mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_SDM_PCW_CHG, 0);
|
||||
|
||||
/* add enable 325M clock for SGMII */
|
||||
mt753x_reg_write(priv, MT7531_ANA_PLLGP_CR5, 0xad0000);
|
||||
|
||||
/* add enable 250SSC clock for RGMII */
|
||||
mt753x_reg_write(priv, MT7531_ANA_PLLGP_CR2, 0x4f40000);
|
||||
|
||||
/*Step 6: Enable MT7531 PLL */
|
||||
mt753x_reg_rmw(priv, MT7531_PLLGP_CR0, RG_COREPLL_EN, RG_COREPLL_EN);
|
||||
|
||||
mt753x_reg_rmw(priv, MT7531_PLLGP_EN, EN_COREPLL, EN_COREPLL);
|
||||
|
||||
udelay(25);
|
||||
}
|
||||
|
||||
static int mt7531_port_sgmii_init(struct mtk_eth_priv *priv,
|
||||
u32 port)
|
||||
{
|
||||
if (port != 5 && port != 6) {
|
||||
printf("mt7531: port %d is not a SGMII port\n", port);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Set SGMII GEN2 speed(2.5G) */
|
||||
mt753x_reg_rmw(priv, MT7531_PHYA_CTRL_SIGNAL3(port),
|
||||
SGMSYS_SPEED_2500, SGMSYS_SPEED_2500);
|
||||
|
||||
/* Disable SGMII AN */
|
||||
mt753x_reg_rmw(priv, MT7531_PCS_CONTROL_1(port),
|
||||
SGMII_AN_ENABLE, 0);
|
||||
|
||||
/* SGMII force mode setting */
|
||||
mt753x_reg_write(priv, MT7531_SGMII_MODE(port), SGMII_FORCE_MODE);
|
||||
|
||||
/* Release PHYA power down state */
|
||||
mt753x_reg_rmw(priv, MT7531_QPHY_PWR_STATE_CTRL(port),
|
||||
SGMII_PHYA_PWD, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7531_port_rgmii_init(struct mtk_eth_priv *priv, u32 port)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
if (port != 5) {
|
||||
printf("error: RGMII mode is not available for port %d\n",
|
||||
port);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mt753x_reg_read(priv, MT7531_CLKGEN_CTRL, &val);
|
||||
val |= GP_CLK_EN;
|
||||
val &= ~GP_MODE_M;
|
||||
val |= GP_MODE_RGMII << GP_MODE_S;
|
||||
val |= TXCLK_NO_REVERSE;
|
||||
val |= RXCLK_NO_DELAY;
|
||||
val &= ~CLK_SKEW_IN_M;
|
||||
val |= CLK_SKEW_IN_NO_CHANGE << CLK_SKEW_IN_S;
|
||||
val &= ~CLK_SKEW_OUT_M;
|
||||
val |= CLK_SKEW_OUT_NO_CHANGE << CLK_SKEW_OUT_S;
|
||||
mt753x_reg_write(priv, MT7531_CLKGEN_CTRL, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mt7531_phy_setting(struct mtk_eth_priv *priv)
|
||||
{
|
||||
int i;
|
||||
u32 val;
|
||||
|
||||
for (i = 0; i < MT753X_NUM_PHYS; i++) {
|
||||
/* Enable HW auto downshift */
|
||||
priv->mii_write(priv, i, 0x1f, 0x1);
|
||||
val = priv->mii_read(priv, i, PHY_EXT_REG_14);
|
||||
val |= PHY_EN_DOWN_SHFIT;
|
||||
priv->mii_write(priv, i, PHY_EXT_REG_14, val);
|
||||
|
||||
/* PHY link down power saving enable */
|
||||
val = priv->mii_read(priv, i, PHY_EXT_REG_17);
|
||||
val |= PHY_LINKDOWN_POWER_SAVING_EN;
|
||||
priv->mii_write(priv, i, PHY_EXT_REG_17, val);
|
||||
|
||||
val = priv->mmd_read(priv, i, 0x1e, PHY_DEV1E_REG_0C6);
|
||||
val &= ~PHY_POWER_SAVING_M;
|
||||
val |= PHY_POWER_SAVING_TX << PHY_POWER_SAVING_S;
|
||||
priv->mmd_write(priv, i, 0x1e, PHY_DEV1E_REG_0C6, val);
|
||||
}
|
||||
}
|
||||
|
||||
static int mt7531_setup(struct mtk_eth_priv *priv)
|
||||
{
|
||||
u16 phy_addr, phy_val;
|
||||
u32 val;
|
||||
u32 pmcr;
|
||||
u32 port5_sgmii;
|
||||
int i;
|
||||
|
||||
priv->mt753x_phy_base = (priv->mt753x_smi_addr + 1) &
|
||||
MT753X_SMI_ADDR_MASK;
|
||||
|
||||
/* Turn off PHYs */
|
||||
for (i = 0; i < MT753X_NUM_PHYS; i++) {
|
||||
phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i);
|
||||
phy_val = priv->mii_read(priv, phy_addr, MII_BMCR);
|
||||
phy_val |= BMCR_PDOWN;
|
||||
priv->mii_write(priv, phy_addr, MII_BMCR, phy_val);
|
||||
}
|
||||
|
||||
/* Force MAC link down before reset */
|
||||
mt753x_reg_write(priv, PMCR_REG(5), FORCE_MODE_LNK);
|
||||
mt753x_reg_write(priv, PMCR_REG(6), FORCE_MODE_LNK);
|
||||
|
||||
/* Switch soft reset */
|
||||
mt753x_reg_write(priv, SYS_CTRL_REG, SW_SYS_RST | SW_REG_RST);
|
||||
udelay(100);
|
||||
|
||||
/* Enable MDC input Schmitt Trigger */
|
||||
mt753x_reg_rmw(priv, MT7531_SMT0_IOLB, SMT_IOLB_5_SMI_MDC_EN,
|
||||
SMT_IOLB_5_SMI_MDC_EN);
|
||||
|
||||
mt7531_core_pll_setup(priv, priv->mcm);
|
||||
|
||||
mt753x_reg_read(priv, MT7531_TOP_SIG_SR, &val);
|
||||
port5_sgmii = !!(val & PAD_DUAL_SGMII_EN);
|
||||
|
||||
/* port5 support either RGMII or SGMII, port6 only support SGMII. */
|
||||
switch (priv->phy_interface) {
|
||||
case PHY_INTERFACE_MODE_RGMII:
|
||||
if (!port5_sgmii)
|
||||
mt7531_port_rgmii_init(priv, 5);
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
mt7531_port_sgmii_init(priv, 6);
|
||||
if (port5_sgmii)
|
||||
mt7531_port_sgmii_init(priv, 5);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
pmcr = MT7531_FORCE_MODE |
|
||||
(IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
|
||||
MAC_MODE | MAC_TX_EN | MAC_RX_EN |
|
||||
BKOFF_EN | BACKPR_EN |
|
||||
FORCE_RX_FC | FORCE_TX_FC |
|
||||
(SPEED_1000M << FORCE_SPD_S) | FORCE_DPX |
|
||||
FORCE_LINK;
|
||||
|
||||
mt753x_reg_write(priv, PMCR_REG(5), pmcr);
|
||||
mt753x_reg_write(priv, PMCR_REG(6), pmcr);
|
||||
|
||||
/* Turn on PHYs */
|
||||
for (i = 0; i < MT753X_NUM_PHYS; i++) {
|
||||
phy_addr = MT753X_PHY_ADDR(priv->mt753x_phy_base, i);
|
||||
phy_val = priv->mii_read(priv, phy_addr, MII_BMCR);
|
||||
phy_val &= ~BMCR_PDOWN;
|
||||
priv->mii_write(priv, phy_addr, MII_BMCR, phy_val);
|
||||
}
|
||||
|
||||
mt7531_phy_setting(priv);
|
||||
|
||||
/* Enable Internal PHYs */
|
||||
val = mt753x_core_reg_read(priv, CORE_PLL_GROUP4);
|
||||
val |= MT7531_BYPASS_MODE;
|
||||
val &= ~MT7531_POWER_ON_OFF;
|
||||
mt753x_core_reg_write(priv, CORE_PLL_GROUP4, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt753x_switch_init(struct mtk_eth_priv *priv)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* Global reset switch */
|
||||
if (priv->mcm) {
|
||||
reset_assert(&priv->rst_mcm);
|
||||
|
@ -565,87 +964,22 @@ static int mt7530_setup(struct mtk_eth_priv *priv)
|
|||
mdelay(1000);
|
||||
}
|
||||
|
||||
/* Modify HWTRAP first to allow direct access to internal PHYs */
|
||||
mt7530_reg_read(priv, HWTRAP_REG, &val);
|
||||
val |= CHG_TRAP;
|
||||
val &= ~C_MDIO_BPS;
|
||||
mt7530_reg_write(priv, MHWTRAP_REG, val);
|
||||
|
||||
/* Calculate the phy base address */
|
||||
val = ((val & SMI_ADDR_M) >> SMI_ADDR_S) << 3;
|
||||
priv->mt7530_phy_base = (val | 0x7) + 1;
|
||||
|
||||
/* Turn off PHYs */
|
||||
for (i = 0; i < MT7530_NUM_PHYS; i++) {
|
||||
phy_addr = MT7530_PHY_ADDR(priv->mt7530_phy_base, i);
|
||||
phy_val = priv->mii_read(priv, phy_addr, MII_BMCR);
|
||||
phy_val |= BMCR_PDOWN;
|
||||
priv->mii_write(priv, phy_addr, MII_BMCR, phy_val);
|
||||
}
|
||||
|
||||
/* Force MAC link down before reset */
|
||||
mt7530_reg_write(priv, PCMR_REG(5), FORCE_MODE);
|
||||
mt7530_reg_write(priv, PCMR_REG(6), FORCE_MODE);
|
||||
|
||||
/* MT7530 reset */
|
||||
mt7530_reg_write(priv, SYS_CTRL_REG, SW_SYS_RST | SW_REG_RST);
|
||||
udelay(100);
|
||||
|
||||
val = (1 << IPG_CFG_S) |
|
||||
MAC_MODE | FORCE_MODE |
|
||||
MAC_TX_EN | MAC_RX_EN |
|
||||
BKOFF_EN | BACKPR_EN |
|
||||
(SPEED_1000M << FORCE_SPD_S) |
|
||||
FORCE_DPX | FORCE_LINK;
|
||||
|
||||
/* MT7530 Port6: Forced 1000M/FD, FC disabled */
|
||||
mt7530_reg_write(priv, PCMR_REG(6), val);
|
||||
|
||||
/* MT7530 Port5: Forced link down */
|
||||
mt7530_reg_write(priv, PCMR_REG(5), FORCE_MODE);
|
||||
|
||||
/* MT7530 Port6: Set to RGMII */
|
||||
mt7530_reg_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_M, P6_INTF_MODE_RGMII);
|
||||
|
||||
/* Hardware Trap: Enable Port6, Disable Port5 */
|
||||
mt7530_reg_read(priv, HWTRAP_REG, &val);
|
||||
val |= CHG_TRAP | LOOPDET_DIS | P5_INTF_DIS |
|
||||
(P5_INTF_SEL_GMAC5 << P5_INTF_SEL_S) |
|
||||
(P5_INTF_MODE_RGMII << P5_INTF_MODE_S);
|
||||
val &= ~(C_MDIO_BPS | P6_INTF_DIS);
|
||||
mt7530_reg_write(priv, MHWTRAP_REG, val);
|
||||
|
||||
/* Setup switch core pll */
|
||||
mt7530_pad_clk_setup(priv, priv->phy_interface);
|
||||
|
||||
/* Lower Tx Driving for TRGMII path */
|
||||
for (i = 0 ; i < NUM_TRGMII_CTRL ; i++)
|
||||
mt7530_reg_write(priv, MT7530_TRGMII_TD_ODT(i),
|
||||
(8 << TD_DM_DRVP_S) | (8 << TD_DM_DRVN_S));
|
||||
|
||||
for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
|
||||
mt7530_reg_rmw(priv, MT7530_TRGMII_RD(i), RD_TAP_M, 16);
|
||||
|
||||
/* Turn on PHYs */
|
||||
for (i = 0; i < MT7530_NUM_PHYS; i++) {
|
||||
phy_addr = MT7530_PHY_ADDR(priv->mt7530_phy_base, i);
|
||||
phy_val = priv->mii_read(priv, phy_addr, MII_BMCR);
|
||||
phy_val &= ~BMCR_PDOWN;
|
||||
priv->mii_write(priv, phy_addr, MII_BMCR, phy_val);
|
||||
}
|
||||
ret = priv->switch_init(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set port isolation */
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (i = 0; i < MT753X_NUM_PORTS; i++) {
|
||||
/* Set port matrix mode */
|
||||
if (i != 6)
|
||||
mt7530_reg_write(priv, PCR_REG(i),
|
||||
mt753x_reg_write(priv, PCR_REG(i),
|
||||
(0x40 << PORT_MATRIX_S));
|
||||
else
|
||||
mt7530_reg_write(priv, PCR_REG(i),
|
||||
mt753x_reg_write(priv, PCR_REG(i),
|
||||
(0x3f << PORT_MATRIX_S));
|
||||
|
||||
/* Set port mode to user port */
|
||||
mt7530_reg_write(priv, PVC_REG(i),
|
||||
mt753x_reg_write(priv, PVC_REG(i),
|
||||
(0x8100 << STAG_VPID_S) |
|
||||
(VLAN_ATTR_USER << VLAN_ATTR_S));
|
||||
}
|
||||
|
@ -659,7 +993,7 @@ static void mtk_phy_link_adjust(struct mtk_eth_priv *priv)
|
|||
u8 flowctrl;
|
||||
u32 mcr;
|
||||
|
||||
mcr = (1 << IPG_CFG_S) |
|
||||
mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
|
||||
(MAC_RX_PKT_LEN_1536 << MAC_RX_PKT_LEN_S) |
|
||||
MAC_MODE | FORCE_MODE |
|
||||
MAC_TX_EN | MAC_RX_EN |
|
||||
|
@ -804,7 +1138,7 @@ static void mtk_mac_init(struct mtk_eth_priv *priv)
|
|||
ge_mode << SYSCFG0_GE_MODE_S(priv->gmac_id));
|
||||
|
||||
if (priv->force_mode) {
|
||||
mcr = (1 << IPG_CFG_S) |
|
||||
mcr = (IPG_96BIT_WITH_SHORT_IPG << IPG_CFG_S) |
|
||||
(MAC_RX_PKT_LEN_1536 << MAC_RX_PKT_LEN_S) |
|
||||
MAC_MODE | FORCE_MODE |
|
||||
MAC_TX_EN | MAC_RX_EN |
|
||||
|
@ -1051,7 +1385,7 @@ static int mtk_eth_probe(struct udevice *dev)
|
|||
return mtk_phy_probe(dev);
|
||||
|
||||
/* Initialize switch */
|
||||
return priv->switch_init(priv);
|
||||
return mt753x_switch_init(priv);
|
||||
}
|
||||
|
||||
static int mtk_eth_remove(struct udevice *dev)
|
||||
|
@ -1160,7 +1494,11 @@ static int mtk_eth_ofdata_to_platdata(struct udevice *dev)
|
|||
if (!strcmp(str, "mt7530")) {
|
||||
priv->sw = SW_MT7530;
|
||||
priv->switch_init = mt7530_setup;
|
||||
priv->mt7530_smi_addr = MT7530_DFL_SMI_ADDR;
|
||||
priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR;
|
||||
} else if (!strcmp(str, "mt7531")) {
|
||||
priv->sw = SW_MT7531;
|
||||
priv->switch_init = mt7531_setup;
|
||||
priv->mt753x_smi_addr = MT753X_DFL_SMI_ADDR;
|
||||
} else {
|
||||
printf("error: unsupported switch\n");
|
||||
return -EINVAL;
|
||||
|
|
|
@ -34,7 +34,9 @@
|
|||
|
||||
/* SGMII subsystem config registers */
|
||||
#define SGMSYS_PCS_CONTROL_1 0x0
|
||||
#define SGMII_LINK_STATUS BIT(18)
|
||||
#define SGMII_AN_ENABLE BIT(12)
|
||||
#define SGMII_AN_RESTART BIT(9)
|
||||
|
||||
#define SGMSYS_SGMII_MODE 0x20
|
||||
#define SGMII_FORCE_MODE 0x31120019
|
||||
|
@ -139,6 +141,11 @@
|
|||
#define FORCE_DPX BIT(1)
|
||||
#define FORCE_LINK BIT(0)
|
||||
|
||||
/* Values of IPG_CFG */
|
||||
#define IPG_96BIT 0
|
||||
#define IPG_96BIT_WITH_SHORT_IPG 1
|
||||
#define IPG_64BIT 2
|
||||
|
||||
/* MAC_RX_PKT_LEN: Max RX packet length */
|
||||
#define MAC_RX_PKT_LEN_1518 0
|
||||
#define MAC_RX_PKT_LEN_1536 1
|
||||
|
@ -178,17 +185,73 @@
|
|||
#define VLAN_ATTR_TRANSLATION 2
|
||||
#define VLAN_ATTR_TRANSPARENT 3
|
||||
|
||||
#define PCMR_REG(p) (0x3000 + (p) * 0x100)
|
||||
/* XXX: all fields are defined under GMAC_PORT_MCR */
|
||||
#define PMCR_REG(p) (0x3000 + (p) * 0x100)
|
||||
/* XXX: all fields of MT7530 are defined under GMAC_PORT_MCR
|
||||
* MT7531 specific fields are defined below
|
||||
*/
|
||||
#define FORCE_MODE_EEE1G BIT(25)
|
||||
#define FORCE_MODE_EEE100 BIT(26)
|
||||
#define FORCE_MODE_TX_FC BIT(27)
|
||||
#define FORCE_MODE_RX_FC BIT(28)
|
||||
#define FORCE_MODE_DPX BIT(29)
|
||||
#define FORCE_MODE_SPD BIT(30)
|
||||
#define FORCE_MODE_LNK BIT(31)
|
||||
#define MT7531_FORCE_MODE FORCE_MODE_EEE1G | FORCE_MODE_EEE100 |\
|
||||
FORCE_MODE_TX_FC | FORCE_MODE_RX_FC | \
|
||||
FORCE_MODE_DPX | FORCE_MODE_SPD | \
|
||||
FORCE_MODE_LNK
|
||||
|
||||
/* MT7531 SGMII Registers */
|
||||
#define MT7531_SGMII_REG_BASE 0x5000
|
||||
#define MT7531_SGMII_REG_PORT_BASE 0x1000
|
||||
#define MT7531_SGMII_REG(p, r) (MT7531_SGMII_REG_BASE + \
|
||||
(p) * MT7531_SGMII_REG_PORT_BASE + (r))
|
||||
#define MT7531_PCS_CONTROL_1(p) MT7531_SGMII_REG(((p) - 5), 0x00)
|
||||
#define MT7531_SGMII_MODE(p) MT7531_SGMII_REG(((p) - 5), 0x20)
|
||||
#define MT7531_QPHY_PWR_STATE_CTRL(p) MT7531_SGMII_REG(((p) - 5), 0xe8)
|
||||
#define MT7531_PHYA_CTRL_SIGNAL3(p) MT7531_SGMII_REG(((p) - 5), 0x128)
|
||||
/* XXX: all fields of MT7531 SGMII are defined under SGMSYS */
|
||||
|
||||
/* MT753x System Control Register */
|
||||
#define SYS_CTRL_REG 0x7000
|
||||
#define SW_PHY_RST BIT(2)
|
||||
#define SW_SYS_RST BIT(1)
|
||||
#define SW_REG_RST BIT(0)
|
||||
|
||||
#define NUM_TRGMII_CTRL 5
|
||||
/* MT7531 */
|
||||
#define MT7531_PHY_IAC 0x701c
|
||||
/* XXX: all fields are defined under GMAC_PIAC_REG */
|
||||
|
||||
#define MT7531_CLKGEN_CTRL 0x7500
|
||||
#define CLK_SKEW_OUT_S 8
|
||||
#define CLK_SKEW_OUT_M 0x300
|
||||
#define CLK_SKEW_IN_S 6
|
||||
#define CLK_SKEW_IN_M 0xc0
|
||||
#define RXCLK_NO_DELAY BIT(5)
|
||||
#define TXCLK_NO_REVERSE BIT(4)
|
||||
#define GP_MODE_S 1
|
||||
#define GP_MODE_M 0x06
|
||||
#define GP_CLK_EN BIT(0)
|
||||
|
||||
/* Values of GP_MODE */
|
||||
#define GP_MODE_RGMII 0
|
||||
#define GP_MODE_MII 1
|
||||
#define GP_MODE_REV_MII 2
|
||||
|
||||
/* Values of CLK_SKEW_IN */
|
||||
#define CLK_SKEW_IN_NO_CHANGE 0
|
||||
#define CLK_SKEW_IN_DELAY_100PPS 1
|
||||
#define CLK_SKEW_IN_DELAY_200PPS 2
|
||||
#define CLK_SKEW_IN_REVERSE 3
|
||||
|
||||
/* Values of CLK_SKEW_OUT */
|
||||
#define CLK_SKEW_OUT_NO_CHANGE 0
|
||||
#define CLK_SKEW_OUT_DELAY_100PPS 1
|
||||
#define CLK_SKEW_OUT_DELAY_200PPS 2
|
||||
#define CLK_SKEW_OUT_REVERSE 3
|
||||
|
||||
#define HWTRAP_REG 0x7800
|
||||
/* MT7530 Modified Hardware Trap Status Registers */
|
||||
#define MHWTRAP_REG 0x7804
|
||||
#define CHG_TRAP BIT(16)
|
||||
#define LOOPDET_DIS BIT(14)
|
||||
|
@ -222,6 +285,8 @@
|
|||
#define P6_INTF_MODE_RGMII 0
|
||||
#define P6_INTF_MODE_TRGMII 1
|
||||
|
||||
#define NUM_TRGMII_CTRL 5
|
||||
|
||||
#define MT7530_TRGMII_RD(n) (0x7a10 + (n) * 8)
|
||||
#define RD_TAP_S 0
|
||||
#define RD_TAP_M 0x7f
|
||||
|
@ -229,8 +294,34 @@
|
|||
#define MT7530_TRGMII_TD_ODT(n) (0x7a54 + (n) * 8)
|
||||
/* XXX: all fields are defined under GMAC_TRGMII_TD_ODT */
|
||||
|
||||
/* MT7530 GPHY MDIO Indirect Access Registers */
|
||||
/* TOP Signals Status Register */
|
||||
#define MT7531_TOP_SIG_SR 0x780c
|
||||
#define PAD_MCM_SMI_EN BIT(0)
|
||||
#define PAD_DUAL_SGMII_EN BIT(1)
|
||||
|
||||
/* MT7531 PLLGP Registers */
|
||||
#define MT7531_PLLGP_EN 0x7820
|
||||
#define EN_COREPLL BIT(2)
|
||||
#define SW_CLKSW BIT(1)
|
||||
#define SW_PLLGP BIT(0)
|
||||
|
||||
#define MT7531_PLLGP_CR0 0x78a8
|
||||
#define RG_COREPLL_EN BIT(22)
|
||||
#define RG_COREPLL_POSDIV_S 23
|
||||
#define RG_COREPLL_POSDIV_M 0x3800000
|
||||
#define RG_COREPLL_SDM_PCW_S 1
|
||||
#define RG_COREPLL_SDM_PCW_M 0x3ffffe
|
||||
#define RG_COREPLL_SDM_PCW_CHG BIT(0)
|
||||
|
||||
/* MT7531 RGMII and SGMII PLL clock */
|
||||
#define MT7531_ANA_PLLGP_CR2 0x78b0
|
||||
#define MT7531_ANA_PLLGP_CR5 0x78bc
|
||||
|
||||
/* MT7531 GPIO GROUP IOLB SMT0 Control */
|
||||
#define MT7531_SMT0_IOLB 0x7f04
|
||||
#define SMT_IOLB_5_SMI_MDC_EN BIT(5)
|
||||
|
||||
/* MT7530 GPHY MDIO Indirect Access Registers */
|
||||
#define MII_MMD_ACC_CTL_REG 0x0d
|
||||
#define MMD_CMD_S 14
|
||||
#define MMD_CMD_M 0xc000
|
||||
|
@ -246,7 +337,6 @@
|
|||
#define MII_MMD_ADDR_DATA_REG 0x0e
|
||||
|
||||
/* MT7530 GPHY MDIO MMD Registers */
|
||||
|
||||
#define CORE_PLL_GROUP2 0x401
|
||||
#define RG_SYSPLL_EN_NORMAL BIT(15)
|
||||
#define RG_SYSPLL_VODEN BIT(14)
|
||||
|
@ -254,6 +344,8 @@
|
|||
#define RG_SYSPLL_POSDIV_M 0x60
|
||||
|
||||
#define CORE_PLL_GROUP4 0x403
|
||||
#define MT7531_BYPASS_MODE BIT(4)
|
||||
#define MT7531_POWER_ON_OFF BIT(5)
|
||||
#define RG_SYSPLL_DDSFBK_EN BIT(12)
|
||||
#define RG_SYSPLL_BIAS_EN BIT(11)
|
||||
#define RG_SYSPLL_BIAS_LPF_EN BIT(10)
|
||||
|
@ -298,4 +390,24 @@
|
|||
#define REG_GSWCK_EN BIT(0)
|
||||
#define REG_TRGMIICK_EN BIT(1)
|
||||
|
||||
/* Extend PHY Control Register 3 */
|
||||
#define PHY_EXT_REG_14 0x14
|
||||
|
||||
/* Fields of PHY_EXT_REG_14 */
|
||||
#define PHY_EN_DOWN_SHFIT BIT(4)
|
||||
|
||||
/* Extend PHY Control Register 4 */
|
||||
#define PHY_EXT_REG_17 0x17
|
||||
|
||||
/* Fields of PHY_EXT_REG_17 */
|
||||
#define PHY_LINKDOWN_POWER_SAVING_EN BIT(4)
|
||||
|
||||
/* PHY RXADC Control Register 7 */
|
||||
#define PHY_DEV1E_REG_0C6 0x0c6
|
||||
|
||||
/* Fields of PHY_DEV1E_REG_0C6 */
|
||||
#define PHY_POWER_SAVING_S 8
|
||||
#define PHY_POWER_SAVING_M 0x300
|
||||
#define PHY_POWER_SAVING_TX 0x0
|
||||
|
||||
#endif /* _MTK_ETH_H_ */
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <env.h>
|
||||
#include <dm.h>
|
||||
#include <wdt.h>
|
||||
#include <mpc8xx.h>
|
||||
|
@ -21,8 +22,15 @@ void hw_watchdog_reset(void)
|
|||
static int mpc8xx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
|
||||
{
|
||||
immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
|
||||
u32 val = CONFIG_SYS_SYPCR;
|
||||
const char *mode = env_get("watchdog_mode");
|
||||
|
||||
out_be32(&immap->im_siu_conf.sc_sypcr, CONFIG_SYS_SYPCR);
|
||||
if (strcmp(mode, "off") == 0)
|
||||
val = val & ~(SYPCR_SWE | SYPCR_SWRI);
|
||||
else if (strcmp(mode, "nmi") == 0)
|
||||
val = (val & ~SYPCR_SWRI) | SYPCR_SWE;
|
||||
|
||||
out_be32(&immap->im_siu_conf.sc_sypcr, val);
|
||||
|
||||
if (!(in_be32(&immap->im_siu_conf.sc_sypcr) & SYPCR_SWE))
|
||||
return -EBUSY;
|
||||
|
|
3
env/Kconfig
vendored
3
env/Kconfig
vendored
|
@ -3,6 +3,9 @@ menu "Environment"
|
|||
config ENV_SUPPORT
|
||||
def_bool y
|
||||
|
||||
config SAVEENV
|
||||
def_bool y if CMD_SAVEENV
|
||||
|
||||
config ENV_IS_NOWHERE
|
||||
bool "Environment is not stored"
|
||||
default y if !ENV_IS_IN_EEPROM && !ENV_IS_IN_EXT4 && \
|
||||
|
|
2
env/Makefile
vendored
2
env/Makefile
vendored
|
@ -7,9 +7,9 @@ obj-$(CONFIG_$(SPL_TPL_)ENV_SUPPORT) += common.o
|
|||
obj-$(CONFIG_$(SPL_TPL_)ENV_SUPPORT) += env.o
|
||||
obj-$(CONFIG_$(SPL_TPL_)ENV_SUPPORT) += attr.o
|
||||
obj-$(CONFIG_$(SPL_TPL_)ENV_SUPPORT) += flags.o
|
||||
obj-$(CONFIG_$(SPL_TPL_)ENV_SUPPORT) += callback.o
|
||||
|
||||
ifndef CONFIG_SPL_BUILD
|
||||
obj-y += callback.o
|
||||
obj-$(CONFIG_ENV_IS_IN_EEPROM) += eeprom.o
|
||||
extra-$(CONFIG_ENV_IS_EMBEDDED) += embedded.o
|
||||
obj-$(CONFIG_ENV_IS_IN_EEPROM) += embedded.o
|
||||
|
|
2
env/callback.c
vendored
2
env/callback.c
vendored
|
@ -55,6 +55,8 @@ void env_callback_init(struct env_entry *var_entry)
|
|||
first_call = 0;
|
||||
}
|
||||
|
||||
var_entry->callback = NULL;
|
||||
|
||||
/* look in the ".callbacks" var for a reference to this variable */
|
||||
if (callback_list != NULL)
|
||||
ret = env_attr_lookup(callback_list, var_name, callback_name);
|
||||
|
|
4
env/ext4.c
vendored
4
env/ext4.c
vendored
|
@ -41,7 +41,6 @@ __weak const char *env_ext4_get_dev_part(void)
|
|||
return (const char *)CONFIG_ENV_EXT4_DEVICE_AND_PART;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CMD_SAVEENV
|
||||
static int env_ext4_save(void)
|
||||
{
|
||||
env_t env_new;
|
||||
|
@ -83,7 +82,6 @@ static int env_ext4_save(void)
|
|||
puts("done\n");
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_CMD_SAVEENV */
|
||||
|
||||
static int env_ext4_load(void)
|
||||
{
|
||||
|
@ -137,5 +135,5 @@ U_BOOT_ENV_LOCATION(ext4) = {
|
|||
.location = ENVL_EXT4,
|
||||
ENV_NAME("EXT4")
|
||||
.load = env_ext4_load,
|
||||
.save = env_save_ptr(env_ext4_save),
|
||||
.save = ENV_SAVE_PTR(env_ext4_save),
|
||||
};
|
||||
|
|
9
env/fat.c
vendored
9
env/fat.c
vendored
|
@ -26,12 +26,8 @@
|
|||
# endif
|
||||
#else
|
||||
# define LOADENV
|
||||
# if defined(CONFIG_CMD_SAVEENV)
|
||||
# define CMD_SAVEENV
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CMD_SAVEENV
|
||||
static int env_fat_save(void)
|
||||
{
|
||||
env_t __aligned(ARCH_DMA_MINALIGN) env_new;
|
||||
|
@ -76,7 +72,6 @@ static int env_fat_save(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CMD_SAVEENV */
|
||||
|
||||
#ifdef LOADENV
|
||||
static int env_fat_load(void)
|
||||
|
@ -135,7 +130,5 @@ U_BOOT_ENV_LOCATION(fat) = {
|
|||
#ifdef LOADENV
|
||||
.load = env_fat_load,
|
||||
#endif
|
||||
#ifdef CMD_SAVEENV
|
||||
.save = env_save_ptr(env_fat_save),
|
||||
#endif
|
||||
.save = ENV_SAVE_PTR(env_fat_save),
|
||||
};
|
||||
|
|
1
env/flags.c
vendored
1
env/flags.c
vendored
|
@ -457,7 +457,6 @@ static int set_flags(const char *name, const char *value, void *priv)
|
|||
|
||||
e.key = name;
|
||||
e.data = NULL;
|
||||
e.callback = NULL;
|
||||
hsearch_r(e, ENV_FIND, &ep, &env_htab, 0);
|
||||
|
||||
/* does the env variable actually exist? */
|
||||
|
|
12
env/sf.c
vendored
12
env/sf.c
vendored
|
@ -21,16 +21,12 @@
|
|||
#include <u-boot/crc.h>
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
#define CMD_SAVEENV
|
||||
#define INITENV
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ENV_OFFSET_REDUND
|
||||
#ifdef CMD_SAVEENV
|
||||
static ulong env_offset = CONFIG_ENV_OFFSET;
|
||||
static ulong env_new_offset = CONFIG_ENV_OFFSET_REDUND;
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_ENV_OFFSET_REDUND */
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
@ -69,7 +65,6 @@ static int setup_flash_device(void)
|
|||
}
|
||||
|
||||
#if defined(CONFIG_ENV_OFFSET_REDUND)
|
||||
#ifdef CMD_SAVEENV
|
||||
static int env_sf_save(void)
|
||||
{
|
||||
env_t env_new;
|
||||
|
@ -148,7 +143,6 @@ static int env_sf_save(void)
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CMD_SAVEENV */
|
||||
|
||||
static int env_sf_load(void)
|
||||
{
|
||||
|
@ -187,7 +181,6 @@ out:
|
|||
return ret;
|
||||
}
|
||||
#else
|
||||
#ifdef CMD_SAVEENV
|
||||
static int env_sf_save(void)
|
||||
{
|
||||
u32 saved_size, saved_offset, sector;
|
||||
|
@ -247,7 +240,6 @@ static int env_sf_save(void)
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CMD_SAVEENV */
|
||||
|
||||
static int env_sf_load(void)
|
||||
{
|
||||
|
@ -313,9 +305,7 @@ U_BOOT_ENV_LOCATION(sf) = {
|
|||
.location = ENVL_SPI_FLASH,
|
||||
ENV_NAME("SPI Flash")
|
||||
.load = env_sf_load,
|
||||
#ifdef CMD_SAVEENV
|
||||
.save = env_save_ptr(env_sf_save),
|
||||
#endif
|
||||
.save = ENV_SAVE_PTR(env_sf_save),
|
||||
#if defined(INITENV) && (CONFIG_ENV_ADDR != 0x0)
|
||||
.init = env_sf_init,
|
||||
#endif
|
||||
|
|
|
@ -177,16 +177,26 @@
|
|||
"initrd_addr=0x88000000\0" \
|
||||
"fdtfile=devtree.dtb\0" \
|
||||
"fdt_addr=0x83000000\0" \
|
||||
"fdt_high=0xffffffffffffffff\0" \
|
||||
"initrd_high=0xffffffffffffffff\0"
|
||||
"boot_name=boot.img\0" \
|
||||
"boot_addr=0x8007f800\0"
|
||||
|
||||
#define CONFIG_BOOTCOMMAND "smhload ${kernel_name} ${kernel_addr}; " \
|
||||
"smhload ${fdtfile} ${fdt_addr}; " \
|
||||
"smhload ${initrd_name} ${initrd_addr} "\
|
||||
"initrd_end; " \
|
||||
"fdt addr ${fdt_addr}; fdt resize; " \
|
||||
"fdt chosen ${initrd_addr} ${initrd_end}; " \
|
||||
"booti $kernel_addr - $fdt_addr"
|
||||
#define CONFIG_BOOTCOMMAND "if smhload ${boot_name} ${boot_addr}; then " \
|
||||
" set bootargs; " \
|
||||
" abootimg addr ${boot_addr}; " \
|
||||
" abootimg get dtb --index=0 fdt_addr; " \
|
||||
" bootm ${boot_addr} ${boot_addr} " \
|
||||
" ${fdt_addr}; " \
|
||||
"else; " \
|
||||
" set fdt_high 0xffffffffffffffff; " \
|
||||
" set initrd_high 0xffffffffffffffff; " \
|
||||
" smhload ${kernel_name} ${kernel_addr}; " \
|
||||
" smhload ${fdtfile} ${fdt_addr}; " \
|
||||
" smhload ${initrd_name} ${initrd_addr} "\
|
||||
" initrd_end; " \
|
||||
" fdt addr ${fdt_addr}; fdt resize; " \
|
||||
" fdt chosen ${initrd_addr} ${initrd_end}; " \
|
||||
" booti $kernel_addr - $fdt_addr; " \
|
||||
"fi"
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -72,6 +72,12 @@
|
|||
"serial#:serialno," \
|
||||
CONFIG_ENV_CALLBACK_LIST_STATIC
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
void env_callback_init(struct env_entry *var_entry);
|
||||
#else
|
||||
static inline void env_callback_init(struct env_entry *var_entry)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ENV_CALLBACK_H__ */
|
||||
|
|
|
@ -207,6 +207,8 @@ struct env_driver {
|
|||
#define env_save_ptr(x) NULL
|
||||
#endif
|
||||
|
||||
#define ENV_SAVE_PTR(x) (CONFIG_IS_ENABLED(SAVEENV) ? (x) : NULL)
|
||||
|
||||
extern struct hsearch_data env_htab;
|
||||
|
||||
#endif /* DO_DEPS_ONLY */
|
||||
|
|
|
@ -343,6 +343,15 @@ int fdt_get_cells_len(const void *blob, char *nr_cells_name);
|
|||
#ifdef USE_HOSTCC
|
||||
int fdtdec_get_int(const void *blob, int node, const char *prop_name,
|
||||
int default_val);
|
||||
|
||||
/*
|
||||
* Count child nodes of one parent node.
|
||||
*
|
||||
* @param blob FDT blob
|
||||
* @param node parent node
|
||||
* @return number of child node; 0 if there is not child node
|
||||
*/
|
||||
int fdtdec_get_child_count(const void *blob, int node);
|
||||
#endif
|
||||
#ifdef CONFIG_FMAN_ENET
|
||||
int fdt_update_ethernet_dt(void *blob);
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include <image.h>
|
||||
#include <inttypes.h>
|
||||
#include "imagetool.h"
|
||||
#include "linux/kernel.h"
|
||||
|
||||
#define __packed __attribute__((packed))
|
||||
|
||||
|
|
|
@ -29,8 +29,10 @@ enum env_action {
|
|||
struct env_entry {
|
||||
const char *key;
|
||||
char *data;
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
int (*callback)(const char *name, const char *value, enum env_op op,
|
||||
int flags);
|
||||
#endif
|
||||
int flags;
|
||||
};
|
||||
|
||||
|
|
|
@ -120,6 +120,7 @@ obj-$(CONFIG_$(SPL_TPL_)STRTO) += strto.o
|
|||
else
|
||||
# Main U-Boot always uses the full printf support
|
||||
obj-y += vsprintf.o strto.o
|
||||
obj-$(CONFIG_OID_REGISTRY) += oid_registry.o
|
||||
endif
|
||||
|
||||
obj-y += date.o
|
||||
|
@ -128,8 +129,6 @@ obj-$(CONFIG_LIB_ELF) += elf.o
|
|||
#
|
||||
# Build a fast OID lookup registry from include/linux/oid_registry.h
|
||||
#
|
||||
obj-$(CONFIG_OID_REGISTRY) += oid_registry.o
|
||||
|
||||
$(obj)/oid_registry.o: $(obj)/oid_registry_data.c
|
||||
|
||||
$(obj)/oid_registry_data.c: $(srctree)/include/linux/oid_registry.h \
|
||||
|
|
11
lib/fdtdec.c
11
lib/fdtdec.c
|
@ -810,17 +810,6 @@ int fdtdec_parse_phandle_with_args(const void *blob, int src_node,
|
|||
return rc;
|
||||
}
|
||||
|
||||
int fdtdec_get_child_count(const void *blob, int node)
|
||||
{
|
||||
int subnode;
|
||||
int num = 0;
|
||||
|
||||
fdt_for_each_subnode(subnode, blob, node)
|
||||
num++;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
int fdtdec_get_byte_array(const void *blob, int node, const char *prop_name,
|
||||
u8 *array, int count)
|
||||
{
|
||||
|
|
|
@ -53,3 +53,14 @@ unsigned int fdtdec_get_uint(const void *blob, int node, const char *prop_name,
|
|||
debug("(not found)\n");
|
||||
return default_val;
|
||||
}
|
||||
|
||||
int fdtdec_get_child_count(const void *blob, int node)
|
||||
{
|
||||
int subnode;
|
||||
int num = 0;
|
||||
|
||||
fdt_for_each_subnode(subnode, blob, node)
|
||||
num++;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
|
|
@ -222,6 +222,17 @@ int hmatch_r(const char *match, int last_idx, struct env_entry **retval,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
do_callback(const struct env_entry *e, const char *name, const char *value,
|
||||
enum env_op op, int flags)
|
||||
{
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
if (e->callback)
|
||||
return e->callback(name, value, op, flags);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare an existing entry with the desired key, and overwrite if the action
|
||||
* is ENV_ENTER. This is simply a helper function for hsearch_r().
|
||||
|
@ -247,9 +258,8 @@ static inline int _compare_and_overwrite_entry(struct env_entry item,
|
|||
}
|
||||
|
||||
/* If there is a callback, call it */
|
||||
if (htab->table[idx].entry.callback &&
|
||||
htab->table[idx].entry.callback(item.key,
|
||||
item.data, env_op_overwrite, flag)) {
|
||||
if (do_callback(&htab->table[idx].entry, item.key,
|
||||
item.data, env_op_overwrite, flag)) {
|
||||
debug("callback() rejected setting variable "
|
||||
"%s, skipping it!\n", item.key);
|
||||
__set_errno(EINVAL);
|
||||
|
@ -402,9 +412,8 @@ int hsearch_r(struct env_entry item, enum env_action action,
|
|||
}
|
||||
|
||||
/* If there is a callback, call it */
|
||||
if (htab->table[idx].entry.callback &&
|
||||
htab->table[idx].entry.callback(item.key, item.data,
|
||||
env_op_create, flag)) {
|
||||
if (do_callback(&htab->table[idx].entry, item.key, item.data,
|
||||
env_op_create, flag)) {
|
||||
debug("callback() rejected setting variable "
|
||||
"%s, skipping it!\n", item.key);
|
||||
_hdelete(item.key, htab, &htab->table[idx].entry, idx);
|
||||
|
@ -441,7 +450,6 @@ static void _hdelete(const char *key, struct hsearch_data *htab,
|
|||
debug("hdelete: DELETING key \"%s\"\n", key);
|
||||
free((void *)ep->key);
|
||||
free(ep->data);
|
||||
ep->callback = NULL;
|
||||
ep->flags = 0;
|
||||
htab->table[idx].used = USED_DELETED;
|
||||
|
||||
|
@ -473,8 +481,8 @@ int hdelete_r(const char *key, struct hsearch_data *htab, int flag)
|
|||
}
|
||||
|
||||
/* If there is a callback, call it */
|
||||
if (htab->table[idx].entry.callback &&
|
||||
htab->table[idx].entry.callback(key, NULL, env_op_delete, flag)) {
|
||||
if (do_callback(&htab->table[idx].entry, key, NULL,
|
||||
env_op_delete, flag)) {
|
||||
debug("callback() rejected deleting variable "
|
||||
"%s, skipping it!\n", key);
|
||||
__set_errno(EINVAL);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
const char hex_asc[] = "0123456789abcdef";
|
||||
const char hex_asc_upper[] = "0123456789ABCDEF";
|
||||
|
||||
#ifdef CONFIG_HEXDUMP
|
||||
#if CONFIG_IS_ENABLED(HEXDUMP)
|
||||
/**
|
||||
* hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
|
||||
* @buf: data blob to dump
|
||||
|
|
|
@ -77,11 +77,6 @@
|
|||
* dependencies on include/config/my/option.h for every
|
||||
* CONFIG_MY_OPTION encountered in any of the prerequisites.
|
||||
*
|
||||
* It will also filter out all the dependencies on *.ver. We need
|
||||
* to make sure that the generated version checksum are globally up
|
||||
* to date before even starting the recursive build, so it's too late
|
||||
* at this point anyway.
|
||||
*
|
||||
* We don't even try to really parse the header files, but
|
||||
* merely grep, i.e. if CONFIG_FOO is mentioned in a comment, it will
|
||||
* be picked up as well. It's not a problem with respect to
|
||||
|
@ -99,19 +94,49 @@
|
|||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
int is_spl_build = 0; /* hack for U-Boot */
|
||||
char tmp_buf[256]; /* hack for U-Boot */
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
fprintf(stderr, "Usage: fixdep [-e] <depfile> <target> <cmdline>\n");
|
||||
fprintf(stderr, " -e insert extra dependencies given on stdin\n");
|
||||
fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* In the intended usage of this program, the stdout is redirected to .*.cmd
|
||||
* files. The return value of printf() and putchar() must be checked to catch
|
||||
* any error, e.g. "No space left on device".
|
||||
*/
|
||||
static void xprintf(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap, format);
|
||||
ret = vprintf(format, ap);
|
||||
if (ret < 0) {
|
||||
perror("fixdep");
|
||||
exit(1);
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void xputchar(int c)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = putchar(c);
|
||||
if (ret == EOF) {
|
||||
perror("fixdep");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print out a dependency path from a symbol name
|
||||
*/
|
||||
|
@ -119,7 +144,7 @@ static void print_dep(const char *m, int slen, const char *dir)
|
|||
{
|
||||
int c, prev_c = '/', i;
|
||||
|
||||
printf(" $(wildcard %s/", dir);
|
||||
xprintf(" $(wildcard %s/", dir);
|
||||
for (i = 0; i < slen; i++) {
|
||||
c = m[i];
|
||||
if (c == '_')
|
||||
|
@ -127,25 +152,10 @@ static void print_dep(const char *m, int slen, const char *dir)
|
|||
else
|
||||
c = tolower(c);
|
||||
if (c != '/' || prev_c != '/')
|
||||
putchar(c);
|
||||
xputchar(c);
|
||||
prev_c = c;
|
||||
}
|
||||
printf(".h) \\\n");
|
||||
}
|
||||
|
||||
static void do_extra_deps(void)
|
||||
{
|
||||
char buf[80];
|
||||
|
||||
while (fgets(buf, sizeof(buf), stdin)) {
|
||||
int len = strlen(buf);
|
||||
|
||||
if (len < 2 || buf[len - 1] != '\n') {
|
||||
fprintf(stderr, "fixdep: bad data on stdin\n");
|
||||
exit(1);
|
||||
}
|
||||
print_dep(buf, len - 1, "include/ksym");
|
||||
}
|
||||
xprintf(".h) \\\n");
|
||||
}
|
||||
|
||||
struct item {
|
||||
|
@ -230,7 +240,6 @@ static void parse_config_file(const char *p)
|
|||
{
|
||||
const char *q, *r;
|
||||
const char *start = p;
|
||||
char tmp_buf[256] = "SPL_"; /* hack for U-Boot */
|
||||
|
||||
while ((p = strstr(p, "CONFIG_"))) {
|
||||
if (p > start && (isalnum(p[-1]) || p[-1] == '_')) {
|
||||
|
@ -239,7 +248,7 @@ static void parse_config_file(const char *p)
|
|||
}
|
||||
p += 7;
|
||||
q = p;
|
||||
while (*q && (isalnum(*q) || *q == '_'))
|
||||
while (isalnum(*q) || *q == '_')
|
||||
q++;
|
||||
if (str_ends_with(p, q - p, "_MODULE"))
|
||||
r = q - 7;
|
||||
|
@ -260,7 +269,7 @@ static void parse_config_file(const char *p)
|
|||
while (isalnum(*q) || *q == '_')
|
||||
q++;
|
||||
r = q;
|
||||
if (r > p && is_spl_build) {
|
||||
if (r > p && tmp_buf[0]) {
|
||||
memcpy(tmp_buf + 4, p, r - p);
|
||||
r = tmp_buf + 4 + (r - p);
|
||||
p = tmp_buf;
|
||||
|
@ -310,8 +319,7 @@ static void *read_file(const char *filename)
|
|||
static int is_ignored_file(const char *s, int len)
|
||||
{
|
||||
return str_ends_with(s, len, "include/generated/autoconf.h") ||
|
||||
str_ends_with(s, len, "include/generated/autoksyms.h") ||
|
||||
str_ends_with(s, len, ".ver");
|
||||
str_ends_with(s, len, "include/generated/autoksyms.h");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -319,7 +327,7 @@ static int is_ignored_file(const char *s, int len)
|
|||
* assignments are parsed not only by make, but also by the rather simple
|
||||
* parser in scripts/mod/sumversion.c.
|
||||
*/
|
||||
static void parse_dep_file(char *m, const char *target, int insert_extra_deps)
|
||||
static void parse_dep_file(char *m, const char *target)
|
||||
{
|
||||
char *p;
|
||||
int is_last, is_target;
|
||||
|
@ -366,13 +374,13 @@ static void parse_dep_file(char *m, const char *target, int insert_extra_deps)
|
|||
*/
|
||||
if (!saw_any_target) {
|
||||
saw_any_target = 1;
|
||||
printf("source_%s := %s\n\n",
|
||||
target, m);
|
||||
printf("deps_%s := \\\n", target);
|
||||
xprintf("source_%s := %s\n\n",
|
||||
target, m);
|
||||
xprintf("deps_%s := \\\n", target);
|
||||
}
|
||||
is_first_dep = 0;
|
||||
} else {
|
||||
printf(" %s \\\n", m);
|
||||
xprintf(" %s \\\n", m);
|
||||
}
|
||||
|
||||
buf = read_file(m);
|
||||
|
@ -395,23 +403,16 @@ static void parse_dep_file(char *m, const char *target, int insert_extra_deps)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
if (insert_extra_deps)
|
||||
do_extra_deps();
|
||||
|
||||
printf("\n%s: $(deps_%s)\n\n", target, target);
|
||||
printf("$(deps_%s):\n", target);
|
||||
xprintf("\n%s: $(deps_%s)\n\n", target, target);
|
||||
xprintf("$(deps_%s):\n", target);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *depfile, *target, *cmdline;
|
||||
int insert_extra_deps = 0;
|
||||
void *buf;
|
||||
|
||||
if (argc == 5 && !strcmp(argv[1], "-e")) {
|
||||
insert_extra_deps = 1;
|
||||
argv++;
|
||||
} else if (argc != 4)
|
||||
if (argc != 4)
|
||||
usage();
|
||||
|
||||
depfile = argv[1];
|
||||
|
@ -419,13 +420,16 @@ int main(int argc, char *argv[])
|
|||
cmdline = argv[3];
|
||||
|
||||
/* hack for U-Boot */
|
||||
if (!strncmp(target, "spl/", 4) || !strncmp(target, "tpl/", 4))
|
||||
is_spl_build = 1;
|
||||
if (!strncmp(target, "spl/", 4))
|
||||
strcpy(tmp_buf, "SPL_");
|
||||
else if (!strncmp(target, "tpl/", 4))
|
||||
strcpy(tmp_buf, "TPL_");
|
||||
/* end U-Boot hack */
|
||||
|
||||
printf("cmd_%s := %s\n\n", target, cmdline);
|
||||
xprintf("cmd_%s := %s\n\n", target, cmdline);
|
||||
|
||||
buf = read_file(depfile);
|
||||
parse_dep_file(buf, target, insert_extra_deps);
|
||||
parse_dep_file(buf, target);
|
||||
free(buf);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
#define IS_FNC_EXEC(c) (cmd_table[c].AIS_cmd == AIS_CMD_FNLOAD)
|
||||
#define WORD_ALIGN0 4
|
||||
#define WORD_ALIGN(len) (((len)+WORD_ALIGN0-1) & ~(WORD_ALIGN0-1))
|
||||
#define MAX_CMD_BUFFER 4096
|
||||
|
||||
static uint32_t ais_img_size;
|
||||
|
@ -202,8 +201,9 @@ static uint32_t *ais_alloc_buffer(struct image_tool_params *params)
|
|||
* is not left to the main program, because after the datafile
|
||||
* the header must be terminated with the Jump & Close command.
|
||||
*/
|
||||
ais_img_size = WORD_ALIGN(sbuf.st_size) + MAX_CMD_BUFFER;
|
||||
ptr = (uint32_t *)malloc(WORD_ALIGN(sbuf.st_size) + MAX_CMD_BUFFER);
|
||||
ais_img_size = ALIGN(sbuf.st_size, WORD_ALIGN0) + MAX_CMD_BUFFER;
|
||||
ptr = (uint32_t *)malloc(ALIGN(sbuf.st_size, WORD_ALIGN0)
|
||||
+ MAX_CMD_BUFFER);
|
||||
if (!ptr) {
|
||||
fprintf(stderr, "%s: malloc return failure: %s\n",
|
||||
params->cmdname, strerror(errno));
|
||||
|
@ -242,7 +242,7 @@ static uint32_t *ais_copy_image(struct image_tool_params *params,
|
|||
*aisptr++ = params->ep;
|
||||
*aisptr++ = sbuf.st_size;
|
||||
memcpy((void *)aisptr, ptr, sbuf.st_size);
|
||||
aisptr += WORD_ALIGN(sbuf.st_size) / sizeof(uint32_t);
|
||||
aisptr += ALIGN(sbuf.st_size, WORD_ALIGN0) / sizeof(uint32_t);
|
||||
|
||||
(void) munmap((void *)ptr, sbuf.st_size);
|
||||
(void) close(dfd);
|
||||
|
|
|
@ -422,7 +422,7 @@ err_buf:
|
|||
*/
|
||||
static int fit_extract_data(struct image_tool_params *params, const char *fname)
|
||||
{
|
||||
void *buf;
|
||||
void *buf = NULL;
|
||||
int buf_ptr;
|
||||
int fit_size, new_size;
|
||||
int fd;
|
||||
|
@ -431,26 +431,33 @@ static int fit_extract_data(struct image_tool_params *params, const char *fname)
|
|||
int ret;
|
||||
int images;
|
||||
int node;
|
||||
int image_number;
|
||||
int align_size;
|
||||
|
||||
align_size = params->bl_len ? params->bl_len : 4;
|
||||
fd = mmap_fdt(params->cmdname, fname, 0, &fdt, &sbuf, false, false);
|
||||
if (fd < 0)
|
||||
return -EIO;
|
||||
fit_size = fdt_totalsize(fdt);
|
||||
|
||||
/* Allocate space to hold the image data we will extract */
|
||||
buf = malloc(fit_size);
|
||||
if (!buf) {
|
||||
ret = -ENOMEM;
|
||||
goto err_munmap;
|
||||
}
|
||||
buf_ptr = 0;
|
||||
|
||||
images = fdt_path_offset(fdt, FIT_IMAGES_PATH);
|
||||
if (images < 0) {
|
||||
debug("%s: Cannot find /images node: %d\n", __func__, images);
|
||||
ret = -EINVAL;
|
||||
goto err_munmap;
|
||||
}
|
||||
image_number = fdtdec_get_child_count(fdt, images);
|
||||
|
||||
/*
|
||||
* Allocate space to hold the image data we will extract,
|
||||
* extral space allocate for image alignment to prevent overflow.
|
||||
*/
|
||||
buf = malloc(fit_size + (align_size * image_number));
|
||||
if (!buf) {
|
||||
ret = -ENOMEM;
|
||||
goto err_munmap;
|
||||
}
|
||||
buf_ptr = 0;
|
||||
|
||||
for (node = fdt_first_subnode(fdt, images);
|
||||
node >= 0;
|
||||
|
@ -478,17 +485,17 @@ static int fit_extract_data(struct image_tool_params *params, const char *fname)
|
|||
buf_ptr);
|
||||
}
|
||||
fdt_setprop_u32(fdt, node, FIT_DATA_SIZE_PROP, len);
|
||||
|
||||
buf_ptr += (len + 3) & ~3;
|
||||
buf_ptr += ALIGN(len, align_size);
|
||||
}
|
||||
|
||||
/* Pack the FDT and place the data after it */
|
||||
fdt_pack(fdt);
|
||||
|
||||
new_size = fdt_totalsize(fdt);
|
||||
new_size = ALIGN(new_size, align_size);
|
||||
fdt_set_totalsize(fdt, new_size);
|
||||
debug("Size reduced from %x to %x\n", fit_size, fdt_totalsize(fdt));
|
||||
debug("External data size %x\n", buf_ptr);
|
||||
new_size = fdt_totalsize(fdt);
|
||||
new_size = (new_size + 3) & ~3;
|
||||
munmap(fdt, sbuf.st_size);
|
||||
|
||||
if (ftruncate(fd, new_size)) {
|
||||
|
@ -527,8 +534,7 @@ static int fit_extract_data(struct image_tool_params *params, const char *fname)
|
|||
err_munmap:
|
||||
munmap(fdt, sbuf.st_size);
|
||||
err:
|
||||
if (buf)
|
||||
free(buf);
|
||||
free(buf);
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
@ -547,7 +553,7 @@ static int fit_import_data(struct image_tool_params *params, const char *fname)
|
|||
if (fd < 0)
|
||||
return -EIO;
|
||||
fit_size = fdt_totalsize(old_fdt);
|
||||
data_base = (fit_size + 3) & ~3;
|
||||
data_base = ALIGN(fit_size, 4);
|
||||
|
||||
/* Allocate space to hold the new FIT */
|
||||
size = sbuf.st_size + 16384;
|
||||
|
@ -556,21 +562,21 @@ static int fit_import_data(struct image_tool_params *params, const char *fname)
|
|||
fprintf(stderr, "%s: Failed to allocate memory (%d bytes)\n",
|
||||
__func__, size);
|
||||
ret = -ENOMEM;
|
||||
goto err_has_fd;
|
||||
goto err_munmap;
|
||||
}
|
||||
ret = fdt_open_into(old_fdt, fdt, size);
|
||||
if (ret) {
|
||||
debug("%s: Failed to expand FIT: %s\n", __func__,
|
||||
fdt_strerror(errno));
|
||||
ret = -EINVAL;
|
||||
goto err_has_fd;
|
||||
goto err_munmap;
|
||||
}
|
||||
|
||||
images = fdt_path_offset(fdt, FIT_IMAGES_PATH);
|
||||
if (images < 0) {
|
||||
debug("%s: Cannot find /images node: %d\n", __func__, images);
|
||||
ret = -EINVAL;
|
||||
goto err_has_fd;
|
||||
goto err_munmap;
|
||||
}
|
||||
|
||||
for (node = fdt_first_subnode(fdt, images);
|
||||
|
@ -591,10 +597,12 @@ static int fit_import_data(struct image_tool_params *params, const char *fname)
|
|||
debug("%s: Failed to write property: %s\n", __func__,
|
||||
fdt_strerror(ret));
|
||||
ret = -EINVAL;
|
||||
goto err_has_fd;
|
||||
goto err_munmap;
|
||||
}
|
||||
}
|
||||
|
||||
munmap(old_fdt, sbuf.st_size);
|
||||
|
||||
/* Close the old fd so we can re-use it. */
|
||||
close(fd);
|
||||
|
||||
|
@ -609,22 +617,24 @@ static int fit_import_data(struct image_tool_params *params, const char *fname)
|
|||
fprintf(stderr, "%s: Can't open %s: %s\n",
|
||||
params->cmdname, fname, strerror(errno));
|
||||
ret = -EIO;
|
||||
goto err_no_fd;
|
||||
goto err;
|
||||
}
|
||||
if (write(fd, fdt, new_size) != new_size) {
|
||||
debug("%s: Failed to write external data to file %s\n",
|
||||
__func__, strerror(errno));
|
||||
ret = -EIO;
|
||||
goto err_has_fd;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
err_has_fd:
|
||||
close(fd);
|
||||
err_no_fd:
|
||||
munmap(old_fdt, sbuf.st_size);
|
||||
free(fdt);
|
||||
close(fd);
|
||||
return 0;
|
||||
|
||||
err_munmap:
|
||||
munmap(old_fdt, sbuf.st_size);
|
||||
err:
|
||||
free(fdt);
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,15 +8,13 @@
|
|||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <getopt.h>
|
||||
#include "imagetool.h"
|
||||
#include "os_support.h"
|
||||
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__((packed))
|
||||
#endif
|
||||
#define KiB 1024
|
||||
#define ALIGN(x, a) __ALIGN_MASK((x), (typeof(x))(a) - 1)
|
||||
#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
/*
|
||||
* min()/max()/clamp() macros that also do
|
||||
|
|
|
@ -307,7 +307,7 @@ static int fit_image_read_data(char *filename, unsigned char *data,
|
|||
|
||||
/* Check that we have read all the file */
|
||||
if (n != sbuf.st_size) {
|
||||
printf("Can't read all file %s (read %ld bytes, expexted %ld)\n",
|
||||
printf("Can't read all file %s (read %zd bytes, expexted %ld)\n",
|
||||
filename, n, sbuf.st_size);
|
||||
goto err;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
|
||||
#define ALIGN(x, a) __ALIGN_MASK((x), (typeof(x))(a) - 1)
|
||||
|
||||
#define IH_ARCH_DEFAULT IH_ARCH_INVALID
|
||||
|
||||
/* Information about a file that needs to be placed into the FIT */
|
||||
|
@ -76,6 +79,7 @@ struct image_tool_params {
|
|||
bool external_data; /* Store data outside the FIT */
|
||||
bool quiet; /* Don't output text in normal operation */
|
||||
unsigned int external_offset; /* Add padding to external data */
|
||||
int bl_len; /* Block length in byte for external data */
|
||||
const char *engine_id; /* Engine to use for signing */
|
||||
};
|
||||
|
||||
|
|
|
@ -32,8 +32,6 @@ static uint32_t rom_version = ROM_V1;
|
|||
|
||||
#define HDMI_FW_SIZE 0x17000 /* Use Last 0x1000 for IVT and CSF */
|
||||
#define ALIGN_SIZE 0x1000
|
||||
#define ALIGN(x,a) __ALIGN_MASK((x), (__typeof__(x))(a) - 1, a)
|
||||
#define __ALIGN_MASK(x,mask,mask2) (((x) + (mask)) / (mask2) * (mask2))
|
||||
|
||||
static uint32_t get_cfg_value(char *token, char *name, int linenr)
|
||||
{
|
||||
|
@ -343,7 +341,6 @@ static int generate_ivt_for_fit(int fd, int fit_offset, uint32_t ep,
|
|||
}
|
||||
|
||||
fit_size = fdt_totalsize(&image_header);
|
||||
fit_size = (fit_size + 3) & ~3;
|
||||
|
||||
fit_size = ALIGN(fit_size, ALIGN_SIZE);
|
||||
|
||||
|
|
|
@ -1015,7 +1015,7 @@ static size_t image_headersz_v1(int *hasext)
|
|||
* The payload should be aligned on some reasonable
|
||||
* boundary
|
||||
*/
|
||||
return ALIGN_SUP(headersz, 4096);
|
||||
return ALIGN(headersz, 4096);
|
||||
}
|
||||
|
||||
int add_binary_header_v1(uint8_t *cur)
|
||||
|
@ -1058,7 +1058,7 @@ int add_binary_header_v1(uint8_t *cur)
|
|||
* up to a 4-byte boundary. Plus 4 bytes for the
|
||||
* next-header byte and 3-byte alignment at the end.
|
||||
*/
|
||||
binhdrsz = ALIGN_SUP(binhdrsz, 4) + 4;
|
||||
binhdrsz = ALIGN(binhdrsz, 4) + 4;
|
||||
hdr->headersz_lsb = cpu_to_le16(binhdrsz & 0xFFFF);
|
||||
hdr->headersz_msb = (binhdrsz & 0xFFFF0000) >> 16;
|
||||
|
||||
|
@ -1082,7 +1082,7 @@ int add_binary_header_v1(uint8_t *cur)
|
|||
|
||||
fclose(bin);
|
||||
|
||||
cur += ALIGN_SUP(s.st_size, 4);
|
||||
cur += ALIGN(s.st_size, 4);
|
||||
|
||||
/*
|
||||
* For now, we don't support more than one binary
|
||||
|
@ -1548,7 +1548,7 @@ static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
|
|||
}
|
||||
|
||||
/* The MVEBU BootROM does not allow non word aligned payloads */
|
||||
sbuf->st_size = ALIGN_SUP(sbuf->st_size, 4);
|
||||
sbuf->st_size = ALIGN(sbuf->st_size, 4);
|
||||
|
||||
version = image_get_version();
|
||||
switch (version) {
|
||||
|
|
|
@ -29,8 +29,6 @@
|
|||
#define IBR_HDR_UART_ID 0x69
|
||||
#define IBR_DEF_ATTRIB 0x00
|
||||
|
||||
#define ALIGN_SUP(x, a) (((x) + (a - 1)) & ~(a - 1))
|
||||
|
||||
/* Structure of the main header, version 0 (Kirkwood, Dove) */
|
||||
struct main_hdr_v0 {
|
||||
uint8_t blockid; /* 0x0 */
|
||||
|
|
|
@ -1,113 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2008 Extreme Engineering Solutions, Inc.
|
||||
*
|
||||
* mmap/munmap implementation derived from:
|
||||
* Clamav Native Windows Port : mmap win32 compatibility layer
|
||||
* Copyright (c) 2005-2006 Gianluigi Tiesi <sherpya@netfarm.it>
|
||||
* Parts by Kees Zeelenberg <kzlg@users.sourceforge.net> (LibGW32C)
|
||||
*/
|
||||
|
||||
#include "mingw_support.h"
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <io.h>
|
||||
|
||||
int fsync(int fd)
|
||||
{
|
||||
return _commit(fd);
|
||||
}
|
||||
|
||||
void *mmap(void *addr, size_t len, int prot, int flags, int fd, int offset)
|
||||
{
|
||||
void *map = NULL;
|
||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||
DWORD cfm_flags = 0, mvf_flags = 0;
|
||||
|
||||
switch (prot) {
|
||||
case PROT_READ | PROT_WRITE:
|
||||
cfm_flags = PAGE_READWRITE;
|
||||
mvf_flags = FILE_MAP_ALL_ACCESS;
|
||||
break;
|
||||
case PROT_WRITE:
|
||||
cfm_flags = PAGE_READWRITE;
|
||||
mvf_flags = FILE_MAP_WRITE;
|
||||
break;
|
||||
case PROT_READ:
|
||||
cfm_flags = PAGE_READONLY;
|
||||
mvf_flags = FILE_MAP_READ;
|
||||
break;
|
||||
default:
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
handle = CreateFileMappingA((HANDLE) _get_osfhandle(fd), NULL,
|
||||
cfm_flags, HIDWORD(len), LODWORD(len), NULL);
|
||||
if (!handle)
|
||||
return MAP_FAILED;
|
||||
|
||||
map = MapViewOfFile(handle, mvf_flags, HIDWORD(offset),
|
||||
LODWORD(offset), len);
|
||||
CloseHandle(handle);
|
||||
|
||||
if (!map)
|
||||
return MAP_FAILED;
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
int munmap(void *addr, size_t len)
|
||||
{
|
||||
if (!UnmapViewOfFile(addr))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Reentrant string tokenizer. Generic version.
|
||||
Copyright (C) 1991,1996-1999,2001,2004,2007 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
*/
|
||||
|
||||
/* Parse S into tokens separated by characters in DELIM.
|
||||
If S is NULL, the saved pointer in SAVE_PTR is used as
|
||||
the next starting point. For example:
|
||||
char s[] = "-abc-=-def";
|
||||
char *sp;
|
||||
x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def"
|
||||
x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL
|
||||
x = strtok_r(NULL, "=", &sp); // x = NULL
|
||||
// s = "abc\0-def\0"
|
||||
*/
|
||||
char *strtok_r(char *s, const char *delim, char **save_ptr)
|
||||
{
|
||||
char *token;
|
||||
|
||||
if (s == NULL)
|
||||
s = *save_ptr;
|
||||
|
||||
/* Scan leading delimiters. */
|
||||
s += strspn(s, delim);
|
||||
if (*s == '\0') {
|
||||
*save_ptr = s;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Find the end of the token. */
|
||||
token = s;
|
||||
s = strpbrk (token, delim);
|
||||
if (s == NULL) {
|
||||
/* This token finishes the string. */
|
||||
*save_ptr = memchr(token, '\0', strlen(token));
|
||||
} else {
|
||||
/* Terminate the token and make *SAVE_PTR point past it. */
|
||||
*s = '\0';
|
||||
*save_ptr = s + 1;
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
#include "getline.c"
|
|
@ -1,45 +0,0 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.0+ */
|
||||
/*
|
||||
* Copyright 2008 Extreme Engineering Solutions, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __MINGW_SUPPORT_H_
|
||||
#define __WINGW_SUPPORT_H_ 1
|
||||
|
||||
/* Defining __INSIDE_MSYS__ helps to prevent u-boot/mingw overlap */
|
||||
#define __INSIDE_MSYS__ 1
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/* mmap protections */
|
||||
#define PROT_READ 0x1 /* Page can be read */
|
||||
#define PROT_WRITE 0x2 /* Page can be written */
|
||||
#define PROT_EXEC 0x4 /* Page can be executed */
|
||||
#define PROT_NONE 0x0 /* Page can not be accessed */
|
||||
|
||||
/* Sharing types (must choose one and only one of these) */
|
||||
#define MAP_SHARED 0x01 /* Share changes */
|
||||
#define MAP_PRIVATE 0x02 /* Changes are private */
|
||||
|
||||
/* File perms */
|
||||
#ifndef S_IRGRP
|
||||
# define S_IRGRP 0
|
||||
#endif
|
||||
#ifndef S_IWGRP
|
||||
# define S_IWGRP 0
|
||||
#endif
|
||||
|
||||
/* Windows 64-bit access macros */
|
||||
#define LODWORD(x) ((DWORD)((DWORDLONG)(x)))
|
||||
#define HIDWORD(x) ((DWORD)(((DWORDLONG)(x) >> 32) & 0xffffffff))
|
||||
|
||||
typedef UINT uint;
|
||||
typedef ULONG ulong;
|
||||
|
||||
int fsync(int fd);
|
||||
void *mmap(void *, size_t, int, int, int, int);
|
||||
int munmap(void *, size_t);
|
||||
char *strtok_r(char *s, const char *delim, char **save_ptr);
|
||||
#include "getline.h"
|
||||
|
||||
#endif /* __MINGW_SUPPORT_H_ */
|
|
@ -7,6 +7,7 @@
|
|||
* Wolfgang Denk, wd@denx.de
|
||||
*/
|
||||
|
||||
#include "imagetool.h"
|
||||
#include "mkimage.h"
|
||||
#include "imximage.h"
|
||||
#include <image.h>
|
||||
|
@ -97,8 +98,9 @@ static void usage(const char *msg)
|
|||
" -i => input filename for ramdisk file\n");
|
||||
#ifdef CONFIG_FIT_SIGNATURE
|
||||
fprintf(stderr,
|
||||
"Signing / verified boot options: [-E] [-k keydir] [-K dtb] [ -c <comment>] [-p addr] [-r] [-N engine]\n"
|
||||
"Signing / verified boot options: [-E] [-B size] [-k keydir] [-K dtb] [ -c <comment>] [-p addr] [-r] [-N engine]\n"
|
||||
" -E => place data outside of the FIT structure\n"
|
||||
" -B => align size in hex for FIT structure and header\n"
|
||||
" -k => set directory containing private keys\n"
|
||||
" -K => write public keys to this .dtb file\n"
|
||||
" -c => add comment in signature node\n"
|
||||
|
@ -143,7 +145,7 @@ static void process_args(int argc, char **argv)
|
|||
int opt;
|
||||
|
||||
while ((opt = getopt(argc, argv,
|
||||
"a:A:b:c:C:d:D:e:Ef:Fk:i:K:ln:N:p:O:rR:qsT:vVx")) != -1) {
|
||||
"a:A:b:B:c:C:d:D:e:Ef:Fk:i:K:ln:N:p:O:rR:qsT:vVx")) != -1) {
|
||||
switch (opt) {
|
||||
case 'a':
|
||||
params.addr = strtoull(optarg, &ptr, 16);
|
||||
|
@ -167,6 +169,15 @@ static void process_args(int argc, char **argv)
|
|||
params.cmdname, optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'B':
|
||||
params.bl_len = strtoull(optarg, &ptr, 16);
|
||||
if (*ptr) {
|
||||
fprintf(stderr, "%s: invalid block length %s\n",
|
||||
params.cmdname, optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'c':
|
||||
params.comment = optarg;
|
||||
|
@ -557,8 +568,8 @@ int main(int argc, char **argv)
|
|||
}
|
||||
if (params.type == IH_TYPE_FIRMWARE_IVT) {
|
||||
/* Add alignment and IVT */
|
||||
uint32_t aligned_filesize = (params.file_size + 0x1000
|
||||
- 1) & ~(0x1000 - 1);
|
||||
uint32_t aligned_filesize = ALIGN(params.file_size,
|
||||
0x1000);
|
||||
flash_header_v2_t ivt_header = { { 0xd1, 0x2000, 0x40 },
|
||||
params.addr, 0, 0, 0, params.addr
|
||||
+ aligned_filesize
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "imagetool.h"
|
||||
#include "../arch/arm/include/asm/arch-sunxi/spl.h"
|
||||
|
||||
#define STAMP_VALUE 0x5F0A6C39
|
||||
|
@ -44,9 +45,6 @@ int gen_check_sum(struct boot_file_head *head_p)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define ALIGN(x, a) __ALIGN_MASK((x), (typeof(x))(a)-1)
|
||||
#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
|
||||
|
||||
#define SUNXI_SRAM_SIZE 0x8000 /* SoC with smaller size are limited before */
|
||||
#define SRAM_LOAD_MAX_SIZE (SUNXI_SRAM_SIZE - sizeof(struct boot_file_head))
|
||||
|
||||
|
|
|
@ -3,13 +3,12 @@
|
|||
* Copyright 2009 Extreme Engineering Solutions, Inc.
|
||||
*/
|
||||
|
||||
#include "compiler.h"
|
||||
|
||||
/*
|
||||
* Include additional files required for supporting different operating systems
|
||||
*/
|
||||
#include "compiler.h"
|
||||
#ifdef __MINGW32__
|
||||
#include "mingw_support.c"
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && __DARWIN_C_LEVEL < 200809L
|
||||
#include "getline.c"
|
||||
#endif
|
||||
|
|
|
@ -11,9 +11,6 @@
|
|||
/*
|
||||
* Include additional files required for supporting different operating systems
|
||||
*/
|
||||
#ifdef __MINGW32__
|
||||
#include "mingw_support.h"
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && __DARWIN_C_LEVEL < 200809L
|
||||
#include "getline.h"
|
||||
|
|
|
@ -203,7 +203,7 @@ static int sfp_sign_buffer(uint8_t *buf, uint8_t ver, uint8_t flags,
|
|||
uint32_t calc_crc;
|
||||
|
||||
/* Align the length up */
|
||||
len = (len + 3) & ~3;
|
||||
len = ALIGN(len, 4);
|
||||
|
||||
/* Build header, adding 4 bytes to length to hold the CRC32. */
|
||||
sfp_build_header(buf + HEADER_OFFSET, ver, flags, len + 4);
|
||||
|
|
Loading…
Reference in a new issue