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

Nick Hudson <[email protected]> Sat, 21 Mar 2026 08:33:59 +0000
Newsgroups gmane.os.netbsd.ports.arm
Message-ID <[email protected]>
On 19/03/2026 22:52, Izumi Tsutsui wrote:
> Hi,
>=20
> Currentl NetBSD/evbarm-earmv7hf GENERIC doesn't work on Raspberry Pi 4B:
>=20

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=3D600001d3
> [   1.0000000] r0 =3D00000000, r1 =3Df4000000, r2 =3D0000009c, r3 =3D010=
00380
> [   1.0000000] r4 =3D00000000, r5 =3D807a0484, r6 =3D00000001, r7 =3D80a=
4b180
> [   1.0000000] r8 =3D807a0470, r9 =3D805baab8, r10=3D807a0484, r11=3D80b=
73f54
> [   1.0000000] r12=3D7f000000, ssp=3D80b73f38, slr=3D80011170, pc =3D000=
00000
>=20
> Stopped in pid 0.0 (system) at  0:      address 0x0 is invalid
> adchis  r3, r7, r4, lsr #26
> db{0}>
> ---
>=20
> 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-s=
rc:rpi4-earmv7hf
>   (diffs are also attached)
>   https://dmesgd.nycbug.org/index.cgi?do=3Dview&id=3D8861
>=20
> The problems are:
>=20
> (0) simplefb(4) property values on Pi 4 (as aarch64):
>       https://mail-index.netbsd.org/port-arm/2026/03/19/msg009556.html
>=20
> (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)
>=20
> (2) There are uint32_t integer overflow in arm32/bus_dma.c
>      triggered by BCM2711 DMA range values
>     =20
> (3) Corex-A72 VFP ID is not handled in sys/arch/arm/vfp/vfp_init.c
>=20
> (4) genet(4) (and brgphy(4)) is not in GENERIC and
>      sys/dev/ic/bcmgenet.c doesn't build on ILP32
>=20
> 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=3D251632
>=20
> and I'm afread NetBSD/arm32 kernels will never support LPAE.
> (It looks 32 bit Raspberry Pi OS supports LPAE though)
>=20
> 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.
>=20
> If there is no objection, I'd like to commit (1)-(4) fixes first.
>=20
> ---
> 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 *range=
s, int nranges,
>  =20
>   	for (i =3D 0, dr =3D ranges; i < nranges; i++, dr++) {
>   		if (pa >=3D dr->dr_sysbase &&
> -		    pa < dr->dr_sysbase + dr->dr_len)
> +		    pa - dr->dr_sysbase < dr->dr_len)
>   			return dr;
>   	}
>  =20
> @@ -180,11 +180,11 @@ _bus_dma_busaddr_to_paddr(bus_dma_tag_t t, bus_add=
r_t curaddr)
>   		return curaddr;
>  =20
>   	for (i =3D 0, dr =3D t->_ranges; i < t->_nranges; i++, dr++) {
> -		if (dr->dr_busbase <=3D curaddr
> -		    && curaddr < dr->dr_busbase + dr->dr_len)
> +		if (curaddr >=3D 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)=
;
>   }
>  =20

Why do you think this is needed?



>   /*
> diff --git a/sys/arch/arm/broadcom/bcm283x_platform.c b/sys/arch/arm/bro=
adcom/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
>  =20
>   #include <libfdt.h>
>  =20
> +#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)
>   }
>  =20
>   #if defined(MULTIPROCESSOR)
> +static bool
> +bcm283x_is_2711(void)
> +{
> +	static const struct device_compatible_entry compat_data[] =3D {
> +		{ .compat =3D "brcm,bcm2711" },
> +		DEVICE_COMPAT_EOL
> +	};
> +	const int root =3D 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 =3D &bcm2836_bs_tag;
> -	bus_space_handle_t ioh =3D BCM2836_ARM_LOCAL_VBASE;
> +	bus_space_tag_t iot;
> +	bus_space_handle_t ioh;
>   	uint64_t mpidr;
> +	bool is2711;
> +
> +	is2711 =3D bcm283x_is_2711();
> +	if (is2711) {
> +		iot =3D &bcm2711_bs_tag;
> +		ioh =3D BCM2711_ARM_LOCAL_VBASE;
> +	} else {
> +		iot =3D &bcm2836_bs_tag;
> +		ioh =3D BCM2836_ARM_LOCAL_VBASE;
> +	}
>  =20
>   	fdtbus_get_reg64(phandle, 0, &mpidr, NULL);
>  =20


This seems completely wrong.

Perhaps the DTS need patching with

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

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

> diff --git a/sys/arch/arm/fdt/arm_simplefb.c b/sys/arch/arm/fdt/arm_simp=
lefb.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;
>  =20
>   	if (strcmp(format, "a8b8g8r8") =3D=3D 0 ||
> -	    strcmp(format, "x8r8g8b8") =3D=3D 0) {
> +	    strcmp(format, "x8r8g8b8") =3D=3D 0 ||
> +	    strcmp(format, "a8r8g8b8") =3D=3D 0) {
>   		depth =3D 32;
>   	} else if (strcmp(format, "r8g8b8a8") =3D=3D 0 ||
>   		   strcmp(format, "b8g8r8x8") =3D=3D 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
>  =20
>   #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 =3D "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 contr=
oller
>   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
>  =20
>   # PCI Ethernet
> @@ -331,6 +332,7 @@ re* 		at pci? dev ? function ?	# Realtek RTL8111GS
>  =20
>   # 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[] =3D {
>   	{ .compat =3D "simple-bus" },
>   	{ .compat =3D "simple-pm-bus" },
> +	{ .compat =3D "simple_bus" },
>   	DEVICE_COMPAT_EOL
>   };

Are you using vendor DTS? Please don't.


>  =20
> 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)
>   	}
>  =20
>   	if (strcmp(format, "a8b8g8r8") =3D=3D 0 ||
> -	    strcmp(format, "x8r8g8b8") =3D=3D 0) {
> +	    strcmp(format, "x8r8g8b8") =3D=3D 0 ||
> +	    strcmp(format, "a8r8g8b8") =3D=3D 0) {
>   		depth =3D 32;
>   	} else if (strcmp(format, "r8g8b8a8") =3D=3D 0 ||
>   		   strcmp(format, "b8g8r8x8") =3D=3D 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 =3D flags | __SHIFTIN(len, GENET_TX_DESC_STATUS_BUFLEN);
>  =20
>   	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);
>   }
>  =20
> @@ -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));
>   }
>  =20
>   static int
>=20


Just use BUS_ADDR_{LO,HI}32