cederom commented on PR #18861:
URL: https://github.com/apache/nuttx/pull/18861#issuecomment-4416873276
Okay here goes the testing :-) All seems to work good :-)
Great work @linguini1 =)
We may want to put some more benchmarks into this config to see what is the
performance gain with smp? :-)
I need to get some sleep, tomorrow will try to read more about this
`putreg64((uint64_t)_start, BCM_SPINTBL_CPU(cpu));` stuff how other archs
implement it :-)
```
% uname -a
FreeBSD hexagon 14.4-RELEASE-p3 FreeBSD 14.4-RELEASE-p3 GENERIC amd64
% git reflog -1
195077a7b6c (HEAD, linguini1/rpi4b-smp) HEAD@{0}: checkout: moving from
master to linguini1/rpi4b-smp
% ./tools/configure.sh -B raspberrypi-4b:smp
Copy files
Select CONFIG_HOST_BSD=y
Refreshing...
(..)
#
# configuration written to .config
#
hexagon% /usr/bin/time -h gmake -j
Create version.h
LN: platform/board to /XXX/nuttx/pr/nuttx-apps.git/platform/dummy
Register: getprime
Register: ostest
Register: smp
Register: dd
Register: nsh
Register: sh
Register: hello
LD: nuttx
Memory region Used Size Region Size %age Used
CP: nuttx.hex
CP: nuttx.bin
Generating config.txt
10,85s real 40,41s user 15,95s sys
% gmake flash
LD: nuttx
Memory region Used Size Region Size %age Used
CP: nuttx.hex
CP: nuttx.bin
Generating config.txt
% cp nuttx.bin rpi4b-nuttx
% cp config.txt rpi4b-nuttx
% ./rpiboot -v -m 1000 -d rpi4b-nuttx
RPIBOOT: build-date 2025/11/10 pkg-version local fe4a6288
Please fit the EMMC_DISABLE / nRPIBOOT jumper before connecting the power
and USB cables to the target device.
If the device fails to connect then please see https://rpltd.co/rpiboot for
debugging tips.
Boot directory 'rpi4b-nuttx'
Loading: rpi4b-nuttx/bootcode4.bin
Waiting for BCM2835/6/7/2711/2712...
Device located successfully
Loading: rpi4b-nuttx/bootcode4.bin
Initialised device correctly
Found serial number 4
last_serial -1 serial 4
Second stage boot server
Received message GetFileSize: config.txt
Loading: rpi4b-nuttx/config.txt
File size = 47 bytes
Received message ReadFile: config.txt
File read: config.txt
libusb_bulk_transfer sent 47 bytes; returned 0
Received message GetFileSize: pieeprom.sig
libusb_bulk_transfer sent 0 bytes; returned 0
Cannot open file pieeprom.sig
Received message GetFileSize: recover4.elf
libusb_bulk_transfer sent 0 bytes; returned 0
Cannot open file recover4.elf
Received message GetFileSize: recovery.elf
libusb_bulk_transfer sent 0 bytes; returned 0
Cannot open file recovery.elf
Received message GetFileSize: start4.elf
Loading: rpi4b-nuttx/start4.elf
File size = 2299008 bytes
Received message ReadFile: start4.elf
File read: start4.elf
libusb_bulk_transfer sent 2299008 bytes; returned 0
Received message GetFileSize: fixup4.dat
Loading: rpi4b-nuttx/fixup4.dat
File size = 5496 bytes
Received message ReadFile: fixup4.dat
File read: fixup4.dat
libusb_bulk_transfer sent 5496 bytes; returned 0
Second stage boot server done
% ./rpiboot -v -m 1000 -d rpi4b-nuttx
RPIBOOT: build-date 2025/11/10 pkg-version local fe4a6288
Please fit the EMMC_DISABLE / nRPIBOOT jumper before connecting the power
and USB cables to the target device.
If the device fails to connect then please see https://rpltd.co/rpiboot for
debugging tips.
Boot directory 'rpi4b-nuttx'
Loading: rpi4b-nuttx/bootcode4.bin
Waiting for BCM2835/6/7/2711/2712...
Device located successfully
Loading embedded: bootcode.bin
Initialised device correctly
Found serial number 1
last_serial -1 serial 1
Second stage boot server
Received message GetFileSize: recovery.elf
libusb_bulk_transfer sent 0 bytes; returned 0
Cannot open file recovery.elf
Received message GetFileSize: config.txt
Loading: rpi4b-nuttx/config.txt
File size = 47 bytes
Received message ReadFile: config.txt
File read: config.txt
libusb_bulk_transfer sent 47 bytes; returned 0
Received message GetFileSize: dt-blob.bin
libusb_bulk_transfer sent 0 bytes; returned 0
Cannot open file dt-blob.bin
Received message GetFileSize: recovery.elf
libusb_bulk_transfer sent 0 bytes; returned 0
Cannot open file recovery.elf
Received message GetFileSize: config.txt
Loading: rpi4b-nuttx/config.txt
File size = 47 bytes
Received message ReadFile: config.txt
File read: config.txt
libusb_bulk_transfer sent 47 bytes; returned 0
Received message GetFileSize: bootcfg.txt
libusb_bulk_transfer sent 0 bytes; returned 0
Cannot open file bootcfg.txt
Received message GetFileSize: nuttx.bin
Loading: rpi4b-nuttx/nuttx.bin
File size = 393216 bytes
Received message GetFileSize: bcm2711-rpi-4-b.dtb
Loading: rpi4b-nuttx/bcm2711-rpi-4-b.dtb
File size = 56289 bytes
Received message ReadFile: bcm2711-rpi-4-b.dtb
File read: bcm2711-rpi-4-b.dtb
libusb_bulk_transfer sent 56289 bytes; returned 0
Received message GetFileSize: overlays/overlay_map.dtb
libusb_bulk_transfer sent 0 bytes; returned 0
Cannot open file overlays/overlay_map.dtb
Received message GetFileSize: config.txt
Loading: rpi4b-nuttx/config.txt
File size = 47 bytes
Received message ReadFile: config.txt
File read: config.txt
libusb_bulk_transfer sent 47 bytes; returned 0
Received message GetFileSize: cmdline.txt
libusb_bulk_transfer sent 0 bytes; returned 0
Cannot open file cmdline.txt
Received message GetFileSize: armstub8-gic.bin
libusb_bulk_transfer sent 0 bytes; returned 0
Cannot open file armstub8-gic.bin
Received message GetFileSize: nuttx.bin
Loading: rpi4b-nuttx/nuttx.bin
File size = 393216 bytes
Received message ReadFile: nuttx.bin
File read: nuttx.bin
libusb_bulk_transfer sent 393216 bytes; returned 0
Received message Done: nuttx.bin
CMD exit
Second stage boot server done
% minicom /dev/cuaU0
Welcome to minicom 2.10
OPTIONS: I18n
Compiled on Mar 2 2026, 17:08:02.
Port /dev/cuaU0, 02:50:56 [U]
Press CTRL-A Z for help on special keys
- Ready to Boot Primary CPU
- Boot from EL2
- Boot from EL1
- Boot to C runtime for OS Initialize
NuttShe- Ready to Boot Second CPU
- Boot from EL2
ll (NSH) NuttX-10.4.0
nsh> --- BBBoot from EL1
- B--o ot ot CorCnrunt mo for OS tiitializ
nsh> uname -a
NuttX 10.4.0 195077a7b6c May 11 2026 02:49:21 arm64 raspberrypi-4b
nsh> ?
help usage: help [-v] [<cmd>]
. cp expr mkrd set truncate
[ cmp false mount kill uname
? dirname fdinfo mv pkill umount
alias df free pidof sleep unset
unalias dmesg memdump printf usleep uptime
basename echo help ps source watch
break env hexdump pwd test xd
cat exec ls rm time wait
cd exit mkdir rmdir true
Builtin Apps:
dd hello ostest smp
getprime nsh sh
nsh> smp
Main[0]: Running on CPU1
Main[0]: Initializing barrier
Main[0]: Thread 1 created
Thread[1]: Started
Thread[1]: Running on CPU0
Main[0]: Thread 2 created
Thread[2]: Started
Thread[2]: Running on CPU2
Main[0]: Thread 3 created
Thread[3]: Started
Main[0]: Thread 4 created
Thread[4]: Started
Thread[3]: Running on CPU1
Main[0]: Thread 5 created
Thread[5]: Started
Thread[4]: Running on CPU1
Main[0]: Now running on CPU3
Thread[5]: Running on CPU3
Thread[2]: Now running on CPU0
Main[0]: Thread 6 created
Thread[6]: Started
Thread[3]: Now running on CPU3
Main[0]: Thread 7 created
Thread[4]: Now running on CPU3
Thread[6]: Running on CPU3
Thread[7]: Started
Main[0]: Now running on CPU0
Thread[5]: Now running on CPU0
Thread[7]: Running on CPU3
Thread[2]: Now running on CPU3
Main[0]: Thread 8 created
Thread[8]: Started
Thread[1]: Now running on CPU1
Thread[4]: Now running on CPU1
Main[0]: Now running on CPU2
Thread[3]: Now running on CPU2
Thread[8]: Running on CPU2
Thread[5]: Now running on CPU2
Thread[7]: Now running on CPU1
Thread[2]: Now running on CPU1
Thread[6]: Now running on CPU0
Thread[1]: Now running on CPU3
Main[0]: Now running on CPU3
Thread[8]: Now running on CPU3
Thread[5]: Now running on CPU1
Thread[7]: Now running on CPU3
Thread[4]: Now running on CPU3
Thread[2]: Now running on CPU2
Thread[3]: Now running on CPU0
Thread[6]: Now running on CPU1
Thread[7]: Now running on CPU1
Thread[8]: Now running on CPU1
Thread[4]: Now running on CPU2
Thread[2]: Now running on CPU0
Thread[1]: Now running on CPU0
Thread[5]: Now running on CPU3
Thread[3]: Now running on CPU3
Thread[6]: Now running on CPU0
Thread[7]: Now running on CPU3
Thread[4]: Now running on CPU1
Thread[2]: Now running on CPU1
Thread[3]: Now running on CPU2
Thread[5]: Now running on CPU2
Thread[8]: Now running on CPU2
Thread[4]: Now running on CPU0
Thread[5]: Now running on CPU0
Thread[6]: Now running on CPU1
Thread[3]: Now running on CPU3
Thread[7]: Now running on CPU2
Thread[8]: Now running on CPU1
Thread[6]: Now running on CPU3
Thread[2]: Now running on CPU2
Thread[3]: Now running on CPU0
Thread[4]: Now running on CPU1
Thread[5]: Now running on CPU3
Thread[7]: Now running on CPU0
Thread[1]: Now running on CPU1
Thread[1]: Calling pthread_barrier_wait()
Thread[3]: Calling pthread_barrier_wait()
Thread[4]: Now running on CPU0
Thread[5]: Now running on CPU2
Thread[7]: Now running on CPU3
Thread[2]: Now running on CPU0
Thread[2]: Calling pthread_barrier_wait()
Thread[6]: Now running on CPU0
Thread[4]: Now running on CPU2
Thread[4]: Calling pthread_barrier_wait()
Thread[5]: Calling pthread_barrier_wait()
Thread[6]: Calling pthread_barrier_wait()
Thread[7]: Calling pthread_barrier_wait()
Thread[8]: Calling pthread_barrier_wait()
Thread[1]: Back with ret=0 (I am not special)
Thread[3]: Back with ret=0 (I am not special)
Thread[2]: Back with ret=0 (I am not special)
Thread[4]: Back with ret=0 (I am not special)
Thread[5]: Back with ret=0 (I am not special)
Thread[8]: Back with ret=PTHREAD_BARRIER_SERIAL_THREAD (I AM SPECIAL)
Thread[6]: Back with ret=0 (I am not special)
Thread[7]: Back with ret=0 (I am not special)
Thread[1]: Now running on CPU0
Thread[3]: Now running on CPU1
Thread[4]: Now running on CPU1
Thread[5]: Now running on CPU1
Thread[6]: Now running on CPU2
Thread[8]: Now running on CPU3
Thread[1]: Now running on CPU3
Thread[3]: Now running on CPU0
Thread[7]: Now running on CPU0
Thread[4]: Now running on CPU3
Thread[5]: Now running on CPU3
Thread[6]: Now running on CPU0
Thread[8]: Now running on CPU2
Thread[1]: Now running on CPU0
Thread[3]: Now running on CPU3
Thread[7]: Now running on CPU2
Thread[2]: Now running on CPU2
Thread[4]: Now running on CPU0
Thread[8]: Now running on CPU0
Thread[1]: Now running on CPU1
Thread[5]: Now running on CPU0
Thread[7]: Now running on CPU0
Thread[2]: Now running on CPU0
Thread[6]: Now running on CPU1
Thread[4]: Now running on CPU3
Thread[3]: Now running on CPU1
Thread[8]: Now running on CPU3
Thread[1]: Now running on CPU3
Thread[5]: Now running on CPU3
Thread[7]: Now running on CPU2
Thread[6]: Now running on CPU2
Thread[3]: Now running on CPU2
Thread[8]: Now running on CPU1
Thread[4]: Now running on CPU1
Thread[1]: Now running on CPU0
Thread[2]: Now running on CPU3
Thread[5]: Now running on CPU2
Thread[6]: Now running on CPU0
Thread[7]: Now running on CPU0
Thread[3]: Now running on CPU3
Thread[8]: Now running on CPU0
Thread[1]: Now running on CPU2
Thread[2]: Now running on CPU2
Thread[5]: Now running on CPU1
Thread[7]: Now running on CPU2
Thread[4]: Now running on CPU2
Thread[3]: Now running on CPU2
Thread[8]: Now running on CPU1
Thread[1]: Now running on CPU0
Thread[6]: Now running on CPU3
Thread[5]: Now running on CPU3
Thread[7]: Now running on CPU0
Thread[3]: Now running on CPU1
Thread[2]: Now running on CPU0
Thread[8]: Now running on CPU0
Thread[1]: Now running on CPU2
Thread[2]: Done
Thread[6]: Now running on CPU2
Thread[4]: Now running on CPU1
Thread[7]: Now running on CPU3
Thread[3]: Now running on CPU2
Thread[8]: Now running on CPU1
Thread[2]: Now running on CPU1
Thread[1]: Now running on CPU1
Thread[5]: Now running on CPU0
Thread[7]: Now running on CPU0
Thread[3]: Now running on CPU1
Thread[7]: Done
Thread[8]: Now running on CPU2
Thread[3]: Done
Thread[4]: Now running on CPU2
Thread[6]: Done
Thread[8]: Done
Thread[4]: Done
Thread[7]: Now running on CPU2
Thread[3]: Now running on CPU2
Thread[4]: Now running on CPU1
Thread[1]: Now running on CPU3
Thread[1]: Done
Main[0]: Thread 1 completed with result=0
Main[0]: Now running on CPU1
Main[0]: Thread 2 completed with result=0
Thread[5]: Done
Main[0]: Now running on CPU0
Main[0]: Thread 3 completed with result=0
Thread[5]: Now running on CPU1
Main[0]: Thread 4 completed with result=0
Main[0]: Thread 5 completed with result=0
Main[0]: Thread 6 completed with result=0
Main[0]: Thread 7 completed with result=0
Main[0]: Thread 8 completed with result=0
nsh> ostest
stdio_test: write fd=1
stdio_test: Standard I/O Check: printf
stdio_test: write fd=2
stdio_test: Standard I/O Check: fprintf to stderr
ostest_main: putenv(Variable1=BadValue3)
ostest_main: setenv(Variable1, GoodValue1, TRUE)
ostest_main: setenv(Variable2, BadValue1, FALSE)
ostest_main: setenv(Variable2, GoodValue2, TRUE)
ostest_main: setenv(Variable3, GoodValue3, FALSE)
ostest_main: setenv(Variable3, BadValue2, FALSE)
show_variable: Variable=Variable1 has value=GoodValue1
show_variable: Variable=Variable2 has value=GoodValue2
show_variable: Variable=Variable3 has value=GoodValue3
ostest_main: Started user_main at PID=23
(..)
End of test memory usage:
VARIABLE BEFORE AFTER
======== ======== ========
arena fbb20000 fbb20000
ordblks 15 15
mxordblk fbaf6c98 fbaf6c98
uordblks 10480 10480
fordblks fbb0fb80 fbb0fb80
user_main: barrier test
barrier_test: Initializing barrier
barrier_test: Thread 0 created
barrier_func: Thread 0 started
barrier_test: Thread 1 created
barrier_func: Thread 1 started
barrier_test: Thread 2 created
barrier_func: Thread 2 started
barrier_test: Thread 3 created
barrier_func: Thread 3 started
barrier_test: Thread 4 created
barrier_func: Thread 4 started
barrier_test: Thread 5 created
barrier_func: Thread 5 started
barrier_test: Thread 6 created
barrier_func: Thread 6 started
barrier_test: Thread 7 created
barrier_func: Thread 7 started
barrier_func: Thread 0 calling pthread_barrier_wait()
barrier_func: Thread 1 calling pthread_barrier_wait()
barrier_func: Thread 2 calling pthread_barrier_wait()
barrier_func: Thread 3 calling pthread_barrier_wait()
barrier_func: Thread 4 calling pthread_barrier_wait()
barrier_func: Thread 5 calling pthread_barrier_wait()
barrier_func: Thread 6 calling pthread_barrier_wait()
barrier_func: Thread 7 calling pthread_barrier_wait()
barrier_func: Thread 7, back with status=PTHREAD_BARRIER_SERIAL_THREAD (I AM
SPECIAL)
barrier_func: Thread 0, back with status=0 (I am not special)
barrier_func: Thread 1, back with status=0 (I am not special)
barrier_func: Thread 2, back with status=0 (I am not special)
barrier_func: Thread 3, back with status=0 (I am not special)
barrier_func: Thread 4, back with status=0 (I am not special)
barrier_func: Thread 5, back with status=0 (I am not special)
barrier_func: Thread 6, back with status=0 (I am not special)
barrier_func: Thread 7 done
barrier_func: Thread 0 done
barrier_func: Thread 1 done
barrier_test: Thread 0 completed with result=0
barrier_test: Thread 1 completed with result=0
barrier_func: Thread 2 done
barrier_test: Thread 2 completed with result=0
barrier_func: Thread 3 done
barrier_test: Thread 3 completed with result=0
barrier_func: Thread 4 done
barrier_test: Thread 4 completed with result=0
barrier_func: Thread 5 done
barrier_test: Thread 5 completed with result=0
barrier_func: Thread 6 done
barrier_test: Thread 6 completed with result=0
barrier_test: Thread 7 completed with result=0
End of test memory usage:
VARIABLE BEFORE AFTER
======== ======== ========
arena fbb20000 fbb20000
ordblks 15 15
mxordblk fbaf6c98 fbaf6c98
uordblks 10480 10480
fordblks fbb0fb80 fbb0fb80
user_main: scheduler lock test
sched_lock: Starting lowpri_thread at 97
sched_lock: Set lowpri_thread priority to 97
sched_lock: Starting highpri_thread at 98
sched_lock: Set highpri_thread priority to 98
sched_lock: Waiting...
sched_lock: PASSED No pre-emption occurred while scheduler was locked.
sched_lock: Starting lowpri_thread at 97
sched_lock: Set lowpri_thread priority to 97
sched_lock: Starting highpri_thread at 98
sched_lock: Set highpri_thread priority to 98
sched_lock: Waiting...
sched_lock: PASSED No pre-emption occurred while scheduler was locked.
sched_lock: Finished
End of test memory usage:
VARIABLE BEFORE AFTER
======== ======== ========
arena fbb20000 fbb20000
ordblks 15 15
mxordblk fbaf6c98 fbaf6c98
uordblks 10480 10480
fordblks fbb0fb80 fbb0fb80
user_main: vfork() test
vfork_test: Child 455 ran successfully
user_main: smp call test
smp_call_test: Test start
smp_call_test: Call cpu 0, nowait
smp_call_test: Call cpu 0, wait
smp_call_test: Call cpu 1, nowait
smp_call_test: Call cpu 1, wait
smp_call_test: Call cpu 2, nowait
smp_call_test: Call cpu 2, wait
smp_call_test: Call cpu 3, nowait
smp_call_test: Call cpu 3, wait
smp_call_test: Call multi cpu, nowait
smp_call_test: Call in interrupt, wait
smp_call_test: Call multi cpu, wait
smp_call_test: Test success
Final memory usage:
VARIABLE BEFORE AFTER
======== ======== ========
arena fbb20000 fbb20000
ordblks 5 15
mxordblk fbb10fd0 fbaf6c98
uordblks e128 10480
fordblks fbb11ed8 fbb0fb80
user_main: Exiting
ostest_main: Exiting with status 0
nsh> getprime
Set thread priority to 10
Set thread policy to SCHED_RR
Start thread #0
thread #0 started, looking for primes < 10000, doing 10 run(s)
thread #0 finished, found 1230 primes, last one was 9973
Done
getprime took 341 msec
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]