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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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
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>
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>
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>
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>
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)
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)
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)
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
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
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>
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>
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>
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>
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>
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>
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>
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>
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>
- 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>
Add a few !defined(CONFIG_ARCH_FAMILY_IMXRT118x) gates similar to 1176 to
buid the common drivers also for 118x variants.
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
- Move/make sure that ep0buf is in usb dma capable memory. Especially if
.data/.bss are in TCM, the buffers need to be placed in another section.
If the section .dmamemory doesn't exist, they will end up in .data like before
- change "#ifdef CONFIG_ARCH_FAMILY_IMXRT117x" into
"#if defined(CONFIG_ARCH_FAMILY_IMXRT117x) || defined(CONFIG_ARCH_FAMILY_IMXRT118x)"
- In imxrt_epcomplete dtd->buffer0 must NOT be used to compute the data buffer's
cache-maintenance address range. The hardware advances buffer0 (and its
"current offset" low-order bits) as the transfer progresses, so by completion
time it points *past* the start of the buffer (at start + xfer_len), not at
the buffer itself. Instead, use the original privreq->req.buf when the transfer
is complete.
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
- Small additions to existing drivers to support more UARTs
- Properly invalidate the cache over DMA RX buffer initially
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
- Add imxrt118x compatible IOMUX definitions, named as IOMUX_VER3. This is the
same IP as what is used for example for IMX9. Instead of directly copying the support
from imx9, pack the padconfig into the same 32-bit value used for GPIO for easy use.
- Add imxrt118x compatible rgpio driver. This is the same GPIO block as what has been used
in imx9. Instead of directly copying the support from IMX9, add pin muxing directly
into GPIO driver as well, to keep the usage compatible with existing IMXRT boards.
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
- Initialize the internal secure element, if configured
- Initialize the TRDC, if configured
- Disable the TCM enabling code when compiling for other than Cortex-M7 chip.
This needs to be skipped for M33 core on imx118x
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
iMXRT118x uses the same security element as the imx93. Just add iMXRT specific
register definitions and port over the driver code.
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
The trdc driver has been copied from arm64/imx93, and modified to fit imxrt118x.
The relevant register definitions have been generated by AI from the RM.
Assisted-by: Claude Code:claude-opus-4-7
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
Add IMXRT AONMIX register addresses and bit definitions in a separate header file
"imxrt118x_blkctrl.h".
The header is generated using AI from imxrt118x reference manual.
Assisted-by: Claude Code:claude-opus-4-7
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
Support reading the OCOTP via the shadow register on imxrt chips with integrated
ELE. On these chips, writing is done via ELE, this is not yet implemented.
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
Add register definitions for IMXRT118x Analog-Digital top level block.
Assisted-by: Claude Code:claude-opus-4-7
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
Port the ccm / clock configuration from iMX93 to iMXRT118x.
Register definitions are generated from RM using AI
Assisted-by: Claude Code:claude-opus-4-7
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
Add interrupt numbering for imxrt118x in imxrt118x_irq.h, and support
for more interrupts in imxrt_irq.c and imxrt_clrpend.c.
The interrupt numbers are generated from the Reference Manual by AI
Assisted-by: Claude Code:claude-opus-4-7
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
Add imxrt118x memorymaps as hardware/rt118x/imxrt118x_memorymap.h
Assisted-by: Claude Code:claude-opus-4-8
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
- Only submit and account for a wrapped second TX segment when scatter/gather descriptors
are available. Without in-memory TCDs, submitting the second segment overwrites the
active hardware descriptor and incorrectly advances the serial buffer past unsent data.
- Invalidate DMA RX buffer initially
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>