Page MenuHomeFreeBSD

support for uart_dev_mu for RPI2, RPI-B
Needs ReviewPublic

Authored by on Jun 13 2018, 10:44 AM.


Group Reviewers

recently added uart_dev_mu driver in D15684 is not in the RPI2 nor RPI-B kernel configuration. This change adds the driver to both kernel config files.

RPI2 (and probably RPI-B) requires an overlay to activate the driver.

Test Plan

Need to test driver with RPI-B kernel.

RPI2 kernel hangs on bootup with existing driver when entry for /soc/serial@7e215040 is marked 'okay' by an overlay. Otherwise, bootup is not affected. Need to determine why enabling the device is causing a boot hang. However, the presence of the driver within the kernel is more or less verified, since the same overlay did nothing when the driver wasn't compiled into the kernel.

Diff Detail

rS FreeBSD src repository
Lint Skipped
Unit Tests Skipped

Event Timeline created this revision.Jun 13 2018, 10:44 AM
db added a comment.Jun 13 2018, 12:42 PM

Obviously the comment "RPI3 aux port" is not quite right now. Perhaps just refer to it as a RPI device?

Do you know why the kernel hangs with this?

I have not figured out why the kernel hangs (yet). I plan on working on it though. Step 1 will be to doctor up the 'mu' source with a bunch of printf()'s so I can see what it's up to, and at some point I may have to set up a complex remote debug environment for it. It might be as simple as having the wrong interrupt or clock assigned by the pre-defined DTB for the RPI2.

for reference, this is what ofwdump believes those settings should be:

ofwdump -p /soc/serial@7e215040

Node 0x20f4: serial@7e215040

  62 72 63 6d 2c 62 63 6d 32 38 33 35 2d 61 75 78 2d 75 61 72 
  74 00 
  7e 21 50 40 00 00 00 40 
  00 00 00 01 00 00 00 1d 
  00 00 00 40 00 00 00 00 
  64 69 73 61 62 6c 65 64 00 
  00 00 00 41 added a comment.EditedJun 14 2018, 6:10 AM

the overlay file in sys/gnu/dts/arm/bcm283x.dtsi has several clock entries for 'aux' related to uart1:

  aux: aux@7e215000 {
          compatible = "brcm,bcm2835-aux";
          #clock-cells = <1>;
          reg = <0x7e215000 0x8>;
          clocks = <&clocks BCM2835_CLOCK_VPU>;

('aux' actually occurs twice)

  uart1: serial@7e215040 {
          compatible = "brcm,bcm2835-aux-uart";
          reg = <0x7e215040 0x40>;
          interrupts = <1 29>;
          clocks = <&aux BCM2835_AUX_CLOCK_UART>;
          status = "disabled";

I'm not sure if this is right or not, but uart0 (the pl011) also seems to be using the BCM2835_CLOCK_VPU

  uart0: serial@7e201000 {
          compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
          reg = <0x7e201000 0x1000>;
          interrupts = <2 25>;
          clocks = <&clocks BCM2835_CLOCK_UART>,
                   <&clocks BCM2835_CLOCK_VPU>;
          clock-names = "uartclk", "apb_pclk";
          arm,primecell-periphid = <0x00241011>;

not sure if this causes problems.  spi and i2c (all 3) use it as well, and I happen to have spi enabled.  NOT loading the overlay to enable spi didn't change anything.

The uart1.dtbo overlay I test with is built from this:


/ {

  compatible = "brcm,bcm2836";
  fragment@0 {
          target-path = "/soc";
          __overlay__ {
                  serial@7e215040 {
                          status = "okay";


I did a test boot with only this overlay (none of the others I am using) and the boot still hung. I'll include part of it since it apparently creates problems with the markup...

/boot/kernel/kernel data=0x740e24+0x1db1dc syms=[0x4+0x77110+0x4+0xab947]
/boot/entropy size=0x1000
/boot/kernel/bcm283x_clkman.ko text=0xe88 data=0x184+0x4 syms=[0x4+0x590+0x4+0x595]
/boot/kernel/bcm283x_pwm.ko text=0x1e0c data=0x1ac+0x4 syms=[0x4+0x710+0x4+0x729]
/boot/kernel/spigen.ko text=0x1ea8 data=0x22c+0x4 syms=[0x4+0x840+0x4+0x72b]
/boot/dtb/bcm2836-rpi-2-b.dtb size=0x4c49
Loaded DTB from file 'bcm2836-rpi-2-b.dtb'.
Loading DTB overlays: 'uart1.dtbo'
/boot/dtb/overlays/uart1.dtbo size=0x126
applying DTB overlay '/boot/dtb/overlays/uart1.dtbo'
Kernel entry at 0x1200180...
Kernel args: (null)
KDB: debugger backends: ddb
KDB: current backend: ddb

- snip -

WARNING: WITNESS option enabled, expect reduced performance.
VT: init without driver.
CPU: ARM Cortex-A7 r0p5 (ECO: 0x00000000)
CPU Features: 
  Multiprocessing, Thumb2, Security, Virtualization, Generic Timer, VMSAv7,
  PXN, LPAE, Coherent Walk
Optional instructions: 
LoUU:2 LoC:3 LoUIS:2 
Cache level 1:
 32KB/64B 4-way data cache WB Read-Alloc Write-Alloc
 32KB/32B 2-way instruction cache Read-Alloc
Cache level 2:
 512KB/64B 8-way unified cache WB Read-Alloc Write-Alloc
real memory  = 0 (0 MB)
avail memory = 1008721920 (961 MB)
FreeBSD/SMP: Multiprocessor System Detected: 4 CPUs

- snip -

  bcm2835_cpufreq0: <CPU Frequency Control> on cpu0
  cpu1: <Open Firmware CPU> on cpulist0
  cpu2: <Open Firmware CPU> on cpulist0
  cpu3: <Open Firmware CPU> on cpulist0
  gpioled0: <GPIO LEDs> on ofwbus0
  cryptosoft0: <software crypto>

(and this is where it hangs - ddb access is possible at this point) added a comment.EditedJun 14 2018, 6:15 PM

added some diagnostics to the uart_mu driver. a quick check shows rapid looping on 'uart_mu_bus_ipend' during startup. Additional test code only spat out a message when 'uart_mu_bus_ipend' would return a non-zero value (which apparently it does not).

This is what the new boot log looks like at the point it loads uart0, until it hangs.  '** BBB' messages are mine.
uart0: <PrimeCell UART (PL011)> mem 0x7e201000-0x7e201fff irq 31 on simplebus0
uart0: console (115200,n,8,1)
spi0: <BCM2708/2835 SPI controller> mem 0x7e204000-0x7e204fff irq 33 on simplebus0
spibus0: <OFW SPI bus> on spi0
iichb0: <BCM2708/2835 BSC controller> mem 0x7e205000-0x7e205fff irq 34 on simplebus0
**BBB calling uart_mu_bus_probe
**BBB calling uart_mu_bus_probe
uart1: <BCM2835 Mini-UART> mem 0x7e215040-0x7e21504b irq 38 on simplebus0
**BBB calling uart_mu_bus_attach
pwm0: <BCM2708/2835 PWM controller> mem 0x7e20c000-0x7e20c027 on simplebus0
sdhci_bcm0: <Broadcom 2708 SDHCI controller> mem 0x7e300000-0x7e3000ff irq 41 on simplebus0
mmc0: <MMC/SD bus> on sdhci_bcm0
iichb1: <BCM2708/2835 BSC controller> mem 0x7e804000-0x7e804fff irq 44 on simplebus0
iichb2: <BCM2708/2835 BSC controller> mem 0x7e805000-0x7e805fff irq 45 on simplebus0
bcm283x_dwcotg0: <DWC OTG 2.0 integrated USB controller (bcm283x)> mem 0x7e980000-0x7e98ffff irq 50 on simplebus0
usbus0 on bcm283x_dwcotg0
vchiq0: <BCM2835 VCHIQ> mem 0x7e00b840-0x7e00b84e irq 52 on simplebus0
vchiq: local ver 8 (min 3), remote ver 8.
pcm0: <VCHIQ audio> on vchiq0
fb0: <BCM2835 VT framebuffer driver> on simplebus0
fbd0 on fb0
VT: initialize with new VT driver "fb".
fb0: 656x416(656x416@0,0) 24bpp
fb0: fbswap: 0, pitch 1968, base 0x3ef34000, screen_size 818688
cpulist0: <Open Firmware CPU Group> on ofwbus0
cpu0: <Open Firmware CPU> on cpulist0
bcm2835_cpufreq0: <CPU Frequency Control> on cpu0
cpu1: <Open Firmware CPU> on cpulist0
cpu2: <Open Firmware CPU> on cpulist0
cpu3: <Open Firmware CPU> on cpulist0
gpioled0: <GPIO LEDs> on ofwbus0
cryptosoft0: <software crypto>
   vm_lowmem_evh_init(0)... done.
   vmem_start_callout(0)... done.

apparently hangs in 'configure_final'

apparently the problem is a bit worse that I thought. the stack backtrace for thread 10000 points to line 300 in init_main.c where the code is attempting to print "done" (for verbose kernel bootup) after completing 'configure_final'. This is the point where the console breaks into ddb.

It appears as if something has locked up the console uart so it can't print any more. However, when I was printing diagnostics for every call to 'uart_mu_bus_ipend', I got infinite repeating messages (and everything else scrolled off). Now that the message for 'uart_mu_bus_ipend' only prints if the return value will be non-zero (indicating a pending interrupt), I don't see those messages, but console output from init_main.c line 300 isn't showing up, either [and the debugger shows exactly that place in the code in the backtrace for thread 10000]

It looks like there are no pinctrl combinations that can give you simultaneous pl011 and mu serial drivers on the RPi 2. manually tweeking the GPIO pins for the serial console will effectively switch between the two types, but only if you can bring up the 'mu ' driver with it NOT connected to active pins (which appears is not possible; ian suggested that without proper pinctrl support, the driver may constantly interrupt on a 'break' state, which explains what I've seen). However, one of the changes here should be retained since the RPi zero needs the 'mu' driver (it similarly has a bluetooth wired to the pl011 like the RPi 3).

once I get an RPi zero to test this on I'll consider revisiting this to get it working.


I should remove this from the diff as you can't really use the 'mu' driver on the RPi model B without completely disabling the pl011 with an overlay, basically making this pointless.

However, in teh case of the RPi zero [which has no kernel config yet] this entry SHOULD be in there.


I should remove this from the diff as you can't really use the 'mu' driver on the RPi 2 without completely disabling the pl011 with an overlay, basically making this pointless.