Commit graph

17398 commits

Author SHA1 Message Date
Royyan Zahir
5f5991a0f2 arch/arm: redirect an M-profile thread to its signal action once
A signal action queued at syscall return pends PendSV for the running
thread, but the same SVC can switch to another thread first. PendSV then
saw that thread, the redirect was lost and the handler did not run until
a later PendSV landed on the target, which could happen while it was
already in arm_sigdeliver: the second redirect overwrote saved_regs, the
inner delivery cleared sigdeliver and the outer one branched to address
0. ostest sighand and signest hard faulted in a protected build.

The redirect is now checked against the thread being switched in, and a
thread already redirected is left alone until arm_sigdeliver restores
its context.

Signed-off-by: Royyan Zahir <royzah@gmail.com>
2026-10-09 15:08:33 -03:00
Ari Kimari
3e456050d3 arch/arm/imxrt: RT1180evk QSPI flash pin and clock configs
Add QSPI flash pin and clock configs

Signed-off-by: Ari Kimari <ari.kimari@tii.ae>
2026-10-09 15:06:56 -03:00
Ari Kimari
afa5c7c65b arch/arm/imxrt: rt118x ocram heap size fix
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
Fix OCRAM heap for rt118x

Signed-off-by: Ari Kimari <ari.kimari@tii.ae>
2026-10-09 22:39:51 +08:00
jsanchez-2g
6189fefdcf arm/stm32h7: Include LSI helper when both consumers are enabled.
The filter expression for CONFIG_STM32_IWDG and CONFIG_STM32_RTC_LSICLOCK
returns "y y" when both are enabled. Comparing that result with "y"
omits stm32_lsi.c, leaving calls to stm32_rcc_enablelsi() unresolved.

Test for a nonempty result instead. Include the helper once when either
or both consumers are enabled, and omit it when neither is enabled.
This changes source selection only, without changing clock or watchdog
policy.

Assisted-by: Codex:GPT-6
Signed-off-by: jsanchez-2g <jsanchez@2g-eng.com>
2026-10-09 18:28:06 +08:00
msli-dev
494cadb869 stm32h7/sdmmc: Add configurable IDMA bounce buffering.
Use per-instance aligned buffers for memory that SDMMC IDMA cannot
access directly or that does not meet cache alignment requirements.
Copy writes before IDMA and copy successful bounced reads in the
waiting thread. Report the configured capacity through maxrequest.

Keep a positive IDMA RAM allow-list and runtime setup validation.
Invalidate only the actual DMA destination, prioritize errors over
DATAEND, and stop data access before releasing buffer ownership.
Reset an active data path on abort while restoring host bus settings;
clear cancellation state and handle immediate/watchdog-start errors.

This commit contains the STM32H7 driver and its Kconfig changes only.
The preceding commit supplies the common SDIO/MMCSD functionality.

Assisted-by: Codex:GPT-6
Signed-off-by: msli-dev <747640013@qq.com>
2026-10-09 18:26:12 +08:00
Jukka Laitinen
70e453c2c4 [UPSTREAM] arch/arm/imxrt: Improve imxrt_lpi2c_reset
Re-initialize the bus even in the case the bus cannot be re-covered. The
client still has a reference to the bus, and may try to access it again.
If the bus is not initialized or the root clock is off, the access may
cause a crash.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-10-09 18:05:05 +08:00
Lourens Naude
447ebd7fd5 arch/arm/src/imxrt: Start the DWT cycle counter for perf events.
CONFIG_ARCH_PERF_EVENTS is on by default for ARMv7-M, but imxrt never
called up_perf_init(), so perf_gettime() read zero and anything timed
with it, rpmsg_ping for one, reported 0 ns.  Initialise the counter with
BOARD_CPU_FREQUENCY after the MPU is set up, as samv7 and stm32h7 do.

Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Lourens Naude <lourens@bearmetal.eu>
2026-10-09 17:54:07 +08:00
Marco Casaroli
a6ddfcd360 arch/arm/rp23xx: Add suspend to RAM in the POWMAN P1.0 state.
P1.0 powers the switched core off and keeps the XIP cache and SRAM.
Every peripheral loses its registers, so the chip comes back through
the bootrom and the ordinary boot, not from the WFI.  The idle governor
never selects it: an application asks for it with the new
BOARDIOC_RP23XX_SUSPEND boardctl() command (arch/chip/pm.h, handled by
the common rp23xx board_ioctl()).

rp23xx_pm_suspend():

- saves the NVIC, writes a marker to POWMAN SCRATCH0, and arms the
  wake: the RP23XX_PM_WAKEUP_GPIO pin in a POWMAN power-up detector,
  and the always-on timer alarm for a timed wake.  An armed RTC alarm
  that comes first powers the chip up itself, so an application can
  set the wake with RTC_SET_ALARM.  Otherwise the RTC alarm is saved
  with the new rp23xx_rtc_savealarm() and given back after the wake
  with rp23xx_rtc_restorealarm().
- cleans the XIP cache, with the RP2350-E11 workaround, because the
  resume discards it and PSRAM can hold task stacks.
- requests P1.0 and waits in WFI.

On the next boot, __start asks rp23xx_pm_resume_pending() (the marker
and CHIP_RESET.HAD_SWCORE_PD) before .bss and .data are touched.  For a
resume it moves to its own stack, because the idle thread still runs on
the idle stack, sets up the hardware with the cold boot code (now
rp23xx_hwinit()), and longjmps back to the suspended thread.  The UARTs
are set up from the driver state in RAM, the PSRAM format is applied
again without detection (the part is still in quad mode), the dormant-
wake GPIOs are armed again (the IO bank lost them, and the next dormant
period could then never end), and the time of day is taken from the
always-on timer.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-09 06:17:57 -03:00
Marco Casaroli
b685c69f25 arch/arm/rp23xx: Add the PM standby and dormant states.
Map the NuttX PM states onto the RP2350 low-power modes:

- PM_STANDBY is the RP2350 SLEEP state: a WFI with the clocks of the
  blocks that have no driver in the configuration gated (SLEEP_EN0/1).
- PM_SLEEP is the DORMANT state: clk_sys moves to the crystal
  oscillator, the PLLs and then the oscillator stop, and the clock tree
  is restored after the wake, as pico-extras does.  Only the GPIO
  dormant-wake detector can wake the chip, so PM_SLEEP gives the
  standby state when no wake GPIO is configured.  The wake GPIO also
  raises a one-shot interrupt, so that the core leaves its WFI and
  restores the PLLs at once.  The time of day is taken back from the
  always-on timer after the wake.

The dormant state stops the UARTs.  A PM_STANDBY wakelock
(pm_staytimeout()) is held for RP23XX_PM_WAKE_HOLD_MS after a dormant
wake and after each character a UART receives.  The serial driver
refuses PM_SLEEP in its prepare callback while a UART transmits.  A
dormant chip does not answer SWD, so the pm configurations use
PM_GOVERNOR_EXPLICIT_RELAX to stay out of it for a time after boot.

With RP23XX_PM_QUIESCE_PADS, arm_pminitialize() also isolates the
unused pads and holds the blocks with no driver in reset.  A floating
bank 0 input settles near 2.2V (erratum RP2350-E9) and its input
buffer then draws a static current in every state.

Also select ARCH_HAVE_PM, and fix the LED PM callbacks of three boards,
which used BOARD_LED where the boards define BOARD_LED1.  They did not
build with CONFIG_PM.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-09 06:17:57 -03:00
Marco Casaroli
5e7ea1ada6 arch/arm/rp23xx, boards/rp23xx: Fix nxstyle errors in files PM touches.
Add the blank line after the declarations in up_putc() and in
rp23xx_led_pminitialize() of three boards.  Whitespace only.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-09 06:17:57 -03:00
Marco Casaroli
a7e83c7fb5 arch: Let pgalloc() extend the selected address environment.
pgalloc() grows a process heap for sbrk().  It extended the address
environment of the running task (addrenv_own).  While exec() sets up a
new process, the caller selects the new address environment and
allocates the new process's stack from its heap.  When that stack does
not fit in the initial heap, the heap must grow, but the running task is
the caller.  For the kernel thread that starts init this was an
assertion; for a user task it would have grown the caller's heap.

Use the selected address environment (addrenv_curr).  For a normal sbrk()
it is the same as addrenv_own.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-09 06:10:52 -03:00
Jukka Laitinen
aba65b2a76 arch/arm/imxrt: Add support for uSDHC switch to HS mode
This allows using >25MHz bus speeds by adding a configration option
to set SDIO_CAPS_SD_HS_MODE capability.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-10-09 12:29:40 +08:00
Jukka Laitinen
f5edfc61df arch/arm/imxrt: Support imxrt118x in the uSDHC driver
- Add the missing clock gating macros for imxrt118x
- Change sw_cd_gpio from int32_t to gpio_pinset_t (64-bits on 118x)
- Invalidate cache again after the data has been received. Cache might
  be refilled by a prefetch or, in theory, by cpu read touching the same
  cache line - even though the latter should not happen.
- Map any DMA accesses to/from DTCM to the shadow address window, which
  gives the uSDHC DMA access to the DTCM.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-10-09 12:29:40 +08:00
Royyan Zahir
e9bafae796 arch/arm/imxrt: finish the CAAM job ring reset
A JRCR reset only flushes and halts the job ring; a second reset, once
JRINT reports the halt done, completes it, as Linux's caam_reset_hw_jr()
does. With the single write the ring stayed halted, so the RNG
instantiate job never completed and every boot logged "job ring did not
answer" before the settle loop's second ring init finished the reset.

Signed-off-by: Royyan Zahir <royzah@gmail.com>
2026-10-08 16:18:42 -03:00
Marco Casaroli
446a7d6934 arch/arm/rp23xx: Clear the DMA callback before invoking it.
The completion handler did:

    dmach->callback(...);
    dmach->callback = NULL;     /* after the call */

so a callback that registers itself again -- which is the only way for a
driver to keep a channel running continuously -- has that registration
wiped the moment it returns.  The channel transfers one more block and
then goes deaf, with no error raised anywhere and nothing in the
registers to say why.  A PWM audio driver hit this and worked around it
by restarting from a thread instead, which put a millisecond of silence
into every buffer boundary.

Lift the callback and its argument out first and clear them before the
call.  One-shot behaviour is unchanged for every existing user, since
none of them re-register from inside the call; the difference is only
that one which does now survives.

Tested on a Pimoroni Pico Plus 2 W (pimoroni-pico-plus-2-w:nsh) with a
local test: a memory-to-memory transfer whose callback starts the next
one, 100 times.  Master gives 1 completion of 100; this change gives 100.
The existing users (SPI, I2S, CYW43439, WS2812) do not start a transfer
from inside the callback, so they do not change.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-08 15:53:54 -03:00
Marco Casaroli
67bf46e3b0 arch/arm/rp23xx: Fix the nxstyle error in rp23xx_dmac.c.
nxstyle reports "Missing blank line after declarations" in
rp23xx_dmachannel().  Add the blank line, because CI checks every file
that a change touches.

No functional change.  The change is whitespace only.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-08 15:53:54 -03:00
raiden00pl
f093edb26c arch/arm/stm32h5: Use common Cortex-M33 USART support
Select STM32_HAVE_IP_USART_M33_V3 and drop the family serial, USART
header, and low-level console sources. Provide the USART clock and RCC
gate definitions for all thirteen ports in stm32_rcc_m33.h and the RX
DMA request numbers in the family DMA signal map. Include the family
DMA header from stm32.h so the common driver reaches the DMA API.

Extend the common Cortex-M33 v3 USART support with the STM32H5
features: USART6, UART7-9, USART10-11, and UART12 ports, the LPUART
prescaler for low baud rates, RX DMA through the family-provided
request number, wakeup-from-stop CR3 definitions, and per-port
descriptors gated by the family peripheral options.

Enable the USART FIFO for every Cortex-M33 family. The low-level
console uses the per-port kernel clock and RCC gate, which corrects
the UART9 and UART12 enable register. The RX DMA callback delivers
data only while reception is enabled.

The non-BSD break ioctl now uses the send-break request register
instead of a CR1 bit this USART IP does not have. Correct the UART12
gates and the RXDMA and console undef lists in the USART driver
header. Raise STM32_NUSART to six on the H56x and H57x parts so UART12
fits the device table, add the missing UART9 buffers, write LPUART CR1
only on the USART path, and build device names with snprintf so minors
above nine are valid.

Keep the termios flow control fields writable so TCSETS compiles with
input flow control, let up_putc emit a bare newline since syslog adds
the carriage return, and make the unconfigure-on-close options
available to every Cortex-M33 family.

Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
2026-10-08 15:53:21 -03:00
raiden00pl
ba50b9d27d arch/arm/stm32h5: Use common Cortex-M33 GPIO and EXTI drivers
Select STM32_HAVE_IP_GPIO_M33_V1 and STM32_HAVE_IP_EXTI_M33_V1 and
drop the family GPIO and EXTI sources and headers in favor of the
common Cortex-M33 v1 implementation. Add the RM0481 line count for the
H56x and H57x parts to the common EXTI line inventory.

Add GPIO_PORTI to the common Cortex-M33 pin encoding for the parts
with a ninth GPIO port.

Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
2026-10-08 15:53:21 -03:00
raiden00pl
15c02fde29 arch/arm/stm32h5: Use common Cortex-M33 core support
Enable STM32_COMMON_M33 for STM32H5 and drop the family reset, NVIC,
SysTick, and idle sources in favor of the common Cortex-M33 v1
implementation. The common heap allocator replaces the generic ARM one
through a STM32_PRIMARY_SRAM_SIZE spanning the contiguous SRAM banks
and skips the SRAM2 region when the primary heap already covers it.

Rename the family RCC header to stm32_rcc_m33.h for the common RCC
dispatch.

Add the SRAM3 parity initialization block and the CONFIG_STM32_ICACHE
enable call to the common reset handler, taken from the STM32H5 start
logic. Without CONFIG_STM32_ICACHE the reset handler disables an
ICACHE left enabled by a bootloader on STM32_HAVE_ICACHE families.

Move the flat-build MPU initialization to stm32_mpuinit_m33_v1.c in
common/stm32, built for every Cortex-M33 family with ARM_MPU, and
declare stm32_mpuinitialize for ARM_MPU as well as protected builds.
Declare stm32_board_initialize in the common start header.

Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
2026-10-08 15:53:21 -03:00
dechao_gong
4e6ad4fb56 arch/arm/rtl8730e: add I2C master driver support
Expose the RTL8730E I2C controllers through the shared Ameba I2C driver
(arch/arm/src/common/ameba/ameba_i2c.c) by adding the chip-specific
glue, build wiring and a board bus table.  The change is gated by
CONFIG_AMEBA_I2C (default disabled).

Chip glue (ameba_i2c_chip.h) supplies the three controller register
bases, the APB function/clock masks -- amebasmart encodes these in
bit 25/26/27 with the group selector bit30=0, unlike the (bit30 |
bit10/11) layout of the KM4-based parts -- and the pad-mux code.
amebasmart has a single generic PINMUX_FUNCTION_I2C shared by every I2C
pad instead of per-signal SCL/SDA crossbar codes, and its
I2C_InitTypeDef omits the DMA request-level fields, so
AMEBA_I2C_HAS_DMA_FIELDS stays undefined.  The whole I2C fwlib lives in
ram_common/ameba_i2c.c rather than lib_rom.a, so it is compiled into
libameba_fwlib.a when I2C is enabled.

The shared driver gains an optional per-controller IP-clock hook,
AMEBA_I2C_IPCLK_FN(bus).  amebasmart needs it because its
I2C_StructInit() fills in a 10 MHz placeholder rather than the real
reference clock (the other Ameba parts fill in a correct XTAL_ClkGet()
/ PLL_GetHBUSClk() / HPERI_ClkGet()), which makes I2C_SetSpeed()
miscompute the SCL counts.  The hook resolves the rate at run time: the
two HS controllers sit on HS_AHB, i.e. NP_PLL divided by
REG_LSYS_CKD_GRP0.CKD_HBUS, so it is a PLL/board setting and not a
constant -- an EVB measured CKD_HBUS=8 (div9, 88.9 MHz) while the SDK's
own I2CCLK_TABLE claims a flat 100 MHz and the register reset value
would imply 80 MHz.  The LP-domain I2C0 keeps its fixed 20 MHz.  Chips
that leave the macro undefined use the fwlib default and are
unaffected; regression-tested on pke8721daf:i2c.

All three controllers are registered: /dev/i2c0 on PA9/PA10, /dev/i2c1
on PA3/PA4 and /dev/i2c2 on PB10/PB11.  Pad choice is constrained on
this chip -- a pad reaches exactly one controller (SDA fixed per
controller, SCL the next pad up), and the pads inside the analogue
audio ranges (PA20-PA29, PA30-PB2, PB3-PB6) are driven by the codec and
leave the bus stuck idle.  Both rules are noted in the table's
comment.

Also add a weak DiagVprintf stub: the I2C fwlib logs through RTK_LOGx()
-> rtk_log_write(), and unlike DiagPrintf that symbol is not in the AP
ROM symbol table.  It is weak so the strong definition in
rtl8730e_wifi_stubs.c still wins when WiFi is enabled; both route to
vprintf.

Hardware-verified on an RTL8730E EVB against a second board running an
I2C slave: register read, write, write/read round-trip, multi-byte dump
and a full address scan, on all three buses at 100 kHz.

Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Assisted-by: Claude <noreply@anthropic.com>
2026-10-08 15:49:34 -03:00
jsanchez-2g
6e41066215 arm/stm32h7: Allow PendSV with high-priority interrupts.
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
With CONFIG_ARCH_HIPRI_INTERRUPT enabled, arm_doirq() dispatches PendSV
for deferred processing. The STM32H7 debug handler unconditionally panics
on that valid interrupt, preventing normal operation with debug enabled.

Guard the panic with CONFIG_ARCH_HIPRI_INTERRUPT, allowing the common
interrupt path to finish signal delivery and context switching. Preserve
the diagnostic when high-priority interrupts are disabled.

Assisted-by: Codex:GPT-6
Signed-off-by: jsanchez-2g <jsanchez@2g-eng.com>
2026-10-08 10:36:28 -03:00
raiden00pl
a57a5f656b arm/nrf54l: add USBHS device support
arm/nrf54l: add USBHS device support

Assisted-by: Codex:GPT-6
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-10-08 09:54:55 -03:00
Jukka Laitinen
9cf38e7fbe arch/arm/imxrt: Make performance optimized memory configuration for M7 NSH
Change the imxrt1180-evk M7 NSH configuration to use the SoC memories
more efficiently:

- Place .data, .bss, idle stack and primary heap into DTCM
- Allocate available OCRAM as a secondary heap
- Add a separate .dmamemory section in OCRAM for USB device DMA
  allocations
- Place .ramfunc into ITCM, together with hand-picked "hot" functions.
  The section is copied to ITCM at boot by the ramfunc copy.

The eDMA accesses DTCM through the SoC's dedicated bus window.

This configuration acts as an example of performance optimization for
imxrt1180 based boards.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-10-08 16:25:44 +08:00
Jukka Laitinen
23ae7e4073 arch/arm/imxrt: Add eDMA support to/from M7 DTCM for imxrt1180
Cortex-M7 core's DTCM is available for other peripherals via a
dedicated address space. If transfers are done to or from the DTCM,
translate addresses to work on this shadow memory region instead, via
which the eDMA can access the DTCM.

This allows using the existing imxrt peripherals, which use DMA, to work
directly even if .data/.bss are located in DTCM.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-10-08 16:25:44 +08:00
Ari Kimari
3a5d5e08d5 arch/arm/imxrt: Add M7 DTCM/ITCM ECC initialization for imxrt118x
Add support for Cortex-M33 code to initialize the M7 TCM memories before
releasing it to run. The TCM has ECC, which needs to be initialized before
the memory is usable for M7.

Specifically, the TCM needs to be initialized sequentially in 64-bit writes.
Use eDMA4 for this; this is the same mechanism which the NXP MCUXpresso SDK
code does.

Split imxrt118x_release_cm7() into imxrt118x_prepare_cm7() and
imxrt118x_start_cm7(). The TCM ECC initialization is done in
imxrt118x_prepare_cm7(), after the M7 has been released from reset and
before the M7 is started. Also reset M7_CFG[TCM_SIZE] to the default
256 KiB ITCM / 256 KiB DTCM layout.

Co-Authored-By: Jukka Laitinen <jukka.laitinen@tii.ae>
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-10-08 16:25:44 +08:00
Jukka Laitinen
59faf7ed2b arch/arm/imxrt: Clean up imxrt118x System Reset Controller definitions
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
Move the imxrt118x SRC register defintions to an own file. They differ
from the other imxrt chips, and were also scattered between blockctrl
and a common imxrt_src headers.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-10-08 13:41:38 +08:00
Marco Casaroli
e7f9aaa52b arch/arm/rp23xx: Check the flash MTD region against the flash size.
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
RP23XX_FLASH_MTD_OFFSET and RP23XX_FLASH_MTD_SIZE come from Kconfig.
If the region ends past the end of the flash, the flash wraps the
address around, and an erase or program hits the start of the flash,
where the NuttX image is.  For example, a 4M region at 1M does not
fit on the 4M flash of a Raspberry Pi Pico 2.

Read the JEDEC ID at initialization, in QMI direct mode as the Pico
SDK flash_do_cmd() does, and refuse a region that does not fit.  The
capacity byte is log2 of the size in bytes.  If the ID does not look
valid, warn and do not check.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-07 18:45:43 -03:00
Marco Casaroli
cb87f99b6e arch/arm/rp23xx: Keep flash writes off PSRAM and flash data.
While the bootrom erases or programs the flash, the QMI is in direct
mode, and an access to the XIP space (flash or PSRAM) gives a bus
fault.  The flash MTD driver accessed it in two cases:

- The data to program was in flash or PSRAM.  flash_range_program()
  read it during the operation.  Now the driver copies each such page
  to an SRAM buffer first.
- The caller's stack was in PSRAM.  This is the normal case with
  RP23XX_PSRAM_HEAP_USER, and possible with RP23XX_PSRAM_HEAP_SINGLE.
  The operation pushed to that stack.  Now the driver switches to a
  small SRAM stack for the operation if the stack is in the XIP space.

The operation data is static (SRAM) since the previous commit.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-07 18:45:43 -03:00
Marco Casaroli
75f8249405 arch/arm/rp23xx: Erase and program the flash in small steps.
The flash MTD driver disabled interrupts for a whole request.  A
multi-block erase or a large write kept them off for seconds.

Erase one 64K block (or one 4K sector where the range is not block
aligned) and program one 256 byte page per step.  Enable interrupts and
release the other core between steps.  A single block erase is still
long, but that is the limit of the flash.

Also, on SMP:

- Do not send the pause call to the CPU that does the operation.
  nxsched_smp_call_single_async() runs it at once on that CPU.
- Keep the isolation data in a static, not on the stack.  The other
  CPU spins on it while the flash is busy.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-07 18:45:43 -03:00
Marco Casaroli
1d8898d7d6 arch/arm/rp23xx: Restore XIP with the bootrom XIP setup function.
After a flash operation the driver called flash_select_xip_read_mode()
with a fixed EBh quad mode and clock divisor 4, and called
flash_enter_cmd_xip() if it "failed".  But that ROM function returns
void, so the check read a random r0.  The fixed mode and divisor can
also be different from the ones the bootrom found at boot.

The datasheet (5.2.7, 5.4.8.10) and the Pico SDK use a different
method: after a flash boot the bootrom leaves an XIP setup function in
the first 256 bytes of boot RAM.  It restores the read mode and clock
divisor found at boot.  Boot RAM is not executable, so copy the
function to SRAM once at initialization, and call the copy.

If boot RAM is empty (no flash boot), use flash_enter_cmd_xip(), as
RP23XX_FLASH_MTD_SAFE_XIP does.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-07 18:45:43 -03:00
Marco Casaroli
ecc0036470 arch/arm/rp23xx: Save and restore the QSPI state around flash writes.
The bootrom flash functions reset the QMI window 1 (chip select 1)
registers and the QSPI pads.  flash_flush_cache() also discards dirty
XIP cache lines.  The flash MTD driver did not save anything, so after
the first erase or program the PSRAM on chip select 1 read garbage,
and PSRAM writes still in the cache were lost.

Do what the Pico SDK hardware_flash library does:

- Clean the XIP cache before the operation.  Clean by set/way through
  the top of the maintenance window, to avoid erratum RP2350-E11.
- Save the QSPI pads and the five QMI M1 registers before, and write
  them back after XIP is restored.  Also keep XIP_CTRL.WRITABLE_M1.

rp23xx_psram_restore() was the earlier fix for this, but nothing called
it.  Remove it.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-07 18:45:43 -03:00
Marco Casaroli
d3e856c56e arch/arm/rp23xx: Add RTC alarm support on the POWMAN always-on timer.
The always-on timer has an alarm comparator, but the RTC driver did not
use it: rp23xx_rtc.c implemented only up_rtc_initialize(),
up_rtc_time() and up_rtc_settime().

Add the alarm and an RTC lower half for /dev/rtc0:

- rp23xx_rtc_setalarm(), rp23xx_rtc_cancelalarm() and
  rp23xx_rtc_rdalarm() on the ALARM_TIME registers and the POWMAN
  timer interrupt.
- An RTC lower half with rdtime, settime, setalarm, setrelative,
  cancelalarm and rdalarm, registered by the common board bringup.

The comparator asserts while the time is past the alarm time, not on
a transition.  So the interrupt handler disables the alarm before it
does anything else; clearing only the status makes the interrupt
repeat.  The arming sequence is the one of
powman_timer_enable_alarm_at_ms() in the Pico SDK.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-07 16:22:56 -03:00
Marco Casaroli
7da84f254e arch/arm/rp23xx: Use the right formats in the PWM period message.
setup_period() printed the uint8_t slice number with %d, and the
uint32_t frequency, the uint16_t top and the uint32_t divisor with %lu.
Use %u for the two small fields and PRIu32 for the two uint32_t fields.

No build warns about this today, because GCC does not check syslog
format strings.  It shows with CONFIG_DEBUG_PWM_INFO only.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-07 16:05:40 -03:00
Marco Casaroli
c383121e80 arch/arm/rp23xx: Fix the nxstyle errors in rp23xx_pwm.c.
Indent the three else blocks and the switch in rp23xx_pwm_ioctl() as
nxstyle wants.  Whitespace only; git diff -w is empty.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-07 16:05:40 -03:00
raiden00pl
3adaf8e043 arm/nrf54l: add TWIM support
arm/nrf54l: add TWIM support

Assisted-by: Codex:GPT-6
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-10-08 01:45:35 +08:00
Marco Casaroli
ebabdd57f3 arch/arm: Keep GCC from making tail calls in an FDPIC module.
With -mfdpic and -mlong-calls, GCC turns a call to an imported function
in tail position into "ldr r3, [r9, #off]; bx r3".  The GOT slot holds
the address of the function descriptor, so the branch goes to the
descriptor in RAM instead of through it, and the core faults.  A normal
call loads the code address and the data base from the descriptor
first.  GCC 13.2 and 15.3 both do this.

Only an optimized build makes tail calls.  The C++ library of
apps/testing/fs/xipfs then faults in its constructor, which ends in a
call to syslog(), and the test stops at "stage the C++ module".

Pass -fno-optimize-sibling-calls with the other FDPIC flags, in the make
build and the CMake build.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-07 11:45:09 -03:00
Marco Casaroli
00e51b847a arch/arm: Pass --fdpic to the assembler for an FDPIC module.
GCC before 14 does not pass --fdpic to the assembler when it compiles
with -mfdpic.  The assembler then rejects every FDPIC relocation with
"Relocation supported only in FDPIC mode".  The NuttX CI image has GCC
13.2, so the crt0.o of an FDPIC configuration does not build there.

Pass -Wa,--fdpic with -mfdpic, in the make build and the CMake build.  A
newer GCC passes the same option itself.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-07 11:45:09 -03:00
Marco Casaroli
f26dbe7870 arch/arm/cmake: Link an FDPIC shared library as a shared object.
With CONFIG_FDPIC, the CMake build gave the FDPIC options to a loadable
module only.  A shared library (DYNLIB) got neither -mfdpic nor the FDPIC
link, but the "-r" link of the non-FDPIC case.  So the library was a
relocatable object, and a module that named it in DT_NEEDED did not link:
"multiple definition" and "dangerous relocation".

Give a shared library the same options as a module, as LDMODULEFLAGS and
CMODULEFLAGS in common/Toolchain.defs already do for the make build.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-07 11:45:09 -03:00
raiden00pl
9e8c81cf4c arm/nrf54l: add SPIM 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
arm/nrf54l: add SPIM support

Assisted-by: Codex:GPT-6
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-10-07 22:10:48 +08:00
Peter van der Perk
7fff8b746b arch/arm/src/imx9: add GPIO5 base address for i.MX95
The i.MX95 has five GPIO instances, but g_gpio_base[] only listed the
first four.  IMX9_GPIO_BASE(n) indexes this table directly, so any
access to port GPIO5 read one element past the end of the array and
caused a crash.

The table was previously selected on CONFIG_ARCH_CHIP_IMX9_CORTEX_M,
which covers both the i.MX93 M33 and the i.MX95 M7.  Since the i.MX93
only has four GPIO instances and does not define IMX9_GPIO5_BASE, key
the five entry table off CONFIG_ARCH_CHIP_IMX95_M7 and keep the four
entry table for the i.MX93 (both the Cortex-A CONFIG_ARCH_CHIP_IMX93
and the Cortex-M CONFIG_ARCH_CHIP_IMX93_M33 variants).

Signed-off-by: Peter van der Perk <peter.vanderperk@nxp.com>
2026-10-07 08:50:46 -03:00
Jukka Laitinen
86632a8fb9 arch/arm/imxrt: Fix nxstyle issues on imxrt_usdhc.c
No functional change, only fixing existing nxstyle issues.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-10-07 08:43:10 -03:00
Ari Kimari
d4d3025059 arch/arm/imxrt: ROM api support
Add ROM api support for rt118x

Signed-off-by: Ari Kimari <ari.kimari@tii.ae>
2026-10-07 08:20:12 -03:00
Marco Casaroli
ed71eb7bc2 arch/arm/rp23xx: Compute the PSRAM QMI timing from the system clock.
RP23XX_PSRAM_M1_TIMING was the constant 0x61a07102.  The comment said
it matched the Pico SDK, but it does not.  The SDK computes the timing
from clk_sys and the APS6404 limits (133 MHz SCK, 8 us maximum select,
18 ns minimum deselect).  At 150 MHz it gives 0x60242202:

  field         old  SDK
  clkdiv        2    2
  rxdelay       1    2
  max_select    16   18
  min_deselect  7    2
  select_hold   3    0

The old RX delay samples the read data half a clk_sys cycle earlier
than the SDK does.  The constant is also wrong for any other clk_sys.

Compute the fields from BOARD_SYS_FREQ at build time, with the SDK
formula, and stop the build if a field is out of range.  The result
is identical to the SDK value at 48, 125, 150, 200, 266 and 300 MHz.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-07 08:19:42 -03:00
Marco Casaroli
860577d771 arch/arm/rp23xx: Wait for QMI direct mode after enabling it.
The RP2350 datasheet (12.14.5) says: set DIRECT_CSR.EN, then poll BUSY
until it is low, before the first direct-mode transfer.  BUSY stays high
while an XIP transfer is in its cooldown.  The Pico SDK waits here too.

rp23xx_psram_detect() did not wait at the two places where it enables
direct mode.  It worked on the boards we tested because the cooldown
ended before the first chip select.  Add the two waits, and put the
BUSY loop in one RAM-resident helper.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-07 08:19:42 -03:00
raiden00pl
20f3b65937 arm/nrf54l: add SAADC 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
arm/nrf54l: add SAADC support

Assisted-by: Codex:GPT-6
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-10-07 13:03:45 +08:00
raiden00pl
f8e6b90ce5 arm/stm32h7: add OctoSPI register definitions
add OctoSPI register definitions

Assisted-by: Codex:GPT-6
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-10-07 04:06:37 +02:00
raiden00pl
7f2ae8ffec arm/stm32h7: add STM32H735 support
add STM32H735 support

Assisted-by: Codex:GPT-6
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-10-07 04:06:37 +02:00
raiden00pl
ba9619bc2b arm/stm32h7: fix nxstyle errors
Fix nxstyle errors in stm32_gpio.c and stm32h7x3xx_rcc.c.

Assisted-by: Claude Code
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-10-07 04:06:37 +02:00
Marco Casaroli
dcd93b0f67 libs/libc/elf: Load the libraries a module names in DT_NEEDED.
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
A module that names a shared library in DT_NEEDED now gets it loaded and
its imports bound against it, rather than being refused.

libelf_insert() does the loading, which is what dlopen() calls anyway: the
library lands in the module registry like anything else, its exports come
back through libelf_getsymbol() -- the same call dlsym() uses -- and a
library named by two modules is loaded once.  A bare name is looked for
along LD_LIBRARY_PATH, where dlopen() looks for it.  Undefined symbols
resolve against the globally registered symbols first, then the modules
this one depends on, then the table exec() supplied.  Nothing here calls
into dlfcn, because this loader is also the kernel's module loader, which
has none.

Each library becomes one of the module's dependencies[], and the dependency
holds it in place of the reference libelf_insert() took.  So a library
loaded only for DT_NEEDED is kept by the modules that depend on it, and
libelf_undepend() unloads it with the last of them; one that dlopen() or
insmod also opened stays until that reference goes too.
CONFIG_LIBC_ELF_MAXDEPEND bounds how many libraries a module may name,
which is what it already meant.

Six things had to be fixed to make it work, none of which a build shows.

reldata was a file-scope global.  Loading a library from inside
libelf_relocatedyn() makes that function reentrant, so the nested load
overwrote the outer one's relocation offsets and the module resumed binding
with the library's DT_REL.  It is now per call.

A cross-object call needs the callee's data base, not the caller's.  A
symbol resolved from an FDPIC library comes back as a descriptor, and
R_ARM_FUNCDESC_VALUE was treating it as a code address and pairing it with
the importing module's GOT.  It now copies both words, so the library runs
with its own.

An object with no imports has no PLT and so no DT_PLTGOT, but it still has
a GOT and still has to be entered with it.  Without the fallback its
descriptors carried a data base of zero and the library read its globals
through a null pointer.

R_ARM_FUNCDESC, a pointer to a descriptor, wrapped a library's descriptor
in a second one.  It now stores the library's descriptor as it is.

The flag that says a resolved value is a descriptor was set only for an
import and never cleared, so the next relocation against a symbol of the
module itself took that symbol for a descriptor too.  It is cleared there.

libelf_symname() was static, and reading a DT_NEEDED name needs it.

A module with DT_NEEDED is refused where CONFIG_LIBC_ELF_MAXDEPEND is zero,
since that is where the dependency logic is compiled out.

A DT_NEEDED library is one shared instance, its data included, because the
loader returns the object already in the registry.  A module started with
exec() is different: that path loads the module afresh each time, so two
running instances have separate data while sharing one copy of the text.

Built for mps3-an547:picostest with CONFIG_FDPIC both ways.  Run on
mps2-an500:xipfs under QEMU: fdpicxip solib loads libcounter.so by name out
of DT_NEEDED, two instances share one pinned copy of its text, and the
library is unloaded, and its pin given back, when the second one exits.  A
library also opened with dlopen() stays loaded after its DT_NEEDED user
exits, and dlclose() unloads it.

With CONFIG_ARCH_ADDRENV the program runs in its own address space, which
a library libelf_insert() loads cannot reach, so DT_NEEDED is refused
there as before.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-06 17:48:49 -03:00
Ricardo Maurizio Paul
dc6e924a95 arch/arm/stm32h5: disable the ICACHE while program memory is modified.
An enabled ICACHE does not manage write transactions: it flags cacheable
writes as errors (ICACHE_SR.ERRF), and RM0481 8.4.5 recommends modifying
the memory with the ICACHE disabled.  On an STM32H563, erasing and
programming a flash block with the ICACHE enabled leaves ICACHE_SR at
0x6 (BSYENDF and ERRF set).

The ICACHE also keeps serving lines cached before the change.  When the
block had been read through the ICACHE just before it was programmed,
up_progmem_write() failed its read-back check with -EIO: the flash held
the new data, with no flash or ECC error flagged, but the read-back hit
the cached erased data.  up_progmem_eraseblock() fails its erased-range
check the same way when programmed data of the block is cached.

Disable the ICACHE for the duration of up_progmem_eraseblock() and
up_progmem_write(), and enable it again afterwards if it was enabled on
entry.  Disabling it invalidates it, so the refill after re-enabling it
sees the new flash content.

If the ICACHE cannot be re-enabled because its invalidate times out, it
is left disabled, which is safe but slower, and an error is logged.

Assisted-by: Claude:claude-sonnet-5-5
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Ricardo Maurizio Paul <ricardopaul@geotab.com>
2026-10-06 16:57:31 -03:00