Commit graph

531 commits

Author SHA1 Message Date
raiden00pl
f2543e5969 x86_64/intel64: make framebuffer setup recoverable
Some checks are pending
Build Documentation / build-html (push) Waiting to run
MemBrowse Memory Report / changes-filter (push) Waiting to run
MemBrowse Memory Report / load-targets (push) Waiting to run
MemBrowse Memory Report / identical (push) Blocked by required conditions
MemBrowse Memory Report / analyze (push) Blocked by required conditions
Return unsupported-format and mapping errors to board bring-up
instead of panicking, so a serial console can remain usable when
no suitable framebuffer exists.

Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: OpenAI Codex:gpt-5
2026-08-21 20:09:15 +08:00
raiden00pl
8f25b7eb60 arch/x86_64: scope user address helper to addrenv
x86_64_uservaddr() depends on the address-environment layout and
is only consumed by the kernel address-environment path.

Guard it with CONFIG_ARCH_ADDRENV so MM_PGALLOC can also be
enabled in flat builds.

Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: OpenAI Codex:gpt-5
2026-08-21 20:08:43 +08:00
raiden00pl
481d1697a8 arch/x86_64: align the user signal frame and skip the ABI red zone
Some checks are pending
MemBrowse Memory Report / changes-filter (push) Waiting to run
MemBrowse Memory Report / load-targets (push) Waiting to run
MemBrowse Memory Report / identical (push) Blocked by required conditions
MemBrowse Memory Report / analyze (push) Blocked by required conditions
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
2026-08-11 22:06:32 +08:00
raiden00pl
2c79c9951b arch/x86_64: run the signal trampoline on the thread kernel stack
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
2026-08-11 22:06:32 +08:00
raiden00pl
4405b12155 arch/x86_64: restore the kernel stack when a signal handler returns
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
2026-08-11 22:06:32 +08:00
Marco Casaroli
067e30e14f arch/x86_64: Build fork() children from the caller's syscall frame.
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>
2026-08-10 08:57:30 -03:00
Marco Casaroli
70c2ef5911 !sched/arch/libc: Give fork() and vfork() their real, separate semantics.
NuttX implemented fork() and vfork() as the same function.  Both were libc
wrappers around a single up_fork() syscall; vfork() differed only by a
trailing waitpid().  Underneath, the child joined the parent's address
environment -- the same addrenv_join() that pthread_create() uses -- and got
a private copy of the stack.  So the child shared .data, .bss and the heap
with its parent and ran concurrently with it.

That is not fork().  It is vfork()-with-a-private-stack under fork()'s name,
and the history says so: today's fork() is NuttX's old vfork(), renamed in
c33d1c9c97 (2023) without any change of behaviour.  The failure was silent --
a program written against POSIX fork() compiled, ran, and had its child's
writes land in the parent's variables.

Separate them into two primitives, chosen by which function the caller
called rather than by what the hardware happens to be:

  fork()   child gets its own copy of the parent's memory at the same
           virtual addresses; runs concurrently.  Only where an address
           environment can be duplicated -- elsewhere it is not declared at
           all, so calling it is a build error naming the function.
  vfork()  child shares the parent's memory; parent suspended until the
           child _exit()s or exec()s.  Implementable everywhere.

Below libc there is still one syscall.  up_fork() gains a bool saying which
primitive the caller used, since the per-architecture register snapshot is
the same for both, and passes it to nxtask_setup_fork(), which is the single
place the memory semantics are decided.  The argument arrives in the first
argument register and is never touched:  each architecture's snapshot takes
some other call-clobbered register for its scratch, so the flag is simply
still there when the C worker is called.

The vfork() parent suspension moves out of libc into nxtask_start_fork(),
released from nxsched_release_tcb() by nxtask_resume_vfork().  Two things
follow: the parent is resumed at exec(), since exec_swap() has already handed
the child's pid to the loaded program by the time the vfork stub exits, and
vfork() no longer depends on CONFIG_SCHED_WAITPID.

Releasing there requires one fix in nxtask_exit().  It raises rtcb->lockcount
directly rather than through sched_lock() while it tears the TCB down, so the
nxsem_post() that wakes the vfork() parent leaves it queued where a blocked
task collects while pre-emption is off -- g_pendingtasks, or g_readytorun on
SMP -- and the matching raw lockcount-- does not publish it the way
sched_unlock() would, leaving the parent stranded with nothing to move it on.
The fix mirrors sched_unlock() for each case:  nxsched_merge_pending(), or
nxsched_deliver_task() under CONFIG_SMP.  Both are no-ops while pre-emption is
still disabled, and up_exit() re-reads this_task() afterwards, so a change of
the ready-to-run head is honoured.  Without it vfork() deadlocks wherever no
other task happens to call sched_unlock() afterwards -- rv-virt:nsh64 and
rv-virt:pnsh64, where NSH is blocked in waitpid() holding the lock, and
qemu-armv8a:citest_smp, which hangs the moment the vfork() test runs.

fork() is built on a new addrenv_fork(), backed by an up_addrenv_fork() hook
that duplicates an address environment into freshly allocated pages mapped at
the same virtual addresses -- unlike up_addrenv_clone(), which copies only
the representation and leaves both pointing at the same page tables.  The
child then adopts the parent's stack geometry rather than being given a
relocated copy: a pointer to a stack local taken before fork() must name the
same object in the child that it named in the parent, and the parent's stack
is already in the duplicate, with its contents, at the parent's address.

No architecture implements up_addrenv_fork() yet, so this commit leaves
fork() unavailable everywhere.  That is the intended state.  It withdraws
fork() from ARCH_ARM, flat ARCH_ARM64, ARCH_RISCV, ARCH_SIM and ARCH_X86_64,
where until now it named the sharing primitive; per-architecture patches
restore it, with POSIX semantics, as up_addrenv_fork() lands.  In the
meantime the sharing primitive is still there under the name that describes
it: vfork() for a child that runs a program, pthread_create() for a second
flow of control that shares memory, posix_spawn() for both at once.

Kconfig: ARCH_HAVE_VFORK inherits ARCH_HAVE_FORK's select lines, conditions
included, so no configuration gains machinery; ARCH_HAVE_FORK is redefined to
mean "can provide POSIX fork() semantics" and now depends on ARCH_ADDRENV.

There is one deliberate departure from "verbatim".  ARCH_ARM selected the
fork family unconditionally, BUILD_KERNEL included, and that has never
worked:  on a kernel build the architecture's fork entry point sees the
kernel's return address and stack pointer rather than the caller's, so the
child resumes at a kernel address.  On qemu-armv7a:knsh master faults in
ostest's fork case with "Child did not run" and then a data abort; without
the condition this change faults the same way through vfork().  ARCH_ARM64
and ARCH_X86_64 already carried "if !BUILD_KERNEL" for exactly this reason --
ARM was the outlier.  Conditioning it turns a runtime fault into an honest
absence, which is the whole point of the change; arch/arm takes the condition
off again in the patch that adds its saved-syscall-frame path.  Only the
MMU-capable ARM ports are affected, since Cortex-M cannot build BUILD_KERNEL
at all.

Also fixes two latent syntax errors found on the way: a missing comma in
riscv_fork.c and mips_fork.c, both in *_FRAMEPOINTER && !SAVE_GP branches
that are never compiled today.

BREAKING CHANGE: fork() is withdrawn from every architecture.  It is no
longer declared in unistd.h, so code that calls it fails to build with an error
naming the function, and the sharing behaviour it used to have is gone rather
than renamed.  CONFIG_ARCH_HAVE_FORK no longer means "fork() exists"; it means
"this configuration can provide POSIX fork() semantics", and no architecture
selects it yet.

Quick fix, chosen by why the call was made:

  to run a program                vfork() + exec*(), or better posix_spawn()
  a second flow of control that   pthread_create()
  shares the caller's memory
  a genuinely independent copy    keep fork(), and wait for the per-arch patch
  of the process                  that implements up_addrenv_fork() and selects
                                  CONFIG_ARCH_HAVE_FORK

Out-of-tree code that tests CONFIG_ARCH_HAVE_FORK to decide whether a
fork-then-exec path is available wants CONFIG_ARCH_HAVE_VFORK instead, which is
selected in exactly the places CONFIG_ARCH_HAVE_FORK used to be.  The full
migration guide is Documentation/guides/fork_vfork_migration.rst.

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-08-10 08:57:30 -03:00
Alan Carvalho de Assis
87260499e1 cmake: Use NUTTX(_DIR/_BIN_DIR) instead CMAKE(_SRC_DIR/_BIN_DIR)
Some checks are pending
MemBrowse Memory Report / changes-filter (push) Waiting to run
MemBrowse Memory Report / load-targets (push) Waiting to run
MemBrowse Memory Report / identical (push) Blocked by required conditions
MemBrowse Memory Report / analyze (push) Blocked by required conditions
This change fixes NuttX’s CMake support when NuttX is embedded
in another project via add_subdirectory(). CMake’s CMAKE_SOURCE_DIR
and CMAKE_BINARY_DIR refer to the outermost project, causing NuttX
to access its .config, generated files, host tools, and build artifacts
in the parent project’s directories. The fix introduces NUTTX_DIR and
NUTTX_BINARY_DIR, based on CMAKE_CURRENT_SOURCE_DIR and
CMAKE_CURRENT_BINARY_DIR, and consistently uses them for NuttX
self-references while preserving existing standalone builds. It fixes
the Kconfig initialization failure reported in #19697 and allows an
embedded sim:nsh build to configure, build, and boot successfully.
The change affects only the CMake build system (not Make or Kconfig
defaults), requires the corresponding nuttx-apps change, and does not
extend add_subdirectory() support to cross-compiled non-sim boards due
to CMake’s toolchain-file limitation.

Fixes #19697.

Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Alan Carvalho de Assis <acassis@gmail.com>
2026-08-09 11:13:08 -03:00
raiden00pl
a7e0bdb0d8 arch/x86_64: align the user stack pointer when entering user space
Some checks are pending
MemBrowse Memory Report / changes-filter (push) Waiting to run
MemBrowse Memory Report / load-targets (push) Waiting to run
MemBrowse Memory Report / identical (push) Blocked by required conditions
MemBrowse Memory Report / analyze (push) Blocked by required conditions
The task and pthread entry points were entered with the stack pointer
left by the kernel side of the startup path, not aligned to the 16
bytes the ABI requires: applications calling a variadic function with
floating point arguments crashed with a general protection exception
on the first SSE store of the argument save area. Align the stack
pointer when returning to user space, where the value is known.

Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
2026-08-07 09:34:30 -03:00
raiden00pl
3e142bbced arch/x86_64: define CMAKE_LD and CMAKE_STRIP for ELF applications
CMAKE_LD was never set, so application link commands were invalid, and
CMAKE_STRIP defaulted to plain 'strip', which removes the symbol and
relocation tables required to load CONFIG_BINFMT_ELF_RELOCATABLE
binaries. Use the host linker and 'strip --strip-unneeded' as on the
other architectures.

Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
2026-08-06 02:39:03 +08:00
raiden00pl
e13fb3d8c1 arch: fix arch_interface guard for kernel builds
arch_interface exists only for CONFIG_BUILD_PROTECTED, but x86_64 and
arm64 referenced it for any non-flat build, breaking CMake
configuration of kernel builds. Use the CONFIG_BUILD_PROTECTED guard
as arm and risc-v do.

Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
2026-08-06 02:39:03 +08:00
raiden00pl
f43ce8add3 arch/x86_64: fix page table levels in pgalloc
Two level errors corrupted kernel memory when a user process extended
its heap with sbrk:

- PGT_LAST was X86_MMU_PT_LEVELS (4), but valid levels are 0-3, so the
  final level entry was written with an out-of-range index.

- x86_64_get_pgtable indexed the PD (level 2) with level 3, installing
  newly allocated page tables into the wrong PD slot.

Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
2026-08-05 13:48:02 +02:00
Alan Carvalho de Assis
c027e7c3e4 tools: fix stale archive members surviving a Kconfig-driven CSRCS change
During the Toybox port to NuttX, Claude noticed that changes in the
menuconfig weren't taking affect. This issue exists for a long time on
NuttX, in fact BayLibre's presentation from 2017 make jokes about our
building system not been reliable:
https://www.youtube.com/watch?v=XUJK2htXxKw&t=320s

Stale archive members from $(AR)'s additive-only behavior can linger
after Kconfig toggles change which files provide a symbol, causing dead
weight or "multiple definition" link errors on incremental builds.
Fixed by splitting ARCHIVE into two macros: ARCHIVE keeps the original
additive behavior for apps/libapps.a, which many independent
subdirectories contribute to across a build, while the new
ARCHIVE_REBUILD deletes then archives for the far more common case
of a single Makefile building its own self-contained $(OBJS)
- all 39 such call sites now use it.

Assisted-By: Claude Sonnet 5
Signed-off-by: Alan C. Assis <acassis@gmail.com>
2026-07-28 21:26:03 -03:00
Marco Casaroli
7fd17c9d7c arch/x86_64: do not wrap the HPET oneshot on a deadline that has passed.
Some checks failed
Build Documentation / build-html (push) Waiting to run
MemBrowse Memory Report / changes-filter (push) Waiting to run
MemBrowse Memory Report / load-targets (push) Waiting to run
MemBrowse Memory Report / identical (push) Blocked by required conditions
MemBrowse Memory Report / analyze (push) Blocked by required conditions
Docker-Linux / push (push) Has been cancelled
intel64_timer_start_absolute() computed "expected - current_us" unsigned.  A
watchdog started with a delay of zero asks for a deadline that is already
current, the subtraction wraps to nearly 2^64, and the comparator is set so
far ahead that the timer never fires.  The CONFIG_INTEL64_HPET_MIN_DELAY
clamp in intel64_oneshot_start() cannot help: the wrapped value is enormous,
not small.

Ask for the shortest delay the hardware can take instead of wrapping, and let
that existing minimum-delay logic pick it.

It presents as ostest hanging in wdog_test with no output and no fault.
apps/testing/ostest/wdog.c:281 calls wdtest_once(&test_wdog, param, 0), and
NSEC2TICK() takes the next few delays (1ns, 10ns, ...) to zero ticks as well;
wdtest_once() then spins forever in its "wait until the callback is triggered
exactly once" loop.

Impact: runtime, ARCH_INTEL64_HPET_ALARM only.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-07-27 18:24:47 -03:00
Marco Casaroli
97dcbc010b arch/x86_64: inherit the kernel low memory mapping in an address environment.
copy_kernel_mappings() copies exactly one PDPT entry, the 1GB linear window
that maps physical 0-1GB at 4GB-5GB.  The boot identity mapping of the low
4GB, which lives in PDPT entries 0-3 of g_pdpt_low (intel64_head.S:756, one
page directory per 1GB) and is where every MMIO register is reached, is not
carried over.

A kernel thread never gets an address environment of its own and
addrenv_switch() leaves the last one in place for it, so as soon as any
process exists, kernel code touching MMIO faults.  The HPET at 0xfed00000
finds it immediately -- CR2=fed000f0, in intel64_hpet_getreg() under
clock_systime_ticks() on the lpwork thread -- and any MMIO driver would.

Inherit the four boot PDPT entries.  They point at the boot page directories
rather than at copies, so anything intel64_map_region() adds later is
inherited too, and they carry no X86_PAGE_USER, so user code still cannot
reach them.

Impact: runtime, CONFIG_ARCH_ADDRENV builds only.  User-space access is
unchanged; the entries added are supervisor-only.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-07-27 18:24:47 -03:00
Marco Casaroli
a8ed107fa0 arch/x86_64: give the page allocator the physical page pool base.
mm_pginitialize() documents heap_start as "the physical address of the start
of memory region", and every x86_64 consumer of mm_pgalloc() agrees:
create_spgtables(), x86_64_get_pgtable() and up_addrenv_create() all put the
result through x86_64_pgvaddr() before touching it.  x86_64_pgvaddr() in turn
range-checks against CONFIG_ARCH_PGPOOL_PBASE (arch/x86_64/src/common/
pgalloc.h:67).  arm64's equivalent passes CONFIG_ARCH_PGPOOL_PBASE.

up_allocate_pgheap() passed CONFIG_ARCH_PGPOOL_VBASE instead, and in the
other branch X86_64_PGPOOL_BASE + X86_64_LOAD_OFFSET, which is the same
mistake spelled out.  Every page handed out was therefore a virtual address
that fell outside the pool's physical window, x86_64_pgvaddr() returned 0,
and the first x86_64_pgwipe() memset NULL.

It presents as a page fault in memset() under create_spgtables() the first
time a process address environment is created, which is loading the init
program.  qemu-intel64:knsh_romfs sets PGPOOL_PBASE=0x00c000000 and
PGPOOL_VBASE=0x10c000000, so the value passed was off by the 4GB load
offset.

Impact: runtime, CONFIG_ARCH_ADDRENV builds only (CONFIG_MM_PGALLOC).

Assisted-by: Claude:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-07-27 18:24:47 -03:00
Marco Casaroli
caa700c138 arch/x86_64: do not demand a TSC frequency for a clock that has none.
g_x86_64_timer_freq is assigned only under ARCH_INTEL64_TSC_DEADLINE or
ARCH_INTEL64_TSC, and is read only by the two intel64_tsc_*.c files those
options build.  With the HPET as the system clock it stays 0, which is
correct and harmless -- but x86_64_timer_calibrate_freq() panics on 0
unconditionally, so the board dies during x86_64_lowsetup().

Require a frequency only where something needs one, which is
ARCH_INTEL64_HAVE_TSC.

The failure mode is worth recording, because it gives nothing to work from:
the PANIC() happens before x86_64_earlyserialinit(), and the panic handler
itself then triple-faults, because _assert() reads up_interrupt_context() --
a %gs-relative load -- and the GS base is not programmed until
x86_64_cpu_priv_set().  The console stays completely empty and the machine
resets.

Impact: runtime, ARCH_INTEL64_HPET_ALARM only.  Configurations with a TSC
are unchanged -- the PANIC() is still compiled for them.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-07-27 18:24:47 -03:00
Marco Casaroli
b11c31ba8a arch/x86_64: make ARCH_INTEL64_HPET_ALARM buildable.
ARCH_INTEL64_HPET_ALARM is one of the three members of the "System Timer
Source" choice, but selecting it does not build.  Taking qemu-intel64:nsh on
master and moving the choice off ARCH_INTEL64_TSC_DEADLINE onto it:

  intel64/intel64_hpet_alarm.c:41:24: error:
      'CONFIG_ARCH_INTEL64_HPET_ALARM_CHAN' undeclared

ARCH_INTEL64_HPET_ALARM_CHAN lives inside "if INTEL64_HPET" and nothing
selects INTEL64_HPET.  Enabling that by hand moves the failure to link time,
because intel64_oneshot_lower.c is built only when INTEL64_ONESHOT is set:

  undefined reference to `oneshot_initialize'

Enabling INTEL64_ONESHOT as well finally reaches the real problem.
intel64_oneshot_lower.c implements the counter flavour of struct
oneshot_operations_s, which exists only with ONESHOT_COUNT:

  intel64_oneshot_lower.c: error: 'const struct oneshot_operations_s' has no
      member named 'start_absolute'
  intel64_oneshot_lower.c: error: implicit declaration of function
      'oneshot_count_init'
  intel64_oneshot_lower.c: error: initialization of
      'int (*)(struct oneshot_lowerhalf_s *, const struct timespec *)' from
      incompatible pointer type ... (four more of these)

ONESHOT, ONESHOT_COUNT and ONESHOT_FAST_DIVISION were selected by
ARCH_INTEL64_TSC_DEADLINE and by nothing else, so the other members of the
same choice could never be built.

Select the four from ARCH_INTEL64_HPET_ALARM as well.  INTEL64_ONESHOT
selects INTEL64_HPET in turn, which is what brings
ARCH_INTEL64_HPET_ALARM_CHAN into existence, so one added select closes all
three stages.

Impact: build only, and only for a configuration that could not be built
before.  No existing defconfig selects ARCH_INTEL64_HPET_ALARM.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-07-27 18:24:47 -03:00
Xiang Xiao
9e141acab3 !include/fcntl.h: align open flags with Linux values
Align the NuttX open(2) flag constants with the Linux asm-generic
values so that the FUSE wire protocol and other cross-platform
interfaces work without conversion.

All code that used '(flags & O_RDONLY)' as a bitmask check (always 0
now that O_RDONLY=0) has been updated to use '(flags & O_ACCMODE)'
comparisons.

The NUTTX_O_* constants in include/nuttx/fs/hostfs.h are updated to
match, and the sim hostfs open flag mapping is fixed.

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2026-06-30 13:43:44 +08:00
leisiji
8121b88666 cmake/elf: Fix ELF entry point from __start to _start
__start is the kernel boot entry for each chip, while _start (defined
in crt0.c) is the correct C runtime entry point for ELF executables.

Signed-off-by: leisiji <2265215145@qq.com>
2026-06-08 16:03:21 +08:00
Xiang Xiao
9ff99c6d0f !nuttx: drop redundant casts on tv_sec/tv_nsec and fix printf formats
Now that time_t is unconditionally 64-bit (signed int64_t) and the
struct timespec fields tv_sec / tv_nsec are wide enough on their own,
the explicit (uint64_t)/(int64_t)/(int) casts that used to guard the
multiplications and subtractions in *_us / *_ms / *_ns helpers are no
longer needed.  Drop them to keep the timekeeping math readable and
consistent with the previous sclock_t/time_t cleanup.

In the same spirit, this commit also:

* Normalises the printf-style format specifiers and casts used to
  print tv_sec / tv_nsec / tv_usec values across arch/, drivers/,
  fs/, sched/ and libs/.  The prior code was a mix of
  "%d"/"%u"/"%ld"/"%lu"/"%lld"/PRIu32/PRIu64 with matching
  (int)/(unsigned long)/(long long)/PRIu* casts; some formats
  truncated time_t on 32-bit hosts, others mismatched signedness or
  width.  Replace all such cases with the portable POSIX-recommended
  forms:

    - tv_sec  (time_t,       signed, impl-defined width) -> %jd  + (intmax_t)
    - tv_nsec (long,         signed)                     -> %ld  (no cast)
    - tv_usec (suseconds_t / long)                       -> %ld  (no cast)

  Add #include <stdint.h> where required.

* Drops a few stale `(FAR const time_t *)&ts.tv_sec` casts and
  related `(FAR struct tm *)` / `(const time_t *)` casts in
  gmtime_r() / localtime_r() / gmtime() callers; ts.tv_sec is plain
  time_t now and the casts only obscured the type.

* Fixes one overflow in fs/procfs/fs_procfscritmon.c where
  all_time.tv_sec * 1000000 could overflow on 32-bit time_t before
  being multiplied again; cast to uint64_t at the start.

No behavioural change.

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2026-05-19 16:21:28 +08:00
Xiang Xiao
c47b1e2c5b !sys/types.h: change time_t and clock_t to int64_t to align with other OSes
POSIX leaves the signedness of time_t and clock_t unspecified, but
mainstream implementations (Linux glibc/musl, the BSDs, macOS, RTEMS,
Zephyr's POSIX layer, Windows _time64) expose time_t as signed 64-bit.
NuttX has historically used uint64_t only because it was tied to the
CONFIG_SYSTEM_TIME64 knob; with that gone, switch:

  time_t   : uint64_t  -> int64_t
  clock_t  : uint64_t  -> int64_t
  CLOCK_MAX: UINT64_MAX -> INT64_MAX

This lets (time_t)-1 sentinels, negative tick deltas, and host-side
headers behave as on every other POSIX system without source churn.

Headers updated:
  - include/sys/types.h, include/limits.h, include/nuttx/clock.h
  - include/nuttx/fs/hostfs.h (nuttx_time_t alias)
  - include/nuttx/{mqueue.h,wdog.h,wqueue.h,timers/clkcnt.h}

Because clock_t is now signed 64-bit, the NuttX-internal sclock_t
alias becomes redundant: every sclock_t/SCLOCK_MAX use is folded
back to clock_t/CLOCK_MAX (notably in sched/wdog, sched/mqueue,
sched/sched, sched/clock, sched/timer, libs/libc/time, fs/vfs and
the drivers/arch consumers below).

Tick/period constants (NSEC_PER_SEC, USEC_PER_SEC, MSEC_PER_SEC,
SEC_PER_MIN, ...) in include/nuttx/clock.h are retyped from "long"
literals to INT64_C(...) so that 64-bit arithmetic no longer
depends on the host's long width.

Strip now-redundant (time_t)/(clock_t)/(unsigned long) casts and
unsigned-only branches across the tree:
  - arch RTC / oneshot / tickless lowerhalfs:
      arm: cxd56xx, efm32, imxrt, lc823450, max326xx, sam34, sama5,
           samd5e5, samv7, stm32, stm32f7, stm32h7, stm32l4, stm32wb,
           xmc4
      mips: pic32mz       sparc: bm3803       x86_64: intel64
      risc-v/xtensa: espressif (esp_i2c[_slave], esp_rtc,
           esp32c3{_i2c,_rtc,_wifi_adapter}, esp32{,s2,s3}_*),
           mpfs_perf
  - drivers: audio/tone, input/aw86225, power/pm/{activity,
           stability}_governor, rpmsg/rpmsg_ping,
           timers/{ds3231,mcp794xx,pcf85263,rx8010},
           wireless/ieee80211/bcm43xxx, wireless/spirit/spirit_spi
  - core: fs/vfs/{fs_poll,fs_timerfd}, mm/iob/iob_alloc,
          libs/libc/{netdb/lib_dnscache,time/{lib_calendar2utc,
          lib_time}}, net/icmp/icmp_pmtu, net/icmpv6/icmpv6_pmtu,
          net/ipfrag, net/tcp/{tcp.h,tcp_timer},
          net/utils/net_snoop, net/mld/mld_query (drop the now-dead
          mld_mrc2mrd helper since signed math handles it directly),
          sched/clock/{clock,clock_initialize},
          sched/sched/{sched_profil,sched_setparam,sched_setscheduler},
          sched/pthread/pthread_create,
          sched/wdog/{wd_gettime,wd_start,wdog.h},
          sched/timer/timer_gettime, sched/mqueue/*

Flip the few in-tree printf format strings that assumed an
unsigned 64-bit tv_sec:
  * drivers/rpmsg/rpmsg_ping.c                       PRIu64 -> PRId64
  * arch/xtensa/src/esp32{,s2,s3}/esp32*_oneshot_lowerhalf.c
                                          PRIu32 (already wrong) -> PRId64

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2026-05-19 16:21:28 +08:00
Xiang Xiao
c6654b1106 !sched/clock: remove CONFIG_SYSTEM_TIME64 and always use 64-bit time
The 32-bit system clock has a limited range (~497 days) and the
configuration knob is no longer worth the complexity given that
practically every modern target already enables it.  Make 64-bit
time_t/clock_t/sclock_t/nuttx_time_t the only supported flavor.

Specifically:
  - Drop the SYSTEM_TIME64 Kconfig option and its dependent
    PERF_OVERFLOW_CORRECTION/HRTIMER guards in sched/Kconfig.
  - Remove every #ifdef CONFIG_SYSTEM_TIME64 branch in headers
    (include/{sys/types.h,limits.h,inttypes.h,nuttx/clock.h,
    nuttx/fs/hostfs.h}) and core code paths
    (sched/clock/clock.h, drivers/power/pm/pm_procfs.c,
    drivers/rpmsg/rpmsg_ping.c, fs/procfs/fs_procfsuptime.c,
    libs/libc/wqueue/work_usrthread.c,
    arch/avr/src/avrdx/avrdx_timerisr_tickless_alarm.c).
  - Strip CONFIG_SYSTEM_TIME64=y from every board defconfig.
  - Update Documentation/guides/rust.rst accordingly.

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2026-05-19 16:21:28 +08:00
Liam Hickey
13ba91a33f arch/*/src/Makefile: Avoid uncessary relinking of the nuttx binary.
The goal is to only execute recipes when there is an actual change in
the prerequisites.

There are several issues which cause the nuttx binary target to be
re-made every time the top level make is run.

1. Previously the target nuttx$(EXEEXT), was used, but make resolved
this in the relative directory make -C $(ARCH_SRC), and couldn’t find
it (need an absolute path: `$(TOPDIR)/..).

2. The .tmp prerequisite for nuttx was always deleted

3. libboard's recipe had a sub-make which may or may not update that
target. This was a phony target, and was therefore always considered out
of date.

These issues were causing the nuttx recipe to be run every make, which
was hiding some missing prerequisites:

1. the .config is a prerequisite for the .tmp target
2. libapps.a (and other linklibs) are pre-requisites for nuttx

Changes:

The changes are only in the build system, and only for arm.

Track nuttx$(EXEEXT) via vpath so Make knows when it's already up to
date without an explicit path. Add $(TOPDIR)/.config as a dependency
to the linker script preprocessing so config changes trigger
re-preprocessing.

Keep the .tmp linker script on disk (clean already removes it) so
timestamp-based dependency checking works across builds. These .tmp
files need to be added to the gitignore or the CI will complain.

Use FORCE pattern for board/libboard to ensure it's always checked
but use the actual library file as the link dependency so nuttx is
only re-linked when library content changes. Add staging libs as
dependency to nuttx link rule so changed app libs trigger re-link.

Signed-off-by: Liam Hickey <williamhickey@geotab.com>
2026-05-18 09:33:58 +02:00
raiden00pl
a9e9607d95 arch/x86_64/intel64: fix signal delivery race in x86_64_sigdeliver
copy logic from arm64 to fix SMP bugs in the signal trampoline
caused signals to be lost or mis-delivered in ostest signest_test
on qemu-intel64/jumbo.

Also update comments so this logic is easier to follow

Signed-off-by: raiden00pl <raiden00@railab.me>
2026-04-21 21:57:44 +08:00
Piyush Patle
13d0e64ee6 style: fix checkpatch issues after debug.h move
Fixed copespell errors, for CI sucess!

Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
2026-04-07 07:50:06 -03:00
Piyush Patle
0dccc8ba21 include/debug.h: Move to include/nuttx/debug.h
debug.h is a NuttX-specific, non-POSIX header. Placing it in the
top-level include/ directory creates naming conflicts with external
projects that define their own debug.h.
This commit moves the canonical header to include/nuttx/debug.h,
following the NuttX convention for non-POSIX/non-standard headers,
and updates all in-tree references.

A backward-compatibility shim is left at include/debug.h that
emits a deprecation #warning and re-includes <nuttx/debug.h>,
allowing out-of-tree code to continue building while migrating.

Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
2026-04-07 07:50:06 -03:00
p-szafonimateusz
8b57a48d8f arch/intel64: add CPU affinity support for irq
add CPU affinity support for interrupts (up_affinity_irq)

Signed-off-by: p-szafonimateusz <p-szafonimateusz@xiaomi.com>
2026-03-31 21:10:51 +08:00
trns1997
219a5ce09e build/cmake/stdlib: guard include/cxx by LIBMINIABI, fix div_t conflict
include/cxx contains NuttX's mini C++ ABI shims and must only be added
to the include path when CONFIG_LIBMINIABI is selected.  tools/Config.mk
was adding it unconditionally for every non-LIBCXX/non-UCLIBCXX build,
and the platform.cmake files for arm, arm64, risc-v, x86_64 and tricore
were adding it inside the CONFIG_LIBCXXTOOLCHAIN block.

With an unpatched downloaded ARM GNU Toolchain, <cstdlib> uses
newlib's stdlib.h, defining div_t as an anonymous struct.  A later
inclusion of NuttX's stdlib.h via <cstdio>->stdio.h->kmalloc.h then
redefines div_t with struct tag div_s, causing a conflicting declaration
error.

Guard the div_t/ldiv_t/lldiv_t definitions in stdlib.h with
redefinitions when a toolchain stdlib.h was already processed.

Also fix lldiv_s members typed as long instead of long long.

Signed-off-by: trns1997 <trns1997@gmail.com>
2026-03-29 16:45:29 -03:00
simbit18
1bbe9276df arch\x86_64: Fix Make style
- Remove spaces from make file

Signed-off-by: simbit18 <simbit18@gmail.com>
2026-03-23 18:16:46 -04:00
SPRESENSE
72b67832ea Makefile: Remove make depend files by make distclean
Intermediate files of make depend like .ddc and .dds may remain
when make is interrupted. Remove them using make distclean.

Signed-off-by: SPRESENSE <41312067+SPRESENSE@users.noreply.github.com>
2026-02-16 16:27:57 +01:00
cqb
7b1e9eb8bc arch/x86_64: replaced loop construct with rep movsb
Replaces inefficient loop construct with rep movsb string instruction.

Signed-off-by: cqb <cqb@sideways.engineering>
2026-02-02 13:58:10 +08:00
humzak711
46e03d0471 arch/x86_64: use pause to reduce power consumption in spin wait loops
Signed-off-by: humzak711 <humzak711@gmail.com>

This commit defines the UP_WFE() macro as the 'pause' instruction for
x86_64. This optimization reduces power consumption and prevents
pipeline flushes caused by memory ordering violations during contended
spinlock acqusitions
2026-01-30 08:09:44 -03:00
wangzhi16
364a633ec3 sched/signal: Optimize code logic
Adjust the up_schedule_sigaction function to facilitate subsequent spinlock optimization work.

Signed-off-by: wangzhi16 <wangzhi16@xiaomi.com>
2026-01-27 21:24:31 +08:00
trns1997
9159f6e353 build/cmake: Add toolchain C++ library linking for all platforms.
Extend CONFIG_LIBCXXTOOLCHAIN support to all remaining platforms
in CMake builds by explicitly locating and linking libstdc++.a
from the toolchain. This prevents build failures caused by STL
header/library mismatches where toolchain headers are included
without the corresponding library.
* Adds nuttx_find_toolchain_lib() calls for all platforms.
* Aligns CMake behavior with Make build system.

Signed-off-by: trns1997 <trns1997@gmail.com>
2026-01-24 19:30:21 +08:00
liwenxiang1
b1fe00fa1e arch/acpi:Fix issue 02 Compile acpidump crash problem
At certain optimization levels, GCC/Clang may insert UD2 if it detects undefined behavior (such as integer overflow or illegal pointer access), causing the program to crash immediately instead of executing unpredictable code.

Signed-off-by: liwenxiang1 <liwenxiang1@xiaomi.com>
2026-01-24 19:28:22 +08:00
humzak711
e47a0dd228 arch/x86_64: optimize assembly instructions for size and performan
Signed-off-by: humzak711 <humzak711@gmail.com>

arch/x86_64: optimize assembly instructions for size and performance
2026-01-24 17:24:41 +08:00
hujun5
a3273e6a96 arch: Add stack alignment and stack size checking when CONFIG_TLS_ALIGNED=y
Add validation to ensure allocated stack size does not exceed TLS_MAXSTACK when
CONFIG_TLS_ALIGNED is enabled, and verify proper stack alignment using STACK_ALIGN_MASK
across all architectures. This improves stack safety and prevents potential TLS overflow conditions.

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2026-01-22 22:18:11 +08:00
ouyangxiangzhen
d404b15d8f arch/x86_64: Fix compilation error.
This commit fixed a compilation error about the undefined sizeof(struct tls_info_s).

Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
2026-01-22 22:14:00 +08:00
hujun5
6f03601169 arch: rename STACK_ALIGNMENT to STACKFRAME_ALIGN across all architectures
Rename STACK_ALIGNMENT macro to STACKFRAME_ALIGN throughout the codebase
to provide clearer naming semantics. The new name better reflects the macro's
purpose of frame alignment rather than general stack alignment.

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2026-01-22 15:37:24 +08:00
hujun5
7ee3890e7a x64_64: it is not necessary to call restore_critical_section in irq
Remove restore_critical_section() call from common_handler() in x86_64 interrupt
processing as it is not necessary during interrupt handling. The critical section
state is properly managed by the interrupt framework elsewhere.

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2026-01-20 11:49:39 -03:00
liwenxiang1
2645e06c86 arch/x86_64: Add gprof
add gprof tool

Signed-off-by: liwenxiang1 <liwenxiang1@xiaomi.com>
2026-01-20 22:43:38 +08:00
liwenxiang1
b1373857b7 arch/x86_64: Resolve the issue of abnormal stack check display.
Resolve the issue of abnormal stack check display

Signed-off-by: liwenxiang1 <liwenxiang1@xiaomi.com>
2026-01-20 22:43:38 +08:00
liwenxiang1
0046070395 arch/x86_64:Add runtime stack size analysis
Add runtime stack size analysis tool

Signed-off-by: liwenxiang1 <liwenxiang1@xiaomi.com>
2026-01-20 22:43:38 +08:00
liwenxiang1
79b82da476 arch/x86_64: Add stack usage
add stack usage tool

Signed-off-by: liwenxiang1 <liwenxiang1@xiaomi.com>
2026-01-20 22:43:38 +08:00
liwenxiang1
bd2cce7f1a arch/x64: fix revoke_low_memory
the virtual address of the page table (PT) is saved into the page directory (PD) entry, but the PD entry should store the physical address instead

Signed-off-by: liwenxiang1 <liwenxiang1@xiaomi.com>
2026-01-20 17:15:50 +08:00
liwenxiang1
46c319d948 arch/x64: Solve the sig_nest hang issue
When an interrupt occurs, the hardware automatically pushes the current RIP/RSP onto the interrupt stack. During the interrupt return, the iretq instruction pops them back. The problem is that the RIP/RSP modified by the signal is stored in the XCP context, whereas iretq operates on the interrupt stack. As a result, the RIP/RSP modified by the signal does not take effect in the iretq instruction, causing the task receiving the signal to fail to jump correctly to the signal handler. This behavior appears as if the signal is lost

Signed-off-by: liwenxiang1 <liwenxiang1@xiaomi.com>
2026-01-20 06:53:04 +08:00
liwenxiang1
41da7121bd arch/x64: interrupt add CFI info
interrupt add CFI info

Signed-off-by: liwenxiang1 <liwenxiang1@xiaomi.com>
2026-01-20 06:52:00 +08:00
hujun5
63e59e26c0 arch: move some macros to public code.
Move stack alignment and kernel stack macros from architecture-specific internal
headers to public include/nuttx/irq.h. Consolidates duplicate definitions across
17 architecture families, reducing code duplication while enabling common code
to access these core alignment utilities without architecture dependencies.

Signed-off-by: hujun5 <hujun5@xiaomi.com>
2026-01-20 01:53:08 +08:00
raiden00pl
f19b28d3d2 arch/x86_64/x86_64_acpi_procfs.c: fix build warnings
fix warnings:

CC:  intel64/intel64_schedulesigaction.c common/x86_64_acpi_procfs.c:121:3: warning: excess elements in struct initializer
  121 |   0444
      |   ^~~~
common/x86_64_acpi_procfs.c:121:3: note: (near initialization for ‘g_acpi_procfs’)
common/x86_64_acpi_procfs.c:129:3: warning: excess elements in struct initializer
  129 |   0
      |   ^
common/x86_64_acpi_procfs.c:129:3: note: (near initialization for ‘g_acpi_file_procfs’)

Signed-off-by: raiden00pl <raiden00@railab.me>
2026-01-19 14:46:34 +01:00