Re: [PATCH 1/6] cpu: add t-head's c9xx

2024-03-27 Thread Nils Le Roux

Hi!

I tested this and it works fine. I also happen to have the glue layer ported
from the Linux somewhere on my machine. If you're interested, please 
reach out

to me and I'll arrange a patch. I have a few remarks on this patch:

On 3/27/24 9:07 AM, w...@redhat.com wrote:

From: Wei Fu 

Signed-off-by: Wei Fu 
Co-authored-by: Yixun Lan 
---
  arch/riscv/Kconfig   |  1 +
  arch/riscv/cpu/c9xx/Kconfig  | 12 
  arch/riscv/cpu/c9xx/Makefile |  5 
  arch/riscv/cpu/c9xx/cpu.c| 51 
  arch/riscv/cpu/c9xx/dram.c   | 36 ++
  arch/riscv/include/asm/csr.h |  2 ++
  board/thead/th1520_lpi4a/Kconfig |  3 +-
  7 files changed, 109 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index ac52c5e6da..ac3b802abe 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -97,6 +97,7 @@ source "arch/riscv/cpu/fu540/Kconfig"
  source "arch/riscv/cpu/fu740/Kconfig"
  source "arch/riscv/cpu/generic/Kconfig"
  source "arch/riscv/cpu/jh7110/Kconfig"
+source "arch/riscv/cpu/c9xx/Kconfig"
  
  # architecture-specific options below
  
diff --git a/arch/riscv/cpu/c9xx/Kconfig b/arch/riscv/cpu/c9xx/Kconfig

new file mode 100644
index 00..5a84bcacd6
--- /dev/null
+++ b/arch/riscv/cpu/c9xx/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2017-2020 Alibaba Group Holding Limited
+
+config RISCV_THEAD
+   bool
+   select ARCH_EARLY_INIT_R
+   imply CPU
+   imply CPU_RISCV
+   imply RISCV_TIMER
+   imply RISCV_RDTIME
+   imply CMD_CPU
diff --git a/arch/riscv/cpu/c9xx/Makefile b/arch/riscv/cpu/c9xx/Makefile
new file mode 100644
index 00..e3f776cb41
--- /dev/null
+++ b/arch/riscv/cpu/c9xx/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2017-2020 Alibaba Group Holding Limited
+
+obj-y += cpu.o dram.o
diff --git a/arch/riscv/cpu/c9xx/cpu.c b/arch/riscv/cpu/c9xx/cpu.c
new file mode 100644
index 00..4b21edd62b
--- /dev/null
+++ b/arch/riscv/cpu/c9xx/cpu.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017-2020 Alibaba Group Holding Limited
+ */
+
+#include 
+#include 
+#include 
+
+/*
+ * cleanup_before_linux() is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * we disable interrupt and caches.
+ */
+int cleanup_before_linux(void)
+{
+   cache_flush();
+
+   return 0;
+}
+
+void flush_dcache_range(unsigned long start, unsigned long end)
+{
+   register unsigned long i asm("a0") = start & 
~(CONFIG_SYS_CACHELINE_SIZE - 1);

Isn't this just round_down/ALIGN_DOWN macro?

+
+   for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
+   asm volatile(".long 0x0295000b");  /* dcache.cpa a0 */
+
+   sync_is();
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long end)
+{
+   register unsigned long i asm("a0") = start & 
~(CONFIG_SYS_CACHELINE_SIZE - 1);
+
+   for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
+   asm volatile(".long 0x02b5000b");  /* dcache.cipa a0 */


`th.dcache.cipa` not only invalidates the dcache, but also flushes it 
which is
not expected here. In practice, this leads to a bug with the dwmac 
driver: when

U-Boot handles an ARP request, it overwrites the ARP request with the ARP
response in-place, directly in the ring buffer[^1]. When re-using the same
buffer later on, the driver will flush this data instead of invalidating
it[^2], and you'll read the ARP response you just sent instead of the packet
just written by the chip.

This can easily be reproduced by downloading a big file using TFTP. As 
soon as

you receive an ARP request, U-Boot hangs, timeouts and requests the packet
again. It also makes TCP completely unusable.

You can use `th.dcache.ipa` instead, as implemented in 
`invalid_dcache_range`.


[^1] 
https://github.com/u-boot/u-boot/blob/a5ec56aea1a56737a4e124d058a6920d16f5e686/net/arp.c#L154-L160
[^2] 
https://github.com/u-boot/u-boot/blob/a5ec56aea1a56737a4e124d058a6920d16f5e686/drivers/net/designware.c#L542



+
+   sync_is();
+}
+
+void invalid_dcache_range(unsigned long start, unsigned long end)


I think this isn't used anywhere.


+{
+   register unsigned long i asm("a0") = start & 
~(CONFIG_SYS_CACHELINE_SIZE - 1);
+
+   for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
+   asm volatile(".long 0x02a5000b");  /* dcache.ipa a0 */
+
+   sync_is();
+}
diff --git a/arch/riscv/cpu/c9xx/dram.c b/arch/riscv/cpu/c9xx/dram.c
new file mode 100644
index 00..614d7bf1cc
--- /dev/null
+++ b/arch/riscv/cpu/c9xx/dram.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng 
+ */
+
+#include 
+#include 
+#include 
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+   return fdtdec_setup_mem_size_base();
+}
+
+int dram_init_banksize(void)
+{
+   return 

[PATCH v2] net: designware: Support high memory nodes

2023-12-02 Thread Nils Le Roux
Some platforms (such as the Lichee Pi 4A) have their dwmac device
addressable only in high memory space. Storing the node's base address
on 32 bits is not possible in such case.

Use platform's physical address type to store the base address.

Signed-off-by: Nils Le Roux 
Cc: Andre Przywara 
---

Changes in v2:
- explicitly define and handle ioaddr as a virtual address
- use an intermediate variable to assign the PCI base address
- use appropriate placeholder to print physical addresses
---
 drivers/net/designware.c | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index a174344b3e..78bfce07f6 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -678,8 +678,8 @@ int designware_eth_probe(struct udevice *dev)
 {
struct eth_pdata *pdata = dev_get_plat(dev);
struct dw_eth_dev *priv = dev_get_priv(dev);
-   u32 iobase = pdata->iobase;
-   ulong ioaddr;
+   phys_addr_t iobase = pdata->iobase;
+   void *ioaddr;
int ret, err;
struct reset_ctl_bulk reset_bulk;
 #ifdef CONFIG_CLK
@@ -740,16 +740,18 @@ int designware_eth_probe(struct udevice *dev)
 * or via a PCI bridge, fill in plat before we probe the hardware.
 */
if (IS_ENABLED(CONFIG_PCI) && device_is_on_pci_bus(dev)) {
-   dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0, );
-   iobase &= PCI_BASE_ADDRESS_MEM_MASK;
-   iobase = dm_pci_mem_to_phys(dev, iobase);
+   u32 pcibase;
 
+   dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0, );
+   pcibase &= PCI_BASE_ADDRESS_MEM_MASK;
+
+   iobase = dm_pci_mem_to_phys(dev, pcibase);
pdata->iobase = iobase;
pdata->phy_interface = PHY_INTERFACE_MODE_RMII;
}
 
-   debug("%s, iobase=%x, priv=%p\n", __func__, iobase, priv);
-   ioaddr = iobase;
+   debug("%s, iobase=%pa, priv=%p\n", __func__, , priv);
+   ioaddr = phys_to_virt(iobase);
priv->mac_regs_p = (struct eth_mac_regs *)ioaddr;
priv->dma_regs_p = (struct eth_dma_regs *)(ioaddr + DW_DMA_BASE_OFFSET);
priv->interface = pdata->phy_interface;
-- 
2.43.0



[PATCH] net: designware: Support high memory nodes

2023-11-11 Thread Nils Le Roux
Some platforms (such as the Lichee Pi 4A) have their dwmac device
addressable only in high memory space. Storing the node's base address
on 32 bits is not possible in such case.

Use platform's physical address type to store the base address.

Signed-off-by: Nils Le Roux 
---

 drivers/net/designware.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index a174344b3e..327732fbf7 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -678,8 +678,8 @@ int designware_eth_probe(struct udevice *dev)
 {
struct eth_pdata *pdata = dev_get_plat(dev);
struct dw_eth_dev *priv = dev_get_priv(dev);
-   u32 iobase = pdata->iobase;
-   ulong ioaddr;
+   phys_addr_t iobase = pdata->iobase;
+   phys_addr_t ioaddr;
int ret, err;
struct reset_ctl_bulk reset_bulk;
 #ifdef CONFIG_CLK
@@ -740,7 +740,7 @@ int designware_eth_probe(struct udevice *dev)
 * or via a PCI bridge, fill in plat before we probe the hardware.
 */
if (IS_ENABLED(CONFIG_PCI) && device_is_on_pci_bus(dev)) {
-   dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0, );
+   dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0, (u32 *));
iobase &= PCI_BASE_ADDRESS_MEM_MASK;
iobase = dm_pci_mem_to_phys(dev, iobase);
 
@@ -748,7 +748,7 @@ int designware_eth_probe(struct udevice *dev)
pdata->phy_interface = PHY_INTERFACE_MODE_RMII;
}
 
-   debug("%s, iobase=%x, priv=%p\n", __func__, iobase, priv);
+   debug("%s, iobase=%llx, priv=%p\n", __func__, (u64)iobase, priv);
ioaddr = iobase;
priv->mac_regs_p = (struct eth_mac_regs *)ioaddr;
priv->dma_regs_p = (struct eth_dma_regs *)(ioaddr + DW_DMA_BASE_OFFSET);
-- 
2.42.1