summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile11
-rw-r--r--arch/arc/lib/libgcc2.c75
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/Kconfig17
-rw-r--r--arch/arm/dts/armada-cp110-master.dtsi1
-rw-r--r--arch/arm/dts/armada-cp110-slave.dtsi1
-rw-r--r--arch/arm/include/asm/mach-imx/mxc_i2c.h6
-rw-r--r--arch/arm/mach-bcm283x/Kconfig67
-rw-r--r--arch/arm/mach-bcm283x/include/mach/mbox.h14
-rw-r--r--arch/arm/mach-bcm283x/include/mach/sdhci.h6
-rw-r--r--arch/arm/mach-bcm283x/include/mach/timer.h6
-rw-r--r--arch/arm/mach-bcm283x/include/mach/wdog.h6
-rw-r--r--arch/arm/mach-bcm283x/mbox.c6
-rw-r--r--arch/riscv/cpu/ax25/Kconfig1
-rw-r--r--arch/riscv/cpu/ax25/cache.c39
-rw-r--r--arch/riscv/cpu/start.S10
-rw-r--r--arch/riscv/dts/ae350_32.dts17
-rw-r--r--arch/riscv/dts/ae350_64.dts17
-rw-r--r--arch/riscv/lib/andes_plic.c36
-rw-r--r--board/AndesTech/ax25-ae350/ax25-ae350.c9
-rw-r--r--board/raspberrypi/rpi/rpi.c32
-rw-r--r--board/sifive/fu540/fu540.c18
-rw-r--r--board/st/stm32mp1/stm32mp1.c16
-rw-r--r--board/synopsys/emsdp/config.mk2
-rw-r--r--board/synopsys/emsdp/emsdp.c37
-rw-r--r--cmd/Kconfig7
-rw-r--r--cmd/Makefile1
-rw-r--r--cmd/mdio.c3
-rw-r--r--cmd/pcap.c71
-rw-r--r--configs/emsdp_defconfig1
-rw-r--r--configs/qemu-riscv32_defconfig1
-rw-r--r--configs/qemu-riscv32_smode_defconfig1
-rw-r--r--configs/qemu-riscv64_defconfig1
-rw-r--r--configs/qemu-riscv64_smode_defconfig1
-rw-r--r--configs/rpi_4_32b_defconfig33
-rw-r--r--configs/rpi_4_defconfig33
-rw-r--r--configs/sandbox_defconfig1
-rw-r--r--doc/README.pcap62
-rw-r--r--doc/api/efi.rst33
-rw-r--r--doc/device-tree-bindings/net/marvell-mdio.txt15
-rw-r--r--doc/device-tree-bindings/net/mdio.txt36
-rw-r--r--doc/driver-model/migration.rst8
-rw-r--r--doc/git-mailrc4
-rw-r--r--drivers/cache/Kconfig9
-rw-r--r--drivers/cache/Makefile1
-rw-r--r--drivers/cache/cache-uclass.c20
-rw-r--r--drivers/cache/cache-v5l2.c186
-rw-r--r--drivers/cache/sandbox_cache.c13
-rw-r--r--drivers/cpu/riscv_cpu.c4
-rw-r--r--drivers/i2c/mxc_i2c.c18
-rw-r--r--drivers/mmc/bcm2835_sdhci.c12
-rw-r--r--drivers/mmc/bcm2835_sdhost.c12
-rw-r--r--drivers/net/Kconfig11
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/designware.c1
-rw-r--r--drivers/net/dwc_eth_qos.c28
-rw-r--r--drivers/net/fsl-mc/Kconfig25
-rw-r--r--drivers/net/fsl_enetc_mdio.c1
-rw-r--r--drivers/net/macb.c8
-rw-r--r--drivers/net/mdio_mux_i2creg.c108
-rw-r--r--drivers/net/mdio_sandbox.c4
-rw-r--r--drivers/net/mvmdio.c236
-rw-r--r--drivers/net/mvpp2.c8
-rw-r--r--drivers/net/pfe_eth/pfe_mdio.c3
-rw-r--r--include/cache.h31
-rw-r--r--include/configs/exynos5-common.h2
-rw-r--r--include/configs/rpi.h4
-rw-r--r--include/configs/sifive-fu540.h1
-rw-r--r--include/efi_api.h4
-rw-r--r--include/efi_loader.h4
-rw-r--r--include/env_callback.h2
-rw-r--r--include/env_flags.h2
-rw-r--r--include/net.h2
-rw-r--r--include/net/pcap.h55
-rw-r--r--include/netdev.h3
-rw-r--r--lib/efi_loader/efi_console.c33
-rw-r--r--lib/efi_loader/efi_device_path.c2
-rw-r--r--lib/efi_loader/efi_device_path_to_text.c31
-rw-r--r--lib/efi_loader/efi_disk.c60
-rw-r--r--lib/efi_loader/efi_gop.c2
-rw-r--r--lib/efi_loader/efi_memory.c82
-rw-r--r--lib/efi_loader/efi_net.c193
-rw-r--r--lib/efi_selftest/efi_selftest_snp.c64
-rw-r--r--net/Makefile1
-rw-r--r--net/eth-uclass.c5
-rw-r--r--net/eth_legacy.c10
-rw-r--r--net/mdio-uclass.c13
-rw-r--r--net/net.c14
-rw-r--r--net/nfs.c19
-rw-r--r--net/nfs.h2
-rw-r--r--net/pcap.c156
-rw-r--r--test/dm/cache.c2
-rw-r--r--tools/prelink-riscv.inc8
92 files changed, 2040 insertions, 238 deletions
diff --git a/Makefile b/Makefile
index c02accfc26..ae56e47b2c 100644
--- a/Makefile
+++ b/Makefile
@@ -1026,6 +1026,17 @@ ifneq ($(CONFIG_WDT),y)
@echo >&2 "===================================================="
endif
endif
+ifneq ($(CONFIG_NET),)
+ifneq ($(CONFIG_DM_ETH),y)
+ @echo >&2 "===================== WARNING ======================"
+ @echo >&2 "This board does not use CONFIG_DM_ETH (Driver Model"
+ @echo >&2 "for Ethernet drivers). Please update the board to use"
+ @echo >&2 "CONFIG_DM_ETH before the v2020.07 release. Failure to"
+ @echo >&2 "update by the deadline may result in board removal."
+ @echo >&2 "See doc/driver-model/migration.rst for more info."
+ @echo >&2 "===================================================="
+endif
+endif
@# Check that this build does not use CONFIG options that we do not
@# know about unless they are in Kconfig. All the existing CONFIG
@# options are whitelisted, so new ones should not be added.
diff --git a/arch/arc/lib/libgcc2.c b/arch/arc/lib/libgcc2.c
index b92a841a37..ab1dbe1c13 100644
--- a/arch/arc/lib/libgcc2.c
+++ b/arch/arc/lib/libgcc2.c
@@ -158,3 +158,78 @@ __umodsi3(long a, long b)
{
return udivmodsi4(a, b, 1);
}
+
+UDWtype
+__udivmoddi4(UDWtype n, UDWtype d, UDWtype *rp)
+{
+ UDWtype q = 0, r = n, y = d;
+ UWtype lz1, lz2, i, k;
+
+ /*
+ * Implements align divisor shift dividend method. This algorithm
+ * aligns the divisor under the dividend and then perform number of
+ * test-subtract iterations which shift the dividend left. Number of
+ * iterations is k + 1 where k is the number of bit positions the
+ * divisor must be shifted left to align it under the dividend.
+ * quotient bits can be saved in the rightmost positions of the
+ * dividend as it shifts left on each test-subtract iteration.
+ */
+
+ if (y <= r) {
+ lz1 = __builtin_clzll(d);
+ lz2 = __builtin_clzll(n);
+
+ k = lz1 - lz2;
+ y = (y << k);
+
+ /*
+ * Dividend can exceed 2 ^ (width - 1) - 1 but still be less
+ * than the aligned divisor. Normal iteration can drops the
+ * high order bit of the dividend. Therefore, first
+ * test-subtract iteration is a special case, saving its
+ * quotient bit in a separate location and not shifting
+ * the dividend.
+ */
+
+ if (r >= y) {
+ r = r - y;
+ q = (1ULL << k);
+ }
+
+ if (k > 0) {
+ y = y >> 1;
+
+ /*
+ * k additional iterations where k regular test
+ * subtract shift dividend iterations are done.
+ */
+ i = k;
+ do {
+ if (r >= y)
+ r = ((r - y) << 1) + 1;
+ else
+ r = (r << 1);
+ i = i - 1;
+ } while (i != 0);
+
+ /*
+ * First quotient bit is combined with the quotient
+ * bits resulting from the k regular iterations.
+ */
+ q = q + r;
+ r = r >> k;
+ q = q - (r << k);
+ }
+ }
+
+ if (rp)
+ *rp = r;
+
+ return q;
+}
+
+UDWtype
+__udivdi3(UDWtype n, UDWtype d)
+{
+ return __udivmoddi4(n, d, (UDWtype *)0);
+}
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
index 42d31fdab0..54d03ae622 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
+++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig
@@ -245,14 +245,6 @@ config FSL_LSCH3
config NXP_LSCH3_2
bool
-config FSL_MC_ENET
- bool "Management Complex network"
- depends on ARCH_LS2080A || ARCH_LS1088A || ARCH_LX2160A
- default y
- select RESV_RAM
- help
- Enable Management Complex (MC) network
-
menu "Layerscape architecture"
depends on FSL_LSCH2 || FSL_LSCH3
@@ -593,15 +585,6 @@ config SYS_FSL_HAS_RGMII
bool
depends on SYS_FSL_EC1 || SYS_FSL_EC2
-
-config SYS_MC_RSV_MEM_ALIGN
- hex "Management Complex reserved memory alignment"
- depends on RESV_RAM
- default 0x20000000 if ARCH_LS2080A || ARCH_LS1088A || ARCH_LX2160A
- help
- Reserved memory needs to be aligned for MC to use. Default value
- is 512MB.
-
config SPL_LDSCRIPT
default "arch/arm/cpu/armv8/u-boot-spl.lds" if ARCH_LS1043A || ARCH_LS1046A || ARCH_LS2080A
diff --git a/arch/arm/dts/armada-cp110-master.dtsi b/arch/arm/dts/armada-cp110-master.dtsi
index 551d00d774..e4c17e9f4b 100644
--- a/arch/arm/dts/armada-cp110-master.dtsi
+++ b/arch/arm/dts/armada-cp110-master.dtsi
@@ -96,6 +96,7 @@
#size-cells = <0>;
compatible = "marvell,orion-mdio";
reg = <0x12a200 0x10>;
+ device-name = "cpm-mdio";
};
cpm_syscon0: system-controller@440000 {
diff --git a/arch/arm/dts/armada-cp110-slave.dtsi b/arch/arm/dts/armada-cp110-slave.dtsi
index 2ea9004f1d..2fbd7b5514 100644
--- a/arch/arm/dts/armada-cp110-slave.dtsi
+++ b/arch/arm/dts/armada-cp110-slave.dtsi
@@ -96,6 +96,7 @@
#size-cells = <0>;
compatible = "marvell,orion-mdio";
reg = <0x12a200 0x10>;
+ device-name = "cps-mdio";
};
cps_syscon0: system-controller@440000 {
diff --git a/arch/arm/include/asm/mach-imx/mxc_i2c.h b/arch/arm/include/asm/mach-imx/mxc_i2c.h
index 8e1ea9af19..81fd981444 100644
--- a/arch/arm/include/asm/mach-imx/mxc_i2c.h
+++ b/arch/arm/include/asm/mach-imx/mxc_i2c.h
@@ -6,6 +6,9 @@
#define __ASM_ARCH_MXC_MXC_I2C_H__
#include <asm-generic/gpio.h>
#include <asm/mach-imx/iomux-v3.h>
+#if CONFIG_IS_ENABLED(CLK)
+#include <clk.h>
+#endif
struct i2c_pin_ctrl {
iomux_v3_cfg_t i2c_mode;
@@ -47,6 +50,9 @@ struct mxc_i2c_bus {
ulong driver_data;
int speed;
struct i2c_pads_info *pads_info;
+#if CONFIG_IS_ENABLED(CLK)
+ struct clk per_clk;
+#endif
#ifndef CONFIG_DM_I2C
int (*idle_bus_fn)(void *p);
void *idle_bus_data;
diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig
index 3eb5a9a897..b08275f598 100644
--- a/arch/arm/mach-bcm283x/Kconfig
+++ b/arch/arm/mach-bcm283x/Kconfig
@@ -26,6 +26,23 @@ config BCM2837_64B
select BCM2837
select ARM64
+config BCM2711
+ bool "Broadcom BCM2711 SoC support"
+ depends on ARCH_BCM283X
+
+config BCM2711_32B
+ bool "Broadcom BCM2711 SoC 32-bit support"
+ depends on ARCH_BCM283X
+ select BCM2711
+ select ARMV7_LPAE
+ select CPU_V7A
+
+config BCM2711_64B
+ bool "Broadcom BCM2711 SoC 64-bit support"
+ depends on ARCH_BCM283X
+ select BCM2711
+ select ARM64
+
menu "Broadcom BCM283X family"
depends on ARCH_BCM283X
@@ -127,6 +144,50 @@ config TARGET_RPI_3
This option creates a build targeting the ARMv8/AArch64 ISA.
select BCM2837_64B
+config TARGET_RPI_4_32B
+ bool "Raspberry Pi 4 32-bit build"
+ help
+ Support for all BCM2711-based Raspberry Pi variants, such as
+ the RPi 4 model B, in AArch32 (32-bit) mode.
+
+ This option assumes the VideoCore firmware is configured to use the
+ mini UART (rather than PL011) for the serial console. This is the
+ default on the RPi 4. To enable the UART console, the following non-
+ default option must be present in config.txt: enable_uart=1. This is
+ required for U-Boot to operate correctly, even if you only care
+ about the HDMI/usbkbd console.
+
+ Due to hardware incompatibilities, this can't be used with
+ BCM283/5/6/7.
+
+ This option creates a build targeting the ARMv7/AArch32 ISA.
+ select BCM2711_32B
+
+config TARGET_RPI_4
+ bool "Raspberry Pi 4 64-bit build"
+ help
+ Support for all BCM2711-based Raspberry Pi variants, such as
+ the RPi 4 model B, in AArch64 (64-bit) mode.
+
+ This option assumes the VideoCore firmware is configured to use the
+ mini UART (rather than PL011) for the serial console. This is the
+ default on the RPi 4. To enable the UART console, the following non-
+ default option must be present in config.txt: enable_uart=1. This is
+ required for U-Boot to operate correctly, even if you only care
+ about the HDMI/usbkbd console.
+
+ Due to hardware incompatibilities, this can't be used with
+ BCM283/5/6/7.
+
+ Also, due to a bug in firmware, switching to 64bit mode doesn't
+ happen automatically based on the kernel's image filename. See
+ https://github.com/raspberrypi/firmware/issues/1193 for more details.
+ Until that is resolved, the configuration (config.txt) needs to
+ explicitly set: arm_64bit=1.
+
+ This option creates a build targeting the ARMv8/AArch64 ISA.
+ select BCM2711_64B
+
endchoice
config SYS_BOARD
@@ -141,4 +202,10 @@ config SYS_SOC
config SYS_CONFIG_NAME
default "rpi"
+config BCM283x_BASE
+ hex
+ default "0x20000000" if BCM2835
+ default "0x3f000000" if BCM2836 || BCM2837
+ default "0xfe000000" if BCM2711
+
endmenu
diff --git a/arch/arm/mach-bcm283x/include/mach/mbox.h b/arch/arm/mach-bcm283x/include/mach/mbox.h
index e3a893e49c..0b6c2543d5 100644
--- a/arch/arm/mach-bcm283x/include/mach/mbox.h
+++ b/arch/arm/mach-bcm283x/include/mach/mbox.h
@@ -37,18 +37,17 @@
/* Raw mailbox HW */
-#ifndef CONFIG_BCM2835
-#define BCM2835_MBOX_PHYSADDR 0x3f00b880
-#else
-#define BCM2835_MBOX_PHYSADDR 0x2000b880
-#endif
+#define BCM2835_MBOX_PHYSADDR (CONFIG_BCM283x_BASE + 0x0000b880)
struct bcm2835_mbox_regs {
u32 read;
u32 rsvd0[5];
- u32 status;
- u32 config;
+ u32 mail0_status;
+ u32 mail0_config;
u32 write;
+ u32 rsvd1[5];
+ u32 mail1_status;
+ u32 mail1_config;
};
#define BCM2835_MBOX_STATUS_WR_FULL 0x80000000
@@ -234,6 +233,7 @@ struct bcm2835_mbox_tag_set_power_state {
#define BCM2835_MBOX_CLOCK_ID_SDRAM 8
#define BCM2835_MBOX_CLOCK_ID_PIXEL 9
#define BCM2835_MBOX_CLOCK_ID_PWM 10
+#define BCM2835_MBOX_CLOCK_ID_EMMC2 12
struct bcm2835_mbox_tag_get_clock_rate {
struct bcm2835_mbox_tag_hdr tag_hdr;
diff --git a/arch/arm/mach-bcm283x/include/mach/sdhci.h b/arch/arm/mach-bcm283x/include/mach/sdhci.h
index 5cb6ec3340..b443c379d8 100644
--- a/arch/arm/mach-bcm283x/include/mach/sdhci.h
+++ b/arch/arm/mach-bcm283x/include/mach/sdhci.h
@@ -6,11 +6,7 @@
#ifndef _BCM2835_SDHCI_H_
#define _BCM2835_SDHCI_H_
-#ifndef CONFIG_BCM2835
-#define BCM2835_SDHCI_BASE 0x3f300000
-#else
-#define BCM2835_SDHCI_BASE 0x20300000
-#endif
+#define BCM2835_SDHCI_BASE (CONFIG_BCM283x_BASE + 0x00300000)
int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq);
diff --git a/arch/arm/mach-bcm283x/include/mach/timer.h b/arch/arm/mach-bcm283x/include/mach/timer.h
index 56b0c356bb..014355e759 100644
--- a/arch/arm/mach-bcm283x/include/mach/timer.h
+++ b/arch/arm/mach-bcm283x/include/mach/timer.h
@@ -6,11 +6,7 @@
#ifndef _BCM2835_TIMER_H
#define _BCM2835_TIMER_H
-#ifndef CONFIG_BCM2835
-#define BCM2835_TIMER_PHYSADDR 0x3f003000
-#else
-#define BCM2835_TIMER_PHYSADDR 0x20003000
-#endif
+#define BCM2835_TIMER_PHYSADDR (CONFIG_BCM283x_BASE + 0x00003000)
#define BCM2835_TIMER_CS_M3 (1 << 3)
#define BCM2835_TIMER_CS_M2 (1 << 2)
diff --git a/arch/arm/mach-bcm283x/include/mach/wdog.h b/arch/arm/mach-bcm283x/include/mach/wdog.h
index 99c88e5df7..8292b3cf1f 100644
--- a/arch/arm/mach-bcm283x/include/mach/wdog.h
+++ b/arch/arm/mach-bcm283x/include/mach/wdog.h
@@ -6,11 +6,7 @@
#ifndef _BCM2835_WDOG_H
#define _BCM2835_WDOG_H
-#ifndef CONFIG_BCM2835
-#define BCM2835_WDOG_PHYSADDR 0x3f100000
-#else
-#define BCM2835_WDOG_PHYSADDR 0x20100000
-#endif
+#define BCM2835_WDOG_PHYSADDR (CONFIG_BCM283x_BASE + 0x00100000)
struct bcm2835_wdog_regs {
u32 unknown0[7];
diff --git a/arch/arm/mach-bcm283x/mbox.c b/arch/arm/mach-bcm283x/mbox.c
index 1642ebd103..3c67f68c17 100644
--- a/arch/arm/mach-bcm283x/mbox.c
+++ b/arch/arm/mach-bcm283x/mbox.c
@@ -27,7 +27,7 @@ int bcm2835_mbox_call_raw(u32 chan, u32 send, u32 *recv)
/* Drain any stale responses */
for (;;) {
- val = readl(&regs->status);
+ val = readl(&regs->mail0_status);
if (val & BCM2835_MBOX_STATUS_RD_EMPTY)
break;
if (get_timer(0) >= endtime) {
@@ -40,7 +40,7 @@ int bcm2835_mbox_call_raw(u32 chan, u32 send, u32 *recv)
/* Wait for space to send */
for (;;) {
- val = readl(&regs->status);
+ val = readl(&regs->mail1_status);
if (!(val & BCM2835_MBOX_STATUS_WR_FULL))
break;
if (get_timer(0) >= endtime) {
@@ -58,7 +58,7 @@ int bcm2835_mbox_call_raw(u32 chan, u32 send, u32 *recv)
/* Wait for the response */
for (;;) {
- val = readl(&regs->status);
+ val = readl(&regs->mail0_status);
if (!(val & BCM2835_MBOX_STATUS_RD_EMPTY))
break;
if (get_timer(0) >= endtime) {
diff --git a/arch/riscv/cpu/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig
index f4b59cb71d..d411a79c21 100644
--- a/arch/riscv/cpu/ax25/Kconfig
+++ b/arch/riscv/cpu/ax25/Kconfig
@@ -6,6 +6,7 @@ config RISCV_NDS
imply RISCV_TIMER
imply ANDES_PLIC if (RISCV_MMODE || SPL_RISCV_MMODE)
imply ANDES_PLMT if (RISCV_MMODE || SPL_RISCV_MMODE)
+ imply V5L2_CACHE
help
Run U-Boot on AndeStar V5 platforms and use some specific features
which are provided by Andes Technology AndeStar V5 families.
diff --git a/arch/riscv/cpu/ax25/cache.c b/arch/riscv/cpu/ax25/cache.c
index cd95058d9d..41de30cc02 100644
--- a/arch/riscv/cpu/ax25/cache.c
+++ b/arch/riscv/cpu/ax25/cache.c
@@ -5,17 +5,24 @@
*/
#include <common.h>
+#include <dm.h>
+#include <dm/uclass-internal.h>
+#include <cache.h>
+#include <asm/csr.h>
+
+#ifdef CONFIG_RISCV_NDS_CACHE
+/* mcctlcommand */
+#define CCTL_REG_MCCTLCOMMAND_NUM 0x7cc
+
+/* D-cache operation */
+#define CCTL_L1D_WBINVAL_ALL 6
+#endif
void flush_dcache_all(void)
{
- /*
- * Andes' AX25 does not have a coherence agent. U-Boot must use data
- * cache flush and invalidate functions to keep data in the system
- * coherent.
- * The implementation of the fence instruction in the AX25 flushes the
- * data cache and is used for this purpose.
- */
- asm volatile ("fence" ::: "memory");
+#ifdef CONFIG_RISCV_NDS_CACHE
+ csr_write(CCTL_REG_MCCTLCOMMAND_NUM, CCTL_L1D_WBINVAL_ALL);
+#endif
}
void flush_dcache_range(unsigned long start, unsigned long end)
@@ -59,11 +66,18 @@ void dcache_enable(void)
{
#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
#ifdef CONFIG_RISCV_NDS_CACHE
+ struct udevice *dev = NULL;
+
asm volatile (
"csrr t1, mcache_ctl\n\t"
"ori t0, t1, 0x2\n\t"
"csrw mcache_ctl, t0\n\t"
);
+
+ uclass_find_first_device(UCLASS_CACHE, &dev);
+
+ if (dev)
+ cache_enable(dev);
#endif
#endif
}
@@ -72,12 +86,19 @@ void dcache_disable(void)
{
#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
#ifdef CONFIG_RISCV_NDS_CACHE
+ struct udevice *dev = NULL;
+
+ csr_write(CCTL_REG_MCCTLCOMMAND_NUM, CCTL_L1D_WBINVAL_ALL);
asm volatile (
- "fence\n\t"
"csrr t1, mcache_ctl\n\t"
"andi t0, t1, ~0x2\n\t"
"csrw mcache_ctl, t0\n\t"
);
+
+ uclass_find_first_device(UCLASS_CACHE, &dev);
+
+ if (dev)
+ cache_disable(dev);
#endif
#endif
}
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index b15209d623..0a2ce6d691 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -269,7 +269,7 @@ fix_rela_dyn:
/*
* skip first reserved entry: address, type, addend
*/
- bne t1, t2, 7f
+ j 10f
6:
LREG t5, -(REGBYTES*2)(t1) /* t5 <-- relocation info:type */
@@ -280,9 +280,7 @@ fix_rela_dyn:
add t5, t5, t6 /* t5 <-- location to fix up in RAM */
add t3, t3, t6 /* t3 <-- location to fix up in RAM */
SREG t5, 0(t3)
-7:
- addi t1, t1, (REGBYTES*3)
- ble t1, t2, 6b
+ j 10f
8:
la t4, __dyn_sym_start
@@ -299,13 +297,15 @@ fix_rela_dyn:
li t5, SYM_SIZE
mul t0, t0, t5
add s5, t4, t0
+ LREG t0, -(REGBYTES)(t1) /* t0 <-- addend */
LREG t5, REGBYTES(s5)
+ add t5, t5, t0
add t5, t5, t6 /* t5 <-- location to fix up in RAM */
add t3, t3, t6 /* t3 <-- location to fix up in RAM */
SREG t5, 0(t3)
10:
addi t1, t1, (REGBYTES*3)
- ble t1, t2, 9b
+ ble t1, t2, 6b
/*
* trap update
diff --git a/arch/riscv/dts/ae350_32.dts b/arch/riscv/dts/ae350_32.dts
index cb6ee13f16..97b7cee983 100644
--- a/arch/riscv/dts/ae350_32.dts
+++ b/arch/riscv/dts/ae350_32.dts
@@ -62,13 +62,18 @@
compatible = "riscv,cpu-intc";
};
};
+ };
- L2: l2-cache@e0500000 {
- compatible = "cache";
- cache-level = <2>;
- cache-size = <0x40000>;
- reg = <0x0 0xe0500000 0x0 0x40000>;
- };
+ L2: l2-cache@e0500000 {
+ compatible = "v5l2cache";
+ cache-level = <2>;
+ cache-size = <0x40000>;
+ reg = <0xe0500000 0x40000>;
+ andes,inst-prefetch = <3>;
+ andes,data-prefetch = <3>;
+ /* The value format is <XRAMOCTL XRAMICTL> */
+ andes,tag-ram-ctl = <0 0>;
+ andes,data-ram-ctl = <0 0>;
};
memory@0 {
diff --git a/arch/riscv/dts/ae350_64.dts b/arch/riscv/dts/ae350_64.dts
index 705491a8e4..d8f00f8d3a 100644
--- a/arch/riscv/dts/ae350_64.dts
+++ b/arch/riscv/dts/ae350_64.dts
@@ -62,13 +62,18 @@
compatible = "riscv,cpu-intc";
};
};
+ };
- L2: l2-cache@e0500000 {
- compatible = "cache";
- cache-level = <2>;
- cache-size = <0x40000>;
- reg = <0x0 0xe0500000 0x0 0x40000>;
- };
+ L2: l2-cache@e0500000 {
+ compatible = "v5l2cache";
+ cache-level = <2>;
+ cache-size = <0x40000>;
+ reg = <0x0 0xe0500000 0x0 0x40000>;
+ andes,inst-prefetch = <3>;
+ andes,data-prefetch = <3>;
+ /* The value format is <XRAMOCTL XRAMICTL> */
+ andes,tag-ram-ctl = <0 0>;
+ andes,data-ram-ctl = <0 0>;
};
memory@0 {
diff --git a/arch/riscv/lib/andes_plic.c b/arch/riscv/lib/andes_plic.c
index 2ffe49ac90..28568e4e2b 100644
--- a/arch/riscv/lib/andes_plic.c
+++ b/arch/riscv/lib/andes_plic.c
@@ -44,15 +44,12 @@ static int init_plic(void);
} \
} while (0)
-static int enable_ipi(int harts)
+static int enable_ipi(int hart)
{
- int i;
- int en = ENABLE_HART_IPI;
+ int en;
- for (i = 0; i < harts; i++) {
- en = en >> i;
- writel(en, (void __iomem *)ENABLE_REG(gd->arch.plic, i));
- }
+ en = ENABLE_HART_IPI >> hart;
+ writel(en, (void __iomem *)ENABLE_REG(gd->arch.plic, hart));
return 0;
}
@@ -60,18 +57,35 @@ static int enable_ipi(int harts)
static int init_plic(void)
{
struct udevice *dev;
+ ofnode node;
int ret;
+ u32 reg;
ret = uclass_find_first_device(UCLASS_CPU, &dev);
if (ret)
return ret;
if (ret == 0 && dev) {
- ret = cpu_get_count(dev);
- if (ret < 0)
- return ret;
+ ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) {
+ const char *device_type;
+
+ device_type = ofnode_read_string(node, "device_type");
+ if (!device_type)
+ continue;
+
+ if (strcmp(device_type, "cpu"))
+ continue;
+
+ /* skip if hart is marked as not available */
+ if (!ofnode_is_available(node))
+ continue;
+
+ /* read hart ID of CPU */
+ ret = ofnode_read_u32(node, "reg", &reg);
+ if (ret == 0)
+ enable_ipi(reg);
+ }
- enable_ipi(ret);
return 0;
}
diff --git a/board/AndesTech/ax25-ae350/ax25-ae350.c b/board/AndesTech/ax25-ae350/ax25-ae350.c
index 3d65ce7b75..b43eebb7a6 100644
--- a/board/AndesTech/ax25-ae350/ax25-ae350.c
+++ b/board/AndesTech/ax25-ae350/ax25-ae350.c
@@ -11,6 +11,7 @@
#include <linux/io.h>
#include <faraday/ftsmc020.h>
#include <fdtdec.h>
+#include <dm.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -93,10 +94,18 @@ int smc_init(void)
return 0;
}
+static void v5l2_init(void)
+{
+ struct udevice *dev;
+
+ uclass_get_device(UCLASS_CACHE, 0, &dev);
+}
+
#ifdef CONFIG_BOARD_EARLY_INIT_F
int board_early_init_f(void)
{
smc_init();
+ v5l2_init();
return 0;
}
diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index 7a6ca8f759..fa57d50c95 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -148,6 +148,11 @@ static const struct rpi_model rpi_models_new_scheme[] = {
DTB_DIR "bcm2837-rpi-cm3.dtb",
false,
},
+ [0x11] = {
+ "4 Model B",
+ DTB_DIR "bcm2711-rpi-4-b.dtb",
+ true,
+ },
};
static const struct rpi_model rpi_models_old_scheme[] = {
@@ -244,7 +249,8 @@ static uint32_t rev_type;
static const struct rpi_model *model;
#ifdef CONFIG_ARM64
-static struct mm_region bcm2837_mem_map[] = {
+#ifndef CONFIG_BCM2711
+static struct mm_region bcm283x_mem_map[] = {
{
.virt = 0x00000000UL,
.phys = 0x00000000UL,
@@ -263,8 +269,28 @@ static struct mm_region bcm2837_mem_map[] = {
0,
}
};
-
-struct mm_region *mem_map = bcm2837_mem_map;
+#else
+static struct mm_region bcm283x_mem_map[] = {
+ {
+ .virt = 0x00000000UL,
+ .phys = 0x00000000UL,
+ .size = 0xfe000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE
+ }, {
+ .virt = 0xfe000000UL,
+ .phys = 0xfe000000UL,
+ .size = 0x01800000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* List terminator */
+ 0,
+ }
+};
+#endif
+struct mm_region *mem_map = bcm283x_mem_map;
#endif
int dram_init(void)
diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c
index 11daf1a75a..47a2090251 100644
--- a/board/sifive/fu540/fu540.c
+++ b/board/sifive/fu540/fu540.c
@@ -122,10 +122,20 @@ static void fu540_setup_macaddr(u32 serialnum)
int misc_init_r(void)
{
- /* Set ethaddr environment variable if not set */
- if (!env_get("ethaddr"))
- fu540_setup_macaddr(fu540_read_serialnum());
-
+ u32 serial_num;
+ char buf[9] = {0};
+
+ /* Set ethaddr environment variable from board serial number */
+ if (!env_get("serial#")) {
+ serial_num = fu540_read_serialnum();
+ if (!serial_num) {
+ WARN(true, "Board serial number should not be 0 !!\n");
+ return 0;
+ }
+ snprintf(buf, sizeof(buf), "%08x", serial_num);
+ env_set("serial#", buf);
+ fu540_setup_macaddr(serial_num);
+ }
return 0;
}
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index fc14ad375c..18f9b84876 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -17,6 +17,7 @@
#include <misc.h>
#include <mtd.h>
#include <mtd_node.h>
+#include <netdev.h>
#include <phy.h>
#include <remoteproc.h>
#include <reset.h>
@@ -683,12 +684,21 @@ void board_quiesce_devices(void)
#endif
}
-/* board interface eth init */
-int board_interface_eth_init(phy_interface_t interface_type,
- bool eth_clk_sel_reg, bool eth_ref_clk_sel_reg)
+/* eth init function : weak called in eqos driver */
+int board_interface_eth_init(struct udevice *dev,
+ phy_interface_t interface_type)
{
u8 *syscfg;
u32 value;
+ bool eth_clk_sel_reg = false;
+ bool eth_ref_clk_sel_reg = false;
+
+ /* Gigabit Ethernet 125MHz clock selection. */
+ eth_clk_sel_reg = dev_read_bool(dev, "st,eth_clk_sel");
+
+ /* Ethernet 50Mhz RMII clock selection */
+ eth_ref_clk_sel_reg =
+ dev_read_bool(dev, "st,eth_ref_clk_sel");
syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
diff --git a/board/synopsys/emsdp/config.mk b/board/synopsys/emsdp/config.mk
new file mode 100644
index 0000000000..67fd7bf82a
--- /dev/null
+++ b/board/synopsys/emsdp/config.mk
@@ -0,0 +1,2 @@
+PLATFORM_CPPFLAGS += -mlittle-endian -mnorm -mswap -mmpy-option=3 \
+ -mbarrel-shifter -mfpu=fpuda_all -mcode-density
diff --git a/board/synopsys/emsdp/emsdp.c b/board/synopsys/emsdp/emsdp.c
index c0770b58c1..7a3fd5b7f2 100644
--- a/board/synopsys/emsdp/emsdp.c
+++ b/board/synopsys/emsdp/emsdp.c
@@ -48,6 +48,43 @@ int mach_cpu_init(void)
return 0;
}
+int board_early_init_r(void)
+{
+#define EMSDP_PSRAM_BASE 0xf2001000
+#define PSRAM_FLASH_CONFIG_REG_0 (void *)(EMSDP_PSRAM_BASE + 0x10)
+#define PSRAM_FLASH_CONFIG_REG_1 (void *)(EMSDP_PSRAM_BASE + 0x14)
+#define CRE_ENABLE BIT(31)
+#define CRE_DRIVE_CMD BIT(6)
+
+#define PSRAM_RCR_DPD BIT(1)
+#define PSRAM_RCR_PAGE_MODE BIT(7)
+
+/*
+ * PSRAM_FLASH_CONFIG_REG_x[30:15] to the address lines[16:1] of flash,
+ * thus "<< 1".
+ */
+#define PSRAM_RCR_SETUP ((PSRAM_RCR_DPD | PSRAM_RCR_PAGE_MODE) << 1)
+
+ // Switch PSRAM controller to command mode
+ writel(CRE_ENABLE | CRE_DRIVE_CMD, PSRAM_FLASH_CONFIG_REG_0);
+ // Program Refresh Configuration Register (RCR) for BANK0
+ writew(0, (void *)(0x10000000 + PSRAM_RCR_SETUP));
+ // Switch PSRAM controller back to memory mode
+ writel(0, PSRAM_FLASH_CONFIG_REG_0);
+
+
+ // Switch PSRAM controller to command mode
+ writel(CRE_ENABLE | CRE_DRIVE_CMD, PSRAM_FLASH_CONFIG_REG_1);
+ // Program Refresh Configuration Register (RCR) for BANK1
+ writew(0, (void *)(0x10800000 + PSRAM_RCR_SETUP));
+ // Switch PSRAM controller back to memory mode
+ writel(0, PSRAM_FLASH_CONFIG_REG_1);
+
+ printf("PSRAM initialized.\n");
+
+ return 0;
+}
+
int board_mmc_init(bd_t *bis)
{
struct dwmci_host *host = NULL;
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 05872fa0d7..98647f58b7 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1339,6 +1339,13 @@ config BOOTP_NTPSERVER
bool "Request & store 'ntpserverip' from BOOTP/DHCP server"
depends on CMD_BOOTP
+config CMD_PCAP
+ bool "pcap capture"
+ help
+ Selecting this will allow capturing all Ethernet packets and store
+ them in physical memory in a PCAP formated file,
+ later to be analyzed by PCAP reader application (IE. WireShark).
+
config BOOTP_PXE
bool "Send PXE client arch to BOOTP/DHCP server"
default y
diff --git a/cmd/Makefile b/cmd/Makefile
index 58827b5679..ac843b4b16 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -103,6 +103,7 @@ obj-$(CONFIG_CMD_NVEDIT_EFI) += nvedit_efi.o
obj-$(CONFIG_CMD_ONENAND) += onenand.o
obj-$(CONFIG_CMD_OSD) += osd.o
obj-$(CONFIG_CMD_PART) += part.o
+obj-$(CONFIG_CMD_PCAP) += pcap.o
ifdef CONFIG_PCI
obj-$(CONFIG_CMD_PCI) += pci.o
endif
diff --git a/cmd/mdio.c b/cmd/mdio.c
index add6440813..22c8fbe856 100644
--- a/cmd/mdio.c
+++ b/cmd/mdio.c
@@ -253,12 +253,13 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
case 'w':
if (pos > 1)
data = simple_strtoul(argv[pos--], NULL, 16);
+ /* Intentional fall-through - Get reg for read and write */
case 'r':
if (pos > 1)
if (extract_reg_range(argv[pos--], &devadlo, &devadhi,
&reglo, &reghi))
return CMD_RET_FAILURE;
-
+ /* Intentional fall-through - Get phy for all commands */
default:
if (pos > 1)
if (extract_phy_range(&argv[2], pos - 1, &bus,
diff --git a/cmd/pcap.c b/cmd/pcap.c
new file mode 100644
index 0000000000..980603f7bd
--- /dev/null
+++ b/cmd/pcap.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Ramon Fried <rfried.dev@gmail.com>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <net/pcap.h>
+
+static int do_pcap_init(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ phys_addr_t addr;
+ unsigned int size;
+
+ if (argc != 3)
+ return CMD_RET_USAGE;
+
+ addr = simple_strtoul(argv[1], NULL, 16);
+ size = simple_strtoul(argv[2], NULL, 10);
+
+ return pcap_init(addr, size) ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
+}
+
+static int do_pcap_start(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ return pcap_start_stop(true) ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
+}
+
+static int do_pcap_stop(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ return pcap_start_stop(false) ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
+}
+
+static int do_pcap_status(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ return pcap_print_status() ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
+}
+
+static int do_pcap_clear(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ return pcap_clear() ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
+}
+
+static char pcap_help_text[] =
+ "- network packet capture\n\n"
+ "pcap\n"
+ "pcap init\t\t\t<addr> <max_size>\n"
+ "pcap start\t\t\tstart capture\n"
+ "pcap stop\t\t\tstop capture\n"
+ "pcap status\t\t\tprint status\n"
+ "pcap clear\t\t\tclear capture buffer\n"
+ "\n"
+ "With:\n"
+ "\t<addr>: user address to which pcap will be stored (hexedcimal)\n"
+ "\t<max_size>: Maximum size of pcap file (decimal)\n"
+ "\n";
+
+U_BOOT_CMD_WITH_SUBCMDS(pcap, "pcap", pcap_help_text,
+ U_BOOT_SUBCMD_MKENT(init, 3, 0, do_pcap_init),
+ U_BOOT_SUBCMD_MKENT(start, 1, 0, do_pcap_start),
+ U_BOOT_SUBCMD_MKENT(stop, 1, 0, do_pcap_stop),
+ U_BOOT_SUBCMD_MKENT(status, 1, 0, do_pcap_status),
+ U_BOOT_SUBCMD_MKENT(clear, 1, 0, do_pcap_clear),
+);
diff --git a/configs/emsdp_defconfig b/configs/emsdp_defconfig
index 64281d0529..5e55e3e2b2 100644
--- a/configs/emsdp_defconfig
+++ b/configs/emsdp_defconfig
@@ -7,6 +7,7 @@ CONFIG_ENV_SIZE=0x1000
CONFIG_SYS_CLK_FREQ=40000000
# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
CONFIG_VERSION_VARIABLE=y
+CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="emsdp# "
# CONFIG_CMD_BOOTD is not set
diff --git a/configs/qemu-riscv32_defconfig b/configs/qemu-riscv32_defconfig
index d5b33b5c2b..fe09a0da88 100644
--- a/configs/qemu-riscv32_defconfig
+++ b/configs/qemu-riscv32_defconfig
@@ -5,5 +5,6 @@ CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT=y
CONFIG_DISPLAY_CPUINFO=y
CONFIG_DISPLAY_BOARDINFO=y
+CONFIG_CMD_BOOTEFI_SELFTEST=y
# CONFIG_CMD_MII is not set
CONFIG_OF_PRIOR_STAGE=y
diff --git a/configs/qemu-riscv32_smode_defconfig b/configs/qemu-riscv32_smode_defconfig
index a80e68b8c7..7103324421 100644
--- a/configs/qemu-riscv32_smode_defconfig
+++ b/configs/qemu-riscv32_smode_defconfig
@@ -6,5 +6,6 @@ CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT=y
CONFIG_DISPLAY_CPUINFO=y
CONFIG_DISPLAY_BOARDINFO=y
+CONFIG_CMD_BOOTEFI_SELFTEST=y
# CONFIG_CMD_MII is not set
CONFIG_OF_PRIOR_STAGE=y
diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu-riscv64_defconfig
index 19a5849226..ef84dfded2 100644
--- a/configs/qemu-riscv64_defconfig
+++ b/configs/qemu-riscv64_defconfig
@@ -6,5 +6,6 @@ CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT=y
CONFIG_DISPLAY_CPUINFO=y
CONFIG_DISPLAY_BOARDINFO=y
+CONFIG_CMD_BOOTEFI_SELFTEST=y
# CONFIG_CMD_MII is not set
CONFIG_OF_PRIOR_STAGE=y
diff --git a/configs/qemu-riscv64_smode_defconfig b/configs/qemu-riscv64_smode_defconfig
index 74743a5ebe..1c7a2d150c 100644
--- a/configs/qemu-riscv64_smode_defconfig
+++ b/configs/qemu-riscv64_smode_defconfig
@@ -7,5 +7,6 @@ CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT=y
CONFIG_DISPLAY_CPUINFO=y
CONFIG_DISPLAY_BOARDINFO=y
+CONFIG_CMD_BOOTEFI_SELFTEST=y
# CONFIG_CMD_MII is not set
CONFIG_OF_PRIOR_STAGE=y
diff --git a/configs/rpi_4_32b_defconfig b/configs/rpi_4_32b_defconfig
new file mode 100644
index 0000000000..a31a617a5f
--- /dev/null
+++ b/configs/rpi_4_32b_defconfig
@@ -0,0 +1,33 @@
+CONFIG_ARM=y
+CONFIG_ARCH_BCM283X=y
+CONFIG_SYS_TEXT_BASE=0x00008000
+CONFIG_TARGET_RPI_4_32B=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_NR_DRAM_BANKS=1
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
+CONFIG_OF_BOARD=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_MISC_INIT_R=y
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_SYS_PROMPT="U-Boot> "
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_FS_UUID=y
+CONFIG_ENV_FAT_INTERFACE="mmc"
+CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_DM_KEYBOARD=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_BCM2835=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_GENERIC is not set
+# CONFIG_REQUIRE_SERIAL_CONSOLE is not set
+CONFIG_DM_VIDEO=y
+CONFIG_SYS_WHITE_ON_BLACK=y
+CONFIG_CONSOLE_SCROLL_LINES=10
+CONFIG_PHYS_TO_BUS=y
+CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/rpi_4_defconfig b/configs/rpi_4_defconfig
new file mode 100644
index 0000000000..da8c960a2a
--- /dev/null
+++ b/configs/rpi_4_defconfig
@@ -0,0 +1,33 @@
+CONFIG_ARM=y
+CONFIG_ARCH_BCM283X=y
+CONFIG_SYS_TEXT_BASE=0x00080000
+CONFIG_TARGET_RPI_4=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_NR_DRAM_BANKS=1
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
+CONFIG_OF_BOARD=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_MISC_INIT_R=y
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_SYS_PROMPT="U-Boot> "
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_FS_UUID=y
+CONFIG_ENV_FAT_INTERFACE="mmc"
+CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_DM_KEYBOARD=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_BCM2835=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_GENERIC is not set
+# CONFIG_REQUIRE_SERIAL_CONSOLE is not set
+CONFIG_DM_VIDEO=y
+CONFIG_SYS_WHITE_ON_BLACK=y
+CONFIG_CONSOLE_SCROLL_LINES=10
+CONFIG_PHYS_TO_BUS=y
+CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 7355e3aa1e..968ffdab61 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -49,6 +49,7 @@ CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
CONFIG_CMD_AXI=y
CONFIG_CMD_AB_SELECT=y
+CONFIG_CMD_PCAP=y
CONFIG_CMD_TFTPPUT=y
CONFIG_CMD_TFTPSRV=y
CONFIG_CMD_RARP=y
diff --git a/doc/README.pcap b/doc/README.pcap
new file mode 100644
index 0000000000..97b3e55fd8
--- /dev/null
+++ b/doc/README.pcap
@@ -0,0 +1,62 @@
+PCAP:
+
+U-boot supports live Ethernet packet capture in PCAP(2.4) format.
+This is enabled by CONFIG_CMD_PCAP.
+
+The capture is stored on physical memory, and should be copied to
+a machine capable of parsing and displaying PCAP files (IE. wireshark)
+If networking works properly one can copy the capture file from physical memory
+using tftpput, or save it to local storage with (sf write, mmc write, fatwrite, etc)
+
+the pcap capturing requires maximum buffer size.
+when the buffer is full an error message will be displayed and then packets
+will silently drop.
+the actual capture file size is populate in the environment variable "pcapsize".
+
+Usage example:
+
+# Initialize pcap capture to physical address (0x100000) with maximum size of
+# 100000 bytes.
+
+# Start capture
+pcap start
+
+# Initialize network activity
+env set ipaddr 10.0.2.15; env set serverip 10.0.2.2; tftp uImage64
+
+# Stop capture
+pcap stop
+
+# pcap init 0x100000 100000
+PCAP capture initialized: addr: 0xffffffff80100000 max length: 100000
+
+# pcap start
+# env set ipaddr 10.0.2.15; env set serverip 10.0.2.2; tftp uImage64
+eth0@10000000: PHY present at 0
+eth0@10000000: link up, 1000Mbps full-duplex (lpa: 0x7c00)
+Using eth0@10000000 device
+TFTP from server 10.0.2.2; our IP address is 10.0.2.15
+Filename 'uImage64'.
+Load address: 0xffffffff88000000
+Loading: #################################################################
+ #################################################################
+ #################################################################
+ #################################################################
+!!! Buffer is full, consider increasing buffer size !!!
+ #################################################################
+ #################################################################
+ #################################################################
+ #################################################################
+ #################################################################
+ #
+ 18.2 MiB/s
+done
+Bytes transferred = 8359376 (7f8dd0 hex)
+PCAP status:
+ Initialized addr: 0xffffffff80100000 max length: 100000
+ Status: Active. file size: 99991
+ Incoming packets: 66 Outgoing packets: 67
+
+# pcap stop
+# tftpput 0xffffffff80100000 $pcapsize 10.0.2.2:capture.pcap
+
diff --git a/doc/api/efi.rst b/doc/api/efi.rst
index 39e2dbae0b..2ca344932e 100644
--- a/doc/api/efi.rst
+++ b/doc/api/efi.rst
@@ -103,3 +103,36 @@ Block device driver
.. kernel-doc:: lib/efi_driver/efi_block_device.c
:internal:
+
+Protocols
+---------
+
+Block IO protocol
+~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: lib/efi_loader/efi_disk.c
+ :internal:
+
+File protocol
+~~~~~~~~~~~~~
+
+.. kernel-doc:: lib/efi_loader/efi_file.c
+ :internal:
+
+Graphical output protocol
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: lib/efi_loader/efi_gop.c
+ :internal:
+
+Network protocols
+~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: lib/efi_loader/efi_net.c
+ :internal:
+
+Text IO protocols
+~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: lib/efi_loader/efi_console.c
+ :internal:
diff --git a/doc/device-tree-bindings/net/marvell-mdio.txt b/doc/device-tree-bindings/net/marvell-mdio.txt
new file mode 100644
index 0000000000..e2038e2145
--- /dev/null
+++ b/doc/device-tree-bindings/net/marvell-mdio.txt
@@ -0,0 +1,15 @@
+* Marvell MDIO Ethernet Controller interface
+
+The Ethernet controllers of the Marvel Armada 3700 and Armada 7k/8k
+have an identical unit that provides an interface with the MDIO bus.
+This driver handles this MDIO interface.
+
+Mandatory properties:
+SoC specific:
+ - #address-cells: Must be <1>.
+ - #size-cells: Must be <0>.
+ - compatible: Should be "marvell,orion-mdio" (for SMI)
+ "marvell,xmdio" (for XSMI)
+ - reg: Base address and size SMI/XMSI bus.
+
+Please refer to "mdio.txt" for generic MDIO bus bindings.
diff --git a/doc/device-tree-bindings/net/mdio.txt b/doc/device-tree-bindings/net/mdio.txt
new file mode 100644
index 0000000000..1595325050
--- /dev/null
+++ b/doc/device-tree-bindings/net/mdio.txt
@@ -0,0 +1,36 @@
+Common MDIO bus properties.
+
+These are generic properties that can apply to any MDIO bus.
+
+Optional properties:
+ - device-name - If present it is used to name the device and MDIO bus.
+ The name must be unique and must not contain spaces.
+
+A list of child nodes, one per device on the bus is expected. These could be
+PHYs, switches or similar devices and child nodes should follow the specific
+binding for the device type.
+
+Example :
+This example shows the structure used for the external MDIO bus on NXP LS1028A
+RDB board. Note that this MDIO device is an integrated PCI function and
+requires no compatible property for probing.
+
+/* definition in SoC dtsi file */
+ pcie@1f0000000 {
+
+ mdio0: pci@0,3 {
+ #address-cells=<0>;
+ #size-cells=<1>;
+ reg = <0x000300 0 0 0 0>;
+ status = "disabled";
+ device-name = "emdio";
+ };
+ };
+/* definition of PHYs in RDB dts file */
+&mdio0 {
+ status = "okay";
+ rdb_phy0: phy@2 {
+ reg = <2>;
+ };
+};
+
diff --git a/doc/driver-model/migration.rst b/doc/driver-model/migration.rst
index a26e7ab7e1..75b85235ef 100644
--- a/doc/driver-model/migration.rst
+++ b/doc/driver-model/migration.rst
@@ -97,3 +97,11 @@ Deadline: 2019.07
The video subsystem has supported driver model since early 2016. Maintainers
should submit patches switching over to using CONFIG_DM_VIDEO and other base
driver model options in time for inclusion in the 2019.07 release.
+
+CONFIG_DM_ETH
+-------------
+Deadline: 2020.07
+
+The network subsystem has supported the driver model since early 2015.
+Maintainers should submit patches switching over to using CONFIG_DM_ETH and
+other base driver model options in time for inclusion in the 2020.07 release.
diff --git a/doc/git-mailrc b/doc/git-mailrc
index a63b76befc..1d36f5845a 100644
--- a/doc/git-mailrc
+++ b/doc/git-mailrc
@@ -35,6 +35,7 @@ alias mariosix Mario Six <mario.six@gdsys.cc>
alias masahiro Masahiro Yamada <yamada.masahiro@socionext.com>
alias mateusz Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
alias maxime Maxime Ripard <maxime.ripard@free-electrons.com>
+alias mbrugger Matthias Brugger <mbrugger@suse.com>
alias monstr Michal Simek <monstr@monstr.eu>
alias prom Minkyu Kang <mk7.kang@samsung.com>
alias ptomsich Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
@@ -74,6 +75,9 @@ alias uniphier uboot, masahiro
alias zynq uboot, monstr
alias rockchip uboot, sjg, kevery, ptomsich
+alias bcm283x uboot, mbrugger
+alias rpi uboot, mbrugger
+
alias m68k uboot, alisonwang, angelo_ts
alias coldfire m68k
diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig
index 24def7ac0f..629039e7a8 100644
--- a/drivers/cache/Kconfig
+++ b/drivers/cache/Kconfig
@@ -22,4 +22,13 @@ config L2X0_CACHE
ARMv7(32-bit) devices. The driver configures the cache settings
found in the device tree.
+config V5L2_CACHE
+ bool "Andes V5L2 cache driver"
+ select CACHE
+ depends on RISCV_NDS_CACHE
+ help
+ Support Andes V5L2 cache controller in AE350 platform.
+ It will configure tag and data ram timing control from the
+ device tree and enable L2 cache.
+
endmenu
diff --git a/drivers/cache/Makefile b/drivers/cache/Makefile
index 9deb961d91..4a6458c602 100644
--- a/drivers/cache/Makefile
+++ b/drivers/cache/Makefile
@@ -2,3 +2,4 @@
obj-$(CONFIG_CACHE) += cache-uclass.o
obj-$(CONFIG_SANDBOX) += sandbox_cache.o
obj-$(CONFIG_L2X0_CACHE) += cache-l2x0.o
+obj-$(CONFIG_V5L2_CACHE) += cache-v5l2.o
diff --git a/drivers/cache/cache-uclass.c b/drivers/cache/cache-uclass.c
index 97ce0249a4..3b20a10f08 100644
--- a/drivers/cache/cache-uclass.c
+++ b/drivers/cache/cache-uclass.c
@@ -17,6 +17,26 @@ int cache_get_info(struct udevice *dev, struct cache_info *info)
return ops->get_info(dev, info);
}
+int cache_enable(struct udevice *dev)
+{
+ struct cache_ops *ops = cache_get_ops(dev);
+
+ if (!ops->enable)
+ return -ENOSYS;
+
+ return ops->enable(dev);
+}
+
+int cache_disable(struct udevice *dev)
+{
+ struct cache_ops *ops = cache_get_ops(dev);
+
+ if (!ops->disable)
+ return -ENOSYS;
+
+ return ops->disable(dev);
+}
+
UCLASS_DRIVER(cache) = {
.id = UCLASS_CACHE,
.name = "cache",
diff --git a/drivers/cache/cache-v5l2.c b/drivers/cache/cache-v5l2.c
new file mode 100644
index 0000000000..d367171b36
--- /dev/null
+++ b/drivers/cache/cache-v5l2.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Andes Technology Corporation
+ * Rick Chen, Andes Technology Corporation <rick@andestech.com>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cache.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <dm/ofnode.h>
+
+struct l2cache {
+ volatile u64 configure;
+ volatile u64 control;
+ volatile u64 hpm0;
+ volatile u64 hpm1;
+ volatile u64 hpm2;
+ volatile u64 hpm3;
+ volatile u64 error_status;
+ volatile u64 ecc_error;
+ volatile u64 cctl_command0;
+ volatile u64 cctl_access_line0;
+ volatile u64 cctl_command1;
+ volatile u64 cctl_access_line1;
+ volatile u64 cctl_command2;
+ volatile u64 cctl_access_line2;
+ volatile u64 cctl_command3;
+ volatile u64 cctl_access_line4;
+ volatile u64 cctl_status;
+};
+
+/* Control Register */
+#define L2_ENABLE 0x1
+/* prefetch */
+#define IPREPETCH_OFF 3
+#define DPREPETCH_OFF 5
+#define IPREPETCH_MSK (3 << IPREPETCH_OFF)
+#define DPREPETCH_MSK (3 << DPREPETCH_OFF)
+/* tag ram */
+#define TRAMOCTL_OFF 8
+#define TRAMICTL_OFF 10
+#define TRAMOCTL_MSK (3 << TRAMOCTL_OFF)
+#define TRAMICTL_MSK BIT(TRAMICTL_OFF)
+/* data ram */
+#define DRAMOCTL_OFF 11
+#define DRAMICTL_OFF 13
+#define DRAMOCTL_MSK (3 << DRAMOCTL_OFF)
+#define DRAMICTL_MSK BIT(DRAMICTL_OFF)
+
+/* CCTL Command Register */
+#define CCTL_CMD_REG(base, hart) ((ulong)(base) + 0x40 + (hart) * 0x10)
+#define L2_WBINVAL_ALL 0x12
+
+/* CCTL Status Register */
+#define CCTL_STATUS_MSK(hart) (0xf << ((hart) * 4))
+#define CCTL_STATUS_IDLE(hart) (0 << ((hart) * 4))
+#define CCTL_STATUS_PROCESS(hart) (1 << ((hart) * 4))
+#define CCTL_STATUS_ILLEGAL(hart) (2 << ((hart) * 4))
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct v5l2_plat {
+ struct l2cache *regs;
+ u32 iprefetch;
+ u32 dprefetch;
+ u32 tram_ctl[2];
+ u32 dram_ctl[2];
+};
+
+static int v5l2_enable(struct udevice *dev)
+{
+ struct v5l2_plat *plat = dev_get_platdata(dev);
+ volatile struct l2cache *regs = plat->regs;
+
+ if (regs)
+ setbits_le32(&regs->control, L2_ENABLE);
+
+ return 0;
+}
+
+static int v5l2_disable(struct udevice *dev)
+{
+ struct v5l2_plat *plat = dev_get_platdata(dev);
+ volatile struct l2cache *regs = plat->regs;
+ u8 hart = gd->arch.boot_hart;
+ void __iomem *cctlcmd = (void __iomem *)CCTL_CMD_REG(regs, hart);
+
+ if ((regs) && (readl(&regs->control) & L2_ENABLE)) {
+ writel(L2_WBINVAL_ALL, cctlcmd);
+
+ while ((readl(&regs->cctl_status) & CCTL_STATUS_MSK(hart))) {
+ if ((readl(&regs->cctl_status) & CCTL_STATUS_ILLEGAL(hart))) {
+ printf("L2 flush illegal! hanging...");
+ hang();
+ }
+ }
+ clrbits_le32(&regs->control, L2_ENABLE);
+ }
+
+ return 0;
+}
+
+static int v5l2_ofdata_to_platdata(struct udevice *dev)
+{
+ struct v5l2_plat *plat = dev_get_platdata(dev);
+ struct l2cache *regs;
+
+ regs = (struct l2cache *)dev_read_addr(dev);
+ plat->regs = regs;
+
+ plat->iprefetch = -EINVAL;
+ plat->dprefetch = -EINVAL;
+ plat->tram_ctl[0] = -EINVAL;
+ plat->dram_ctl[0] = -EINVAL;
+
+ /* Instruction and data fetch prefetch depth */
+ dev_read_u32(dev, "andes,inst-prefetch", &plat->iprefetch);
+ dev_read_u32(dev, "andes,data-prefetch", &plat->dprefetch);
+
+ /* Set tag RAM and data RAM setup and output cycle */
+ dev_read_u32_array(dev, "andes,tag-ram-ctl", plat->tram_ctl, 2);
+ dev_read_u32_array(dev, "andes,data-ram-ctl", plat->dram_ctl, 2);
+
+ return 0;
+}
+
+static int v5l2_probe(struct udevice *dev)
+{
+ struct v5l2_plat *plat = dev_get_platdata(dev);
+ struct l2cache *regs = plat->regs;
+ u32 ctl_val;
+
+ ctl_val = readl(&regs->control);
+
+ if (!(ctl_val & L2_ENABLE))
+ ctl_val |= L2_ENABLE;
+
+ if (plat->iprefetch != -EINVAL) {
+ ctl_val &= ~(IPREPETCH_MSK);
+ ctl_val |= (plat->iprefetch << IPREPETCH_OFF);
+ }
+
+ if (plat->dprefetch != -EINVAL) {
+ ctl_val &= ~(DPREPETCH_MSK);
+ ctl_val |= (plat->dprefetch << DPREPETCH_OFF);
+ }
+
+ if (plat->tram_ctl[0] != -EINVAL) {
+ ctl_val &= ~(TRAMOCTL_MSK | TRAMICTL_MSK);
+ ctl_val |= plat->tram_ctl[0] << TRAMOCTL_OFF;
+ ctl_val |= plat->tram_ctl[1] << TRAMICTL_OFF;
+ }
+
+ if (plat->dram_ctl[0] != -EINVAL) {
+ ctl_val &= ~(DRAMOCTL_MSK | DRAMICTL_MSK);
+ ctl_val |= plat->dram_ctl[0] << DRAMOCTL_OFF;
+ ctl_val |= plat->dram_ctl[1] << DRAMICTL_OFF;
+ }
+
+ writel(ctl_val, &regs->control);
+
+ return 0;
+}
+
+static const struct udevice_id v5l2_cache_ids[] = {
+ { .compatible = "v5l2cache" },
+ {}
+};
+
+static const struct cache_ops v5l2_cache_ops = {
+ .enable = v5l2_enable,
+ .disable = v5l2_disable,
+};
+
+U_BOOT_DRIVER(v5l2_cache) = {
+ .name = "v5l2_cache",
+ .id = UCLASS_CACHE,
+ .of_match = v5l2_cache_ids,
+ .ofdata_to_platdata = v5l2_ofdata_to_platdata,
+ .probe = v5l2_probe,
+ .platdata_auto_alloc_size = sizeof(struct v5l2_plat),
+ .ops = &v5l2_cache_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/cache/sandbox_cache.c b/drivers/cache/sandbox_cache.c
index 14cc6b0c0a..9050c4cf34 100644
--- a/drivers/cache/sandbox_cache.c
+++ b/drivers/cache/sandbox_cache.c
@@ -17,8 +17,21 @@ static int sandbox_get_info(struct udevice *dev, struct cache_info *info)
return 0;
}
+static int sandbox_enable(struct udevice *dev)
+{
+ return 0;
+}
+
+static int snadbox_disable(struct udevice *dev)
+{
+ return 0;
+}
+
+
static const struct cache_ops sandbox_cache_ops = {
.get_info = sandbox_get_info,
+ .enable = sandbox_enable,
+ .disable = snadbox_disable,
};
static const struct udevice_id sandbox_cache_ids[] = {
diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c
index f77c126499..28ad0aa30f 100644
--- a/drivers/cpu/riscv_cpu.c
+++ b/drivers/cpu/riscv_cpu.c
@@ -46,6 +46,10 @@ static int riscv_cpu_get_count(struct udevice *dev)
ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) {
const char *device_type;
+ /* skip if hart is marked as not available in the device tree */
+ if (!ofnode_is_available(node))
+ continue;
+
device_type = ofnode_read_string(node, "device_type");
if (!device_type)
continue;
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 20f6dc4ecb..786b5a2226 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -149,7 +149,12 @@ static uint8_t i2c_imx_get_clk(struct mxc_i2c_bus *i2c_bus, unsigned int rate)
#endif
/* Divider value calculation */
+#if CONFIG_IS_ENABLED(CLK)
+ i2c_clk_rate = clk_get_rate(&i2c_bus->per_clk);
+#else
i2c_clk_rate = mxc_get_clock(MXC_I2C_CLK);
+#endif
+
div = (i2c_clk_rate + rate - 1) / rate;
if (div < i2c_clk_div[0][0])
clk_div = 0;
@@ -891,9 +896,22 @@ static int mxc_i2c_probe(struct udevice *bus)
i2c_bus->bus = bus;
/* Enable clk */
+#if CONFIG_IS_ENABLED(CLK)
+ ret = clk_get_by_index(bus, 0, &i2c_bus->per_clk);
+ if (ret) {
+ printf("Failed to get i2c clk\n");
+ return ret;
+ }
+ ret = clk_enable(&i2c_bus->per_clk);
+ if (ret) {
+ printf("Failed to enable i2c clk\n");
+ return ret;
+ }
+#else
ret = enable_i2c_clk(1, bus->seq);
if (ret < 0)
return ret;
+#endif
/*
* See Documentation/devicetree/bindings/i2c/i2c-imx.txt
diff --git a/drivers/mmc/bcm2835_sdhci.c b/drivers/mmc/bcm2835_sdhci.c
index bf3304c4dc..bc9ee95fd5 100644
--- a/drivers/mmc/bcm2835_sdhci.c
+++ b/drivers/mmc/bcm2835_sdhci.c
@@ -178,12 +178,13 @@ static int bcm2835_sdhci_probe(struct udevice *dev)
fdt_addr_t base;
int emmc_freq;
int ret;
+ int clock_id = (int)dev_get_driver_data(dev);
base = devfdt_get_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
- ret = bcm2835_get_mmc_clock(BCM2835_MBOX_CLOCK_ID_EMMC);
+ ret = bcm2835_get_mmc_clock(clock_id);
if (ret < 0) {
debug("%s: Failed to set MMC clock (err=%d)\n", __func__, ret);
return ret;
@@ -230,7 +231,14 @@ static int bcm2835_sdhci_probe(struct udevice *dev)
}
static const struct udevice_id bcm2835_sdhci_match[] = {
- { .compatible = "brcm,bcm2835-sdhci" },
+ {
+ .compatible = "brcm,bcm2835-sdhci",
+ .data = BCM2835_MBOX_CLOCK_ID_EMMC
+ },
+ {
+ .compatible = "brcm,bcm2711-emmc2",
+ .data = BCM2835_MBOX_CLOCK_ID_EMMC2
+ },
{ /* sentinel */ }
};
diff --git a/drivers/mmc/bcm2835_sdhost.c b/drivers/mmc/bcm2835_sdhost.c
index 1ce019af57..7f70acaf39 100644
--- a/drivers/mmc/bcm2835_sdhost.c
+++ b/drivers/mmc/bcm2835_sdhost.c
@@ -234,7 +234,7 @@ static void bcm2835_reset_internal(struct bcm2835_host *host)
static int bcm2835_wait_transfer_complete(struct bcm2835_host *host)
{
- int timediff = 0;
+ ulong tstart_ms = get_timer(0);
while (1) {
u32 edm, fsm;
@@ -254,11 +254,13 @@ static int bcm2835_wait_transfer_complete(struct bcm2835_host *host)
break;
}
- /* Error out after 100000 register reads (~1s) */
- if (timediff++ == 100000) {
+ /* Error out after ~1s */
+ ulong tlapse_ms = get_timer(tstart_ms);
+ if ( tlapse_ms > 1000 /* ms */ ) {
+
dev_err(host->dev,
- "wait_transfer_complete - still waiting after %d retries\n",
- timediff);
+ "wait_transfer_complete - still waiting after %lu ms\n",
+ tlapse_ms);
bcm2835_dumpregs(host);
return -ETIMEDOUT;
}
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 084e095229..2ce3092db0 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1,5 +1,6 @@
source "drivers/net/phy/Kconfig"
source "drivers/net/pfe_eth/Kconfig"
+source "drivers/net/fsl-mc/Kconfig"
config DM_ETH
bool "Enable Driver Model for Ethernet drivers"
@@ -603,4 +604,14 @@ config MDIO_MUX_I2CREG
an I2C chip. The board it was developed for uses a mux controlled by
on-board FPGA which in turn is accessed as a chip over I2C.
+config MVMDIO
+ bool "Marvell MDIO interface support"
+ depends on DM_MDIO
+ help
+ This driver supports the MDIO interface found in the network
+ interface units of the Marvell EBU SoCs (Kirkwood, Orion5x,
+ Dove, Armada 370, Armada XP, Armada 37xx and Armada7K/8K/8KP).
+
+ This driver is used by the MVPP2 and MVNETA drivers.
+
endif # NETDEVICES
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 71c0889355..30991834ec 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_MDIO_MUX_SANDBOX) += mdio_mux_sandbox.o
obj-$(CONFIG_MPC8XX_FEC) += mpc8xx_fec.o
obj-$(CONFIG_MT7628_ETH) += mt7628-eth.o
obj-$(CONFIG_MVGBE) += mvgbe.o
+obj-$(CONFIG_MVMDIO) += mvmdio.o
obj-$(CONFIG_MVNETA) += mvneta.o
obj-$(CONFIG_MVPP2) += mvpp2.o
obj-$(CONFIG_NATSEMI) += natsemi.o
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index c4fe40b19a..145eeac45f 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -847,7 +847,6 @@ int designware_eth_ofdata_to_platdata(struct udevice *dev)
static const struct udevice_id designware_eth_ids[] = {
{ .compatible = "allwinner,sun7i-a20-gmac" },
- { .compatible = "altr,socfpga-stmmac" },
{ .compatible = "amlogic,meson6-dwmac" },
{ .compatible = "amlogic,meson-gx-dwmac" },
{ .compatible = "amlogic,meson-gxbb-dwmac" },
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 07b36675a7..455709338c 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -621,7 +621,7 @@ err:
return ret;
}
-void eqos_stop_clks_tegra186(struct udevice *dev)
+static void eqos_stop_clks_tegra186(struct udevice *dev)
{
struct eqos_priv *eqos = dev_get_priv(dev);
@@ -636,7 +636,7 @@ void eqos_stop_clks_tegra186(struct udevice *dev)
debug("%s: OK\n", __func__);
}
-void eqos_stop_clks_stm32(struct udevice *dev)
+static void eqos_stop_clks_stm32(struct udevice *dev)
{
struct eqos_priv *eqos = dev_get_priv(dev);
@@ -1290,7 +1290,7 @@ err:
return ret;
}
-void eqos_stop(struct udevice *dev)
+static void eqos_stop(struct udevice *dev)
{
struct eqos_priv *eqos = dev_get_priv(dev);
int i;
@@ -1344,7 +1344,7 @@ void eqos_stop(struct udevice *dev)
debug("%s: OK\n", __func__);
}
-int eqos_send(struct udevice *dev, void *packet, int length)
+static int eqos_send(struct udevice *dev, void *packet, int length)
{
struct eqos_priv *eqos = dev_get_priv(dev);
struct eqos_desc *tx_desc;
@@ -1385,7 +1385,7 @@ int eqos_send(struct udevice *dev, void *packet, int length)
return -ETIMEDOUT;
}
-int eqos_recv(struct udevice *dev, int flags, uchar **packetp)
+static int eqos_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct eqos_priv *eqos = dev_get_priv(dev);
struct eqos_desc *rx_desc;
@@ -1409,7 +1409,7 @@ int eqos_recv(struct udevice *dev, int flags, uchar **packetp)
return length;
}
-int eqos_free_pkt(struct udevice *dev, uchar *packet, int length)
+static int eqos_free_pkt(struct udevice *dev, uchar *packet, int length)
{
struct eqos_priv *eqos = dev_get_priv(dev);
uchar *packet_expected;
@@ -1591,8 +1591,8 @@ err_free_reset_eqos:
}
/* board-specific Ethernet Interface initializations. */
-__weak int board_interface_eth_init(int interface_type, bool eth_clk_sel_reg,
- bool eth_ref_clk_sel_reg)
+__weak int board_interface_eth_init(struct udevice *dev,
+ phy_interface_t interface_type)
{
return 0;
}
@@ -1602,8 +1602,6 @@ static int eqos_probe_resources_stm32(struct udevice *dev)
struct eqos_priv *eqos = dev_get_priv(dev);
int ret;
phy_interface_t interface;
- bool eth_clk_sel_reg = false;
- bool eth_ref_clk_sel_reg = false;
debug("%s(dev=%p):\n", __func__, dev);
@@ -1614,15 +1612,7 @@ static int eqos_probe_resources_stm32(struct udevice *dev)
return -EINVAL;
}
- /* Gigabit Ethernet 125MHz clock selection. */
- eth_clk_sel_reg = dev_read_bool(dev, "st,eth_clk_sel");
-
- /* Ethernet 50Mhz RMII clock selection */
- eth_ref_clk_sel_reg =
- dev_read_bool(dev, "st,eth_ref_clk_sel");
-
- ret = board_interface_eth_init(interface, eth_clk_sel_reg,
- eth_ref_clk_sel_reg);
+ ret = board_interface_eth_init(dev, interface);
if (ret)
return -EINVAL;
diff --git a/drivers/net/fsl-mc/Kconfig b/drivers/net/fsl-mc/Kconfig
new file mode 100644
index 0000000000..25a2cb8ffa
--- /dev/null
+++ b/drivers/net/fsl-mc/Kconfig
@@ -0,0 +1,25 @@
+#
+# NXP Management Complex
+#
+
+menuconfig FSL_MC_ENET
+ bool "NXP Management Complex"
+ depends on ARCH_LS2080A || ARCH_LS1088A || ARCH_LX2160A
+ default y
+ select RESV_RAM
+ help
+ Enable Management Complex (MC) network
+ This is NXP Management Complex menuconfig
+ that contains all MC related config options
+
+if FSL_MC_ENET
+
+config SYS_MC_RSV_MEM_ALIGN
+ hex "Management Complex reserved memory alignment"
+ depends on RESV_RAM
+ default 0x20000000 if ARCH_LS2080A || ARCH_LS1088A || ARCH_LX2160A
+ help
+ Reserved memory needs to be aligned for MC to use. Default value
+ is 512MB.
+
+endif # FSL_MC_ENET
diff --git a/drivers/net/fsl_enetc_mdio.c b/drivers/net/fsl_enetc_mdio.c
index 60d21537b8..b4463a58a5 100644
--- a/drivers/net/fsl_enetc_mdio.c
+++ b/drivers/net/fsl_enetc_mdio.c
@@ -144,6 +144,7 @@ U_BOOT_DRIVER(enetc_mdio) = {
static struct pci_device_id enetc_mdio_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, PCI_DEVICE_ID_ENETC_MDIO) },
+ { }
};
U_BOOT_PCI_DEVICE(enetc_mdio, enetc_mdio_ids);
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index c99cf663a4..377188e361 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -296,13 +296,15 @@ static inline void macb_flush_ring_desc(struct macb_device *macb, bool rx)
static inline void macb_flush_rx_buffer(struct macb_device *macb)
{
flush_dcache_range(macb->rx_buffer_dma, macb->rx_buffer_dma +
- ALIGN(MACB_RX_BUFFER_SIZE, PKTALIGN));
+ ALIGN(macb->rx_buffer_size * MACB_RX_RING_SIZE,
+ PKTALIGN));
}
static inline void macb_invalidate_rx_buffer(struct macb_device *macb)
{
invalidate_dcache_range(macb->rx_buffer_dma, macb->rx_buffer_dma +
- ALIGN(MACB_RX_BUFFER_SIZE, PKTALIGN));
+ ALIGN(macb->rx_buffer_size * MACB_RX_RING_SIZE,
+ PKTALIGN));
}
#if defined(CONFIG_CMD_NET)
@@ -643,7 +645,7 @@ static int macb_phy_init(struct macb_device *macb, const char *name)
/* First check for GMAC and that it is GiB capable */
if (gem_is_gigabit_capable(macb)) {
- lpa = macb_mdio_read(macb, MII_LPA);
+ lpa = macb_mdio_read(macb, MII_STAT1000);
if (lpa & (LPA_1000FULL | LPA_1000HALF | LPA_1000XFULL |
LPA_1000XHALF)) {
diff --git a/drivers/net/mdio_mux_i2creg.c b/drivers/net/mdio_mux_i2creg.c
new file mode 100644
index 0000000000..3e82898f46
--- /dev/null
+++ b/drivers/net/mdio_mux_i2creg.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Alex Marginean, NXP
+ */
+
+#include <dm.h>
+#include <errno.h>
+#include <miiphy.h>
+#include <i2c.h>
+
+/*
+ * This driver is used for MDIO muxes driven by writing to a register of an I2C
+ * chip. The board it was developed for uses a mux controlled by on-board FPGA
+ * which in turn is accessed as a chip over I2C.
+ */
+
+struct mdio_mux_i2creg_priv {
+ struct udevice *chip;
+ int reg;
+ int mask;
+};
+
+static int mdio_mux_i2creg_select(struct udevice *mux, int cur, int sel)
+{
+ struct mdio_mux_i2creg_priv *priv = dev_get_priv(mux);
+ u8 val, val_old;
+
+ /* if last selection didn't change we're good to go */
+ if (cur == sel)
+ return 0;
+
+ val_old = dm_i2c_reg_read(priv->chip, priv->reg);
+ val = (val_old & ~priv->mask) | (sel & priv->mask);
+ debug("%s: chip %s, reg %x, val %x => %x\n", __func__, priv->chip->name,
+ priv->reg, val_old, val);
+ dm_i2c_reg_write(priv->chip, priv->reg, val);
+
+ return 0;
+}
+
+static const struct mdio_mux_ops mdio_mux_i2creg_ops = {
+ .select = mdio_mux_i2creg_select,
+};
+
+static int mdio_mux_i2creg_probe(struct udevice *dev)
+{
+ struct mdio_mux_i2creg_priv *priv = dev_get_priv(dev);
+ ofnode chip_node, bus_node;
+ struct udevice *i2c_bus;
+ u32 reg_mask[2];
+ u32 chip_addr;
+ int err;
+
+ /* read the register addr/mask pair */
+ err = dev_read_u32_array(dev, "mux-reg-masks", reg_mask, 2);
+ if (err) {
+ debug("%s: error reading mux-reg-masks property\n", __func__);
+ return err;
+ }
+
+ /* parent should be an I2C chip, grandparent should be an I2C bus */
+ chip_node = ofnode_get_parent(dev->node);
+ bus_node = ofnode_get_parent(chip_node);
+
+ err = uclass_get_device_by_ofnode(UCLASS_I2C, bus_node, &i2c_bus);
+ if (err) {
+ debug("%s: can't find I2C bus for node %s\n", __func__,
+ ofnode_get_name(bus_node));
+ return err;
+ }
+
+ err = ofnode_read_u32(chip_node, "reg", &chip_addr);
+ if (err) {
+ debug("%s: can't read chip address in %s\n", __func__,
+ ofnode_get_name(chip_node));
+ return err;
+ }
+
+ err = i2c_get_chip(i2c_bus, (uint)chip_addr, 1, &priv->chip);
+ if (err) {
+ debug("%s: can't find i2c chip device for addr %x\n", __func__,
+ chip_addr);
+ return err;
+ }
+
+ priv->reg = (int)reg_mask[0];
+ priv->mask = (int)reg_mask[1];
+
+ debug("%s: chip %s, reg %x, mask %x\n", __func__, priv->chip->name,
+ priv->reg, priv->mask);
+
+ return 0;
+}
+
+static const struct udevice_id mdio_mux_i2creg_ids[] = {
+ { .compatible = "mdio-mux-i2creg" },
+ { }
+};
+
+U_BOOT_DRIVER(mdio_mux_i2creg) = {
+ .name = "mdio_mux_i2creg",
+ .id = UCLASS_MDIO_MUX,
+ .of_match = mdio_mux_i2creg_ids,
+ .probe = mdio_mux_i2creg_probe,
+ .ops = &mdio_mux_i2creg_ops,
+ .priv_auto_alloc_size = sizeof(struct mdio_mux_i2creg_priv),
+};
diff --git a/drivers/net/mdio_sandbox.c b/drivers/net/mdio_sandbox.c
index df053f5381..b731f60a98 100644
--- a/drivers/net/mdio_sandbox.c
+++ b/drivers/net/mdio_sandbox.c
@@ -27,7 +27,7 @@ static int mdio_sandbox_read(struct udevice *dev, int addr, int devad, int reg)
return -ENODEV;
if (devad != MDIO_DEVAD_NONE)
return -ENODEV;
- if (reg < 0 || reg > SANDBOX_PHY_REG_CNT)
+ if (reg < 0 || reg >= SANDBOX_PHY_REG_CNT)
return -ENODEV;
return priv->reg[reg];
@@ -45,7 +45,7 @@ static int mdio_sandbox_write(struct udevice *dev, int addr, int devad, int reg,
return -ENODEV;
if (devad != MDIO_DEVAD_NONE)
return -ENODEV;
- if (reg < 0 || reg > SANDBOX_PHY_REG_CNT)
+ if (reg < 0 || reg >= SANDBOX_PHY_REG_CNT)
return -ENODEV;
priv->reg[reg] = val;
diff --git a/drivers/net/mvmdio.c b/drivers/net/mvmdio.c
new file mode 100644
index 0000000000..ec6805e536
--- /dev/null
+++ b/drivers/net/mvmdio.c
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ * Author: Ken Ma<make@marvell.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <miiphy.h>
+#include <phy.h>
+#include <asm/io.h>
+#include <wait_bit.h>
+
+#define MVMDIO_SMI_DATA_SHIFT 0
+#define MVMDIO_SMI_PHY_ADDR_SHIFT 16
+#define MVMDIO_SMI_PHY_REG_SHIFT 21
+#define MVMDIO_SMI_READ_OPERATION BIT(26)
+#define MVMDIO_SMI_WRITE_OPERATION 0
+#define MVMDIO_SMI_READ_VALID BIT(27)
+#define MVMDIO_SMI_BUSY BIT(28)
+
+#define MVMDIO_XSMI_MGNT_REG 0x0
+#define MVMDIO_XSMI_PHYADDR_SHIFT 16
+#define MVMDIO_XSMI_DEVADDR_SHIFT 21
+#define MVMDIO_XSMI_WRITE_OPERATION (0x5 << 26)
+#define MVMDIO_XSMI_READ_OPERATION (0x7 << 26)
+#define MVMDIO_XSMI_READ_VALID BIT(29)
+#define MVMDIO_XSMI_BUSY BIT(30)
+#define MVMDIO_XSMI_ADDR_REG 0x8
+
+enum mvmdio_bus_type {
+ BUS_TYPE_SMI,
+ BUS_TYPE_XSMI
+};
+
+struct mvmdio_priv {
+ void *mdio_base;
+ enum mvmdio_bus_type type;
+};
+
+static int mvmdio_smi_read(struct udevice *dev, int addr,
+ int devad, int reg)
+{
+ struct mvmdio_priv *priv = dev_get_priv(dev);
+ u32 val;
+ int ret;
+
+ if (devad != MDIO_DEVAD_NONE)
+ return -EOPNOTSUPP;
+
+ ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_SMI_BUSY,
+ false, CONFIG_SYS_HZ, false);
+ if (ret < 0)
+ return ret;
+
+ writel(((addr << MVMDIO_SMI_PHY_ADDR_SHIFT) |
+ (reg << MVMDIO_SMI_PHY_REG_SHIFT) |
+ MVMDIO_SMI_READ_OPERATION),
+ priv->mdio_base);
+
+ ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_SMI_BUSY,
+ false, CONFIG_SYS_HZ, false);
+ if (ret < 0)
+ return ret;
+
+ val = readl(priv->mdio_base);
+ if (!(val & MVMDIO_SMI_READ_VALID)) {
+ pr_err("SMI bus read not valid\n");
+ return -ENODEV;
+ }
+
+ return val & GENMASK(15, 0);
+}
+
+static int mvmdio_smi_write(struct udevice *dev, int addr, int devad,
+ int reg, u16 value)
+{
+ struct mvmdio_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ if (devad != MDIO_DEVAD_NONE)
+ return -EOPNOTSUPP;
+
+ ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_SMI_BUSY,
+ false, CONFIG_SYS_HZ, false);
+ if (ret < 0)
+ return ret;
+
+ writel(((addr << MVMDIO_SMI_PHY_ADDR_SHIFT) |
+ (reg << MVMDIO_SMI_PHY_REG_SHIFT) |
+ MVMDIO_SMI_WRITE_OPERATION |
+ (value << MVMDIO_SMI_DATA_SHIFT)),
+ priv->mdio_base);
+
+ return 0;
+}
+
+static int mvmdio_xsmi_read(struct udevice *dev, int addr,
+ int devad, int reg)
+{
+ struct mvmdio_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ if (devad == MDIO_DEVAD_NONE)
+ return -EOPNOTSUPP;
+
+ ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_XSMI_BUSY,
+ false, CONFIG_SYS_HZ, false);
+ if (ret < 0)
+ return ret;
+
+ writel(reg & GENMASK(15, 0), priv->mdio_base + MVMDIO_XSMI_ADDR_REG);
+ writel(((addr << MVMDIO_XSMI_PHYADDR_SHIFT) |
+ (devad << MVMDIO_XSMI_DEVADDR_SHIFT) |
+ MVMDIO_XSMI_READ_OPERATION),
+ priv->mdio_base + MVMDIO_XSMI_MGNT_REG);
+
+ ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_XSMI_BUSY,
+ false, CONFIG_SYS_HZ, false);
+ if (ret < 0)
+ return ret;
+
+ if (!(readl(priv->mdio_base + MVMDIO_XSMI_MGNT_REG) &
+ MVMDIO_XSMI_READ_VALID)) {
+ pr_err("XSMI bus read not valid\n");
+ return -ENODEV;
+ }
+
+ return readl(priv->mdio_base + MVMDIO_XSMI_MGNT_REG) & GENMASK(15, 0);
+}
+
+static int mvmdio_xsmi_write(struct udevice *dev, int addr, int devad,
+ int reg, u16 value)
+{
+ struct mvmdio_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ if (devad == MDIO_DEVAD_NONE)
+ return -EOPNOTSUPP;
+
+ ret = wait_for_bit_le32(priv->mdio_base, MVMDIO_XSMI_BUSY,
+ false, CONFIG_SYS_HZ, false);
+ if (ret < 0)
+ return ret;
+
+ writel(reg & GENMASK(15, 0), priv->mdio_base + MVMDIO_XSMI_ADDR_REG);
+ writel(((addr << MVMDIO_XSMI_PHYADDR_SHIFT) |
+ (devad << MVMDIO_XSMI_DEVADDR_SHIFT) |
+ MVMDIO_XSMI_WRITE_OPERATION | value),
+ priv->mdio_base + MVMDIO_XSMI_MGNT_REG);
+
+ return 0;
+}
+
+static int mvmdio_read(struct udevice *dev, int addr, int devad, int reg)
+{
+ struct mvmdio_priv *priv = dev_get_priv(dev);
+ int err = -ENOTSUPP;
+
+ switch (priv->type) {
+ case BUS_TYPE_SMI:
+ err = mvmdio_smi_read(dev, addr, devad, reg);
+ break;
+ case BUS_TYPE_XSMI:
+ err = mvmdio_xsmi_read(dev, addr, devad, reg);
+ break;
+ }
+
+ return err;
+}
+
+static int mvmdio_write(struct udevice *dev, int addr, int devad, int reg,
+ u16 value)
+{
+ struct mvmdio_priv *priv = dev_get_priv(dev);
+ int err = -ENOTSUPP;
+
+ switch (priv->type) {
+ case BUS_TYPE_SMI:
+ err = mvmdio_smi_write(dev, addr, devad, reg, value);
+ break;
+ case BUS_TYPE_XSMI:
+ err = mvmdio_xsmi_write(dev, addr, devad, reg, value);
+ break;
+ }
+
+ return err;
+}
+
+/*
+ * Name the device, we use the device tree node name.
+ * This can be overwritten by MDIO class code if device-name property is
+ * present.
+ */
+static int mvmdio_bind(struct udevice *dev)
+{
+ if (ofnode_valid(dev->node))
+ device_set_name(dev, ofnode_get_name(dev->node));
+
+ return 0;
+}
+
+/* Get device base address and type, either C22 SMII or C45 XSMI */
+static int mvmdio_probe(struct udevice *dev)
+{
+ struct mvmdio_priv *priv = dev_get_priv(dev);
+
+ priv->mdio_base = (void *)dev_read_addr(dev);
+ priv->type = (enum mvmdio_bus_type)dev_get_driver_data(dev);
+
+ return 0;
+}
+
+static const struct mdio_ops mvmdio_ops = {
+ .read = mvmdio_read,
+ .write = mvmdio_write,
+};
+
+static const struct udevice_id mvmdio_ids[] = {
+ { .compatible = "marvell,orion-mdio", .data = BUS_TYPE_SMI },
+ { .compatible = "marvell,xmdio", .data = BUS_TYPE_XSMI },
+ { }
+};
+
+U_BOOT_DRIVER(mvmdio) = {
+ .name = "mvmdio",
+ .id = UCLASS_MDIO,
+ .of_match = mvmdio_ids,
+ .bind = mvmdio_bind,
+ .probe = mvmdio_probe,
+ .ops = &mvmdio_ops,
+ .priv_auto_alloc_size = sizeof(struct mvmdio_priv),
+};
+
diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c
index bcc6fe92a9..bd89725e77 100644
--- a/drivers/net/mvpp2.c
+++ b/drivers/net/mvpp2.c
@@ -5321,6 +5321,13 @@ static void mvpp2_stop(struct udevice *dev)
mvpp2_cleanup_txqs(port);
}
+static int mvpp2_write_hwaddr(struct udevice *dev)
+{
+ struct mvpp2_port *port = dev_get_priv(dev);
+
+ return mvpp2_prs_update_mac_da(port, port->dev_addr);
+}
+
static int mvpp22_smi_phy_addr_cfg(struct mvpp2_port *port)
{
writel(port->phyaddr, port->priv->iface_base +
@@ -5525,6 +5532,7 @@ static const struct eth_ops mvpp2_ops = {
.send = mvpp2_send,
.recv = mvpp2_recv,
.stop = mvpp2_stop,
+ .write_hwaddr = mvpp2_write_hwaddr
};
static struct driver mvpp2_driver = {
diff --git a/drivers/net/pfe_eth/pfe_mdio.c b/drivers/net/pfe_eth/pfe_mdio.c
index 2dde9e7ac8..62309670fa 100644
--- a/drivers/net/pfe_eth/pfe_mdio.c
+++ b/drivers/net/pfe_eth/pfe_mdio.c
@@ -110,7 +110,6 @@ static int pfe_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr,
u32 phy;
u32 reg_data;
int timeout = MDIO_TIMEOUT;
- int val;
if (dev_addr == MDIO_DEVAD_NONE) {
reg = ((reg_addr & EMAC_MII_DATA_RA_MASK) <<
@@ -150,7 +149,7 @@ static int pfe_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr,
debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phy_addr,
reg_addr, data);
- return val;
+ return 0;
}
static void pfe_configure_serdes(struct pfe_eth_dev *priv)
diff --git a/include/cache.h b/include/cache.h
index c6334ca27f..32f59fd8f7 100644
--- a/include/cache.h
+++ b/include/cache.h
@@ -22,6 +22,22 @@ struct cache_ops {
* @return 0 if OK, -ve on error
*/
int (*get_info)(struct udevice *dev, struct cache_info *info);
+
+ /**
+ * enable() - Enable cache
+ *
+ * @dev: Device to check (UCLASS_CACHE)
+ * @return 0 if OK, -ve on error
+ */
+ int (*enable)(struct udevice *dev);
+
+ /**
+ * disable() - Flush and disable cache
+ *
+ * @dev: Device to check (UCLASS_CACHE)
+ * @return 0 if OK, -ve on error
+ */
+ int (*disable)(struct udevice *dev);
};
#define cache_get_ops(dev) ((struct cache_ops *)(dev)->driver->ops)
@@ -35,4 +51,19 @@ struct cache_ops {
*/
int cache_get_info(struct udevice *dev, struct cache_info *info);
+/**
+ * cache_enable() - Enable cache
+ *
+ * @dev: Device to check (UCLASS_CACHE)
+ * @return 0 if OK, -ve on error
+ */
+int cache_enable(struct udevice *dev);
+
+/**
+ * cache_disable() - Flush and disable cache
+ *
+ * @dev: Device to check (UCLASS_CACHE)
+ * @return 0 if OK, -ve on error
+ */
+int cache_disable(struct udevice *dev);
#endif
diff --git a/include/configs/exynos5-common.h b/include/configs/exynos5-common.h
index 397bbf6d9d..e0a4d76d53 100644
--- a/include/configs/exynos5-common.h
+++ b/include/configs/exynos5-common.h
@@ -128,9 +128,9 @@
#define EXYNOS_IRAM_SECONDARY_BASE 0x02020018
#define BOOT_TARGET_DEVICES(func) \
+ func(MMC, mmc, 2) \
func(MMC, mmc, 1) \
func(MMC, mmc, 0) \
- func(MMC, mmc, 2) \
func(PXE, pxe, na) \
func(DHCP, dhcp, na)
diff --git a/include/configs/rpi.h b/include/configs/rpi.h
index 8473cecd94..77d2d5458a 100644
--- a/include/configs/rpi.h
+++ b/include/configs/rpi.h
@@ -55,6 +55,10 @@
#define CONFIG_SYS_MEMTEST_END 0x00200000
#define CONFIG_LOADADDR 0x00200000
+#ifdef CONFIG_ARM64
+#define CONFIG_SYS_BOOTM_LEN SZ_64M
+#endif
+
/* Devices */
/* GPIO */
#define CONFIG_BCM2835_GPIO
diff --git a/include/configs/sifive-fu540.h b/include/configs/sifive-fu540.h
index 858b7a7da1..736ceb1f48 100644
--- a/include/configs/sifive-fu540.h
+++ b/include/configs/sifive-fu540.h
@@ -26,6 +26,7 @@
#define CONFIG_ENV_SIZE SZ_128K
#define BOOT_TARGET_DEVICES(func) \
+ func(MMC, mmc, 0) \
func(DHCP, dhcp, na)
#include <config_distro_bootcmd.h>
diff --git a/include/efi_api.h b/include/efi_api.h
index 43778197af..cb895f31e5 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -483,7 +483,7 @@ struct efi_device_path_cdrom_path {
struct efi_device_path dp;
u32 boot_entry;
u64 partition_start;
- u64 partition_end;
+ u64 partition_size;
} __packed;
struct efi_device_path_file_path {
@@ -1281,6 +1281,8 @@ struct efi_simple_network {
struct efi_mac_address *dest_addr, u16 *protocol);
struct efi_event *wait_for_packet;
struct efi_simple_network_mode *mode;
+ /* private fields */
+ u32 int_status;
};
#define EFI_PXE_BASE_CODE_PROTOCOL_GUID \
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 5298ea7997..00eba8afa4 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -478,6 +478,10 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
/* Adds a range into the EFI memory map */
efi_status_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type,
bool overlap_only_ram);
+/* Adds a conventional range into the EFI memory map */
+efi_status_t efi_add_conventional_memory_map(u64 ram_start, u64 ram_end,
+ u64 ram_top);
+
/* Called by board init to initialize the EFI drivers */
efi_status_t efi_driver_init(void);
/* Called by board init to initialize the EFI memory map */
diff --git a/include/env_callback.h b/include/env_callback.h
index 982c07854d..74da20eec3 100644
--- a/include/env_callback.h
+++ b/include/env_callback.h
@@ -42,7 +42,7 @@
#define DNS_CALLBACK
#endif
-#ifdef CONFIG_CMD_NET
+#ifdef CONFIG_NET
#define NET_CALLBACKS \
"bootfile:bootfile," \
"ipaddr:ipaddr," \
diff --git a/include/env_flags.h b/include/env_flags.h
index e5380f2948..725841a891 100644
--- a/include/env_flags.h
+++ b/include/env_flags.h
@@ -36,7 +36,7 @@ enum env_flags_varaccess {
#define CONFIG_ENV_FLAGS_LIST_STATIC ""
#endif
-#ifdef CONFIG_CMD_NET
+#ifdef CONFIG_NET
#ifdef CONFIG_REGEX
#define ETHADDR_WILDCARD "\\d*"
#else
diff --git a/include/net.h b/include/net.h
index a54d5eeac5..75a16e4c8f 100644
--- a/include/net.h
+++ b/include/net.h
@@ -816,7 +816,7 @@ static inline int is_valid_ethaddr(const u8 *addr)
static inline void net_random_ethaddr(uchar *addr)
{
int i;
- unsigned int seed = get_timer(0);
+ unsigned int seed = get_ticks();
for (i = 0; i < 6; i++)
addr[i] = rand_r(&seed);
diff --git a/include/net/pcap.h b/include/net/pcap.h
new file mode 100644
index 0000000000..512ba982f1
--- /dev/null
+++ b/include/net/pcap.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2019
+ * Ramon Fried <rfried.dev@gmail.com>
+ */
+
+/**
+ * pcap_init() - Initialize PCAP memory buffer
+ *
+ * @paddr physicaly memory address to store buffer
+ * @size maximum size of capture file in memory
+ *
+ * @return 0 on success, -ERROR on error
+ */
+int pcap_init(phys_addr_t paddr, unsigned long size);
+
+/**
+ * pcap_start_stop() - start / stop pcap capture
+ *
+ * @start if true, start capture if false stop capture
+ *
+ * @return 0 on success, -ERROR on error
+ */
+int pcap_start_stop(bool start);
+
+/**
+ * pcap_clear() - clear pcap capture buffer and statistics
+ *
+ * @return 0 on success, -ERROR on error
+ */
+int pcap_clear(void);
+
+/**
+ * pcap_print_status() - print status of pcap capture
+ *
+ * @return 0 on success, -ERROR on error
+ */
+int pcap_print_status(void);
+
+/**
+ * pcap_active() - check if pcap is enabled
+ *
+ * @return TRUE if active, FALSE if not.
+ */
+bool pcap_active(void);
+
+/**
+ * pcap_post() - Post a packet to PCAP file
+ *
+ * @packet: packet to post
+ * @len: packet length in bytes
+ * @outgoing packet direction (outgoing/incoming)
+ * @return 0 on success, -ERROR on error
+ */
+int pcap_post(const void *packet, size_t len, bool outgoing);
diff --git a/include/netdev.h b/include/netdev.h
index a40c4adaad..68a3fceab6 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -10,6 +10,7 @@
#ifndef _NETDEV_H_
#define _NETDEV_H_
+#include <phy_interface.h>
/*
* Board and CPU-specific initialization functions
@@ -21,6 +22,8 @@
*/
int board_eth_init(bd_t *bis);
+int board_interface_eth_init(struct udevice *dev,
+ phy_interface_t interface_type);
int cpu_eth_init(bd_t *bis);
/* Driver initialization prototypes */
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index d4765afb98..a55e4b33ec 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -156,13 +156,14 @@ static efi_status_t EFIAPI efi_cout_output_string(
* Update the cursor position.
*
* The UEFI spec provides advance rules for U+0000, U+0008, U+000A,
- * and U000D. All other characters, including control characters
- * U+0007 (BEL) and U+0009 (TAB), have to increase the column by one.
+ * and U000D. All other control characters are ignored. Any non-control
+ * character increase the column by one.
*/
for (p = string; *p; ++p) {
switch (*p) {
case '\b': /* U+0008, backspace */
- con->cursor_column = max(0, con->cursor_column - 1);
+ if (con->cursor_column)
+ con->cursor_column--;
break;
case '\n': /* U+000A, newline */
con->cursor_column = 0;
@@ -178,14 +179,21 @@ static efi_status_t EFIAPI efi_cout_output_string(
*/
break;
default:
- con->cursor_column++;
+ /* Exclude control codes */
+ if (*p > 0x1f)
+ con->cursor_column++;
break;
}
if (con->cursor_column >= mode->columns) {
con->cursor_column = 0;
con->cursor_row++;
}
- con->cursor_row = min(con->cursor_row, (s32)mode->rows - 1);
+ /*
+ * When we exceed the row count the terminal will scroll up one
+ * line. We have to adjust the cursor position.
+ */
+ if (con->cursor_row >= mode->rows && con->cursor_row)
+ con->cursor_row--;
}
out:
@@ -211,9 +219,9 @@ static bool cout_mode_matches(struct cout_mode *mode, int rows, int cols)
/**
* query_console_serial() - query console size
*
- * @rows pointer to return number of rows
- * @columns pointer to return number of columns
- * Returns 0 on success
+ * @rows: pointer to return number of rows
+ * @cols: pointer to return number of columns
+ * Returns: 0 on success
*/
static int query_console_serial(int *rows, int *cols)
{
@@ -371,6 +379,10 @@ static efi_status_t EFIAPI efi_cout_set_mode(
if (mode_number >= efi_con_mode.max_mode)
return EFI_EXIT(EFI_UNSUPPORTED);
+
+ if (!efi_cout_modes[mode_number].present)
+ return EFI_EXIT(EFI_UNSUPPORTED);
+
efi_con_mode.mode = mode_number;
EFI_CALL(efi_cout_clear_screen(this));
@@ -452,7 +464,7 @@ struct efi_simple_text_output_protocol efi_con_out = {
* struct efi_cin_notify_function - registered console input notify function
*
* @link: link to list
- * @data: key to notify
+ * @key: key to notify
* @function: function to call
*/
struct efi_cin_notify_function {
@@ -470,6 +482,7 @@ static LIST_HEAD(cin_notify_functions);
* set_shift_mask() - set shift mask
*
* @mod: Xterm shift mask
+ * @key_state: receives the state of the shift, alt, control, and logo keys
*/
void set_shift_mask(int mod, struct efi_key_state *key_state)
{
@@ -492,7 +505,7 @@ void set_shift_mask(int mod, struct efi_key_state *key_state)
*
* This gets called when we have already parsed CSI.
*
- * @modifiers: bit mask (shift, alt, ctrl)
+ * @key_state: receives the state of the shift, alt, control, and logo keys
* @return: the unmodified code
*/
static int analyze_modifiers(struct efi_key_state *key_state)
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index eeeb806836..ea39f13b73 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -665,7 +665,7 @@ static void *dp_part_node(void *buf, struct blk_desc *desc, int part)
cddp->dp.sub_type = DEVICE_PATH_SUB_TYPE_CDROM_PATH;
cddp->dp.length = sizeof(*cddp);
cddp->partition_start = info.start;
- cddp->partition_end = info.size;
+ cddp->partition_size = info.size;
buf = &cddp[1];
} else {
diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c
index 96fd08971b..b20b7c097c 100644
--- a/lib/efi_loader/efi_device_path_to_text.c
+++ b/lib/efi_loader/efi_device_path_to_text.c
@@ -60,9 +60,18 @@ static char *dp_hardware(char *s, struct efi_device_path *dp)
break;
}
case DEVICE_PATH_SUB_TYPE_VENDOR: {
+ int i, n;
struct efi_device_path_vendor *vdp =
(struct efi_device_path_vendor *)dp;
- s += sprintf(s, "VenHw(%pUl)", &vdp->guid);
+
+ s += sprintf(s, "VenHw(%pUl", &vdp->guid);
+ n = (int)vdp->dp.length - sizeof(struct efi_device_path_vendor);
+ if (n > 0) {
+ s += sprintf(s, ",");
+ for (i = 0; i < n; ++i)
+ s += sprintf(s, "%02x", vdp->vendor_data[i]);
+ }
+ s += sprintf(s, ")");
break;
}
default:
@@ -115,17 +124,16 @@ static char *dp_msging(char *s, struct efi_device_path *dp)
break;
}
case DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR: {
+ int i, n = sizeof(struct efi_mac_addr);
struct efi_device_path_mac_addr *mdp =
(struct efi_device_path_mac_addr *)dp;
- if (mdp->if_type != 0 && mdp->if_type != 1)
- break;
-
- s += sprintf(s, "MAC(%02x%02x%02x%02x%02x%02x,0x%1x)",
- mdp->mac.addr[0], mdp->mac.addr[1],
- mdp->mac.addr[2], mdp->mac.addr[3],
- mdp->mac.addr[4], mdp->mac.addr[5],
- mdp->if_type);
+ if (mdp->if_type <= 1)
+ n = 6;
+ s += sprintf(s, "MAC(");
+ for (i = 0; i < n; ++i)
+ s += sprintf(s, "%02x", mdp->mac.addr[i]);
+ s += sprintf(s, ",%u)", mdp->if_type);
break;
}
@@ -133,7 +141,7 @@ static char *dp_msging(char *s, struct efi_device_path *dp)
struct efi_device_path_usb_class *ucdp =
(struct efi_device_path_usb_class *)dp;
- s += sprintf(s, "USBClass(%x,%x,%x,%x,%x)",
+ s += sprintf(s, "UsbClass(0x%x,0x%x,0x%x,0x%x,0x%x)",
ucdp->vendor_id, ucdp->product_id,
ucdp->device_class, ucdp->device_subclass,
ucdp->device_protocol);
@@ -206,7 +214,8 @@ static char *dp_media(char *s, struct efi_device_path *dp)
case DEVICE_PATH_SUB_TYPE_CDROM_PATH: {
struct efi_device_path_cdrom_path *cddp =
(struct efi_device_path_cdrom_path *)dp;
- s += sprintf(s, "CDROM(0x%x)", cddp->boot_entry);
+ s += sprintf(s, "CDROM(%u,0x%llx,0x%llx)", cddp->boot_entry,
+ cddp->partition_start, cddp->partition_size);
break;
}
case DEVICE_PATH_SUB_TYPE_FILE_PATH: {
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 7a6b06821a..9007a5f77f 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -41,11 +41,26 @@ struct efi_disk_obj {
struct blk_desc *desc;
};
+/**
+ * efi_disk_reset() - reset block device
+ *
+ * This function implements the Reset service of the EFI_BLOCK_IO_PROTOCOL.
+ *
+ * As U-Boot's block devices do not have a reset function simply return
+ * EFI_SUCCESS.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ *
+ * @this: pointer to the BLOCK_IO_PROTOCOL
+ * @extended_verification: extended verification
+ * Return: status code
+ */
static efi_status_t EFIAPI efi_disk_reset(struct efi_block_io *this,
char extended_verification)
{
EFI_ENTRY("%p, %x", this, extended_verification);
- return EFI_EXIT(EFI_DEVICE_ERROR);
+ return EFI_EXIT(EFI_SUCCESS);
}
enum efi_disk_direction {
@@ -69,12 +84,12 @@ static efi_status_t efi_disk_rw_blocks(struct efi_block_io *this,
blocks = buffer_size / blksz;
lba += diskobj->offset;
- debug("EFI: %s:%d blocks=%x lba=%llx blksz=%x dir=%d\n", __func__,
- __LINE__, blocks, lba, blksz, direction);
+ EFI_PRINT("blocks=%x lba=%llx blksz=%x dir=%d\n",
+ blocks, lba, blksz, direction);
/* We only support full block access */
if (buffer_size & (blksz - 1))
- return EFI_DEVICE_ERROR;
+ return EFI_BAD_BUFFER_SIZE;
if (direction == EFI_DISK_READ)
n = blk_dread(desc, lba, blocks, buffer);
@@ -84,7 +99,7 @@ static efi_status_t efi_disk_rw_blocks(struct efi_block_io *this,
/* We don't do interrupts, so check for timers cooperatively */
efi_timer_check();
- debug("EFI: %s:%d n=%lx blocks=%x\n", __func__, __LINE__, n, blocks);
+ EFI_PRINT("n=%lx blocks=%x\n", n, blocks);
if (n != blocks)
return EFI_DEVICE_ERROR;
@@ -99,6 +114,20 @@ static efi_status_t EFIAPI efi_disk_read_blocks(struct efi_block_io *this,
void *real_buffer = buffer;
efi_status_t r;
+ if (!this)
+ return EFI_INVALID_PARAMETER;
+ /* TODO: check for media changes */
+ if (media_id != this->media->media_id)
+ return EFI_MEDIA_CHANGED;
+ if (!this->media->media_present)
+ return EFI_NO_MEDIA;
+ /* media->io_align is a power of 2 */
+ if ((uintptr_t)buffer & (this->media->io_align - 1))
+ return EFI_INVALID_PARAMETER;
+ if (lba * this->media->block_size + buffer_size >
+ this->media->last_block * this->media->block_size)
+ return EFI_INVALID_PARAMETER;
+
#ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
if (buffer_size > EFI_LOADER_BOUNCE_BUFFER_SIZE) {
r = efi_disk_read_blocks(this, media_id, lba,
@@ -134,6 +163,22 @@ static efi_status_t EFIAPI efi_disk_write_blocks(struct efi_block_io *this,
void *real_buffer = buffer;
efi_status_t r;
+ if (!this)
+ return EFI_INVALID_PARAMETER;
+ if (this->media->read_only)
+ return EFI_WRITE_PROTECTED;
+ /* TODO: check for media changes */
+ if (media_id != this->media->media_id)
+ return EFI_MEDIA_CHANGED;
+ if (!this->media->media_present)
+ return EFI_NO_MEDIA;
+ /* media->io_align is a power of 2 */
+ if ((uintptr_t)buffer & (this->media->io_align - 1))
+ return EFI_INVALID_PARAMETER;
+ if (lba * this->media->block_size + buffer_size >
+ this->media->last_block * this->media->block_size)
+ return EFI_INVALID_PARAMETER;
+
#ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
if (buffer_size > EFI_LOADER_BOUNCE_BUFFER_SIZE) {
r = efi_disk_write_blocks(this, media_id, lba,
@@ -288,6 +333,11 @@ static efi_status_t efi_disk_add_dev(
/* Fill in EFI IO Media info (for read/write callbacks) */
diskobj->media.removable_media = desc->removable;
diskobj->media.media_present = 1;
+ /*
+ * MediaID is just an arbitrary counter.
+ * We have to change it if the medium is removed or changed.
+ */
+ diskobj->media.media_id = 1;
diskobj->media.block_size = desc->blksz;
diskobj->media.io_align = desc->blksz;
diskobj->media.last_block = desc->lba - offset;
diff --git a/lib/efi_loader/efi_gop.c b/lib/efi_loader/efi_gop.c
index cad509bfea..1511e3bdb4 100644
--- a/lib/efi_loader/efi_gop.c
+++ b/lib/efi_loader/efi_gop.c
@@ -319,7 +319,7 @@ static efi_status_t gop_blt_vid_to_buf(struct efi_gop *this,
* details.
*
* @this: the graphical output protocol
- * @model_number: the mode to be set
+ * @mode_number: the mode to be set
* Return: status code
*/
static efi_status_t EFIAPI gop_set_mode(struct efi_gop *this, u32 mode_number)
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index b5775e0399..83cbc9154f 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -655,6 +655,54 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
return EFI_SUCCESS;
}
+/**
+ * efi_add_conventional_memory_map() - add a RAM memory area to the map
+ *
+ * @ram_start: start address of a RAM memory area
+ * @ram_end: end address of a RAM memory area
+ * @ram_top: max address to be used as conventional memory
+ * Return: status code
+ */
+efi_status_t efi_add_conventional_memory_map(u64 ram_start, u64 ram_end,
+ u64 ram_top)
+{
+ u64 pages;
+
+ /* Remove partial pages */
+ ram_end &= ~EFI_PAGE_MASK;
+ ram_start = (ram_start + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
+
+ if (ram_end <= ram_start) {
+ /* Invalid mapping */
+ return EFI_INVALID_PARAMETER;
+ }
+
+ pages = (ram_end - ram_start) >> EFI_PAGE_SHIFT;
+
+ efi_add_memory_map(ram_start, pages,
+ EFI_CONVENTIONAL_MEMORY, false);
+
+ /*
+ * Boards may indicate to the U-Boot memory core that they
+ * can not support memory above ram_top. Let's honor this
+ * in the efi_loader subsystem too by declaring any memory
+ * above ram_top as "already occupied by firmware".
+ */
+ if (ram_top < ram_start) {
+ /* ram_top is before this region, reserve all */
+ efi_add_memory_map(ram_start, pages,
+ EFI_BOOT_SERVICES_DATA, true);
+ } else if ((ram_top >= ram_start) && (ram_top < ram_end)) {
+ /* ram_top is inside this region, reserve parts */
+ pages = (ram_end - ram_top) >> EFI_PAGE_SHIFT;
+
+ efi_add_memory_map(ram_top, pages,
+ EFI_BOOT_SERVICES_DATA, true);
+ }
+
+ return EFI_SUCCESS;
+}
+
__weak void efi_add_known_memory(void)
{
u64 ram_top = board_get_usable_ram_top(0) & ~EFI_PAGE_MASK;
@@ -672,42 +720,12 @@ __weak void efi_add_known_memory(void)
/* Add RAM */
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
- u64 ram_end, ram_start, pages;
+ u64 ram_end, ram_start;
ram_start = (uintptr_t)map_sysmem(gd->bd->bi_dram[i].start, 0);
ram_end = ram_start + gd->bd->bi_dram[i].size;
- /* Remove partial pages */
- ram_end &= ~EFI_PAGE_MASK;
- ram_start = (ram_start + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
-
- if (ram_end <= ram_start) {
- /* Invalid mapping, keep going. */
- continue;
- }
-
- pages = (ram_end - ram_start) >> EFI_PAGE_SHIFT;
-
- efi_add_memory_map(ram_start, pages,
- EFI_CONVENTIONAL_MEMORY, false);
-
- /*
- * Boards may indicate to the U-Boot memory core that they
- * can not support memory above ram_top. Let's honor this
- * in the efi_loader subsystem too by declaring any memory
- * above ram_top as "already occupied by firmware".
- */
- if (ram_top < ram_start) {
- /* ram_top is before this region, reserve all */
- efi_add_memory_map(ram_start, pages,
- EFI_BOOT_SERVICES_DATA, true);
- } else if ((ram_top >= ram_start) && (ram_top < ram_end)) {
- /* ram_top is inside this region, reserve parts */
- pages = (ram_end - ram_top) >> EFI_PAGE_SHIFT;
-
- efi_add_memory_map(ram_top, pages,
- EFI_BOOT_SERVICES_DATA, true);
- }
+ efi_add_conventional_memory_map(ram_start, ram_end, ram_top);
}
}
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
index 825e064f9a..82d2595847 100644
--- a/lib/efi_loader/efi_net.c
+++ b/lib/efi_loader/efi_net.c
@@ -1,8 +1,18 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * EFI application network access support
+ * Simple network protocol
+ * PXE base code protocol
*
- * Copyright (c) 2016 Alexander Graf
+ * Copyright (c) 2016 Alexander Graf
+ *
+ * The simple network protocol has the following statuses and services
+ * to move between them:
+ *
+ * Start(): EfiSimpleNetworkStopped -> EfiSimpleNetworkStarted
+ * Initialize(): EfiSimpleNetworkStarted -> EfiSimpleNetworkInitialized
+ * Shutdown(): EfiSimpleNetworkInitialized -> EfiSimpleNetworkStarted
+ * Stop(): EfiSimpleNetworkStarted -> EfiSimpleNetworkStopped
+ * Reset(): EfiSimpleNetworkInitialized -> EfiSimpleNetworkInitialized
*/
#include <common.h>
@@ -66,10 +76,13 @@ static efi_status_t EFIAPI efi_net_start(struct efi_simple_network *this)
goto out;
}
- if (this->mode->state != EFI_NETWORK_STOPPED)
+ if (this->mode->state != EFI_NETWORK_STOPPED) {
ret = EFI_ALREADY_STARTED;
- else
+ } else {
+ this->int_status = 0;
+ wait_for_packet->is_signaled = false;
this->mode->state = EFI_NETWORK_STARTED;
+ }
out:
return EFI_EXIT(ret);
}
@@ -96,10 +109,13 @@ static efi_status_t EFIAPI efi_net_stop(struct efi_simple_network *this)
goto out;
}
- if (this->mode->state == EFI_NETWORK_STOPPED)
+ if (this->mode->state == EFI_NETWORK_STOPPED) {
ret = EFI_NOT_STARTED;
- else
+ } else {
+ /* Disable hardware and put it into the reset state */
+ eth_halt();
this->mode->state = EFI_NETWORK_STOPPED;
+ }
out:
return EFI_EXIT(ret);
}
@@ -130,6 +146,15 @@ static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this,
goto out;
}
+ switch (this->mode->state) {
+ case EFI_NETWORK_INITIALIZED:
+ case EFI_NETWORK_STARTED:
+ break;
+ default:
+ r = EFI_NOT_STARTED;
+ goto out;
+ }
+
/* Setup packet buffers */
net_init();
/* Disable hardware and put it into the reset state */
@@ -144,6 +169,8 @@ static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this,
r = EFI_DEVICE_ERROR;
goto out;
} else {
+ this->int_status = 0;
+ wait_for_packet->is_signaled = false;
this->mode->state = EFI_NETWORK_INITIALIZED;
}
out:
@@ -164,9 +191,31 @@ out:
static efi_status_t EFIAPI efi_net_reset(struct efi_simple_network *this,
int extended_verification)
{
+ efi_status_t ret;
+
EFI_ENTRY("%p, %x", this, extended_verification);
- return EFI_EXIT(EFI_CALL(efi_net_initialize(this, 0, 0)));
+ /* Check parameters */
+ if (!this) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ switch (this->mode->state) {
+ case EFI_NETWORK_INITIALIZED:
+ break;
+ case EFI_NETWORK_STOPPED:
+ ret = EFI_NOT_STARTED;
+ goto out;
+ default:
+ ret = EFI_DEVICE_ERROR;
+ goto out;
+ }
+
+ this->mode->state = EFI_NETWORK_STARTED;
+ ret = EFI_CALL(efi_net_initialize(this, 0, 0));
+out:
+ return EFI_EXIT(ret);
}
/*
@@ -191,8 +240,21 @@ static efi_status_t EFIAPI efi_net_shutdown(struct efi_simple_network *this)
goto out;
}
+ switch (this->mode->state) {
+ case EFI_NETWORK_INITIALIZED:
+ break;
+ case EFI_NETWORK_STOPPED:
+ ret = EFI_NOT_STARTED;
+ goto out;
+ default:
+ ret = EFI_DEVICE_ERROR;
+ goto out;
+ }
+
eth_halt();
- this->mode->state = EFI_NETWORK_STOPPED;
+ this->int_status = 0;
+ wait_for_packet->is_signaled = false;
+ this->mode->state = EFI_NETWORK_STARTED;
out:
return EFI_EXIT(ret);
@@ -270,7 +332,7 @@ static efi_status_t EFIAPI efi_net_statistics(struct efi_simple_network *this,
/*
* efi_net_mcastiptomac() - translate multicast IP address to MAC address
*
- * This function implements the Statistics service of the
+ * This function implements the MCastIPtoMAC service of the
* EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
* (UEFI) specification for details.
*
@@ -285,9 +347,49 @@ static efi_status_t EFIAPI efi_net_mcastiptomac(struct efi_simple_network *this,
struct efi_ip_address *ip,
struct efi_mac_address *mac)
{
+ efi_status_t ret = EFI_SUCCESS;
+
EFI_ENTRY("%p, %x, %p, %p", this, ipv6, ip, mac);
- return EFI_EXIT(EFI_INVALID_PARAMETER);
+ if (!this || !ip || !mac) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ if (ipv6) {
+ ret = EFI_UNSUPPORTED;
+ goto out;
+ }
+
+ /* Multi-cast addresses are in the range 224.0.0.0 - 239.255.255.255 */
+ if ((ip->ip_addr[0] & 0xf0) != 0xe0) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ };
+
+ switch (this->mode->state) {
+ case EFI_NETWORK_INITIALIZED:
+ case EFI_NETWORK_STARTED:
+ break;
+ default:
+ ret = EFI_NOT_STARTED;
+ goto out;
+ }
+
+ memset(mac, 0, sizeof(struct efi_mac_address));
+
+ /*
+ * Copy lower 23 bits of IPv4 multi-cast address
+ * RFC 1112, RFC 7042 2.1.1.
+ */
+ mac->mac_addr[0] = 0x01;
+ mac->mac_addr[1] = 0x00;
+ mac->mac_addr[2] = 0x5E;
+ mac->mac_addr[3] = ip->ip_addr[1] & 0x7F;
+ mac->mac_addr[4] = ip->ip_addr[2];
+ mac->mac_addr[5] = ip->ip_addr[3];
+out:
+ return EFI_EXIT(ret);
}
/**
@@ -297,7 +399,7 @@ static efi_status_t EFIAPI efi_net_mcastiptomac(struct efi_simple_network *this,
* Protocol. See the UEFI spec for details.
*
* @this: the instance of the Simple Network Protocol
- * @readwrite: true for read, false for write
+ * @read_write: true for read, false for write
* @offset: offset in NVRAM
* @buffer_size: size of buffer
* @buffer: buffer
@@ -350,10 +452,8 @@ static efi_status_t EFIAPI efi_net_get_status(struct efi_simple_network *this,
}
if (int_status) {
- /* We send packets synchronously, so nothing is outstanding */
- *int_status = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
- if (new_rx_packet)
- *int_status |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
+ *int_status = this->int_status;
+ this->int_status = 0;
}
if (txbuf)
*txbuf = new_tx_packet;
@@ -404,15 +504,33 @@ static efi_status_t EFIAPI efi_net_transmit
goto out;
}
- if (header_size) {
- /*
- * TODO: We would need to create the header
- * if header_size != 0
- */
- ret = EFI_UNSUPPORTED;
+ /* At least the IP header has to fit into the buffer */
+ if (buffer_size < this->mode->media_header_size) {
+ ret = EFI_BUFFER_TOO_SMALL;
goto out;
}
+ /*
+ * TODO:
+ * Support VLANs. Use net_set_ether() for copying the header. Use a
+ * U_BOOT_ENV_CALLBACK to update the media header size.
+ */
+ if (header_size) {
+ struct ethernet_hdr *header = buffer;
+
+ if (!dest_addr || !protocol ||
+ header_size != this->mode->media_header_size) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+ if (!src_addr)
+ src_addr = &this->mode->current_address;
+
+ memcpy(header->et_dest, dest_addr, ARP_HLEN);
+ memcpy(header->et_src, src_addr, ARP_HLEN);
+ header->et_protlen = htons(*protocol);
+ }
+
switch (this->mode->state) {
case EFI_NETWORK_STOPPED:
ret = EFI_NOT_STARTED;
@@ -429,7 +547,7 @@ static efi_status_t EFIAPI efi_net_transmit
net_send_packet(transmit_buffer, buffer_size);
new_tx_packet = buffer;
-
+ this->int_status |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
out:
return EFI_EXIT(ret);
}
@@ -487,12 +605,6 @@ static efi_status_t EFIAPI efi_net_receive
ret = EFI_NOT_READY;
goto out;
}
- /* Check that we at least received an Ethernet header */
- if (net_rx_packet_len < sizeof(struct ethernet_hdr)) {
- new_rx_packet = false;
- ret = EFI_NOT_READY;
- goto out;
- }
/* Fill export parameters */
eth_hdr = (struct ethernet_hdr *)net_rx_packet;
protlen = ntohs(eth_hdr->et_protlen);
@@ -517,7 +629,8 @@ static efi_status_t EFIAPI efi_net_receive
/* Copy packet */
memcpy(buffer, net_rx_packet, net_rx_packet_len);
*buffer_size = net_rx_packet_len;
- new_rx_packet = false;
+ new_rx_packet = 0;
+ this->int_status &= ~EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
out:
return EFI_EXIT(ret);
}
@@ -526,6 +639,9 @@ out:
* efi_net_set_dhcp_ack() - take note of a selected DHCP IP address
*
* This function is called by dhcp_handler().
+ *
+ * @pkt: packet received by dhcp_handler()
+ * @len: length of the packet received
*/
void efi_net_set_dhcp_ack(void *pkt, int len)
{
@@ -548,7 +664,6 @@ void efi_net_set_dhcp_ack(void *pkt, int len)
static void efi_net_push(void *pkt, int len)
{
new_rx_packet = true;
- wait_for_packet->is_signaled = true;
}
/**
@@ -556,8 +671,8 @@ static void efi_net_push(void *pkt, int len)
*
* This notification function is called in every timer cycle.
*
- * @event the event for which this notification function is registered
- * @context event context - not used in this function
+ * @event: the event for which this notification function is registered
+ * @context: event context - not used in this function
*/
static void EFIAPI efi_network_timer_notify(struct efi_event *event,
void *context)
@@ -577,6 +692,17 @@ static void EFIAPI efi_network_timer_notify(struct efi_event *event,
push_packet = efi_net_push;
eth_rx();
push_packet = NULL;
+ if (new_rx_packet) {
+ /* Check that we at least received an Ethernet header */
+ if (net_rx_packet_len >=
+ sizeof(struct ethernet_hdr)) {
+ this->int_status |=
+ EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
+ wait_for_packet->is_signaled = true;
+ } else {
+ new_rx_packet = 0;
+ }
+ }
}
out:
EFI_EXIT(EFI_SUCCESS);
@@ -751,9 +877,10 @@ efi_status_t efi_net_register(void)
netobj->net.transmit = efi_net_transmit;
netobj->net.receive = efi_net_receive;
netobj->net.mode = &netobj->net_mode;
- netobj->net_mode.state = EFI_NETWORK_STARTED;
+ netobj->net_mode.state = EFI_NETWORK_STOPPED;
memcpy(netobj->net_mode.current_address.mac_addr, eth_get_ethaddr(), 6);
netobj->net_mode.hwaddr_size = ARP_HLEN;
+ netobj->net_mode.media_header_size = ETHER_HDR_SIZE;
netobj->net_mode.max_packet_size = PKTSIZE;
netobj->net_mode.if_type = ARP_ETHER;
diff --git a/lib/efi_selftest/efi_selftest_snp.c b/lib/efi_selftest/efi_selftest_snp.c
index 4c26619001..9797ecaf42 100644
--- a/lib/efi_selftest/efi_selftest_snp.c
+++ b/lib/efi_selftest/efi_selftest_snp.c
@@ -228,6 +228,26 @@ static int setup(const efi_handle_t handle,
efi_st_error("WaitForPacket event missing\n");
return EFI_ST_FAILURE;
}
+ if (net->mode->state == EFI_NETWORK_INITIALIZED) {
+ /*
+ * Shut down network adapter.
+ */
+ ret = net->shutdown(net);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to shut down network adapter\n");
+ return EFI_ST_FAILURE;
+ }
+ }
+ if (net->mode->state == EFI_NETWORK_STARTED) {
+ /*
+ * Stop network adapter.
+ */
+ ret = net->stop(net);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to stop network adapter\n");
+ return EFI_ST_FAILURE;
+ }
+ }
/*
* Start network adapter.
*/
@@ -236,6 +256,10 @@ static int setup(const efi_handle_t handle,
efi_st_error("Failed to start network adapter\n");
return EFI_ST_FAILURE;
}
+ if (net->mode->state != EFI_NETWORK_STARTED) {
+ efi_st_error("Failed to start network adapter\n");
+ return EFI_ST_FAILURE;
+ }
/*
* Initialize network adapter.
*/
@@ -244,6 +268,10 @@ static int setup(const efi_handle_t handle,
efi_st_error("Failed to initialize network adapter\n");
return EFI_ST_FAILURE;
}
+ if (net->mode->state != EFI_NETWORK_INITIALIZED) {
+ efi_st_error("Failed to initialize network adapter\n");
+ return EFI_ST_FAILURE;
+ }
return EFI_ST_SUCCESS;
}
@@ -268,6 +296,7 @@ static int execute(void)
struct efi_mac_address destaddr;
size_t buffer_size;
u8 *addr;
+
/*
* The timeout is to occur after 10 s.
*/
@@ -298,6 +327,8 @@ static int execute(void)
events[0] = timer;
events[1] = net->wait_for_packet;
for (;;) {
+ u32 int_status;
+
/*
* Wait for packet to be received or timer event.
*/
@@ -323,8 +354,17 @@ static int execute(void)
* Receive packet
*/
buffer_size = sizeof(buffer);
- net->receive(net, NULL, &buffer_size, &buffer,
- &srcaddr, &destaddr, NULL);
+ ret = net->get_status(net, &int_status, NULL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to get status");
+ return EFI_ST_FAILURE;
+ }
+ if (!(int_status & EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT)) {
+ efi_st_error("RX interrupt not set");
+ return EFI_ST_FAILURE;
+ }
+ ret = net->receive(net, NULL, &buffer_size, &buffer,
+ &srcaddr, &destaddr, NULL);
if (ret != EFI_SUCCESS) {
efi_st_error("Failed to receive packet");
return EFI_ST_FAILURE;
@@ -400,21 +440,29 @@ static int teardown(void)
}
if (net) {
/*
- * Stop network adapter.
+ * Shut down network adapter.
*/
- ret = net->stop(net);
+ ret = net->shutdown(net);
if (ret != EFI_SUCCESS) {
- efi_st_error("Failed to stop network adapter\n");
+ efi_st_error("Failed to shut down network adapter\n");
exit_status = EFI_ST_FAILURE;
}
+ if (net->mode->state != EFI_NETWORK_STARTED) {
+ efi_st_error("Failed to shutdown network adapter\n");
+ return EFI_ST_FAILURE;
+ }
/*
- * Shut down network adapter.
+ * Stop network adapter.
*/
- ret = net->shutdown(net);
+ ret = net->stop(net);
if (ret != EFI_SUCCESS) {
- efi_st_error("Failed to shut down network adapter\n");
+ efi_st_error("Failed to stop network adapter\n");
exit_status = EFI_ST_FAILURE;
}
+ if (net->mode->state != EFI_NETWORK_STOPPED) {
+ efi_st_error("Failed to stop network adapter\n");
+ return EFI_ST_FAILURE;
+ }
}
return exit_status;
diff --git a/net/Makefile b/net/Makefile
index 826544f05f..2a700c8401 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_CMD_LINK_LOCAL) += link_local.o
obj-$(CONFIG_NET) += net.o
obj-$(CONFIG_CMD_NFS) += nfs.o
obj-$(CONFIG_CMD_PING) += ping.o
+obj-$(CONFIG_CMD_PCAP) += pcap.o
obj-$(CONFIG_CMD_RARP) += rarp.o
obj-$(CONFIG_CMD_SNTP) += sntp.o
obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o
diff --git a/net/eth-uclass.c b/net/eth-uclass.c
index 1d5d2f03b7..3bd98b01ad 100644
--- a/net/eth-uclass.c
+++ b/net/eth-uclass.c
@@ -11,6 +11,7 @@
#include <net.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
+#include <net/pcap.h>
#include "eth_internal.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -344,6 +345,10 @@ int eth_send(void *packet, int length)
/* We cannot completely return the error at present */
debug("%s: send() returned error %d\n", __func__, ret);
}
+#if defined(CONFIG_CMD_PCAP)
+ if (ret >= 0)
+ pcap_post(packet, length, true);
+#endif
return ret;
}
diff --git a/net/eth_legacy.c b/net/eth_legacy.c
index 850f362d87..41f5263526 100644
--- a/net/eth_legacy.c
+++ b/net/eth_legacy.c
@@ -11,6 +11,7 @@
#include <net.h>
#include <phy.h>
#include <linux/errno.h>
+#include <net/pcap.h>
#include "eth_internal.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -352,10 +353,17 @@ int eth_is_active(struct eth_device *dev)
int eth_send(void *packet, int length)
{
+ int ret;
+
if (!eth_current)
return -ENODEV;
- return eth_current->send(eth_current, packet, length);
+ ret = eth_current->send(eth_current, packet, length);
+#if defined(CONFIG_CMD_PCAP)
+ if (ret >= 0)
+ pcap_post(packet, lengeth, true);
+#endif
+ return ret;
}
int eth_rx(void)
diff --git a/net/mdio-uclass.c b/net/mdio-uclass.c
index 36a404ff44..6f922e80b6 100644
--- a/net/mdio-uclass.c
+++ b/net/mdio-uclass.c
@@ -23,6 +23,17 @@ void dm_mdio_probe_devices(void)
static int dm_mdio_post_bind(struct udevice *dev)
{
+ const char *dt_name;
+
+ /* set a custom name for the MDIO device, if present in DT */
+ if (ofnode_valid(dev->node)) {
+ dt_name = ofnode_read_string(dev->node, "device-name");
+ if (dt_name) {
+ debug("renaming dev %s to %s\n", dev->name, dt_name);
+ device_set_name(dev, dt_name);
+ }
+ }
+
/*
* MDIO command doesn't like spaces in names, don't allow them to keep
* it happy
@@ -75,7 +86,7 @@ static int dm_mdio_post_probe(struct udevice *dev)
pdata->mii_bus->write = mdio_write;
pdata->mii_bus->reset = mdio_reset;
pdata->mii_bus->priv = dev;
- strncpy(pdata->mii_bus->name, dev->name, MDIO_NAME_LEN);
+ strncpy(pdata->mii_bus->name, dev->name, MDIO_NAME_LEN - 1);
return mdio_register(pdata->mii_bus);
}
diff --git a/net/net.c b/net/net.c
index 40511db645..ded86e7456 100644
--- a/net/net.c
+++ b/net/net.c
@@ -96,6 +96,9 @@
#include <net.h>
#include <net/fastboot.h>
#include <net/tftp.h>
+#if defined(CONFIG_CMD_PCAP)
+#include <net/pcap.h>
+#endif
#if defined(CONFIG_LED_STATUS)
#include <miiphy.h>
#include <status_led.h>
@@ -672,6 +675,11 @@ done:
net_set_icmp_handler(NULL);
#endif
net_set_state(prev_net_state);
+
+#if defined(CONFIG_CMD_PCAP)
+ if (pcap_active())
+ pcap_print_status();
+#endif
return ret;
}
@@ -1084,6 +1092,9 @@ void net_process_received_packet(uchar *in_packet, int len)
debug_cond(DEBUG_NET_PKT, "packet received\n");
+#if defined(CONFIG_CMD_PCAP)
+ pcap_post(in_packet, len, false);
+#endif
net_rx_packet = in_packet;
net_rx_packet_len = len;
et = (struct ethernet_hdr *)in_packet;
@@ -1253,6 +1264,9 @@ void net_process_received_packet(uchar *in_packet, int len)
return;
}
+ if (ntohs(ip->udp_len) < UDP_HDR_SIZE || ntohs(ip->udp_len) > ntohs(ip->ip_len))
+ return;
+
debug_cond(DEBUG_DEV_PKT,
"received UDP (to=%pI4, from=%pI4, len=%d)\n",
&dst_ip, &src_ip, len);
diff --git a/net/nfs.c b/net/nfs.c
index d6a7f8e827..aca0ca55f3 100644
--- a/net/nfs.c
+++ b/net/nfs.c
@@ -196,10 +196,10 @@ static void rpc_req(int rpc_prog, int rpc_proc, uint32_t *data, int datalen)
rpc_pkt.u.call.vers = htonl(2); /* portmapper is version 2 */
}
rpc_pkt.u.call.proc = htonl(rpc_proc);
- p = (uint32_t *)&(rpc_pkt.u.call.data);
+ p = rpc_pkt.u.call.data;
if (datalen)
- memcpy((char *)p, (char *)data, datalen*sizeof(uint32_t));
+ memcpy(p, data, datalen * sizeof(uint32_t));
pktlen = (char *)p + datalen * sizeof(uint32_t) - (char *)&rpc_pkt;
@@ -566,11 +566,15 @@ static int nfs_lookup_reply(uchar *pkt, unsigned len)
}
if (supported_nfs_versions & NFSV2_FLAG) {
+ if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + NFS_FHSIZE) > len)
+ return -NFS_RPC_DROP;
memcpy(filefh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE);
} else { /* NFSV3_FLAG */
filefh3_length = ntohl(rpc_pkt.u.reply.data[1]);
if (filefh3_length > NFS3_FHSIZE)
filefh3_length = NFS3_FHSIZE;
+ if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + filefh3_length) > len)
+ return -NFS_RPC_DROP;
memcpy(filefh, rpc_pkt.u.reply.data + 2, filefh3_length);
}
@@ -579,7 +583,7 @@ static int nfs_lookup_reply(uchar *pkt, unsigned len)
static int nfs3_get_attributes_offset(uint32_t *data)
{
- if (ntohl(data[1]) != 0) {
+ if (data[1]) {
/* 'attributes_follow' flag is TRUE,
* so we have attributes on 21 dwords */
/* Skip unused values :
@@ -634,6 +638,9 @@ static int nfs_readlink_reply(uchar *pkt, unsigned len)
/* new path length */
rlen = ntohl(rpc_pkt.u.reply.data[1 + nfsv3_data_offset]);
+ if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + rlen) > len)
+ return -NFS_RPC_DROP;
+
if (*((char *)&(rpc_pkt.u.reply.data[2 + nfsv3_data_offset])) != '/') {
int pathlen;
@@ -701,6 +708,9 @@ static int nfs_read_reply(uchar *pkt, unsigned len)
&(rpc_pkt.u.reply.data[4 + nfsv3_data_offset]);
}
+ if (((uchar *)&(rpc_pkt.u.reply.data[0]) - (uchar *)(&rpc_pkt) + rlen) > len)
+ return -9999;
+
if (store_block(data_ptr, nfs_offset, rlen))
return -9999;
@@ -732,6 +742,9 @@ static void nfs_handler(uchar *pkt, unsigned dest, struct in_addr sip,
debug("%s\n", __func__);
+ if (len > sizeof(struct rpc_t))
+ return;
+
if (dest != nfs_our_port)
return;
diff --git a/net/nfs.h b/net/nfs.h
index a377c90088..68ada0efeb 100644
--- a/net/nfs.h
+++ b/net/nfs.h
@@ -78,7 +78,7 @@ struct rpc_t {
NFS_MAX_ATTRS];
} reply;
} u;
-} __attribute__((packed));
+};
void nfs_start(void); /* Begin NFS */
diff --git a/net/pcap.c b/net/pcap.c
new file mode 100644
index 0000000000..4036d8a3fa
--- /dev/null
+++ b/net/pcap.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Ramon Fried <rfried.dev@gmail.com>
+ */
+
+#include <common.h>
+#include <net.h>
+#include <net/pcap.h>
+#include <time.h>
+#include <asm/io.h>
+
+#define LINKTYPE_ETHERNET 1
+
+static bool initialized;
+static bool running;
+static bool buffer_full;
+static void *buf;
+static unsigned int max_size;
+static unsigned int pos;
+
+static unsigned long incoming_count;
+static unsigned long outgoing_count;
+
+struct pcap_header {
+ u32 magic;
+ u16 version_major;
+ u16 version_minor;
+ s32 thiszone;
+ u32 sigfigs;
+ u32 snaplen;
+ u32 network;
+};
+
+struct pcap_packet_header {
+ u32 ts_sec;
+ u32 ts_usec;
+ u32 incl_len;
+ u32 orig_len;
+};
+
+static struct pcap_header file_header = {
+ .magic = 0xa1b2c3d4,
+ .version_major = 2,
+ .version_minor = 4,
+ .snaplen = 65535,
+ .network = LINKTYPE_ETHERNET,
+};
+
+int pcap_init(phys_addr_t paddr, unsigned long size)
+{
+ buf = map_physmem(paddr, size, 0);
+ if (!buf) {
+ printf("Failed mapping PCAP memory\n");
+ return -ENOMEM;
+ }
+
+ printf("PCAP capture initialized: addr: 0x%lx max length: %lu\n",
+ (unsigned long)buf, size);
+
+ memcpy(buf, &file_header, sizeof(file_header));
+ pos = sizeof(file_header);
+ max_size = size;
+ initialized = true;
+ running = false;
+ buffer_full = false;
+ incoming_count = 0;
+ outgoing_count = 0;
+ return 0;
+}
+
+int pcap_start_stop(bool start)
+{
+ if (!initialized) {
+ printf("error: pcap was not initialized\n");
+ return -ENODEV;
+ }
+
+ running = start;
+
+ return 0;
+}
+
+int pcap_clear(void)
+{
+ if (!initialized) {
+ printf("error: pcap was not initialized\n");
+ return -ENODEV;
+ }
+
+ pos = sizeof(file_header);
+ incoming_count = 0;
+ outgoing_count = 0;
+ buffer_full = false;
+
+ printf("pcap capture cleared\n");
+ return 0;
+}
+
+int pcap_post(const void *packet, size_t len, bool outgoing)
+{
+ struct pcap_packet_header header;
+ u64 cur_time = timer_get_us();
+
+ if (!initialized || !running || !buf)
+ return -ENODEV;
+
+ if (buffer_full)
+ return -ENOMEM;
+
+ if ((pos + len + sizeof(header)) >= max_size) {
+ buffer_full = true;
+ printf("\n!!! Buffer is full, consider increasing buffer size !!!\n");
+ return -ENOMEM;
+ }
+
+ header.ts_sec = cur_time / 1000000;
+ header.ts_usec = cur_time % 1000000;
+ header.incl_len = len;
+ header.orig_len = len;
+
+ memcpy(buf + pos, &header, sizeof(header));
+ pos += sizeof(header);
+ memcpy(buf + pos, packet, len);
+ pos += len;
+
+ if (outgoing)
+ outgoing_count++;
+ else
+ incoming_count++;
+
+ env_set_hex("pcapsize", pos);
+
+ return 0;
+}
+
+int pcap_print_status(void)
+{
+ if (!initialized) {
+ printf("pcap was not initialized\n");
+ return -ENODEV;
+ }
+ printf("PCAP status:\n");
+ printf("\tInitialized addr: 0x%lx\tmax length: %u\n",
+ (unsigned long)buf, max_size);
+ printf("\tStatus: %s.\t file size: %u\n", running ? "Active" : "Idle",
+ pos);
+ printf("\tIncoming packets: %lu Outgoing packets: %lu\n",
+ incoming_count, outgoing_count);
+
+ return 0;
+}
+
+bool pcap_active(void)
+{
+ return running;
+}
diff --git a/test/dm/cache.c b/test/dm/cache.c
index d4144aab76..2e244b109f 100644
--- a/test/dm/cache.c
+++ b/test/dm/cache.c
@@ -14,6 +14,8 @@ static int dm_test_reset(struct unit_test_state *uts)
ut_assertok(uclass_get_device(UCLASS_CACHE, 0, &dev_cache));
ut_assertok(cache_get_info(dev, &info));
+ ut_assertok(cache_enable(dev));
+ ut_assertok(cache_disable(dev));
return 0;
}
diff --git a/tools/prelink-riscv.inc b/tools/prelink-riscv.inc
index 8b40ec430a..f2b5467f5b 100644
--- a/tools/prelink-riscv.inc
+++ b/tools/prelink-riscv.inc
@@ -27,6 +27,8 @@
#define target32_to_cpu CONCAT(PRELINK_BYTEORDER, 32_to_cpu)
#define target64_to_cpu CONCAT(PRELINK_BYTEORDER, 64_to_cpu)
#define targetnn_to_cpu CONCAT3(PRELINK_BYTEORDER, PRELINK_INC_BITS, _to_cpu)
+#define cpu_to_target32 CONCAT3(cpu_to_, PRELINK_BYTEORDER, 32)
+#define cpu_to_target64 CONCAT3(cpu_to_, PRELINK_BYTEORDER, 64)
static void* get_offset_bonn (void* data, Elf_Phdr* phdrs, size_t phnum, Elf_Addr addr)
{
@@ -92,9 +94,9 @@ static void prelink_bonn(void *data)
if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_RELATIVE)
*((uintnn_t*) buf) = r->r_addend;
else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_32)
- *((uint32_t*) buf) = dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value;
+ *((uint32_t*) buf) = cpu_to_target32(targetnn_to_cpu(dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value) + targetnn_to_cpu(r->r_addend));
else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_64)
- *((uint64_t*) buf) = dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value;
+ *((uint64_t*) buf) = cpu_to_target64(targetnn_to_cpu(dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value) + targetnn_to_cpu(r->r_addend));
}
}
@@ -113,6 +115,8 @@ static void prelink_bonn(void *data)
#undef target32_to_cpu
#undef target64_to_cpu
#undef targetnn_to_cpu
+#undef cpu_to_target32
+#undef cpu_to_target64
#undef CONCAT_IMPL
#undef CONCAT