Boot failure on Rock-pi-4-a when compiling with clang.

2023-08-02 Thread Ying-Chun Liu (PaulLiu)

Hi all,

I'd like to have some ideas for debugging this conditions.
When compiling with default gnu toolchain. It works great.

When compiling with clang (clang-14 or clang-15),
I'll get hang sometimes.
The following are two boot logs:

1.
  U-Boot SPL 2023.10-rc1-00207-g38dedebc54-dirty (Aug 03 2023 - 08:08:00 +0800)
  Trying to boot from MMC1
  ## Checking hash(es) for config config-1 ... OK
  ## Checking hash(es) for Image atf-1 ... sha256+ OK
  ## Checking hash(es) for Image u-boot ... sha256+ OK
  ## Checking hash(es) for Image fdt-1 ... sha256+ OK
  ## Checking hash(es) for Image atf-2 ... sha256+ OK
  ## Checking hash(es) for Image atf-3 ... sha256+ OK
  ## Checking hash(es) for Image atf-4 ... sha256+ OK
  spl_load_fit_image: Skip load 'atf-5': image size is 0!


  U-Boot 2023.10-rc1-00207-g38dedebc54-dirty (Aug 03 2023 - 08:08:00 +0800)

  SoC: Rockchip rk3399
  Reset cause: POR
  Model: Radxa ROCK Pi 4A
  DRAM:  initcall sequence 002aeb80 failed at call 002042a8 
(err=-
  19)
  ### ERROR ### Please RESET the board ###

2.
  U-Boot TPL 2023.04-maybe-dirty (Jan 01 1970 - 00:00:00)
  lpddr4_set_rate: change freq to 400MHz 0, 1
  Channel 0: LPDDR4, 400MHz
  BW=32 Col=10 Bk=8 CS0 Row=16/15 CS=1 Die BW=16 Size=2048MB
  Channel 1: LPDDR4, 400MHz
  BW=32 Col=10 Bk=8 CS0 Row=16/15 CS=1 Die BW=16 Size=2048MB
  256B stride
  lpddr4_set_rate: change freq to 800MHz 1, 0
  Trying to boot from BOOTROM
  Returning to boot ROM...

  U-Boot SPL 2023.04-maybe-dirty (Jan 01 1970 - 00:00:00 +)
  Trying to boot from MMC1
  fdt_addr: 0x2e9c88
  Device tree error at node '__symbols__'
  Some drivers failed to bind
  initcall sequence 002a95f8 failed at call 00224138 (err=-11)
  ### ERROR ### Please RESET the board ###

As you can see, the bug happened at difference places. For the difference of 1 and 2, I just turn on 
the "fastboot over UDP" function.


Bisect is not working. Because if I keep turn on/off more extra functions (like fastboot over USB) 
it can boot sometimes. It seems to me that this could be some alignment or size of code problem 
because if I turn on something, the size of the binaries will be different. And some of it works, 
some not.


Now I only know that v2023.01 works well. And v2023.04 is unstable. I tried to bisect between them 
but found an unrelated commit. Because some bad commit could runs good just because of the probability.


Any ideas on how to debug this further?

I'm building U-boot by.
make O="/tmp/a1" \
 CROSS_COMPILE="aarch64-linux-gnu-" \
 CC="clang -target aarch64-linux-gnu" \
 HOSTCC="clang" \
 rock-pi-4-rk3399_defconfig
make O="/tmp/a1" \
 CROSS_COMPILE="aarch64-linux-gnu-" \
 CC="clang -target aarch64-linux-gnu" \
 HOSTCC="clang"
In Debian Trixie.

Yours,
Paul





OpenPGP_0x44173FA13D05.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH v2 5/6] net: add fastboot TCP documentation and IP6-only mode

2023-07-14 Thread Ying-Chun Liu (PaulLiu)

Reviewed-by: Ying-Chun Liu (PaulLiu) 


On 2023/5/11 00:59, Dmitrii Merkurev wrote:

Command to start IP6 only TCP fastboot:
fastboot tcp -ipv6

Signed-off-by: Dmitrii Merkurev 
Cc: Ying-Chun Liu (PaulLiu) 
Cc: Simon Glass 
Сс: Joe Hershberger 
Сс: Ramon Fried 
---
  cmd/fastboot.c   | 29 +
  doc/android/fastboot.rst |  8 +++-
  2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/cmd/fastboot.c b/cmd/fastboot.c
index 3d5ff951eb..36f744ae01 100644
--- a/cmd/fastboot.c
+++ b/cmd/fastboot.c
@@ -12,6 +12,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -121,10 +122,23 @@ static int do_fastboot(struct cmd_tbl *cmdtp, int flag, 
int argc,
  {
uintptr_t buf_addr = (uintptr_t)NULL;
size_t buf_size = 0;
+   bool is_ipv6_only = false;
+   bool is_usb = false;
+   bool is_udp = false;
+   bool is_tcp = false;
  
  	if (argc < 2)

return CMD_RET_USAGE;
  
+	if (IS_ENABLED(CONFIG_IPV6)) {

+   use_ip6 = false;
+   /* IPv6 parameter has to be always *last* */
+   if (!strcmp(argv[argc - 1], USE_IP6_CMD_PARAM)) {
+   is_ipv6_only = true;
+   --argc;
+   }
+   }
+
while (argc > 1 && **(argv + 1) == '-') {
char *arg = *++argv;
  
@@ -159,11 +173,18 @@ NXTARG:
  
  	fastboot_init((void *)buf_addr, buf_size);
  
-	if (!strcmp(argv[1], "udp"))

+   is_usb = strcmp(argv[1], "usb") == 0;
+   is_udp = strcmp(argv[1], "udp") == 0;
+   is_tcp = strcmp(argv[1], "tcp") == 0;
+
+   if (is_ipv6_only && is_tcp)
+   use_ip6 = true;
+
+   if (is_udp)
return do_fastboot_udp(argc, argv, buf_addr, buf_size);
-   if (!strcmp(argv[1], "tcp"))
+   if (is_tcp)
return do_fastboot_tcp(argc, argv, buf_addr, buf_size);
-   if (!strcmp(argv[1], "usb")) {
+   if (is_usb) {
argv++;
argc--;
}
@@ -174,7 +195,7 @@ NXTARG:
  U_BOOT_CMD(
fastboot, CONFIG_SYS_MAXARGS, 1, do_fastboot,
"run as a fastboot usb or udp device",
-   "[-l addr] [-s size] usb  | udp\n"
+   "[-l addr] [-s size] usb  | udp [-ipv6] | tcp [-ipv6]\n"
"\taddr - address of buffer used during data transfers ("
__stringify(CONFIG_FASTBOOT_BUF_ADDR) ")\n"
"\tsize - size of buffer used during data transfers ("
diff --git a/doc/android/fastboot.rst b/doc/android/fastboot.rst
index 1ad8a897c8..aa6e9e5a9e 100644
--- a/doc/android/fastboot.rst
+++ b/doc/android/fastboot.rst
@@ -181,13 +181,19 @@ Enter into fastboot by executing the fastboot command in 
U-Boot for either USB::
  
 => fastboot usb 0
  
-or UDP::

+UDP::
  
 => fastboot udp

 link up on port 0, speed 100, full duplex
 Using ethernet@4a10 device
 Listening for fastboot command on 192.168.0.102
  
+or TCP::

+
+   => fastboot tcp
+   Using ethernet@4a10 device
+   Listening for fastboot command on 192.168.0.102
+
  On the client side you can fetch the bootloader version for instance::
  
 $ fastboot getvar version-bootloader


Re: [PATCH 0/1] virtio: add driver for virtio_console devices

2023-06-13 Thread Ying-Chun Liu (PaulLiu)




On 2023/6/9 17:27, Bin Meng wrote:

Hi,

On Tue, Jun 6, 2023 at 9:26 PM Ying-Chun Liu (PaulLiu)
 wrote:


This is an implementation of single-character virtio-console. Part of the
patch is based on barebox implementations.

To test the patch, we can build qemu_arm64_defconfig target. Enable
CONFIG_VIRTIO_CONSOLE. And run qemu-system-aarch64 with
  -device virtio-serial-pci,id=virtio-serial0 \
  -chardev file,id=charconsole0,path=/tmp/serialconsolelog \
  -device virtconsole,chardev=charconsole0,id=console0 \



With this command, it still uses the on-board UART but not
virtio-console. Would you please post test instructions on using
virtio-console as the U-Boot serial console? Thanks!



Hi Bin,

Yes. The way to test this is.
I compile U-boot for qemu_arm64_defconfig
Enable the following configs manually.
CONFIG_VIRTIO_CONSOLE=y
CONFIG_CONSOLE_MUX=y
CONFIG_SYS_CONSOLE_IS_IN_ENV=y

Now run qemu with the following commands.
qemu-system-aarch64 -machine virt -cpu cortex-a57 -nographic \
-device virtio-serial-pci,id=virtio-serial0 \
-chardev file,id=charconsole0,path=/tmp/serialconsolelog \
-device virtconsole,chardev=charconsole0,id=console0 \
-bios /tmp/uboot-qemu-clang/u-boot.bin

In U-boot prompt,
we run
1. virtio scan
2. coninfo
In coninfo, we can see there is a new console device called virtio-console#XX
Then.
3. setenv stdout pl011@900,virtio-console#XX
And then all the output will also be output to /tmp/serialconsolelog on host.

This is the minimum example of testing the driver.
If we want to test it more then we might need to modify the -chardev to not use 
a file.
For example, we can use a telnet server.
-chardev socket,id=charconsole0,host=127.0.0.1,port=10023,telnet=on,server

After set stdin and stdout to pl011@900,virtio-console#XX
We can use "telnet localhost 10023" to access the U-boot prompt in qemu.

Yours,
Paul



[PATCH 1/1] virtio: add driver for virtio_console devices

2023-06-06 Thread Ying-Chun Liu (PaulLiu)
From: "A. Cody Schuffelen" 

This is an implementation of single-character virtio-console. Part of the
patch is based on barebox implementations.

Signed-off-by: A. Cody Schuffelen 
[ Paul: pick from the Android tree. Rebase to the upstream. Small fixes. ]
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Link: 
https://android.googlesource.com/platform/external/u-boot/+/bc68da98ebf835a50d869cf01c535ac936bfcb11
Link: 
https://git.pengutronix.de/cgit/barebox/tree/drivers/serial/virtio_console.c?id=180a551d542844b70012d7b94a415aacdcf31d45
Link: 
https://android.googlesource.com/platform/external/u-boot/+/4581f7c6e96d7332b534ae20de356a4554594d08
Cc: Bin Meng 
---
 drivers/virtio/Kconfig  |   8 ++
 drivers/virtio/Makefile |   1 +
 drivers/virtio/virtio-uclass.c  |   1 +
 drivers/virtio/virtio_console.c | 158 
 include/virtio.h|   2 +
 5 files changed, 170 insertions(+)
 create mode 100644 drivers/virtio/virtio_console.c

diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index 852f6735b6..94aaf70ab9 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -68,6 +68,14 @@ config VIRTIO_BLK
  This is the virtual block driver for virtio. It can be used with
  QEMU based targets.
 
+config VIRTIO_CONSOLE
+   bool "virtio console driver"
+   depends on VIRTIO
+   default y
+   help
+ This is the virtual console driver for virtio. It can be used
+ with QEMU based targets.
+
 config VIRTIO_RNG
bool "virtio rng driver"
depends on DM_RNG
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index 4c63a6c690..c816f66aa6 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -10,4 +10,5 @@ obj-$(CONFIG_VIRTIO_PCI_LEGACY) += virtio_pci_legacy.o
 obj-$(CONFIG_VIRTIO_SANDBOX) += virtio_sandbox.o
 obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
 obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o
+obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o
 obj-$(CONFIG_VIRTIO_RNG) += virtio_rng.o
diff --git a/drivers/virtio/virtio-uclass.c b/drivers/virtio/virtio-uclass.c
index 31bb21c534..9c54c67572 100644
--- a/drivers/virtio/virtio-uclass.c
+++ b/drivers/virtio/virtio-uclass.c
@@ -30,6 +30,7 @@
 static const char *const virtio_drv_name[VIRTIO_ID_MAX_NUM] = {
[VIRTIO_ID_NET] = VIRTIO_NET_DRV_NAME,
[VIRTIO_ID_BLOCK]   = VIRTIO_BLK_DRV_NAME,
+   [VIRTIO_ID_CONSOLE] = VIRTIO_CONSOLE_DRV_NAME,
[VIRTIO_ID_RNG] = VIRTIO_RNG_DRV_NAME,
 };
 
diff --git a/drivers/virtio/virtio_console.c b/drivers/virtio/virtio_console.c
new file mode 100644
index 00..1d4b319b08
--- /dev/null
+++ b/drivers/virtio/virtio_console.c
@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Tuomas Tynkkynen 
+ * Copyright (C) 2018, Bin Meng 
+ * Copyright (C) 2006, 2007, 2009 Rusty Russell, IBM Corporation
+ * Copyright (C) 2009, 2010, 2011 Red Hat, Inc.
+ * Copyright (C) 2009, 2010, 2011 Amit Shah 
+ * Copyright (C) 2021 Ahmad Fatoum
+ * Copyright (C) 2021, Google LLC, schuffe...@google.com (A. Cody Schuffelen)
+ * Copyright (C) 2023, Linaro
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "virtio_blk.h"
+
+struct virtio_console_priv {
+   struct virtqueue *receiveq_port0;
+   struct virtqueue *transmitq_port0;
+   unsigned char inbuf[1] __aligned(4);
+};
+
+static int virtio_console_bind(struct udevice *dev)
+{
+   struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(dev->parent);
+
+   /* Indicate what driver features we support */
+   virtio_driver_features_init(uc_priv, NULL, 0, NULL, 0);
+
+   return 0;
+}
+
+/*
+ * Create a scatter-gather list representing our input buffer and put
+ * it in the queue.
+ */
+static void add_inbuf(struct virtio_console_priv *priv)
+{
+   struct virtio_sg sg;
+   struct virtio_sg *sgs[1];
+   int ret;
+
+   sgs[0] = 
+   sg.addr = priv->inbuf;
+   sg.length = sizeof(priv->inbuf);
+
+   ret = virtqueue_add(priv->receiveq_port0, sgs, 0, 1);
+   /* We should always be able to add one buffer to an empty queue. */
+   WARN(ret < 0, "%s: virtqueue_add failed\n", __func__);
+
+   virtqueue_kick(priv->receiveq_port0);
+}
+
+static int virtio_console_probe(struct udevice *dev)
+{
+   struct virtio_console_priv *priv = dev_get_priv(dev);
+   int ret;
+
+   struct virtqueue *virtqueues[2];
+
+   ret = virtio_find_vqs(dev, 2, virtqueues);
+   if (ret < 0) {
+   debug("%s: virtio_find_vqs failed\n", __func__);
+   return ret;
+   }
+
+   priv->receiveq_port0 = virtqueues[0];
+   priv->transmitq_port0 = virtqueues[1];
+
+   /* Register the input buffer the first time. */
+   add_inbuf(priv);
+
+   return 0;
+}
+
+static int virtio_con

[PATCH 0/1] virtio: add driver for virtio_console devices

2023-06-06 Thread Ying-Chun Liu (PaulLiu)
This is an implementation of single-character virtio-console. Part of the
patch is based on barebox implementations.

To test the patch, we can build qemu_arm64_defconfig target. Enable
CONFIG_VIRTIO_CONSOLE. And run qemu-system-aarch64 with
 -device virtio-serial-pci,id=virtio-serial0 \
 -chardev file,id=charconsole0,path=/tmp/serialconsolelog \
 -device virtconsole,chardev=charconsole0,id=console0 \

When in U-boot console, type "dm tree" and we should be able to see the
virtio-console device.

A. Cody Schuffelen (1):
  virtio: add driver for virtio_console devices

 drivers/virtio/Kconfig  |   8 ++
 drivers/virtio/Makefile |   1 +
 drivers/virtio/virtio-uclass.c  |   1 +
 drivers/virtio/virtio_console.c | 158 
 include/virtio.h|   2 +
 5 files changed, 170 insertions(+)
 create mode 100644 drivers/virtio/virtio_console.c

-- 
2.39.2



Re: [PATCH v2 3/6] net: introduce TCP/IP6 support

2023-05-24 Thread Ying-Chun Liu (PaulLiu)




On 2023/5/11 00:59, Dmitrii Merkurev wrote:

Add TCP/IP6 related headers and reuse refactored TCP/IP
implementation

Signed-off-by: Dmitrii Merkurev 
Cc: Ying-Chun Liu (PaulLiu) 
Cc: Simon Glass 
Сс: Joe Hershberger 
Сс: Ramon Fried 
---
  include/net/tcp6.h | 106 +
  include/net6.h |  14 ++
  net/Makefile   |   1 +
  net/net.c  |   6 +++
  net/net6.c |  72 +-
  net/tcp6.c |  99 ++
  6 files changed, 288 insertions(+), 10 deletions(-)
  create mode 100644 include/net/tcp6.h
  create mode 100644 net/tcp6.c

diff --git a/include/net/tcp6.h b/include/net/tcp6.h
new file mode 100644
index 00..3db125ecc5
--- /dev/null
+++ b/include/net/tcp6.h
@@ -0,0 +1,106 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ */
+
+#ifndef __TCP6_H__
+#define __TCP6_H__
+
+#if defined(CONFIG_PROT_TCP)
+
+#include 
+#include 
+
+/**
+ * typedef rxhand_tcp6_f() - An incoming TCP IPv6 packet handler.
+ * @pkt: pointer to the application packet
+ * @dport: destination TCP port
+ * @sip: source IP6 address
+ * @sport: source TCP port
+ * @tcp_seq_num: TCP sequential number
+ * @tcp_ack_num: TCP acknowledgment number
+ * @action: TCP packet type (SYN, ACK, FIN, etc)
+ */
+typedef void rxhand_tcp6_f(uchar *pkt, u16 dport,
+  struct in6_addr sip, u16 sport,
+  u32 tcp_seq_num, u32 tcp_ack_num,
+  u8 action, unsigned int len);
+
+/**
+ * struct ip6_tcp_hdr_o - IP6 + TCP header + TCP options
+ * @ip_hdr: IP6 + TCP header
+ * @tcp_hdr: TCP header
+ * @tcp_o: TCP options
+ * @end: end of IP6/TCP header
+ */
+struct ip6_tcp_hdr_o {
+   struct  ip6_hdrip_hdr;
+   struct  tcp_hdrtcp_hdr;
+   struct  tcp_hdr_o  tcp_o;
+   u8  end;
+} __packed;
+
+#define IP6_TCP_O_SIZE (sizeof(struct ip6_tcp_hdr_o))
+
+/**
+ * struct ip6_tcp_hdr_s - IP6 + TCP header + TCP options
+ * @ip_hdr: IP6 + TCP header
+ * @tcp_hdr: TCP header
+ * @t_opt: TCP Timestamp Option
+ * @sack_v: TCP SACK Option
+ * @end: end of options
+ */
+struct ip6_tcp_hdr_s {
+   struct  ip6_hdrip_hdr;
+   struct  tcp_hdrtcp_hdr;
+   struct  tcp_t_opt  t_opt;
+   struct  tcp_sack_v sack_v;
+   u8  end;
+} __packed;
+
+#define IP6_TCP_SACK_SIZE (sizeof(struct ip6_tcp_hdr_s))
+
+/**
+ * union tcp6_build_pkt - union for building TCP/IP6 packet.
+ * @ip: IP6 and TCP header plus TCP options
+ * @sack: IP6 and TCP header plus SACK options
+ * @raw: buffer
+ */
+union tcp6_build_pkt {
+   struct ip6_tcp_hdr_o ip;
+   struct ip6_tcp_hdr_s sack;
+   uchar  raw[1600];
+} __packed;
+
+/**
+ * net_set_tcp6_handler6() - set application TCP6 packet handler
+ * @param f pointer to callback function
+ */
+void net_set_tcp_handler6(rxhand_tcp6_f *f);
+
+/**
+ * net_set_tcp_header6() - set
+ * @pkt: pointer to IP6/TCP headers
+ * @dport: destination TCP port
+ * @sport: source TCP port
+ * @payload_len: payload length
+ * @action: TCP packet type (SYN, ACK, FIN, etc)
+ * @tcp_seq_num: TCP sequential number
+ * @tcp_ack_num: TCP acknowledgment number
+ *
+ * returns TCP header size
+ */
+int net_set_tcp_header6(uchar *pkt, u16 dport, u16 sport, int payload_len,
+   u8 action, u32 tcp_seq_num, u32 tcp_ack_num);
+
+void net_set_tcp_handler6(rxhand_tcp6_f *f);
+
+/**
+ * rxhand_tcp6() - handle incoming IP6 TCP packet
+ * @param b pointer to IP6/TCP packet builder struct
+ * @param len full packet length
+ */
+void rxhand_tcp6(union tcp6_build_pkt *b, unsigned int len);
+
+#endif // CONFIG_PROT_TCP
+#endif // __TCP6_H__
diff --git a/include/net6.h b/include/net6.h
index beafc05338..fa926f07ac 100644
--- a/include/net6.h
+++ b/include/net6.h
@@ -344,6 +344,20 @@ int ip6_add_hdr(uchar *xip, struct in6_addr *src, struct 
in6_addr *dest,
  int net_send_udp_packet6(uchar *ether, struct in6_addr *dest, int dport,
 int sport, int len);
  
+/**

+ * net_send_tcp_packet6() - Make up TCP packet and send it
+ *
+ * @payload_len: TCP payload length
+ * @dport:  destination port
+ * @sport:  source port
+ * @action: TCP flag (SYN, ACL, PUSH, etc)
+ * @tcp_seq_num: TCP sequence number
+ * @tcp_ack_num: TCP ackno
+ * Return: 0 if send successfully, -1 otherwise
+ */
+int net_send_tcp_packet6(int payload_len, int dport, int sport, u8 action,
+u32 tcp_seq_num, u32 tcp_ack_num);
+
  /**
   * net_ip6_handler() - Handle IPv6 packet
   *
diff --git a/net/Makefile b/net/Makefile
index 3e2d061338..002b0f68a2 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_TCP_FUNCTION_FASTBOOT)  += fastboot_tcp.o
  obj-$(CONFIG_CMD_WOL)  += wol.o
  obj-$(CONFIG_PROT_UDP) += udp.o
  obj-$(CONFIG_PROT_TCP) += tcp.o
+obj-$(CONFIG_IPV6) += tcp6.o
  obj-$(CONFIG_CMD_WGET) += wget.o
  
  # Disable

Re: [PATCH v2 2/6] net: prepare existing TCP stack to be reused by IP6

2023-05-24 Thread Ying-Chun Liu (PaulLiu)




On 2023/5/11 00:59, Dmitrii Merkurev wrote:

Changes:
1. Separate reusable part from net_set_tcp_header to
net_set_tcp_header_common
2. Make TCP signatures reusable by receiving particular
IP agnostic TCP headers
3. Extract net_send_ip_packet6 from net_send_udp_packet6
to reuse the code
4. Expose TCP state machine related functions

This allows us to reuse TCP logic between IP and IP6 stack.

Signed-off-by: Dmitrii Merkurev 
Cc: Ying-Chun Liu (PaulLiu) 
Cc: Simon Glass 
Сс: Joe Hershberger 
Сс: Ramon Fried 
---
  include/net/tcp.h | 109 +--
  net/net.c |  18 ++-
  net/net6.c|  78 ---
  net/tcp.c | 337 --
  4 files changed, 372 insertions(+), 170 deletions(-)

diff --git a/include/net/tcp.h b/include/net/tcp.h
index 93ed728dfe..344b4be2a4 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -8,10 +8,20 @@
  #ifndef __TCP_H__
  #define __TCP_H__
  
+#include 

+
  #define TCP_ACTIVITY 127  /* Number of packets received   */
/* before console progress mark */
  
+/*

+ * TCP lengths are stored as a rounded up number of 32 bit words.
+ * Add 3 to length round up, rounded, then divided into the
+ * length in 32 bit words.
+ */
+#define LEN_B_TO_DW(x) ((x) >> 2)
+#define ROUND_TCPHDR_LEN(x) (LEN_B_TO_DW((x) + 3))
  #define GET_TCP_HDR_LEN_IN_BYTES(x) ((x) >> 2)
+#define SHIFT_TO_TCPHDRLEN_FIELD(x) ((x) << 4)
  
  /**

   * struct tcp_hdr - TCP header
@@ -24,7 +34,7 @@
   * @tcp_win: TCP windows size
   * @tcp_xsum: Checksum
   * @tcp_ugr: Pointer to urgent data
-*/
+ */
  struct tcp_hdr {
u16 tcp_src;
u16 tcp_dst;
@@ -163,18 +173,14 @@ struct tcp_t_opt {
   */
  
  /**

- * struct ip_tcp_hdr_o - IP + TCP header + TCP options
- * @ip_hdr: IP + TCP header
- * @tcp_hdr: TCP header
+ * struct tcp_hdr_o - TCP options
   * @mss: TCP MSS Option
   * @scale: TCP Windows Scale Option
   * @sack_p: TCP Sack-Permitted Option
   * @t_opt: TCP Timestamp Option
   * @end: end of options
   */
-struct ip_tcp_hdr_o {
-   struct  ip_hdr ip_hdr;
-   struct  tcp_hdrtcp_hdr;
+struct tcp_hdr_o {
struct  tcp_mssmss;
struct  tcp_scale  scale;
struct  tcp_sack_p sack_p;
@@ -182,6 +188,22 @@ struct ip_tcp_hdr_o {
u8  end;
  } __packed;
  
+#define TCP_O_SIZE (sizeof(struct tcp_hdr_o))

+
+/**
+ * struct ip_tcp_hdr_o - IP + TCP header + TCP options
+ * @ip_hdr: IP + TCP header
+ * @tcp_hdr: TCP header
+ * @tcp_o: TCP options
+ * @end: end of IP/TCP header
+ */
+struct ip_tcp_hdr_o {
+   struct  ip_hdr ip_hdr;
+   struct  tcp_hdrtcp_hdr;
+   struct  tcp_hdr_o  tcp_o;
+   u8  end;
+} __packed;
+
  #define IP_TCP_O_SIZE (sizeof(struct ip_tcp_hdr_o))
  
  /**

@@ -209,7 +231,7 @@ struct ip_tcp_hdr_s {
  
  /**

   * struct pseudo_hdr - Pseudo Header
- * @padding: pseudo hdr size = ip_tcp hdr size
+ * @padding: pseudo hdr size = ip hdr size
   * @p_src: Source IP address
   * @p_dst: Destination IP address
   * @rsvd: reserved
@@ -236,7 +258,6 @@ struct pseudo_hdr {
   *
   * Build Pseudo header in packed buffer
   * first, calculate TCP checksum, then build IP header in packed buffer.
- *
   */
  union tcp_build_pkt {
struct pseudo_hdr ph;
@@ -269,9 +290,77 @@ enum tcp_state {
  
  enum tcp_state tcp_get_tcp_state(void);

  void tcp_set_tcp_state(enum tcp_state new_state);
-int tcp_set_tcp_header(uchar *pkt, int dport, int sport, int payload_len,
+
+/**
+ * net_set_tcp_header_common() - IP version agnostic TCP header building 
implementation
+ *
+ * @tcp_hdr: pointer to TCP header struct
+ * @tcp_o: pointer to TCP options header struct
+ * @sack_t_opt: pointer to TCP sack options header struct
+ * @sack_v: pointer to TCP sack header struct
+ * @dport: destination TCP port
+ * @sport: source TCP port
+ * @payload_len: TCP payload len
+ * @action: TCP action (SYN, ACK, FIN, etc)
+ * @tcp_seq_num: TCP sequential number
+ * @tcp_ack_num: TCP acknowledgment number
+ *
+ * returns TCP header
+ */
+int net_set_tcp_header_common(struct tcp_hdr *tcp_hdr, struct tcp_hdr_o *tcp_o,
+ struct tcp_t_opt *sack_t_opt, struct tcp_sack_v 
*sack_v,
+ u16 dport, u16 sport, int payload_len, u8 action,
+ u32 tcp_seq_num, u32 tcp_ack_num);
+
+/**
+ * net_set_tcp_header() - IPv4 TCP header bulding implementation
+ *
+ * @pkt: pointer to the IP header
+ * @dport: destination TCP port
+ * @sport: source TCP port
+ * @payload_len: TCP payload len
+ * @action: TCP action (SYN, ACK, FIN, etc)
+ * @tcp_seq_num: TCP sequential number
+ * @tcp_ack_num: TCP acknowledgment number
+ *
+ * returns TCP header
+ */
+int net_set_tcp_header(uchar *pkt, u16 dport, u16 sport, int payload_len,
   u8 action, u32 tcp_seq_num, u32 tcp_ack_num);
  
+/**

+ * tcp_parse_options() - parsing TCP 

Re: [PATCH v2 1/6] net: split IP_TCP header into separate IP/IP6 and TCP headers

2023-05-24 Thread Ying-Chun Liu (PaulLiu)

Reviewed-by: Ying-Chun Liu (PaulLiu) 

On 2023/5/11 00:59, Dmitrii Merkurev wrote:

This allows us to reuse TCP logic between IP and IP6 stack.

Signed-off-by: Dmitrii Merkurev 
Cc: Ying-Chun Liu (PaulLiu) 
Cc: Simon Glass 
Сс: Joe Hershberger 
Сс: Ramon Fried 
---
  include/net/tcp.h | 54 
  net/tcp.c | 70 +++
  test/cmd/wget.c   | 48 ++--
  3 files changed, 85 insertions(+), 87 deletions(-)

diff --git a/include/net/tcp.h b/include/net/tcp.h
index c29d4ce24a..93ed728dfe 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -5,20 +5,16 @@
   * Copyright 2017 Duncan Hare, All rights reserved.
   */
  
+#ifndef __TCP_H__

+#define __TCP_H__
+
  #define TCP_ACTIVITY 127  /* Number of packets received   */
/* before console progress mark */
+
+#define GET_TCP_HDR_LEN_IN_BYTES(x) ((x) >> 2)
+
  /**
- * struct ip_tcp_hdr - IP and TCP header
- * @ip_hl_v: header length and version
- * @ip_tos: type of service
- * @ip_len: total length
- * @ip_id: identification
- * @ip_off: fragment offset field
- * @ip_ttl: time to live
- * @ip_p: protocol
- * @ip_sum: checksum
- * @ip_src: Source IP address
- * @ip_dst: Destination IP address
+ * struct tcp_hdr - TCP header
   * @tcp_src: TCP source port
   * @tcp_dst: TCP destination port
   * @tcp_seq: TCP sequence number
@@ -28,18 +24,8 @@
   * @tcp_win: TCP windows size
   * @tcp_xsum: Checksum
   * @tcp_ugr: Pointer to urgent data
- */
-struct ip_tcp_hdr {
-   u8  ip_hl_v;
-   u8  ip_tos;
-   u16 ip_len;
-   u16 ip_id;
-   u16 ip_off;
-   u8  ip_ttl;
-   u8  ip_p;
-   u16 ip_sum;
-   struct in_addr  ip_src;
-   struct in_addr  ip_dst;
+*/
+struct tcp_hdr {
u16 tcp_src;
u16 tcp_dst;
u32 tcp_seq;
@@ -51,8 +37,8 @@ struct ip_tcp_hdr {
u16 tcp_ugr;
  } __packed;
  
-#define IP_TCP_HDR_SIZE		(sizeof(struct ip_tcp_hdr))

-#define TCP_HDR_SIZE   (IP_TCP_HDR_SIZE  - IP_HDR_SIZE)
+#define TCP_HDR_SIZE   (sizeof(struct tcp_hdr))
+#define IP_TCP_HDR_SIZE (IP_HDR_SIZE + TCP_HDR_SIZE)
  
  #define TCP_DATA	0x00	/* Data Packet - internal use only	*/

  #define TCP_FIN   0x01/* Finish flag  
*/
@@ -178,7 +164,8 @@ struct tcp_t_opt {
  
  /**

   * struct ip_tcp_hdr_o - IP + TCP header + TCP options
- * @hdr: IP + TCP header
+ * @ip_hdr: IP + TCP header
+ * @tcp_hdr: TCP header
   * @mss: TCP MSS Option
   * @scale: TCP Windows Scale Option
   * @sack_p: TCP Sack-Permitted Option
@@ -186,7 +173,8 @@ struct tcp_t_opt {
   * @end: end of options
   */
  struct ip_tcp_hdr_o {
-   struct  ip_tcp_hdr hdr;
+   struct  ip_hdr ip_hdr;
+   struct  tcp_hdrtcp_hdr;
struct  tcp_mssmss;
struct  tcp_scale  scale;
struct  tcp_sack_p sack_p;
@@ -198,15 +186,17 @@ struct ip_tcp_hdr_o {
  
  /**

   * struct ip_tcp_hdr_s - IP + TCP header + TCP options
- * @hdr: IP + TCP header
+ * @ip_hdr: IP + TCP header
+ * @tcp_hdr: TCP header
   * @t_opt: TCP Timestamp Option
   * @sack_v: TCP SACK Option
   * @end: end of options
   */
  struct ip_tcp_hdr_s {
-   struct  ip_tcp_hdr  hdr;
-   struct  tcp_t_opt   t_opt;
-   struct  tcp_sack_v  sack_v;
+   struct  ip_hdr ip_hdr;
+   struct  tcp_hdrtcp_hdr;
+   struct  tcp_t_opt  t_opt;
+   struct  tcp_sack_v sack_v;
u8  end;
  } __packed;
  
@@ -303,3 +293,5 @@ void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int len);
  
  u16 tcp_set_pseudo_header(uchar *pkt, struct in_addr src, struct in_addr dest,

  int tcp_len, int pkt_len);
+
+#endif // __TCP_H__
diff --git a/net/tcp.c b/net/tcp.c
index a713e1dd60..10ce799814 100644
--- a/net/tcp.c
+++ b/net/tcp.c
@@ -155,7 +155,7 @@ u16 tcp_set_pseudo_header(uchar *pkt, struct in_addr src, 
struct in_addr dest,
   */
  int net_set_ack_options(union tcp_build_pkt *b)
  {
-   b->sack.hdr.tcp_hlen = 
SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE));
+   b->sack.tcp_hdr.tcp_hlen = 
SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE));
  
  	b->sack.t_opt.kind = TCP_O_TS;

b->sack.t_opt.len = TCP_OPT_LEN_A;
@@ -187,12 +187,12 @@ int net_set_ack_options(union tcp_build_pkt *b)
b->sack.sack_v.hill[3].r = TCP_O_NOP;
}
  
-		b->sack.hdr.tcp_hlen = SHIFT_TO_TCPHDRLEN_FIELD(ROUND_TCPHDR_LEN(TCP_HDR_SIZE +

+   b->sack.tcp_hdr.tcp_hlen = 
SHIFT_TO_TCPHDRLEN_FIELD(ROUND_TCPHDR_LEN(TCP_HDR_SIZE +

 TCP_TSOPT_SIZE +
   

[PATCH 5/6] virtio: Allocate bounce buffers for devices with VIRTIO_F_IOMMU_PLATFORM

2023-03-29 Thread Ying-Chun Liu (PaulLiu)
From: Will Deacon 

In preparation for bouncing virtio data for devices advertising the
VIRTIO_F_IOMMU_PLATFORM feature, allocate an array of bounce buffer
structures in the vring, one per descriptor.

Signed-off-by: Will Deacon 
[ Paul: pick from the Android tree. Rebase to the upstream ]
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Bin Meng 
Link: 
https://android.googlesource.com/platform/external/u-boot/+/3e052749e7c50c4c1a6014e645ae3b9be3710c07
---
 drivers/virtio/virtio_ring.c | 25 -
 include/virtio_ring.h|  5 -
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 1bd19add75..de75786ca7 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -6,6 +6,7 @@
  * virtio ring implementation
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -292,6 +293,7 @@ struct virtqueue *vring_create_virtqueue(unsigned int 
index, unsigned int num,
struct udevice *vdev = uc_priv->vdev;
struct virtqueue *vq;
void *queue = NULL;
+   struct bounce_buffer *bbs = NULL;
struct vring vring;
 
/* We assume num is a power of 2 */
@@ -320,17 +322,29 @@ struct virtqueue *vring_create_virtqueue(unsigned int 
index, unsigned int num,
return NULL;
 
memset(queue, 0, vring_size(num, vring_align));
-   vring_init(, num, queue, vring_align);
 
-   vq = __vring_new_virtqueue(index, vring, udev);
-   if (!vq) {
-   virtio_free_pages(vdev, queue, DIV_ROUND_UP(vring.size, 
PAGE_SIZE));
-   return NULL;
+   if (virtio_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) {
+   bbs = calloc(num, sizeof(*bbs));
+   if (!bbs)
+   goto err_free_queue;
}
+
+   vring_init(, num, queue, vring_align, bbs);
+
+   vq = __vring_new_virtqueue(index, vring, udev);
+   if (!vq)
+   goto err_free_bbs;
+
debug("(%s): created vring @ %p for vq @ %p with num %u\n", udev->name,
  queue, vq, num);
 
return vq;
+
+err_free_bbs:
+   free(bbs);
+err_free_queue:
+   virtio_free_pages(vdev, queue, DIV_ROUND_UP(vring.size, PAGE_SIZE));
+   return NULL;
 }
 
 void vring_del_virtqueue(struct virtqueue *vq)
@@ -339,6 +353,7 @@ void vring_del_virtqueue(struct virtqueue *vq)
  DIV_ROUND_UP(vq->vring.size, PAGE_SIZE));
free(vq->vring_desc_shadow);
list_del(>list);
+   free(vq->vring.bouncebufs);
free(vq);
 }
 
diff --git a/include/virtio_ring.h b/include/virtio_ring.h
index 8f8a55c7bd..e8e91044a2 100644
--- a/include/virtio_ring.h
+++ b/include/virtio_ring.h
@@ -87,6 +87,7 @@ struct vring_used {
 struct vring {
unsigned int num;
size_t size;
+   struct bounce_buffer *bouncebufs;
struct vring_desc *desc;
struct vring_avail *avail;
struct vring_used *used;
@@ -146,10 +147,12 @@ static inline unsigned int vring_size(unsigned int num, 
unsigned long align)
 }
 
 static inline void vring_init(struct vring *vr, unsigned int num, void *p,
- unsigned long align)
+ unsigned long align,
+ struct bounce_buffer *bouncebufs)
 {
vr->num = num;
vr->size = vring_size(num, align);
+   vr->bouncebufs = bouncebufs;
vr->desc = p;
vr->avail = p + num * sizeof(struct vring_desc);
vr->used = (void *)(((uintptr_t)>avail->ring[num] +
-- 
2.39.2



[PATCH 6/6] virtio: Use bounce buffers when VIRTIO_F_IOMMU_PLATFORM is set

2023-03-29 Thread Ying-Chun Liu (PaulLiu)
From: Will Deacon 

Devices advertising the VIRTIO_F_IOMMU_PLATFORM feature require
platform-specific handling to configure their DMA transactions.

When handling virtio descriptors for such a device, use bounce
buffers to ensure that the underlying buffers are always aligned
to and padded to PAGE_SIZE in preparation for platform specific
handling at page granularity.

Signed-off-by: Will Deacon 
[ Paul: pick from the Android tree. Rebase to the upstream ]
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Bin Meng 
Link: 
https://android.googlesource.com/platform/external/u-boot/+/1eff171e613ee67dca71dbe97be7282e2db17011
---
 drivers/virtio/virtio_ring.c | 48 +++-
 1 file changed, 47 insertions(+), 1 deletion(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index de75786ca7..c9adcce5c0 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -28,14 +28,51 @@ static void virtio_free_pages(struct udevice *vdev, void 
*ptr, u32 npages)
free(ptr);
 }
 
+static int __bb_force_page_align(struct bounce_buffer *state)
+{
+   const ulong align_mask = PAGE_SIZE - 1;
+
+   if ((ulong)state->user_buffer & align_mask)
+   return 0;
+
+   if (state->len != state->len_aligned)
+   return 0;
+
+   return 1;
+}
+
 static unsigned int virtqueue_attach_desc(struct virtqueue *vq, unsigned int i,
  struct virtio_sg *sg, u16 flags)
 {
struct vring_desc_shadow *desc_shadow = >vring_desc_shadow[i];
struct vring_desc *desc = >vring.desc[i];
+   void *addr;
+
+   if (IS_ENABLED(CONFIG_BOUNCE_BUFFER) && vq->vring.bouncebufs) {
+   struct bounce_buffer *bb = >vring.bouncebufs[i];
+   unsigned int bbflags;
+   int ret;
+
+   if (flags & VRING_DESC_F_WRITE)
+   bbflags = GEN_BB_WRITE;
+   else
+   bbflags = GEN_BB_READ;
+
+   ret = bounce_buffer_start_extalign(bb, sg->addr, sg->length,
+  bbflags, PAGE_SIZE,
+  __bb_force_page_align);
+   if (ret) {
+   debug("%s: failed to allocate bounce buffer (length 
0x%zx)\n",
+ vq->vdev->name, sg->length);
+   }
+
+   addr = bb->bounce_buffer;
+   } else {
+   addr = sg->addr;
+   }
 
/* Update the shadow descriptor. */
-   desc_shadow->addr = (u64)(uintptr_t)sg->addr;
+   desc_shadow->addr = (u64)(uintptr_t)addr;
desc_shadow->len = sg->length;
desc_shadow->flags = flags;
 
@@ -50,6 +87,15 @@ static unsigned int virtqueue_attach_desc(struct virtqueue 
*vq, unsigned int i,
 
 static void virtqueue_detach_desc(struct virtqueue *vq, unsigned int idx)
 {
+   struct vring_desc *desc = >vring.desc[idx];
+   struct bounce_buffer *bb;
+
+   if (!IS_ENABLED(CONFIG_BOUNCE_BUFFER) || !vq->vring.bouncebufs)
+   return;
+
+   bb = >vring.bouncebufs[idx];
+   bounce_buffer_stop(bb);
+   desc->addr = cpu_to_virtio64(vq->vdev, (u64)(uintptr_t)bb->user_buffer);
 }
 
 int virtqueue_add(struct virtqueue *vq, struct virtio_sg *sgs[],
-- 
2.39.2



[PATCH 2/6] virtio: pci: Tear down VQs in virtio_pci_reset()

2023-03-29 Thread Ying-Chun Liu (PaulLiu)
From: Will Deacon 

The pages backing the virtqueues for virtio PCI devices are not freed
on reset, despite the virtqueue structure being freed as part of the
driver '->priv_auto' destruction at ->remove() time.

Call virtio_pci_del_vqs() from virtio_pci_reset() to free the virtqueue
pages before freeing the virtqueue structure itself.

Signed-off-by: Will Deacon 
[ Paul: pick from the Android tree. Rebase to the upstream ]
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Bin Meng 
Link: 
https://android.googlesource.com/platform/external/u-boot/+/5ed54ccd83cbffd0d8719ce650604b4e44b5b0d8
---
 drivers/virtio/virtio_pci_modern.c | 38 +++---
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/virtio/virtio_pci_modern.c 
b/drivers/virtio/virtio_pci_modern.c
index cfde4007f5..3cdc2d2d6f 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -218,25 +218,6 @@ static int virtio_pci_set_status(struct udevice *udev, u8 
status)
return 0;
 }
 
-static int virtio_pci_reset(struct udevice *udev)
-{
-   struct virtio_pci_priv *priv = dev_get_priv(udev);
-
-   /* 0 status means a reset */
-   iowrite8(0, >common->device_status);
-
-   /*
-* After writing 0 to device_status, the driver MUST wait for a read
-* of device_status to return 0 before reinitializing the device.
-* This will flush out the status write, and flush in device writes,
-* including MSI-X interrupts, if any.
-*/
-   while (ioread8(>common->device_status))
-   udelay(1000);
-
-   return 0;
-}
-
 static int virtio_pci_get_features(struct udevice *udev, u64 *features)
 {
struct virtio_pci_priv *priv = dev_get_priv(udev);
@@ -363,6 +344,25 @@ static int virtio_pci_find_vqs(struct udevice *udev, 
unsigned int nvqs,
return 0;
 }
 
+static int virtio_pci_reset(struct udevice *udev)
+{
+   struct virtio_pci_priv *priv = dev_get_priv(udev);
+
+   /* 0 status means a reset */
+   iowrite8(0, >common->device_status);
+
+   /*
+* After writing 0 to device_status, the driver MUST wait for a read
+* of device_status to return 0 before reinitializing the device.
+* This will flush out the status write, and flush in device writes,
+* including MSI-X interrupts, if any.
+*/
+   while (ioread8(>common->device_status))
+   udelay(1000);
+
+   return virtio_pci_del_vqs(udev);
+}
+
 static int virtio_pci_notify(struct udevice *udev, struct virtqueue *vq)
 {
struct virtio_pci_priv *priv = dev_get_priv(udev);
-- 
2.39.2



[PATCH 4/6] virtio: Add helper functions to attach/detach vring descriptors

2023-03-29 Thread Ying-Chun Liu (PaulLiu)
From: Will Deacon 

Move the attach and detach logic for manipulating vring descriptors
out into their own functions so that we can later extend these to
bounce the data for devices with VIRTIO_F_IOMMU_PLATFORM set.

Signed-off-by: Will Deacon 
[ Paul: pick from the Android tree. Rebase to the upstream ]
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Bin Meng 
Link: 
https://android.googlesource.com/platform/external/u-boot/+/f73258a4bfe968c5f935db45f2ec5cc0104ee796
---
 drivers/virtio/virtio_ring.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 5aeb13fd59..1bd19add75 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -47,6 +47,10 @@ static unsigned int virtqueue_attach_desc(struct virtqueue 
*vq, unsigned int i,
return desc_shadow->next;
 }
 
+static void virtqueue_detach_desc(struct virtqueue *vq, unsigned int idx)
+{
+}
+
 int virtqueue_add(struct virtqueue *vq, struct virtio_sg *sgs[],
  unsigned int out_sgs, unsigned int in_sgs)
 {
@@ -165,10 +169,12 @@ static void detach_buf(struct virtqueue *vq, unsigned int 
head)
i = head;
 
while (vq->vring_desc_shadow[i].flags & VRING_DESC_F_NEXT) {
+   virtqueue_detach_desc(vq, i);
i = vq->vring_desc_shadow[i].next;
vq->num_free++;
}
 
+   virtqueue_detach_desc(vq, i);
vq->vring_desc_shadow[i].next = vq->free_head;
vq->free_head = head;
 
-- 
2.39.2



[PATCH 3/6] virtio: Allocate virtqueue in page-size units

2023-03-29 Thread Ying-Chun Liu (PaulLiu)
From: Will Deacon 

In preparation for explicit bouncing of virtqueue pages for devices
advertising the VIRTIO_F_IOMMU_PLATFORM feature, introduce a couple
of wrappers around virtqueue allocation and freeing operations,
ensuring that buffers are handled in terms of page-size units.

Signed-off-by: Will Deacon 
[ Paul: pick from the Android tree. Rebase to the upstream ]
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Bin Meng 
Link: 
https://android.googlesource.com/platform/external/u-boot/+/b4bb5227d4cf4fdfcd8b4e1ff2692d3a54d1482a
---
 drivers/virtio/virtio_ring.c | 24 
 include/virtio_ring.h| 16 +---
 2 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index f71bab7847..5aeb13fd59 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -15,6 +15,17 @@
 #include 
 #include 
 #include 
+#include 
+
+static void *virtio_alloc_pages(struct udevice *vdev, u32 npages)
+{
+   return memalign(PAGE_SIZE, npages * PAGE_SIZE);
+}
+
+static void virtio_free_pages(struct udevice *vdev, void *ptr, u32 npages)
+{
+   free(ptr);
+}
 
 static unsigned int virtqueue_attach_desc(struct virtqueue *vq, unsigned int i,
  struct virtio_sg *sg, u16 flags)
@@ -271,6 +282,8 @@ struct virtqueue *vring_create_virtqueue(unsigned int 
index, unsigned int num,
 unsigned int vring_align,
 struct udevice *udev)
 {
+   struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(udev);
+   struct udevice *vdev = uc_priv->vdev;
struct virtqueue *vq;
void *queue = NULL;
struct vring vring;
@@ -283,7 +296,9 @@ struct virtqueue *vring_create_virtqueue(unsigned int 
index, unsigned int num,
 
/* TODO: allocate each queue chunk individually */
for (; num && vring_size(num, vring_align) > PAGE_SIZE; num /= 2) {
-   queue = memalign(PAGE_SIZE, vring_size(num, vring_align));
+   size_t sz = vring_size(num, vring_align);
+
+   queue = virtio_alloc_pages(vdev, DIV_ROUND_UP(sz, PAGE_SIZE));
if (queue)
break;
}
@@ -293,7 +308,7 @@ struct virtqueue *vring_create_virtqueue(unsigned int 
index, unsigned int num,
 
if (!queue) {
/* Try to get a single page. You are my only hope! */
-   queue = memalign(PAGE_SIZE, vring_size(num, vring_align));
+   queue = virtio_alloc_pages(vdev, 1);
}
if (!queue)
return NULL;
@@ -303,7 +318,7 @@ struct virtqueue *vring_create_virtqueue(unsigned int 
index, unsigned int num,
 
vq = __vring_new_virtqueue(index, vring, udev);
if (!vq) {
-   free(queue);
+   virtio_free_pages(vdev, queue, DIV_ROUND_UP(vring.size, 
PAGE_SIZE));
return NULL;
}
debug("(%s): created vring @ %p for vq @ %p with num %u\n", udev->name,
@@ -314,7 +329,8 @@ struct virtqueue *vring_create_virtqueue(unsigned int 
index, unsigned int num,
 
 void vring_del_virtqueue(struct virtqueue *vq)
 {
-   free(vq->vring.desc);
+   virtio_free_pages(vq->vdev, vq->vring.desc,
+ DIV_ROUND_UP(vq->vring.size, PAGE_SIZE));
free(vq->vring_desc_shadow);
list_del(>list);
free(vq);
diff --git a/include/virtio_ring.h b/include/virtio_ring.h
index c77c212cff..8f8a55c7bd 100644
--- a/include/virtio_ring.h
+++ b/include/virtio_ring.h
@@ -86,6 +86,7 @@ struct vring_used {
 
 struct vring {
unsigned int num;
+   size_t size;
struct vring_desc *desc;
struct vring_avail *avail;
struct vring_used *used;
@@ -137,23 +138,24 @@ struct virtqueue {
 #define vring_used_event(vr)   ((vr)->avail->ring[(vr)->num])
 #define vring_avail_event(vr)  (*(__virtio16 *)&(vr)->used->ring[(vr)->num])
 
+static inline unsigned int vring_size(unsigned int num, unsigned long align)
+{
+   return ((sizeof(struct vring_desc) * num +
+   sizeof(__virtio16) * (3 + num)  + align - 1) & ~(align - 1)) +
+   sizeof(__virtio16) * 3 + sizeof(struct vring_used_elem) * num;
+}
+
 static inline void vring_init(struct vring *vr, unsigned int num, void *p,
  unsigned long align)
 {
vr->num = num;
+   vr->size = vring_size(num, align);
vr->desc = p;
vr->avail = p + num * sizeof(struct vring_desc);
vr->used = (void *)(((uintptr_t)>avail->ring[num] +
   sizeof(__virtio16) + align - 1) & ~(align - 1));
 }
 
-static inline unsigned int vring_size(unsigned int num, unsigned long align)
-{
-   return ((sizeof(struct vring_desc) * num +
-   sizeof(__virtio16) * (3 + num)  + align - 1)

[PATCH 1/6] virtio: Expose VIRTIO_F_IOMMU_PLATFORM in device features

2023-03-29 Thread Ying-Chun Liu (PaulLiu)
From: Will Deacon 

If we detect the VIRTIO_F_IOMMU_PLATFORM transport feature for a device,
then expose it in the device features.

Signed-off-by: Will Deacon 
[ Paul: pick from the Android tree. Rebase to the upstream ]
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Bin Meng 
Link: 
https://android.googlesource.com/platform/external/u-boot/+/9693bd26bfcfe77d6a1295a561420e08c5daf019
---
 drivers/virtio/virtio-uclass.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/virtio/virtio-uclass.c b/drivers/virtio/virtio-uclass.c
index de9bc90359..b3fb3dbfad 100644
--- a/drivers/virtio/virtio-uclass.c
+++ b/drivers/virtio/virtio-uclass.c
@@ -336,7 +336,7 @@ static int virtio_uclass_child_pre_probe(struct udevice 
*vdev)
/* Transport features always preserved to pass to finalize_features */
for (i = VIRTIO_TRANSPORT_F_START; i < VIRTIO_TRANSPORT_F_END; i++)
if ((device_features & (1ULL << i)) &&
-   (i == VIRTIO_F_VERSION_1))
+   (i == VIRTIO_F_VERSION_1 || i == VIRTIO_F_IOMMU_PLATFORM))
__virtio_set_bit(vdev->parent, i);
 
debug("(%s) final negotiated features supported %016llx\n",
-- 
2.39.2



[PATCH 0/6] virtio: Use bounce buffers when VIRTIO_F_IOMMU_PLATFORM set

2023-03-29 Thread Ying-Chun Liu (PaulLiu)
These patches will use bounce buffers when VIRTIO_F_IOMMU_PLATFORM feature
is in a virtio device.

This feature can be tested with qemu with -device virtio-iommu-pci.
So that when a -device virtio-blk-pci with iommu_platform=true, it will
uses the bounce buffer instead.

Will Deacon (6):
  virtio: Expose VIRTIO_F_IOMMU_PLATFORM in device features
  virtio: pci: Tear down VQs in virtio_pci_reset()
  virtio: Allocate virtqueue in page-size units
  virtio: Add helper functions to attach/detach vring descriptors
  virtio: Allocate bounce buffers for devices with
VIRTIO_F_IOMMU_PLATFORM
  virtio: Use bounce buffers when VIRTIO_F_IOMMU_PLATFORM is set

 drivers/virtio/virtio-uclass.c |   2 +-
 drivers/virtio/virtio_pci_modern.c |  38 +--
 drivers/virtio/virtio_ring.c   | 101 ++---
 include/virtio_ring.h  |  21 +++---
 4 files changed, 125 insertions(+), 37 deletions(-)

-- 
2.39.2



[PATCH 3/3] armv8: enable HAFDBS for other ELx when FEAT_HAFDBS is present

2023-03-17 Thread Ying-Chun Liu (PaulLiu)
From: meitao 

u-boot could be run at EL1/EL2/EL3. so we set it as same as EL1 does.
otherwise it will hang when enable mmu, that is what we encounter
in our SOC.

Signed-off-by: meitao 
[ Paul: pick from the Android tree. Rebase to the upstream ]
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Tom Rini 
Link: 
https://android.googlesource.com/platform/external/u-boot/+/3bf38943aeab4700c2319bff2a1477d99c6afd2f
---
 arch/arm/cpu/armv8/cache_v8.c|  6 +-
 arch/arm/include/asm/armv8/mmu.h | 10 --
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index 4c6a1b1d6c..cb1131a048 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -94,11 +94,15 @@ u64 get_tcr(u64 *pips, u64 *pva_bits)
if (el == 1) {
tcr = TCR_EL1_RSVD | (ips << 32) | TCR_EPD1_DISABLE;
if (gd->arch.has_hafdbs)
-   tcr |= TCR_HA | TCR_HD;
+   tcr |= TCR_EL1_HA | TCR_EL1_HD;
} else if (el == 2) {
tcr = TCR_EL2_RSVD | (ips << 16);
+   if (gd->arch.has_hafdbs)
+   tcr |= TCR_EL2_HA | TCR_EL2_HD;
} else {
tcr = TCR_EL3_RSVD | (ips << 16);
+   if (gd->arch.has_hafdbs)
+   tcr |= TCR_EL3_HA | TCR_EL3_HD;
}
 
/* PTWs cacheable, inner/outer WBWA and inner shareable */
diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h
index 98a27db316..19a9e112a4 100644
--- a/arch/arm/include/asm/armv8/mmu.h
+++ b/arch/arm/include/asm/armv8/mmu.h
@@ -102,8 +102,14 @@
 #define TCR_TG0_16K(2 << 14)
 #define TCR_EPD1_DISABLE   (1 << 23)
 
-#define TCR_HA BIT(39)
-#define TCR_HD BIT(40)
+#define TCR_EL1_HA BIT(39)
+#define TCR_EL1_HD BIT(40)
+
+#define TCR_EL2_HA BIT(21)
+#define TCR_EL2_HD BIT(22)
+
+#define TCR_EL3_HA BIT(21)
+#define TCR_EL3_HD BIT(22)
 
 #define TCR_EL1_RSVD   (1U << 31)
 #define TCR_EL2_RSVD   (1U << 31 | 1 << 23)
-- 
2.39.2



[PATCH 2/3] arm64: Use level-2 for largest block mappings when FEAT_HAFDBS is present

2023-03-17 Thread Ying-Chun Liu (PaulLiu)
From: Marc Zyngier 

In order to make invalidation by VA more efficient, set the largest
block mapping to 2MB, mapping it onto level-2. This has no material
impact on u-boot's runtime performance, and allows a huge speedup
when cleaning the cache.

Signed-off-by: Marc Zyngier 
[ Paul: pick from the Android tree. Rebase to the upstream ]
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Tom Rini 
Link: 
https://android.googlesource.com/platform/external/u-boot/+/417a73581a72ff6d6ee4b0938117b8a23e32f7e8
---
 arch/arm/cpu/armv8/cache_v8.c  | 14 ++
 arch/arm/include/asm/global_data.h |  1 +
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index 4760064ee1..4c6a1b1d6c 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -314,7 +314,7 @@ static void map_range(u64 virt, u64 phys, u64 size, int 
level,
for (i = idx; size; i++) {
u64 next_size, *next_table;
 
-   if (level >= 1 &&
+   if (level >= gd->arch.first_block_level &&
size >= map_size && !(virt & (map_size - 1))) {
if (level == 3)
table[i] = phys | attrs | PTE_TYPE_PAGE;
@@ -353,6 +353,9 @@ static void add_map(struct mm_region *map)
if (va_bits < 39)
level = 1;
 
+   if (!gd->arch.first_block_level)
+   gd->arch.first_block_level = 1;
+
if (gd->arch.has_hafdbs)
attrs |= PTE_DBM | PTE_RDONLY;
 
@@ -369,7 +372,7 @@ static void count_range(u64 virt, u64 size, int level, int 
*cntp)
for (i = idx; size; i++) {
u64 next_size;
 
-   if (level >= 1 &&
+   if (level >= gd->arch.first_block_level &&
size >= map_size && !(virt & (map_size - 1))) {
virt += map_size;
size -= map_size;
@@ -410,10 +413,13 @@ __weak u64 get_page_table_size(void)
u64 size, mmfr1;
 
asm volatile("mrs %0, id_aa64mmfr1_el1" : "=r" (mmfr1));
-   if ((mmfr1 & 0xf) == 2)
+   if ((mmfr1 & 0xf) == 2) {
gd->arch.has_hafdbs = true;
-   else
+   gd->arch.first_block_level = 2;
+   } else {
gd->arch.has_hafdbs = false;
+   gd->arch.first_block_level = 1;
+   }
 
/* Account for all page tables we would need to cover our memory map */
size = one_pt * count_ranges();
diff --git a/arch/arm/include/asm/global_data.h 
b/arch/arm/include/asm/global_data.h
index eda99b5b41..9d94cbe665 100644
--- a/arch/arm/include/asm/global_data.h
+++ b/arch/arm/include/asm/global_data.h
@@ -52,6 +52,7 @@ struct arch_global_data {
 #if defined(CONFIG_ARM64)
unsigned long tlb_fillptr;
unsigned long tlb_emerg;
+   unsigned int first_block_level;
bool has_hafdbs;
 #endif
 #endif
-- 
2.39.2



[PATCH 1/3] arm64: Use FEAT_HAFDBS to track dirty pages when available

2023-03-17 Thread Ying-Chun Liu (PaulLiu)
From: Marc Zyngier 

Some recent arm64 cores have a facility that allows the page
table walker to track the dirty state of a page. This makes it
really efficient to perform CMOs by VA as we only need to look
at dirty pages.

Signed-off-by: Marc Zyngier 
[ Paul: pick from the Android tree. Rebase to the upstream ]
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Tom Rini 
Link: 
https://android.googlesource.com/platform/external/u-boot/+/3c433724e6f830a6b2edd5ec3d4a504794887263
---
 arch/arm/cpu/armv8/cache_v8.c  | 16 +++-
 arch/arm/include/asm/armv8/mmu.h   | 14 ++
 arch/arm/include/asm/global_data.h |  1 +
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index 697334086f..4760064ee1 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -93,6 +93,8 @@ u64 get_tcr(u64 *pips, u64 *pva_bits)
 
if (el == 1) {
tcr = TCR_EL1_RSVD | (ips << 32) | TCR_EPD1_DISABLE;
+   if (gd->arch.has_hafdbs)
+   tcr |= TCR_HA | TCR_HD;
} else if (el == 2) {
tcr = TCR_EL2_RSVD | (ips << 16);
} else {
@@ -200,6 +202,9 @@ static void __cmo_on_leaves(void (*cmo_fn)(unsigned long, 
unsigned long),
attrs != PTE_BLOCK_MEMTYPE(MT_NORMAL_NC))
continue;
 
+   if (gd->arch.has_hafdbs && (pte & (PTE_RDONLY | PTE_DBM)) != 
PTE_DBM)
+   continue;
+
end = va + BIT(level2shift(level)) - 1;
 
/* No intersection with RAM? */
@@ -348,6 +353,9 @@ static void add_map(struct mm_region *map)
if (va_bits < 39)
level = 1;
 
+   if (gd->arch.has_hafdbs)
+   attrs |= PTE_DBM | PTE_RDONLY;
+
map_range(map->virt, map->phys, map->size, level,
  (u64 *)gd->arch.tlb_addr, attrs);
 }
@@ -399,7 +407,13 @@ static int count_ranges(void)
 __weak u64 get_page_table_size(void)
 {
u64 one_pt = MAX_PTE_ENTRIES * sizeof(u64);
-   u64 size;
+   u64 size, mmfr1;
+
+   asm volatile("mrs %0, id_aa64mmfr1_el1" : "=r" (mmfr1));
+   if ((mmfr1 & 0xf) == 2)
+   gd->arch.has_hafdbs = true;
+   else
+   gd->arch.has_hafdbs = false;
 
/* Account for all page tables we would need to cover our memory map */
size = one_pt * count_ranges();
diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h
index 9f58cedb65..98a27db316 100644
--- a/arch/arm/include/asm/armv8/mmu.h
+++ b/arch/arm/include/asm/armv8/mmu.h
@@ -49,10 +49,13 @@
 #define PTE_TYPE_BLOCK (1 << 0)
 #define PTE_TYPE_VALID (1 << 0)
 
-#define PTE_TABLE_PXN  (1UL << 59)
-#define PTE_TABLE_XN   (1UL << 60)
-#define PTE_TABLE_AP   (1UL << 61)
-#define PTE_TABLE_NS   (1UL << 63)
+#define PTE_RDONLY BIT(7)
+#define PTE_DBMBIT(51)
+
+#define PTE_TABLE_PXN  BIT(59)
+#define PTE_TABLE_XN   BIT(60)
+#define PTE_TABLE_AP   BIT(61)
+#define PTE_TABLE_NS   BIT(63)
 
 /*
  * Block
@@ -99,6 +102,9 @@
 #define TCR_TG0_16K(2 << 14)
 #define TCR_EPD1_DISABLE   (1 << 23)
 
+#define TCR_HA BIT(39)
+#define TCR_HD BIT(40)
+
 #define TCR_EL1_RSVD   (1U << 31)
 #define TCR_EL2_RSVD   (1U << 31 | 1 << 23)
 #define TCR_EL3_RSVD   (1U << 31 | 1 << 23)
diff --git a/arch/arm/include/asm/global_data.h 
b/arch/arm/include/asm/global_data.h
index 9e746e380a..eda99b5b41 100644
--- a/arch/arm/include/asm/global_data.h
+++ b/arch/arm/include/asm/global_data.h
@@ -52,6 +52,7 @@ struct arch_global_data {
 #if defined(CONFIG_ARM64)
unsigned long tlb_fillptr;
unsigned long tlb_emerg;
+   bool has_hafdbs;
 #endif
 #endif
 #ifdef CFG_SYS_MEM_RESERVE_SECURE
-- 
2.39.2



[PATCH 0/3] Use FEAT_HAFDBS to track dirty pages

2023-03-17 Thread Ying-Chun Liu (PaulLiu)
For some ARM64 cores there is a facility that allows the page
table walker to track the dirty state of a page. These commits
enhances the performance of CMOs by VA.

Marc Zyngier (2):
  arm64: Use FEAT_HAFDBS to track dirty pages when available
  arm64: Use level-2 for largest block mappings when FEAT_HAFDBS is
present

meitao (1):
  armv8: enable HAFDBS for other ELx when FEAT_HAFDBS is present

 arch/arm/cpu/armv8/cache_v8.c  | 30 +++---
 arch/arm/include/asm/armv8/mmu.h   | 20 
 arch/arm/include/asm/global_data.h |  2 ++
 3 files changed, 45 insertions(+), 7 deletions(-)

-- 
2.39.2



[PATCH 1/1] compulab: imx8mm-cl-iot-gate: Fix some function declarations in ddr.h

2023-03-13 Thread Ying-Chun Liu (PaulLiu)
We have a few places here that the function declarations do not
match their prototypes, correct them.

Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Tom Rini 
Cc: Stefano Babic 
Cc: Fabio Estevam 
Cc: NXP i.MX U-Boot Team 
---
 board/compulab/imx8mm-cl-iot-gate/ddr/ddr.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/board/compulab/imx8mm-cl-iot-gate/ddr/ddr.h 
b/board/compulab/imx8mm-cl-iot-gate/ddr/ddr.h
index f7d4fdc101..508b4a565c 100644
--- a/board/compulab/imx8mm-cl-iot-gate/ddr/ddr.h
+++ b/board/compulab/imx8mm-cl-iot-gate/ddr/ddr.h
@@ -25,7 +25,7 @@ struct lpddr4_tcm_desc {
 
 u32 cl_eeprom_get_ddrinfo(void);
 u32 cl_eeprom_set_ddrinfo(u32 ddrinfo);
-u32 cl_eeprom_get_subind(void);
-u32 cl_eeprom_set_subind(u32 subind);
+u8 cl_eeprom_get_subind(void);
+u8 cl_eeprom_set_subind(u8 subind);
 u32 cl_eeprom_get_osize(void);
 #endif
-- 
2.39.2



[PATCH 0/1] compulab: imx8mm-cl-iot-gate: Fix some function declarations in ddr.h

2023-03-13 Thread Ying-Chun Liu (PaulLiu)
We have a few places here that the function declarations do not
match their prototypes, correct them.

This bug was found by Tom.
https://lists.denx.de/pipermail/u-boot/2023-March/511786.html
And we fixes this bug by modifying ddr.h instead.

Ying-Chun Liu (PaulLiu) (1):
  compulab: imx8mm-cl-iot-gate: Fix some function declarations in ddr.h

 board/compulab/imx8mm-cl-iot-gate/ddr/ddr.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

-- 
2.39.2



[PATCH 0/1] lib/vsprintf.c: fix integer overflow in vsprintf

2023-03-08 Thread Ying-Chun Liu (PaulLiu)
vsnprintf_internal() adds 'size' to 'buf' and vsprintf() sets 'size'
to 'INT_MAX' which can overflow.  This causes sprintf() to fail when
initializing the environment on 8GB.

Instead of using 'INT_MAX', we use SIZE_MAX - buf, which is the
largest possible string that could fit without overflowing 'size'.

Tom Cherry (1):
  lib/vsprintf.c: fix integer overflow in vsprintf

 lib/vsprintf.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

-- 
2.39.2



[PATCH 1/1] lib/vsprintf.c: fix integer overflow in vsprintf

2023-03-08 Thread Ying-Chun Liu (PaulLiu)
From: Tom Cherry 

vsnprintf_internal() adds 'size' to 'buf' and vsprintf() sets 'size'
to 'INT_MAX' which can overflow.  This causes sprintf() to fail when
initializing the environment on 8GB.

Instead of using 'INT_MAX', we use SIZE_MAX - buf, which is the
largest possible string that could fit without overflowing 'size'.

Signed-off-by: Tom Cherry 
[ Paul: pick from the Android tree. Rebase to the upstream ]
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Tom Rini 
Link: 
https://android.googlesource.com/platform/external/u-boot/+/43aae5d4415e0f9d744fb798acd52429d09957ce
---
 lib/vsprintf.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 2d13e68b57..cd89c56a8f 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -794,7 +794,12 @@ int scnprintf(char *buf, size_t size, const char *fmt, ...)
  */
 int vsprintf(char *buf, const char *fmt, va_list args)
 {
-   return vsnprintf_internal(buf, INT_MAX, fmt, args);
+   /* vsnprintf_internal adds size to buf, so use a size that won't
+* overflow.
+*/
+   size_t max_size = SIZE_MAX - (size_t)buf;
+
+   return vsnprintf_internal(buf, max_size, fmt, args);
 }
 
 int sprintf(char *buf, const char *fmt, ...)
-- 
2.39.2



[PATCH 2/2] arm64: Reduce PT size estimation complexity

2023-02-14 Thread Ying-Chun Liu (PaulLiu)
From: Marc Zyngier 

count_required_pts()'s complexity is high if mappings are not using the
largest possible block size (due to some other requirement such as tracking
dirty pages, for example).

Let's switch to a method that follows the pattern established with
the add_map() helper, and make it almost instantaneous instead of
taking a large amount of time if 2MB mappings are in use instead of
1GB.

Signed-off-by: Marc Zyngier 
Signed-off-by: Pierre-Clément Tosi 
[ Paul: pick from the Android tree. Fixup Pierre's commit. Rebase to the
  upstream ]
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Tom Rini 
Link: 
https://android.googlesource.com/platform/external/u-boot/+/5d756d147e31a1cdaaa261a50e526404ca5968f5
Link: 
https://android.googlesource.com/platform/external/u-boot/+/6be9330601d81545c7c941e3609f35bf68a09059
---
 arch/arm/cpu/armv8/cache_v8.c | 109 +++---
 1 file changed, 34 insertions(+), 75 deletions(-)

diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index 876344e1b4..697334086f 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -352,98 +352,57 @@ static void add_map(struct mm_region *map)
  (u64 *)gd->arch.tlb_addr, attrs);
 }
 
-enum pte_type {
-   PTE_INVAL,
-   PTE_BLOCK,
-   PTE_LEVEL,
-};
-
-/*
- * This is a recursively called function to count the number of
- * page tables we need to cover a particular PTE range. If you
- * call this with level = -1 you basically get the full 48 bit
- * coverage.
- */
-static int count_required_pts(u64 addr, int level, u64 maxaddr)
+static void count_range(u64 virt, u64 size, int level, int *cntp)
 {
-   int levelshift = level2shift(level);
-   u64 levelsize = 1ULL << levelshift;
-   u64 levelmask = levelsize - 1;
-   u64 levelend = addr + levelsize;
-   int r = 0;
-   int i;
-   enum pte_type pte_type = PTE_INVAL;
+   u64 map_size = BIT_ULL(level2shift(level));
+   int i, idx;
 
-   for (i = 0; mem_map[i].size || mem_map[i].attrs; i++) {
-   struct mm_region *map = _map[i];
-   u64 start = map->virt;
-   u64 end = start + map->size;
+   idx = (virt >> level2shift(level)) & (MAX_PTE_ENTRIES - 1);
+   for (i = idx; size; i++) {
+   u64 next_size;
 
-   /* Check if the PTE would overlap with the map */
-   if (max(addr, start) <= min(levelend, end)) {
-   start = max(addr, start);
-   end = min(levelend, end);
+   if (level >= 1 &&
+   size >= map_size && !(virt & (map_size - 1))) {
+   virt += map_size;
+   size -= map_size;
 
-   /* We need a sub-pt for this level */
-   if ((start & levelmask) || (end & levelmask)) {
-   pte_type = PTE_LEVEL;
-   break;
-   }
+   continue;
+   }
 
-   /* Lv0 can not do block PTEs, so do levels here too */
-   if (level <= 0) {
-   pte_type = PTE_LEVEL;
-   break;
-   }
+   /* Going one level down */
+   (*cntp)++;
+   next_size = min(map_size - (virt & (map_size - 1)), size);
 
-   /* PTE is active, but fits into a block */
-   pte_type = PTE_BLOCK;
-   }
-   }
+   count_range(virt, next_size, level + 1, cntp);
 
-   /*
-* Block PTEs at this level are already covered by the parent page
-* table, so we only need to count sub page tables.
-*/
-   if (pte_type == PTE_LEVEL) {
-   int sublevel = level + 1;
-   u64 sublevelsize = 1ULL << level2shift(sublevel);
-
-   /* Account for the new sub page table ... */
-   r = 1;
-
-   /* ... and for all child page tables that one might have */
-   for (i = 0; i < MAX_PTE_ENTRIES; i++) {
-   r += count_required_pts(addr, sublevel, maxaddr);
-   addr += sublevelsize;
-
-   if (addr >= maxaddr) {
-   /*
-* We reached the end of address space, no need
-* to look any further.
-*/
-   break;
-   }
-   }
+   virt += next_size;
+   size -= next_size;
}
-
-   return r;
 }
 
-/* Returns the estimated required size of all page tables */
-__weak u64 get_page_table_size(void)
+static int count_ranges(void)
 {
-   u64 one_pt = MAX_PTE

[PATCH 1/2] arm64: Reduce add_map() complexity

2023-02-14 Thread Ying-Chun Liu (PaulLiu)
From: Marc Zyngier 

In the add_map() function, for each level it populates, it iterates from
the root of the PT tree, making it ineficient if a mapping needs to occur
past level 1.

Instead, replace it with a recursive (and much simpler) algorithm
that keeps the complexity as low as possible. With this, mapping
512GB at level 2 goes from several seconds down to not measurable
on an A55 machine.

We keep the block mappings at level 1 for now though.

Signed-off-by: Marc Zyngier 
Signed-off-by: Pierre-Clément Tosi 
[ Paul: pick from the Android tree. Fixup Pierre's commit. Rebase to the
  upstream ]
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Tom Rini 
Link: 
https://android.googlesource.com/platform/external/u-boot/+/96ad729cf4cab53bdff8222bb3eb256f38b5c3a6
Link: 
https://android.googlesource.com/platform/external/u-boot/+/6be9330601d81545c7c941e3609f35bf68a09059
---
 arch/arm/cpu/armv8/cache_v8.c | 94 +--
 1 file changed, 46 insertions(+), 48 deletions(-)

diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index f333ad8889..876344e1b4 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -299,61 +299,59 @@ static void split_block(u64 *pte, int level)
set_pte_table(pte, new_table);
 }
 
-/* Add one mm_region map entry to the page tables */
-static void add_map(struct mm_region *map)
+static void map_range(u64 virt, u64 phys, u64 size, int level,
+ u64 *table, u64 attrs)
 {
-   u64 *pte;
-   u64 virt = map->virt;
-   u64 phys = map->phys;
-   u64 size = map->size;
-   u64 attrs = map->attrs | PTE_TYPE_BLOCK | PTE_BLOCK_AF;
-   u64 blocksize;
-   int level;
-   u64 *new_table;
+   u64 map_size = BIT_ULL(level2shift(level));
+   int i, idx;
 
-   while (size) {
-   pte = find_pte(virt, 0);
-   if (pte && (pte_type(pte) == PTE_TYPE_FAULT)) {
-   debug("Creating table for virt 0x%llx\n", virt);
-   new_table = create_table();
-   set_pte_table(pte, new_table);
-   }
+   idx = (virt >> level2shift(level)) & (MAX_PTE_ENTRIES - 1);
+   for (i = idx; size; i++) {
+   u64 next_size, *next_table;
 
-   for (level = 1; level < 4; level++) {
-   pte = find_pte(virt, level);
-   if (!pte)
-   panic("pte not found\n");
-
-   blocksize = 1ULL << level2shift(level);
-   debug("Checking if pte fits for virt=%llx size=%llx 
blocksize=%llx\n",
- virt, size, blocksize);
-   if (size >= blocksize && !(virt & (blocksize - 1))) {
-   /* Page fits, create block PTE */
-   debug("Setting PTE %p to block virt=%llx\n",
- pte, virt);
-   if (level == 3)
-   *pte = phys | attrs | PTE_TYPE_PAGE;
-   else
-   *pte = phys | attrs;
-   virt += blocksize;
-   phys += blocksize;
-   size -= blocksize;
-   break;
-   } else if (pte_type(pte) == PTE_TYPE_FAULT) {
-   /* Page doesn't fit, create subpages */
-   debug("Creating subtable for virt 0x%llx 
blksize=%llx\n",
- virt, blocksize);
-   new_table = create_table();
-   set_pte_table(pte, new_table);
-   } else if (pte_type(pte) == PTE_TYPE_BLOCK) {
-   debug("Split block into subtable for virt 
0x%llx blksize=0x%llx\n",
- virt, blocksize);
-   split_block(pte, level);
-   }
+   if (level >= 1 &&
+   size >= map_size && !(virt & (map_size - 1))) {
+   if (level == 3)
+   table[i] = phys | attrs | PTE_TYPE_PAGE;
+   else
+   table[i] = phys | attrs;
+
+   virt += map_size;
+   phys += map_size;
+   size -= map_size;
+
+   continue;
}
+
+   /* Going one level down */
+   if (pte_type([i]) == PTE_TYPE_FAULT)
+   set_pte_table([i], create_table());
+
+   next_table = (u64 *)(table[i] & GENMASK_ULL(47, PAGE_SHIFT));
+ 

[PATCH 0/2] Reduce the complexity of add_map() and count_required_pts()

2023-02-14 Thread Ying-Chun Liu (PaulLiu)
Reduce the complexity of add_map() and count_required_pts() to gain
better performance.

Marc Zyngier (2):
  arm64: Reduce add_map() complexity
  arm64: Reduce PT size estimation complexity

 arch/arm/cpu/armv8/cache_v8.c | 201 +-
 1 file changed, 79 insertions(+), 122 deletions(-)

-- 
2.39.1



[PATCH v2 2/2] arm64: Initialize TLB memory if CMO_BY_VA_ONLY

2023-02-08 Thread Ying-Chun Liu (PaulLiu)
From: Pierre-Clément Tosi 

Memory used to hold the page tables is allocated from the top of RAM
with no prior initialization and could therefore hold invalid data. As
invalidate_dcache_all() will be called before the MMU has been
initialized and as that function relies indirectly on the page tables
when using CMO_BY_VA_ONLY, these must be in a valid state from their
allocation.

Signed-off-by: Pierre-Clément Tosi 
[ Paul: pick from the Android tree. Fix checkpatch warnings, and rebased
  to the upstream. ]
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Tom Rini 
Link: 
https://android.googlesource.com/platform/external/u-boot/+/e3ceef4230b772186c6853cace4a676a407e6ab7
---
v2: Fix the Signed-off-by list.
---
 arch/arm/lib/cache.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c
index 1a589c7e2a..7a16015867 100644
--- a/arch/arm/lib/cache.c
+++ b/arch/arm/lib/cache.c
@@ -159,6 +159,15 @@ __weak int arm_reserve_mmu(void)
 */
gd->arch.tlb_allocated = gd->arch.tlb_addr;
 #endif
+
+   if (IS_ENABLED(CONFIG_CMO_BY_VA_ONLY)) {
+   /*
+* As invalidate_dcache_all() will be called before
+* mmu_setup(), we should make sure that the PTs are
+* already in a valid state.
+*/
+   memset((void *)gd->arch.tlb_addr, 0, gd->arch.tlb_size);
+   }
 #endif
 
return 0;
-- 
2.39.1



[PATCH v2 1/2] arm: cpu: Add optional CMOs by VA

2023-02-08 Thread Ying-Chun Liu (PaulLiu)
From: Marc Zyngier 

Exposing set/way cache maintenance to a virtual machine is unsafe, not
least because the instructions are not permission-checked but also
because they are not broadcast between CPUs. Consequently, KVM traps and
emulates such maintenance in the host kernel using by-VA operations and
looping over the stage-2 page-tables. However, when running under
protected KVM, these instructions are not able to be emulated and will
instead result in an exception being delivered to the guest.

Introduce CONFIG_CMO_BY_VA_ONLY so that virtual platforms can select
this option and perform by-VA cache maintenance instead of using the
set/way instructions.

Signed-off-by: Marc Zyngier 
Signed-off-by: Will Deacon 
Signed-off-by: Pierre-Clément Tosi 
[ Paul: pick from the Android tree. Fixup Pierre's commit. And fix some
  checkpatch warnings. Rebased to upstream. ]
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Tom Rini 
Link: 
https://android.googlesource.com/platform/external/u-boot/+/db5507f47f4f57f766d52f753ff2cc761afc213b
Link: 
https://android.googlesource.com/platform/external/u-boot/+/2baf54e743380a1e4a6bc2dbdde020a2e783ff67
---
v2: Fix the Signed-off-by list.
---
 arch/arm/cpu/armv8/Kconfig|  4 ++
 arch/arm/cpu/armv8/cache.S| 50 +-
 arch/arm/cpu/armv8/cache_v8.c | 97 ++-
 arch/arm/cpu/armv8/cpu.c  | 30 +++
 4 files changed, 155 insertions(+), 26 deletions(-)

diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig
index 1305238c9d..7d5cf1594d 100644
--- a/arch/arm/cpu/armv8/Kconfig
+++ b/arch/arm/cpu/armv8/Kconfig
@@ -1,5 +1,9 @@
 if ARM64
 
+config CMO_BY_VA_ONLY
+   bool "Force cache maintenance to be exclusively by VA"
+   depends on !SYS_DISABLE_DCACHE_OPS
+
 config ARMV8_SPL_EXCEPTION_VECTORS
bool "Install crash dump exception vectors"
depends on SPL
diff --git a/arch/arm/cpu/armv8/cache.S b/arch/arm/cpu/armv8/cache.S
index d1cee23437..3fe935cf28 100644
--- a/arch/arm/cpu/armv8/cache.S
+++ b/arch/arm/cpu/armv8/cache.S
@@ -12,6 +12,7 @@
 #include 
 #include 
 
+#ifndef CONFIG_CMO_BY_VA_ONLY
 /*
  * void __asm_dcache_level(level)
  *
@@ -116,6 +117,41 @@ ENTRY(__asm_invalidate_dcache_all)
 ENDPROC(__asm_invalidate_dcache_all)
 .popsection
 
+.pushsection .text.__asm_flush_l3_dcache, "ax"
+WEAK(__asm_flush_l3_dcache)
+   mov x0, #0  /* return status as success */
+   ret
+ENDPROC(__asm_flush_l3_dcache)
+.popsection
+
+.pushsection .text.__asm_invalidate_l3_icache, "ax"
+WEAK(__asm_invalidate_l3_icache)
+   mov x0, #0  /* return status as success */
+   ret
+ENDPROC(__asm_invalidate_l3_icache)
+.popsection
+
+#else  /* CONFIG_CMO_BY_VA */
+
+/*
+ * Define these so that they actively clash with in implementation
+ * accidentally selecting CONFIG_CMO_BY_VA
+ */
+
+.pushsection .text.__asm_invalidate_l3_icache, "ax"
+ENTRY(__asm_invalidate_l3_icache)
+   mov x0, xzr
+   ret
+ENDPROC(__asm_invalidate_l3_icache)
+.popsection
+.pushsection .text.__asm_flush_l3_dcache, "ax"
+ENTRY(__asm_flush_l3_dcache)
+   mov x0, xzr
+   ret
+ENDPROC(__asm_flush_l3_dcache)
+.popsection
+#endif /* CONFIG_CMO_BY_VA */
+
 /*
  * void __asm_flush_dcache_range(start, end)
  *
@@ -189,20 +225,6 @@ WEAK(__asm_invalidate_l3_dcache)
 ENDPROC(__asm_invalidate_l3_dcache)
 .popsection
 
-.pushsection .text.__asm_flush_l3_dcache, "ax"
-WEAK(__asm_flush_l3_dcache)
-   mov x0, #0  /* return status as success */
-   ret
-ENDPROC(__asm_flush_l3_dcache)
-.popsection
-
-.pushsection .text.__asm_invalidate_l3_icache, "ax"
-WEAK(__asm_invalidate_l3_icache)
-   mov x0, #0  /* return status as success */
-   ret
-ENDPROC(__asm_invalidate_l3_icache)
-.popsection
-
 /*
  * void __asm_switch_ttbr(ulong new_ttbr)
  *
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index 2a226fd063..f333ad8889 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -163,6 +163,83 @@ static u64 *find_pte(u64 addr, int level)
return NULL;
 }
 
+#ifdef CONFIG_CMO_BY_VA_ONLY
+static void __cmo_on_leaves(void (*cmo_fn)(unsigned long, unsigned long),
+   u64 pte, int level, u64 base)
+{
+   u64 *ptep;
+   int i;
+
+   ptep = (u64 *)(pte & GENMASK_ULL(47, PAGE_SHIFT));
+   for (i = 0; i < PAGE_SIZE / sizeof(u64); i++) {
+   u64 end, va = base + i * BIT(level2shift(level));
+   u64 type, attrs;
+
+   pte = ptep[i];
+   type = pte & PTE_TYPE_MASK;
+   attrs = pte & PMD_ATTRINDX_MASK;
+   debug("PTE %llx at level %d VA %llx\n", pte, level, va);
+
+   /* Not valid? next! */
+   if (!(type & PTE_TYPE_VALID))
+   continu

[PATCH v2 0/2] arm: cpu: Add optional CMOs by VA

2023-02-08 Thread Ying-Chun Liu (PaulLiu)
Exposing set/way cache maintenance to a virtual machine is unsafe, not
least because the instructions are not permission-checked but also
because they are not broadcast between CPUs. Consequently, KVM traps and
emulates such maintenance in the host kernel using by-VA operations and
looping over the stage-2 page-tables. However, when running under
protected KVM, these instructions are not able to be emulated and will
instead result in an exception being delivered to the guest.

Introduce CONFIG_CMO_BY_VA_ONLY so that virtual platforms can select
this option and perform by-VA cache maintenance instead of using the
set/way instructions.

Marc Zyngier (1):
  arm: cpu: Add optional CMOs by VA

Pierre-Clément Tosi (1):
  arm64: Initialize TLB memory if CMO_BY_VA_ONLY

v2: Fix the Signed-off-by list.

 arch/arm/cpu/armv8/Kconfig|  4 ++
 arch/arm/cpu/armv8/cache.S| 50 +-
 arch/arm/cpu/armv8/cache_v8.c | 97 ++-
 arch/arm/cpu/armv8/cpu.c  | 30 +++
 arch/arm/lib/cache.c  |  9 
 5 files changed, 164 insertions(+), 26 deletions(-)

-- 
2.39.1



[PATCH 2/2] arm64: Initialize TLB memory if CMO_BY_VA_ONLY

2023-02-07 Thread Ying-Chun Liu (PaulLiu)
Memory used to hold the page tables is allocated from the top of RAM
with no prior initialization and could therefore hold invalid data. As
invalidate_dcache_all() will be called before the MMU has been
initialized and as that function relies indirectly on the page tables
when using CMO_BY_VA_ONLY, these must be in a valid state from their
allocation.

Signed-off-by: Ying-Chun Liu (PaulLiu) 
Signed-off-by: Pierre-Clément Tosi 
Cc: Tom Rini 
---
 arch/arm/lib/cache.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/lib/cache.c b/arch/arm/lib/cache.c
index 1a589c7e2a..7a16015867 100644
--- a/arch/arm/lib/cache.c
+++ b/arch/arm/lib/cache.c
@@ -159,6 +159,15 @@ __weak int arm_reserve_mmu(void)
 */
gd->arch.tlb_allocated = gd->arch.tlb_addr;
 #endif
+
+   if (IS_ENABLED(CONFIG_CMO_BY_VA_ONLY)) {
+   /*
+* As invalidate_dcache_all() will be called before
+* mmu_setup(), we should make sure that the PTs are
+* already in a valid state.
+*/
+   memset((void *)gd->arch.tlb_addr, 0, gd->arch.tlb_size);
+   }
 #endif
 
return 0;
-- 
2.39.1



[PATCH 1/2] arm: cpu: Add optional CMOs by VA

2023-02-07 Thread Ying-Chun Liu (PaulLiu)
Exposing set/way cache maintenance to a virtual machine is unsafe, not
least because the instructions are not permission-checked but also
because they are not broadcast between CPUs. Consequently, KVM traps and
emulates such maintenance in the host kernel using by-VA operations and
looping over the stage-2 page-tables. However, when running under
protected KVM, these instructions are not able to be emulated and will
instead result in an exception being delivered to the guest.

Introduce CONFIG_CMO_BY_VA_ONLY so that virtual platforms can select
this option and perform by-VA cache maintenance instead of using the
set/way instructions.

Signed-off-by: Ying-Chun Liu (PaulLiu) 
Signed-off-by: Marc Zyngier 
Signed-off-by: Will Deacon 
Cc: Tom Rini 
---
 arch/arm/cpu/armv8/Kconfig|  4 ++
 arch/arm/cpu/armv8/cache.S| 50 +-
 arch/arm/cpu/armv8/cache_v8.c | 97 ++-
 arch/arm/cpu/armv8/cpu.c  | 30 +++
 4 files changed, 155 insertions(+), 26 deletions(-)

diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig
index 1305238c9d..7d5cf1594d 100644
--- a/arch/arm/cpu/armv8/Kconfig
+++ b/arch/arm/cpu/armv8/Kconfig
@@ -1,5 +1,9 @@
 if ARM64
 
+config CMO_BY_VA_ONLY
+   bool "Force cache maintenance to be exclusively by VA"
+   depends on !SYS_DISABLE_DCACHE_OPS
+
 config ARMV8_SPL_EXCEPTION_VECTORS
bool "Install crash dump exception vectors"
depends on SPL
diff --git a/arch/arm/cpu/armv8/cache.S b/arch/arm/cpu/armv8/cache.S
index d1cee23437..3fe935cf28 100644
--- a/arch/arm/cpu/armv8/cache.S
+++ b/arch/arm/cpu/armv8/cache.S
@@ -12,6 +12,7 @@
 #include 
 #include 
 
+#ifndef CONFIG_CMO_BY_VA_ONLY
 /*
  * void __asm_dcache_level(level)
  *
@@ -116,6 +117,41 @@ ENTRY(__asm_invalidate_dcache_all)
 ENDPROC(__asm_invalidate_dcache_all)
 .popsection
 
+.pushsection .text.__asm_flush_l3_dcache, "ax"
+WEAK(__asm_flush_l3_dcache)
+   mov x0, #0  /* return status as success */
+   ret
+ENDPROC(__asm_flush_l3_dcache)
+.popsection
+
+.pushsection .text.__asm_invalidate_l3_icache, "ax"
+WEAK(__asm_invalidate_l3_icache)
+   mov x0, #0  /* return status as success */
+   ret
+ENDPROC(__asm_invalidate_l3_icache)
+.popsection
+
+#else  /* CONFIG_CMO_BY_VA */
+
+/*
+ * Define these so that they actively clash with in implementation
+ * accidentally selecting CONFIG_CMO_BY_VA
+ */
+
+.pushsection .text.__asm_invalidate_l3_icache, "ax"
+ENTRY(__asm_invalidate_l3_icache)
+   mov x0, xzr
+   ret
+ENDPROC(__asm_invalidate_l3_icache)
+.popsection
+.pushsection .text.__asm_flush_l3_dcache, "ax"
+ENTRY(__asm_flush_l3_dcache)
+   mov x0, xzr
+   ret
+ENDPROC(__asm_flush_l3_dcache)
+.popsection
+#endif /* CONFIG_CMO_BY_VA */
+
 /*
  * void __asm_flush_dcache_range(start, end)
  *
@@ -189,20 +225,6 @@ WEAK(__asm_invalidate_l3_dcache)
 ENDPROC(__asm_invalidate_l3_dcache)
 .popsection
 
-.pushsection .text.__asm_flush_l3_dcache, "ax"
-WEAK(__asm_flush_l3_dcache)
-   mov x0, #0  /* return status as success */
-   ret
-ENDPROC(__asm_flush_l3_dcache)
-.popsection
-
-.pushsection .text.__asm_invalidate_l3_icache, "ax"
-WEAK(__asm_invalidate_l3_icache)
-   mov x0, #0  /* return status as success */
-   ret
-ENDPROC(__asm_invalidate_l3_icache)
-.popsection
-
 /*
  * void __asm_switch_ttbr(ulong new_ttbr)
  *
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index 2a226fd063..f333ad8889 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -163,6 +163,83 @@ static u64 *find_pte(u64 addr, int level)
return NULL;
 }
 
+#ifdef CONFIG_CMO_BY_VA_ONLY
+static void __cmo_on_leaves(void (*cmo_fn)(unsigned long, unsigned long),
+   u64 pte, int level, u64 base)
+{
+   u64 *ptep;
+   int i;
+
+   ptep = (u64 *)(pte & GENMASK_ULL(47, PAGE_SHIFT));
+   for (i = 0; i < PAGE_SIZE / sizeof(u64); i++) {
+   u64 end, va = base + i * BIT(level2shift(level));
+   u64 type, attrs;
+
+   pte = ptep[i];
+   type = pte & PTE_TYPE_MASK;
+   attrs = pte & PMD_ATTRINDX_MASK;
+   debug("PTE %llx at level %d VA %llx\n", pte, level, va);
+
+   /* Not valid? next! */
+   if (!(type & PTE_TYPE_VALID))
+   continue;
+
+   /* Not a leaf? Recurse on the next level */
+   if (!(type == PTE_TYPE_BLOCK ||
+ (level == 3 && type == PTE_TYPE_PAGE))) {
+   __cmo_on_leaves(cmo_fn, pte, level + 1, va);
+   continue;
+   }
+
+   /*
+* From this point, this must be a leaf.
+*
+ 

[PATCH 0/2] arm: cpu: Add optional CMOs by VA

2023-02-07 Thread Ying-Chun Liu (PaulLiu)
Exposing set/way cache maintenance to a virtual machine is unsafe, not
least because the instructions are not permission-checked but also
because they are not broadcast between CPUs. Consequently, KVM traps and
emulates such maintenance in the host kernel using by-VA operations and
looping over the stage-2 page-tables. However, when running under
protected KVM, these instructions are not able to be emulated and will
instead result in an exception being delivered to the guest.

Introduce CONFIG_CMO_BY_VA_ONLY so that virtual platforms can select
this option and perform by-VA cache maintenance instead of using the
set/way instructions.

Ying-Chun Liu (PaulLiu) (2):
  arm: cpu: Add optional CMOs by VA
  arm64: Initialize TLB memory if CMO_BY_VA_ONLY

 arch/arm/cpu/armv8/Kconfig|  4 ++
 arch/arm/cpu/armv8/cache.S| 50 +-
 arch/arm/cpu/armv8/cache_v8.c | 97 ++-
 arch/arm/cpu/armv8/cpu.c  | 30 +++
 arch/arm/lib/cache.c  |  9 
 5 files changed, 164 insertions(+), 26 deletions(-)

-- 
2.39.1



[PATCH v4 2/2] dts: imx8mp-rsb3720: modify configrations to load fip into memory

2023-01-17 Thread Ying-Chun Liu (PaulLiu)
The changes of commit 6a21c695213b ("arm: dts: imx8mp: add of-list
support to common imx8mp-u-boot.dtsi") breaks the loading of the fip.
This commit fixes the break by modify the configuration properly.

Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Stefano Babic 
Cc: Fabio Estevam 
Cc: NXP i.MX U-Boot Team 
---
v2: just rebase to the latest master branch.
v3: rebase to the latest master branch.
---
 arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi 
b/arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi
index 4419967ee4..32d9fbc886 100644
--- a/arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi
+++ b/arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi
@@ -158,12 +158,10 @@
};
};
};
-
-   configurations {
-   conf {
-   loadables = "atf", "fip";
-   };
-   };
};
};
 };
+
+_configuration {
+   loadables = "atf", "fip";
+};
-- 
2.39.0



[PATCH v4 1/2] dts: imx8mp: assign binman_configuration label to config-SEQ

2023-01-17 Thread Ying-Chun Liu (PaulLiu)
assign a label for config-SEQ so that the board dts can modify
the configuration more easily.

Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Stefano Babic 
Cc: Fabio Estevam 
Cc: NXP i.MX U-Boot Team 
---
v2: just rebase to the latest master branch.
v3: rebase to the latest master branch.
v4: fix subject and commit log: node name -> label
---
 arch/arm/dts/imx8mp-u-boot.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/dts/imx8mp-u-boot.dtsi b/arch/arm/dts/imx8mp-u-boot.dtsi
index f9883aa133..cb9b5b649a 100644
--- a/arch/arm/dts/imx8mp-u-boot.dtsi
+++ b/arch/arm/dts/imx8mp-u-boot.dtsi
@@ -148,7 +148,7 @@
configurations {
default = "@config-DEFAULT-SEQ";
 
-   @config-SEQ {
+   binman_configuration: @config-SEQ {
description = "NAME";
fdt = "fdt-SEQ";
firmware = "uboot";
-- 
2.39.0



[PATCH v4 0/2] dts: imx8mp-rsb3720: modify configrations to load fip into memory

2023-01-17 Thread Ying-Chun Liu (PaulLiu)
The changes of commit 6a21c695213b ("arm: dts: imx8mp: add of-list
support to common imx8mp-u-boot.dtsi") breaks the loading of the fip.
This commit fixes the break by modify the configuration properly.

v2: just rebase to the latest master branch.
v3: rebase to the latest master branch.
v4: fix subject and commit log: node name -> label

Ying-Chun Liu (PaulLiu) (2):
  dts: imx8mp: assign binman_configuration label to config-SEQ
  dts: imx8mp-rsb3720: modify configrations to load fip into memory

 arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi | 10 --
 arch/arm/dts/imx8mp-u-boot.dtsi|  2 +-
 2 files changed, 5 insertions(+), 7 deletions(-)

-- 
2.39.0



[PATCH v3 2/2] dts: imx8mp-rsb3720: modify configrations to load fip into memory

2023-01-17 Thread Ying-Chun Liu (PaulLiu)
The changes of commit 6a21c695213b ("arm: dts: imx8mp: add of-list
support to common imx8mp-u-boot.dtsi") breaks the loading of the fip.
This commit fixes the break by modify the configuration properly.

Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Stefano Babic 
Cc: Fabio Estevam 
Cc: NXP i.MX U-Boot Team 
---
 arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi 
b/arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi
index 4419967ee4..32d9fbc886 100644
--- a/arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi
+++ b/arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi
@@ -158,12 +158,10 @@
};
};
};
-
-   configurations {
-   conf {
-   loadables = "atf", "fip";
-   };
-   };
};
};
 };
+
+_configuration {
+   loadables = "atf", "fip";
+};
-- 
2.39.0



[PATCH v3 1/2] dts: imx8mp: assign binman_configuration node name to config-SEQ

2023-01-17 Thread Ying-Chun Liu (PaulLiu)
assign a node name for config-SEQ so that the board dts can modify
the configuration more easily.

Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Stefano Babic 
Cc: Fabio Estevam 
Cc: NXP i.MX U-Boot Team 
---
v2: just rebase to the latest master branch.
v3: rebase to the latest master branch.
---
 arch/arm/dts/imx8mp-u-boot.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/dts/imx8mp-u-boot.dtsi b/arch/arm/dts/imx8mp-u-boot.dtsi
index f9883aa133..cb9b5b649a 100644
--- a/arch/arm/dts/imx8mp-u-boot.dtsi
+++ b/arch/arm/dts/imx8mp-u-boot.dtsi
@@ -148,7 +148,7 @@
configurations {
default = "@config-DEFAULT-SEQ";
 
-   @config-SEQ {
+   binman_configuration: @config-SEQ {
description = "NAME";
fdt = "fdt-SEQ";
firmware = "uboot";
-- 
2.39.0



[PATCH v3 0/2] dts: imx8mp-rsb3720: modify configrations to load fip into memory

2023-01-17 Thread Ying-Chun Liu (PaulLiu)
The changes of commit 6a21c695213b ("arm: dts: imx8mp: add of-list
support to common imx8mp-u-boot.dtsi") breaks the loading of the fip.
This commit fixes the break by modify the configuration properly.

v2: just rebase to the latest master branch.
v3: rebase to the latest master branch.

Ying-Chun Liu (PaulLiu) (2):
  dts: imx8mp: assign binman_configuration node name to config-SEQ
  dts: imx8mp-rsb3720: modify configrations to load fip into memory

 arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi | 10 --
 arch/arm/dts/imx8mp-u-boot.dtsi|  2 +-
 2 files changed, 5 insertions(+), 7 deletions(-)

-- 
2.39.0



Re: [PATCH v20 2/4] net: Add wget application

2022-11-08 Thread Ying-Chun Liu (PaulLiu)




On 2022/11/9 05:03, Sean Anderson wrote:

On 11/8/22 01:17, Ying-Chun Liu (PaulLiu) wrote:

From: "Ying-Chun Liu (PaulLiu)" 

This commit adds a simple wget command that can download files
from http server.

The command syntax is
wget ${loadaddr} 

Signed-off-by: Duncan Hare 
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Reviewed-by: Simon Glass 
Cc: Christian Gmeiner 
Cc: Joe Hershberger 
Cc: Michal Simek 
Cc: Ramon Fried 
---
v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
  Remove magic numbers. Use kernel-doc format.
v16: Add more kernel-doc. Fix more double spaces.
v17: Fix wget with address timeout issue reported by Ramon.
v20: Rebase to latest master and resolve conflict.
---
  cmd/Kconfig|   7 +
  cmd/net.c  |  13 ++
  include/net.h  |   2 +-
  include/net/wget.h |  22 +++
  net/Makefile   |   1 +
  net/net.c  |   6 +
  net/wget.c | 438 +
  7 files changed, 488 insertions(+), 1 deletion(-)
  create mode 100644 include/net/wget.h
  create mode 100644 net/wget.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 105406496e..d093581b24 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1798,6 +1798,13 @@ config SYS_DISABLE_AUTOLOAD
  is complete.  Enable this option to disable this behavior and instead
  require files to be loaded over the network by subsequent commands.
  
+config CMD_WGET

+   bool "wget"
+   select TCP
+   help
+ wget is a simple command to download kernel, or other files,
+ from a http server over TCP.
+
  config CMD_MII
bool "mii"
imply CMD_MDIO
diff --git a/cmd/net.c b/cmd/net.c
index addcad3ac1..f6d9f5ea3a 100644
--- a/cmd/net.c
+++ b/cmd/net.c
@@ -125,6 +125,19 @@ U_BOOT_CMD(
  );
  #endif
  
+#if defined(CONFIG_CMD_WGET)

+static int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const 
argv[])
+{
+   return netboot_common(WGET, cmdtp, argc, argv);
+}
+
+U_BOOT_CMD(
+   wget,   3,  1,  do_wget,
+   "boot image via network using HTTP protocol",
+   "[loadAddress] [[hostIPaddr:]path and image name]"
+);
+#endif
+
  static void netboot_update_env(void)
  {
char tmp[22];
diff --git a/include/net.h b/include/net.h
index f4140523c2..e0c7804827 100644
--- a/include/net.h
+++ b/include/net.h
@@ -561,7 +561,7 @@ extern int  net_restart_wrap;   /* Tried all 
network devices */
  
  enum proto_t {

BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP, NCSI
+   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP, NCSI, WGET
  };
  
  extern char	net_boot_file_name[1024];/* Boot File name */

diff --git a/include/net/wget.h b/include/net/wget.h
new file mode 100644
index 00..da0920de11
--- /dev/null
+++ b/include/net/wget.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Duncan Hare Copyright 2017
+ */
+
+/**
+ * wget_start() - begin wget
+ */
+void wget_start(void);
+
+enum wget_state {
+   WGET_CLOSED,
+   WGET_CONNECTING,
+   WGET_CONNECTED,
+   WGET_TRANSFERRING,
+   WGET_TRANSFERRED
+};
+
+#define DEBUG_WGET 0   /* Set to 1 for debug messages */
+#define SERVER_PORT80
+#define WGET_RETRY_COUNT   30
+#define WGET_TIMEOUT   2000UL
diff --git a/net/Makefile b/net/Makefile
index d131d1cb1a..4f757a224c 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_UDP_FUNCTION_FASTBOOT)  += fastboot.o
  obj-$(CONFIG_CMD_WOL)  += wol.o
  obj-$(CONFIG_PROT_UDP) += udp.o
  obj-$(CONFIG_PROT_TCP) += tcp.o
+obj-$(CONFIG_CMD_WGET) += wget.o
  
  # Disable this warning as it is triggered by:

  # sprintf(buf, index ? "foo%d" : "foo", index)
diff --git a/net/net.c b/net/net.c
index 7878a9970b..8c630f9467 100644
--- a/net/net.c
+++ b/net/net.c
@@ -118,6 +118,7 @@
  #include "wol.h"
  #endif
  #include 
+#include 
  
  /** BOOTP EXTENTIONS **/
  
@@ -517,6 +518,11 @@ restart:

nfs_start();
break;
  #endif
+#if defined(CONFIG_CMD_WGET)
+   case WGET:
+   wget_start();
+   break;
+#endif
  #if defined(CONFIG_CMD_CDP)
case CDP:
cdp_start();
diff --git a/net/wget.c b/net/wget.c
new file mode 100644
index 00..3826c4b364
--- /dev/null
+++ b/net/wget.c
@@ -0,0 +1,438 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * WGET/HTTP support driver based on U-BOOT's nfs.c
+ * Copyright Duncan Hare  2017
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const char bootfile1[] = "GET ";
+static const char bootfile3[] = " HTT

[PATCH v20 4/4] test: cmd: add test for wget command.

2022-11-07 Thread Ying-Chun Liu (PaulLiu)
From: "Ying-Chun Liu (PaulLiu)" 

Simulate a TCP HTTP server's response for testing wget command.

Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Christian Gmeiner 
Cc: Joe Hershberger 
Cc: Michal Simek 
Cc: Ramon Fried 
Cc: Simon Glass 
---
 test/cmd/Makefile |   1 +
 test/cmd/wget.c   | 206 ++
 2 files changed, 207 insertions(+)
 create mode 100644 test/cmd/wget.c

diff --git a/test/cmd/Makefile b/test/cmd/Makefile
index 6dd6e81875..bc961df3dc 100644
--- a/test/cmd/Makefile
+++ b/test/cmd/Makefile
@@ -20,3 +20,4 @@ ifdef CONFIG_SANDBOX
 obj-$(CONFIG_CMD_SETEXPR) += setexpr.o
 endif
 obj-$(CONFIG_CMD_TEMPERATURE) += temperature.o
+obj-$(CONFIG_CMD_WGET) += wget.o
diff --git a/test/cmd/wget.c b/test/cmd/wget.c
new file mode 100644
index 00..ed83fc94a5
--- /dev/null
+++ b/test/cmd/wget.c
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Linaro
+ *
+ * (C) Copyright 2022
+ * Ying-Chun Liu (PaulLiu) 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define SHIFT_TO_TCPHDRLEN_FIELD(x) ((x) << 4)
+#define LEN_B_TO_DW(x) ((x) >> 2)
+
+static int sb_arp_handler(struct udevice *dev, void *packet,
+ unsigned int len)
+{
+   struct eth_sandbox_priv *priv = dev_get_priv(dev);
+   struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
+   int ret = 0;
+
+   if (ntohs(arp->ar_op) == ARPOP_REQUEST) {
+   priv->fake_host_ipaddr = net_read_ip(>ar_spa);
+
+   ret = sandbox_eth_recv_arp_req(dev);
+   if (ret)
+   return ret;
+   ret = sandbox_eth_arp_req_to_reply(dev, packet, len);
+   return ret;
+   }
+
+   return -EPROTONOSUPPORT;
+}
+
+static int sb_syn_handler(struct udevice *dev, void *packet,
+ unsigned int len)
+{
+   struct eth_sandbox_priv *priv = dev_get_priv(dev);
+   struct ethernet_hdr *eth = packet;
+   struct ip_tcp_hdr *tcp = packet + ETHER_HDR_SIZE;
+   struct ethernet_hdr *eth_send;
+   struct ip_tcp_hdr *tcp_send;
+
+   /* Don't allow the buffer to overrun */
+   if (priv->recv_packets >= PKTBUFSRX)
+   return 0;
+
+   eth_send = (void *)priv->recv_packet_buffer[priv->recv_packets];
+   memcpy(eth_send->et_dest, eth->et_src, ARP_HLEN);
+   memcpy(eth_send->et_src, priv->fake_host_hwaddr, ARP_HLEN);
+   eth_send->et_protlen = htons(PROT_IP);
+   tcp_send = (void *)eth_send + ETHER_HDR_SIZE;
+   tcp_send->tcp_src = tcp->tcp_dst;
+   tcp_send->tcp_dst = tcp->tcp_src;
+   tcp_send->tcp_seq = htonl(0);
+   tcp_send->tcp_ack = htonl(ntohl(tcp->tcp_seq) + 1);
+   tcp_send->tcp_hlen = 
SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE));
+   tcp_send->tcp_flags = TCP_SYN | TCP_ACK;
+   tcp_send->tcp_win = htons(PKTBUFSRX * TCP_MSS >> TCP_SCALE);
+   tcp_send->tcp_xsum = 0;
+   tcp_send->tcp_ugr = 0;
+   tcp_send->tcp_xsum = tcp_set_pseudo_header((uchar *)tcp_send,
+  tcp->ip_src,
+  tcp->ip_dst,
+  TCP_HDR_SIZE,
+  IP_TCP_HDR_SIZE);
+   net_set_ip_header((uchar *)tcp_send,
+ tcp->ip_src,
+ tcp->ip_dst,
+ IP_TCP_HDR_SIZE,
+ IPPROTO_TCP);
+
+   priv->recv_packet_length[priv->recv_packets] =
+   ETHER_HDR_SIZE + IP_TCP_HDR_SIZE;
+   ++priv->recv_packets;
+
+   return 0;
+}
+
+static int sb_ack_handler(struct udevice *dev, void *packet,
+ unsigned int len)
+{
+   struct eth_sandbox_priv *priv = dev_get_priv(dev);
+   struct ethernet_hdr *eth = packet;
+   struct ip_tcp_hdr *tcp = packet + ETHER_HDR_SIZE;
+   struct ethernet_hdr *eth_send;
+   struct ip_tcp_hdr *tcp_send;
+   void *data;
+   int pkt_len;
+   int payload_len = 0;
+   const char *payload1 = "HTTP/1.1 200 OK\r\n"
+   "Content-Length: 30\r\n\r\n\r\n"
+   "Hi\r\n";
+
+   /* Don't allow the buffer to overrun */
+   if (priv->recv_packets >= PKTBUFSRX)
+   return 0;
+
+   eth_send = (void *)priv->recv_packet_buffer[priv->recv_packets];
+   memcpy(eth_send->et_dest, eth->et_src, ARP_HLEN);
+   memcpy(eth_send->et_src, priv->fake_host_hwaddr, ARP_HLEN);
+   eth_send->et_protlen = htons(PROT_IP);
+   tcp_send = (void *)eth_send + ETHER_HDR_SIZE;
+   tcp_send->

[PATCH v20 3/4] doc: cmd: wget: add documentation

2022-11-07 Thread Ying-Chun Liu (PaulLiu)
From: "Ying-Chun Liu (PaulLiu)" 

Add documentation for the wget command.

Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Christian Gmeiner 
Cc: Joe Hershberger 
Cc: Michal Simek 
Cc: Ramon Fried 
Cc: Simon Glass 
---
 doc/usage/cmd/wget.rst | 61 ++
 doc/usage/index.rst|  1 +
 2 files changed, 62 insertions(+)
 create mode 100644 doc/usage/cmd/wget.rst

diff --git a/doc/usage/cmd/wget.rst b/doc/usage/cmd/wget.rst
new file mode 100644
index 00..4fcfa03954
--- /dev/null
+++ b/doc/usage/cmd/wget.rst
@@ -0,0 +1,61 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+wget command
+
+
+Synopsis
+
+
+::
+wget address [[hostIPaddr:]path]
+
+Description
+---
+
+The wget command is used to download a file from an HTTP server.
+
+wget command will use HTTP over TCP to download files from an HTTP server.
+Currently it can only download image from an HTTP server hosted on port 80.
+
+address
+memory address for the data downloaded
+
+hostIPaddr
+IP address of the HTTP server, defaults to the value of environment
+variable *serverip*
+
+path
+path of the file to be downloaded.
+
+Example
+---
+
+In the example the following steps are executed:
+
+* setup client network address
+* download a file from the HTTP server
+
+::
+
+=> setenv autoload no
+=> dhcp
+BOOTP broadcast 1
+*** Unhandled DHCP Option in OFFER/ACK: 23
+*** Unhandled DHCP Option in OFFER/ACK: 23
+DHCP client bound to address 192.168.1.105 (210 ms)
+=> wget ${loadaddr} 192.168.1.254:/index.html
+HTTP/1.0 302 Found
+Packets received 4, Transfer Successful
+
+Configuration
+-
+
+The command is only available if CONFIG_CMD_WGET=y.
+
+CONFIG_PROT_TCP_SACK can be turned on for the TCP SACK options. This will
+help increasing the downloading speed.
+
+Return value
+
+
+The return value $? is 0 (true) on success and 1 (false) otherwise.
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index df50746c34..13ade7dffc 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -75,6 +75,7 @@ Shell commands
cmd/true
cmd/ums
cmd/wdt
+   cmd/wget
cmd/xxd
 
 Booting OS
-- 
2.35.1



[PATCH v20 2/4] net: Add wget application

2022-11-07 Thread Ying-Chun Liu (PaulLiu)
From: "Ying-Chun Liu (PaulLiu)" 

This commit adds a simple wget command that can download files
from http server.

The command syntax is
wget ${loadaddr} 

Signed-off-by: Duncan Hare 
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Reviewed-by: Simon Glass 
Cc: Christian Gmeiner 
Cc: Joe Hershberger 
Cc: Michal Simek 
Cc: Ramon Fried 
---
v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.
v16: Add more kernel-doc. Fix more double spaces.
v17: Fix wget with address timeout issue reported by Ramon.
v20: Rebase to latest master and resolve conflict.
---
 cmd/Kconfig|   7 +
 cmd/net.c  |  13 ++
 include/net.h  |   2 +-
 include/net/wget.h |  22 +++
 net/Makefile   |   1 +
 net/net.c  |   6 +
 net/wget.c | 438 +
 7 files changed, 488 insertions(+), 1 deletion(-)
 create mode 100644 include/net/wget.h
 create mode 100644 net/wget.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 105406496e..d093581b24 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1798,6 +1798,13 @@ config SYS_DISABLE_AUTOLOAD
  is complete.  Enable this option to disable this behavior and instead
  require files to be loaded over the network by subsequent commands.
 
+config CMD_WGET
+   bool "wget"
+   select TCP
+   help
+ wget is a simple command to download kernel, or other files,
+ from a http server over TCP.
+
 config CMD_MII
bool "mii"
imply CMD_MDIO
diff --git a/cmd/net.c b/cmd/net.c
index addcad3ac1..f6d9f5ea3a 100644
--- a/cmd/net.c
+++ b/cmd/net.c
@@ -125,6 +125,19 @@ U_BOOT_CMD(
 );
 #endif
 
+#if defined(CONFIG_CMD_WGET)
+static int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const 
argv[])
+{
+   return netboot_common(WGET, cmdtp, argc, argv);
+}
+
+U_BOOT_CMD(
+   wget,   3,  1,  do_wget,
+   "boot image via network using HTTP protocol",
+   "[loadAddress] [[hostIPaddr:]path and image name]"
+);
+#endif
+
 static void netboot_update_env(void)
 {
char tmp[22];
diff --git a/include/net.h b/include/net.h
index f4140523c2..e0c7804827 100644
--- a/include/net.h
+++ b/include/net.h
@@ -561,7 +561,7 @@ extern int  net_restart_wrap;   /* Tried all 
network devices */
 
 enum proto_t {
BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP, NCSI
+   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP, NCSI, WGET
 };
 
 extern charnet_boot_file_name[1024];/* Boot File name */
diff --git a/include/net/wget.h b/include/net/wget.h
new file mode 100644
index 00..da0920de11
--- /dev/null
+++ b/include/net/wget.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Duncan Hare Copyright 2017
+ */
+
+/**
+ * wget_start() - begin wget
+ */
+void wget_start(void);
+
+enum wget_state {
+   WGET_CLOSED,
+   WGET_CONNECTING,
+   WGET_CONNECTED,
+   WGET_TRANSFERRING,
+   WGET_TRANSFERRED
+};
+
+#define DEBUG_WGET 0   /* Set to 1 for debug messages */
+#define SERVER_PORT80
+#define WGET_RETRY_COUNT   30
+#define WGET_TIMEOUT   2000UL
diff --git a/net/Makefile b/net/Makefile
index d131d1cb1a..4f757a224c 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_UDP_FUNCTION_FASTBOOT)  += fastboot.o
 obj-$(CONFIG_CMD_WOL)  += wol.o
 obj-$(CONFIG_PROT_UDP) += udp.o
 obj-$(CONFIG_PROT_TCP) += tcp.o
+obj-$(CONFIG_CMD_WGET) += wget.o
 
 # Disable this warning as it is triggered by:
 # sprintf(buf, index ? "foo%d" : "foo", index)
diff --git a/net/net.c b/net/net.c
index 7878a9970b..8c630f9467 100644
--- a/net/net.c
+++ b/net/net.c
@@ -118,6 +118,7 @@
 #include "wol.h"
 #endif
 #include 
+#include 
 
 /** BOOTP EXTENTIONS **/
 
@@ -517,6 +518,11 @@ restart:
nfs_start();
break;
 #endif
+#if defined(CONFIG_CMD_WGET)
+   case WGET:
+   wget_start();
+   break;
+#endif
 #if defined(CONFIG_CMD_CDP)
case CDP:
cdp_start();
diff --git a/net/wget.c b/net/wget.c
new file mode 100644
index 00..3826c4b364
--- /dev/null
+++ b/net/wget.c
@@ -0,0 +1,438 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * WGET/HTTP support driver based on U-BOOT's nfs.c
+ * Copyright Duncan Hare  2017
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const char bootfile1[] = "GET ";
+static const char bootfile3[] = " HTTP/1.0\r\n\r\n";
+static const char http_eom[] = "\r\n\r\n";
+static const char http_ok[] = "200";
+static c

[PATCH v20 1/4] net: Add TCP protocol

2022-11-07 Thread Ying-Chun Liu (PaulLiu)
From: "Ying-Chun Liu (PaulLiu)" 

Currently file transfers are done using tftp or NFS both
over udp. This requires a request to be sent from client
(u-boot) to the boot server.

The current standard is TCP with selective acknowledgment.

Signed-off-by: Duncan Hare 
Signed-off-by: Duncan Hare 
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Reviewed-by: Simon Glass 
Cc: Christian Gmeiner 
Cc: Joe Hershberger 
Cc: Michal Simek 
Cc: Ramon Fried 
---
v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.
v16: Add more kernel-doc. Fix more double spaces.
v19: export tcp_set_pseudo_header() for unit test.
---
 include/net.h |  36 ++-
 include/net/tcp.h | 299 +++
 net/Kconfig   |  16 ++
 net/Makefile  |   1 +
 net/net.c |  30 ++
 net/tcp.c | 720 ++
 6 files changed, 1093 insertions(+), 9 deletions(-)
 create mode 100644 include/net/tcp.h
 create mode 100644 net/tcp.c

diff --git a/include/net.h b/include/net.h
index 32364ed0ce..f4140523c2 100644
--- a/include/net.h
+++ b/include/net.h
@@ -365,6 +365,7 @@ struct vlan_ethernet_hdr {
 #define PROT_NCSI  0x88f8  /* NC-SI control packets*/
 
 #define IPPROTO_ICMP1  /* Internet Control Message Protocol*/
+#define IPPROTO_TCP6   /* Transmission Control Protocol*/
 #define IPPROTO_UDP17  /* User Datagram Protocol   */
 
 /*
@@ -690,19 +691,36 @@ static inline void net_send_packet(uchar *pkt, int len)
(void) eth_send(pkt, len);
 }
 
-/*
- * Transmit "net_tx_packet" as UDP packet, performing ARP request if needed
- *  (ether will be populated)
- *
- * @param ether Raw packet buffer
- * @param dest IP address to send the datagram to
- * @param dport Destination UDP port
- * @param sport Source UDP port
- * @param payload_len Length of data after the UDP header
+/**
+ * net_send_ip_packet() - Transmit "net_tx_packet" as UDP or TCP packet,
+ *send ARP request if needed (ether will be populated)
+ * @ether: Raw packet buffer
+ * @dest: IP address to send the datagram to
+ * @dport: Destination UDP port
+ * @sport: Source UDP port
+ * @payload_len: Length of data after the UDP header
+ * @action: TCP action to be performed
+ * @tcp_seq_num: TCP sequence number of this transmission
+ * @tcp_ack_num: TCP stream acknolegement number
+ *
+ * Return: 0 on success, other value on failure
  */
 int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport,
   int payload_len, int proto, u8 action, u32 tcp_seq_num,
   u32 tcp_ack_num);
+/**
+ * net_send_tcp_packet() - Transmit TCP packet.
+ * @payload_len: length of payload
+ * @dport: Destination TCP port
+ * @sport: Source TCP port
+ * @action: TCP action to be performed
+ * @tcp_seq_num: TCP sequence number of this transmission
+ * @tcp_ack_num: TCP stream acknolegement number
+ *
+ * Return: 0 on success, other value on failure
+ */
+int net_send_tcp_packet(int payload_len, int dport, int sport, u8 action,
+   u32 tcp_seq_num, u32 tcp_ack_num);
 int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport,
int sport, int payload_len);
 
diff --git a/include/net/tcp.h b/include/net/tcp.h
new file mode 100644
index 00..322551694f
--- /dev/null
+++ b/include/net/tcp.h
@@ -0,0 +1,299 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * TCP Support with SACK for file transfer.
+ *
+ * Copyright 2017 Duncan Hare, All rights reserved.
+ */
+
+#define TCP_ACTIVITY 127   /* Number of packets received   */
+   /* before console progress mark */
+/**
+ * struct ip_tcp_hdr - IP and TCP header
+ * @ip_hl_v: header length and version
+ * @ip_tos: type of service
+ * @ip_len: total length
+ * @ip_id: identification
+ * @ip_off: fragment offset field
+ * @ip_ttl: time to live
+ * @ip_p: protocol
+ * @ip_sum: checksum
+ * @ip_src: Source IP address
+ * @ip_dst: Destination IP address
+ * @tcp_src: TCP source port
+ * @tcp_dst: TCP destination port
+ * @tcp_seq: TCP sequence number
+ * @tcp_ack: TCP Acknowledgment number
+ * @tcp_hlen: 4 bits TCP header Length/4, 4 bits reserved, 2 more bits reserved
+ * @tcp_flag: flags of TCP
+ * @tcp_win: TCP windows size
+ * @tcp_xsum: Checksum
+ * @tcp_ugr: Pointer to urgent data
+ */
+struct ip_tcp_hdr {
+   u8  ip_hl_v;
+   u8  ip_tos;
+   u16 ip_len;
+   u16 ip_id;
+   u16 ip_off;
+   u8  ip_ttl;
+   u8  ip_p;
+   u16 ip_sum;
+   struct in_addr  ip_src;
+   struct in_addr  ip_dst;
+   u16 tcp_src;
+   u16   

[PATCH v20 0/4] add TCP and HTTP for downloading images

2022-11-07 Thread Ying-Chun Liu (PaulLiu)
From: "Ying-Chun Liu (PaulLiu)" 

This patch is a refresh from previous patches made by
Duncan Hare . I've contacted him and
continue to work on this patch.

This patch introduce a TCP stack with SACK. And a simple wget command
to download images from http server.

v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.
v16: Add more kernel-doc. Fix more double spaces.
v17: Fix wget with address timeout issue reported by Ramon.
v18: Add documentation for wget command.
v19: Add unit test for wget command.
v20: Rebase to latest master and resolve conflict.

Ying-Chun Liu (PaulLiu) (4):
  net: Add TCP protocol
  net: Add wget application
  doc: cmd: wget: add documentation
  test: cmd: add test for wget command.

 cmd/Kconfig|   7 +
 cmd/net.c  |  13 +
 doc/usage/cmd/wget.rst |  61 
 doc/usage/index.rst|   1 +
 include/net.h  |  38 ++-
 include/net/tcp.h  | 299 +
 include/net/wget.h |  22 ++
 net/Kconfig|  16 +
 net/Makefile   |   2 +
 net/net.c  |  36 +++
 net/tcp.c  | 720 +
 net/wget.c | 438 +
 test/cmd/Makefile  |   1 +
 test/cmd/wget.c| 206 
 14 files changed, 1850 insertions(+), 10 deletions(-)
 create mode 100644 doc/usage/cmd/wget.rst
 create mode 100644 include/net/tcp.h
 create mode 100644 include/net/wget.h
 create mode 100644 net/tcp.c
 create mode 100644 net/wget.c
 create mode 100644 test/cmd/wget.c

-- 
2.35.1



[PATCH 1/1] imx8m: ddr_init: fix reading of DDR4 MR registers

2022-10-19 Thread Ying-Chun Liu (PaulLiu)
Accorting to commit 290ffe57886271a6 we need to read more significant
bytes to get a non-zero value. However commit 7e9bd84883aeb1e2 removes
it by accident. Thus we add the changes back. This is needed to let
imx8mm-cl-iot-gate to boot correctly.

Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Fabio Estevam 
Cc: Marek Vasut 
Cc: Peng Fan 
Cc: Rasmus Villemoes 
Cc: Stefano Babic 
Cc: NXP i.MX U-Boot Team 
---
 drivers/ddr/imx/imx8m/ddr_init.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/ddr/imx/imx8m/ddr_init.c b/drivers/ddr/imx/imx8m/ddr_init.c
index d964184ddc..7a683b1d36 100644
--- a/drivers/ddr/imx/imx8m/ddr_init.c
+++ b/drivers/ddr/imx/imx8m/ddr_init.c
@@ -134,8 +134,14 @@ unsigned int lpddr4_mr_read(unsigned int mr_rank, unsigned 
int mr_addr)
tmp = reg32_read(DRC_PERF_MON_MRR0_DAT(0));
} while ((tmp & 0x8) == 0);
tmp = reg32_read(DRC_PERF_MON_MRR1_DAT(0));
-   tmp = tmp & 0xff;
reg32_write(DRC_PERF_MON_MRR0_DAT(0), 0x4);
+   while (tmp) { // try to find a significant byte in the word
+   if (tmp & 0xff) {
+   tmp &= 0xff;
+   break;
+   }
+   tmp >>= 8;
+   }
 
return tmp;
 }
-- 
2.35.1



[PATCH 0/1] imx8m: ddr_init: fix reading of DDR4 MR registers

2022-10-19 Thread Ying-Chun Liu (PaulLiu)
Accorting to commit 290ffe57886271a6 we need to read more significant
bytes to get a non-zero value. However commit 7e9bd84883aeb1e2 removes
it by accident. Thus we add the changes back. This is needed to let
imx8mm-cl-iot-gate to boot correctly.

Ying-Chun Liu (PaulLiu) (1):
  imx8m: ddr_init: fix reading of DDR4 MR registers

 drivers/ddr/imx/imx8m/ddr_init.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

-- 
2.35.1



[PATCH v19 2/4] net: Add wget application

2022-10-19 Thread Ying-Chun Liu (PaulLiu)
This commit adds a simple wget command that can download files
from http server.

The command syntax is
wget ${loadaddr} 

Signed-off-by: Duncan Hare 
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Reviewed-by: Simon Glass 
Cc: Christian Gmeiner 
Cc: Joe Hershberger 
Cc: Michal Simek 
Cc: Ramon Fried 
---
v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.
v16: Add more kernel-doc. Fix more double spaces.
v17: Fix wget with address timeout issue reported by Ramon.
---
 cmd/Kconfig|   7 +
 cmd/net.c  |  13 ++
 include/net.h  |   2 +-
 include/net/wget.h |  22 +++
 net/Makefile   |   1 +
 net/net.c  |   6 +
 net/wget.c | 438 +
 7 files changed, 488 insertions(+), 1 deletion(-)
 create mode 100644 include/net/wget.h
 create mode 100644 net/wget.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 49247a41c0..c1283d949f 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1791,6 +1791,13 @@ config SYS_DISABLE_AUTOLOAD
  is complete.  Enable this option to disable this behavior and instead
  require files to be loaded over the network by subsequent commands.
 
+config CMD_WGET
+   bool "wget"
+   select TCP
+   help
+ wget is a simple command to download kernel, or other files,
+ from a http server over TCP.
+
 config CMD_MII
bool "mii"
imply CMD_MDIO
diff --git a/cmd/net.c b/cmd/net.c
index 46f8c87b69..fb19d18b64 100644
--- a/cmd/net.c
+++ b/cmd/net.c
@@ -124,6 +124,19 @@ U_BOOT_CMD(
 );
 #endif
 
+#if defined(CONFIG_CMD_WGET)
+static int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const 
argv[])
+{
+   return netboot_common(WGET, cmdtp, argc, argv);
+}
+
+U_BOOT_CMD(
+   wget,   3,  1,  do_wget,
+   "boot image via network using HTTP protocol",
+   "[loadAddress] [[hostIPaddr:]path and image name]"
+);
+#endif
+
 static void netboot_update_env(void)
 {
char tmp[22];
diff --git a/include/net.h b/include/net.h
index 6d8d3fd971..5d52264360 100644
--- a/include/net.h
+++ b/include/net.h
@@ -561,7 +561,7 @@ extern int  net_restart_wrap;   /* Tried all 
network devices */
 
 enum proto_t {
BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP
+   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP, WGET
 };
 
 extern charnet_boot_file_name[1024];/* Boot File name */
diff --git a/include/net/wget.h b/include/net/wget.h
new file mode 100644
index 00..da0920de11
--- /dev/null
+++ b/include/net/wget.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Duncan Hare Copyright 2017
+ */
+
+/**
+ * wget_start() - begin wget
+ */
+void wget_start(void);
+
+enum wget_state {
+   WGET_CLOSED,
+   WGET_CONNECTING,
+   WGET_CONNECTED,
+   WGET_TRANSFERRING,
+   WGET_TRANSFERRED
+};
+
+#define DEBUG_WGET 0   /* Set to 1 for debug messages */
+#define SERVER_PORT80
+#define WGET_RETRY_COUNT   30
+#define WGET_TIMEOUT   2000UL
diff --git a/net/Makefile b/net/Makefile
index d131d1cb1a..4f757a224c 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_UDP_FUNCTION_FASTBOOT)  += fastboot.o
 obj-$(CONFIG_CMD_WOL)  += wol.o
 obj-$(CONFIG_PROT_UDP) += udp.o
 obj-$(CONFIG_PROT_TCP) += tcp.o
+obj-$(CONFIG_CMD_WGET) += wget.o
 
 # Disable this warning as it is triggered by:
 # sprintf(buf, index ? "foo%d" : "foo", index)
diff --git a/net/net.c b/net/net.c
index 5333cce57e..033ceda6e1 100644
--- a/net/net.c
+++ b/net/net.c
@@ -117,6 +117,7 @@
 #include "wol.h"
 #endif
 #include 
+#include 
 
 /** BOOTP EXTENTIONS **/
 
@@ -505,6 +506,11 @@ restart:
nfs_start();
break;
 #endif
+#if defined(CONFIG_CMD_WGET)
+   case WGET:
+   wget_start();
+   break;
+#endif
 #if defined(CONFIG_CMD_CDP)
case CDP:
cdp_start();
diff --git a/net/wget.c b/net/wget.c
new file mode 100644
index 00..3826c4b364
--- /dev/null
+++ b/net/wget.c
@@ -0,0 +1,438 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * WGET/HTTP support driver based on U-BOOT's nfs.c
+ * Copyright Duncan Hare  2017
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const char bootfile1[] = "GET ";
+static const char bootfile3[] = " HTTP/1.0\r\n\r\n";
+static const char http_eom[] = "\r\n\r\n";
+static const char http_ok[] = "200";
+static const char content_len[] = "Content-Length";
+static const char linefeed[] = "\r\n";

[PATCH v19 3/4] doc: cmd: wget: add documentation

2022-10-19 Thread Ying-Chun Liu (PaulLiu)
Add documentation for the wget command.

Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Simon Glass 
---
 doc/usage/cmd/wget.rst | 61 ++
 doc/usage/index.rst|  1 +
 2 files changed, 62 insertions(+)
 create mode 100644 doc/usage/cmd/wget.rst

diff --git a/doc/usage/cmd/wget.rst b/doc/usage/cmd/wget.rst
new file mode 100644
index 00..4fcfa03954
--- /dev/null
+++ b/doc/usage/cmd/wget.rst
@@ -0,0 +1,61 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+wget command
+
+
+Synopsis
+
+
+::
+wget address [[hostIPaddr:]path]
+
+Description
+---
+
+The wget command is used to download a file from an HTTP server.
+
+wget command will use HTTP over TCP to download files from an HTTP server.
+Currently it can only download image from an HTTP server hosted on port 80.
+
+address
+memory address for the data downloaded
+
+hostIPaddr
+IP address of the HTTP server, defaults to the value of environment
+variable *serverip*
+
+path
+path of the file to be downloaded.
+
+Example
+---
+
+In the example the following steps are executed:
+
+* setup client network address
+* download a file from the HTTP server
+
+::
+
+=> setenv autoload no
+=> dhcp
+BOOTP broadcast 1
+*** Unhandled DHCP Option in OFFER/ACK: 23
+*** Unhandled DHCP Option in OFFER/ACK: 23
+DHCP client bound to address 192.168.1.105 (210 ms)
+=> wget ${loadaddr} 192.168.1.254:/index.html
+HTTP/1.0 302 Found
+Packets received 4, Transfer Successful
+
+Configuration
+-
+
+The command is only available if CONFIG_CMD_WGET=y.
+
+CONFIG_PROT_TCP_SACK can be turned on for the TCP SACK options. This will
+help increasing the downloading speed.
+
+Return value
+
+
+The return value $? is 0 (true) on success and 1 (false) otherwise.
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 90221015ee..11f5fcfaff 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -73,6 +73,7 @@ Shell commands
cmd/true
cmd/ums
cmd/wdt
+   cmd/wget
cmd/xxd
 
 Booting OS
-- 
2.35.1



[PATCH v19 4/4] test: cmd: add test for wget command.

2022-10-19 Thread Ying-Chun Liu (PaulLiu)
Simulate a TCP HTTP server's response for testing wget command.

Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Simon Glass 
---
 test/cmd/Makefile |   1 +
 test/cmd/wget.c   | 206 ++
 2 files changed, 207 insertions(+)
 create mode 100644 test/cmd/wget.c

diff --git a/test/cmd/Makefile b/test/cmd/Makefile
index f2a5f4ed80..89bdfae907 100644
--- a/test/cmd/Makefile
+++ b/test/cmd/Makefile
@@ -19,3 +19,4 @@ ifdef CONFIG_SANDBOX
 obj-$(CONFIG_CMD_SETEXPR) += setexpr.o
 endif
 obj-$(CONFIG_CMD_TEMPERATURE) += temperature.o
+obj-$(CONFIG_CMD_WGET) += wget.o
diff --git a/test/cmd/wget.c b/test/cmd/wget.c
new file mode 100644
index 00..ed83fc94a5
--- /dev/null
+++ b/test/cmd/wget.c
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Linaro
+ *
+ * (C) Copyright 2022
+ * Ying-Chun Liu (PaulLiu) 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define SHIFT_TO_TCPHDRLEN_FIELD(x) ((x) << 4)
+#define LEN_B_TO_DW(x) ((x) >> 2)
+
+static int sb_arp_handler(struct udevice *dev, void *packet,
+ unsigned int len)
+{
+   struct eth_sandbox_priv *priv = dev_get_priv(dev);
+   struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
+   int ret = 0;
+
+   if (ntohs(arp->ar_op) == ARPOP_REQUEST) {
+   priv->fake_host_ipaddr = net_read_ip(>ar_spa);
+
+   ret = sandbox_eth_recv_arp_req(dev);
+   if (ret)
+   return ret;
+   ret = sandbox_eth_arp_req_to_reply(dev, packet, len);
+   return ret;
+   }
+
+   return -EPROTONOSUPPORT;
+}
+
+static int sb_syn_handler(struct udevice *dev, void *packet,
+ unsigned int len)
+{
+   struct eth_sandbox_priv *priv = dev_get_priv(dev);
+   struct ethernet_hdr *eth = packet;
+   struct ip_tcp_hdr *tcp = packet + ETHER_HDR_SIZE;
+   struct ethernet_hdr *eth_send;
+   struct ip_tcp_hdr *tcp_send;
+
+   /* Don't allow the buffer to overrun */
+   if (priv->recv_packets >= PKTBUFSRX)
+   return 0;
+
+   eth_send = (void *)priv->recv_packet_buffer[priv->recv_packets];
+   memcpy(eth_send->et_dest, eth->et_src, ARP_HLEN);
+   memcpy(eth_send->et_src, priv->fake_host_hwaddr, ARP_HLEN);
+   eth_send->et_protlen = htons(PROT_IP);
+   tcp_send = (void *)eth_send + ETHER_HDR_SIZE;
+   tcp_send->tcp_src = tcp->tcp_dst;
+   tcp_send->tcp_dst = tcp->tcp_src;
+   tcp_send->tcp_seq = htonl(0);
+   tcp_send->tcp_ack = htonl(ntohl(tcp->tcp_seq) + 1);
+   tcp_send->tcp_hlen = 
SHIFT_TO_TCPHDRLEN_FIELD(LEN_B_TO_DW(TCP_HDR_SIZE));
+   tcp_send->tcp_flags = TCP_SYN | TCP_ACK;
+   tcp_send->tcp_win = htons(PKTBUFSRX * TCP_MSS >> TCP_SCALE);
+   tcp_send->tcp_xsum = 0;
+   tcp_send->tcp_ugr = 0;
+   tcp_send->tcp_xsum = tcp_set_pseudo_header((uchar *)tcp_send,
+  tcp->ip_src,
+  tcp->ip_dst,
+  TCP_HDR_SIZE,
+  IP_TCP_HDR_SIZE);
+   net_set_ip_header((uchar *)tcp_send,
+ tcp->ip_src,
+ tcp->ip_dst,
+ IP_TCP_HDR_SIZE,
+ IPPROTO_TCP);
+
+   priv->recv_packet_length[priv->recv_packets] =
+   ETHER_HDR_SIZE + IP_TCP_HDR_SIZE;
+   ++priv->recv_packets;
+
+   return 0;
+}
+
+static int sb_ack_handler(struct udevice *dev, void *packet,
+ unsigned int len)
+{
+   struct eth_sandbox_priv *priv = dev_get_priv(dev);
+   struct ethernet_hdr *eth = packet;
+   struct ip_tcp_hdr *tcp = packet + ETHER_HDR_SIZE;
+   struct ethernet_hdr *eth_send;
+   struct ip_tcp_hdr *tcp_send;
+   void *data;
+   int pkt_len;
+   int payload_len = 0;
+   const char *payload1 = "HTTP/1.1 200 OK\r\n"
+   "Content-Length: 30\r\n\r\n\r\n"
+   "Hi\r\n";
+
+   /* Don't allow the buffer to overrun */
+   if (priv->recv_packets >= PKTBUFSRX)
+   return 0;
+
+   eth_send = (void *)priv->recv_packet_buffer[priv->recv_packets];
+   memcpy(eth_send->et_dest, eth->et_src, ARP_HLEN);
+   memcpy(eth_send->et_src, priv->fake_host_hwaddr, ARP_HLEN);
+   eth_send->et_protlen = htons(PROT_IP);
+   tcp_send = (void *)eth_send + ETHER_HDR_SIZE;
+   tcp_send->tcp_src = tcp->tcp_dst;
+   tcp_send->tcp_dst = tcp->tcp_src;
+   data = (void *)tcp_send + IP_TCP_HDR_SIZE;
+
+   if (nt

[PATCH v19 1/4] net: Add TCP protocol

2022-10-19 Thread Ying-Chun Liu (PaulLiu)
Currently file transfers are done using tftp or NFS both
over udp. This requires a request to be sent from client
(u-boot) to the boot server.

The current standard is TCP with selective acknowledgment.

Signed-off-by: Duncan Hare 
Signed-off-by: Duncan Hare 
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Reviewed-by: Simon Glass 
Cc: Christian Gmeiner 
Cc: Joe Hershberger 
Cc: Michal Simek 
Cc: Ramon Fried 
---
v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.
v16: Add more kernel-doc. Fix more double spaces.
v19: export tcp_set_pseudo_header() for unit test.
---
 include/net.h |  36 ++-
 include/net/tcp.h | 299 +++
 net/Kconfig   |  16 ++
 net/Makefile  |   1 +
 net/net.c |  30 ++
 net/tcp.c | 720 ++
 6 files changed, 1093 insertions(+), 9 deletions(-)
 create mode 100644 include/net/tcp.h
 create mode 100644 net/tcp.c

diff --git a/include/net.h b/include/net.h
index c06b577808..6d8d3fd971 100644
--- a/include/net.h
+++ b/include/net.h
@@ -365,6 +365,7 @@ struct vlan_ethernet_hdr {
 #define PROT_NCSI  0x88f8  /* NC-SI control packets*/
 
 #define IPPROTO_ICMP1  /* Internet Control Message Protocol*/
+#define IPPROTO_TCP6   /* Transmission Control Protocol*/
 #define IPPROTO_UDP17  /* User Datagram Protocol   */
 
 /*
@@ -690,19 +691,36 @@ static inline void net_send_packet(uchar *pkt, int len)
(void) eth_send(pkt, len);
 }
 
-/*
- * Transmit "net_tx_packet" as UDP packet, performing ARP request if needed
- *  (ether will be populated)
- *
- * @param ether Raw packet buffer
- * @param dest IP address to send the datagram to
- * @param dport Destination UDP port
- * @param sport Source UDP port
- * @param payload_len Length of data after the UDP header
+/**
+ * net_send_ip_packet() - Transmit "net_tx_packet" as UDP or TCP packet,
+ *send ARP request if needed (ether will be populated)
+ * @ether: Raw packet buffer
+ * @dest: IP address to send the datagram to
+ * @dport: Destination UDP port
+ * @sport: Source UDP port
+ * @payload_len: Length of data after the UDP header
+ * @action: TCP action to be performed
+ * @tcp_seq_num: TCP sequence number of this transmission
+ * @tcp_ack_num: TCP stream acknolegement number
+ *
+ * Return: 0 on success, other value on failure
  */
 int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport,
   int payload_len, int proto, u8 action, u32 tcp_seq_num,
   u32 tcp_ack_num);
+/**
+ * net_send_tcp_packet() - Transmit TCP packet.
+ * @payload_len: length of payload
+ * @dport: Destination TCP port
+ * @sport: Source TCP port
+ * @action: TCP action to be performed
+ * @tcp_seq_num: TCP sequence number of this transmission
+ * @tcp_ack_num: TCP stream acknolegement number
+ *
+ * Return: 0 on success, other value on failure
+ */
+int net_send_tcp_packet(int payload_len, int dport, int sport, u8 action,
+   u32 tcp_seq_num, u32 tcp_ack_num);
 int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport,
int sport, int payload_len);
 
diff --git a/include/net/tcp.h b/include/net/tcp.h
new file mode 100644
index 00..322551694f
--- /dev/null
+++ b/include/net/tcp.h
@@ -0,0 +1,299 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * TCP Support with SACK for file transfer.
+ *
+ * Copyright 2017 Duncan Hare, All rights reserved.
+ */
+
+#define TCP_ACTIVITY 127   /* Number of packets received   */
+   /* before console progress mark */
+/**
+ * struct ip_tcp_hdr - IP and TCP header
+ * @ip_hl_v: header length and version
+ * @ip_tos: type of service
+ * @ip_len: total length
+ * @ip_id: identification
+ * @ip_off: fragment offset field
+ * @ip_ttl: time to live
+ * @ip_p: protocol
+ * @ip_sum: checksum
+ * @ip_src: Source IP address
+ * @ip_dst: Destination IP address
+ * @tcp_src: TCP source port
+ * @tcp_dst: TCP destination port
+ * @tcp_seq: TCP sequence number
+ * @tcp_ack: TCP Acknowledgment number
+ * @tcp_hlen: 4 bits TCP header Length/4, 4 bits reserved, 2 more bits reserved
+ * @tcp_flag: flags of TCP
+ * @tcp_win: TCP windows size
+ * @tcp_xsum: Checksum
+ * @tcp_ugr: Pointer to urgent data
+ */
+struct ip_tcp_hdr {
+   u8  ip_hl_v;
+   u8  ip_tos;
+   u16 ip_len;
+   u16 ip_id;
+   u16 ip_off;
+   u8  ip_ttl;
+   u8  ip_p;
+   u16 ip_sum;
+   struct in_addr  ip_src;
+   struct in_addr  ip_dst;
+   u16 tcp_src;
+   u16 tcp_dst;
+   u32 

[PATCH v19 0/4] add TCP and HTTP for downloading images

2022-10-19 Thread Ying-Chun Liu (PaulLiu)
This patch is a refresh from previous patches made by
Duncan Hare . I've contacted him and
continue to work on this patch.

This patch introduce a TCP stack with SACK. And a simple wget command
to download images from http server.

v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.
v16: Add more kernel-doc. Fix more double spaces.
v17: Fix wget with address timeout issue reported by Ramon.
v18: Add documentation for wget command.
v19: Add unit test for wget command.

Ying-Chun Liu (PaulLiu) (4):
  net: Add TCP protocol
  net: Add wget application
  doc: cmd: wget: add documentation
  test: cmd: add test for wget command.

 cmd/Kconfig|   7 +
 cmd/net.c  |  13 +
 doc/usage/cmd/wget.rst |  61 
 doc/usage/index.rst|   1 +
 include/net.h  |  38 ++-
 include/net/tcp.h  | 299 +
 include/net/wget.h |  22 ++
 net/Kconfig|  16 +
 net/Makefile   |   2 +
 net/net.c  |  36 +++
 net/tcp.c  | 720 +
 net/wget.c | 438 +
 test/cmd/Makefile  |   1 +
 test/cmd/wget.c| 206 
 14 files changed, 1850 insertions(+), 10 deletions(-)
 create mode 100644 doc/usage/cmd/wget.rst
 create mode 100644 include/net/tcp.h
 create mode 100644 include/net/wget.h
 create mode 100644 net/tcp.c
 create mode 100644 net/wget.c
 create mode 100644 test/cmd/wget.c

-- 
2.35.1



[PATCH v18 2/3] net: Add wget application

2022-10-17 Thread Ying-Chun Liu (PaulLiu)
This commit adds a simple wget command that can download files
from http server.

The command syntax is
wget ${loadaddr} 

Signed-off-by: Duncan Hare 
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Reviewed-by: Simon Glass 
Cc: Christian Gmeiner 
Cc: Joe Hershberger 
Cc: Michal Simek 
Cc: Ramon Fried 
---
v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.
v16: Add more kernel-doc. Fix more double spaces.
v17: Fix wget with address timeout issue reported by Ramon.
---
 cmd/Kconfig|   7 +
 cmd/net.c  |  13 ++
 include/net.h  |   2 +-
 include/net/wget.h |  22 +++
 net/Makefile   |   1 +
 net/net.c  |   6 +
 net/wget.c | 428 +
 7 files changed, 478 insertions(+), 1 deletion(-)
 create mode 100644 include/net/wget.h
 create mode 100644 net/wget.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 49247a41c0..c1283d949f 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1791,6 +1791,13 @@ config SYS_DISABLE_AUTOLOAD
  is complete.  Enable this option to disable this behavior and instead
  require files to be loaded over the network by subsequent commands.
 
+config CMD_WGET
+   bool "wget"
+   select TCP
+   help
+ wget is a simple command to download kernel, or other files,
+ from a http server over TCP.
+
 config CMD_MII
bool "mii"
imply CMD_MDIO
diff --git a/cmd/net.c b/cmd/net.c
index 46f8c87b69..fb19d18b64 100644
--- a/cmd/net.c
+++ b/cmd/net.c
@@ -124,6 +124,19 @@ U_BOOT_CMD(
 );
 #endif
 
+#if defined(CONFIG_CMD_WGET)
+static int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const 
argv[])
+{
+   return netboot_common(WGET, cmdtp, argc, argv);
+}
+
+U_BOOT_CMD(
+   wget,   3,  1,  do_wget,
+   "boot image via network using HTTP protocol",
+   "[loadAddress] [[hostIPaddr:]path and image name]"
+);
+#endif
+
 static void netboot_update_env(void)
 {
char tmp[22];
diff --git a/include/net.h b/include/net.h
index 6d8d3fd971..5d52264360 100644
--- a/include/net.h
+++ b/include/net.h
@@ -561,7 +561,7 @@ extern int  net_restart_wrap;   /* Tried all 
network devices */
 
 enum proto_t {
BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP
+   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP, WGET
 };
 
 extern charnet_boot_file_name[1024];/* Boot File name */
diff --git a/include/net/wget.h b/include/net/wget.h
new file mode 100644
index 00..da0920de11
--- /dev/null
+++ b/include/net/wget.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Duncan Hare Copyright 2017
+ */
+
+/**
+ * wget_start() - begin wget
+ */
+void wget_start(void);
+
+enum wget_state {
+   WGET_CLOSED,
+   WGET_CONNECTING,
+   WGET_CONNECTED,
+   WGET_TRANSFERRING,
+   WGET_TRANSFERRED
+};
+
+#define DEBUG_WGET 0   /* Set to 1 for debug messages */
+#define SERVER_PORT80
+#define WGET_RETRY_COUNT   30
+#define WGET_TIMEOUT   2000UL
diff --git a/net/Makefile b/net/Makefile
index d131d1cb1a..4f757a224c 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_UDP_FUNCTION_FASTBOOT)  += fastboot.o
 obj-$(CONFIG_CMD_WOL)  += wol.o
 obj-$(CONFIG_PROT_UDP) += udp.o
 obj-$(CONFIG_PROT_TCP) += tcp.o
+obj-$(CONFIG_CMD_WGET) += wget.o
 
 # Disable this warning as it is triggered by:
 # sprintf(buf, index ? "foo%d" : "foo", index)
diff --git a/net/net.c b/net/net.c
index 5333cce57e..033ceda6e1 100644
--- a/net/net.c
+++ b/net/net.c
@@ -117,6 +117,7 @@
 #include "wol.h"
 #endif
 #include 
+#include 
 
 /** BOOTP EXTENTIONS **/
 
@@ -505,6 +506,11 @@ restart:
nfs_start();
break;
 #endif
+#if defined(CONFIG_CMD_WGET)
+   case WGET:
+   wget_start();
+   break;
+#endif
 #if defined(CONFIG_CMD_CDP)
case CDP:
cdp_start();
diff --git a/net/wget.c b/net/wget.c
new file mode 100644
index 00..ae69da49d4
--- /dev/null
+++ b/net/wget.c
@@ -0,0 +1,428 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * WGET/HTTP support driver based on U-BOOT's nfs.c
+ * Copyright Duncan Hare  2017
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const char bootfile1[] = "GET ";
+static const char bootfile3[] = " HTTP/1.0\r\n\r\n";
+static const char http_eom[] = "\r\n\r\n";
+static const char http_ok[] = "200";
+static const char content_len[] = "Content-Length";
+static const char linefeed[] = "\r\n";

[PATCH v18 3/3] doc: cmd: wget: add documentation

2022-10-17 Thread Ying-Chun Liu (PaulLiu)
Add documentation for the wget command.

Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Simon Glass 
---
 doc/usage/cmd/wget.rst | 61 ++
 doc/usage/index.rst|  1 +
 2 files changed, 62 insertions(+)
 create mode 100644 doc/usage/cmd/wget.rst

diff --git a/doc/usage/cmd/wget.rst b/doc/usage/cmd/wget.rst
new file mode 100644
index 00..4fcfa03954
--- /dev/null
+++ b/doc/usage/cmd/wget.rst
@@ -0,0 +1,61 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+wget command
+
+
+Synopsis
+
+
+::
+wget address [[hostIPaddr:]path]
+
+Description
+---
+
+The wget command is used to download a file from an HTTP server.
+
+wget command will use HTTP over TCP to download files from an HTTP server.
+Currently it can only download image from an HTTP server hosted on port 80.
+
+address
+memory address for the data downloaded
+
+hostIPaddr
+IP address of the HTTP server, defaults to the value of environment
+variable *serverip*
+
+path
+path of the file to be downloaded.
+
+Example
+---
+
+In the example the following steps are executed:
+
+* setup client network address
+* download a file from the HTTP server
+
+::
+
+=> setenv autoload no
+=> dhcp
+BOOTP broadcast 1
+*** Unhandled DHCP Option in OFFER/ACK: 23
+*** Unhandled DHCP Option in OFFER/ACK: 23
+DHCP client bound to address 192.168.1.105 (210 ms)
+=> wget ${loadaddr} 192.168.1.254:/index.html
+HTTP/1.0 302 Found
+Packets received 4, Transfer Successful
+
+Configuration
+-
+
+The command is only available if CONFIG_CMD_WGET=y.
+
+CONFIG_PROT_TCP_SACK can be turned on for the TCP SACK options. This will
+help increasing the downloading speed.
+
+Return value
+
+
+The return value $? is 0 (true) on success and 1 (false) otherwise.
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 90221015ee..11f5fcfaff 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -73,6 +73,7 @@ Shell commands
cmd/true
cmd/ums
cmd/wdt
+   cmd/wget
cmd/xxd
 
 Booting OS
-- 
2.35.1



[PATCH v18 1/3] net: Add TCP protocol

2022-10-17 Thread Ying-Chun Liu (PaulLiu)
Currently file transfers are done using tftp or NFS both
over udp. This requires a request to be sent from client
(u-boot) to the boot server.

The current standard is TCP with selective acknowledgment.

Signed-off-by: Duncan Hare 
Signed-off-by: Duncan Hare 
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Reviewed-by: Simon Glass 
Cc: Christian Gmeiner 
Cc: Joe Hershberger 
Cc: Michal Simek 
Cc: Ramon Fried 
---
v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.
v16: Add more kernel-doc. Fix more double spaces.
---
 include/net.h |  36 ++-
 include/net/tcp.h | 312 
 net/Kconfig   |  16 ++
 net/Makefile  |   1 +
 net/net.c |  30 ++
 net/tcp.c | 720 ++
 6 files changed, 1106 insertions(+), 9 deletions(-)
 create mode 100644 include/net/tcp.h
 create mode 100644 net/tcp.c

diff --git a/include/net.h b/include/net.h
index c06b577808..6d8d3fd971 100644
--- a/include/net.h
+++ b/include/net.h
@@ -365,6 +365,7 @@ struct vlan_ethernet_hdr {
 #define PROT_NCSI  0x88f8  /* NC-SI control packets*/
 
 #define IPPROTO_ICMP1  /* Internet Control Message Protocol*/
+#define IPPROTO_TCP6   /* Transmission Control Protocol*/
 #define IPPROTO_UDP17  /* User Datagram Protocol   */
 
 /*
@@ -690,19 +691,36 @@ static inline void net_send_packet(uchar *pkt, int len)
(void) eth_send(pkt, len);
 }
 
-/*
- * Transmit "net_tx_packet" as UDP packet, performing ARP request if needed
- *  (ether will be populated)
- *
- * @param ether Raw packet buffer
- * @param dest IP address to send the datagram to
- * @param dport Destination UDP port
- * @param sport Source UDP port
- * @param payload_len Length of data after the UDP header
+/**
+ * net_send_ip_packet() - Transmit "net_tx_packet" as UDP or TCP packet,
+ *send ARP request if needed (ether will be populated)
+ * @ether: Raw packet buffer
+ * @dest: IP address to send the datagram to
+ * @dport: Destination UDP port
+ * @sport: Source UDP port
+ * @payload_len: Length of data after the UDP header
+ * @action: TCP action to be performed
+ * @tcp_seq_num: TCP sequence number of this transmission
+ * @tcp_ack_num: TCP stream acknolegement number
+ *
+ * Return: 0 on success, other value on failure
  */
 int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport,
   int payload_len, int proto, u8 action, u32 tcp_seq_num,
   u32 tcp_ack_num);
+/**
+ * net_send_tcp_packet() - Transmit TCP packet.
+ * @payload_len: length of payload
+ * @dport: Destination TCP port
+ * @sport: Source TCP port
+ * @action: TCP action to be performed
+ * @tcp_seq_num: TCP sequence number of this transmission
+ * @tcp_ack_num: TCP stream acknolegement number
+ *
+ * Return: 0 on success, other value on failure
+ */
+int net_send_tcp_packet(int payload_len, int dport, int sport, u8 action,
+   u32 tcp_seq_num, u32 tcp_ack_num);
 int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport,
int sport, int payload_len);
 
diff --git a/include/net/tcp.h b/include/net/tcp.h
new file mode 100644
index 00..9c97f2f315
--- /dev/null
+++ b/include/net/tcp.h
@@ -0,0 +1,312 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * TCP Support with SACK for file transfer.
+ *
+ * Copyright 2017 Duncan Hare, All rights reserved.
+ */
+
+#define TCP_ACTIVITY 127   /* Number of packets received   */
+   /* before console progress mark */
+/**
+ * struct ip_tcp_hdr - IP and TCP header
+ * @ip_hl_v: header length and version
+ * @ip_tos: type of service
+ * @ip_len: total length
+ * @ip_id: identification
+ * @ip_off: fragment offset field
+ * @ip_ttl: time to live
+ * @ip_p: protocol
+ * @ip_sum: checksum
+ * @ip_src: Source IP address
+ * @ip_dst: Destination IP address
+ * @tcp_src: TCP source port
+ * @tcp_dst: TCP destination port
+ * @tcp_seq: TCP sequence number
+ * @tcp_ack: TCP Acknowledgment number
+ * @tcp_hlen: 4 bits TCP header Length/4, 4 bits reserved, 2 more bits reserved
+ * @tcp_flag: flags of TCP
+ * @tcp_win: TCP windows size
+ * @tcp_xsum: Checksum
+ * @tcp_ugr: Pointer to urgent data
+ */
+struct ip_tcp_hdr {
+   u8  ip_hl_v;
+   u8  ip_tos;
+   u16 ip_len;
+   u16 ip_id;
+   u16 ip_off;
+   u8  ip_ttl;
+   u8  ip_p;
+   u16 ip_sum;
+   struct in_addr  ip_src;
+   struct in_addr  ip_dst;
+   u16 tcp_src;
+   u16 tcp_dst;
+   u32 tcp_seq;
+   u32 tcp_ack;
+   u8  

[PATCH v18 0/3] add TCP and HTTP for downloading images

2022-10-17 Thread Ying-Chun Liu (PaulLiu)
This patch is a refresh from previous patches made by
Duncan Hare . I've contacted him and
continue to work on this patch.

This patch introduce a TCP stack with SACK. And a simple wget command
to download images from http server.

v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.
v16: Add more kernel-doc. Fix more double spaces.
v17: Fix wget with address timeout issue reported by Ramon.
v18: Add documentation for wget command.

Ying-Chun Liu (PaulLiu) (3):
  net: Add TCP protocol
  net: Add wget application
  doc: cmd: wget: add documentation

 cmd/Kconfig|   7 +
 cmd/net.c  |  13 +
 doc/usage/cmd/wget.rst |  61 
 doc/usage/index.rst|   1 +
 include/net.h  |  38 ++-
 include/net/tcp.h  | 312 ++
 include/net/wget.h |  22 ++
 net/Kconfig|  16 +
 net/Makefile   |   2 +
 net/net.c  |  36 +++
 net/tcp.c  | 720 +
 net/wget.c | 428 
 12 files changed, 1646 insertions(+), 10 deletions(-)
 create mode 100644 doc/usage/cmd/wget.rst
 create mode 100644 include/net/tcp.h
 create mode 100644 include/net/wget.h
 create mode 100644 net/tcp.c
 create mode 100644 net/wget.c

-- 
2.35.1



[PATCH v2 2/2] dts: imx8mp-rsb3720: modify configrations to load fip into memory

2022-08-23 Thread Ying-Chun Liu (PaulLiu)
From: "Ying-Chun Liu (PaulLiu)" 

The changes of commit 6a21c695213b ("arm: dts: imx8mp: add of-list
support to common imx8mp-u-boot.dtsi") breaks the loading of the fip.
This commit fixes the break by modify the configuration properly.

Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Stefano Babic 
Cc: Fabio Estevam 
Cc: NXP i.MX U-Boot Team 
---
 arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi 
b/arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi
index 4419967ee4..32d9fbc886 100644
--- a/arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi
+++ b/arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi
@@ -158,12 +158,10 @@
};
};
};
-
-   configurations {
-   conf {
-   loadables = "atf", "fip";
-   };
-   };
};
};
 };
+
+_configuration {
+   loadables = "atf", "fip";
+};
-- 
2.35.1



[PATCH v2 1/2] dts: imx8mp: assign binman_configuration node name to config-SEQ

2022-08-23 Thread Ying-Chun Liu (PaulLiu)
From: "Ying-Chun Liu (PaulLiu)" 

assign a node name for config-SEQ so that the board dts can modify
the configuration more easily.

Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Stefano Babic 
Cc: Fabio Estevam 
Cc: NXP i.MX U-Boot Team 
---
v2: just rebase to the latest master branch.
---
 arch/arm/dts/imx8mp-u-boot.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/dts/imx8mp-u-boot.dtsi b/arch/arm/dts/imx8mp-u-boot.dtsi
index adb243..6cb0bb2d4c 100644
--- a/arch/arm/dts/imx8mp-u-boot.dtsi
+++ b/arch/arm/dts/imx8mp-u-boot.dtsi
@@ -148,7 +148,7 @@
configurations {
default = "@config-DEFAULT-SEQ";
 
-   @config-SEQ {
+   binman_configuration: @config-SEQ {
description = "NAME";
fdt = "fdt-SEQ";
firmware = "uboot";
-- 
2.35.1



[PATCH v2 0/2] dts: imx8mp-rsb3720: modify configrations to load fip into memory

2022-08-23 Thread Ying-Chun Liu (PaulLiu)
From: "Ying-Chun Liu (PaulLiu)" 

The changes of commit 6a21c695213b ("arm: dts: imx8mp: add of-list
support to common imx8mp-u-boot.dtsi") breaks the loading of the fip.
This commit fixes the break by modify the configuration properly.

v2: just rebase to the latest master branch.

Ying-Chun Liu (PaulLiu) (2):
  dts: imx8mp: assign binman_configuration node name to config-SEQ
  dts: imx8mp-rsb3720: modify configrations to load fip into memory

 arch/arm/dts/imx8mp-rsb3720-a1-u-boot.dtsi | 10 --
 arch/arm/dts/imx8mp-u-boot.dtsi|  2 +-
 2 files changed, 5 insertions(+), 7 deletions(-)
-- 
2.35.1



[PATCH v17 2/2] net: Add wget application

2022-07-08 Thread Ying-Chun Liu (PaulLiu)
From: "Ying-Chun Liu (PaulLiu)" 

This commit adds a simple wget command that can download files
from http server.

The command syntax is
wget ${loadaddr} 

Signed-off-by: Duncan Hare 
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Christian Gmeiner 
Cc: Joe Hershberger 
Cc: Michal Simek 
Cc: Ramon Fried 
---
v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.
v16: Add more kernel-doc. Fix more double spaces.
v17: Fix wget with address timeout issue reported by Ramon.
---
 cmd/Kconfig|   7 +
 cmd/net.c  |  13 ++
 include/net.h  |   2 +-
 include/net/wget.h |  22 +++
 net/Makefile   |   1 +
 net/net.c  |   6 +
 net/wget.c | 428 +
 7 files changed, 478 insertions(+), 1 deletion(-)
 create mode 100644 include/net/wget.h
 create mode 100644 net/wget.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 09193b61b9..5a5f2f1df8 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1715,6 +1715,13 @@ config NFS_TIMEOUT
  "ERROR: Cannot umount" in nfs command, try longer timeout such as
  1.
 
+config CMD_WGET
+   bool "wget"
+   select TCP
+   help
+ wget is a simple command to download kernel, or other files,
+ from a http server over TCP.
+
 config CMD_MII
bool "mii"
imply CMD_MDIO
diff --git a/cmd/net.c b/cmd/net.c
index 3619c843d8..60fd785061 100644
--- a/cmd/net.c
+++ b/cmd/net.c
@@ -124,6 +124,19 @@ U_BOOT_CMD(
 );
 #endif
 
+#if defined(CONFIG_CMD_WGET)
+static int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const 
argv[])
+{
+   return netboot_common(WGET, cmdtp, argc, argv);
+}
+
+U_BOOT_CMD(
+   wget,   3,  1,  do_wget,
+   "boot image via network using HTTP protocol",
+   "[loadAddress] [[hostIPaddr:]path and image name]"
+);
+#endif
+
 static void netboot_update_env(void)
 {
char tmp[22];
diff --git a/include/net.h b/include/net.h
index b7bac86cf1..fb80a8981d 100644
--- a/include/net.h
+++ b/include/net.h
@@ -559,7 +559,7 @@ extern int  net_restart_wrap;   /* Tried all 
network devices */
 
 enum proto_t {
BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP
+   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP, WGET
 };
 
 extern charnet_boot_file_name[1024];/* Boot File name */
diff --git a/include/net/wget.h b/include/net/wget.h
new file mode 100644
index 00..da0920de11
--- /dev/null
+++ b/include/net/wget.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Duncan Hare Copyright 2017
+ */
+
+/**
+ * wget_start() - begin wget
+ */
+void wget_start(void);
+
+enum wget_state {
+   WGET_CLOSED,
+   WGET_CONNECTING,
+   WGET_CONNECTED,
+   WGET_TRANSFERRING,
+   WGET_TRANSFERRED
+};
+
+#define DEBUG_WGET 0   /* Set to 1 for debug messages */
+#define SERVER_PORT80
+#define WGET_RETRY_COUNT   30
+#define WGET_TIMEOUT   2000UL
diff --git a/net/Makefile b/net/Makefile
index d131d1cb1a..4f757a224c 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_UDP_FUNCTION_FASTBOOT)  += fastboot.o
 obj-$(CONFIG_CMD_WOL)  += wol.o
 obj-$(CONFIG_PROT_UDP) += udp.o
 obj-$(CONFIG_PROT_TCP) += tcp.o
+obj-$(CONFIG_CMD_WGET) += wget.o
 
 # Disable this warning as it is triggered by:
 # sprintf(buf, index ? "foo%d" : "foo", index)
diff --git a/net/net.c b/net/net.c
index 751d0251be..cee2ff8100 100644
--- a/net/net.c
+++ b/net/net.c
@@ -117,6 +117,7 @@
 #include "wol.h"
 #endif
 #include 
+#include 
 
 /** BOOTP EXTENTIONS **/
 
@@ -505,6 +506,11 @@ restart:
nfs_start();
break;
 #endif
+#if defined(CONFIG_CMD_WGET)
+   case WGET:
+   wget_start();
+   break;
+#endif
 #if defined(CONFIG_CMD_CDP)
case CDP:
cdp_start();
diff --git a/net/wget.c b/net/wget.c
new file mode 100644
index 00..ae69da49d4
--- /dev/null
+++ b/net/wget.c
@@ -0,0 +1,428 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * WGET/HTTP support driver based on U-BOOT's nfs.c
+ * Copyright Duncan Hare  2017
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const char bootfile1[] = "GET ";
+static const char bootfile3[] = " HTTP/1.0\r\n\r\n";
+static const char http_eom[] = "\r\n\r\n";
+static const char http_ok[] = "200";
+static const char content_len[] = "Content-Length";
+static const char linefeed[] = "\r\n";
+static struct in_addr web_server_ip;
+

[PATCH v17 1/2] net: Add TCP protocol

2022-07-08 Thread Ying-Chun Liu (PaulLiu)
From: "Ying-Chun Liu (PaulLiu)" 

Currently file transfers are done using tftp or NFS both
over udp. This requires a request to be sent from client
(u-boot) to the boot server.

The current standard is TCP with selective acknowledgment.

Signed-off-by: Duncan Hare 
Signed-off-by: Duncan Hare 
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Christian Gmeiner 
Cc: Joe Hershberger 
Cc: Michal Simek 
Cc: Ramon Fried 
---
v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.
v16: Add more kernel-doc. Fix more double spaces.
---
 include/net.h |  36 ++-
 include/net/tcp.h | 312 
 net/Kconfig   |  16 ++
 net/Makefile  |   1 +
 net/net.c |  30 ++
 net/tcp.c | 720 ++
 6 files changed, 1106 insertions(+), 9 deletions(-)
 create mode 100644 include/net/tcp.h
 create mode 100644 net/tcp.c

diff --git a/include/net.h b/include/net.h
index e3889a0bc8..b7bac86cf1 100644
--- a/include/net.h
+++ b/include/net.h
@@ -365,6 +365,7 @@ struct vlan_ethernet_hdr {
 #define PROT_NCSI  0x88f8  /* NC-SI control packets*/
 
 #define IPPROTO_ICMP1  /* Internet Control Message Protocol*/
+#define IPPROTO_TCP6   /* Transmission Control Protocol*/
 #define IPPROTO_UDP17  /* User Datagram Protocol   */
 
 /*
@@ -688,19 +689,36 @@ static inline void net_send_packet(uchar *pkt, int len)
(void) eth_send(pkt, len);
 }
 
-/*
- * Transmit "net_tx_packet" as UDP packet, performing ARP request if needed
- *  (ether will be populated)
- *
- * @param ether Raw packet buffer
- * @param dest IP address to send the datagram to
- * @param dport Destination UDP port
- * @param sport Source UDP port
- * @param payload_len Length of data after the UDP header
+/**
+ * net_send_ip_packet() - Transmit "net_tx_packet" as UDP or TCP packet,
+ *send ARP request if needed (ether will be populated)
+ * @ether: Raw packet buffer
+ * @dest: IP address to send the datagram to
+ * @dport: Destination UDP port
+ * @sport: Source UDP port
+ * @payload_len: Length of data after the UDP header
+ * @action: TCP action to be performed
+ * @tcp_seq_num: TCP sequence number of this transmission
+ * @tcp_ack_num: TCP stream acknolegement number
+ *
+ * Return: 0 on success, other value on failure
  */
 int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport,
   int payload_len, int proto, u8 action, u32 tcp_seq_num,
   u32 tcp_ack_num);
+/**
+ * net_send_tcp_packet() - Transmit TCP packet.
+ * @payload_len: length of payload
+ * @dport: Destination TCP port
+ * @sport: Source TCP port
+ * @action: TCP action to be performed
+ * @tcp_seq_num: TCP sequence number of this transmission
+ * @tcp_ack_num: TCP stream acknolegement number
+ *
+ * Return: 0 on success, other value on failure
+ */
+int net_send_tcp_packet(int payload_len, int dport, int sport, u8 action,
+   u32 tcp_seq_num, u32 tcp_ack_num);
 int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport,
int sport, int payload_len);
 
diff --git a/include/net/tcp.h b/include/net/tcp.h
new file mode 100644
index 00..9c97f2f315
--- /dev/null
+++ b/include/net/tcp.h
@@ -0,0 +1,312 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * TCP Support with SACK for file transfer.
+ *
+ * Copyright 2017 Duncan Hare, All rights reserved.
+ */
+
+#define TCP_ACTIVITY 127   /* Number of packets received   */
+   /* before console progress mark */
+/**
+ * struct ip_tcp_hdr - IP and TCP header
+ * @ip_hl_v: header length and version
+ * @ip_tos: type of service
+ * @ip_len: total length
+ * @ip_id: identification
+ * @ip_off: fragment offset field
+ * @ip_ttl: time to live
+ * @ip_p: protocol
+ * @ip_sum: checksum
+ * @ip_src: Source IP address
+ * @ip_dst: Destination IP address
+ * @tcp_src: TCP source port
+ * @tcp_dst: TCP destination port
+ * @tcp_seq: TCP sequence number
+ * @tcp_ack: TCP Acknowledgment number
+ * @tcp_hlen: 4 bits TCP header Length/4, 4 bits reserved, 2 more bits reserved
+ * @tcp_flag: flags of TCP
+ * @tcp_win: TCP windows size
+ * @tcp_xsum: Checksum
+ * @tcp_ugr: Pointer to urgent data
+ */
+struct ip_tcp_hdr {
+   u8  ip_hl_v;
+   u8  ip_tos;
+   u16 ip_len;
+   u16 ip_id;
+   u16 ip_off;
+   u8  ip_ttl;
+   u8  ip_p;
+   u16 ip_sum;
+   struct in_addr  ip_src;
+   struct in_addr  ip_dst;
+   u16 tcp_src;
+   u16 tcp_dst;
+   u32 tcp_seq;
+   u32  

[PATCH v17 0/2] add TCP and HTTP for downloading images

2022-07-08 Thread Ying-Chun Liu (PaulLiu)
From: "Ying-Chun Liu (PaulLiu)" 

This patch is a refresh from previous patches made by
Duncan Hare . I've contacted him and
continue to work on this patch.

This patch introduce a TCP stack with SACK. And a simple wget command
to download images from http server.

v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.
v16: Add more kernel-doc. Fix more double spaces.
v17: Fix wget with address timeout issue reported by Ramon.

Ying-Chun Liu (PaulLiu) (2):
  net: Add TCP protocol
  net: Add wget application

 cmd/Kconfig|   7 +
 cmd/net.c  |  13 +
 include/net.h  |  38 ++-
 include/net/tcp.h  | 312 
 include/net/wget.h |  22 ++
 net/Kconfig|  16 +
 net/Makefile   |   2 +
 net/net.c  |  36 +++
 net/tcp.c  | 720 +
 net/wget.c | 428 +++
 10 files changed, 1584 insertions(+), 10 deletions(-)
 create mode 100644 include/net/tcp.h
 create mode 100644 include/net/wget.h
 create mode 100644 net/tcp.c
 create mode 100644 net/wget.c

-- 
2.35.1



[PATCH v16 1/2] net: Add TCP protocol

2022-06-10 Thread Ying-Chun Liu (PaulLiu)
From: "Ying-Chun Liu (PaulLiu)" 

Currently file transfers are done using tftp or NFS both
over udp. This requires a request to be sent from client
(u-boot) to the boot server.

The current standard is TCP with selective acknowledgment.

Signed-off-by: Duncan Hare 
Signed-off-by: Duncan Hare 
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Christian Gmeiner 
Cc: Joe Hershberger 
Cc: Michal Simek 
Cc: Ramon Fried 
---
v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.
v16: Add more kernel-doc. Fix more double spaces. 
---
 include/net.h |  36 ++-
 include/net/tcp.h | 312 
 net/Kconfig   |  16 ++
 net/Makefile  |   1 +
 net/net.c |  30 ++
 net/tcp.c | 720 ++
 6 files changed, 1106 insertions(+), 9 deletions(-)
 create mode 100644 include/net/tcp.h
 create mode 100644 net/tcp.c

diff --git a/include/net.h b/include/net.h
index e3889a0bc8..b7bac86cf1 100644
--- a/include/net.h
+++ b/include/net.h
@@ -365,6 +365,7 @@ struct vlan_ethernet_hdr {
 #define PROT_NCSI  0x88f8  /* NC-SI control packets*/
 
 #define IPPROTO_ICMP1  /* Internet Control Message Protocol*/
+#define IPPROTO_TCP6   /* Transmission Control Protocol*/
 #define IPPROTO_UDP17  /* User Datagram Protocol   */
 
 /*
@@ -688,19 +689,36 @@ static inline void net_send_packet(uchar *pkt, int len)
(void) eth_send(pkt, len);
 }
 
-/*
- * Transmit "net_tx_packet" as UDP packet, performing ARP request if needed
- *  (ether will be populated)
- *
- * @param ether Raw packet buffer
- * @param dest IP address to send the datagram to
- * @param dport Destination UDP port
- * @param sport Source UDP port
- * @param payload_len Length of data after the UDP header
+/**
+ * net_send_ip_packet() - Transmit "net_tx_packet" as UDP or TCP packet,
+ *send ARP request if needed (ether will be populated)
+ * @ether: Raw packet buffer
+ * @dest: IP address to send the datagram to
+ * @dport: Destination UDP port
+ * @sport: Source UDP port
+ * @payload_len: Length of data after the UDP header
+ * @action: TCP action to be performed
+ * @tcp_seq_num: TCP sequence number of this transmission
+ * @tcp_ack_num: TCP stream acknolegement number
+ *
+ * Return: 0 on success, other value on failure
  */
 int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport,
   int payload_len, int proto, u8 action, u32 tcp_seq_num,
   u32 tcp_ack_num);
+/**
+ * net_send_tcp_packet() - Transmit TCP packet.
+ * @payload_len: length of payload
+ * @dport: Destination TCP port
+ * @sport: Source TCP port
+ * @action: TCP action to be performed
+ * @tcp_seq_num: TCP sequence number of this transmission
+ * @tcp_ack_num: TCP stream acknolegement number
+ *
+ * Return: 0 on success, other value on failure
+ */
+int net_send_tcp_packet(int payload_len, int dport, int sport, u8 action,
+   u32 tcp_seq_num, u32 tcp_ack_num);
 int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport,
int sport, int payload_len);
 
diff --git a/include/net/tcp.h b/include/net/tcp.h
new file mode 100644
index 00..9c97f2f315
--- /dev/null
+++ b/include/net/tcp.h
@@ -0,0 +1,312 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * TCP Support with SACK for file transfer.
+ *
+ * Copyright 2017 Duncan Hare, All rights reserved.
+ */
+
+#define TCP_ACTIVITY 127   /* Number of packets received   */
+   /* before console progress mark */
+/**
+ * struct ip_tcp_hdr - IP and TCP header
+ * @ip_hl_v: header length and version
+ * @ip_tos: type of service
+ * @ip_len: total length
+ * @ip_id: identification
+ * @ip_off: fragment offset field
+ * @ip_ttl: time to live
+ * @ip_p: protocol
+ * @ip_sum: checksum
+ * @ip_src: Source IP address
+ * @ip_dst: Destination IP address
+ * @tcp_src: TCP source port
+ * @tcp_dst: TCP destination port
+ * @tcp_seq: TCP sequence number
+ * @tcp_ack: TCP Acknowledgment number
+ * @tcp_hlen: 4 bits TCP header Length/4, 4 bits reserved, 2 more bits reserved
+ * @tcp_flag: flags of TCP
+ * @tcp_win: TCP windows size
+ * @tcp_xsum: Checksum
+ * @tcp_ugr: Pointer to urgent data
+ */
+struct ip_tcp_hdr {
+   u8  ip_hl_v;
+   u8  ip_tos;
+   u16 ip_len;
+   u16 ip_id;
+   u16 ip_off;
+   u8  ip_ttl;
+   u8  ip_p;
+   u16 ip_sum;
+   struct in_addr  ip_src;
+   struct in_addr  ip_dst;
+   u16 tcp_src;
+   u16 tcp_dst;
+   u32 tcp_seq;
+   u32  

[PATCH v16 2/2] net: Add wget application

2022-06-10 Thread Ying-Chun Liu (PaulLiu)
From: "Ying-Chun Liu (PaulLiu)" 

This commit adds a simple wget command that can download files
from http server.

The command syntax is
wget ${loadaddr} 

Signed-off-by: Duncan Hare 
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Christian Gmeiner 
Cc: Joe Hershberger 
Cc: Michal Simek 
Cc: Ramon Fried 
---
v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.
v16: Add more kernel-doc. Fix more double spaces. 
---
 cmd/Kconfig|   7 +
 cmd/net.c  |  13 ++
 include/net.h  |   2 +-
 include/net/wget.h |  22 +++
 net/Makefile   |   1 +
 net/net.c  |   6 +
 net/wget.c | 426 +
 7 files changed, 476 insertions(+), 1 deletion(-)
 create mode 100644 include/net/wget.h
 create mode 100644 net/wget.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 09193b61b9..5a5f2f1df8 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1715,6 +1715,13 @@ config NFS_TIMEOUT
  "ERROR: Cannot umount" in nfs command, try longer timeout such as
  1.
 
+config CMD_WGET
+   bool "wget"
+   select TCP
+   help
+ wget is a simple command to download kernel, or other files,
+ from a http server over TCP.
+
 config CMD_MII
bool "mii"
imply CMD_MDIO
diff --git a/cmd/net.c b/cmd/net.c
index 3619c843d8..60fd785061 100644
--- a/cmd/net.c
+++ b/cmd/net.c
@@ -124,6 +124,19 @@ U_BOOT_CMD(
 );
 #endif
 
+#if defined(CONFIG_CMD_WGET)
+static int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const 
argv[])
+{
+   return netboot_common(WGET, cmdtp, argc, argv);
+}
+
+U_BOOT_CMD(
+   wget,   3,  1,  do_wget,
+   "boot image via network using HTTP protocol",
+   "[loadAddress] [[hostIPaddr:]path and image name]"
+);
+#endif
+
 static void netboot_update_env(void)
 {
char tmp[22];
diff --git a/include/net.h b/include/net.h
index b7bac86cf1..fb80a8981d 100644
--- a/include/net.h
+++ b/include/net.h
@@ -559,7 +559,7 @@ extern int  net_restart_wrap;   /* Tried all 
network devices */
 
 enum proto_t {
BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP
+   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP, WGET
 };
 
 extern charnet_boot_file_name[1024];/* Boot File name */
diff --git a/include/net/wget.h b/include/net/wget.h
new file mode 100644
index 00..da0920de11
--- /dev/null
+++ b/include/net/wget.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Duncan Hare Copyright 2017
+ */
+
+/**
+ * wget_start() - begin wget
+ */
+void wget_start(void);
+
+enum wget_state {
+   WGET_CLOSED,
+   WGET_CONNECTING,
+   WGET_CONNECTED,
+   WGET_TRANSFERRING,
+   WGET_TRANSFERRED
+};
+
+#define DEBUG_WGET 0   /* Set to 1 for debug messages */
+#define SERVER_PORT80
+#define WGET_RETRY_COUNT   30
+#define WGET_TIMEOUT   2000UL
diff --git a/net/Makefile b/net/Makefile
index d131d1cb1a..4f757a224c 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_UDP_FUNCTION_FASTBOOT)  += fastboot.o
 obj-$(CONFIG_CMD_WOL)  += wol.o
 obj-$(CONFIG_PROT_UDP) += udp.o
 obj-$(CONFIG_PROT_TCP) += tcp.o
+obj-$(CONFIG_CMD_WGET) += wget.o
 
 # Disable this warning as it is triggered by:
 # sprintf(buf, index ? "foo%d" : "foo", index)
diff --git a/net/net.c b/net/net.c
index 751d0251be..cee2ff8100 100644
--- a/net/net.c
+++ b/net/net.c
@@ -117,6 +117,7 @@
 #include "wol.h"
 #endif
 #include 
+#include 
 
 /** BOOTP EXTENTIONS **/
 
@@ -505,6 +506,11 @@ restart:
nfs_start();
break;
 #endif
+#if defined(CONFIG_CMD_WGET)
+   case WGET:
+   wget_start();
+   break;
+#endif
 #if defined(CONFIG_CMD_CDP)
case CDP:
cdp_start();
diff --git a/net/wget.c b/net/wget.c
new file mode 100644
index 00..6a2e92f17b
--- /dev/null
+++ b/net/wget.c
@@ -0,0 +1,426 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * WGET/HTTP support driver based on U-BOOT's nfs.c
+ * Copyright Duncan Hare  2017
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const char bootfile1[] = "GET ";
+static const char bootfile3[] = " HTTP/1.0\r\n\r\n";
+static const char http_eom[] = "\r\n\r\n";
+static const char http_ok[] = "200";
+static const char content_len[] = "Content-Length";
+static const char linefeed[] = "\r\n";
+static struct in_addr web_server_ip;
+static int our_port;
+static int wget_timeout_count;
+
+struct pkt_q

[PATCH v16 0/2] add TCP and HTTP for downloading images

2022-06-10 Thread Ying-Chun Liu (PaulLiu)
From: "Ying-Chun Liu (PaulLiu)" 

This patch is a refresh from previous patches made by
Duncan Hare . I've contacted him and
continue to work on this patch.

This patch introduce a TCP stack with SACK. And a simple wget command
to download images from http server.

v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.
v16: Add more kernel-doc. Fix more double spaces.     

Ying-Chun Liu (PaulLiu) (2):
  net: Add TCP protocol
  net: Add wget application

 cmd/Kconfig|   7 +
 cmd/net.c  |  13 +
 include/net.h  |  38 ++-
 include/net/tcp.h  | 312 
 include/net/wget.h |  22 ++
 net/Kconfig|  16 +
 net/Makefile   |   2 +
 net/net.c  |  36 +++
 net/tcp.c  | 720 +
 net/wget.c | 426 +++
 10 files changed, 1582 insertions(+), 10 deletions(-)
 create mode 100644 include/net/tcp.h
 create mode 100644 include/net/wget.h
 create mode 100644 net/tcp.c
 create mode 100644 net/wget.c

-- 
2.35.1



[PATCH v15 1/2] net: Add TCP protocol

2022-06-10 Thread Ying-Chun Liu (PaulLiu)
From: "Ying-Chun Liu (PaulLiu)" 

Currently file transfers are done using tftp or NFS both
over udp. This requires a request to be sent from client
(u-boot) to the boot server.

The current standard is TCP with selective acknowledgment.

Signed-off-by: Duncan Hare 
Signed-off-by: Duncan Hare 
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Christian Gmeiner 
Cc: Joe Hershberger 
Cc: Michal Simek 
Cc: Ramon Fried 
---
v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.
---
 include/net.h |  36 ++-
 include/net/tcp.h | 312 
 net/Kconfig   |  16 ++
 net/Makefile  |   1 +
 net/net.c |  30 ++
 net/tcp.c | 712 ++
 6 files changed, 1098 insertions(+), 9 deletions(-)
 create mode 100644 include/net/tcp.h
 create mode 100644 net/tcp.c

diff --git a/include/net.h b/include/net.h
index e3889a0bc8..b7bac86cf1 100644
--- a/include/net.h
+++ b/include/net.h
@@ -365,6 +365,7 @@ struct vlan_ethernet_hdr {
 #define PROT_NCSI  0x88f8  /* NC-SI control packets*/
 
 #define IPPROTO_ICMP1  /* Internet Control Message Protocol*/
+#define IPPROTO_TCP6   /* Transmission Control Protocol*/
 #define IPPROTO_UDP17  /* User Datagram Protocol   */
 
 /*
@@ -688,19 +689,36 @@ static inline void net_send_packet(uchar *pkt, int len)
(void) eth_send(pkt, len);
 }
 
-/*
- * Transmit "net_tx_packet" as UDP packet, performing ARP request if needed
- *  (ether will be populated)
- *
- * @param ether Raw packet buffer
- * @param dest IP address to send the datagram to
- * @param dport Destination UDP port
- * @param sport Source UDP port
- * @param payload_len Length of data after the UDP header
+/**
+ * net_send_ip_packet() - Transmit "net_tx_packet" as UDP or TCP packet,
+ *send ARP request if needed (ether will be populated)
+ * @ether: Raw packet buffer
+ * @dest: IP address to send the datagram to
+ * @dport: Destination UDP port
+ * @sport: Source UDP port
+ * @payload_len: Length of data after the UDP header
+ * @action: TCP action to be performed
+ * @tcp_seq_num: TCP sequence number of this transmission
+ * @tcp_ack_num: TCP stream acknolegement number
+ *
+ * Return: 0 on success, other value on failure
  */
 int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport,
   int payload_len, int proto, u8 action, u32 tcp_seq_num,
   u32 tcp_ack_num);
+/**
+ * net_send_tcp_packet() - Transmit TCP packet.
+ * @payload_len: length of payload
+ * @dport: Destination TCP port
+ * @sport: Source TCP port
+ * @action: TCP action to be performed
+ * @tcp_seq_num: TCP sequence number of this transmission
+ * @tcp_ack_num: TCP stream acknolegement number
+ *
+ * Return: 0 on success, other value on failure
+ */
+int net_send_tcp_packet(int payload_len, int dport, int sport, u8 action,
+   u32 tcp_seq_num, u32 tcp_ack_num);
 int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport,
int sport, int payload_len);
 
diff --git a/include/net/tcp.h b/include/net/tcp.h
new file mode 100644
index 00..9c97f2f315
--- /dev/null
+++ b/include/net/tcp.h
@@ -0,0 +1,312 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * TCP Support with SACK for file transfer.
+ *
+ * Copyright 2017 Duncan Hare, All rights reserved.
+ */
+
+#define TCP_ACTIVITY 127   /* Number of packets received   */
+   /* before console progress mark */
+/**
+ * struct ip_tcp_hdr - IP and TCP header
+ * @ip_hl_v: header length and version
+ * @ip_tos: type of service
+ * @ip_len: total length
+ * @ip_id: identification
+ * @ip_off: fragment offset field
+ * @ip_ttl: time to live
+ * @ip_p: protocol
+ * @ip_sum: checksum
+ * @ip_src: Source IP address
+ * @ip_dst: Destination IP address
+ * @tcp_src: TCP source port
+ * @tcp_dst: TCP destination port
+ * @tcp_seq: TCP sequence number
+ * @tcp_ack: TCP Acknowledgment number
+ * @tcp_hlen: 4 bits TCP header Length/4, 4 bits reserved, 2 more bits reserved
+ * @tcp_flag: flags of TCP
+ * @tcp_win: TCP windows size
+ * @tcp_xsum: Checksum
+ * @tcp_ugr: Pointer to urgent data
+ */
+struct ip_tcp_hdr {
+   u8  ip_hl_v;
+   u8  ip_tos;
+   u16 ip_len;
+   u16 ip_id;
+   u16 ip_off;
+   u8  ip_ttl;
+   u8  ip_p;
+   u16 ip_sum;
+   struct in_addr  ip_src;
+   struct in_addr  ip_dst;
+   u16 tcp_src;
+   u16 tcp_dst;
+   u32 tcp_seq;
+   u32 tcp_ack;
+   u8  tcp_hlen;
+  

[PATCH v15 2/2] net: Add wget application

2022-06-10 Thread Ying-Chun Liu (PaulLiu)
From: "Ying-Chun Liu (PaulLiu)" 

This commit adds a simple wget command that can download files
from http server.

The command syntax is
wget ${loadaddr} 

Signed-off-by: Duncan Hare 
Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Christian Gmeiner 
Cc: Joe Hershberger 
Cc: Michal Simek 
Cc: Ramon Fried 
---
v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.
---
 cmd/Kconfig|   7 +
 cmd/net.c  |  13 ++
 include/net.h  |   2 +-
 include/net/wget.h |  22 +++
 net/Makefile   |   1 +
 net/net.c  |   6 +
 net/wget.c | 426 +
 7 files changed, 476 insertions(+), 1 deletion(-)
 create mode 100644 include/net/wget.h
 create mode 100644 net/wget.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 09193b61b9..5a5f2f1df8 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1715,6 +1715,13 @@ config NFS_TIMEOUT
  "ERROR: Cannot umount" in nfs command, try longer timeout such as
  1.
 
+config CMD_WGET
+   bool "wget"
+   select TCP
+   help
+ wget is a simple command to download kernel, or other files,
+ from a http server over TCP.
+
 config CMD_MII
bool "mii"
imply CMD_MDIO
diff --git a/cmd/net.c b/cmd/net.c
index 3619c843d8..60fd785061 100644
--- a/cmd/net.c
+++ b/cmd/net.c
@@ -124,6 +124,19 @@ U_BOOT_CMD(
 );
 #endif
 
+#if defined(CONFIG_CMD_WGET)
+static int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const 
argv[])
+{
+   return netboot_common(WGET, cmdtp, argc, argv);
+}
+
+U_BOOT_CMD(
+   wget,   3,  1,  do_wget,
+   "boot image via network using HTTP protocol",
+   "[loadAddress] [[hostIPaddr:]path and image name]"
+);
+#endif
+
 static void netboot_update_env(void)
 {
char tmp[22];
diff --git a/include/net.h b/include/net.h
index b7bac86cf1..fb80a8981d 100644
--- a/include/net.h
+++ b/include/net.h
@@ -559,7 +559,7 @@ extern int  net_restart_wrap;   /* Tried all 
network devices */
 
 enum proto_t {
BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP
+   TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP, WGET
 };
 
 extern charnet_boot_file_name[1024];/* Boot File name */
diff --git a/include/net/wget.h b/include/net/wget.h
new file mode 100644
index 00..da0920de11
--- /dev/null
+++ b/include/net/wget.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Duncan Hare Copyright 2017
+ */
+
+/**
+ * wget_start() - begin wget
+ */
+void wget_start(void);
+
+enum wget_state {
+   WGET_CLOSED,
+   WGET_CONNECTING,
+   WGET_CONNECTED,
+   WGET_TRANSFERRING,
+   WGET_TRANSFERRED
+};
+
+#define DEBUG_WGET 0   /* Set to 1 for debug messages */
+#define SERVER_PORT80
+#define WGET_RETRY_COUNT   30
+#define WGET_TIMEOUT   2000UL
diff --git a/net/Makefile b/net/Makefile
index d131d1cb1a..4f757a224c 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_UDP_FUNCTION_FASTBOOT)  += fastboot.o
 obj-$(CONFIG_CMD_WOL)  += wol.o
 obj-$(CONFIG_PROT_UDP) += udp.o
 obj-$(CONFIG_PROT_TCP) += tcp.o
+obj-$(CONFIG_CMD_WGET) += wget.o
 
 # Disable this warning as it is triggered by:
 # sprintf(buf, index ? "foo%d" : "foo", index)
diff --git a/net/net.c b/net/net.c
index 751d0251be..cee2ff8100 100644
--- a/net/net.c
+++ b/net/net.c
@@ -117,6 +117,7 @@
 #include "wol.h"
 #endif
 #include 
+#include 
 
 /** BOOTP EXTENTIONS **/
 
@@ -505,6 +506,11 @@ restart:
nfs_start();
break;
 #endif
+#if defined(CONFIG_CMD_WGET)
+   case WGET:
+   wget_start();
+   break;
+#endif
 #if defined(CONFIG_CMD_CDP)
case CDP:
cdp_start();
diff --git a/net/wget.c b/net/wget.c
new file mode 100644
index 00..4389e4ca23
--- /dev/null
+++ b/net/wget.c
@@ -0,0 +1,426 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * WGET/HTTP support driver based on U-BOOT's nfs.c
+ * Copyright Duncan Hare  2017
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const char bootfile1[] = "GET ";
+static const char bootfile3[] = " HTTP/1.0\r\n\r\n";
+static const char http_eom[] = "\r\n\r\n";
+static const char http_ok[] = "200";
+static const char content_len[] = "Content-Length";
+static const char linefeed[] = "\r\n";
+static struct in_addr web_server_ip;
+static int our_port;
+static int wget_timeout_count;
+
+struct pkt_qd {
+   uchar *pkt;
+   unsigned int tcp_seq_num;

[PATCH v15 0/2] add TCP and HTTP for downloading images

2022-06-10 Thread Ying-Chun Liu (PaulLiu)
From: "Ying-Chun Liu (PaulLiu)" 

This patch is a refresh from previous patches made by
Duncan Hare . I've contacted him and
continue to work on this patch.
 
This patch introduce a TCP stack with SACK. And a simple wget command
to download images from http server.

v1-v12: Made by Duncan, didn't tracked.
v13: Fix some issues which is reviewed by Christian
v14: Add options to enable/disable SACK.
v15: Fix various syntax errors reviewed by Michal.
 Remove magic numbers. Use kernel-doc format.

Ying-Chun Liu (PaulLiu) (2):
  net: Add TCP protocol
  net: Add wget application

 cmd/Kconfig|   7 +
 cmd/net.c  |  13 +
 include/net.h  |  38 ++-
 include/net/tcp.h  | 312 
 include/net/wget.h |  22 ++
 net/Kconfig|  16 +
 net/Makefile   |   2 +
 net/net.c  |  36 +++
 net/tcp.c  | 712 +
 net/wget.c | 426 +++
 10 files changed, 1574 insertions(+), 10 deletions(-)
 create mode 100644 include/net/tcp.h
 create mode 100644 include/net/wget.h
 create mode 100644 net/tcp.c
 create mode 100644 net/wget.c

-- 
2.35.1



[PATCH 1/1] configs: imx8mm-cl-iot-gate: enable extension command

2022-05-25 Thread Ying-Chun Liu (PaulLiu)
For imx8mm-cl-iot-gate we can use extension command to scan
extension boards attached on the mainboard. We enable the
extension command by default for users to detect the extension
boards.

Signed-off-by: Ying-Chun Liu (PaulLiu) 
Cc: Stefano Babic 
Cc: Fabio Estevam 
Cc: NXP i.MX U-Boot Team 
---
 configs/imx8mm-cl-iot-gate-optee_defconfig | 2 ++
 configs/imx8mm-cl-iot-gate_defconfig   | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/configs/imx8mm-cl-iot-gate-optee_defconfig 
b/configs/imx8mm-cl-iot-gate-optee_defconfig
index 8b3d1b3ef1..4a07d9afd7 100644
--- a/configs/imx8mm-cl-iot-gate-optee_defconfig
+++ b/configs/imx8mm-cl-iot-gate-optee_defconfig
@@ -31,6 +31,7 @@ CONFIG_SPL_POWER=y
 CONFIG_SPL_WATCHDOG=y
 CONFIG_SYS_PROMPT="u-boot=> "
 CONFIG_CMD_BOOTEFI_SELFTEST=y
+CONFIG_CMD_EXTENSION=y
 CONFIG_CMD_NVEDIT_EFI=y
 CONFIG_CMD_EEPROM=y
 CONFIG_CMD_SHA1SUM=y
@@ -79,6 +80,7 @@ CONFIG_FASTBOOT_BUF_SIZE=0x500
 CONFIG_FASTBOOT_FLASH=y
 CONFIG_FASTBOOT_FLASH_MMC_DEV=2
 CONFIG_MXC_GPIO=y
+CONFIG_DM_PCA953X=y
 CONFIG_DM_I2C=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_MISC=y
diff --git a/configs/imx8mm-cl-iot-gate_defconfig 
b/configs/imx8mm-cl-iot-gate_defconfig
index b418e86248..ccdacf56d9 100644
--- a/configs/imx8mm-cl-iot-gate_defconfig
+++ b/configs/imx8mm-cl-iot-gate_defconfig
@@ -33,6 +33,7 @@ CONFIG_SPL_POWER=y
 CONFIG_SPL_WATCHDOG=y
 CONFIG_SYS_PROMPT="u-boot=> "
 CONFIG_CMD_BOOTEFI_SELFTEST=y
+CONFIG_CMD_EXTENSION=y
 CONFIG_CMD_NVEDIT_EFI=y
 CONFIG_CMD_EEPROM=y
 CONFIG_CMD_SHA1SUM=y
@@ -82,6 +83,7 @@ CONFIG_FASTBOOT_BUF_SIZE=0x500
 CONFIG_FASTBOOT_FLASH=y
 CONFIG_FASTBOOT_FLASH_MMC_DEV=2
 CONFIG_MXC_GPIO=y
+CONFIG_DM_PCA953X=y
 CONFIG_DM_I2C=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_MISC=y
-- 
2.35.1



[PATCH 0/1] configs: imx8mm-cl-iot-gate: enable extension command

2022-05-25 Thread Ying-Chun Liu (PaulLiu)
For imx8mm-cl-iot-gate we can use extension command to scan
extension boards attached on the mainboard. We enable the
extension command by default for users to detect the extension
boards.

Ying-Chun Liu (PaulLiu) (1):
  configs: imx8mm-cl-iot-gate: enable extension command

 configs/imx8mm-cl-iot-gate-optee_defconfig | 2 ++
 configs/imx8mm-cl-iot-gate_defconfig   | 2 ++
 2 files changed, 4 insertions(+)

-- 
2.35.1



Re: [PATCH v14 1/2] net: Add TCP protocol

2022-04-21 Thread Ying-Chun Liu (PaulLiu)

Hi Ying,
You woke up an old can, Can you elaborate on the changes you did to
the original patchset ?
I'm reviewing this instead of Joe, so I want to get some context.

I would appreciate it if you could separate the SACK support to a
separate patch, preferably option based.
The TCP stack is complicated enough and will require a lot of
tinkering / bug fixing in the future. It's best if we could turn
on/off specific RFC which are not originally part of the TCP protocol.

Thanks,
Ramon


Hi Ramon,

Please review this patch again.

I've added an option to disable/enable SACK.
However it is harder to separate the SACK support as a separate commit.
I continue the old one which was together with SACK already.

Thanks a lot,
Paul



Re: Question about extension board used in U-boot

2021-09-21 Thread Ying-Chun Liu (PaulLiu)
Hi Heinrich,

I think I met some chicken and egg problem. Or I misunderstand something
you mentioned.


So I tried board_fdt_blob_setup() and board_fix_fdt().
Both are too early.
I need i2c to be drived first. And then I can use
dm_i2c_probe() on different address to detect which extension board it is.
However, in board_fdt_blob_setup() or board_fix_fdt(). i2c seems not
working there.
I can do the detection in board_late_init() but it is just too late for
U-boot itself.
Good for Linux kernel though.


Sorry for my bad English. Measured boot is already working on my branch.
But the way I implemented this is directly modify the dts of U-boot and
assume
the TPM extension board is always there. Thus this is not upstreamable.


I think let me upstream some code by extension manager first (for linux
kernel first).
And then we can see how the detection is implemented and how to modify
it for U-boot.


Thanks,
Paul


Heinrich Schuchardt 於 2021/9/18 下午3:14 寫道:
>
>
> On 9/18/21 8:54 AM, François Ozog wrote:
>> Le sam. 18 sept. 2021 à 08:49, François Ozog
>>  a
>> écrit :
>>
>>> Hi Paul
>>>
>>> Too posting because I think we also need to address this at a higher
>>> level.
>>>
>>> i think we discussed this topic quite a while back. I may be wrong
>>> but it
>>> may be Bill Mills who proposed to have an eeprom on the extensions
>>> that the
>>> carrier board can use to detect and fetch proper overlay. Another
>>> way would
>>> be that the contract between the extension board and the carrier board
>>> includes an i2c accessible storage to fetch an overlay that would
>>> identify
>>> the board and give all details.
>>>
>> i just forgot to state that the mode is well known: SPD for DIMMs.
>>
>>> Bottom line, a software only solution seems not entirely satisfying.
>>> In that suboptimal case, U-Boot shall be able to assemble a DT for
>>> itself
>>> and another for OS (may be same in some cases) through scripting.
>>> And in
>>> this case, come your questions  below
>>>
>>> .
>>>
>>> Le sam. 18 sept. 2021 à 01:21, Ying-Chun Liu (PaulLiu)
>>> 
>>> a écrit :
>>>
>>>> Hi all,
>>>>
>>>>
>>>> I have some questions about how to implement extension board usage.
>>>> My case is on imx8mm-cl-iot-gate. It can add three different types of
>>>> extension boards.
>>>> One of the extension boards is SPI extension which have 3 empty slots.
>>>> And you can add
>>>> some small boards onto it. One of them is a "TPM2" module.
>
> You could implement the weak function board_fdt_blob_setup() to detect
> your addon boards and extend the devicetree.
>
>
>>>>
>>>>
>>>> My first question is if I want to use tpm2 in U-boot for measured
>>>> boot.
>>>> How to implement this right? Currently I just modify the dts used by
>>>> U-boot to let it drive
>
> Measured boot is provided in U-Boot v2021.10-rc4 based on TPMv2. Just
> enable CONFIG_EFI_TCG2_PROTOCOL.
>
>>>> the extension board. And let it drive the TPM. But it is not good for
>>>> upstreaming because
>>>> when other types of extension boards installed then it is not working.
>>>> Where to implement this? What is the best practice of this?
>>>
>>>
>>>> The second question is about extension manager.
>>>> I have read the extension.rst. I think I'll implement this anyway
>>>> because then
>>>> I can have a command to query what type of extension boards I have.
>>>> And if the extension board is the 3 slots one. I can then detect which
>>>> slot is the TPM.
>>>> I'll implement this anyway because the "extension" command is
>>>> convenient
>>>> for users.
>>>> But it seems to me that it only solves the problem for Linux kernel.
>>>> It can apply a DTB Overlay to Linux DTB to let Linux knows we have
>>>> that
>>>> extension board.
>>>> But it is too late for U-boot itself, right?
>>>>
>>>>
>>>> The third question is I'm also dong SystemReady IR certificate.
>>>> That means
>>>> the dtb for Linux is directly provided by U-boot. We use U-boot dtb
>>>> directly to Linux
>>>> kernel. In this case, how to modify that dts dynamically to feed to
>>>> the
>>>> Linux kernel by
>>>> the extension manager?
>
> U-Boot has a fdt command which you could use to apply overlays. Or
> implement function board_fdt_blob_setup().
>
> Best regards
>
> Heinrich
>
>>>> What is the best practice if I want to use U-boot dts for Linux in
>>>> implementation?
>>>>
>>>>
>>>> Thanks a lot.
>>>>
>>>>
>>>> Yours,
>>>> Paul
>>>>
>>>>
>>>> -- 
>>> François-Frédéric Ozog | *Director Business Development*
>>> T: +33.67221.6485
>>> francois.o...@linaro.org | Skype: ffozog
>>>
>>> -- 
>> François-Frédéric Ozog | *Director Business Development*
>> T: +33.67221.6485
>> francois.o...@linaro.org | Skype: ffozog
>> ___
>> boot-architecture mailing list
>> boot-architect...@lists.linaro.org
>> https://lists.linaro.org/mailman/listinfo/boot-architecture
>>



OpenPGP_signature
Description: OpenPGP digital signature


Question about extension board used in U-boot

2021-09-17 Thread Ying-Chun Liu (PaulLiu)
Hi all,


I have some questions about how to implement extension board usage.
My case is on imx8mm-cl-iot-gate. It can add three different types of
extension boards.
One of the extension boards is SPI extension which have 3 empty slots.
And you can add
some small boards onto it. One of them is a "TPM2" module.


My first question is if I want to use tpm2 in U-boot for measured boot.
How to implement this right? Currently I just modify the dts used by
U-boot to let it drive
the extension board. And let it drive the TPM. But it is not good for
upstreaming because
when other types of extension boards installed then it is not working.
Where to implement this? What is the best practice of this?


The second question is about extension manager.
I have read the extension.rst. I think I'll implement this anyway
because then
I can have a command to query what type of extension boards I have.
And if the extension board is the 3 slots one. I can then detect which
slot is the TPM.
I'll implement this anyway because the "extension" command is convenient
for users.
But it seems to me that it only solves the problem for Linux kernel.
It can apply a DTB Overlay to Linux DTB to let Linux knows we have that
extension board.
But it is too late for U-boot itself, right?


The third question is I'm also dong SystemReady IR certificate. That means
the dtb for Linux is directly provided by U-boot. We use U-boot dtb
directly to Linux
kernel. In this case, how to modify that dts dynamically to feed to the
Linux kernel by
the extension manager?
What is the best practice if I want to use U-boot dts for Linux in
implementation?


Thanks a lot.


Yours,
Paul




OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH] usb: ehci-mx6: Limit PHY address parsing to !CONFIG_PHY

2021-04-28 Thread Ying-Chun Liu (PaulLiu)

Marek Vasut 於 2021/4/28 上午12:06 寫道:
> For systems which use generic PHY support and implement USB PHY driver,
> the parsing of PHY properties is unnecessary, disable it.
>
> Signed-off-by: Marek Vasut 
> Cc: Fabio Estevam 
> Cc: Peng Fan 
> Cc: Stefano Babic 
> Cc: Tim Harvey 
> Cc: Ye Li 
> Cc: uboot-imx 
> ---
>  drivers/usb/host/ehci-mx6.c | 17 -
>  1 file changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
> index 7642a31b655..06be9deaaae 100644
> --- a/drivers/usb/host/ehci-mx6.c
> +++ b/drivers/usb/host/ehci-mx6.c
> @@ -265,6 +265,8 @@ int usb_phy_mode(int port)
>  }
>  #endif
>  
> +#if !defined(CONFIG_PHY)
> +/* Should be done in the MXS PHY driver */
>  static void usb_oc_config(struct usbnc_regs *usbnc, int index)
>  {
>   void __iomem *ctrl = (void __iomem *)(>ctrl[index]);
> @@ -285,6 +287,7 @@ static void usb_oc_config(struct usbnc_regs *usbnc, 
int index)
>   clrbits_le32(ctrl, UCTRL_PWR_POL);
>  #endif
>  }
> +#endif
>  
>  #if !CONFIG_IS_ENABLED(DM_USB)
>  /**
> @@ -432,10 +435,12 @@ struct ehci_mx6_priv_data {
>   struct clk clk;
>   struct phy phy;
>   enum usb_init_type init_type;
> +#if !defined(CONFIG_PHY)
>   int portnr;
>   void __iomem *phy_addr;
>   void __iomem *misc_addr;
>   void __iomem *anatop_addr;
> +#endif
>  };
>  
>  static int mx6_init_after_reset(struct ehci_ctrl *dev)
> @@ -448,14 +453,14 @@ static int mx6_init_after_reset(struct ehci_ctrl *dev)
>   usb_power_config_mx6(priv->anatop_addr, priv->portnr);
>   usb_power_config_mx7(priv->misc_addr);
>   usb_power_config_mx7ulp(priv->phy_addr);
> -#endif
>  
>   usb_oc_config(priv->misc_addr, priv->portnr);
>  
> -#if !defined(CONFIG_PHY) && (defined(CONFIG_MX6) || defined(CONFIG_MX7ULP))
> +#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP)
>   usb_internal_phy_clock_gate(priv->phy_addr, 1);
>   usb_phy_enable(ehci, priv->phy_addr);
>  #endif
> +#endif
>  
>  #if CONFIG_IS_ENABLED(DM_REGULATOR)
>   if (priv->vbus_supply) {
> @@ -558,6 +563,7 @@ static int ehci_usb_of_to_plat(struct udevice *dev)
>  
>  static int mx6_parse_dt_addrs(struct udevice *dev)
>  {
> +#if !defined(CONFIG_PHY)
>   struct ehci_mx6_priv_data *priv = dev_get_priv(dev);
>   int phy_off, misc_off;
>   const void *blob = gd->fdt_blob;
> @@ -594,7 +600,7 @@ static int mx6_parse_dt_addrs(struct udevice *dev)
>  
>   priv->misc_addr = addr;
>  
> -#if !defined(CONFIG_PHY) && defined(CONFIG_MX6)
> +#if defined(CONFIG_MX6)
>   int anatop_off;
>  
>   /* Resolve ANATOP offset through USB PHY node */
> @@ -607,6 +613,7 @@ static int mx6_parse_dt_addrs(struct udevice *dev)
>   return -EINVAL;
>  
>   priv->anatop_addr = addr;
> +#endif
>  #endif
>   return 0;
>  }
> @@ -661,14 +668,14 @@ static int ehci_usb_probe(struct udevice *dev)
>   usb_power_config_mx6(priv->anatop_addr, priv->portnr);
>   usb_power_config_mx7(priv->misc_addr);
>   usb_power_config_mx7ulp(priv->phy_addr);
> -#endif
>  
>   usb_oc_config(priv->misc_addr, priv->portnr);
>  
> -#if !defined(CONFIG_PHY) && (defined(CONFIG_MX6) || defined(CONFIG_MX7ULP))
> +#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP)
>   usb_internal_phy_clock_gate(priv->phy_addr, 1);
>   usb_phy_enable(ehci, priv->phy_addr);
>  #endif
> +#endif
>  
>  #if CONFIG_IS_ENABLED(DM_REGULATOR)
>   if (priv->vbus_supply) {


Tested-by: Ying-Chun Liu (PaulLiu) 


Tested on IMX8M Compulab IoT gate







OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH V2 24/24] ARM: imx8m: verdin-imx8mm: Enable USB Host support

2021-04-22 Thread Ying-Chun Liu (PaulLiu)
Hi Marek,

I have the same issue on my iMX8MM based board.
Are you continue working on the patch for iMX8MM or should I dig into
this problem?

I'm asking this just for not duplicating efforts.
So if you are not working on this then I'll see if I can properly
retrieve the necessary patches to make this work.


I think something is missing from previous patch set

https://lists.denx.de/pipermail/u-boot/2020-September/426757.html


Yours,
Paul

Tim Harvey 於 2021/4/20 上午8:33 寫道:
> On Sun, Apr 11, 2021 at 9:35 AM Marek Vasut  wrote:
>> Enable USB host support on MX8MM Verdin.
>>
>> Signed-off-by: Marek Vasut 
>> Cc: Marcel Ziswiler 
>> Cc: Max Krummenacher 
>> Cc: Oleksandr Suvorov 
>> ---
>> V2: No change
>> ---
>>  configs/verdin-imx8mm_defconfig | 8 +++-
>>  include/configs/verdin-imx8mm.h | 5 +
>>  2 files changed, 12 insertions(+), 1 deletion(-)
>>
>> diff --git a/configs/verdin-imx8mm_defconfig 
>> b/configs/verdin-imx8mm_defconfig
>> index ea0b5978f1..c8c3420b6a 100644
>> --- a/configs/verdin-imx8mm_defconfig
>> +++ b/configs/verdin-imx8mm_defconfig
>> @@ -37,7 +37,6 @@ CONFIG_SPL_BOARD_INIT=y
>>  CONFIG_SPL_SEPARATE_BSS=y
>>  CONFIG_SPL_I2C_SUPPORT=y
>>  CONFIG_SPL_POWER_SUPPORT=y
>> -CONFIG_SPL_USB_HOST_SUPPORT=y
>>  CONFIG_SPL_WATCHDOG_SUPPORT=y
>>  CONFIG_SYS_PROMPT="Verdin iMX8MM # "
>>  # CONFIG_BOOTM_NETBSD is not set
>> @@ -50,6 +49,7 @@ CONFIG_CMD_FUSE=y
>>  CONFIG_CMD_GPIO=y
>>  CONFIG_CMD_I2C=y
>>  CONFIG_CMD_MMC=y
>> +CONFIG_CMD_USB=y
>>  CONFIG_CMD_CACHE=y
>>  CONFIG_CMD_UUID=y
>>  CONFIG_CMD_REGULATOR=y
>> @@ -89,6 +89,8 @@ CONFIG_MII=y
>>  CONFIG_PINCTRL=y
>>  CONFIG_SPL_PINCTRL=y
>>  CONFIG_PINCTRL_IMX8M=y
>> +CONFIG_POWER_DOMAIN=y
>> +CONFIG_IMX8M_POWER_DOMAIN=y
>>  CONFIG_DM_PMIC=y
>>  CONFIG_SPL_DM_PMIC_PCA9450=y
>>  CONFIG_DM_PMIC_PFUZE100=y
>> @@ -101,5 +103,9 @@ CONFIG_SPL_SYSRESET=y
>>  CONFIG_SYSRESET_PSCI=y
>>  CONFIG_SYSRESET_WATCHDOG=y
>>  CONFIG_DM_THERMAL=y
>> +CONFIG_USB=y
>> +CONFIG_DM_USB=y
>> +# CONFIG_SPL_DM_USB is not set
>> +CONFIG_USB_EHCI_HCD=y
>>  CONFIG_IMX_WATCHDOG=y
>>  CONFIG_OF_LIBFDT_OVERLAY=y
>> diff --git a/include/configs/verdin-imx8mm.h 
>> b/include/configs/verdin-imx8mm.h
>> index 4751bf5a5a..e2a817891c 100644
>> --- a/include/configs/verdin-imx8mm.h
>> +++ b/include/configs/verdin-imx8mm.h
>> @@ -117,5 +117,10 @@
>>  #define FEC_QUIRK_ENET_MAC
>>  #define IMX_FEC_BASE   0x30BE
>>
>> +/* USB Configs */
>> +#define CONFIG_EHCI_HCD_INIT_AFTER_RESET
>> +#define CONFIG_MXC_USB_PORTSC  (PORT_PTS_UTMI | PORT_PTS_PTW)
>> +#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
>> +
>>  #endif /*_VERDIN_IMX8MM_H */
>>
>> --
>> 2.30.2
>>
> Marek,
>
> Thanks for your work on USB support for IMX8M!
>
> I'm attempting to add USB support to the venice board following this
> example but I think there are still some things missing from the dt to
> make this work. I find that mx6_parse_dt_adds failes; Looks like it is
> required to have an alias that points to the phy but then it fails
> because the phy doesn't have a reg. Also, it would see the
> CONFIG_MXC_USB_PORTSC is no longer needed as that is now the default.
>
> Best regards,
>
> Tim



OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH v2 1/2] power: regulator: add driver for ANATOP regulator

2021-03-23 Thread Ying-Chun Liu (PaulLiu)
Hi Sean,

Thanks for the review. I fix almost of the issues. Will upload the v3 soon.

Still have some questions.


Sean Anderson 於 2021/3/23 下午11:06 寫道:
>
>
>
> if (anatop_reg->supply) {
>     ret = regulator_set_value(anatop_reg->supply, uV + 15);
>     if (ret)
>     return ret;
> }
>

What is 15? Is it the min_dropout_uV?

Should I set it to 125000 instead?



>
>
> 
> ret = regulator_set_enable(sreg->supply, true);
> if (ret)
>     return ret;
>

Since vin-supply is optional, I change it to

    ret = device_get_supply_regulator(dev, "vin-supply",
  _reg->supply);
    if (!ret) {
    ret = regulator_set_enable(anatop_reg->supply, true);
    if (ret)
    return ret;
    }

Is this ok?

> > +
> > +    ret = ofnode_read_u32(dev_ofnode(dev),
>
> > +U_BOOT_DRIVER(anatop_regulator) = {
> > +    .name = "anatop_regulator",
> > +    .id = UCLASS_REGULATOR,
> > +    .ops = _regulator_ops,
> > +    .of_match = of_anatop_regulator_match_tbl,
> > +    .plat_auto = sizeof(struct anatop_regulator),
> > +    .probe = anatop_regulator_probe,
> > +};
> >


Yours,
Paul



Re: [PATCH 1/2] dts: add iot-gate-imx8 dts file

2020-12-01 Thread Ying-Chun Liu (PaulLiu)


Peter Robinson 於 2020/12/2 上午2:02 寫道:
> Hi Ying-Chun Liu,
>
> On Tue, Dec 1, 2020 at 5:35 PM Ying-Chun Liu  wrote:
>> From: "Ying-Chun Liu (PaulLiu)" 
>>
>> Add board dts for iot-gate-imx8
>>
>> Signed-off-by: Kirill Kapranov 
>> Signed-off-by: Uri Mashiach 
>> Signed-off-by: Valentin Raevsky 
>> Signed-off-by: Ying-Chun Liu (PaulLiu) 
>> ---
>>  arch/arm/dts/Makefile  |   2 +
>>  arch/arm/dts/iot-gate-imx8-u-boot.dtsi | 131 ++
>>  arch/arm/dts/iot-gate-imx8.dts | 550 +
> The naming of these files are incorrect, all upstream Linux and U-Boot
> files are SoC then name, so based on the name of the include file and
> other imx8mm based devices it should likely be imx8mm-iot-gate.dts or
> similar.
>

Hi Peter,

Thanks a lot.

I will change everything to imx8mm-iot-gate immediately and resent the
patches.

Yours,
Paul