Commit graph

25147 commits

Author SHA1 Message Date
Ulaş Sertan Kemeç
762d2b7958 Documentation/am67: Document GPIO and SPI support on t3-gem-o1.
Add a Peripheral Support section to the board page listing the GPIO and
MCU_MCSPI0 drivers, and replace the "UART console only" warning on both
the chip and board pages -- it no longer describes the port.  The
replacement states what actually constrains the port: NuttX runs on the
R5F under RemoteProc and depends on the bootloader or Linux Device
Manager having powered and clocked the peripherals, because there is no
TISCI client yet.

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Ulaş Sertan Kemeç <sertan.usk@gmail.com>
2026-09-14 18:45:44 -03:00
halak0013
4f3b818c3f arch/arm/am67: Add GPIO and MCU_MCSPI0 master driver.
Adds the AM67 GPIO lower half and a polled MCU_MCSPI0 master driver, with the
pad configuration both need.  The K3 instance is not the OMAP2 layout: an HL
header block precedes the functional registers.

Chip select is released only after CHSTAT.EOT, since a high SCLK otherwise
drops it mid-word and truncates the write, and CHCTRL.EN stays asserted between
transfers.

t3-gem-o1 registers /dev/spi0 for its ICM-20948 (CS3) and LPS22DF (CS1), and
raises NSH_MAXARGUMENTS to 16 so the spi tool can address a device.

Verified on t3-gem-o1: WHO_AM_I reads 0xEA on CS3 and 0xB4 on CS1, and the
ICM-20948 streams continuous accelerometer samples over the bus.

Co-authored-by: Ulaş Sertan Kemeç <sertan.usk@gmail.com>
Assisted-by: Cursor
Assisted-by: Claude Code:claude-opus-4-8
Signed-off-by: Ulaş Sertan Kemeç <sertan.usk@gmail.com>
2026-09-14 18:45:44 -03:00
raiden00pl
9f5b02fb5a arch/arm/stm32: Fix nxstyle issues in stm32_usbdev_m0_v1.c
Fix nxstyle issues in stm32_usbdev_m0_v1.c

Assisted-by: Claude Code
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-09-14 18:32:23 -03:00
raiden00pl
93db0083df arch/arm/stm32c0: Add USB device support
add USB device support for STM32C0

Assisted-by: Claude Code
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-09-14 18:32:23 -03:00
raiden00pl
11128e5543 arch/arm/stm32: Add STM32C0 to HSI48 M0 driver
add STM32C0 to HSI48 M0 driver

Assisted-by: Claude Code
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-09-14 18:32:23 -03:00
raiden00pl
47042a6014 arch/arm/stm32c0: Fix RCC CRS and HSIUSB48 bits
APB1 bit 16 is CRS, not CRC (CRC is on AHB). RCC_CRRCR only holds the
HSIUSB48 calibration; the HSIUSB48 enable lives in RCC_CR.

Assisted-by: Claude Code
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-09-14 18:32:23 -03:00
raiden00pl
63ca8d1cbc arch/arm/stm32: Add USBDEV_M0_V2 IP flag
Gate the 32-bit USB DRD FS path of the common M0 usbdev driver on
STM32_HAVE_IP_USBDEV_M0_V2 instead of the STM32G0 family symbol.

Assisted-by: Claude Code
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-09-14 18:32:23 -03:00
Jukka Laitinen
885bdef4c3 arch/arm/src/imxrt/imxrt_usbdev.c: Fix nxstyle issues
Some checks are pending
MemBrowse Memory Report / changes-filter (push) Waiting to run
MemBrowse Memory Report / load-targets (push) Waiting to run
MemBrowse Memory Report / identical (push) Blocked by required conditions
MemBrowse Memory Report / analyze (push) Blocked by required conditions
Add blank lines, fix alignment and add braces to switch-case

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-14 11:03:40 -03:00
Jukka Laitinen
5ec9e6c663 arch/arm/src/imxrt/imxrt_start.c: Fix nxstyle issues
Fix alignment, add blank lines and add braces where missing.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-14 11:03:40 -03:00
Jukka Laitinen
2651e2d7f0 arch/arm/src/imxrt/imxrt_serial.c: Fix nxstyle issues
Fix alignment in multiple places

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-14 11:03:40 -03:00
Jukka Laitinen
ce37887dde arch/arm/src/imxrt/imxrt_ocotp.c: Fix nxstyle issues
Add a missing blank line

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-14 11:03:40 -03:00
Jukka Laitinen
2a3f06b7bd arch/arm/src/imxrt/imxrt_lpspi.c: Fix nxstyle issues
Add braces to switch-case

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-14 11:03:40 -03:00
Jukka Laitinen
61b81b63a9 arch/arm/src/imxrt/imxrt_lpi2c.c: Fix nxstyle issues
Add blank lines, fix alignment and add braces to switch-case

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-14 11:03:40 -03:00
Jukka Laitinen
11e2f01296 arch/arm/src/imxrt/imxrt_irq.c: Fix nxstyle issues
Fix alignment issues

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-14 11:03:40 -03:00
Jukka Laitinen
ec2faf8dc1 arch/arm/src/imxrt/imxrt_allocateheap.c: Fix nxstyle issues
Add a missing blank line

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-14 11:03:40 -03:00
Darryl Ring
bc11615732 arch/arm/stm32: Fix includes
Some checks are pending
MemBrowse Memory Report / changes-filter (push) Waiting to run
MemBrowse Memory Report / load-targets (push) Waiting to run
MemBrowse Memory Report / identical (push) Blocked by required conditions
MemBrowse Memory Report / analyze (push) Blocked by required conditions
Remove extra includes sections and quote include arm_internal.h.

Signed-off-by: Darryl Ring <darryl@bluerobotics.com>
2026-09-14 09:07:46 +08:00
Darryl Ring
b5bb6f33df arch/arm/stm32h5: Use MDIO bus
Copy the MDIO bus changes from the STM32H7 port.

Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Darryl Ring <darryl@bluerobotics.com>
2026-09-14 09:07:46 +08:00
Lingao Meng
89c4b8ccaf arch/sim: Add runtime HCI socket target option
Some checks are pending
Build Documentation / build-html (push) Waiting to run
MemBrowse Memory Report / changes-filter (push) Waiting to run
MemBrowse Memory Report / load-targets (push) Waiting to run
MemBrowse Memory Report / identical (push) Blocked by required conditions
MemBrowse Memory Report / analyze (push) Blocked by required conditions
Allow sim HCI socket users to select the host-side HCI target at runtime
with --bt-dev.  Passing --bt-dev=hciN overrides CONFIG_SIM_HCISOCKET_DEVID
for the BlueZ HCI user channel, while omitting the option keeps the existing
configured default behavior.

Also allow --bt-dev=/path/to/socket to connect to an H:4 stream exposed
through a Unix-domain socket.  This lets sim applications use a controller
provided by another host process or by a UART-to-Unix-socket bridge without
requiring BlueZ raw HCI privileges for the NuttX process.

Use host-side output for early --bt-dev parse errors, since NuttX stdio is
not initialized before nx_start().

Document the BlueZ and Unix socket modes, including the capability
requirements for BlueZ and the socat bridge example for Unix socket mode.

Testing:

  Host: Ubuntu 22.04 x86_64
  Board/config: sim:bthcisock

  Style checks:

    git diff --check HEAD~2..HEAD
    PATH=/home/mi/bsim-auto-test/.venv/bin:$PATH \
      ./tools/checkpatch.sh -c -u -m -g HEAD~2..HEAD

  Clean build:

    make distclean
    ./tools/configure.sh -l -a ../../nuttx-apps sim:bthcisock
    kconfig-tweak --file .config --set-val STACK_USAGE_WARNING 0
    make olddefconfig
    make -j16

  Invalid runtime argument smoke test:

    ./nuttx --bt-dev=invalid

  Verified the command exits with status 1 and reports the invalid target
  without crashing before nx_start().

  Unix socket HCI smoke test:

    socat -d -d UNIX-LISTEN:/tmp/hci.sock,fork,reuseaddr \
      /dev/ttyACM2,b1000000,raw,echo=0,crtscts=1
    printf 'ifconfig\nbt bnep0 info\npoweroff\n' | \
      timeout 20s ./nuttx --bt-dev=/tmp/hci.sock

  Verified the sim registers the Bluetooth network device as bnep0 and
  bt bnep0 info reads the controller state through the Unix-socket HCI
  path, including BDAddr aa:bb:cc:dd:ee:ff from the attached controller.

Assisted-by: OpenAI Codex
Signed-off-by: Lingao Meng <menglingao@xiaomi.com>
2026-09-13 18:31:59 -03:00
Lingao Meng
6c147f8484 arch/sim: Fix HCI socket watchdog lifetime
Start the simulated HCI socket receive watchdog only after the host HCI
socket has been opened successfully.  The previous code armed the watchdog
immediately after driver registration, before the Bluetooth stack opened the
driver and before the device had a valid host fd.

Cancel the watchdog on close/free and close any opened host fd during
allocation-failure cleanup.  This keeps the polling path tied to the actual
socket lifetime and prevents the watchdog from polling an invalid host fd.

Testing:

  Host: Ubuntu 22.04 x86_64
  Board/config: sim:bthcisock

  Style checks:

    git diff --check HEAD~2..HEAD
    PATH=/home/mi/bsim-auto-test/.venv/bin:$PATH \
      ./tools/checkpatch.sh -c -u -m -g HEAD~2..HEAD

  Clean build:

    make distclean
    ./tools/configure.sh -l -a ../../nuttx-apps sim:bthcisock
    kconfig-tweak --file .config --set-val STACK_USAGE_WARNING 0
    make olddefconfig
    make -j16

  Default startup smoke test:

    printf 'poweroff\n' | timeout 10s ./nuttx

  Verified the sim still reaches NSH and powers off cleanly.  When no
  host HCI controller is available through the default BlueZ target, the
  board reports sim_bthcisock_register() failure and continues booting;
  no invalid-fd watchdog crash occurs.

Assisted-by: OpenAI Codex
Signed-off-by: Lingao Meng <menglingao@xiaomi.com>
2026-09-13 18:31:59 -03:00
Lingao Meng
598a1035a0 arch/sim: Add BabbleSim discrete time support
Add support for using a BabbleSim PHY as the monotonic time source for
the Linux sim target.  When CONFIG_SIM_BSIM_TIME is enabled, the sim
host build links a small host-side time helper against the BabbleSim
PhyCom and Util libraries.  The helper joins the BabbleSim PHY wait
protocol and advances NuttX monotonic time through PB_MSG_WAIT requests
instead of Linux wall-time sleeps.

A SIM binary built with CONFIG_SIM_BSIM_TIME enabled joins BabbleSim time
at startup.  Runtime options allow the test runner to select the
BabbleSim simulation id, PHY id, and device number:

  --sim-bsim-sid=<simulation-id>
  --sim-bsim-pid=<phy-id>
  --sim-bsim-dev=<device-number>

Keep the integration inside the sim host time path rather than exposing
a new application API.  RTC/realtime reads still use the host realtime
clock; the BabbleSim source is used only for monotonic time after the sim
has joined the PHY.  The Kconfig option depends on the sleep based
walltime mode and is disabled for SMP and non-Linux hosts.

The build requires BSIM_COMPONENTS_PATH for headers and either
BSIM_OUT_PATH or BSIM_LIBS_DIR for shared libraries.  The path checks are
skipped for clean, distclean, clean_context, and context targets so a
tree with CONFIG_SIM_BSIM_TIME enabled can still be cleaned without
exporting the BabbleSim environment first.

Document the configuration, build environment, runtime options, and the
requirement that the BabbleSim PHY process is started separately by the
test runner.

Testing:

  Host: Ubuntu 22.04 x86_64
  Board/config: sim:nsh

  Style check:

    git diff --check

  Default sim build and smoke test:

    ./tools/configure.sh -l -a ../nuttx-apps sim:nsh
    make -j16
    printf 'help\npoweroff\n' | timeout 20s ./nuttx

  BabbleSim-enabled build:

    kconfig-tweak --file .config \
      -e SIM_WALLTIME_SLEEP \
      -d SIM_WALLTIME_SIGNAL \
      -e SIM_BSIM_TIME
    make olddefconfig
    BSIM_OUT_PATH=/tmp/bsworld/build/babblesim/bsim \
    BSIM_COMPONENTS_PATH=/tmp/bsworld/build/babblesim/bsim/components \
      make -j16

  Verified actual BabbleSim PHY time integration without a controller by
  starting bs_2G4_phy_v1 and running NSH usleep through the PHY wait
  barrier:

    bs_2G4_phy_v1 -s=<sid> -D=1 -defmodem=BLE_simple -nodump
    printf 'usleep 1000000\npoweroff\n' | \
      ./nuttx --sim-bsim-sid=<sid> \
              --sim-bsim-pid=2G4 \
              --sim-bsim-dev=0

  The same 1 second simulated sleep completed in 19 ms wall time when no
  handbrake device was present.  With handbrake registered as device 1:

    bs_2G4_phy_v1 -s=<sid> -D=2 -defmodem=BLE_simple -nodump
    bs_device_handbrake -s=<sid> -p=2G4 -d=1 -pp=50000 -r=1

  the same NuttX usleep test completed in 985 ms wall time.  A shorter
  200 ms check showed the same behavior: 27 ms without handbrake and
  172 ms with handbrake.  This verifies that NuttX sim time advances
  through the BabbleSim PHY and that the handbrake affects the NuttX sim
  device.

  Also verified make distclean succeeds after CONFIG_SIM_BSIM_TIME was
  enabled and without exporting BSIM_COMPONENTS_PATH.

  BSWorld out-of-tree native BLE examples:

    ./tools/configure.sh -l /path/to/bsim-auto-test/tests/nuttx/native_ble/source/advertiser/config
    make -j16
    exodus --tarball -o /path/to/bsim-auto-test/tests/nuttx/native_ble/source/advertiser/prebuilt/nuttx.tgz nuttx
    ./tools/configure.sh -l /path/to/bsim-auto-test/tests/nuttx/native_ble/source/scanner/config
    make -j16
    exodus --tarball -o /path/to/bsim-auto-test/tests/nuttx/native_ble/source/scanner/prebuilt/nuttx.tgz nuttx
    pytest tests/nuttx/native_ble -q --no-ellisys

Assisted-by: OpenAI Codex
Signed-off-by: Lingao Meng <menglingao@xiaomi.com>
2026-09-13 18:31:59 -03:00
Marco Casaroli
50a735bf86 libs/libc/machine/arm: Relocate FDPIC function descriptors.
A function pointer under FDPIC is not a code address.  Because each
PT_LOAD segment is placed independently, a pointer has to carry the data
base its callee will need, so it is a two-word descriptor: the entry
point, and the base to install in the PIC register before branching.
R_ARM_FUNCDESC_VALUE says "the thing you are patching is such a
descriptor", and R_ARM_FUNCDESC says "manufacture one and give me its
address".

Both need state a relocation cannot carry.  A descriptor's second word is
the *object's* data base, from DT_PLTGOT, and R_ARM_FUNCDESC carves
descriptors from a pool whose cursor has to survive from one relocation
to the next.  up_relocate() is handed only a relocation, a resolved
symbol and an address to patch.

arch_data is the existing channel for exactly this -- RISC-V already uses
it to remember a HI20 relocation while its LO12 partner is processed --
but nothing has ever put loader state into it: it is declared zeroed and
written only by up_relocate() itself.  So ARCH_ELFDATA_INIT and
ARCH_ELFDATA_FINI are added, seeding the block from the loadinfo before
the relocation loop and reading the cursor back after.  Both default to
nothing, so an architecture that does not define them is unaffected, and
RISC-V's use of arch_data is untouched.  libelf_relocatedyn() walks both
dynamic tables under one arch_data, so the cursor spans the whole object.

The addend handling is the part that is easy to get wrong.  REL format
keeps the addend in place, in the word about to become the entry point,
and a pointer to a static function is referenced through its *section*
symbol -- the value is the section base and the offset, including the
Thumb bit, is entirely in the addend.  Dropping it yields an even address
and the core faults trying to execute it as ARM code.

The GOT written into a descriptor is the loading object's own, even for
an imported function, which is what makes a callback work: when the base
firmware's qsort() calls back into a module's comparison function, the
module needs its own data base in the PIC register.

libelf_relocatedyn()'s imported-symbol path needed a change to suit.  It
stores the resolved address directly and never calls up_relocate(), which
cannot produce a two-word descriptor, so under FDPIC the resolved value
now goes through up_relocate() and the relocation type decides what to
write.

Implemented for armv7-m and armv8-m, the profiles FDPIC targets; the
other ARM variants gain the arch_data block but no new relocations.
Built and booted mps3-an547:picostest and lm3s6965-ek:qemu-nxflat, the
ELF PIC and NXFLAT users of this code, both unchanged.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-13 16:03:32 -03:00
Huang Qi
4e196729e7 arch/risc-v: Add CLIC interrupt threshold support
Some checks are pending
Build Documentation / build-html (push) Waiting to run
MemBrowse Memory Report / changes-filter (push) Waiting to run
MemBrowse Memory Report / load-targets (push) Waiting to run
MemBrowse Memory Report / identical (push) Blocked by required conditions
MemBrowse Memory Report / analyze (push) Blocked by required conditions
and documentation it

Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
2026-09-13 08:31:16 -03:00
Peter van der Perk
ad176ac47f arch/arm/imxrt: fix nxstyle alignment in imxrt_clockconfig_ver2.c
Some checks failed
MemBrowse Memory Report / changes-filter (push) Has been cancelled
MemBrowse Memory Report / load-targets (push) Has been cancelled
MemBrowse Memory Report / identical (push) Has been cancelled
MemBrowse Memory Report / analyze (push) Has been cancelled
Fix nxstyle issues

Signed-off-by: Peter van der Perk <peter.vanderperk@nxp.com>
2026-09-11 12:54:06 -03:00
Peter van der Perk
94a5e23714 arch/arm/src/imxrt: keep the boot ROM's XIP FlexSPI clock setting
When executing in place from flash, the XIP FlexSPI clock must not be
reconfigured during the initial clock setup. The boot ROM configures the
clock for its flash read sequence, and changing it before the board installs
a suitable high-speed read sequence can break instruction fetch. The board's
flash setup may reconfigure the clock afterward.

Signed-off-by: Peter van der Perk <peter.vanderperk@nxp.com>
2026-09-11 12:54:06 -03:00
luke kun
412931f707 arch/risc-v/src/common: fix wrong vregs access in up_initial_state
vregs is a member of struct xcptcontext, not tcb_s.

Signed-off-by: luke kun <donghaokun@lixiang.com>
2026-09-11 21:18:59 +08:00
Ulaş Sertan Kemeç
7d0b46b1f5 arch/arm/am67: Mark the DDR MPU region Non-shareable.
LDREX/STREX to Shareable memory needs an external exclusive monitor, and this
Cortex-R5F has none on the path to DDR; Non-shareable uses the core-local
monitor instead.  Every atomic compiles to inline LDREX here, since the chip
selects no LIBC_ATOMIC_* backend and falls back to LIBC_ATOMIC_TOOLCHAIN.

Verified on t3-gem-o1: without this the core runs but the console never
appears; with it the same image boots and ostest exits with status 0.

Assisted-by: Claude Code:claude-opus-4-8
Signed-off-by: Ulaş Sertan Kemeç <sertan.usk@gmail.com>
2026-09-11 02:59:59 +08:00
Marco Casaroli
5866c4e3af xtensa: Support BUILD_KERNEL.
Add what a kernel build needs on Xtensa:  a crt0 for a user process, the
kernel stack allocation that a system call switches to, the syscall entry and
return path for an unprivileged caller, and the initial register state that
starts a user task at EL0 with its save area on the kernel stack.

On the ESP32-S3 the arch code that runs while the flash mapping is in flux
moves to IRAM, and the kernel heap is placed above the user .bss so that
up_allocate_kheap() and the user address environment do not overlap.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-10 23:28:43 +08:00
raiden00pl
7e5bf155b5 arch/intel64: don't clear the oneshot handler from the HPET ISR
Some checks are pending
MemBrowse Memory Report / changes-filter (push) Waiting to run
MemBrowse Memory Report / load-targets (push) Waiting to run
MemBrowse Memory Report / identical (push) Blocked by required conditions
MemBrowse Memory Report / analyze (push) Blocked by required conditions
intel64_oneshot_handler() cleared oneshot->handler and oneshot->arg
after picking them up, without holding g_oneshot_spin, while
intel64_oneshot_start() re-arms the timer under that lock from another
CPU.  Now that the HPET ISR stays attached across a re-arm, a stale
interrupt can interleave with start(): it reads the freshly installed
handler, clears it, and start() then sets running = true again, so the
genuine expiry that follows finds running == true with a NULL handler
and jumps to address zero from interrupt context (page fault at RIP 0
in the CPU0 IDLE task while the LTP lio_listio tests were running), or
the alarm is simply lost and the tickless system stops.

The handler and its argument are owned by start() and cancel(); the ISR
only needs to read them.  Leave them alone in the ISR and skip the call
if none is installed.  The remaining effect of a stale interrupt is an
early invocation of the alarm callback, which is harmless: the tickless
scheduler re-evaluates its expirations and re-arms the timer.

Assisted-by: Claude Code
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-09-10 10:23:46 +08:00
raiden00pl
3270e9584e arch/intel64: keep the HPET ISR attached when the timer is stopped
intel64_hpet_setisr() with a NULL handler detached the ISR with
irq_attach(irq, NULL), which installs irq_unexpected_isr().  The oneshot
driver does this every time the timer expires or is re-armed, so an HPET
interrupt already in flight to another CPU lands on the unexpected ISR
and panics the system:

  irq_unexpected_isr: ERROR irq: 34

seen under SMP with the LTP test suite.  Just mask the interrupt and keep
the ISR attached; intel64_oneshot_handler() already treats an interrupt
that arrives while the timer is not running as spurious.

Assisted-by: Claude Code
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-09-10 10:23:46 +08:00
raiden00pl
ba083f5403 arch/intel64: fix nxstyle issues in intel64_hpet.c
fix nxstyle issues in intel64_hpet.c

Assisted-by: Claude Code
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-09-10 10:23:46 +08:00
raiden00pl
dfc8f82b0b arch/intel64: fix self-deadlock in intel64_oneshot_start()
intel64_oneshot_start() takes g_oneshot_spin and then, if the timer is
already running, calls intel64_oneshot_cancel(), which takes the same
spinlock again.  Spinlocks are not recursive, so the CPU spins forever
on its own lock while holding the critical section; the HPET timer ISR
on another CPU then blocks on g_cpu_irqlock and the system hangs.

This is hit as soon as the tickless scheduler re-arms a running HPET
oneshot timer under SMP (ostest task_restart, LTP aio tests).

Stop the running timer inline instead of calling cancel: disable the
interrupt, detach the ISR so up_enable_irq() does not assert on a busy
IRQ, and clear the running flag.  The ISR, comparator and interrupt
enable are reprogrammed by the rest of the function anyway.

Assisted-by: Claude Code
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-09-10 10:23:46 +08:00
Marco Casaroli
69061ea246 arch/arm: Say which linker is missing when FDPIC has none.
Without this the build says "arm-uclinuxfdpiceabi-ld: Command not found",
which does not say what that is, where to get it, or that the prefix can be
changed.

The make build reports at the link rather than while parsing, so that a tree
configured for FDPIC on a host without the linker can still be cleaned and
reconfigured: an error at parse time takes make distclean with it.  The
cmake build reports while configuring, where nothing is built yet.

Both name FDPIC_CROSSDEV, so a linker under another prefix can be used.

Checked on mps3-an547:picostest with CONFIG_FDPIC and the linker off PATH:
make distclean succeeds, and a module link stops with the message.  With the
linker present the modules build as before.

Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-09 10:21:21 +08:00
Marco Casaroli
77f263b4fa cmake: Build FDPIC modules the way the make build does.
The same two differences as in common/Toolchain.defs: the compiler is told
-mfdpic -fPIC, and the module link is done by an arm-uclinuxfdpiceabi
linker.

That linker is not the one that links the firmware, so the module link needs
a variable of its own.  CMAKE_ELF_LD is the ordinary linker unless the
architecture sets it, which arm does under CONFIG_FDPIC.

The linker script needs nothing here: it is generated from
libs/libc/elf/gnu-elf.ld.in, which both build systems preprocess, and the
FDPIC segments are already in it.

-r is now conditional on CONFIG_PIC being off, which is what
common/Toolchain.defs has always done and the cmake build did not: a
position independent module is linked as an executable, and an FDPIC one as
a shared object, so neither wants it.

-fno-use-cxa-atexit mirrors CXXELFFLAGS for the same reason it was added
there.

Configured and built mps3-an547:picostest with CONFIG_FDPIC through cmake and
ninja: the modules in bin/ are ARM FDPIC with two PT_LOAD segments.

Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-09 10:21:21 +08:00
Marco Casaroli
4cdd3cdbda arch/arm, libs/libc/elf: Build FDPIC modules in the normal ELF build.
With CONFIG_FDPIC selected, a module built by apps/Application.mk is now an
FDPIC shared object.  Nothing about how a module is written or built
changes: the same MODULE = m in the same Makefile, the same crt0 and the
same linker script.

Two things differ from the position independent build beside it.  The
compiler is told -mfdpic -fPIC, and the link is done by an
arm-uclinuxfdpiceabi linker.  The stock arm-none-eabi compiler emits correct
FDPIC objects for both C and C++, so only the link needs it: the stock
linker carries the armelf emulation alone and would turn every import into
an R_ARM_JUMP_SLOT, one word, where the ABI wants an R_ARM_FUNCDESC_VALUE,
which is two, a code address and the data base that goes with it.  Such a
module links cleanly and then calls out of itself with the caller's data
base still in r9.  That linker is in the CI image.

gnu-elf.ld.in gains the two segments an FDPIC module needs, under
CONFIG_FDPIC, because the loader places its read-only and writable segments
independently, and names .dynamic, because a shared object is bound through
it.  The sections themselves are untouched and so are the symbols crt0.c
walks, so one script serves both and both build systems get it.

.bss moves to the end of the script, for every configuration and not only
FDPIC.  It held no file content but sat ahead of .got and .dynamic, which
do, so the writable segment's p_filesz had to span it and the module file
carried the whole of .bss.  A module with 16 KiB of .bss went from 26724 to
10340 bytes, and its writable segment from p_filesz 0x40ac to 0xac against
an unchanged p_memsz.  The loader reads p_filesz off the media, so it read
those bytes too.

Built for mps3-an547:picostest with apps/examples/elf, CONFIG_FDPIC both
ways.  With it on, every module in apps/bin is ARM FDPIC with two PT_LOAD
segments and enters at _start; hello++3, which has a static C++ object,
carries DT_INIT_ARRAY and DT_FINI_ARRAY.  With it off the generated script
has no PHDRS and the modules are what they were.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-09 10:21:21 +08:00
Huskya
a60ee84197 arch/arm/src/common/stm32: accept interface-recipient GET/SET_DESCRIPTOR
Some checks are pending
MemBrowse Memory Report / changes-filter (push) Waiting to run
MemBrowse Memory Report / load-targets (push) Waiting to run
MemBrowse Memory Report / identical (push) Blocked by required conditions
MemBrowse Memory Report / analyze (push) Blocked by required conditions
HID class devices fetch the HID Report Descriptor with a
GET_DESCRIPTOR setup packet whose recipient is an interface
(bmRequestType 0x81, wValue 0x2200).  stm32_ep0out_stdrequest() only
dispatches device-recipient descriptor requests and stalls the rest,
so HID class devices cannot enumerate.  Dispatch interface-recipient
requests to the class driver as well.

Signed-off-by: Huskya <itshusky01@gmail.com>
2026-09-09 10:16:12 +08:00
Michal Lenc
48c75c5752 arch/risc-v/src/eic7700x/Kconfig: fix broken kconfig-frontends parsing
kconfig-frontends package needs newline at the end of Kconfig file,
otherwise the parsing fails.

Signed-off-by: Michal Lenc <michallenc@seznam.cz>
2026-09-09 10:15:05 +08:00
Marco Casaroli
1aa32bbc07 libs/libc/elf: Place an FDPIC object's segments independently.
An ET_DYN object is loaded into one allocation with its data behind its
text, because its data references sit at a fixed distance from the code
that makes them.  An FDPIC object does not work that way: it reaches its
data through a base register, so the two segments can be placed wherever
suits, and the point of the format is that the read-only one is left on
the media and executed there while only the writable one is copied.  One
copy of the text then serves every instance.

So libelf_load() grows a second case.  The object announces itself in the
OS/ABI byte, which is noted once in libelf_loadhdrs() rather than
re-derived; e_flags cannot be used for this, as an FDPIC object's are an
unremarkable EABI version and testing them would reject every valid
module.  Text is taken from the media address plus the segment's own file
offset -- the same arithmetic the ET_REL path already does with
sh_offset -- and libelf_loadfile() does not read it.  If the filesystem
cannot show its media, the loader copies the text to RAM instead.  The
module then loses the shared text and the flash saving, but it runs.

Obtaining that address needs two mechanisms, and they are not
interchangeable.  A compacting filesystem can move a file's blocks, so it
hands out an address only with a pin that holds them still and expects
the pin back; xipfs is the one in tree.  A filesystem whose layout never
changes has nothing to hold and answers FIOC_XIPBASE with a bare address;
romfs and tmpfs are those.  libelf_xipacquire() asks for the pin first,
because a filesystem that needs one is not safe without it, and
libelf_unload() gives it back.  The loader asks for a pin only if it can
hold one, or the pin would stay for ever.

The pin is thus not specific to FDPIC.  Any module that executes in place
from a compacting filesystem takes one, and gives it back at unload.

mmap() is not used, though both filesystems implement it.  The mapping
would be recorded against whichever task called the loader, while the
release happens when the module's own task exits, which is a different
group -- so the pin would outlive the module and the extent would never
become movable again.

Unloading has to change with placement: the existing path frees only
textalloc because ET_DYN had a single allocation, which would leak an
FDPIC object's data and free media the filesystem only lent us.

Nothing here runs for a non-FDPIC object; every branch is behind the flag
and the single-allocation path is untouched.  Built and booted
mps3-an547:picostest, which is CONFIG_ELF with CONFIG_PIC, with no change
in behaviour.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-08 16:31:16 -03:00
Marco Casaroli
9f1107862b binfmt, arch/arm: Add the CONFIG_FDPIC option and the ABI header.
The commits that follow teach the ELF loader to load an FDPIC object.  This
puts the option they hang off and the definitions they share in one place
first, so each of them builds on its own.

CONFIG_FDPIC depends on ARCH_HAVE_ELF_FDPIC, which an architecture selects
when it has a PIC base register and the FDPIC relocations.  Only armv7-m
and armv8-m select it today, and it defaults off, so nothing changes for
anyone who does not ask for it.

include/nuttx/fdpic.h holds what both sides of the loader need: the two
word function descriptor an FDPIC module passes instead of a code address,
the test for whether the caller is such a module, and the call sequence
that enters one with its own data base.  All of it is behind CONFIG_FDPIC,
thus the header is empty without it and a file may include it
unconditionally.

The call sequence itself is architecture specific, so arch/arm/include/arch.h
supplies it as up_fdpic_invoke(), beside the other PIC base register macros.
up_setpicbase() cannot serve here: the register has to hold the module's
base for exactly one call and then go back, and nothing in C tells the
compiler the register is live across that call, so the save, the install,
the branch and the restore have to be one sequence.

Built for mps3-an547:bl and mps3-an547:picostest, with CONFIG_FDPIC off,
which is every configuration in the tree.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-08 16:31:16 -03:00
wangjianyu3
7e53ba18f8 arch/arm/rp2040: fix IN endpoint DPSRAM index for bare-eplog callers
rp2040_allocep() indexes the endpoint's DPSRAM buffer/control
registers via RP2040_DPINDEX(eplog) and RP2040_EPINDEX(eplog), both
of which take the transfer direction from the direction bit of
'eplog' itself instead of trusting the explicit 'in' argument that
is also passed to this function.

This is harmless for callers that always encode the direction bit
into 'eplog' (e.g. CDC/ACM's CDCACM_MKEPBULKIN()/MKEPINTIN(), which
OR in USB_DIR_IN), since 'in' then always agrees with that bit.  But
drivers/usbdev/usbdev_fs.c (the generic ADB/fastboot class driver)
calls DEV_ALLOCEP() with a bare endpoint number in 'eplog' (no
direction bit) and passes the direction only via the separate 'in'
parameter - matching this function's own "direction bit ignored"
contract for 'eplog' (see its Input Parameters doc, and the
pre-existing "Ignore any direction bits in the logical address"
comment, both dating back to the original driver in b860e3c4ad).
For such a bare-number IN endpoint, USB_ISEPOUT(eplog) always
evaluates true (the IN bit is never set on a plain number), so
RP2040_DPINDEX(eplog) silently pointed the endpoint's buffer/control
registers at its OUT slot instead of its IN slot.  The real IN slot
was left unconfigured, so the SIE responded to every IN token on
that endpoint with a STALL - confirmed on real hardware via usbmon:
'C Bi:1:050:6 -32 0' (EPIPE) on every attempt, while the paired OUT
endpoint (which "accidentally" resolved to the correct slot for the
same reason) worked fine.

Fix: normalize 'eplog' to agree with the explicit 'in' argument
before it is used by RP2040_EPINDEX()/RP2040_DPINDEX(), so both
macros keep their original, single-argument form and every use of
eplog's direction bit below this point is consistent with 'in'.
Existing 0x80-encoded callers (EP0, CDC/ACM) already agree with 'in'
and are unaffected by the normalization.

Also fix two pre-existing nxstyle violations in this same file
(a misaligned comment block under USB_REQ_SYNCHFRAME, and a bare
';' body instead of empty braces on a while loop), both dating back
to the original driver in b860e3c4ad as well; CI runs nxstyle on
the whole file whenever it is touched.

Assisted-by: OpenCode:claude-sonnet-5
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
2026-09-08 08:22:37 -03:00
zhangyu117
9b9d87b69c arch/atomic: remove up_testset in spinlock
Remove the per-arch testset implementation from the spinlock layer.

The testset abstraction predates the unified spinlock.h API and is no
longer used now that all arches provide spin_lock_irqsave()/
spin_unlock_irqrestore() directly.  Drop the per-arch *_testset.{c,S}
implementations and spinlock.h files for arm, sim, sparc, tricore,
x86_64, and xtensa, along with the CXD56_TESTSET,
CXD56_TESTSET_WITH_HWSEM, and CXD56_ATOMIC_WITH_HWSEM Kconfig options
in arch/arm/src/cxd56xx, and simplify the CXD56 semaphore pool loop
in cxd56_sph.c to a single unconditional range.

Signed-off-by: zhangyu117 <zhangyu117@xiaomi.com>
2026-09-08 08:58:54 +08:00
Justin Hammond
c47d7151d7 arch/risc-v/eic7700x: Maintain the data cache through the L3 controller.
The EIC7700X is not cache coherent.  No device that moves data on its
own snoops the harts' caches or is snooped by them, so a buffer handed
to a device needs the cache maintained around the transfer.  The harts
are coherent with each other; it is DMA that is not.

The RISC-V standard offers no way to do that here: the Zicbom extension
this core does not implement is the portable answer, and there is no
other.  Maintenance is instead a store to the L3 controller carrying the
physical address of a cache block.  That store is the only operation the
hardware offers: it writes back and invalidates together, so a block
cannot be dropped without being written out first.  Everything built on
top is shaped by that, which is why a range being invalidated has to own
whole blocks.

The L3 is inclusive of the L1 data cache and back invalidates it, so one
store per block maintains the whole hierarchy, with nothing to do per
hart.  The block size is 64 bytes, which is what makes the descriptor
rules in the storage and network drivers what they are.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-07 10:03:52 -03:00
Justin Hammond
1686bb6c9e arch/risc-v/eic7700x: Add CPU core clock control.
Drives the speed of the four application cores.  The rate is set to any
of the operating points the vendor validates, all of which share a core
voltage, so this touches no regulator.

The cores run from the PLL being reprogrammed, so they park on a slower
clock first, through a selector the vendor names as glitch free.  While
parked the PLL is stopped, given new dividers, restarted and watched
until it locks; if it never locks the cores stay parked, since returning
them to an unlocked PLL does not fail safely.

Above a gigahertz the bus ratio must be two to one before the cores
return: the bus fabric does not reach beyond about eight hundred
megahertz.  That is the one step in the sequence software cannot recover
from, so the mux is moved before the ratio.

The rate is measured rather than derived.  The cores are counted against
the crystal derived time counter and the result reported beside what the
clock tree computes, because the manual and the vendor's code number the
CPU PLL's outputs differently.  The core selector's parent is
cpupll_fout1, and the three CPU PLL outputs are marked
CLK_GET_RATE_NOCACHE since this driver reprograms that PLL at run time.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-07 10:03:33 -03:00
Jacob Dahl
304cbb1372 arch/arm/stm32h7: poll MDIO completion in microseconds, not 5 ms steps
stm32_c22_read() and stm32_c22_write() waited for the MACMDIOAR busy bit
with up_mdelay(5) between checks. A Clause 22 frame takes about 30 us,
so the first check always sees the bus busy and every PHY register
access costs a 5 ms busy-wait, roughly 150 times the transfer.

stm32_phyinit() waits for link-up with PHY_RETRY_TIMEOUT (6552) MSR
reads. With no cable attached that is 33 s of CPU spent in
up_mdelay() inside ifup, with the network lock held: on an STM32H753
the netinit thread pinned the core at 44% for the first 65 s after
boot and every socket operation on other threads blocked until it gave
up. Before the MDIO bus refactor, stm32_phyread() polled the busy bit
in a tight loop.

Poll every 10 us instead, with the timeout expressed in microseconds so
the total bound stays at 10 ms, and report the timeout from the result
rather than the loop counter so a transfer that completes on the last
iteration is not logged as timed out.

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
2026-09-07 09:57:52 -03:00
wangjianyu3
71499bd66e boards/rp2040: support reboot bootloader via reset_usb_boot()
Add reset_usb_boot ROM function typedef and wire it into
board_reset() so that 'nsh> reboot bootloader'
(BOARDIOC_SOFTRESETCAUSE_ENTER_BOOTLOADER) on RP2040 boards enters
BOOTSEL USB mass-storage mode directly, matching the behavior
already available on rp23xx boards.  All other status values keep
the existing up_systemreset() behavior.

This affects all boards under boards/arm/rp2040/common (pico,
pico-w, feather-rp2040, xiao-rp2040, w5500-evb-pico, etc.) since
the change is in the shared board_reset() implementation.

Assisted-by: GitHubCopilot:claude-4.6-opus
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
2026-09-05 10:36:07 +08:00
jsanchez-2g
6b5673a433 stm32g0: Add flash bank swap support
Add APIs to toggle the dual-bank flash mapping and reload the option bytes. Reject bank swapping when BOOT_LOCK is enabled and leave the swap operation as a no-op on single-bank devices.

Assisted-by: OpenAI Codex <codex@openai.com>
Signed-off-by: jsanchez-2g <jsanchez@2g-eng.com>
2026-09-05 10:34:48 +08:00
Justin Hammond
0a85476f7c arch/risc-v/eic7700x: Describe the clock tree the boot loader leaves.
Nothing in this port knew what any clock ran at, so a driver needing a
rate had to carry a hard coded one, which is wrong the moment the boot
loader changes.

Register the Clock and Reset Generator with the NuttX clock framework:
the PLLs, muxes, dividers and gates covering the low speed peripherals,
the U84 cluster, the RTC and timers, the NOC, boot SPI, SCPU, LPCPU, DDR
and TCU, the high speed peripherals, the always on DMA and secure blocks,
the GPU, DSP, die to die link and NPU, and the video input, output and
codec paths.  The tree is visible through /proc/clk.

Registration writes nothing: the tree comes up describing what the boot
loader left behind.  A clock moves only when a driver asks, by enabling a
gate, setting a divider or reparenting a mux.  A mux carrying a clock the
system is running on will speed up on request and refuses to slow down,
because that changes the timing every driver downstream was configured
for while they are using it.

The PLL post divider fields do not sit where the TRM's register diagram
puts them; they are ordered here to match the rates the tree reports.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-04 15:56:37 -03:00
Justin Hammond
01106b4784 arch/risc-v/eic7700x: Add the blank lines nxstyle asks for.
Two declarations in eic7700x_start.c are followed immediately by a
statement, which nxstyle reports as "Missing blank line after
declarations".  Both predate this series and are already in master, but
CI runs checkpatch over the whole range rather than per commit, so any
change touching this file is reported against them.

Whitespace only, no functional change.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-04 15:56:37 -03:00
Marco Casaroli
0d31418ba8 arch, boards, cmake: Build C++ ELF modules without __cxa_atexit.
A C++ module with a static object does not link.  GCC registers each such
object's destructor with __cxa_atexit(dtor, obj, &__dso_handle), and
__dso_handle comes from crtbegin, which a module does not link:

  hello++3.cxx:119: undefined reference to `__dso_handle'

It is reachable today with CONFIG_PIC, where a module is linked as an
executable and the symbol has to resolve.  Without it the link is
relocatable, the symbol stays undefined and nothing complains until
something makes it resolve.

-fno-use-cxa-atexit registers the destructors with atexit() instead, which
puts them in .fini_array.  That is also where libelf_uninit() looks for them
when the module is unloaded, so the flag that makes the link work is also
the flag that makes the destructors run.

The option goes wherever CXXELFFLAGS is defined, which is the architecture
Toolchain.defs and the boards that reassign it.  The toolchains that are not
GCC or Clang are left alone: ceva, tricore, z16 and the z80 family.

The CMake build sets it once, next to where the architecture elf.cmake is
included.  A generator expression keeps it off the C compiles, because the
option is valid for C++ alone and GCC warns about it otherwise, and the
compiler id gates it so that a toolchain which is neither GCC nor Clang does
not see it.  It cannot go in the toolchain file itself: CMake reads that file
again inside try_compile, in a project that has not included the NuttX
extensions, so the call is an unknown command there.

Reproduced with apps/examples/elf on mps3-an547:picostest with CONFIG_PIC
enabled: hello++3 fails to link before and links after.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-04 15:44:24 -03:00
AlmAck
784c6519de arch/arm/nrf53: enable the application core flash cache
The nRF5340 application core comes out of reset with its flash cache
disabled and nothing in the tree turns it on.  nrf53_start() does call
nrf53_enable_icache(), but that drives NVMC ICACHECNF and is gated on
NRF53_FLASH_PREFETCH, which depends on NRF53_NETCORE -- so it is not
even compiled for an application core build.

The nRF5340 places the application core cache in a separate CACHE
peripheral at 0x50001000.  NRF53_CACHE_BASE is already defined in
hardware/nrf53_memorymap_cpuapp.h, but there was no register header and
no enable.  Add both, behind a new NRF53_CACHE option.

The option defaults to n, matching ARMV7M_ICACHE and
ARMV8M_ICACHE/DCACHE, so that upgrading does not silently change the
behaviour of an existing configuration.

Measured on nrf5340-dk at 64 MHz with apps/benchmarks/scbench:

  protected-build syscall round trip   64.1 us -> 29.6 us
  userspace sem wait + post pair       4.75 us -> 1.95 us

Flat builds benefit equally; the gain is on any flash-resident code
path.

Per the nRF5340 Product Specification, 'CACHE - Instruction and data
cache', 'both instruction and data accesses towards flash memory or XIP
code regions are cached'.  The cache does not observe NVMC programming,
so nrf53_flash.c has to account for it: both up_progmem_eraseblock() and
up_progmem_write() read back what they just programmed to verify it, and
up_progmem_ispageerased() reads a whole page, so lines covering the
region being programmed are commonly resident.  Bypass the cache for the
duration of an erase or a write and invalidate it before re-enabling, so
the verify reads the array and later readers do too.  That file is built
only when NRF53_PROGMEM is selected, which is not the default.

Signed-off-by: AlmAck <gluca86@gmail.com>
2026-09-04 13:50:15 -03:00
jsanchez-2g
b75b93fd32 stm32g0: Fix erase bank selection after bank swap
The flash page number follows the logical memory mapping, but BKER selects a physical flash bank. Account for the nSWAP_BANK option when selecting BKER so erasing a logical address targets the corresponding physical bank after a swap.

Assisted-by: OpenAI Codex <codex@openai.com>
Signed-off-by: jsanchez-2g <jsanchez@2g-eng.com>
2026-09-04 13:44:51 -03:00