Commit graph

63392 commits

Author SHA1 Message Date
Arnav Sharma
6cd19e661b docs: document common DMA driver framework
Document the common DMA driver framework and its usage.

Describe the DMA controller and client interfaces, channel and
transfer lifecycle, DMA links, controller implementation
requirements, and existing in-tree users.

Add references to the audio DMA and 16550 UART implementations
to provide concrete usage examples.

Signed-off-by: Arnav Sharma <2006arnavsharma@gmail.com>
2026-09-20 22:29:26 +08:00
yushuailong
a298c1734e sched/irq: Preserve all handlers when extending IRQ chains.
Allocate the new handler node independently of the initial chain
conversion so handlers beyond the second are appended instead of silently
dropped.  Delay vector conversion until both required nodes are available
to avoid leaving a partially constructed chain on allocation failure.

Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
2026-09-20 22:28:55 +08:00
Justin Hammond
c7d6f51b9c drivers/usbhost: Stop retrying an xHCI port that will not enumerate.
xhci_enumerate() reports failure by marking the hub port disconnected,
which is what makes xhci_wait() return and the attempt repeat.  The root
port is still connected, so the two disagree again immediately and the
attempt repeats for as long as the device stays plugged in.  A device that
fails every time is retried forever: 1055 attempts in 90 seconds on an
EIC7700X board, enough console traffic to make the board unusable.

Count consecutive failures per root port and stop at
CONFIG_USBHOST_XHCI_ENUM_RETRIES, leaving the port as it is so xhci_wait()
blocks until something physically changes.  A new connection clears the
count, as does a successful enumeration, so a device needing a second
attempt still gets one.  The default of three rides out a slow device or a
marginal reset.

The same board now makes three attempts, reports that it has given up and
falls silent, while a keyboard on the other port enumerates throughout.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
18c834b7d3 drivers/usbhost: Release the xHCI slot when enumeration fails.
A device slot is a finite controller resource: HCSPARAMS1 reports how many
exist and Enable Slot fails with No Slots Available once they are gone.
Two paths took one and returned without giving it back.

xhci_device_init() enables a slot before initialising the transfer ring,
the slot context and the device address, and each of those returned
directly on failure.  It also treated a slot number larger than the
controller supports as success, since Enable Slot itself had succeeded.

xhci_enumerate() is the larger leak: the device is addressed by the time
usbhost_enumerate() runs, so a device whose descriptor cannot be read, or
that no class driver claims, leaves the slot held.  That path clears
hport->connected so the port is retried, taking another slot each time.

Release the slot on both paths with xhci_device_deinit(), which issues
Disable Slot, clears the DCBAA entry and resets the context.  The endpoint
ring is left allocated; xhci_ring_init() reuses an existing one.

Tested on an EIC7700X board with a device no class driver claims, so the
port retries indefinitely: previously the eighth attempt failed with
completion code 9 and the controller enumerated nothing further on either
port; now 1104 consecutive attempts produced no slot failure.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
fc58227802 drivers/usbhost: Serialise xHCI transfers per endpoint.
xhci_ctrl_xfer() and xhci_transfer() release the controller lock before
xhci_transfer_wait(), so the lock does not cover the interval in which a
transfer is outstanding.  Two threads issuing requests on the same
endpoint both reach xhci_ioc_setup(), and the second trips the
DEBUGASSERT(!epinfo->iocwait) that guards it, or overwrites the first
thread's completion state where assertions are compiled out.

A default control endpoint reaches this readily: every interface driver on
a composite device speaks through endpoint 0, so a two interface HID
keyboard runs two poll threads both issuing GET_REPORT.

Other host controller drivers hold the controller lock across the wait,
which here would serialise the whole controller and give up the per
endpoint rings xHCI provides.  Add a mutex to struct xhci_epinfo_s and
hold that instead.  It is taken before the controller lock on both paths,
so the order is endpoint then controller.

xhci_epfree() also freed the endpoint container without destroying iocsem.
Destroy both.

Reachable on any xHCI controller, independently of the preceding commits.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
a5431319bb drivers/usbhost: Make xHCI asynchronous transfers deliver their data.
Submitting an asynchronous transfer refused any buffer needing a cache
line stand-in, and that test also refuses every buffer whose length is not
a whole number of cache lines, which an interrupt transfer's rarely is: a
HID keyboard reads eight bytes.  Every submission returned -EFAULT before
a descriptor was written, and a class driver resubmitting from its
completion callback never sees a second chance.

The refusal existed because the copy out of a stand-in is done by the
blocked caller, and an asynchronous transfer has none.  The work queue
thread handling the completion will do: a buffer given to DRVR_ASYNCH
comes from DRVR_ALLOC, so it is kernel memory reachable from any thread.
Use the same stand-in machinery as every other transfer and finish the DMA
in the completion, just before the callback.  A cancelled transfer returns
its stand-in on cancellation.

The callback also moves outside the spinlock.  It is class driver code
that queues work and takes its own locks, and it may now free a stand-in.
Whether a completion is synchronous is still decided under the lock, since
a posted waiter may be carrying a new transfer immediately.

The asynchronous setup now records the requested length, as the
synchronous setup does.  The byte count handed to the callback is worked
out from it and the residue, and was previously whatever the endpoint held
from an earlier transfer.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
62a7507427 drivers/usbhost: Check for the device before allocating an endpoint.
A root hub port whose enumeration failed is enumerated again, and the slot
the failed attempt used has been given back by then, so the port has no
device context behind it.  xhci_epalloc() took that pointer and wrote the
new endpoint through it without looking, so the retry stored through NULL
and took the system down in answer to a device that had merely failed to
come up.

Check for the device, and free the endpoint that has no home rather than
leaking it.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
a11cecd100 drivers/usbhost: Convert the xHCI endpoint interval from the descriptor.
The Interval field of an endpoint context is an exponent: the controller
services the endpoint every 2^Interval microframes.  An endpoint
descriptor states its period differently depending on device speed, so the
number cannot be copied across, which is what this did.  A low speed
keyboard asking to be polled every 10ms was programmed as 2^10
microframes, which the controller would not accept: Configure Endpoint
went unanswered and allocation failed with -EIO.

Low and full speed interrupt endpoints state a period in frames, so the
exponent is the highest bit of that period in microframes, clamped to the
range the specification allows.  Other periodic endpoints already state an
exponent, one greater than the one wanted here.  Control and bulk
endpoints are not periodic and the field means nothing to them.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
f8ea0f3d02 drivers/usbhost: Copy an xHCI stand-in buffer in the caller's context.
The copy out of a stand-in was done in the completion handler, which runs
on a work queue, while the buffer it copies into may belong to a user
process whose addresses mean nothing there.  Reading a block device
directly from a user program faulted.  The caller is blocked until the
transfer finishes, so the copy belongs there.

An asynchronous transfer has no blocked caller to come back to, so a
buffer that would need a stand-in is refused for that path.  Its callers
are class drivers using kernel memory, which do not need one.  The
refusal is lifted once the completion path can do the copy itself.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
a4475ca284 drivers/usbhost: Announce what an xHCI port has attached.
Report each device as it comes up, and report it going away.

The announcement is made at the end of the port enable rather than at
connect, because the PORTSC speed field means nothing until the port has
been reset: a USB2 port reports its reset default, full speed, until then,
so every device would be announced at 12Mbps regardless of what it
negotiates a moment later.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
6b24a0cac5 drivers/usbhost: Carry the xHCI transfer chain across the ring join.
A transfer described by more than one TRB can reach the end of the ring
part way through, so the link that sends the controller back to the
beginning falls inside the transfer rather than between two of them.
Written without the chain bit, that link ends the transfer where it
stands: the controller follows it, considers the work finished, and
reports nothing, because the TRB that asked for the completion interrupt
is on the far side of the join.  Nothing waiting is woken, and transfers
have no timeout, so the symptom is a read that never returns.

Carry the chain bit onto the link when the TRB it follows has it.

Reading 1MiB from a USB drive, where the last two sizes did not complete
at all before:

    512 byte blocks     166 KB/s
    4 KiB blocks       1333 KB/s
    32 KiB blocks     10666 KB/s
    64 KiB blocks     15515 KB/s

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
432ef71ed7 drivers/usbhost: Describe devices to an xHCI controller correctly.
What a controller is told about a device before it will accept it.  A DWC3
core validates these where QEMU's controller does not.

- HCCPARAMS1 says whether context structures are 32 or 64 bytes, and the
  wider form was refused outright with -EIO; the EIC7700X reports
  0x0220fe45 on both of its controllers, so this driver could not have
  driven either.  A wide context is the same fields with reserved space
  after them, so only the stride changes.  Read it at start up and use it
  wherever a context array is walked.
- Contexts must be 64 byte aligned, since every device context base
  address array entry points at one, and the output context came from
  kmm_zalloc().
- The slot context never carried the device speed, which has no valid
  zero, so a validating controller answers Address Device with a parameter
  error.  The speed was already implied by the endpoint context's maximum
  packet size.  The numbering is xHCI's own, hence the mapping.
- The output device context was cleared and never flushed.  That context
  is the controller's to write, so what stays behind is a dirty line of
  zeros written back over the slot state, and the next command against the
  slot is refused with a context state error.  Enumeration reached
  SET_ADDRESS and stopped.
- A buffer copied through an aligned stand-in was copied back using buflen,
  which control transfers deliberately leave zero, so a descriptor read
  copied nothing back and the caller was handed whatever its buffer held
  before.  Keep the requested length separately, and maintain the cache
  over the whole stand-in rather than the part in use.
- A buffer the controller cannot reach is now copied through a stand-in
  rather than refused.  -EFAULT works for a caller with somewhere better
  to put the data, and fails outright for one without: reading a block
  device directly from a user program returned an error where the transfer
  could have gone through a stand-in.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
c288d9f9e4 drivers/usbhost: Compute the event ring segment count at full width.
The number of event ring segments a controller allows is a power of two
reported as its exponent, and the exponent can reach 15.  Computing
1 << exponent into the uint8_t that holds it wraps to zero on any
controller offering more than 128 segments, and a controller told its
event ring table holds no entries has nowhere to report anything: every
command times out.

Work it out at full width and narrow afterwards.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
ecbd1870d3 drivers/usbhost: Report which xHCI command was rejected.
A failed command logged only its completion code.  The difference between
a refused Address Device and a refused Evaluate Context is most of the
diagnosis, and the completion code does not give it.

Keep the command type before the result overwrites the TRB, and name it in
the message.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
cf93053f74 drivers/usbhost: Read xHCI HCIVERSION with an aligned access.
The register dump read HCIVERSION with a 32-bit access at offset two.  It
is a 16-bit register sharing a word with CAPLENGTH, so that is an
unaligned read of a device register: harmless where the bus permits it and
a fault where it does not.

Read the word once and take both fields from it.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
0ed5e61bcf drivers/usbhost: Maintain the cache over xHCI data buffers.
The controller moves every byte itself, so on a machine whose caches are
not coherent with it the driver must flush before the controller reads and
invalidate before the processor does.  Data buffers got no maintenance at
all: nothing pushed before an OUT, nothing dropped after an IN.

Cache operations act a whole line at a time, which is unsafe for a buffer
that does not own its lines: invalidating drops whatever else shares the
line, and a writeback lands on top of what the controller has just put
there.  Mass storage passes a 31 byte command block and a 13 byte status
out of its instance structure.  Such a buffer is copied through an aligned
stand-in; anything large comes from a filesystem or from xhci_ioalloc(),
which now rounds its length up as well as aligning its start, so what it
returns owns its last line.

Whether the controller can reach a buffer at all is asked of the platform
through a new dmacapable operation, since it is a property of the system
the controller was fitted into rather than of the controller.  A platform
that does not supply it is taken to accept every address, which is what
existing users have.  A refused buffer gives -EFAULT, which the FAT
filesystem answers by retrying through its own DMA-safe sector buffer.

The device output context is also invalidated before the assigned address
is read out of it; the controller wrote that address, and reading without
invalidating returns whatever the processor had cached.

Compiles to nothing where there is no cache to maintain, and dmacapable is
NULL on PCI, so the existing user is unaffected.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
9e1e3a272a drivers/usbhost: Chain xHCI TRBs across a 64K boundary.
A Normal TRB describes one run of memory that may not cross a 64K
boundary, and the block layer hands down whole multi-sector reads whose
length is bounded by nothing here.  One TRB was programmed regardless, so
a long enough transfer, or merely one starting near the wrong side of a
boundary, produced a descriptor the controller is entitled to reject or to
satisfy in part.

Program as many as the run needs, chained, asking for the completion
interrupt only on the last so one event still arrives for the transfer.
A transfer needing more TRBs than the ring holds is refused.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
cd30b682a4 drivers/usbhost: Flush the xHCI rings and structures by address.
xhci_ctrl_start() published the event ring segment table, the device
context base address array and the scratchpad pointers with
up_flush_dcache_all(), which an architecture whose cache can only be
maintained by address implements as a barrier and nothing more, so none of
them reached memory.  The controller then reads whatever those addresses
held before, which presents as every command timing out with no events
arriving.  Flush each structure by address.

xhci_ring_init() has the same fault from the other direction: it clears a
whole ring and flushes only the link entry it writes afterwards, leaving
the rest of the clearing in the cache.  The controller writes into that
memory itself, so a line written back later lands on top of an event
somebody is waiting for.  Flush the whole ring.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
8f88d73275 drivers/usbhost: Set the xHCI interrupter moderation interval.
The interval was left at its reset value of 4000, a millisecond, which is
how long the controller waits after an event before reporting it.  Every
completion paid that, and mass storage spends three transfers on a
request.

Set it to 160, which is 40us, as Linux does.  Zero puts no bound on how
often a controller may interrupt: a keyboard on an interrupt endpoint then
takes them continuously and occupies a processor.

Measured on a DWC3 with a USB 2.0 drive, doorbell to interrupt 986-1021us
before and 13-56us after:

    reading 1MiB          before        after
    512 byte blocks      166 KB/s     775 KB/s
    32 KiB blocks      10666 KB/s   18618 KB/s

    mounting a FAT32 volume: 92.7s before, 21.1s after

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
de440f910a drivers/usbhost: Silence the xHCI interrupter until its worker has run.
The handler read the status, queued the work that would answer it, and
returned with the source still asserted.  On a level triggered line the
interrupt controller sees the condition still true and raises it again at
once, so the work that would have cleared it never runs.

Mask the interrupter in the handler and let the worker unmask when it is
done.  The unmask clears the pending flag in the same write, because a
message is sent on that flag's clear to set transition and events that
arrived while the interrupter was masked have already set it.

Clearing opens its own window, so the worker drains the ring again after
unmasking and repeats while a drain finds anything; xhci_events_poll()
returns how many events it handled for that purpose.  A drain that finds
nothing is the only state in which no event can have been lost.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
f78decb390 drivers/usbhost: Acknowledge xHCI events before walking the ring.
The event ring was acknowledged after being walked.  An event arriving
during the walk sets the pending bit again, and clearing the bit
afterwards discards it.  Transfers have no timeout, so the transfer that
event belonged to waits forever.

Acknowledge first.  A spurious second pass over an empty ring costs
nothing.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
e03c23c4ae drivers/usbhost: Do not disable an xHCI port while probing it.
xhci_probe_ports() wrote PORTSC back to clear the change bits, including
PED, which is write-one-to-clear.  A port that came up enabled, which is
what a device attached at power up produces, was switched off by the act
of reading it.

Mask PED out of the value written back.  The port status worker already
does this.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Justin Hammond
648aa30e37 drivers/usbhost: Attach the xHCI interrupt after the controller starts.
The handler defers to a worker that walks the event ring, and the ring is
not allocated until the controller is started, several steps later.  A
controller left running by a boot loader has an interrupt pending as soon
as the line is enabled, so attaching earlier is a race with nothing able
to answer it.

Attach after the start, and clear USBSTS and the interrupter pending flag
once the handler is in place: a message signalled interrupt is sent on the
flag's clear to set transition, so a flag raised before the handler
existed would never produce another.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 22:28:07 +08:00
Abhishek Mishra
4b86c1dd23 docs: document chroot jail root
Describe the jail, leftover pre-opened fds, the NSH command-form scrub,
and the flat-build trust boundary shared with credentials.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
2026-09-20 22:27:38 +08:00
Abhishek Mishra
2977db2632 fs: add chroot() syscall
Add CONFIG_FS_CHROOT and POSIX chroot(). Store the jail as an
absolute path on the task group, and require euid 0 when user
identity is enabled.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
2026-09-20 22:27:38 +08:00
Abhishek Mishra
a0adad6602 fs: start absolute lookups at the jail root
Prepare paths in inode_search_setup(): prepend tg_root, canonicalize
with a jail-floor dst_min, then walk from g_root_inode. Replace
SETUP_SEARCH / RELEASE_SEARCH with inode_search_setup() /
inode_search_release().

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
2026-09-20 22:27:38 +08:00
Abhishek Mishra
6c7f604f79 sched: add per-group filesystem jail root
Store the jail as an absolute path on the task group, copy it to
children, and free it when the last member leaves.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
2026-09-20 22:27:38 +08:00
Justin Hammond
1757b28b1f drivers/sensors: Use sensor_data_t for the electrical quantities.
The voltage, current, power, resistance and conductivity messages
declare their measurement as float, where every other message in
uorb.h declares it as sensor_data_t.  That type is b16_t under
CONFIG_SENSORS_USE_B16 and float otherwise, so on a fixed point
configuration these five are the only sensors still producing floats.

A driver that computes in sensor_data_t, as the helpers in fixedmath.h
encourage, then assigns a b16_t to a float field: the raw fixed point
integer is stored as a float and the reading is wrong by 65536 with no
diagnostic.

The accumulators keep int64_t.  Energy in uJ and charge in uC are
counts of micro units rather than measurements, and neither is
affected by the fixed point option.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Justin Hammond <justin@dynam.ac>
2026-09-20 09:23:37 -04:00
Daniel P. Carvalho
964c68b109 Documentation/ptp: correct the PTP clock driver page.
The page did not match the code in several places.

- Describe struct ptp_ops_s as it is: adjfine takes parts per billion,
  adjphase, getres and control exist, there is no getcaps, and gettime
  has a system timestamp argument. State which operations are optional
  and give the real ptp_clock_register() arguments.
- Replace the CLOCKFD() macro, which does not exist, with the clock
  identifier built from CLOCK_SHIFT and CLOCK_FD, in all examples.
- Fix the frequency values: struct timex freq is in parts per million
  with 16 fractional bits, so +10 ppm is 655360.
- List the modes clock_adjtime() handles for a PTP clock
  (ADJ_SETOFFSET, ADJ_FREQUENCY, ADJ_OFFSET for the phase) and say that
  the others return -ENOTSUP.
- PTP_CLOCK_GETTIME and PTP_CLOCK_SETTIME take a struct timespec. Add
  the ioctls that were missing.
- The dummy driver uses CLOCK_REALTIME, not the monotonic clock.
- Point to ptpd instead of ptp4l and timemaster, which are not part of
  NuttX, and use the real CONFIG_DEBUG_PTP options.

Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
Assisted-by: Claude:claude-sonnet-5
2026-09-20 08:22:33 -03:00
Royyan Zahir
0cb794570c crypto: fix chacha constants under GCC 15.
GCC 15 added -Wunterminated-string-initialization, and both constants fill
their array exactly, leaving no room for the terminator. Every build with
that compiler fails, since crypto/Makefile treats warnings as errors.

Neither is used as a string: they are read as sixteen bytes through
U8TO32_LITTLE(). Letting the array size follow the literal keeps them
readable, costs one byte each, and needs no attribute that only some
compilers have.

The cipher state is unchanged for both key sizes.

Signed-off-by: Royyan Zahir <royzah@gmail.com>
2026-09-20 08:22:11 -03:00
Daniel P. Carvalho
ee23dd03c5 net/pkt: remove unused variable conn in append_timestamping
Variable conn is declared and initialized in append_timestamping()
but never referenced, triggering -Wunused-variable compiler warning.

Assisted-by: Gemini:gemini-3.8-pro
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-09-19 18:32:45 -03:00
Daniel P. Carvalho
3589fceab3 arch/arm/stm32: implement PTP hardware clock driver (/dev/ptp0)
Implement lower-half PTP hardware clock operations (struct ptp_lowerhalf_s
and struct ptp_ops_s) in the STM32 Ethernet driver and register it with the
generic PTP clock framework (drivers/timers/ptp_clock.c) to expose /dev/ptp0.

Supported operations:
- adjfine: adjust PTP clock frequency in parts per billion (ppb)
- adjphase: adjust PTP clock phase via hardware TSSTU
- adjtime: shift PTP clock time by signed delta in nanoseconds
- gettime: atomic double-read of hardware timestamp registers
- settime: initialize hardware timestamp counter via TSSTI
- getres: return 1 ns clock resolution

Also fix a sign bug in stm32_eth_ptp_adjust() where uint64_t addend
promoted negative ppb adjustments to unsigned, corrupting frequency trim
for crystals running faster than nominal.

Follow-up to #20148 per review recommendation to use the standard POSIX
/dev/ptp0 character driver instead of custom socket ioctls.

Assisted-by: Gemini:gemini-3.8-pro
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-09-19 18:32:45 -03:00
Daniel P. Carvalho
c21d96eb68 arch/arm/stm32: deliver direct hardware counter timestamps for PTP.
The MAC hardware counter is the PTP clock reference. Delivering its
raw timestamp directly (instead of synthesizing one against
CLOCK_REALTIME, which starts at an arbitrary boot-time phase) lets the
PTP daemon close the feedback loop and phase-lock the MAC counter -
and therefore the physical PPS output - to the master.

Assisted-by: Gemini:gemini-3.8-flash-medium
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-09-19 18:32:45 -03:00
Daniel P. Carvalho
6f7d54d096 arch/arm/stm32: Disable reception of self-transmitted frames.
Set ETH_MACCR_ROD unconditionally when configuring the MAC. In
half-duplex mode the MAC otherwise reflects every frame it transmits
back to its own receiver, flooding the receive path with our own
traffic right as a genuine reply arrives. The bit has no effect in
full-duplex (confirmed on our hardware: fduplex=1), so setting it
unconditionally is safe and changes nothing observable for boards
already running full-duplex.

The sibling stm32f7 driver has the same gap (ETH_MACCR_ROD cleared
but never set) and stm32h7's equivalent ETH_MACCR_DO bit has the same
issue; both are left out of scope here since only m3m4_v1 hardware
was available to validate against.

Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
(cherry picked from commit 41536cb8c9f5ff448864d2eb490b35aea7cdafcf)
2026-09-19 18:32:45 -03:00
Daniel P. Carvalho
5938f58fd8 arch/arm/stm32: Convert RX hardware timestamp before pkt_input().
stm32_receive() called pkt_input() before
stm32_eth_ptp_convert_rxtime(), so every packet handed to a packet
socket carried the previous frame's RX timestamp instead of its own
in dev->d_rxtime. Reorder so the timestamp is converted first.

Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
(cherry picked from commit 9bfa20da28da79a567e3b38cb127767cf9e03042)
2026-09-19 18:32:45 -03:00
Daniel P. Carvalho
efec7da49f drivers/timers: Add TMRDEPPATH/TMRVPATH for PTP clock drivers.
Every other timer driver block in this Make.defs sets TMRDEPPATH and
TMRVPATH so DEPPATH/VPATH include this directory. CONFIG_PTP_CLOCK
and CONFIG_PTP_CLOCK_DUMMY were the only two missing it, leaving
ptp_clock.c/ptp_clock_dummy.c unreachable via VPATH and without a
generated dependency file when no other timer driver in this file is
also selected.

Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
(cherry picked from commit 6d3812229d1c527971bf3a2b9d7d2675796fc688)
2026-09-19 18:32:45 -03:00
Alan Carvalho de Assis
5ec51ae6d5 wireless/bluetooth: Validate lengths when parsing advertising reports.
le_adv_report() took the report count and each report's data length from
the event and used them without checking either against the data that was
actually received:

  - the declared data length indexes the RSSI octet, so a length larger
    than the event reads past the end of the buffer;
  - the loop was bounded only by the report count, so a count larger than
    the payload walks off the end of it;
  - bt_buf_consume() only checks its bound with DEBUGASSERT(), so on a
    build without assertions the buffer length underflows rather than
    reporting the problem.

Check that the event is long enough for the count, then check each report
against the remaining length before reading its data or its RSSI, and
stop parsing when a report does not fit.

While here, include the RSSI octet when advancing to the next report.
sizeof() of the report structure does not account for it, because the
data member is a zero-length array, so every report after the first
started one octet early.

Ref: Core v6.0, Vol 4, Part E, 7.7.65.2 (LE Advertising Report event)
Testing: builds for sim:bluetooth with Make; every commit in this series
verified to build individually.  Not yet exercised at runtime - the
scriptable controller that can inject a malformed report is added
separately.

Signed-off-by: Alan C. Assis <acassis@gmail.com>
Assisted-by: Claude Code Opus 5
2026-09-19 18:30:43 -03:00
Daniel P. Carvalho
bc566da957 mm/iob: fix CONFIG_NET_TIMESTAMPING typo in iob_alloc
net: add SO_TIMESTAMPING support for PKT sockets gated the io_conn
reset in iob_alloc_committed() and iob_tryalloc_internal() on
CONFIG_NET_TIMESTAMPING, then merged that symbol into
CONFIG_NET_TIMESTAMP without updating mm/iob/iob_alloc.c. Both
#ifdefs there test a symbol that no longer exists, so the reset is
never compiled in.

Recycled IOBs therefore kept the io_conn of their previous owner, and
pkt_input() treated ordinary received frames as TX timestamp loopback,
queueing them on conn->errahead instead of readahead.

Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
Assisted-by: Claude:claude-sonnet-5
2026-09-19 16:36:47 -03:00
Abhishek Mishra
b180dc17ae Documentation,drivers/aie: align machine learning docs with current code
The tflm tool registered DEPTHWISE_CONV_2D in nuttx-apps#3773, but the
docs still listed eight operators. Document the unused -C compile path,
that the sim helper uses heap I/O, and the pinned TFLM/CMSIS/NNABLA
versions. Add missing gemmlowp, KissFFT, Ruy, and FlatBuffers pages,
document the AI-engine character driver, and wire it into CMake.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
2026-09-19 15:16:18 -03:00
Daniel P. Carvalho
774387d980 stm32/comp: propagate enable error and handle lock in ioctl
In comp_ioctl(), propagate the return code of comp_enable() to caller so
failures (such as when the comparator CSR register is locked) return -EPERM.
Also call comp_lock_set() if the comparator was configured with locking,
handling cases where initialization was delayed.

Assisted-by: Gemini:gemini-3.8-pro
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-09-19 22:41:17 +08:00
Daniel P. Carvalho
3f4dc2ddf3 boards: stm32g4: regenerate nucleo-g431kb comp defconfig
CONFIG_EXAMPLES_COMP_DACPATH matched its Kconfig default value, which
make savedefconfig drops as redundant. The stale explicit line made
the committed defconfig differ from what a clean savedefconfig
produces, failing CI's defconfig-completeness check even though the
board builds fine either way.

Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-09-19 22:41:17 +08:00
Daniel P. Carvalho
e433409fcc stm32: implement comp ioctl and update nucleo-g431kb defconfig
Implement ao_ioctl in stm32_comp_m3m4_v2.c to handle ANIOC_COMP_ENABLE and
ANIOC_COMP_DISABLE commands. Also add CONFIG_STM32_COMP_INIT_DISABLED to
allow keeping the comparator disabled after driver initialization until
explicitly enabled.

Update nucleo-g431kb:comp defconfig to enable CONFIG_EXAMPLES_COMP and
set default DAC path for comparator ramp verification.

Assisted-by: Gemini:gemini-2.5-pro
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-09-19 22:41:17 +08:00
Daniel P. Carvalho
fc9fec46da analog: add ANIOC_COMP_ENABLE and ANIOC_COMP_DISABLE commands
Define standard IOCTL commands to enable and disable analog comparator
devices from user-space applications.

Assisted-by: Gemini:gemini-2.5-pro
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
2026-09-19 22:41:17 +08:00
Jukka Laitinen
66703d0957 tools/imxrt1180: Add a standalone C program for simple AHAB container creation
Add a standalone tool to create AHAB container for imxrt118x. This can
generate a trivial unsigned image without appending ELE.

The tool can be used to create bootable images for m33. To do anything
more complicated, the user needs to use the official SPSDK tool from
NXP.

Assisted-by: Claude Code:claude-opus-5-0
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-19 22:38:45 +08:00
Jukka Laitinen
be5bf6133b arch/arm/imxrt: Add support for ELE FW for imxrt1180-evk
Add support for loading the secure element firmware.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-19 22:38:45 +08:00
Jukka Laitinen
af24d2094a Documentation/imxrt: Add documentation for imxrt118x arch and imxrt1180-evk
Add the documentation for the new supported board configurations and for the architecture,

Assisted-by: Claude Code:claude-opus-4-7
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-19 22:38:45 +08:00
Jukka Laitinen
fae67d1608 boards/arm/imxrt/imxrt1180-evk: Add imxrt1189 evaluation board configurations
This adds the initial board configurattions for building NuttX for imxrt1189-evk.
Also add a script building the NXP container image for bootloaders (m33 images)

The board boots on Cortex-M33 core, for which there are two m33 targets: nsh-m33 and bl.

- "bl" target does basic initialization of ELE and TRDC and just releases the M7 to run
  at 0x20080000.
- "nsh-m33" target just boots nuttx into nsh shell on m33

- The "nsh" target is for M7 core. It can be flashed at 0x20080000, and
  it boots to nsh shell with a proper bootloader on m33 (the bl target does this).

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-19 22:38:45 +08:00
Jukka Laitinen
c5e2c4b3f7 arch/arm/imxrt: Configure MPU for imxrt118x
We must enable the MPU on IMXRT118x to be able to keep writeback dcache on.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-19 22:38:45 +08:00
Jukka Laitinen
e71c9c799a arch/arm/imxrt: Add a function imxrt118x_release_cm7 to start M7 core
Add a function which can be called from M33 core on imx118x to start
executing on M7 core.

The function:
- Configures the M7 clock root
- Releases M7 from reset
- Asks the secure element to release the M7 (ENABLE_APC)
- Enables the M7 clock

The function is compiled in when a configuration flag
CONFIG_IMXRT_CM7_BOOT=y

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-19 22:38:45 +08:00
Jukka Laitinen
5b7d69307c arch/arm/imxrt: Add iMXRT118x capable eDMA driver
- Add driver supporting the DMA3 and DMA4 in iMXRT118x chips. The driver is first copied
  from imx93, and then changed just the relevant parts (function names, clocking and
  irq handling) to match the imx118x configuration.
- Add the DMA channel numbering in hardware/rt118x/imxrt118x_dmamux.h from RM
  by claude.

Assisted-by: Claude Code:claude-opus-4-7
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-09-19 22:38:45 +08:00