Commit graph

63737 commits

Author SHA1 Message Date
Marco Casaroli
f8c0bc77fb arch/risc-v: Recover from a user fault without a kernel stack.
In CONFIG_BUILD_PROTECTED, a user task that touches memory it does not
own must be terminated on its own.  The rest of the system must keep
running.  riscv_fault_handler() already does this: it checks for a fault
taken from U-mode, sets TCB_FLAG_FORCED_CANCEL and changes the exception
return to _exit(SIGSEGV) in privileged mode.  But the whole block was
inside #ifdef CONFIG_ARCH_KERNEL_STACK.  Configurations that do not
select that symbol, such as rv-virt:pnsh and rv-virt:pnsh64, fell
through to PANIC_WITH_REGS().  A contained user-space bug stopped the
whole system.

Only the last line of the block needs a kernel stack:

    running_regs()[REG_SP] = tcb->xcp.ktopstk;

because xcp.ktopstk exists only with one.  Narrow the guard to that
assignment, so the rest compiles in all configurations.  arm64 already
does the same in arm64_fatal_handler().

It is correct to leave REG_SP unchanged.  In riscv_exception_common.S
the switch to the kernel stack at exception entry is also inside
#ifdef CONFIG_ARCH_KERNEL_STACK.  Without a kernel stack, the exception
frame goes on the user stack and REG_SP holds the user SP.
dispatch_syscall() already runs on that stack, so the kernel runs all
system calls of this task there, exit() included.  Running _exit on it
after a fault is the same case and adds no new exposure.  The stack also
stays mapped until the scheduler switches away, because a build without
a kernel stack cannot select CONFIG_ARCH_ADDRENV
(riscv_exception_common.S has an #error for that combination).

No behaviour change in other builds.  The recovery runs only when the
saved STATUS_PPP is clear, that is, when the fault came from U-mode.  In
CONFIG_BUILD_FLAT, tasks run at kernel privilege (M-mode, or S-mode on
the nsbi configurations), so STATUS_PPP is set and the panic path stays
the same.  CONFIG_BUILD_KERNEL configurations select ARCH_KERNEL_STACK
through ARCH_ADDRENV, so their code does not change.

Tested on QEMU with examples/sandbox and ostest.  On rv-virt:pnsh and
rv-virt:pnsh64 a forbidden read or write of kernel memory now kills
only the offending task, with status 2816 (SIGSEGV).  The shell and an
unrelated thread keep running.  Before this change the same access
caused a PANIC.  ostest exits with status 0 on both, before and after
this change.  rv-virt:knsh still builds, and its riscv_exception.o
differs only in the __LINE__ value of the PANIC call.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-08 15:50:39 -03:00
Marco Casaroli
05931b7014 Documentation: Describe the per-object wait lists of the scheduler.
nuttx_tasking.rst lists g_waitingforsemaphore, g_waitingformqnotempty and
g_waitingformqnotfull as task lists.  They no longer exist: a task that
waits for a semaphore, an event or a message queue is on a prioritized
wait list in that object.  Describe that, and remove the three lists.

Also spell "preempted" as codespell wants, because CI checks every file
that a change touches.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-08 15:50:03 -03:00
Marco Casaroli
7e6c2eaf00 fs/inode: Name the inode tree lock in the comments, not g_inode_sem.
Three comments say that the caller of inode_search() and
_inode_linktarget() holds the g_inode_sem semaphore.  That semaphore no
longer exists.  The caller holds the inode tree lock, from inode_lock()
or inode_rlock().  No code change.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-08 15:50:03 -03:00
Marco Casaroli
810c12770e sched: Remove the names of task lists that no longer exist from comments.
Three comments say that g_waitingforsemaphore must be prioritized, and the
message queue code says that its waiters are in g_waitingformqnotempty and
g_waitingformqnotfull.  These lists do not exist.  A task that waits for a
semaphore, an event or a message queue is on a prioritized wait list in
that object, which g_tasklisttable finds through TLIST_ATTR_OFFSET.

Say that in the comments.  No code change.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-08 15:50:03 -03:00
Marco Casaroli
7fde8a3d29 sched/init: Fix the nxstyle error in nx_start.c.
nxstyle reports "Bad left brace alignment" for the block that sets up
the heaps in nx_start().  Indent the block like the code around it,
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:50:03 -03:00
dechao_gong
b7069dc376 Documentation/rtl8730e: document the I2C master buses
Add a Features bullet and an "i2c" configuration section to the
RTL8730E EVB board page describing I2C0-2 as /dev/i2c0-2, the pads the
board table registers and the i2ctool scan command, following the
pke8721daf board format.

Note the two pad constraints that are specific to this chip: a pad
reaches exactly one I2C controller (unlike the GPIO and UART
crossbars), and the pads inside the analogue audio ranges are driven by
the codec and cannot carry I2C.

Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Assisted-by: Claude <noreply@anthropic.com>
2026-10-08 15:49:34 -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
Marco Casaroli
42fc52a1e9 arch/arm64: Implement up_addrenv_pa_to_va().
OpenAMP libmetal calls up_addrenv_pa_to_va() and up_addrenv_va_to_pa(),
and every virtio driver uses libmetal.  With CONFIG_DEV_SIMPLE_ADDRENV,
drivers/misc/addrenv.c provides both.  Without it, arm64 provides only
up_addrenv_va_to_pa(), in arm64_physpgaddr.c.  So an arm64 build with
an MMU and any virtio driver does not link, flat or kernel:

  undefined reference to `up_addrenv_pa_to_va'

The flat qemu-armv8a virtio configurations set CONFIG_DEV_SIMPLE_ADDRENV.
That does not fit a kernel build: its table gives the same address back
for a user address of the process.

Add up_addrenv_pa_to_va() next to up_addrenv_va_to_pa().  It translates
the page pool and the kernel RAM with arm64_pgvaddr(), and any other
address to itself.  up_addrenv_va_to_pa() must then give back the same
physical address, otherwise the function returns NULL, as
include/nuttx/arch.h specifies.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-08 14:52:28 -03:00
Marco Casaroli
8ed7f00450 libs/libc: Generate the system symbol tables in the CMake build.
With CONFIG_EXECFUNCS_SYSTEM_SYMTAB, the make build generates
exec_symtab.c from libc.csv, libm.csv and syscall.csv with the host
tool mksymtab.  CONFIG_LIBC_ELF_SYSTEM_SYMTAB does the same for
elf_sys_symtab.c.  The CMake build did neither, so a CMake configuration
with one of these options did not link:

  binfmt_execsymtab.c: undefined reference to `g_symtab'

Do the same in libs/libc/CMakeLists.txt: build mksymtab as a host tool,
sort the three lists by name, generate the table with the configured
array and count names, and add it to the C library.  mksymtab runs in
the build directory with relative names, so the output is the same as
from the make build.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-08 14:24:56 -03:00
Marco Casaroli
f565c81c3b Documentation, boards/rp23xx: Describe FDPIC and add a test configuration.
Documentation/os/binfmt/fdpic.rst covers what an FDPIC module is and what
it adds over the position independent ELF support already in the tree, how
the loader places one, where shared libraries come from and how they are
found, which entry points resolve a function descriptor and the rules for
adding another, and how to build a module and a library.  A comparison
table places it against NXFLAT and PIC ELF, and the reference section
records the object layout and the relocations.

pimoroni-pico-2-plus:xipfs-fdpic is the configuration the series was tested
on: xipfs on the board's QSPI flash, the ELF loader with CONFIG_FDPIC, and
apps/examples/fdpicxip with apps/testing/fs/xipfs.

CONFIG_DEFAULT_TASK_STACKSIZE is 4096 there rather than the rp23xx default
of 2048.  Both sides of the loader need it: a module that calls into the
firmware's printf family overflows 2048, and with no MPU that is a lockup
rather than a diagnostic.  CONFIG_ELF_STACKSIZE follows it, and
apps/testing/fs/xipfs sizes its own task from it.

CONFIG_HAVE_CXXINITIALIZE is set because crt0 runs the constructors of a
module only with it, and the xipfs suite checks that they ran.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-08 14:24:34 -03:00
Marco Casaroli
8e283e3acd boards/pimoroni-pico-2-plus: Define _sinit and _einit.
The linker scripts of the board name the bounds of .init_array the way the
Pico SDK does, __init_array_start and __init_array_end, and do not
define _sinit and _einit.  lib_cxx_initialize() walks _sinit to _einit,
so a configuration with CONFIG_HAVE_CXXINITIALIZE does not link:
"undefined reference to `_sinit'".

Define _sinit and _einit at the same places in the three scripts.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-08 14:24: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
Daniel P. Carvalho
b27b064931 arch/mips/pic32mz: fix the GPIO_EDGE_RISING pin encoding.
GPIO_EDGE_RISING was (12 << GPIO_CN_SHIFT), which sets bits 10 and 11
(GPIO_PULLDOWN | GPIO_EDGE_DETECT) instead of the edge type bit 12 that
its comment describes.  A pin configured for rising edges therefore also
got the pull-down, and a falling-edge pin with GPIO_PULLDOWN was taken
as a rising-edge pin.  Use bit 12.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-10-08 09:54:07 -03:00
Daniel P. Carvalho
a8338c1add arch/mips/pic32mz: receive full size Ethernet frames.
The RX byte count and the EMAC1MAXF limit both include the 4-byte FCS,
but the driver did not account for it:

- RXBUFSZ was programmed with CONFIG_NET_ETH_PKTSIZE, rounded down to
  16 bytes (1504 for 1514), so longer frames were split into fragments
  and dropped.
- EMAC1MAXF was set to CONFIG_NET_ETH_PKTSIZE, so the MAC rejected
  frames longer than CONFIG_NET_ETH_PKTSIZE - 4.
- d_len included the FCS.

Make room for the FCS in the buffers, program RXBUFSZ with the aligned
buffer size and EMAC1MAXF with CONFIG_NET_ETH_PKTSIZE + 4, and remove
the FCS from d_len.  The largest ping that got an answer was 1458
bytes; it is now 1472, the full 1500-byte MTU.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-10-08 09:53:45 -03:00
Daniel P. Carvalho
8eae6d950d arch/mips/pic32mz: fix the Ethernet D-Cache coherency.
VIRT_ADDR() converted the DMA buffer addresses to KSEG1, while the
buffers come from g_buffers, which is linked in KSEG0 when the data
memory is cached.  Buffers then ended up in the free list under both
aliases.  Use the segment g_buffers is linked in instead.

A buffer handed to an RX descriptor may still have dirty D-Cache lines,
at least the free list link written into it.  If such a line is evicted
while the DMA writes the frame, it overwrites part of the frame.
Discard the buffer from the D-Cache before giving it to the DMA.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-10-08 09:53:45 -03:00
Daniel P. Carvalho
74eafb0354 arch/mips/pic32mz: wait for the MII management busy flag to be set.
After starting an MII management command, the driver executed 16 NOPs
before waiting for the busy flag to clear.  The flag is set a few clock
cycles after the command, and when the code runs from the I-Cache the
NOPs end before that: the wait returned at once and phyread() returned
the previous read data.  With the L1 cache enabled the PHY was not found
(ID1 read as 0x3000) and the interface never came up.

Poll until the busy flag is set, bounded in case the command has
already completed, before waiting for it to clear.  A management frame
lasts 64 MDC cycles, so the flag cannot be missed.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-10-08 09:53:45 -03:00
Daniel P. Carvalho
58b2989c64 arch/mips/pic32mz: re-initialize the Ethernet free buffer list on ifup.
pic32mz_bufferinit() appended every buffer to pd_freebuffers without
emptying the list first.  On the first ifup the list is empty (the
driver structure was cleared), but on later ones it still holds the
buffers that were free at ifdown.  Appending them again truncates the
list and loses buffers, depending on which ones were free.  With too few
buffers left the driver could no longer transmit or replace RX buffers,
so after ifdown/ifup the interface stayed up without answering (not
even ARP) until the next ifdown/ifup.

Reproduced with ifdown/ifup from NSH while pinging the board every
10 ms: 3 of 10 cycles left the interface dead before the fix, none
after it.  This also happens on cable reconnection with
CONFIG_NETINIT_MONITOR, which takes the interface down and up.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-10-08 09:53:45 -03:00
Daniel P. Carvalho
81f3d7443d arch/mips/pic32mz: add PHY ioctls and link interrupts to the Ethernet driver.
The driver had no d_ioctl, so CONFIG_NETDEV_PHY_IOCTL had no effect.
Implement SIOCGMIIPHY, SIOCGMIIREG and SIOCSMIIREG and, with
CONFIG_ARCH_PHY_INTERRUPT, SIOCMIINOTIFY.  SIOCMIINOTIFY subscribes
through phy_notify_subscribe() (the board provides arch_phy_irq()) and
enables the PHY link down and auto-negotiation complete interrupts.
This is what CONFIG_NETINIT_MONITOR needs.

The PHY interrupt is implemented for the LAN8720 and LAN8740; add their
interrupt source/mask register bits to mii.h.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-10-08 09:53:45 -03:00
Daniel P. Carvalho
ea65363d57 arch/mips/pic32mz: keep the PHY auto-negotiation enabled.
After a successful auto-negotiation, pic32mz_phyinit() called
pic32mz_phymode() with the negotiated speed and duplex.  That function
clears MII_MCR_ANENABLE, so the PHY stayed in a forced mode.  The link
keeps working until the cable is removed, but on reconnection the PHY
no longer negotiates and, against an auto-negotiating partner, the link
stays down (seen with a LAN8720A: MCR 0x2100, MSR without link status).

Only force the mode when CONFIG_PIC32MZ_PHY_AUTONEG is not selected.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-10-08 09:53:45 -03:00
Daniel P. Carvalho
2851f1c09e arch/mips/pic32mz: fix the Ethernet driver TX ring, RX buffers and MAC.
- Close the TX descriptor ring on the last TX descriptor.  It used
  CONFIG_PIC32MZ_ETH_NRXDESC, so with more RX than TX descriptors the
  DMA ran past the TX ring and stopped transmitting after two packets.
- Decrement ETHSTAT.BUFCNT (ETHCON1.BUFCDEC) for each received
  descriptor that is processed.
- Drop a received packet instead of asserting when no buffer is free to
  replace the one in the RX descriptor.
- Program EMAC1SA0-2 with the MAC address assigned to the device, if
  any.  The driver only read these registers, which are preloaded with a
  factory address on PIC32MZ EC/EF but reset to zero on PIC32MZ-W1.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-10-08 09:53:45 -03:00
Daniel P. Carvalho
322a1c081c arch/mips/pic32mz: fix nxstyle issues in pic32mz_ethernet.c.
Fix the indentation of a wd_cancel() call and add braces to an empty
while loop, so that the file passes checkpatch.sh.  No functional change.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-10-08 09:53:45 -03:00
Marco Casaroli
a2a1f881e2 Documentation/qemu-armv8a: Note fork() and the semihosting flag.
The kernel mode section shows the QEMU command but does not say why
-semihosting is there.  Without it the guest traps in smh_call and stops in
AppBringUp, which reads as a kernel defect and is not one.  It cost me a
session once.

Also state that a kernel build is the only mode on this board with POSIX
fork(), and that vfork() is available in every mode.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-08 09:35:07 -03:00
Marco Casaroli
b63dd89238 arch/arm64: Implement up_addrenv_fork() and provide POSIX fork().
Duplicate an address environment into freshly allocated pages mapped at the
same virtual addresses, which is what POSIX fork() is built on.  It lives in
arm64_addrenv_mmu.c:  an MPU address environment is a set of protection
regions over one physical address space, not a mapping that can be duplicated
at the same virtual addresses.  So ARCH_ARM64 selects ARCH_HAVE_FORK only
in a kernel build with ARCH_ADDRENV.  The condition repeats the
ARCH_ADDRENV dependency, because a select bypasses depends on.

arm64_fork_stack() then lets the child run at the parent's stack addresses.  A
pointer to a stack local taken before fork() must name the same object in the
child that it named in the parent, so the child adopts the parent's stack
geometry rather than being given a relocated copy; the parent's stack is
already in the duplicate, at the parent's address, with its contents.  With a
zero offset arm64_fork_reloc() is then the identity, so the register context
needs no further special casing.

Verified on qemu-armv8a:knsh under qemu-system-aarch64:  ostest's fork_test
reports "Parent and child had independent memory", and vfork_test passes.

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-08 09:35:07 -03:00
Daniel P. Carvalho
5faf14e41f arch/mips/jz4780: record the running task on interrupt exit.
jz4780_decodeirq() saves the interrupted context into
g_running_tasks[this_cpu()]->xcp.regs on entry, but nothing updates
g_running_tasks[] after a context switch: every interrupt saves the
context into the Idle task's TCB, and once a task exits (up_exit() sets
the entry to NULL) no context is saved at all and the next context
switch restores stale registers.

Set g_running_tasks[this_cpu()] to this_task() before returning, as
pic32mz_decodeirq() does.  This is the same bug that crashed the
PIC32MZ-W1 when the netinit thread exited.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-10-08 09:28:21 -03:00
Daniel P. Carvalho
d4097a27e2 arch/mips/pic32mx: record the running task on interrupt exit.
pic32mx_decodeirq() saves the interrupted context into
g_running_tasks[this_cpu()]->xcp.regs on entry, but nothing updates
g_running_tasks[] after a context switch: every interrupt saves the
context into the Idle task's TCB, and once a task exits (up_exit() sets
the entry to NULL) no context is saved at all and the next context
switch restores stale registers.

Set g_running_tasks[this_cpu()] to this_task() before returning, as
pic32mz_decodeirq() does.  This is the same bug that crashed the
PIC32MZ-W1 when the netinit thread exited.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-10-08 09:28:21 -03:00
Daniel P. Carvalho
4f7de715a7 arch/mips/jz4780: fix nxstyle issues in jz4780_decodeirq.c.
Add the missing blank lines after declarations.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-10-08 09:28:21 -03:00
Daniel P. Carvalho
7956039dfd arch/mips/pic32mz: record the running task on interrupt exit.
pic32mz_decodeirq() saves the interrupted context to the TCB in
g_running_tasks[], but never updated g_running_tasks[] after a context
switch.  It kept pointing at the Idle task from nx_start(), so every
interrupt overwrote the Idle task's saved registers, and after up_exit()
set it to NULL no context was saved at all.  The next context switch
then restored stale registers; on PIC32MZ-W1 the system crashed as soon
as the netinit thread exited.

Set g_running_tasks[] to this_task() before returning, as the other
architectures do.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-10-08 09:28:21 -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
raiden00pl
45de63940b drivers/net/telnet: Send a bare carriage return as CR NUL.
telnet_putchar() dropped every CR from the user buffer. RFC 854
requires a CR to be followed by LF or NUL, so send it and add a NUL
if the next character is not LF.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-10-08 13:29:50 +08:00
raiden00pl
9f52373558 drivers/net/telnet: Send CR LF as end of line.
telnet_putchar() appended the carriage return after the line feed, so
every output line ended with LF CR. RFC 854 defines the telnet end of
line as CR LF.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-10-08 13:29:50 +08:00
raiden00pl
35e0427bef drivers/net/telnet: Fix nxstyle issues.
Indent the switch cases in telnet_ioctl() and factory_ioctl(), align a
closing brace and wrap a long comment line. No functional change.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-10-08 13:29:50 +08:00
Marco Casaroli
8308e4b782 fs/v9fs: Do not copy the comma after the virtio tag.
virtio_9p_create() copies the tag from "tag=" to the next comma, and the
length it computes includes the comma.  So a tag that is not the last
option never matches the mount tag of the device:

  nsh> mount -t v9fs -o tag=host,trans=virtio /mnt
  nsh: mount: mount failed: 19

Copy only the characters of the tag.  The allocation is zeroed, so one
more byte terminates it.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-08 13:29:48 +08:00
Marco Casaroli
506a69a03d fs/v9fs: Do not parse past the end of the mount options.
v9fs_client_init() steps over each option with "options += length + 1",
to skip the comma after it.  The last option has no comma, so the step
goes past the terminating NUL, and the loop parses the memory after the
string as more options.  If that memory has a "trans=" or "uname=", it
replaces the option given.

For example, NSH keeps the next argument after the options:

  nsh> mount -t v9fs -o trans=virtio,tag=host trans=x /mnt
  nsh: mount: mount failed: 2

The parser reads "trans=x", and there is no transport "x".  The same
thing happens to options in .rodata, as CONFIG_INIT_MOUNT_DATA is.

Skip the comma only when there is one.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-10-08 13:29:48 +08:00
Marco Casaroli
58bd942b35 fs/v9fs: Fix the nxstyle errors in client.c and virtio_9p.c.
nxstyle reports "Missing blank line after declarations" in three places.
Add the blank lines, 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 13:29:48 +08:00
p-szafonimateusz
501bf8634d arch/sim/sim_cansock.c: drain all pending TX frames per txavail
Loop devif_poll() until it reports nothing more
to send, matching the batch-drain behaviour of the upper-half CAN
drivers, so a transfer completes on one notification.

Signed-off-by: p-szafonimateusz <p-szafonimateusz@xiaomi.com>
2026-10-08 12:13:38 +08:00
p-szafonimateusz
1f17f72e3d arch/sim/sim_cansock.c: fix dirty d_buf pointer
d_buf pointer should be clear after use

Signed-off-by: p-szafonimateusz <p-szafonimateusz@xiaomi.com>
2026-10-08 12:13: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
14b7c8972d boards/arm/rp23xx: Fix the nxstyle errors in rp23xx_common_bringup.c.
Indent the flash MTD block 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: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