Skip to content

drivers/serial: Refactor PL011 to be general-purpose#18837

Open
linguini1 wants to merge 1 commit intoapache:masterfrom
linguini1:pl011-uart
Open

drivers/serial: Refactor PL011 to be general-purpose#18837
linguini1 wants to merge 1 commit intoapache:masterfrom
linguini1:pl011-uart

Conversation

@linguini1
Copy link
Copy Markdown
Contributor

@linguini1 linguini1 commented May 2, 2026

Summary

This commit refactors the PL011 UART driver so that it can be re-used for any number of UART interfaces depending on the board/chip. This commit also hooks the UART interface configuration/selection for PL011 UART interfaces into the same Kconfig used for regular UART interfaces. Now UART interfaces are configured in a standard, extensible way.

Related to #18836. Needed to unblock progress on the RPi4B PL011 UART interfaces for GSoC 2026.

Impact

Impacts only the 4 (simulator) boards that used PL011 UART.

Testing

For each of the QEMU boards, I tested their gdbstub demos since those configurations use both UART interfaces, not just a console.

QEMU ARMv8A

Details
$ qemu-system-aarch64 -cpu cortex-a53 -nographic -machine virt,virtualization=on,gic-version=3 -net none -kernel ./nuttx -serial mon:stdio -serial pty
char device redirected to /dev/pts/1 (label serial1)
- Ready to Boot Primary CPU
- Boot from EL2
- Boot from EL1
- Boot to C runtime for OS Initialize

NuttShell (NSH) NuttX-12.13.0
nsh> ps
  TID   PID  PPID PRI POLICY   TYPE    NPX STATE    EVENT     SIGMASK            STACK    USED FILLED COMMAND
    0     0     0   0 FIFO     Kthread   - Ready              0000000000000000 0008144 0001664  20.4%  Idle_Task
    1     0     0 192 RR       Kthread   - Waiting  Semaphore 0000000000000000 0008080 0001152  14.2%  hpwork 0x403cf6d0 0x403cf758
    3     3     0 100 RR       Task      - Running            0000000000000000 0008112 0003840  47.3%  nsh_main
nsh> ls
/:
 dev/
 proc/
 tmp/
$ gdb nuttx -ex "target remote /dev/pts/1"
GNU gdb (GDB) 17.1
Copyright (C) 2025 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from nuttx...
Remote debugging using /dev/pts/1
0x0000000040297528 in up_idle () at common/arm64_idle.c:65
65      }
(gdb) exit

QEMU ARMv7A

Details
$ qemu-system-arm -cpu cortex-a7 -nographic -machine virt,virtualization=off,gic-version=2 -net none -kernel ./nuttx  -serial mon:stdio -serial pty
char device redirected to /dev/pts/2 (label serial1)
nx_start: Entry
uart_register: Registering /dev/console
uart_register: Registering /dev/ttyS0
work_start_highpri: Starting high-priority kernel worker thread(s)
nxtask_activate: hpwork pid=1,TCB=0x4020d5c0
nxtask_activate: AppBringUp pid=2,TCB=0x4020e690
nx_start_application: Starting init thread
task_spawn: name=nsh_main entry=0x60ccac file_actions=0 attr=0x4020f724 argv=0x4020f720
nxtask_activate: nsh_main pid=3,TCB=0x4020f790
nxtask_exit: AppBringUp pid=2,TCB=0x4020e690
lib_cxx_initialize: _sinit: 0x631110 _einit: 0x631110

NuttShell (NSH) NuttX-12.13.0
nsh> nx_start: CPU0: Beginning Idle Loop

nsh> ps
  TID   PID  PPID PRI POLICY   TYPE    NPX STATE    EVENT     SIGMASK            STACK    USED FILLED COMMAND
    0     0     0   0 FIFO     Kthread   - Ready              0000000000000000 0004072 0000704  17.2%  Idle_Task
    1     0     0 192 RR       Kthread   - Waiting  Semaphore 0000000000000000 0004024 0000456  11.3%  hpwork 0x40200150 0x40200198
    3     3     0 100 RR       Task      - Running            0000000000000000 0004048 0001552  38.3%  nsh_main
nsh>
$ gdb nuttx -ex "target remote /dev/pts/2"
GNU gdb (GDB) 17.1
Copyright (C) 2025 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from nuttx...
Remote debugging using /dev/pts/2
0x0060c488 in up_idle () at chip/qemu_idle.c:63
63      }
(gdb) exit

For the FVP boards, I tested compilation only.

The CXD32 and and Goldfish chips don't have any defconfigs to test.

@github-actions github-actions Bot added Arch: arm Issues related to ARM (32-bit) architecture Arch: arm64 Issues related to ARM64 (64-bit) architecture Area: Drivers Drivers issues Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces. Board: arm Board: arm64 labels May 2, 2026
@linguini1 linguini1 requested review from cederom and michallenc May 2, 2026 19:53
This commit refactors the PL011 UART driver so that it can be re-used
for any number of UART interfaces depending on the board/chip. This
commit also hooks the UART interface configuration/selection for PL011
UART interfaces into the same Kconfig used for regular UART interfaces.
Now UART interfaces are configured in a standard, extensible way.

Signed-off-by: Matteo Golin <matteo.golin@gmail.com>
@linguini1
Copy link
Copy Markdown
Contributor Author

linguini1 commented May 2, 2026

I am able to run the qemu-armv8a:citest binary locally with the same invocation used by NTFC:

$ qemu-system-aarch64 -cpu cortex-a53 -nographic -machine virt,virtualization=on,gic-version=3 -net none -chardev stdio,id=con,mux=on -serial chardev:con -mon chardev=con,mode=readline -kernel ./nuttx

NuttShell (NSH) NuttX-12.13.0
nsh> ps
  TID   PID  PPID PRI POLICY   TYPE    NPX STATE    EVENT     SIGMASK            STACK    USED FILLED COMMAND
    0     0     0   0 FIFO     Kthread   - Ready              0000000000000000 0008144 0001616  19.8%  Idle_Task
    1     0     0 192 RR       Kthread   - Waiting  Semaphore 0000000000000000 0008080 0001200  14.8%  hpwork 0x404196a0 0x40419728
    3     3     0 100 RR       Task      - Running            0000000000000000 0008112 0003728  45.9%  nsh_main
nsh> ls
/:
 dev/
 proc/
 tmp/
nsh>

It's also odd that it works for SMP.

@linguini1
Copy link
Copy Markdown
Contributor Author

@raiden00pl Do you have any idea why this change might cause NTFC to fail with a boot timeout on qemu-armv8a:citest but not qemu-armv8a:citest_smp?

@raiden00pl
Copy link
Copy Markdown
Member

no idea. NTFC should export nuttx.elf in CI artifacts, but for some reason these are not present for qemu-armv8a:citest and qemu-armv8a:citest_smp. What's funny - it works for all other targets citest targets.

Now I see that this target uses cmake, so that might be the reason for the missing elf in the artifacts.

@xiaoxiang781216 xiaoxiang781216 linked an issue May 3, 2026 that may be closed by this pull request
1 task
*
***************************************************************************/

void pl011_serialinit(void)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why drop the default implementation which could avoid the code duplication in the common case. it's better that:

  1. keep pl011_serialinit/pl011_earlyserialinit if one of CONFIG_UARTx_PL011 is enabled
  2. add pl011_dev_init, so the special case could call the new function directly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this function is no longer useful. It needs access to the device structs for the PL011 interfaces in order to register them, but these are defined outside this module now.

If we keep this function, then we can no longer:

  • Define an arbitrary number of interfaces
  • Use the standard UART config options for configuring PL011 UART

It should now be up to the chip logic to register the UART interfaces instead, as with all other UART drivers. Otherwise we don't have the benefits and we must also maintain two separate ways of doing things. There are only 3 boards that use PL011 right now, so it's not a super common case.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but the similar config duplicated in the many places now. I would prefer to keep the origin global definition, so the common usage could be simplified.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure there's a way around that except by maintaining two interfaces for PL011 registration and all the old Kconfig options. Plus, I will have to add some refactoring for more granular interrupt management.

Let me brainstorm and get back to you, maybe I can keep the init function and still remove the PL011-specific Kconfig functions. The main challenge is selection of the base addresses and IRQ numbers.

@linguini1
Copy link
Copy Markdown
Contributor Author

Now I see that this target uses cmake, so that might be the reason for the missing elf in the artifacts.

I'll try building with CMake in case that reveals what the issue might be.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: arm Issues related to ARM (32-bit) architecture Arch: arm64 Issues related to ARM64 (64-bit) architecture Area: Drivers Drivers issues Board: arm Board: arm64 Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Re-usable PL011 UART driver

3 participants