Commit graph

63565 commits

Author SHA1 Message Date
Claude
6e14c8cfe5 net/netdev: add NETDEV_TX_STAMP and handle SIOCETHTOOL ETHTOOL_GET_TS_INFO
Add the NETDEV_TX_STAMP capability flag to d_features, next to the
existing NETDEV_RX_STAMP, so a driver can declare that it delivers
hardware TX timestamps.

SIOCETHTOOL and ETHTOOL_GET_TS_INFO were already defined but not
implemented.  Add struct ethtool_ts_info, with the same layout as
Linux, and handle SIOCETHTOOL in netdev_ioctl.c so that userspace (such
as ptpd) can query the timestamping capabilities of an interface the
same way linuxptp/ptp4l does on Linux:

- ETHTOOL_GET_TS_INFO fills so_timestamping from d_features:
  RX_HARDWARE | RAW_HARDWARE with NETDEV_RX_STAMP, otherwise
  RX_SOFTWARE | SOFTWARE (the stack stamps received packets with
  CLOCK_REALTIME), and TX_HARDWARE | RAW_HARDWARE with NETDEV_TX_STAMP.
  phc_index is -1, tx_types and rx_filters are zero.
- Any other ethtool command is passed to the driver's d_ioctl when
  CONFIG_NETDEV_IOCTL is enabled, otherwise -ENOTTY is returned.

Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-09-28 12:53:24 -03:00
Claude
b7001f2d9f include/sys/socket.h: give SOF_TIMESTAMPING_* their Linux values
All SOF_TIMESTAMPING_* flags currently alias 1 << SO_TIMESTAMPING, so
they cannot tell hardware from software or RX from TX.  Give them their
distinct Linux values, and add SOF_TIMESTAMPING_RX_HARDWARE,
SOF_TIMESTAMPING_RX_SOFTWARE and SOF_TIMESTAMPING_SYS_HARDWARE, so that
they can also describe the timestamping capabilities of an interface
(so_timestamping of ETHTOOL_GET_TS_INFO).

This does not change behaviour: setsockopt(SO_TIMESTAMPING) only checks
for a non-zero value and getsockopt() returns 0 or 1, so existing users
and binaries built with the previous values keep working.  The
individual flags are still not honoured.

Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-09-28 12:53:24 -03:00
Royyan Zahir
68dd87f4df arch/arm64/imx9: add key store, signing and persistence to the ELE
The EdgeLock Enclave offers a key store the mailbox driver did not
reach. A key generated in there is permitted one algorithm and one
usage, and export can be withheld, so the private half has no command
that returns it.

Adds the session, key store and key management services, key generation,
signing by handle, and the storage exchange that makes a key store
outlive a boot. Storage runs the other way round from every other
command: the enclave asks the host to write its key store down and to
give it back, and those requests arrive while a command of this side's
is still outstanding, so the reply tag is what tells them apart.

Two things a port has to know and neither reference nor header says.
Key store commands carry a trailing crc, the exclusive or of every word
including the header, without which the enclave answers rating 0xb9. And
a persistent key lifetime is a statement of intent: the strict flag on
key generation is what writes the key to the store, and without it a
store exported around the key comes back without it.

Every mailbox wait is bounded. An enclave that stops answering must not
take the calling thread with it, and a reply buffer is a kilobyte, which
does not belong on the stack of whatever task asked for a signature.

Tested on an i.MX93: a P-256 key generated in the enclave, signing a
digest whose signature verifies against the returned public half on a
host, and still doing so after the board has been powered off.

Signed-off-by: Royyan Zahir <royzah@gmail.com>
2026-09-28 21:50:43 +08:00
Justin Hammond
86da4d11ea drivers/usbhost: Correct the style of usbhost_hub.c.
nxstyle reports fourteen errors in this file.  The switch in
usbhost_hub_configdesc() puts its case labels level with the brace that
opens the switch rather than one step further in, and a declaration is
followed straight away by a statement.

CI checks every file a patch touches rather than only the lines it
changes, so these have to go before anything else in this file can be
altered.

Whitespace, three comments rewrapped to stay inside the line limit
after the extra indent, and one blank line.  No code changes: git diff
-w shows only the comments.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-28 21:45:57 +08:00
Justin Hammond
ed046adeb4 drivers/usbhost: Tell the host stack which controller a port belongs to.
struct usbhost_roothubport_s carries the number of the controller its port
belongs to, so a port can be named on a system with more than one.
Nothing set it.

Take the number from whoever brings the controller up rather than counting
registrations, which would agree with the name the driver reports only
while controllers are registered in the order they are named.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-28 21:45:57 +08:00
Justin Hammond
ba7c7e1f77 drivers/usbhost: Support USB hubs on xHCI.
The driver refused CONFIG_USBHOST_HUB outright.  Everything needed to
describe a device behind a hub is now in place, so implement the rest.

- xhci_device_init() took a root hub port and read the slot, the control
  endpoint and the device out of it, all of which belong to the device.
  It now takes the hub port and the control endpoint, and records the
  device on the root port only when that is where it sits: once a hub is
  plugged in, the device a root port names is the hub.  xhci_address_set()
  and xhci_device_deinit() likewise work on a device, and
  xhci_disconnect() finds the device by the port going away.
- The hub asks for a port's control endpoint before it reports the
  connection, so xhci_epalloc() has nothing to attach one to.  It returns
  an endpoint with no slot, and xhci_connect() gives it one when it
  creates the device.
- A hub must be described to the controller as a hub before anything
  behind it can be reached, and nothing knows it is one when its slot is
  created.  xhci_hub_update() corrects the slot context with a Configure
  Endpoint command the first time something appears behind it.
- A hub reports each changed port without waiting for the last to be dealt
  with, so the connect method queues them; holding one pointer meant the
  second report overwrote the first.  No more can be outstanding than the
  controller has slots.
- Report the root port and slot counts from HCSPARAMS1, and the port count
  from a hub's descriptor.

Tested on an EIC7700X board with a hub on one controller and a keyboard on
the other.  Behind the hub, a 59 GB mass storage device mounts and reads a
file back, and a composite CDC device gives four ttyACM nodes.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-28 21:45:57 +08:00
Justin Hammond
9af6540381 drivers/usbhost: Describe a device behind a hub to the xHCI controller.
A controller reaches a device by the path to it and, for a slow device,
through the hub that translates for it.  Neither was described, so a
device behind a hub was addressed as though it were on the root port.

The route string is that path: each hub between the device and the root
contributes a nibble holding the port the next thing down occupies, tier
nearest the root in the lowest nibble.  Walking up from the device reaches
the deepest tier first, so shifting left by a nibble each time leaves them
in the order the field wants.  The walk stops after five, which is what
the field holds and what USB allows, and a port above fifteen is clamped.

Slot context dword 2 names the transaction translator carrying a low or
full speed device behind a high speed hub.  It reports the hub by slot,
where EHCI reports it by USB address, and it names the nearest high speed
ancestor rather than the immediate parent, since a full speed hub below a
high speed one is itself carried by the translator above it.  The think
time comes from the hub descriptor by way of the hub class driver, in the
same units.

xhci_epalloc() carried a copy of sam_ehci.c's block, writing
epinfo->hubaddr and epinfo->hubport, which is how EHCI describes a split
transaction in its queue head.  This driver never read either field, and
xHCI wants the information in the slot context.  Both fields and the code
setting them are removed.

Multi-TT is not set, for the reason given in the previous commit.

No functional change: hubs cannot be enabled yet, and a device on a root
port has neither hubs above it nor a translator.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-28 21:45:57 +08:00
Justin Hammond
572b7a0b55 usbhost: Report what a hub is on the port it occupies.
Some host controllers must be told about the hubs in a topology, not only
about the device at the end of it.  xHCI is one: a hub's slot context
carries a hub flag, its downstream port count and the think time of its
transaction translator, and the controller routes to anything behind that
hub using them.

The hub class driver already reads both values from the hub descriptor and
keeps them privately.  Publish them on the hub's own hub port, beside the
speed and function address that already describe the device attached
there.  A driver setting up a device behind a hub finds them on that
device's parent.

They are written before the hub activates any downstream port, so they are
in place before there is anything behind it, and a port with no hub
reports zero ports because the hub class clears each child before use.
Nothing is required to read them.

Fields rather than a driver method: a method would need a null check at
the call site and would define an order it must be called in.  Both are
inside CONFIG_USBHOST_HUB, as struct usbhost_hubport_s's parent pointer
already is.

Multi-TT is not included; it comes from the hub's interface protocol
rather than its descriptor, and driving a multi-TT hub as single-TT costs
bandwidth behind it but is correct.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-28 21:45:57 +08:00
Justin Hammond
260603c4f0 drivers/usbhost: Key an xHCI device by its port, not by the root port.
The slot, the default control endpoint and the device context lived in
struct xhci_rhport_s, and anything needing a device reached it as
rhport->dev.  That holds only while every device is plugged straight into
the controller; a hub puts several behind one root port, each with its own
slot and context.

Two keys replace it.  An endpoint records the slot it was opened on, so
xhci_dev_from_ep() answers which device a transfer belongs to.  A hub port
belongs to one device wherever it sits, so xhci_dev_from_hport() answers
which device is on a port when there is no endpoint to ask yet.

The functions converted here used both at once: xhci_ep0configure() issued
Evaluate Context for epinfo->slot while filling in rhport->dev's context,
and xhci_ctrl_xfer() reached the endpoint ring through the port and back.
xhci_slot_init() read the speed and control ring through the port, which
would fail quietly, since the slot context speed field has no valid zero
and a low speed device behind a high speed hub does not share its speed.

No functional change for a directly attached device: its port's slot and
its endpoint's slot are the same, and its hub port is the root port's own.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-28 21:45:57 +08:00
yushuailong
4aeac45cda sched/profil: Fix declaration spacing.
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
Add the blank line required by nxstyle after the SMP-local declaration in
the profiling timer handler.

Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
2026-09-28 06:44:34 -03:00
yushuailong
dd7d211f7b sched/profil: Bound samples to complete counters.
Round the usable profiling buffer size down to complete unsigned short
counters before deriving highpc. Without this, an odd-sized buffer can
allow the timer handler to increment a counter that extends one byte past
the buffer.

Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
2026-09-28 06:44:34 -03:00
yushuailong
d5c4433a01 sched/waitpid: Preserve child status with WNOWAIT.
When waitpid(-1) finds an exited child in the retained status list, honor
WNOWAIT instead of unconditionally removing and freeing the child entry.
This makes the any-child path consistent with the specific-PID and SIGCHLD
paths.

Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
2026-09-28 06:44:34 -03:00
Ahmed Ashraf NourEldeen
556f0bc0a6 boards/arm/stm32l4/stm32l476vg-disco: Add CMakeLists.txt.
Add CMake build support for the stm32l476vg-disco board by introducing
board and source CMakeLists.txt files.

This allows the stm32l476vg-disco:nsh configuration to build successfully
with the CMake build system.

Fixes: #20366

Signed-off-by: Ahmed Ashraf NourEldeen <a.programmer55559@gmail.com>
2026-09-28 06:43:27 -03:00
raiden00pl
a8ac2e74e0 arch/nrf52: add SAADC external TIMER trigger over PPI
The SAADC internal sample timer only works with a single enabled
channel, so hardware-timed multi-channel scan was not possible.  Add
NRF52_SAADC_TIMER_PPI, a third trigger mode in which a general-purpose
TIMER compare event is routed to TASKS_SAMPLE over PPI.  All enabled
channels are scanned, and the TIMER prescaler allows much lower sample
rates than the internal timer, which is limited to 16MHz/CC with CC in
80..2047.

NRF52_SAADC_CONTINUOUS is no longer tied to the internal timer and
works with either source.  Its EasyDMA buffers now hold
NRF52_SAADC_CONTINUOUS_BUFLEN whole scans rather than that many single
samples, so MAXCNT becomes chan_len * BUFLEN.  Samples are interleaved
scan by scan, so a channel map is built once at configure() time and
passed to the upper half with the batch; the upper half already accepts
a per-sample channel array.  A single-channel configuration produces
the same MAXCNT and the same delivery as before.

Because both features want a PPI channel, add a build-time check that
NRF52_SAADC_PPI_CHANNEL and NRF52_SAADC_CONTINUOUS_PPI_CH differ, and
constrain the latter under the SoftDevice controller like the former.

NRF52_SAADC_CHANNELS gains a default and range for the new mode, and
documents that the internal timer is restricted to one channel.

Assisted-by: Claude Code
Signed-off-by: raiden00pl <raiden00@railab.me>
2026-09-28 11:20:31 +02:00
Justin Hammond
4a08b90a29 boards/risc-v/eic7700x: Enable the pinctrl procfs entry.
Publishes /proc/pinctrl on both boards, which lists every pad with the
function it currently carries.  The startup banner counts how many pads
differ from their reset values, once, at boot; this answers the same
question at any later moment, which is what is wanted when a driver has
just reconfigured a pad and the result is not what was expected.

PINCTRL_PROCFS depends on FS_PROCFS_REGISTER, the entry registering
itself at run time rather than being one of the built in ones.  Neither
board set it, and without it the symbol is dropped when the configuration
is regenerated and the entry never appears, which is silent: the
defconfig still reads as though the feature were on.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-28 16:19:01 +08:00
Justin Hammond
2bd1334ec4 arch/risc-v/eic7700x: Describe the pads through procfs.
Implements the pinctrl get_pad method, so /proc/pinctrl and
PINCTRLC_GETPAD carry what this block is actually holding: each layout's
common fields with their validity bits, and the layout's own fields, the
RGMII and mode-select voltage bits and the oscillator tuning, as
key:value text.

Names every pad and every documented function select in one
PINCTRL_PADNAME() table, so func:2 on S_MODE reads as GPIO94 rather than
as a number.  The names are the manual's own; a pad's name describes its
default function, not its current one.  The table costs about 9 KiB and
is built only with the file that reads it; the name helpers return NULL
without it and the strings stay empty.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-28 16:19:01 +08:00
Justin Hammond
f35dd7813e boards/risc-v/eic7700x: Report the pads at startup.
Log one line from board start up with the pad count and how many differ
from their reset defaults, through eic7700x_pinctrl_count().  A helper
holds its locals so nothing stays on the stack for the bring up that
follows.

Turn the pinctrl driver's error output on for both boards, so a refused
pad write says why rather than merely failing.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-28 16:19:01 +08:00
Justin Hammond
830eab5f81 arch/risc-v/eic7700x: Describe and configure the pads.
Every ball on this SoC is shared between several functions, and nothing
in this port could see which function a pad carried or change it.  A
driver that finds nothing cannot tell a dead block from a pad still
pointed somewhere else.

Registers the CLMM pad multiplexer with the pinctrl framework and defines
every pad and every function select the manual documents, across the
straps, JTAG, PCIe, HDMI, Ethernet, I2S, SPI, GPIO, USB, I2C, UART, fan
and MIPI CSI groups.  Writes nothing at start up: a pad only moves when a
driver asks.

eic7700x_pinctrl_count() reports how many pads currently differ from
their reset defaults, which after boot is the set the boot loader and the
drivers have configured; the board start up logs it.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-28 16:19:01 +08:00
Marco Casaroli
b3237cf912 tools/ci: Build the NXFLAT configurations that convert a module.
Some checks failed
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
Docker-Linux / push (push) Has been cancelled
Nine of the seventeen configurations that set CONFIG_NXFLAT are on the CI
blacklist, and they are exactly the ones that build a module: the converter
they need was not in the tree.  ldnxflat is in it now, so eagle100:nxflat and
lm3s6965-ek:qemu-nxflat come off the list.  Both were built with the toolchain
CI uses.

The other seven stay off for reasons of their own.  The thttpd configurations
need CONFIG_BOARDCTL_ROMDISK, which their defconfigs do not set, and the older
boards define their own CPICFLAGS without filtering --fixed-r9 out, so the
compiler refuses r9 as the PIC register.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-27 11:25:12 -03:00
Marco Casaroli
e9913a1579 tools/nxflat: Add a driver for the NXFLAT test suite.
Building an NXFLAT module takes four tools in sequence, and there was no way
to exercise them without a board.  testsuite.sh builds every module of
apps/examples/nxflat/tests for cortex-m3 against a configured tree's headers,
and reports the stage each one stopped at and the relocations it carried.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-27 11:25:12 -03:00
Marco Casaroli
c9cd9db25f tools/nxflat: Add an Apache-licensed NXFLAT converter.
ldnxflat is the last piece of the NXFLAT toolchain that NuttX cannot carry.
It descends from elf2flt through four sets of copyright holders, so it is GPL
by that descent and not merely by its libbfd dependency.  This is a new
implementation, written from include/nxflat.h, from what binfmt/libnxflat does
with the container, and from the ELF specification.  The relocation arithmetic
is that of libs/libc/machine/arm/armv7-m/arch_elf.c, which the ELF loader runs
on the target for the same relocations, and which brings R_ARM_TARGET1 with
it.

NXFLAT is not an ARM format.  Its loader only adds a base to a 32-bit word, so
the segments, the GOT, the relocation records and the header are common to
every architecture.  An architecture supplies a table entry, an entry-point
convention and a relocation handler; an object for a machine with no entry is
refused by name.

The GOT is built here, because ld -r emits none: one entry per symbol that a
GOT-relative reference names, at the start of D-Space, each with a relocation
record of its own.  An entry may hold a function, which is what makes a
function pointer reached through the GOT work.

Two defects of the out-of-tree tool do not survive.  A GOT entry naming a .bss
object lost its section's address and pointed at the start of D-Space, the GOT
itself, so on lm3s6965-ek:qemu-nxflat the longjmp test panics with PC 0 and
the five tests after it never run.  The alignment gap before .bss went missing
from h_bssend as well, leaving D-Space short.

The tool is built and named like the rest of the toolchain.  Makefile.host
builds it, Unix.mk makes a configuration that sets CONFIG_NXFLAT depend on it
beside mknxflat, and LDNXFLAT points at the tool in the tree rather than one
on PATH.

All eight C modules of apps/examples/nxflat/tests convert and run to
completion under qemu-system-arm -M lm3s6965evb.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-27 11:25:12 -03:00
Marco Casaroli
31acf10057 tools/nxflat: Split the ELF reader out of mknxflat.
The converter that follows reads the same objects as mknxflat, so the reader
goes into a file of its own before it gains a second user.  nxflat_elf.c
normalises the tables that describe the object -- the headers, the symbols,
the relocation entries -- into the host's order, and leaves the section
contents alone, because those are the target's bytes and the tools write them
out again.  A tool reads a field without knowing whose order it arrived in.

The -d option goes with it.  It chose a dynamic symbol table, which the ld -r
object these tools convert does not have, and which the NXFLAT loader cannot
use anyway: imports reach a module through the array mknxflat generates.

The output is unchanged.  The thunk mknxflat generates for each of the eleven
modules of apps/examples/nxflat/tests is byte identical to the one the
previous version generated.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-27 11:25:12 -03:00
Marco Casaroli
60d01d779f arch/arm: Reach an NXFLAT module's read-only data through the GOT.
A module's D-Space is separate from its I-Space, so its read-only data is not
at a fixed offset from its text.  GCC assumes that it is and loads a string
literal PC-relative, which reads I-Space at run time.  A module could
therefore carry no string and reach no static.

lm3s6965-ek has had -mno-pic-data-is-text-relative in its own Make.defs since
2021 (issue #3737), and the CMake build gives it to every PIC configuration,
so the flag moves to where it belonged and the board's copy goes.  That copy
also probed for GCC older than 4.9.4, which NuttX no longer supports.  Clang
has no such option, hence the guard.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-27 11:25:12 -03:00
Royyan Zahir
40783f8343 Documentation/imx9: describe the ELE random number generator
The i.MX9x platform page carried only a board toctree, so there was nowhere
describing what the chip supports.

Add a peripheral table and a section on the random number generator: the
Kconfig chain, which of DEV_RANDOM and DEV_URANDOM come on by themselves,
and the health checks a block must pass before a read returns it.

Signed-off-by: Royyan Zahir <royzah@gmail.com>
2026-09-27 11:02:13 -03:00
Royyan Zahir
f7f8107a0a arch/arm64/imx9: add an ELE-backed /dev/random driver.
The i.MX9 has a true random number generator behind the EdgeLock Enclave
and imx9_ele_get_random() to reach it, but nothing registers a character
device for it, so the entropy pool is never seeded from hardware. stm32h7,
nrf52, lpc54xx and rp23xx all provide one; imx9 does not.

imx9_ele.c was built only for CONFIG_IMX9_BOOTLOADER, putting the enclave
out of reach of the application core. It moves behind a new CONFIG_IMX9_ELE
that the bootloader selects, so existing configurations build as before.

A transfer that never lands is silent, so the buffer is prefilled with a
pattern and a block still holding it is refused, as is an all-zero block
and, by the FIPS 140-2 continuous test, a repeat of the one before.

Compiles for imx93-evk:nsh with CONFIG_IMX9_RNG=y.

Signed-off-by: Royyan Zahir <royzah@gmail.com>
2026-09-27 11:02:13 -03:00
zhanghongyu
53ac762e79 drivers/vhost: Optimize vhost-net performance and robustness
Suppress the peer notifications while a ring keeps delivering work, batch
the receive completions into one kick per burst and drop the redundant
txdone signal from the transmit path.  Validate the peer controlled frame
lengths, accept descriptor chains on both lanes, keep every ring access on
the upper half's work thread so the interrupt context callbacks stay lock
free, and prefer the MAC from the configuration space, falling back to the
Kconfig address or a random one.

Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
2026-09-27 18:41:30 +08:00
yushuailong
fed0c445ed docs/wdog: Document wd_start_next delay requirement.
Clarify that wd_start_next() requires a positive delay so callers do not
attempt to schedule the next expiration at the previous expiration time.

Assisted-by: OpenAI Codex <noreply@openai.com>
Signed-off-by: yushuailong <yyyusl@qq.com>
2026-09-26 22:18:02 +08:00
yushuailong
e5d9960f56 sched/wdog: Reject zero delay in wd_start_next.
wd_start_next() schedules relative to the previous expiration.  A zero
value reuses that expiration, so a callback can immediately reinsert an
already expired watchdog and make wd_expiration() loop without advancing
time.

Reject non-positive delays to guarantee that the next expiration advances.

Assisted-by: OpenAI Codex <noreply@openai.com>
Signed-off-by: yushuailong <yyyusl@qq.com>
2026-09-26 22:18:02 +08:00
Marco Casaroli
bfb2cd5541 Documentation/esp32s3-devkit: Describe the kernel build configurations.
Describe kernel_oct and kernel_n8r2 next to the other configurations of this
board.

The entry for kernel_oct carries what a user needs and cannot guess:  a KERNEL
build is the only mode with fork() on this chip, the page pool is reached
through a scratch mapping rather than a permanent window, the ROMFS is linked
into the kernel image so a change to an application needs the whole
export-import-mkromfsimg-relink chain, how to confirm that the ROMFS is really
in the image, and that the shell needs the full path of a program.

The entry for kernel_n8r2 states its limit.  Each region of a process is 2
pages, ostest has 115 KiB of text against a 128 KiB text region, and a larger
program needs a module with more PSRAM.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-26 11:13:57 -03:00
Marco Casaroli
1a061d9b4e boards/esp32s3-devkit: Add kernel_n8r2, a kernel build for 2 MB PSRAM.
kernel_oct targets a WROOM-2 N32R8V:  octal flash, and 8 MB of PSRAM for the
page pool.  The defaults size the pool for that part, with 8 pages of 64 KiB
for each of the text, data and heap regions, so 1.5 MB per process.  fork()
duplicates the address environment, so a parent and a child need 3 MB at once
and a module with 2 MB of PSRAM cannot do it.

kernel_n8r2 sizes the same build for such a module.  Each region is 2 pages,
so a process takes 384 KiB and a fork() peaks at 768 KiB, inside a 1.5 MB pool
placed at 0x80000 to leave the start of the PSRAM alone.

The flash is quad and runs in DIO mode, so this configuration also exercises
the CONFIG_ESP32S3_FLASH_MODE_OCT guard in kernel-space.ld from the quad side,
which kernel_oct cannot.

This is tight by construction.  ostest has 115 KiB of text against a 128 KiB
text region.  A larger program needs a module with more PSRAM, not a larger
pool.

Verified on an ESP32-S3-DevKitC with an N8R2 module, 8 MB flash in DIO mode
and 2 MB of embedded quad PSRAM.  ostest reports "Parent and child had
independent memory" and exits with status 0.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-26 11:13:57 -03:00
Marco Casaroli
1bc7cfeeb1 arch/xtensa: Provide POSIX fork() on the ESP32-S3.
up_addrenv_fork() duplicates an address environment into freshly allocated
pages mapped at the same virtual addresses.  The text, data and heap regions
of the source are walked one page at a time and copied into fresh pages hung
off the child's own directory, using the two kmap slots that
CONFIG_ARCH_KMAP_NPAGES reserves for exactly this.

xtensa_fork.c already took both paths:  a child that keeps the parent's stack
addresses needs no relocation, which is what a duplicated address environment
gives it.  Only the hook and the Kconfig default were missing.

fork() is offered on a kernel build, which is the only mode with per-process
address environments.

Verified on an ESP32-S3-WROOM-2 with esp32s3-devkit:kernel_oct.  ostest
reports "Parent and child had independent memory" and exits with status 0.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-26 11:13:57 -03:00
Marco Casaroli
ce59fb6e71 xtensa/esp32s3: Reach a page pool page through a scratch mapping.
The page pool is carved out of the PSRAM that user processes run from, and
the external memory permissions are indexed by physical address, so a
permanent kernel window onto the pool is a window onto every process, which
no permission setting can close.

Stop mapping the pool.  The kernel reaches a pool page through a small
scratch region instead, mapped for one operation and invalidated afterwards.
esp32s3_pgmap() takes a slot, esp32s3_pgunmap() releases it, and
ARCH_KMAP_VBASE and ARCH_KMAP_NPAGES describe the region.  Two slots are
enough, because the deepest user is up_addrenv_fork(), which holds a source
and a destination page at once.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-26 11:13:57 -03:00
Marco Casaroli
f14e807c11 xtensa/esp32s3: Wire the chip into the kernel build.
The common Xtensa BUILD_KERNEL support needs the chip to say what it can do
and where its memory goes.

The chip selects the address environment options it now implements, keeps the
kernel and user heaps apart, and the linker scripts separate kernel from user
text and data so the two worlds can be given different permissions.

kernel_oct configures a board for it, with the user-program layout and the
boot ROMFS a kernel build loads its programs from.  The ROMFS placeholder is
rebuilt with the image, the generated copy is ignored, and the programs are
given stack sizes and room for a fork() child.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-26 11:13:57 -03:00
Marco Casaroli
bf3a5b0b35 libs/libc/elf: Link a kernel-build program the way the loader loads it.
The loader packs the allocatable sections of a fully linked program into the
text and data regions in section header order, and on a chip that selects
ARCH_HAVE_TEXT_HEAP_WORD_ALIGNED_READ every section that is not executable
goes to the data region.  The template left .rodata in the text region, so
the addresses the program carries did not say where it would be loaded.

.rodata now leads the data region on such a chip, .eh_frame is placed rather
than left an orphan, and the Xtensa literal pools are gathered with the text
they belong to:  a literal section is not executable, so an orphan one would
be loaded into the data region, away from the code that reads it.

The ESP32-S3 needs all three.  With them the shared template lays out a user
program exactly as the board script it replaces did, section for section.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-26 11:13:57 -03:00
Marco Casaroli
54419e870d xtensa/esp32s3: Implement per-process address environments.
Give the ESP32-S3 the arch_addrenv_t machinery that BUILD_KERNEL needs:  a
per-process page directory built from the 64 KiB MMU pages of the chip, with
allocation, teardown, and the vaddr-to-paddr translation that the kernel uses
to reach a user buffer.

The MMU, PMS and WCL primitives are exposed as an arch API first, because the
address environment code and the protected user split both need them and
neither owns them.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-26 11:13:57 -03:00
Marco Casaroli
b7f3c06b09 xtensa/esp32s3: keep octal-flash init in IRAM for the protected build
The protected kernel linker (kernel-space.ld) placed the octal (OPI)
flash bring-up helpers -- esp_rom_spiflash / esp_rom_opiflash_*,
spi_flash_oct_flash_init, mmu_hal, mspi_timing_*, bootloader_flash*,
efuse_hal/efuse_utility, esp_mmu_map and esp32s3_spi_timing -- in mapped
flash.  During configure_cpu_caches() / spi_flash_init_chip_state() in
__start these run while the flash mapping is being reconfigured, which
faults (illegal instruction) on octal-flash modules such as the
ESP32-S3-WROOM-2.  Quad-flash parts never exercise the OPI path, so the
problem was latent.

Place those functions in .iram0.text (mirroring the flat sections
script) so they are safe to execute during flash reconfiguration.

Assisted-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-26 11:13:57 -03:00
Marco Casaroli
54fcbe888b xtensa/esp32s3: add recoverable cache-attribute fault dispatcher (Unit B)
Route the precise cache-attribute permission faults -- Load/Store/InstrFetch
Prohibited (EXCCAUSE 28/29/20) -- from xtensa_user() to a new dispatcher,
esp32s3_pagefault_dispatch().  On a serviced fault the register frame is
returned so the exception vector's RFE re-executes the faulting instruction;
otherwise it declines to the existing panic path.  Gated by
CONFIG_ESP32S3_PAGEFAULT (default n, depends on BUILD_PROTECTED); the build
is unchanged when the option is off.

This is the recoverable-fault primitive the address-environment / demand-paging
work builds on.  Proven on the ESP32-S3-DevKitC WROOM-2:

- A precise LoadProhibited carries a tracking EXCVADDR (the exact faulting
  address), and RFE cleanly re-executes the faulted load on return -- verified
  with CONFIG_ESP32S3_PAGEFAULT_SELFTEST (the identical instruction restarts
  three times, then steps past, and the task resumes with the shell alive).
- ESP32-S3 PMS (World Controller) permission violations are NOT delivered as
  these precise causes; they raise the asynchronous DRAM0/IRAM0 PMS-monitor
  interrupt, so PMS is an isolation (kill) mechanism, not a restartable one.

No regression: esp32s3-devkit:knsh (WROOM-2) boots to nsh and ostest passes
with the option enabled.

Assisted-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-26 11:13:57 -03:00
Marco Casaroli
7a006e7ef6 binfmt/elf: Load FDPIC modules through the ELF loader.
exec() of an FDPIC module now works.  The loader already places such an
object and binds it; what was missing is everything binfmt has to carry
across from the load to the running task.

The task needs the module's data base in its PIC base register.  binfmt
builds a D-Space for any object with a GOT, taking the base from the .got
section address; an FDPIC object names it in DT_PLTGOT instead, which the
loader has already translated, so the two are the same idea reached by
different routes and both are what up_initial_state() installs.

Constructors are not binfmt's business.  A module carries its own crt0,
which walks .init_array on the task that runs the module and then calls
main, so they run in the module's own context and with its own data base.
For a module that arrives through dlopen(), libelf_insert() walks the array
instead, and it enters each entry through fdpic_invoke() because a
descriptor resolved on the calling task carries the wrong base.

The read-only segment of a module that executes in place is held by a
filesystem pin.  The load takes it, and the module owns it from the point
where nothing can fail any more; it is given back when the task that runs
the module exits.  The pin is held through a reference to the file rather
than a descriptor, because the descriptor belongs to the task that called
the loader and the release happens on another one.

libelf_remove() and libelf_uninit() give back what an FDPIC module holds:
the pin, and the writable segment, while the read-only one is media rather
than an allocation and must not be freed.

Built for mps3-an547:picostest with CONFIG_FDPIC both ways.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-26 11:13:30 -03:00
Alin Jerpelea
3b301b4844 Documentation: add NuttX 13.1.0 release notes
add release notes for NuttX 13.1.0 release

Signed-off-by: Alin Jerpelea <alin.jerpelea@sony.com>
2026-09-26 10:54:27 -03:00
Jukka Laitinen
63208908ac arch/arm/imxrt: Allow serial console in uarts 9-12
iMXRT118x may have up to 12 uarts. Allow setting the console also on those.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-26 17:05:47 +08:00
Jukka Laitinen
c64d30dbbc arch/arm/imxrt: Clean up TRDC configuration
The TRDC (Trusted Resource Domain Controller) configuration should be completely
driven by the board configuration, and not hard-coded:

- Add tables for the current GPIO configuration and MDA configuration.
- Fix the GPIO configurations for M7; previously GPIO access from M7 was
  denied because of secure/nonsecure setting.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-26 17:05:34 +08:00
Jukka Laitinen
6ef704ee83 arch/arm/imxrt: Fix imxrt118x rgpio compiler warning
Move GPIO_PIN definition from imxrt118x_gpio.h to imxrt_rgpio.h to
remove redefinition warning.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-26 17:05:34 +08:00
jsanchez-2g
463d8a71d7 arch/arm/stm32h7: Dump FDCAN Rx/Tx FIFO status registers.
fdcan_dumpregs() printed the Rx FIFO 0 and Tx buffer configuration
registers (RXF0C, TXBC) but not their live status counterparts
(RXF0S, TXFQS), and did not print the Rx FIFO 1 configuration or
status registers (RXF1C, RXF1S) at all.

Add the missing RXF1C configuration line and the RXF0S, RXF1S, and
TXFQS status lines so every configured FIFO/buffer's fill-level
state is visible alongside its configuration, matching the existing
dump grouping.

Convert fdcan_dumpregs() from printf() to ninfo(), matching the
logging convention already used elsewhere in this file
(ninfo/nerr), per upstream review feedback.

Compile-tested: boards/arm/stm32h7/nucleo-h743zi2/configs/socketcan
with CONFIG_STM32_FDCAN_REGDEBUG=y, CONFIG_DEBUG_INFO=y.

Assisted-by: Claude:claude-sonnet-4.5
Signed-off-by: jsanchez-2g <jsanchez@2g-eng.com>
2026-09-26 09:59:13 +08:00
Marco Casaroli
f741c9369a libs/libc/dirent: Add a blank line after a declaration.
nxstyle wants a blank line between a declaration and the statements that
follow it.  The line is not new, but it sits within three lines of the
FDPIC change in this series, so CI reads it as part of the patch.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-25 10:46:48 -03:00
Marco Casaroli
43694933ce libc, sched: Resolve FDPIC descriptors at module callback entry points.
The base firmware and an FDPIC module disagree about what a function
pointer is.  Firmware is not built FDPIC, so to it a pointer is a code
address and it branches there.  A module passes the address of a two word
descriptor instead, because its code and data are placed independently and
a bare code address would leave the callee unable to find its own data.  A
firmware routine that takes a callback therefore branches into the
module's data segment and faults.

So the ten entry points that can be handed a callback by a module resolve
the descriptor before storing or branching to it: qsort, bsearch,
pthread_create, signal, sigaction, task_create and task_create_with_stack,
task_spawn, pthread_once, scandir, and mq_notify and timer_create with
SIGEV_THREAD.

Which one resolves matters as much as that one does.  Resolving twice would
take an already resolved code address for a descriptor and read two words
from the instruction stream, so each pointer is resolved exactly once, at
the outermost point that sees it.  signal() passes its argument through
untouched because sigaction() and then nxsig_action() will resolve it,
which covers a module calling sigaction() directly as well.  qsort() is
split so that the public entry resolves and the recursive implementation
does not.  scandir() resolves its filter but not its comparison function,
which it hands to qsort().

Whether a caller is a module at all is asked of the PIC base register,
which up_initial_state() sets only for a task that has a D-Space.  A plain
kernel task therefore reads zero and is left alone.

SIGEV_THREAD is the case the register cannot answer, because the callback
runs later on a work queue worker that carries no module's base at all.
The base is captured instead when the notification is registered, in the
module's own context, and installed around the call.

All of it is behind CONFIG_FDPIC, which defaults off.  Built for
mps3-an547:picostest both ways; with it off the entry points compile to
what they were.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-25 10:46:48 -03:00
Marcio Ribeiro
9f89c1c2a6 boards/risc-v/esp32c2/esp8684-devkitm: add ESP8684-DevKitM board
Add NSH bringup for the Espressif ESP8684-DevKitM. The nsh defconfig
uses a 26 MHz XTAL, 4 MB flash, and debug features for the MINI-1 module.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Marcio Ribeiro <marcio.ribeiro@espressif.com>
2026-09-25 21:08:00 +08:00
Marcio Ribeiro
13bfc34db3 boards/risc-v/esp32c2/common: add shared board support for ESP32-C2
Add linker scripts and shared board drivers reused by ESP32-C2 boards,
and wire common Kconfig into the board configuration tree.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Marcio Ribeiro <marcio.ribeiro@espressif.com>
2026-09-25 21:08:00 +08:00
Marcio Ribeiro
25a3aaaa9d arch/risc-v/esp32c2: add ESP32-C2 chip support
Introduce RV32IMC chip architecture with HAL integration and Espressif
common Kconfig for the ESP8684 SoC, including XTAL, UART0 pin range,
and SPI flash clock options.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Marcio Ribeiro <marcio.ribeiro@espressif.com>
2026-09-25 21:08:00 +08:00
Marco Casaroli
5513029711 arch/arm: Build a loadable module and a shared library as FDPIC too.
CONFIG_FDPIC teaches the ELF module path what an FDPIC object is, so an
application built as a module gets -mfdpic -fPIC and the
arm-uclinuxfdpiceabi linker.  The loadable module path, which apps builds
with DYNLIB = y and which apps/Library.mk uses for a shared library, was
left as it was: a -r partial link with the stock linker.  That leaves an
object with no dynamic section, so the loader has nothing to bind an import
to, and there is no way to build a library an FDPIC module can call.

Give that path the same treatment.  CMODULEFLAGS and CXXMODULEFLAGS gain the
FDPIC compiler flags, and LDMODULEFLAGS links a shared object rather than a
partial one.  The entry point is left to the caller, because a module is
entered at _start while a library is only ever called into.

CXXMODULEFLAGS is also defined for the first time.  apps/Library.mk compiles
every C++ source of a shared library with it and no architecture defined it,
so those sources were compiled with no architecture flags at all.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-25 09:56:10 -03:00
Austin.Chen
5197329b67 arch/arm/stm32h5: add SDMMC1/SDMMC2 driver
Add the STM32H5 SDMMC1/SDMMC2 lower-half SDIO driver (interrupt-mode and
IDMA transfers, SD/SDIO card mode), following the same structure as the
existing STM32H7 SDMMC driver.

Three fixes were needed to get this actually building, selectable, and
correct:

- The driver checked CONFIG_STM32H5_SDMMC1/CONFIG_STM32H5_SDMMC_IDMA/
  CONFIG_STM32H5_SDMMC_XFRDEBUG, but the real Kconfig symbols selected by
  this chip are the shared CONFIG_STM32_SDMMC1/CONFIG_STM32_SDMMC_IDMA/
  CONFIG_STM32_SDMMC_XFRDEBUG (see arch/arm/src/common/stm32/Kconfig.sdio,
  Kconfig.periph). With the old names the driver silently compiled out.
  Renamed all guards in stm32_sdmmc.c to match. Also fixed a similar typo,
  STM32H5_SRAM3_SIZE -> STM32_SRAM3_SIZE, in the IDMA-reach check.

- arch/arm/src/common/stm32/Kconfig.sdio's STM32_SDMMC_IDMA and the
  SDMMC1/2 SDIO-mode/pull-up options depended on ARCH_CHIP_STM32H7 /
  STM32_COMMON_F7_H7 only. Extended STM32_SDMMC_IDMA to also allow
  ARCH_CHIP_STM32H5, and switched the SDIO-mode/pull-up options to
  STM32_COMMON_F7_H7_H5, matching the pattern already used for other
  STM32H5 peripherals (Ethernet, ADC, SPI, timers).

- stm32_sdmmc.c was only added to Make.defs, not to CMakeLists.txt, so
  the driver would silently be omitted from CMake builds. Added it to
  the same unconditional source list as stm32_exti_gpio.c.

Also ports a fix from a related STM32H7 SDMMC commit
(2cb7b7c03e): stm32_recvdma()'s aligned
IDMA receive path invalidated the destination buffer before the DMA but
never again after it completed, so a speculative cache prefetch into
that buffer between those two points could shadow the freshly-received
data with a stale line. Added the missing post-DMA invalidate, matching
the pattern already used elsewhere on this chip for other DMA-capable
peripherals (e.g. stm32_ethernet.c's RX path).

Needed for a custom STM32H5 board that uses SDMMC1 in SDIO mode with
IDMA to talk to an onboard WiFi module.

Co-authored-by: Liam Howatt <liamhowatt@geotab.com>
Signed-off-by: Marwan Madkour <marwanmadkour@geotab.com>
2026-09-25 18:30:40 +08:00