All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/12] riscv: Add support for P8700 platform on Boston board
@ 2025-07-29 16:21 Uros Stajic
  2025-07-29 16:22 ` [PATCH v3 01/12] riscv: Add initial support for P8700 SoC Uros Stajic
                   ` (11 more replies)
  0 siblings, 12 replies; 20+ messages in thread
From: Uros Stajic @ 2025-07-29 16:21 UTC (permalink / raw)
  To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Uros Stajic

This patch series adds platform support for the P8700 processor
running on the Boston board.

P8700-F is a high-performance RV64GC SoC that supports hardware
multithreading and optional multi-cluster configurations.

----
Changes in v3:
- 01/12 - Split original patch into CPU/Board parts
- 02/12 - New patch: extracted board-specific logic from original 01/12
- 01/12 - Relocated object rule for p8700 into p8700-specific Makefile
- 01/12 - Explained .word usage for mcache instruction and replaced it
          with symbolic macro
- 01/12 - Replaced inline assembly lw instruction with readl()
- 01/12 - Removed p8700 code from start.S, moved to harts_early_init()
- 02/12 - Fixed operand spacing in assembly
- 02/12 - Replaced hardcoded address with properly macros
- 02/12 - Switched from riscv,isa to riscv,isa-extensions
- 02/12 - Sorted DT properties properly

Changes in v2:
- 03/11 - Remove redundant pcie_xilinx_probe() and update commit
	  message accordingly.
----


Chao-ying Fu (11):
  riscv: Add initial support for P8700 SoC
  board: boston-riscv: Add initial support for P8700 Boston board
  gpio: Add GPIO driver for Intel EG20T
  pci: xilinx: Avoid writing memory base/limit for root bridge
  riscv: Add support for MIPS GIC syscon on RISC-V SoCs
  net: pch_gbe: Add PHY reset and MAC address fallback for RISC-V
  libfdt: Allow non-64b aligned memreserve entries
  riscv: p8700: Add software emulation for AMO* instructions
  riscv: p8700: Add Coherence Manager (CM) and IOCU support
  riscv: boston: Add support for LED character display command
  cmd: riscv: Add 'startharts' command to start multiple harts

Uros Stajic (1):
  timer: p8700: Add support for reading time from memory-mapped mtime

 arch/riscv/Kconfig                          |  22 ++
 arch/riscv/cpu/p8700/Kconfig                |  15 +
 arch/riscv/cpu/p8700/Makefile               |  12 +
 arch/riscv/cpu/p8700/cache.c                | 103 +++++++
 arch/riscv/cpu/p8700/cm-iocu.c              |  75 +++++
 arch/riscv/cpu/p8700/cm.c                   |  92 ++++++
 arch/riscv/cpu/p8700/cpu.c                  |  13 +
 arch/riscv/cpu/p8700/dram.c                 |  37 +++
 arch/riscv/cpu/p8700/emu-amo.S              | 254 +++++++++++++++++
 arch/riscv/cpu/p8700/p8700_platform_setup.S | 169 +++++++++++
 arch/riscv/dts/Makefile                     |   1 +
 arch/riscv/dts/boston-p8700.dts             | 256 +++++++++++++++++
 arch/riscv/include/asm/arch-p8700/cm.h      |  61 ++++
 arch/riscv/include/asm/arch-p8700/p8700.h   | 144 ++++++++++
 arch/riscv/include/asm/global_data.h        |   2 +
 arch/riscv/include/asm/io.h                 |  86 ++++++
 arch/riscv/lib/Makefile                     |   1 +
 arch/riscv/lib/interrupts.c                 | 299 ++++++++++++++++++++
 arch/riscv/lib/mips_gic.c                   |  47 +++
 board/mips/boston-riscv/Kconfig             |  51 ++++
 board/mips/boston-riscv/MAINTAINERS         |  15 +
 board/mips/boston-riscv/Makefile            |  10 +
 board/mips/boston-riscv/boston-lcd.h        |  20 ++
 board/mips/boston-riscv/boston-regs.h       |  38 +++
 board/mips/boston-riscv/boston-riscv.c      |   9 +
 board/mips/boston-riscv/checkboard.c        |  43 +++
 board/mips/boston-riscv/config.mk           |  15 +
 board/mips/boston-riscv/display.c           |  33 +++
 board/mips/boston-riscv/iocu.c              | 104 +++++++
 board/mips/boston-riscv/lowlevel_init.S     |  20 ++
 board/mips/boston-riscv/reset.c             |  15 +
 cmd/Kconfig                                 |  14 +
 cmd/Makefile                                |   2 +
 cmd/display.c                               |  51 ++++
 cmd/start_harts.c                           | 103 +++++++
 configs/boston-p8700_defconfig              |  95 +++++++
 doc/README.LED_display                      |  26 ++
 drivers/clk/Kconfig                         |   2 +-
 drivers/gpio/Kconfig                        |   7 +
 drivers/gpio/Makefile                       |   1 +
 drivers/gpio/eg20t-gpio.c                   | 138 +++++++++
 drivers/net/pch_gbe.c                       |  37 ++-
 drivers/net/pch_gbe.h                       |   1 +
 drivers/pci/pcie_xilinx.c                   |   9 +
 drivers/timer/riscv_timer.c                 |   7 +
 include/asm-generic/global_data.h           |   5 +
 include/configs/boston-riscv.h              |  11 +
 include/interrupt.h                         |  19 ++
 include/led-display.h                       |  33 +++
 net/eth-uclass.c                            |   2 +
 scripts/dtc/libfdt/fdt_ro.c                 |  11 +-
 51 files changed, 2630 insertions(+), 6 deletions(-)
 create mode 100644 arch/riscv/cpu/p8700/Kconfig
 create mode 100644 arch/riscv/cpu/p8700/Makefile
 create mode 100644 arch/riscv/cpu/p8700/cache.c
 create mode 100644 arch/riscv/cpu/p8700/cm-iocu.c
 create mode 100644 arch/riscv/cpu/p8700/cm.c
 create mode 100644 arch/riscv/cpu/p8700/cpu.c
 create mode 100644 arch/riscv/cpu/p8700/dram.c
 create mode 100644 arch/riscv/cpu/p8700/emu-amo.S
 create mode 100644 arch/riscv/cpu/p8700/p8700_platform_setup.S
 create mode 100644 arch/riscv/dts/boston-p8700.dts
 create mode 100644 arch/riscv/include/asm/arch-p8700/cm.h
 create mode 100644 arch/riscv/include/asm/arch-p8700/p8700.h
 create mode 100644 arch/riscv/lib/mips_gic.c
 create mode 100644 board/mips/boston-riscv/Kconfig
 create mode 100644 board/mips/boston-riscv/MAINTAINERS
 create mode 100644 board/mips/boston-riscv/Makefile
 create mode 100644 board/mips/boston-riscv/boston-lcd.h
 create mode 100644 board/mips/boston-riscv/boston-regs.h
 create mode 100644 board/mips/boston-riscv/boston-riscv.c
 create mode 100644 board/mips/boston-riscv/checkboard.c
 create mode 100644 board/mips/boston-riscv/config.mk
 create mode 100644 board/mips/boston-riscv/display.c
 create mode 100644 board/mips/boston-riscv/iocu.c
 create mode 100644 board/mips/boston-riscv/lowlevel_init.S
 create mode 100644 board/mips/boston-riscv/reset.c
 create mode 100644 cmd/display.c
 create mode 100644 cmd/start_harts.c
 create mode 100644 configs/boston-p8700_defconfig
 create mode 100644 doc/README.LED_display
 create mode 100644 drivers/gpio/eg20t-gpio.c
 create mode 100644 include/configs/boston-riscv.h
 create mode 100644 include/led-display.h

-- 
2.34.1

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v3 01/12] riscv: Add initial support for P8700 SoC
  2025-07-29 16:21 [PATCH v3 00/12] riscv: Add support for P8700 platform on Boston board Uros Stajic
@ 2025-07-29 16:22 ` Uros Stajic
  2025-07-29 16:22 ` [PATCH v3 02/12] board: boston-riscv: Add initial support for P8700 Boston board Uros Stajic
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Uros Stajic @ 2025-07-29 16:22 UTC (permalink / raw)
  To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic

From: Chao-ying Fu <cfu@mips.com>

Add initial platform support for the P8700-F, a high-performance
multi-core RV64GC SoC with optional multi-cluster configuration and
hardware multithreading.

This patch introduces the initial platform code necessary to support
the P8700 CPU in U-Boot.

Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
 arch/riscv/Kconfig                          |   1 +
 arch/riscv/cpu/p8700/Kconfig                |  15 ++
 arch/riscv/cpu/p8700/Makefile               |   9 ++
 arch/riscv/cpu/p8700/cache.c                |  93 +++++++++++
 arch/riscv/cpu/p8700/cpu.c                  |  13 ++
 arch/riscv/cpu/p8700/dram.c                 |  37 +++++
 arch/riscv/cpu/p8700/p8700_platform_setup.S | 169 ++++++++++++++++++++
 arch/riscv/include/asm/arch-p8700/p8700.h   | 110 +++++++++++++
 8 files changed, 447 insertions(+)
 create mode 100644 arch/riscv/cpu/p8700/Kconfig
 create mode 100644 arch/riscv/cpu/p8700/Makefile
 create mode 100644 arch/riscv/cpu/p8700/cache.c
 create mode 100644 arch/riscv/cpu/p8700/cpu.c
 create mode 100644 arch/riscv/cpu/p8700/dram.c
 create mode 100644 arch/riscv/cpu/p8700/p8700_platform_setup.S
 create mode 100644 arch/riscv/include/asm/arch-p8700/p8700.h

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 8c6feae5735..eb721edca2c 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -127,6 +127,7 @@ source "arch/riscv/cpu/jh7110/Kconfig"
 source "arch/riscv/cpu/k1/Kconfig"
 source "arch/riscv/cpu/k230/Kconfig"
 source "arch/riscv/cpu/th1520/Kconfig"
+source "arch/riscv/cpu/p8700/Kconfig"
 
 # architecture-specific options below
 
diff --git a/arch/riscv/cpu/p8700/Kconfig b/arch/riscv/cpu/p8700/Kconfig
new file mode 100644
index 00000000000..0e5e4c9eda6
--- /dev/null
+++ b/arch/riscv/cpu/p8700/Kconfig
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+
+config P8700_RISCV
+	bool
+	select ARCH_EARLY_INIT_R
+	imply CPU
+	imply CPU_RISCV
+	imply RISCV_TIMER
+	imply SIFIVE_CLINT if (RISCV_MMODE || SPL_RISCV_MMODE)
+	imply CMD_CPU
+	imply SPL_CPU_SUPPORT
+	imply SPL_OPENSBI
+	imply SPL_LOAD_FIT
diff --git a/arch/riscv/cpu/p8700/Makefile b/arch/riscv/cpu/p8700/Makefile
new file mode 100644
index 00000000000..4dfbddc5cba
--- /dev/null
+++ b/arch/riscv/cpu/p8700/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+
+obj-y += cache.o
+obj-y += cpu.o
+obj-y += dram.o
+
+obj-$(CONFIG_P8700_RISCV) += p8700_platform_setup.o
diff --git a/arch/riscv/cpu/p8700/cache.c b/arch/riscv/cpu/p8700/cache.c
new file mode 100644
index 00000000000..7559c688321
--- /dev/null
+++ b/arch/riscv/cpu/p8700/cache.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+ */
+
+#include <cpu_func.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch-p8700/p8700.h>
+
+#define MCACHE_BASE_INST 0xec0500f3
+
+/* NOTE: We force to use a0 in mcache to encode via .word.
+ * 0xec0500f3 is a manually encoded custom RISC-V MCACHE instruction.
+ * The bits [19:15] are set to 01010, selecting register x10 (a0)
+ * as the source operand.
+ * The bits [24:20] represent the 'op' field, which is currently set to 0.
+ * Different cache operations are applied by OR-ing (op << 20) dynamically
+ * to this base value.
+ * Because of this encoding, the variable 'addr' is forced into register a0,
+ * so that the MCACHE instruction uses the address in a0 as its operand.
+ */
+#define cache_loop(start, end, lsize, op) do {				\
+	const __typeof__(lsize) __lsize = (lsize);			\
+	const register void *addr asm("a0") = (const void *)((start) & ~(__lsize - 1));	\
+	const void *aend = (const void *)(((end) - 1) & ~(__lsize - 1));	\
+	for (; addr <= aend; addr += __lsize)				\
+		asm volatile (".word %0 | %1 # force to use %2" \
+					::"i"(MCACHE_BASE_INST), "i"((op) << 20), "r"(addr)); \
+} while (0)
+
+static unsigned long lsize;
+static unsigned long l1d_total_size;
+static unsigned long slsize;
+
+static void probe_cache_config(void)
+{
+	lsize = 64;
+	l1d_total_size = 64 * 1024;
+
+	int l2_config = 0;
+
+	l2_config = readl((void __iomem *)GCR_L2_CONFIG);
+	int l2_line_size_info = (l2_config >> L2_LINE_SIZE_SHIFT)
+				& L2_LINE_SIZE_MASK;
+	slsize = (l2_line_size_info == 0) ? 0 : 1 << (l2_line_size_info + 1);
+}
+
+void flush_dcache_range(unsigned long start, unsigned long end)
+{
+	if (lsize == 0)
+		probe_cache_config();
+
+	/* aend will be miscalculated when size is zero, so we return here */
+	if (start >= end)
+		return;
+
+	cache_loop(start, end, lsize, HIT_WRITEBACK_INV_D);
+
+	/* flush L2 cache */
+	if (slsize)
+		cache_loop(start, end, slsize, HIT_WRITEBACK_INV_SD);
+
+	/* Instruction Hazard Barrier (IHB) — a hint-encoded SLLI (rd=0, rs1=0, imm=1).
+	 * Ensures that all subsequent instruction fetches, including speculative ones,
+	 * observe state changes from prior instructions.
+	 * Required after MCACHE instructions when instruction fetch depends on cache ops.
+	 */
+	asm volatile ("slli x0,x0,1 # ihb");
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long end)
+{
+	if (lsize == 0)
+		probe_cache_config();
+
+	/* aend will be miscalculated when size is zero, so we return here */
+	if (start >= end)
+		return;
+
+	/* invalidate L2 cache */
+	if (slsize)
+		cache_loop(start, end, slsize, HIT_INVALIDATE_SD);
+
+	cache_loop(start, end, lsize, HIT_INVALIDATE_D);
+
+	/* Instruction Hazard Barrier (IHB) — a hint-encoded SLLI (rd=0, rs1=0, imm=1).
+	 * Ensures that all subsequent instruction fetches, including speculative ones,
+	 * observe state changes from prior instructions.
+	 * Required after MCACHE instructions when instruction fetch depends on cache ops.
+	 */
+	asm volatile ("slli x0,x0,1 # ihb");
+}
diff --git a/arch/riscv/cpu/p8700/cpu.c b/arch/riscv/cpu/p8700/cpu.c
new file mode 100644
index 00000000000..ee0d8f377ac
--- /dev/null
+++ b/arch/riscv/cpu/p8700/cpu.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+ */
+
+extern void p8700_platform_setup(void);
+extern void set_flash_uncached(void);
+
+void harts_early_init(void)
+{
+    p8700_platform_setup();
+    set_flash_uncached();
+}
diff --git a/arch/riscv/cpu/p8700/dram.c b/arch/riscv/cpu/p8700/dram.c
new file mode 100644
index 00000000000..2b54326be39
--- /dev/null
+++ b/arch/riscv/cpu/p8700/dram.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <fdtdec.h>
+#include <init.h>
+#include <linux/sizes.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+	return fdtdec_setup_mem_size_base();
+}
+
+int dram_init_banksize(void)
+{
+	return fdtdec_setup_memory_banksize();
+}
+
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
+{
+	if (IS_ENABLED(CONFIG_64BIT)) {
+		/*
+		 * Ensure that we run from first 4GB so that all
+		 * addresses used by U-Boot are 32bit addresses.
+		 *
+		 * This in-turn ensures that 32bit DMA capable
+		 * devices work fine because DMA mapping APIs will
+		 * provide 32bit DMA addresses only.
+		 */
+		if (gd->ram_top > SZ_4G)
+			return SZ_4G;
+	}
+	return gd->ram_top;
+}
diff --git a/arch/riscv/cpu/p8700/p8700_platform_setup.S b/arch/riscv/cpu/p8700/p8700_platform_setup.S
new file mode 100644
index 00000000000..7c4475a03dd
--- /dev/null
+++ b/arch/riscv/cpu/p8700/p8700_platform_setup.S
@@ -0,0 +1,169 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <elf.h>
+#include <system-constants.h>
+#include <asm/encoding.h>
+#include <generated/asm-offsets.h>
+#include <asm/arch-p8700/p8700.h>
+
+.global p8700_platform_setup
+.global set_flash_uncached
+
+p8700_platform_setup:
+	addi sp, sp, -48
+	sd s6, 0(sp)
+	sd s7, 8(sp)
+	sd s8, 16(sp)
+	sd s9, 24(sp)
+	sd s10, 32(sp)
+	sd s11, 40(sp)
+
+	move s6, ra
+	move s7, x10
+	move s8, x5
+	move s9, x6
+	move s10, x7
+	move s11, x8
+
+	li	x1, 0
+	li	x5, 0
+	li	x6, 0
+	li	x7, 0
+	li	x8, 0
+	li	x10, 0
+
+	/* a0 has mhartid */
+	csrr	a0, CSR_MHARTID
+
+	li	t0, BOSTON_PLAT_DDR3STAT
+1:	lw	t1, 0(t0)
+	andi	t1, t1, BOSTON_PLAT_DDR3STAT_CALIB
+	beqz	t1, 1b
+
+	/* Test mhartid lowest 4 bits */
+	andi	t0, a0, 0xf
+	bne	t0, zero, setup_pmp
+
+	li	s0, CM_BASE
+	li	t0, 0x1fb80000
+	/* Get cluster number to update CM_BASE */
+	srl	t1, a0, MHARTID_CLUSTER_SHIFT
+	andi	t1, t1, MHARTID_CLUSTER_MASK
+	sll	t1, t1, CM_BASE_CLUSTER_SHIFT
+	add	s0, s0, t1
+	move	t1, s0
+
+	/* Test mhartid lowest 16 bits */
+	li	t2, 0xffff
+	and	t2, a0, t2
+	bne	t2, zero, cm_relocate_done
+	sd	t1, GCR_BASE_OFFSET(t0)
+cm_relocate_done:
+
+	li	t0, GCR_CL_COH_EN_EN
+
+	/* Get core number to update CM_BASE */
+	srl	t1, a0, MHARTID_CORE_SHIFT
+	andi	t1, t1, MHARTID_CORE_MASK
+	sll	t1, t1, CM_BASE_CORE_SHIFT
+	add	s0, s0, t1
+	INDEXED(sd, t0, t1, P8700_GCR_C0_COH_EN, s0)
+3:
+
+	/* Test mhartid */
+	bne	a0, zero, setup_pmp
+
+	/* Map all PCIe DMA access to its default, non-IOCU, target */
+	li	t0, BOSTON_PLAT_NOCPCIE0ADDR
+	sw	zero, 0(t0)
+	li	t0, BOSTON_PLAT_NOCPCIE1ADDR
+	sw	zero, 0(t0)
+	li	t0, BOSTON_PLAT_NOCPCIE2ADDR
+	sw	zero, 0(t0)
+
+setup_pmp:
+	/* Setup PMP */
+	li	t0, 0x2fffffff # 2G from 0x80000000
+	csrw	pmpaddr1, t0
+	li	t0, 0x07ff7fff # 0x40000 from 0x1ffc0000
+	csrw	pmpaddr2, t0
+	li	t0, 0x07f3ffff # 2M from 0x1fc00000
+	csrw	pmpaddr3, t0
+	li	t0, 0x1fffffffffffffff # All from 0x0
+	csrw	pmpaddr4, t0
+	li	t0, ((PMP_NAPOT | PMP_R | PMP_W | PMP_X) << 32) | \
+			((PMP_NAPOT | PMP_R | PMP_X) << 24) | \
+			((PMP_NAPOT | PMP_R | PMP_W | PMP_X) << 16) | \
+			((PMP_NAPOT | PMP_R | PMP_W | PMP_X) << 8)
+	csrw	pmpcfg0, t0
+
+	/* Test mhartid */
+	bne	a0, zero, 2f
+	/* HART 0: Set cacheable for pmp0, pmp1, pmp3, uncacheable for pmp2, pmp4 */
+	li	t0, (CCA_CACHE_DISABLE << 32) | (CCA_CACHE_ENABLE << 24) | \
+			(CCA_CACHE_DISABLE << 16) | (CCA_CACHE_ENABLE << 8) | CCA_CACHE_ENABLE
+	j	3f
+2:	/* HART 1 or above: Set cacheable for pmp0, pmp1, uncacheable for pmp2, pmp3, pmp4 */
+	li	t0, (CCA_CACHE_DISABLE << 32) | (CCA_CACHE_DISABLE << 24) | \
+			(CCA_CACHE_DISABLE << 16) | (CCA_CACHE_ENABLE << 8) | CCA_CACHE_ENABLE
+3:
+	csrw	CSR_PMACFG0, t0
+	fence
+
+	/* Test mhartid */
+	beq	a0, zero, 1f
+	/* Jump to 0x80000000 */
+	li	t0, CONFIG_SYS_LOAD_ADDR
+	jr	t0
+1:
+	move ra, s6
+	move x10, s7
+	move x5, s8
+	move x6, s9
+	move x7, s10
+	move x8, s11
+
+	ld s6, 0(sp)
+	ld s7, 8(sp)
+	ld s8, 16(sp)
+	ld s9, 24(sp)
+	ld s10, 32(sp)
+	ld s11, 40(sp)
+	addi sp, sp, 48
+
+	ret
+
+set_flash_uncached:
+	addi	sp, sp, -32
+	sd	s6, 0(sp)
+	sd	s7, 8(sp)
+	sd	s8, 16(sp)
+
+	move s6, ra
+	move s7, x5
+	move s8, x6
+
+	/* Set flash uncached at pmp3 */
+	csrr	t0, CSR_PMACFG0
+	li	t1, 0xffffffffffffffff - (0xff << 24)
+	and	t0, t0, t1
+	li	t1, (CCA_CACHE_DISABLE << 24)
+	or	t0, t0, t1
+	csrw	CSR_PMACFG0, t0
+	fence
+
+	move ra, s6
+	move x5, s7
+	move x6, s8
+
+	ld	s8, 16(sp)
+	ld	s7, 8(sp)
+	ld	s6, 0(sp)
+	addi	sp, sp, 32
+
+	ret
diff --git a/arch/riscv/include/asm/arch-p8700/p8700.h b/arch/riscv/include/asm/arch-p8700/p8700.h
new file mode 100644
index 00000000000..5ca9b4b9497
--- /dev/null
+++ b/arch/riscv/include/asm/arch-p8700/p8700.h
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+ */
+
+#ifndef __P8700_H__
+#define __P8700_H__
+
+#define CSR_MIPSCONFIG7		0x7d7
+#define CSR_PMACFG0			0x7e0
+
+#define MHARTID_HART_SHIFT	0
+#define MHARTID_HART_MASK	0xf
+#define MHARTID_CORE_SHIFT	4
+#define MHARTID_CORE_MASK	0xff
+#define MHARTID_CLUSTER_SHIFT	16
+#define MHARTID_CLUSTER_MASK	0xf
+
+#define MARCHID_UARCH_SHIFT	0
+#define MARCHID_UARCH_MASK	0xff
+#define MARCHID_CLASS_SHIFT	8
+#define MARCHID_CLASS_MASK	0xff
+#define MARCHID_CLASS_M		0
+#define MARCHID_CLASS_I		1
+#define MARCHID_CLASS_P		2
+
+#define CM_BASE_CORE_SHIFT	8
+#define CM_BASE_CLUSTER_SHIFT	19
+
+#define P8700_TIMER_ADDR	0x16108050
+
+#define CCA_CACHE_ENABLE	0
+#define CCA_BUFFER_CACHE	1
+#define CCA_CACHE_DISABLE	2
+#define CCA_UNCACHE_ACC		3
+#define PMA_SPECULATION		(0x1 << 3)
+
+#define L1_I_CACHE      0
+#define L1_D_CACHE      1
+#define L3_CACHE        2
+#define L2_CACHE        3
+
+#define HIT_INVALIDATE          4
+#define HIT_WRITEBACK_INV       5
+
+#define HIT_INVALIDATE_D        ((HIT_INVALIDATE << 2) | L1_D_CACHE)
+#define HIT_INVALIDATE_SD       ((HIT_INVALIDATE << 2) | L2_CACHE)
+#define HIT_WRITEBACK_INV_D     ((HIT_WRITEBACK_INV << 2) | L1_D_CACHE)
+#define HIT_WRITEBACK_INV_SD    ((HIT_WRITEBACK_INV << 2) | L2_CACHE)
+
+#define L1D_LINE_SIZE_SHIFT	10
+#define L1D_LINE_SIZE_MASK	0x7
+
+#define GCR_L2_CONFIG	0x16100130
+#define L2_LINE_SIZE_SHIFT	8
+#define L2_LINE_SIZE_MASK	0xf
+
+#define PMP_R			0x01
+#define PMP_W			0x02
+#define PMP_X			0x04
+#define PMP_TOR			0x8
+#define PMP_NA4			0x10
+#define PMP_NAPOT		0x18
+
+#define CM_BASE			0x16100000
+#define CPC_BASE		(CM_BASE + 0x8000)
+
+/* CPC Block offsets */
+#define CPC_OFF_LOCAL		0x2000
+
+#define CPC_PWRUP_CTL		0x0030
+
+#define CPC_SYS_CONFIG		0x0140
+
+#define CPC_Cx_CMD		0x0000
+#define CPC_Cx_CMD_RESET	0x4
+
+#define P8700_GCR_C0_COH_EN	0x20f8
+#define P8700_GCR_C1_COH_EN	0x21f8
+#define P8700_GCR_C2_COH_EN	0x22f8
+#define P8700_GCR_C3_COH_EN	0x23f8
+#define P8700_GCR_C4_COH_EN	0x24f8
+#define P8700_GCR_C5_COH_EN	0x25f8
+
+#define GCR_CL_COH_EN		0x2008
+#define GCR_CL_COH_EN_EN	(0x1 << 0)
+#define GCR_BASE_OFFSET		0x0008
+#define GIC_BASE_OFFSET		0x0080
+#define CPC_BASE_OFFSET		0x0088
+#define ENABLE			0x1
+#define COUNT_STOP		(0x1 << 28)
+#define GIC_LOCAL_SECTION_OFS	0x8000
+#define GIC_VL_MASK		0x08
+#define GIC_VL_RMASK		0x0c
+#define GIC_VL_SMASK		0x10
+#define GIC_VL_COMPARE_MAP	0x44
+
+#define INDEXED(op, reg, idx, offset, base) \
+	li	idx, offset	;\
+	add	idx, idx, base	;\
+	op	reg, (idx)
+
+#define BOSTON_PLAT_BASE	0x17ffd000
+#define BOSTON_PLAT_DDR3STAT	(BOSTON_PLAT_BASE + 0x14)
+#define BOSTON_PLAT_DDR3STAT_CALIB	(0x1 << 2)
+#define BOSTON_PLAT_NOCPCIE0ADDR        (BOSTON_PLAT_BASE + 0x3c)
+#define BOSTON_PLAT_NOCPCIE1ADDR        (BOSTON_PLAT_BASE + 0x40)
+#define BOSTON_PLAT_NOCPCIE2ADDR        (BOSTON_PLAT_BASE + 0x44)
+
+#endif /* __P8700_H__ */
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 02/12] board: boston-riscv: Add initial support for P8700 Boston board
  2025-07-29 16:21 [PATCH v3 00/12] riscv: Add support for P8700 platform on Boston board Uros Stajic
  2025-07-29 16:22 ` [PATCH v3 01/12] riscv: Add initial support for P8700 SoC Uros Stajic
@ 2025-07-29 16:22 ` Uros Stajic
  2025-07-29 16:22 ` [PATCH v3 03/12] gpio: Add GPIO driver for Intel EG20T Uros Stajic
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Uros Stajic @ 2025-07-29 16:22 UTC (permalink / raw)
  To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic

From: Chao-ying Fu <cfu@mips.com>

Implement initial board-level support for the P8700 Boston SoC.

Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
 arch/riscv/Kconfig                      |  10 +
 arch/riscv/dts/Makefile                 |   1 +
 arch/riscv/dts/boston-p8700.dts         | 256 ++++++++++++++++++++++++
 board/mips/boston-riscv/Kconfig         |  43 ++++
 board/mips/boston-riscv/MAINTAINERS     |   9 +
 board/mips/boston-riscv/Makefile        |   8 +
 board/mips/boston-riscv/boston-lcd.h    |  20 ++
 board/mips/boston-riscv/boston-regs.h   |  38 ++++
 board/mips/boston-riscv/boston-riscv.c  |   9 +
 board/mips/boston-riscv/checkboard.c    |  43 ++++
 board/mips/boston-riscv/config.mk       |  15 ++
 board/mips/boston-riscv/lowlevel_init.S |  18 ++
 board/mips/boston-riscv/reset.c         |  15 ++
 configs/boston-p8700_defconfig          |  94 +++++++++
 drivers/clk/Kconfig                     |   2 +-
 include/asm-generic/global_data.h       |   5 +
 include/configs/boston-riscv.h          |  11 +
 17 files changed, 596 insertions(+), 1 deletion(-)
 create mode 100644 arch/riscv/dts/boston-p8700.dts
 create mode 100644 board/mips/boston-riscv/Kconfig
 create mode 100644 board/mips/boston-riscv/MAINTAINERS
 create mode 100644 board/mips/boston-riscv/Makefile
 create mode 100644 board/mips/boston-riscv/boston-lcd.h
 create mode 100644 board/mips/boston-riscv/boston-regs.h
 create mode 100644 board/mips/boston-riscv/boston-riscv.c
 create mode 100644 board/mips/boston-riscv/checkboard.c
 create mode 100644 board/mips/boston-riscv/config.mk
 create mode 100644 board/mips/boston-riscv/lowlevel_init.S
 create mode 100644 board/mips/boston-riscv/reset.c
 create mode 100644 configs/boston-p8700_defconfig
 create mode 100644 include/configs/boston-riscv.h

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index eb721edca2c..b05e0622908 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -58,6 +58,15 @@ config TARGET_XILINX_MBV
 config TARGET_ASPEED_AST2700_IBEX
 	bool "Support Ibex RISC-V cores on Aspeed AST2700 SoC"
 
+config TARGET_MIPS_BOSTON
+	bool "Support Mips Boston Board"
+	select DM
+	select DM_GPIO
+	select DM_SERIAL
+	select OF_CONTROL
+	select DISTRO_DEFAULTS
+	imply CMD_DM
+
 endchoice
 
 config SYS_ICACHE_OFF
@@ -115,6 +124,7 @@ source "board/spacemit/bananapi-f3/Kconfig"
 source "board/starfive/visionfive2/Kconfig"
 source "board/thead/th1520_lpi4a/Kconfig"
 source "board/xilinx/mbv/Kconfig"
+source "board/mips/boston-riscv/Kconfig"
 
 # platform-specific options below
 source "arch/riscv/cpu/andes/Kconfig"
diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile
index 2b10c2d6c01..1531013f798 100644
--- a/arch/riscv/dts/Makefile
+++ b/arch/riscv/dts/Makefile
@@ -15,6 +15,7 @@ dtb-$(CONFIG_TARGET_TH1520_LPI4A) += th1520-lichee-pi-4a.dtb
 dtb-$(CONFIG_TARGET_XILINX_MBV) += xilinx-mbv32.dtb
 dtb-$(CONFIG_TARGET_XILINX_MBV) += xilinx-mbv64.dtb
 dtb-$(CONFIG_TARGET_ASPEED_AST2700_IBEX) += ast2700-ibex.dtb
+dtb-$(CONFIG_TARGET_MIPS_BOSTON) += boston-p8700.dtb
 
 include $(srctree)/scripts/Makefile.dts
 
diff --git a/arch/riscv/dts/boston-p8700.dts b/arch/riscv/dts/boston-p8700.dts
new file mode 100644
index 00000000000..5f52ff58a3e
--- /dev/null
+++ b/arch/riscv/dts/boston-p8700.dts
@@ -0,0 +1,256 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/clock/boston-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/mips-gic.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	model = "p8700";
+	compatible = "img,boston";
+
+	chosen {
+		stdout-path = &uart0;
+		bootargs = "root=/dev/sda rw earlycon console=ttyS0,115200n8r";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		timebase-frequency = <20000000>;
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "riscv";
+			reg = <0>;
+			mmu-type = "riscv,sv39";
+			riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zba", "zbb";
+			clocks = <&clk_boston BOSTON_CLK_CPU>;
+			clock-frequency = <20000000>;
+			bootph-all;
+			status = "okay";
+		};
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x80000000 0x80000000>;
+	};
+
+	gic: interrupt-controller {
+		compatible = "mti,gic";
+
+		interrupt-controller;
+		#interrupt-cells = <3>;
+
+		timer {
+			compatible = "mti,gic-timer";
+			interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>;
+			clocks = <&clk_boston BOSTON_CLK_CPU>;
+		};
+	};
+
+	pci0: pci@10000000 {
+		device_type = "pci";
+		compatible = "xlnx,axi-pcie-host-1.00.a";
+		reg = <0x10000000 0x2000000>;
+
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SHARED 2 IRQ_TYPE_LEVEL_HIGH>;
+
+		ranges = <0x02000000 0 0x40000000
+			  0x40000000 0 0x40000000>;
+
+		bus-range = <0x00 0xff>;
+
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0 0 0 1 &pci0_intc 1>,
+				<0 0 0 2 &pci0_intc 2>,
+				<0 0 0 3 &pci0_intc 3>,
+				<0 0 0 4 &pci0_intc 4>;
+
+		status = "disabled";
+
+		pci0_intc: interrupt-controller {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <1>;
+		};
+	};
+
+	pci1: pci@12000000 {
+		device_type = "pci";
+		compatible = "xlnx,axi-pcie-host-1.00.a";
+		reg = <0x12000000 0x2000000>;
+
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SHARED 1 IRQ_TYPE_LEVEL_HIGH>;
+
+		ranges = <0x02000000 0 0x20000000
+			  0x20000000 0 0x20000000>;
+
+		bus-range = <0x00 0xff>;
+
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0 0 0 1 &pci1_intc 1>,
+				<0 0 0 2 &pci1_intc 2>,
+				<0 0 0 3 &pci1_intc 3>,
+				<0 0 0 4 &pci1_intc 4>;
+
+		status = "disabled";
+
+		pci1_intc: interrupt-controller {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <1>;
+		};
+	};
+
+	pci2: pci@14000000 {
+		device_type = "pci";
+		compatible = "xlnx,axi-pcie-host-1.00.a";
+		reg = <0x14000000 0x2000000>;
+
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SHARED 0 IRQ_TYPE_LEVEL_HIGH>;
+
+		ranges = <0x02000000 0 0x16000000
+			  0x16000000 0 0x100000>;
+
+		bus-range = <0x00 0xff>;
+
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0 0 0 1 &pci2_intc 1>,
+				<0 0 0 2 &pci2_intc 2>,
+				<0 0 0 3 &pci2_intc 3>,
+				<0 0 0 4 &pci2_intc 4>;
+
+		status = "disabled";
+
+		pci2_intc: interrupt-controller {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <1>;
+		};
+
+		pci2_root@0,0,0 {
+			compatible = "pci10ee,7021", "pci-bridge";
+			reg = <0x00000000 0 0 0 0>;
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+
+			eg20t_bridge@1,0,0 {
+				compatible = "pci8086,8800", "pci-bridge";
+				reg = <0x00010000 0 0 0 0>;
+
+				#address-cells = <3>;
+				#size-cells = <2>;
+				#interrupt-cells = <1>;
+
+				eg20t_mac@2,0,1 {
+					compatible = "pci8086,8802", "intel,pch-gbe";
+					reg = <0x00020100 0 0 0 0>;
+					phy-reset-gpios = <&eg20t_gpio 6 GPIO_ACTIVE_LOW>;
+				};
+
+				eg20t_gpio: eg20t_gpio@2,0,2 {
+					compatible = "pci8086,8803", "intel,eg20t-gpio";
+					reg = <0x00020200 0 0 0 0>;
+
+					gpio-controller;
+					#gpio-cells = <2>;
+				};
+
+				mmc0: mmc@2,4,0 {
+					compatible = "intel,apl-sd";
+					reg = <0x00022000 0 0 0 0>;
+				};
+
+				mmc1: mmc@2,4,1 {
+					compatible = "intel,apl-sd";
+					reg = <0x00022100 0 0 0 0>;
+				};
+
+				eg20t_i2c@2,12,2 {
+					compatible = "pci8086,8817";
+					reg = <0x00026200 0 0 0 0>;
+
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					rtc@0x68 {
+						compatible = "st,m41t81s";
+						reg = <0x68>;
+					};
+				};
+			};
+		};
+	};
+
+	plat_regs: system-controller@17ffd000 {
+		compatible = "img,boston-platform-regs", "syscon";
+		reg = <0x17ffd000 0x1000>;
+		bootph-all;
+	};
+
+	clk_boston: clock {
+		compatible = "img,boston-clock";
+		#clock-cells = <1>;
+		regmap = <&plat_regs>;
+		bootph-all;
+	};
+
+	reboot: syscon-reboot {
+		compatible = "syscon-reboot";
+		regmap = <&plat_regs>;
+		offset = <0x10>;
+		mask = <0x10>;
+	};
+
+	uart0: uart@17ffe000 {
+		compatible = "ns16550a";
+		reg = <0x17ffe000 0x1000>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SHARED 3 IRQ_TYPE_LEVEL_HIGH>;
+
+		clocks = <&clk_boston BOSTON_CLK_SYS>;
+		clock-frequency = <20000000>;
+
+		bootph-all;
+	};
+
+	lcd: lcd@17fff000 {
+		compatible = "img,boston-lcd";
+		reg = <0x17fff000 0x8>;
+	};
+
+	flash@18000000 {
+		compatible = "cfi-flash";
+		reg = <0x18000000 0x8000000>;
+		bank-width = <2>;
+	};
+};
diff --git a/board/mips/boston-riscv/Kconfig b/board/mips/boston-riscv/Kconfig
new file mode 100644
index 00000000000..68c5fc50489
--- /dev/null
+++ b/board/mips/boston-riscv/Kconfig
@@ -0,0 +1,43 @@
+if TARGET_MIPS_BOSTON
+
+config SYS_BOARD
+	default "boston-riscv"
+
+config SYS_VENDOR
+	default "mips"
+
+config SYS_CONFIG_NAME
+	default "boston-riscv"
+
+config SYS_CPU
+	default "p8700"
+
+config BOARD_SPECIFIC_OPTIONS
+    def_bool y
+    select P8700_RISCV
+    imply SYS_NS16550
+
+config SYS_CACHELINE_SIZE
+    default 64
+
+config SYS_SDRAM_BASE
+    hex
+    default 0x80000000
+
+config SYS_INIT_SP_ADDR
+    hex
+    default 0x80200000
+
+config STANDALONE_LOAD_ADDR
+    hex
+    default 0x80200000
+
+config SYS_MAX_FLASH_BANKS_DETECT
+    bool
+    default y
+
+config PHY_REALTEK
+    bool
+    default y
+
+endif
diff --git a/board/mips/boston-riscv/MAINTAINERS b/board/mips/boston-riscv/MAINTAINERS
new file mode 100644
index 00000000000..e350121395e
--- /dev/null
+++ b/board/mips/boston-riscv/MAINTAINERS
@@ -0,0 +1,9 @@
+BOSTON-RISCV BOARD
+M:	Chao-ying Fu <cfu@mips.com>
+S:	Maintained
+F:	board/mips/boston-riscv/
+F:	include/configs/boston-riscv.h
+F:  arch/riscv/cpu/p8700/
+F:  arch/riscv/include/asm/arch-p8700/
+F:  configs/boston-p8700_defconfig
+F:  arch/riscv/dts/boston-p8700.dts
diff --git a/board/mips/boston-riscv/Makefile b/board/mips/boston-riscv/Makefile
new file mode 100644
index 00000000000..0615c677d23
--- /dev/null
+++ b/board/mips/boston-riscv/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2016 Imagination Technologies
+
+obj-y += boston-riscv.o
+obj-y += checkboard.o
+obj-y += lowlevel_init.o
+obj-y += reset.o
diff --git a/board/mips/boston-riscv/boston-lcd.h b/board/mips/boston-riscv/boston-lcd.h
new file mode 100644
index 00000000000..5f5cd0fe126
--- /dev/null
+++ b/board/mips/boston-riscv/boston-lcd.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ */
+
+#ifndef __BOARD_BOSTON_LCD_H__
+#define __BOARD_BOSTON_LCD_H__
+
+/**
+ * lowlevel_display() - Display a message on Boston's LCD
+ * @msg: The string to display
+ *
+ * Display the string @msg on the 7 character LCD display of the Boston board.
+ * This is typically used for debug or to present some form of status
+ * indication to the user, allowing faults to be identified when things go
+ * wrong early enough that the UART isn't up.
+ */
+void lowlevel_display(const char msg[static 8]);
+
+#endif /* __BOARD_BOSTON_LCD_H__ */
diff --git a/board/mips/boston-riscv/boston-regs.h b/board/mips/boston-riscv/boston-regs.h
new file mode 100644
index 00000000000..4d5ea8833ab
--- /dev/null
+++ b/board/mips/boston-riscv/boston-regs.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ */
+
+#ifndef __BOARD_BOSTON_REGS_H__
+#define __BOARD_BOSTON_REGS_H__
+
+#ifndef BOSTON_PLAT_BASE
+#define BOSTON_PLAT_BASE		(0x17ffd000)
+#endif
+#define BOSTON_LCD_BASE			(0x17fff000)
+
+/*
+ * Platform Register Definitions
+ */
+#define BOSTON_PLAT_CORE_CL		(BOSTON_PLAT_BASE + 0x04)
+
+#define BOSTON_PLAT_SOFT_RST		(BOSTON_PLAT_BASE + 0x10)
+#define BOSTON_PLAT_SOFT_RST_SYSTEM	(0x1 << 4)
+
+#define BOSTON_PLAT_DDR3STAT		(BOSTON_PLAT_BASE + 0x14)
+#define BOSTON_PLAT_DDR3STAT_CALIB	(0x1 << 2)
+
+#define BOSTON_PLAT_BUILDCFG0           (BOSTON_PLAT_BASE + 0x34)
+#define BOSTON_PLAT_BUILDCFG0_IOCU     (0x1 << 0)
+#define BOSTON_PLAT_BUILDCFG0_PCIE0    (0x1 << 1)
+#define BOSTON_PLAT_BUILDCFG0_PCIE1    (0x1 << 2)
+#define BOSTON_PLAT_BUILDCFG0_PCIE2    (0x1 << 3)
+#define BOSTON_PLAT_BUILDCFG0_CFG_LTR  (0xf << 4)
+#define BOSTON_PLAT_BUILDCFG0_CFG_NUM  (0xff << 8)
+#define BOSTON_PLAT_BUILDCFG0_DP       (0x1 << 24)
+#define BOSTON_PLAT_BUILDCFG0_DP_MULT  (0xf << 28)
+
+#define BOSTON_PLAT_DDRCONF0		(BOSTON_PLAT_BASE + 0x38)
+#define BOSTON_PLAT_DDRCONF0_SIZE	(0xf << 0)
+
+#endif /* __BOARD_BOSTON_REGS_H__ */
diff --git a/board/mips/boston-riscv/boston-riscv.c b/board/mips/boston-riscv/boston-riscv.c
new file mode 100644
index 00000000000..e5cd6c42cf7
--- /dev/null
+++ b/board/mips/boston-riscv/boston-riscv.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ */
+
+int board_init(void)
+{
+	return 0;
+}
diff --git a/board/mips/boston-riscv/checkboard.c b/board/mips/boston-riscv/checkboard.c
new file mode 100644
index 00000000000..c7bf6734433
--- /dev/null
+++ b/board/mips/boston-riscv/checkboard.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ */
+
+#include "boston-lcd.h"
+#include "boston-regs.h"
+#include <init.h>
+#include <asm/io.h>
+#include <asm/arch-p8700/p8700.h>
+
+int checkboard(void)
+{
+	u32 changelist, cfg, core, uarch;
+	u64 marchid;
+
+	lowlevel_display("U-boot  ");
+
+	printf("Board: Mips Boston RISC-V\n");
+
+	changelist = __raw_readl((uint32_t *)BOSTON_PLAT_CORE_CL);
+	if (changelist > 1) {
+		asm volatile ("csrr %0, marchid" : "=r"(marchid)::);
+		core = (marchid >> MARCHID_CLASS_SHIFT) & MARCHID_CLASS_MASK;
+		uarch = (marchid >> MARCHID_UARCH_SHIFT) & MARCHID_UARCH_MASK;
+
+		printf("Core:  class%x uarch%x cl%x", core, uarch, changelist);
+
+		cfg = __raw_readl((uint32_t *)BOSTON_PLAT_BUILDCFG0);
+		if (cfg & BOSTON_PLAT_BUILDCFG0_CFG_NUM)
+			printf(" config %u",
+			       (cfg & BOSTON_PLAT_BUILDCFG0_CFG_NUM) >> 8);
+		if (cfg & BOSTON_PLAT_BUILDCFG0_CFG_LTR)
+			printf("%c",
+			       'a' + ((cfg & BOSTON_PLAT_BUILDCFG0_CFG_LTR) >> 4) - 1);
+		if (cfg & BOSTON_PLAT_BUILDCFG0_DP)
+			printf(", x%u debug port",
+			       (cfg & BOSTON_PLAT_BUILDCFG0_DP_MULT) >> 28);
+		printf("\n");
+	}
+
+	return 0;
+}
diff --git a/board/mips/boston-riscv/config.mk b/board/mips/boston-riscv/config.mk
new file mode 100644
index 00000000000..c1e242f1088
--- /dev/null
+++ b/board/mips/boston-riscv/config.mk
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+quiet_cmd_srec_cat = SRECCAT $@
+      cmd_srec_cat = srec_cat -output $@ -$2 \
+			$< -binary \
+			-fill 0x00 -within $< -binary -range-pad 16 \
+			-offset $3
+
+u-boot.mcs: u-boot.bin
+	$(call cmd,srec_cat,intel,0x7c00000)
+
+# if srec_cat is present build u-boot.mcs by default
+has_srec_cat = $(call try-run,srec_cat -VERSion,y,n)
+INPUTS-$(has_srec_cat) += u-boot.mcs
+CLEAN_FILES += u-boot.mcs
diff --git a/board/mips/boston-riscv/lowlevel_init.S b/board/mips/boston-riscv/lowlevel_init.S
new file mode 100644
index 00000000000..8fa85749e40
--- /dev/null
+++ b/board/mips/boston-riscv/lowlevel_init.S
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ */
+
+#include "boston-regs.h"
+
+.data
+
+msg_ddr_cal:	.ascii "DDR Cal "
+msg_ddr_ok:	.ascii "DDR OK  "
+
+.text
+
+	.globl lowlevel_display
+lowlevel_display:
+	li	t0, BOSTON_LCD_BASE
+	jr	ra
diff --git a/board/mips/boston-riscv/reset.c b/board/mips/boston-riscv/reset.c
new file mode 100644
index 00000000000..8e7e0572aad
--- /dev/null
+++ b/board/mips/boston-riscv/reset.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017 Imagination Technologies
+ */
+
+#include "boston-regs.h"
+#include <asm/io.h>
+#include <linux/delay.h>
+
+void _machine_restart(void)
+{
+	writel(BOSTON_PLAT_SOFT_RST_SYSTEM, (void __iomem *)BOSTON_PLAT_SOFT_RST);
+
+	udelay(1000);
+}
diff --git a/configs/boston-p8700_defconfig b/configs/boston-p8700_defconfig
new file mode 100644
index 00000000000..3df7ffe50b3
--- /dev/null
+++ b/configs/boston-p8700_defconfig
@@ -0,0 +1,94 @@
+CONFIG_RISCV=y
+CONFIG_SYS_TEXT_BASE=0x1fc00000
+CONFIG_ENV_SIZE=0x40000
+CONFIG_ENV_SECT_SIZE=0x40000
+CONFIG_TARGET_MIPS_BOSTON=y
+CONFIG_DEFAULT_DEVICE_TREE="boston-p8700"
+
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_BEST_MATCH=y
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_SYS_PROMPT="boston # "
+CONFIG_CMD_GREPENV=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_SYS_MEMTEST_START=0x80000000
+CONFIG_SYS_MEMTEST_END=0x90000000
+CONFIG_BOOTDELAY=-1
+
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ARCH_RV64I=y
+CONFIG_DISPLAY_CPUINFO=y
+CONFIG_DISPLAY_BOARDINFO=y
+#CONFIG_CMD_BOOTEFI_SELFTEST=y
+#CONFIG_CMD_NVEDIT_EFI=y
+CONFIG_CMD_MII=y
+# CONFIG_OF_PRIOR_STAGE=y
+CONFIG_DM_MTD=y
+CONFIG_SMP=n
+CONFIG_XIP=y
+CONFIG_CLK_BOSTON=y
+CONFIG_RISCV_ISA_C=n
+CONFIG_SHOW_REGS=y
+CONFIG_SYS_NS16550=y
+
+CONFIG_CMD_PCI=y
+CONFIG_CMD_SNTP=y
+CONFIG_CMD_DNS=y
+CONFIG_CMD_LINK_LOCAL=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_ENV_ADDR=0x1ffc0000
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_MTD=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_FLASH_CFI_DRIVER=y
+CONFIG_CFI_FLASH=y
+CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
+CONFIG_SYS_FLASH_USE_PROTECTION=y
+CONFIG_SYS_FLASH_CFI=y
+CONFIG_SYS_FLASH_PROTECTION=y
+CONFIG_DM_ETH=y
+CONFIG_PCH_GBE=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_PCI_XILINX=y
+CONFIG_LZ4=y
+CONFIG_CLK=y
+CONFIG_EG20T_GPIO=y
+
+CONFIG_MMC=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_CPU=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_EMBED=y
+CONFIG_CPU=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_PCI=y
+
+CONFIG_UNIT_TEST=y
+CONFIG_UT_LIB=n
+CONFIG_UT_LIB_ASN1=n
+CONFIG_UT_LOG=n
+CONFIG_UT_TIME=y
+CONFIG_UT_UNICODE=n
+CONFIG_UT_ENV=n
+CONFIG_UT_OVERLAY=n
+
+CONFIG_SYS_LOAD_ADDR=0x80000000
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80200000
+CONFIG_TEXT_BASE=0x1fc00000
+CONFIG_SYS_MALLOC_LEN=0x00800000
+CONFIG_SYS_BOOTM_LEN=0x04000000
+CONFIG_SYS_MAX_FLASH_SECT=1024
+CONFIG_PHY_ANEG_TIMEOUT=40000
+CONFIG_NET_RETRY_COUNT=10
+CONFIG_ENV_CALLBACK_LIST_STATIC="io.coherent:io_coherent,"
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index e6483ddc88b..6b3103f6cf8 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -59,7 +59,7 @@ config CLK_BCM6345
 	  clocks on BCM6345 SoCs. HW has no rate changing capabilities.
 
 config CLK_BOSTON
-	def_bool y if TARGET_BOSTON
+	def_bool y if TARGET_BOSTON || TARGET_MIPS_BOSTON
 	depends on CLK
 	select REGMAP
 	select SYSCON
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 506ee51cdb0..7b25de7bb68 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -702,6 +702,11 @@ enum gd_flags {
 	 * drivers shall not be called.
 	 */
 	GD_FLG_HAVE_CONSOLE = 0x8000000,
+	/**
+	 * @GD_FLG_COHERENT_DMA: DMA is cache-coherent.
+	 *
+	 */
+	GD_FLG_COHERENT_DMA = 0x10000000,
 };
 
 #endif /* __ASSEMBLY__ */
diff --git a/include/configs/boston-riscv.h b/include/configs/boston-riscv.h
new file mode 100644
index 00000000000..3b3e2567214
--- /dev/null
+++ b/include/configs/boston-riscv.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+ */
+
+#ifndef __CONFIG_BOSTON_RISCV_H
+#define __CONFIG_BOSTON_RISCV_H
+
+#include <linux/sizes.h>
+
+#endif /* __CONFIG_BOSTON_RISCV_H */
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 03/12] gpio: Add GPIO driver for Intel EG20T
  2025-07-29 16:21 [PATCH v3 00/12] riscv: Add support for P8700 platform on Boston board Uros Stajic
  2025-07-29 16:22 ` [PATCH v3 01/12] riscv: Add initial support for P8700 SoC Uros Stajic
  2025-07-29 16:22 ` [PATCH v3 02/12] board: boston-riscv: Add initial support for P8700 Boston board Uros Stajic
@ 2025-07-29 16:22 ` Uros Stajic
  2025-08-01  8:51   ` Yao Zi
  2025-07-29 16:23 ` [PATCH v3 04/12] pci: xilinx: Avoid writing memory base/limit for root bridge Uros Stajic
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 20+ messages in thread
From: Uros Stajic @ 2025-07-29 16:22 UTC (permalink / raw)
  To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic

From: Chao-ying Fu <cfu@mips.com>

Add a GPIO driver for the Intel EG20T Platform Controller Hub, which
exposes a set of 12 GPIOs via PCI MMIO.

The driver implements basic GPIO operations (input/output direction,
value read/write, and function query) using the U-Boot driver model
infrastructure. It maps the required BAR1 region via `dm_pci_map_bar`
and uses internal registers to control pin state and direction.

This driver is required for platforms using EG20T, such as P8700-based
systems, to access GPIOs through the standard U-Boot DM GPIO framework.

Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
 board/mips/boston-riscv/MAINTAINERS |   1 +
 drivers/gpio/Kconfig                |   7 ++
 drivers/gpio/Makefile               |   1 +
 drivers/gpio/eg20t-gpio.c           | 138 ++++++++++++++++++++++++++++
 4 files changed, 147 insertions(+)
 create mode 100644 drivers/gpio/eg20t-gpio.c

diff --git a/board/mips/boston-riscv/MAINTAINERS b/board/mips/boston-riscv/MAINTAINERS
index e350121395e..bc59a628c79 100644
--- a/board/mips/boston-riscv/MAINTAINERS
+++ b/board/mips/boston-riscv/MAINTAINERS
@@ -7,3 +7,4 @@ F:  arch/riscv/cpu/p8700/
 F:  arch/riscv/include/asm/arch-p8700/
 F:  configs/boston-p8700_defconfig
 F:  arch/riscv/dts/boston-p8700.dts
+F:  drivers/gpio/eg20t-gpio.c
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 58e464106a3..26040947a69 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -726,3 +726,10 @@ config MPFS_GPIO
 		Enable to support the GPIO driver on Polarfire SoC
 
 endif
+
+config EG20T_GPIO
+        bool "Intel EG20T GPIO driver"
+        depends on DM_GPIO && DM_PCI
+        help
+          Enable this to support the GPIO controller found in the Intel EG20T
+          Platform Controller Hub.
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 83e10c79b91..e44122cb9aa 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -81,3 +81,4 @@ obj-$(CONFIG_FTGPIO010)		+= ftgpio010.o
 obj-$(CONFIG_$(PHASE_)ADP5585_GPIO)	+= adp5585_gpio.o
 obj-$(CONFIG_RZG2L_GPIO)	+= rzg2l-gpio.o
 obj-$(CONFIG_MPFS_GPIO)	+= mpfs_gpio.o
+obj-$(CONFIG_EG20T_GPIO)	+= eg20t-gpio.o
diff --git a/drivers/gpio/eg20t-gpio.c b/drivers/gpio/eg20t-gpio.c
new file mode 100644
index 00000000000..d41ca4bfb17
--- /dev/null
+++ b/drivers/gpio/eg20t-gpio.c
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ */
+
+#include <dm.h>
+#include <errno.h>
+#include <pci.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <log.h>
+
+enum {
+	REG_IEN		= 0x00,
+	REG_ISTATUS	= 0x04,
+	REG_IDISP	= 0x08,
+	REG_ICLR	= 0x0c,
+	REG_IMASK	= 0x10,
+	REG_IMASKCLR	= 0x14,
+	REG_PO		= 0x18,
+	REG_PI		= 0x1c,
+	REG_PM		= 0x20,
+};
+
+struct eg20t_gpio_priv {
+	void *base;
+};
+
+static int eg20t_gpio_get_value(struct udevice *dev, unsigned int offset)
+{
+	struct eg20t_gpio_priv *priv = dev_get_priv(dev);
+	u32 pm, pval;
+
+	pm = readl(priv->base + REG_PM);
+	if ((pm >> offset) & 0x1)
+		pval = readl(priv->base + REG_PO);
+	else
+		pval = readl(priv->base + REG_PI);
+
+	return (pval >> offset) & 0x1;
+}
+
+static int eg20t_gpio_set_value(struct udevice *dev, unsigned int offset,
+				int value)
+{
+	struct eg20t_gpio_priv *priv = dev_get_priv(dev);
+	u32 po;
+
+	po = readl(priv->base + REG_PO);
+	if (value)
+		po |= 1 << offset;
+	else
+		po &= ~(1 << offset);
+	writel(po, priv->base + REG_PO);
+	return 0;
+}
+
+static int eg20t_gpio_direction_input(struct udevice *dev, unsigned int offset)
+{
+	struct eg20t_gpio_priv *priv = dev_get_priv(dev);
+	u32 pm;
+
+	pm = readl(priv->base + REG_PM);
+	pm &= ~(1 << offset);
+	writel(pm, priv->base + REG_PM);
+	return 0;
+}
+
+static int eg20t_gpio_direction_output(struct udevice *dev, unsigned int offset,
+				       int value)
+{
+	struct eg20t_gpio_priv *priv = dev_get_priv(dev);
+	u32 pm;
+
+	pm = readl(priv->base + REG_PM);
+	pm |= 1 << offset;
+	writel(pm, priv->base + REG_PM);
+
+	return eg20t_gpio_set_value(dev, offset, value);
+}
+
+static int eg20t_gpio_get_function(struct udevice *dev, unsigned int offset)
+{
+	struct eg20t_gpio_priv *priv = dev_get_priv(dev);
+	u32 pm;
+
+	pm = readl(priv->base + REG_PM);
+
+	if ((pm >> offset) & 0x1)
+		return GPIOF_OUTPUT;
+
+	return GPIOF_INPUT;
+}
+
+static const struct dm_gpio_ops eg20t_gpio_ops = {
+	.direction_input	= eg20t_gpio_direction_input,
+	.direction_output	= eg20t_gpio_direction_output,
+	.get_value		= eg20t_gpio_get_value,
+	.set_value		= eg20t_gpio_set_value,
+	.get_function		= eg20t_gpio_get_function,
+};
+
+static int eg20t_gpio_probe(struct udevice *dev)
+{
+	struct eg20t_gpio_priv *priv = dev_get_priv(dev);
+	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+
+	priv->base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_1, PCI_REGION_MEM);
+	if (!priv->base) {
+		debug("failed to map GPIO registers\n");
+		return -EINVAL;
+	}
+
+	uc_priv->gpio_count = 12;
+	uc_priv->bank_name = "eg20t";
+	return 0;
+}
+
+static const struct udevice_id eg20t_gpio_ids[] = {
+	{ .compatible = "intel,eg20t-gpio" },
+	{ }
+};
+
+U_BOOT_DRIVER(eg20t_gpio) = {
+	.name	= "eg20t-gpio",
+	.id	= UCLASS_GPIO,
+	.of_match = eg20t_gpio_ids,
+	.probe	= eg20t_gpio_probe,
+	.priv_auto_alloc_size = sizeof(struct eg20t_gpio_priv),
+	.ops	= &eg20t_gpio_ops,
+};
+
+static struct pci_device_id eg20t_gpio_supported[] = {
+	{ PCI_VENDOR_ID_INTEL, 0x8803 },
+	{ },
+};
+
+U_BOOT_PCI_DEVICE(eg20t_gpio, eg20t_gpio_supported);
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 04/12] pci: xilinx: Avoid writing memory base/limit for root bridge
  2025-07-29 16:21 [PATCH v3 00/12] riscv: Add support for P8700 platform on Boston board Uros Stajic
                   ` (2 preceding siblings ...)
  2025-07-29 16:22 ` [PATCH v3 03/12] gpio: Add GPIO driver for Intel EG20T Uros Stajic
@ 2025-07-29 16:23 ` Uros Stajic
  2025-07-29 16:23 ` [PATCH v3 05/12] riscv: Add support for MIPS GIC syscon on RISC-V SoCs Uros Stajic
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Uros Stajic @ 2025-07-29 16:23 UTC (permalink / raw)
  To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic

From: Chao-ying Fu <cfu@mips.com>

Avoid writing to PCI_MEMORY_BASE and PCI_MEMORY_LIMIT registers for
bus 0, device 0 (the root bridge) in the Xilinx PCIe driver.

On platforms such as the MIPS Boston board, writing to these fields
results in incorrect values (e.g. base = 0x0, limit = 0x1600), which
causes Linux to fail PCIe memory space assignment.

As a result, Linux can boot successfully and probe the PCIe bus and
all connected devices on platforms like the MIPS Boston board.

Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
 drivers/pci/pcie_xilinx.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/pci/pcie_xilinx.c b/drivers/pci/pcie_xilinx.c
index 63058e8e7c5..4ef20474a0b 100644
--- a/drivers/pci/pcie_xilinx.c
+++ b/drivers/pci/pcie_xilinx.c
@@ -132,6 +132,15 @@ static int pcie_xilinx_write_config(struct udevice *bus, pci_dev_t bdf,
 				    uint offset, ulong value,
 				    enum pci_size_t size)
 {
+	if (bdf == PCI_BDF(bus->seq_, 0, 0)) {
+		switch (offset) {
+		case PCI_MEMORY_BASE:
+		case PCI_MEMORY_LIMIT:
+			/* Writing the memory base or limit causes problems */
+			return 0;
+		}
+	}
+
 	return pci_generic_mmap_write_config(bus, pcie_xilinx_config_address,
 					     bdf, offset, value, size);
 }
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 05/12] riscv: Add support for MIPS GIC syscon on RISC-V SoCs
  2025-07-29 16:21 [PATCH v3 00/12] riscv: Add support for P8700 platform on Boston board Uros Stajic
                   ` (3 preceding siblings ...)
  2025-07-29 16:23 ` [PATCH v3 04/12] pci: xilinx: Avoid writing memory base/limit for root bridge Uros Stajic
@ 2025-07-29 16:23 ` Uros Stajic
  2025-07-29 16:23 ` [PATCH v3 06/12] net: pch_gbe: Add PHY reset and MAC address fallback for RISC-V Uros Stajic
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Uros Stajic @ 2025-07-29 16:23 UTC (permalink / raw)
  To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic

From: Chao-ying Fu <cfu@mips.com>

Add basic support for the MIPS GIC syscon used on the P8700 SoC.
Enables access to interrupt control via device tree matching.

Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
 arch/riscv/Kconfig                  | 11 +++++++
 arch/riscv/cpu/p8700/Kconfig        |  2 +-
 arch/riscv/lib/Makefile             |  1 +
 arch/riscv/lib/mips_gic.c           | 47 +++++++++++++++++++++++++++++
 board/mips/boston-riscv/MAINTAINERS |  1 +
 5 files changed, 61 insertions(+), 1 deletion(-)
 create mode 100644 arch/riscv/lib/mips_gic.c

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index b05e0622908..aada4f4061e 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -385,6 +385,17 @@ config SIFIVE_CACHE
 	help
 	  This enables the operations to configure SiFive cache
 
+config MIPS_GIC
+	bool
+	depends on RISCV_MMODE || SPL_RISCV_MMODE
+	select REGMAP
+	select SYSCON
+	select SPL_REGMAP if SPL
+	select SPL_SYSCON if SPL
+	help
+	  The MIPS GIC block holds memory-mapped control and status registers
+	  associated with software and timer interrupts.
+
 config ANDES_PLICSW
 	bool
 	depends on RISCV_MMODE || SPL_RISCV_MMODE
diff --git a/arch/riscv/cpu/p8700/Kconfig b/arch/riscv/cpu/p8700/Kconfig
index 0e5e4c9eda6..223130d5443 100644
--- a/arch/riscv/cpu/p8700/Kconfig
+++ b/arch/riscv/cpu/p8700/Kconfig
@@ -8,7 +8,7 @@ config P8700_RISCV
 	imply CPU
 	imply CPU_RISCV
 	imply RISCV_TIMER
-	imply SIFIVE_CLINT if (RISCV_MMODE || SPL_RISCV_MMODE)
+	imply MIPS_GIC if (RISCV_MMODE || SPL_RISCV_MMODE)
 	imply CMD_CPU
 	imply SPL_CPU_SUPPORT
 	imply SPL_OPENSBI
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index db8d235c699..692b56cc3f0 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_SYS_CACHE_THEAD_CMO) += thead_cmo.o
 ifeq ($(CONFIG_$(PHASE_)RISCV_MMODE),y)
 obj-$(CONFIG_$(PHASE_)RISCV_ACLINT) += aclint_ipi.o
 obj-$(CONFIG_ANDES_PLICSW) += andes_plicsw.o
+obj-$(CONFIG_MIPS_GIC) += mips_gic.o
 else
 obj-$(CONFIG_SBI) += sbi.o
 obj-$(CONFIG_SBI_IPI) += sbi_ipi.o
diff --git a/arch/riscv/lib/mips_gic.c b/arch/riscv/lib/mips_gic.c
new file mode 100644
index 00000000000..7d761c58e74
--- /dev/null
+++ b/arch/riscv/lib/mips_gic.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+ *
+ * U-Boot syscon driver for MIPS GIC.
+ */
+
+#include <dm.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/syscon.h>
+#include <linux/err.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int riscv_init_ipi(void)
+{
+	return 0;
+}
+
+int riscv_send_ipi(int hart)
+{
+	return 0;
+}
+
+int riscv_clear_ipi(int hart)
+{
+	return 0;
+}
+
+int riscv_get_ipi(int hart, int *pending)
+{
+	return 0;
+}
+
+static const struct udevice_id mips_gic_ids[] = {
+	{ .compatible = "mips,gic0", .data = RISCV_SYSCON_PLICSW },
+	{ }
+};
+
+U_BOOT_DRIVER(mips_gic) = {
+	.name		= "mips_gic",
+	.id		= UCLASS_SYSCON,
+	.of_match	= mips_gic_ids,
+	.flags		= DM_FLAG_PRE_RELOC,
+};
diff --git a/board/mips/boston-riscv/MAINTAINERS b/board/mips/boston-riscv/MAINTAINERS
index bc59a628c79..0d9a951441f 100644
--- a/board/mips/boston-riscv/MAINTAINERS
+++ b/board/mips/boston-riscv/MAINTAINERS
@@ -8,3 +8,4 @@ F:  arch/riscv/include/asm/arch-p8700/
 F:  configs/boston-p8700_defconfig
 F:  arch/riscv/dts/boston-p8700.dts
 F:  drivers/gpio/eg20t-gpio.c
+F:  arch/riscv/lib/mips_gic.c
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 06/12] net: pch_gbe: Add PHY reset and MAC address fallback for RISC-V
  2025-07-29 16:21 [PATCH v3 00/12] riscv: Add support for P8700 platform on Boston board Uros Stajic
                   ` (4 preceding siblings ...)
  2025-07-29 16:23 ` [PATCH v3 05/12] riscv: Add support for MIPS GIC syscon on RISC-V SoCs Uros Stajic
@ 2025-07-29 16:23 ` Uros Stajic
  2025-07-29 16:24 ` [PATCH v3 07/12] libfdt: Allow non-64b aligned memreserve entries Uros Stajic
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Uros Stajic @ 2025-07-29 16:23 UTC (permalink / raw)
  To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic

From: Chao-ying Fu <cfu@mips.com>

Add optional PHY reset support via GPIO defined in the device tree.

Improve robustness by handling probe errors and falling back to the
environment-provided MAC address if no hardware MAC is found.

Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
 board/mips/boston-riscv/Kconfig |  4 ++++
 drivers/net/pch_gbe.c           | 37 +++++++++++++++++++++++++++++++--
 drivers/net/pch_gbe.h           |  1 +
 net/eth-uclass.c                |  2 ++
 4 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/board/mips/boston-riscv/Kconfig b/board/mips/boston-riscv/Kconfig
index 68c5fc50489..4d55d96603e 100644
--- a/board/mips/boston-riscv/Kconfig
+++ b/board/mips/boston-riscv/Kconfig
@@ -40,4 +40,8 @@ config PHY_REALTEK
     bool
     default y
 
+config TFTP_FILE_NAME_MAX_LEN
+    int "Maximum length of TFTP file name"
+    default 256
+
 endif
diff --git a/drivers/net/pch_gbe.c b/drivers/net/pch_gbe.c
index adeca3d040d..dea8ab828ac 100644
--- a/drivers/net/pch_gbe.c
+++ b/drivers/net/pch_gbe.c
@@ -7,6 +7,7 @@
 
 #include <cpu_func.h>
 #include <dm.h>
+#include <env.h>
 #include <errno.h>
 #include <log.h>
 #include <malloc.h>
@@ -15,6 +16,7 @@
 #include <miiphy.h>
 #include <linux/delay.h>
 #include "pch_gbe.h"
+#include <asm/gpio.h>
 
 #if !defined(CONFIG_PHYLIB)
 # error "PCH Gigabit Ethernet driver requires PHYLIB - missing CONFIG_PHYLIB"
@@ -33,6 +35,13 @@ static void pch_gbe_mac_read(struct pch_gbe_regs *mac_regs, u8 *addr)
 	macid_lo = readl(&mac_regs->mac_adr[0].low) & 0xffff;
 	debug("pch_gbe: macid_hi %#x macid_lo %#x\n", macid_hi, macid_lo);
 
+	if (!macid_lo && !macid_hi) {
+		if (eth_env_get_enetaddr("ethaddr", addr))
+			return;
+
+		printf("No MAC found in either EG20T H/W or environment");
+	}
+
 	addr[0] = (u8)(macid_hi & 0xff);
 	addr[1] = (u8)((macid_hi >> 8) & 0xff);
 	addr[2] = (u8)((macid_hi >> 16) & 0xff);
@@ -74,6 +83,14 @@ static int pch_gbe_reset(struct udevice *dev)
 	priv->rx_idx = 0;
 	priv->tx_idx = 0;
 
+	if (dm_gpio_is_valid(&priv->gpio_phy_reset)) {
+		/* Reset the PHY */
+		dm_gpio_set_value(&priv->gpio_phy_reset, 1);
+		udelay(15000);
+		dm_gpio_set_value(&priv->gpio_phy_reset, 0);
+		udelay(5000);
+	}
+
 	writel(PCH_GBE_ALL_RST, &mac_regs->reset);
 
 	/*
@@ -450,6 +467,11 @@ static int pch_gbe_probe(struct udevice *dev)
 	plat->iobase = (ulong)iobase;
 	priv->mac_regs = (struct pch_gbe_regs *)iobase;
 
+	err = gpio_request_by_name(dev, "phy-reset-gpios", 0,
+				   &priv->gpio_phy_reset, GPIOD_IS_OUT);
+	if (err && (err != -ENOENT))
+		return err;
+
 	/* Read MAC address from SROM and initialize dev->enetaddr with it */
 	pch_gbe_mac_read(priv->mac_regs, plat->enetaddr);
 
@@ -459,9 +481,17 @@ static int pch_gbe_probe(struct udevice *dev)
 
 	err = pch_gbe_reset(dev);
 	if (err)
-		return err;
+		goto out_err;
+
+	err = pch_gbe_phy_init(dev);
+	if (err)
+		goto out_err;
 
-	return pch_gbe_phy_init(dev);
+	return 0;
+out_err:
+	if (dm_gpio_is_valid(&priv->gpio_phy_reset))
+		dm_gpio_free(dev, &priv->gpio_phy_reset);
+	return err;
 }
 
 static int pch_gbe_remove(struct udevice *dev)
@@ -472,6 +502,9 @@ static int pch_gbe_remove(struct udevice *dev)
 	mdio_unregister(priv->bus);
 	mdio_free(priv->bus);
 
+	if (dm_gpio_is_valid(&priv->gpio_phy_reset))
+		dm_gpio_free(dev, &priv->gpio_phy_reset);
+
 	return 0;
 }
 
diff --git a/drivers/net/pch_gbe.h b/drivers/net/pch_gbe.h
index 7e0fdbfd5a3..dcbb94094bc 100644
--- a/drivers/net/pch_gbe.h
+++ b/drivers/net/pch_gbe.h
@@ -292,6 +292,7 @@ struct pch_gbe_priv {
 	struct udevice *dev;
 	int rx_idx;
 	int tx_idx;
+	struct gpio_desc gpio_phy_reset;
 };
 
 #endif /* _PCH_GBE_H_ */
diff --git a/net/eth-uclass.c b/net/eth-uclass.c
index a233912fd8e..f9f24305fb3 100644
--- a/net/eth-uclass.c
+++ b/net/eth-uclass.c
@@ -463,6 +463,8 @@ int eth_rx(void)
 			break;
 		if (!eth_is_active(current))
 			break;
+		if (net_state == NETLOOP_FAIL)
+			break;
 	}
 	if (ret == -EAGAIN)
 		ret = 0;
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 07/12] libfdt: Allow non-64b aligned memreserve entries
  2025-07-29 16:21 [PATCH v3 00/12] riscv: Add support for P8700 platform on Boston board Uros Stajic
                   ` (5 preceding siblings ...)
  2025-07-29 16:23 ` [PATCH v3 06/12] net: pch_gbe: Add PHY reset and MAC address fallback for RISC-V Uros Stajic
@ 2025-07-29 16:24 ` Uros Stajic
  2025-07-29 16:24 ` [PATCH v3 08/12] riscv: p8700: Add software emulation for AMO* instructions Uros Stajic
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Uros Stajic @ 2025-07-29 16:24 UTC (permalink / raw)
  To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic

From: Chao-ying Fu <cfu@mips.com>

Although memreserve entries in an FDT are 64-bit aligned relative to the
start of the FDT, we cannot guarantee that the FDT itself is 64-bit aligned
in memory. This is especially common when using a FIT image, where the
alignment of the embedded DTB cannot be controlled.

On systems that do not support unaligned 64-bit memory accesses, this leads
to faults when accessing the memreserve section before the FDT is relocated.
To resolve this, copy the 64-bit values into suitably aligned on-stack
variables before accessing them.

Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
 scripts/dtc/libfdt/fdt_ro.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
index d65656aaa8b..1c18aea66ab 100644
--- a/scripts/dtc/libfdt/fdt_ro.c
+++ b/scripts/dtc/libfdt/fdt_ro.c
@@ -174,6 +174,7 @@ static const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n)
 
 int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
 {
+	uint64_t u64;
 	const struct fdt_reserve_entry *re;
 
 	FDT_RO_PROBE(fdt);
@@ -181,8 +182,10 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
 	if (fdt_chk_extra() && !re)
 		return -FDT_ERR_BADOFFSET;
 
-	*address = fdt64_to_cpu(re->address);
-	*size = fdt64_to_cpu(re->size);
+	memcpy(&u64, &re->address, sizeof(u64));
+	*address = fdt64_to_cpu(u64);
+	memcpy(&u64, &re->size, sizeof(u64));
+	*size = fdt64_to_cpu(u64);
 	return 0;
 }
 
@@ -190,9 +193,11 @@ int fdt_num_mem_rsv(const void *fdt)
 {
 	int i;
 	const struct fdt_reserve_entry *re;
+	uint64_t u64;
 
 	for (i = 0; (re = fdt_mem_rsv(fdt, i)) != NULL; i++) {
-		if (fdt64_to_cpu(re->size) == 0)
+		memcpy(&u64, &re->size, sizeof(u64));
+		if (fdt64_to_cpu(u64) == 0)
 			return i;
 	}
 	return -FDT_ERR_TRUNCATED;
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 08/12] riscv: p8700: Add software emulation for AMO* instructions
  2025-07-29 16:21 [PATCH v3 00/12] riscv: Add support for P8700 platform on Boston board Uros Stajic
                   ` (6 preceding siblings ...)
  2025-07-29 16:24 ` [PATCH v3 07/12] libfdt: Allow non-64b aligned memreserve entries Uros Stajic
@ 2025-07-29 16:24 ` Uros Stajic
  2025-08-01  7:54   ` Yao Zi
  2025-07-29 16:24 ` [PATCH v3 09/12] riscv: p8700: Add Coherence Manager (CM) and IOCU support Uros Stajic
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 20+ messages in thread
From: Uros Stajic @ 2025-07-29 16:24 UTC (permalink / raw)
  To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic

From: Chao-ying Fu <cfu@mips.com>

This patch adds software emulation for atomic memory operations (AMO)
instructions that may not be supported in hardware.

The `emu-amo.s` file provides assembly implementations of the
aforementioned operations. Corresponding handler logic is integrated
into the illegal instruction trap to catch and emulate unsupported
AMO* instructions at runtime.

Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
 arch/riscv/cpu/p8700/Makefile  |   1 +
 arch/riscv/cpu/p8700/emu-amo.S | 254 ++++++++++++++++++++++++++++
 arch/riscv/lib/interrupts.c    | 299 +++++++++++++++++++++++++++++++++
 include/interrupt.h            |  19 +++
 4 files changed, 573 insertions(+)
 create mode 100644 arch/riscv/cpu/p8700/emu-amo.S

diff --git a/arch/riscv/cpu/p8700/Makefile b/arch/riscv/cpu/p8700/Makefile
index 4dfbddc5cba..22f96401640 100644
--- a/arch/riscv/cpu/p8700/Makefile
+++ b/arch/riscv/cpu/p8700/Makefile
@@ -5,5 +5,6 @@
 obj-y += cache.o
 obj-y += cpu.o
 obj-y += dram.o
+obj-y += emu-amo.o
 
 obj-$(CONFIG_P8700_RISCV) += p8700_platform_setup.o
diff --git a/arch/riscv/cpu/p8700/emu-amo.S b/arch/riscv/cpu/p8700/emu-amo.S
new file mode 100644
index 00000000000..b7005339939
--- /dev/null
+++ b/arch/riscv/cpu/p8700/emu-amo.S
@@ -0,0 +1,254 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+ */
+
+        .text
+
+        .align 3
+	.globl	atomic_swap_w
+atomic_swap_w:
+	lw	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+1:	lr.w	a5,(a4)
+	bne	a5,a0,2b
+	sc.w	a6,a1,(a4)
+	bnez	a6,1b
+	ret
+
+        .align 3
+	.globl	atomic_swap_d
+atomic_swap_d:
+	ld	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+1:	lr.d	a5,(a4)
+	bne	a5,a0,2b
+	sc.d	a6,a1,(a4)
+	bnez	a6,1b
+	ret
+
+        .align 3
+	.globl	atomic_add_w
+atomic_add_w:
+	lw	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+	addw	a3,a5,a1
+1:	lr.w	a5,(a4)
+	bne	a5,a0,2b
+	sc.w	a6,a3,(a4)
+	bnez	a6,1b
+	ret
+
+        .align 3
+	.globl	atomic_add_d
+atomic_add_d:
+	ld	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+	add	a3,a5,a1
+1:	lr.d	a5,(a4)
+	bne	a5,a0,2b
+	sc.d	a6,a3,(a4)
+	bnez	a6,1b
+	ret
+
+        .align 3
+	.globl	atomic_and_w
+atomic_and_w:
+	lw	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+	and	a3,a5,a1
+1:	lr.w	a5,(a4)
+	bne	a5,a0,2b
+	sc.w	a6,a3,(a4)
+	bnez	a6,1b
+	ret
+
+        .align 3
+	.globl	atomic_and_d
+atomic_and_d:
+	ld	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+	and	a3,a5,a1
+1:	lr.d	a5,(a4)
+	bne	a5,a0,2b
+	sc.d	a6,a3,(a4)
+	bnez	a6,1b
+	ret
+
+        .align 3
+	.globl	atomic_or_w
+atomic_or_w:
+	lw	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+	or	a3,a5,a1
+1:	lr.w	a5,(a4)
+	bne	a5,a0,2b
+	sc.w	a6,a3,(a4)
+	bnez	a6,1b
+	ret
+
+        .align 3
+	.globl	atomic_or_d
+atomic_or_d:
+	ld	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+	or	a3,a5,a1
+1:	lr.d	a5,(a4)
+	bne	a5,a0,2b
+	sc.d	a6,a3,(a4)
+	bnez	a6,1b
+	ret
+
+        .align 3
+	.globl	atomic_xor_w
+atomic_xor_w:
+	lw	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+	xor	a3,a5,a1
+1:	lr.w	a5,(a4)
+	bne	a5,a0,2b
+	sc.w	a6,a3,(a4)
+	bnez	a6,1b
+	ret
+
+        .align 3
+	.globl	atomic_xor_d
+atomic_xor_d:
+	ld	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+	xor	a3,a5,a1
+1:	lr.d	a5,(a4)
+	bne	a5,a0,2b
+	sc.d	a6,a3,(a4)
+	bnez	a6,1b
+	ret
+
+        .align 3
+	.globl	atomic_max_w
+atomic_max_w:
+	lw	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+	mv	a3,a5
+	bge	a5,a1,1f
+	mv	a3,a1
+1:	lr.w	a5,(a4)
+	bne	a5,a0,2b
+	sc.w	a6,a3,(a4)
+	bnez	a6,1b
+	ret
+
+        .align 3
+	.globl	atomic_max_d
+atomic_max_d:
+	ld	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+	mv	a3,a5
+	bge	a5,a1,1f
+	mv	a3,a1
+1:	lr.d	a5,(a4)
+	bne	a5,a0,2b
+	sc.d	a6,a3,(a4)
+	bnez	a6,1b
+	ret
+
+        .align 3
+	.globl	atomic_maxu_w
+atomic_maxu_w:
+	lw	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+	mv	a3,a5
+	bgeu	a5,a1,1f
+	mv	a3,a1
+1:	lr.w	a5,(a4)
+	bne	a5,a0,2b
+	sc.w	a6,a3,(a4)
+	bnez	a6,1b
+	ret
+
+        .align 3
+	.globl	atomic_maxu_d
+atomic_maxu_d:
+	ld	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+	mv	a3,a5
+	bgeu	a5,a1,1f
+	mv	a3,a1
+1:	lr.d	a5,(a4)
+	bne	a5,a0,2b
+	sc.d	a6,a3,(a4)
+	bnez	a6,1b
+	ret
+
+        .align 3
+	.globl	atomic_min_w
+atomic_min_w:
+	lw	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+	mv	a3,a5
+	bge	a1,a5,1f
+	mv	a3,a1
+1:	lr.w	a5,(a4)
+	bne	a5,a0,2b
+	sc.w	a6,a3,(a4)
+	bnez	a6,1b
+	ret
+
+        .align 3
+	.globl	atomic_min_d
+atomic_min_d:
+	ld	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+	mv	a3,a5
+	bge	a1,a5,1f
+	mv	a3,a1
+1:	lr.d	a5,(a4)
+	bne	a5,a0,2b
+	sc.d	a6,a3,(a4)
+	bnez	a6,1b
+	ret
+
+        .align 3
+	.globl	atomic_minu_w
+atomic_minu_w:
+	lw	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+	mv	a3,a5
+	bgeu	a1,a5,1f
+	mv	a3,a1
+1:	lr.w	a5,(a4)
+	bne	a5,a0,2b
+	sc.w	a6,a3,(a4)
+	bnez	a6,1b
+	ret
+
+        .align 3
+	.globl	atomic_minu_d
+atomic_minu_d:
+	ld	a5,0(a0)
+	mv	a4,a0
+2:	mv	a0,a5
+	mv	a3,a5
+	bgeu	a1,a5,1f
+	mv	a3,a1
+1:	lr.d	a5,(a4)
+	bne	a5,a0,2b
+	sc.d	a6,a3,(a4)
+	bnez	a6,1b
+	ret
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c
index ef1056eeb6f..906916c762f 100644
--- a/arch/riscv/lib/interrupts.c
+++ b/arch/riscv/lib/interrupts.c
@@ -22,6 +22,36 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#define ILLEGAL_INSTRUCTION 2
+#define AMO_MASK 0xf800707f
+#define AQRL_MASK 0x06000000
+#define AQRL_SHIFT 25
+#define RS2_MASK 0x01f00000
+#define RS2_SHIFT 20
+#define RS1_MASK 0x000f8000
+#define RS1_SHIFT 15
+#define RD_MASK 0x00000f80
+#define RD_SHIFT 7
+
+#define AMOADD_D_MATCH 0x0000302f
+#define AMOADD_W_MATCH 0x0000202f
+#define AMOAND_D_MATCH 0x6000302f
+#define AMOAND_W_MATCH 0x6000202f
+#define AMOMAX_D_MATCH 0xa000302f
+#define AMOMAX_W_MATCH 0xa000202f
+#define AMOMAXU_D_MATCH 0xe000302f
+#define AMOMAXU_W_MATCH 0xe000202f
+#define AMOMIN_D_MATCH 0x8000302f
+#define AMOMIN_W_MATCH 0x8000202f
+#define AMOMINU_D_MATCH 0xc000302f
+#define AMOMINU_W_MATCH 0xc000202f
+#define AMOOR_D_MATCH 0x4000302f
+#define AMOOR_W_MATCH 0x4000202f
+#define AMOSWAP_D_MATCH 0x0800302f
+#define AMOSWAP_W_MATCH 0x0800202f
+#define AMOXOR_D_MATCH 0x2000302f
+#define AMOXOR_W_MATCH 0x2000202f
+
 void set_resume(struct resume_data *data)
 {
 	gd->arch.resume = data;
@@ -115,6 +145,184 @@ static void show_code(ulong epc)
 		printf("%04x%s", pos[i], i + 1 == len ? ")\n" : " ");
 }
 
+static ulong get_reg(struct pt_regs *regs, int reg_num)
+{
+	switch (reg_num) {
+	case 0:
+		return 0;
+	case 1:
+		return regs->ra;
+	case 2:
+		return regs->sp;
+	case 3:
+		return regs->gp;
+	case 4:
+		return regs->tp;
+	case 5:
+		return regs->t0;
+	case 6:
+		return regs->t1;
+	case 7:
+		return regs->t2;
+	case 8:
+		return regs->s0;
+	case 9:
+		return regs->s1;
+	case 10:
+		return regs->a0;
+	case 11:
+		return regs->a1;
+	case 12:
+		return regs->a2;
+	case 13:
+		return regs->a3;
+	case 14:
+		return regs->a4;
+	case 15:
+		return regs->a5;
+	case 16:
+		return regs->a6;
+	case 17:
+		return regs->a7;
+	case 18:
+		return regs->s2;
+	case 19:
+		return regs->s3;
+	case 20:
+		return regs->s4;
+	case 21:
+		return regs->s5;
+	case 22:
+		return regs->s6;
+	case 23:
+		return regs->s7;
+	case 24:
+		return regs->s8;
+	case 25:
+		return regs->s9;
+	case 26:
+		return regs->s10;
+	case 27:
+		return regs->s11;
+	case 28:
+		return regs->t3;
+	case 29:
+		return regs->t4;
+	case 30:
+		return regs->t5;
+	case 31:
+		return regs->t6;
+	default:
+		printf("Error reg_num=%d for %s\n", reg_num, __func__);
+		break;
+	}
+	return 0;
+}
+
+static void set_reg(struct pt_regs *regs, int reg_num, ulong reg_value)
+{
+	switch (reg_num) {
+	case 0:
+		break;
+	case 1:
+		regs->ra = reg_value;
+		break;
+	case 2:
+		regs->sp = reg_value;
+		break;
+	case 3:
+		regs->gp = reg_value;
+		break;
+	case 4:
+		regs->tp = reg_value;
+		break;
+	case 5:
+		regs->t0 = reg_value;
+		break;
+	case 6:
+		regs->t1 = reg_value;
+		break;
+	case 7:
+		regs->t2 = reg_value;
+		break;
+	case 8:
+		regs->s0 = reg_value;
+		break;
+	case 9:
+		regs->s1 = reg_value;
+		break;
+	case 10:
+		regs->a0 = reg_value;
+		break;
+	case 11:
+		regs->a1 = reg_value;
+		break;
+	case 12:
+		regs->a2 = reg_value;
+		break;
+	case 13:
+		regs->a3 = reg_value;
+		break;
+	case 14:
+		regs->a4 = reg_value;
+		break;
+	case 15:
+		regs->a5 = reg_value;
+		break;
+	case 16:
+		regs->a6 = reg_value;
+		break;
+	case 17:
+		regs->a7 = reg_value;
+		break;
+	case 18:
+		regs->s2 = reg_value;
+		break;
+	case 19:
+		regs->s3 = reg_value;
+		break;
+	case 20:
+		regs->s4 = reg_value;
+		break;
+	case 21:
+		regs->s5 = reg_value;
+		break;
+	case 22:
+		regs->s6 = reg_value;
+		break;
+	case 23:
+		regs->s7 = reg_value;
+		break;
+	case 24:
+		regs->s8 = reg_value;
+		break;
+	case 25:
+		regs->s9 = reg_value;
+		break;
+	case 26:
+		regs->s10 = reg_value;
+		break;
+	case 27:
+		regs->s11 = reg_value;
+		break;
+	case 28:
+		regs->t3 = reg_value;
+		break;
+	case 29:
+		regs->t4 = reg_value;
+		break;
+	case 30:
+		regs->t5 = reg_value;
+		break;
+	case 31:
+		regs->t6 = reg_value;
+		break;
+	default:
+		printf("Error reg_num=%d for %s\n", reg_num, __func__);
+		break;
+	}
+}
+
 static void _exit_trap(ulong code, ulong epc, ulong tval, struct pt_regs *regs)
 {
 	static const char * const exception_code[] = {
@@ -140,6 +348,97 @@ static void _exit_trap(ulong code, ulong epc, ulong tval, struct pt_regs *regs)
 		gd->arch.resume->code = code;
 		longjmp(gd->arch.resume->jump, 1);
 	}
+	if (IS_ENABLED(CONFIG_P8700_RISCV) && code == ILLEGAL_INSTRUCTION) {
+		// Fetch one 16-bit op at a time to deal with 16-bit alignment.
+		// FIXME! For the big-endian mode, we need to swap bytes.
+		unsigned short op0 = *(unsigned short *)epc;
+		unsigned short op1 = *((unsigned short *)epc + 1);
+		unsigned int opcode = (op1 << 16) | op0;
+		//int aqrl = (opcode & AQRL_MASK) >> AQRL_SHIFT;
+		int rs2 = (opcode & RS2_MASK) >> RS2_SHIFT;
+		int rs1 = (opcode & RS1_MASK) >> RS1_SHIFT;
+		int rd = (opcode & RD_MASK) >> RD_SHIFT;
+		ulong rs2_value = get_reg(regs, rs2);
+		ulong rs1_value = get_reg(regs, rs1);
+		ulong rd_value = 0;
+
+		switch (opcode & AMO_MASK) {
+		case AMOADD_D_MATCH:
+			rd_value = atomic_add_d(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		case AMOADD_W_MATCH:
+			rd_value = atomic_add_w(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		case AMOAND_D_MATCH:
+			rd_value = atomic_and_d(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		case AMOAND_W_MATCH:
+			rd_value = atomic_and_w(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		case AMOMAX_D_MATCH:
+			rd_value = atomic_max_d(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		case AMOMAX_W_MATCH:
+			rd_value = atomic_max_w(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		case AMOMAXU_D_MATCH:
+			rd_value = atomic_maxu_d(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		case AMOMAXU_W_MATCH:
+			rd_value = atomic_maxu_w(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		case AMOMIN_D_MATCH:
+			rd_value = atomic_min_d(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		case AMOMIN_W_MATCH:
+			rd_value = atomic_min_w(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		case AMOMINU_D_MATCH:
+			rd_value = atomic_minu_d(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		case AMOMINU_W_MATCH:
+			rd_value = atomic_minu_w(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		case AMOOR_D_MATCH:
+			rd_value = atomic_or_d(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		case AMOOR_W_MATCH:
+			rd_value = atomic_or_w(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		case AMOSWAP_D_MATCH:
+			rd_value = atomic_swap_d(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		case AMOSWAP_W_MATCH:
+			rd_value = atomic_swap_w(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		case AMOXOR_D_MATCH:
+			rd_value = atomic_xor_d(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		case AMOXOR_W_MATCH:
+			rd_value = atomic_xor_w(rs1_value, rs2_value);
+			set_reg(regs, rd, rd_value);
+
+		default:
+			break;
+		}
+	}
 
 	if (code < ARRAY_SIZE(exception_code))
 		printf("Unhandled exception: %s\n", exception_code[code]);
diff --git a/include/interrupt.h b/include/interrupt.h
index 6ea28b54a56..5fc983afccb 100644
--- a/include/interrupt.h
+++ b/include/interrupt.h
@@ -43,3 +43,22 @@ struct resume_data {
  * Return:	0 before an exception, 1 after an exception occurred
  */
 void set_resume(struct resume_data *data);
+
+ulong atomic_swap_w(ulong val, ulong addr);
+ulong atomic_swap_d(ulong val, ulong addr);
+ulong atomic_add_w(ulong val, ulong addr);
+ulong atomic_add_d(ulong val, ulong addr);
+ulong atomic_and_w(ulong val, ulong addr);
+ulong atomic_and_d(ulong val, ulong addr);
+ulong atomic_or_w(ulong val, ulong addr);
+ulong atomic_or_d(ulong val, ulong addr);
+ulong atomic_xor_w(ulong val, ulong addr);
+ulong atomic_xor_d(ulong val, ulong addr);
+ulong atomic_max_w(ulong val, ulong addr);
+ulong atomic_max_d(ulong val, ulong addr);
+ulong atomic_maxu_w(ulong val, ulong addr);
+ulong atomic_maxu_d(ulong val, ulong addr);
+ulong atomic_min_w(ulong val, ulong addr);
+ulong atomic_min_d(ulong val, ulong addr);
+ulong atomic_minu_w(ulong val, ulong addr);
+ulong atomic_minu_d(ulong val, ulong addr);
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 09/12] riscv: p8700: Add Coherence Manager (CM) and IOCU support
  2025-07-29 16:21 [PATCH v3 00/12] riscv: Add support for P8700 platform on Boston board Uros Stajic
                   ` (7 preceding siblings ...)
  2025-07-29 16:24 ` [PATCH v3 08/12] riscv: p8700: Add software emulation for AMO* instructions Uros Stajic
@ 2025-07-29 16:24 ` Uros Stajic
  2025-08-01  8:47   ` Yao Zi
  2025-07-29 16:24 ` [PATCH v3 10/12] riscv: boston: Add support for LED character display command Uros Stajic
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 20+ messages in thread
From: Uros Stajic @ 2025-07-29 16:24 UTC (permalink / raw)
  To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic

From: Chao-ying Fu <cfu@mips.com>

Add support for Coherence Manager (CM) and IOCU discovery and
configuration on the P8700 platform.

Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
 arch/riscv/cpu/p8700/Makefile             |   2 +
 arch/riscv/cpu/p8700/cache.c              |  10 +++
 arch/riscv/cpu/p8700/cm-iocu.c            |  75 ++++++++++++++++
 arch/riscv/cpu/p8700/cm.c                 |  92 +++++++++++++++++++
 arch/riscv/include/asm/arch-p8700/cm.h    |  61 +++++++++++++
 arch/riscv/include/asm/arch-p8700/p8700.h |  31 +++++++
 arch/riscv/include/asm/global_data.h      |   2 +
 arch/riscv/include/asm/io.h               |  86 ++++++++++++++++++
 board/mips/boston-riscv/Makefile          |   1 +
 board/mips/boston-riscv/iocu.c            | 104 ++++++++++++++++++++++
 10 files changed, 464 insertions(+)
 create mode 100644 arch/riscv/cpu/p8700/cm-iocu.c
 create mode 100644 arch/riscv/cpu/p8700/cm.c
 create mode 100644 arch/riscv/include/asm/arch-p8700/cm.h
 create mode 100644 board/mips/boston-riscv/iocu.c

diff --git a/arch/riscv/cpu/p8700/Makefile b/arch/riscv/cpu/p8700/Makefile
index 22f96401640..ed45f3f77e1 100644
--- a/arch/riscv/cpu/p8700/Makefile
+++ b/arch/riscv/cpu/p8700/Makefile
@@ -3,6 +3,8 @@
 # Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
 
 obj-y += cache.o
+obj-y += cm.o
+obj-y += cm-iocu.o
 obj-y += cpu.o
 obj-y += dram.o
 obj-y += emu-amo.o
diff --git a/arch/riscv/cpu/p8700/cache.c b/arch/riscv/cpu/p8700/cache.c
index 7559c688321..b465b4090bb 100644
--- a/arch/riscv/cpu/p8700/cache.c
+++ b/arch/riscv/cpu/p8700/cache.c
@@ -48,6 +48,11 @@ static void probe_cache_config(void)
 
 void flush_dcache_range(unsigned long start, unsigned long end)
 {
+	DECLARE_GLOBAL_DATA_PTR;
+
+	if (gd->flags & GD_FLG_COHERENT_DMA)
+		return;
+
 	if (lsize == 0)
 		probe_cache_config();
 
@@ -71,6 +76,11 @@ void flush_dcache_range(unsigned long start, unsigned long end)
 
 void invalidate_dcache_range(unsigned long start, unsigned long end)
 {
+	DECLARE_GLOBAL_DATA_PTR;
+
+	if (gd->flags & GD_FLG_COHERENT_DMA)
+		return;
+
 	if (lsize == 0)
 		probe_cache_config();
 
diff --git a/arch/riscv/cpu/p8700/cm-iocu.c b/arch/riscv/cpu/p8700/cm-iocu.c
new file mode 100644
index 00000000000..5850647d20f
--- /dev/null
+++ b/arch/riscv/cpu/p8700/cm-iocu.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MIPS Coherence Manager (CM) Support
+ *
+ * Copyright (c) 2016 Imagination Technologies Ltd.
+ */
+#include <asm/io.h>
+#include <asm/global_data.h>
+#include <asm/arch-p8700/cm.h>
+
+__weak bool plat_iocu_usable(unsigned int cluster, unsigned int iocu)
+{
+	return true;
+}
+
+static int init_cluster_iocus(unsigned int cluster)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	void __iomem *global_gcrs;
+	u32 cfg, num_iocus, num_iocus_usable, local_cluster;
+	int i;
+
+	local_cluster = mips_cluster_id();
+
+	global_gcrs = mips_cm_base();
+	if (cluster != local_cluster) {
+		// FIXME
+		return 1;
+	}
+
+	cfg = __raw_readl(global_gcrs + GCR_CONFIG);
+	num_iocus = cfg >> GCR_CONFIG_NUMIOCU_SHIFT;
+	num_iocus &= GCR_CONFIG_NUMIOCU_MASK;
+	gd->arch.num_iocus += num_iocus;
+
+	/* Discover how many IOCUs are usable */
+	num_iocus_usable = num_iocus;
+	for (i = num_iocus - 1; i >= 0; i--) {
+		if (!plat_iocu_usable(cluster, i))
+			num_iocus_usable--;
+	}
+	gd->arch.num_iocus_usable += num_iocus_usable;
+
+	/* If the cluster has no usable IOCUs there's nothing to do */
+	if (num_iocus_usable == 0) {
+		if (cluster != local_cluster)
+			power_down_cluster(cluster);
+
+		return 0;
+	}
+
+	/* If the IOCUs are in the local cluster we're good to go already */
+	if (cluster == local_cluster)
+		return 0;
+
+	/* Ensure that the cluster's L2 cache is initialised */
+	return init_cluster_l2(cluster);
+}
+
+int mips_cm_init_iocus(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	unsigned int cluster;
+	int err;
+
+	for (cluster = 0; cluster < mips_cm_num_clusters(); cluster++) {
+		err = init_cluster_iocus(cluster);
+		if (err) {
+			gd->arch.num_iocus_usable = err;
+			return 0;
+		}
+	}
+
+	return 0;
+}
diff --git a/arch/riscv/cpu/p8700/cm.c b/arch/riscv/cpu/p8700/cm.c
new file mode 100644
index 00000000000..ce7485c564d
--- /dev/null
+++ b/arch/riscv/cpu/p8700/cm.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MIPS Coherence Manager (CM) Support
+ *
+ * Copyright (c) 2016 Imagination Technologies Ltd.
+ */
+
+#include <asm/io.h>
+#include <asm/arch-p8700/cm.h>
+#include <asm/arch-p8700/p8700.h>
+
+static void mips_cpc_init(void)
+{
+}
+
+__weak const struct mmio_region *get_mmio_regions(void)
+{
+	return NULL;
+}
+
+static void p8700_setup_mmio_limits(void)
+{
+	void __iomem *gcrs = mips_cm_base();
+	const struct mmio_region *rgn = get_mmio_regions();
+	unsigned int num_clusters = mips_cm_num_clusters();
+	unsigned int limit = MIPS_CM_MMIO_LIMIT / num_clusters;
+	unsigned int i, reg_off;
+
+	if (!rgn)
+		return;
+
+	if (num_clusters != 1) {
+		// FIXME! Need to support multiple clusters.
+		return;
+	}
+
+	reg_off = GCR_MMIO0_BOTTOM;
+
+	for (i = 0; rgn[i].addr_high; i++) {
+		__raw_writeq(rgn[i].addr_high & GCR_MMIO0_TOP_ADDR,
+			     gcrs + reg_off + (GCR_MMIO0_TOP - GCR_MMIO0_BOTTOM));
+
+		__raw_writeq((rgn[i].addr_low & GCR_MMIO0_BOTTOM_ADDR) |
+			     (rgn[i].port << GCR_MMIO0_BOTTOM_PORT_SHIFT) |
+			     (rgn[i].enable ? GCR_MMIO0_BOTTOM_ENABLE : 0),
+			     gcrs + reg_off);
+		reg_off += GCR_MMIO1_BOTTOM - GCR_MMIO0_BOTTOM;
+	}
+
+	__raw_writel(limit, gcrs + GCR_MMIO_REQ_LIMIT);
+}
+
+int power_up_cluster(unsigned int cluster)
+{
+	return 0;
+}
+
+int power_down_cluster(unsigned int cluster)
+{
+	return 0;
+}
+
+int init_cluster_l2(unsigned int cluster)
+{
+	return 0;
+}
+
+int mips_cm_init(void)
+{
+	int err;
+
+	mips_cpc_init();
+
+	err = mips_cm_init_iocus();
+	if (err)
+		return err;
+
+	p8700_setup_mmio_limits();
+
+	return 0;
+}
+
+int arch_cpu_init(void)
+{
+	int err;
+
+	err = mips_cm_init();
+	if (err)
+		return err;
+
+	return 0;
+}
diff --git a/arch/riscv/include/asm/arch-p8700/cm.h b/arch/riscv/include/asm/arch-p8700/cm.h
new file mode 100644
index 00000000000..ab5ea7385b2
--- /dev/null
+++ b/arch/riscv/include/asm/arch-p8700/cm.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2021, Chao-ying Fu <cfu@mips.com>
+ */
+
+#ifndef __P8700_CM_H__
+#define __P8700_CM_H__
+
+#include <asm/arch-p8700/p8700.h>
+
+struct mmio_region {
+	phys_addr_t addr_low;
+	phys_addr_t addr_high;
+	unsigned int port : 4;
+	unsigned int enable : 1;
+};
+
+const struct mmio_region *get_mmio_regions(void);
+
+void setup_redirect(unsigned int cluster, unsigned int core,
+		    unsigned int vp, unsigned int block);
+
+int mips_cm_init_iocus(void);
+
+int power_up_cluster(unsigned int cluster);
+int power_down_cluster(unsigned int cluster);
+int init_cluster_l2(unsigned int cluster);
+
+static inline void *mips_cm_base(void)
+{
+	return (void *)CM_BASE;
+}
+
+static inline void *mips_cpc_base(void)
+{
+	return (void *)CPC_BASE;
+}
+
+static inline unsigned int mips_cm_num_clusters(void)
+{
+	u32 cfg;
+
+	cfg = __raw_readl(mips_cm_base() + GCR_CONFIG);
+	cfg >>= GCR_CONFIG_NUMCLUSTERS_SHIFT;
+	cfg &= GCR_CONFIG_NUMCLUSTERS_MASK;
+
+	return cfg;
+}
+
+static inline unsigned int mips_cluster_id(void)
+{
+	u32 temp;
+
+	asm volatile("csrr %0, mhartid" : "=r"(temp));
+	temp >>= MHARTID_CLUSTER_SHIFT;
+	temp &= MHARTID_CLUSTER_MASK;
+
+	return temp;
+}
+
+#endif /* __P8700_CM_H__ */
diff --git a/arch/riscv/include/asm/arch-p8700/p8700.h b/arch/riscv/include/asm/arch-p8700/p8700.h
index 5ca9b4b9497..6c47de9a633 100644
--- a/arch/riscv/include/asm/arch-p8700/p8700.h
+++ b/arch/riscv/include/asm/arch-p8700/p8700.h
@@ -65,6 +65,10 @@
 #define CM_BASE			0x16100000
 #define CPC_BASE		(CM_BASE + 0x8000)
 
+/* Block offsets */
+#define GCR_OFF_GLOBAL		0x0000
+#define GCR_OFF_LOCAL		0x2000
+
 /* CPC Block offsets */
 #define CPC_OFF_LOCAL		0x2000
 
@@ -75,6 +79,33 @@
 #define CPC_Cx_CMD		0x0000
 #define CPC_Cx_CMD_RESET	0x4
 
+/* GCR_CONFIG */
+#define GCR_CONFIG						0x0000
+#define GCR_REV							0x0030
+#define GCR_CONFIG_NUMCLUSTERS_SHIFT	23
+#define GCR_CONFIG_NUMCLUSTERS_MASK	    0x7f
+#define GCR_CONFIG_NUMIOCU_SHIFT	    8
+#define GCR_CONFIG_NUMIOCU_MASK		    0xf
+#define GCR_CONFIG_NUMCORES_SHIFT	    0
+#define GCR_CONFIG_NUMCORES_MASK	    0xff
+
+/* GCR_REV CM versions */
+#define GCR_REV_CM3			0x0800
+#define GCR_REV_CM3_5		0x0900
+
+#define GCR_MMIO_REQ_LIMIT				0x06f8
+#define GCR_MMIO0_BOTTOM				0x0700
+#define GCR_MMIO0_BOTTOM_ADDR			(0xffffffffull << 16)
+#define GCR_MMIO0_BOTTOM_PORT_SHIFT		2
+#define GCR_MMIO0_BOTTOM_PORT			(0xf << 2)
+#define GCR_MMIO0_BOTTOM_DISABLE_LIMIT	(0x1 << 1)
+#define GCR_MMIO0_BOTTOM_ENABLE			(0x1 << 0)
+#define GCR_MMIO0_TOP					0x0708
+#define GCR_MMIO0_TOP_ADDR				(0xffffffffull << 16)
+#define GCR_MMIO1_BOTTOM				0x0710
+
+#define MIPS_CM_MMIO_LIMIT	4
+
 #define P8700_GCR_C0_COH_EN	0x20f8
 #define P8700_GCR_C1_COH_EN	0x21f8
 #define P8700_GCR_C2_COH_EN	0x22f8
diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
index 33f2b5ec5c8..fce2f2bb77d 100644
--- a/arch/riscv/include/asm/global_data.h
+++ b/arch/riscv/include/asm/global_data.h
@@ -44,6 +44,8 @@ struct arch_global_data {
 	ulong smbios_start;		/* Start address of SMBIOS table */
 #endif
 	struct resume_data *resume;
+	int num_iocus;
+	int num_iocus_usable;
 };
 
 #include <asm-generic/global_data.h>
diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
index da165858034..fb79d0a8d32 100644
--- a/arch/riscv/include/asm/io.h
+++ b/arch/riscv/include/asm/io.h
@@ -15,6 +15,91 @@ static inline void sync(void)
 {
 }
 
+/*
+ * Generic virtual read/write.  Note that we don't support half-word
+ * read/writes.  We define __arch_*[bl] here, and leave __arch_*w
+ * to the architecture specific code.
+ */
+
+#if CONFIG_P8700_RISCV
+#ifdef CONFIG_ARCH_MAP_SYSMEM
+static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)
+{
+	if (paddr < PHYS_SDRAM_0_SIZE + PHYS_SDRAM_1_SIZE)
+		paddr = paddr | 0x40000000;
+	return (void *)(uintptr_t)paddr;
+}
+
+static inline void *unmap_sysmem(const void *vaddr)
+{
+	phys_addr_t paddr = (phys_addr_t)vaddr;
+
+	paddr = paddr & ~0x40000000;
+	return (void *)(uintptr_t)paddr;
+}
+
+static inline phys_addr_t map_to_sysmem(const void *ptr)
+{
+	return (phys_addr_t)(uintptr_t)ptr;
+}
+#endif
+
+static inline unsigned char __arch_getb(const volatile void __iomem *mem)
+{
+	unsigned char value;
+
+	asm volatile("lbu %0,0(%1)" : "=r"(value) : "r"(mem));
+
+	return value;
+}
+
+static inline unsigned short __arch_getw(const volatile void __iomem *mem)
+{
+	unsigned short value;
+
+	asm volatile("lhu %0,0(%1)" : "=r"(value) : "r"(mem));
+
+	return value;
+}
+
+static inline unsigned int __arch_getl(const volatile void __iomem *mem)
+{
+	unsigned int value;
+
+	asm volatile("lw %0,0(%1)" : "=r"(value) : "r"(mem));
+
+	return value;
+}
+
+static inline unsigned long long __arch_getq(const volatile void __iomem *mem)
+{
+	unsigned long long value;
+
+	asm volatile("ld %0,0(%1)" : "=r"(value) : "r"(mem));
+
+	return value;
+}
+
+static inline void __arch_putb(unsigned char value, volatile void __iomem *mem)
+{
+	asm volatile("sb %0,0(%1)"::"r"(value), "r"(mem));
+}
+
+static inline void __arch_putw(unsigned short value, volatile void __iomem *mem)
+{
+	asm volatile("sh %0,0(%1)"::"r"(value), "r"(mem));
+}
+
+static inline void __arch_putl(unsigned int value, volatile void __iomem *mem)
+{
+	asm volatile("sw %0,0(%1)"::"r"(value), "r"(mem));
+}
+
+static inline void __arch_putq(unsigned int value, volatile void __iomem *mem)
+{
+	asm volatile("sd %0,0(%1)"::"r"(value), "r"(mem));
+}
+#else
 #define __arch_getb(a)			(*(volatile unsigned char *)(a))
 #define __arch_getw(a)			(*(volatile unsigned short *)(a))
 #define __arch_getl(a)			(*(volatile unsigned int *)(a))
@@ -24,6 +109,7 @@ static inline void sync(void)
 #define __arch_putw(v, a)		(*(volatile unsigned short *)(a) = (v))
 #define __arch_putl(v, a)		(*(volatile unsigned int *)(a) = (v))
 #define __arch_putq(v, a)		(*(volatile unsigned long long *)(a) = (v))
+#endif
 
 #define __raw_writeb(v, a)		__arch_putb(v, a)
 #define __raw_writew(v, a)		__arch_putw(v, a)
diff --git a/board/mips/boston-riscv/Makefile b/board/mips/boston-riscv/Makefile
index 0615c677d23..c67c001d4e6 100644
--- a/board/mips/boston-riscv/Makefile
+++ b/board/mips/boston-riscv/Makefile
@@ -4,5 +4,6 @@
 
 obj-y += boston-riscv.o
 obj-y += checkboard.o
+obj-y += iocu.o
 obj-y += lowlevel_init.o
 obj-y += reset.o
diff --git a/board/mips/boston-riscv/iocu.c b/board/mips/boston-riscv/iocu.c
new file mode 100644
index 00000000000..8478670f350
--- /dev/null
+++ b/board/mips/boston-riscv/iocu.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2016 Imagination Technologies Ltd.
+ */
+
+#include <dm.h>
+#include <env_callback.h>
+#include <asm/io.h>
+#include <asm/arch-p8700/cm.h>
+#include "boston-regs.h"
+
+static const struct mmio_region mmio_regions[] = {
+	{ 0x10000000, 0x160f0000, .enable = 1 },
+	{ 0x17ff0000, 0x17ff0000, .enable = 1 },
+	{ 0 },
+};
+
+const struct mmio_region *get_mmio_regions(void)
+{
+	return mmio_regions;
+}
+
+static int set_io_coherent(bool coherent)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	if (!coherent) {
+		printf("I/O:   Non-Coherent (Forced by environment)\n");
+		goto noncoherent;
+	}
+
+	if (gd->arch.num_iocus_usable < 0) {
+		printf("I/O:   Non-Coherent (IOCU init error %d)\n",
+		       gd->arch.num_iocus_usable);
+		goto noncoherent;
+	}
+
+	if (gd->arch.num_iocus == 0) {
+		printf("I/O:   Non-Coherent (No IOCU)\n");
+		goto noncoherent;
+	}
+
+	if (gd->arch.num_iocus_usable == 0) {
+		printf("I/O:   Non-Coherent (IOCU not connected)\n");
+		goto noncoherent;
+	}
+
+	/*
+	 * We have some number of connected IOCUs. Map all PCIe DMA access to
+	 * hit the IOCU by offsetting the addresses as they pass from the PCIe
+	 * controller to the NoC.
+	 */
+	writel(0x10, (u32 *)BOSTON_PLAT_NOCPCIE0ADDR);
+	writel(0x10, (u32 *)BOSTON_PLAT_NOCPCIE1ADDR);
+	writel(0x10, (u32 *)BOSTON_PLAT_NOCPCIE2ADDR);
+
+	/* Record that I/O is coherent */
+	gd->flags |= GD_FLG_COHERENT_DMA;
+
+	printf("I/O:   Coherent\n");
+	return 0;
+
+noncoherent:
+	/* Map all PCIe DMA access to its default, non-IOCU, target */
+	writel(0x00, (u32 *)BOSTON_PLAT_NOCPCIE0ADDR);
+	writel(0x00, (u32 *)BOSTON_PLAT_NOCPCIE1ADDR);
+	writel(0x00, (u32 *)BOSTON_PLAT_NOCPCIE2ADDR);
+
+	/* Record that I/O is not coherent */
+	gd->flags &= ~GD_FLG_COHERENT_DMA;
+	return 0;
+}
+
+static int on_io_coherent(const char *name, const char *value,
+			  enum env_op op, int flags)
+{
+	switch (op) {
+	case env_op_create:
+	case env_op_overwrite:
+		if (!strcmp(value, "0")) {
+			set_io_coherent(false);
+		} else if (!strcmp(value, "1")) {
+			set_io_coherent(true);
+		} else {
+			printf("### io.coherent must equal 0 or 1\n");
+			return -EINVAL;
+		}
+		return 0;
+
+	case env_op_delete:
+		set_io_coherent(true);
+		return 0;
+
+	default:
+		return 0;
+	}
+}
+
+U_BOOT_ENV_CALLBACK(io_coherent, on_io_coherent);
+
+int misc_init_f(void)
+{
+	return set_io_coherent(env_get_yesno("io.coherent") != 0);
+}
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 10/12] riscv: boston: Add support for LED character display command
  2025-07-29 16:21 [PATCH v3 00/12] riscv: Add support for P8700 platform on Boston board Uros Stajic
                   ` (8 preceding siblings ...)
  2025-07-29 16:24 ` [PATCH v3 09/12] riscv: p8700: Add Coherence Manager (CM) and IOCU support Uros Stajic
@ 2025-07-29 16:24 ` Uros Stajic
  2025-07-29 16:25 ` [PATCH v3 11/12] cmd: riscv: Add 'startharts' command to start multiple harts Uros Stajic
  2025-07-29 16:25 ` [PATCH v3 12/12] timer: p8700: Add support for reading time from memory-mapped mtime Uros Stajic
  11 siblings, 0 replies; 20+ messages in thread
From: Uros Stajic @ 2025-07-29 16:24 UTC (permalink / raw)
  To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic

From: Chao-ying Fu <cfu@mips.com>

Add basic support for the 8-char LED display on P8700-based Boston
Board using display_set() and display_putc(), enabling the generic
'display' command with clear and home support.

Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
 board/mips/boston-riscv/Kconfig         |  4 ++
 board/mips/boston-riscv/MAINTAINERS     |  3 ++
 board/mips/boston-riscv/Makefile        |  1 +
 board/mips/boston-riscv/display.c       | 33 ++++++++++++++++
 board/mips/boston-riscv/lowlevel_init.S |  2 +
 cmd/Kconfig                             |  8 ++++
 cmd/Makefile                            |  1 +
 cmd/display.c                           | 51 +++++++++++++++++++++++++
 doc/README.LED_display                  | 26 +++++++++++++
 include/led-display.h                   | 33 ++++++++++++++++
 10 files changed, 162 insertions(+)
 create mode 100644 board/mips/boston-riscv/display.c
 create mode 100644 cmd/display.c
 create mode 100644 doc/README.LED_display
 create mode 100644 include/led-display.h

diff --git a/board/mips/boston-riscv/Kconfig b/board/mips/boston-riscv/Kconfig
index 4d55d96603e..5ab89cb5a69 100644
--- a/board/mips/boston-riscv/Kconfig
+++ b/board/mips/boston-riscv/Kconfig
@@ -44,4 +44,8 @@ config TFTP_FILE_NAME_MAX_LEN
     int "Maximum length of TFTP file name"
     default 256
 
+config CMD_DISPLAY
+	bool "Enable display command"
+	default y
+
 endif
diff --git a/board/mips/boston-riscv/MAINTAINERS b/board/mips/boston-riscv/MAINTAINERS
index 0d9a951441f..b04dcde943a 100644
--- a/board/mips/boston-riscv/MAINTAINERS
+++ b/board/mips/boston-riscv/MAINTAINERS
@@ -9,3 +9,6 @@ F:  configs/boston-p8700_defconfig
 F:  arch/riscv/dts/boston-p8700.dts
 F:  drivers/gpio/eg20t-gpio.c
 F:  arch/riscv/lib/mips_gic.c
+F:  cmd/display.c
+F:  include/led-display.h
+F:  doc/README.LED_display
diff --git a/board/mips/boston-riscv/Makefile b/board/mips/boston-riscv/Makefile
index c67c001d4e6..2a180820a74 100644
--- a/board/mips/boston-riscv/Makefile
+++ b/board/mips/boston-riscv/Makefile
@@ -7,3 +7,4 @@ obj-y += checkboard.o
 obj-y += iocu.o
 obj-y += lowlevel_init.o
 obj-y += reset.o
+obj-y += display.o
diff --git a/board/mips/boston-riscv/display.c b/board/mips/boston-riscv/display.c
new file mode 100644
index 00000000000..cd222cb6648
--- /dev/null
+++ b/board/mips/boston-riscv/display.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017 Imagination Technologies
+ *
+ */
+#include <led-display.h>
+#include <asm/io.h>
+#include "boston-lcd.h"
+#include <string.h>
+
+static char buf[8];
+static int pos;
+
+void display_set(int cmd)
+{
+	if (cmd & DISPLAY_CLEAR)
+		memset(buf, ' ', sizeof(buf));
+
+	if (cmd & DISPLAY_HOME)
+		pos = 0;
+
+	lowlevel_display(buf);
+}
+
+int display_putc(char c)
+{
+	if (pos >= 8)
+		return -1;
+
+	buf[pos++] = c;
+	lowlevel_display(buf);
+	return c;
+}
diff --git a/board/mips/boston-riscv/lowlevel_init.S b/board/mips/boston-riscv/lowlevel_init.S
index 8fa85749e40..f65021a0974 100644
--- a/board/mips/boston-riscv/lowlevel_init.S
+++ b/board/mips/boston-riscv/lowlevel_init.S
@@ -15,4 +15,6 @@ msg_ddr_ok:	.ascii "DDR OK  "
 	.globl lowlevel_display
 lowlevel_display:
 	li	t0, BOSTON_LCD_BASE
+	ld	t1, 0(a0)
+	sd	t1, 0(t0)
 	jr	ra
diff --git a/cmd/Kconfig b/cmd/Kconfig
index b3b5be1ea79..298a3ca6ce3 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2319,6 +2319,14 @@ config CMD_CLS
 	  Enable the 'cls' command which clears the screen contents
 	  on video frame buffer.
 
+config CMD_DISPLAY
+	bool "Enable the 'display' command, for character displays"
+	help
+	  (this needs porting to driver model)
+	  This enables the 'display' command which allows a string to be
+	  displayed on a simple board-specific display. Implement
+	  display_putc() to use it.
+
 config CMD_EFIDEBUG
 	bool "efidebug - display/configure UEFI environment"
 	depends on EFI_LOADER
diff --git a/cmd/Makefile b/cmd/Makefile
index 12e948fd1b9..a313ddb1f29 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_CMD_SOUND) += sound.o
 ifdef CONFIG_POST
 obj-$(CONFIG_CMD_DIAG) += diag.o
 endif
+obj-$(CONFIG_CMD_DISPLAY) += display.o
 obj-$(CONFIG_CMD_ADTIMG) += adtimg.o
 obj-$(CONFIG_CMD_ABOOTIMG) += abootimg.o
 obj-$(CONFIG_CMD_CYCLIC) += cyclic.o
diff --git a/cmd/display.c b/cmd/display.c
new file mode 100644
index 00000000000..0602345e6c9
--- /dev/null
+++ b/cmd/display.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2005
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#include <command.h>
+#include <led-display.h>
+
+#undef DEBUG_DISP
+
+int do_display(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
+{
+	int i;
+
+	/* Clear display */
+	display_set(DISPLAY_CLEAR | DISPLAY_HOME);
+
+	if (argc < 2)
+		return (0);
+
+	for (i = 1; i < argc; i++) {
+		char *p = argv[i];
+
+		if (i > 1) { /* Insert a space between strings */
+			display_putc(' ');
+		}
+
+		while ((*p)) {
+#ifdef DEBUG_DISP
+			putc(*p);
+#endif
+			display_putc(*p++);
+		}
+	}
+
+#ifdef DEBUG_DISP
+	putc('\n');
+#endif
+
+	return (0);
+}
+
+/***************************************************/
+
+U_BOOT_CMD(display,	CONFIG_SYS_MAXARGS,	1,	do_display,
+	   "display string on dot matrix display",
+	   "[<string>]\n"
+	   "    - with <string> argument: display <string> on dot matrix display\n"
+	   "    - without arguments: clear dot matrix display"
+);
diff --git a/doc/README.LED_display b/doc/README.LED_display
new file mode 100644
index 00000000000..19977ea7e0d
--- /dev/null
+++ b/doc/README.LED_display
@@ -0,0 +1,26 @@
+LED display internal API
+=======================================
+
+This README describes the LED display API.
+
+The API is defined by the include file include/led-display.h
+
+The first step in to define CONFIG_CMD_DISPLAY in the board config file.
+Then you need to provide the following functions to access LED display:
+
+void display_set(int cmd);
+
+This function should control the state of the LED display. Argument is
+an ORed combination of the following values:
+ DISPLAY_CLEAR	-- clear the display
+ DISPLAY_HOME	-- set the position to the beginning of display
+
+int display_putc(char c);
+
+This function should display it's parameter on the LED display in the
+current position. Returns the displayed character on success or -1 in
+case of failure.
+
+With this functions defined 'display' command will display it's
+arguments on the LED display (or clear the display if called without
+arguments).
diff --git a/include/led-display.h b/include/led-display.h
new file mode 100644
index 00000000000..50830903b0d
--- /dev/null
+++ b/include/led-display.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2005-2010
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2010
+ * Sergei Poselenov, Emcraft Systems, sposelenov@emcraft.com.
+ */
+
+#ifndef _led_display_h_
+#define _led_display_h_
+
+/* Display Commands */
+#define DISPLAY_CLEAR	0x1 /* Clear the display */
+#define DISPLAY_HOME	0x2 /* Set cursor at home position */
+#define DISPLAY_LINE2	0x4 /* Move to line 2 */
+
+void display_set(int cmd);
+int display_putc(char c);
+
+static inline void display_puts(const char *str)
+{
+	while (str[0])
+		display_putc(*str++);
+}
+
+static inline void display_sets(const char *str)
+{
+	display_set(DISPLAY_CLEAR | DISPLAY_HOME);
+	display_puts(str);
+}
+
+#endif
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 11/12] cmd: riscv: Add 'startharts' command to start multiple harts
  2025-07-29 16:21 [PATCH v3 00/12] riscv: Add support for P8700 platform on Boston board Uros Stajic
                   ` (9 preceding siblings ...)
  2025-07-29 16:24 ` [PATCH v3 10/12] riscv: boston: Add support for LED character display command Uros Stajic
@ 2025-07-29 16:25 ` Uros Stajic
  2025-07-29 16:25 ` [PATCH v3 12/12] timer: p8700: Add support for reading time from memory-mapped mtime Uros Stajic
  11 siblings, 0 replies; 20+ messages in thread
From: Uros Stajic @ 2025-07-29 16:25 UTC (permalink / raw)
  To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu, Uros Stajic

From: Chao-ying Fu <cfu@mips.com>

Introduce the 'startharts' command for RISC-V targets, which prints
or executes commands to power up and reset all harts and jump to
0x80000000. The command supports optional cluster/core count and
immediate execution via the 'g' argument.

Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
 arch/riscv/include/asm/arch-p8700/p8700.h |   3 +
 board/mips/boston-riscv/MAINTAINERS       |   1 +
 cmd/Kconfig                               |   6 ++
 cmd/Makefile                              |   1 +
 cmd/start_harts.c                         | 103 ++++++++++++++++++++++
 configs/boston-p8700_defconfig            |   1 +
 6 files changed, 115 insertions(+)
 create mode 100644 cmd/start_harts.c

diff --git a/arch/riscv/include/asm/arch-p8700/p8700.h b/arch/riscv/include/asm/arch-p8700/p8700.h
index 6c47de9a633..20868eee419 100644
--- a/arch/riscv/include/asm/arch-p8700/p8700.h
+++ b/arch/riscv/include/asm/arch-p8700/p8700.h
@@ -77,8 +77,11 @@
 #define CPC_SYS_CONFIG		0x0140
 
 #define CPC_Cx_CMD		0x0000
+#define CPC_Cx_CMD_PWRUP	0x3
 #define CPC_Cx_CMD_RESET	0x4
 
+#define CPC_Cx_VP_RUN		0x0028
+
 /* GCR_CONFIG */
 #define GCR_CONFIG						0x0000
 #define GCR_REV							0x0030
diff --git a/board/mips/boston-riscv/MAINTAINERS b/board/mips/boston-riscv/MAINTAINERS
index b04dcde943a..0e2f4c277d3 100644
--- a/board/mips/boston-riscv/MAINTAINERS
+++ b/board/mips/boston-riscv/MAINTAINERS
@@ -12,3 +12,4 @@ F:  arch/riscv/lib/mips_gic.c
 F:  cmd/display.c
 F:  include/led-display.h
 F:  doc/README.LED_display
+F:  cmd/start_harts.c
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 298a3ca6ce3..d319cfdbf3e 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2327,6 +2327,12 @@ config CMD_DISPLAY
 	  displayed on a simple board-specific display. Implement
 	  display_putc() to use it.
 
+config CMD_START_HARTS
+	bool "Start harts"
+	depends on RISCV
+	help
+	  This prints commands to start all harts and go 0x80000000.
+
 config CMD_EFIDEBUG
 	bool "efidebug - display/configure UEFI environment"
 	depends on EFI_LOADER
diff --git a/cmd/Makefile b/cmd/Makefile
index a313ddb1f29..baec824260f 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_CMD_SOUND) += sound.o
 ifdef CONFIG_POST
 obj-$(CONFIG_CMD_DIAG) += diag.o
 endif
+obj-$(CONFIG_CMD_START_HARTS) += start_harts.o
 obj-$(CONFIG_CMD_DISPLAY) += display.o
 obj-$(CONFIG_CMD_ADTIMG) += adtimg.o
 obj-$(CONFIG_CMD_ABOOTIMG) += abootimg.o
diff --git a/cmd/start_harts.c b/cmd/start_harts.c
new file mode 100644
index 00000000000..0d074778b6d
--- /dev/null
+++ b/cmd/start_harts.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2005
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
+#include <command.h>
+#include <asm/arch-p8700/p8700.h>
+
+int start_harts(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
+{
+	int n_cluster = 1;
+	int n_core = 1;
+	int run = 0;
+	int cl, co;
+	long cmd_reg;
+
+	if (argc > 1 && argv[1][0] > '0' && argv[1][0] <= '9')
+		n_cluster = argv[1][0] - '0';
+	if (argc > 2 && argv[2][0] > '0' && argv[2][0] <= '9')
+		n_core = argv[2][0] - '0';
+	if (argc > 3)
+		run = (argv[3][0] == 'g');
+
+	for (cl = 1; cl < n_cluster; cl++) {
+		cmd_reg = CPC_BASE + (cl << CM_BASE_CLUSTER_SHIFT) +
+					CPC_OFF_LOCAL + CPC_Cx_CMD;
+		printf("# Start cluster %d core 0 hart 0\n", cl);
+		printf("mw.q 0x%lx %d\n", cmd_reg, CPC_Cx_CMD_PWRUP);
+		if (run == 1) {
+			asm volatile("sd %0, 0(%1)"::"r"(CPC_Cx_CMD_PWRUP), "r"(cmd_reg));
+			asm volatile("fence");
+		}
+
+		printf("mw.q 0x%lx %d\n", cmd_reg, CPC_Cx_CMD_RESET);
+		if (run == 1) {
+			asm volatile("sd %0, 0(%1)"::"r"(CPC_Cx_CMD_RESET), "r"(cmd_reg));
+			asm volatile("fence");
+		}
+
+		cmd_reg = CPC_BASE + (cl << CM_BASE_CLUSTER_SHIFT) + CPC_OFF_LOCAL + CPC_Cx_VP_RUN;
+		printf("mw.q 0x%lx 1\n", cmd_reg);
+
+		if (run == 1) {
+			asm volatile("sd %0, 0(%1)"::"r"(1), "r"(cmd_reg));
+			asm volatile("fence");
+		}
+	}
+
+	for (cl = 0; cl < n_cluster; cl++) {
+		for (co = 1; co < n_core; co++) {
+			cmd_reg = CPC_BASE + (cl << CM_BASE_CLUSTER_SHIFT) +
+						(co << CM_BASE_CORE_SHIFT) +
+						CPC_OFF_LOCAL + CPC_Cx_CMD;
+			printf("# Start cluster %d core %d hart 0\n", cl, co);
+			printf("mw.q 0x%lx %d\n", cmd_reg, CPC_Cx_CMD_RESET);
+			if (run == 1) {
+				asm volatile("sd %0, 0(%1)"::"r"(CPC_Cx_CMD_RESET), "r"(cmd_reg));
+				asm volatile("fence");
+			}
+
+			cmd_reg = CPC_BASE + (cl << CM_BASE_CLUSTER_SHIFT) +
+						(co << CM_BASE_CORE_SHIFT) +
+						CPC_OFF_LOCAL + CPC_Cx_VP_RUN;
+			printf("mw.q 0x%lx 1\n", cmd_reg);
+			if (run == 1) {
+				asm volatile("sd %0, 0(%1)"::"r"(1), "r"(cmd_reg));
+				asm volatile("fence");
+			}
+		}
+	}
+
+	for (cl = 0; cl < n_cluster; cl++) {
+		for (co = 0; co < n_core; co++) {
+			printf("# Start cluster %d core %d all harts\n", cl, co);
+			cmd_reg = CPC_BASE + (cl << CM_BASE_CLUSTER_SHIFT) +
+						(co << CM_BASE_CORE_SHIFT) +
+						CPC_OFF_LOCAL + CPC_Cx_VP_RUN;
+			printf("mw.q 0x%lx 0xff\n", cmd_reg);
+			if (run == 1) {
+				asm volatile("sd %0, 0(%1)"::"r"(0xff), "r"(cmd_reg));
+				asm volatile("fence");
+			}
+		}
+	}
+
+	printf("go 0x80000000\n");
+	if (run == 1) {
+		void (*addr)(void) = (void (*)(void))0x80000000;
+		(*addr)();
+	}
+
+	return 0;
+}
+
+/***************************************************/
+
+U_BOOT_CMD(startharts, CONFIG_SYS_MAXARGS, 1, start_harts,
+	   "print commands to start all harts and go 0x80000000",
+	   "[<#clusters:1-9>] [<#cores_per_cluster:1-9>] [g]\n"
+	   "    - print commands to start all harts and go 0x80000000\n"
+	   "      If the 3rd parameter is 'g', execute all comamnds."
+);
diff --git a/configs/boston-p8700_defconfig b/configs/boston-p8700_defconfig
index 3df7ffe50b3..85ed687107e 100644
--- a/configs/boston-p8700_defconfig
+++ b/configs/boston-p8700_defconfig
@@ -72,6 +72,7 @@ CONFIG_OF_EMBED=y
 CONFIG_CPU=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_PCI=y
+CONFIG_CMD_START_HARTS=y
 
 CONFIG_UNIT_TEST=y
 CONFIG_UT_LIB=n
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 12/12] timer: p8700: Add support for reading time from memory-mapped mtime
  2025-07-29 16:21 [PATCH v3 00/12] riscv: Add support for P8700 platform on Boston board Uros Stajic
                   ` (10 preceding siblings ...)
  2025-07-29 16:25 ` [PATCH v3 11/12] cmd: riscv: Add 'startharts' command to start multiple harts Uros Stajic
@ 2025-07-29 16:25 ` Uros Stajic
  2025-07-31  5:57   ` Yao Zi
  11 siblings, 1 reply; 20+ messages in thread
From: Uros Stajic @ 2025-07-29 16:25 UTC (permalink / raw)
  To: u-boot@lists.denx.de; +Cc: Djordje Todorovic, Uros Stajic

The P8700 core does not support reading the time CSR directly and
raises an illegal instruction exception. This patch adds support for
reading the timer value via its memory-mapped address at 0x16108050
when running on a P8700 processor.

Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
---
 drivers/timer/riscv_timer.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/timer/riscv_timer.c b/drivers/timer/riscv_timer.c
index 1f4980ceb38..5138236a028 100644
--- a/drivers/timer/riscv_timer.c
+++ b/drivers/timer/riscv_timer.c
@@ -18,8 +18,15 @@
 #include <timer.h>
 #include <asm/csr.h>
 
+#define P8700_TIMER_ADDR 0x16108050
+
 static u64 notrace riscv_timer_get_count(struct udevice *dev)
 {
+	if (IS_ENABLED(CONFIG_P8700_RISCV)) {
+		u32 *mtime_addr = (u32 *)P8700_TIMER_ADDR;
+		return *mtime_addr;
+	}
+
 	__maybe_unused u32 hi, lo;
 
 	if (IS_ENABLED(CONFIG_64BIT))
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 12/12] timer: p8700: Add support for reading time from memory-mapped mtime
  2025-07-29 16:25 ` [PATCH v3 12/12] timer: p8700: Add support for reading time from memory-mapped mtime Uros Stajic
@ 2025-07-31  5:57   ` Yao Zi
  2025-08-19  7:59     ` Uros Stajic
  0 siblings, 1 reply; 20+ messages in thread
From: Yao Zi @ 2025-07-31  5:57 UTC (permalink / raw)
  To: Uros Stajic, u-boot@lists.denx.de; +Cc: Djordje Todorovic

On Tue, Jul 29, 2025 at 04:25:14PM +0000, Uros Stajic wrote:
> The P8700 core does not support reading the time CSR directly and
> raises an illegal instruction exception. This patch adds support for
> reading the timer value via its memory-mapped address at 0x16108050
> when running on a P8700 processor.
> 
> Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
> ---
>  drivers/timer/riscv_timer.c | 7 +++++++
>  1 file changed, 7 insertions(+)

Sorry that I didn't review v2 further, but

> diff --git a/drivers/timer/riscv_timer.c b/drivers/timer/riscv_timer.c
> index 1f4980ceb38..5138236a028 100644
> --- a/drivers/timer/riscv_timer.c
> +++ b/drivers/timer/riscv_timer.c
> @@ -18,8 +18,15 @@
>  #include <timer.h>
>  #include <asm/csr.h>
>  
> +#define P8700_TIMER_ADDR 0x16108050
> +
>  static u64 notrace riscv_timer_get_count(struct udevice *dev)
>  {
> +	if (IS_ENABLED(CONFIG_P8700_RISCV)) {
> +		u32 *mtime_addr = (u32 *)P8700_TIMER_ADDR;
> +		return *mtime_addr;
> +	}
> +

This introduces platform-specific code to the generic RISC-V
TIME-CSR-based timer driver.

If your platform doesn't implement a TIME CSR in hardware, I suggest
using riscv_aclint_timer.c if the provider of P8700_TIMER is
compatible with the RISC-V ACLINT specification, or just introducing a
new driver otherwise.

Regards,
Yao Zi

>  	__maybe_unused u32 hi, lo;
>  
>  	if (IS_ENABLED(CONFIG_64BIT))
> -- 
> 2.34.1

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 08/12] riscv: p8700: Add software emulation for AMO* instructions
  2025-07-29 16:24 ` [PATCH v3 08/12] riscv: p8700: Add software emulation for AMO* instructions Uros Stajic
@ 2025-08-01  7:54   ` Yao Zi
  2025-08-19  7:47     ` Uros Stajic
  0 siblings, 1 reply; 20+ messages in thread
From: Yao Zi @ 2025-08-01  7:54 UTC (permalink / raw)
  To: Uros Stajic, u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu

On Tue, Jul 29, 2025 at 04:24:17PM +0000, Uros Stajic wrote:
> From: Chao-ying Fu <cfu@mips.com>
> 
> This patch adds software emulation for atomic memory operations (AMO)
> instructions that may not be supported in hardware.
> 
> The `emu-amo.s` file provides assembly implementations of the
> aforementioned operations. Corresponding handler logic is integrated
> into the illegal instruction trap to catch and emulate unsupported
> AMO* instructions at runtime.

The main body of U-Boot is executed by only one CPU, so I don't think
there're chances for atomic instructions; disassembly of a U-Boot binary
built with qemu-riscv64_smode_defconfig confirms the idea: the only four
amo instructions locate in arch/riscv/cpu/start.S for picking the HART
to run U-Boot.

I suggest implementing a LR/SC-based codepath for HART lottery logic in
start.S, and introducing a new Kconfig entry (maybe CONFIG_ISA_ZAMMO) to
represent the availability of Zammo extension. We could use the
alternative path for RISC-V platforms that don't implement Zammo and
disable CONFIG_ISA_ZAAMO, which saves a lot of lines and make the code
cleaner.

Regards,
Yao Zi

> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
> ---
>  arch/riscv/cpu/p8700/Makefile  |   1 +
>  arch/riscv/cpu/p8700/emu-amo.S | 254 ++++++++++++++++++++++++++++
>  arch/riscv/lib/interrupts.c    | 299 +++++++++++++++++++++++++++++++++
>  include/interrupt.h            |  19 +++
>  4 files changed, 573 insertions(+)
>  create mode 100644 arch/riscv/cpu/p8700/emu-amo.S

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 09/12] riscv: p8700: Add Coherence Manager (CM) and IOCU support
  2025-07-29 16:24 ` [PATCH v3 09/12] riscv: p8700: Add Coherence Manager (CM) and IOCU support Uros Stajic
@ 2025-08-01  8:47   ` Yao Zi
  2025-08-19  7:55     ` Uros Stajic
  0 siblings, 1 reply; 20+ messages in thread
From: Yao Zi @ 2025-08-01  8:47 UTC (permalink / raw)
  To: Uros Stajic, u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu

On Tue, Jul 29, 2025 at 04:24:36PM +0000, Uros Stajic wrote:
> From: Chao-ying Fu <cfu@mips.com>
> 
> Add support for Coherence Manager (CM) and IOCU discovery and
> configuration on the P8700 platform.
> 
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
> ---
>  arch/riscv/cpu/p8700/Makefile             |   2 +
>  arch/riscv/cpu/p8700/cache.c              |  10 +++
>  arch/riscv/cpu/p8700/cm-iocu.c            |  75 ++++++++++++++++
>  arch/riscv/cpu/p8700/cm.c                 |  92 +++++++++++++++++++
>  arch/riscv/include/asm/arch-p8700/cm.h    |  61 +++++++++++++
>  arch/riscv/include/asm/arch-p8700/p8700.h |  31 +++++++
>  arch/riscv/include/asm/global_data.h      |   2 +
>  arch/riscv/include/asm/io.h               |  86 ++++++++++++++++++
>  board/mips/boston-riscv/Makefile          |   1 +
>  board/mips/boston-riscv/iocu.c            | 104 ++++++++++++++++++++++
>  10 files changed, 464 insertions(+)
>  create mode 100644 arch/riscv/cpu/p8700/cm-iocu.c
>  create mode 100644 arch/riscv/cpu/p8700/cm.c
>  create mode 100644 arch/riscv/include/asm/arch-p8700/cm.h
>  create mode 100644 board/mips/boston-riscv/iocu.c
> 

...

> diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
> index da165858034..fb79d0a8d32 100644
> --- a/arch/riscv/include/asm/io.h
> +++ b/arch/riscv/include/asm/io.h

These changes don't seem to be related to the commit message. Please
split them into a separate patch (if these are really necessary, see
my comments below).

> @@ -15,6 +15,91 @@ static inline void sync(void)
>  {
>  }
>  
> +/*
> + * Generic virtual read/write.  Note that we don't support half-word
> + * read/writes.  We define __arch_*[bl] here, and leave __arch_*w
> + * to the architecture specific code.
> + */

But you do define half-word operations. This comment looks like the one
removed in d5af15bf515 ("riscv: Clean up asm/io.h"), and seems already
out-of-date.

> +#if CONFIG_P8700_RISCV
> +#ifdef CONFIG_ARCH_MAP_SYSMEM
> +static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)
> +{
> +	if (paddr < PHYS_SDRAM_0_SIZE + PHYS_SDRAM_1_SIZE)
> +		paddr = paddr | 0x40000000;
> +	return (void *)(uintptr_t)paddr;
> +}
> +
> +static inline void *unmap_sysmem(const void *vaddr)
> +{
> +	phys_addr_t paddr = (phys_addr_t)vaddr;
> +
> +	paddr = paddr & ~0x40000000;
> +	return (void *)(uintptr_t)paddr;
> +}
> +
> +static inline phys_addr_t map_to_sysmem(const void *ptr)
> +{
> +	return (phys_addr_t)(uintptr_t)ptr;
> +}
> +#endif
> +
> +static inline unsigned char __arch_getb(const volatile void __iomem *mem)
> +{
> +	unsigned char value;
> +
> +	asm volatile("lbu %0,0(%1)" : "=r"(value) : "r"(mem));
> +
> +	return value;
> +}
> +
> +static inline unsigned short __arch_getw(const volatile void __iomem *mem)
> +{
> +	unsigned short value;
> +
> +	asm volatile("lhu %0,0(%1)" : "=r"(value) : "r"(mem));
> +
> +	return value;
> +}
> +
> +static inline unsigned int __arch_getl(const volatile void __iomem *mem)
> +{
> +	unsigned int value;
> +
> +	asm volatile("lw %0,0(%1)" : "=r"(value) : "r"(mem));
> +
> +	return value;
> +}
> +
> +static inline unsigned long long __arch_getq(const volatile void __iomem *mem)
> +{
> +	unsigned long long value;
> +
> +	asm volatile("ld %0,0(%1)" : "=r"(value) : "r"(mem));
> +
> +	return value;
> +}
> +
> +static inline void __arch_putb(unsigned char value, volatile void __iomem *mem)
> +{
> +	asm volatile("sb %0,0(%1)"::"r"(value), "r"(mem));
> +}
> +
> +static inline void __arch_putw(unsigned short value, volatile void __iomem *mem)
> +{
> +	asm volatile("sh %0,0(%1)"::"r"(value), "r"(mem));
> +}
> +
> +static inline void __arch_putl(unsigned int value, volatile void __iomem *mem)
> +{
> +	asm volatile("sw %0,0(%1)"::"r"(value), "r"(mem));
> +}
> +
> +static inline void __arch_putq(unsigned int value, volatile void __iomem *mem)
> +{
> +	asm volatile("sd %0,0(%1)"::"r"(value), "r"(mem));
> +}

I don't see any reason not to use the generic macros for P8700, these
inline assembly should basically behave the same as the C-version below.
Could you please explain it futher?

Thanks,
Yao Zi

> +#else
>  #define __arch_getb(a)			(*(volatile unsigned char *)(a))
>  #define __arch_getw(a)			(*(volatile unsigned short *)(a))
>  #define __arch_getl(a)			(*(volatile unsigned int *)(a))
> @@ -24,6 +109,7 @@ static inline void sync(void)
>  #define __arch_putw(v, a)		(*(volatile unsigned short *)(a) = (v))
>  #define __arch_putl(v, a)		(*(volatile unsigned int *)(a) = (v))
>  #define __arch_putq(v, a)		(*(volatile unsigned long long *)(a) = (v))
> +#endif
>  
>  #define __raw_writeb(v, a)		__arch_putb(v, a)
>  #define __raw_writew(v, a)		__arch_putw(v, a)
> +}

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 03/12] gpio: Add GPIO driver for Intel EG20T
  2025-07-29 16:22 ` [PATCH v3 03/12] gpio: Add GPIO driver for Intel EG20T Uros Stajic
@ 2025-08-01  8:51   ` Yao Zi
  0 siblings, 0 replies; 20+ messages in thread
From: Yao Zi @ 2025-08-01  8:51 UTC (permalink / raw)
  To: Uros Stajic, u-boot@lists.denx.de; +Cc: Djordje Todorovic, Chao-ying Fu

On Tue, Jul 29, 2025 at 04:22:43PM +0000, Uros Stajic wrote:
> From: Chao-ying Fu <cfu@mips.com>
> 
> Add a GPIO driver for the Intel EG20T Platform Controller Hub, which
> exposes a set of 12 GPIOs via PCI MMIO.
> 
> The driver implements basic GPIO operations (input/output direction,
> value read/write, and function query) using the U-Boot driver model
> infrastructure. It maps the required BAR1 region via `dm_pci_map_bar`
> and uses internal registers to control pin state and direction.
> 
> This driver is required for platforms using EG20T, such as P8700-based
> systems, to access GPIOs through the standard U-Boot DM GPIO framework.
> 
> Signed-off-by: Chao-ying Fu <cfu@mips.com>
> Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
> ---
>  board/mips/boston-riscv/MAINTAINERS |   1 +
>  drivers/gpio/Kconfig                |   7 ++
>  drivers/gpio/Makefile               |   1 +
>  drivers/gpio/eg20t-gpio.c           | 138 ++++++++++++++++++++++++++++
>  4 files changed, 147 insertions(+)
>  create mode 100644 drivers/gpio/eg20t-gpio.c
> 
> diff --git a/board/mips/boston-riscv/MAINTAINERS b/board/mips/boston-riscv/MAINTAINERS
> index e350121395e..bc59a628c79 100644
> --- a/board/mips/boston-riscv/MAINTAINERS
> +++ b/board/mips/boston-riscv/MAINTAINERS
> @@ -7,3 +7,4 @@ F:  arch/riscv/cpu/p8700/
>  F:  arch/riscv/include/asm/arch-p8700/
>  F:  configs/boston-p8700_defconfig
>  F:  arch/riscv/dts/boston-p8700.dts
> +F:  drivers/gpio/eg20t-gpio.c
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 58e464106a3..26040947a69 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -726,3 +726,10 @@ config MPFS_GPIO
>  		Enable to support the GPIO driver on Polarfire SoC
>  
>  endif
> +
> +config EG20T_GPIO
> +        bool "Intel EG20T GPIO driver"
> +        depends on DM_GPIO && DM_PCI
> +        help
> +          Enable this to support the GPIO controller found in the Intel EG20T
> +          Platform Controller Hub.
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index 83e10c79b91..e44122cb9aa 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -81,3 +81,4 @@ obj-$(CONFIG_FTGPIO010)		+= ftgpio010.o
>  obj-$(CONFIG_$(PHASE_)ADP5585_GPIO)	+= adp5585_gpio.o
>  obj-$(CONFIG_RZG2L_GPIO)	+= rzg2l-gpio.o
>  obj-$(CONFIG_MPFS_GPIO)	+= mpfs_gpio.o
> +obj-$(CONFIG_EG20T_GPIO)	+= eg20t-gpio.o
> diff --git a/drivers/gpio/eg20t-gpio.c b/drivers/gpio/eg20t-gpio.c
> new file mode 100644
> index 00000000000..d41ca4bfb17
> --- /dev/null
> +++ b/drivers/gpio/eg20t-gpio.c
> @@ -0,0 +1,138 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2016 Imagination Technologies
> + */
> +
> +#include <dm.h>
> +#include <errno.h>
> +#include <pci.h>
> +#include <asm/io.h>
> +#include <asm/gpio.h>
> +#include <log.h>
> +
> +enum {
> +	REG_IEN		= 0x00,
> +	REG_ISTATUS	= 0x04,
> +	REG_IDISP	= 0x08,
> +	REG_ICLR	= 0x0c,
> +	REG_IMASK	= 0x10,
> +	REG_IMASKCLR	= 0x14,
> +	REG_PO		= 0x18,
> +	REG_PI		= 0x1c,
> +	REG_PM		= 0x20,
> +};
> +
> +struct eg20t_gpio_priv {
> +	void *base;
> +};
> +
> +static int eg20t_gpio_get_value(struct udevice *dev, unsigned int offset)
> +{
> +	struct eg20t_gpio_priv *priv = dev_get_priv(dev);
> +	u32 pm, pval;
> +
> +	pm = readl(priv->base + REG_PM);
> +	if ((pm >> offset) & 0x1)
> +		pval = readl(priv->base + REG_PO);
> +	else
> +		pval = readl(priv->base + REG_PI);
> +
> +	return (pval >> offset) & 0x1;
> +}
> +
> +static int eg20t_gpio_set_value(struct udevice *dev, unsigned int offset,
> +				int value)
> +{
> +	struct eg20t_gpio_priv *priv = dev_get_priv(dev);
> +	u32 po;
> +
> +	po = readl(priv->base + REG_PO);
> +	if (value)
> +		po |= 1 << offset;
> +	else
> +		po &= ~(1 << offset);
> +	writel(po, priv->base + REG_PO);
> +	return 0;
> +}

This file contains inconsistent usage of empty lines between statements
and the final return among functions. I think it's better to keep the
style aligned.

Regards,
Yao Zi

> +
> +static int eg20t_gpio_direction_input(struct udevice *dev, unsigned int offset)
> +{
> +	struct eg20t_gpio_priv *priv = dev_get_priv(dev);
> +	u32 pm;
> +
> +	pm = readl(priv->base + REG_PM);
> +	pm &= ~(1 << offset);
> +	writel(pm, priv->base + REG_PM);
> +	return 0;
> +}
> +
> +static int eg20t_gpio_direction_output(struct udevice *dev, unsigned int offset,
> +				       int value)
> +{
> +	struct eg20t_gpio_priv *priv = dev_get_priv(dev);
> +	u32 pm;
> +
> +	pm = readl(priv->base + REG_PM);
> +	pm |= 1 << offset;
> +	writel(pm, priv->base + REG_PM);
> +
> +	return eg20t_gpio_set_value(dev, offset, value);
> +}
> +
> +static int eg20t_gpio_get_function(struct udevice *dev, unsigned int offset)
> +{
> +	struct eg20t_gpio_priv *priv = dev_get_priv(dev);
> +	u32 pm;
> +
> +	pm = readl(priv->base + REG_PM);
> +
> +	if ((pm >> offset) & 0x1)
> +		return GPIOF_OUTPUT;
> +
> +	return GPIOF_INPUT;
> +}
> +
> +static const struct dm_gpio_ops eg20t_gpio_ops = {
> +	.direction_input	= eg20t_gpio_direction_input,
> +	.direction_output	= eg20t_gpio_direction_output,
> +	.get_value		= eg20t_gpio_get_value,
> +	.set_value		= eg20t_gpio_set_value,
> +	.get_function		= eg20t_gpio_get_function,
> +};
> +
> +static int eg20t_gpio_probe(struct udevice *dev)
> +{
> +	struct eg20t_gpio_priv *priv = dev_get_priv(dev);
> +	struct gpio_dev_priv *uc_priv = dev->uclass_priv;
> +
> +	priv->base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_1, PCI_REGION_MEM);
> +	if (!priv->base) {
> +		debug("failed to map GPIO registers\n");
> +		return -EINVAL;
> +	}
> +
> +	uc_priv->gpio_count = 12;
> +	uc_priv->bank_name = "eg20t";
> +	return 0;
> +}
> +
> +static const struct udevice_id eg20t_gpio_ids[] = {
> +	{ .compatible = "intel,eg20t-gpio" },
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(eg20t_gpio) = {
> +	.name	= "eg20t-gpio",
> +	.id	= UCLASS_GPIO,
> +	.of_match = eg20t_gpio_ids,
> +	.probe	= eg20t_gpio_probe,
> +	.priv_auto_alloc_size = sizeof(struct eg20t_gpio_priv),
> +	.ops	= &eg20t_gpio_ops,
> +};
> +
> +static struct pci_device_id eg20t_gpio_supported[] = {
> +	{ PCI_VENDOR_ID_INTEL, 0x8803 },
> +	{ },
> +};
> +
> +U_BOOT_PCI_DEVICE(eg20t_gpio, eg20t_gpio_supported);
> -- 
> 2.34.1

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 08/12] riscv: p8700: Add software emulation for AMO* instructions
  2025-08-01  7:54   ` Yao Zi
@ 2025-08-19  7:47     ` Uros Stajic
  0 siblings, 0 replies; 20+ messages in thread
From: Uros Stajic @ 2025-08-19  7:47 UTC (permalink / raw)
  To: Yao Zi; +Cc: u-boot@lists.denx.de



On 1. 8. 25. 09:54, Yao Zi wrote:
> [Some people who received this message don't often get email from ziyao@disroot.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> 
> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
> 
> 
> On Tue, Jul 29, 2025 at 04:24:17PM +0000, Uros Stajic wrote:
>> From: Chao-ying Fu <cfu@mips.com>
>>
>> This patch adds software emulation for atomic memory operations (AMO)
>> instructions that may not be supported in hardware.
>>
>> The `emu-amo.s` file provides assembly implementations of the
>> aforementioned operations. Corresponding handler logic is integrated
>> into the illegal instruction trap to catch and emulate unsupported
>> AMO* instructions at runtime.
> 
> The main body of U-Boot is executed by only one CPU, so I don't think
> there're chances for atomic instructions; disassembly of a U-Boot binary
> built with qemu-riscv64_smode_defconfig confirms the idea: the only four
> amo instructions locate in arch/riscv/cpu/start.S for picking the HART
> to run U-Boot.
> 
> I suggest implementing a LR/SC-based codepath for HART lottery logic in
> start.S, and introducing a new Kconfig entry (maybe CONFIG_ISA_ZAMMO) to
> represent the availability of Zammo extension. We could use the
> alternative path for RISC-V platforms that don't implement Zammo and
> disable CONFIG_ISA_ZAAMO, which saves a lot of lines and make the code
> cleaner.
> 
> Regards,
> Yao Zi
> 
>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>> Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
>> ---
>>   arch/riscv/cpu/p8700/Makefile  |   1 +
>>   arch/riscv/cpu/p8700/emu-amo.S | 254 ++++++++++++++++++++++++++++
>>   arch/riscv/lib/interrupts.c    | 299 +++++++++++++++++++++++++++++++++
>>   include/interrupt.h            |  19 +++
>>   4 files changed, 573 insertions(+)
>>   create mode 100644 arch/riscv/cpu/p8700/emu-amo.S

Thank you for your suggestions! We decided to park this patch for now,
since we no longer have AMO instructions in our OpenSBI. We may
consider upstreaming this later.

Regards,
Uros

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 09/12] riscv: p8700: Add Coherence Manager (CM) and IOCU support
  2025-08-01  8:47   ` Yao Zi
@ 2025-08-19  7:55     ` Uros Stajic
  0 siblings, 0 replies; 20+ messages in thread
From: Uros Stajic @ 2025-08-19  7:55 UTC (permalink / raw)
  To: Yao Zi; +Cc: u-boot@lists.denx.de



On 1. 8. 25. 10:47, Yao Zi wrote:
> [Some people who received this message don't often get email from ziyao@disroot.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> 
> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
> 
> 
> On Tue, Jul 29, 2025 at 04:24:36PM +0000, Uros Stajic wrote:
>> From: Chao-ying Fu <cfu@mips.com>
>>
>> Add support for Coherence Manager (CM) and IOCU discovery and
>> configuration on the P8700 platform.
>>
>> Signed-off-by: Chao-ying Fu <cfu@mips.com>
>> Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
>> ---
>>   arch/riscv/cpu/p8700/Makefile             |   2 +
>>   arch/riscv/cpu/p8700/cache.c              |  10 +++
>>   arch/riscv/cpu/p8700/cm-iocu.c            |  75 ++++++++++++++++
>>   arch/riscv/cpu/p8700/cm.c                 |  92 +++++++++++++++++++
>>   arch/riscv/include/asm/arch-p8700/cm.h    |  61 +++++++++++++
>>   arch/riscv/include/asm/arch-p8700/p8700.h |  31 +++++++
>>   arch/riscv/include/asm/global_data.h      |   2 +
>>   arch/riscv/include/asm/io.h               |  86 ++++++++++++++++++
>>   board/mips/boston-riscv/Makefile          |   1 +
>>   board/mips/boston-riscv/iocu.c            | 104 ++++++++++++++++++++++
>>   10 files changed, 464 insertions(+)
>>   create mode 100644 arch/riscv/cpu/p8700/cm-iocu.c
>>   create mode 100644 arch/riscv/cpu/p8700/cm.c
>>   create mode 100644 arch/riscv/include/asm/arch-p8700/cm.h
>>   create mode 100644 board/mips/boston-riscv/iocu.c
>>
> 
> ...
> 
>> diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
>> index da165858034..fb79d0a8d32 100644
>> --- a/arch/riscv/include/asm/io.h
>> +++ b/arch/riscv/include/asm/io.h
> 
> These changes don't seem to be related to the commit message. Please
> split them into a separate patch (if these are really necessary, see
> my comments below).
> 
>> @@ -15,6 +15,91 @@ static inline void sync(void)
>>   {
>>   }
>>
>> +/*
>> + * Generic virtual read/write.  Note that we don't support half-word
>> + * read/writes.  We define __arch_*[bl] here, and leave __arch_*w
>> + * to the architecture specific code.
>> + */
> 
> But you do define half-word operations. This comment looks like the one
> removed in d5af15bf515 ("riscv: Clean up asm/io.h"), and seems already
> out-of-date.
> 
>> +#if CONFIG_P8700_RISCV
>> +#ifdef CONFIG_ARCH_MAP_SYSMEM
>> +static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)
>> +{
>> +     if (paddr < PHYS_SDRAM_0_SIZE + PHYS_SDRAM_1_SIZE)
>> +             paddr = paddr | 0x40000000;
>> +     return (void *)(uintptr_t)paddr;
>> +}
>> +
>> +static inline void *unmap_sysmem(const void *vaddr)
>> +{
>> +     phys_addr_t paddr = (phys_addr_t)vaddr;
>> +
>> +     paddr = paddr & ~0x40000000;
>> +     return (void *)(uintptr_t)paddr;
>> +}
>> +
>> +static inline phys_addr_t map_to_sysmem(const void *ptr)
>> +{
>> +     return (phys_addr_t)(uintptr_t)ptr;
>> +}
>> +#endif
>> +
>> +static inline unsigned char __arch_getb(const volatile void __iomem *mem)
>> +{
>> +     unsigned char value;
>> +
>> +     asm volatile("lbu %0,0(%1)" : "=r"(value) : "r"(mem));
>> +
>> +     return value;
>> +}
>> +
>> +static inline unsigned short __arch_getw(const volatile void __iomem *mem)
>> +{
>> +     unsigned short value;
>> +
>> +     asm volatile("lhu %0,0(%1)" : "=r"(value) : "r"(mem));
>> +
>> +     return value;
>> +}
>> +
>> +static inline unsigned int __arch_getl(const volatile void __iomem *mem)
>> +{
>> +     unsigned int value;
>> +
>> +     asm volatile("lw %0,0(%1)" : "=r"(value) : "r"(mem));
>> +
>> +     return value;
>> +}
>> +
>> +static inline unsigned long long __arch_getq(const volatile void __iomem *mem)
>> +{
>> +     unsigned long long value;
>> +
>> +     asm volatile("ld %0,0(%1)" : "=r"(value) : "r"(mem));
>> +
>> +     return value;
>> +}
>> +
>> +static inline void __arch_putb(unsigned char value, volatile void __iomem *mem)
>> +{
>> +     asm volatile("sb %0,0(%1)"::"r"(value), "r"(mem));
>> +}
>> +
>> +static inline void __arch_putw(unsigned short value, volatile void __iomem *mem)
>> +{
>> +     asm volatile("sh %0,0(%1)"::"r"(value), "r"(mem));
>> +}
>> +
>> +static inline void __arch_putl(unsigned int value, volatile void __iomem *mem)
>> +{
>> +     asm volatile("sw %0,0(%1)"::"r"(value), "r"(mem));
>> +}
>> +
>> +static inline void __arch_putq(unsigned int value, volatile void __iomem *mem)
>> +{
>> +     asm volatile("sd %0,0(%1)"::"r"(value), "r"(mem));
>> +}
> 
> I don't see any reason not to use the generic macros for P8700, these
> inline assembly should basically behave the same as the C-version below.
> Could you please explain it futher?
> 
> Thanks,
> Yao Zi
> 
>> +#else
>>   #define __arch_getb(a)                       (*(volatile unsigned char *)(a))
>>   #define __arch_getw(a)                       (*(volatile unsigned short *)(a))
>>   #define __arch_getl(a)                       (*(volatile unsigned int *)(a))
>> @@ -24,6 +109,7 @@ static inline void sync(void)
>>   #define __arch_putw(v, a)            (*(volatile unsigned short *)(a) = (v))
>>   #define __arch_putl(v, a)            (*(volatile unsigned int *)(a) = (v))
>>   #define __arch_putq(v, a)            (*(volatile unsigned long long *)(a) = (v))
>> +#endif
>>
>>   #define __raw_writeb(v, a)           __arch_putb(v, a)
>>   #define __raw_writew(v, a)           __arch_putw(v, a)
>> +}

Thank you for the feedback! After review, the use of generic macros
already provides equivalent behavior, which makes the inline assembly
versions redundant.

The patch will be updated to adopt the generic implementation
in the next revision.

Regards,
Uros

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 12/12] timer: p8700: Add support for reading time from memory-mapped mtime
  2025-07-31  5:57   ` Yao Zi
@ 2025-08-19  7:59     ` Uros Stajic
  0 siblings, 0 replies; 20+ messages in thread
From: Uros Stajic @ 2025-08-19  7:59 UTC (permalink / raw)
  To: Yao Zi; +Cc: u-boot@lists.denx.de



On 31. 7. 25. 07:57, Yao Zi wrote:
> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
> 
> 
> On Tue, Jul 29, 2025 at 04:25:14PM +0000, Uros Stajic wrote:
>> The P8700 core does not support reading the time CSR directly and
>> raises an illegal instruction exception. This patch adds support for
>> reading the timer value via its memory-mapped address at 0x16108050
>> when running on a P8700 processor.
>>
>> Signed-off-by: Uros Stajic <uros.stajic@htecgroup.com>
>> ---
>>   drivers/timer/riscv_timer.c | 7 +++++++
>>   1 file changed, 7 insertions(+)
> 
> Sorry that I didn't review v2 further, but
> 
>> diff --git a/drivers/timer/riscv_timer.c b/drivers/timer/riscv_timer.c
>> index 1f4980ceb38..5138236a028 100644
>> --- a/drivers/timer/riscv_timer.c
>> +++ b/drivers/timer/riscv_timer.c
>> @@ -18,8 +18,15 @@
>>   #include <timer.h>
>>   #include <asm/csr.h>
>>
>> +#define P8700_TIMER_ADDR 0x16108050
>> +
>>   static u64 notrace riscv_timer_get_count(struct udevice *dev)
>>   {
>> +     if (IS_ENABLED(CONFIG_P8700_RISCV)) {
>> +             u32 *mtime_addr = (u32 *)P8700_TIMER_ADDR;
>> +             return *mtime_addr;
>> +     }
>> +
> 
> This introduces platform-specific code to the generic RISC-V
> TIME-CSR-based timer driver.
> 
> If your platform doesn't implement a TIME CSR in hardware, I suggest
> using riscv_aclint_timer.c if the provider of P8700_TIMER is
> compatible with the RISC-V ACLINT specification, or just introducing a
> new driver otherwise.
> 
> Regards,
> Yao Zi
> 
>>        __maybe_unused u32 hi, lo;
>>
>>        if (IS_ENABLED(CONFIG_64BIT))
>> --
>> 2.34.1

Thank you for the review and suggestion! I was able to resolve the
issue by using riscv_aclint_timer, and the updated changes will be
included in v4.

Regards,
Uros

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2025-08-19  9:52 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-29 16:21 [PATCH v3 00/12] riscv: Add support for P8700 platform on Boston board Uros Stajic
2025-07-29 16:22 ` [PATCH v3 01/12] riscv: Add initial support for P8700 SoC Uros Stajic
2025-07-29 16:22 ` [PATCH v3 02/12] board: boston-riscv: Add initial support for P8700 Boston board Uros Stajic
2025-07-29 16:22 ` [PATCH v3 03/12] gpio: Add GPIO driver for Intel EG20T Uros Stajic
2025-08-01  8:51   ` Yao Zi
2025-07-29 16:23 ` [PATCH v3 04/12] pci: xilinx: Avoid writing memory base/limit for root bridge Uros Stajic
2025-07-29 16:23 ` [PATCH v3 05/12] riscv: Add support for MIPS GIC syscon on RISC-V SoCs Uros Stajic
2025-07-29 16:23 ` [PATCH v3 06/12] net: pch_gbe: Add PHY reset and MAC address fallback for RISC-V Uros Stajic
2025-07-29 16:24 ` [PATCH v3 07/12] libfdt: Allow non-64b aligned memreserve entries Uros Stajic
2025-07-29 16:24 ` [PATCH v3 08/12] riscv: p8700: Add software emulation for AMO* instructions Uros Stajic
2025-08-01  7:54   ` Yao Zi
2025-08-19  7:47     ` Uros Stajic
2025-07-29 16:24 ` [PATCH v3 09/12] riscv: p8700: Add Coherence Manager (CM) and IOCU support Uros Stajic
2025-08-01  8:47   ` Yao Zi
2025-08-19  7:55     ` Uros Stajic
2025-07-29 16:24 ` [PATCH v3 10/12] riscv: boston: Add support for LED character display command Uros Stajic
2025-07-29 16:25 ` [PATCH v3 11/12] cmd: riscv: Add 'startharts' command to start multiple harts Uros Stajic
2025-07-29 16:25 ` [PATCH v3 12/12] timer: p8700: Add support for reading time from memory-mapped mtime Uros Stajic
2025-07-31  5:57   ` Yao Zi
2025-08-19  7:59     ` Uros Stajic

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.