Port-arm archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Raspberry Pi 4 support on 32 bit earmv7hf GENERIC kernel



On 19/03/2026 22:52, Izumi Tsutsui wrote:
Hi,

Currentl NetBSD/evbarm-earmv7hf GENERIC doesn't work on Raspberry Pi 4B:


Seems strange, but "OK"...

Part of me thinks this is unecessary as it unnecessarily bloats GENERIC
for 32bit platforms.

---
[   1.0000000] NetBSD/evbarm (fdt) booting ...
[   1.0000000] [ Kernel symbol table missing! ]
[   1.0000000] Fatal kernel mode prefetch abort at 0x00000000
[   1.0000000] trapframe: 0x80b73ee8, spsr=600001d3
[   1.0000000] r0 =00000000, r1 =f4000000, r2 =0000009c, r3 =01000380
[   1.0000000] r4 =00000000, r5 =807a0484, r6 =00000001, r7 =80a4b180
[   1.0000000] r8 =807a0470, r9 =805baab8, r10=807a0484, r11=80b73f54
[   1.0000000] r12=7f000000, ssp=80b73f38, slr=80011170, pc =00000000

Stopped in pid 0.0 (system) at  0:      address 0x0 is invalid
adchis  r3, r7, r4, lsr #26
db{0}>
---

There are more several issue around Pi4 / BCM2711 support,
but with the following changes NetBSD/evbarm-earmv7hf GENERIC
works on my Raspberry Pi 4B:
  https://github.com/tsutsui/netbsd-src/compare/trunk...tsutsui:netbsd-src:rpi4-earmv7hf
  (diffs are also attached)
  https://dmesgd.nycbug.org/index.cgi?do=view&id=8861

The problems are:

(0) simplefb(4) property values on Pi 4 (as aarch64):
      https://mail-index.netbsd.org/port-arm/2026/03/19/msg009556.html

(1) On 32 bit kernels BCM2711 specific bus_space initialization
     is necessary in sys/arch/arm/broadcom/bcm283x_platform.c
     (not sure if it's okay to use "/" (root) properties)

(2) There are uint32_t integer overflow in arm32/bus_dma.c
     triggered by BCM2711 DMA range values
(3) Corex-A72 VFP ID is not handled in sys/arch/arm/vfp/vfp_init.c

(4) genet(4) (and brgphy(4)) is not in GENERIC and
     sys/dev/ic/bcmgenet.c doesn't build on ILP32

Note xhci(4) on PCIe on Pi 4 will never work on 32 bit kernels
because PA of PCIe is outside 4GB range (around 0x600000000)
  https://forums.raspberrypi.com/viewtopic.php?t=251632

and I'm afread NetBSD/arm32 kernels will never support LPAE.
(It looks 32 bit Raspberry Pi OS supports LPAE though)

dwctwo(4) USB controller is still available on Pi 4 and
it's conntected to USB-C power connector, so we can still
use USB keyboard via Type-C to Type-A OTG cable with power
splitter etc.

If there is no objection, I'd like to commit (1)-(4) fixes first.

---
diff --git a/sys/arch/arm/arm32/bus_dma.c b/sys/arch/arm/arm32/bus_dma.c
index c41fb1e1a065..a6d693a4dae5 100644
--- a/sys/arch/arm/arm32/bus_dma.c
+++ b/sys/arch/arm/arm32/bus_dma.c
@@ -160,7 +160,7 @@ _bus_dma_paddr_inrange(struct arm32_dma_range *ranges, int nranges,
for (i = 0, dr = ranges; i < nranges; i++, dr++) {
  		if (pa >= dr->dr_sysbase &&
-		    pa < dr->dr_sysbase + dr->dr_len)
+		    pa - dr->dr_sysbase < dr->dr_len)
  			return dr;
  	}
@@ -180,11 +180,11 @@ _bus_dma_busaddr_to_paddr(bus_dma_tag_t t, bus_addr_t curaddr)
  		return curaddr;
for (i = 0, dr = t->_ranges; i < t->_nranges; i++, dr++) {
-		if (dr->dr_busbase <= curaddr
-		    && curaddr < dr->dr_busbase + dr->dr_len)
+		if (curaddr >= dr->dr_busbase &&
+		    curaddr - dr->dr_busbase < dr->dr_len)
  			return curaddr - dr->dr_busbase + dr->dr_sysbase;
  	}
-	panic("%s: curaddr %#" PRIxBUSADDR "not in range", __func__, curaddr);
+	panic("%s: curaddr %#" PRIxBUSADDR " not in range", __func__, curaddr);
  }

Why do you think this is needed?



  /*
diff --git a/sys/arch/arm/broadcom/bcm283x_platform.c b/sys/arch/arm/broadcom/bcm283x_platform.c
index 8751d3af1236..3066b4eeaf26 100644
--- a/sys/arch/arm/broadcom/bcm283x_platform.c
+++ b/sys/arch/arm/broadcom/bcm283x_platform.c
@@ -74,6 +74,8 @@ __KERNEL_RCSID(0, "$NetBSD: bcm283x_platform.c,v 1.54 2026/01/08 00:51:20 christ
#include <libfdt.h> +#include <dev/ofw/openfirm.h>
+
  #include <arm/broadcom/bcm2835reg.h>
  #include <arm/broadcom/bcm2835var.h>
  #include <arm/broadcom/bcm283x_platform.h>
@@ -856,12 +858,42 @@ bcm2711_bootparams(void)
  }
#if defined(MULTIPROCESSOR)
+static bool
+bcm283x_is_2711(void)
+{
+	static const struct device_compatible_entry compat_data[] = {
+		{ .compat = "brcm,bcm2711" },
+		DEVICE_COMPAT_EOL
+	};
+	const int root = OF_finddevice("/");
+
+	if (root < 0) {
+		return false;
+	}
+
+	if (of_compatible_match(root, compat_data) > 0) {
+		return true;
+	}
+
+	return false;
+}
+
  static int
  cpu_enable_bcm2836(int phandle)
  {
-	bus_space_tag_t iot = &bcm2836_bs_tag;
-	bus_space_handle_t ioh = BCM2836_ARM_LOCAL_VBASE;
+	bus_space_tag_t iot;
+	bus_space_handle_t ioh;
  	uint64_t mpidr;
+	bool is2711;
+
+	is2711 = bcm283x_is_2711();
+	if (is2711) {
+		iot = &bcm2711_bs_tag;
+		ioh = BCM2711_ARM_LOCAL_VBASE;
+	} else {
+		iot = &bcm2836_bs_tag;
+		ioh = BCM2836_ARM_LOCAL_VBASE;
+	}
fdtbus_get_reg64(phandle, 0, &mpidr, NULL);


This seems completely wrong.

Perhaps the DTS need patching with

bcm2711.dtsi:           enable-method = "brcm,bcm2836-smp"; // for ARM 32-bit

s/brcm,bcm2836-smp/brcm,bcm2711-smp/

diff --git a/sys/arch/arm/fdt/arm_simplefb.c b/sys/arch/arm/fdt/arm_simplefb.c
index 23f17ecd1730..cc8f213e6523 100644
--- a/sys/arch/arm/fdt/arm_simplefb.c
+++ b/sys/arch/arm/fdt/arm_simplefb.c
@@ -213,7 +213,8 @@ arm_simplefb_preattach(void)
  		return;
if (strcmp(format, "a8b8g8r8") == 0 ||
-	    strcmp(format, "x8r8g8b8") == 0) {
+	    strcmp(format, "x8r8g8b8") == 0 ||
+	    strcmp(format, "a8r8g8b8") == 0) {
  		depth = 32;
  	} else if (strcmp(format, "r8g8b8a8") == 0 ||
  		   strcmp(format, "b8g8r8x8") == 0) {


Seems ok.

diff --git a/sys/arch/arm/include/vfpreg.h b/sys/arch/arm/include/vfpreg.h
index bf7a015b8969..ac156e252edc 100644
--- a/sys/arch/arm/include/vfpreg.h
+++ b/sys/arch/arm/include/vfpreg.h
@@ -69,6 +69,7 @@
  #define FPU_VFP_CORTEXA17	0x410330e0
  #define FPU_VFP_CORTEXA53	0x41034030
  #define FPU_VFP_CORTEXA57	0x41034070
+#define FPU_VFP_CORTEXA72	0x41034080
  #define FPU_VFP_MV88SV58XX	0x56022090
#define VFP_FPEXC_EX 0x80000000 /* EXception status bit */
diff --git a/sys/arch/arm/vfp/vfp_init.c b/sys/arch/arm/vfp/vfp_init.c
index 29955c6eacf1..5e0e5bca8db4 100644
--- a/sys/arch/arm/vfp/vfp_init.c
+++ b/sys/arch/arm/vfp/vfp_init.c
@@ -115,6 +115,7 @@ load_vfpregs(const struct vfpreg *fregs)
  	case FPU_VFP_CORTEXA15_QEMU:
  	case FPU_VFP_CORTEXA53:
  	case FPU_VFP_CORTEXA57:
+	case FPU_VFP_CORTEXA72:
  #endif
  		load_vfpregs_hi(fregs->vfp_regs);
  #ifdef CPU_ARM11
@@ -139,6 +140,7 @@ save_vfpregs(struct vfpreg *fregs)
  	case FPU_VFP_CORTEXA15_QEMU:
  	case FPU_VFP_CORTEXA53:
  	case FPU_VFP_CORTEXA57:
+	case FPU_VFP_CORTEXA72:
  #endif
  		save_vfpregs_hi(fregs->vfp_regs);
  #ifdef CPU_ARM11
@@ -322,6 +324,7 @@ vfp_attach(struct cpu_info *ci)
  	case FPU_VFP_CORTEXA17:
  	case FPU_VFP_CORTEXA53:
  	case FPU_VFP_CORTEXA57:
+	case FPU_VFP_CORTEXA72:
  		if (armreg_cpacr_read() & CPACR_V7_ASEDIS) {
  			model = "VFP 4.0+";
  		} else {

OK

diff --git a/sys/arch/evbarm/conf/GENERIC b/sys/arch/evbarm/conf/GENERIC
index d7a63937f19b..d38fcf574048 100644
--- a/sys/arch/evbarm/conf/GENERIC
+++ b/sys/arch/evbarm/conf/GENERIC
@@ -324,6 +324,7 @@ cemac* 		at fdt?			# Cadence EMAC/GEM ethernet controller
  cpsw*		at fdt?			# TI CPSW 3-port Ethernet Switch
  emac* 		at fdt?			# Allwinner Fast/Gigabit Ethernet (EMAC)
  enet*		at fdt?			# i.MX FEC
+genet*		at fdt?			# Broadcom GENET v5
  smsh* 		at fdt?			# SMSC LAN9118
# PCI Ethernet
@@ -331,6 +332,7 @@ re* 		at pci? dev ? function ?	# Realtek RTL8111GS
# MII/PHY support
  atphy* 		at mii? phy ?		# Attansic/Atheros PHYs
+brgphy* 	at mii? phy ?		# Broadcom BCM5400-family PHYs
  exphy* 		at mii? phy ?		# 3Com internal PHYs
  gentbi* 	at mii? phy ?		# Generic Ten-Bit 1000BASE-[CLS]X PHYs
  glxtphy* 	at mii? phy ?		# Level One LXT-1000 PHYs
diff --git a/sys/dev/fdt/fdtbus.c b/sys/dev/fdt/fdtbus.c
index e557b0c6479a..fc244ef1e88a 100644
--- a/sys/dev/fdt/fdtbus.c
+++ b/sys/dev/fdt/fdtbus.c
@@ -90,6 +90,7 @@ static void	fdt_post_attach(struct fdt_node *);
  static const struct device_compatible_entry compat_data[] = {
  	{ .compat = "simple-bus" },
  	{ .compat = "simple-pm-bus" },
+	{ .compat = "simple_bus" },
  	DEVICE_COMPAT_EOL
  };

Are you using vendor DTS? Please don't.


diff --git a/sys/dev/fdt/simplefb.c b/sys/dev/fdt/simplefb.c
index a39646ea6e0b..cc05b13659a1 100644
--- a/sys/dev/fdt/simplefb.c
+++ b/sys/dev/fdt/simplefb.c
@@ -157,7 +157,8 @@ simplefb_attach_genfb(struct simplefb_softc *sc)
  	}
if (strcmp(format, "a8b8g8r8") == 0 ||
-	    strcmp(format, "x8r8g8b8") == 0) {
+	    strcmp(format, "x8r8g8b8") == 0 ||
+	    strcmp(format, "a8r8g8b8") == 0) {
  		depth = 32;
  	} else if (strcmp(format, "r8g8b8a8") == 0 ||
  		   strcmp(format, "b8g8r8x8") == 0) {


OK, I guess.

diff --git a/sys/dev/ic/bcmgenet.c b/sys/dev/ic/bcmgenet.c
index 36c0cbfe1358..0705db0e948c 100644
--- a/sys/dev/ic/bcmgenet.c
+++ b/sys/dev/ic/bcmgenet.c
@@ -189,7 +189,7 @@ genet_setup_txdesc(struct genet_softc *sc, int index, int flags,
  	status = flags | __SHIFTIN(len, GENET_TX_DESC_STATUS_BUFLEN);
WR4(sc, GENET_TX_DESC_ADDRESS_LO(index), (uint32_t)paddr);
-	WR4(sc, GENET_TX_DESC_ADDRESS_HI(index), (uint32_t)(paddr >> 32));
+	WR4(sc, GENET_TX_DESC_ADDRESS_HI(index), (uint32_t)((uint64_t)paddr >> 32));
  	WR4(sc, GENET_TX_DESC_STATUS(index), status);
  }
@@ -259,7 +259,7 @@ genet_setup_rxdesc(struct genet_softc *sc, int index,
      bus_addr_t paddr, bus_size_t len)
  {
  	WR4(sc, GENET_RX_DESC_ADDRESS_LO(index), (uint32_t)paddr);
-	WR4(sc, GENET_RX_DESC_ADDRESS_HI(index), (uint32_t)(paddr >> 32));
+	WR4(sc, GENET_RX_DESC_ADDRESS_HI(index), (uint32_t)((uint64_t)paddr >> 32));
  }
static int



Just use BUS_ADDR_{LO,HI}32





Home | Main Index | Thread Index | Old Index