Replace the iLLD helpers IfxCpu_resetAndStartCounters() and
IfxCpu_getClockCounter() in the performance-counter path with direct
CSR accesses via tricore_mtcr()/tricore_mfcr().
tricore_reset_ccnt() disables the CPU cycle counter (CPU_CCTRL), clears
CPU_CCNT, then re-enables it; up_perf_gettime() reads CPU_CCNT directly.
This removes the arch/tricore perf path's dependency on the Infineon
iLLD layer. No behavior change.
Signed-off-by: zhangyu117 <zhangyu117@xiaomi.com>
Replace the iLLD register structures (Ifx_CPU_PCON0/1/2, Ifx_CPU_DCON0/1/2)
and the IfxCpu_cfg.h cache-size/line-size macros in the cache path with
direct CSR accesses via tricore_mtcr()/tricore_mfcr() and locally defined
PCON/DCON bit masks. Also switch __isync()/__dsync() to the UP_ISB()/
UP_DSB() barrier wrappers.
This removes the arch/tricore cache path's dependency on the Infineon
iLLD layer. No behavior change.
Signed-off-by: zhangyu117 <zhangyu117@xiaomi.com>
Add tricore_mtcr()/tricore_mfcr() inline-assembly wrappers for the
MTCR/MFCR (move to/from Core Special Function Register) instructions.
These let arch/tricore code access CSRs directly without relying on the
Infineon iLLD intrinsics, and are used by the following iLLD-removal
change in the performance-counter path.
Signed-off-by: zhangyu117 <zhangyu117@xiaomi.com>
The `rx_pin` configuration when `CONFIG_S32K3XX_FLEXCAN2` is defined is
overwritten if `PIN_CAN2_ENABLE` is defined, breaking the flexcan config
for S32K3 MCU.
Signed-off-by: Javier Alonso <javieralonso@geotab.com>
The `rx_pin` configuration when `CONFIG_KINETIS_FLEXCAN2` is defined is
overwritten if `PIN_CAN2_ENABLE` is defined, breaking the flexcan config
for Kinetis MCU. Additionally, the `.enable_high` configuration points to
a non-defined constant/macro (looks like a legacy from the first driver
definition). Based on regularly maintained drivers (such as s32k3), this
was changed to `CAN2_ENABLE_OUT`
Signed-off-by: Javier Alonso <javieralonso@geotab.com>
The `rx_pin` configuration when `CONFIG_S32K1XX_FLEXCAN2` is defined is
overwritten if `PIN_CAN2_ENABLE` is defined, breaking the flexcan config
for S32K1 MCU. Additionally, the `.enable_high` configuration points to
a non-defined constant/macro (looks like a legacy from the first driver
definition). Based on regularly maintained drivers (such as s32k3), this
was changed to `CAN2_ENABLE_OUT`
Signed-off-by: Javier Alonso <javieralonso@geotab.com>
This reverts commit 9b0d46c222.
This change was made to fix a problem in NTFC with kernel build,
but it introduces an incompatibility with make.
We are reverting this change and the NTFC issue will be resolved
on the NTFC side.
Signed-off-by: raiden00pl <raiden00@railab.me>
Document CONFIG_SCHED_NGROUPS, setgroups/getgroups/initgroups, and
setresuid/setresgid in the user identity guide.
Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Complete the POSIX credential setters for real/effective/saved UID and
GID so login and privilege-drop paths can clear saved-root without
relying on setreuid patterns alone.
Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Track supplementary GIDs per task group, wire setgroups/getgroups
syscalls when CONFIG_SCHED_NGROUPS > 0, and honor them in DAC checks
via nxsched_has_gid(). When NGROUPS is 0, libc provides getgroups/
setgroups stubs. initgroups() fails instead of silently truncating
when membership exceeds CONFIG_SCHED_NGROUPS.
Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
cromfs_read()'s fast path decompresses a block directly into the
caller's buffer whenever a read reaches a block at its start and the
caller has room for the whole decompressed block, bypassing the
per-file decompression cache (ff_buffer). It nonetheless marked that
block as cached by setting ff_offset, without ever writing ff_buffer
itself.
A later read of the same block that fell onto the slow path trusted
that false cache tag, skipped decompression, and copied from
ff_buffer without it ever having been populated for that block. A
repeated identical fast-path read of the same block hit the same
false tag and skipped decompression entirely, leaving the caller's
buffer untouched and returning whatever was already there.
Fixed by having the fast path only read the cache, never populate it:
reuse ff_buffer when a prior slow-path read already cached the same
block, otherwise decompress straight into the caller's buffer without
touching ff_offset/ff_buffer.
Co-authored-by: Pavlo
Assisted-by: Claude Code:claude-sonnet-5
Signed-off-by: alexcekay <alexander@auterion.com>
In udp_input()'s broadcast/multicast fan-out loop, each iteration
calls netdev_iob_replace(dev, iob) to swap in a freshly cloned iob
before handing the packet to the next matching connection. That
function unconditionally sets dev->d_len = iob->io_pktlen, which is
the full frame length (IP + UDP headers + payload), undoing the
'dev->d_len -= udpiplen' done once before the loop to strip the
headers off for udp_input_conn().
As a result, every connection after the first sees a d_len that is
udpiplen (IP+UDP header length, eg 28 bytes for IPv4) too large.
This value flows into udp_datahandler() as buflen (it reads
dev->d_len directly) and is stored as the queued packet's declared
length in the connection's read-ahead iob chain. Once more than one
such oversized entry has queued up in the same chain, the consumer
(udp_readahead() in udp_recvfrom.c) parses the following entry's
metadata starting at the wrong offset, so whatever byte happens to
land on src_addr_size is trusted as-is. That single byte (0-255) is
then used as the length in iob_copyout(srcaddr, iob, src_addr_size,
...), which fills a fixed-size stack buffer with no bounds check
outside a DEBUGASSERT - compiled out in release builds - so an
oversized value overflows that stack buffer.
Re-apply the same '-= udpiplen' header-stripping after each
netdev_iob_replace() call in the loop, matching what's already done
once before the loop for the first connection.
Inside udp_input_conn, d_appdata is always set first, and since neither
the ICMP nor ICMPv6 process accesses d_appdata, the redundant d_appdata
settings have been removed.
Signed-off-by: yi chen <94xhn1@gmail.com>
The I2C master driver support for the RTL8721Dx (pke8721daf) and RTL8721F
(rtl8721f_evb) boards was merged without the matching board documentation.
Add the missing I2C entry to each board's Features list and an "i2c"
configuration section describing the /dev/i2cN devices, the board pin
table, and the i2ctool usage, mirroring the existing gpio/uart sections.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Assisted-by: Claude <noreply@anthropic.com>
Wire the RTL8720F to the shared Ameba I2C master driver
(arch/arm/src/common/ameba/ameba_i2c.c), reusing it unchanged.
Add the per-chip header arch/arm/src/rtl8720f/ameba_i2c_chip.h supplying
the chip's I2C wiring: two controllers (I2C0/I2C1) on their non-secure
register aliases (0x401c8000 / 0x401c9000), the APBPeriph function/clock
masks, the crossbar SCL/SDA pad-mux codes (59/60 and 61/62), and
AMEBA_I2C_HAS_DMA_FIELDS=1 (the chip's I2C_InitTypeDef carries the DMA
request-level fields).
Add the board glue: rtl8720f_i2c.c registers I2C0 at /dev/i2c0
(PA22/PA23) and I2C1 at /dev/i2c1 (PA24/PA25), plus the build wiring
(Make.defs / CMakeLists.txt / ameba_board.mk pull in the common driver
and the fwlib ram_common/ameba_i2c.c data-table source), the bringup
registration hook and the board header declaration.
Add the i2c defconfig (minimal NSH with the i2ctool) and document the
config in the board index.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Assisted-by: Claude <noreply@anthropic.com>
Wire the shared common UART driver
(arch/arm/src/common/ameba/ameba_uart.c) into RTL8720F. Add an
ameba_uart_chip.h supplying the per-chip UART parameters: two
general-purpose controllers (UART0/UART1), their non-secure register
bases (0x401C3000 / 0x401C4000 -- the fwlib UART_DEV_TABLE points at
the non-secure alias), NVIC vectors, APBPeriph function/clock masks
and the crossbar TX/RX pad-mux function codes.
The fwlib ROM UART routines index data tables (UART_DEV_TABLE,
APBPeriph_UARTx) that live in fwlib ram_common/ameba_uart.c, so that
source is compiled in when CONFIG_AMEBA_UART is set. Wire
CONFIG_AMEBA_UART into Make.defs/CMakeLists/ameba_board.mk, add the
board port table (UART0 at /dev/ttyS1, PA22 TX / PA23 RX, 115200 8N1)
with bringup registration, a uart config and board documentation.
Hardware-verified on rtl8720f_evb: serialrx/serialblaster over a
PA22-to-PA23 TX/RX loopback transferred all 2600 bytes intact.
Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
RTL8720F drives all GPIO through a single 32-pin port A controller
served by one NVIC vector, unlike RTL8721Dx (ports A/B) or RTL8721F
(ports A/B/C). Add an ameba_gpio_chip.h that configures the shared
common GPIO driver (arch/arm/src/common/ameba/ameba_gpio.c) for a
single port: AMEBA_GPIO_NPORTS=1, AMEBA_GPIO_PORT_IRQS={GPIOA} and
the APBPeriph_GPIO gate bits.
GPIO_INTStatusGet/ClearEdge live in the RTL8720F ROM symbol table, so
no fwlib ram_common object needs compiling in. Wire CONFIG_AMEBA_GPIO
into Make.defs/CMakeLists/Kconfig, add the board pin table (PA22 out,
PA23 in, PA24 interrupt) with bringup registration and a gpio config.
Hardware-verified on rtl8720f_evb: output, input and (falling-edge)
interrupt all confirmed via a PA22-to-PA24 loopback.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Assisted-by: Claude <noreply@anthropic.com>
stm32_waitresponse() polls SDIO_STA bounded only by an iteration
counter, set to 0x7fffffff for all R1/R1B/R2/R4/R5/R6 commands. The
hardware CTIMEOUT flag is the intended exit for a missing response,
but it is only generated while the card clock is running and the CPSM
has reached its Wait state. If the card clock stops or the peripheral
fails, SDIO_STA never updates and the loop spins for INT32_MAX
iterations while holding the FAT filesystem lock, at the caller's
priority-inheritance boosted priority if higher priority tasks block
on the filesystem. Since the mmcsd layer retries failed commands,
the driver's recovery paths are never reached and the system never
recovers.
Bound the wait by time instead: 250 ms for response-bearing commands
(the largest timeout the SD specification allows for any operation)
and 10 ms for the no-response/R3/R7 cases. CTIMEOUT remains the
normal error exit within microseconds; the software bound only fires
when the peripheral itself is dead, converting an unbounded spin into
-ETIMEDOUT so the existing mmcsd retry logic can run.
Signed-off-by: Luka Filipović <filipovicluka3@gmail.com>
Assisted-by: Claude Code:claude-fable-5
olddefconfig only ran when .config was generated from the defconfig,
so changes applied to an existing .config (e.g. with kconfig-tweak)
never got their dependent defaults. Run olddefconfig on reconfigure as
well, as the Make flow does on every build.
Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
Wire the shared Ameba I2C master lower-half (arch/arm/src/common/
ameba/ameba_i2c.c) into the RTL8721F (amebagreen2) build through a
per-chip header (ameba_i2c_chip.h), and register the RTL8721F EVB
buses at /dev/i2cN.
Per-chip differences from the other Ameba SoCs (non-secure register
bases, crossbar pinmux codes, APB clock masks and the fwlib
I2C_InitTypeDef layout) are isolated in ameba_i2c_chip.h; no change to
the shared driver is needed.
Verified end-to-end on hardware against a second Ameba board acting
as an I2C slave: address ACK, register write and read-back over
repeated-START, and bus scan all pass on I2C0 (PA22/PA23).
Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Add a shared NuttX I2C master lower-half for the Realtek Ameba I2C
controllers (I2C0/I2C1) in arch/arm/src/common/ameba, driven through
the SDK fwlib in polling mode. Per-chip wiring (controller count,
register bases, clock masks, crossbar pad-mux codes and the fwlib
I2C_InitTypeDef layout) lives in arch/arm/src/rtl8721dx/ameba_i2c_chip.h
so a port to the other Ameba chips only supplies a same-named header.
Each controller registers as /dev/i2cN from pke8721daf bring-up through
the stock I2C character driver; a dedicated `i2c` defconfig drives the
i2ctool for validation.
Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
esp32s3_bringup.c still guards on CONFIG_ESP32S3_RT_TIMER, includes
"esp32s3_rt_timer.h" and calls esp32s3_rt_timer_init(). None of those
exist any more: c17e16eaed ("xtensa/espressif: Update common-source
integration for Xtensa devices") deleted the chip-specific RT timer and
replaced it with the common-source HR Timer, and updated every other
esp32s3 board's bringup to CONFIG_ESPRESSIF_HR_TIMER /
"espressif/esp_hr_timer.h" / esp_hr_timer_init(). This board was missed.
The stale guard is not dead code: ESPRESSIF_WIRELESS selects
ESP32S3_RT_TIMER (which survives only as a deprecated alias that selects
ESPRESSIF_HR_TIMER), so enabling Wi-Fi on this board turns the guard on and
the build fails outright:
board/esp32s3_bringup.c:61:12: fatal error: esp32s3_rt_timer.h:
No such file or directory
No esp32s3-ws-lcd128 defconfig enables Wi-Fi, which is why CI has not
caught it.
Switch to the same guard, include and initializer the other esp32s3 boards
use. No functional change for the existing defconfigs: they leave both
ESP32S3_RT_TIMER and ESPRESSIF_HR_TIMER unset, so the block stays compiled
out.
Verified with esp32s3-ws-lcd128:nsh plus CONFIG_ESPRESSIF_WIFI=y (and the
Wi-Fi prerequisites the in-tree wifi defconfigs set: SCHED_LPWORK,
DRIVERS_WIRELESS/DRIVERS_IEEE80211, NETDEV_WIRELESS_IOCTL, IOB_NCHAINS,
TLS_TASK_NELEM, TIMER): the fatal error above before the change, a clean
build and image after it, with no other change to the configuration.
Signed-off-by: Ricard Rosson <ricard@groundbits.com>
Assisted-by: Claude Opus 5 (Claude Code)
Rewrite arch_memcpy.S and arch_memset.S to be register-width aware on
both RV32 and RV64 using REG_L/REG_S/SZREG macros from asm.h.
memcpy gains:
- 16xSZREG unrolled main loop (128B/iter on RV64, 64B on RV32).
- Shift-merge path for misaligned src: reads two aligned words
straddling each output word and shifts them together, so no load
or store is ever misaligned.
- Single SZREG and byte loops for remainder and small copies.
memset gains:
- 32xSZREG unrolled main loop (256B/iter on RV64, 128B on RV32)
using Duff's device for non-power-of-two remainders.
- .option norvc ensures fixed 4-byte instruction width for correct
jump offset calculation in the Duff's device entry.
- Zero-length input handled correctly (branch to guarded tail).
The old memcpy always used lw/sw even on RV64, wasting half the
memory bandwidth. The old memset unrolled only 16 bytes per iteration.
Signed-off-by: ganjing <ganjing@xiaomi.com>
Add word-at-a-time strlcpy using DETECTNULL for both the copy phase
and the strlen tail when truncated. The copy loop aligns src and
processes a register at a time, falling to bytewise for the last word
containing the terminator. When truncated, the remaining src length
is measured with a second word-at-a-time loop.
strlcpy has 46 call sites in a typical kernel image (more than strcpy)
and is not covered by newlib OPTSPEED, making it a high-value target.
Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: ganjing <ganjing@xiaomi.com>
Reduce branch overhead in the memcmp main loop by comparing four
words per iteration: XOR each pair, OR the four differences together,
and branch once. On a mismatch the single-word loop locates the
exact differing word within four words of the fault.
Add a beqz guard at .Lbyte_cmp entry to handle the case where the
4-word loop consumes all remaining bytes exactly.
Measured on QEMU RV32: memcmp(128) 313 -> 271 cycles (13% faster).
Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: ganjing <ganjing@xiaomi.com>
Add assembly-optimized implementations for 14 string/memory functions
using word-at-a-time techniques (DETECTNULL, broadcast+XOR) and
XLEN-adaptive macros for both RV32 and RV64:
- memmove: direction check + forward tail to memcpy, reverse path
with 16xSZREG unroll and shift-merge for misaligned src.
- memcmp: word-granularity compare when both pointers share alignment,
bytewise fallback for mismatched pointers.
- memchr: broadcast target byte, XOR with each word, DETECTNULL to
find matches. Counter-based bounds (no pointer overflow).
- strlen: DETECTNULL word loop, constants loaded from .srodata.
- strnlen: strlen with counter-based length limit.
- strcpy/strncpy: word loop with DETECTNULL, zero-fill remainder
for strncpy. strncpy reuses strcpy via #define USE_AS_STRNCPY.
- stpcpy/stpncpy: reuse strcpy/strncpy via #define USE_AS_STPCPY.
- strchr/strchrnul: broadcast+XOR detecting both target char and
null simultaneously. strchrnul reuses strchr via #define.
- strrchr: forward scan recording last match position.
- strncmp: word-at-a-time compare with null detection and counter.
- strcat: strlen(dst) then strcpy(dst_end, src) word-at-a-time.
Each function is independently selectable via CONFIG_RISCV_<FUNC>,
or all enabled together with CONFIG_RISCV_STRING_FUNCTION=y.
Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: ganjing <ganjing@xiaomi.com>
A protected build on the ESP32 could only use the legacy IDF image format.
Kconfig allowed simple boot to be selected with BUILD_PROTECTED, because the
legacy format is only a default and not a select, but the result did not link
and then did not boot.
Simple boot has no second-stage bootloader. __start() maps the flash itself,
so everything it reaches must already be in RAM. kernel-space.ld pinned none
of it, and it did not place esp32_start at all, so the entry point went to the
flash the code was about to map. The chip loaded the RAM segments, jumped to
0x400d0ba4 and took an IllegalInstruction on the first instruction.
So this pins the bootloader, flash, ROM, clock and log objects that
bootloader_init() and map_rom_segments() reach, along with esp32_start itself,
and defines the six _image_* symbols that __start() needs. All of it is
behind CONFIG_ESPRESSIF_SIMPLE_BOOT, so a legacy build gets the same IRAM it
had before.
kernel-space.ld also had no `#include <nuttx/config.h>'. It held no
conditionals until now, so nothing showed the omission: the new blocks
compiled away silently and the link failed as if the file had not been
changed.
The default is unchanged. A protected build still selects the legacy format
unless the user clears CONFIG_ESP32_APP_FORMAT_LEGACY.
Verified on an ESP32-DevKitC V4, ESP32-D0WD-V3 revision 3.1, with
esp32-devkitc:knsh and the legacy format turned off. The kernel flashes at
0x1000 and the user image at 0x90000, with no bootloader and no partition
table. It maps seven segments, reaches NSH, and runs ostest to the same point
as the legacy build.
Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
BUILD_PROTECTED defaults ESP32S3_APP_FORMAT_LEGACY to y, so a protected build
has always needed the ESP-IDF second-stage bootloader. Nothing about the
protected layout requires it: the kernel and user images are described
entirely by ESP32S3_KERNEL_OFFSET, ESP32S3_KERNEL_IMAGE_SIZE and
ESP32S3_KERNEL_RAM_SIZE, and esp32s3_userspace() maps the user image itself.
Three obstacles stood in the way.
Those three symbols were gated on ESP32S3_APP_FORMAT_LEGACY, but
protected_memory.ld needs all of them for KIROM, KDROM, UIROM, UDROM, KDRAM
and UDRAM. Without them the region lengths underflow to 2**64-1 and the
kernel/user RAM split lands nowhere, which the hardware reports as a DRAM0
PMS monitor violation once the first user process runs. The offset becomes
0x0 for simple boot, where the image is flashed at the start of the device.
protected_memory.ld had no case for a 32 MB part, so FLASH_SIZE was
undefined there and ROM, UIROM and UDROM underflowed the same way.
flat_memory.ld has had the case all along.
kernel-space.ld defined none of the symbols simple boot needs
(_image_irom_*, _image_drom_*, _bss_*), and kept none of the early code
resident. __start() runs bootloader_init() and map_rom_segments() before any
flash mapping exists, so everything they reach has to be in RAM -- including
map_rom_segments() itself, which unmaps the MMU it is running from, and
nuttx_enter_critical(), reached from rtc_clk_init() by way of regi2c. These
mirror what esp32s3_sections.ld already does for the flat build.
Verified on an ESP32-S3-WROOM-2 (32 MB octal flash), esp32s3-devkit:knsh with
FLASH_MODE_OCT: boots to NSH and runs ostest, where it reaches the same
timedmutex abort as every other target. The legacy path is untouched.
Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
The ondemand governor (devfreq_ondemand.c) references dev->governor_data
to store its private state, and defines devfreq_ondemand(), but neither
the field in struct devfreq_s nor the function declaration were present
in include/nuttx/devfreq.h. As a result, building with
CONFIG_DEVFREQ_GOV_ONDEMAND=y failed to compile.
These two definitions were originally introduced by a downstream commit
that was not part of the devfreq upstreaming series, so the gap only
surfaced when the ondemand governor is enabled (which additionally
requires !CONFIG_SCHED_CPULOAD_NONE and is off by default).
Add the governor_data field to struct devfreq_s and declare
devfreq_ondemand() alongside the other governors.
Signed-off-by: guanyi <guanyi@xiaomi.com>
The signal frame was built inside the 128 byte red zone of the
interrupted user code and inherited its stack alignment, so a leaf
function could lose live data to the siginfo copy and the handler
could fault on an SSE access. Build the frame below the red zone,
16 byte aligned; the naked trampoline calls the handler itself and
its call provides the return address slot.
Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
For a thread interrupted in user mode the trampoline ran on the user
stack, where the signal handler then grows over its frame. Run it on
the thread kernel stack, unused while the thread is in user mode. The
stack cannot be selected from the saved CS: up_initial_state() records
the caller CS, a kernel selector even for user threads.
Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
SYS_signal_handler_return restored RSP from saved_rsp, which is not
written when a task signals itself: synchronous dispatch skips
up_schedule_sigaction(), so the kernel stack pointer was set to zero
and the next push faulted. Save the kernel stack pointer at dispatch
in xcp.kstkptr, as risc-v does, and restore that.
Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
The Espressif Wi-Fi stack cannot work unless the esp_timer subsystem has
been initialized, but nothing in the Wi-Fi code does that: it is left to
each board's bringup to call esp_hr_timer_init() first. Any board that
does not happen to make that call dies on the first RF enable.
The dependency is not visible from the Wi-Fi sources. The path is:
board_wlan_init() -> esp_wlan_sta_initialize() -> esp_wlan_initialize()
-> esp_wifi_initialize() -> esp_wifi_api_adapter_init()
and later, when the radio is first powered up:
esp_phy_enable_wrapper() -> esp_phy_enable() (esp-hal-3rdparty,
components/esp_phy/src/phy_init.c) -> phy_track_pll_init()
(components/esp_phy/src/phy_common.c)
phy_track_pll_init() calls esp_timer_create() and
esp_timer_start_periodic() wrapped in ESP_ERROR_CHECK(). Both return
ESP_ERR_INVALID_STATE while esp_timer is uninitialized, because the HAL's
own esp_timer_init_os() startup hook is compiled out on NuttX
(#ifndef __NuttX__ in components/esp_timer/src/esp_timer.c), so the timer
task and the timer ISR only ever get created from NuttX's
esp_hr_timer_init() -> esp_timer_init().
Initialize the HR Timer at the top of esp_wifi_api_adapter_init(), where
the requirement actually originates. esp_hr_timer_init() is idempotent
(it early-returns once the subsystem is up), so boards that already call
it during bringup are unaffected. Also make ESPRESSIF_WIRELESS select
ESPRESSIF_HR_TIMER explicitly instead of inheriting it through the
deprecated ESP32{,S2,S3}_RT_TIMER symbols, so the timer adapter is
guaranteed to be built whenever the radio is.
This is deliberately limited to Xtensa. The RISC-V common-espressif tree
has the same unenforced dependency, but nothing is broken there today: its
ESPRESSIF_WIRELESS already selects both ESPRESSIF_HR_TIMER and RTC_DRIVER,
and esp_rtc.c initializes the timer. The mirror change can follow from
someone able to test it on RISC-V hardware.
This was diagnosed on an out-of-tree ESP32-S3 board whose bringup lacked
the call. The failure gives no panic output at all and looks exactly like
a CPU lockup: the system tick stops, the console dies mid-line and USB
stays enumerated but unresponsive. It was tracked down with ROM-level
ets_printf() breadcrumbs along the init path plus a high-priority thread
that busy-waits on ets_delay_us(): the breadcrumb trail ends inside
phy_track_pll_init() and never reaches the print after it, and the
busy-wait thread keeps printing while every sleep()-based thread stops
waking, showing the tick is gone. Initializing the timer ahead of Wi-Fi
init makes the same image associate to an AP, obtain a DHCP lease and
serve telnet. Validated on ESP32-S3 silicon (240 MHz, no PSRAM, 16 MiB
flash).
esp32s3-devkit:wifi builds clean with the change.
Signed-off-by: Ricard Rosson <ricard@groundbits.com>
Assisted-by: Claude Opus 5 (Claude Code)
Change the arch/mips/src/Makefile to build nuttx with CONFIG_ALLSYMS
enabled in MIPS architecture. This enables symbol name showing in
system, such as 'dumpstack 3' shows both functions name and addresses.
This change is referred to arch/tricore/src/Makefile and updated to
work well with MIPS. And it works with and without CONFIG_ALLSYMS enabled.
Fixes apache#19728
Signed-off-by: wangtao <twangpicasso@gmail.com>
A full ostest run never reached the end on esp32-devkitc:knsh. It stopped in
the barrier test:
barrier_test: ERROR thread 6 create, status=12
ostest_main: Exiting with status 256
The cause is the interaction of two settings that are each reasonable on their
own. CONFIG_TLS_ALIGNED is set and CONFIG_TLS_LOG2_MAXSTACK is 13, so every
pthread stack must start on an 8 KiB boundary. The barrier threads take the
2 KiB default stack, so each one occupies an 8 KiB aligned slot. Eight of them
do not fit the 96 KiB user heap of a protected build once the tests before them
have fragmented it, and up_create_stack() fails:
up_create_stack: ERROR: Failed to allocate stack, size 2048
The flat build has the same two settings and passes, because its heap is
320 KiB against 96 KiB here.
So this lowers the barrier thread count for this configuration only. Four
threads still test a barrier, and they leave margin: six was the most that
ever started, so six would pass with none.
The user heap cannot grow far. User data has to sit in the MMU governed window
of SRAM2, which is 128 KiB in total, and the kernel holds the first 32 KiB of
it.
Verified on an ESP32-DevKitC V4, ESP32-D0WD-V3 revision 3.1. All four threads
reach the barrier and ostest reports "Exiting with status 0".
Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
Implement architecture-specific ELF header definitions and relocation handling
for the MIPS architecture to enable loadable modules.
Fixes#19178.
Changes include:
- Add `arch/mips/include/elf.h` with MIPS ELF relocation types and
architecture-specific ELF data structures (`arch_elfdata_s`).
- Implement `libs/libc/machine/mips/arch_elf.c` containing `up_checkarch`,
`up_relocate`, and `up_relocateadd` functions handling `R_MIPS_NONE`,
`R_MIPS_32`, `R_MIPS_26`, `R_MIPS_HI16`, and `R_MIPS_LO16` relocations.
- Integrate MIPS machine-specific C library support in
`libs/libc/machine/mips/Make.defs`.
- Update `LDMODULEFLAGS` in `arch/mips/src/mips32/Toolchain.defs` to include the
little-endian (`-EL`) flag.
- Update `up_coherent_dcache` for proper cache synchronization on JZ4780.
Signed-off-by: Lwazi Dube <lwazeh@gmail.com>
SPI_VIA_IOMUX used SPI2 IOMUX pin macros that are undefined when SPI2
is disabled or on chips without IOMUX SPI pins (e.g. ESP32-P4), so the
driver took the IOMUX path and never routed SPI3 via the GPIO matrix.
Signed-off-by: Filipe Cavalcanti <filipe.cavalcanti@espressif.com>
romfs_cachenode() tracked the allocated size of rn_child in a uint8_t
while rn_count is a uint16_t. Past 256 entries the size wraps to zero,
the grow condition rn_count == num - 1 can never be true again and the
array is not reallocated: entries are written beyond the allocation,
corrupting the heap.
Track the allocated size in a size_t.
Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
Correct the number of GPIO ports (STM32_NPORTS) from 8 to 9 and include
GPIOI in the g_gpiobase array. Also fix the comparison that would
prevent the GPIOI clock from being enabled (this is really a no-op,
though).
Signed-off-by: Darryl Ring <darryl@bluerobotics.com>
Replace the iLLD Ifx_Ssw_infiniteLoop() helper in the idle path with
a self-contained 'loopu' instruction wrapper (tricore_idle_loop()).
The 'loopu' (loop unconditional) instruction branches back to itself
until an interrupt is taken, which is the standard TriCore low-power
idle sequence; the GNU and Tasking assemblers spell the backward
label differently, so the macro dispatches on the toolchain.
This removes the arch/tricore idle path's dependency on the Infineon
iLLD/Ssw layer. No behavior change: the loop is still interrupted by
any IRQ that causes a context switch away from the idle task.
Signed-off-by: zhangyu117 <zhangyu117@xiaomi.com>
QEMU's b-l475e-iot01a machine models the STM32L4x5 core peripherals, but
not the QUADSPI controller or the on-board MX25R6435F flash. The nsh
configuration therefore panics during board bring-up, inside
stm32_qspi_initialize() -> mx25rxx_initialize() -> qspi_command(), before
the console has produced any output.
Add a qemu configuration that is nsh without CONFIG_B_L475E_IOT01A_MTD_FLASH
and the QSPI/MTD/SMARTFS chain that symbol selects. It boots to an NSH
prompt on USART1 under:
qemu-system-arm -M b-l475e-iot01a -nographic -kernel nuttx
Document the new configuration, including the fact that QEMU's STM32L4x5
USART model never calls qemu_chr_fe_accept_input() after the guest reads
RDR. Console input consequently stalls after the first byte or two when a
line is pasted or piped in, although typing at human speed works.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
Add the board photo and replace the placeholder todo in the RTL8721F EVB
documentation index with a figure directive so the board page renders the
hardware image, matching the other Realtek board pages.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Assisted-by: Claude <noreply@anthropic.com>
Expose the RTL8721F general-purpose UARTs through the shared Ameba serial
driver in arch/arm/src/common/ameba. Only the chip-specific glue is added:
a new ameba_uart_chip.h supplying the green2 register bases, IRQs, clock
masks and UART TX/RX pin-mux function codes, plus the build wiring and a
board port table registering UART0 at /dev/ttyS1. The common serial layer
is reused unchanged.
A new "uart" board config enables the driver with the serialrx and
serialblaster examples and runtime TERMIOS support.
Verified on RTL8721F EVB hardware with a PA24/PA25 loopback: single-message
echo, 2600-byte serialrx/serialblaster throughput with no loss, and TERMIOS
reconfiguration (CS7 data-bit truncation, parity and stop-bit ioctl
round-trip, and 9600 baud reprogramming) all pass.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Assisted-by: Claude <noreply@anthropic.com>
In a kernel build vfork() is reached through a system call, so the return
address and stack pointer the architecture's entry point can see for itself
are the kernel's, not the caller's. A child built from those resumes at a
kernel address, which is why x86_64 selected the fork family only for the
flat build.
x86_64_syscall() now publishes the caller's frame in xcp.sregs for the
duration of the stub call, and x86_64_fork() builds the child from it:
x86_64_fork_syscall() when xcp.sregs is non-NULL, so that the child
returns from the very same `syscall' instruction as
the parent, in user mode, on its own stack;
x86_64_fork_direct() otherwise, which is the flat build and any kernel
thread that calls the entry point as a plain
function.
The discriminator is xcp.sregs rather than TCB_FLAG_SYSCALL, which arm64 and
RISC-V use: that flag also defers signal actions, x86_64 has never raised it,
and its kernel-build signal path does not survive being made to -- a
pre-existing problem that does not belong to this work.
Two properties of SYSCALL/SYSRET shape the child's frame. The instruction
leaves the caller's RIP and RFLAGS in RCX and R11 rather than on a stack, so
they are moved into the RIP and RFLAGS slots of the interrupt frame the child
is resumed from; and the hardware never records the caller's CS and SS at all,
SYSRETQ reconstructing them from IA32_STAR, so the child's are filled in with
the user code and data selectors at RPL 3. The frame is therefore not copied
wholesale: the extended state and the general registers are inherited, while
the segment registers and the thread pointer stay as up_initial_state() left
them, the child's stack being a fresh allocation the parent's FS base does not
describe.
x86_64_fork_relocfp() is new and is not optional here. A function returns
with `leave', which feeds the frame pointer into the stack pointer, so
relocating only the RBP the child resumes with gets it exactly one frame:
the next return loads a saved RBP still pointing into the parent's stack.
With that in place ARCH_X86_64 can select ARCH_HAVE_VFORK unconditionally.
Build-verified on qemu-intel64:knsh_romfs and qemu-intel64:ostest. NuttX on
qemu-intel64 requires tsc-deadline and pcid, which TCG does not implement, so
it cannot be run on this host.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
In a kernel or protected build vfork() is reached through a system call, so
the return address and stack pointer that the entry point in
arm64_fork_func.S can snapshot for itself belong to the kernel-side stub, not
to the caller. A child built from that snapshot resumes at a kernel address
on a kernel stack. This is why arm64 selected the fork family only for the
flat build.
Record what the caller was actually doing instead. arm64_sync_exc passes the
exception frame to dispatch_syscall() in x7 -- x0-x6 carry the call number and
its six parameters, so x7 is free -- and dispatch_syscall() stores it in
xcp.sregs, mirroring what riscv_swint.c does.
arm64_fork() then chooses where the caller's registers live:
arm64_fork_syscall() when TCB_FLAG_SYSCALL is set, rebuilding the child
from xcp.sregs so that it returns from the very same
SVC as the parent;
arm64_fork_direct() otherwise, which is the flat build and any kernel
thread that calls the entry point as a plain function.
The stack copy and the relocation of pointers into it are shared by both
paths in arm64_fork_stack() and arm64_fork_reloc().
With that in place ARCH_ARM64 can select ARCH_HAVE_VFORK unconditionally.
Verified on qemu-armv8a:knsh (BUILD_KERNEL), qemu-armv8a:nsh (BUILD_FLAT) and
qemu-armv8a:citest_smp under qemu-system-aarch64: ostest's vfork_test passes
on all three, and it was absent from knsh before the change. The protected
configurations are build-verified only (fvp-armv8r:pnsh), there being no
emulator for them here.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>