summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/base64/base64-decode.c165
-rw-r--r--cpukit/base64/base64-encode.c121
-rw-r--r--cpukit/compression/xz/COPYING (renamed from cpukit/libmisc/xz/COPYING)0
-rw-r--r--cpukit/compression/xz/README (renamed from cpukit/libmisc/xz/README)0
-rw-r--r--cpukit/compression/xz/xz_config.h (renamed from cpukit/libmisc/xz/xz_config.h)0
-rw-r--r--cpukit/compression/xz/xz_crc32.c (renamed from cpukit/libmisc/xz/xz_crc32.c)0
-rw-r--r--cpukit/compression/xz/xz_crc64.c (renamed from cpukit/libmisc/xz/xz_crc64.c)0
-rw-r--r--cpukit/compression/xz/xz_dec_lzma2.c (renamed from cpukit/libmisc/xz/xz_dec_lzma2.c)0
-rw-r--r--cpukit/compression/xz/xz_dec_stream.c (renamed from cpukit/libmisc/xz/xz_dec_stream.c)0
-rw-r--r--cpukit/compression/xz/xz_lzma2.h (renamed from cpukit/libmisc/xz/xz_lzma2.h)0
-rw-r--r--cpukit/compression/xz/xz_private.h (renamed from cpukit/libmisc/xz/xz_private.h)0
-rw-r--r--cpukit/compression/xz/xz_stream.h (renamed from cpukit/libmisc/xz/xz_stream.h)0
-rw-r--r--cpukit/compression/zlib/ChangeLog.zlib (renamed from cpukit/zlib/ChangeLog.zlib)0
-rw-r--r--cpukit/compression/zlib/FAQ (renamed from cpukit/zlib/FAQ)0
-rw-r--r--cpukit/compression/zlib/README (renamed from cpukit/zlib/README)0
-rw-r--r--cpukit/compression/zlib/adler32.c (renamed from cpukit/zlib/adler32.c)0
-rw-r--r--cpukit/compression/zlib/compress.c (renamed from cpukit/zlib/compress.c)0
-rw-r--r--cpukit/compression/zlib/crc32.c (renamed from cpukit/zlib/crc32.c)0
-rw-r--r--cpukit/compression/zlib/crc32.h (renamed from cpukit/zlib/crc32.h)0
-rw-r--r--cpukit/compression/zlib/deflate.c (renamed from cpukit/zlib/deflate.c)0
-rw-r--r--cpukit/compression/zlib/deflate.h (renamed from cpukit/zlib/deflate.h)0
-rw-r--r--cpukit/compression/zlib/doc/algorithm.txt (renamed from cpukit/zlib/doc/algorithm.txt)0
-rw-r--r--cpukit/compression/zlib/doc/rfc1950.txt (renamed from cpukit/zlib/doc/rfc1950.txt)0
-rw-r--r--cpukit/compression/zlib/doc/rfc1951.txt (renamed from cpukit/zlib/doc/rfc1951.txt)0
-rw-r--r--cpukit/compression/zlib/doc/rfc1952.txt (renamed from cpukit/zlib/doc/rfc1952.txt)0
-rw-r--r--cpukit/compression/zlib/doc/txtvsbin.txt (renamed from cpukit/zlib/doc/txtvsbin.txt)0
-rw-r--r--cpukit/compression/zlib/gzclose.c (renamed from cpukit/zlib/gzclose.c)0
-rw-r--r--cpukit/compression/zlib/gzguts.h (renamed from cpukit/zlib/gzguts.h)0
-rw-r--r--cpukit/compression/zlib/gzlib.c (renamed from cpukit/zlib/gzlib.c)0
-rw-r--r--cpukit/compression/zlib/gzread.c (renamed from cpukit/zlib/gzread.c)0
-rw-r--r--cpukit/compression/zlib/gzwrite.c (renamed from cpukit/zlib/gzwrite.c)0
-rw-r--r--cpukit/compression/zlib/infback.c (renamed from cpukit/zlib/infback.c)0
-rw-r--r--cpukit/compression/zlib/inffast.c (renamed from cpukit/zlib/inffast.c)0
-rw-r--r--cpukit/compression/zlib/inffast.h (renamed from cpukit/zlib/inffast.h)0
-rw-r--r--cpukit/compression/zlib/inffixed.h (renamed from cpukit/zlib/inffixed.h)0
-rw-r--r--cpukit/compression/zlib/inflate.c (renamed from cpukit/zlib/inflate.c)0
-rw-r--r--cpukit/compression/zlib/inflate.h (renamed from cpukit/zlib/inflate.h)0
-rw-r--r--cpukit/compression/zlib/inftrees.c (renamed from cpukit/zlib/inftrees.c)0
-rw-r--r--cpukit/compression/zlib/inftrees.h (renamed from cpukit/zlib/inftrees.h)0
-rw-r--r--cpukit/compression/zlib/trees.c (renamed from cpukit/zlib/trees.c)0
-rw-r--r--cpukit/compression/zlib/trees.h (renamed from cpukit/zlib/trees.h)0
-rw-r--r--cpukit/compression/zlib/uncompr.c (renamed from cpukit/zlib/uncompr.c)0
-rw-r--r--cpukit/compression/zlib/zutil.c (renamed from cpukit/zlib/zutil.c)0
-rw-r--r--cpukit/compression/zlib/zutil.h (renamed from cpukit/zlib/zutil.h)0
-rw-r--r--cpukit/crc/crc24q.c148
-rw-r--r--cpukit/dev/can/can.c507
-rw-r--r--cpukit/dev/flash/flashdev.c47
-rw-r--r--cpukit/dev/ioprintf.c (renamed from cpukit/score/src/ioprintf.c)4
-rw-r--r--cpukit/dev/iorelax.c (renamed from cpukit/score/src/iorelax.c)4
-rw-r--r--cpukit/dev/iovprintf.c (renamed from cpukit/score/src/iovprintf.c)4
-rw-r--r--cpukit/doxygen.h25
-rw-r--r--cpukit/doxygen/appl-config.h52
-rw-r--r--cpukit/doxygen/build.h82
-rw-r--r--cpukit/doxygen/mainpage.h206
-rw-r--r--cpukit/doxygen/top-level-groups.h8
-rw-r--r--cpukit/ftpd/ftpd.c14
-rw-r--r--cpukit/include/dev/can/can-msg.h105
-rw-r--r--cpukit/include/dev/can/can.h284
-rw-r--r--cpukit/include/dev/can/canqueueimpl.h231
-rw-r--r--cpukit/include/dev/flash/flashdev.h9
-rw-r--r--cpukit/include/machine/_timecounter.h2
-rw-r--r--cpukit/include/pci/irq.h17
-rw-r--r--cpukit/include/rtems/base64.h (renamed from cpukit/include/rtems/score/io.h)114
-rw-r--r--cpukit/include/rtems/confdefs/clock.h5
-rw-r--r--cpukit/include/rtems/config.h2
-rw-r--r--cpukit/include/rtems/crc.h106
-rw-r--r--cpukit/include/rtems/dev/io.h123
-rw-r--r--cpukit/include/rtems/imfs.h2
-rw-r--r--cpukit/include/rtems/libio.h5
-rw-r--r--cpukit/include/rtems/linkersets.h50
-rw-r--r--cpukit/include/rtems/posix/posixapi.h6
-rw-r--r--cpukit/include/rtems/posix/spinlockimpl.h8
-rw-r--r--cpukit/include/rtems/regulator.h502
-rw-r--r--cpukit/include/rtems/regulatorimpl.h135
-rw-r--r--cpukit/include/rtems/rtems/cache.h7
-rw-r--r--cpukit/include/rtems/rtems/mainpage.h951
-rw-r--r--cpukit/include/rtems/rtems/partdata.h6
-rw-r--r--cpukit/include/rtems/rtems/tasks.h27
-rw-r--r--cpukit/include/rtems/rtl/rtl-allocator.h46
-rw-r--r--cpukit/include/rtems/rtl/rtl-obj.h199
-rw-r--r--cpukit/include/rtems/rtl/rtl-sym.h26
-rw-r--r--cpukit/include/rtems/rtl/rtl.h8
-rw-r--r--cpukit/include/rtems/score/atomic.h962
-rw-r--r--cpukit/include/rtems/score/basedefs.h19
-rw-r--r--cpukit/include/rtems/score/cpustdatomic.h986
-rw-r--r--cpukit/include/rtems/score/isr.h14
-rw-r--r--cpukit/include/rtems/score/mpci.h3
-rw-r--r--cpukit/include/rtems/score/mpciimpl.h3
-rw-r--r--cpukit/include/rtems/score/mrspimpl.h2
-rw-r--r--cpukit/include/rtems/score/processormask.h379
-rw-r--r--cpukit/include/rtems/score/processormaskimpl.h437
-rw-r--r--cpukit/include/rtems/score/smpimpl.h2
-rw-r--r--cpukit/include/rtems/score/thread.h80
-rw-r--r--cpukit/include/rtems/score/threadimpl.h2
-rw-r--r--cpukit/include/rtems/score/tls.h120
-rw-r--r--cpukit/include/rtems/sysinit.h91
-rw-r--r--cpukit/include/rtems/termiosdevice.h300
-rw-r--r--cpukit/include/rtems/termiostypes.h244
-rw-r--r--cpukit/include/rtems/test-gcov.h (renamed from cpukit/include/rtems/score/gcov.h)17
-rw-r--r--cpukit/include/rtems/test-info.h21
-rw-r--r--cpukit/include/rtems/test-printer.h69
-rw-r--r--cpukit/include/rtems/test.h22
-rw-r--r--cpukit/include/rtems/thread.h21
-rw-r--r--cpukit/include/sys/_ffcounter.h9
-rw-r--r--cpukit/include/sys/endian.h9
-rw-r--r--cpukit/include/sys/priority.h8
-rw-r--r--cpukit/include/sys/statvfs.h7
-rw-r--r--cpukit/include/sys/timeffc.h9
-rw-r--r--cpukit/include/sys/timepps.h9
-rw-r--r--cpukit/include/sys/timetc.h9
-rw-r--r--cpukit/include/sys/timex.h9
-rw-r--r--cpukit/libblock/src/bdbuf.c3
-rw-r--r--cpukit/libblock/src/blkdev-imfs.c2
-rw-r--r--cpukit/libblock/src/media.c6
-rw-r--r--cpukit/libcsupport/src/cachecoherentalloc.c30
-rw-r--r--cpukit/libcsupport/src/getpid.c1
-rw-r--r--cpukit/libcsupport/src/getppid.c2
-rw-r--r--cpukit/libcsupport/src/isatty_r.c1
-rw-r--r--cpukit/libcsupport/src/malloc_p.h11
-rw-r--r--cpukit/libcsupport/src/sup_fs_location.c1
-rw-r--r--cpukit/libcsupport/src/termiosinitialize.c11
-rw-r--r--cpukit/libcsupport/src/vprintk.c2
-rw-r--r--cpukit/libdl/rtl-alloc-heap.c5
-rw-r--r--cpukit/libdl/rtl-allocator.c135
-rw-r--r--cpukit/libdl/rtl-archive.c3
-rw-r--r--cpukit/libdl/rtl-elf.c55
-rw-r--r--cpukit/libdl/rtl-mdreloc-aarch64.c45
-rw-r--r--cpukit/libdl/rtl-mdreloc-arm.c9
-rw-r--r--cpukit/libdl/rtl-mdreloc-bfin.c6
-rw-r--r--cpukit/libdl/rtl-mdreloc-i386.c6
-rw-r--r--cpukit/libdl/rtl-mdreloc-lm32.c6
-rw-r--r--cpukit/libdl/rtl-mdreloc-m68k.c6
-rw-r--r--cpukit/libdl/rtl-mdreloc-microblaze.c298
-rw-r--r--cpukit/libdl/rtl-mdreloc-mips.c6
-rw-r--r--cpukit/libdl/rtl-mdreloc-moxie.c6
-rw-r--r--cpukit/libdl/rtl-mdreloc-powerpc.c24
-rw-r--r--cpukit/libdl/rtl-mdreloc-riscv.c6
-rw-r--r--cpukit/libdl/rtl-mdreloc-sparc.c160
-rw-r--r--cpukit/libdl/rtl-mdreloc-v850.c6
-rw-r--r--cpukit/libdl/rtl-obj.c209
-rw-r--r--cpukit/libdl/rtl-shell.c2
-rw-r--r--cpukit/libdl/rtl-sym.c40
-rw-r--r--cpukit/libdl/rtl-tls.c (renamed from cpukit/score/cpu/aarch64/include/rtems/score/cpuatomic.h)27
-rw-r--r--cpukit/libdl/rtl-tls.h (renamed from cpukit/score/cpu/microblaze/include/rtems/score/cpuatomic.h)24
-rw-r--r--cpukit/libdl/rtl.c8
-rw-r--r--cpukit/libfs/src/dosfs/fat.c2
-rw-r--r--cpukit/libfs/src/dosfs/fat_fat_operations.c12
-rw-r--r--cpukit/libfs/src/dosfs/msdos_create.c2
-rw-r--r--cpukit/libfs/src/dosfs/msdos_dir.c14
-rw-r--r--cpukit/libfs/src/dosfs/msdos_file.c7
-rw-r--r--cpukit/libfs/src/dosfs/msdos_misc.c5
-rw-r--r--cpukit/libfs/src/dosfs/msdos_mknod.c2
-rw-r--r--cpukit/libfs/src/imfs/imfs_load_tar.c8
-rw-r--r--cpukit/libfs/src/imfs/imfs_memfile.c1
-rw-r--r--cpukit/libfs/src/jffs2/include/linux/mutex.h31
-rw-r--r--cpukit/libfs/src/jffs2/include/linux/rwsem.h16
-rw-r--r--cpukit/libfs/src/jffs2/include/linux/workqueue.h8
-rw-r--r--cpukit/libfs/src/jffs2/src/fs-rtems.c99
-rw-r--r--cpukit/libfs/src/jffs2/src/jffs2_fs_sb.h3
-rw-r--r--cpukit/libfs/src/jffs2/src/os-rtems.h4
-rw-r--r--cpukit/libfs/src/jffs2/src/scan.c24
-rw-r--r--cpukit/libmisc/regulator/regulator.c680
-rw-r--r--cpukit/libmisc/rtems-fdt/rtems-fdt.c2
-rw-r--r--cpukit/libmisc/shell/shell.c150
-rw-r--r--cpukit/libmisc/uuid/gen_uuid.c11
-rw-r--r--cpukit/libtest/gcovdumpinfo.c (renamed from cpukit/score/src/gcovdumpinfo.c)4
-rw-r--r--cpukit/libtest/gcovdumpinfobase64.c (renamed from cpukit/score/src/gcovdumpinfobase64.c)14
-rw-r--r--cpukit/libtest/gcovinfoset.c (renamed from cpukit/score/src/gcovinfoset.c)4
-rw-r--r--cpukit/libtest/t-test-busy-tick.c3
-rw-r--r--cpukit/libtest/t-test-busy.c3
-rw-r--r--cpukit/libtest/t-test-checks-eno.c13
-rw-r--r--cpukit/libtest/t-test-checks-psx.c5
-rw-r--r--cpukit/libtest/t-test-checks.c13
-rw-r--r--cpukit/libtest/t-test-hash-sha256.c18
-rw-r--r--cpukit/libtest/t-test-interrupt.c3
-rw-r--r--cpukit/libtest/t-test-rtems-context.c13
-rw-r--r--cpukit/libtest/t-test-rtems-fds.c13
-rw-r--r--cpukit/libtest/t-test-rtems-heap.c13
-rw-r--r--cpukit/libtest/t-test-rtems-measure.c13
-rw-r--r--cpukit/libtest/t-test-rtems-memory.c9
-rw-r--r--cpukit/libtest/t-test-rtems-objs.c5
-rw-r--r--cpukit/libtest/t-test-rtems-posix-keys.c5
-rw-r--r--cpukit/libtest/t-test-rtems.c13
-rw-r--r--cpukit/libtest/t-test-rtems.h5
-rw-r--r--cpukit/libtest/t-test-thread-switch.c3
-rw-r--r--cpukit/libtest/t-test-time.c13
-rw-r--r--cpukit/libtest/t-test.c49
-rw-r--r--cpukit/libtest/testbeginend.c10
-rw-r--r--cpukit/libtest/testextension.c1
-rw-r--r--cpukit/libtest/testgcovbspreset.c2
-rw-r--r--cpukit/libtest/testgcovcpufatalhalt.c2
-rw-r--r--cpukit/libtest/testgcovdumpinfo.c32
-rw-r--r--cpukit/libtest/testrun.c27
-rw-r--r--cpukit/libtest/testwrappers.c2
-rw-r--r--cpukit/libtrace/record/record-dump-base64.c7
-rw-r--r--cpukit/libtrace/record/record-dump-zbase64.c9
-rw-r--r--cpukit/posix/src/condtimedwait.c1
-rw-r--r--cpukit/posix/src/killinfo.c2
-rw-r--r--cpukit/posix/src/mutexattrsetprotocol.c1
-rw-r--r--cpukit/posix/src/mutexunlock.c2
-rw-r--r--cpukit/posix/src/psignal.c1
-rw-r--r--cpukit/posix/src/psignalclearsignals.c1
-rw-r--r--cpukit/posix/src/psignalsetprocesssignals.c1
-rw-r--r--cpukit/posix/src/psignalunblockthread.c1
-rw-r--r--cpukit/posix/src/pthreadgetschedparam.c1
-rw-r--r--cpukit/posix/src/pthreadsetschedparam.c1
-rw-r--r--cpukit/sapi/src/cpucounterconverter.c9
-rw-r--r--cpukit/sapi/src/sapirbtreeinsert.c1
-rw-r--r--cpukit/sapi/src/version.c10
-rw-r--r--cpukit/score/cpu/aarch64/aarch64-exception-frame-print.c2
-rw-r--r--cpukit/score/cpu/aarch64/include/libcpu/mmu-vmsav8-64.h4
-rw-r--r--cpukit/score/cpu/aarch64/include/rtems/score/cpuimpl.h7
-rw-r--r--cpukit/score/cpu/arm/__tls_get_addr.c2
-rw-r--r--cpukit/score/cpu/arm/arm-exception-frame-print.c145
-rw-r--r--cpukit/score/cpu/arm/armv4-isr-install-vector.c75
-rw-r--r--cpukit/score/cpu/arm/cpu.c28
-rw-r--r--cpukit/score/cpu/arm/include/libcpu/arm-cp15.h26
-rw-r--r--cpukit/score/cpu/arm/include/rtems/score/armv7m.h11
-rw-r--r--cpukit/score/cpu/arm/include/rtems/score/cpu.h2
-rw-r--r--cpukit/score/cpu/arm/include/rtems/score/cpuatomic.h33
-rw-r--r--cpukit/score/cpu/arm/include/rtems/score/cpuimpl.h7
-rw-r--r--cpukit/score/cpu/bfin/include/rtems/score/cpuatomic.h14
-rw-r--r--cpukit/score/cpu/bfin/include/rtems/score/cpuimpl.h12
-rw-r--r--cpukit/score/cpu/i386/cpu_asm.S2
-rw-r--r--cpukit/score/cpu/i386/include/rtems/score/cpu.h13
-rw-r--r--cpukit/score/cpu/i386/include/rtems/score/cpuatomic.h33
-rw-r--r--cpukit/score/cpu/i386/include/rtems/score/cpuimpl.h11
-rw-r--r--cpukit/score/cpu/lm32/include/rtems/score/cpuatomic.h14
-rw-r--r--cpukit/score/cpu/lm32/include/rtems/score/cpuimpl.h12
-rw-r--r--cpukit/score/cpu/m68k/include/rtems/score/cpuatomic.h33
-rw-r--r--cpukit/score/cpu/m68k/include/rtems/score/cpuimpl.h11
-rw-r--r--cpukit/score/cpu/microblaze/include/machine/elf_machdep.h83
-rw-r--r--cpukit/score/cpu/microblaze/include/rtems/score/cpuimpl.h7
-rw-r--r--cpukit/score/cpu/mips/include/rtems/score/cpuatomic.h33
-rw-r--r--cpukit/score/cpu/mips/include/rtems/score/cpuimpl.h12
-rw-r--r--cpukit/score/cpu/moxie/include/rtems/score/cpuatomic.h33
-rw-r--r--cpukit/score/cpu/moxie/include/rtems/score/cpuimpl.h12
-rw-r--r--cpukit/score/cpu/nios2/include/rtems/score/cpuatomic.h33
-rw-r--r--cpukit/score/cpu/nios2/include/rtems/score/cpuimpl.h7
-rw-r--r--cpukit/score/cpu/no_cpu/cpuidle.c16
-rw-r--r--cpukit/score/cpu/no_cpu/include/rtems/score/cpuimpl.h16
-rw-r--r--cpukit/score/cpu/or1k/include/rtems/score/cpuatomic.h33
-rw-r--r--cpukit/score/cpu/or1k/include/rtems/score/cpuimpl.h8
-rw-r--r--cpukit/score/cpu/powerpc/include/rtems/asm.h10
-rw-r--r--cpukit/score/cpu/powerpc/include/rtems/score/cpuatomic.h33
-rw-r--r--cpukit/score/cpu/powerpc/include/rtems/score/cpuimpl.h7
-rw-r--r--cpukit/score/cpu/riscv/include/rtems/score/cpuatomic.h31
-rw-r--r--cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h7
-rw-r--r--cpukit/score/cpu/sh/include/rtems/score/cpuatomic.h14
-rw-r--r--cpukit/score/cpu/sh/include/rtems/score/cpuimpl.h12
-rw-r--r--cpukit/score/cpu/sparc/cpu_asm.S35
-rw-r--r--cpukit/score/cpu/sparc/include/libcpu/grlib-tn-0018.h9
-rw-r--r--cpukit/score/cpu/sparc/include/rtems/score/cpu.h45
-rw-r--r--cpukit/score/cpu/sparc/include/rtems/score/cpuatomic.h33
-rw-r--r--cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h14
-rw-r--r--cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h105
-rw-r--r--cpukit/score/cpu/sparc/sparc-counter-asm.S151
-rw-r--r--cpukit/score/cpu/sparc/sparc-isr-handler.S6
-rw-r--r--cpukit/score/cpu/sparc/syscall.S2
-rw-r--r--cpukit/score/cpu/sparc/syscall.h8
-rw-r--r--cpukit/score/cpu/sparc64/include/rtems/score/cpuatomic.h33
-rw-r--r--cpukit/score/cpu/sparc64/include/rtems/score/cpuimpl.h12
-rw-r--r--cpukit/score/cpu/v850/include/rtems/score/cpuatomic.h33
-rw-r--r--cpukit/score/cpu/v850/include/rtems/score/cpuimpl.h12
-rw-r--r--cpukit/score/cpu/x86_64/include/rtems/score/cpuatomic.h14
-rw-r--r--cpukit/score/cpu/x86_64/include/rtems/score/cpuimpl.h22
-rw-r--r--cpukit/score/src/hash.c4
-rw-r--r--cpukit/score/src/iobase64.c111
-rw-r--r--cpukit/score/src/isr.c2
-rw-r--r--cpukit/score/src/objectextendinformation.c2
-rw-r--r--cpukit/score/src/objectinitializeinformation.c1
-rw-r--r--cpukit/score/src/processormaskcopy.c2
-rw-r--r--cpukit/score/src/threadchangepriority.c1
-rw-r--r--cpukit/score/src/threadq.c2
-rw-r--r--cpukit/score/src/threadqenqueue.c1
-rw-r--r--cpukit/score/src/threadqops.c3
-rw-r--r--cpukit/score/src/threadqtimeout.c1
-rw-r--r--cpukit/score/src/threadrestart.c3
-rw-r--r--cpukit/score/src/tlsallocsize.c43
-rw-r--r--cpukit/score/src/userextiterate.c4
280 files changed, 7012 insertions, 5433 deletions
diff --git a/cpukit/base64/base64-decode.c b/cpukit/base64/base64-decode.c
new file mode 100644
index 0000000000..5739266528
--- /dev/null
+++ b/cpukit/base64/base64-decode.c
@@ -0,0 +1,165 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSImplBase64
+ *
+ * @brief This source file contains the implementation of
+ * _Base64_Decode_initialize() and _Base64_Decode().
+ */
+
+/*
+ * Copyright (C) 2023 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rtems/base64.h>
+
+#define SPACE 253
+
+#define PAD 254
+
+#define INVALID 255
+
+const uint8_t _Base64_Decoding[128] = {
+ ['A'] = 0, ['B'] = 1, ['C'] = 2, ['D'] = 3,
+ ['E'] = 4, ['F'] = 5, ['G'] = 6, ['H'] = 7,
+ ['I'] = 8, ['J'] = 9, ['K'] = 10, ['L'] = 11,
+ ['M'] = 12, ['N'] = 13, ['O'] = 14, ['P'] = 15,
+ ['Q'] = 16, ['R'] = 17, ['S'] = 18, ['T'] = 19,
+ ['U'] = 20, ['V'] = 21, ['W'] = 22, ['X'] = 23,
+ ['Y'] = 24, ['Z'] = 25, ['a'] = 26, ['b'] = 27,
+ ['c'] = 28, ['d'] = 29, ['e'] = 30, ['f'] = 31,
+ ['g'] = 32, ['h'] = 33, ['i'] = 34, ['j'] = 35,
+ ['k'] = 36, ['l'] = 37, ['m'] = 38, ['n'] = 39,
+ ['o'] = 40, ['p'] = 41, ['q'] = 42, ['r'] = 43,
+ ['s'] = 44, ['t'] = 45, ['u'] = 46, ['v'] = 47,
+ ['w'] = 48, ['x'] = 49, ['y'] = 50, ['z'] = 51,
+ ['0'] = 52, ['1'] = 53, ['2'] = 54, ['3'] = 55,
+ ['4'] = 56, ['5'] = 57, ['6'] = 58, ['7'] = 59,
+ ['8'] = 60, ['9'] = 61, ['+'] = 62, ['-'] = 62,
+ ['/'] = 63, ['_'] = 63, ['='] = PAD, [' '] = SPACE,
+ ['\t'] = SPACE, ['\n'] = SPACE, ['\v'] = SPACE, ['\f'] = SPACE,
+ ['\r'] = SPACE, [0] = INVALID, [1] = INVALID, [2] = INVALID,
+ [3] = INVALID, [4] = INVALID, [5] = INVALID, [6] = INVALID,
+ [7] = INVALID, [8] = INVALID, [14] = INVALID, [15] = INVALID,
+ [16] = INVALID, [17] = INVALID, [18] = INVALID, [19] = INVALID,
+ [20] = INVALID, [21] = INVALID, [22] = INVALID, [23] = INVALID,
+ [24] = INVALID, [25] = INVALID, [26] = INVALID, [27] = INVALID,
+ [28] = INVALID, [29] = INVALID, [30] = INVALID, [31] = INVALID,
+ [33] = INVALID, [34] = INVALID, [35] = INVALID, [36] = INVALID,
+ [37] = INVALID, [38] = INVALID, [39] = INVALID, [40] = INVALID,
+ [41] = INVALID, [42] = INVALID, [44] = INVALID, [46] = INVALID,
+ [58] = INVALID, [59] = INVALID, [60] = INVALID, [62] = INVALID,
+ [63] = INVALID, [64] = INVALID, [91] = INVALID, [92] = INVALID,
+ [93] = INVALID, [94] = INVALID, [96] = INVALID, [123] = INVALID,
+ [124] = INVALID, [125] = INVALID, [126] = INVALID, [127] = INVALID};
+
+void _Base64_Decode_initialize(Base64_Decode_control* self,
+ uint8_t* target,
+ size_t target_size) {
+ self->state = BASE64_DECODE_STATE_0;
+ self->target = target;
+ self->target_end = target + target_size;
+}
+
+Base64_Decode_status _Base64_Decode(Base64_Decode_control* self, char ch) {
+ uint8_t decoded_ch;
+ uint8_t next_ch;
+ uint8_t* target;
+ const uint8_t* target_end;
+ Base64_Decode_state next_state;
+
+ if ((unsigned char)ch >= 128) {
+ return BASE64_DECODE_INVALID_INPUT;
+ }
+
+ decoded_ch = _Base64_Decoding[(unsigned char)ch];
+
+ if (decoded_ch == SPACE) {
+ return BASE64_DECODE_SUCCESS;
+ }
+
+ target = self->target;
+
+ if (decoded_ch == PAD) {
+ self->target_end = target;
+ return BASE64_DECODE_SUCCESS;
+ }
+
+ if (decoded_ch == INVALID) {
+ return BASE64_DECODE_INVALID_INPUT;
+ }
+
+ target_end = self->target_end;
+
+ if (target == target_end) {
+ return BASE64_DECODE_OVERFLOW;
+ }
+
+ switch (self->state) {
+ case BASE64_DECODE_STATE_0:
+ *target = decoded_ch << 2;
+ next_state = BASE64_DECODE_STATE_1;
+ break;
+
+ case BASE64_DECODE_STATE_1:
+ *target |= decoded_ch >> 4;
+ next_ch = (decoded_ch & 0x0fU) << 4;
+ ++target;
+
+ if (target != target_end) {
+ *target = next_ch;
+ } else if (next_ch != 0) {
+ return BASE64_DECODE_OVERFLOW;
+ }
+
+ next_state = BASE64_DECODE_STATE_2;
+ break;
+
+ case BASE64_DECODE_STATE_2:
+ *target |= decoded_ch >> 2;
+ next_ch = (decoded_ch & 0x03U) << 6;
+ ++target;
+
+ if (target != target_end) {
+ *target = next_ch;
+ } else if (next_ch != 0) {
+ return BASE64_DECODE_OVERFLOW;
+ }
+
+ next_state = BASE64_DECODE_STATE_3;
+ break;
+
+ default: /* BASE64_DECODE_STATE_3 */
+ *target |= decoded_ch;
+ ++target;
+ next_state = BASE64_DECODE_STATE_0;
+ break;
+ }
+
+ self->state = next_state;
+ self->target = target;
+ return BASE64_DECODE_SUCCESS;
+}
diff --git a/cpukit/base64/base64-encode.c b/cpukit/base64/base64-encode.c
new file mode 100644
index 0000000000..0110f3ff67
--- /dev/null
+++ b/cpukit/base64/base64-encode.c
@@ -0,0 +1,121 @@
+/* SPDX-License-Identifier: ISC */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSImplBase64
+ *
+ * @brief This source file contains the implementation of
+ * _Base64_Encode() and _Base64url_Encode().
+ */
+
+/*
+ * Copyright (C) 2020, 2024 embedded brains GmbH & Co. KG
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <rtems/base64.h>
+
+static void
+_Base64_Put(int c, void *arg, IO_Put_char put_char)
+{
+ (*put_char)(c, arg);
+}
+
+static int
+_Base64_Do_encode(IO_Put_char put_char, void *arg, const void *src,
+ size_t srclen, const char *wordbreak, int wordlen, const uint8_t *encoding)
+{
+ unsigned int loops = 0;
+ const unsigned char *in = src;
+ int out = 0;
+
+ if (wordlen < 4) {
+ wordlen = 4;
+ }
+
+ while (srclen > 2) {
+ _Base64_Put(encoding[(in[0]>>2)&0x3f], arg, put_char);
+ _Base64_Put(encoding[((in[0]<<4)&0x30)|
+ ((in[1]>>4)&0x0f)], arg, put_char);
+ _Base64_Put(encoding[((in[1]<<2)&0x3c)|
+ ((in[2]>>6)&0x03)], arg, put_char);
+ _Base64_Put(encoding[in[2]&0x3f], arg, put_char);
+ in += 3;
+ srclen -= 3;
+ out += 4;
+
+ loops++;
+ if (srclen != 0 &&
+ (int)((loops + 1) * 4) >= wordlen)
+ {
+ const char *w = wordbreak;
+ loops = 0;
+ while (*w != '\0') {
+ _Base64_Put(*w, arg, put_char);
+ ++w;
+ ++out;
+ }
+ }
+ }
+ if (srclen == 2) {
+ _Base64_Put(encoding[(in[0]>>2)&0x3f], arg, put_char);
+ _Base64_Put(encoding[((in[0]<<4)&0x30)|
+ ((in[1]>>4)&0x0f)], arg, put_char);
+ _Base64_Put(encoding[((in[1]<<2)&0x3c)], arg, put_char);
+ _Base64_Put('=', arg, put_char);
+ out += 4;
+ } else if (srclen == 1) {
+ _Base64_Put(encoding[(in[0]>>2)&0x3f], arg, put_char);
+ _Base64_Put(encoding[((in[0]<<4)&0x30)], arg, put_char);
+ _Base64_Put('=', arg, put_char);
+ _Base64_Put('=', arg, put_char);
+ out += 4;
+ }
+ return out;
+}
+
+const uint8_t _Base64_Encoding[64] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', '+', '/'
+};
+
+int
+_Base64_Encode(IO_Put_char put_char, void *arg, const void *src, size_t srclen,
+ const char *wordbreak, int wordlen)
+{
+ return _Base64_Do_encode(put_char, arg, src, srclen, wordbreak,
+ wordlen, _Base64_Encoding);
+}
+
+const uint8_t _Base64url_Encoding[64] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', '-', '_'
+};
+
+int
+_Base64url_Encode(IO_Put_char put_char, void *arg, const void *src,
+ size_t srclen, const char *wordbreak, int wordlen)
+{
+ return _Base64_Do_encode(put_char, arg, src, srclen, wordbreak,
+ wordlen, _Base64url_Encoding);
+}
diff --git a/cpukit/libmisc/xz/COPYING b/cpukit/compression/xz/COPYING
index fc4fbf798d..fc4fbf798d 100644
--- a/cpukit/libmisc/xz/COPYING
+++ b/cpukit/compression/xz/COPYING
diff --git a/cpukit/libmisc/xz/README b/cpukit/compression/xz/README
index 1d5b9d85b2..1d5b9d85b2 100644
--- a/cpukit/libmisc/xz/README
+++ b/cpukit/compression/xz/README
diff --git a/cpukit/libmisc/xz/xz_config.h b/cpukit/compression/xz/xz_config.h
index eb9dac1a4b..eb9dac1a4b 100644
--- a/cpukit/libmisc/xz/xz_config.h
+++ b/cpukit/compression/xz/xz_config.h
diff --git a/cpukit/libmisc/xz/xz_crc32.c b/cpukit/compression/xz/xz_crc32.c
index 34532d14fd..34532d14fd 100644
--- a/cpukit/libmisc/xz/xz_crc32.c
+++ b/cpukit/compression/xz/xz_crc32.c
diff --git a/cpukit/libmisc/xz/xz_crc64.c b/cpukit/compression/xz/xz_crc64.c
index ca1caee899..ca1caee899 100644
--- a/cpukit/libmisc/xz/xz_crc64.c
+++ b/cpukit/compression/xz/xz_crc64.c
diff --git a/cpukit/libmisc/xz/xz_dec_lzma2.c b/cpukit/compression/xz/xz_dec_lzma2.c
index 6de808c5b3..6de808c5b3 100644
--- a/cpukit/libmisc/xz/xz_dec_lzma2.c
+++ b/cpukit/compression/xz/xz_dec_lzma2.c
diff --git a/cpukit/libmisc/xz/xz_dec_stream.c b/cpukit/compression/xz/xz_dec_stream.c
index d6525506a1..d6525506a1 100644
--- a/cpukit/libmisc/xz/xz_dec_stream.c
+++ b/cpukit/compression/xz/xz_dec_stream.c
diff --git a/cpukit/libmisc/xz/xz_lzma2.h b/cpukit/compression/xz/xz_lzma2.h
index 071d67bee9..071d67bee9 100644
--- a/cpukit/libmisc/xz/xz_lzma2.h
+++ b/cpukit/compression/xz/xz_lzma2.h
diff --git a/cpukit/libmisc/xz/xz_private.h b/cpukit/compression/xz/xz_private.h
index 482b90f363..482b90f363 100644
--- a/cpukit/libmisc/xz/xz_private.h
+++ b/cpukit/compression/xz/xz_private.h
diff --git a/cpukit/libmisc/xz/xz_stream.h b/cpukit/compression/xz/xz_stream.h
index 66cb5a7055..66cb5a7055 100644
--- a/cpukit/libmisc/xz/xz_stream.h
+++ b/cpukit/compression/xz/xz_stream.h
diff --git a/cpukit/zlib/ChangeLog.zlib b/cpukit/compression/zlib/ChangeLog.zlib
index f310bb0fcd..f310bb0fcd 100644
--- a/cpukit/zlib/ChangeLog.zlib
+++ b/cpukit/compression/zlib/ChangeLog.zlib
diff --git a/cpukit/zlib/FAQ b/cpukit/compression/zlib/FAQ
index 99b7cf92e4..99b7cf92e4 100644
--- a/cpukit/zlib/FAQ
+++ b/cpukit/compression/zlib/FAQ
diff --git a/cpukit/zlib/README b/cpukit/compression/zlib/README
index ba34d1894a..ba34d1894a 100644
--- a/cpukit/zlib/README
+++ b/cpukit/compression/zlib/README
diff --git a/cpukit/zlib/adler32.c b/cpukit/compression/zlib/adler32.c
index d0be4380a3..d0be4380a3 100644
--- a/cpukit/zlib/adler32.c
+++ b/cpukit/compression/zlib/adler32.c
diff --git a/cpukit/zlib/compress.c b/cpukit/compression/zlib/compress.c
index 2ad5326c14..2ad5326c14 100644
--- a/cpukit/zlib/compress.c
+++ b/cpukit/compression/zlib/compress.c
diff --git a/cpukit/zlib/crc32.c b/cpukit/compression/zlib/crc32.c
index f8357b083f..f8357b083f 100644
--- a/cpukit/zlib/crc32.c
+++ b/cpukit/compression/zlib/crc32.c
diff --git a/cpukit/zlib/crc32.h b/cpukit/compression/zlib/crc32.h
index 137df68d61..137df68d61 100644
--- a/cpukit/zlib/crc32.h
+++ b/cpukit/compression/zlib/crc32.h
diff --git a/cpukit/zlib/deflate.c b/cpukit/compression/zlib/deflate.c
index 4a689db359..4a689db359 100644
--- a/cpukit/zlib/deflate.c
+++ b/cpukit/compression/zlib/deflate.c
diff --git a/cpukit/zlib/deflate.h b/cpukit/compression/zlib/deflate.h
index 1a06cd5f25..1a06cd5f25 100644
--- a/cpukit/zlib/deflate.h
+++ b/cpukit/compression/zlib/deflate.h
diff --git a/cpukit/zlib/doc/algorithm.txt b/cpukit/compression/zlib/doc/algorithm.txt
index c97f495020..c97f495020 100644
--- a/cpukit/zlib/doc/algorithm.txt
+++ b/cpukit/compression/zlib/doc/algorithm.txt
diff --git a/cpukit/zlib/doc/rfc1950.txt b/cpukit/compression/zlib/doc/rfc1950.txt
index ce6428a0f2..ce6428a0f2 100644
--- a/cpukit/zlib/doc/rfc1950.txt
+++ b/cpukit/compression/zlib/doc/rfc1950.txt
diff --git a/cpukit/zlib/doc/rfc1951.txt b/cpukit/compression/zlib/doc/rfc1951.txt
index 403c8c722f..403c8c722f 100644
--- a/cpukit/zlib/doc/rfc1951.txt
+++ b/cpukit/compression/zlib/doc/rfc1951.txt
diff --git a/cpukit/zlib/doc/rfc1952.txt b/cpukit/compression/zlib/doc/rfc1952.txt
index a8e51b4567..a8e51b4567 100644
--- a/cpukit/zlib/doc/rfc1952.txt
+++ b/cpukit/compression/zlib/doc/rfc1952.txt
diff --git a/cpukit/zlib/doc/txtvsbin.txt b/cpukit/compression/zlib/doc/txtvsbin.txt
index 2a901eaa68..2a901eaa68 100644
--- a/cpukit/zlib/doc/txtvsbin.txt
+++ b/cpukit/compression/zlib/doc/txtvsbin.txt
diff --git a/cpukit/zlib/gzclose.c b/cpukit/compression/zlib/gzclose.c
index caeb99a317..caeb99a317 100644
--- a/cpukit/zlib/gzclose.c
+++ b/cpukit/compression/zlib/gzclose.c
diff --git a/cpukit/zlib/gzguts.h b/cpukit/compression/zlib/gzguts.h
index 57faf37165..57faf37165 100644
--- a/cpukit/zlib/gzguts.h
+++ b/cpukit/compression/zlib/gzguts.h
diff --git a/cpukit/zlib/gzlib.c b/cpukit/compression/zlib/gzlib.c
index 55da46a453..55da46a453 100644
--- a/cpukit/zlib/gzlib.c
+++ b/cpukit/compression/zlib/gzlib.c
diff --git a/cpukit/zlib/gzread.c b/cpukit/compression/zlib/gzread.c
index dd77381596..dd77381596 100644
--- a/cpukit/zlib/gzread.c
+++ b/cpukit/compression/zlib/gzread.c
diff --git a/cpukit/zlib/gzwrite.c b/cpukit/compression/zlib/gzwrite.c
index eb8a0e5893..eb8a0e5893 100644
--- a/cpukit/zlib/gzwrite.c
+++ b/cpukit/compression/zlib/gzwrite.c
diff --git a/cpukit/zlib/infback.c b/cpukit/compression/zlib/infback.c
index babeaf1806..babeaf1806 100644
--- a/cpukit/zlib/infback.c
+++ b/cpukit/compression/zlib/infback.c
diff --git a/cpukit/zlib/inffast.c b/cpukit/compression/zlib/inffast.c
index 1fec7f363f..1fec7f363f 100644
--- a/cpukit/zlib/inffast.c
+++ b/cpukit/compression/zlib/inffast.c
diff --git a/cpukit/zlib/inffast.h b/cpukit/compression/zlib/inffast.h
index e5c1aa4ca8..e5c1aa4ca8 100644
--- a/cpukit/zlib/inffast.h
+++ b/cpukit/compression/zlib/inffast.h
diff --git a/cpukit/zlib/inffixed.h b/cpukit/compression/zlib/inffixed.h
index d628327769..d628327769 100644
--- a/cpukit/zlib/inffixed.h
+++ b/cpukit/compression/zlib/inffixed.h
diff --git a/cpukit/zlib/inflate.c b/cpukit/compression/zlib/inflate.c
index 8acbef44e9..8acbef44e9 100644
--- a/cpukit/zlib/inflate.c
+++ b/cpukit/compression/zlib/inflate.c
diff --git a/cpukit/zlib/inflate.h b/cpukit/compression/zlib/inflate.h
index f127b6b1fa..f127b6b1fa 100644
--- a/cpukit/zlib/inflate.h
+++ b/cpukit/compression/zlib/inflate.h
diff --git a/cpukit/zlib/inftrees.c b/cpukit/compression/zlib/inftrees.c
index 57d2793bec..57d2793bec 100644
--- a/cpukit/zlib/inftrees.c
+++ b/cpukit/compression/zlib/inftrees.c
diff --git a/cpukit/zlib/inftrees.h b/cpukit/compression/zlib/inftrees.h
index f53665311c..f53665311c 100644
--- a/cpukit/zlib/inftrees.h
+++ b/cpukit/compression/zlib/inftrees.h
diff --git a/cpukit/zlib/trees.c b/cpukit/compression/zlib/trees.c
index 5f305c4722..5f305c4722 100644
--- a/cpukit/zlib/trees.c
+++ b/cpukit/compression/zlib/trees.c
diff --git a/cpukit/zlib/trees.h b/cpukit/compression/zlib/trees.h
index d35639d82a..d35639d82a 100644
--- a/cpukit/zlib/trees.h
+++ b/cpukit/compression/zlib/trees.h
diff --git a/cpukit/zlib/uncompr.c b/cpukit/compression/zlib/uncompr.c
index f9532f46c1..f9532f46c1 100644
--- a/cpukit/zlib/uncompr.c
+++ b/cpukit/compression/zlib/uncompr.c
diff --git a/cpukit/zlib/zutil.c b/cpukit/compression/zlib/zutil.c
index 9543ae825e..9543ae825e 100644
--- a/cpukit/zlib/zutil.c
+++ b/cpukit/compression/zlib/zutil.c
diff --git a/cpukit/zlib/zutil.h b/cpukit/compression/zlib/zutil.h
index d3b95f0c27..d3b95f0c27 100644
--- a/cpukit/zlib/zutil.h
+++ b/cpukit/compression/zlib/zutil.h
diff --git a/cpukit/crc/crc24q.c b/cpukit/crc/crc24q.c
new file mode 100644
index 0000000000..c96ec88a47
--- /dev/null
+++ b/cpukit/crc/crc24q.c
@@ -0,0 +1,148 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSImplCRC
+ *
+ * @brief This source file contains the implementation of
+ * _CRC24Q_Update() and _CRC24Q_Sequence_update().
+ *
+ * The CRC-24Q cyclic redundancy checksum is used for example by Qualcomm,
+ * RTCM104v3, and LTE-A.
+ */
+
+/*
+ * Copyright (C) 2023 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rtems/crc.h>
+
+static const uint32_t _CRC24Q_Table[256] = {
+ UINT32_C(0x000000), UINT32_C(0x864CFB), UINT32_C(0x8AD50D),
+ UINT32_C(0x0C99F6), UINT32_C(0x93E6E1), UINT32_C(0x15AA1A),
+ UINT32_C(0x1933EC), UINT32_C(0x9F7F17), UINT32_C(0xA18139),
+ UINT32_C(0x27CDC2), UINT32_C(0x2B5434), UINT32_C(0xAD18CF),
+ UINT32_C(0x3267D8), UINT32_C(0xB42B23), UINT32_C(0xB8B2D5),
+ UINT32_C(0x3EFE2E), UINT32_C(0xC54E89), UINT32_C(0x430272),
+ UINT32_C(0x4F9B84), UINT32_C(0xC9D77F), UINT32_C(0x56A868),
+ UINT32_C(0xD0E493), UINT32_C(0xDC7D65), UINT32_C(0x5A319E),
+ UINT32_C(0x64CFB0), UINT32_C(0xE2834B), UINT32_C(0xEE1ABD),
+ UINT32_C(0x685646), UINT32_C(0xF72951), UINT32_C(0x7165AA),
+ UINT32_C(0x7DFC5C), UINT32_C(0xFBB0A7), UINT32_C(0x0CD1E9),
+ UINT32_C(0x8A9D12), UINT32_C(0x8604E4), UINT32_C(0x00481F),
+ UINT32_C(0x9F3708), UINT32_C(0x197BF3), UINT32_C(0x15E205),
+ UINT32_C(0x93AEFE), UINT32_C(0xAD50D0), UINT32_C(0x2B1C2B),
+ UINT32_C(0x2785DD), UINT32_C(0xA1C926), UINT32_C(0x3EB631),
+ UINT32_C(0xB8FACA), UINT32_C(0xB4633C), UINT32_C(0x322FC7),
+ UINT32_C(0xC99F60), UINT32_C(0x4FD39B), UINT32_C(0x434A6D),
+ UINT32_C(0xC50696), UINT32_C(0x5A7981), UINT32_C(0xDC357A),
+ UINT32_C(0xD0AC8C), UINT32_C(0x56E077), UINT32_C(0x681E59),
+ UINT32_C(0xEE52A2), UINT32_C(0xE2CB54), UINT32_C(0x6487AF),
+ UINT32_C(0xFBF8B8), UINT32_C(0x7DB443), UINT32_C(0x712DB5),
+ UINT32_C(0xF7614E), UINT32_C(0x19A3D2), UINT32_C(0x9FEF29),
+ UINT32_C(0x9376DF), UINT32_C(0x153A24), UINT32_C(0x8A4533),
+ UINT32_C(0x0C09C8), UINT32_C(0x00903E), UINT32_C(0x86DCC5),
+ UINT32_C(0xB822EB), UINT32_C(0x3E6E10), UINT32_C(0x32F7E6),
+ UINT32_C(0xB4BB1D), UINT32_C(0x2BC40A), UINT32_C(0xAD88F1),
+ UINT32_C(0xA11107), UINT32_C(0x275DFC), UINT32_C(0xDCED5B),
+ UINT32_C(0x5AA1A0), UINT32_C(0x563856), UINT32_C(0xD074AD),
+ UINT32_C(0x4F0BBA), UINT32_C(0xC94741), UINT32_C(0xC5DEB7),
+ UINT32_C(0x43924C), UINT32_C(0x7D6C62), UINT32_C(0xFB2099),
+ UINT32_C(0xF7B96F), UINT32_C(0x71F594), UINT32_C(0xEE8A83),
+ UINT32_C(0x68C678), UINT32_C(0x645F8E), UINT32_C(0xE21375),
+ UINT32_C(0x15723B), UINT32_C(0x933EC0), UINT32_C(0x9FA736),
+ UINT32_C(0x19EBCD), UINT32_C(0x8694DA), UINT32_C(0x00D821),
+ UINT32_C(0x0C41D7), UINT32_C(0x8A0D2C), UINT32_C(0xB4F302),
+ UINT32_C(0x32BFF9), UINT32_C(0x3E260F), UINT32_C(0xB86AF4),
+ UINT32_C(0x2715E3), UINT32_C(0xA15918), UINT32_C(0xADC0EE),
+ UINT32_C(0x2B8C15), UINT32_C(0xD03CB2), UINT32_C(0x567049),
+ UINT32_C(0x5AE9BF), UINT32_C(0xDCA544), UINT32_C(0x43DA53),
+ UINT32_C(0xC596A8), UINT32_C(0xC90F5E), UINT32_C(0x4F43A5),
+ UINT32_C(0x71BD8B), UINT32_C(0xF7F170), UINT32_C(0xFB6886),
+ UINT32_C(0x7D247D), UINT32_C(0xE25B6A), UINT32_C(0x641791),
+ UINT32_C(0x688E67), UINT32_C(0xEEC29C), UINT32_C(0x3347A4),
+ UINT32_C(0xB50B5F), UINT32_C(0xB992A9), UINT32_C(0x3FDE52),
+ UINT32_C(0xA0A145), UINT32_C(0x26EDBE), UINT32_C(0x2A7448),
+ UINT32_C(0xAC38B3), UINT32_C(0x92C69D), UINT32_C(0x148A66),
+ UINT32_C(0x181390), UINT32_C(0x9E5F6B), UINT32_C(0x01207C),
+ UINT32_C(0x876C87), UINT32_C(0x8BF571), UINT32_C(0x0DB98A),
+ UINT32_C(0xF6092D), UINT32_C(0x7045D6), UINT32_C(0x7CDC20),
+ UINT32_C(0xFA90DB), UINT32_C(0x65EFCC), UINT32_C(0xE3A337),
+ UINT32_C(0xEF3AC1), UINT32_C(0x69763A), UINT32_C(0x578814),
+ UINT32_C(0xD1C4EF), UINT32_C(0xDD5D19), UINT32_C(0x5B11E2),
+ UINT32_C(0xC46EF5), UINT32_C(0x42220E), UINT32_C(0x4EBBF8),
+ UINT32_C(0xC8F703), UINT32_C(0x3F964D), UINT32_C(0xB9DAB6),
+ UINT32_C(0xB54340), UINT32_C(0x330FBB), UINT32_C(0xAC70AC),
+ UINT32_C(0x2A3C57), UINT32_C(0x26A5A1), UINT32_C(0xA0E95A),
+ UINT32_C(0x9E1774), UINT32_C(0x185B8F), UINT32_C(0x14C279),
+ UINT32_C(0x928E82), UINT32_C(0x0DF195), UINT32_C(0x8BBD6E),
+ UINT32_C(0x872498), UINT32_C(0x016863), UINT32_C(0xFAD8C4),
+ UINT32_C(0x7C943F), UINT32_C(0x700DC9), UINT32_C(0xF64132),
+ UINT32_C(0x693E25), UINT32_C(0xEF72DE), UINT32_C(0xE3EB28),
+ UINT32_C(0x65A7D3), UINT32_C(0x5B59FD), UINT32_C(0xDD1506),
+ UINT32_C(0xD18CF0), UINT32_C(0x57C00B), UINT32_C(0xC8BF1C),
+ UINT32_C(0x4EF3E7), UINT32_C(0x426A11), UINT32_C(0xC426EA),
+ UINT32_C(0x2AE476), UINT32_C(0xACA88D), UINT32_C(0xA0317B),
+ UINT32_C(0x267D80), UINT32_C(0xB90297), UINT32_C(0x3F4E6C),
+ UINT32_C(0x33D79A), UINT32_C(0xB59B61), UINT32_C(0x8B654F),
+ UINT32_C(0x0D29B4), UINT32_C(0x01B042), UINT32_C(0x87FCB9),
+ UINT32_C(0x1883AE), UINT32_C(0x9ECF55), UINT32_C(0x9256A3),
+ UINT32_C(0x141A58), UINT32_C(0xEFAAFF), UINT32_C(0x69E604),
+ UINT32_C(0x657FF2), UINT32_C(0xE33309), UINT32_C(0x7C4C1E),
+ UINT32_C(0xFA00E5), UINT32_C(0xF69913), UINT32_C(0x70D5E8),
+ UINT32_C(0x4E2BC6), UINT32_C(0xC8673D), UINT32_C(0xC4FECB),
+ UINT32_C(0x42B230), UINT32_C(0xDDCD27), UINT32_C(0x5B81DC),
+ UINT32_C(0x57182A), UINT32_C(0xD154D1), UINT32_C(0x26359F),
+ UINT32_C(0xA07964), UINT32_C(0xACE092), UINT32_C(0x2AAC69),
+ UINT32_C(0xB5D37E), UINT32_C(0x339F85), UINT32_C(0x3F0673),
+ UINT32_C(0xB94A88), UINT32_C(0x87B4A6), UINT32_C(0x01F85D),
+ UINT32_C(0x0D61AB), UINT32_C(0x8B2D50), UINT32_C(0x145247),
+ UINT32_C(0x921EBC), UINT32_C(0x9E874A), UINT32_C(0x18CBB1),
+ UINT32_C(0xE37B16), UINT32_C(0x6537ED), UINT32_C(0x69AE1B),
+ UINT32_C(0xEFE2E0), UINT32_C(0x709DF7), UINT32_C(0xF6D10C),
+ UINT32_C(0xFA48FA), UINT32_C(0x7C0401), UINT32_C(0x42FA2F),
+ UINT32_C(0xC4B6D4), UINT32_C(0xC82F22), UINT32_C(0x4E63D9),
+ UINT32_C(0xD11CCE), UINT32_C(0x575035), UINT32_C(0x5BC9C3),
+ UINT32_C(0xDD8538)};
+
+static inline uint32_t _CRC24Q_do_update(uint32_t crc, uint8_t byte) {
+ return (crc << 8) ^ _CRC24Q_Table[byte ^ (uint8_t)(crc >> 16)];
+}
+
+uint32_t _CRC24Q_Update(uint32_t crc, uint8_t byte) {
+ return _CRC24Q_do_update(crc, byte);
+}
+
+uint32_t _CRC24Q_Sequence_update(uint32_t crc,
+ const void* bytes,
+ size_t size_in_bytes) {
+ const uint8_t* the_bytes = bytes;
+
+ for (size_t i = 0; i < size_in_bytes; ++i) {
+ crc = _CRC24Q_do_update(crc, the_bytes[i]);
+ }
+
+ return crc;
+}
diff --git a/cpukit/dev/can/can.c b/cpukit/dev/can/can.c
deleted file mode 100644
index 9f3fe0db98..0000000000
--- a/cpukit/dev/can/can.c
+++ /dev/null
@@ -1,507 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/**
- * @file
- *
- * @ingroup CANBus
- *
- * @brief Controller Area Network (CAN) Bus Implementation
- *
- */
-
-/*
- * Copyright (C) 2022 Prashanth S (fishesprashanth@gmail.com)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <inttypes.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <fcntl.h>
-
-#include <rtems/imfs.h>
-#include <rtems/thread.h>
-
-#include <dev/can/canqueueimpl.h>
-#include <dev/can/can.h>
-
-#define can_interrupt_lock_acquire(bus) \
- do { \
- CAN_DEBUG_LOCK("acquiring lock\n"); \
- real_can_interrupt_lock_acquire(bus); \
- } while (0);
-
-#define can_interrupt_lock_release(bus) \
- do { \
- CAN_DEBUG_LOCK("releasing lock\n"); \
- real_can_interrupt_lock_release(bus); \
- } while (0);
-
-static int
-can_bus_open(rtems_libio_t *iop, const char *path, int oflag, mode_t mode);
-static ssize_t
-can_bus_read(rtems_libio_t *iop, void *buffer, size_t count);
-static ssize_t
-can_bus_write(rtems_libio_t *iop, const void *buffer, size_t count);
-static int
-can_bus_ioctl(rtems_libio_t *iop, ioctl_command_t request, void *buffer);
-
-static int can_xmit(struct can_bus *bus);
-
-static int can_bus_create_sem(struct can_bus *);
-static int try_sem(struct can_bus *);
-static int take_sem(struct can_bus *);
-static int give_sem(struct can_bus *);
-
-
-static void can_bus_obtain(can_bus *bus)
-{
- CAN_DEBUG("can_bus_obtain Entry\n");
- rtems_mutex_lock(&bus->mutex);
- CAN_DEBUG("can_bus_obtain Exit\n");
-}
-
-static void can_bus_release(can_bus *bus)
-{
- CAN_DEBUG("can_bus_release Entry\n");
- rtems_mutex_unlock(&bus->mutex);
- CAN_DEBUG("can_bus_release Exit\n");
-}
-
-static void can_bus_destroy_mutex(struct can_bus *bus)
-{
- rtems_mutex_destroy(&bus->mutex);
-}
-
-static int can_bus_create_sem(struct can_bus *bus)
-{
- int ret = 0;
-
- ret = rtems_semaphore_create(rtems_build_name('c', 'a', 'n', bus->index),
- CAN_TX_BUF_COUNT, RTEMS_FIFO | RTEMS_COUNTING_SEMAPHORE | RTEMS_LOCAL,
- 0, &bus->tx_fifo_sem_id);
-
- if (ret != 0) {
- CAN_ERR("can_create_sem: rtems_semaphore_create failed %d\n", ret);
- }
-
- return ret;
-}
-
-static void can_bus_free_tx_semaphore(struct can_bus *bus)
-{
- rtems_semaphore_delete(bus->tx_fifo_sem_id);
-}
-
-static void real_can_interrupt_lock_acquire(struct can_bus *bus)
-{
- bus->can_dev_ops->dev_int(bus->priv, false);
- can_bus_obtain(bus);
-}
-
-static void real_can_interrupt_lock_release(struct can_bus *bus)
-{
- can_bus_release(bus);
- bus->can_dev_ops->dev_int(bus->priv, true);
-}
-
-static int take_sem(struct can_bus *bus)
-{
- int ret = rtems_semaphore_obtain(bus->tx_fifo_sem_id, RTEMS_WAIT,
- RTEMS_NO_TIMEOUT);
-#ifdef CAN_DEBUG_LOCK
- if (ret == RTEMS_SUCCESSFUL) {
- bus->sem_count++;
- CAN_DEBUG_LOCK("take_sem: Semaphore count = %d\n", bus->sem_count);
- if (bus->sem_count > CAN_TX_BUF_COUNT) {
- CAN_ERR("take_sem error: sem_count is misleading\n");
- return RTEMS_INTERNAL_ERROR;
- }
- }
-#endif /* CAN_DEBUG_LOCK */
-
- return ret;
-}
-
-static int give_sem(struct can_bus *bus)
-{
- int ret = rtems_semaphore_release(bus->tx_fifo_sem_id);
-
-#ifdef CAN_DEBUG_LOCK
- if (ret == RTEMS_SUCCESSFUL) {
- bus->sem_count--;
- CAN_DEBUG_LOCK("give_sem: Semaphore count = %d\n", bus->sem_count);
- if (bus->sem_count < 0) {
- CAN_ERR("give_sem error: sem_count is misleading\n");
- return RTEMS_INTERNAL_ERROR;
- }
- }
-#endif /* CAN_DEBUG_LOCK */
-
- return ret;
-}
-
-static int try_sem(struct can_bus *bus)
-{
- int ret = rtems_semaphore_obtain(bus->tx_fifo_sem_id, RTEMS_NO_WAIT,
- RTEMS_NO_TIMEOUT);
-#ifdef CAN_DEBUG_LOCK
- if (ret == RTEMS_SUCCESSFUL) {
- bus->sem_count++;
- CAN_DEBUG_LOCK("try_sem: Semaphore count = %d\n", bus->sem_count);
- if (bus->sem_count > CAN_TX_BUF_COUNT) {
- CAN_ERR("take_sem error: sem_count is misleading\n");
- return RTEMS_INTERNAL_ERROR;
- }
- }
-#endif /* CAN_DEBUG_LOCK */
-
- return ret;
-}
-
-static int
-can_bus_open(rtems_libio_t *iop, const char *path, int oflag, mode_t mode)
-{
- CAN_DEBUG("can_bus_open\n");
-
- return 0;
-}
-
-/* Should be called only with CAN interrupts disabled */
-int can_receive(struct can_bus *bus, struct can_msg *msg)
-{
- memcpy(&bus->can_rx_msg, msg, CAN_MSG_LEN(msg));
-
- return CAN_MSG_LEN(msg);
-}
-
-/* FIXME: Should be modified to read count number of bytes, Now sending one can_msg */
-static ssize_t can_bus_read(rtems_libio_t *iop, void *buffer, size_t count)
-{
- int len;
-
- can_bus *bus = IMFS_generic_get_context_by_iop(iop);
- if (bus == NULL) {
- return -RTEMS_NOT_DEFINED;
- }
-
- struct can_msg *msg = (struct can_msg *)buffer;
-
- len = CAN_MSG_LEN(&bus->can_rx_msg);
-
- if (count < len) {
- CAN_DEBUG("can_bus_read: buffer size is small min "
- "sizeof(struct can_msg) = %" PRIuPTR "\n",
- sizeof(struct can_msg));
- return -RTEMS_INVALID_SIZE;
- }
-
- can_interrupt_lock_acquire(bus);
- memcpy(msg, &bus->can_rx_msg, len);
- can_interrupt_lock_release(bus);
-
- return len;
-}
-
-/* This function is a critical section and should be called
- * with CAN interrupts disabled and mutually exclusive
- */
-static int can_xmit(struct can_bus *bus)
-{
- int ret = RTEMS_SUCCESSFUL;
-
- struct can_msg *msg = NULL;
-
- CAN_DEBUG(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> can_xmit Entry\n");
-
- while (1) {
- CAN_DEBUG("can_dev_ops->dev_tx_ready\n");
- if (bus->can_dev_ops->dev_tx_ready(bus->priv) != true) {
- break;
- }
-
- CAN_DEBUG("can_tx_get_data_buf\n");
- msg = can_bus_tx_get_data_buf(bus);
- if (msg == NULL) {
- break;
- }
-
- CAN_DEBUG("can_dev_ops->dev_tx\n");
- ret = bus->can_dev_ops->dev_tx(bus->priv, msg);
- if (ret != RTEMS_SUCCESSFUL) {
- CAN_ERR("can_xmit: dev_send failed\n");
- break;
- }
-
- ret = give_sem(bus);
- if (ret != RTEMS_SUCCESSFUL) {
- CAN_ERR("can_xmit: rtems_semaphore_release failed = %d\n", ret);
- break;
- }
- }
-
- CAN_DEBUG(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> can_xmit Exit\n");
-
- return ret;
-}
-
-void can_print_msg(struct can_msg const *msg)
-{
-#ifdef CAN_DEBUG
- CAN_DEBUG("\n----------------------------------------------------------------\n");
- CAN_DEBUG("id = %d len = %d flags = 0x%08X\n", msg->id, msg->len, msg->flags);
-
- CAN_DEBUG("msg->data[0] = 0x%08x\n", ((uint32_t *)msg->data)[0]);
- CAN_DEBUG("msg->data[1] = 0x%08x\n", ((uint32_t *)msg->data)[1]);
-
- for (int i = 0; i < msg->len; i++) {
- CAN_DEBUG("%02x\n", ((char *)msg->data)[i]);
- }
-
- CAN_DEBUG("\n-----------------------------------------------------------------\n");
-#endif /* CAN_DEBUG */
-}
-
-/* can_tx_done should be called only with CAN interrupts disabled */
-int can_tx_done(struct can_bus *bus)
-{
- CAN_DEBUG("------------ can_tx_done Entry\n");
- int ret = RTEMS_SUCCESSFUL;
-
- if (bus->can_dev_ops->dev_tx_ready(bus->priv) == true) {
- ret = can_xmit(bus);
- }
- CAN_DEBUG("------------ can_tx_done Exit\n");
-
- return ret;
-}
-
-/* FIXME: Add support to send multiple CAN msgs for can_bus_write */
-static ssize_t
-can_bus_write(rtems_libio_t *iop, const void *buffer, size_t count)
-{
- can_bus *bus = IMFS_generic_get_context_by_iop(iop);
-
- if (bus == NULL || bus->can_dev_ops->dev_tx == NULL) {
- return -RTEMS_NOT_DEFINED;
- }
-
- int ret = RTEMS_SUCCESSFUL;
-
- struct can_msg const *msg = buffer;
- struct can_msg *fifo_buf = NULL;
-
- uint32_t msg_size = CAN_MSG_LEN(msg);
-
- CAN_DEBUG_TX("can_bus_write: can_msg_size = %u\n", msg_size);
- if (msg_size > sizeof(struct can_msg)) {
- CAN_ERR("can_bus_write: can message "
- "len error msg_size = %u struct can_msg = %" PRIxPTR "\n",
- msg_size, sizeof(struct can_msg));
- return -RTEMS_INVALID_SIZE;
- }
-
- if ((iop->flags & O_NONBLOCK) != 0) {
- ret = try_sem(bus);
- if (ret != RTEMS_SUCCESSFUL) {
- return -ret;
- }
- } else {
- ret = take_sem(bus);
- if (ret != RTEMS_SUCCESSFUL) {
- CAN_ERR("can_bus_write: cannot take semaphore\n");
- return -ret;
- }
- }
-
- can_interrupt_lock_acquire(bus);
-
- fifo_buf = can_bus_tx_get_empty_buf(bus);
- if (fifo_buf == NULL) {
- /* This error will not happen until buffer counts are not synchronized */
- CAN_ERR("can_bus_write: Buffer counts are not synchronized with semaphore count\n");
- ret = -RTEMS_INTERNAL_ERROR;
- goto release_lock_and_return;
- }
-
- CAN_DEBUG_TX("can_bus_write: empty_count = %u\n", bus->tx_fifo.empty_count);
-
- CAN_DEBUG_TX("can_bus_write: copying msg from application to driver buffer\n");
- memcpy(fifo_buf, msg, msg_size);
-
- if (bus->can_dev_ops->dev_tx_ready(bus->priv) == true) {
- ret = can_xmit(bus);
- if (ret != RTEMS_SUCCESSFUL) {
- ret = -ret;
- goto release_lock_and_return;
- }
- }
-
- ret = msg_size;
-
-release_lock_and_return:
- can_interrupt_lock_release(bus);
- return ret;
-}
-
-static int
-can_bus_ioctl(rtems_libio_t *iop, ioctl_command_t request, void *buffer)
-{
- can_bus *bus = IMFS_generic_get_context_by_iop(iop);
-
- if (bus == NULL || bus->can_dev_ops->dev_ioctl == NULL) {
- return -RTEMS_NOT_DEFINED;
- }
-
- can_bus_obtain(bus);
-
- bus->can_dev_ops->dev_ioctl(bus->priv, NULL, 0);
-
- can_bus_release(bus);
-
- return RTEMS_SUCCESSFUL;
-}
-
-static const rtems_filesystem_file_handlers_r can_bus_handler = {
- .open_h = can_bus_open,
- .close_h = rtems_filesystem_default_close,
- .read_h = can_bus_read,
- .write_h = can_bus_write,
- .ioctl_h = can_bus_ioctl,
- .lseek_h = rtems_filesystem_default_lseek,
- .fstat_h = IMFS_stat,
- .ftruncate_h = rtems_filesystem_default_ftruncate,
- .fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
- .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
- .fcntl_h = rtems_filesystem_default_fcntl,
- .kqfilter_h = rtems_filesystem_default_kqfilter,
- .mmap_h = rtems_filesystem_default_mmap,
- .poll_h = rtems_filesystem_default_poll,
- .readv_h = rtems_filesystem_default_readv,
- .writev_h = rtems_filesystem_default_writev
-};
-
-static void can_bus_node_destroy(IMFS_jnode_t *node)
-{
- can_bus *bus;
-
- bus = IMFS_generic_get_context_by_node(node);
- (*bus->destroy)(bus);
-
- IMFS_node_destroy_default(node);
-}
-
-static const
-IMFS_node_control can_bus_node_control = IMFS_GENERIC_INITIALIZER(&can_bus_handler,
- IMFS_node_initialize_generic, can_bus_node_destroy);
-
-rtems_status_code can_bus_register(can_bus *bus, const char *bus_path)
-{
- int ret = RTEMS_SUCCESSFUL;
-
- static uint8_t index = 0;
-
- if (index == CAN_BUS_REG_MAX) {
- CAN_ERR("can_bus_register: can bus registration limit reached\n");
- return RTEMS_TOO_MANY;
- }
-
- bus->index = index++;
- CAN_DEBUG("Registering CAN bus index = %u\n", bus->index);
-
- ret = IMFS_make_generic_node(bus_path, S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
- &can_bus_node_control, bus);
- if (ret != RTEMS_SUCCESSFUL) {
- CAN_ERR("can_bus_register: Creating node failed = %d\n", ret);
- goto fail;
- }
-
- if ((ret = can_bus_create_sem(bus)) != RTEMS_SUCCESSFUL) {
- CAN_ERR("can_bus_register: can_create_sem failed = %d\n", ret);
- goto fail;
- }
-
- if ((ret = can_bus_create_tx_buffers(bus)) != RTEMS_SUCCESSFUL) {
- CAN_ERR("can_bus_register: can_create_tx_buffers failed = %d\n", ret);
- goto free_tx_semaphore;
- }
-
- return ret;
-
-free_tx_semaphore:
- rtems_semaphore_delete(bus->tx_fifo_sem_id);
-
-fail:
- can_bus_destroy_mutex(bus);
- return ret;
-
-}
-
-static void can_bus_destroy(can_bus *bus)
-{
- can_bus_free_tx_buffers(bus);
- can_bus_free_tx_semaphore(bus);
- can_bus_destroy_mutex(bus);
-}
-
-static int can_bus_do_init(can_bus *bus, void (*destroy)(can_bus *bus))
-{
- rtems_mutex_init(&bus->mutex, "CAN Bus");
- bus->destroy = can_bus_destroy;
-
- return RTEMS_SUCCESSFUL;
-}
-
-static void can_bus_destroy_and_free(can_bus *bus)
-{
- can_bus_destroy(bus);
- free(bus);
-}
-
-int can_bus_init(can_bus *bus)
-{
- memset(bus, 0, sizeof(*bus));
-
- return can_bus_do_init(bus, can_bus_destroy);
-}
-
-can_bus *can_bus_alloc_and_init(size_t size)
-{
- can_bus *bus = NULL;
-
- if (size >= sizeof(*bus)) {
- bus = calloc(1, size);
- if (bus == NULL) {
- CAN_ERR("can_bus_alloc_and_init: calloc failed\b");
- return NULL;
- }
-
- int rv = can_bus_do_init(bus, can_bus_destroy_and_free);
- if (rv != 0) {
- CAN_ERR("can_bus_alloc_and_init: can_bus_do_init failed\n");
- return NULL;
- }
- }
- return bus;
-}
diff --git a/cpukit/dev/flash/flashdev.c b/cpukit/dev/flash/flashdev.c
index 4b7a0560ff..f39f8dde4d 100644
--- a/cpukit/dev/flash/flashdev.c
+++ b/cpukit/dev/flash/flashdev.c
@@ -135,6 +135,13 @@ static int rtems_flashdev_get_addr(
off_t *addr
);
+static int rtems_flashdev_get_abs_addr(
+ rtems_flashdev *flash,
+ rtems_libio_t *iop,
+ size_t count,
+ off_t *addr
+);
+
static int rtems_flashdev_update_and_return(
rtems_libio_t *iop,
int status,
@@ -313,7 +320,7 @@ static int rtems_flashdev_read_write(
int status;
if ( read_buff == NULL && write_buff == NULL ) {
- return 0;
+ rtems_set_errno_and_return_minus_one( EINVAL );
}
/* Get flash address */
@@ -383,6 +390,8 @@ static int rtems_flashdev_ioctl(
case RTEMS_FLASHDEV_IOCTL_WRITE_BLOCK_SIZE:
err = rtems_flashdev_ioctl_write_block_size( flash, arg );
break;
+ default:
+ err = EINVAL;
}
rtems_flashdev_release( flash );
@@ -565,6 +574,28 @@ static int rtems_flashdev_get_addr(
return 0;
}
+static int rtems_flashdev_get_abs_addr(
+ rtems_flashdev *flash,
+ rtems_libio_t *iop,
+ size_t count,
+ off_t *addr
+)
+{
+ off_t new_offset;
+
+ /* Check address is in valid region */
+ new_offset = *addr + count;
+
+ if (rtems_flashdev_check_offset_region(flash, iop, new_offset)) {
+ return -1;
+ }
+
+ /* Get address for operation */
+ if ( rtems_flashdev_is_region_defined( iop ) ) {
+ *addr = ( *addr + rtems_flashdev_get_region_offset( flash, iop ) );
+ }
+ return 0;
+}
static int rtems_flashdev_update_and_return(
rtems_libio_t *iop,
int status,
@@ -588,7 +619,7 @@ static int rtems_flashdev_ioctl_erase(
)
{
rtems_flashdev_region *erase_args_1;
- off_t check_offset;
+ off_t new_offset;
int status;
if ( flash->erase == NULL ) {
@@ -597,16 +628,14 @@ static int rtems_flashdev_ioctl_erase(
erase_args_1 = (rtems_flashdev_region *) arg;
/* Check erasing valid region */
- check_offset = erase_args_1->offset + erase_args_1->size;
- if ( rtems_flashdev_is_region_defined( iop ) && (
- rtems_flashdev_check_offset_region(flash, iop, check_offset) ||
- ( erase_args_1->offset <
- rtems_flashdev_get_region_offset( flash, iop ) ) ) ) {
- rtems_set_errno_and_return_minus_one( EINVAL );
+ new_offset = erase_args_1->offset;
+ status = rtems_flashdev_get_abs_addr(flash, iop, erase_args_1->size, &new_offset);
+ if ( status < 0 ) {
+ return status;
}
/* Erase flash */
- status = ( *flash->erase )( flash, erase_args_1->offset, erase_args_1->size );
+ status = ( *flash->erase )( flash, new_offset, erase_args_1->size );
return status;
}
diff --git a/cpukit/score/src/ioprintf.c b/cpukit/dev/ioprintf.c
index 8ae4213ab1..1f16389b47 100644
--- a/cpukit/score/src/ioprintf.c
+++ b/cpukit/dev/ioprintf.c
@@ -3,7 +3,7 @@
/**
* @file
*
- * @ingroup RTEMSScoreIO
+ * @ingroup RTEMSDeviceIO
*
* @brief This source file contains the implementation of
* _IO_Printf().
@@ -38,7 +38,7 @@
#include "config.h"
#endif
-#include <rtems/score/io.h>
+#include <rtems/dev/io.h>
int _IO_Printf( IO_Put_char put_char, void *arg, char const *fmt, ... )
{
diff --git a/cpukit/score/src/iorelax.c b/cpukit/dev/iorelax.c
index 1b155377a9..5fdefac151 100644
--- a/cpukit/score/src/iorelax.c
+++ b/cpukit/dev/iorelax.c
@@ -3,7 +3,7 @@
/**
* @file
*
- * @ingroup RTEMSScoreIO
+ * @ingroup RTEMSDeviceIO
*
* @brief This source file contains the implementation of _IO_Relax().
*/
@@ -37,7 +37,7 @@
#include "config.h"
#endif
-#include <rtems/score/io.h>
+#include <rtems/dev/io.h>
#include <rtems/score/cpuimpl.h>
void _IO_Relax( void )
diff --git a/cpukit/score/src/iovprintf.c b/cpukit/dev/iovprintf.c
index 0e8eb0b47b..99b11b691d 100644
--- a/cpukit/score/src/iovprintf.c
+++ b/cpukit/dev/iovprintf.c
@@ -1,7 +1,7 @@
/**
* @file
*
- * @ingroup RTEMSScoreIO
+ * @ingroup RTEMSDeviceIO
*
* @brief This source file contains the implementation of
* _IO_Vprintf().
@@ -45,7 +45,7 @@
* @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
*/
-#include <rtems/score/io.h>
+#include <rtems/dev/io.h>
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: head/sys/kern/subr_prf.c 336417 2018-07-17 14:56:54Z markj $");
diff --git a/cpukit/doxygen.h b/cpukit/doxygen.h
index 661955a501..a1ba3ece4a 100644
--- a/cpukit/doxygen.h
+++ b/cpukit/doxygen.h
@@ -43,7 +43,30 @@
*
* @ingroup RTEMSDeviceDrivers
*
- * @brief Time Test 27 Support
+ * @brief The Time Test 27 (TM27) support is used to measure the timing of
+ * the interrupt processing.
+ *
+ * The TMS27 support should provide two software generated interrupt requests,
+ * one low priority request raised by Cause_tm27_intr() and one higher priority
+ * request raised by Lower_tm27_intr(). Both requests should be cleared by
+ * Clear_tm27_intr(). A handler provided by the test should be installed
+ * through Install_tm27_vector(). This function should initialize the system
+ * so that the software generated interrupt requests can be raised and cleared.
+ *
+ * If the raise functions Cause_tm27_intr() and Lower_tm27_intr() do not
+ * trigger the interrupt immediately, then the TM27 support shall define
+ * MUST_WAIT_FOR_INTERRUPT to one, otherwise MUST_WAIT_FOR_INTERRUPT shall be
+ * defined to zero.
+ *
+ * The TM27 support may define TM27_INTERRUPT_VECTOR_DEFAULT to indicate the
+ * interrupt vector of the interrupt request raised by Cause_tm27_intr().
+ *
+ * The TM27 support may define TM27_INTERRUPT_VECTOR_ALTERNATIVE to provide an
+ * alternative software generated interrupt request which is raised by
+ * _TM27_Raise_alternative() and cleared by _TM27_Clear_alternative(). Both
+ * functions shall return an RTEMS status code. This interrupt vector may be
+ * used to test the interrupt controller support on targets which do not
+ * provide generic software generated interrupts.
*/
/**
diff --git a/cpukit/doxygen/appl-config.h b/cpukit/doxygen/appl-config.h
index 558a40cb0b..de93acbaa7 100644
--- a/cpukit/doxygen/appl-config.h
+++ b/cpukit/doxygen/appl-config.h
@@ -11,7 +11,7 @@
/*
* Copyright (C) 2019, 2023 embedded brains GmbH & Co. KG
* Copyright (C) 2010 Gedare Bloom
- * Copyright (C) 1988, 2022 On-Line Applications Research Corporation (OAR)
+ * Copyright (C) 1988, 2023 On-Line Applications Research Corporation (OAR)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -1116,7 +1116,7 @@
*
* @par Notes
* @parblock
- * The application shall define exactly one of the following configuration
+ * The application shall define at least one of the following configuration
* options
*
* * ``CONFIGURE_RTEMS_INIT_TASKS_TABLE``,
@@ -1126,6 +1126,10 @@
* * @ref CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
*
* otherwise a compile time error in the configuration file will occur.
+ *
+ * The Classic API initialization task performs the <a
+ * href="https://docs.rtems.org/branches/master/c-user/initialization/operations.html">Global
+ * Construction</a>.
* @endparblock
*/
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
@@ -2471,6 +2475,34 @@
*/
#define CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK
+/* Generated from spec:/acfg/if/jffs2-delayed-write-task-priority */
+
+/**
+ * @brief This configuration option is an integer define.
+ *
+ * @anchor CONFIGURE_JFFS2_DELAYED_WRITE_TASK_PRIORITY
+ *
+ * The value of this configuration option defines the JFFS2 delayed write task
+ * priority.
+ *
+ * @par Default Value
+ * The default value is 15.
+ *
+ * @par Constraints
+ * @parblock
+ * The following constraints apply to this configuration option:
+ *
+ * * The configuration option is not included in the pre-qualified feature set
+ * of RTEMS. Applications which are restricted to only use interfaces of the
+ * pre-qualified feature set of RTEMS shall not use the configuration option.
+ *
+ * * The value of the configuration option shall be a valid Classic API task
+ * priority. The set of valid task priorities depends on the scheduler
+ * configuration.
+ * @endparblock
+ */
+#define CONFIGURE_JFFS2_DELAYED_WRITE_TASK_PRIORITY
+
/* Generated from spec:/acfg/if/use-devfs-as-base-filesystem */
/**
@@ -3281,7 +3313,7 @@
* The following constraints apply to this configuration option:
*
* * The value of the configuration option shall be greater than or equal to
- * zero.
+ * one.
*
* * The value of the configuration option shall be less than or equal to <a
* href="https://en.cppreference.com/w/c/types/integer">UINT32_MAX</a>.
@@ -3504,7 +3536,7 @@
* user IDLE task with the @ref CONFIGURE_IDLE_TASK_BODY configuration option,
* otherwise a compile time error in the configuration file will occur.
*
- * The application shall define exactly one of the following configuration
+ * The application shall define at least one of the following configuration
* options
*
* * @ref CONFIGURE_RTEMS_INIT_TASKS_TABLE,
@@ -3514,6 +3546,11 @@
* * ``CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION``
*
* otherwise a compile time error in the configuration file will occur.
+ *
+ * If no Classic API initialization task and no POSIX API initialization thread
+ * is configured, then no <a
+ * href="https://docs.rtems.org/branches/master/c-user/initialization/operations.html">Global
+ * Construction</a> is performed.
* @endparblock
*/
#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
@@ -4364,7 +4401,7 @@
*
* @par Notes
* @parblock
- * The application shall define exactly one of the following configuration
+ * The application shall define at least one of the following configuration
* options
*
* * @ref CONFIGURE_RTEMS_INIT_TASKS_TABLE,
@@ -4374,6 +4411,11 @@
* * @ref CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
*
* otherwise a compile time error in the configuration file will occur.
+ *
+ * If no Classic API initialization task is configured, then the POSIX API
+ * initialization thread performs the <a
+ * href="https://docs.rtems.org/branches/master/c-user/initialization/operations.html">Global
+ * Construction</a>.
* @endparblock
*/
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
diff --git a/cpukit/doxygen/build.h b/cpukit/doxygen/build.h
new file mode 100644
index 0000000000..696a6e1723
--- /dev/null
+++ b/cpukit/doxygen/build.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSImplDoxygen
+ *
+ * @brief This header file defines build system related Doxygen items.
+ */
+
+/*
+ * Copyright (C) 2023 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @defgroup RTEMSImplBuild Build Options
+ *
+ * @ingroup RTEMSImpl
+ *
+ * @brief This group contains files generated by the build system.
+ */
+
+/**
+ * @ingroup RTEMSImplBuild
+ *
+ * @file bsps/include/bspopts.h
+ *
+ * @brief This header file provides the BSP options definitions.
+ */
+
+/**
+ * @ingroup RTEMSImplBuild
+ *
+ * @file cpukit/include/version-vc-key.h
+ *
+ * @brief This header file provides the version control key definitions.
+ */
+
+/**
+ * @ingroup RTEMSImplBuild
+ *
+ * @file cpukit/include/config.h
+ *
+ * @brief This header file provides system configuration definitions.
+ */
+
+/**
+ * @ingroup RTEMSImplBuild
+ *
+ * @file cpukit/include/rtems/testopts.h
+ *
+ * @brief This header file provides test program definitions.
+ */
+
+/**
+ * @ingroup RTEMSImplBuild
+ *
+ * @file cpukit/include/rtems/score/cpuopts.h
+ *
+ * @brief This header file provides the CPU options definitions.
+ */
diff --git a/cpukit/doxygen/mainpage.h b/cpukit/doxygen/mainpage.h
new file mode 100644
index 0000000000..6eb0de7b36
--- /dev/null
+++ b/cpukit/doxygen/mainpage.h
@@ -0,0 +1,206 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSImplDoxygen
+ *
+ * @brief This file exists to provide a top level description of RTEMS for
+ * Doxygen.
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ * Copyright (C) 1989, 2014 On-Line Applications Research Corporation (OAR)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @mainpage
+ *
+ * The Real-Time Executive for Multiprocessor Systems (RTEMS) is a
+ * multi-threaded, single address-space, real-time operating system with no
+ * kernel-space/user-space separation. It is capable to operate in an SMP
+ * configuration providing a state of the art feature set.
+ *
+ * RTEMS and all third-party software distributed with RTEMS which may be
+ * linked to the application is licensed under permissive open source licenses.
+ * This means that the licenses do not propagate to the application software.
+ * Most of the original RTEMS code is now under the [BSD 2-Clause
+ * license](https://git.rtems.org/rtems/tree/LICENSE.BSD-2-Clause). Some
+ * code of RTEMS is under a legacy license, the [modified GPL 2.0 or later
+ * license with an exception for static
+ * linking](https://git.rtems.org/rtems/tree/LICENSE). It exposes no license
+ * requirements on application code. Everything necessary to build RTEMS
+ * applications is available as open source software. This makes you
+ * completely vendor independent.
+ *
+ * RTEMS provides the following basic feature set:
+ *
+ * - @ref RTEMSAPI
+ *
+ * - POSIX with
+ * [pthreads](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html)
+ * (enables a broad range of standard software to run on RTEMS)
+ *
+ * - @ref RTEMSAPIClassic
+ *
+ * - C11 (including
+ * [thread](https://en.cppreference.com/w/c/thread) support)
+ *
+ * - C++11 (including
+ * [thread](https://en.cppreference.com/w/cpp/thread>) support)
+ *
+ * - Newlib and GCC internal
+ *
+ * - Programming languages
+ *
+ * - C/C++/OpenMP (RTEMS Source Builder, RSB)
+ *
+ * - Ada (RSB, ``--with-ada``)
+ *
+ * - Erlang
+ *
+ * - Fortran (RSB, ``--with-fortran``)
+ *
+ * - Python and MicroPython
+ *
+ * - Parallel languages
+ *
+ * - [Embedded Multicore Building Blocks](https://embb.io/)
+ *
+ * - [OpenMP](https://www.openmp.org/)
+ *
+ * - Thread synchronization and communication
+ *
+ * - Mutexes with and without locking protocols
+ *
+ * - Counting semaphores
+ *
+ * - Binary semaphores
+ *
+ * - Condition variables
+ *
+ * - Events
+ *
+ * - Message queues
+ *
+ * - Barriers
+ *
+ * - [Futex](@ref RTEMSScoreFutex) (used by OpenMP barriers)
+ *
+ * - Epoch Based Reclamation (libbsd)
+ *
+ * - Locking protocols
+ *
+ * - Transitive Priority Inheritance
+ *
+ * - OMIP (SMP feature)
+ *
+ * - Priority Ceiling
+ *
+ * - MrsP (SMP feature)
+ *
+ * - Scalable timer and timeout support
+ *
+ * - Lock-free timestamps (FreeBSD timecounters)
+ *
+ * - Responsive interrupt management
+ *
+ * - Thread-Local Storage (TLS) as specified by C11/C++11 and later standard
+ * revisions
+ *
+ * - Link-time configurable schedulers
+ *
+ * - Fixed-priority
+ *
+ * - Job-level fixed-priority (EDF)
+ *
+ * - Constant Bandwidth Server (experimental)
+ *
+ * - Clustered scheduling (SMP feature)
+ *
+ * - Flexible link-time configuration
+ *
+ * - Job-level fixed-priority scheduler (EDF) with support for one-to-one
+ * and one-to-all thread to processor affinities (default SMP scheduler)
+ *
+ * - Fixed-priority scheduler
+ *
+ * - Proof-of-concept strong APA scheduler
+ *
+ * - Focus on link-time application-specific configuration
+ *
+ * - Linker-set based initialization (similar to global C++ constructors)
+ *
+ * - Operating system uses fine-grained locking (SMP feature)
+ *
+ * - Dynamic memory allocators
+ *
+ * - First-fit (default)
+ *
+ * - Universal Memory Allocator
+ * ([UMA](https://www.freebsd.org/cgi/man.cgi?query=uma&sektion=9),
+ * libbsd)
+ *
+ * - File systems
+ *
+ * - IMFS
+ *
+ * - FAT
+ *
+ * - RFS
+ *
+ * - NFSv2
+ *
+ * - JFFS2 (NOR flashes)
+ *
+ * - [YAFFS2](https://git.rtems.org/sebh/rtems-yaffs2.git/)
+ * (NAND flashes, GPL or commercial license required)
+ *
+ * - Device drivers
+ *
+ * - Termios (serial interfaces)
+ *
+ * - I2C (Linux user-space API compatible)
+ *
+ * - SPI (Linux user-space API compatible)
+ *
+ * - Network stacks (legacy, libbsd, lwIP)
+ *
+ * - USB stack (libbsd)
+ *
+ * - SD/MMC card stack (libbsd)
+ *
+ * - Framebuffer (Linux user-space API compatible, Qt)
+ *
+ * - Application runs in kernel-space and can access hardware directly
+ *
+ * - [libbsd](https://git.rtems.org/rtems-libbsd/)
+ *
+ * - Port of FreeBSD user-space and kernel-space components to RTEMS
+ *
+ * - Easy access to FreeBSD software for RTEMS
+ *
+ * - Support to stay in synchronization with FreeBSD
+ */
diff --git a/cpukit/doxygen/top-level-groups.h b/cpukit/doxygen/top-level-groups.h
index fd32db347a..9d34b3e3dd 100644
--- a/cpukit/doxygen/top-level-groups.h
+++ b/cpukit/doxygen/top-level-groups.h
@@ -41,6 +41,14 @@
*/
/**
+ * @defgroup RTEMSAPISystemLibrary System Library
+ *
+ * @ingroup RTEMSAPI
+ *
+ * @brief This group contains the system library APIs of RTEMS.
+ */
+
+/**
* @defgroup RTEMSDeviceDrivers Device Drivers
*
* @brief This group contains the device drivers.
diff --git a/cpukit/ftpd/ftpd.c b/cpukit/ftpd/ftpd.c
index ceb5c5d5b9..a925126dee 100644
--- a/cpukit/ftpd/ftpd.c
+++ b/cpukit/ftpd/ftpd.c
@@ -576,10 +576,9 @@ send_reply(FTPD_SessionInfo_t *info, int code, const char *text)
* Output parameters:
* returns 1 on success, 0 on failure.
*/
-static int
+static void
set_socket_timeout(int s, int seconds)
{
- int res = 0;
struct timeval tv;
int len = sizeof(tv);
@@ -591,9 +590,6 @@ set_socket_timeout(int s, int seconds)
syslog(LOG_ERR, "ftpd: Can't set send timeout on socket: %s.", serr());
else if(0 != setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, len))
syslog(LOG_ERR, "ftpd: Can't set receive timeout on socket: %s.", serr());
- else
- res = 1;
- return res;
}
/*
@@ -688,8 +684,7 @@ data_socket(FTPD_SessionInfo_t *info)
}
info->data_socket = s;
info->use_default = 1;
- if(s >= 0)
- set_socket_timeout(s, info->idle);
+ set_socket_timeout(s, info->idle);
return s;
}
@@ -1568,8 +1563,8 @@ command_pasv(FTPD_SessionInfo_t *info)
syslog(LOG_ERR, "ftpd: Error binding PASV socket: %s", serr());
else if (0 > listen(s, 1))
syslog(LOG_ERR, "ftpd: Error listening on PASV socket: %s", serr());
- else if (set_socket_timeout(s, info->idle))
{
+ set_socket_timeout(s, info->idle);
if (0 == getsockname(s, (struct sockaddr *)&addr, &addrLen))
{
char buf[FTPD_BUFSIZE];
@@ -2030,12 +2025,11 @@ ftpd_daemon(rtems_task_argument args RTEMS_UNUSED)
ss = accept(s, (struct sockaddr *)&addr, &addrLen);
if (0 > ss)
syslog(LOG_ERR, "ftpd: Error accepting control connection: %s", serr());
- else if(!set_socket_timeout(ss, ftpd_timeout))
- close_socket(ss);
else
{
FTPD_SessionInfo_t *info;
+ set_socket_timeout(ss, ftpd_timeout);
info = task_pool_obtain();
if (NULL == info)
{
diff --git a/cpukit/include/dev/can/can-msg.h b/cpukit/include/dev/can/can-msg.h
deleted file mode 100644
index 9863e14d84..0000000000
--- a/cpukit/include/dev/can/can-msg.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/**
- * @file
- *
- * @ingroup CANBus
- *
- * @brief Controller Area Network (CAN) Bus Implementation
- *
- */
-
-/*
- * Copyright (C) 2022 Prashanth S <fishesprashanth@gmail.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _DEV_CAN_CAN_MSG_H
-#define _DEV_CAN_CAN_MSG_H
-
-/**
- * @defgroup Controller Area Network (CAN) Driver
- *
- * @ingroup RTEMSDeviceDrivers
- *
- * @brief Controller Area Network (CAN) bus and device driver support.
- *
- * @{
- */
-
-/**
- * @defgroup CANBus CAN Bus Driver
- *
- * @ingroup CAN
- *
- * @{
- */
-
-/**
- * @brief CAN message size
- */
-#define CAN_MSG_MAX_SIZE (8u)
-
-/**
- * @brief Number of CAN tx buffers
- */
-#define CAN_TX_BUF_COUNT (10u)
-
-/**
- * @brief Number of CAN rx buffers
- */
-#define CAN_RX_BUF_COUNT (2u)
-
-#define CAN_MSGLEN(msg) (sizeof(struct can_msg) - (CAN_MSG_MAX_SIZE - msg->len))
-
-/**
- * @brief CAN message structure.
- */
-struct can_msg {
- /**
- * @brief CAN message id.
- */
- uint32_t id;
- /**
- * @brief CAN message timestamp.
- */
- uint32_t timestamp;
- /**
- * @brief CAN message flags RTR | BRS | EXT.
- */
- uint16_t flags;
- /**
- * @brief CAN message length.
- */
- uint16_t len;
- /**
- * @brief CAN message.
- */
- uint8_t data[CAN_MSG_MAX_SIZE];
-};
-
-/** @} */ /* end of CAN message */
-
-/** @} */
-
-#endif /* _DEV_CAN_CAN_MSG_H */
diff --git a/cpukit/include/dev/can/can.h b/cpukit/include/dev/can/can.h
deleted file mode 100644
index 9e55395039..0000000000
--- a/cpukit/include/dev/can/can.h
+++ /dev/null
@@ -1,284 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/**
- * @file
- *
- * @ingroup CANBus
- *
- * @brief Controller Area Network (CAN) Bus Implementation
- *
- */
-
-/*
- * Copyright (C) 2022 Prashanth S (fishesprashanth@gmail.com)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _DEV_CAN_CAN_H
-#define _DEV_CAN_CAN_H
-
-#include <rtems/imfs.h>
-#include <rtems/thread.h>
-#include <semaphore.h>
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <dev/can/can-msg.h>
-
-#define DEBUG(str, ...) \
- do { \
- printf("CAN: %s:%d ID: %08X ", __FILE__, __LINE__, rtems_task_self()); \
- printf(str, ##__VA_ARGS__); \
- } while (false);
-
-#define CAN_DEBUG(str, ...) DEBUG(str, ##__VA_ARGS__)
-#define CAN_DEBUG_BUF(str, ...) CAN_DEBUG(str, ##__VA_ARGS__)
-#define CAN_DEBUG_ISR(str, ...) CAN_DEBUG(str, ##__VA_ARGS__)
-#define CAN_DEBUG_LOCK(str, ...) CAN_DEBUG(str, ##__VA_ARGS__)
-#define CAN_DEBUG_RX(str, ...) CAN_DEBUG(str, ##__VA_ARGS__)
-#define CAN_DEBUG_TX(str, ...) CAN_DEBUG(str, ##__VA_ARGS__)
-#define CAN_DEBUG_REG(str, ...) //CAN_DEBUG(str, ##__VA_ARGS__)
-#define CAN_ERR(str, ...) DEBUG(str, ##__VA_ARGS__)
-
-#define CAN_MSG_LEN(msg) ((char *)(&((struct can_msg *)msg)->data[(uint16_t)((struct can_msg *)msg)->len]) - (char *)(msg))
-
-/* Maximum Bus Reg (255) */
-#define CAN_BUS_REG_MAX (255)
-
-/**
- * @defgroup Controller Area Network (CAN) Driver
- *
- * @ingroup RTEMSDeviceDrivers
- *
- * @brief Controller Area Network (CAN) bus and device driver support.
- *
- * @{
- */
-
-/**
- * @defgroup CANBus CAN Bus Driver
- *
- * @ingroup CAN
- *
- * @{
- */
-
-/**
- * @brief CAN tx fifo data structure.
- */
-struct ring_buf {
- /**
- * @brief Pointer to array of can_msg structure.
- */
- struct can_msg *pbuf;
- /**
- * @brief Index of the next free buffer.
- */
- uint32_t head;
- /**
- * @brief Index of the produced buffer.
- */
- uint32_t tail;
- /**
- * @brief Number of empty buffers.
- */
- uint32_t empty_count;
-};
-
-/**
- * @brief CAN Controller device specific operations.
- * These function pointers are initialized by the CAN device driver while
- * registering (can_bus_register).
- */
-typedef struct can_dev_ops {
- /**
- * @brief Transfers CAN messages to device fifo.
- *
- * @param[in] priv device control structure.
- * @param[in] msg can_msg message structure.
- *
- * @retval 0 Successful operation.
- * @retval >0 error number in case of an error.
- */
- int32_t (*dev_tx)(void *priv, struct can_msg *msg);
- /**
- * @brief Check device is ready to transfer a CAN message
- *
- * @param[in] priv device control structure.
- *
- * @retval true device ready.
- * @retval false device not ready.
- */
- bool (*dev_tx_ready)(void *priv);
- /**
- * @brief Enable/Disable CAN interrupts.
- *
- * @param[in] priv device control structure.
- * @param[in] flag true/false to Enable/Disable CAN interrupts.
- *
- */
- void (*dev_int)(void *priv, bool flag);
- /**
- * @brief CAN device specific I/O controls.
- *
- * @param[in] priv device control structure.
- * @param[in] buffer This depends on the cmd.
- * @param[in] cmd Device specific I/O commands.
- *
- * @retval 0 Depends on the cmd.
- */
- int32_t (*dev_ioctl)(void *priv, void *buffer, size_t cmd);
-} can_dev_ops;
-
-/**
- * @name CAN bus control
- *
- * @{
- */
-
-/**
- * @brief Obtains the bus.
- *
- * This command has no argument.
- */
-typedef struct can_bus {
- /**
- * @brief Device specific control.
- */
- void *priv;
- /**
- * @brief Device controller index.
- */
- uint8_t index;
- /**
- * @brief Device specific operations.
- */
- struct can_dev_ops *can_dev_ops;
- /**
- * @brief tx fifo.
- */
- struct ring_buf tx_fifo;
- /**
- * @brief Counting semaphore id (for fifo sync).
- */
- rtems_id tx_fifo_sem_id;
-
- /* FIXME: Using only one CAN msg buffer, Should create a ring buffer */
- /**
- * @brief rx fifo.
- */
- struct can_msg can_rx_msg;
- /**
- * @brief Mutex to handle bus concurrency.
- */
- rtems_mutex mutex;
- /**
- * @brief Destroys the bus.
- *
- * @param[in] bus control structure.
- */
- void (*destroy)(struct can_bus *bus);
-#ifdef CAN_DEBUG_LOCK
-
- /**
- * @brief For debugging semaphore obtain/release.
- */
- int sem_count;
-
-#endif /* CAN_DEBUG_LOCK */
-
-} can_bus;
-
-/** @} */
-
-/**
- * @brief Register a CAN node with the CAN bus driver.
- *
- * @param[in] bus bus control structure.
- * @param[in] bus_path path of device node.
- *
- * @retval >=0 rtems status.
- */
-rtems_status_code can_bus_register(can_bus *bus, const char *bus_path);
-
-/**
- * @brief Allocate and initilaize bus control structure.
- *
- * @param[in] size Size of the bus control structure.
- *
- * @retval NULL No memory available.
- * @retval Address Pointer to the allocated bus control structure.
- */
-can_bus *can_bus_alloc_and_init(size_t size);
-
-/**
- * @brief initilaize bus control structure.
- *
- * @param[in] bus bus control structure.
- *
- * @retval 0 success.
- * @retval >0 error number.
- */
-int can_bus_init(can_bus *bus);
-
-/**
- * @brief Initiates CAN message transfer.
- *
- * Should be called with CAN interrupt disabled.
- *
- * @param[in] bus Bus control structure.
- *
- * @retval 0 success.
- * @retval >0 error number.
- */
-int can_tx_done(struct can_bus *bus);
-
-/**
- * @brief Sends the received CAN message to the application.
- *
- * Should be called by the device when CAN message should be sent to applicaiton.
- * Should be called only with CAN interrupts disabled.
- *
- * @param[in] bus bus control structure.
- * @param[in] msg can_msg structure.
- *
- * @retval 0 success.
- * @retval >0 error number.
- */
-int can_receive(struct can_bus *bus, struct can_msg *msg);
-
-/**
- * @brief Prints the can_msg values pointed by msg.
- *
- * @param[in] msg can_msg structure.
- *
- */
-void can_print_msg(struct can_msg const *msg);
-
-/** @} */ /* end of CAN device driver */
-
-/** @} */
-
-#endif /* _DEV_CAN_CAN_H */
diff --git a/cpukit/include/dev/can/canqueueimpl.h b/cpukit/include/dev/can/canqueueimpl.h
deleted file mode 100644
index ef0d56fe31..0000000000
--- a/cpukit/include/dev/can/canqueueimpl.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/**
- * @file
- *
- * @ingroup CANBus
- *
- * @brief Controller Area Network (CAN) Bus Implementation
- *
- */
-
-/*
- * Copyright (C) 2022 Prashanth S <fishesprashanth@gmail.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _DEV_CAN_CAN_QUEUE_H
-#define _DEV_CAN_CAN_QUEUE_H
-
-#include <rtems/imfs.h>
-#include <rtems/thread.h>
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <dev/can/can-msg.h>
-#include <dev/can/can.h>
-
-/**
- * @defgroup Controller Area Network (CAN) Driver
- *
- * @ingroup RTEMSDeviceDrivers
- *
- * @brief Controller Area Network (CAN) bus and device driver support.
- *
- * @{
- */
-
-/**
- * @defgroup CANBus CAN Bus Driver
- *
- * @ingroup CAN
- *
- * @{
- */
-
-/**
- * @brief Create CAN tx buffers.
- *
- * @param[in] bus Bus control structure.
- *
- * @retval 0 Successful operation.
- * @retval >0 error number in case of an error.
- */
-static rtems_status_code can_bus_create_tx_buffers(struct can_bus *bus);
-
-/**
- * @brief Free CAN tx buffers.
- *
- * @param[in] bus Bus control structure.
- *
- */
-static void can_bus_free_tx_buffers(struct can_bus *bus);
-
-/**
- * @brief Check for atleast one empty CAN tx buffer.
- *
- * @param[in] bus Bus control structure.
- *
- * @retval true If atleast one CAN buffer is empty.
- * @retval false If no CAN buffer is empty.
- */
-static bool can_bus_tx_buf_is_empty(struct can_bus *bus);
-
-/**
- * @brief Get a produced tx buffer to transmit from the tx fifo.
- *
- * @param[in] bus Bus control structure.
- *
- * @retval can_msg Pointer to can_msg structure buffer.
- * @retval NULL If no can_msg buffer.
- */
-static struct can_msg *can_bus_tx_get_data_buf(struct can_bus *bus);
-
-/**
- * @brief Get a empty tx buffer.
- *
- * @param[in] bus Bus control structure.
- *
- * @retval can_msg Pointer to can_msg structure buffer.
- * @retval NULL If no empty can_msg buffer.
- */
-static struct can_msg *can_bus_tx_get_empty_buf(struct can_bus *bus);
-
-/**
- * @brief Creates tx buffers for the CAN bus driver.
- *
- * @param[in] bus Bus control structure.
- *
- * @retval rtems_status_code
- */
-static rtems_status_code can_bus_create_tx_buffers(struct can_bus *bus)
-{
- bus->tx_fifo.pbuf = (struct can_msg *)malloc(CAN_TX_BUF_COUNT *
- sizeof(struct can_msg));
- if (bus->tx_fifo.pbuf == NULL) {
- CAN_ERR("can_create_tx_buffers: malloc failed\n");
- return RTEMS_NO_MEMORY;
- }
-
- bus->tx_fifo.empty_count = CAN_TX_BUF_COUNT;
-
- return RTEMS_SUCCESSFUL;
-}
-
-/**
- * @brief Free tx buffers for the CAN bus driver.
- *
- * @param[in] bus Bus control structure.
- *
- */
-static void can_bus_free_tx_buffers(struct can_bus *bus)
-{
- free(bus->tx_fifo.pbuf);
-}
-
-/**
- * @brief Check if there is atleast one tx buffer in the CAN
- * bus driver.
- *
- * @param[in] bus Bus control structure.
- *
- * @retval true - If there is at least one free tx buffer.
- * false - If there is no free tx buffer.
- */
-static bool can_bus_tx_buf_is_empty(struct can_bus *bus)
-{
- if (bus->tx_fifo.empty_count == 0) {
- return false;
- }
-
- return true;
-}
-
-/**
- * @brief To get a can_msg tx buf which contains valid data to send in
- * in the CAN bus.
- *
- * Note: freeing the returned data buf is done in the same function,
- * So the returned buffer should be sent before releasing the
- * lock acquired while calling this function.
- *
- * @param[in] bus Bus control structure.
- *
- * @retval *can_msg - If there is atleast one tx buffer to send in the CAN bus.
- * NULL - If there is no valid tx buffer.
- */
-static struct can_msg *can_bus_tx_get_data_buf(struct can_bus *bus)
-{
- struct can_msg *msg = NULL;
-
- if (bus->tx_fifo.empty_count == CAN_TX_BUF_COUNT ||
- bus->tx_fifo.tail >= CAN_TX_BUF_COUNT) {
- CAN_DEBUG_BUF("can_bus_tx_get_data_buf: All buffers are empty\n");
- return NULL;
- }
-
- msg = &bus->tx_fifo.pbuf[bus->tx_fifo.tail];
- bus->tx_fifo.empty_count++;
- bus->tx_fifo.tail = (bus->tx_fifo.tail + 1) % CAN_TX_BUF_COUNT;
-
- return msg;
-}
-
-/**
- * @brief To get a can_msg tx buf which is empty (contains no valid data).
- *
- * Note: marking the returned buf valid is done in the same function
- * So a valid CAN message should be copied to the returned buffer before
- * releasing the lock acquired while calling this function.
- *
- * @param[in] bus Bus control structure.
- *
- * @retval *can_msg - If there is atleast one empty tx buffer.
- * NULL - If there is no empty tx buffer.
- */
-static struct can_msg *can_bus_tx_get_empty_buf(struct can_bus *bus)
-{
- struct can_msg *msg = NULL;
-
- /* Check whether there is a empty CAN msg buffer */
- if (can_bus_tx_buf_is_empty(bus) == false) {
- CAN_DEBUG_BUF("can_bus_tx_get_empty_buf: No empty buffer\n");
- return NULL;
- }
-
- bus->tx_fifo.empty_count--;
-
- /* tx_fifo.head always points to a empty buffer if there is atleast one */
- msg = &bus->tx_fifo.pbuf[bus->tx_fifo.head];
- bus->tx_fifo.head = (bus->tx_fifo.head + 1) % CAN_TX_BUF_COUNT;
-
- return msg;
-}
-
-/** @} */ /* end of CAN device driver */
-
-/** @} */
-
-#endif /*_DEV_CAN_CAN_QUEUE_H */
diff --git a/cpukit/include/dev/flash/flashdev.h b/cpukit/include/dev/flash/flashdev.h
index d1dc08a5c4..6759357206 100644
--- a/cpukit/include/dev/flash/flashdev.h
+++ b/cpukit/include/dev/flash/flashdev.h
@@ -39,6 +39,11 @@
#include <rtems/thread.h>
#include <sys/types.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
typedef struct rtems_flashdev rtems_flashdev;
/**
@@ -454,6 +459,10 @@ void rtems_flashdev_destroy_and_free(
rtems_flashdev *flash
);
+#ifdef __cplusplus
+}
+#endif
+
/** @} */
#endif /* _DEV_FLASHDEV_H */
diff --git a/cpukit/include/machine/_timecounter.h b/cpukit/include/machine/_timecounter.h
index 127e5f6fd3..e20e051f84 100644
--- a/cpukit/include/machine/_timecounter.h
+++ b/cpukit/include/machine/_timecounter.h
@@ -3,6 +3,8 @@
/**
* @file
*
+ * @ingroup RTEMSScoreTimecounter
+ *
* @brief This header file provides timecounter definitions for the kernel space
* (_KERNEL is defined before including <sys/time.h>) and RTEMS.
*/
diff --git a/cpukit/include/pci/irq.h b/cpukit/include/pci/irq.h
index 4069f1ffa8..8617dd1680 100644
--- a/cpukit/include/pci/irq.h
+++ b/cpukit/include/pci/irq.h
@@ -38,18 +38,9 @@
#ifndef __PCI_IRQ_H__
#define __PCI_IRQ_H__
-#include <rtems/irq-extension.h>
+#include <rtems/rtems/intr.h>
#include <rtems/score/basedefs.h>
-/*
- * FIXME: This should be available via the IRQ extensions API.
- *
- * https://devel.rtems.org/ticket/3269
- */
-void BSP_shared_interrupt_clear(int irq);
-void BSP_shared_interrupt_unmask(int irq);
-void BSP_shared_interrupt_mask(int irq);
-
/* PCI Handler (ISR) called when IRQ is generated by any of the PCI devices
* connected to the same PCI IRQ Pin. This has been defined the same way as
* rtems_interrupt_handler in order for BSPs to "direct-map" the register
@@ -106,7 +97,7 @@ static inline int pci_interrupt_unregister(int irq, pci_isr isr,
*/
static inline void pci_interrupt_unmask(int irq)
{
- BSP_shared_interrupt_unmask(irq);
+ (void)rtems_interrupt_vector_enable((rtems_vector_number)irq);
}
/* Disable shared PCI IRQ handler. This function will mask the interrupt
@@ -122,7 +113,7 @@ static inline void pci_interrupt_unmask(int irq)
*/
static inline void pci_interrupt_mask(int irq)
{
- BSP_shared_interrupt_mask(irq);
+ (void)rtems_interrupt_vector_disable((rtems_vector_number)irq);
}
/* Acknowledge the interrupt controller by writing to the interrupt controller.
@@ -136,7 +127,7 @@ static inline void pci_interrupt_mask(int irq)
*/
static inline void pci_interrupt_clear(int irq)
{
- BSP_shared_interrupt_clear(irq);
+ (void)rtems_interrupt_clear((rtems_vector_number)irq);
}
#endif /* !__PCI_IRQ_H__ */
diff --git a/cpukit/include/rtems/score/io.h b/cpukit/include/rtems/base64.h
index 9cd401eb1d..58e48a8c33 100644
--- a/cpukit/include/rtems/score/io.h
+++ b/cpukit/include/rtems/base64.h
@@ -3,14 +3,14 @@
/**
* @file
*
- * @ingroup RTEMSScoreIO
+ * @ingroup RTEMSImplBase64
*
* @brief This header file provides the interfaces of the
- * @ref RTEMSScoreIO.
+ * @ref RTEMSImplBase64.
*/
/*
- * Copyright (c) 2017 embedded brains GmbH & Co. KG
+ * Copyright (C) 2020, 2024 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,42 +34,35 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _RTEMS_SCORE_IO_H
-#define _RTEMS_SCORE_IO_H
+#ifndef _RTEMS_BASE64_H
+#define _RTEMS_BASE64_H
-#include <rtems/score/basedefs.h>
-
-#include <stdarg.h>
+#include <rtems/dev/io.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
- * @defgroup RTEMSScoreIO IO Handler
+ * @defgroup RTEMSImplBase64 Base64 Encoding and Decoding
*
- * @ingroup RTEMSScore
+ * @ingroup RTEMSImpl
*
- * @brief This group contains the IO Handler implementation.
+ * @brief This group contains support functions for base64 and base64url
+ * encoding and decoding.
*
* @{
*/
-typedef void ( *IO_Put_char )( int c, void *arg );
-
-int _IO_Printf(
- IO_Put_char put_char,
- void *arg,
- char const *fmt,
- ...
-) RTEMS_PRINTFLIKE( 3, 4 );
+/**
+ * @brief Maps a 6-bit integer to the corresponding base64 encoding.
+ */
+extern const uint8_t _Base64_Encoding[ 64 ];
-int _IO_Vprintf(
- IO_Put_char put_char,
- void *arg,
- char const *fmt,
- va_list ap
-);
+/**
+ * @brief Maps a 6-bit integer to the corresponding base64url encoding.
+ */
+extern const uint8_t _Base64url_Encoding[ 64 ];
/**
* @brief Outputs the source buffer in base64 encoding.
@@ -93,7 +86,7 @@ int _IO_Vprintf(
*
* @return Returns the count of output characters.
*/
-int _IO_Base64(
+int _Base64_Encode(
IO_Put_char put_char,
void *arg,
const void *src,
@@ -124,7 +117,7 @@ int _IO_Base64(
*
* @return Returns the count of output characters.
*/
-int _IO_Base64url(
+int _Base64url_Encode(
IO_Put_char put_char,
void *arg,
const void *src,
@@ -134,17 +127,72 @@ int _IO_Base64url(
);
/**
- * @brief Issues a couple of no-operation instructions.
+ * @brief Represents the base64 and base64url decoder state.
+ */
+typedef enum {
+ BASE64_DECODE_STATE_0,
+ BASE64_DECODE_STATE_1,
+ BASE64_DECODE_STATE_2,
+ BASE64_DECODE_STATE_3
+} Base64_Decode_state;
+
+/**
+ * @brief Contains the base64 and base64url decoder control.
+ */
+typedef struct {
+ Base64_Decode_state state;
+ uint8_t *target;
+ const uint8_t *target_end;
+} Base64_Decode_control;
+
+/**
+ * @brief Maps a 7-bit character to the associated 6-bit integer as defined by
+ * the base64 or base64url encoding or a special value.
+ */
+extern const uint8_t _Base64_Decoding[ 128 ];
+
+/**
+ * @brief Initializes the base64 decoder.
+ *
+ * @param[out] self is the base64 decoder control to initialize.
+ *
+ * @param[out] target is the base address of the target area for decoding.
+ *
+ * @param target_size is the size in bytes of the target area for decoding.
+ */
+void _Base64_Decode_initialize(
+ Base64_Decode_control *self,
+ uint8_t *target,
+ size_t target_size
+);
+
+/**
+ * @brief Represents the base64 and base64url decoder status.
+ */
+typedef enum {
+ BASE64_DECODE_SUCCESS,
+ BASE64_DECODE_OVERFLOW,
+ BASE64_DECODE_INVALID_INPUT
+} Base64_Decode_status;
+
+/**
+ * @brief Decodes the character.
+ *
+ * The decoder accepts base64 and base64url encodings. White space is ignored.
*
- * This function may be used to burn a couple of processor cycles with minimum
- * impact on the system bus. It may be used in busy wait loops.
+ * @param[in, out] self is the base64 decoder control.
+ *
+ * @param ch is the character to decode.
*/
-void _IO_Relax( void );
+Base64_Decode_status _Base64_Decode(
+ Base64_Decode_control *self,
+ char ch
+);
-/** @} */
+/** @} */
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#endif /* _RTEMS_SCORE_IO_H */
+#endif /* _RTEMS_BASE64_H */
diff --git a/cpukit/include/rtems/confdefs/clock.h b/cpukit/include/rtems/confdefs/clock.h
index 26519cc70b..e57daa899b 100644
--- a/cpukit/include/rtems/confdefs/clock.h
+++ b/cpukit/include/rtems/confdefs/clock.h
@@ -70,6 +70,11 @@
#warning "The clock ticks per second is not an integer"
#endif
+#if defined(CONFIGURE_TICKS_PER_TIMESLICE) \
+ && CONFIGURE_TICKS_PER_TIMESLICE <= 0
+ #error "CONFIGURE_TICKS_PER_TIMESLICE shall be greater than zero"
+#endif
+
#if CONFIGURE_MICROSECONDS_PER_TICK <= 0
#error "CONFIGURE_MICROSECONDS_PER_TICK must be positive"
#endif
diff --git a/cpukit/include/rtems/config.h b/cpukit/include/rtems/config.h
index 40d703d61a..a19d809cf9 100644
--- a/cpukit/include/rtems/config.h
+++ b/cpukit/include/rtems/config.h
@@ -438,7 +438,7 @@ const char *rtems_get_version_string( void );
* @endparblock
*/
#define rtems_configuration_get_interrupt_stack_size() \
- ((size_t) _ISR_Stack_size)
+ ((size_t) _ISR_Stack_size_object)
/* Generated from spec:/rtems/config/if/get-maximum-extensions */
diff --git a/cpukit/include/rtems/crc.h b/cpukit/include/rtems/crc.h
new file mode 100644
index 0000000000..1158dbcd7b
--- /dev/null
+++ b/cpukit/include/rtems/crc.h
@@ -0,0 +1,106 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSImplCRC
+ *
+ * @brief This header file provides the interfaces of the
+ * @ref RTEMSImplCRC.
+ */
+
+/*
+ * Copyright (C) 2024 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTEMS_CRC_H
+#define _RTEMS_CRC_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup RTEMSImplCRC Cyclic Redundancy Check (CRC) Support
+ *
+ * @ingroup RTEMSImpl
+ *
+ * @brief This group contains functions to calculate
+ * Cyclic Redundancy Check (CRC) values.
+ *
+ * @{
+ */
+
+
+/**
+ * @brief This constant represents the default CRC-24Q seed state.
+ */
+#define CRC24Q_SEED 0U
+
+/**
+ * @brief This constant provides a mask to get a valid CRC-24Q value from the
+ * integers returned by _CRC24Q_Update() and _CRC24Q_Sequence_update().
+ */
+#define CRC24Q_MASK 0xffffffU
+
+/**
+ * @brief Updates the CRC-24Q state using a byte.
+ *
+ * @param crc is the input CRC-24Q state.
+ *
+ * @param byte is the byte updating the input CRC-24Q state.
+ *
+ * @return Returns the updated CRC-24Q state. Use the #CRC24Q_MASK to get a
+ * valid CRC-24Q value.
+ */
+uint32_t _CRC24Q_Update( uint32_t crc, uint8_t byte );
+
+/**
+ * @brief Updates the CRC-24Q state using a sequence of bytes.
+ *
+ * @param crc is the input CRC-24Q state.
+ *
+ * @param bytes[in] is the sequence of bytes updating the input CRC-24Q state.
+ *
+ * @param size_in_bytes is the size in bytes of the byte sequence.
+ *
+ * @return Returns the updated CRC-24Q state. Use the #CRC24Q_MASK to get a
+ * valid CRC-24Q value.
+ */
+uint32_t _CRC24Q_Sequence_update(
+ uint32_t crc,
+ const void *bytes,
+ size_t size_in_bytes
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_CRC_H */
diff --git a/cpukit/include/rtems/dev/io.h b/cpukit/include/rtems/dev/io.h
new file mode 100644
index 0000000000..b8bcde7af4
--- /dev/null
+++ b/cpukit/include/rtems/dev/io.h
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSDeviceIO
+ *
+ * @brief This header file provides the interfaces of the
+ * @ref RTEMSDeviceIO.
+ */
+
+/*
+ * Copyright (C) 2017, 2023 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTEMS_DEV_IO_H
+#define _RTEMS_DEV_IO_H
+
+#include <rtems/score/basedefs.h>
+
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup RTEMSDeviceIO Device I/O Support
+ *
+ * @ingroup RTEMSDeviceDrivers
+ *
+ * @brief This group contains the Device I/O Support API and implementation.
+ *
+ * @{
+ */
+
+/**
+ * @brief This type defines the put character handler.
+ *
+ * @param c is the character to put.
+ *
+ * @param arg is the user-provided argument.
+ */
+typedef void ( *IO_Put_char )( int c, void *arg );
+
+/**
+ * @brief Prints characters using the put character handler according to the
+ * format string.
+ *
+ * @param put_char is the put character handler.
+ *
+ * @param arg is the user-provided argument for the put character handler.
+ *
+ * @param fmt is the printf()-style format string.
+ *
+ * @param ... is the list of parameters required by the format string.
+ *
+ * @return Returns the count of put characters.
+ */
+int _IO_Printf(
+ IO_Put_char put_char,
+ void *arg,
+ char const *fmt,
+ ...
+) RTEMS_PRINTFLIKE( 3, 4 );
+
+/**
+ * @brief Prints characters using the put character handler according to the
+ * format string.
+ *
+ * @param put_char is the put character handler.
+ *
+ * @param arg is the user-provided argument for the put character handler.
+ *
+ * @param fmt is the printf()-style format string.
+ *
+ * @param ap is the argument list required by the format string.
+ *
+ * @return Returns the count of put characters.
+ */
+int _IO_Vprintf(
+ IO_Put_char put_char,
+ void *arg,
+ char const *fmt,
+ va_list ap
+);
+
+/**
+ * @brief Issues a couple of no-operation instructions.
+ *
+ * This function may be used to burn a couple of processor cycles with minimum
+ * impact on the system bus. It may be used in busy wait loops.
+ */
+void _IO_Relax( void );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_DEV_IO_H */
diff --git a/cpukit/include/rtems/imfs.h b/cpukit/include/rtems/imfs.h
index 7db9b4e462..405f489ab3 100644
--- a/cpukit/include/rtems/imfs.h
+++ b/cpukit/include/rtems/imfs.h
@@ -477,7 +477,7 @@ extern void IMFS_fsunmount(
*/
extern int rtems_tarfs_load(
const char *mountpoint,
- uint8_t *tar_image,
+ const void *tar_image,
size_t tar_size
);
diff --git a/cpukit/include/rtems/libio.h b/cpukit/include/rtems/libio.h
index cb0e6879a9..5424a2a03c 100644
--- a/cpukit/include/rtems/libio.h
+++ b/cpukit/include/rtems/libio.h
@@ -56,6 +56,7 @@
#include <rtems/fs.h>
#include <rtems/chain.h>
#include <rtems/score/atomic.h>
+#include <rtems/termiosdevice.h>
#ifdef __cplusplus
extern "C" {
@@ -1360,7 +1361,7 @@ typedef struct {
/**
* @brief Parameter block for open/close.
*/
-typedef struct {
+typedef struct rtems_libio_open_close_args {
rtems_libio_t *iop;
uint32_t flags;
uint32_t mode;
@@ -1902,7 +1903,7 @@ typedef struct rtems_termios_callbacks {
int (*setAttributes)(int minor, const struct termios *t);
int (*stopRemoteTx)(int minor);
int (*startRemoteTx)(int minor);
- int outputUsesInterrupts;
+ rtems_termios_device_mode outputUsesInterrupts;
} rtems_termios_callbacks;
static inline void rtems_termios_initialize( void )
diff --git a/cpukit/include/rtems/linkersets.h b/cpukit/include/rtems/linkersets.h
index ef1b0d38d4..a5d7b1b037 100644
--- a/cpukit/include/rtems/linkersets.h
+++ b/cpukit/include/rtems/linkersets.h
@@ -1,5 +1,13 @@
/* SPDX-License-Identifier: BSD-2-Clause */
+/**
+ * @file
+ *
+ * @ingroup RTEMSAPILinkerSets
+ *
+ * @brief This header file provides the linker sets API.
+ */
+
/*
* Copyright (C) 2015, 2020 embedded brains GmbH & Co. KG
*
@@ -34,6 +42,36 @@
extern "C" {
#endif /* __cplusplus */
+/**
+ * @ingroup RTEMSImpl
+ *
+ * @brief Obfuscates a pointer to prevent compiler optimizations.
+ *
+ * @param ptr is the pointer to obfuscate.
+ *
+ * @return Returns the unsigned integer representation of the obfuscated
+ * pointer.
+ */
+static inline uintptr_t _Linker_set_Obfuscate( const void *ptr )
+{
+ uintptr_t addr;
+
+ addr = (uintptr_t) ptr;
+ RTEMS_OBFUSCATE_VARIABLE( addr );
+
+ return addr;
+}
+
+/**
+ * @defgroup RTEMSAPILinkerSets Linker Sets
+ *
+ * @ingroup RTEMSAPI
+ *
+ * @brief This group contains the linker sets API.
+ *
+ * @{
+ */
+
#define RTEMS_LINKER_SET_BEGIN( set ) \
_Linker_set_##set##_begin
@@ -129,16 +167,6 @@ extern "C" {
decl \
RTEMS_SECTION( ".rtemsrwset." #set ".content" )
-static inline uintptr_t _Linker_set_Obfuscate( const void *ptr )
-{
- uintptr_t addr;
-
- addr = (uintptr_t) ptr;
- RTEMS_OBFUSCATE_VARIABLE( addr );
-
- return addr;
-}
-
#define RTEMS_LINKER_SET_SIZE( set ) \
( _Linker_set_Obfuscate( RTEMS_LINKER_SET_END( set ) ) \
- _Linker_set_Obfuscate( RTEMS_LINKER_SET_BEGIN( set ) ) )
@@ -157,6 +185,8 @@ static inline uintptr_t _Linker_set_Obfuscate( const void *ptr )
++item \
)
+/** @} */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/cpukit/include/rtems/posix/posixapi.h b/cpukit/include/rtems/posix/posixapi.h
index 24c1dc51e0..5d78573ef7 100644
--- a/cpukit/include/rtems/posix/posixapi.h
+++ b/cpukit/include/rtems/posix/posixapi.h
@@ -3,10 +3,10 @@
/**
* @file
*
- * @brief POSIX API Implementation
+ * @ingroup POSIXAPI
*
- * This include file defines the top level interface to the POSIX API
- * implementation in RTEMS.
+ * @brief This header file provides interfaces used by the POSIX API
+ * implementation.
*/
/*
diff --git a/cpukit/include/rtems/posix/spinlockimpl.h b/cpukit/include/rtems/posix/spinlockimpl.h
index 855e57cc14..10424f1961 100644
--- a/cpukit/include/rtems/posix/spinlockimpl.h
+++ b/cpukit/include/rtems/posix/spinlockimpl.h
@@ -2,11 +2,11 @@
/**
* @file
- *
- * @brief Inlined Routines from the POSIX Spinlock Manager
*
- * This file contains the static inlin implementation of the inlined
- * routines from the POSIX Spinlock Manager.
+ * @ingroup POSIXAPI
+ *
+ * @brief This header file provides interfaces used by the POSIX Spinlock
+ * implementation.
*/
/*
diff --git a/cpukit/include/rtems/regulator.h b/cpukit/include/rtems/regulator.h
new file mode 100644
index 0000000000..442040a180
--- /dev/null
+++ b/cpukit/include/rtems/regulator.h
@@ -0,0 +1,502 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RegulatorAPI
+ *
+ * @brief This header file defines the Regulator API.
+ *
+ */
+
+/*
+ * Copyright (C) 2023 On-Line Applications Research Corporation (OAR)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @defgroup RegulatorAPI Regulator API
+ *
+ * @brief Regulator APIs
+ *
+ * The Regulator provides a set of APIs to manage input sources which
+ * produces bursts of message traffic.
+ *
+ * The regulator is designed to sit logically between two entities -- a
+ * source and a destination, where it limits the traffic sent to the
+ * destination to prevent it from being flooded with messages from the
+ * source. This can be used to accommodate bursts of input from a source
+ * and meter it out to a destination. The maximum number of messages
+ * which can be buffered in the regulator is specified by the
+ * @a maximum_messages field in the @a rtems_regulator_attributes
+ * structure passed as an argument to @a rtems_regulator_create().
+ *
+ * The regulator library accepts an input stream of messages from a
+ * source and delivers them to a destination. The regulator assumes that the
+ * input stream from the source contains sporadic bursts of data which can
+ * exceed the acceptable rate of the destination. By limiting the message rate,
+ * the regulator prevents an overflow of messages.
+ *
+ * The regulator can be configured for the input buffering required to manage
+ * the maximum burst and for the metering rate for the output. The output rate
+ * is in messages per second. If the sender produces data too fast, the
+ * regulator will buffer the configured number of messages.
+ *
+ * A configuration capability is provided to allow for adaptation to different
+ * message streams. The regulator can also support running multiple instances,
+ * which could be used on independent message streams.
+ *
+ * The regulator provides a simple interface to the application for avoiding
+ * bursts of input from a fast source overflowing a slower destination.
+ *
+ * It is assumed that the application has a design limit on the number of
+ * messages which may be buffered. All messages accepted by the regulator,
+ * assuming no overflow on input, will eventually be output by the Delivery
+ * thread.
+ *
+ * A regulator instance is used as follows from the producer/source side:
+ *
+ * @code
+ * while (1)
+ * use rtems_regulator_obtain_buffer to obtain a buffer
+ * input operation to fetch data into the buffer
+ * rtems_regulator_send(buffer, size of message)
+ * @endcode
+ *
+ * The delivery of message buffers to the Destination and subsequent
+ * release is performed in the context of the delivery thread by either
+ * the delivery function or delivery thread. Details are below.
+ *
+ * The sequence diagram below shows the interaction between a message Source,
+ * a Regulator instance, and RTEMS, given the usage described in the above
+ * paragraphs.
+ *
+ * \startuml "Regulator Application Input Source Usage"
+ * Source -> Regulator : rtems_regulator_obtain_buffer(regulator, buffer)
+ * Regulator -> RTEMS : rtems_partition_get_buffer(id, buffer)
+ * RTEMS --> Regulator : rtems_status_code
+ * Regulator --> Source : rtems_status_code
+ * Source -> Regulator : rtems_regulator_send(regulator, message, length)
+ * Regulator -> RTEMS : rtems_message_queue_send(id, message, size)
+ * RTEMS --> Regulator : rtems_status_code
+ * Regulator --> Source : rtems_status_code
+ * \enduml
+ *
+ * As illustrated in the sequence diagram, the Source usually corresponds
+ * to application software reading a system input. The Source obtains a
+ * buffer from the Regulator instance and fills it with incoming data.
+ * The application explicitly obtaining a buffer and filling it in allows
+ * for zero copy operations on the Source side.
+ *
+ * The Source then sends the buffer to the Regulator instance. The Regulator
+ * the sends the buffer via a message queue which to the Delivery thread.
+ * The Delivery thread executes periodically at a rate specified at
+ * Regulation creation. At each period, the Delivery thread attempts to
+ * receive up to a configured number of buffers and invoke the Delivery
+ * function to deliver them to the Destination.
+ *
+ * The Delivery function is provided by the application for this
+ * specific Regulator instance. Depending on the Destination, it may use
+ * a function which copies the buffer contents (e.g., write()) or which
+ * operates directly on the buffer contents (e.g. DMA from buffer). In
+ * the case of a Destination which copies the buffer contents, the buffer
+ * can be released via @a rtems_regulator_release_buffer() as soon as the
+ * function or copying completes. In the case where the delivery uses the
+ * buffer and returns, the call to @a rtems_regulator_release_buffer()
+ * will occur when the use of the buffer is complete (e.g. completion
+ * of DMA transfer). This explicit and deliberate exposure of buffering
+ * provides the application with the ability to avoid copying the contents.
+ *
+ * After the Source has sent the message to the Regulator instance,
+ * the Source is free to process another input and the Regulator
+ * instance will ensure that the buffer is delivered to the Delivery
+ * function and Destination.
+ *
+ * The Regulator implementation uses the RTEMS Classic API Partition Manager
+ * to manage the buffer pool and the RTEMS Classic API Message Queue
+ * Manager to send the buffer to the Delivery thread.
+ */
+
+#ifndef REGULATOR_H
+#define REGULATOR_H
+
+#include <stdlib.h>
+
+#include <rtems.h>
+
+/**
+ * @ingroup RegulatorAPI
+ *
+ * @brief Regulator Delivery Function Type
+ *
+ * The user provides a function which is invoked to deliver a message
+ * to the output. It is invoked by the Delivery thread created as part
+ * of @a rtems_regulator_create(). The priority and stack size of the
+ * Delivery thread are specified in the regulator attribute set.
+ *
+ * It takes three parameters:
+ *
+ * @param[in] context is an untyped pointer to a user context
+ * @param[in] message points to the message
+ * @param[in] length is the message size
+ *
+ * The following is an example deliverer function. It assumes that the
+ * application has defined the my_context_t structure and it has at least
+ * the socket field. The @a message passed in originated with an
+ * application source which obtained the @a message buffer using
+ * @a rtems_regulator_obtain_buffer(), filled it in with source data,
+ * and used @a rtems_regulator_send() to hand to the regulator instance
+ * for later delivery.
+ *
+ * @code
+ * bool my_deliverer(
+ * void *context,
+ * void *message,
+ * size_t length
+ * )
+ * {
+ * my_context_t *my_context;
+ *
+ * my_context = (my_context_t *)context;
+ *
+ * write(my_context->socket, message, length);
+ * rtems_regulator_release_buffer(message);
+ * // return false to indicate we released the buffer
+ * return false;
+ * }
+ * @endcode
+ *
+ * The delivery function returns true to indicate that the delivery thread
+ * should release the buffer or false to indicate that it released the
+ * buffer. If the delivery function invokes a function like @a write()
+ * to deliver the message to the destination, then the buffer can be
+ * released immediately after the call. If the delivery function does
+ * something like setting up a DMA transfer of the buffer, it cannot be
+ * released until after the DMA is complete.
+ *
+ * The following sequence diagram shows the behavior of the Delivery thread
+ * body and its interaction with the user-supplied deliverer() function.
+ *
+ * \startuml "Regulator Delivery Thread Body"
+ * loop while (1)
+ * "Delivery Thread" -> RTEMS : rtems_rate_monotonic_period(id, delivery_thread_period)
+ * loop for 0 : maximum_to_dequeue_per_period
+ * "Delivery Thread" -> RTEMS : rtems_message_queue_receive(id, message, size, wait, 0)
+ * RTEMS --> "Delivery Thread" : rtems_status_code
+ * group if [rtems_status_code != RTEMS_SUCCESSFUL]
+ * RTEMS -> "Delivery Thread" : break
+ * end
+ * "Delivery Thread" -> Application : deliverer(context, buffer, length)
+ * "Delivery Thread" -> RTEMS : rtems_partition_return_buffer(id, buffer)
+ * RTEMS --> "Delivery Thread" : rtems_status_code
+ * end
+ * end
+ * \enduml
+ *
+ * In the above sequence diagram, the key points are:
+ *
+ * -# The Delivery Thread Body is periodically executed.
+ * -# During each period, up to the instance configuration parameter
+ * @a maximum_to_dequeue_per_period may be dequeued and
+ * passed the application's delivery function for processing.
+ *
+ * Note that the application explicitly obtains buffers from the
+ * regulator instance but that the release may be done by Delivery
+ * Thread, the Delivery function, or later when the buffer contents
+ * are transferred.
+ */
+typedef bool (*rtems_regulator_deliverer)(
+ void *context,
+ void *message,
+ size_t length
+);
+
+/**
+ * @ingroup RegulatorAPI
+ *
+ * @brief Attributes for Regulator Instance
+ *
+ * An instance of this structure must be populated by the application
+ * before creating an instance of the regulator. These settings tailor
+ * the behavior of the regulator instance.
+ */
+typedef struct {
+ /** Application function to invoke to output a message to the destination*/
+ rtems_regulator_deliverer deliverer;
+
+ /** Context pointer to pass to deliver function */
+ void *deliverer_context;
+
+ /** Maximum size message to process */
+ size_t maximum_message_size;
+
+ /** Maximum number of messages to be able to buffer */
+ size_t maximum_messages;
+
+ /** Priority of Delivery thread */
+ rtems_task_priority delivery_thread_priority;
+
+ /** Stack size of Delivery thread */
+ size_t delivery_thread_stack_size;
+
+ /** Period (in ticks) of Delivery thread */
+ rtems_interval delivery_thread_period;
+
+ /** Maximum messages to dequeue per period */
+ size_t maximum_to_dequeue_per_period;
+
+} rtems_regulator_attributes;
+
+/**
+ * @ingroup RegulatorAPI
+ *
+ * @brief Statistics for Regulator Instance
+ *
+ * An instance of this structure is provided to the directive
+ * @a rtems_regulator_get_statistics and is filled in by that service.
+ */
+typedef struct {
+ /** Number of successfully obtained buffers. */
+ size_t obtained;
+
+ /** Number of successfully released buffers. */
+ size_t released;
+
+ /** Number of successfully delivered buffers. */
+ size_t delivered;
+
+ /** Rate Monotonic Period statistics for Delivery Thread */
+ rtems_rate_monotonic_period_statistics period_statistics;
+
+} rtems_regulator_statistics;
+
+/**
+ * @ingroup RegulatorAPI
+ *
+ * @brief Regulator Internal Structure
+ */
+struct _Regulator_Control;
+
+/**
+ * @ingroup RegulatorAPI
+ *
+ * @brief Regulator Instance
+ *
+ * This is used by the application as the handle to a Regulator instance.
+ */
+typedef struct _Regulator_Control *rtems_regulator_instance;
+
+/**
+ * @ingroup RegulatorAPI
+ *
+ * @brief Create a regulator
+ *
+ * This function creates an instance of a regulator. It uses the provided
+ * @a attributes to create the instance return in @a regulator. This instance
+ * will allocate the buffers associated with the regulator instance as well
+ * as the Delivery thread.
+ *
+ * The @a attributes structure defines the priority and stack size of
+ * the Delivery thread dedicated to this regulator instance. It also
+ * defines the period of the Delivery thread and the maximum number of
+ * messages that may be delivered per period via invocation of the
+ * delivery function.
+ *
+ * For each regulator instance, the following resources are allocated:
+ *
+ * - A memory area for the regulator control block using @a malloc().
+ * - A RTEMS Classic API Message Queue is constructed with message
+ * buffer memory allocated using @a malloc(). Each message consists
+ * of a pointer and a length.
+ * - A RTEMS Classic API Partition.
+ * - A RTEMS Classic API Rate Monotonic Period.
+ *
+ * @param[in] attributes specify the regulator instance attributes
+ * @param[inout] regulator will point to the regulator instance
+ *
+ * @return an RTEMS status code indicating success or failure.
+ *
+ * @note This function allocates memory for the buffers holding messages,
+ * an Delivery thread and an RTEMS partition. When it executes, the
+ * Delivery thread will create an RTEMS rate monotonic period.
+ */
+rtems_status_code rtems_regulator_create(
+ rtems_regulator_attributes *attributes,
+ rtems_regulator_instance **regulator
+);
+
+/**
+ * @ingroup RegulatorAPI
+ *
+ * @brief Delete a regulator
+ *
+ * This function is used to delete the specified @a regulator instance.
+ *
+ * It is the responsibility of the user to ensure that any resources
+ * such as sockets or open file descriptors used by the delivery
+ * function are also deleted. It is likely safer to delete those
+ * delivery resources after deleting the regulator instance rather than
+ * before.
+ *
+ * @param[in] regulator is the instance to delete
+ * @param[in] ticks is the maximum number of ticks to wait for
+ * the delivery thread to shutdown.
+ *
+ * @return an RTEMS status code indicating success or failure.
+ *
+ * @note This function deallocates the resources allocated during
+ * @a rtems_regulator_create().
+ */
+rtems_status_code rtems_regulator_delete(
+ rtems_regulator_instance *regulator,
+ rtems_interval ticks
+);
+
+/**
+ * @ingroup RegulatorAPI
+ *
+ * @brief Obtain Buffer from Regulator
+ *
+ * This function is used to obtain a buffer from the regulator's pool. The
+ * @a buffer returned is assumed to be filled in with contents and used
+ * in a subsequent call to @a rtems_regulator_send(). When the @a buffer is
+ * delivered, it is expected to be released. If the @a buffer is not
+ * successfully accepted by this function, then it should be returned
+ * using @a rtems_regulator_release_buffer() or used to send another message.
+ *
+ * The @a buffer is of the maximum_message_size specified in the attributes
+ * passed in to @a rtems_regulator_create().
+ *
+ * @param[in] regulator is the regulator instance to operate upon
+ * @param[out] buffer will point to the allocated buffer
+ *
+ * @return an RTEMS status code indicating success or failure.
+ *
+ * @note This function does not perform dynamic allocation. It obtains a
+ * buffer from the pool allocated during @a rtems_regulator_create().
+ *
+ * @note Any attempt to write outside the buffer area is undefined.
+ */
+rtems_status_code rtems_regulator_obtain_buffer(
+ rtems_regulator_instance *regulator,
+ void **buffer
+);
+
+/**
+ * @ingroup RegulatorAPI
+ *
+ * @brief Release Previously Obtained Regulator Buffer
+ *
+ * This function is used to release a buffer to the regulator's pool. It is
+ * assumed that the @a buffer returned will not be used by the application
+ * anymore. The @a buffer must have previously been allocated by
+ * @a rtems_regulator_obtain_buffer() and NOT passed to
+ * @a rtems_regulator_send().
+ *
+ * If a subsequent @a rtems_regulator_send() using this @a buffer is
+ * successful, the @a buffer will eventually be processed by the delivery
+ * thread and released.
+ *
+ * @param[in] regulator is the regulator instance to operate upon
+ * @param[out] buffer will point to the buffer to release
+ *
+ * @return an RTEMS status code indicating success or failure.
+ *
+ * @note This function does not perform dynamic deallocation. It releases a
+ * buffer to the pool allocated during @a rtems_regulator_create().
+ */
+rtems_status_code rtems_regulator_release_buffer(
+ rtems_regulator_instance *regulator,
+ void *buffer
+);
+
+/**
+ * @ingroup RegulatorAPI
+ *
+ * @brief Send to regulator instance
+ *
+ * This function is used by the producer to send a @a message to the
+ * @a regulator for later delivery by the Delivery thread. The message is
+ * contained in the memory pointed to by @a message and is @a length
+ * bytes in length.
+ *
+ * It is required that the @a message buffer was obtained via
+ * @a rtems_regulator_obtain_buffer().
+ *
+ * It is assumed that the @a message buffer has been filled in with
+ * application content to deliver.
+ *
+ * If the @a rtems_regulator_send() is successful, the buffer is enqueued
+ * inside the regulator instance for subsequent delivery. After the
+ * @a message is delivered, it may be released by either delivery
+ * function or the application code depending on the implementation.
+ *
+ * The status @a RTEMS_TOO_MANY is returned if the regulator's
+ * internal queue is full. This indicates that the configured
+ * maximum number of messages was insufficient. It is the
+ * responsibility of the caller to decide whether to hold messages,
+ * drop them, or print a message that the maximum number of messages
+ * should be increased.
+ *
+ * If @a rtems_regulator_send() is unsuccessful, it is the application's
+ * responsibility to release the buffer. If it is successfully sent,
+ * then it becomes the responsibility of the delivery function to
+ * release it.
+ *
+ * @param[in] regulator is the regulator instance to operate upon
+ * @param[out] message points to the message to deliver
+ * @param[out] length is the size of the message in bytes
+ *
+ * @return an RTEMS status code indicating success or failure.
+ *
+ */
+rtems_status_code rtems_regulator_send(
+ rtems_regulator_instance *regulator,
+ void *message,
+ size_t length
+);
+
+/**
+ * @ingroup RegulatorAPI
+ *
+ * @brief Obtain statistics for regulator instance
+ *
+ * This function is used by the application to obtain statistics
+ * information about the regulator instance.
+ *
+ * If the @a obtained and @a released fields in the returned
+ * @a statistics structure are equal, then there are no buffers
+ * outstanding from this regulator instance.
+ *
+ * @param[in] regulator is the regulator instance to operate upon
+ * @param[inout] statistics points to the statistics structure to fill in
+ *
+ * @return an RTEMS status code indicating success or failure.
+ *
+ */
+rtems_status_code rtems_regulator_get_statistics(
+ rtems_regulator_instance *regulator,
+ rtems_regulator_statistics *statistics
+);
+
+#endif /* REGULATOR_H */
diff --git a/cpukit/include/rtems/regulatorimpl.h b/cpukit/include/rtems/regulatorimpl.h
new file mode 100644
index 0000000000..a5652a764d
--- /dev/null
+++ b/cpukit/include/rtems/regulatorimpl.h
@@ -0,0 +1,135 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RegulatorInternalAPI
+ *
+ * @brief Regulator Library Implementation Support
+ */
+
+/*
+ * Copyright (C) 2023 On-Line Applications Research Corporation (OAR)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @defgroup RegulatorInternalAPI Regulator API Internals
+ *
+ * @brief Regulator Internal Information
+ *
+ * This concerns implementation information about the Regulator.
+ */
+
+#ifndef RTEMS_REGULATORIMPL_H
+#define RTEMS_REGULATORIMPL_H
+
+#include <stdatomic.h>
+
+#include <rtems/chain.h>
+
+
+/**
+ * @ingroup RegulatorInternalAPI
+ *
+ * This constant is used to indicate the regulator instance is initialized.
+ */
+#define REGULATOR_INITIALIZED 0xDeadF00d
+
+/**
+ * @ingroup RegulatorInternalAPI
+ *
+ * @brief Regulator Message Instance Management Structure
+ */
+typedef struct {
+ /** This points to the message contents. */
+ void *buffer;
+ /** This is the length of the message. */
+ size_t length;
+} _Regulator_Message_t;
+
+/**
+ * @ingroup RegulatorInternalAPI
+ *
+ * @brief Regulator Statistics Private Structure
+ *
+ * An instance of this structure is allocated per regulator instance.
+ */
+typedef struct {
+ /** Number of successfully obtained buffers. */
+ atomic_size_t obtained;
+
+ /** Number of successfully released buffers. */
+ atomic_size_t released;
+
+ /** Number of successfully delivered buffers. */
+ atomic_size_t delivered;
+} _Regulator_Statistics;
+
+/**
+ * @ingroup RegulatorInternalAPI
+ *
+ * @brief Regulator Instance Private Structure
+ *
+ * An instance of this structure is allocated per regulator instance.
+ */
+typedef struct {
+ /** Has magic value when instance is usable */
+ uint32_t initialized;
+
+ /** Attributes for this instance -- copied from user */
+ rtems_regulator_attributes Attributes;
+
+ /** Pointer to allocated message memory */
+ void *message_memory;
+
+ /** Pointer to allocated memory for RTEMS Message Queue for pending buffers*/
+ void *message_queue_storage;
+
+ /** RTEMS Message Queue of pending outgoing messages */
+ rtems_id queue_id;
+
+ /** RTEMS Partition for pool of unused messages */
+ rtems_id messages_partition_id;
+
+ /** RTEMS Task for performing output */
+ rtems_id delivery_thread_id;
+
+ /** Id of period used by output thread */
+ rtems_id delivery_thread_period_id;
+
+ /** Indicates Delivery thread is running */
+ bool delivery_thread_is_running;
+
+ /** Indicates Delivery thread has been requested to exit */
+ bool delivery_thread_request_exit;
+
+ /** Indicates Delivery thread has exited */
+ bool delivery_thread_has_exited;
+
+ /** Internal Statistics */
+ _Regulator_Statistics Statistics;
+
+} _Regulator_Control;
+
+#endif /* RTEMS_REGULATORIMPL_H */
diff --git a/cpukit/include/rtems/rtems/cache.h b/cpukit/include/rtems/rtems/cache.h
index 20c630a3eb..d59a3fddca 100644
--- a/cpukit/include/rtems/rtems/cache.h
+++ b/cpukit/include/rtems/rtems/cache.h
@@ -59,6 +59,7 @@
#include <stddef.h>
#include <stdint.h>
+#include <rtems/rtems/status.h>
#ifdef __cplusplus
extern "C" {
@@ -89,6 +90,10 @@ extern "C" {
*
* @param size is the size in bytes of the cache coherent memory area to add.
*
+ * @retval ::RTEMS_SUCCESSFUL The requested operation was successful.
+ *
+ * @retval ::RTEMS_UNSATISFIED The requested operation was not successful.
+ *
* @par Constraints
* @parblock
* The following constraints apply to this directive:
@@ -102,7 +107,7 @@ extern "C" {
* cause the calling task to be preempted.
* @endparblock
*/
-void rtems_cache_coherent_add_area( void *begin, uintptr_t size );
+rtems_status_code rtems_cache_coherent_add_area( void *begin, uintptr_t size );
/* Generated from spec:/rtems/cache/if/coherent-allocate */
diff --git a/cpukit/include/rtems/rtems/mainpage.h b/cpukit/include/rtems/rtems/mainpage.h
deleted file mode 100644
index f168cc3395..0000000000
--- a/cpukit/include/rtems/rtems/mainpage.h
+++ /dev/null
@@ -1,951 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/**
- * @file
- *
- * @ingroup RTEMSImplDoxygen
- *
- * @brief This file exists to provide a top level description of RTEMS for
- * Doxygen.
- */
-
-/*
- * COPYRIGHT (c) 1989-2014.
- * On-Line Applications Research Corporation (OAR).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @mainpage
- *
- * The RTEMS real-time operating systems is a layered system with each of the
- * public APIs implemented in terms of a common foundation layer called the
- * SuperCore. This is the Doxygen generated documentation for the RTEMS CPU
- * Kit including the Classic API, POSIX API and SuperCore.
- */
-
-/**
- * @page RTEMSPreface RTEMS History and Introduction
- *
- * In recent years, the cost required to develop a software product has
- * increased significantly while the target hardware costs have decreased. Now
- * a larger portion of money is expended in developing, using, and maintaining
- * software. The trend in computing costs is the complete dominance of software
- * over hardware costs. Because of this, it is necessary that formal
- * disciplines be established to increase the probability that software is
- * characterized by a high degree of correctness, maintainability, and
- * portability. In addition, these disciplines must promote practices that aid
- * in the consistent and orderly development of a software system within
- * schedule and budgetary constraints. To be effective, these disciplines must
- * adopt standards which channel individual software efforts toward a common
- * goal.
- *
- * The push for standards in the software development field has been met with
- * various degrees of success. The Microprocessor Operating Systems Interfaces
- * (MOSI) effort has experienced only limited success. As popular as the UNIX
- * operating system has grown, the attempt to develop a standard interface
- * definition to allow portable application development has only recently begun
- * to produce the results needed in this area. Unfortunately, very little
- * effort has been expended to provide standards addressing the needs of the
- * real-time community. Several organizations have addressed this need during
- * recent years.
- *
- * The Real Time Executive Interface Definition (RTEID) was developed by
- * Motorola with technical input from Software Components Group. RTEID was
- * adopted by the VMEbus International Trade Association (VITA) as a baseline
- * draft for their proposed standard multiprocessor, real-time executive
- * interface, Open Real-Time Kernel Interface Definition (ORKID). These two
- * groups are currently working together with the IEEE P1003.4 committee to
- * insure that the functionality of their proposed standards is adopted as the
- * real-time extensions to POSIX.
- *
- * This emerging standard defines an interface for the development of real-time
- * software to ease the writing of real-time application programs that are
- * directly portable across multiple real-time executive implementations. This
- * interface includes both the source code interfaces and run-time behavior as
- * seen by a real-time application. It does not include the details of how a
- * kernel implements these functions. The standard's goal is to serve as a
- * complete definition of external interfaces so that application code that
- * conforms to these interfaces will execute properly in all real-time
- * executive environments. With the use of a standards compliant executive,
- * routines that acquire memory blocks, create and manage message queues,
- * establish and use semaphores, and send and receive signals need not be
- * redeveloped for a different real-time environment as long as the new
- * environment is compliant with the standard. Software developers need only
- * concentrate on the hardware dependencies of the real-time system.
- * Furthermore, most hardware dependencies for real-time applications can be
- * localized to the device drivers.
- *
- * A compliant executive provides simple and flexible real-time
- * multiprocessing. It easily lends itself to both tightly-coupled and
- * loosely-coupled configurations (depending on the system hardware
- * configuration). Objects such as tasks, queues, events, signals, semaphores,
- * and memory blocks can be designated as global objects and accessed by any
- * task regardless of which processor the object and the accessing task reside.
- *
- * The acceptance of a standard for real-time executives will produce the same
- * advantages enjoyed from the push for UNIX standardization by AT&T's System V
- * Interface Definition and IEEE's POSIX efforts. A compliant multiprocessing
- * executive will allow close coupling between UNIX systems and real-time
- * executives to provide the many benefits of the UNIX development environment
- * to be applied to real-time software development. Together they provide the
- * necessary laboratory environment to implement real-time, distributed,
- * embedded systems using a wide variety of computer architectures.
- *
- * A study was completed in 1988, within the Research, Development, and
- * Engineering Center, U.S. Army Missile Command, which compared the various
- * aspects of the Ada programming language as they related to the application
- * of Ada code in distributed and/or multiple processing systems. Several
- * critical conclusions were derived from the study. These conclusions have a
- * major impact on the way the Army develops application software for embedded
- * applications. These impacts apply to both in-house software development and
- * contractor developed software.
- *
- * A conclusion of the analysis, which has been previously recognized by other
- * agencies attempting to utilize Ada in a distributed or multiprocessing
- * environment, is that the Ada programming language does not adequately
- * support multiprocessing. Ada does provide a mechanism for multi-tasking,
- * however, this capability exists only for a single processor system. The
- * language also does not have inherent capabilities to access global named
- * variables, flags or program code. These critical features are essential in
- * order for data to be shared between processors. However, these drawbacks do
- * have workarounds which are sometimes awkward and defeat the intent of
- * software maintainability and portability goals.
- *
- * Another conclusion drawn from the analysis, was that the run time executives
- * being delivered with the Ada compilers were too slow and inefficient to be
- * used in modern missile systems. A run time executive is the core part of the
- * run time system code, or operating system code, that controls task
- * scheduling, input/output management and memory management. Traditionally,
- * whenever efficient executive (also known as kernel) code was required by the
- * application, the user developed in-house software. This software was usually
- * written in assembly language for optimization.
- *
- * Because of this shortcoming in the Ada programming language, software
- * developers in research and development and contractors for project managed
- * systems, are mandated by technology to purchase and utilize off-the-shelf
- * third party kernel code. The contractor, and eventually the Government, must
- * pay a licensing fee for every copy of the kernel code used in an embedded
- * system.
- *
- * The main drawback to this development environment is that the Government
- * does not own, nor has the right to modify code contained within the kernel.
- * V&V techniques in this situation are more difficult than if the complete
- * source code were available. Responsibility for system failures due to faulty
- * software is yet another area to be resolved under this environment.
- *
- * The Guidance and Control Directorate began a software development effort to
- * address these problems. A project to develop an experimental run time kernel
- * was begun that will eliminate the major drawbacks of the Ada programming
- * language mentioned above. The Real Time Executive for Multiprocessor Systems
- * (RTEMS) provides full capabilities for management of tasks, interrupts,
- * time, and multiple processors in addition to those features typical of
- * generic operating systems. The code is Government owned, so no licensing
- * fees are necessary. RTEMS has been implemented in both the Ada and C
- * programming languages. It has been ported to the following processor
- * families:
- *
- * - Altera NIOS II
- * - Analog Devices Blackfin
- * - ARM
- * - Freescale (formerly Motorola) MC68xxx
- * - Freescale (formerly Motorola) MC683xx
- * - Freescale (formerly Motorola) ColdFire
- * - Intel i386 and above
- * - Lattice Semiconductor LM32
- * - MIPS
- * - PowerPC
- * - Renesas (formerly Hitachi) SuperH
- * - Renesas (formerly Hitachi) H8/300
- * - SPARC
- * - Texas Instruments C3x/C4x
- * - UNIX
- *
- * Support for other processor families, including RISC, CISC, and DSP, is
- * planned. Since almost all of RTEMS is written in a high level language,
- * ports to additional processor families require minimal effort.
- *
- * RTEMS multiprocessor support is capable of handling either homogeneous or
- * heterogeneous systems. The kernel automatically compensates for
- * architectural differences (byte swapping, etc.) between processors. This
- * allows a much easier transition from one processor family to another without
- * a major system redesign.
- *
- * Since the proposed standards are still in draft form, RTEMS cannot and does
- * not claim compliance. However, the status of the standard is being carefully
- * monitored to guarantee that RTEMS provides the functionality specified in
- * the standard. Once approved, RTEMS will be made compliant.
- */
-
-/**
- * @page RTEMSOverview RTEMS Overview
- *
- * @section RTEMSOverviewSecIntroduction Introduction
- *
- * RTEMS, Real-Time Executive for Multiprocessor Systems, is a real-time
- * executive (kernel) which provides a high performance environment for
- * embedded military applications including the following features:
- *
- * - multitasking capabilities
- * - homogeneous and heterogeneous multiprocessor systems
- * - event-driven, priority-based, preemptive scheduling
- * - optional rate monotonic scheduling
- * - intertask communication and synchronization
- * - priority inheritance
- * - responsive interrupt management
- * - dynamic memory allocation
- * - high level of user configurability
- *
- * This manual describes the usage of RTEMS for applications written in the C
- * programming language. Those implementation details that are processor
- * dependent are provided in the Applications Supplement documents. A
- * supplement document which addresses specific architectural issues that
- * affect RTEMS is provided for each processor type that is supported.
- *
- * @section RTEMSOverviewSecRealtimeApplicationSystems Real-time Application Systems
- *
- * Real-time application systems are a special class of computer applications.
- * They have a complex set of characteristics that distinguish them from other
- * software problems. Generally, they must adhere to more rigorous
- * requirements. The correctness of the system depends not only on the results
- * of computations, but also on the time at which the results are produced. The
- * most important and complex characteristic of real-time application systems
- * is that they must receive and respond to a set of external stimuli within
- * rigid and critical time constraints referred to as deadlines. Systems can be
- * buried by an avalanche of interdependent, asynchronous or cyclical event
- * streams.
- *
- * Deadlines can be further characterized as either hard or soft based upon the
- * value of the results when produced after the deadline has passed. A deadline
- * is hard if the results have no value or if their use will result in a
- * catastrophic event. In contrast, results which are produced after a soft
- * deadline may have some value.
- *
- * Another distinguishing requirement of real-time application systems is the
- * ability to coordinate or manage a large number of concurrent activities.
- * Since software is a synchronous entity, this presents special problems. One
- * instruction follows another in a repeating synchronous cycle. Even though
- * mechanisms have been developed to allow for the processing of external
- * asynchronous events, the software design efforts required to process and
- * manage these events and tasks are growing more complicated.
- *
- * The design process is complicated further by spreading this activity over a
- * set of processors instead of a single processor. The challenges associated
- * with designing and building real-time application systems become very
- * complex when multiple processors are involved. New requirements such as
- * interprocessor communication channels and global resources that must be
- * shared between competing processors are introduced. The ramifications of
- * multiple processors complicate each and every characteristic of a real-time
- * system.
- *
- * @section RTEMSOverviewSecRealtimeExecutive Real-time Executive
- *
- * Fortunately, real-time operating systems or real-time executives serve as a
- * cornerstone on which to build the application system. A real-time
- * multitasking executive allows an application to be cast into a set of
- * logical, autonomous processes or tasks which become quite manageable. Each
- * task is internally synchronous, but different tasks execute independently,
- * resulting in an asynchronous processing stream. Tasks can be dynamically
- * paused for many reasons resulting in a different task being allowed to
- * execute for a period of time. The executive also provides an interface to
- * other system components such as interrupt handlers and device drivers.
- * System components may request the executive to allocate and coordinate
- * resources, and to wait for and trigger synchronizing conditions. The
- * executive system calls effectively extend the CPU instruction set to support
- * efficient multitasking. By causing tasks to travel through well-defined
- * state transitions, system calls permit an application to demand-switch
- * between tasks in response to real-time events.
- *
- * By proper grouping of responses to stimuli into separate tasks, a system can
- * now asynchronously switch between independent streams of execution, directly
- * responding to external stimuli as they occur. This allows the system design
- * to meet critical performance specifications which are typically measured by
- * guaranteed response time and transaction throughput. The multiprocessor
- * extensions of RTEMS provide the features necessary to manage the extra
- * requirements introduced by a system distributed across several processors.
- * It removes the physical barriers of processor boundaries from the world of
- * the system designer, enabling more critical aspects of the system to receive
- * the required attention. Such a system, based on an efficient real-time,
- * multiprocessor executive, is a more realistic model of the outside world or
- * environment for which it is designed. As a result, the system will always be
- * more logical, efficient, and reliable.
- *
- * By using the directives provided by RTEMS, the real-time applications
- * developer is freed from the problem of controlling and synchronizing
- * multiple tasks and processors. In addition, one need not develop, test,
- * debug, and document routines to manage memory, pass messages, or provide
- * mutual exclusion. The developer is then able to concentrate solely on the
- * application. By using standard software components, the time and cost
- * required to develop sophisticated real-time applications is significantly
- * reduced.
- *
- * @section RTEMSOverviewSecApplicationArchitecture RTEMS Application Architecture
- *
- * One important design goal of RTEMS was to provide a bridge between two
- * critical layers of typical real-time systems. As shown in the following
- * figure, RTEMS serves as a buffer between the project dependent application
- * code and the target hardware. Most hardware dependencies for real-time
- * applications can be localized to the low level device drivers.
- *
- * @todo Image RTEMS Application Architecture
- *
- * The RTEMS I/O interface manager provides an efficient tool for incorporating
- * these hardware dependencies into the system while simultaneously providing a
- * general mechanism to the application code that accesses them. A well
- * designed real-time system can benefit from this architecture by building a
- * rich library of standard application components which can be used repeatedly
- * in other real-time projects.
- *
- * @section RTEMSOverviewSecInternalArchitecture RTEMS Internal Architecture
- *
- * RTEMS can be viewed as a set of layered components that work in harmony to
- * provide a set of services to a real-time application system. The executive
- * interface presented to the application is formed by grouping directives into
- * logical sets called resource managers. Functions utilized by multiple
- * managers such as scheduling, dispatching, and object management are provided
- * in the executive core. The executive core depends on a small set of CPU
- * dependent routines. Together these components provide a powerful run time
- * environment that promotes the development of efficient real-time application
- * systems. The following figure illustrates this organization:
- *
- * @todo Image RTEMS Architecture
- *
- * Subsequent chapters present a detailed description of the capabilities
- * provided by each of the following RTEMS managers:
- *
- * - initialization
- * - task
- * - interrupt
- * - clock
- * - timer
- * - semaphore
- * - message
- * - event
- * - signal
- * - partition
- * - region
- * - dual ported memory
- * - I/O
- * - fatal error
- * - rate monotonic
- * - user extensions
- * - multiprocessing
- *
- * @section RTEMSOverviewSecUserCustomization User Customization and Extensibility
- *
- * As 32-bit microprocessors have decreased in cost, they have become
- * increasingly common in a variety of embedded systems. A wide range of custom
- * and general-purpose processor boards are based on various 32-bit
- * processors. RTEMS was designed to make no assumptions concerning the
- * characteristics of individual microprocessor families or of specific support
- * hardware. In addition, RTEMS allows the system developer a high degree of
- * freedom in customizing and extending its features.
- *
- * RTEMS assumes the existence of a supported microprocessor and sufficient
- * memory for both RTEMS and the real-time application. Board dependent
- * components such as clocks, interrupt controllers, or I/O devices can be
- * easily integrated with RTEMS. The customization and extensibility features
- * allow RTEMS to efficiently support as many environments as possible.
- *
- * @section RTEMSOverviewSecPortability Portability
- *
- * The issue of portability was the major factor in the creation of RTEMS.
- * Since RTEMS is designed to isolate the hardware dependencies in the specific
- * board support packages, the real-time application should be easily ported to
- * any other processor. The use of RTEMS allows the development of real-time
- * applications which can be completely independent of a particular
- * microprocessor architecture.
- *
- * @section RTEMSOverviewSecMemoryRequirements Memory Requirements
- *
- * Since memory is a critical resource in many real-time embedded systems,
- * RTEMS was specifically designed to automatically leave out all services that
- * are not required from the run-time environment. Features such as networking,
- * various filesystems, and many other features are completely optional. This
- * allows the application designer the flexibility to tailor RTEMS to most
- * efficiently meet system requirements while still satisfying even the most
- * stringent memory constraints. As a result, the size of the RTEMS executive
- * is application dependent.
- *
- * RTEMS requires RAM to manage each instance of an RTEMS object that is
- * created. Thus the more RTEMS objects an application needs, the more memory
- * that must be reserved. See Configuring a System Determining Memory
- * Requirements for more details.
- *
- * @todo Link to Configuring a SystemDetermining Memory Requirements
- *
- * RTEMS utilizes memory for both code and data space. Although RTEMS' data
- * space must be in RAM, its code space can be located in either ROM or RAM.
- *
- * @section RTEMSOverviewSecAudience Audience
- *
- * This manual was written for experienced real-time software developers.
- * Although some background is provided, it is assumed that the reader is
- * familiar with the concepts of task management as well as intertask
- * communication and synchronization. Since directives, user related data
- * structures, and examples are presented in C, a basic understanding of the C
- * programming language is required to fully understand the material presented.
- * However, because of the similarity of the Ada and C RTEMS implementations,
- * users will find that the use and behavior of the two implementations is very
- * similar. A working knowledge of the target processor is helpful in
- * understanding some of RTEMS' features. A thorough understanding of the
- * executive cannot be obtained without studying the entire manual because many
- * of RTEMS' concepts and features are interrelated. Experienced RTEMS users
- * will find that the manual organization facilitates its use as a reference
- * document.
- */
-
-/**
- * @addtogroup RTEMSAPIClassic
- *
- * The facilities provided by RTEMS are built upon a foundation of very
- * powerful concepts. These concepts must be understood before the application
- * developer can efficiently utilize RTEMS. The purpose of this chapter is to
- * familiarize one with these concepts.
- *
- * @section ClassicRTEMSSecObjects Objects
- *
- * RTEMS provides directives which can be used to dynamically create, delete,
- * and manipulate a set of predefined object types. These types include tasks,
- * message queues, semaphores, memory regions, memory partitions, timers,
- * ports, and rate monotonic periods. The object-oriented nature of RTEMS
- * encourages the creation of modular applications built upon re-usable
- * "building block" routines.
- *
- * All objects are created on the local node as required by the application and
- * have an RTEMS assigned ID. All objects have a user-assigned name. Although a
- * relationship exists between an object's name and its RTEMS assigned ID, the
- * name and ID are not identical. Object names are completely arbitrary and
- * selected by the user as a meaningful "tag" which may commonly reflect the
- * object's use in the application. Conversely, object IDs are designed to
- * facilitate efficient object manipulation by the executive.
- *
- * @subsection ClassicRTEMSSubSecObjectNames Object Names
- *
- * An object name is an unsigned 32-bit entity associated with the
- * object by the user. The data type @ref rtems_name is used to store object names.
- *
- * Although not required by RTEMS, object names are often composed of four
- * ASCII characters which help identify that object. For example, a task which
- * causes a light to blink might be called "LITE". The rtems_build_name()
- * routine is provided to build an object name from four ASCII characters. The
- * following example illustrates this:
- *
- * @code
- * rtems_name my_name = rtems_build_name('L', 'I', 'T', 'E');
- * @endcode
- *
- * However, it is not required that the application use ASCII characters to
- * build object names. For example, if an application requires one-hundred
- * tasks, it would be difficult to assign meaningful ASCII names to each task.
- * A more convenient approach would be to name them the binary values one
- * through one-hundred, respectively.
- *
- * RTEMS provides a helper routine, rtems_object_get_name(), which can be used to
- * obtain the name of any RTEMS object using just its ID. This routine attempts
- * to convert the name into a printable string.
- *
- * @subsection ClassicRTEMSSubSecObjectIdentifiers Object Identifiers
- *
- * An object ID is a unique unsigned integer value which uniquely identifies an
- * object instance. Object IDs are passed as arguments to many directives in
- * RTEMS and RTEMS translates the ID to an internal object pointer. The
- * efficient manipulation of object IDs is critical to the performance of RTEMS
- * services. Because of this, there are two object ID formats defined. Each
- * target architecture specifies which format it will use. There is a 32-bit
- * format which is used for most of the supported architectures and supports
- * multiprocessor configurations. There is also a simpler 16-bit format which
- * is appropriate for smaller target architectures and does not support
- * multiprocessor configurations.
- *
- * @subsubsection ClassicRTEMSSubSec32BitObjectIdentifierFormat 32-Bit Object Identifier Format
- *
- * The 32-bit format for an object ID is composed of four parts: API,
- * object class, node, and index. The data type @ref rtems_id is used to store
- * object IDs.
- *
- * <table>
- * <tr>
- * <th>Bits</th>
- * <td>31</td><td>30</td><td>29</td><td>28</td><td>27</td><td>26</td><td>25</td><td>24</td>
- * <td>23</td><td>22</td><td>21</td><td>20</td><td>19</td><td>18</td><td>17</td><td>16</td>
- * <td>15</td><td>14</td><td>13</td><td>12</td><td>11</td><td>10</td><td>09</td><td>08</td>
- * <td>07</td><td>06</td><td>05</td><td>04</td><td>03</td><td>02</td><td>01</td><td>00</td>
- * </tr>
- * <tr>
- * <th>Contents</th>
- * <td colspan=5>Class</td><td colspan=3>API</td><td colspan=8>Node</td><td colspan=16>Object Index</td>
- * </tr>
- * </table>
- *
- * The most significant five bits are the object class. The next three bits
- * indicate the API to which the object class belongs. The next eight bits
- * (16 .. 23) are the number of the node on which this object was created. The
- * node number is always one (1) in a single processor system. The least
- * significant 16-bits form an identifier within a particular object type.
- * This identifier, called the object index, ranges in value from one to the
- * maximum number of objects configured for this object type.
- *
- * @subsubsection ClassicRTEMSSubSec16BitObjectIdentifierFormat 16-Bit Object Identifier Format
- *
- * The 16-bit format for an object ID is composed of three parts: API, object
- * class, and index. The data type @ref rtems_id is used to store object IDs.
- *
- * <table>
- * <tr>
- * <th>Bits</th>
- * <td>15</td><td>14</td><td>13</td><td>12</td><td>11</td><td>10</td><td>09</td><td>08</td>
- * <td>07</td><td>06</td><td>05</td><td>04</td><td>03</td><td>02</td><td>01</td><td>00</td>
- * </tr>
- * <tr>
- * <th>Contents</th>
- * <td colspan=5>Class</td><td colspan=3>API</td><td colspan=8>Object Index</td>
- * </tr>
- * </table>
- *
- * The 16-bit format is designed to be as similar as possible to the 32-bit
- * format. The differences are limited to the elimination of the node field
- * and reduction of the index field from 16-bits to 8-bits. Thus the 16-bit
- * format only supports up to 255 object instances per API/Class combination
- * and single processor systems. As this format is typically utilized by 16-bit
- * processors with limited address space, this is more than enough object
- * instances.
- *
- * @subsection ClassicRTEMSSubSecObjectIdentiferDescription Object Identifer Description
- *
- * The components of an object ID make it possible to quickly locate any object
- * in even the most complicated multiprocessor system. Object ID's are
- * associated with an object by RTEMS when the object is created and the
- * corresponding ID is returned by the appropriate object create directive. The
- * object ID is required as input to all directives involving objects, except
- * those which create an object or obtain the ID of an object.
- *
- * The object identification directives can be used to dynamically obtain a
- * particular object's ID given its name. This mapping is accomplished by
- * searching the name table associated with this object type. If the name is
- * non-unique, then the ID associated with the first occurrence of the name
- * will be returned to the application. Since object IDs are returned when the
- * object is created, the object identification directives are not necessary in
- * a properly designed single processor application.
- *
- * In addition, services are provided to portably examine the subcomponents of
- * an RTEMS ID. These services are described in detail later in this manual but
- * are prototyped as follows:
- *
- * - rtems_object_id_get_api()
- * - rtems_object_id_get_class()
- * - rtems_object_id_get_node()
- * - rtems_object_id_get_index()
- *
- * An object control block is a data structure defined by RTEMS which contains
- * the information necessary to manage a particular object type. For efficiency
- * reasons, the format of each object type's control block is different.
- * However, many of the fields are similar in function. The number of each type
- * of control block is application dependent and determined by the values
- * specified in the user's Configuration Table. An object control block is
- * allocated at object create time and freed when the object is deleted. With
- * the exception of user extension routines, object control blocks are not
- * directly manipulated by user applications.
- *
- * @section ClassicRTEMSSecComSync Communication and Synchronization
- *
- * In real-time multitasking applications, the ability for cooperating
- * execution threads to communicate and synchronize with each other is
- * imperative. A real-time executive should provide an application with the
- * following capabilities
- *
- * - data transfer between cooperating tasks,
- * - data transfer between tasks and ISRs,
- * - synchronization of cooperating tasks, and
- * - synchronization of tasks and ISRs.
- *
- * Most RTEMS managers can be used to provide some form of communication and/or
- * synchronization. However, managers dedicated specifically to communication
- * and synchronization provide well established mechanisms which directly map
- * to the application's varying needs. This level of flexibility allows the
- * application designer to match the features of a particular manager with the
- * complexity of communication and synchronization required. The following
- * managers were specifically designed for communication and synchronization:
- *
- * - @ref ClassicSem
- * - @ref ClassicMessageQueue
- * - @ref ClassicEvent
- * - @ref ClassicSignal
- *
- * The semaphore manager supports mutual exclusion involving the
- * synchronization of access to one or more shared user resources. Binary
- * semaphores may utilize the optional priority inheritance algorithm to avoid
- * the problem of priority inversion. The message manager supports both
- * communication and synchronization, while the event manager primarily
- * provides a high performance synchronization mechanism. The signal manager
- * supports only asynchronous communication and is typically used for exception
- * handling.
- *
- * @section ClassicRTEMSSecTime Time
- *
- * The development of responsive real-time applications requires an
- * understanding of how RTEMS maintains and supports time-related operations.
- * The basic unit of time in RTEMS is known as a tick. The frequency of clock
- * ticks is completely application dependent and determines the granularity and
- * accuracy of all interval and calendar time operations.
- *
- * By tracking time in units of ticks, RTEMS is capable of supporting interval
- * timing functions such as task delays, timeouts, timeslicing, the delayed
- * execution of timer service routines, and the rate monotonic scheduling of
- * tasks. An interval is defined as a number of ticks relative to the current
- * time. For example, when a task delays for an interval of ten ticks, it is
- * implied that the task will not execute until ten clock ticks have occurred.
- * All intervals are specified using data type @ref rtems_interval.
- *
- * A characteristic of interval timing is that the actual interval period may
- * be a fraction of a tick less than the interval requested. This occurs
- * because the time at which the delay timer is set up occurs at some time
- * between two clock ticks. Therefore, the first countdown tick occurs in less
- * than the complete time interval for a tick. This can be a problem if the
- * clock granularity is large.
- *
- * The rate monotonic scheduling algorithm is a hard real-time scheduling
- * methodology. This methodology provides rules which allows one to guarantee
- * that a set of independent periodic tasks will always meet their deadlines --
- * even under transient overload conditions. The rate monotonic manager
- * provides directives built upon the Clock Manager's interval timer support
- * routines.
- *
- * Interval timing is not sufficient for the many applications which require
- * that time be kept in wall time or true calendar form. Consequently, RTEMS
- * maintains the current date and time. This allows selected time operations to
- * be scheduled at an actual calendar date and time. For example, a task could
- * request to delay until midnight on New Year's Eve before lowering the ball
- * at Times Square. The data type @ref rtems_time_of_day is used to specify
- * calendar time in RTEMS services. See Clock Manager Time and Date Data
- * Structures.
- *
- * @todo Link to Clock Manager Time and Date Data Structures
- *
- * Obviously, the directives which use intervals or wall time cannot operate
- * without some external mechanism which provides a periodic clock tick. This
- * clock tick is typically provided by a real time clock or counter/timer
- * device.
- *
- * @section ClassicRTEMSSecMemoryManagement Memory Management
- *
- * RTEMS memory management facilities can be grouped into two classes: dynamic
- * memory allocation and address translation. Dynamic memory allocation is
- * required by applications whose memory requirements vary through the
- * application's course of execution. Address translation is needed by
- * applications which share memory with another CPU or an intelligent
- * Input/Output processor. The following RTEMS managers provide facilities to
- * manage memory:
- *
- * - @ref ClassicRegion
- * - @ref ClassicPart
- * - @ref ClassicDPMEM
- *
- * RTEMS memory management features allow an application to create simple
- * memory pools of fixed size buffers and/or more complex memory pools of
- * variable size segments. The partition manager provides directives to manage
- * and maintain pools of fixed size entities such as resource control blocks.
- * Alternatively, the region manager provides a more general purpose memory
- * allocation scheme that supports variable size blocks of memory which are
- * dynamically obtained and freed by the application. The dual-ported memory
- * manager provides executive support for address translation between internal
- * and external dual-ported RAM address space.
- */
-
-/**
- * @addtogroup RTEMSAPIClassicTasks
- *
- * @section ClassicTasksSecTaskDefinition Task Definition
- *
- * Many definitions of a task have been proposed in computer literature.
- * Unfortunately, none of these definitions encompasses all facets of the
- * concept in a manner which is operating system independent. Several of the
- * more common definitions are provided to enable each user to select a
- * definition which best matches their own experience and understanding of the
- * task concept:
- *
- * - a "dispatchable" unit.
- * - an entity to which the processor is allocated.
- * - an atomic unit of a real-time, multiprocessor system.
- * - single threads of execution which concurrently compete for resources.
- * - a sequence of closely related computations which can execute concurrently
- * with other computational sequences.
- *
- * From RTEMS' perspective, a task is the smallest thread of execution which
- * can compete on its own for system resources. A task is manifested by the
- * existence of a task control block (TCB).
- *
- * @section ClassicTasksSecTaskControlBlock Task Control Block
- *
- * The Task Control Block (TCB) is an RTEMS defined data structure which
- * contains all the information that is pertinent to the execution of a task.
- * During system initialization, RTEMS reserves a TCB for each task configured.
- * A TCB is allocated upon creation of the task and is returned to the TCB free
- * list upon deletion of the task.
- *
- * The TCB's elements are modified as a result of system calls made by the
- * application in response to external and internal stimuli. TCBs are the only
- * RTEMS internal data structure that can be accessed by an application via
- * user extension routines. The TCB contains a task's name, ID, current
- * priority, current and starting states, execution mode, TCB user extension
- * pointer, scheduling control structures, as well as data required by a
- * blocked task.
- *
- * A task's context is stored in the TCB when a task switch occurs. When the
- * task regains control of the processor, its context is restored from the TCB.
- * When a task is restarted, the initial state of the task is restored from the
- * starting context area in the task's TCB.
- *
- * @section ClassicTasksSecTaskStates Task States
- *
- * A task may exist in one of the following five states:
- *
- * - executing - Currently scheduled to the CPU
- * - ready - May be scheduled to the CPU
- * - blocked - Unable to be scheduled to the CPU
- * - dormant - Created task that is not started
- * - non-existent - Uncreated or deleted task
- *
- * An active task may occupy the executing, ready, blocked or dormant state,
- * otherwise the task is considered non-existent. One or more tasks may be
- * active in the system simultaneously. Multiple tasks communicate,
- * synchronize, and compete for system resources with each other via system
- * calls. The multiple tasks appear to execute in parallel, but actually each
- * is dispatched to the CPU for periods of time determined by the RTEMS
- * scheduling algorithm. The scheduling of a task is based on its current state
- * and priority.
- *
- * @section ClassicTasksSecTaskPriority Task Priority
- *
- * A task's priority determines its importance in relation to the other tasks
- * executing on the same processor. RTEMS supports 255 levels of priority
- * ranging from 1 to 255. The data type rtems_task_priority() is used to store
- * task priorities.
- *
- * Tasks of numerically smaller priority values are more important tasks than
- * tasks of numerically larger priority values. For example, a task at priority
- * level 5 is of higher privilege than a task at priority level 10. There is no
- * limit to the number of tasks assigned to the same priority.
- *
- * Each task has a priority associated with it at all times. The initial value
- * of this priority is assigned at task creation time. The priority of a task
- * may be changed at any subsequent time.
- *
- * Priorities are used by the scheduler to determine which ready task will be
- * allowed to execute. In general, the higher the logical priority of a task,
- * the more likely it is to receive processor execution time.
- *
- * @section ClassicTasksSecTaskMode Task Mode
- *
- * A task's execution mode is a combination of the following four components:
- *
- * - preemption
- * - ASR processing
- * - timeslicing
- * - interrupt level
- *
- * It is used to modify RTEMS' scheduling process and to alter the execution
- * environment of the task. The data type rtems_task_mode() is used to manage
- * the task execution mode.
- *
- * The preemption component allows a task to determine when control of the
- * processor is relinquished. If preemption is disabled (@c
- * RTEMS_NO_PREEMPT), the task will retain control of the
- * processor as long as it is in the executing state -- even if a higher
- * priority task is made ready. If preemption is enabled (@c RTEMS_PREEMPT)
- * and a higher priority task is made ready, then the processor will be
- * taken away from the current task immediately and given to the higher
- * priority task.
- *
- * The timeslicing component is used by the RTEMS scheduler to determine how
- * the processor is allocated to tasks of equal priority. If timeslicing is
- * enabled (@c RTEMS_TIMESLICE), then RTEMS will limit the amount of time the
- * task can execute before the processor is allocated to another ready task of
- * equal priority. The length of the timeslice is application dependent and
- * specified in the Configuration Table. If timeslicing is disabled (@c
- * RTEMS_NO_TIMESLICE), then the task will be allowed to
- * execute until a task of higher priority is made ready. If @c
- * RTEMS_NO_PREEMPT is selected, then the timeslicing component is ignored by
- * the scheduler.
- *
- * The asynchronous signal processing component is used to determine when
- * received signals are to be processed by the task. If signal processing is
- * enabled (@c RTEMS_ASR), then signals sent to the task will be processed
- * the next time the task executes. If signal processing is disabled (@c
- * RTEMS_NO_ASR), then all signals received by the task will
- * remain posted until signal processing is enabled. This component affects
- * only tasks which have established a routine to process asynchronous signals.
- *
- * The interrupt level component is used to determine which interrupts will be
- * enabled when the task is executing. @c RTEMS_INTERRUPT_LEVEL(n) specifies
- * that the task will execute at interrupt level n.
- *
- * - @ref RTEMS_PREEMPT - enable preemption (default)
- * - @ref RTEMS_NO_PREEMPT - disable preemption
- * - @ref RTEMS_NO_TIMESLICE - disable timeslicing (default)
- * - @ref RTEMS_TIMESLICE - enable timeslicing
- * - @ref RTEMS_ASR - enable ASR processing (default)
- * - @ref RTEMS_NO_ASR - disable ASR processing
- * - @ref RTEMS_INTERRUPT_LEVEL(0) - enable all interrupts (default)
- * - @ref RTEMS_INTERRUPT_LEVEL(n) - execute at interrupt level n
- *
- * The set of default modes may be selected by specifying the @ref
- * RTEMS_DEFAULT_MODES constant.
- *
- * @section ClassicTasksSecAccessingTaskArguments Accessing Task Arguments
- *
- * All RTEMS tasks are invoked with a single argument which is specified when
- * they are started or restarted. The argument is commonly used to communicate
- * startup information to the task. The simplest manner in which to define a
- * task which accesses it argument is:
- *
- * @code
- * rtems_task user_task(
- * rtems_task_argument argument
- * );
- * @endcode
- *
- * Application tasks requiring more information may view this single argument
- * as an index into an array of parameter blocks.
- *
- * @section ClassicTasksSecFloatingPointConsiderations Floating Point Considerations
- *
- * Creating a task with the @ref RTEMS_FLOATING_POINT attribute flag results in
- * additional memory being allocated for the TCB to store the state of the
- * numeric coprocessor during task switches. This additional memory is NOT
- * allocated for @ref RTEMS_NO_FLOATING_POINT tasks. Saving and restoring the
- * context of a @c RTEMS_FLOATING_POINT task takes longer than that of a @c
- * RTEMS_NO_FLOATING_POINT task because of the relatively large amount of time
- * required for the numeric coprocessor to save or restore its computational
- * state.
- *
- * Since RTEMS was designed specifically for embedded military applications
- * which are floating point intensive, the executive is optimized to avoid
- * unnecessarily saving and restoring the state of the numeric coprocessor. The
- * state of the numeric coprocessor is only saved when a @c
- * RTEMS_FLOATING_POINT task is dispatched and that task was not the last task
- * to utilize the coprocessor. In a system with only one @c
- * RTEMS_FLOATING_POINT task, the state of the numeric coprocessor will never
- * be saved or restored.
- *
- * Although the overhead imposed by @c RTEMS_FLOATING_POINT tasks is minimal,
- * some applications may wish to completely avoid the overhead associated with
- * @c RTEMS_FLOATING_POINT tasks and still utilize a numeric coprocessor. By
- * preventing a task from being preempted while performing a sequence of
- * floating point operations, a @c RTEMS_NO_FLOATING_POINT task can utilize
- * the numeric coprocessor without incurring the overhead of a @c
- * RTEMS_FLOATING_POINT context switch. This approach also avoids the
- * allocation of a floating point context area. However, if this approach is
- * taken by the application designer, NO tasks should be created as @c
- * RTEMS_FLOATING_POINT tasks. Otherwise, the floating point context will not
- * be correctly maintained because RTEMS assumes that the state of the numeric
- * coprocessor will not be altered by @c RTEMS_NO_FLOATING_POINT tasks.
- *
- * If the supported processor type does not have hardware floating capabilities
- * or a standard numeric coprocessor, RTEMS will not provide built-in support
- * for hardware floating point on that processor. In this case, all tasks are
- * considered @c RTEMS_NO_FLOATING_POINT whether created as @c
- * RTEMS_FLOATING_POINT or @c RTEMS_NO_FLOATING_POINT tasks. A floating point
- * emulation software library must be utilized for floating point operations.
- *
- * On some processors, it is possible to disable the floating point unit
- * dynamically. If this capability is supported by the target processor, then
- * RTEMS will utilize this capability to enable the floating point unit only
- * for tasks which are created with the @c RTEMS_FLOATING_POINT attribute.
- * The consequence of a @c RTEMS_NO_FLOATING_POINT task attempting to access
- * the floating point unit is CPU dependent but will generally result in an
- * exception condition.
- *
- * @section ClassicTasksSecPerTaskVariables Per Task Variables
- *
- * Per task variables are no longer available. In particular the
- * rtems_task_variable_add(), rtems_task_variable_get() and
- * rtems_task_variable_delete() functions are neither declared nor defined
- * anymore. Use thread local storage or POSIX Keys instead.
- *
- * @section ClassicTasksSecBuildingTaskAttributeSet Building a Task Attribute Set
- *
- * In general, an attribute set is built by a bitwise OR of the desired
- * components. The set of valid task attribute components is listed below:
- *
- * - @ref RTEMS_NO_FLOATING_POINT - does not use coprocessor (default)
- * - @ref RTEMS_FLOATING_POINT - uses numeric coprocessor
- * - @ref RTEMS_LOCAL - local task (default)
- * - @ref RTEMS_GLOBAL - global task
- *
- * Attribute values are specifically designed to be mutually exclusive,
- * therefore bitwise OR and addition operations are equivalent as long as each
- * attribute appears exactly once in the component list. A component listed as
- * a default is not required to appear in the component list, although it is a
- * good programming practice to specify default components. If all defaults are
- * desired, then @ref RTEMS_DEFAULT_ATTRIBUTES should be used. This example
- * demonstrates the attribute_set parameter needed to create a local task which
- * utilizes the numeric coprocessor. The attribute_set parameter could be @c
- * RTEMS_FLOATING_POINT or @c RTEMS_LOCAL | @c RTEMS_FLOATING_POINT. The
- * attribute_set parameter can be set to @c RTEMS_FLOATING_POINT because @c
- * RTEMS_LOCAL is the default for all created tasks. If the task were global
- * and used the numeric coprocessor, then the attribute_set parameter would be
- * @c RTEMS_GLOBAL | @c RTEMS_FLOATING_POINT.
- *
- * @section ClassicTasksSecBuildingModeAndMask Building a Mode and Mask
- *
- * In general, a mode and its corresponding mask is built by a bitwise OR of
- * the desired components. The set of valid mode constants and each mode's
- * corresponding mask constant is listed below:
- *
- * <table>
- * <tr><th>Mode Constant</th><th>Mask Constant</th><th>Description</th></tr>
- * <tr><td>@ref RTEMS_PREEMPT</td><td>@ref RTEMS_PREEMPT_MASK</td><td>enables preemption</td></tr>
- * <tr><td>@ref RTEMS_NO_PREEMPT</td><td>@ref RTEMS_PREEMPT_MASK</td><td>disables preemption</td></tr>
- * <tr><td>@ref RTEMS_NO_TIMESLICE</td><td>@ref RTEMS_TIMESLICE_MASK</td><td>disables timeslicing</td></tr>
- * <tr><td>@ref RTEMS_TIMESLICE</td><td>@ref RTEMS_TIMESLICE_MASK</td><td>enables timeslicing</td></tr>
- * <tr><td>@ref RTEMS_ASR</td><td>@ref RTEMS_ASR_MASK</td><td>enables ASR processing</td></tr>
- * <tr><td>@ref RTEMS_NO_ASR</td><td>@ref RTEMS_ASR_MASK</td><td>disables ASR processing</td></tr>
- * <tr><td>@ref RTEMS_INTERRUPT_LEVEL(0)</td><td>@ref RTEMS_INTERRUPT_MASK</td><td>enables all interrupts</td></tr>
- * <tr><td>@ref RTEMS_INTERRUPT_LEVEL(n)</td><td>@ref RTEMS_INTERRUPT_MASK</td><td>sets interrupts level n</td></tr>
- * </table>
- *
- * Mode values are specifically designed to be mutually exclusive, therefore
- * bitwise OR and addition operations are equivalent as long as each mode
- * appears exactly once in the component list. A mode component listed as a
- * default is not required to appear in the mode component list, although it is
- * a good programming practice to specify default components. If all defaults
- * are desired, the mode @ref RTEMS_DEFAULT_MODES and the mask @ref
- * RTEMS_ALL_MODE_MASKS should be used.
- *
- * The following example demonstrates the mode and mask parameters used with
- * the rtems_task_mode() directive to place a task at interrupt level 3 and
- * make it non-preemptible. The mode should be set to @c
- * RTEMS_INTERRUPT_LEVEL(3) | @c RTEMS_NO_PREEMPT to indicate the desired
- * preemption mode and interrupt level, while the mask parameter should be set
- * to @c RTEMS_INTERRUPT_MASK | @c RTEMS_PREEMPT_MASK to indicate that
- * the calling task's interrupt level and preemption mode are being altered.
- */
-
- /**
- * @defgroup LocalPackages Local Packages
- *
- * @ingroup RTEMSAPIClassic
- *
- * @brief Local packages.
- */
diff --git a/cpukit/include/rtems/rtems/partdata.h b/cpukit/include/rtems/rtems/partdata.h
index 864c47294e..6df4af81c5 100644
--- a/cpukit/include/rtems/rtems/partdata.h
+++ b/cpukit/include/rtems/rtems/partdata.h
@@ -116,6 +116,8 @@ typedef struct {
extern Objects_Information _Partition_Information;
#if defined(RTEMS_MULTIPROCESSING)
+struct _Thread_Control;
+
/**
* @brief Sends the extract proxy request.
*
@@ -126,8 +128,8 @@ extern Objects_Information _Partition_Information;
* @param id is the partition identifier.
*/
void _Partition_MP_Send_extract_proxy (
- Thread_Control *the_thread,
- Objects_Id id
+ struct _Thread_Control *the_thread,
+ Objects_Id id
);
#endif
diff --git a/cpukit/include/rtems/rtems/tasks.h b/cpukit/include/rtems/rtems/tasks.h
index 45be8a8730..84dd646fe7 100644
--- a/cpukit/include/rtems/rtems/tasks.h
+++ b/cpukit/include/rtems/rtems/tasks.h
@@ -10,7 +10,7 @@
/*
* Copyright (C) 2020, 2021 embedded brains GmbH & Co. KG
- * Copyright (C) 1988, 2017 On-Line Applications Research Corporation (OAR)
+ * Copyright (C) 1988, 2023 On-Line Applications Research Corporation (OAR)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -234,7 +234,7 @@ typedef void rtems_task;
/**
* @ingroup RTEMSAPIClassicTasks
*
- * @brief This type defines the entry point of an RTEMS task.
+ * @brief This type defines the task entry point of an RTEMS task.
*/
typedef rtems_task ( *rtems_task_entry )( rtems_task_argument );
@@ -897,8 +897,8 @@ rtems_id rtems_task_self( void );
*
* This directive readies the task, specified by ``id``, for execution based on
* the priority and execution mode specified when the task was created. The
- * entry point of the task is given in ``entry_point``. The task's entry point
- * argument is contained in ``argument``.
+ * task entry point of the task is given in ``entry_point``. The task's entry
+ * point argument is contained in ``argument``.
*
* @retval ::RTEMS_SUCCESSFUL The requested operation was successful.
*
@@ -1544,15 +1544,16 @@ rtems_status_code rtems_task_mode(
/**
* @ingroup RTEMSAPIClassicTasks
*
- * @brief Wakes up after an interval in clock ticks or yields the processor.
+ * @brief Wakes up after a count of clock ticks have occurred or yields the
+ * processor.
*
- * @param ticks is the interval in clock ticks to delay the task or
+ * @param ticks is the count of clock ticks to delay the task or
* #RTEMS_YIELD_PROCESSOR to yield the processor.
*
- * This directive blocks the calling task for the specified ``ticks`` of clock
- * ticks if the value is not equal to #RTEMS_YIELD_PROCESSOR. When the
- * requested interval has elapsed, the task is made ready. The clock tick
- * directives automatically updates the delay period. The calling task may
+ * This directive blocks the calling task for the specified ``ticks`` count of
+ * clock ticks if the value is not equal to #RTEMS_YIELD_PROCESSOR. When the
+ * requested count of ticks have occurred, the task is made ready. The clock
+ * tick directives automatically update the delay period. The calling task may
* give up the processor and remain in the ready state by specifying a value of
* #RTEMS_YIELD_PROCESSOR in ``ticks``.
*
@@ -1561,7 +1562,11 @@ rtems_status_code rtems_task_mode(
* @par Notes
* Setting the system date and time with the rtems_clock_set() directive and
* similar directives which set CLOCK_REALTIME have no effect on a
- * rtems_task_wake_after() blocked task.
+ * rtems_task_wake_after() blocked task. The delay until first clock tick will
+ * never be a whole clock tick interval since this directive will never execute
+ * exactly on a clock tick. Applications requiring use of a clock
+ * (CLOCK_REALTIME or CLOCK_MONOTONIC) instead of clock ticks should make use
+ * of clock_nanosleep().
*
* @par Constraints
* @parblock
diff --git a/cpukit/include/rtems/rtl/rtl-allocator.h b/cpukit/include/rtems/rtl/rtl-allocator.h
index 8ffaf58c3c..7d291c65f4 100644
--- a/cpukit/include/rtems/rtl/rtl-allocator.h
+++ b/cpukit/include/rtems/rtl/rtl-allocator.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
- * COPYRIGHT (c) 2012, 2018 Chris Johns <chrisj@rtems.org>
+ * COPYRIGHT (c) 2012, 2018, 2023 Chris Johns <chrisj@rtems.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -69,6 +69,7 @@ typedef enum rtems_rtl_alloc_tags rtems_rtl_alloc_tag;
enum rtems_rtl_alloc_cmd {
RTEMS_RTL_ALLOC_NEW, /**< Allocate new memory. */
RTEMS_RTL_ALLOC_DEL, /**< Delete allocated memory. */
+ RTEMS_RTL_ALLOC_RESIZE, /**< Resize allocated memory. */
RTEMS_RTL_ALLOC_LOCK, /**< Lock the allocator. */
RTEMS_RTL_ALLOC_UNLOCK, /**< Unlock the allocator. */
RTEMS_RTL_ALLOC_WR_ENABLE, /**< Enable writes to the memory. */
@@ -143,6 +144,25 @@ void* rtems_rtl_alloc_new (rtems_rtl_alloc_tag tag, size_t size, bool zero);
void rtems_rtl_alloc_del (rtems_rtl_alloc_tag tag, void* address);
/**
+ * The Runtime Loader allocator resize resizes allocated memory.
+ *
+ * This call resizes a previously allocated block of memory. If the
+ * provided address cannot be resized it is deleted and a new block is
+ * allocated and the contents of the existing memory is copied.
+ *
+ *
+ * @param tag The type of allocation request.
+ * @param address The memory address to resize. A NULL is ignored.
+ * @param size The size of the allocation.
+ * @param zero If true the memory is cleared.
+ * @return void* The memory address or NULL is not memory available.
+ */
+void* rtems_rtl_alloc_resize (rtems_rtl_alloc_tag tag,
+ void* address,
+ size_t size,
+ bool zero);
+
+/**
* The Runtime Loader allocator lock. An allocator that depends on a
* separate allocation process, for example the heap, may need to be
* locked during loading of an object file to make sure the locality
@@ -267,6 +287,30 @@ bool rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
void** bss_base, size_t bss_size);
/**
+ * Resize the allocated memory for a module given the new size of the text,
+ * const, data and bss sections. If any part of the allocation fails the
+ * allocated is deleted.
+ *
+ * @param text_base Pointer to the text base pointer.
+ * @param text_size The size of the read/exec section.
+ * @param const_base Pointer to the const base pointer.
+ * @param const_size The size of the read only section.
+ * @param eh_base Pointer to the eh base pointer.
+ * @param eh_size The size of the eh section.
+ * @param data_base Pointer to the data base pointer.
+ * @param data_size The size of the read/write secton.
+ * @param bss_base Pointer to the bss base pointer.
+ * @param bss_size The size of the read/write.
+ * @retval true The memory has been allocated.
+ * @retval false The allocation of memory has failed.
+ */
+bool rtems_rtl_alloc_module_resize (void** text_base, size_t text_size,
+ void** const_base, size_t const_size,
+ void** eh_base, size_t eh_size,
+ void** data_base, size_t data_size,
+ void** bss_base, size_t bss_size);
+
+/**
* Free the memory allocated to a module.
*
* @param text_base Pointer to the text base pointer.
diff --git a/cpukit/include/rtems/rtl/rtl-obj.h b/cpukit/include/rtems/rtl/rtl-obj.h
index 6b47eb1205..3523958bfd 100644
--- a/cpukit/include/rtems/rtl/rtl-obj.h
+++ b/cpukit/include/rtems/rtl/rtl-obj.h
@@ -198,65 +198,66 @@ typedef bool (*rtems_rtl_obj_depends_iterator) (rtems_rtl_obj* obj,
*/
struct rtems_rtl_obj
{
- rtems_chain_node link; /**< The node's link in the chain. */
- uint32_t flags; /**< The status of the object file. */
- size_t users; /**< Users of this object file, number of loads. */
- size_t refs; /**< References to the object file. */
- int format; /**< The format of the object file. */
- const char* fname; /**< The file name for the object. */
- const char* oname; /**< The object file name. Can be
- * relative. */
- const char* aname; /**< The archive name containing the
- * object. NULL means the object is not
- * in a lib */
- off_t ooffset; /**< The object offset in the archive. */
- size_t fsize; /**< Size of the object file. */
- rtems_chain_control sections; /**< The sections of interest in the object
- * file. */
- rtems_chain_control dependents; /**< The dependent object files. */
- rtems_rtl_obj_sym* local_table; /**< Local symbol table. */
- size_t local_syms; /**< Local symbol count. */
- size_t local_size; /**< Local symbol memory usage. */
- rtems_rtl_obj_sym* global_table; /**< Global symbol table. */
- size_t global_syms; /**< Global symbol count. */
- size_t global_size; /**< Global symbol memory usage. */
- size_t unresolved; /**< The number of unresolved relocations. */
- void* text_base; /**< The base address of the text section
- * in memory. */
- size_t text_size; /**< The size of the text section. */
- void* const_base; /**< The base address of the const section
- * in memory. */
- size_t const_size; /**< The size of the const section. */
- void* eh_base; /**< The base address of the eh section in
- * memory. */
- size_t eh_size; /**< The size of the eh section. */
- void* data_base; /**< The base address of the data section
- * in memory. */
- size_t data_size; /**< The size of the data section. */
- void* bss_base; /**< The base address of the bss section in
- * memory. */
- size_t bss_size; /**< The size of the bss section. */
- size_t exec_size; /**< The amount of executable memory
- * allocated */
- void* entry; /**< The entry point of the module. */
- uint32_t checksum; /**< The checksum of the text sections. A
- * zero means do not checksum. */
- uint32_t* sec_num; /**< The sec nums of each obj. */
- uint32_t obj_num; /**< The count of elf files in an rtl
- * obj. */
- void* trampoline; /**< Trampoline memory. Used for fixups or
- * veneers */
- size_t tramp_size; /**< Size of a tramopline slot. */
- size_t tramps_size; /**< Size of the trampoline memory. */
- void* tramp_brk; /**< Trampoline memory allocator. MD
- * relocators can take memory from the
- * break up to the size. */
- size_t tramp_relocs; /**< Number of slots reserved for
- * relocs. The remainder are for
- * unresolved symbols. */
- struct link_map* linkmap; /**< For GDB. */
- void* loader; /**< The file details specific to a
- * loader. */
+ rtems_chain_node link; /**< The node's link in the chain. */
+ uint32_t flags; /**< The status of the object file. */
+ size_t users; /**< Users of this object file, number of loads. */
+ size_t refs; /**< References to the object file. */
+ int format; /**< The format of the object file. */
+ const char* fname; /**< The file name for the object. */
+ const char* oname; /**< The object file name. Can be
+ * relative. */
+ const char* aname; /**< The archive name containing the
+ * object. NULL means the object is not
+ * in a lib */
+ off_t ooffset; /**< The object offset in the archive. */
+ size_t fsize; /**< Size of the object file. */
+ rtems_chain_control sections; /**< The sections of interest in the object
+ * file. */
+ rtems_chain_control dependents; /**< The dependent object files. */
+ rtems_rtl_obj_sym* local_table; /**< Local symbol table. */
+ size_t local_syms; /**< Local symbol count. */
+ size_t local_size; /**< Local symbol memory usage. */
+ rtems_rtl_obj_sym* global_table; /**< Global symbol table. */
+ size_t global_syms; /**< Global symbol count. */
+ size_t global_size; /**< Global symbol memory usage. */
+ size_t unresolved; /**< The number of unresolved relocations. */
+ void* text_base; /**< The base address of the text section
+ * in memory. */
+ size_t text_size; /**< The size of the text section. */
+ void* const_base; /**< The base address of the const section
+ * in memory. */
+ size_t const_size; /**< The size of the const section. */
+ void* eh_base; /**< The base address of the eh section in
+ * memory. */
+ size_t eh_size; /**< The size of the eh section. */
+ void* data_base; /**< The base address of the data section
+ * in memory. */
+ size_t data_size; /**< The size of the data section. */
+ void* bss_base; /**< The base address of the bss section in
+ * memory. */
+ size_t bss_size; /**< The size of the bss section. */
+ size_t exec_size; /**< The amount of executable memory
+ * allocated */
+ void* entry; /**< The entry point of the module. */
+ uint32_t checksum; /**< The checksum of the text sections. A
+ * zero means do not checksum. */
+ uint32_t* sec_num; /**< The sec nums of each obj. */
+ uint32_t obj_num; /**< The count of elf files in an rtl
+ * obj. */
+ void* tramp_base; /**< Trampoline memory. Used for fixups or
+ * veneers */
+ size_t tramp_size; /**< Size of a trampoline memory. */
+ size_t tramp_slots; /**< The number of tampoline slots. */
+ size_t tramp_slot_size; /**< The number of tampoline slots. */
+ void* tramp_brk; /**< Trampoline memory allocator. MD
+ * relocators can take memory from the
+ * break up to the size. */
+ size_t tramp_relocs; /**< Number of slots reserved for
+ * relocs. The remainder are for
+ * unresolved symbols. */
+ struct link_map* linkmap; /**< For GDB. */
+ void* loader; /**< The file details specific to a
+ * loader. */
};
/**
@@ -387,6 +388,17 @@ static inline bool rtems_rtl_obj_has_symbol (const rtems_rtl_obj* obj,
}
/**
+ * Does the object file have any trampolines?
+ *
+ * @param obj The object file's descriptor to check for available space.
+ * @retval bool Returns @true if the object file has trampolines
+ */
+static inline size_t rtems_rtl_obj_has_trampolines (const rtems_rtl_obj* obj)
+{
+ return obj->tramp_slot_size != 0 && obj->tramp_slots != 0;
+}
+
+/**
* Is there space in the trampoline memory for a trapoline.
*
* @param obj The object file's descriptor to check for available space.
@@ -395,7 +407,7 @@ static inline bool rtems_rtl_obj_has_symbol (const rtems_rtl_obj* obj,
*/
static inline size_t rtems_rtl_obj_tramp_avail_space (const rtems_rtl_obj* obj)
{
- return (char*) obj->tramp_brk - (char*) obj->trampoline;
+ return (char*) obj->tramp_brk - (char*) obj->tramp_base;
}
/**
@@ -408,8 +420,8 @@ static inline size_t rtems_rtl_obj_tramp_avail_space (const rtems_rtl_obj* obj)
static inline bool rtems_rtl_obj_has_tramp_space (const rtems_rtl_obj* obj,
const size_t size)
{
- return (obj->trampoline != NULL &&
- (rtems_rtl_obj_tramp_avail_space (obj) + size) <= obj->tramps_size);
+ return (obj->tramp_base != NULL &&
+ (rtems_rtl_obj_tramp_avail_space (obj) + size) <= obj->tramp_size);
}
/**
@@ -420,20 +432,19 @@ static inline bool rtems_rtl_obj_has_tramp_space (const rtems_rtl_obj* obj,
*/
static inline size_t rtems_rtl_obj_trampoline_slots (const rtems_rtl_obj* obj)
{
- return obj->trampoline == NULL || obj->tramp_size == 0 ?
- 0 : obj->tramps_size / obj->tramp_size;
+ return obj->tramp_slots;
}
/**
- * Number of trampolines.
+ * Number of trampoline slot available.
*
* @param obj The object file's descriptor.
- * @retval size_t The number of trampolines.
+ * @retval size_t The number of trampoline slots available.
*/
static inline size_t rtems_rtl_obj_trampolines (const rtems_rtl_obj* obj)
{
- return obj->trampoline == NULL || obj->tramp_size == 0 ?
- 0 : rtems_rtl_obj_tramp_avail_space (obj) / obj->tramp_size;
+ return obj->tramp_base == NULL || obj->tramp_slots == 0 ?
+ 0 : rtems_rtl_obj_tramp_avail_space (obj) / obj->tramp_slot_size;
}
/**
@@ -572,22 +583,6 @@ rtems_rtl_obj_sect* rtems_rtl_obj_find_section_by_mask (const rtems_rtl_obj* obj
uint32_t mask);
/**
- * Allocate a table for trampoline fixup calls.
- *
- * @param obj The object file's descriptor.
- * @retval true The table was allocated.
- * @retval false The alloction failed.
- */
-bool rtems_rtl_obj_alloc_trampoline (rtems_rtl_obj* obj);
-
-/**
- * Erase the object file descriptor's trampoline table..
- *
- * @param obj The object file's descriptor.
- */
-void rtems_rtl_obj_erase_trampoline (rtems_rtl_obj* obj);
-
-/**
* Allocate a table for dependent objects.
*
* @param obj The object file's descriptor.
@@ -750,6 +745,24 @@ size_t rtems_rtl_obj_bss_size (const rtems_rtl_obj* obj);
uint32_t rtems_rtl_obj_bss_alignment (const rtems_rtl_obj* obj);
/**
+ * The trampoline size.
+ *
+ * @param obj The object file's descriptor.
+ * @return size_t The size of the trampoline memory of the object file.
+ */
+size_t rtems_rtl_obj_tramp_size (const rtems_rtl_obj* obj);
+
+/**
+ * The trampolinme alignment for the architecture.
+ *
+ * This is implemented and set in the architecture backend.
+ *
+ * @param obj The object file's descriptor.
+ * @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
+ */
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj);
+
+/**
* Relocate the object file. The object file's section are parsed for any
* relocation type sections.
*
@@ -810,11 +823,19 @@ bool rtems_rtl_obj_load_symbols (rtems_rtl_obj* obj,
* @retval true The object has been sucessfully loaded.
* @retval false The load failed. The RTL error has been set.
*/
-bool
-rtems_rtl_obj_alloc_sections (rtems_rtl_obj* obj,
- int fd,
- rtems_rtl_obj_sect_handler handler,
- void* data);
+bool rtems_rtl_obj_alloc_sections (rtems_rtl_obj* obj,
+ int fd,
+ rtems_rtl_obj_sect_handler handler,
+ void* data);
+
+/**
+ * Resize the sections.
+ *
+ * @param obj The object file's descriptor.
+ * @retval true The object has been sucessfully loaded.
+ * @retval false The load failed. The RTL error has been set.
+ */
+bool rtems_rtl_obj_resize_sections (rtems_rtl_obj* obj);
/**
* Load the sections that have been allocated memory in the target. The bss
diff --git a/cpukit/include/rtems/rtl/rtl-sym.h b/cpukit/include/rtems/rtl/rtl-sym.h
index 0d29a6ae40..3502b303b8 100644
--- a/cpukit/include/rtems/rtl/rtl-sym.h
+++ b/cpukit/include/rtems/rtl/rtl-sym.h
@@ -63,6 +63,22 @@ typedef struct rtems_rtl_symbols
} rtems_rtl_symbols;
/**
+ * A TLS variable offset call. There is one per base image TLS
+ * variable.
+ */
+typedef size_t (*rtems_rtl_tls_offset_func)(void);
+
+/**
+ * A TLS symbol offset entry. It is used with an exported symbol table
+ * to find a TSL table offset for a variable at runtime.
+ */
+typedef struct rtems_rtl_tls_offset
+{
+ size_t index; /** exported symbol table index */
+ rtems_rtl_tls_offset_func offset; /** TLS offset function */
+} rtems_rtl_tls_offset;
+
+/**
* Open a symbol table with the specified number of buckets.
*
* @param symbols The symbol table to open.
@@ -101,10 +117,14 @@ void rtems_rtl_symbol_table_close (rtems_rtl_symbols* symbols);
* @param obj The object table the symbols are for.
* @param esyms The exported symbol table.
* @param size The size of the table in bytes.
+ * @param tls_offsets The TLS offsets table. If NULL none provided.
+ * @param tls_size The number TLS offset entries in the table.
*/
-bool rtems_rtl_symbol_global_add (rtems_rtl_obj* obj,
- const unsigned char* esyms,
- unsigned int size);
+bool rtems_rtl_symbol_global_add (rtems_rtl_obj* obj,
+ const unsigned char* esyms,
+ unsigned int size,
+ rtems_rtl_tls_offset* tls_offsets,
+ unsigned int tls_size);
/**
* Find a symbol given the symbol label in the global symbol table.
diff --git a/cpukit/include/rtems/rtl/rtl.h b/cpukit/include/rtems/rtl/rtl.h
index 0fd4e74cdf..bd3dce588a 100644
--- a/cpukit/include/rtems/rtl/rtl.h
+++ b/cpukit/include/rtems/rtl/rtl.h
@@ -393,9 +393,13 @@ bool rtems_rtl_path_prepend (const char* path);
*
* @param esyms The exported symbol table.
* @param count The size of the exported symbol table.
+ * @param tls_offsets The TLS offsets table. If NULL none provided.
+ * @param tls_size The number TLS offset entries in the table.
*/
-void rtems_rtl_base_sym_global_add (const unsigned char* esyms,
- unsigned int count);
+void rtems_rtl_base_sym_global_add (const unsigned char* esyms,
+ unsigned int count,
+ rtems_rtl_tls_offset* tls_offsets,
+ unsigned int tls_size);
/**
* Return the object file descriptor for the base image. The object file
diff --git a/cpukit/include/rtems/score/atomic.h b/cpukit/include/rtems/score/atomic.h
index 161b0ec03e..9ef1779e60 100644
--- a/cpukit/include/rtems/score/atomic.h
+++ b/cpukit/include/rtems/score/atomic.h
@@ -10,6 +10,7 @@
*/
/*
+ * Copyright (C) 2015 embedded brains GmbH & Co. KG
* COPYRIGHT (c) 2012-2013 Deng Hengyi.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,7 +38,7 @@
#ifndef _RTEMS_SCORE_ATOMIC_H
#define _RTEMS_SCORE_ATOMIC_H
-#include <rtems/score/cpuatomic.h>
+#include <rtems/score/basedefs.h>
/**
* @defgroup RTEMSScoreAtomic Atomic Operations
@@ -54,122 +55,935 @@
* @{
*/
-typedef CPU_atomic_Uint Atomic_Uint;
+#ifdef RTEMS_SMP
+ #if defined(__cplusplus) \
+ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))
+ /*
+ * The GCC 4.9 ships its own <stdatomic.h> which is not C++ compatible. The
+ * suggested solution was to include <atomic> in case C++ is used. This works
+ * at least with GCC 4.9. See also:
+ *
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60932
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60940
+ */
+ #include <atomic>
+ #define _RTEMS_SCORE_ATOMIC_USE_ATOMIC
+ #else
+ #include <stdatomic.h>
+ #define _RTEMS_SCORE_ATOMIC_USE_STDATOMIC
+ #endif
+#else
+ #include <rtems/score/isrlevel.h>
+#endif
-typedef CPU_atomic_Ulong Atomic_Ulong;
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
-typedef CPU_atomic_Uintptr Atomic_Uintptr;
+typedef std::atomic_uint Atomic_Uint;
-typedef CPU_atomic_Flag Atomic_Flag;
+typedef std::atomic_ulong Atomic_Ulong;
-typedef CPU_atomic_Order Atomic_Order;
+typedef std::atomic_uintptr_t Atomic_Uintptr;
-#define ATOMIC_ORDER_RELAXED CPU_ATOMIC_ORDER_RELAXED
+typedef std::atomic_flag Atomic_Flag;
-#define ATOMIC_ORDER_ACQUIRE CPU_ATOMIC_ORDER_ACQUIRE
+typedef std::memory_order Atomic_Order;
-#define ATOMIC_ORDER_RELEASE CPU_ATOMIC_ORDER_RELEASE
+#define ATOMIC_ORDER_RELAXED std::memory_order_relaxed
-#define ATOMIC_ORDER_ACQ_REL CPU_ATOMIC_ORDER_ACQ_REL
+#define ATOMIC_ORDER_ACQUIRE std::memory_order_acquire
-#define ATOMIC_ORDER_SEQ_CST CPU_ATOMIC_ORDER_SEQ_CST
+#define ATOMIC_ORDER_RELEASE std::memory_order_release
-#define ATOMIC_INITIALIZER_UINT( value ) CPU_ATOMIC_INITIALIZER_UINT( value )
+#define ATOMIC_ORDER_ACQ_REL std::memory_order_acq_rel
-#define ATOMIC_INITIALIZER_ULONG( value ) CPU_ATOMIC_INITIALIZER_ULONG( value )
+#define ATOMIC_ORDER_SEQ_CST std::memory_order_seq_cst
-#define ATOMIC_INITIALIZER_UINTPTR( value ) CPU_ATOMIC_INITIALIZER_UINTPTR( value )
+#define ATOMIC_INITIALIZER_UINT( value ) ATOMIC_VAR_INIT( value )
-#define ATOMIC_INITIALIZER_FLAG CPU_ATOMIC_INITIALIZER_FLAG
+#define ATOMIC_INITIALIZER_ULONG( value ) ATOMIC_VAR_INIT( value )
-#define _Atomic_Fence( order ) _CPU_atomic_Fence( order )
+#define ATOMIC_INITIALIZER_UINTPTR( value ) ATOMIC_VAR_INIT( value )
-#define _Atomic_Init_uint( obj, desired ) \
- _CPU_atomic_Init_uint( obj, desired )
+#define ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT
-#define _Atomic_Init_ulong( obj, desired ) \
- _CPU_atomic_Init_ulong( obj, desired )
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
-#define _Atomic_Init_uintptr( obj, desired ) \
- _CPU_atomic_Init_uintptr( obj, desired )
+typedef atomic_uint Atomic_Uint;
-#define _Atomic_Load_uint( obj, order ) \
- _CPU_atomic_Load_uint( obj, order )
+typedef atomic_ulong Atomic_Ulong;
-#define _Atomic_Load_ulong( obj, order ) \
- _CPU_atomic_Load_ulong( obj, order )
+typedef atomic_uintptr_t Atomic_Uintptr;
-#define _Atomic_Load_uintptr( obj, order ) \
- _CPU_atomic_Load_uintptr( obj, order )
+typedef atomic_flag Atomic_Flag;
-#define _Atomic_Store_uint( obj, desr, order ) \
- _CPU_atomic_Store_uint( obj, desr, order )
+typedef memory_order Atomic_Order;
-#define _Atomic_Store_ulong( obj, desr, order ) \
- _CPU_atomic_Store_ulong( obj, desr, order )
+#define ATOMIC_ORDER_RELAXED memory_order_relaxed
-#define _Atomic_Store_uintptr( obj, desr, order ) \
- _CPU_atomic_Store_uintptr( obj, desr, order )
+#define ATOMIC_ORDER_ACQUIRE memory_order_acquire
-#define _Atomic_Fetch_add_uint( obj, arg, order ) \
- _CPU_atomic_Fetch_add_uint( obj, arg, order )
+#define ATOMIC_ORDER_RELEASE memory_order_release
-#define _Atomic_Fetch_add_ulong( obj, arg, order ) \
- _CPU_atomic_Fetch_add_ulong( obj, arg, order )
+#define ATOMIC_ORDER_ACQ_REL memory_order_acq_rel
-#define _Atomic_Fetch_add_uintptr( obj, arg, order ) \
- _CPU_atomic_Fetch_add_uintptr( obj, arg, order )
+#define ATOMIC_ORDER_SEQ_CST memory_order_seq_cst
-#define _Atomic_Fetch_sub_uint( obj, arg, order ) \
- _CPU_atomic_Fetch_sub_uint( obj, arg, order )
+#define ATOMIC_INITIALIZER_UINT( value ) ATOMIC_VAR_INIT( value )
-#define _Atomic_Fetch_sub_ulong( obj, arg, order ) \
- _CPU_atomic_Fetch_sub_ulong( obj, arg, order )
+#define ATOMIC_INITIALIZER_ULONG( value ) ATOMIC_VAR_INIT( value )
-#define _Atomic_Fetch_sub_uintptr( obj, arg, order ) \
- _CPU_atomic_Fetch_sub_uintptr( obj, arg, order )
+#define ATOMIC_INITIALIZER_UINTPTR( value ) ATOMIC_VAR_INIT( value )
-#define _Atomic_Fetch_or_uint( obj, arg, order ) \
- _CPU_atomic_Fetch_or_uint( obj, arg, order )
+#define ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT
-#define _Atomic_Fetch_or_ulong( obj, arg, order ) \
- _CPU_atomic_Fetch_or_ulong( obj, arg, order )
+#else
-#define _Atomic_Fetch_or_uintptr( obj, arg, order ) \
- _CPU_atomic_Fetch_or_uintptr( obj, arg, order )
+typedef unsigned int Atomic_Uint;
-#define _Atomic_Fetch_and_uint( obj, arg, order ) \
- _CPU_atomic_Fetch_and_uint( obj, arg, order )
+typedef unsigned long Atomic_Ulong;
-#define _Atomic_Fetch_and_ulong( obj, arg, order ) \
- _CPU_atomic_Fetch_and_ulong( obj, arg, order )
+typedef uintptr_t Atomic_Uintptr;
-#define _Atomic_Fetch_and_uintptr( obj, arg, order ) \
- _CPU_atomic_Fetch_and_uintptr( obj, arg, order )
+typedef bool Atomic_Flag;
-#define _Atomic_Exchange_uint( obj, desr, order ) \
- _CPU_atomic_Exchange_uint( obj, desr, order )
+typedef int Atomic_Order;
-#define _Atomic_Exchange_ulong( obj, desr, order ) \
- _CPU_atomic_Exchange_ulong( obj, desr, order )
+#define ATOMIC_ORDER_RELAXED 0
-#define _Atomic_Exchange_uintptr( obj, desr, order ) \
- _CPU_atomic_Exchange_uintptr( obj, desr, order )
+#define ATOMIC_ORDER_ACQUIRE 2
-#define _Atomic_Compare_exchange_uint( obj, expected, desired, succ, fail ) \
- _CPU_atomic_Compare_exchange_uint( obj, expected, desired, succ, fail )
+#define ATOMIC_ORDER_RELEASE 3
-#define _Atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail ) \
- _CPU_atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail )
+#define ATOMIC_ORDER_ACQ_REL 4
-#define _Atomic_Compare_exchange_uintptr( obj, expected, desired, succ, fail ) \
- _CPU_atomic_Compare_exchange_uintptr( obj, expected, desired, succ, fail )
+#define ATOMIC_ORDER_SEQ_CST 5
-#define _Atomic_Flag_clear( obj, order ) \
- _CPU_atomic_Flag_clear( obj, order )
+#define ATOMIC_INITIALIZER_UINT( value ) ( value )
-#define _Atomic_Flag_test_and_set( obj, order ) \
- _CPU_atomic_Flag_test_and_set( obj, order )
+#define ATOMIC_INITIALIZER_ULONG( value ) ( value )
+
+#define ATOMIC_INITIALIZER_UINTPTR( value ) ( value )
+
+#define ATOMIC_INITIALIZER_FLAG false
+
+#endif
+
+/**
+ * @brief Sets up a cpu fence.
+ *
+ * @param[out] order The order for the fence.
+ */
+static inline void _Atomic_Fence( Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ std::atomic_thread_fence( order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ atomic_thread_fence( order );
+#else
+ (void) order;
+ RTEMS_COMPILER_MEMORY_BARRIER();
+#endif
+}
+
+/**
+ * @brief Initializes Uint.
+ *
+ * @param[out] obj The CPU atomic Uint to initialize.
+ * @param desired The desired value for @a obj.
+ */
+static inline void _Atomic_Init_uint( Atomic_Uint *obj, unsigned int desired )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ obj->store( desired );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ atomic_init( obj, desired );
+#else
+ *obj = desired;
+#endif
+}
+
+/**
+ * @brief Initializes Ulong.
+ *
+ * @param[out] obj The CPU atomic Ulong to initialize.
+ * @param desired The desired value for @a obj.
+ */
+static inline void _Atomic_Init_ulong( Atomic_Ulong *obj, unsigned long desired )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ obj->store( desired );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ atomic_init( obj, desired );
+#else
+ *obj = desired;
+#endif
+}
+
+/**
+ * @brief Initializes Uintptr.
+ *
+ * @param[out] obj The CPU atomic Uintptr to initialize.
+ * @param desired The desired value for @a obj.
+ */
+static inline void _Atomic_Init_uintptr( Atomic_Uintptr *obj, uintptr_t desired )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ obj->store( desired );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ atomic_init( obj, desired );
+#else
+ *obj = desired;
+#endif
+}
+
+/**
+ * @brief Loads value of Uint considering the order.
+ *
+ * @param obj The CPU atomic Uint to get the value from.
+ * @param order The atomic order for getting the value.
+ *
+ * @return The value of @a obj considering the @a order.
+ */
+static inline unsigned int _Atomic_Load_uint( const Atomic_Uint *obj, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->load( order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_load_explicit( obj, order );
+#else
+ unsigned int val;
+
+ (void) order;
+ val = *obj;
+ RTEMS_COMPILER_MEMORY_BARRIER();
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Loads value of Ulong considering the order.
+ *
+ * @param obj The CPU atomic Ulong to get the value from.
+ * @param order The atomic order for getting the value.
+ *
+ * @return The value of @a obj considering the @a order.
+ */
+static inline unsigned long _Atomic_Load_ulong( const Atomic_Ulong *obj, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->load( order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_load_explicit( obj, order );
+#else
+ unsigned long val;
+
+ (void) order;
+ val = *obj;
+ RTEMS_COMPILER_MEMORY_BARRIER();
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Loads value of Uintptr considering the order.
+ *
+ * @param obj The CPU atomic Uintptr to get the value from.
+ * @param order The atomic order for getting the value.
+ *
+ * @return The value of @a obj considering the @a order.
+ */
+static inline uintptr_t _Atomic_Load_uintptr( const Atomic_Uintptr *obj, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->load( order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_load_explicit( obj, order );
+#else
+ uintptr_t val;
+
+ (void) order;
+ val = *obj;
+ RTEMS_COMPILER_MEMORY_BARRIER();
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Stores a value to Uint considering the order.
+ *
+ * @param[out] obj The CPU atomic Uint to store a value in.
+ * @param desired The desired value for @a obj.
+ * @param order The atomic order for storing the value.
+ */
+static inline void _Atomic_Store_uint( Atomic_Uint *obj, unsigned int desired, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ obj->store( desired, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ atomic_store_explicit( obj, desired, order );
+#else
+ (void) order;
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ *obj = desired;
+#endif
+}
+
+/**
+ * @brief Stores a value to Ulong considering the order.
+ *
+ * @param[out] obj The CPU atomic Ulong to store a value in.
+ * @param desired The desired value for @a obj.
+ * @param order The atomic order for storing the value.
+ */
+static inline void _Atomic_Store_ulong( Atomic_Ulong *obj, unsigned long desired, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ obj->store( desired, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ atomic_store_explicit( obj, desired, order );
+#else
+ (void) order;
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ *obj = desired;
+#endif
+}
+
+/**
+ * @brief Stores a value to Uintptr considering the order.
+ *
+ * @param[out] obj The CPU atomic Uintptr to store a value in.
+ * @param desired The desired value for @a obj.
+ * @param order The atomic order for storing the value.
+ */
+static inline void _Atomic_Store_uintptr( Atomic_Uintptr *obj, uintptr_t desired, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ obj->store( desired, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ atomic_store_explicit( obj, desired, order );
+#else
+ (void) order;
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ *obj = desired;
+#endif
+}
+
+/**
+ * @brief Fetches current value of Uint and adds a value to the stored value.
+ *
+ * @param[in, out] obj The CPU atomic Uint to get the value from and add @a arg to.
+ * @param arg The value to add to @a obj.
+ * @param order The atomic order for the operation.
+ *
+ * @return The value of @a obj prior to the addition of @a arg.
+ */
+static inline unsigned int _Atomic_Fetch_add_uint( Atomic_Uint *obj, unsigned int arg, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->fetch_add( arg, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_fetch_add_explicit( obj, arg, order );
+#else
+ unsigned int val;
+ ISR_Level level;
+
+ (void) order;
+ _ISR_Local_disable( level );
+ val = *obj;
+ *obj = val + arg;
+ _ISR_Local_enable( level );
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Fetches current value of Ulong and adds a value to the stored value.
+ *
+ * @param[in, out] obj The CPU atomic Ulong to get the value from and add @a arg to.
+ * @param arg The value to add to @a obj.
+ * @param order The atomic order for the operation.
+ *
+ * @return The value of @a obj prior to the addition of @a arg.
+ */
+static inline unsigned long _Atomic_Fetch_add_ulong( Atomic_Ulong *obj, unsigned long arg, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->fetch_add( arg, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_fetch_add_explicit( obj, arg, order );
+#else
+ unsigned long val;
+ ISR_Level level;
+
+ (void) order;
+ _ISR_Local_disable( level );
+ val = *obj;
+ *obj = val + arg;
+ _ISR_Local_enable( level );
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Fetches current value of Uintptr and adds a value to the stored value.
+ *
+ * @param[in, out] obj The CPU atomic Uintptr to get the value from and add @a arg to.
+ * @param arg The value to add to @a obj.
+ * @param order The atomic order for the operation.
+ *
+ * @return The value of @a obj prior to the addition of @a arg.
+ */
+static inline uintptr_t _Atomic_Fetch_add_uintptr( Atomic_Uintptr *obj, uintptr_t arg, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->fetch_add( arg, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_fetch_add_explicit( obj, arg, order );
+#else
+ uintptr_t val;
+ ISR_Level level;
+
+ (void) order;
+ _ISR_Local_disable( level );
+ val = *obj;
+ *obj = val + arg;
+ _ISR_Local_enable( level );
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Fetches current value of Uint and subtracts a value from the stored value.
+ *
+ * @param[in, out] obj The CPU atomic Uint to get the value from and subtract @a arg from.
+ * @param arg The value to subtract from @a obj.
+ * @param order The atomic order for the operation.
+ *
+ * @return The value of @a obj prior to the subtraction of @a arg.
+ */
+static inline unsigned int _Atomic_Fetch_sub_uint( Atomic_Uint *obj, unsigned int arg, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->fetch_sub( arg, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_fetch_sub_explicit( obj, arg, order );
+#else
+ unsigned int val;
+ ISR_Level level;
+
+ (void) order;
+ _ISR_Local_disable( level );
+ val = *obj;
+ *obj = val - arg;
+ _ISR_Local_enable( level );
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Fetches current value of Ulong and subtracts a value from the stored value.
+ *
+ * @param[in, out] obj The CPU atomic Ulong to get the value from and subtract @a arg from.
+ * @param arg The value to subtract from @a obj.
+ * @param order The atomic order for the operation.
+ *
+ * @return The value of @a obj prior to the subtraction of @a arg.
+ */
+static inline unsigned long _Atomic_Fetch_sub_ulong( Atomic_Ulong *obj, unsigned long arg, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->fetch_sub( arg, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_fetch_sub_explicit( obj, arg, order );
+#else
+ unsigned long val;
+ ISR_Level level;
+
+ (void) order;
+ _ISR_Local_disable( level );
+ val = *obj;
+ *obj = val - arg;
+ _ISR_Local_enable( level );
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Fetches current value of Uintptr and subtracts a value from the stored value.
+ *
+ * @param[in, out] obj The CPU atomic Uintptr to get the value from and subtract @a arg from.
+ * @param arg The value to subtract from @a obj.
+ * @param order The atomic order for the operation.
+ *
+ * @return The value of @a obj prior to the subtraction of @a arg.
+ */
+static inline uintptr_t _Atomic_Fetch_sub_uintptr( Atomic_Uintptr *obj, uintptr_t arg, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->fetch_sub( arg, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_fetch_sub_explicit( obj, arg, order );
+#else
+ uintptr_t val;
+ ISR_Level level;
+
+ (void) order;
+ _ISR_Local_disable( level );
+ val = *obj;
+ *obj = val - arg;
+ _ISR_Local_enable( level );
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Fetches current value of Uint and ORs a value with the stored value.
+ *
+ * @param[in, out] obj The CPU atomic Uint to get the value from and OR @a arg to.
+ * @param arg The value to OR with @a obj.
+ * @param order The atomic order for the operation.
+ *
+ * @return The value of @a obj prior to the OR operation with @a arg.
+ */
+static inline unsigned int _Atomic_Fetch_or_uint( Atomic_Uint *obj, unsigned int arg, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->fetch_or( arg, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_fetch_or_explicit( obj, arg, order );
+#else
+ unsigned int val;
+ ISR_Level level;
+
+ (void) order;
+ _ISR_Local_disable( level );
+ val = *obj;
+ *obj = val | arg;
+ _ISR_Local_enable( level );
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Fetches current value of Ulong and ORs a value with the stored value.
+ *
+ * @param[in, out] obj The CPU atomic Ulong to get the value from and OR @a arg to.
+ * @param arg The value to OR with @a obj.
+ * @param order The atomic order for the operation.
+ *
+ * @return The value of @a obj prior to the OR operation with @a arg.
+ */
+static inline unsigned long _Atomic_Fetch_or_ulong( Atomic_Ulong *obj, unsigned long arg, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->fetch_or( arg, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_fetch_or_explicit( obj, arg, order );
+#else
+ unsigned long val;
+ ISR_Level level;
+
+ (void) order;
+ _ISR_Local_disable( level );
+ val = *obj;
+ *obj = val | arg;
+ _ISR_Local_enable( level );
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Fetches current value of Uintptr and ORs a value with the stored value.
+ *
+ * @param[in, out] obj The CPU atomic Uintptr to get the value from and OR @a arg to.
+ * @param arg The value to OR with @a obj.
+ * @param order The atomic order for the operation.
+ *
+ * @return The value of @a obj prior to the OR operation with @a arg.
+ */
+static inline uintptr_t _Atomic_Fetch_or_uintptr( Atomic_Uintptr *obj, uintptr_t arg, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->fetch_or( arg, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_fetch_or_explicit( obj, arg, order );
+#else
+ uintptr_t val;
+ ISR_Level level;
+
+ (void) order;
+ _ISR_Local_disable( level );
+ val = *obj;
+ *obj = val | arg;
+ _ISR_Local_enable( level );
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Fetches current value of Uint and ANDs a value with the stored value.
+ *
+ * @param[in, out] obj The CPU atomic Uint to get the value from and AND @a arg to.
+ * @param arg The value to AND with @a obj.
+ * @param order The atomic order for the operation.
+ *
+ * @return The value of @a obj prior to the AND operation with @a arg.
+ */
+static inline unsigned int _Atomic_Fetch_and_uint( Atomic_Uint *obj, unsigned int arg, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->fetch_and( arg, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_fetch_and_explicit( obj, arg, order );
+#else
+ unsigned int val;
+ ISR_Level level;
+
+ (void) order;
+ _ISR_Local_disable( level );
+ val = *obj;
+ *obj = val & arg;
+ _ISR_Local_enable( level );
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Fetches current value of Ulong and ANDs a value with the stored value.
+ *
+ * @param[in, out] obj The CPU atomic Ulong to get the value from and AND @a arg to.
+ * @param arg The value to AND with @a obj.
+ * @param order The atomic order for the operation.
+ *
+ * @return The value of @a obj prior to the AND operation with @a arg.
+ */
+static inline unsigned long _Atomic_Fetch_and_ulong( Atomic_Ulong *obj, unsigned long arg, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->fetch_and( arg, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_fetch_and_explicit( obj, arg, order );
+#else
+ unsigned long val;
+ ISR_Level level;
+
+ (void) order;
+ _ISR_Local_disable( level );
+ val = *obj;
+ *obj = val & arg;
+ _ISR_Local_enable( level );
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Fetches current value of Uintptr and ANDs a value with the stored value.
+ *
+ * @param[in, out] obj The CPU atomic Uintptr to get the value from and AND @a arg to.
+ * @param arg The value to AND with @a obj.
+ * @param order The atomic order for the operation.
+ *
+ * @return The value of @a obj prior to the AND operation with @a arg.
+ */
+static inline uintptr_t _Atomic_Fetch_and_uintptr( Atomic_Uintptr *obj, uintptr_t arg, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->fetch_and( arg, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_fetch_and_explicit( obj, arg, order );
+#else
+ uintptr_t val;
+ ISR_Level level;
+
+ (void) order;
+ _ISR_Local_disable( level );
+ val = *obj;
+ *obj = val & arg;
+ _ISR_Local_enable( level );
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Fetches current value of Uint and sets its value.
+ *
+ * @param[in, out] obj The CPU atomic Uint to get the value from and set the value to @a desired.
+ * @param arg The value to set for @a obj.
+ * @param order The atomic order for the operation.
+ *
+ * @return The value of @a obj prior to the exchange with @a desired.
+ */
+static inline unsigned int _Atomic_Exchange_uint( Atomic_Uint *obj, unsigned int desired, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->exchange( desired, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_exchange_explicit( obj, desired, order );
+#else
+ unsigned int val;
+ ISR_Level level;
+
+ (void) order;
+ _ISR_Local_disable( level );
+ val = *obj;
+ *obj = desired;
+ _ISR_Local_enable( level );
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Fetches current value of Ulong and sets its value.
+ *
+ * @param[in, out] obj The CPU atomic Ulong to get the value from and set the value to @a desired.
+ * @param arg The value to set for @a obj.
+ * @param order The atomic order for the operation.
+ *
+ * @return The value of @a obj prior to the exchange with @a desired.
+ */
+static inline unsigned long _Atomic_Exchange_ulong( Atomic_Ulong *obj, unsigned long desired, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->exchange( desired, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_exchange_explicit( obj, desired, order );
+#else
+ unsigned long val;
+ ISR_Level level;
+
+ (void) order;
+ _ISR_Local_disable( level );
+ val = *obj;
+ *obj = desired;
+ _ISR_Local_enable( level );
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Fetches current value of Uintptr and sets its value.
+ *
+ * @param[in, out] obj The CPU atomic Uintptr to get the value from and set the value to @a desired.
+ * @param arg The value to set for @a obj.
+ * @param order The atomic order for the operation.
+ *
+ * @return The value of @a obj prior to the exchange with @a desired.
+ */
+static inline uintptr_t _Atomic_Exchange_uintptr( Atomic_Uintptr *obj, uintptr_t desired, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->exchange( desired, order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_exchange_explicit( obj, desired, order );
+#else
+ uintptr_t val;
+ ISR_Level level;
+
+ (void) order;
+ _ISR_Local_disable( level );
+ val = *obj;
+ *obj = desired;
+ _ISR_Local_enable( level );
+
+ return val;
+#endif
+}
+
+/**
+ * @brief Checks if value of Uint is as expected.
+ *
+ * This method checks if the value of @a obj is equal to the value of @a expected. If
+ * this is the case, the value of @a obj is changed to @a desired. Otherwise, the value
+ * of @a obj is changed to @a expected.
+ *
+ * @param[in, out] obj The CPU atomic Uint to operate upon.
+ * @param[in, out] expected The expected value of @a obj. If @a obj has a different
+ * value, @a expected is changed to the actual value of @a obj.
+ * @param desired The new value of @a obj if the old value of @a obj was as expected.
+ * @param succ The order if it is successful.
+ * @param fail The order if it fails.
+ *
+ * @retval true The old value of @a obj was as expected.
+ * @retval false The old value of @a obj was not as expected.
+ */
+static inline bool _Atomic_Compare_exchange_uint( Atomic_Uint *obj, unsigned int *expected, unsigned int desired, Atomic_Order succ, Atomic_Order fail )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->compare_exchange_strong( *expected, desired, succ, fail );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail );
+#else
+ bool success;
+ ISR_Level level;
+ unsigned int actual;
+
+ (void) succ;
+ (void) fail;
+ _ISR_Local_disable( level );
+ actual = *obj;
+ success = ( actual == *expected );
+ if ( success ) {
+ *obj = desired;
+ } else {
+ *expected = actual;
+ }
+ _ISR_Local_enable( level );
+
+ return success;
+#endif
+}
+
+/**
+ * @brief Checks if value of Ulong is as expected.
+ *
+ * This method checks if the value of @a obj is equal to the value of @a expected. If
+ * this is the case, the value of @a obj is changed to @a desired. Otherwise, the value
+ * of @a obj is changed to @a expected.
+ *
+ * @param[in, out] obj The CPU atomic Ulong to operate upon.
+ * @param[in, out] expected The expected value of @a obj. If @a obj has a different
+ * value, @a expected is changed to the actual value of @a obj.
+ * @param desired The new value of @a obj if the old value of @a obj was as expected.
+ * @param succ The order if it is successful.
+ * @param fail The order if it fails.
+ *
+ * @retval true The old value of @a obj was as expected.
+ * @retval false The old value of @a obj was not as expected.
+ */
+static inline bool _Atomic_Compare_exchange_ulong( Atomic_Ulong *obj, unsigned long *expected, unsigned long desired, Atomic_Order succ, Atomic_Order fail )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->compare_exchange_strong( *expected, desired, succ, fail );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail );
+#else
+ bool success;
+ ISR_Level level;
+ unsigned long actual;
+
+ (void) succ;
+ (void) fail;
+ _ISR_Local_disable( level );
+ actual = *obj;
+ success = ( actual == *expected );
+ if ( success ) {
+ *obj = desired;
+ } else {
+ *expected = actual;
+ }
+ _ISR_Local_enable( level );
+
+ return success;
+#endif
+}
+
+/**
+ * @brief Checks if value of Uintptr is as expected.
+ *
+ * This method checks if the value of @a obj is equal to the value of @a expected. If
+ * this is the case, the value of @a obj is changed to @a desired. Otherwise, the value
+ * of @a obj is changed to @a expected.
+ *
+ * @param[in, out] obj The CPU atomic Uintptr to operate upon.
+ * @param[in, out] expected The expected value of @a obj. If @a obj has a different
+ * value, @a expected is changed to the actual value of @a obj.
+ * @param desired The new value of @a obj if the old value of @a obj was as expected.
+ * @param succ The order if it is successful.
+ * @param fail The order if it fails.
+ *
+ * @retval true The old value of @a obj was as expected.
+ * @retval false The old value of @a obj was not as expected.
+ */
+static inline bool _Atomic_Compare_exchange_uintptr( Atomic_Uintptr *obj, uintptr_t *expected, uintptr_t desired, Atomic_Order succ, Atomic_Order fail )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->compare_exchange_strong( *expected, desired, succ, fail );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail );
+#else
+ bool success;
+ ISR_Level level;
+ uintptr_t actual;
+
+ (void) succ;
+ (void) fail;
+ _ISR_Local_disable( level );
+ actual = *obj;
+ success = ( actual == *expected );
+ if ( success ) {
+ *obj = desired;
+ } else {
+ *expected = actual;
+ }
+ _ISR_Local_enable( level );
+
+ return success;
+#endif
+}
+
+/**
+ * @brief Clears the atomic flag.
+ *
+ * @param[out] obj The atomic flag to be cleared.
+ * @param order The atomic order for the operation.
+ */
+static inline void _Atomic_Flag_clear( Atomic_Flag *obj, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ obj->clear( order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ atomic_flag_clear_explicit( obj, order );
+#else
+ (void) order;
+ *obj = false;
+#endif
+}
+
+/**
+ * @brief Returns current flag state and sets it.
+ *
+ * @param[in, out] obj The atomic flag to be set.
+ * @param order The atomic order for the operation.
+ *
+ * @retval true @a obj was set prior to this operation.
+ * @retval false @a obj was not set prior to this operation.
+ */
+static inline bool _Atomic_Flag_test_and_set( Atomic_Flag *obj, Atomic_Order order )
+{
+#if defined(_RTEMS_SCORE_ATOMIC_USE_ATOMIC)
+ return obj->test_and_set( order );
+#elif defined(_RTEMS_SCORE_ATOMIC_USE_STDATOMIC)
+ return atomic_flag_test_and_set_explicit( obj, order );
+#else
+ bool flag;
+ ISR_Level level;
+
+ (void) order;
+ _ISR_Local_disable( level );
+ flag = *obj;
+ *obj = true;
+ _ISR_Local_enable( level );
+
+ return flag;
+#endif
+}
/** @} */
diff --git a/cpukit/include/rtems/score/basedefs.h b/cpukit/include/rtems/score/basedefs.h
index 99fda67e8c..010728d795 100644
--- a/cpukit/include/rtems/score/basedefs.h
+++ b/cpukit/include/rtems/score/basedefs.h
@@ -10,7 +10,7 @@
*/
/*
- * Copyright (C) 2014 Paval Pisa
+ * Copyright (C) 2014 Pavel Pisa
* Copyright (C) 2011, 2013 On-Line Applications Research Corporation (OAR)
* Copyright (C) 2009, 2023 embedded brains GmbH & Co. KG
*
@@ -168,9 +168,9 @@ extern "C" {
*
* @return Returns the alignment requirement of the type.
*/
-#if __cplusplus >= 201103L
+#if defined( __cplusplus ) && __cplusplus >= 201103L
#define RTEMS_ALIGNOF( _type_name ) alignof( _type_name )
-#elif __STDC_VERSION__ >= 201112L
+#elif defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 201112L
#define RTEMS_ALIGNOF( _type_name ) _Alignof( _type_name )
#else
#define RTEMS_ALIGNOF( _type_name ) sizeof( _type_name )
@@ -376,9 +376,9 @@ extern "C" {
* @brief Tells the compiler in a function declaration that this function does
* not return.
*/
-#if __cplusplus >= 201103L
+#if defined( __cplusplus ) && __cplusplus >= 201103L
#define RTEMS_NO_RETURN [[noreturn]]
-#elif __STDC_VERSION__ >= 201112L
+#elif defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 201112L
#define RTEMS_NO_RETURN _Noreturn
#elif defined(__GNUC__)
#define RTEMS_NO_RETURN __attribute__(( __noreturn__ ))
@@ -833,9 +833,9 @@ extern "C" {
*
* @param _msg is the error message in case the static assertion fails.
*/
-#if __cplusplus >= 201103L
+#if defined( __cplusplus ) && __cplusplus >= 201103L
#define RTEMS_STATIC_ASSERT( _cond, _msg ) static_assert( _cond, # _msg )
-#elif __STDC_VERSION__ >= 201112L
+#elif defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 201112L
#define RTEMS_STATIC_ASSERT( _cond, _msg ) _Static_assert( _cond, # _msg )
#else
#define RTEMS_STATIC_ASSERT( _cond, _msg ) \
@@ -999,11 +999,12 @@ extern "C" {
*
* @param _value is the value of the symbol. On the value a macro expansion is
* performed and afterwards it is stringified. It shall expand to an integer
- * expression understood by the assembler.
+ * expression understood by the assembler. The value shall be representable
+ * in the code model of the target architecture.
*
* This macro shall be placed at file scope.
*/
-#if defined(__USER_LABEL_PREFIX__)
+#if defined(__GNUC__)
#define RTEMS_DEFINE_GLOBAL_SYMBOL( _name, _value ) \
__asm__( \
"\t.globl " RTEMS_XSTRING( RTEMS_SYMBOL_NAME( _name ) ) \
diff --git a/cpukit/include/rtems/score/cpustdatomic.h b/cpukit/include/rtems/score/cpustdatomic.h
deleted file mode 100644
index f1afa6bec2..0000000000
--- a/cpukit/include/rtems/score/cpustdatomic.h
+++ /dev/null
@@ -1,986 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/**
- * @file
- *
- * @ingroup RTEMSScoreAtomicCPU
- *
- * @brief This header file provides the interfaces of the
- * @ref RTEMSScoreAtomicCPU.
- */
-
-/*
- * COPYRIGHT (c) 2013 Deng Hengyi.
- * Copyright (c) 2015 embedded brains GmbH & Co. KG
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTEMS_SCORE_CPUSTDATOMIC_H
-#define _RTEMS_SCORE_CPUSTDATOMIC_H
-
-#include <rtems/score/basedefs.h>
-
-/**
- * @defgroup RTEMSScoreAtomicCPU C11/C++11 Atomic Operations
- *
- * @ingroup RTEMSScoreAtomic
- *
- * @brief This group contains the atomic operations implementation using
- * functions provided by the C11/C++11.
- *
- * @{
- */
-
-#ifdef RTEMS_SMP
- #if defined(__cplusplus) \
- && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))
- /*
- * The GCC 4.9 ships its own <stdatomic.h> which is not C++ compatible. The
- * suggested solution was to include <atomic> in case C++ is used. This works
- * at least with GCC 4.9. See also:
- *
- * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60932
- * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60940
- */
- #include <atomic>
- #define _RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC
- #else
- #include <stdatomic.h>
- #define _RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC
- #endif
-#else
- #include <rtems/score/isrlevel.h>
-#endif
-
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
-
-typedef std::atomic_uint CPU_atomic_Uint;
-
-typedef std::atomic_ulong CPU_atomic_Ulong;
-
-typedef std::atomic_uintptr_t CPU_atomic_Uintptr;
-
-typedef std::atomic_flag CPU_atomic_Flag;
-
-typedef std::memory_order CPU_atomic_Order;
-
-#define CPU_ATOMIC_ORDER_RELAXED std::memory_order_relaxed
-
-#define CPU_ATOMIC_ORDER_ACQUIRE std::memory_order_acquire
-
-#define CPU_ATOMIC_ORDER_RELEASE std::memory_order_release
-
-#define CPU_ATOMIC_ORDER_ACQ_REL std::memory_order_acq_rel
-
-#define CPU_ATOMIC_ORDER_SEQ_CST std::memory_order_seq_cst
-
-#define CPU_ATOMIC_INITIALIZER_UINT( value ) ATOMIC_VAR_INIT( value )
-
-#define CPU_ATOMIC_INITIALIZER_ULONG( value ) ATOMIC_VAR_INIT( value )
-
-#define CPU_ATOMIC_INITIALIZER_UINTPTR( value ) ATOMIC_VAR_INIT( value )
-
-#define CPU_ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT
-
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
-
-typedef atomic_uint CPU_atomic_Uint;
-
-typedef atomic_ulong CPU_atomic_Ulong;
-
-typedef atomic_uintptr_t CPU_atomic_Uintptr;
-
-typedef atomic_flag CPU_atomic_Flag;
-
-typedef memory_order CPU_atomic_Order;
-
-#define CPU_ATOMIC_ORDER_RELAXED memory_order_relaxed
-
-#define CPU_ATOMIC_ORDER_ACQUIRE memory_order_acquire
-
-#define CPU_ATOMIC_ORDER_RELEASE memory_order_release
-
-#define CPU_ATOMIC_ORDER_ACQ_REL memory_order_acq_rel
-
-#define CPU_ATOMIC_ORDER_SEQ_CST memory_order_seq_cst
-
-#define CPU_ATOMIC_INITIALIZER_UINT( value ) ATOMIC_VAR_INIT( value )
-
-#define CPU_ATOMIC_INITIALIZER_ULONG( value ) ATOMIC_VAR_INIT( value )
-
-#define CPU_ATOMIC_INITIALIZER_UINTPTR( value ) ATOMIC_VAR_INIT( value )
-
-#define CPU_ATOMIC_INITIALIZER_FLAG ATOMIC_FLAG_INIT
-
-#else
-
-typedef unsigned int CPU_atomic_Uint;
-
-typedef unsigned long CPU_atomic_Ulong;
-
-typedef uintptr_t CPU_atomic_Uintptr;
-
-typedef bool CPU_atomic_Flag;
-
-typedef int CPU_atomic_Order;
-
-#define CPU_ATOMIC_ORDER_RELAXED 0
-
-#define CPU_ATOMIC_ORDER_ACQUIRE 2
-
-#define CPU_ATOMIC_ORDER_RELEASE 3
-
-#define CPU_ATOMIC_ORDER_ACQ_REL 4
-
-#define CPU_ATOMIC_ORDER_SEQ_CST 5
-
-#define CPU_ATOMIC_INITIALIZER_UINT( value ) ( value )
-
-#define CPU_ATOMIC_INITIALIZER_ULONG( value ) ( value )
-
-#define CPU_ATOMIC_INITIALIZER_UINTPTR( value ) ( value )
-
-#define CPU_ATOMIC_INITIALIZER_FLAG false
-
-#endif
-
-/**
- * @brief Sets up a cpu fence.
- *
- * @param[out] order The order for the fence.
- */
-static inline void _CPU_atomic_Fence( CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- std::atomic_thread_fence( order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- atomic_thread_fence( order );
-#else
- (void) order;
- RTEMS_COMPILER_MEMORY_BARRIER();
-#endif
-}
-
-/**
- * @brief Initializes Uint.
- *
- * @param[out] obj The CPU atomic Uint to initialize.
- * @param desired The desired value for @a obj.
- */
-static inline void _CPU_atomic_Init_uint( CPU_atomic_Uint *obj, unsigned int desired )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- obj->store( desired );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- atomic_init( obj, desired );
-#else
- *obj = desired;
-#endif
-}
-
-/**
- * @brief Initializes Ulong.
- *
- * @param[out] obj The CPU atomic Ulong to initialize.
- * @param desired The desired value for @a obj.
- */
-static inline void _CPU_atomic_Init_ulong( CPU_atomic_Ulong *obj, unsigned long desired )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- obj->store( desired );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- atomic_init( obj, desired );
-#else
- *obj = desired;
-#endif
-}
-
-/**
- * @brief Initializes Uintptr.
- *
- * @param[out] obj The CPU atomic Uintptr to initialize.
- * @param desired The desired value for @a obj.
- */
-static inline void _CPU_atomic_Init_uintptr( CPU_atomic_Uintptr *obj, uintptr_t desired )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- obj->store( desired );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- atomic_init( obj, desired );
-#else
- *obj = desired;
-#endif
-}
-
-/**
- * @brief Loads value of Uint considering the order.
- *
- * @param obj The CPU atomic Uint to get the value from.
- * @param order The atomic order for getting the value.
- *
- * @return The value of @a obj considering the @a order.
- */
-static inline unsigned int _CPU_atomic_Load_uint( const CPU_atomic_Uint *obj, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->load( order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_load_explicit( obj, order );
-#else
- unsigned int val;
-
- (void) order;
- val = *obj;
- RTEMS_COMPILER_MEMORY_BARRIER();
-
- return val;
-#endif
-}
-
-/**
- * @brief Loads value of Ulong considering the order.
- *
- * @param obj The CPU atomic Ulong to get the value from.
- * @param order The atomic order for getting the value.
- *
- * @return The value of @a obj considering the @a order.
- */
-static inline unsigned long _CPU_atomic_Load_ulong( const CPU_atomic_Ulong *obj, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->load( order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_load_explicit( obj, order );
-#else
- unsigned long val;
-
- (void) order;
- val = *obj;
- RTEMS_COMPILER_MEMORY_BARRIER();
-
- return val;
-#endif
-}
-
-/**
- * @brief Loads value of Uintptr considering the order.
- *
- * @param obj The CPU atomic Uintptr to get the value from.
- * @param order The atomic order for getting the value.
- *
- * @return The value of @a obj considering the @a order.
- */
-static inline uintptr_t _CPU_atomic_Load_uintptr( const CPU_atomic_Uintptr *obj, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->load( order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_load_explicit( obj, order );
-#else
- uintptr_t val;
-
- (void) order;
- val = *obj;
- RTEMS_COMPILER_MEMORY_BARRIER();
-
- return val;
-#endif
-}
-
-/**
- * @brief Stores a value to Uint considering the order.
- *
- * @param[out] obj The CPU atomic Uint to store a value in.
- * @param desired The desired value for @a obj.
- * @param order The atomic order for storing the value.
- */
-static inline void _CPU_atomic_Store_uint( CPU_atomic_Uint *obj, unsigned int desired, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- obj->store( desired, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- atomic_store_explicit( obj, desired, order );
-#else
- (void) order;
- RTEMS_COMPILER_MEMORY_BARRIER();
- *obj = desired;
-#endif
-}
-
-/**
- * @brief Stores a value to Ulong considering the order.
- *
- * @param[out] obj The CPU atomic Ulong to store a value in.
- * @param desired The desired value for @a obj.
- * @param order The atomic order for storing the value.
- */
-static inline void _CPU_atomic_Store_ulong( CPU_atomic_Ulong *obj, unsigned long desired, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- obj->store( desired, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- atomic_store_explicit( obj, desired, order );
-#else
- (void) order;
- RTEMS_COMPILER_MEMORY_BARRIER();
- *obj = desired;
-#endif
-}
-
-/**
- * @brief Stores a value to Uintptr considering the order.
- *
- * @param[out] obj The CPU atomic Uintptr to store a value in.
- * @param desired The desired value for @a obj.
- * @param order The atomic order for storing the value.
- */
-static inline void _CPU_atomic_Store_uintptr( CPU_atomic_Uintptr *obj, uintptr_t desired, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- obj->store( desired, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- atomic_store_explicit( obj, desired, order );
-#else
- (void) order;
- RTEMS_COMPILER_MEMORY_BARRIER();
- *obj = desired;
-#endif
-}
-
-/**
- * @brief Fetches current value of Uint and adds a value to the stored value.
- *
- * @param[in, out] obj The CPU atomic Uint to get the value from and add @a arg to.
- * @param arg The value to add to @a obj.
- * @param order The atomic order for the operation.
- *
- * @return The value of @a obj prior to the addition of @a arg.
- */
-static inline unsigned int _CPU_atomic_Fetch_add_uint( CPU_atomic_Uint *obj, unsigned int arg, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->fetch_add( arg, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_fetch_add_explicit( obj, arg, order );
-#else
- unsigned int val;
- ISR_Level level;
-
- (void) order;
- _ISR_Local_disable( level );
- val = *obj;
- *obj = val + arg;
- _ISR_Local_enable( level );
-
- return val;
-#endif
-}
-
-/**
- * @brief Fetches current value of Ulong and adds a value to the stored value.
- *
- * @param[in, out] obj The CPU atomic Ulong to get the value from and add @a arg to.
- * @param arg The value to add to @a obj.
- * @param order The atomic order for the operation.
- *
- * @return The value of @a obj prior to the addition of @a arg.
- */
-static inline unsigned long _CPU_atomic_Fetch_add_ulong( CPU_atomic_Ulong *obj, unsigned long arg, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->fetch_add( arg, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_fetch_add_explicit( obj, arg, order );
-#else
- unsigned long val;
- ISR_Level level;
-
- (void) order;
- _ISR_Local_disable( level );
- val = *obj;
- *obj = val + arg;
- _ISR_Local_enable( level );
-
- return val;
-#endif
-}
-
-/**
- * @brief Fetches current value of Uintptr and adds a value to the stored value.
- *
- * @param[in, out] obj The CPU atomic Uintptr to get the value from and add @a arg to.
- * @param arg The value to add to @a obj.
- * @param order The atomic order for the operation.
- *
- * @return The value of @a obj prior to the addition of @a arg.
- */
-static inline uintptr_t _CPU_atomic_Fetch_add_uintptr( CPU_atomic_Uintptr *obj, uintptr_t arg, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->fetch_add( arg, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_fetch_add_explicit( obj, arg, order );
-#else
- uintptr_t val;
- ISR_Level level;
-
- (void) order;
- _ISR_Local_disable( level );
- val = *obj;
- *obj = val + arg;
- _ISR_Local_enable( level );
-
- return val;
-#endif
-}
-
-/**
- * @brief Fetches current value of Uint and subtracts a value from the stored value.
- *
- * @param[in, out] obj The CPU atomic Uint to get the value from and subtract @a arg from.
- * @param arg The value to subtract from @a obj.
- * @param order The atomic order for the operation.
- *
- * @return The value of @a obj prior to the subtraction of @a arg.
- */
-static inline unsigned int _CPU_atomic_Fetch_sub_uint( CPU_atomic_Uint *obj, unsigned int arg, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->fetch_sub( arg, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_fetch_sub_explicit( obj, arg, order );
-#else
- unsigned int val;
- ISR_Level level;
-
- (void) order;
- _ISR_Local_disable( level );
- val = *obj;
- *obj = val - arg;
- _ISR_Local_enable( level );
-
- return val;
-#endif
-}
-
-/**
- * @brief Fetches current value of Ulong and subtracts a value from the stored value.
- *
- * @param[in, out] obj The CPU atomic Ulong to get the value from and subtract @a arg from.
- * @param arg The value to subtract from @a obj.
- * @param order The atomic order for the operation.
- *
- * @return The value of @a obj prior to the subtraction of @a arg.
- */
-static inline unsigned long _CPU_atomic_Fetch_sub_ulong( CPU_atomic_Ulong *obj, unsigned long arg, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->fetch_sub( arg, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_fetch_sub_explicit( obj, arg, order );
-#else
- unsigned long val;
- ISR_Level level;
-
- (void) order;
- _ISR_Local_disable( level );
- val = *obj;
- *obj = val - arg;
- _ISR_Local_enable( level );
-
- return val;
-#endif
-}
-
-/**
- * @brief Fetches current value of Uintptr and subtracts a value from the stored value.
- *
- * @param[in, out] obj The CPU atomic Uintptr to get the value from and subtract @a arg from.
- * @param arg The value to subtract from @a obj.
- * @param order The atomic order for the operation.
- *
- * @return The value of @a obj prior to the subtraction of @a arg.
- */
-static inline uintptr_t _CPU_atomic_Fetch_sub_uintptr( CPU_atomic_Uintptr *obj, uintptr_t arg, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->fetch_sub( arg, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_fetch_sub_explicit( obj, arg, order );
-#else
- uintptr_t val;
- ISR_Level level;
-
- (void) order;
- _ISR_Local_disable( level );
- val = *obj;
- *obj = val - arg;
- _ISR_Local_enable( level );
-
- return val;
-#endif
-}
-
-/**
- * @brief Fetches current value of Uint and ORs a value with the stored value.
- *
- * @param[in, out] obj The CPU atomic Uint to get the value from and OR @a arg to.
- * @param arg The value to OR with @a obj.
- * @param order The atomic order for the operation.
- *
- * @return The value of @a obj prior to the OR operation with @a arg.
- */
-static inline unsigned int _CPU_atomic_Fetch_or_uint( CPU_atomic_Uint *obj, unsigned int arg, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->fetch_or( arg, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_fetch_or_explicit( obj, arg, order );
-#else
- unsigned int val;
- ISR_Level level;
-
- (void) order;
- _ISR_Local_disable( level );
- val = *obj;
- *obj = val | arg;
- _ISR_Local_enable( level );
-
- return val;
-#endif
-}
-
-/**
- * @brief Fetches current value of Ulong and ORs a value with the stored value.
- *
- * @param[in, out] obj The CPU atomic Ulong to get the value from and OR @a arg to.
- * @param arg The value to OR with @a obj.
- * @param order The atomic order for the operation.
- *
- * @return The value of @a obj prior to the OR operation with @a arg.
- */
-static inline unsigned long _CPU_atomic_Fetch_or_ulong( CPU_atomic_Ulong *obj, unsigned long arg, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->fetch_or( arg, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_fetch_or_explicit( obj, arg, order );
-#else
- unsigned long val;
- ISR_Level level;
-
- (void) order;
- _ISR_Local_disable( level );
- val = *obj;
- *obj = val | arg;
- _ISR_Local_enable( level );
-
- return val;
-#endif
-}
-
-/**
- * @brief Fetches current value of Uintptr and ORs a value with the stored value.
- *
- * @param[in, out] obj The CPU atomic Uintptr to get the value from and OR @a arg to.
- * @param arg The value to OR with @a obj.
- * @param order The atomic order for the operation.
- *
- * @return The value of @a obj prior to the OR operation with @a arg.
- */
-static inline uintptr_t _CPU_atomic_Fetch_or_uintptr( CPU_atomic_Uintptr *obj, uintptr_t arg, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->fetch_or( arg, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_fetch_or_explicit( obj, arg, order );
-#else
- uintptr_t val;
- ISR_Level level;
-
- (void) order;
- _ISR_Local_disable( level );
- val = *obj;
- *obj = val | arg;
- _ISR_Local_enable( level );
-
- return val;
-#endif
-}
-
-/**
- * @brief Fetches current value of Uint and ANDs a value with the stored value.
- *
- * @param[in, out] obj The CPU atomic Uint to get the value from and AND @a arg to.
- * @param arg The value to AND with @a obj.
- * @param order The atomic order for the operation.
- *
- * @return The value of @a obj prior to the AND operation with @a arg.
- */
-static inline unsigned int _CPU_atomic_Fetch_and_uint( CPU_atomic_Uint *obj, unsigned int arg, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->fetch_and( arg, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_fetch_and_explicit( obj, arg, order );
-#else
- unsigned int val;
- ISR_Level level;
-
- (void) order;
- _ISR_Local_disable( level );
- val = *obj;
- *obj = val & arg;
- _ISR_Local_enable( level );
-
- return val;
-#endif
-}
-
-/**
- * @brief Fetches current value of Ulong and ANDs a value with the stored value.
- *
- * @param[in, out] obj The CPU atomic Ulong to get the value from and AND @a arg to.
- * @param arg The value to AND with @a obj.
- * @param order The atomic order for the operation.
- *
- * @return The value of @a obj prior to the AND operation with @a arg.
- */
-static inline unsigned long _CPU_atomic_Fetch_and_ulong( CPU_atomic_Ulong *obj, unsigned long arg, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->fetch_and( arg, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_fetch_and_explicit( obj, arg, order );
-#else
- unsigned long val;
- ISR_Level level;
-
- (void) order;
- _ISR_Local_disable( level );
- val = *obj;
- *obj = val & arg;
- _ISR_Local_enable( level );
-
- return val;
-#endif
-}
-
-/**
- * @brief Fetches current value of Uintptr and ANDs a value with the stored value.
- *
- * @param[in, out] obj The CPU atomic Uintptr to get the value from and AND @a arg to.
- * @param arg The value to AND with @a obj.
- * @param order The atomic order for the operation.
- *
- * @return The value of @a obj prior to the AND operation with @a arg.
- */
-static inline uintptr_t _CPU_atomic_Fetch_and_uintptr( CPU_atomic_Uintptr *obj, uintptr_t arg, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->fetch_and( arg, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_fetch_and_explicit( obj, arg, order );
-#else
- uintptr_t val;
- ISR_Level level;
-
- (void) order;
- _ISR_Local_disable( level );
- val = *obj;
- *obj = val & arg;
- _ISR_Local_enable( level );
-
- return val;
-#endif
-}
-
-/**
- * @brief Fetches current value of Uint and sets its value.
- *
- * @param[in, out] obj The CPU atomic Uint to get the value from and set the value to @a desired.
- * @param arg The value to set for @a obj.
- * @param order The atomic order for the operation.
- *
- * @return The value of @a obj prior to the exchange with @a desired.
- */
-static inline unsigned int _CPU_atomic_Exchange_uint( CPU_atomic_Uint *obj, unsigned int desired, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->exchange( desired, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_exchange_explicit( obj, desired, order );
-#else
- unsigned int val;
- ISR_Level level;
-
- (void) order;
- _ISR_Local_disable( level );
- val = *obj;
- *obj = desired;
- _ISR_Local_enable( level );
-
- return val;
-#endif
-}
-
-/**
- * @brief Fetches current value of Ulong and sets its value.
- *
- * @param[in, out] obj The CPU atomic Ulong to get the value from and set the value to @a desired.
- * @param arg The value to set for @a obj.
- * @param order The atomic order for the operation.
- *
- * @return The value of @a obj prior to the exchange with @a desired.
- */
-static inline unsigned long _CPU_atomic_Exchange_ulong( CPU_atomic_Ulong *obj, unsigned long desired, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->exchange( desired, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_exchange_explicit( obj, desired, order );
-#else
- unsigned long val;
- ISR_Level level;
-
- (void) order;
- _ISR_Local_disable( level );
- val = *obj;
- *obj = desired;
- _ISR_Local_enable( level );
-
- return val;
-#endif
-}
-
-/**
- * @brief Fetches current value of Uintptr and sets its value.
- *
- * @param[in, out] obj The CPU atomic Uintptr to get the value from and set the value to @a desired.
- * @param arg The value to set for @a obj.
- * @param order The atomic order for the operation.
- *
- * @return The value of @a obj prior to the exchange with @a desired.
- */
-static inline uintptr_t _CPU_atomic_Exchange_uintptr( CPU_atomic_Uintptr *obj, uintptr_t desired, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->exchange( desired, order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_exchange_explicit( obj, desired, order );
-#else
- uintptr_t val;
- ISR_Level level;
-
- (void) order;
- _ISR_Local_disable( level );
- val = *obj;
- *obj = desired;
- _ISR_Local_enable( level );
-
- return val;
-#endif
-}
-
-/**
- * @brief Checks if value of Uint is as expected.
- *
- * This method checks if the value of @a obj is equal to the value of @a expected. If
- * this is the case, the value of @a obj is changed to @a desired. Otherwise, the value
- * of @a obj is changed to @a expected.
- *
- * @param[in, out] obj The CPU atomic Uint to operate upon.
- * @param[in, out] expected The expected value of @a obj. If @a obj has a different
- * value, @a expected is changed to the actual value of @a obj.
- * @param desired The new value of @a obj if the old value of @a obj was as expected.
- * @param succ The order if it is successful.
- * @param fail The order if it fails.
- *
- * @retval true The old value of @a obj was as expected.
- * @retval false The old value of @a obj was not as expected.
- */
-static inline bool _CPU_atomic_Compare_exchange_uint( CPU_atomic_Uint *obj, unsigned int *expected, unsigned int desired, CPU_atomic_Order succ, CPU_atomic_Order fail )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->compare_exchange_strong( *expected, desired, succ, fail );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail );
-#else
- bool success;
- ISR_Level level;
- unsigned int actual;
-
- (void) succ;
- (void) fail;
- _ISR_Local_disable( level );
- actual = *obj;
- success = ( actual == *expected );
- if ( success ) {
- *obj = desired;
- } else {
- *expected = actual;
- }
- _ISR_Local_enable( level );
-
- return success;
-#endif
-}
-
-/**
- * @brief Checks if value of Ulong is as expected.
- *
- * This method checks if the value of @a obj is equal to the value of @a expected. If
- * this is the case, the value of @a obj is changed to @a desired. Otherwise, the value
- * of @a obj is changed to @a expected.
- *
- * @param[in, out] obj The CPU atomic Ulong to operate upon.
- * @param[in, out] expected The expected value of @a obj. If @a obj has a different
- * value, @a expected is changed to the actual value of @a obj.
- * @param desired The new value of @a obj if the old value of @a obj was as expected.
- * @param succ The order if it is successful.
- * @param fail The order if it fails.
- *
- * @retval true The old value of @a obj was as expected.
- * @retval false The old value of @a obj was not as expected.
- */
-static inline bool _CPU_atomic_Compare_exchange_ulong( CPU_atomic_Ulong *obj, unsigned long *expected, unsigned long desired, CPU_atomic_Order succ, CPU_atomic_Order fail )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->compare_exchange_strong( *expected, desired, succ, fail );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail );
-#else
- bool success;
- ISR_Level level;
- unsigned long actual;
-
- (void) succ;
- (void) fail;
- _ISR_Local_disable( level );
- actual = *obj;
- success = ( actual == *expected );
- if ( success ) {
- *obj = desired;
- } else {
- *expected = actual;
- }
- _ISR_Local_enable( level );
-
- return success;
-#endif
-}
-
-/**
- * @brief Checks if value of Uintptr is as expected.
- *
- * This method checks if the value of @a obj is equal to the value of @a expected. If
- * this is the case, the value of @a obj is changed to @a desired. Otherwise, the value
- * of @a obj is changed to @a expected.
- *
- * @param[in, out] obj The CPU atomic Uintptr to operate upon.
- * @param[in, out] expected The expected value of @a obj. If @a obj has a different
- * value, @a expected is changed to the actual value of @a obj.
- * @param desired The new value of @a obj if the old value of @a obj was as expected.
- * @param succ The order if it is successful.
- * @param fail The order if it fails.
- *
- * @retval true The old value of @a obj was as expected.
- * @retval false The old value of @a obj was not as expected.
- */
-static inline bool _CPU_atomic_Compare_exchange_uintptr( CPU_atomic_Uintptr *obj, uintptr_t *expected, uintptr_t desired, CPU_atomic_Order succ, CPU_atomic_Order fail )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->compare_exchange_strong( *expected, desired, succ, fail );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_compare_exchange_strong_explicit( obj, expected, desired, succ, fail );
-#else
- bool success;
- ISR_Level level;
- uintptr_t actual;
-
- (void) succ;
- (void) fail;
- _ISR_Local_disable( level );
- actual = *obj;
- success = ( actual == *expected );
- if ( success ) {
- *obj = desired;
- } else {
- *expected = actual;
- }
- _ISR_Local_enable( level );
-
- return success;
-#endif
-}
-
-/**
- * @brief Clears the atomic flag.
- *
- * @param[out] obj The atomic flag to be cleared.
- * @param order The atomic order for the operation.
- */
-static inline void _CPU_atomic_Flag_clear( CPU_atomic_Flag *obj, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- obj->clear( order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- atomic_flag_clear_explicit( obj, order );
-#else
- (void) order;
- *obj = false;
-#endif
-}
-
-/**
- * @brief Returns current flag state and sets it.
- *
- * @param[in, out] obj The atomic flag to be set.
- * @param order The atomic order for the operation.
- *
- * @retval true @a obj was set prior to this operation.
- * @retval false @a obj was not set prior to this operation.
- */
-static inline bool _CPU_atomic_Flag_test_and_set( CPU_atomic_Flag *obj, CPU_atomic_Order order )
-{
-#if defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_ATOMIC)
- return obj->test_and_set( order );
-#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
- return atomic_flag_test_and_set_explicit( obj, order );
-#else
- bool flag;
- ISR_Level level;
-
- (void) order;
- _ISR_Local_disable( level );
- flag = *obj;
- *obj = true;
- _ISR_Local_enable( level );
-
- return flag;
-#endif
-}
-
-/** @} */
-
-#endif /* _RTEMS_SCORE_CPUSTDATOMIC_H */
diff --git a/cpukit/include/rtems/score/isr.h b/cpukit/include/rtems/score/isr.h
index bb1f3cee50..96ad816245 100644
--- a/cpukit/include/rtems/score/isr.h
+++ b/cpukit/include/rtems/score/isr.h
@@ -98,7 +98,11 @@ extern ISR_Handler_entry _ISR_Vector_table[ CPU_INTERRUPT_NUMBER_OF_VECTORS ];
#endif
/**
- * @brief Global symbol with a value equal to the configure interrupt stack size.
+ * @brief Provides the configured interrupt stack size through an address.
+ *
+ * The address of this global symbol is equal to the configured interrupt stack
+ * size. The address of this symbol has an arbitrary value an may not be
+ * representable in the code model used by the compiler.
*
* This global symbol is defined by the application configuration option
* CONFIGURE_INIT_TASK_STACK_SIZE via <rtems/confdefs.h>.
@@ -106,6 +110,14 @@ extern ISR_Handler_entry _ISR_Vector_table[ CPU_INTERRUPT_NUMBER_OF_VECTORS ];
RTEMS_DECLARE_GLOBAL_SYMBOL( _ISR_Stack_size );
/**
+ * @brief Provides the configured interrupt stack size through an object.
+ *
+ * This object is provided to avoid issues with the _ISR_Stack_size symbol
+ * address and the code model used by the compiler.
+ */
+extern const char * const volatile _ISR_Stack_size_object;
+
+/**
* @brief The interrupt stack area begin.
*
* The interrupt stack area is defined by the application configuration via
diff --git a/cpukit/include/rtems/score/mpci.h b/cpukit/include/rtems/score/mpci.h
index 874c195e95..796c881929 100644
--- a/cpukit/include/rtems/score/mpci.h
+++ b/cpukit/include/rtems/score/mpci.h
@@ -40,9 +40,6 @@
#define _RTEMS_SCORE_MPCI_H
#include <rtems/score/mppkt.h>
-#include <rtems/score/thread.h>
-#include <rtems/score/threadq.h>
-#include <rtems/score/watchdog.h>
#ifdef __cplusplus
extern "C" {
diff --git a/cpukit/include/rtems/score/mpciimpl.h b/cpukit/include/rtems/score/mpciimpl.h
index b646d4be4d..d0c2d0558a 100644
--- a/cpukit/include/rtems/score/mpciimpl.h
+++ b/cpukit/include/rtems/score/mpciimpl.h
@@ -39,6 +39,9 @@
#define _RTEMS_SCORE_MPCIIMPL_H
#include <rtems/score/mpci.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/watchdog.h>
#include <rtems/score/status.h>
#ifdef __cplusplus
diff --git a/cpukit/include/rtems/score/mrspimpl.h b/cpukit/include/rtems/score/mrspimpl.h
index 7a6c86d57c..fd783bf2a0 100644
--- a/cpukit/include/rtems/score/mrspimpl.h
+++ b/cpukit/include/rtems/score/mrspimpl.h
@@ -130,6 +130,7 @@ static inline Priority_Control _MRSP_Get_priority(
uint32_t scheduler_index;
scheduler_index = _Scheduler_Get_index( scheduler );
+ _Assert( scheduler_index < _Scheduler_Count );
return mrsp->ceiling_priorities[ scheduler_index ];
}
@@ -149,6 +150,7 @@ static inline void _MRSP_Set_priority(
uint32_t scheduler_index;
scheduler_index = _Scheduler_Get_index( scheduler );
+ _Assert( scheduler_index < _Scheduler_Count );
mrsp->ceiling_priorities[ scheduler_index ] = new_priority;
}
diff --git a/cpukit/include/rtems/score/processormask.h b/cpukit/include/rtems/score/processormask.h
index ce23f6c10d..71ed37cd0e 100644
--- a/cpukit/include/rtems/score/processormask.h
+++ b/cpukit/include/rtems/score/processormask.h
@@ -39,9 +39,7 @@
#include <rtems/score/cpu.h>
-#include <sys/cpuset.h>
-
-#include <strings.h>
+#include <sys/_bitset.h>
#ifdef __cplusplus
extern "C" {
@@ -123,381 +121,6 @@ extern "C" {
*/
typedef __BITSET_DEFINE( Processor_mask, CPU_MAXIMUM_PROCESSORS ) Processor_mask;
-/**
- * @brief Sets the bits of the mask to zero, also considers CPU_MAXIMUM_PROCESSORS.
- *
- * @param[out] mask The mask to set to zero.
- */
-static inline void _Processor_mask_Zero( Processor_mask *mask )
-{
- __BIT_ZERO( CPU_MAXIMUM_PROCESSORS, mask );
-}
-
-/**
- * @brief Checks if the mask is zero, also considers CPU_MAXIMUM_PROCESSORS.
- *
- * @param mask The mask to check whether is is zero
- *
- * @retval true The mask is zero.
- * @retval false The mask is not zero.
- */
-static inline bool _Processor_mask_Is_zero( const Processor_mask *mask )
-{
- return __BIT_EMPTY( CPU_MAXIMUM_PROCESSORS, mask );
-}
-
-/**
- * @brief Fills the mask, also considers CPU_MAXIMUM_PROCESSORS.
- *
- * @param[out] mask The mask to fill
- */
-static inline void _Processor_mask_Fill( Processor_mask *mask )
-{
- __BIT_FILL( CPU_MAXIMUM_PROCESSORS, mask );
-}
-
-/**
- * @brief Copies the mask to another mask, also considers CPU_MAXIMUM_PROCESSORS.
- *
- * @param[out] dst The mask to copy @a src to.
- * @param src The mask to copy to @a dst.
- */
-static inline void _Processor_mask_Assign(
- Processor_mask *dst, const Processor_mask *src
-)
-{
- __BIT_COPY( CPU_MAXIMUM_PROCESSORS, src, dst );
-}
-
-/**
- * @brief Sets the specified index bit of the mask.
- *
- * @param[out] mask The mask to set the bit of.
- * @param index The index of the bit that shall be set.
- */
-static inline void _Processor_mask_Set(
- Processor_mask *mask,
- uint32_t index
-)
-{
- __BIT_SET( CPU_MAXIMUM_PROCESSORS, index, mask );
-}
-
-/**
- * @brief Clears the specified index bit of the mask.
- *
- * @param[out] mask The mask to clear the bit of.
- * @param index The index of the bit that shall be cleared.
- */
-static inline void _Processor_mask_Clear(
- Processor_mask *mask,
- uint32_t index
-)
-{
- __BIT_CLR( CPU_MAXIMUM_PROCESSORS, index, mask );
-}
-
-/**
- * @brief Checks if the specified index bit of the mask is set.
- *
- * @param mask The mask to check if the specified bit is set.
- * @param index The index of the bit that is checked.
- *
- * @retval true The specified index bit is set.
- * @retval false The specified index bit is not set.
- */
-static inline bool _Processor_mask_Is_set(
- const Processor_mask *mask,
- uint32_t index
-)
-{
- return __BIT_ISSET( CPU_MAXIMUM_PROCESSORS, index, mask );
-}
-
-/**
- * @brief Checks if the processor sets a and b are equal.
- *
- * @param a The first processor set.
- * @param b The seconde processor set.
- *
- * @retval true The processor sets a and b are equal.
- * @retval false The processor sets a and b are not equal.
- */
-static inline bool _Processor_mask_Is_equal(
- const Processor_mask *a,
- const Processor_mask *b
-)
-{
- return !__BIT_CMP( CPU_MAXIMUM_PROCESSORS, a, b );
-}
-
-/**
- * @brief Checks if the intersection of the processor sets a and b is
- * non-empty.
- *
- * @param a The first processor set.
- * @param b The second processor set.
- *
- * @retval true The intersection of the processor sets a and b is non-empty.
- * @retval false The intersection of the processor sets a and b is empty.
- */
-static inline bool _Processor_mask_Has_overlap(
- const Processor_mask *a,
- const Processor_mask *b
-)
-{
- return __BIT_OVERLAP( CPU_MAXIMUM_PROCESSORS, a, b );
-}
-
-/**
- * @brief Checks if the processor set small is a subset of processor set
- * big.
- *
- * @param big The bigger processor set.
- * @param small The smaller processor set.
- *
- * @retval true @a small is a subset of @a big.
- * @retval false @a small is not a subset of @a big.
- */
-static inline bool _Processor_mask_Is_subset(
- const Processor_mask *big,
- const Processor_mask *small
-)
-{
- return __BIT_SUBSET( CPU_MAXIMUM_PROCESSORS, big, small );
-}
-
-/**
- * @brief Performs a bitwise a = b & c.
- *
- * @param[out] a The processor mask that is set by this operation.
- * @param b The first parameter of the AND-operation.
- * @param c The second parameter of the AND-operation.
- */
-static inline void _Processor_mask_And(
- Processor_mask *a,
- const Processor_mask *b,
- const Processor_mask *c
-)
-{
- __BIT_AND2( CPU_MAXIMUM_PROCESSORS, a, b, c );
-}
-
-/**
- * @brief Performs a bitwise a = b | c.
- *
- * @param[out] a The processor mask that is set by this operation.
- * @param b The first parameter of the OR-operation.
- * @param c The second parameter of the OR-operation.
- */
-static inline void _Processor_mask_Or(
- Processor_mask *a,
- const Processor_mask *b,
- const Processor_mask *c
-)
-{
- __BIT_OR2( CPU_MAXIMUM_PROCESSORS, a, b, c );
-}
-
-/**
- * @brief Performs a bitwise a = b ^ c.
- *
- * @param[out] a The processor mask that is set by this operation.
- * @param b The first parameter of the XOR-operation.
- * @param c The second parameter of the XOR-operation.
- */
-static inline void _Processor_mask_Xor(
- Processor_mask *a,
- const Processor_mask *b,
- const Processor_mask *c
-)
-{
- __BIT_XOR2( CPU_MAXIMUM_PROCESSORS, a, b, c );
-}
-
-/**
- * @brief Gets the number of set bits in the processor mask.
- *
- * @param a The processor mask of which the set bits are counted.
- *
- * @return The number of set bits in @a a.
- */
-static inline uint32_t _Processor_mask_Count( const Processor_mask *a )
-{
- return (uint32_t) __BIT_COUNT( CPU_MAXIMUM_PROCESSORS, a );
-}
-
-/**
- * @brief Finds the last set of the processor mask.
- *
- * @param a The processor mask wo find the last set of.
- *
- * @return The last set of @a a.
- */
-static inline uint32_t _Processor_mask_Find_last_set( const Processor_mask *a )
-{
- return (uint32_t) __BIT_FLS( CPU_MAXIMUM_PROCESSORS, a );
-}
-
-/**
- * @brief Returns the subset of 32 processors containing the specified index as
- * an unsigned 32-bit integer.
- *
- * @param mask The processor mask.
- * @param index The specified index.
- *
- * @return The subset containing the specified index as an unsigned 32-bit integer.
- */
-static inline uint32_t _Processor_mask_To_uint32_t(
- const Processor_mask *mask,
- uint32_t index
-)
-{
- long bits = mask->__bits[ index / _BITSET_BITS ];
-
- return (uint32_t) ( bits >> ( 32 * ( ( index % _BITSET_BITS ) / 32 ) ) );
-}
-
-/**
- * @brief Creates a processor set from an unsigned 32-bit integer relative to
- * the specified index.
- *
- * @param[out] mask The mask that is created.
- * @param bits The bits for creating the mask.
- * @param index The index to which the mask is relative.
- */
-static inline void _Processor_mask_From_uint32_t(
- Processor_mask *mask,
- uint32_t bits,
- uint32_t index
-)
-{
- _Processor_mask_Zero( mask );
- mask->__bits[ __bitset_words( index ) ] = ((long) bits) << (32 * (index % _BITSET_BITS) / 32);
-}
-
-/**
- * @brief Creates a processor set from the specified index.
- *
- * @param[out] The mask that is created.
- * @param index The specified index.
- */
-static inline void _Processor_mask_From_index(
- Processor_mask *mask,
- uint32_t index
-)
-{
- __BIT_SETOF( CPU_MAXIMUM_PROCESSORS, (int) index, mask );
-}
-
-typedef enum {
- PROCESSOR_MASK_COPY_LOSSLESS,
- PROCESSOR_MASK_COPY_PARTIAL_LOSS,
- PROCESSOR_MASK_COPY_COMPLETE_LOSS,
- PROCESSOR_MASK_COPY_INVALID_SIZE
-} Processor_mask_Copy_status;
-
-/**
- * @brief Checks if the copy status guarantees at most partial loss.
- *
- * @param status The copy status to check.
- *
- * @retval true At most partial loss can be guaranteed.
- * @retval false The status indicates more than partial loss.
- */
-static inline bool _Processor_mask_Is_at_most_partial_loss(
- Processor_mask_Copy_status status
-)
-{
- return (unsigned int) status <= PROCESSOR_MASK_COPY_PARTIAL_LOSS;
-}
-
-/**
- * @brief Copies one mask to another.
- *
- * @param[out] dst The destination of the copy operation.
- * @param dst_size The size of @a dst.
- * @param src The source of the copy operation.
- * @param src_size The size of @a src.
- *
- * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy
- * operation is lossless.
- * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due
- * to the sizes of @a src and @a dst.
- * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due
- * to the sizes of @a src and @a dst.
- * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes
- * is invalid (bigger than the size of a long).
- */
-Processor_mask_Copy_status _Processor_mask_Copy(
- long *dst,
- size_t dst_size,
- const long *src,
- size_t src_size
-);
-
-/**
- * @brief Copies one mask to another.
- *
- * @param src The source for the copy operation.
- * @param dst_size The size of @a dst.
- * @param[out] dst The destination for the copy operation.
- *
- * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy
- * operation is lossless.
- * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due
- * to the sizes of @a src and @a dst.
- * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due
- * to the sizes of @a src and @a dst.
- * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes
- * is invalid (bigger than the size of a long).
- */
-static inline Processor_mask_Copy_status _Processor_mask_To_cpu_set_t(
- const Processor_mask *src,
- size_t dst_size,
- cpu_set_t *dst
-)
-{
- return _Processor_mask_Copy(
- &dst->__bits[ 0 ],
- dst_size,
- &src->__bits[ 0 ],
- sizeof( *src )
- );
-}
-
-/**
- * @brief Copies one mask to another.
- *
- * @param src The source for the copy operation.
- * @param src_size The size of @a src.
- * @param[out] dst The destination for the copy operation.
- *
- * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy
- * operation is lossless.
- * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due
- * to the sizes of @a src and @a dst.
- * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due
- * to the sizes of @a src and @a dst.
- * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes
- * is invalid (bigger than the size of a long).
- */
-static inline Processor_mask_Copy_status _Processor_mask_From_cpu_set_t(
- Processor_mask *dst,
- size_t src_size,
- const cpu_set_t *src
-)
-{
- return _Processor_mask_Copy(
- &dst->__bits[ 0 ],
- sizeof( *dst ),
- &src->__bits[ 0 ],
- src_size
- );
-}
-
-extern const Processor_mask _Processor_mask_The_one_and_only;
-
/** @} */
#ifdef __cplusplus
diff --git a/cpukit/include/rtems/score/processormaskimpl.h b/cpukit/include/rtems/score/processormaskimpl.h
new file mode 100644
index 0000000000..bc997edfd4
--- /dev/null
+++ b/cpukit/include/rtems/score/processormaskimpl.h
@@ -0,0 +1,437 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreProcessorMask
+ *
+ * @brief This header file provides the interfaces of the
+ * @ref RTEMSScoreProcessorMask.
+ */
+
+/*
+ * Copyright (C) 2016, 2017 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTEMS_SCORE_PROCESSORMASKIMPL_H
+#define _RTEMS_SCORE_PROCESSORMASKIMPL_H
+
+#include <rtems/score/processormask.h>
+
+#include <sys/cpuset.h>
+
+#include <strings.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @addtogroup RTEMSScoreProcessorMask
+ *
+ * @{
+ */
+
+/**
+ * @brief Sets the bits of the mask to zero, also considers CPU_MAXIMUM_PROCESSORS.
+ *
+ * @param[out] mask The mask to set to zero.
+ */
+static inline void _Processor_mask_Zero( Processor_mask *mask )
+{
+ __BIT_ZERO( CPU_MAXIMUM_PROCESSORS, mask );
+}
+
+/**
+ * @brief Checks if the mask is zero, also considers CPU_MAXIMUM_PROCESSORS.
+ *
+ * @param mask The mask to check whether is is zero
+ *
+ * @retval true The mask is zero.
+ * @retval false The mask is not zero.
+ */
+static inline bool _Processor_mask_Is_zero( const Processor_mask *mask )
+{
+ return __BIT_EMPTY( CPU_MAXIMUM_PROCESSORS, mask );
+}
+
+/**
+ * @brief Fills the mask, also considers CPU_MAXIMUM_PROCESSORS.
+ *
+ * @param[out] mask The mask to fill
+ */
+static inline void _Processor_mask_Fill( Processor_mask *mask )
+{
+ __BIT_FILL( CPU_MAXIMUM_PROCESSORS, mask );
+}
+
+/**
+ * @brief Copies the mask to another mask, also considers CPU_MAXIMUM_PROCESSORS.
+ *
+ * @param[out] dst The mask to copy @a src to.
+ * @param src The mask to copy to @a dst.
+ */
+static inline void _Processor_mask_Assign(
+ Processor_mask *dst, const Processor_mask *src
+)
+{
+ __BIT_COPY( CPU_MAXIMUM_PROCESSORS, src, dst );
+}
+
+/**
+ * @brief Sets the specified index bit of the mask.
+ *
+ * @param[out] mask The mask to set the bit of.
+ * @param index The index of the bit that shall be set.
+ */
+static inline void _Processor_mask_Set(
+ Processor_mask *mask,
+ uint32_t index
+)
+{
+ __BIT_SET( CPU_MAXIMUM_PROCESSORS, index, mask );
+}
+
+/**
+ * @brief Clears the specified index bit of the mask.
+ *
+ * @param[out] mask The mask to clear the bit of.
+ * @param index The index of the bit that shall be cleared.
+ */
+static inline void _Processor_mask_Clear(
+ Processor_mask *mask,
+ uint32_t index
+)
+{
+ __BIT_CLR( CPU_MAXIMUM_PROCESSORS, index, mask );
+}
+
+/**
+ * @brief Checks if the specified index bit of the mask is set.
+ *
+ * @param mask The mask to check if the specified bit is set.
+ * @param index The index of the bit that is checked.
+ *
+ * @retval true The specified index bit is set.
+ * @retval false The specified index bit is not set.
+ */
+static inline bool _Processor_mask_Is_set(
+ const Processor_mask *mask,
+ uint32_t index
+)
+{
+ return __BIT_ISSET( CPU_MAXIMUM_PROCESSORS, index, mask );
+}
+
+/**
+ * @brief Checks if the processor sets a and b are equal.
+ *
+ * @param a The first processor set.
+ * @param b The seconde processor set.
+ *
+ * @retval true The processor sets a and b are equal.
+ * @retval false The processor sets a and b are not equal.
+ */
+static inline bool _Processor_mask_Is_equal(
+ const Processor_mask *a,
+ const Processor_mask *b
+)
+{
+ return !__BIT_CMP( CPU_MAXIMUM_PROCESSORS, a, b );
+}
+
+/**
+ * @brief Checks if the intersection of the processor sets a and b is
+ * non-empty.
+ *
+ * @param a The first processor set.
+ * @param b The second processor set.
+ *
+ * @retval true The intersection of the processor sets a and b is non-empty.
+ * @retval false The intersection of the processor sets a and b is empty.
+ */
+static inline bool _Processor_mask_Has_overlap(
+ const Processor_mask *a,
+ const Processor_mask *b
+)
+{
+ return __BIT_OVERLAP( CPU_MAXIMUM_PROCESSORS, a, b );
+}
+
+/**
+ * @brief Checks if the processor set small is a subset of processor set
+ * big.
+ *
+ * @param big The bigger processor set.
+ * @param small The smaller processor set.
+ *
+ * @retval true @a small is a subset of @a big.
+ * @retval false @a small is not a subset of @a big.
+ */
+static inline bool _Processor_mask_Is_subset(
+ const Processor_mask *big,
+ const Processor_mask *small
+)
+{
+ return __BIT_SUBSET( CPU_MAXIMUM_PROCESSORS, big, small );
+}
+
+/**
+ * @brief Performs a bitwise a = b & c.
+ *
+ * @param[out] a The processor mask that is set by this operation.
+ * @param b The first parameter of the AND-operation.
+ * @param c The second parameter of the AND-operation.
+ */
+static inline void _Processor_mask_And(
+ Processor_mask *a,
+ const Processor_mask *b,
+ const Processor_mask *c
+)
+{
+ __BIT_AND2( CPU_MAXIMUM_PROCESSORS, a, b, c );
+}
+
+/**
+ * @brief Performs a bitwise a = b | c.
+ *
+ * @param[out] a The processor mask that is set by this operation.
+ * @param b The first parameter of the OR-operation.
+ * @param c The second parameter of the OR-operation.
+ */
+static inline void _Processor_mask_Or(
+ Processor_mask *a,
+ const Processor_mask *b,
+ const Processor_mask *c
+)
+{
+ __BIT_OR2( CPU_MAXIMUM_PROCESSORS, a, b, c );
+}
+
+/**
+ * @brief Performs a bitwise a = b ^ c.
+ *
+ * @param[out] a The processor mask that is set by this operation.
+ * @param b The first parameter of the XOR-operation.
+ * @param c The second parameter of the XOR-operation.
+ */
+static inline void _Processor_mask_Xor(
+ Processor_mask *a,
+ const Processor_mask *b,
+ const Processor_mask *c
+)
+{
+ __BIT_XOR2( CPU_MAXIMUM_PROCESSORS, a, b, c );
+}
+
+/**
+ * @brief Gets the number of set bits in the processor mask.
+ *
+ * @param a The processor mask of which the set bits are counted.
+ *
+ * @return The number of set bits in @a a.
+ */
+static inline uint32_t _Processor_mask_Count( const Processor_mask *a )
+{
+ return (uint32_t) __BIT_COUNT( CPU_MAXIMUM_PROCESSORS, a );
+}
+
+/**
+ * @brief Finds the last set of the processor mask.
+ *
+ * @param a The processor mask wo find the last set of.
+ *
+ * @return The last set of @a a.
+ */
+static inline uint32_t _Processor_mask_Find_last_set( const Processor_mask *a )
+{
+ return (uint32_t) __BIT_FLS( CPU_MAXIMUM_PROCESSORS, a );
+}
+
+/**
+ * @brief Returns the subset of 32 processors containing the specified index as
+ * an unsigned 32-bit integer.
+ *
+ * @param mask The processor mask.
+ * @param index The specified index.
+ *
+ * @return The subset containing the specified index as an unsigned 32-bit integer.
+ */
+static inline uint32_t _Processor_mask_To_uint32_t(
+ const Processor_mask *mask,
+ uint32_t index
+)
+{
+ long bits = mask->__bits[ index / _BITSET_BITS ];
+
+ return (uint32_t) ( bits >> ( 32 * ( ( index % _BITSET_BITS ) / 32 ) ) );
+}
+
+/**
+ * @brief Creates a processor set from an unsigned 32-bit integer relative to
+ * the specified index.
+ *
+ * @param[out] mask The mask that is created.
+ * @param bits The bits for creating the mask.
+ * @param index The index to which the mask is relative.
+ */
+static inline void _Processor_mask_From_uint32_t(
+ Processor_mask *mask,
+ uint32_t bits,
+ uint32_t index
+)
+{
+ _Processor_mask_Zero( mask );
+ mask->__bits[ __bitset_words( index ) ] = ((long) bits) << (32 * (index % _BITSET_BITS) / 32);
+}
+
+/**
+ * @brief Creates a processor set from the specified index.
+ *
+ * @param[out] The mask that is created.
+ * @param index The specified index.
+ */
+static inline void _Processor_mask_From_index(
+ Processor_mask *mask,
+ uint32_t index
+)
+{
+ __BIT_SETOF( CPU_MAXIMUM_PROCESSORS, (int) index, mask );
+}
+
+typedef enum {
+ PROCESSOR_MASK_COPY_LOSSLESS,
+ PROCESSOR_MASK_COPY_PARTIAL_LOSS,
+ PROCESSOR_MASK_COPY_COMPLETE_LOSS,
+ PROCESSOR_MASK_COPY_INVALID_SIZE
+} Processor_mask_Copy_status;
+
+/**
+ * @brief Checks if the copy status guarantees at most partial loss.
+ *
+ * @param status The copy status to check.
+ *
+ * @retval true At most partial loss can be guaranteed.
+ * @retval false The status indicates more than partial loss.
+ */
+static inline bool _Processor_mask_Is_at_most_partial_loss(
+ Processor_mask_Copy_status status
+)
+{
+ return (unsigned int) status <= PROCESSOR_MASK_COPY_PARTIAL_LOSS;
+}
+
+/**
+ * @brief Copies one mask to another.
+ *
+ * @param[out] dst The destination of the copy operation.
+ * @param dst_size The size of @a dst.
+ * @param src The source of the copy operation.
+ * @param src_size The size of @a src.
+ *
+ * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy
+ * operation is lossless.
+ * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due
+ * to the sizes of @a src and @a dst.
+ * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due
+ * to the sizes of @a src and @a dst.
+ * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes
+ * is invalid (bigger than the size of a long).
+ */
+Processor_mask_Copy_status _Processor_mask_Copy(
+ long *dst,
+ size_t dst_size,
+ const long *src,
+ size_t src_size
+);
+
+/**
+ * @brief Copies one mask to another.
+ *
+ * @param src The source for the copy operation.
+ * @param dst_size The size of @a dst.
+ * @param[out] dst The destination for the copy operation.
+ *
+ * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy
+ * operation is lossless.
+ * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due
+ * to the sizes of @a src and @a dst.
+ * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due
+ * to the sizes of @a src and @a dst.
+ * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes
+ * is invalid (bigger than the size of a long).
+ */
+static inline Processor_mask_Copy_status _Processor_mask_To_cpu_set_t(
+ const Processor_mask *src,
+ size_t dst_size,
+ cpu_set_t *dst
+)
+{
+ return _Processor_mask_Copy(
+ &dst->__bits[ 0 ],
+ dst_size,
+ &src->__bits[ 0 ],
+ sizeof( *src )
+ );
+}
+
+/**
+ * @brief Copies one mask to another.
+ *
+ * @param src The source for the copy operation.
+ * @param src_size The size of @a src.
+ * @param[out] dst The destination for the copy operation.
+ *
+ * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy
+ * operation is lossless.
+ * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due
+ * to the sizes of @a src and @a dst.
+ * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due
+ * to the sizes of @a src and @a dst.
+ * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes
+ * is invalid (bigger than the size of a long).
+ */
+static inline Processor_mask_Copy_status _Processor_mask_From_cpu_set_t(
+ Processor_mask *dst,
+ size_t src_size,
+ const cpu_set_t *src
+)
+{
+ return _Processor_mask_Copy(
+ &dst->__bits[ 0 ],
+ sizeof( *dst ),
+ &src->__bits[ 0 ],
+ src_size
+ );
+}
+
+extern const Processor_mask _Processor_mask_The_one_and_only;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_PROCESSORMASKIMPL_H */
diff --git a/cpukit/include/rtems/score/smpimpl.h b/cpukit/include/rtems/score/smpimpl.h
index 2ffc047070..a8e3a3be15 100644
--- a/cpukit/include/rtems/score/smpimpl.h
+++ b/cpukit/include/rtems/score/smpimpl.h
@@ -40,7 +40,7 @@
#include <rtems/score/smp.h>
#include <rtems/score/percpu.h>
-#include <rtems/score/processormask.h>
+#include <rtems/score/processormaskimpl.h>
#include <rtems/fatal.h>
#ifdef __cplusplus
diff --git a/cpukit/include/rtems/score/thread.h b/cpukit/include/rtems/score/thread.h
index 9a9d2e038f..8ca7d85205 100644
--- a/cpukit/include/rtems/score/thread.h
+++ b/cpukit/include/rtems/score/thread.h
@@ -719,50 +719,50 @@ typedef struct {
* The individual state flags must be a power of two to allow use of bit
* operations to manipulate and evaluate the thread life state.
*/
-typedef enum {
- /**
- * @brief Indicates that the thread life is protected.
- *
- * If this flag is set, then the thread restart or delete requests are deferred
- * until the protection and deferred change flags are cleared. It is used by
- * _Thread_Set_life_protection().
- */
- THREAD_LIFE_PROTECTED = 0x1,
+typedef unsigned int Thread_Life_state;
- /**
- * @brief Indicates that thread is restarting.
- *
- * If this flag is set, then a thread restart request is in pending. See
- * _Thread_Restart_self() and _Thread_Restart_other().
- */
- THREAD_LIFE_RESTARTING = 0x2,
+/**
+ * @brief Indicates that the thread life is protected.
+ *
+ * If this flag is set, then the thread restart or delete requests are deferred
+ * until the protection and deferred change flags are cleared. It is used by
+ * _Thread_Set_life_protection().
+ */
+#define THREAD_LIFE_PROTECTED 0x1U
- /**
- * @brief Indicates that thread is terminating.
- *
- * If this flag is set, then a thread termination request is in pending. See
- * _Thread_Exit() and _Thread_Cancel().
- */
- THREAD_LIFE_TERMINATING = 0x4,
+/**
+ * @brief Indicates that thread is restarting.
+ *
+ * If this flag is set, then a thread restart request is in pending. See
+ * _Thread_Restart_self() and _Thread_Restart_other().
+ */
+#define THREAD_LIFE_RESTARTING 0x2U
- /**
- * @brief Indicates that thread life changes are deferred.
- *
- * If this flag is set, then the thread restart or delete requests are deferred
- * until the protection and deferred change flags are cleared. It is used by
- * pthread_setcanceltype().
- */
- THREAD_LIFE_CHANGE_DEFERRED = 0x8,
+/**
+ * @brief Indicates that thread is terminating.
+ *
+ * If this flag is set, then a thread termination request is in pending. See
+ * _Thread_Exit() and _Thread_Cancel().
+ */
+#define THREAD_LIFE_TERMINATING 0x4U
- /**
- * @brief Indicates that thread is detached.
- *
- * If this flag is set, then the thread is detached. Detached threads do not
- * wait during termination for other threads to join. See rtems_task_delete(),
- * rtems_task_exit(), and pthread_detach().
- */
- THREAD_LIFE_DETACHED = 0x10
-} Thread_Life_state;
+/**
+ * @brief Indicates that thread life changes are deferred.
+ *
+ * If this flag is set, then the thread restart or delete requests are deferred
+ * until the protection and deferred change flags are cleared. It is used by
+ * pthread_setcanceltype().
+ */
+#define THREAD_LIFE_CHANGE_DEFERRED 0x8U
+
+/**
+ * @brief Indicates that thread is detached.
+ *
+ * If this flag is set, then the thread is detached. Detached threads do not
+ * wait during termination for other threads to join. See rtems_task_delete(),
+ * rtems_task_exit(), and pthread_detach().
+ */
+#define THREAD_LIFE_DETACHED 0x10U
/**
* @brief Thread life control.
diff --git a/cpukit/include/rtems/score/threadimpl.h b/cpukit/include/rtems/score/threadimpl.h
index a82f412887..36ddb785e9 100644
--- a/cpukit/include/rtems/score/threadimpl.h
+++ b/cpukit/include/rtems/score/threadimpl.h
@@ -1598,12 +1598,12 @@ static inline Scheduler_Node *_Thread_Scheduler_get_node_by_index(
size_t scheduler_index
)
{
+ _Assert( scheduler_index < _Scheduler_Count );
#if defined(RTEMS_SMP)
return (Scheduler_Node *)
( (uintptr_t) the_thread->Scheduler.nodes
+ scheduler_index * _Scheduler_Node_size );
#else
- _Assert( scheduler_index == 0 );
(void) scheduler_index;
return the_thread->Scheduler.nodes;
#endif
diff --git a/cpukit/include/rtems/score/tls.h b/cpukit/include/rtems/score/tls.h
index fa3ee0afa2..8716c5230c 100644
--- a/cpukit/include/rtems/score/tls.h
+++ b/cpukit/include/rtems/score/tls.h
@@ -10,7 +10,7 @@
*/
/*
- * Copyright (C) 2014, 2022 embedded brains GmbH & Co. KG
+ * Copyright (C) 2014, 2023 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -59,31 +59,51 @@ extern "C" {
* @{
*/
-extern char _TLS_Data_begin[];
-
-extern char _TLS_Data_end[];
+/**
+ * @brief Represents the TLS configuration.
+ */
+typedef struct {
+ /**
+ * @brief This member is initialized to _TLS_Data_begin.
+ */
+ const char *data_begin;
-extern char _TLS_Data_size[];
+ /**
+ * @brief This member is initialized to _TLS_Data_size.
+ */
+ const char *data_size;
-extern char _TLS_BSS_begin[];
+ /**
+ * @brief This member is initialized to _TLS_BSS_begin.
+ */
+ const char *bss_begin;
-extern char _TLS_BSS_end[];
+ /**
+ * @brief This member is initialized to _TLS_BSS_size.
+ */
+ const char *bss_size;
-extern char _TLS_BSS_size[];
+ /**
+ * @brief This member is initialized to _TLS_Size.
+ */
+ const char *size;
-extern char _TLS_Size[];
+ /**
+ * @brief This member is initialized to _TLS_Alignment.
+ */
+ const char *alignment;
+} TLS_Configuration;
/**
- * @brief The TLS section alignment.
+ * @brief Provides the TLS configuration.
*
- * This symbol is provided by the linker command file as the maximum alignment
- * of the .tdata and .tbss sections. The linker ensures that the first TLS
- * output section is aligned to the maximum alignment of all TLS output
- * sections, see function _bfd_elf_tls_setup() in bfd/elflink.c of the GNU
- * Binutils sources. The linker command file must take into account the case
- * that the .tdata section is empty and the .tbss section is non-empty.
+ * Directly using symbols with an arbitrary absolute address such as
+ * _TLS_Alignment may not work with all code models (for example the AArch64
+ * tiny and small code models). Store the addresses in a read-only object.
+ * Using the volatile qualifier ensures that the compiler actually loads the
+ * address from the object.
*/
-extern char _TLS_Alignment[];
+extern const volatile TLS_Configuration _TLS_Configuration;
typedef struct {
/*
@@ -116,38 +136,24 @@ typedef struct {
} TLS_Index;
/**
- * @brief Gets the size of the thread-local storage data in bytes.
- *
- * @return Returns the size of the thread-local storage data in bytes.
- */
-static inline uintptr_t _TLS_Get_size( void )
-{
- uintptr_t size;
-
- /*
- * We must be careful with using _TLS_Size here since this could lead GCC to
- * assume that this symbol is not 0 and the tests for 0 will be optimized
- * away.
- */
- size = (uintptr_t) _TLS_Size;
- RTEMS_OBFUSCATE_VARIABLE( size );
- return size;
-}
-
-/**
* @brief Gets the size of the thread control block area in bytes.
*
+ * @param config is the TLS configuration.
+ *
* @return Returns the size of the thread control block area in bytes.
*/
-static inline uintptr_t _TLS_Get_thread_control_block_area_size( void )
+static inline uintptr_t _TLS_Get_thread_control_block_area_size(
+ const volatile TLS_Configuration *config
+)
{
#if CPU_THREAD_LOCAL_STORAGE_VARIANT == 11
uintptr_t alignment;
- alignment = (uintptr_t) _TLS_Alignment;
+ alignment = (uintptr_t) config->alignment;
return RTEMS_ALIGN_UP( sizeof( TLS_Thread_control_block ), alignment );
#else
+ (void) config;
return sizeof( TLS_Thread_control_block );
#endif
}
@@ -163,17 +169,23 @@ uintptr_t _TLS_Get_allocation_size( void );
/**
* @brief Initializes the thread-local storage data.
*
+ * @param config is the TLS configuration.
+ *
* @param[out] tls_data is the thread-local storage data to initialize.
*/
-static inline void _TLS_Copy_and_clear( void *tls_data )
+static inline void _TLS_Copy_and_clear(
+ const volatile TLS_Configuration *config,
+ void *tls_data
+)
{
- tls_data = memcpy( tls_data, _TLS_Data_begin, (uintptr_t) _TLS_Data_size );
+ tls_data =
+ memcpy( tls_data, config->data_begin, (uintptr_t) config->data_size );
memset(
(char *) tls_data +
- (uintptr_t) _TLS_BSS_begin - (uintptr_t) _TLS_Data_begin,
+ (uintptr_t) config->bss_begin - (uintptr_t) config->data_begin,
0,
- (uintptr_t) _TLS_BSS_size
+ (uintptr_t) config->bss_size
);
}
@@ -213,20 +225,22 @@ static inline void _TLS_Initialize_TCB_and_DTV(
*/
static inline void *_TLS_Initialize_area( void *tls_area )
{
- uintptr_t alignment;
- void *tls_data;
- TLS_Thread_control_block *tcb;
- TLS_Dynamic_thread_vector *dtv;
- void *return_value;
+ const volatile TLS_Configuration *config;
+ uintptr_t alignment;
+ void *tls_data;
+ TLS_Thread_control_block *tcb;
+ TLS_Dynamic_thread_vector *dtv;
+ void *return_value;
#if CPU_THREAD_LOCAL_STORAGE_VARIANT == 11
- uintptr_t tcb_size;
+ uintptr_t tcb_size;
#endif
#if CPU_THREAD_LOCAL_STORAGE_VARIANT == 20
- uintptr_t size;
- uintptr_t alignment_2;
+ uintptr_t size;
+ uintptr_t alignment_2;
#endif
- alignment = (uintptr_t) _TLS_Alignment;
+ config = &_TLS_Configuration;
+ alignment = (uintptr_t) config->alignment;
#ifdef __i386__
dtv = NULL;
@@ -249,7 +263,7 @@ static inline void *_TLS_Initialize_area( void *tls_area )
#elif CPU_THREAD_LOCAL_STORAGE_VARIANT == 20
alignment_2 = RTEMS_ALIGN_UP( alignment, CPU_SIZEOF_POINTER );
tls_area = (void *) RTEMS_ALIGN_UP( (uintptr_t) tls_area, alignment_2 );
- size = _TLS_Get_size();
+ size = (uintptr_t) config->size;
tcb = (TLS_Thread_control_block *)
((char *) tls_area + RTEMS_ALIGN_UP( size, alignment_2 ));
tls_data = (char *) tcb - RTEMS_ALIGN_UP( size, alignment );
@@ -259,7 +273,7 @@ static inline void *_TLS_Initialize_area( void *tls_area )
#endif
_TLS_Initialize_TCB_and_DTV( tls_data, tcb, dtv );
- _TLS_Copy_and_clear( tls_data );
+ _TLS_Copy_and_clear( config, tls_data );
return return_value;
}
diff --git a/cpukit/include/rtems/sysinit.h b/cpukit/include/rtems/sysinit.h
index b973ecfc91..3e6f4d9933 100644
--- a/cpukit/include/rtems/sysinit.h
+++ b/cpukit/include/rtems/sysinit.h
@@ -1,7 +1,15 @@
/* SPDX-License-Identifier: BSD-2-Clause */
+/**
+ * @file
+ *
+ * @ingroup RTEMSAPISystemInit
+ *
+ * @brief This header file provides the API of the @ref RTEMSAPISystemInit.
+ */
+
/*
- * Copyright (C) 2015, 2020 embedded brains GmbH & Co. KG
+ * Copyright (C) 2015, 2023 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,6 +42,54 @@
extern "C" {
#endif /* __cplusplus */
+/**
+ * @ingroup RTEMSImpl
+ *
+ * @brief Enables a verbose system initialization.
+ */
+void _Sysinit_Verbose( void );
+
+/**
+ * @ingroup RTEMSImpl
+ *
+ * @brief Creates the system initialization item associated with the handler
+ * and index.
+ *
+ * The enum helps to detect typos in the module and order parameters of
+ * RTEMS_SYSINIT_ITEM().
+ */
+#define _RTEMS_SYSINIT_INDEX_ITEM( handler, index ) \
+ enum { _Sysinit_##handler = index }; \
+ RTEMS_LINKER_ROSET_ITEM_ORDERED( \
+ _Sysinit, \
+ rtems_sysinit_item, \
+ handler, \
+ index \
+ ) = { handler }
+
+/**
+ * @ingroup RTEMSImpl
+ *
+ * @brief Creates the system initialization item associated with the handler,
+ * module, and order.
+ *
+ * This helper macro is used to perform parameter expansion in
+ * RTEMS_SYSINIT_ITEM().
+ */
+#define _RTEMS_SYSINIT_ITEM( handler, module, order ) \
+ _RTEMS_SYSINIT_INDEX_ITEM( handler, 0x##module##order )
+
+/**
+ * @defgroup RTEMSAPISystemInit System Initialization Support
+ *
+ * @ingroup RTEMSAPI
+ *
+ * @brief The system initialization support provides an ordered invocation of
+ * system initialization handlers registered in a linker set.
+ *
+ * @{
+ */
+
/*
* The value of each module define must consist of exactly six hexadecimal
* digits without a 0x-prefix. A 0x-prefix is concatenated with the module and
@@ -133,29 +189,22 @@ typedef struct {
rtems_sysinit_handler handler;
} rtems_sysinit_item;
-/* The enum helps to detect typos in the module and order parameters */
-#define _RTEMS_SYSINIT_INDEX_ITEM( handler, index ) \
- enum { _Sysinit_##handler = index }; \
- RTEMS_LINKER_ROSET_ITEM_ORDERED( \
- _Sysinit, \
- rtems_sysinit_item, \
- handler, \
- index \
- ) = { handler }
-
-/* Create index from module and order */
-#define _RTEMS_SYSINIT_ITEM( handler, module, order ) \
- _RTEMS_SYSINIT_INDEX_ITEM( handler, 0x##module##order )
-
-/* Perform parameter expansion */
+/**
+ * @brief Creates the system initialization item associated with the handler,
+ * module, and order.
+ *
+ * @param handler is the system initialization handler.
+ *
+ * @param module is the system initialization module. It shall be a 6-digit
+ * hex number without a 0x-prefix.
+ *
+ * @param order is the system initialization order with respect to the module.
+ * It shall be a 2-digit hex number without a 0x-prefix.
+ */
#define RTEMS_SYSINIT_ITEM( handler, module, order ) \
_RTEMS_SYSINIT_ITEM( handler, module, order )
-/**
- * @brief System initialization handler to enable a verbose system
- * initialization.
- */
-void _Sysinit_Verbose( void );
+/** @} */
#ifdef __cplusplus
}
diff --git a/cpukit/include/rtems/termiosdevice.h b/cpukit/include/rtems/termiosdevice.h
new file mode 100644
index 0000000000..17d05e61f6
--- /dev/null
+++ b/cpukit/include/rtems/termiosdevice.h
@@ -0,0 +1,300 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TermiostypesSupport
+ *
+ * @brief This header file provides the interfaces of the
+ * @ref TermiostypesSupport.
+ */
+
+/*
+ * Copyright (C) 2014, 2017 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTEMS_TERMIOSDEVICE_H
+#define _RTEMS_TERMIOSDEVICE_H
+
+#include <rtems/thread.h>
+#include <rtems/rtems/intr.h>
+
+#include <sys/ioccom.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct rtems_libio_open_close_args;
+struct rtems_termios_tty;
+struct termios;
+
+/**
+ * @defgroup TermiostypesSupport RTEMS Termios Device Support
+ *
+ * @ingroup libcsupport
+ *
+ * @brief This group contains the Termios Device Support provided by RTEMS.
+ */
+
+/**
+ * @brief Termios device context.
+ *
+ * @see RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER(),
+ * rtems_termios_device_context_initialize() and
+ * rtems_termios_device_install().
+ */
+typedef struct rtems_termios_device_context {
+ union {
+ /* Used for TERMIOS_POLLED and TERMIOS_IRQ_DRIVEN */
+ rtems_interrupt_lock interrupt;
+
+ /* Used for TERMIOS_IRQ_SERVER_DRIVEN and TERMIOS_TASK_DRIVEN */
+ rtems_mutex mutex;
+ } lock;
+
+ void ( *lock_acquire )(
+ struct rtems_termios_device_context *,
+ rtems_interrupt_lock_context *
+ );
+
+ void ( *lock_release )(
+ struct rtems_termios_device_context *,
+ rtems_interrupt_lock_context *
+ );
+} rtems_termios_device_context;
+
+typedef enum {
+ TERMIOS_POLLED,
+ TERMIOS_IRQ_DRIVEN,
+ TERMIOS_TASK_DRIVEN,
+ TERMIOS_IRQ_SERVER_DRIVEN
+} rtems_termios_device_mode;
+
+/**
+ * @brief Termios device handler.
+ *
+ * @see rtems_termios_device_install().
+ */
+typedef struct {
+ /**
+ * @brief First open of this device.
+ *
+ * @param[in] tty The Termios control. This parameter may be passed to
+ * interrupt service routines since it must be provided for the
+ * rtems_termios_enqueue_raw_characters() and
+ * rtems_termios_dequeue_characters() functions.
+ * @param[in] context The Termios device context.
+ * @param[in] term The current Termios attributes.
+ * @param[in] args The open/close arguments. This is parameter provided to
+ * support legacy drivers. It must not be used by new drivers.
+ *
+ * @retval true Successful operation.
+ * @retval false Cannot open device.
+ *
+ * @see rtems_termios_get_device_context() and rtems_termios_set_best_baud().
+ */
+ bool (*first_open)(
+ struct rtems_termios_tty *tty,
+ rtems_termios_device_context *context,
+ struct termios *term,
+ struct rtems_libio_open_close_args *args
+ );
+
+ /**
+ * @brief Last close of this device.
+ *
+ * @param[in] tty The Termios control.
+ * @param[in] context The Termios device context.
+ * @param[in] args The open/close arguments. This is parameter provided to
+ * support legacy drivers. It must not be used by new drivers.
+ */
+ void (*last_close)(
+ struct rtems_termios_tty *tty,
+ rtems_termios_device_context *context,
+ struct rtems_libio_open_close_args *args
+ );
+
+ /**
+ * @brief Polled read.
+ *
+ * In case mode is TERMIOS_IRQ_DRIVEN, TERMIOS_IRQ_SERVER_DRIVEN or
+ * TERMIOS_TASK_DRIVEN, then data is received via
+ * rtems_termios_enqueue_raw_characters().
+ *
+ * @param[in] context The Termios device context.
+ *
+ * @retval char The received data encoded as unsigned char.
+ * @retval -1 No data currently available.
+ */
+ int (*poll_read)(rtems_termios_device_context *context);
+
+ /**
+ * @brief Polled write in case mode is TERMIOS_POLLED or write support
+ * otherwise.
+ *
+ * @param[in] context The Termios device context.
+ * @param[in] buf The output buffer.
+ * @param[in] len The output buffer length in characters.
+ */
+ void (*write)(
+ rtems_termios_device_context *context,
+ const char *buf,
+ size_t len
+ );
+
+ /**
+ * @brief Set attributes after a Termios settings change.
+ *
+ * @param[in] context The Termios device context.
+ * @param[in] term The new Termios attributes.
+ *
+ * @retval true Successful operation.
+ * @retval false Invalid attributes.
+ */
+ bool (*set_attributes)(
+ rtems_termios_device_context *context,
+ const struct termios *term
+ );
+
+ /**
+ * @brief IO control handler.
+ *
+ * Invoked in case the Termios layer cannot deal with the IO request.
+ *
+ * @param[in] context The Termios device context.
+ * @param[in] request The IO control request.
+ * @param[in] buffer The IO control buffer.
+ */
+ int (*ioctl)(
+ rtems_termios_device_context *context,
+ ioctl_command_t request,
+ void *buffer
+ );
+
+ /**
+ * @brief Termios device mode.
+ */
+ rtems_termios_device_mode mode;
+} rtems_termios_device_handler;
+
+/**
+ * @brief Termios device flow control handler.
+ *
+ * @see rtems_termios_device_install().
+ */
+typedef struct {
+ /**
+ * @brief Indicate to stop remote transmitter.
+ *
+ * @param[in] context The Termios device context.
+ */
+ void (*stop_remote_tx)(rtems_termios_device_context *context);
+
+ /**
+ * @brief Indicate to start remote transmitter.
+ *
+ * @param[in] context The Termios device context.
+ */
+ void (*start_remote_tx)(rtems_termios_device_context *context);
+} rtems_termios_device_flow;
+
+void rtems_termios_device_lock_acquire_default(
+ rtems_termios_device_context *ctx,
+ rtems_interrupt_lock_context *lock_context
+);
+
+void rtems_termios_device_lock_release_default(
+ rtems_termios_device_context *ctx,
+ rtems_interrupt_lock_context *lock_context
+);
+
+/**
+ * @brief Initializes a device context.
+ *
+ * @param[in] context The Termios device context.
+ * @param[in] name The name for the interrupt lock. This name must be a
+ * string persistent throughout the life time of this lock. The name is only
+ * used if profiling is enabled.
+ */
+static inline void rtems_termios_device_context_initialize(
+ rtems_termios_device_context *context,
+ const char *name
+)
+{
+ rtems_interrupt_lock_initialize( &context->lock.interrupt, name );
+ context->lock_acquire = rtems_termios_device_lock_acquire_default;
+ context->lock_release = rtems_termios_device_lock_release_default;
+}
+
+/**
+ * @brief Initializer for static initialization of Termios device contexts.
+ *
+ * @param name The name for the interrupt lock. It must be a string. The name
+ * is only used if profiling is enabled.
+ */
+#define RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( name ) \
+ { \
+ { RTEMS_INTERRUPT_LOCK_INITIALIZER( name ) }, \
+ rtems_termios_device_lock_acquire_default, \
+ rtems_termios_device_lock_release_default \
+ }
+
+/**
+ * @brief Acquires the device lock.
+ *
+ * @param[in] context The device context.
+ * @param[in] lock_context The local interrupt lock context for an acquire and
+ * release pair.
+ */
+static inline void rtems_termios_device_lock_acquire(
+ rtems_termios_device_context *context,
+ rtems_interrupt_lock_context *lock_context
+)
+{
+ ( *context->lock_acquire )( context, lock_context );
+}
+
+/**
+ * @brief Releases the device lock.
+ *
+ * @param[in] context The device context.
+ * @param[in] lock_context The local interrupt lock context for an acquire and
+ * release pair.
+ */
+static inline void rtems_termios_device_lock_release(
+ rtems_termios_device_context *context,
+ rtems_interrupt_lock_context *lock_context
+)
+{
+ ( *context->lock_release )( context, lock_context );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_TERMIOSDEVICE_H */
diff --git a/cpukit/include/rtems/termiostypes.h b/cpukit/include/rtems/termiostypes.h
index 67f3461b1f..5cf418a5eb 100644
--- a/cpukit/include/rtems/termiostypes.h
+++ b/cpukit/include/rtems/termiostypes.h
@@ -39,8 +39,7 @@
#include <rtems/libio.h>
#include <rtems/assoc.h>
#include <rtems/chain.h>
-#include <rtems/thread.h>
-#include <sys/ioccom.h>
+#include <rtems/termiosdevice.h>
#include <stdint.h>
#include <termios.h>
@@ -49,11 +48,9 @@ extern "C" {
#endif
/**
- * @defgroup TermiostypesSupport RTEMS Termios Device Support
+ * @addtogroup TermiostypesSupport
*
- * @ingroup libcsupport
- *
- * @brief RTEMS Termios Device Support Internal Data Structures
+ * @{
*/
/*
@@ -75,211 +72,6 @@ struct rtems_termios_rawbuf {
rtems_binary_semaphore Semaphore;
};
-typedef enum {
- TERMIOS_POLLED,
- TERMIOS_IRQ_DRIVEN,
- TERMIOS_TASK_DRIVEN,
- TERMIOS_IRQ_SERVER_DRIVEN
-} rtems_termios_device_mode;
-
-struct rtems_termios_tty;
-
-/**
- * @brief Termios device context.
- *
- * @see RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER(),
- * rtems_termios_device_context_initialize() and
- * rtems_termios_device_install().
- */
-typedef struct rtems_termios_device_context {
- union {
- /* Used for TERMIOS_POLLED and TERMIOS_IRQ_DRIVEN */
- rtems_interrupt_lock interrupt;
-
- /* Used for TERMIOS_IRQ_SERVER_DRIVEN or TERMIOS_TASK_DRIVEN */
- rtems_mutex mutex;
- } lock;
-
- void ( *lock_acquire )(
- struct rtems_termios_device_context *,
- rtems_interrupt_lock_context *
- );
-
- void ( *lock_release )(
- struct rtems_termios_device_context *,
- rtems_interrupt_lock_context *
- );
-} rtems_termios_device_context;
-
-void rtems_termios_device_lock_acquire_default(
- rtems_termios_device_context *ctx,
- rtems_interrupt_lock_context *lock_context
-);
-
-void rtems_termios_device_lock_release_default(
- rtems_termios_device_context *ctx,
- rtems_interrupt_lock_context *lock_context
-);
-
-/**
- * @brief Initializes a device context.
- *
- * @param[in] context The Termios device context.
- * @param[in] name The name for the interrupt lock. This name must be a
- * string persistent throughout the life time of this lock. The name is only
- * used if profiling is enabled.
- */
-static inline void rtems_termios_device_context_initialize(
- rtems_termios_device_context *context,
- const char *name
-)
-{
- rtems_interrupt_lock_initialize( &context->lock.interrupt, name );
- context->lock_acquire = rtems_termios_device_lock_acquire_default;
- context->lock_release = rtems_termios_device_lock_release_default;
-}
-
-/**
- * @brief Initializer for static initialization of Termios device contexts.
- *
- * @param name The name for the interrupt lock. It must be a string. The name
- * is only used if profiling is enabled.
- */
-#define RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( name ) \
- { \
- { RTEMS_INTERRUPT_LOCK_INITIALIZER( name ) }, \
- rtems_termios_device_lock_acquire_default, \
- rtems_termios_device_lock_release_default \
- }
-
-/**
- * @brief Termios device handler.
- *
- * @see rtems_termios_device_install().
- */
-typedef struct {
- /**
- * @brief First open of this device.
- *
- * @param[in] tty The Termios control. This parameter may be passed to
- * interrupt service routines since it must be provided for the
- * rtems_termios_enqueue_raw_characters() and
- * rtems_termios_dequeue_characters() functions.
- * @param[in] context The Termios device context.
- * @param[in] term The current Termios attributes.
- * @param[in] args The open/close arguments. This is parameter provided to
- * support legacy drivers. It must not be used by new drivers.
- *
- * @retval true Successful operation.
- * @retval false Cannot open device.
- *
- * @see rtems_termios_get_device_context() and rtems_termios_set_best_baud().
- */
- bool (*first_open)(
- struct rtems_termios_tty *tty,
- rtems_termios_device_context *context,
- struct termios *term,
- rtems_libio_open_close_args_t *args
- );
-
- /**
- * @brief Last close of this device.
- *
- * @param[in] tty The Termios control.
- * @param[in] context The Termios device context.
- * @param[in] args The open/close arguments. This is parameter provided to
- * support legacy drivers. It must not be used by new drivers.
- */
- void (*last_close)(
- struct rtems_termios_tty *tty,
- rtems_termios_device_context *context,
- rtems_libio_open_close_args_t *args
- );
-
- /**
- * @brief Polled read.
- *
- * In case mode is TERMIOS_IRQ_DRIVEN, TERMIOS_IRQ_SERVER_DRIVEN or
- * TERMIOS_TASK_DRIVEN, then data is received via
- * rtems_termios_enqueue_raw_characters().
- *
- * @param[in] context The Termios device context.
- *
- * @retval char The received data encoded as unsigned char.
- * @retval -1 No data currently available.
- */
- int (*poll_read)(rtems_termios_device_context *context);
-
- /**
- * @brief Polled write in case mode is TERMIOS_POLLED or write support
- * otherwise.
- *
- * @param[in] context The Termios device context.
- * @param[in] buf The output buffer.
- * @param[in] len The output buffer length in characters.
- */
- void (*write)(
- rtems_termios_device_context *context,
- const char *buf,
- size_t len
- );
-
- /**
- * @brief Set attributes after a Termios settings change.
- *
- * @param[in] context The Termios device context.
- * @param[in] term The new Termios attributes.
- *
- * @retval true Successful operation.
- * @retval false Invalid attributes.
- */
- bool (*set_attributes)(
- rtems_termios_device_context *context,
- const struct termios *term
- );
-
- /**
- * @brief IO control handler.
- *
- * Invoked in case the Termios layer cannot deal with the IO request.
- *
- * @param[in] context The Termios device context.
- * @param[in] request The IO control request.
- * @param[in] buffer The IO control buffer.
- */
- int (*ioctl)(
- rtems_termios_device_context *context,
- ioctl_command_t request,
- void *buffer
- );
-
- /**
- * @brief Termios device mode.
- */
- rtems_termios_device_mode mode;
-} rtems_termios_device_handler;
-
-/**
- * @brief Termios device flow control handler.
- *
- * @see rtems_termios_device_install().
- */
-typedef struct {
- /**
- * @brief Indicate to stop remote transmitter.
- *
- * @param[in] context The Termios device context.
- */
- void (*stop_remote_tx)(rtems_termios_device_context *context);
-
- /**
- * @brief Indicate to start remote transmitter.
- *
- * @param[in] context The Termios device context.
- */
- void (*start_remote_tx)(rtems_termios_device_context *context);
-} rtems_termios_device_flow;
-
/**
* @brief Termios device node for installed devices.
*
@@ -456,36 +248,6 @@ static inline void *rtems_termios_get_device_context(
}
/**
- * @brief Acquires the device lock.
- *
- * @param[in] context The device context.
- * @param[in] lock_context The local interrupt lock context for an acquire and
- * release pair.
- */
-static inline void rtems_termios_device_lock_acquire(
- rtems_termios_device_context *context,
- rtems_interrupt_lock_context *lock_context
-)
-{
- ( *context->lock_acquire )( context, lock_context );
-}
-
-/**
- * @brief Releases the device lock.
- *
- * @param[in] context The device context.
- * @param[in] lock_context The local interrupt lock context for an acquire and
- * release pair.
- */
-static inline void rtems_termios_device_lock_release(
- rtems_termios_device_context *context,
- rtems_interrupt_lock_context *lock_context
-)
-{
- ( *context->lock_release )( context, lock_context );
-}
-
-/**
* @brief Sets the best baud value in the Termios control.
*
* The valid Termios baud values are between 0 and 460800. The Termios baud
diff --git a/cpukit/include/rtems/score/gcov.h b/cpukit/include/rtems/test-gcov.h
index 35e0480f6b..3664e91c64 100644
--- a/cpukit/include/rtems/score/gcov.h
+++ b/cpukit/include/rtems/test-gcov.h
@@ -3,10 +3,9 @@
/**
* @file
*
- * @ingroup RTEMSScoreGcov
+ * @ingroup RTEMSImplGcov
*
- * @brief This header file provides the interfaces of the
- * @ref RTEMSScoreGcov.
+ * @brief This header file provides the interfaces of the @ref RTEMSImplGcov.
*/
/*
@@ -34,22 +33,22 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _RTEMS_SCORE_GCOV_H
-#define _RTEMS_SCORE_GCOV_H
+#ifndef _RTEMS_TEST_GCOV_H
+#define _RTEMS_TEST_GCOV_H
#include <gcov.h>
#include <rtems/linkersets.h>
-#include <rtems/score/io.h>
+#include <rtems/dev/io.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
- * @defgroup RTEMSScoreGcov Gcov Support
+ * @defgroup RTEMSImplGcov Gcov Support
*
- * @ingroup RTEMSScore
+ * @ingroup RTEMSTestFrameworkImpl
*
* @brief This group contains the gocv support.
*
@@ -84,4 +83,4 @@ void _Gcov_Dump_info_base64( IO_Put_char put_char, void *arg );
}
#endif /* __cplusplus */
-#endif /* _RTEMS_SCORE_GCOV_H */
+#endif /* _RTEMS_TEST_GCOV_H */
diff --git a/cpukit/include/rtems/test-info.h b/cpukit/include/rtems/test-info.h
index 055ed4f25b..a5c00c423a 100644
--- a/cpukit/include/rtems/test-info.h
+++ b/cpukit/include/rtems/test-info.h
@@ -1,5 +1,13 @@
/* SPDX-License-Identifier: BSD-2-Clause */
+/**
+ * @file
+ *
+ * @ingroup RTEMSTest
+ *
+ * @brief This header file provides interfaces of the RTEMS Test Support.
+ */
+
/*
* Copyright (C) 2014, 2018 embedded brains GmbH & Co. KG
*
@@ -29,7 +37,6 @@
#define _RTEMS_TEST_H
#include <rtems.h>
-#include <rtems/printer.h>
#include <rtems/score/atomic.h>
#include <rtems/score/smpbarrier.h>
@@ -53,11 +60,6 @@ extern "C" {
extern const char rtems_test_name[];
/**
- * @brief Each test must define a printer.
- */
-extern rtems_printer rtems_test_printer;
-
-/**
* @brief Fatal extension for tests.
*/
void rtems_test_fatal_extension(
@@ -125,13 +127,6 @@ int rtems_test_end(const char* name);
*/
RTEMS_NO_RETURN void rtems_test_exit(int status);
-/**
- * @brief Prints via the RTEMS printer.
- *
- * @return As specified by printf().
- */
-int rtems_test_printf(const char* format, ...) RTEMS_PRINTFLIKE(1, 2);
-
#define RTEMS_TEST_PARALLEL_PROCESSOR_MAX 32
typedef struct rtems_test_parallel_job rtems_test_parallel_job;
diff --git a/cpukit/include/rtems/test-printer.h b/cpukit/include/rtems/test-printer.h
new file mode 100644
index 0000000000..6625aa5a29
--- /dev/null
+++ b/cpukit/include/rtems/test-printer.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTest
+ *
+ * @brief This header file provides interfaces of the RTEMS Test Support.
+ */
+
+/*
+ * Copyright (C) 2014, 2023 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTEMS_TEST_PRINTER_H
+#define _RTEMS_TEST_PRINTER_H
+
+#include <rtems/printer.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @addtogroup RTEMSTest
+ *
+ * @{
+ */
+
+/**
+ * @brief Provides an RTEMS printer for tests.
+ */
+extern rtems_printer rtems_test_printer;
+
+/**
+ * @brief Prints via the RTEMS test printer.
+ *
+ * @return Returns the count of output characters as specified by printf().
+ */
+int rtems_test_printf( const char *format, ... ) RTEMS_PRINTFLIKE( 1, 2 );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_TEST_PRINTER_H */
diff --git a/cpukit/include/rtems/test.h b/cpukit/include/rtems/test.h
index 79313343a0..b8e7934883 100644
--- a/cpukit/include/rtems/test.h
+++ b/cpukit/include/rtems/test.h
@@ -1,6 +1,15 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
*
+ * @ingroup RTEMSTestFramework
+ *
+ * @brief This header file provides interfaces of the
+ * RTEMS Test Framework.
+ */
+
+/*
* Copyright (C) 2017, 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
@@ -77,6 +86,11 @@ typedef struct T_fixture_node {
unsigned int failures;
} T_fixture_node;
+typedef struct T_remark {
+ struct T_remark *next;
+ const char *remark;
+} T_remark;
+
#define T_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
/*
@@ -98,7 +112,7 @@ typedef struct T_fixture_node {
/**
* @defgroup RTEMSTestFrameworkImpl RTEMS Test Framework Implementation
*
- * @ingroup RTEMSTestFramework
+ * @ingroup RTEMSImpl
*
* @brief Implementation details.
*
@@ -2318,6 +2332,8 @@ void *T_fixture_context(void);
void T_set_fixture_context(void *);
+void T_add_remark(T_remark *);
+
void *T_push_fixture(T_fixture_node *, const T_fixture *);
void T_pop_fixture(void);
diff --git a/cpukit/include/rtems/thread.h b/cpukit/include/rtems/thread.h
index 739744b4e0..c3d7de67f4 100644
--- a/cpukit/include/rtems/thread.h
+++ b/cpukit/include/rtems/thread.h
@@ -1,5 +1,14 @@
/* SPDX-License-Identifier: BSD-2-Clause */
+/**
+ * @file
+ *
+ * @ingroup RTEMSAPISelfContainedObjects
+ *
+ * @brief This header file provides the API of
+ * @ref RTEMSAPISelfContainedObjects.
+ */
+
/*
* Copyright (c) 2017 embedded brains GmbH & Co. KG
*
@@ -45,6 +54,16 @@ void _Semaphore_Post_binary(struct _Semaphore_Control *);
typedef struct _Mutex_Control rtems_mutex;
+/**
+ * @defgroup RTEMSAPISelfContainedObjects Self-Contained Objects
+ *
+ * @ingroup RTEMSAPI
+ *
+ * @brief This group contains the self-contained objects API.
+ *
+ * @{
+ */
+
#define RTEMS_MUTEX_INITIALIZER( name ) _MUTEX_NAMED_INITIALIZER( name )
static __inline void rtems_mutex_init( rtems_mutex *mutex, const char *name )
@@ -309,6 +328,8 @@ static __inline void rtems_binary_semaphore_destroy(
_Semaphore_Destroy( &binary_semaphore->Semaphore );
}
+/** @} */
+
__END_DECLS
#endif /* _RTEMS_THREAD_H */
diff --git a/cpukit/include/sys/_ffcounter.h b/cpukit/include/sys/_ffcounter.h
index d83c48cd44..802c7d3224 100644
--- a/cpukit/include/sys/_ffcounter.h
+++ b/cpukit/include/sys/_ffcounter.h
@@ -1,3 +1,12 @@
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreTimecounter
+ *
+ * @brief This header file provides interfaces of the feed-forward clock
+ * counter.
+ */
+
/*-
* Copyright (c) 2011 The University of Melbourne
* All rights reserved.
diff --git a/cpukit/include/sys/endian.h b/cpukit/include/sys/endian.h
index 0849a6a90b..cdd6201736 100644
--- a/cpukit/include/sys/endian.h
+++ b/cpukit/include/sys/endian.h
@@ -1,3 +1,12 @@
+/**
+ * @file
+ *
+ * @ingroup RTEMSAPISystemLibrary
+ *
+ * @brief This header file provides interfaces of the system endianness
+ * support.
+ */
+
/*-
* Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.org>
* All rights reserved.
diff --git a/cpukit/include/sys/priority.h b/cpukit/include/sys/priority.h
index 855edb63c2..37d0d938dc 100644
--- a/cpukit/include/sys/priority.h
+++ b/cpukit/include/sys/priority.h
@@ -1,3 +1,11 @@
+/**
+ * @file
+ *
+ * @ingroup RTEMSAPISystemLibrary
+ *
+ * @brief This header file provides interfaces of the process priority support.
+ */
+
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
diff --git a/cpukit/include/sys/statvfs.h b/cpukit/include/sys/statvfs.h
index 52d8e9d3fa..655f9a596c 100644
--- a/cpukit/include/sys/statvfs.h
+++ b/cpukit/include/sys/statvfs.h
@@ -3,10 +3,11 @@
/**
* @file
*
- * @brief Interface to the statvfs() Set of API Methods
+ * @ingroup RTEMSAPISystemLibrary
*
- * This include file defines the interface to the statvfs() set of
- * API methods. The statvfs as defined by the SUS:
+ * @brief This header file provides the statvfs() and fstatvfs() interfaces.
+ *
+ * The statvfs() is defined by the SUS:
*
* - http://www.opengroup.org/onlinepubs/009695399/basedefs/sys/statvfs.h.html
*/
diff --git a/cpukit/include/sys/timeffc.h b/cpukit/include/sys/timeffc.h
index c04de97f1d..13abd37a2b 100644
--- a/cpukit/include/sys/timeffc.h
+++ b/cpukit/include/sys/timeffc.h
@@ -1,3 +1,12 @@
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreTimecounter
+ *
+ * @brief This header file provides interfaces of the feed-back and
+ * feed-forward clock implementations.
+ */
+
/*-
* Copyright (c) 2011 The University of Melbourne
* All rights reserved.
diff --git a/cpukit/include/sys/timepps.h b/cpukit/include/sys/timepps.h
index 030c734477..502d93833e 100644
--- a/cpukit/include/sys/timepps.h
+++ b/cpukit/include/sys/timepps.h
@@ -1,3 +1,12 @@
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreTimecounter
+ *
+ * @brief This header file provides interfaces of the Pulse Per Second (PPS)
+ * support.
+ */
+
/*-
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
diff --git a/cpukit/include/sys/timetc.h b/cpukit/include/sys/timetc.h
index 1ef58b378d..8f2537692c 100644
--- a/cpukit/include/sys/timetc.h
+++ b/cpukit/include/sys/timetc.h
@@ -1,3 +1,12 @@
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreTimecounter
+ *
+ * @brief This header file provides interfaces of the timecounter
+ * implementation.
+ */
+
/*-
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
diff --git a/cpukit/include/sys/timex.h b/cpukit/include/sys/timex.h
index 8e763bb30f..36b1fcdb5a 100644
--- a/cpukit/include/sys/timex.h
+++ b/cpukit/include/sys/timex.h
@@ -1,3 +1,12 @@
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreTimecounter
+ *
+ * @brief This header file provides interfaces of the Network Time Protocol
+ * (NTP) support.
+ */
+
/*-
***********************************************************************
* *
diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c
index 06b756272f..ee6f1d9347 100644
--- a/cpukit/libblock/src/bdbuf.c
+++ b/cpukit/libblock/src/bdbuf.c
@@ -39,7 +39,6 @@
#include <pthread.h>
#include <rtems.h>
-#include <rtems/error.h>
#include <rtems/thread.h>
#include <rtems/score/assert.h>
@@ -2902,7 +2901,7 @@ rtems_bdbuf_set_block_size (rtems_disk_device *dd,
* device later.
*/
if (sync)
- rtems_bdbuf_syncdev (dd);
+ (void) rtems_bdbuf_syncdev (dd);
rtems_bdbuf_lock_cache ();
diff --git a/cpukit/libblock/src/blkdev-imfs.c b/cpukit/libblock/src/blkdev-imfs.c
index 67f7c98c9d..e562619d4d 100644
--- a/cpukit/libblock/src/blkdev-imfs.c
+++ b/cpukit/libblock/src/blkdev-imfs.c
@@ -269,7 +269,7 @@ static void rtems_blkdev_imfs_destroy(IMFS_jnode_t *node)
rtems_blkdev_imfs_context *ctx = IMFS_generic_get_context_by_node(node);
rtems_disk_device *dd = &ctx->dd;
- rtems_bdbuf_syncdev(dd);
+ (void) rtems_bdbuf_syncdev(dd);
rtems_bdbuf_purge_dev(dd);
if (ctx->fd >= 0) {
diff --git a/cpukit/libblock/src/media.c b/cpukit/libblock/src/media.c
index 3ab01602ae..cc6bb70f91 100644
--- a/cpukit/libblock/src/media.c
+++ b/cpukit/libblock/src/media.c
@@ -194,7 +194,7 @@ static void error(
const char *dest
)
{
- notify(RTEMS_MEDIA_EVENT_ERROR, state, src, dest);
+ (void) notify(RTEMS_MEDIA_EVENT_ERROR, state, src, dest);
}
static media_item *get_media_item(
@@ -434,7 +434,7 @@ static rtems_status_code process_event(
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
rtems_status_code sc_retry = RTEMS_SUCCESSFUL;
- rtems_media_state state = RTEMS_MEDIA_STATE_FAILED;
+ rtems_media_state state;
char *dest = NULL;
do {
@@ -519,7 +519,7 @@ static rtems_status_code mount_worker(
&mount_options
);
if (rv != 0) {
- rmdir(mount_path);
+ (void) rmdir(mount_path);
free(mount_path);
(*mount_options.converter->handler->destroy)(mount_options.converter);
diff --git a/cpukit/libcsupport/src/cachecoherentalloc.c b/cpukit/libcsupport/src/cachecoherentalloc.c
index 198eb907b5..ed17ebffcb 100644
--- a/cpukit/libcsupport/src/cachecoherentalloc.c
+++ b/cpukit/libcsupport/src/cachecoherentalloc.c
@@ -97,7 +97,7 @@ void rtems_cache_coherent_free( void *ptr )
_RTEMS_Unlock_allocator();
}
-static void add_area(
+static rtems_status_code add_area(
void *area_begin,
uintptr_t area_size
)
@@ -105,31 +105,37 @@ static void add_area(
Heap_Control *heap = cache_coherent_heap;
if ( heap == NULL ) {
- bool ok;
-
heap = &cache_coherent_heap_instance;
- ok = _Heap_Initialize( heap, area_begin, area_size, 0 );
- if ( ok ) {
- cache_coherent_heap = heap;
+ if ( _Heap_Initialize( heap, area_begin, area_size, 0 ) == 0 ) {
+ return RTEMS_UNSATISFIED;
}
+ cache_coherent_heap = heap;
} else {
- _Heap_Extend( heap, area_begin, area_size, 0 );
+ if (_Heap_Extend( heap, area_begin, area_size, 0 ) == 0) {
+ return RTEMS_UNSATISFIED;
+ }
}
+ return RTEMS_SUCCESSFUL;
}
-void rtems_cache_coherent_add_area(
+rtems_status_code rtems_cache_coherent_add_area(
void *area_begin,
uintptr_t area_size
)
{
- if ( _System_state_Is_up( _System_state_Get()) ) {
+ rtems_status_code sc;
+ bool needs_locking = _System_state_Is_up( _System_state_Get());
+
+ if ( needs_locking ) {
_RTEMS_Lock_allocator();
+ }
- add_area( area_begin, area_size );
+ sc = add_area( area_begin, area_size );
+ if ( needs_locking ) {
_RTEMS_Unlock_allocator();
- } else {
- add_area( area_begin, area_size );
}
+
+ return sc;
}
diff --git a/cpukit/libcsupport/src/getpid.c b/cpukit/libcsupport/src/getpid.c
index 84cab91a39..464504de7e 100644
--- a/cpukit/libcsupport/src/getpid.c
+++ b/cpukit/libcsupport/src/getpid.c
@@ -40,7 +40,6 @@
#include <unistd.h>
#include <rtems.h>
-#include <rtems/seterr.h>
/**
* 4.1.1 Get Process and Parent Process IDs, P1003.1b-1993, p. 83
diff --git a/cpukit/libcsupport/src/getppid.c b/cpukit/libcsupport/src/getppid.c
index 46d1cc8e08..2ca7a8f900 100644
--- a/cpukit/libcsupport/src/getppid.c
+++ b/cpukit/libcsupport/src/getppid.c
@@ -46,8 +46,6 @@
#include <unistd.h>
-#include <rtems/seterr.h>
-
pid_t _POSIX_types_Ppid = 0;
/**
diff --git a/cpukit/libcsupport/src/isatty_r.c b/cpukit/libcsupport/src/isatty_r.c
index 7a758c54a8..3ae285fb26 100644
--- a/cpukit/libcsupport/src/isatty_r.c
+++ b/cpukit/libcsupport/src/isatty_r.c
@@ -44,7 +44,6 @@
*/
#include <unistd.h>
#include <reent.h>
-#include <sys/stat.h>
int _isatty_r(
struct _reent *ptr,
diff --git a/cpukit/libcsupport/src/malloc_p.h b/cpukit/libcsupport/src/malloc_p.h
index ac25cd31d1..115198cb40 100644
--- a/cpukit/libcsupport/src/malloc_p.h
+++ b/cpukit/libcsupport/src/malloc_p.h
@@ -1,8 +1,15 @@
/* SPDX-License-Identifier: BSD-2-Clause */
-/*
- * RTEMS Malloc Family Internal Header
+/**
+ * @file
+ *
+ * @ingroup libcsupport
*
+ * @brief This header file provides interfaces used by the memory allocator
+ * implementation.
+ */
+
+/*
* COPYRIGHT (c) 1989-2007.
* On-Line Applications Research Corporation (OAR).
*
diff --git a/cpukit/libcsupport/src/sup_fs_location.c b/cpukit/libcsupport/src/sup_fs_location.c
index 1f533f37f4..a121b252fb 100644
--- a/cpukit/libcsupport/src/sup_fs_location.c
+++ b/cpukit/libcsupport/src/sup_fs_location.c
@@ -39,7 +39,6 @@
#include <stdlib.h>
#include <rtems/libio_.h>
-#include <rtems/score/threaddispatch.h>
rtems_interrupt_lock rtems_filesystem_mt_entry_lock_control =
RTEMS_INTERRUPT_LOCK_INITIALIZER("mount table entry");
diff --git a/cpukit/libcsupport/src/termiosinitialize.c b/cpukit/libcsupport/src/termiosinitialize.c
index 35aa1eb955..ae80243b2a 100644
--- a/cpukit/libcsupport/src/termiosinitialize.c
+++ b/cpukit/libcsupport/src/termiosinitialize.c
@@ -1,8 +1,11 @@
/**
- * @file
+ * @file
*
- * @brief Termios Initialization
- * @ingroup Termios
+ * @ingroup TermiostypesSupport
+ *
+ * @brief This source file contains the implementation of
+ * rtems_termios_device_lock_acquire_default() and
+ * rtems_termios_device_lock_release_default().
*/
/*
@@ -17,7 +20,7 @@
#include "config.h"
#endif
-#include <rtems/termiostypes.h>
+#include <rtems/termiosdevice.h>
void
rtems_termios_device_lock_acquire_default(
diff --git a/cpukit/libcsupport/src/vprintk.c b/cpukit/libcsupport/src/vprintk.c
index e46cdad60f..f4ac81c5fc 100644
--- a/cpukit/libcsupport/src/vprintk.c
+++ b/cpukit/libcsupport/src/vprintk.c
@@ -38,7 +38,7 @@
#endif
#include <rtems/bspIo.h>
-#include <rtems/score/io.h>
+#include <rtems/dev/io.h>
int vprintk( const char *fmt, va_list ap )
{
diff --git a/cpukit/libdl/rtl-alloc-heap.c b/cpukit/libdl/rtl-alloc-heap.c
index 10150a0753..f90233874e 100644
--- a/cpukit/libdl/rtl-alloc-heap.c
+++ b/cpukit/libdl/rtl-alloc-heap.c
@@ -9,7 +9,7 @@
*/
/*
- * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ * COPYRIGHT (c) 2012,2023 Chris Johns <chrisj@rtems.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -54,6 +54,9 @@ rtems_rtl_alloc_heap (rtems_rtl_alloc_cmd cmd,
free (*address);
*address = NULL;
break;
+ case RTEMS_RTL_ALLOC_RESIZE:
+ *address = realloc (*address, size);
+ break;
case RTEMS_RTL_ALLOC_LOCK:
_RTEMS_Lock_allocator();
break;
diff --git a/cpukit/libdl/rtl-allocator.c b/cpukit/libdl/rtl-allocator.c
index f09690d71a..7503183367 100644
--- a/cpukit/libdl/rtl-allocator.c
+++ b/cpukit/libdl/rtl-allocator.c
@@ -9,7 +9,7 @@
*/
/*
- * COPYRIGHT (c) 2012, 2018 Chris Johns <chrisj@rtems.org>
+ * COPYRIGHT (c) 2012, 2018, 2023 Chris Johns <chrisj@rtems.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -110,6 +110,39 @@ rtems_rtl_alloc_del (rtems_rtl_alloc_tag tag, void* address)
rtems_rtl_unlock ();
}
+void* rtems_rtl_alloc_resize (rtems_rtl_alloc_tag tag,
+ void* address,
+ size_t size,
+ bool zero)
+{
+ rtems_rtl_data* rtl = rtems_rtl_lock ();
+ const void* prev_address = address;
+
+ /*
+ * Resize memory of an existing allocation. The address field is set
+ * by the allocator and may change.
+ */
+ if (rtl != NULL)
+ rtl->allocator.allocator (RTEMS_RTL_ALLOC_RESIZE, tag, &address, size);
+
+ rtems_rtl_unlock ();
+
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
+ printf ("rtl: alloc: resize: %s%s prev-addr=%p addr=%p size=%zu\n",
+ rtems_rtl_trace_tag_label (tag), prev_address == address ? "" : " MOVED",
+ prev_address, address, size);
+
+ /*
+ * Only zero the memory if asked to and the resize was successful. We
+ * cannot clear the resized area if bigger than the previouis allocation
+ * because we do not have the original size.
+ */
+ if (address != NULL && zero)
+ memset (address, 0, size);
+
+ return address;
+}
+
void
rtems_rtl_alloc_wr_enable (rtems_rtl_alloc_tag tag, void* address)
{
@@ -277,21 +310,23 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
{
*text_base = *const_base = *data_base = *bss_base = NULL;
- if (text_size)
+ if (data_size != 0)
{
- *text_base = rtems_rtl_alloc_new (rtems_rtl_alloc_text_tag (),
- text_size, false);
- if (!*text_base)
+ *data_base = rtems_rtl_alloc_new (rtems_rtl_alloc_data_tag (),
+ data_size, false);
+ if (*data_base == NULL)
{
+ rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
+ data_base, bss_base);
return false;
}
}
- if (const_size)
+ if (bss_size != 0)
{
- *const_base = rtems_rtl_alloc_new (rtems_rtl_alloc_const_tag (),
- const_size, false);
- if (!*const_base)
+ *bss_base = rtems_rtl_alloc_new (rtems_rtl_alloc_bss_tag (),
+ bss_size, false);
+ if (*bss_base == NULL)
{
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
data_base, bss_base);
@@ -299,11 +334,11 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
}
}
- if (eh_size)
+ if (eh_size != 0)
{
*eh_base = rtems_rtl_alloc_new (rtems_rtl_alloc_eh_tag (),
eh_size, false);
- if (!*eh_base)
+ if (*eh_base == NULL)
{
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
data_base, bss_base);
@@ -311,11 +346,11 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
}
}
- if (data_size)
+ if (const_size != 0)
{
- *data_base = rtems_rtl_alloc_new (rtems_rtl_alloc_data_tag (),
- data_size, false);
- if (!*data_base)
+ *const_base = rtems_rtl_alloc_new (rtems_rtl_alloc_const_tag (),
+ const_size, false);
+ if (*const_base == NULL)
{
rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
data_base, bss_base);
@@ -323,14 +358,72 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
}
}
- if (bss_size)
+ if (text_size != 0)
{
- *bss_base = rtems_rtl_alloc_new (rtems_rtl_alloc_bss_tag (),
- bss_size, false);
- if (!*bss_base)
+ *text_base = rtems_rtl_alloc_new (rtems_rtl_alloc_text_tag (),
+ text_size, false);
+ if (*text_base == NULL)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool
+rtems_rtl_alloc_module_resize (void** text_base, size_t text_size,
+ void** const_base, size_t const_size,
+ void** eh_base, size_t eh_size,
+ void** data_base, size_t data_size,
+ void** bss_base, size_t bss_size)
+{
+ if (data_size != 0)
+ {
+ *data_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_data_tag (),
+ *data_base, data_size, false);
+ if (*data_base == NULL)
+ {
+ return false;
+ }
+ }
+
+ if (bss_size != 0)
+ {
+ *bss_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_bss_tag (),
+ *bss_base, bss_size, false);
+ if (*bss_base == NULL)
+ {
+ return false;
+ }
+ }
+
+ if (eh_size != 0)
+ {
+ *eh_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_eh_tag (),
+ *eh_base, eh_size, false);
+ if (*eh_base == NULL)
+ {
+ return false;
+ }
+ }
+
+ if (const_size != 0)
+ {
+ *const_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_const_tag (),
+ *const_base, const_size, false);
+ if (*const_base == NULL)
+ {
+ return false;
+ }
+ }
+
+ if (text_size != 0)
+ {
+ *text_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_text_tag (),
+ *text_base, text_size, false);
+ if (*text_base == NULL)
{
- rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
- data_base, bss_base);
return false;
}
}
diff --git a/cpukit/libdl/rtl-archive.c b/cpukit/libdl/rtl-archive.c
index f916336f7c..4a6d2cbf0b 100644
--- a/cpukit/libdl/rtl-archive.c
+++ b/cpukit/libdl/rtl-archive.c
@@ -1174,6 +1174,7 @@ rtems_rtl_obj_archive_find_obj (int fd,
*/
if (header[0] == '/')
{
+ const char* name_ = *name;
off_t extended_off;
switch (header[1])
@@ -1190,7 +1191,7 @@ rtems_rtl_obj_archive_find_obj (int fd,
* return the result.
*/
*extended_file_names = *ooffset + RTEMS_RTL_AR_FHDR_SIZE;
- if (*name[0] == '/' && *name[1] == '/')
+ if (name_[0] == '/' && name_[1] == '/')
{
*ooffset = *ooffset + RTEMS_RTL_AR_FHDR_SIZE;
return true;
diff --git a/cpukit/libdl/rtl-elf.c b/cpukit/libdl/rtl-elf.c
index 5754070518..dd6d8617bb 100644
--- a/cpukit/libdl/rtl-elf.c
+++ b/cpukit/libdl/rtl-elf.c
@@ -178,12 +178,19 @@ rtems_rtl_elf_find_symbol (rtems_rtl_obj* obj,
/*
* If the symbol type is STT_NOTYPE the symbol references a global
- * symbol. The gobal symbol table is searched to find it and that value
+ * symbol. The global symbol table is searched to find it and that value
* returned. If the symbol is local to the object module the section for the
* symbol is located and it's base added to the symbol's value giving an
* absolute location.
+ *
+ * If the symbols type of TLS return the symbols value. It is the
+ * offset from the thread's TLS area base. The offset is set by the
+ * linker for the base image and by the TLS allocator for loaded
+ * modules. There is no section and no absolute base.
*/
- if (ELF_ST_TYPE(sym->st_info) == STT_NOTYPE || sym->st_shndx == SHN_COMMON)
+ if (ELF_ST_TYPE (sym->st_info) == STT_NOTYPE ||
+ sym->st_shndx == SHN_COMMON ||
+ ELF_ST_TYPE (sym->st_info) == STT_TLS)
{
/*
* Search the object file then the global table for the symbol.
@@ -247,6 +254,13 @@ rtems_rtl_elf_reloc_parser (rtems_rtl_obj* obj,
rtems_rtl_elf_rel_status rs;
/*
+ * TLS are not parsed.
+ */
+ if (ELF_ST_TYPE (sym->st_info) == STT_TLS) {
+ return true;
+ }
+
+ /*
* Check the reloc record to see if a trampoline is needed.
*/
if (is_rela)
@@ -302,7 +316,7 @@ rtems_rtl_elf_reloc_parser (rtems_rtl_obj* obj,
* Find the symbol's object file. It cannot be NULL so ignore that result
* if returned, it means something is corrupted. We are in an iterator.
*/
- rtems_rtl_obj* sobj = rtems_rtl_find_obj_with_symbol (symbol);
+ rtems_rtl_obj* sobj = rtems_rtl_find_obj_with_symbol (symbol);
if (sobj != NULL)
{
/*
@@ -791,7 +805,7 @@ rtems_rtl_elf_tramp_resolve_reloc (rtems_rtl_unresolv_rec* rec,
}
if (unresolved || rs == rtems_rtl_elf_rel_tramp_add)
- tramp->obj->tramps_size += tramp->obj->tramp_size;
+ ++tramp->obj->tramp_slots;
if (rs == rtems_rtl_elf_rel_failure)
{
*failure = true;
@@ -804,7 +818,7 @@ rtems_rtl_elf_tramp_resolve_reloc (rtems_rtl_unresolv_rec* rec,
}
static bool
-rtems_rtl_elf_alloc_trampoline (rtems_rtl_obj* obj, size_t unresolved)
+rtems_rtl_elf_find_trampolines (rtems_rtl_obj* obj, size_t unresolved)
{
rtems_rtl_tramp_data td = { 0 };
td.obj = obj;
@@ -815,21 +829,20 @@ rtems_rtl_elf_alloc_trampoline (rtems_rtl_obj* obj, size_t unresolved)
if (td.failure)
return false;
rtems_rtl_trampoline_remove (obj);
- obj->tramp_relocs = obj->tramp_size == 0 ? 0 : obj->tramps_size / obj->tramp_size;
+ obj->tramp_relocs = obj->tramp_slots;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
- printf ("rtl: tramp:elf: tramps: %zu count:%zu total:%zu\n",
+ printf ("rtl: tramp:elf: tramps: slots:%zu count:%zu total:%zu\n",
obj->tramp_relocs, td.count, td.total);
/*
* Add on enough space to handle the unresolved externals that need to be
* resolved at some point in time. They could all require fixups and
* trampolines.
*/
- obj->tramps_size += obj->tramp_size * unresolved;
+ obj->tramp_slots += unresolved;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
- printf ("rtl: tramp:elf: slots: %zu (%zu)\n",
- obj->tramp_size == 0 ? 0 : obj->tramps_size / obj->tramp_size,
- obj->tramps_size);
- return rtems_rtl_obj_alloc_trampoline (obj);
+ printf ("rtl: tramp:elf: slots:%zu (%zu)\n",
+ obj->tramp_slots, obj->tramp_slots * obj->tramp_slot_size);
+ return true;
}
static bool
@@ -1716,7 +1729,7 @@ rtems_rtl_elf_file_load (rtems_rtl_obj* obj, int fd)
/*
* Set the format's architecture's maximum tramp size.
*/
- obj->tramp_size = rtems_rtl_elf_relocate_tramp_max_size ();
+ obj->tramp_slot_size = rtems_rtl_elf_relocate_tramp_max_size ();
/*
* Parse the section information first so we have the memory map of the object
@@ -1765,13 +1778,23 @@ rtems_rtl_elf_file_load (rtems_rtl_obj* obj, int fd)
if (!rtems_rtl_obj_alloc_sections (obj, fd, rtems_rtl_elf_arch_alloc, &ehdr))
return false;
- if (!rtems_rtl_obj_load_symbols (obj, fd, rtems_rtl_elf_symbols_locate, &ehdr))
+ if (!rtems_rtl_elf_dependents (obj, &relocs))
return false;
- if (!rtems_rtl_elf_dependents (obj, &relocs))
+ if (!rtems_rtl_elf_find_trampolines (obj, relocs.unresolved))
return false;
- if (!rtems_rtl_elf_alloc_trampoline (obj, relocs.unresolved))
+ /*
+ * Resize the sections to allocate the trampoline memory as part of
+ * the text section.
+ */
+ if (rtems_rtl_obj_has_trampolines (obj))
+ {
+ if (!rtems_rtl_obj_resize_sections (obj))
+ return false;
+ }
+
+ if (!rtems_rtl_obj_load_symbols (obj, fd, rtems_rtl_elf_symbols_locate, &ehdr))
return false;
/*
diff --git a/cpukit/libdl/rtl-mdreloc-aarch64.c b/cpukit/libdl/rtl-mdreloc-aarch64.c
index 46f87e9178..1eb1d1e87d 100644
--- a/cpukit/libdl/rtl-mdreloc-aarch64.c
+++ b/cpukit/libdl/rtl-mdreloc-aarch64.c
@@ -78,9 +78,11 @@ __RCSID("$NetBSD: mdreloc.c,v 1.14 2020/06/16 21:01:30 joerg Exp $");
#include "rtl-elf.h"
#include "rtl-error.h"
#include <rtems/rtl/rtl-trace.h>
-#include "rtl-unwind-arm.h"
#include <rtems/score/tls.h>
+#include "rtl-unwind.h"
+#include "rtl-unwind-dw2.h"
+
struct tls_data {
size_t td_tlsindex;
Elf_Addr td_tlsoffs;
@@ -161,6 +163,12 @@ get_veneer_size(int type)
return 16;
}
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+ (void) obj;
+ return sizeof(uint64_t);
+}
+
size_t
rtems_rtl_elf_relocate_tramp_max_size (void)
{
@@ -309,11 +317,7 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
}
if (!parsing) {
- target = (Elf_Addr)symvalue + rela->r_addend;
- /* Calculate offset accounting for the DTV */
- target -= (uintptr_t)_TLS_Data_begin;
- target += sizeof(TLS_Dynamic_thread_vector);
-
+ target = (Elf_Addr)symvalue;
target >>= shift;
target &= WIDTHMASK(12);
if (of_check && target >= of_check) {
@@ -388,6 +392,7 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
target -= (uintptr_t)where >> 12;
if (checkoverflow(target, 21, raddr, " x 4k", where, off)) {
+ printf("]] %d\n", __LINE__);
return rtems_rtl_elf_rel_failure;
}
@@ -418,6 +423,13 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
return rtems_rtl_elf_rel_failure;
}
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf (
+ "rtl: JUMP26/PC26/CALL: insn=%p where=%p target=%p raddr=%p parsing=%d\n",
+ insn, (void*) where, (void*)(uintptr_t) target, (void*)(uintptr_t) raddr,
+ parsing
+ );
+
target = (intptr_t)target >> 2;
if (((Elf_Sword)target > 0x1FFFFFF) || ((Elf_Sword)target < -0x2000000)) {
@@ -437,9 +449,8 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
return rtems_rtl_elf_rel_failure;
}
- tramp_addr = ((Elf_Addr)(uintptr_t)obj->tramp_brk) | (symvalue & 1);
+ tramp_addr = ((Elf_Addr)(uintptr_t) obj->tramp_brk) | (symvalue & 1);
obj->tramp_brk = set_veneer(obj->tramp_brk, symvalue);
-
target = tramp_addr + rela->r_addend - (uintptr_t)where;
target = (uintptr_t)target >> 2;
}
@@ -464,6 +475,7 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
raddr = (Elf_Addr)symvalue + rela->r_addend;
target = raddr - (uintptr_t)where;
if (checkoverflow(target, 32, raddr, "", where, off)) {
+ printf("]] %d\n", __LINE__);
return rtems_rtl_elf_rel_failure;
}
*where32 = target;
@@ -561,3 +573,20 @@ rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
rtems_rtl_set_error (EINVAL, "rela type record not supported");
return rtems_rtl_elf_rel_failure;
}
+
+bool
+rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
+ const char* name,
+ uint32_t flags) {
+ return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
+}
+
+bool
+rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj) {
+ return rtems_rtl_elf_unwind_dw2_register (obj);
+}
+
+bool
+rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj) {
+ return rtems_rtl_elf_unwind_dw2_deregister (obj);
+}
diff --git a/cpukit/libdl/rtl-mdreloc-arm.c b/cpukit/libdl/rtl-mdreloc-arm.c
index fbfd42dc58..16efbe79da 100644
--- a/cpukit/libdl/rtl-mdreloc-arm.c
+++ b/cpukit/libdl/rtl-mdreloc-arm.c
@@ -108,6 +108,12 @@ get_veneer_size(int type)
return 8;
}
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+ (void) obj;
+ return sizeof(uint32_t);
+}
+
size_t
rtems_rtl_elf_relocate_tramp_max_size (void)
{
@@ -526,7 +532,6 @@ rtems_rtl_elf_reloc_rel (rtems_rtl_obj* obj,
break;
case R_TYPE(TLS_LE32):
-#if ALLOW_UNTESTED_RELOCS
if (!parsing) {
addend = *where;
*where = symvalue + addend;
@@ -535,7 +540,7 @@ rtems_rtl_elf_reloc_rel (rtems_rtl_obj* obj,
(void *)*where, where, rtems_rtl_obj_oname (obj));
}
break;
-#endif
+
case R_TYPE(TLS_GD32):
case R_TYPE(TLS_LDM32):
case R_TYPE(TLS_LDO32):
diff --git a/cpukit/libdl/rtl-mdreloc-bfin.c b/cpukit/libdl/rtl-mdreloc-bfin.c
index f46b86ce34..cf3f3f88c0 100644
--- a/cpukit/libdl/rtl-mdreloc-bfin.c
+++ b/cpukit/libdl/rtl-mdreloc-bfin.c
@@ -99,6 +99,12 @@ load_ptr(void *where)
return (res);
}
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+ (void) obj;
+ return sizeof(uint32_t);
+}
+
size_t
rtems_rtl_elf_relocate_tramp_max_size (void)
{
diff --git a/cpukit/libdl/rtl-mdreloc-i386.c b/cpukit/libdl/rtl-mdreloc-i386.c
index 40b09d4be2..09cbe4f42f 100644
--- a/cpukit/libdl/rtl-mdreloc-i386.c
+++ b/cpukit/libdl/rtl-mdreloc-i386.c
@@ -64,6 +64,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
return true;
}
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+ (void) obj;
+ return sizeof(uint32_t);
+}
+
size_t
rtems_rtl_elf_relocate_tramp_max_size (void)
{
diff --git a/cpukit/libdl/rtl-mdreloc-lm32.c b/cpukit/libdl/rtl-mdreloc-lm32.c
index de0609345f..af904cd126 100644
--- a/cpukit/libdl/rtl-mdreloc-lm32.c
+++ b/cpukit/libdl/rtl-mdreloc-lm32.c
@@ -92,6 +92,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
return true;
}
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+ (void) obj;
+ return sizeof(uint32_t);
+}
+
size_t
rtems_rtl_elf_relocate_tramp_max_size (void)
{
diff --git a/cpukit/libdl/rtl-mdreloc-m68k.c b/cpukit/libdl/rtl-mdreloc-m68k.c
index 873574ef7c..a88d612c28 100644
--- a/cpukit/libdl/rtl-mdreloc-m68k.c
+++ b/cpukit/libdl/rtl-mdreloc-m68k.c
@@ -77,6 +77,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
return true;
}
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+ (void) obj;
+ return sizeof(uint32_t);
+}
+
size_t
rtems_rtl_elf_relocate_tramp_max_size (void)
{
diff --git a/cpukit/libdl/rtl-mdreloc-microblaze.c b/cpukit/libdl/rtl-mdreloc-microblaze.c
new file mode 100644
index 0000000000..0956e22bc7
--- /dev/null
+++ b/cpukit/libdl/rtl-mdreloc-microblaze.c
@@ -0,0 +1,298 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2023 On-Line Applications Research Corporation (OAR)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <rtems/rtl/rtl.h>
+#include "rtl-elf.h"
+#include "rtl-error.h"
+#include <rtems/rtl/rtl-trace.h>
+#include "rtl-unwind.h"
+#include "rtl-unwind-dw2.h"
+
+uint32_t
+rtems_rtl_elf_section_flags (const rtems_rtl_obj* obj,
+ const Elf_Shdr* shdr) {
+ (void) obj;
+ (void) shdr;
+ return 0;
+}
+
+uint32_t
+rtems_rtl_elf_arch_parse_section (const rtems_rtl_obj* obj,
+ int section,
+ const char* name,
+ const Elf_Shdr* shdr,
+ const uint32_t flags) {
+ (void) obj;
+ (void) section;
+ (void) name;
+ (void) shdr;
+ return flags;
+}
+
+bool
+rtems_rtl_elf_arch_section_alloc (const rtems_rtl_obj* obj,
+ rtems_rtl_obj_sect* sect) {
+ (void) obj;
+ (void) sect;
+ return false;
+}
+
+bool
+rtems_rtl_elf_arch_section_free (const rtems_rtl_obj* obj,
+ rtems_rtl_obj_sect* sect) {
+ (void) obj;
+ (void) sect;
+ return false;
+}
+
+bool
+rtems_rtl_elf_rel_resolve_sym (Elf_Word type) {
+ return type != 0;
+}
+
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+ (void) obj;
+ return sizeof(uint32_t);
+}
+
+size_t
+rtems_rtl_elf_relocate_tramp_max_size (void) {
+ /*
+ * Disable by returning 0.
+ */
+ return 0;
+}
+
+rtems_rtl_elf_rel_status
+rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue) {
+ (void) obj;
+ (void) rel;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ return rtems_rtl_elf_rel_no_error;
+}
+
+static void write16le(void *loc, uint16_t val) {
+ *((uint16_t *) loc) = val;
+}
+
+static void write32le(void *loc, uint32_t val) {
+ *((uint32_t *) loc) = val;
+}
+
+static uint16_t read16le(void *loc) {
+ return *((uint16_t *) loc);
+}
+
+static uint32_t read32le(void *loc) {
+ return *((uint32_t *) loc);
+}
+
+static rtems_rtl_elf_rel_status
+rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
+ const Elf_Rela* rela,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue,
+ const bool parsing) {
+ Elf_Word *where;
+ Elf_Word addend = (Elf_Word)rela->r_addend;
+ Elf_Addr target;
+
+ where = (Elf_Addr *)(sect->base + rela->r_offset);
+
+ /* Target value */
+ target = (Elf_Addr)symvalue + addend;
+ /* Final PCREL value */
+ Elf_Word pcrel_val = target - ((Elf_Word)where);
+
+ if (parsing) {
+ return rtems_rtl_elf_rel_no_error;
+ }
+
+ switch (ELF_R_TYPE(rela->r_info)) {
+ case R_TYPE(NONE):
+ break;
+
+ case R_TYPE(64):
+ /* Set the lower 16 bits of where to the upper 16 bits of target */
+ write16le(where,
+ (read16le(where) & 0xFFFF0000) | (target >> 16));
+ /* Set the lower 16 bits of where + 4 to the lower 16 bits of target */
+ write16le(where + 1,
+ (read16le(where + 1) & 0xFFFF0000) | (target & 0xFFFF));
+ break;
+
+ case R_TYPE(32):
+ {
+ uintptr_t addr = (uintptr_t)where;
+ if ((uintptr_t)where & 3) {
+ /* `where` is not aligned to a 4-byte boundary. */
+ uintptr_t addr_down = addr & ~3;
+ uintptr_t addr_up = (addr + 3) & ~3;
+
+ uint32_t value_down = read32le((void*)addr_down);
+ uint32_t value_up = read32le((void*)addr_up);
+
+ /*
+ * Calculate how many bytes `where` is offset from the previous 4-byte
+ * boundary.
+ */
+ unsigned offset = addr & 3;
+
+ /*
+ * Combine `target` with `value_down` and `value_up` to form the new
+ * values to write.
+ */
+ uint32_t new_value_down = (value_down & ((1 << (offset * 8)) - 1)) |
+ (target << (offset * 8));
+ uint32_t new_value_up = (value_up & ~((1 << (offset * 8)) - 1)) |
+ (target >> ((4 - offset) * 8));
+
+ write32le((void*)addr_down, new_value_down);
+ write32le((void*)addr_up, new_value_up);
+ } else {
+ write32le(where, target);
+ }
+ }
+ break;
+
+ case R_TYPE(32_PCREL):
+ write32le(where, pcrel_val);
+
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("rtl: R_MICROBLAZE_32_PCREL %p @ %p in %s\n",
+ (void *) * (where), where, rtems_rtl_obj_oname (obj));
+ break;
+
+ case R_TYPE(64_PCREL):
+ /*
+ * Compensate for the fact that the PC is 4 bytes ahead of the instruction
+ */
+ pcrel_val -= 4;
+ /* Set the lower 16 bits of where to the upper 16 bits of target */
+ write16le(where,
+ (read16le(where) & 0xFFFF0000) | (pcrel_val >> 16));
+ /* Set the lower 16 bits of where + 4 to the lower 16 bits of target */
+ write16le(where + 1,
+ (read16le(where + 1) & 0xFFFF0000) | (pcrel_val & 0xFFFF));
+
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("rtl: R_MICROBLAZE_64_PCREL %p @ %p in %s\n",
+ (void *) * (where), where, rtems_rtl_obj_oname (obj));
+ break;
+
+ case R_TYPE(32_PCREL_LO):
+ write16le(where, (read16le(where) & 0xFFFF0000) | (pcrel_val & 0xFFFF));
+ break;
+
+ default:
+ rtems_rtl_set_error (EINVAL,
+ "%s: Unsupported relocation type %d "
+ "in non-PLT relocations",
+ sect->name, (uint32_t) ELF_R_TYPE(rela->r_info));
+ return rtems_rtl_elf_rel_failure;
+ }
+
+ return rtems_rtl_elf_rel_no_error;
+}
+
+rtems_rtl_elf_rel_status
+rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
+ const Elf_Rela* rela,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue) {
+ return rtems_rtl_elf_reloc_rela (obj,
+ rela,
+ sect,
+ symname,
+ syminfo,
+ symvalue,
+ false);
+}
+
+rtems_rtl_elf_rel_status
+rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
+ const Elf_Rela* rela,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue) {
+ return rtems_rtl_elf_reloc_rela (obj,
+ rela,
+ sect,
+ symname,
+ syminfo,
+ symvalue,
+ true);
+}
+
+rtems_rtl_elf_rel_status
+rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue) {
+ rtems_rtl_set_error (EINVAL, "rel type record not supported");
+ return rtems_rtl_elf_rel_failure;
+}
+
+bool
+rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
+ const char* name,
+ uint32_t flags) {
+ return rtems_rtl_elf_unwind_dw2_parse (obj, name, flags);
+}
+
+bool
+rtems_rtl_elf_unwind_register (rtems_rtl_obj* obj) {
+ return rtems_rtl_elf_unwind_dw2_register (obj);
+}
+
+bool
+rtems_rtl_elf_unwind_deregister (rtems_rtl_obj* obj) {
+ return rtems_rtl_elf_unwind_dw2_deregister (obj);
+}
diff --git a/cpukit/libdl/rtl-mdreloc-mips.c b/cpukit/libdl/rtl-mdreloc-mips.c
index d43b144895..91d88c9986 100644
--- a/cpukit/libdl/rtl-mdreloc-mips.c
+++ b/cpukit/libdl/rtl-mdreloc-mips.c
@@ -93,6 +93,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
return true;
}
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+ (void) obj;
+ return sizeof(uint32_t);
+}
+
size_t
rtems_rtl_elf_relocate_tramp_max_size (void)
{
diff --git a/cpukit/libdl/rtl-mdreloc-moxie.c b/cpukit/libdl/rtl-mdreloc-moxie.c
index 6238ac99d2..a3cfe63b6a 100644
--- a/cpukit/libdl/rtl-mdreloc-moxie.c
+++ b/cpukit/libdl/rtl-mdreloc-moxie.c
@@ -93,6 +93,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
return true;
}
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+ (void) obj;
+ return sizeof(uint32_t);
+}
+
size_t
rtems_rtl_elf_relocate_tramp_max_size (void)
{
diff --git a/cpukit/libdl/rtl-mdreloc-powerpc.c b/cpukit/libdl/rtl-mdreloc-powerpc.c
index c6062c872a..09c2ab1512 100644
--- a/cpukit/libdl/rtl-mdreloc-powerpc.c
+++ b/cpukit/libdl/rtl-mdreloc-powerpc.c
@@ -207,6 +207,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
return true;
}
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+ (void) obj;
+ return sizeof(uint32_t);
+}
+
size_t
rtems_rtl_elf_relocate_tramp_max_size (void)
{
@@ -348,37 +354,47 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
break;
case R_TYPE(16_HA):
+ case R_TYPE(TPREL16_HA):
/*
* value:6; Field:half16; Expression: #ha(S+A)
+ * value:72; Field:half16; Expression: #ha(S+A)
*/
if (!parsing) {
tmp = symvalue + rela->r_addend;
*(uint16_t *)where = (((tmp >> 16) + ((tmp & 0x8000) ? 1: 0)) & 0xffff);
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
- printf ("rtl: 16_HA %p @ %p in %s\n",
+ printf ("rtl: %s16_HA %p @ %p in %s\n",
+ ELF_R_TYPE(rela->r_info) == R_TYPE(TPREL16_HA) ? "TPREL" : "",
(void *)*(where), where, rtems_rtl_obj_oname (obj));
}
break;
case R_TYPE(16_HI):
+ case R_TYPE(TPREL16_HI):
/*
* value:5; Field:half16; Expression: #hi(S+A)
+ * value:71; Field:half16; Expression: #hi(S+A)
*/
if (!parsing) {
*(uint16_t *)where = ((symvalue + rela->r_addend) >> 16) & 0xffff;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
- printf ("rtl: 16_HI %p @ %p in %s\n",
+ printf ("rtl: %s16_HI %p @ %p in %s\n",
+ ELF_R_TYPE(rela->r_info) == R_TYPE(TPREL16_HI) ? "TPREL" : "",
(void *)*where, where, rtems_rtl_obj_oname (obj));
}
break;
+
case R_TYPE(16_LO):
+ case R_TYPE(TPREL16_LO):
/*
* value:4; Field:half16; Expression: #lo(S+A)
+ * value:71; Field:half16; Expression: #lo(S+A)
*/
if (!parsing) {
*(uint16_t *)where = (symvalue + (rela->r_addend)) & 0xffff;
if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
- printf ("rtl: 16_LO %p @ %p in %s\n",
+ printf ("rtl: %s16_LO %p @ %p in %s\n",
+ ELF_R_TYPE(rela->r_info) == R_TYPE(TPREL16_LO) ? "TPREL" : "",
(void *)*where, where, rtems_rtl_obj_oname (obj));
}
break;
@@ -484,7 +500,7 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj,
(void *)rela->r_offset, (void *)*where);
rtems_rtl_set_error (EINVAL,
"%s: Unsupported relocation type %" PRId32
- "in non-PLT relocations",
+ " in non-PLT relocations",
sect->name, (uint32_t) ELF_R_TYPE(rela->r_info));
return rtems_rtl_elf_rel_failure;
}
diff --git a/cpukit/libdl/rtl-mdreloc-riscv.c b/cpukit/libdl/rtl-mdreloc-riscv.c
index e6778dcc90..c0b7556366 100644
--- a/cpukit/libdl/rtl-mdreloc-riscv.c
+++ b/cpukit/libdl/rtl-mdreloc-riscv.c
@@ -89,6 +89,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type) {
return true;
}
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+ (void) obj;
+ return sizeof(uint32_t);
+}
+
size_t
rtems_rtl_elf_relocate_tramp_max_size (void) {
/*
diff --git a/cpukit/libdl/rtl-mdreloc-sparc.c b/cpukit/libdl/rtl-mdreloc-sparc.c
index f8a4312a8a..9810de988e 100644
--- a/cpukit/libdl/rtl-mdreloc-sparc.c
+++ b/cpukit/libdl/rtl-mdreloc-sparc.c
@@ -87,46 +87,66 @@ static const uint32_t reloc_target_flags[] = {
_RF_G| _RF_SZ(32) | _RF_RS(10), /* GOT22 */
_RF_S|_RF_A|_RF_P| _RF_SZ(32) | _RF_RS(0), /* PC10 */
_RF_S|_RF_A|_RF_P| _RF_SZ(32) | _RF_RS(10), /* PC22 */
- _RF_A|_RF_P| _RF_SZ(32) | _RF_RS(2), /* WPLT30 */
- _RF_SZ(32) | _RF_RS(0), /* COPY */
+ _RF_A|_RF_P| _RF_SZ(32) | _RF_RS(2), /* WPLT30 */
+ _RF_SZ(32) | _RF_RS(0), /* COPY */
_RF_S|_RF_A| _RF_SZ(32) | _RF_RS(0), /* GLOB_DAT */
- _RF_SZ(32) | _RF_RS(0), /* JMP_SLOT */
- _RF_A| _RF_B|_RF_SZ(32) | _RF_RS(0), /* RELATIVE */
- _RF_S|_RF_A| _RF_U|_RF_SZ(32) | _RF_RS(0), /* UA_32 */
+ _RF_SZ(32) | _RF_RS(0), /* JMP_SLOT */
+ _RF_A| _RF_B| _RF_SZ(32) | _RF_RS(0), /* RELATIVE */
+ _RF_S|_RF_A|_RF_U| _RF_SZ(32) | _RF_RS(0), /* UA_32 */
+
+ /* TLS and 64 bit relocs not listed here... */
};
+#define RELOC_TARGET_FLAGS_SIZE \
+ (sizeof(reloc_target_flags) / sizeof(reloc_target_flags[0]))
-#define NOT_CURRENTLY_USED_BUT_MAYBE_USEFUL
-#ifdef NOT_CURRENTLY_USED_BUT_MAYBE_USEFUL
+#define RTLD_DEBUG_RELOC
+#ifdef RTLD_DEBUG_RELOC
static const char *reloc_names[] = {
"NONE", "RELOC_8", "RELOC_16", "RELOC_32", "DISP_8",
"DISP_16", "DISP_32", "WDISP_30", "WDISP_22", "HI22",
"22", "13", "LO10", "GOT10", "GOT13",
"GOT22", "PC10", "PC22", "WPLT30", "COPY",
- "GLOB_DAT", "JMP_SLOT", "RELATIVE", "UA_32"
+ "GLOB_DAT", "JMP_SLOT", "RELATIVE", "UA_32",
+
+ /* not used with 32bit userland, besides a few of the TLS ones */
+ "PLT32",
+ "HIPLT22", "LOPLT10", "LOPLT10", "PCPLT22", "PCPLT32",
+ "10", "11", "64", "OLO10", "HH22",
+ "HM10", "LM22", "PC_HH22", "PC_HM10", "PC_LM22",
+ "WDISP16", "WDISP19", "GLOB_JMP", "7", "5", "6",
+ "DISP64", "PLT64", "HIX22", "LOX10", "H44", "M44",
+ "L44", "REGISTER", "UA64", "UA16",
+ "TLS_GD_HI22", "TLS_GD_LO10", "TLS_GD_ADD", "TLS_GD_CALL",
+ "TLS_LDM_HI22", "TLS_LDM_LO10", "TLS_LDM_ADD", "TLS_LDM_CALL",
+ "TLS_LDO_HIX22", "TLS_LDO_LOX10", "TLS_LDO_ADD", "TLS_IE_HI22",
+ "TLS_IE_LO10", "TLS_IE_LD", "TLS_IE_LDX", "TLS_IE_ADD", "TLS_LE_HIX22",
+ "TLS_LE_LOX10", "TLS_DTPMOD32", "TLS_DTPMOD64", "TLS_DTPOFF32",
+ "TLS_DTPOFF64", "TLS_TPOFF32", "TLS_TPOFF64",
};
#endif
-#define RELOC_RESOLVE_SYMBOL(t) ((reloc_target_flags[t] & _RF_S) != 0)
-#define RELOC_PC_RELATIVE(t) ((reloc_target_flags[t] & _RF_P) != 0)
-#define RELOC_BASE_RELATIVE(t) ((reloc_target_flags[t] & _RF_B) != 0)
-#define RELOC_UNALIGNED(t) ((reloc_target_flags[t] & _RF_U) != 0)
-#define RELOC_USE_ADDEND(t) ((reloc_target_flags[t] & _RF_A) != 0)
-#define RELOC_TARGET_SIZE(t) ((reloc_target_flags[t] >> 8) & 0xff)
-#define RELOC_VALUE_RIGHTSHIFT(t) (reloc_target_flags[t] & 0xff)
+#define RELOC_RESOLVE_SYMBOL(t) ((reloc_target_flags[t] & _RF_S) != 0)
+#define RELOC_PC_RELATIVE(t) ((reloc_target_flags[t] & _RF_P) != 0)
+#define RELOC_BASE_RELATIVE(t) ((reloc_target_flags[t] & _RF_B) != 0)
+#define RELOC_UNALIGNED(t) ((reloc_target_flags[t] & _RF_U) != 0)
+#define RELOC_USE_ADDEND(t) ((reloc_target_flags[t] & _RF_A) != 0)
+#define RELOC_TARGET_SIZE(t) ((reloc_target_flags[t] >> 8) & 0xff)
+#define RELOC_VALUE_RIGHTSHIFT(t) (reloc_target_flags[t] & 0xff)
+#define RELOC_TLS(t) (t >= R_TYPE(TLS_GD_HI22))
static const int reloc_target_bitmask[] = {
#define _BM(x) (~(-(1ULL << (x))))
- 0, /* NONE */
- _BM(8), _BM(16), _BM(32), /* RELOC_8, _16, _32 */
- _BM(8), _BM(16), _BM(32), /* DISP8, DISP16, DISP32 */
- _BM(30), _BM(22), /* WDISP30, WDISP22 */
- _BM(22), _BM(22), /* HI22, _22 */
- _BM(13), _BM(10), /* RELOC_13, _LO10 */
- _BM(10), _BM(13), _BM(22), /* GOT10, GOT13, GOT22 */
- _BM(10), _BM(22), /* _PC10, _PC22 */
- _BM(30), 0, /* _WPLT30, _COPY */
- -1, -1, -1, /* _GLOB_DAT, JMP_SLOT, _RELATIVE */
- _BM(32) /* _UA32 */
+ 0, /* NONE */
+ _BM(8), _BM(16), _BM(32), /* RELOC_8, _16, _32 */
+ _BM(8), _BM(16), _BM(32), /* DISP8, DISP16, DISP32 */
+ _BM(30), _BM(22), /* WDISP30, WDISP22 */
+ _BM(22), _BM(22), /* HI22, _22 */
+ _BM(13), _BM(10), /* RELOC_13, _LO10 */
+ _BM(10), _BM(13), _BM(22), /* GOT10, GOT13, GOT22 */
+ _BM(10), _BM(22), /* _PC10, _PC22 */
+ _BM(30), 0, /* _WPLT30, _COPY */
+ -1, -1, -1, /* _GLOB_DAT, JMP_SLOT, _RELATIVE */
+ _BM(32) /* _UA32 */
#undef _BM
};
#define RELOC_VALUE_BITMASK(t) (reloc_target_bitmask[t])
@@ -173,7 +193,26 @@ rtems_rtl_elf_arch_section_free (const rtems_rtl_obj* obj,
bool
rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
{
- return RELOC_RESOLVE_SYMBOL (type) ? true : false;
+ bool r = false;
+ if (type < RELOC_TARGET_FLAGS_SIZE) {
+ r = RELOC_RESOLVE_SYMBOL (type) ? true : false;
+ }
+ switch (type) {
+ case R_TYPE(TLS_DTPOFF32):
+ case R_TYPE(TLS_LE_HIX22):
+ case R_TYPE(TLS_LE_LOX10):
+ r = true;
+ break;
+ default:
+ break;
+ }
+ return r;
+}
+
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+ (void) obj;
+ return sizeof(uint32_t);
}
size_t
@@ -241,6 +280,73 @@ rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
value = rela->r_addend;
/*
+ * Handle TLS relocations here, they are different.
+ */
+ if (RELOC_TLS(type)) {
+ switch (type) {
+ case R_TYPE(TLS_DTPMOD32):
+ #if NETBSD_CODE__NOT_USED
+ *where = (Elf_Addr)defobj->tlsindex;
+ #endif
+
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf("rtl: reloc: TLS_DTPMOD32 %s in %s --> %p\n",
+ symname, rtems_rtl_obj_oname (obj), (void *)*where);
+ break;
+
+ case R_TYPE(TLS_DTPOFF32):
+ *where = (Elf_Addr)(symvalue + rela->r_addend);
+
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf("rtl: reloc: TLS_DTPOFF32 %s in %s --> %p\n",
+ symname, rtems_rtl_obj_oname (obj), (void *)*where);
+ break;
+
+ case R_TYPE(TLS_TPOFF32):
+ #if NETBSD_CODE__NOT_USED
+ if (!defobj->tls_static &&
+ _rtld_tls_offset_allocate(__UNCONST(defobj)))
+ return ;
+
+ *where = (Elf_Addr)(def->st_value -
+ defobj->tlsoffset + rela->r_addend);
+ #endif
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf("rtl: reloc: TLS_TPOFF32 %s in %s --> %p\n",
+ symname, rtems_rtl_obj_oname (obj), (void *)*where);
+ return rtems_rtl_elf_rel_failure;
+
+ case R_TYPE(TLS_LE_HIX22):
+ *where |= ((symvalue + rela->r_addend) ^ 0xffffffff) >> 10;
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf("rtl: reloc: R_SPARC_TLS_LE_HIX22 %s in %s --> %p\n",
+ symname, rtems_rtl_obj_oname (obj), (void *)*where);
+ break;
+
+ case R_TYPE(TLS_LE_LOX10):
+ *where |= ((symvalue + rela->r_addend) & 0x3ff) | 0x1c00;
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf("rtl: reloc: R_SPARC_TLS_LE_LOX10 %s in %s --> %p\n",
+ symname, rtems_rtl_obj_oname (obj), (void *)*where);
+ break;
+
+ default:
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf("rtl: reloc: unknown TLS relo: %d for %s in %s --> %p\n",
+ type, symname, rtems_rtl_obj_oname (obj), (void *)*where);
+ return rtems_rtl_elf_rel_failure;
+ }
+ return rtems_rtl_elf_rel_no_error;
+ }
+
+ /*
+ * If it is no TLS relocation (handled above), we can not
+ * deal with it if it is beyond R_SPARC_6.
+ */
+ if (type > R_TYPE(6))
+ return rtems_rtl_elf_rel_failure;
+
+ /*
* Handle relative relocs here, as an optimization.
*/
if (type == R_TYPE (RELATIVE)) {
diff --git a/cpukit/libdl/rtl-mdreloc-v850.c b/cpukit/libdl/rtl-mdreloc-v850.c
index 8d1f3c02a7..826763a2b5 100644
--- a/cpukit/libdl/rtl-mdreloc-v850.c
+++ b/cpukit/libdl/rtl-mdreloc-v850.c
@@ -93,6 +93,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
return true;
}
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+ (void) obj;
+ return sizeof(uint32_t);
+}
+
size_t
rtems_rtl_elf_relocate_tramp_max_size (void)
{
diff --git a/cpukit/libdl/rtl-obj.c b/cpukit/libdl/rtl-obj.c
index 24d1e09048..c99e9f703f 100644
--- a/cpukit/libdl/rtl-obj.c
+++ b/cpukit/libdl/rtl-obj.c
@@ -137,7 +137,6 @@ rtems_rtl_obj_free (rtems_rtl_obj* obj)
rtems_rtl_obj_erase_sections (obj);
rtems_rtl_obj_erase_dependents (obj);
rtems_rtl_symbol_obj_erase (obj);
- rtems_rtl_obj_erase_trampoline (obj);
rtems_rtl_obj_free_names (obj);
if (obj->sec_num != NULL)
free (obj->sec_num);
@@ -600,26 +599,6 @@ rtems_rtl_obj_find_section_by_mask (const rtems_rtl_obj* obj,
}
bool
-rtems_rtl_obj_alloc_trampoline (rtems_rtl_obj* obj)
-{
- if (obj->tramps_size == 0)
- return true;
- obj->trampoline = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
- obj->tramps_size,
- true);
- if (obj->trampoline == NULL)
- rtems_rtl_set_error (ENOMEM, "no memory for the trampoline");
- obj->tramp_brk = obj->trampoline;
- return obj->trampoline != NULL;
-}
-
-void
-rtems_rtl_obj_erase_trampoline (rtems_rtl_obj* obj)
-{
- rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, obj->trampoline);
-}
-
-bool
rtems_rtl_obj_alloc_dependents (rtems_rtl_obj* obj, size_t dependents)
{
rtems_rtl_obj_depends* depends;
@@ -828,6 +807,12 @@ rtems_rtl_obj_bss_size (const rtems_rtl_obj* obj)
return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_BSS);
}
+size_t
+rtems_rtl_obj_tramp_size (const rtems_rtl_obj* obj)
+{
+ return obj->tramp_slots * obj->tramp_slot_size;
+}
+
uint32_t
rtems_rtl_obj_bss_alignment (const rtems_rtl_obj* obj)
{
@@ -919,10 +904,10 @@ rtems_rtl_obj_synchronize_cache (rtems_rtl_obj* obj)
size);
}
- if (obj->trampoline != NULL)
+ if (obj->tramp_base != NULL)
{
- rtems_cache_instruction_sync_after_code_change(obj->trampoline,
- obj->tramps_size);
+ rtems_cache_instruction_sync_after_code_change(obj->tramp_base,
+ obj->tramp_size);
}
}
@@ -1047,6 +1032,7 @@ rtems_rtl_obj_sections_locate (uint32_t mask,
{
base_offset = rtems_rtl_obj_align (base_offset, sect->alignment);
sect->base = base + base_offset;
+ base_offset += sect->size;
}
if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
@@ -1055,9 +1041,6 @@ rtems_rtl_obj_sections_locate (uint32_t mask,
order, sect->name, sect->base, sect->size,
sect->flags, sect->alignment, sect->link);
- if (sect->base)
- base_offset += sect->size;
-
++order;
node = rtems_chain_first (sections);
@@ -1069,34 +1052,95 @@ rtems_rtl_obj_sections_locate (uint32_t mask,
}
}
-bool
-rtems_rtl_obj_alloc_sections (rtems_rtl_obj* obj,
- int fd,
- rtems_rtl_obj_sect_handler handler,
- void* data)
+static void
+rtems_rtl_obj_set_sizes (rtems_rtl_obj* obj)
{
size_t text_size;
+ size_t tramp_size;
size_t const_size;
size_t eh_size;
size_t data_size;
size_t bss_size;
- text_size = rtems_rtl_obj_text_size (obj) + rtems_rtl_obj_const_alignment (obj);
- const_size = rtems_rtl_obj_const_size (obj) + rtems_rtl_obj_eh_alignment (obj);
- eh_size = rtems_rtl_obj_eh_size (obj) + rtems_rtl_obj_data_alignment (obj);
- data_size = rtems_rtl_obj_data_size (obj) + rtems_rtl_obj_bss_alignment (obj);
- bss_size = rtems_rtl_obj_bss_size (obj);
+ /*
+ * The allocator may not align memory to the required boundary. Add
+ * the alignment size to the size allocated.
+ */
+ text_size = rtems_rtl_obj_text_size (obj) + rtems_rtl_obj_text_alignment (obj);
+ tramp_size = rtems_rtl_obj_tramp_size (obj);
+ if (tramp_size != 0)
+ tramp_size += rtems_rtl_obj_tramp_alignment (obj);
+ const_size = rtems_rtl_obj_const_size (obj) + rtems_rtl_obj_const_alignment (obj);
+ eh_size = rtems_rtl_obj_eh_size (obj) + rtems_rtl_obj_eh_alignment (obj);
+ data_size = rtems_rtl_obj_data_size (obj) + rtems_rtl_obj_data_alignment (obj);
+ bss_size = rtems_rtl_obj_bss_size (obj) + rtems_rtl_obj_bss_alignment (obj);
/*
* Set the sizes held in the object data. We need this for a fast reference.
*/
- obj->text_size = text_size;
+ obj->text_size = text_size + tramp_size;
+ obj->tramp_size = tramp_size;
obj->const_size = const_size;
obj->data_size = data_size;
obj->eh_size = eh_size;
obj->bss_size = bss_size;
+ obj->exec_size = text_size + const_size + eh_size + data_size + bss_size;
+}
+
+static void
+rtems_rtl_obj_print_sizes (rtems_rtl_obj* obj, const char* label)
+{
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
+ {
+ printf ("rtl: %s sect: text - b:%p s:%zi a:%" PRIu32 "\n",
+ label, obj->text_base, obj->text_size, rtems_rtl_obj_text_alignment (obj));
+ printf ("rtl: %s sect: tramp - b:%p s:%zi a:%" PRIu32 "\n",
+ label, obj->tramp_base, obj->tramp_size, rtems_rtl_obj_tramp_alignment (obj));
+ printf ("rtl: %s sect: const - b:%p s:%zi a:%" PRIu32 "\n",
+ label, obj->const_base, obj->const_size, rtems_rtl_obj_const_alignment (obj));
+ printf ("rtl: %s sect: eh - b:%p s:%zi a:%" PRIu32 "\n",
+ label, obj->eh_base, obj->eh_size, rtems_rtl_obj_eh_alignment (obj));
+ printf ("rtl: %s sect: data - b:%p s:%zi a:%" PRIu32 "\n",
+ label, obj->data_base, obj->data_size, rtems_rtl_obj_data_alignment (obj));
+ printf ("rtl: %s sect: bss - b:%p s:%zi a:%" PRIu32 "\n",
+ label, obj->bss_base, obj->bss_size, rtems_rtl_obj_bss_alignment (obj));
+ }
+}
+
+static void
+rtems_rtl_obj_locate (rtems_rtl_obj* obj)
+{
/*
+ * Locate all text, data and bss sections in seperate operations so each type of
+ * section is grouped together.
+ */
+ rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_TEXT,
+ rtems_rtl_alloc_text_tag (),
+ obj, obj->text_base);
+ rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_CONST,
+ rtems_rtl_alloc_const_tag (),
+ obj, obj->const_base);
+ rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_EH,
+ rtems_rtl_alloc_eh_tag (),
+ obj, obj->eh_base);
+ rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_DATA,
+ rtems_rtl_alloc_data_tag (),
+ obj, obj->data_base);
+ rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_BSS,
+ rtems_rtl_alloc_bss_tag (),
+ obj, obj->bss_base);
+}
+
+bool
+rtems_rtl_obj_alloc_sections (rtems_rtl_obj* obj,
+ int fd,
+ rtems_rtl_obj_sect_handler handler,
+ void* data)
+{
+ rtems_rtl_obj_set_sizes (obj);
+
+ /*
* Perform any specific allocations for sections.
*/
if (handler != NULL)
@@ -1116,33 +1160,28 @@ rtems_rtl_obj_alloc_sections (rtems_rtl_obj* obj,
* Let the allocator manage the actual allocation. The user can use the
* standard heap or provide a specific allocator with memory protection.
*/
- if (!rtems_rtl_alloc_module_new (&obj->text_base, text_size,
- &obj->const_base, const_size,
- &obj->eh_base, eh_size,
- &obj->data_base, data_size,
- &obj->bss_base, bss_size))
+ if (!rtems_rtl_alloc_module_new (&obj->text_base, obj->text_size,
+ &obj->const_base, obj->const_size,
+ &obj->eh_base, obj->eh_size,
+ &obj->data_base, obj->data_size,
+ &obj->bss_base, obj->bss_size))
{
obj->exec_size = 0;
rtems_rtl_set_error (ENOMEM, "no memory to load obj");
return false;
}
- obj->exec_size = text_size + const_size + eh_size + data_size + bss_size;
-
- if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
+ /*
+ * Set the trampoline base if there are trampolines
+ */
+ if (obj->tramp_size != 0)
{
- printf ("rtl: load sect: text - b:%p s:%zi a:%" PRIu32 "\n",
- obj->text_base, text_size, rtems_rtl_obj_text_alignment (obj));
- printf ("rtl: load sect: const - b:%p s:%zi a:%" PRIu32 "\n",
- obj->const_base, const_size, rtems_rtl_obj_const_alignment (obj));
- printf ("rtl: load sect: eh - b:%p s:%zi a:%" PRIu32 "\n",
- obj->eh_base, eh_size, rtems_rtl_obj_eh_alignment (obj));
- printf ("rtl: load sect: data - b:%p s:%zi a:%" PRIu32 "\n",
- obj->data_base, data_size, rtems_rtl_obj_data_alignment (obj));
- printf ("rtl: load sect: bss - b:%p s:%zi a:%" PRIu32 "\n",
- obj->bss_base, bss_size, rtems_rtl_obj_bss_alignment (obj));
+ obj->tramp_base = obj->tramp_brk =
+ obj->text_base + obj->text_size - obj->tramp_size;
}
+ rtems_rtl_obj_print_sizes (obj, "alloc");
+
/*
* Determine the load order.
*/
@@ -1153,24 +1192,48 @@ rtems_rtl_obj_alloc_sections (rtems_rtl_obj* obj,
rtems_rtl_obj_sections_link_order (RTEMS_RTL_OBJ_SECT_BSS, obj);
/*
- * Locate all text, data and bss sections in seperate operations so each type of
- * section is grouped together.
+ * Locate the sections to the allocated section bases
*/
- rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_TEXT,
- rtems_rtl_alloc_text_tag (),
- obj, obj->text_base);
- rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_CONST,
- rtems_rtl_alloc_const_tag (),
- obj, obj->const_base);
- rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_EH,
- rtems_rtl_alloc_eh_tag (),
- obj, obj->eh_base);
- rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_DATA,
- rtems_rtl_alloc_data_tag (),
- obj, obj->data_base);
- rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_BSS,
- rtems_rtl_alloc_bss_tag (),
- obj, obj->bss_base);
+ rtems_rtl_obj_locate (obj);
+
+ return true;
+}
+
+bool
+rtems_rtl_obj_resize_sections (rtems_rtl_obj* obj)
+{
+ rtems_rtl_obj_set_sizes (obj);
+
+ /*
+ * Let the allocator manage the resizing.
+ */
+ if (!rtems_rtl_alloc_module_resize (&obj->text_base, obj->text_size,
+ &obj->const_base, obj->const_size,
+ &obj->eh_base, obj->eh_size,
+ &obj->data_base, obj->data_size,
+ &obj->bss_base, obj->bss_size))
+ {
+ rtems_rtl_obj_free (obj);
+ obj->exec_size = 0;
+ rtems_rtl_set_error (ENOMEM, "no memory resize obj");
+ return false;
+ }
+
+ /*
+ * Set the trampoline base if there are trampolines
+ */
+ if (obj->tramp_size != 0)
+ {
+ obj->tramp_base = obj->tramp_brk =
+ obj->text_base + obj->text_size - obj->tramp_size;
+ }
+
+ rtems_rtl_obj_print_sizes (obj, "resize");
+
+ /*
+ * Locate the sections to the allocated section bases
+ */
+ rtems_rtl_obj_locate (obj);
return true;
}
diff --git a/cpukit/libdl/rtl-shell.c b/cpukit/libdl/rtl-shell.c
index 69de6bad83..18f1e08901 100644
--- a/cpukit/libdl/rtl-shell.c
+++ b/cpukit/libdl/rtl-shell.c
@@ -572,7 +572,7 @@ rtems_rtl_obj_printer (rtems_rtl_obj_print* print, rtems_rtl_obj* obj)
rtems_printf (print->printer, "%-*cslots : %zu\n", indent + 4, ' ',
slots);
rtems_printf (print->printer, "%-*csize : %zu\n", indent + 4, ' ',
- obj->tramps_size);
+ obj->tramp_size);
rtems_printf (print->printer, "%-*cslot size : %zu\n", indent + 4, ' ',
obj->tramp_size);
rtems_printf (print->printer, "%-*cused : %zu\n", indent + 4, ' ',
diff --git a/cpukit/libdl/rtl-sym.c b/cpukit/libdl/rtl-sym.c
index 5c9c3981df..bd203fd158 100644
--- a/cpukit/libdl/rtl-sym.c
+++ b/cpukit/libdl/rtl-sym.c
@@ -77,6 +77,22 @@ rtems_rtl_symbol_global_insert (rtems_rtl_symbols* symbols,
&symbol->node);
}
+static rtems_rtl_tls_offset*
+rtems_rtl_symbol_find_tls_offset (size_t index,
+ rtems_rtl_tls_offset* tls_offsets,
+ size_t tls_size)
+{
+ size_t entry;
+ for (entry = 0; entry < tls_size; ++entry)
+ {
+ if (tls_offsets[entry].index == index)
+ {
+ return &tls_offsets[entry];
+ }
+ }
+ return NULL;
+}
+
bool
rtems_rtl_symbol_table_open (rtems_rtl_symbols* symbols,
size_t buckets)
@@ -103,9 +119,11 @@ rtems_rtl_symbol_table_close (rtems_rtl_symbols* symbols)
}
bool
-rtems_rtl_symbol_global_add (rtems_rtl_obj* obj,
- const unsigned char* esyms,
- unsigned int size)
+rtems_rtl_symbol_global_add (rtems_rtl_obj* obj,
+ const unsigned char* esyms,
+ unsigned int size,
+ rtems_rtl_tls_offset* tls_offsets,
+ unsigned int tls_size)
{
rtems_rtl_symbols* symbols;
rtems_rtl_obj_sym* sym;
@@ -159,6 +177,9 @@ rtems_rtl_symbol_global_add (rtems_rtl_obj* obj,
symbols = rtems_rtl_global_symbols ();
+ obj->global_syms = count;
+
+ count = 0;
s = 0;
sym = obj->global_table;
@@ -171,24 +192,29 @@ rtems_rtl_symbol_global_add (rtems_rtl_obj* obj,
*/
union {
uint8_t data[sizeof (void*)];
- void* value;
+ void* voidp;
} copy_voidp;
+ rtems_rtl_tls_offset* tls_off;
int b;
sym->name = (const char*) &esyms[s];
s += strlen (sym->name) + 1;
for (b = 0; b < sizeof (void*); ++b, ++s)
copy_voidp.data[b] = esyms[s];
- sym->value = copy_voidp.value;
+ tls_off = rtems_rtl_symbol_find_tls_offset (count, tls_offsets, tls_size);
+ if (tls_off == NULL) {
+ sym->value = copy_voidp.voidp;
+ } else {
+ sym->value = (void*) tls_off->offset();
+ }
if (rtems_rtl_trace (RTEMS_RTL_TRACE_GLOBAL_SYM))
printf ("rtl: esyms: %s -> %8p\n", sym->name, sym->value);
if (rtems_rtl_symbol_global_find (sym->name) == NULL)
rtems_rtl_symbol_global_insert (symbols, sym);
+ ++count;
++sym;
}
- obj->global_syms = count;
-
return true;
}
diff --git a/cpukit/score/cpu/aarch64/include/rtems/score/cpuatomic.h b/cpukit/libdl/rtl-tls.c
index ed8091d73c..7eb12831eb 100644
--- a/cpukit/score/cpu/aarch64/include/rtems/score/cpuatomic.h
+++ b/cpukit/libdl/rtl-tls.c
@@ -3,14 +3,17 @@
/**
* @file
*
- * @ingroup RTEMSScoreCPU
+ * @ingroup rtems_rtld
*
- * @brief AArch64 Atomics support
+ * @brief RTEMS Run-Time Link Editor Thread Local Storage
+ *
+ * TLS support the RTL.
*/
/*
- * Copyright (C) 2020 On-Line Applications Research Corporation (OAR)
- * Written by Kinsey Moore <kinsey.moore@oarcorp.com>
+ * COPYRIGHT (c) 2023 Chris Johns <chrisj@rtems.org>
+ *
+ * Copyright (C) 2023 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,9 +37,17 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "rtl-tls.h"
-#include <rtems/score/cpustdatomic.h>
+#include <rtems/score/cpuimpl.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/thread.h>
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
+void* rtems_rtl_tls_get_base (void)
+{
+ return _CPU_Get_TLS_thread_pointer (&_Thread_Get_executing()->Registers);
+}
diff --git a/cpukit/score/cpu/microblaze/include/rtems/score/cpuatomic.h b/cpukit/libdl/rtl-tls.h
index 6dc769b95a..78dc738dd4 100644
--- a/cpukit/score/cpu/microblaze/include/rtems/score/cpuatomic.h
+++ b/cpukit/libdl/rtl-tls.h
@@ -3,13 +3,15 @@
/**
* @file
*
- * @ingroup RTEMSScoreCPU
+ * @ingroup rtems_rtld
*
- * @brief MicroBlaze atomic support
+ * @brief RTEMS Run-Time Link Editor Thread Local Storage
+ *
+ * TLS support the RTL.
*/
/*
- * Copyright (C) 2021 On-Line Applications Research Corporation (OAR)
+ * COPYRIGHT (c) 2023 Chris Johns <chrisj@rtems.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,9 +35,17 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
+#if !defined (_RTEMS_RTL_TLS_H_)
+#define _RTEMS_RTL_TLS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+void* rtems_rtl_tls_get_base (void);
-#include <rtems/score/cpustdatomic.h>
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
+#endif
diff --git a/cpukit/libdl/rtl.c b/cpukit/libdl/rtl.c
index 21ddb00aac..8250af24c9 100644
--- a/cpukit/libdl/rtl.c
+++ b/cpukit/libdl/rtl.c
@@ -857,8 +857,10 @@ rtems_rtl_path_prepend (const char* path)
}
void
-rtems_rtl_base_sym_global_add (const unsigned char* esyms,
- unsigned int size)
+rtems_rtl_base_sym_global_add (const unsigned char* esyms,
+ unsigned int size,
+ rtems_rtl_tls_offset* tls_offsets,
+ unsigned int tls_size)
{
if (rtems_rtl_trace (RTEMS_RTL_TRACE_GLOBAL_SYM))
printf ("rtl: adding global symbols, table size %u\n", size);
@@ -869,7 +871,7 @@ rtems_rtl_base_sym_global_add (const unsigned char* esyms,
return;
}
- rtems_rtl_symbol_global_add (rtl->base, esyms, size);
+ rtems_rtl_symbol_global_add (rtl->base, esyms, size, tls_offsets, tls_size);
rtems_rtl_unlock ();
}
diff --git a/cpukit/libfs/src/dosfs/fat.c b/cpukit/libfs/src/dosfs/fat.c
index 9229406dec..88b4a2859b 100644
--- a/cpukit/libfs/src/dosfs/fat.c
+++ b/cpukit/libfs/src/dosfs/fat.c
@@ -93,7 +93,6 @@ fat_buf_release(fat_fs_info_t *fs_info)
uint32_t sec_num = fs_info->c.blk_num;
bool sec_of_fat = ((sec_num >= fs_info->vol.fat_loc) &&
(sec_num < fs_info->vol.rdir_loc));
- uint32_t blk = fat_sector_num_to_block_num(fs_info, sec_num);
uint32_t blk_ofs = fat_sector_offset_to_block_offset(fs_info,
sec_num,
0);
@@ -115,6 +114,7 @@ fat_buf_release(fat_fs_info_t *fs_info)
for (i = 1; i < fs_info->vol.fats; i++)
{
rtems_bdbuf_buffer *bd;
+ uint32_t blk;
sec_num = fs_info->c.blk_num + fs_info->vol.fat_length * i,
blk = fat_sector_num_to_block_num(fs_info, sec_num);
diff --git a/cpukit/libfs/src/dosfs/fat_fat_operations.c b/cpukit/libfs/src/dosfs/fat_fat_operations.c
index 24a408f9c7..fe6bbf03ce 100644
--- a/cpukit/libfs/src/dosfs/fat_fat_operations.c
+++ b/cpukit/libfs/src/dosfs/fat_fat_operations.c
@@ -203,9 +203,9 @@ fat_free_fat_clusters_chain(
cur_cln = next_cln;
}
- fs_info->vol.next_cl = chain;
- if (fs_info->vol.free_cls != FAT_UNDEFINED_VALUE)
- fs_info->vol.free_cls += freed_cls_cnt;
+ fs_info->vol.next_cl = chain;
+ if (fs_info->vol.free_cls != FAT_UNDEFINED_VALUE)
+ fs_info->vol.free_cls += freed_cls_cnt;
fat_buf_release(fs_info);
if (rc1 != RC_OK)
@@ -356,7 +356,7 @@ fat_set_fat_cluster(
if (rc != RC_OK)
return rc;
- *sec_buf &= 0x00;
+ *sec_buf = 0x00;
*sec_buf |= (uint8_t)((fat16_clv & 0xFF00)>>8);
@@ -364,7 +364,7 @@ fat_set_fat_cluster(
}
else
{
- *(sec_buf + ofs + 1) &= 0x00;
+ *(sec_buf + ofs + 1) = 0x00;
*(sec_buf + ofs + 1) |= (uint8_t )((fat16_clv & 0xFF00)>>8);
}
@@ -372,7 +372,7 @@ fat_set_fat_cluster(
else
{
fat16_clv = ((uint16_t )in_val) & FAT_FAT12_MASK;
- *(sec_buf + ofs) &= 0x00;
+ *(sec_buf + ofs) = 0x00;
*(sec_buf + ofs) |= (uint8_t)(fat16_clv & 0x00FF);
diff --git a/cpukit/libfs/src/dosfs/msdos_create.c b/cpukit/libfs/src/dosfs/msdos_create.c
index 26df0451c9..f71969f787 100644
--- a/cpukit/libfs/src/dosfs/msdos_create.c
+++ b/cpukit/libfs/src/dosfs/msdos_create.c
@@ -202,7 +202,7 @@ msdos_creat_node(const rtems_filesystem_location_info_t *parent_loc,
fs_info->fat.vol.bpc,
&unused);
if (rc != RC_OK)
- goto err;
+ goto error;
/*
* dot and dotdot entries are identical to new node except the
diff --git a/cpukit/libfs/src/dosfs/msdos_dir.c b/cpukit/libfs/src/dosfs/msdos_dir.c
index 4ae2c32415..d9585635d9 100644
--- a/cpukit/libfs/src/dosfs/msdos_dir.c
+++ b/cpukit/libfs/src/dosfs/msdos_dir.c
@@ -339,14 +339,14 @@ msdos_dir_read(rtems_libio_t *iop, void *buffer, size_t count)
iop->offset = iop->offset + sizeof(struct dirent);
cmpltd += (sizeof(struct dirent));
count -= (sizeof(struct dirent));
+ }
- /* inode number extracted, close fat-file */
- rc = fat_file_close(&fs_info->fat, tmp_fat_fd);
- if (rc != RC_OK)
- {
- msdos_fs_unlock(fs_info);
- return rc;
- }
+ /* inode number extracted, close fat-file */
+ rc = fat_file_close(&fs_info->fat, tmp_fat_fd);
+ if (rc != RC_OK)
+ {
+ msdos_fs_unlock(fs_info);
+ return rc;
}
}
diff --git a/cpukit/libfs/src/dosfs/msdos_file.c b/cpukit/libfs/src/dosfs/msdos_file.c
index d142968337..e25f292484 100644
--- a/cpukit/libfs/src/dosfs/msdos_file.c
+++ b/cpukit/libfs/src/dosfs/msdos_file.c
@@ -179,7 +179,7 @@ msdos_file_ftruncate(rtems_libio_t *iop, off_t length)
length,
&new_length);
if (rc == RC_OK && length != new_length) {
- fat_file_truncate(&fs_info->fat, fat_fd, old_length);
+ (void) fat_file_truncate(&fs_info->fat, fat_fd, old_length);
errno = ENOSPC;
rc = -1;
}
@@ -223,6 +223,11 @@ msdos_file_sync(rtems_libio_t *iop)
}
rc = fat_sync(&fs_info->fat);
+ if (rc != RC_OK)
+ {
+ msdos_fs_unlock(fs_info);
+ return rc;
+ }
msdos_fs_unlock(fs_info);
diff --git a/cpukit/libfs/src/dosfs/msdos_misc.c b/cpukit/libfs/src/dosfs/msdos_misc.c
index 8bde792ae5..cd59c494ea 100644
--- a/cpukit/libfs/src/dosfs/msdos_misc.c
+++ b/cpukit/libfs/src/dosfs/msdos_misc.c
@@ -288,7 +288,6 @@ msdos_long_to_short(rtems_dosfs_convert_control *converter,
&codepage_name_len);
if (eno == EINVAL)
{
- eno = 0;
type = MSDOS_NAME_LONG;
}
else
@@ -1304,7 +1303,6 @@ static int
msdos_find_file_in_directory (
const uint8_t *filename_converted,
const size_t name_len_for_compare,
- const size_t name_len_for_save,
const msdos_name_type_t name_type,
msdos_fs_info_t *fs_info,
fat_file_fd_t *fat_fd,
@@ -1747,6 +1745,8 @@ msdos_add_file (
/* Get position of short file name entry */
ret = msdos_get_pos(fs_info, fat_fd, bts2rd, short_file_offset,
&dir_pos->sname);
+ if (ret != RC_OK)
+ return ret;
/*
* Handle the entry writes.
@@ -1918,7 +1918,6 @@ msdos_find_name_in_fat_file (
retval = msdos_find_file_in_directory (
buffer,
name_len_for_compare,
- name_len_for_save,
name_type,
fs_info,
fat_fd,
diff --git a/cpukit/libfs/src/dosfs/msdos_mknod.c b/cpukit/libfs/src/dosfs/msdos_mknod.c
index 934805c5f1..8fe01e4985 100644
--- a/cpukit/libfs/src/dosfs/msdos_mknod.c
+++ b/cpukit/libfs/src/dosfs/msdos_mknod.c
@@ -44,7 +44,7 @@ int msdos_mknod(
)
{
int rc = RC_OK;
- fat_file_type_t type = 0;
+ fat_file_type_t type = FAT_DIRECTORY;
/*
* Figure out what type of msdos node this is.
diff --git a/cpukit/libfs/src/imfs/imfs_load_tar.c b/cpukit/libfs/src/imfs/imfs_load_tar.c
index ec651d820a..18c5366b56 100644
--- a/cpukit/libfs/src/imfs/imfs_load_tar.c
+++ b/cpukit/libfs/src/imfs/imfs_load_tar.c
@@ -45,7 +45,7 @@
int rtems_tarfs_load(
const char *mountpoint,
- uint8_t *tar_image,
+ const void *tar_image,
size_t tar_size
)
{
@@ -57,6 +57,7 @@ int rtems_tarfs_load(
size_t len;
Untar_HeaderContext ctx;
unsigned long ptr;
+ const uint8_t *image;
len = strlen( mountpoint );
if ( len >= sizeof( buf ) - UNTAR_FILE_NAME_SIZE - 2 ) {
@@ -82,11 +83,12 @@ int rtems_tarfs_load(
}
ptr = 0;
+ image = tar_image;
while ( ptr + 512 <= tar_size ) {
int retval;
- retval = Untar_ProcessHeader( &ctx, (const char *) &tar_image[ ptr ] );
+ retval = Untar_ProcessHeader( &ctx, (const char *) &image[ ptr ] );
if ( retval != UNTAR_SUCCESSFUL ) {
return -1;
}
@@ -97,7 +99,7 @@ int rtems_tarfs_load(
retval = IMFS_make_linearfile(
ctx.file_path,
ctx.mode,
- &tar_image[ ptr ],
+ &image[ ptr ],
ctx.file_size
);
if ( retval != 0 ) {
diff --git a/cpukit/libfs/src/imfs/imfs_memfile.c b/cpukit/libfs/src/imfs/imfs_memfile.c
index 66c67c6ba0..3930fd6ae5 100644
--- a/cpukit/libfs/src/imfs/imfs_memfile.c
+++ b/cpukit/libfs/src/imfs/imfs_memfile.c
@@ -638,7 +638,6 @@ ssize_t IMFS_memfile_write(
fprintf(stdout, "write %d in %d: %*s\n", to_copy, block, to_copy, src );
#endif
memcpy( &(*block_ptr)[ 0 ], src, my_length );
- my_length = 0;
copied += to_copy;
}
diff --git a/cpukit/libfs/src/jffs2/include/linux/mutex.h b/cpukit/libfs/src/jffs2/include/linux/mutex.h
index be8709f125..cc82a3f17a 100644
--- a/cpukit/libfs/src/jffs2/include/linux/mutex.h
+++ b/cpukit/libfs/src/jffs2/include/linux/mutex.h
@@ -1,19 +1,30 @@
#ifndef __LINUX_MUTEX_H
#define __LINUX_MUTEX_H
-#include <rtems/thread.h>
-
-struct mutex { rtems_mutex r_m; };
+struct mutex { };
#define DEFINE_MUTEX(m) struct mutex m
-#define mutex_init(m) rtems_mutex_init(&(m)->r_m, "JFFS2 Mutex");
-
-#define mutex_lock(m) rtems_mutex_lock(&(m)->r_m);
-
-#define mutex_lock_interruptible(m) ({ mutex_lock(m); 0; })
-
-#define mutex_unlock(m) rtems_mutex_unlock(&(m)->r_m);
+static inline void mutex_init(struct mutex *m)
+{
+ (void) m;
+}
+
+static inline void mutex_lock(struct mutex *m)
+{
+ (void) m;
+}
+
+static inline int mutex_lock_interruptible(struct mutex *m)
+{
+ (void) m;
+ return 0;
+}
+
+static inline void mutex_unlock(struct mutex *m)
+{
+ (void) m;
+}
#define mutex_is_locked(m) 1
diff --git a/cpukit/libfs/src/jffs2/include/linux/rwsem.h b/cpukit/libfs/src/jffs2/include/linux/rwsem.h
index 9db6d45ad2..e59e1cede3 100644
--- a/cpukit/libfs/src/jffs2/include/linux/rwsem.h
+++ b/cpukit/libfs/src/jffs2/include/linux/rwsem.h
@@ -1,20 +1,16 @@
#ifndef __LINUX_RWSEM_H__
#define __LINUX_RWSEM_H__
-#include <pthread.h>
+struct rw_semaphore {};
-struct rw_semaphore {
- pthread_rwlock_t lock;
-};
+#define init_rwsem(rwsem)
-#define init_rwsem(rwsem) pthread_rwlock_init(&(rwsem)->lock, NULL)
+#define down_read(rwsem)
-#define down_read(rwsem) pthread_rwlock_rdlock(&(rwsem)->lock)
+#define down_write(rwsem)
-#define down_write(rwsem) pthread_rwlock_wrlock(&(rwsem)->lock)
+#define up_read(rwsem)
-#define up_read(rwsem) pthread_rwlock_unlock(&(rwsem)->lock)
-
-#define up_write(rwsem) pthread_rwlock_unlock(&(rwsem)->lock)
+#define up_write(rwsem)
#endif /* __LINUX_RWSEM_H__ */
diff --git a/cpukit/libfs/src/jffs2/include/linux/workqueue.h b/cpukit/libfs/src/jffs2/include/linux/workqueue.h
index 45a2942bfc..9811c7cd3e 100644
--- a/cpukit/libfs/src/jffs2/include/linux/workqueue.h
+++ b/cpukit/libfs/src/jffs2/include/linux/workqueue.h
@@ -2,6 +2,7 @@
#define __LINUX_WORKQUEUE_H__
#include <rtems/chain.h>
+#include <linux/mutex.h>
struct work_struct { rtems_chain_node node; };
@@ -11,7 +12,6 @@ struct work_struct { rtems_chain_node node; };
})
#define INIT_DELAYED_WORK(delayed_work, delayed_workqueue_callback) ({ \
- _Chain_Initialize_node(&(delayed_work)->work.node); \
(delayed_work)->callback = delayed_workqueue_callback; \
})
@@ -20,8 +20,12 @@ struct work_struct { rtems_chain_node node; };
typedef void (*work_callback_t)(struct work_struct *work);
struct delayed_work {
struct work_struct work;
- uint64_t execution_time;
+ struct mutex dw_mutex;
+ volatile bool pending;
+ volatile uint64_t execution_time;
work_callback_t callback;
+ /* Superblock provided for locking */
+ struct super_block *sb;
};
#define to_delayed_work(work) RTEMS_CONTAINER_OF(work, struct delayed_work, work)
diff --git a/cpukit/libfs/src/jffs2/src/fs-rtems.c b/cpukit/libfs/src/jffs2/src/fs-rtems.c
index 59d03effe6..029cba6618 100644
--- a/cpukit/libfs/src/jffs2/src/fs-rtems.c
+++ b/cpukit/libfs/src/jffs2/src/fs-rtems.c
@@ -579,6 +579,9 @@ static int rtems_jffs2_ioctl(
break;
case RTEMS_JFFS2_FORCE_GARBAGE_COLLECTION:
eno = -jffs2_garbage_collect_pass(&inode->i_sb->jffs2_sb);
+ if (!eno) {
+ eno = -jffs2_flush_wbuf_pad(&inode->i_sb->jffs2_sb);
+ }
break;
default:
eno = EINVAL;
@@ -1066,6 +1069,7 @@ static void rtems_jffs2_fsunmount(rtems_filesystem_mount_table_entry_t *mt_entry
/* Flush any pending writes */
if (!sb_rdonly(&fs_info->sb)) {
jffs2_flush_wbuf_gc(c, 0);
+ jffs2_flush_wbuf_pad(c);
}
#endif
@@ -1241,39 +1245,41 @@ rtems_chain_control delayed_work_chain;
/* Lock for protecting the delayed work chain */
struct mutex delayed_work_mutex;
-void jffs2_queue_delayed_work(struct delayed_work *work, int delay_ms)
+/*
+ * All delayed work structs are initialized and added to the chain during FS
+ * init. Must be called with no locks held
+ */
+static void add_delayed_work_to_chain(struct delayed_work *work)
{
+ /* Initialize delayed work */
+ mutex_init(&work->dw_mutex);
+ work->pending = false;
+ _Chain_Initialize_node(&work->work.node); \
+ work->callback = NULL;
+
mutex_lock(&delayed_work_mutex);
- if (rtems_chain_is_node_off_chain(&work->work.node)) {
- work->execution_time = rtems_clock_get_uptime_nanoseconds() + delay_ms*1000000;
- rtems_chain_append(&delayed_work_chain, &work->work.node);
- }
+ rtems_chain_append_unprotected(&delayed_work_chain, &work->work.node);
mutex_unlock(&delayed_work_mutex);
}
-static void jffs2_remove_delayed_work(struct delayed_work *dwork)
+void jffs2_queue_delayed_work(struct delayed_work *work, int delay_ms)
{
- struct delayed_work* work;
- rtems_chain_node* node;
-
- mutex_lock(&delayed_work_mutex);
- if (rtems_chain_is_node_off_chain(&dwork->work.node)) {
- mutex_unlock(&delayed_work_mutex);
- return;
+ mutex_lock(&work->dw_mutex);
+ if (!work->pending) {
+ work->execution_time = rtems_clock_get_uptime_nanoseconds();
+ work->execution_time += delay_ms*1000000;
+ work->pending = true;
}
+ mutex_unlock(&work->dw_mutex);
+}
- node = rtems_chain_first(&delayed_work_chain);
- while (!rtems_chain_is_tail(&delayed_work_chain, node)) {
- work = (struct delayed_work*) node;
- rtems_chain_node* next_node = rtems_chain_next(node);
- if (work == dwork) {
- rtems_chain_extract(node);
- mutex_unlock(&delayed_work_mutex);
- return;
- }
- node = next_node;
- }
+/* Clean up during FS unmount */
+static void jffs2_remove_delayed_work(struct delayed_work *dwork)
+{
+ mutex_lock(&delayed_work_mutex);
+ rtems_chain_extract_unprotected(&dwork->work.node);
mutex_unlock(&delayed_work_mutex);
+ /* Don't run pending delayed work, this will happen during unmount */
}
static void process_delayed_work(void)
@@ -1291,15 +1297,27 @@ static void process_delayed_work(void)
node = rtems_chain_first(&delayed_work_chain);
while (!rtems_chain_is_tail(&delayed_work_chain, node)) {
work = (struct delayed_work*) node;
- rtems_chain_node* next_node = rtems_chain_next(node);
- if (rtems_clock_get_uptime_nanoseconds() >= work->execution_time) {
- rtems_chain_extract(node);
- work->callback(&work->work);
+ node = rtems_chain_next(node);
+
+ if (!work->pending) {
+ continue;
+ }
+
+ if (rtems_clock_get_uptime_nanoseconds() < work->execution_time) {
+ continue;
}
- node = next_node;
+
+ mutex_lock(&work->dw_mutex);
+ work->pending = false;
+ mutex_unlock(&work->dw_mutex);
+
+ rtems_jffs2_do_lock(work->sb);
+ work->callback(&work->work);
+ rtems_jffs2_do_unlock(work->sb);
}
mutex_unlock(&delayed_work_mutex);
}
+
/* Task for processing delayed work */
static rtems_task delayed_work_task(
rtems_task_argument unused
@@ -1308,7 +1326,7 @@ static rtems_task delayed_work_task(
(void)unused;
while (1) {
process_delayed_work();
- sleep(1);
+ usleep(1);
}
}
@@ -1369,6 +1387,12 @@ int rtems_jffs2_initialize(
if (err == 0) {
sb = &fs_info->sb;
c = JFFS2_SB_INFO(sb);
+#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
+ c->wbuf_dwork.sb = sb;
+ add_delayed_work_to_chain(&c->wbuf_dwork);
+#endif
+ spin_lock_init(&c->erase_completion_lock);
+ spin_lock_init(&c->inocache_lock);
c->mtd = NULL;
rtems_recursive_mutex_init(&sb->s_mutex, RTEMS_FILESYSTEM_TYPE_JFFS2);
}
@@ -1455,6 +1479,9 @@ int rtems_jffs2_initialize(
return 0;
} else {
if (fs_info != NULL) {
+#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
+ jffs2_remove_delayed_work(&c->wbuf_dwork);
+#endif
free(c->mtd);
c->mtd = NULL;
rtems_jffs2_free_fs_info(fs_info, do_mount_fs_was_successful);
@@ -1503,6 +1530,8 @@ static struct _inode *new_inode(struct super_block *sb)
inode->i_cache_next = NULL; // Newest inode, about to be cached
+ mutex_init(&JFFS2_INODE_INFO(inode)->sem);
+
// Add to the icache
for (cached_inode = sb->s_root; cached_inode != NULL;
cached_inode = cached_inode->i_cache_next) {
@@ -1619,8 +1648,14 @@ void jffs2_iput(struct _inode *i)
static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
{
- memset(f, 0, sizeof(*f));
- mutex_init(&f->sem);
+ /* These must be set manually to preserve other members */
+ f->highest_version = 0;
+ f->fragtree = RB_ROOT;
+ f->metadata = NULL;
+ f->dents = NULL;
+ f->target = NULL;
+ f->flags = 0;
+ f->usercompr = 0;
}
static void jffs2_clear_inode (struct _inode *inode)
diff --git a/cpukit/libfs/src/jffs2/src/jffs2_fs_sb.h b/cpukit/libfs/src/jffs2/src/jffs2_fs_sb.h
index 4ee43a6f30..7960f92f85 100644
--- a/cpukit/libfs/src/jffs2/src/jffs2_fs_sb.h
+++ b/cpukit/libfs/src/jffs2/src/jffs2_fs_sb.h
@@ -75,6 +75,9 @@ struct jffs2_sb_info {
uint32_t bad_size;
uint32_t sector_size;
uint32_t unchecked_size;
+#ifdef __rtems__
+ uint32_t obsolete_size;
+#endif
uint32_t nr_free_blocks;
uint32_t nr_erasing_blocks;
diff --git a/cpukit/libfs/src/jffs2/src/os-rtems.h b/cpukit/libfs/src/jffs2/src/os-rtems.h
index 63841a5e50..4bc6f5df13 100644
--- a/cpukit/libfs/src/jffs2/src/os-rtems.h
+++ b/cpukit/libfs/src/jffs2/src/os-rtems.h
@@ -100,6 +100,10 @@ struct _inode {
struct super_block {
struct jffs2_sb_info jffs2_sb;
+ /*
+ * If granular locking is ever enabled for JFFS2, the inode cache
+ * (s_root) needs to be protected due to NAND delayed writes.
+ */
struct _inode * s_root;
rtems_jffs2_flash_control *s_flash_control;
rtems_jffs2_compressor_control *s_compressor_control;
diff --git a/cpukit/libfs/src/jffs2/src/scan.c b/cpukit/libfs/src/jffs2/src/scan.c
index 10663feb1f..8ac4a40414 100644
--- a/cpukit/libfs/src/jffs2/src/scan.c
+++ b/cpukit/libfs/src/jffs2/src/scan.c
@@ -264,14 +264,32 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
}
#endif
if (c->nr_erasing_blocks) {
+#ifdef __rtems__
+ if (c->obsolete_size != c->dirty_size) {
+#endif
if (!c->used_size && !c->unchecked_size &&
((c->nr_free_blocks+empty_blocks+bad_blocks) != c->nr_blocks || bad_blocks == c->nr_blocks)) {
pr_notice("Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n");
pr_notice("empty_blocks %d, bad_blocks %d, c->nr_blocks %d\n",
empty_blocks, bad_blocks, c->nr_blocks);
+#ifdef __rtems__
+ pr_notice("nr_erasing_blocks %d, used 0x%x, dirty 0x%x, wasted 0x%x, free 0x%x, erasing 0x%x, bad 0x%x, obsolete 0x%x, unchecked 0x%x\n",
+ c->nr_erasing_blocks,
+ c->used_size,
+ c->dirty_size,
+ c->wasted_size,
+ c->free_size,
+ c->erasing_size,
+ c->bad_size,
+ c->obsolete_size,
+ c->unchecked_size);
+#endif
ret = -EIO;
goto out;
}
+#ifdef __rtems__
+ }
+#endif
spin_lock(&c->erase_completion_lock);
jffs2_garbage_collect_trigger(c);
spin_unlock(&c->erase_completion_lock);
@@ -646,6 +664,9 @@ scan_more:
sizeof(struct jffs2_unknown_node),
jeb->offset, c->sector_size, ofs,
sizeof(*node));
+#ifdef __rtems__
+ c->obsolete_size += (jeb->offset + c->sector_size - ofs);
+#endif
if ((err = jffs2_scan_dirty_space(c, jeb, (jeb->offset + c->sector_size)-ofs)))
return err;
break;
@@ -796,6 +817,9 @@ scan_more:
if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen)))))
return err;
ofs += PAD(je32_to_cpu(node->totlen));
+#ifdef __rtems__
+ c->obsolete_size += PAD(je32_to_cpu(node->totlen));
+#endif
continue;
}
diff --git a/cpukit/libmisc/regulator/regulator.c b/cpukit/libmisc/regulator/regulator.c
new file mode 100644
index 0000000000..97a48be4f5
--- /dev/null
+++ b/cpukit/libmisc/regulator/regulator.c
@@ -0,0 +1,680 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @brief Regulator Library Implementation
+ */
+
+/*
+ * Copyright (C) 2022 On-Line Applications Research Corporation (OAR)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+
+#include <rtems.h>
+#include <rtems/regulator.h>
+#include <string.h>
+
+#include <rtems/regulatorimpl.h>
+
+/**
+ * @ingroup RegulatorInternalAPI
+ *
+ * This method is the body for the task which delivers the output for
+ * this regulator instance at the configured rate.
+ *
+ * @param[in] arg points to the regulator instance this thread
+ * is associated with
+ *
+ * @note The argument passed in cannot be NULL if the
+ * rtems_regulator_create worked.
+ */
+static rtems_task _Regulator_Output_task_body(
+ rtems_task_argument arg
+)
+{
+ _Regulator_Control *the_regulator = (_Regulator_Control *)arg;
+ rtems_status_code sc;
+ size_t to_dequeue;
+ _Regulator_Message_t regulator_message;
+ size_t regulator_message_size;
+ bool release_it;
+
+ the_regulator->delivery_thread_is_running = true;
+
+ /**
+ * This thread uses a rate monotonic period object instance. A rate
+ * monotonic period object must be created by the thread using it.
+ * It can be deleted by any thread which simplifies clean up.
+ *
+ * The rate_monotonic_create() call can fail if the application
+ * is incorrectly configured. This thread has no way to report the
+ * failure. If it continues with an invalid id, then the thread will
+ * not block on the period and spin continuously consuming CPU. The only
+ * alternatives are to invoke rtems_fatal_error_occurred() or silently
+ * exit the thread.
+ */
+ sc = rtems_rate_monotonic_create(
+ rtems_build_name('P', 'E', 'R', 'D'),
+ &the_regulator->delivery_thread_period_id
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ goto exit_delivery_thread;
+ }
+
+ /**
+ * Loop on the rate_monotonic_period() based on the specified period.
+ */
+ while (1) {
+ sc = rtems_rate_monotonic_period(
+ the_regulator->delivery_thread_period_id,
+ the_regulator->Attributes.delivery_thread_period
+ );
+ _Assert_Unused_variable_equals(sc, RTEMS_SUCCESSFUL);
+
+ /**
+ * If the delivery thread has been requested to exit, then
+ * quit processing messages, break out of this loop, and exit
+ * this thread.
+ */
+ if (the_regulator->delivery_thread_request_exit) {
+ break;
+ }
+
+ /**
+ * Loop for the configured number of messages to deliver per period.
+ * If we reach the point, there are no more messages, block for the
+ * rest of this period. If there are messages, deliver them.
+ */
+ for (to_dequeue = 0;
+ to_dequeue < the_regulator->Attributes.maximum_to_dequeue_per_period;
+ to_dequeue++) {
+ regulator_message_size = sizeof(_Regulator_Message_t);
+ sc = rtems_message_queue_receive(
+ the_regulator->queue_id,
+ &regulator_message,
+ &regulator_message_size,
+ RTEMS_NO_WAIT,
+ 0
+ );
+ _Assert_Unused_variable_equals(sc, RTEMS_SUCCESSFUL);
+ if (sc != RTEMS_SUCCESSFUL) {
+ break;
+ }
+
+ release_it = the_regulator->Attributes.deliverer(
+ the_regulator->Attributes.deliverer_context,
+ regulator_message.buffer,
+ regulator_message.length
+ );
+
+ the_regulator->Statistics.delivered++;
+
+ /**
+ * The message was successfully delivered. If the delivery function
+ * wants the buffer returned, do it now. The delivery to the Destination
+ * may involve handing the buffer off to something like DMA
+ * and need to wait for it to complete before releasing the buffer.
+ *
+ * Note that this is the underlying RTEMS service
+ * used by @a rtems_regulator_obtain_buffer() and @a
+ * rtems_regulator_release_buffer().
+ */
+ if (release_it == true) {
+ the_regulator->Statistics.released++;
+ sc = rtems_partition_return_buffer(
+ the_regulator->messages_partition_id,
+ regulator_message.buffer
+ );
+ _Assert_Unused_variable_equals(sc, RTEMS_SUCCESSFUL);
+ }
+ }
+ }
+
+ /**
+ * This thread was requested to exit. Do so.
+ */
+exit_delivery_thread:
+ the_regulator->delivery_thread_is_running = false;
+ the_regulator->delivery_thread_has_exited = true;
+
+ (void) rtems_rate_monotonic_delete(the_regulator->delivery_thread_period_id);
+
+ rtems_task_exit();
+}
+
+/**
+ * @ingroup RegulatorInternalAPI
+ *
+ * This method frees the resources associated with a regulator instance.
+ * The resources are freed in the opposite of the order in which they are
+ * allocated. This is used on error cases in @a rtems_regulator_create() and in
+ * @a rtems_regulator_delete().
+ *
+ * @param[in] the_regulator is the instance to operate upon
+ * @param[in] ticks is the length of time to wait for the delivery thread
+ * to exit
+ *
+ * @return This method returns true is successful and false on timeout.
+ */
+static bool _Regulator_Free_helper(
+ _Regulator_Control *the_regulator,
+ rtems_interval ticks
+)
+{
+ rtems_status_code sc;
+
+
+ /*
+ * If the output thread has not started running, then we can just delete it.
+ */
+
+ if (ticks == 0 || the_regulator->delivery_thread_is_running == false) {
+ sc = rtems_task_delete(the_regulator->delivery_thread_id);
+ _Assert_Unused_variable_equals(sc, RTEMS_SUCCESSFUL);
+ } else {
+ rtems_interval remaining = ticks;
+
+ the_regulator->delivery_thread_request_exit = true;
+
+ while (1) {
+ if (the_regulator->delivery_thread_has_exited) {
+ break;
+ }
+
+ if (remaining == 0) {
+ return false;
+ }
+
+ (void) rtems_task_wake_after(1);
+ remaining--;
+ }
+ }
+
+ /*
+ * The output thread deletes the rate monotonic period that it created.
+ */
+
+ /*
+ * The regulator's message_queue_storage is implicitly freed by this call.
+ */
+ sc = rtems_message_queue_delete(the_regulator->queue_id);
+ _Assert_Unused_variable_equals(sc, RTEMS_SUCCESSFUL);
+
+ sc = rtems_partition_delete(the_regulator->messages_partition_id);
+ _Assert_Unused_variable_equals(sc, RTEMS_SUCCESSFUL);
+
+ if (the_regulator->message_memory) {
+ free(the_regulator->message_memory);
+ }
+
+ the_regulator->initialized = 0;
+ free(the_regulator);
+ return true;
+}
+
+/**
+ * @ingroup RegulatorInternalAPI
+ */
+rtems_status_code rtems_regulator_create(
+ rtems_regulator_attributes *attributes,
+ rtems_regulator_instance **regulator
+)
+{
+ _Regulator_Control *the_regulator;
+ rtems_status_code sc;
+ size_t alloc_size;
+
+ /**
+ * Perform basic validation of parameters
+ */
+ if (attributes == NULL) {
+ return RTEMS_INVALID_ADDRESS;
+ }
+
+ if (regulator == NULL) {
+ return RTEMS_INVALID_ADDRESS;
+ }
+
+ /**
+ * Verify attributes are OK. Some are checked by calls to object create
+ * methods. Specifically the following are not checked:
+ *
+ * - delivery_thread_priority by rtems_task_create()
+ * - delivery_thread_stack_size can be any value
+ */
+ if (attributes->deliverer == NULL) {
+ return RTEMS_INVALID_ADDRESS;
+ }
+
+ if (attributes->maximum_messages == 0) {
+ return RTEMS_INVALID_NUMBER;
+ }
+
+ if (attributes->maximum_message_size == 0) {
+ return RTEMS_INVALID_SIZE;
+ }
+
+ if (attributes->maximum_to_dequeue_per_period == 0) {
+ return RTEMS_INVALID_NUMBER;
+ }
+
+ if (attributes->delivery_thread_period == 0) {
+ return RTEMS_INVALID_NUMBER;
+ }
+
+ /**
+ * Allocate memory for regulator instance
+ */
+ the_regulator = (_Regulator_Control *) calloc(sizeof(_Regulator_Control), 1);
+ if (the_regulator == NULL) {
+ return RTEMS_NO_MEMORY;
+ }
+
+ /**
+ * We do NOT want the delivery_thread_id field to be initialized to 0. If the
+ * @a rtems_task_create() fails, then the field will not be overwritten.
+ * This results in an attempt to rtems_task_delete(0) during clean
+ * up. The thread ID of 0 is self which results in the calling thread
+ * accidentally deleting itself.
+ */
+ the_regulator->delivery_thread_id = (rtems_id) -1;
+
+ /**
+ * Copy the attributes to an internal area for later use
+ */
+ the_regulator->Attributes = *attributes;
+
+ /**
+ * Allocate memory for the messages. There is no need to zero out the
+ * message memory because the user should fill that in.
+ */
+ alloc_size = attributes->maximum_message_size * attributes->maximum_messages;
+ the_regulator->message_memory = calloc(alloc_size, 1);
+ if (the_regulator->message_memory == NULL) {
+ _Regulator_Free_helper(the_regulator, 0);
+ return RTEMS_NO_MEMORY;
+ }
+
+ /**
+ * Associate message memory with a partition so allocations are atomic
+ */
+ sc = rtems_partition_create(
+ rtems_build_name('P', 'O', 'O', 'L'),
+ the_regulator->message_memory,
+ alloc_size,
+ attributes->maximum_message_size,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &the_regulator->messages_partition_id
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ _Regulator_Free_helper(the_regulator, 0);
+ return sc;
+ }
+
+ /**
+ * Create the message queue between the sender and output thread
+ */
+ RTEMS_MESSAGE_QUEUE_BUFFER(sizeof(_Regulator_Message_t)) regulator_message_t;
+
+ size_t storage_size = sizeof(regulator_message_t) * attributes->maximum_messages;
+
+ the_regulator->message_queue_storage = malloc(storage_size);
+ if (the_regulator->message_queue_storage == NULL) {
+ _Regulator_Free_helper(the_regulator, 0);
+ return RTEMS_NO_MEMORY;
+ }
+
+ rtems_message_queue_config mq_config = {
+ .name = rtems_build_name('S', 'N', 'D', 'Q'),
+ .maximum_pending_messages = attributes->maximum_messages,
+ .maximum_message_size = sizeof(_Regulator_Message_t),
+ .storage_area = the_regulator->message_queue_storage,
+ .storage_size = storage_size,
+ .storage_free = free,
+ .attributes = RTEMS_DEFAULT_ATTRIBUTES
+ };
+ sc = rtems_message_queue_construct(
+ &mq_config,
+ &the_regulator->queue_id
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ _Regulator_Free_helper(the_regulator, 0);
+ return sc;
+ }
+
+ /**
+ * @note A rate monotonic period object must be created by the thread
+ * using it. Thus that specific create operation is not included
+ * in this method. All other resources are allocated here.
+ */
+
+ /**
+ * Create the output thread Using the priority and stack size attributes
+ * specified by the user.
+ */
+ sc = rtems_task_create(
+ rtems_build_name('R', 'E', 'G', 'U'),
+ attributes->delivery_thread_priority,
+ attributes->delivery_thread_stack_size,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &the_regulator->delivery_thread_id
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ _Regulator_Free_helper(the_regulator, 0);
+ return sc;
+ }
+
+ /**
+ * Start the output thread.
+ *
+ * @note There should be no way this call can fail. The task id is valid,
+ * the regulator output thread entry point is valid, and the argument
+ * is valid.
+ */
+ the_regulator->delivery_thread_is_running = true;
+ the_regulator->delivery_thread_request_exit = false;
+ the_regulator->delivery_thread_has_exited = false;
+
+ sc = rtems_task_start(
+ the_regulator->delivery_thread_id,
+ _Regulator_Output_task_body,
+ (rtems_task_argument) the_regulator
+ );
+ _Assert_Unused_variable_equals(sc, RTEMS_SUCCESSFUL);
+
+ /**
+ * The regulator is successfully initialized. Set the initialized field
+ * to reflect this and return the instance pointer.
+ */
+ the_regulator->initialized = REGULATOR_INITIALIZED;
+
+ *regulator = (void *)the_regulator;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/**
+ * @brief Validate the regulator instance provided by the user
+ *
+ * Validate the regulator instance provided by the user
+ *
+ * @param[in] regulator is the instance provided by the user
+ * @param[inout] status will contain the RTEMS status for this check
+ *
+ * @return This method returns a @a _Regulator_Control instance pointer
+ * which is NULL if invalid or points to the internal regulator
+ * control structure if valid.
+ */
+static inline _Regulator_Control *_Regulator_Get(
+ rtems_regulator_instance *regulator,
+ rtems_status_code *status
+)
+{
+ _Regulator_Control *the_regulator = (_Regulator_Control *) regulator;
+
+ if (the_regulator == NULL) {
+ *status = RTEMS_INVALID_ADDRESS;
+ return NULL;
+ }
+
+ if (the_regulator->initialized != REGULATOR_INITIALIZED) {
+ *status = RTEMS_INCORRECT_STATE;
+ return NULL;
+ }
+
+ status = RTEMS_SUCCESSFUL;
+ return the_regulator;
+}
+
+/**
+ * @ingroup RegulatorInternalAPI
+ */
+rtems_status_code rtems_regulator_delete(
+ rtems_regulator_instance *regulator,
+ rtems_interval ticks
+)
+{
+ _Regulator_Control *the_regulator;
+ rtems_status_code status;
+
+ /**
+ * Convert external handle to internal instance pointer
+ */
+ the_regulator = _Regulator_Get(regulator, &status);
+ if (the_regulator == NULL) {
+ return status;
+ }
+
+ /**
+ * There can be no buffers outstanding
+ */
+ _Regulator_Statistics *stats = &the_regulator->Statistics;
+
+ if (stats->obtained != stats->released ) {
+ return RTEMS_RESOURCE_IN_USE;
+ }
+
+ /**
+ * Free the resources associated with this regulator instance.
+ */
+ bool bc;
+ bc = _Regulator_Free_helper(the_regulator, ticks);
+ if (bc == false) {
+ return RTEMS_TIMEOUT;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/**
+ * @ingroup RegulatorInternalAPI
+ *
+ * Allocate a buffer for the caller using the internal partition.
+ */
+rtems_status_code rtems_regulator_obtain_buffer(
+ rtems_regulator_instance *regulator,
+ void **buffer
+)
+{
+ _Regulator_Control *the_regulator;
+ rtems_status_code status;
+
+ /**
+ * Convert external handle to internal instance pointer
+ */
+ the_regulator = _Regulator_Get(regulator, &status);
+ if (the_regulator == NULL) {
+ return status;
+ }
+
+ /**
+ * Allocate a buffer for the user application from the buffer pool managed
+ * by an Classic API partition.
+ */
+ status = rtems_partition_get_buffer(
+ the_regulator->messages_partition_id,
+ buffer
+ );
+
+ if (status == RTEMS_SUCCESSFUL) {
+ the_regulator->Statistics.obtained++;
+ }
+
+ return status;
+}
+
+/**
+ * @ingroup RegulatorInternalAPI
+ *
+ * Allocate a buffer for the caller using the internal partition.
+ */
+rtems_status_code rtems_regulator_release_buffer(
+ rtems_regulator_instance *regulator,
+ void *buffer
+)
+{
+ _Regulator_Control *the_regulator;
+ rtems_status_code status;
+
+ /**
+ * Convert external handle to internal instance pointer
+ */
+ the_regulator = _Regulator_Get(regulator, &status);
+ if (the_regulator == NULL) {
+ return status;
+ }
+
+ /**
+ * Deallocate the buffer to the buffer pool managed by a Classic
+ * API partition.
+ */
+ status = rtems_partition_return_buffer(
+ the_regulator->messages_partition_id,
+ buffer
+ );
+
+ if (status == RTEMS_SUCCESSFUL) {
+ the_regulator->Statistics.released++;
+ }
+
+ return status;
+}
+
+/**
+ * @ingroup RegulatorInternalAPI
+ */
+rtems_status_code rtems_regulator_send(
+ rtems_regulator_instance *regulator,
+ void *message,
+ size_t length
+)
+{
+ _Regulator_Control *the_regulator;
+ rtems_status_code status;
+ _Regulator_Message_t regulator_message;
+
+ the_regulator = (_Regulator_Control *) regulator;
+
+ /**
+ * Validate the arguments and ensure the regulator was successfully
+ * initialized.
+ */
+ if (message == NULL) {
+ return RTEMS_INVALID_ADDRESS;
+ }
+
+ if (length == 0) {
+ return RTEMS_INVALID_NUMBER;
+ }
+
+ /**
+ * Convert external handle to internal instance pointer
+ */
+ the_regulator = _Regulator_Get(regulator, &status);
+ if (the_regulator == NULL) {
+ return status;
+ }
+
+ /**
+ * Place the message pointer and length into a temporary structure. This
+ * lets the implementation internally send the message by reference and
+ * have a zero-copy implementation.
+ */
+ regulator_message.buffer = message;
+ regulator_message.length = length;
+
+ /**
+ * Send the application message to the output thread for delivery using
+ * a Classic API message queue.
+ */
+ status = rtems_message_queue_send(
+ the_regulator->queue_id,
+ &regulator_message,
+ sizeof(_Regulator_Message_t)
+ );
+ if (status != RTEMS_SUCCESSFUL) {
+ return status;
+ }
+
+ return status;
+}
+
+/**
+ * @ingroup RegulatorInternalAPI
+ */
+rtems_status_code rtems_regulator_get_statistics(
+ rtems_regulator_instance *regulator,
+ rtems_regulator_statistics *statistics
+)
+{
+ _Regulator_Control *the_regulator;
+ rtems_status_code status;
+
+ /**
+ * Validate the arguments and ensure the regulator was successfully
+ * initialized.
+ */
+ if (statistics == NULL) {
+ return RTEMS_INVALID_ADDRESS;
+ }
+
+ /**
+ * Convert external handle to internal instance pointer
+ */
+ the_regulator = _Regulator_Get(regulator, &status);
+ if (the_regulator == NULL) {
+ return status;
+ }
+
+ /**
+ * Zero out the statistics structure in case the get period statistics
+ * fails below.
+ */
+ memset(statistics, 0, sizeof(rtems_regulator_statistics));
+
+ /**
+ * Fill in the caller's statistics structure from information
+ * maintained by the regulator instance about buffers processed.
+ */
+ statistics->obtained = the_regulator->Statistics.obtained;
+ statistics->released = the_regulator->Statistics.released;
+ statistics->delivered = the_regulator->Statistics.delivered;
+
+ /**
+ * Attempt to retrieve the delivery thread's period's statistics.
+ *
+ * NOTE; If the Delivery Thread has not run yet, the period will not
+ * exist yet. We should not fail for this reason but it is why
+ * we zeroed out the entire structure above.
+ */
+ (void) rtems_rate_monotonic_get_statistics(
+ the_regulator->delivery_thread_period_id,
+ &statistics->period_statistics
+ );
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/cpukit/libmisc/rtems-fdt/rtems-fdt.c b/cpukit/libmisc/rtems-fdt/rtems-fdt.c
index ec8f270eef..9f8d7bfb24 100644
--- a/cpukit/libmisc/rtems-fdt/rtems-fdt.c
+++ b/cpukit/libmisc/rtems-fdt/rtems-fdt.c
@@ -1165,7 +1165,7 @@ rtems_fdt_get_value (const char* path,
}
if (length == sizeof (uintptr_t))
- *value = rtems_fdt_get_uint32 (prop);
+ *value = rtems_fdt_get_uintptr (prop);
else
*value = 0;
diff --git a/cpukit/libmisc/shell/shell.c b/cpukit/libmisc/shell/shell.c
index cd83aa56d1..9cefc80255 100644
--- a/cpukit/libmisc/shell/shell.c
+++ b/cpukit/libmisc/shell/shell.c
@@ -806,6 +806,109 @@ void rtems_shell_print_env(
#endif
/*
+ * Wait for the string to return or timeout.
+ */
+static bool rtems_shell_term_wait_for(const int fd, const char* str, const int timeout)
+{
+ int msec = timeout;
+ int i = 0;
+ while (msec-- > 0 && str[i] != '\0') {
+ char ch[2];
+ if (read(fd, &ch[0], 1) == 1) {
+ fflush(stdout);
+ if (ch[0] != str[i++]) {
+ return false;
+ }
+ msec = timeout;
+ } else {
+ usleep(1000);
+ }
+ }
+ if (msec == 0) {
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Buffer a string up to the end string
+ */
+static int rtems_shell_term_buffer_until(const int fd,
+ char* buf,
+ const int size,
+ const char* end,
+ const int timeout)
+{
+ int msec = timeout;
+ int i = 0;
+ int e = 0;
+ memset(&buf[0], 0, size);
+ while (msec-- > 0 && i < size && end[e] != '\0') {
+ char ch[2];
+ if (read(fd, &ch[0], 1) == 1) {
+ fflush(stdout);
+ buf[i++] = ch[0];
+ if (ch[0] == end[e]) {
+ e++;
+ } else {
+ e = 0;
+ }
+ msec = timeout;
+ } else {
+ usleep(1000);
+ }
+ }
+ if (msec == 0 || end[e] != '\0') {
+ return -1;
+ }
+ i -= e;
+ if (i < size) {
+ buf[i] = '\0';
+ }
+ return i;
+}
+
+/*
+ * Determine if the terminal has the row and column values
+ * swapped
+ *
+ * https://github.com/tmux/tmux/issues/3457
+ *
+ * Tmux has a bug where the lines and cols are swapped. There is a lag
+ * in the time it takes to get the fix into code so see if tmux is
+ * running and which version and work around the bug.
+ *
+ * The terminal device needs to have VMIN=0, and VTIME=0
+ */
+static bool rtems_shell_term_row_column_swapped(const int fd, const int timeout) {
+ char buf[64];
+ memset(&buf[0], 0, sizeof(buf));
+ /*
+ * CSI > Ps q
+ * Ps = 0 => DCS > | text ST
+ */
+ fputs("\033[>0q", stdout);
+ fflush(stdout);
+ if (rtems_shell_term_wait_for(fd, "\033P>|", timeout)) {
+ int len = rtems_shell_term_buffer_until(fd, buf, sizeof(buf), "\033\\", timeout);
+ if (len > 0) {
+ if (memcmp(buf, "tmux ", 5) == 0) {
+ static const char* bad_versions[] = {
+ "3.2", "3.2a", "3.3", "3.3a"
+ };
+ size_t i;
+ for (i = 0; i < RTEMS_ARRAY_SIZE(bad_versions); ++i) {
+ if (strcmp(bad_versions[i], buf + 5) == 0) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+/*
* Direct method to get the size of an XTERM window.
*
* If you do not use an XTERM the env variables are not define.
@@ -814,6 +917,7 @@ static void rtems_shell_winsize( void )
{
const int fd = fileno(stdin);
struct winsize ws;
+ const int timeout = 150;
char buf[64];
bool ok = false;
int lines = 0;
@@ -831,9 +935,6 @@ static void rtems_shell_winsize( void )
term.c_cc[VMIN] = 0;
term.c_cc[VTIME] = 0;
if (tcsetattr (fd, TCSADRAIN, &term) >= 0) {
- int msec = 50;
- int len = 0;
- int i = 0;
memset(&buf[0], 0, sizeof(buf));
/*
* https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Miscellaneous
@@ -842,35 +943,34 @@ static void rtems_shell_winsize( void )
*/
fputs("\033[18t", stdout);
fflush(stdout);
- while (msec-- > 0 && len < sizeof(buf)) {
- char ch[2];
- if (read(fd, &ch[0], 1) == 1) {
- buf[len++] = ch[0];
- msec = 50;
- } else {
- usleep(1000);
- }
- }
- while (i < len) {
- static const char resp[] = "\033[8;";
- if (memcmp(resp, &buf[i], sizeof(resp) - 1) == 0) {
- i += sizeof(resp) - 1;
- while (i < len && buf[i] != ';') {
+ if (rtems_shell_term_wait_for(fd, "\033[8;", timeout)) {
+ int len = rtems_shell_term_buffer_until(fd, buf, sizeof(buf), ";", timeout);
+ if (len > 0) {
+ int i;
+ lines = 0;
+ i = 0;
+ while (i < len) {
lines *= 10;
lines += buf[i++] - '0';
}
- cols = 0;
- ++i;
- while (i < len && buf[i] != 't') {
- cols *= 10;
- cols += buf[i++] - '0';
+ len = rtems_shell_term_buffer_until(fd, buf, sizeof(buf), "t", timeout);
+ if (len > 0) {
+ cols = 0;
+ i = 0;
+ while (i < len) {
+ cols *= 10;
+ cols += buf[i++] - '0';
+ }
+ ok = true;
}
- } else {
- i++;
}
- ok = true;
}
}
+ if (rtems_shell_term_row_column_swapped(fd, timeout)) {
+ int tmp = lines;
+ lines = cols;
+ cols = tmp;
+ }
tcsetattr (fd, TCSADRAIN, &cterm);
}
}
diff --git a/cpukit/libmisc/uuid/gen_uuid.c b/cpukit/libmisc/uuid/gen_uuid.c
index 71b8a569bb..5601c887c9 100644
--- a/cpukit/libmisc/uuid/gen_uuid.c
+++ b/cpukit/libmisc/uuid/gen_uuid.c
@@ -171,7 +171,12 @@ static int get_random_fd(void)
fcntl(fd, F_SETFD, i | FD_CLOEXEC);
}
#endif
+#ifdef __rtems__
+ srand((((time_t)getpid()) << ((sizeof(pid_t)*CHAR_BIT)>>1)) ^ getuid()
+ ^ tv.tv_sec ^ tv.tv_usec);
+#else
srand((getpid() << ((sizeof(pid_t)*CHAR_BIT)>>1)) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
+#endif
#ifdef DO_JRAND_MIX
jrand_seed[0] = getpid() ^ (tv.tv_sec & 0xFFFF);
jrand_seed[1] = getppid() ^ (tv.tv_usec & 0xFFFF);
@@ -343,11 +348,17 @@ static int get_clock(uint32_t *clock_high, uint32_t *clock_low,
state_fd = open("/var/lib/libuuid/clock.txt",
O_RDWR|O_CREAT, 0660);
(void) umask(save_umask);
+#ifdef __rtems__
+ if (state_fd >= 0) {
+#endif
state_f = fdopen(state_fd, "r+");
if (!state_f) {
close(state_fd);
state_fd = -1;
}
+#ifdef __rtems__
+ }
+#endif
}
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
diff --git a/cpukit/score/src/gcovdumpinfo.c b/cpukit/libtest/gcovdumpinfo.c
index be00df2db8..87021ad613 100644
--- a/cpukit/score/src/gcovdumpinfo.c
+++ b/cpukit/libtest/gcovdumpinfo.c
@@ -3,7 +3,7 @@
/**
* @file
*
- * @ingroup RTEMSScoreIO
+ * @ingroup RTEMSImplGcov
*
* @brief This source file contains the implementation of _Gcov_Ddump_info().
*/
@@ -37,7 +37,7 @@
#include "config.h"
#endif
-#include <rtems/score/gcov.h>
+#include <rtems/test-gcov.h>
typedef struct {
IO_Put_char put_char;
diff --git a/cpukit/score/src/gcovdumpinfobase64.c b/cpukit/libtest/gcovdumpinfobase64.c
index b7a9849084..62cd89ac7e 100644
--- a/cpukit/score/src/gcovdumpinfobase64.c
+++ b/cpukit/libtest/gcovdumpinfobase64.c
@@ -3,7 +3,7 @@
/**
* @file
*
- * @ingroup RTEMSScoreIO
+ * @ingroup RTEMSImplGcov
*
* @brief This source file contains the implementation of
* _Gcov_Dump_info_base64().
@@ -38,11 +38,13 @@
#include "config.h"
#endif
-#include <rtems/score/gcov.h>
+#include <rtems/test-gcov.h>
#include <limits.h>
#include <string.h>
+#include <rtems/base64.h>
+
typedef struct {
IO_Put_char put_char;
void *arg;
@@ -77,7 +79,7 @@ static void _Gcov_Base64_encode( int c, void *arg )
if ( index == RTEMS_ARRAY_SIZE( ctx->buf ) - 1 ) {
index = 0;
- _IO_Base64(
+ _Base64_Encode(
_Gcov_Base64_put_char,
ctx,
ctx->buf,
@@ -100,5 +102,9 @@ void _Gcov_Dump_info_base64( IO_Put_char put_char, void *arg )
ctx.put_char = put_char;
ctx.arg = arg;
_Gcov_Dump_info( _Gcov_Base64_encode, &ctx );
- _IO_Base64( _Gcov_Base64_put_char, &ctx, ctx.buf, ctx.index, NULL, INT_MAX );
+
+ if ( ctx.index > 0 ) {
+ _Base64_Encode( put_char, arg, ctx.buf, ctx.index, NULL, INT_MAX );
+ ( *put_char )( '\n', arg );
+ }
}
diff --git a/cpukit/score/src/gcovinfoset.c b/cpukit/libtest/gcovinfoset.c
index cb22e8252b..284c993d32 100644
--- a/cpukit/score/src/gcovinfoset.c
+++ b/cpukit/libtest/gcovinfoset.c
@@ -3,7 +3,7 @@
/**
* @file
*
- * @ingroup RTEMSScoreIO
+ * @ingroup RTEMSImplGcov
*
* @brief This source file contains the definition of the gcov information
* linker set.
@@ -38,6 +38,6 @@
#include "config.h"
#endif
-#include <rtems/score/gcov.h>
+#include <rtems/test-gcov.h>
RTEMS_LINKER_ROSET( gcov_info, const struct gcov_info * );
diff --git a/cpukit/libtest/t-test-busy-tick.c b/cpukit/libtest/t-test-busy-tick.c
index b7fed247fa..5e45757f24 100644
--- a/cpukit/libtest/t-test-busy-tick.c
+++ b/cpukit/libtest/t-test-busy-tick.c
@@ -5,7 +5,8 @@
*
* @ingroup RTEMSTestFrameworkImpl
*
- * @brief Implementation of T_get_one_clock_tick_busy().
+ * @brief This source file contains the implementation of
+ * T_get_one_clock_tick_busy().
*/
/*
diff --git a/cpukit/libtest/t-test-busy.c b/cpukit/libtest/t-test-busy.c
index 8583284087..e28fa3e5e4 100644
--- a/cpukit/libtest/t-test-busy.c
+++ b/cpukit/libtest/t-test-busy.c
@@ -5,7 +5,8 @@
*
* @ingroup RTEMSTestFrameworkImpl
*
- * @brief Implementation of T_busy().
+ * @brief This source file contains the implementation of
+ * T_busy().
*/
/*
diff --git a/cpukit/libtest/t-test-checks-eno.c b/cpukit/libtest/t-test-checks-eno.c
index 5b450ccf99..48736915b4 100644
--- a/cpukit/libtest/t-test-checks-eno.c
+++ b/cpukit/libtest/t-test-checks-eno.c
@@ -1,6 +1,15 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestFrameworkImpl
*
+ * @brief This source file contains the implementation of
+ * T_strerror(), T_check_eno(), and T_check_eno_success().
+ */
+
+/*
* Copyright (C) 2018 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
diff --git a/cpukit/libtest/t-test-checks-psx.c b/cpukit/libtest/t-test-checks-psx.c
index 5394ea537a..5d6ec25bda 100644
--- a/cpukit/libtest/t-test-checks-psx.c
+++ b/cpukit/libtest/t-test-checks-psx.c
@@ -3,7 +3,10 @@
/**
* @file
*
- * @brief
+ * @ingroup RTEMSTestFrameworkImpl
+ *
+ * @brief This source file contains the implementation of
+ * T_check_psx_error() and T_check_psx_success().
*/
/*
diff --git a/cpukit/libtest/t-test-checks.c b/cpukit/libtest/t-test-checks.c
index 40479a8277..b83e83f1f3 100644
--- a/cpukit/libtest/t-test-checks.c
+++ b/cpukit/libtest/t-test-checks.c
@@ -1,6 +1,15 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestFrameworkImpl
*
+ * @brief This source file contains the implementation of various RTEMS Test
+ * Framework check functions.
+ */
+
+/*
* Copyright (C) 2018 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
diff --git a/cpukit/libtest/t-test-hash-sha256.c b/cpukit/libtest/t-test-hash-sha256.c
index a9aa4df023..79da4b5dfb 100644
--- a/cpukit/libtest/t-test-hash-sha256.c
+++ b/cpukit/libtest/t-test-hash-sha256.c
@@ -1,6 +1,15 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
*
+ * @ingroup RTEMSTestFrameworkImpl
+ *
+ * @brief This source file contains the implementation of
+ * T_report_hash_sha256_update() and T_report_hash_sha256().
+ */
+
+/*
* Copyright (C) 2019, 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
@@ -26,7 +35,6 @@
*/
#include <rtems/test.h>
-#include <rtems/score/io.h>
#include <limits.h>
@@ -36,6 +44,8 @@
#include <openssl/sha.h>
#endif
+#include <rtems/base64.h>
+
typedef struct {
SHA256_CTX sha256;
T_putchar putchar;
@@ -85,7 +95,7 @@ T_report_hash_sha256_finalize(void)
ctx = &T_report_hash_sha256_instance;
SHA256_Final(hash, &ctx->sha256);
T_printf("Y:ReportHash:SHA256:");
- (void)_IO_Base64url(ctx->putchar, ctx->putchar_arg, hash,
+ (void)_Base64url_Encode(ctx->putchar, ctx->putchar_arg, hash,
sizeof(hash), NULL, INT_MAX);
T_printf("\n");
}
diff --git a/cpukit/libtest/t-test-interrupt.c b/cpukit/libtest/t-test-interrupt.c
index 800724dd93..8796dc0b5a 100644
--- a/cpukit/libtest/t-test-interrupt.c
+++ b/cpukit/libtest/t-test-interrupt.c
@@ -5,7 +5,8 @@
*
* @ingroup RTEMSTestFrameworkImpl
*
- * @brief Implementation of T_interrupt_test().
+ * @brief This source file contains the implementation of
+ * T_interrupt_test().
*/
/*
diff --git a/cpukit/libtest/t-test-rtems-context.c b/cpukit/libtest/t-test-rtems-context.c
index 351a29a1ca..1405db0c7d 100644
--- a/cpukit/libtest/t-test-rtems-context.c
+++ b/cpukit/libtest/t-test-rtems-context.c
@@ -1,6 +1,15 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestFrameworkImpl
*
+ * @brief This source file contains the implementation of
+ * T_check_task_context().
+ */
+
+/*
* Copyright (C) 2019 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
diff --git a/cpukit/libtest/t-test-rtems-fds.c b/cpukit/libtest/t-test-rtems-fds.c
index df5279f585..2b520972d2 100644
--- a/cpukit/libtest/t-test-rtems-fds.c
+++ b/cpukit/libtest/t-test-rtems-fds.c
@@ -1,6 +1,15 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestFrameworkImpl
*
+ * @brief This source file contains the implementation of
+ * T_check_file_descriptors().
+ */
+
+/*
* Copyright (C) 2018 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
diff --git a/cpukit/libtest/t-test-rtems-heap.c b/cpukit/libtest/t-test-rtems-heap.c
index ac54e96fc7..2fb069a50e 100644
--- a/cpukit/libtest/t-test-rtems-heap.c
+++ b/cpukit/libtest/t-test-rtems-heap.c
@@ -1,6 +1,15 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestFrameworkImpl
*
+ * @brief This source file contains the implementation of
+ * T_check_heap().
+ */
+
+/*
* Copyright (C) 2018 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
diff --git a/cpukit/libtest/t-test-rtems-measure.c b/cpukit/libtest/t-test-rtems-measure.c
index c165fc8f2a..2a2376cd27 100644
--- a/cpukit/libtest/t-test-rtems-measure.c
+++ b/cpukit/libtest/t-test-rtems-measure.c
@@ -1,6 +1,15 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestFrameworkImpl
*
+ * @brief This source file contains the implementation of
+ * T_measure_runtime().
+ */
+
+/*
* Copyright (C) 2018, 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
diff --git a/cpukit/libtest/t-test-rtems-memory.c b/cpukit/libtest/t-test-rtems-memory.c
index 1d41192f56..ed0908ae10 100644
--- a/cpukit/libtest/t-test-rtems-memory.c
+++ b/cpukit/libtest/t-test-rtems-memory.c
@@ -1,5 +1,14 @@
/* SPDX-License-Identifier: BSD-2-Clause */
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestFrameworkImpl
+ *
+ * @brief This source file contains the implementation of
+ * T_memory_allocate(), T_memory_deallocate(), and T_memory_action().
+ */
+
/*
* Copyright (C) 2020 embedded brains GmbH & Co. KG
*
diff --git a/cpukit/libtest/t-test-rtems-objs.c b/cpukit/libtest/t-test-rtems-objs.c
index 2eb3db6f7f..ce752424b5 100644
--- a/cpukit/libtest/t-test-rtems-objs.c
+++ b/cpukit/libtest/t-test-rtems-objs.c
@@ -3,9 +3,10 @@
/**
* @file
*
- * @ingroup RTEMSTestFramework
+ * @ingroup RTEMSTestFrameworkImpl
*
- * @brief RTEMS Objects Support for Test Framework
+ * @brief This source file contains the implementation of the RTEMS objects
+ * test support.
*/
/*
diff --git a/cpukit/libtest/t-test-rtems-posix-keys.c b/cpukit/libtest/t-test-rtems-posix-keys.c
index a26988e27a..65153d3d33 100644
--- a/cpukit/libtest/t-test-rtems-posix-keys.c
+++ b/cpukit/libtest/t-test-rtems-posix-keys.c
@@ -3,9 +3,10 @@
/**
* @file
*
- * @ingroup RTEMSTestFramework
+ * @ingroup RTEMSTestFrameworkImpl
*
- * @brief RTEMS POSIX Keys Support for Test Framework
+ * @brief This source file contains the implementation of
+ * T_check_posix_keys().
*/
/*
diff --git a/cpukit/libtest/t-test-rtems.c b/cpukit/libtest/t-test-rtems.c
index 97864c1c76..d4fc6827af 100644
--- a/cpukit/libtest/t-test-rtems.c
+++ b/cpukit/libtest/t-test-rtems.c
@@ -1,6 +1,15 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestFrameworkImpl
*
+ * @brief This source file contains the implementation of
+ * T_putchar_default(), T_check_rsc(), and T_check_rsc_success().
+ */
+
+/*
* Copyright (C) 2018 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
diff --git a/cpukit/libtest/t-test-rtems.h b/cpukit/libtest/t-test-rtems.h
index 9d40f1aa9b..d429c4f5bd 100644
--- a/cpukit/libtest/t-test-rtems.h
+++ b/cpukit/libtest/t-test-rtems.h
@@ -3,9 +3,10 @@
/**
* @file
*
- * @ingroup RTEMSTestFrameworkImpl
+ * @ingroup RTEMSTestFramework
*
- * @brief RTEMS Support for Test Framework
+ * @brief This header file provides the RTEMS-specific API of the RTEMS Test
+ * Framework.
*/
/*
diff --git a/cpukit/libtest/t-test-thread-switch.c b/cpukit/libtest/t-test-thread-switch.c
index 44cd819dd1..99d2d7ee29 100644
--- a/cpukit/libtest/t-test-thread-switch.c
+++ b/cpukit/libtest/t-test-thread-switch.c
@@ -5,7 +5,8 @@
*
* @ingroup RTEMSTestFrameworkImpl
*
- * @brief Implementation of T_thread_switch_record().
+ * @brief This source file contains the implementation of the thread switch
+ * recorder.
*/
/*
diff --git a/cpukit/libtest/t-test-time.c b/cpukit/libtest/t-test-time.c
index 3f953626a5..2acb75f799 100644
--- a/cpukit/libtest/t-test-time.c
+++ b/cpukit/libtest/t-test-time.c
@@ -1,6 +1,15 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestFrameworkImpl
*
+ * @brief This source file contains the implementation of the time and ticks
+ * test support.
+ */
+
+/*
* Copyright (C) 2018 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
diff --git a/cpukit/libtest/t-test.c b/cpukit/libtest/t-test.c
index 4f3bf56142..1230505edf 100644
--- a/cpukit/libtest/t-test.c
+++ b/cpukit/libtest/t-test.c
@@ -1,7 +1,16 @@
-/*
- * SPDX-License-Identifier: BSD-2-Clause
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestFrameworkImpl
*
- * Copyright (C) 2018, 2020 embedded brains GmbH & Co. KG
+ * @brief This source file contains the core implementation of RTEMS Test
+ * Framework.
+ */
+
+/*
+ * Copyright (C) 2018, 2023 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,7 +46,7 @@
#include <stdatomic.h>
#ifdef __rtems__
-#include <rtems/score/io.h>
+#include <rtems/dev/io.h>
#include <rtems/score/percpu.h>
#include <rtems/score/smp.h>
#include <rtems/score/threadimpl.h>
@@ -63,6 +72,7 @@ typedef struct {
T_fixture_node *fixtures;
T_fixture_node case_fixture;
LIST_HEAD(, T_destructor) destructors;
+ T_remark remarks;
T_time case_begin_time;
atomic_uint planned_steps;
atomic_uint steps;
@@ -922,6 +932,23 @@ T_call_destructors(const T_context *ctx)
#endif
}
+static void
+T_make_remarks(T_context *ctx)
+{
+ T_remark *remark;
+
+ remark = ctx->remarks.next;
+
+ while (remark != &ctx->remarks) {
+ T_remark *current;
+
+ current = remark;
+ remark = current->next;
+ current->next = NULL;
+ T_do_log(ctx, T_QUIET, "R:%s\n", current->remark);
+ }
+}
+
static T_context *
T_do_run_initialize(const T_config *config)
{
@@ -973,6 +1000,7 @@ T_do_case_begin(T_context *ctx, const T_case_context *tc)
ctx->current_case = tc;
ctx->fixtures = &ctx->case_fixture;
LIST_INIT(&ctx->destructors);
+ ctx->remarks.next = &ctx->remarks;
atomic_store_explicit(&ctx->planned_steps, UINT_MAX,
memory_order_relaxed);
atomic_store_explicit(&ctx->steps, 0, memory_order_relaxed);
@@ -1024,6 +1052,7 @@ T_do_case_end(T_context *ctx, const T_case_context *tc)
T_call_destructors(ctx);
config = ctx->config;
T_actions_backward(config, T_EVENT_CASE_END, tc->name);
+ T_make_remarks(ctx);
planned_steps = atomic_fetch_add_explicit(&ctx->planned_steps,
0, memory_order_relaxed);
@@ -1284,6 +1313,18 @@ T_pop_fixture(void)
T_do_pop_fixture(&T_instance);
}
+void
+T_add_remark(T_remark *remark)
+{
+ if (remark->next == NULL) {
+ T_context *ctx;
+
+ ctx = &T_instance;
+ remark->next = ctx->remarks.next;
+ ctx->remarks.next = remark;
+ }
+}
+
size_t
T_get_scope(const char * const * const *desc, char *buf, size_t n,
const size_t *second_indices)
diff --git a/cpukit/libtest/testbeginend.c b/cpukit/libtest/testbeginend.c
index 067155fef3..eca8712b35 100644
--- a/cpukit/libtest/testbeginend.c
+++ b/cpukit/libtest/testbeginend.c
@@ -1,5 +1,14 @@
/* SPDX-License-Identifier: BSD-2-Clause */
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestFrameworkImpl
+ *
+ * @brief This source file contains the implementation of
+ * rtems_test_begin() and rtems_test_end().
+ */
+
/*
* Copyright (C) 2014, 2018 embedded brains GmbH & Co. KG
*
@@ -32,6 +41,7 @@
#endif
#include <rtems/test-info.h>
+#include <rtems/test-printer.h>
#include <rtems/bspIo.h>
#include <rtems/version.h>
diff --git a/cpukit/libtest/testextension.c b/cpukit/libtest/testextension.c
index bba6a53a75..483c13ca85 100644
--- a/cpukit/libtest/testextension.c
+++ b/cpukit/libtest/testextension.c
@@ -30,6 +30,7 @@
#endif
#include <rtems/test-info.h>
+#include <rtems/test-printer.h>
#include <rtems/profiling.h>
#include <rtems/bspIo.h>
diff --git a/cpukit/libtest/testgcovbspreset.c b/cpukit/libtest/testgcovbspreset.c
index 2b1e399bc4..f40102c944 100644
--- a/cpukit/libtest/testgcovbspreset.c
+++ b/cpukit/libtest/testgcovbspreset.c
@@ -3,7 +3,7 @@
/**
* @file
*
- * @ingroup RTEMSTest
+ * @ingroup RTEMSTestFrameworkImpl
*
* @brief This source file contains the implementation of a wrapper for
* bsp_reset() which dumps the gcov information using
diff --git a/cpukit/libtest/testgcovcpufatalhalt.c b/cpukit/libtest/testgcovcpufatalhalt.c
index 55a4c3ee40..9ac242885b 100644
--- a/cpukit/libtest/testgcovcpufatalhalt.c
+++ b/cpukit/libtest/testgcovcpufatalhalt.c
@@ -3,7 +3,7 @@
/**
* @file
*
- * @ingroup RTEMSTest
+ * @ingroup RTEMSTestFrameworkImpl
*
* @brief This source file contains the implementation of a wrapper for
* _CPU_Fatal_halt() which dumps the gcov information using
diff --git a/cpukit/libtest/testgcovdumpinfo.c b/cpukit/libtest/testgcovdumpinfo.c
index 68ce0439fa..9687280e21 100644
--- a/cpukit/libtest/testgcovdumpinfo.c
+++ b/cpukit/libtest/testgcovdumpinfo.c
@@ -3,14 +3,14 @@
/**
* @file
*
- * @ingroup RTEMSTest
+ * @ingroup RTEMSTestFrameworkImpl
*
* @brief This source file contains the implementation of
* rtems_test_gcov_dump_info().
*/
/*
- * Copyright (C) 2021, 2022 embedded brains GmbH & Co. KG
+ * Copyright (C) 2021, 2023 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -40,14 +40,26 @@
#include <rtems/test-info.h>
-#include <rtems/score/gcov.h>
+#include <rtems/test-gcov.h>
#include <rtems/score/isrlock.h>
+#include <rtems/score/hash.h>
#include <rtems/bspIo.h>
ISR_LOCK_DEFINE( static, gcov_dump_lock, "gcov dump" );
static bool gcov_dump_done;
+static Hash_Context gcov_hash;
+
+static void gcov_put_char( int c, void *arg )
+{
+ uint8_t byte;
+
+ rtems_put_char( c, arg );
+ byte = (uint8_t) c;
+ _Hash_Add_data( &gcov_hash, &byte, sizeof( byte ) );
+}
+
void rtems_test_gcov_dump_info( void )
{
ISR_lock_Context lock_context;
@@ -55,11 +67,21 @@ void rtems_test_gcov_dump_info( void )
_ISR_lock_ISR_disable_and_acquire( &gcov_dump_lock, &lock_context );
if ( !gcov_dump_done ) {
+ Hash_Control result;
+
gcov_dump_done = true;
_IO_Printf( rtems_put_char, NULL, "\n*** BEGIN OF GCOV INFO BASE64 ***\n" );
- _Gcov_Dump_info_base64( rtems_put_char, NULL );
- _IO_Printf( rtems_put_char, NULL, "\n*** END OF GCOV INFO BASE64 ***\n" );
+ _Hash_Initialize( &gcov_hash );
+ _Gcov_Dump_info_base64( gcov_put_char, NULL );
+ _Hash_Finalize( &gcov_hash, &result );
+ _IO_Printf( rtems_put_char, NULL, "*** END OF GCOV INFO BASE64 ***\n" );
+ _IO_Printf(
+ rtems_put_char,
+ NULL,
+ "*** GCOV INFO SHA256 %s ***\n",
+ _Hash_Get_string( &result )
+ );
}
_ISR_lock_Release_and_ISR_enable( &gcov_dump_lock, &lock_context );
diff --git a/cpukit/libtest/testrun.c b/cpukit/libtest/testrun.c
index 0d392e4581..e7be6e91a7 100644
--- a/cpukit/libtest/testrun.c
+++ b/cpukit/libtest/testrun.c
@@ -3,13 +3,13 @@
/**
* @file
*
- * @ingroup RTEMSAPI
+ * @ingroup RTEMSTest
*
- * @brief Implementation of rtems_test_run_default().
+ * @brief This source file provides the implementation of rtems_test_run().
*/
/*
- * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ * Copyright (C) 2020, 2023 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -38,6 +38,7 @@
#endif
#include <rtems/test-info.h>
+#include <rtems/test-printer.h>
#include <rtems/test.h>
#include <stdlib.h>
@@ -65,7 +66,7 @@ static const T_config config = {
.buf = buffer,
.buf_size = sizeof( buffer ),
.putchar = T_putchar_default,
- .verbosity = T_VERBOSE,
+ .verbosity = T_NORMAL,
.now = T_now_clock,
.allocate = malloc,
.deallocate = free,
@@ -73,17 +74,33 @@ static const T_config config = {
.actions = actions
};
+static int printer(void *context, const char *fmt, va_list ap)
+{
+ (void) context;
+ return T_vprintf(fmt, ap);
+}
+
void rtems_test_run(
rtems_task_argument arg,
const RTEMS_TEST_STATE state
)
{
+ rtems_print_printer previous_printer;
+ int exit_code;
+
(void) arg;
rtems_test_begin( rtems_test_name, state );
T_register();
- if ( T_main( &config ) == 0 ) {
+ previous_printer = rtems_test_printer.printer;
+ rtems_test_printer.printer = printer;
+
+ exit_code = T_main( &config );
+
+ rtems_test_printer.printer = previous_printer;
+
+ if ( exit_code == 0 ) {
rtems_test_end( rtems_test_name );
}
diff --git a/cpukit/libtest/testwrappers.c b/cpukit/libtest/testwrappers.c
index 3c6e8fccc3..2316208f7c 100644
--- a/cpukit/libtest/testwrappers.c
+++ b/cpukit/libtest/testwrappers.c
@@ -29,7 +29,7 @@
#include "config.h"
#endif
-#include <rtems/test-info.h>
+#include <rtems/test-printer.h>
int __wrap_printf(const char* format, ...);
int __wrap_puts(const char *str);
diff --git a/cpukit/libtrace/record/record-dump-base64.c b/cpukit/libtrace/record/record-dump-base64.c
index a021c7016c..9438041664 100644
--- a/cpukit/libtrace/record/record-dump-base64.c
+++ b/cpukit/libtrace/record/record-dump-base64.c
@@ -30,11 +30,12 @@
#endif
#include <rtems/recorddump.h>
-#include <rtems/score/io.h>
#include <limits.h>
#include <string.h>
+#include <rtems/base64.h>
+
typedef struct {
IO_Put_char put_char;
void *arg;
@@ -76,7 +77,7 @@ static void chunk( void *arg, const void *data, size_t length )
if ( index == RTEMS_ARRAY_SIZE( ctx->buf ) - 1 ) {
index = 0;
- _IO_Base64(
+ _Base64_Encode(
put_char,
ctx,
ctx->buf,
@@ -94,7 +95,7 @@ static void chunk( void *arg, const void *data, size_t length )
static void flush( dump_context *ctx )
{
- _IO_Base64( put_char, ctx, ctx->buf, ctx->index, NULL, INT_MAX );
+ _Base64_Encode( put_char, ctx, ctx->buf, ctx->index, NULL, INT_MAX );
}
void rtems_record_dump_base64( IO_Put_char put_char, void *arg )
diff --git a/cpukit/libtrace/record/record-dump-zbase64.c b/cpukit/libtrace/record/record-dump-zbase64.c
index 9359429d0b..43bd0ecff8 100644
--- a/cpukit/libtrace/record/record-dump-zbase64.c
+++ b/cpukit/libtrace/record/record-dump-zbase64.c
@@ -30,11 +30,12 @@
#endif
#include <rtems/recorddump.h>
-#include <rtems/score/io.h>
#include <limits.h>
#include <string.h>
+#include <rtems/base64.h>
+
static void *dump_zalloc( void *opaque, unsigned items, unsigned size )
{
rtems_record_dump_base64_zlib_context *ctx;
@@ -96,7 +97,7 @@ static void chunk( void *arg, const void *data, size_t length )
ctx->stream.next_out = &ctx->buf[ 0 ];
ctx->stream.avail_out = sizeof( ctx->buf );
- _IO_Base64( put_char, ctx, ctx->buf, sizeof( ctx->buf ), NULL, INT_MAX );
+ _Base64_Encode( put_char, ctx, ctx->buf, sizeof( ctx->buf ), NULL, INT_MAX );
}
}
}
@@ -115,11 +116,11 @@ static void flush( rtems_record_dump_base64_zlib_context *ctx )
ctx->stream.next_out = &ctx->buf[ 0 ];
ctx->stream.avail_out = sizeof( ctx->buf );
- _IO_Base64( put_char, ctx, ctx->buf, sizeof( ctx->buf ), NULL, INT_MAX );
+ _Base64_Encode( put_char, ctx, ctx->buf, sizeof( ctx->buf ), NULL, INT_MAX );
}
}
- _IO_Base64(
+ _Base64_Encode(
put_char,
ctx,
ctx->buf,
diff --git a/cpukit/posix/src/condtimedwait.c b/cpukit/posix/src/condtimedwait.c
index b063aac9b1..258e38a357 100644
--- a/cpukit/posix/src/condtimedwait.c
+++ b/cpukit/posix/src/condtimedwait.c
@@ -39,7 +39,6 @@
#endif
#include <rtems/posix/condimpl.h>
-#include <rtems/score/todimpl.h>
/*
* 11.4.4 Waiting on a Condition, P1003.1c/Draft 10, p. 105
diff --git a/cpukit/posix/src/killinfo.c b/cpukit/posix/src/killinfo.c
index 2765ab30ca..bde511504a 100644
--- a/cpukit/posix/src/killinfo.c
+++ b/cpukit/posix/src/killinfo.c
@@ -47,7 +47,6 @@
#include <rtems/posix/pthreadimpl.h>
#include <rtems/posix/psignalimpl.h>
#include <rtems/score/isr.h>
-#include <rtems/score/schedulerimpl.h>
#include <rtems/score/statesimpl.h>
#include <rtems/seterr.h>
@@ -324,7 +323,6 @@ int _POSIX_signals_Send(
* + sigprocmask() unblocks the signal, OR
* + sigaction() which changes the handler to SIG_IGN.
*/
- the_thread = NULL;
goto post_process_signal;
/*
diff --git a/cpukit/posix/src/mutexattrsetprotocol.c b/cpukit/posix/src/mutexattrsetprotocol.c
index 5a6c44cf52..c3205c9a75 100644
--- a/cpukit/posix/src/mutexattrsetprotocol.c
+++ b/cpukit/posix/src/mutexattrsetprotocol.c
@@ -44,7 +44,6 @@
#include <rtems/score/coremuteximpl.h>
#include <rtems/score/watchdog.h>
#include <rtems/posix/muteximpl.h>
-#include <rtems/posix/priorityimpl.h>
/*
* 13.6.1 Mutex Initialization Scheduling Attributes, P1003.1c/Draft 10, p. 128
diff --git a/cpukit/posix/src/mutexunlock.c b/cpukit/posix/src/mutexunlock.c
index 681aa8fd1b..0644cec188 100644
--- a/cpukit/posix/src/mutexunlock.c
+++ b/cpukit/posix/src/mutexunlock.c
@@ -41,8 +41,6 @@
#include <rtems/posix/muteximpl.h>
#include <rtems/posix/posixapi.h>
-#include <string.h>
-
bool _POSIX_Mutex_Auto_initialization( POSIX_Mutex_Control *the_mutex )
{
unsigned long zero;
diff --git a/cpukit/posix/src/psignal.c b/cpukit/posix/src/psignal.c
index a829c60ee1..3bfd779630 100644
--- a/cpukit/posix/src/psignal.c
+++ b/cpukit/posix/src/psignal.c
@@ -50,7 +50,6 @@
#include <rtems/posix/psignalimpl.h>
#include <rtems/posix/pthreadimpl.h>
#include <rtems/config.h>
-#include <rtems/seterr.h>
#include <rtems/sysinit.h>
/*
diff --git a/cpukit/posix/src/psignalclearsignals.c b/cpukit/posix/src/psignalclearsignals.c
index f31cbf0d27..0c8ae8e1a6 100644
--- a/cpukit/posix/src/psignalclearsignals.c
+++ b/cpukit/posix/src/psignalclearsignals.c
@@ -44,7 +44,6 @@
#include <rtems/score/isr.h>
#include <rtems/score/thread.h>
-#include <rtems/seterr.h>
#include <rtems/posix/threadsup.h>
#include <rtems/posix/psignalimpl.h>
#include <rtems/posix/pthreadimpl.h>
diff --git a/cpukit/posix/src/psignalsetprocesssignals.c b/cpukit/posix/src/psignalsetprocesssignals.c
index 213de57406..9af03943f4 100644
--- a/cpukit/posix/src/psignalsetprocesssignals.c
+++ b/cpukit/posix/src/psignalsetprocesssignals.c
@@ -43,7 +43,6 @@
#include <rtems/score/isr.h>
#include <rtems/score/thread.h>
-#include <rtems/seterr.h>
#include <rtems/posix/threadsup.h>
#include <rtems/posix/psignalimpl.h>
#include <rtems/posix/pthreadimpl.h>
diff --git a/cpukit/posix/src/psignalunblockthread.c b/cpukit/posix/src/psignalunblockthread.c
index 5b0168c22d..61c2602b96 100644
--- a/cpukit/posix/src/psignalunblockthread.c
+++ b/cpukit/posix/src/psignalunblockthread.c
@@ -46,7 +46,6 @@
#include <rtems/score/threadimpl.h>
#include <rtems/score/threadqimpl.h>
#include <rtems/score/watchdogimpl.h>
-#include <rtems/seterr.h>
#include <rtems/posix/threadsup.h>
#include <rtems/posix/psignalimpl.h>
#include <rtems/posix/pthreadimpl.h>
diff --git a/cpukit/posix/src/pthreadgetschedparam.c b/cpukit/posix/src/pthreadgetschedparam.c
index 09c2611ce9..88ea525d1b 100644
--- a/cpukit/posix/src/pthreadgetschedparam.c
+++ b/cpukit/posix/src/pthreadgetschedparam.c
@@ -47,7 +47,6 @@
#include <rtems/posix/pthreadimpl.h>
#include <rtems/posix/pthreadattrimpl.h>
#include <rtems/posix/priorityimpl.h>
-#include <rtems/score/schedulerimpl.h>
#include <rtems/score/threadimpl.h>
int pthread_getschedparam(
diff --git a/cpukit/posix/src/pthreadsetschedparam.c b/cpukit/posix/src/pthreadsetschedparam.c
index 18168a5501..06508ef451 100644
--- a/cpukit/posix/src/pthreadsetschedparam.c
+++ b/cpukit/posix/src/pthreadsetschedparam.c
@@ -49,7 +49,6 @@
#include <rtems/posix/pthreadimpl.h>
#include <rtems/posix/priorityimpl.h>
#include <rtems/score/threadimpl.h>
-#include <rtems/score/schedulerimpl.h>
static int _POSIX_Set_sched_param(
Thread_Control *the_thread,
diff --git a/cpukit/sapi/src/cpucounterconverter.c b/cpukit/sapi/src/cpucounterconverter.c
index 4cabdc5e4a..587fe460df 100644
--- a/cpukit/sapi/src/cpucounterconverter.c
+++ b/cpukit/sapi/src/cpucounterconverter.c
@@ -1,5 +1,14 @@
/* SPDX-License-Identifier: BSD-2-Clause */
+/**
+ * @file
+ *
+ * @ingroup RTEMSImpl
+ *
+ * @brief This source file contains a implementation of the counter value
+ * conversion functions.
+ */
+
/*
* Copyright (C) 2014, 2018 embedded brains GmbH & Co. KG
*
diff --git a/cpukit/sapi/src/sapirbtreeinsert.c b/cpukit/sapi/src/sapirbtreeinsert.c
index 0d0871891c..41fc47ef33 100644
--- a/cpukit/sapi/src/sapirbtreeinsert.c
+++ b/cpukit/sapi/src/sapirbtreeinsert.c
@@ -39,7 +39,6 @@
#endif
#include <rtems/rbtree.h>
-#include <rtems/score/rbtreeimpl.h>
RTEMS_STATIC_ASSERT(
sizeof( rtems_rbtree_compare_result ) >= sizeof( intptr_t ),
diff --git a/cpukit/sapi/src/version.c b/cpukit/sapi/src/version.c
index 385cf83f2a..7197ddd153 100644
--- a/cpukit/sapi/src/version.c
+++ b/cpukit/sapi/src/version.c
@@ -3,7 +3,7 @@
/**
* @file
*
- * @ingroup RTEMSAPIClassicVersion
+ * @ingroup RTEMSImplClassic
*
* @brief This source file contains the implementation of rtems_version(),
* rtems_version_control_key(), rtems_version_major(), rtems_version_minor(),
@@ -54,8 +54,8 @@
const char *rtems_version( void )
{
-#ifdef RTEMS_VERSION_VC_KEY
- return RTEMS_VERSION "." RTEMS_VERSION_VC_KEY;
+#ifdef RTEMS_VERSION_CONTROL_KEY
+ return RTEMS_VERSION "." RTEMS_VERSION_CONTROL_KEY;
#else
return RTEMS_VERSION;
#endif
@@ -78,8 +78,8 @@ int rtems_version_revision( void )
const char *rtems_version_control_key( void )
{
-#ifdef RTEMS_VERSION_VC_KEY
- return RTEMS_VERSION_VC_KEY;
+#ifdef RTEMS_VERSION_CONTROL_KEY
+ return RTEMS_VERSION_CONTROL_KEY;
#else
return "";
#endif
diff --git a/cpukit/score/cpu/aarch64/aarch64-exception-frame-print.c b/cpukit/score/cpu/aarch64/aarch64-exception-frame-print.c
index c5b477c72f..04a3dfdc0d 100644
--- a/cpukit/score/cpu/aarch64/aarch64-exception-frame-print.c
+++ b/cpukit/score/cpu/aarch64/aarch64-exception-frame-print.c
@@ -45,7 +45,7 @@
#include <inttypes.h>
#include <rtems/score/cpu.h>
-#include <rtems/score/io.h>
+#include <rtems/dev/io.h>
#include <rtems/bspIo.h>
typedef struct {
diff --git a/cpukit/score/cpu/aarch64/include/libcpu/mmu-vmsav8-64.h b/cpukit/score/cpu/aarch64/include/libcpu/mmu-vmsav8-64.h
index 0d65004f88..ca9b60e6d1 100644
--- a/cpukit/score/cpu/aarch64/include/libcpu/mmu-vmsav8-64.h
+++ b/cpukit/score/cpu/aarch64/include/libcpu/mmu-vmsav8-64.h
@@ -70,7 +70,7 @@ extern "C" {
#define AARCH64_MMU_CODE_RW_CACHED AARCH64_MMU_DATA_RW_CACHED
#define AARCH64_MMU_DATA_RO \
- ( AARCH64_MMU_FLAGS_BASE | MMU_DESC_MAIR_ATTR( 1 ) | MMU_DESC_WRITE_DISABLE )
+ ( AARCH64_MMU_FLAGS_BASE | MMU_DESC_MAIR_ATTR( 2 ) | MMU_DESC_WRITE_DISABLE )
#define AARCH64_MMU_CODE AARCH64_MMU_DATA_RO
#define AARCH64_MMU_CODE_RW AARCH64_MMU_DATA_RW
@@ -78,7 +78,7 @@ extern "C" {
#define AARCH64_MMU_DATA_RW_CACHED \
( AARCH64_MMU_FLAGS_BASE | MMU_DESC_MAIR_ATTR( 3 ) )
#define AARCH64_MMU_DATA_RW \
- ( AARCH64_MMU_FLAGS_BASE | MMU_DESC_MAIR_ATTR( 1 ) )
+ ( AARCH64_MMU_FLAGS_BASE | MMU_DESC_MAIR_ATTR( 2 ) )
#define AARCH64_MMU_DEVICE ( AARCH64_MMU_FLAGS_BASE | MMU_DESC_MAIR_ATTR( 0 ) )
rtems_status_code aarch64_mmu_map(
diff --git a/cpukit/score/cpu/aarch64/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/aarch64/include/rtems/score/cpuimpl.h
index b520e8bffb..8a0e476899 100644
--- a/cpukit/score/cpu/aarch64/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/aarch64/include/rtems/score/cpuimpl.h
@@ -174,6 +174,13 @@ static inline void _CPU_Use_thread_local_storage(
);
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ return (void *)(uintptr_t) context->thread_id;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/arm/__tls_get_addr.c b/cpukit/score/cpu/arm/__tls_get_addr.c
index 7ef42fdcb4..407bf3d639 100644
--- a/cpukit/score/cpu/arm/__tls_get_addr.c
+++ b/cpukit/score/cpu/arm/__tls_get_addr.c
@@ -48,7 +48,7 @@ void *__tls_get_addr(const TLS_Index *ti)
{
const Thread_Control *executing = _Thread_Get_executing();
void *tls_data = (char *) executing->Registers.thread_id
- + _TLS_Get_thread_control_block_area_size();
+ + _TLS_Get_thread_control_block_area_size( &_TLS_Configuration );
assert(ti->module == 1);
diff --git a/cpukit/score/cpu/arm/arm-exception-frame-print.c b/cpukit/score/cpu/arm/arm-exception-frame-print.c
index 7bc6795ea5..b089648184 100644
--- a/cpukit/score/cpu/arm/arm-exception-frame-print.c
+++ b/cpukit/score/cpu/arm/arm-exception-frame-print.c
@@ -41,11 +41,14 @@
#include <inttypes.h>
#include <rtems/score/cpu.h>
+#if defined(ARM_MULTILIB_ARCH_V7M)
+#include <rtems/score/armv7m.h>
+#endif
#include <rtems/bspIo.h>
static void _ARM_VFP_context_print( const ARM_VFP_context *vfp_context )
{
-#ifdef ARM_MULTILIB_VFP_D32
+#ifdef ARM_MULTILIB_VFP
if ( vfp_context != NULL ) {
const uint64_t *dx = &vfp_context->register_d0;
int i;
@@ -56,7 +59,14 @@ static void _ARM_VFP_context_print( const ARM_VFP_context *vfp_context )
vfp_context->register_fpscr
);
- for ( i = 0; i < 32; ++i ) {
+#if defined(ARM_MULTILIB_VFP_D32)
+ int regcount = 32;
+#elif defined(ARM_MULTILIB_VFP_D16)
+ int regcount = 16;
+#else
+ int regcount = 0;
+#endif
+ for ( i = 0; i < regcount; ++i ) {
uint32_t low = (uint32_t) dx[i];
uint32_t high = (uint32_t) (dx[i] >> 32);
@@ -66,6 +76,136 @@ static void _ARM_VFP_context_print( const ARM_VFP_context *vfp_context )
#endif
}
+static void _ARM_Cortex_M_fault_info_print( void )
+{
+#if defined(ARM_MULTILIB_ARCH_V7M)
+ /*
+ * prints content of additional debugging registers
+ * available on Cortex-Mx where x > 0 cores.
+ */
+ uint32_t cfsr = _ARMV7M_SCB->cfsr;
+ uint8_t mmfsr = ARMV7M_SCB_CFSR_MMFSR_GET( cfsr );
+ uint8_t bfsr = ( ARMV7M_SCB_CFSR_BFSR_GET( cfsr ) >> 8 );
+ uint16_t ufsr = ( ARMV7M_SCB_CFSR_UFSR_GET( cfsr ) >> 16 );
+ uint32_t hfsr = _ARMV7M_SCB->hfsr;
+ if ( mmfsr > 0 ) {
+ printk( "MMFSR= 0x%08" PRIx32 " (memory fault)\n", mmfsr );
+ if ( ( mmfsr & 0x1 ) != 0 ) {
+ printk( " IACCVIOL : 1 (instruction access violation)\n" );
+ }
+ if ( ( mmfsr & 0x2 ) != 0 ) {
+ printk( " DACCVIOL : 1 (data access violation)\n" );
+ }
+ if ( (mmfsr & 0x8 ) != 0 ) {
+ printk(
+ " MUNSTKERR : 1 (fault on unstacking on exception return)\n"
+ );
+ }
+ if ( ( mmfsr & 0x10 ) != 0 ) {
+ printk( " MSTKERR : 1 (fault on stacking on exception entry)\n" );
+ }
+ if ( (mmfsr & 0x20 ) != 0 ) {
+ printk( " MLSPERR : 1 (fault during lazy FP stack preservation)\n" );
+ }
+ if ( (mmfsr & 0x80 ) != 0 ) {
+ printk(
+ " MMFARVALID : 1 -> 0x%08" PRIx32 " (error address)\n",
+ _ARMV7M_SCB->mmfar
+ );
+ }
+ else {
+ printk( " MMFARVALID : 0 (undetermined error address)\n" );
+ }
+ }
+ if ( bfsr > 0 ) {
+ printk( "BFSR = 0x%08" PRIx32 " (bus fault)\n", bfsr );
+ if ( ( bfsr & 0x1 ) != 0 ) {
+ printk( " IBUSERR : 1 (instruction fetch error)\n" );
+ }
+ if ( (bfsr & 0x2 ) != 0 ) {
+ printk(
+ " PRECISERR : 1 (data bus error with known exact location)\n"
+ );
+ }
+ if ( ( bfsr & 0x4) != 0 ) {
+ printk(
+ " IMPRECISERR: 1 (data bus error without known exact location)\n"
+ );
+ }
+ if ( (bfsr & 0x8 ) != 0 ) {
+ printk(
+ " UNSTKERR : 1 (fault on unstacking on exception return)\n"
+ );
+ }
+ if ( ( bfsr & 0x10 ) != 0 ) {
+ printk( " STKERR : 1 (fault on stacking on exception entry)\n" );
+ }
+ if ( ( bfsr & 0x20 ) != 0 ) {
+ printk( " LSPERR : 1 (fault during lazy FP stack preservation)\n" );
+ }
+ if ( (bfsr & 0x80 ) != 0 ) {
+ printk(
+ " BFARVALID : 1 -> 0x%08" PRIx32 " (error address)\n",
+ _ARMV7M_SCB->bfar
+ );
+ }
+ else {
+ printk( " BFARVALID : 0 (undetermined error address)\n" );
+ }
+ }
+ if ( ufsr > 0 ) {
+ printk( "UFSR = 0x%08" PRIx32 " (usage fault)\n", ufsr);
+ if ( (ufsr & 0x1 ) != 0 ) {
+ printk( " UNDEFINSTR : 1 (undefined instruction issued)\n");
+ }
+ if ( (ufsr & 0x2 ) != 0 ) {
+ printk(
+ " INVSTATE : 1"
+ " (invalid instruction state"
+ " (Thumb not set in EPSR or invalid IT state in EPSR))\n"
+ );
+ }
+ if ( (ufsr & 0x4 ) != 0 ) {
+ printk( " INVPC : 1 (integrity check failure on EXC_RETURN)\n" );
+ }
+ if ( (ufsr & 0x8 ) != 0 ) {
+ printk(
+ " NOCP : 1"
+ " (coprocessor instruction issued"
+ " but coprocessor disabled or non existent)\n"
+ );
+ }
+ if ( ( ufsr & 0x100) != 0 ) {
+ printk( " UNALIGNED : 1 (unaligned access operation occurred)\n" );
+ }
+ if ( ( ufsr & 0x200) != 0 ) {
+ printk( " DIVBYZERO : 1 (division by zero)" );
+ }
+ }
+ if ( (hfsr & (
+ ARMV7M_SCB_HFSR_VECTTBL_MASK
+ | ARMV7M_SCB_HFSR_DEBUGEVT_MASK
+ | ARMV7M_SCB_HFSR_FORCED_MASK
+ ) ) != 0 ) {
+ printk( "HFSR = 0x%08" PRIx32 " (hard fault)\n", hfsr );
+ if ( (hfsr & ARMV7M_SCB_HFSR_VECTTBL_MASK ) != 0 ) {
+ printk(
+ " VECTTBL : 1 (error in address located in vector table)\n"
+ );
+ }
+ if ( (hfsr & ARMV7M_SCB_HFSR_FORCED_MASK ) != 0 ) {
+ printk(
+ " FORCED : 1 (configurable fault escalated to hard fault)\n"
+ );
+ }
+ if ( (hfsr & ARMV7M_SCB_HFSR_DEBUGEVT_MASK ) != 0 ) {
+ printk(
+ " DEBUGEVT : 1 (debug event occurred with debug system disabled)\n"
+ );
+ }
+ }
+#endif
+}
void _CPU_Exception_frame_print( const CPU_Exception_frame *frame )
{
printk(
@@ -109,4 +249,5 @@ void _CPU_Exception_frame_print( const CPU_Exception_frame *frame )
);
_ARM_VFP_context_print( frame->vfp_context );
+ _ARM_Cortex_M_fault_info_print();
}
diff --git a/cpukit/score/cpu/arm/armv4-isr-install-vector.c b/cpukit/score/cpu/arm/armv4-isr-install-vector.c
new file mode 100644
index 0000000000..739b02f8bf
--- /dev/null
+++ b/cpukit/score/cpu/arm/armv4-isr-install-vector.c
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreCPUARM
+ *
+ * @brief This source file contains the ARM-specific _CPU_ISR_install_vector().
+ */
+
+/*
+ * COPYRIGHT (c) 2000 Canon Research Centre France SA.
+ * Emmanuel Raguet, mailto:raguet@crf.canon.fr
+ *
+ * Copyright (c) 2002 Advent Networks, Inc
+ * Jay Monkman <jmonkman@adventnetworks.com>
+ *
+ * Copyright (C) 2009, 2017 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/cpu.h>
+
+#ifdef ARM_MULTILIB_ARCH_V4
+
+void _CPU_ISR_install_vector(
+ uint32_t vector,
+ CPU_ISR_handler new_handler,
+ CPU_ISR_handler *old_handler
+)
+{
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
+ /* Redirection table starts at the end of the vector table */
+ CPU_ISR_handler volatile *table = (CPU_ISR_handler *) (MAX_EXCEPTIONS * 4);
+
+ CPU_ISR_handler current_handler = table [vector];
+
+ /* The current handler is now the old one */
+ if (old_handler != NULL) {
+ *old_handler = current_handler;
+ }
+
+ /* Write only if necessary to avoid writes to a maybe read-only memory */
+ if (current_handler != new_handler) {
+ table [vector] = new_handler;
+ }
+#pragma GCC diagnostic pop
+}
+
+#endif /* ARM_MULTILIB_ARCH_V4 */
diff --git a/cpukit/score/cpu/arm/cpu.c b/cpukit/score/cpu/arm/cpu.c
index 65f1ad2014..c27f4de9f9 100644
--- a/cpukit/score/cpu/arm/cpu.c
+++ b/cpukit/score/cpu/arm/cpu.c
@@ -8,8 +8,7 @@
* @brief This source file contains static assertions to ensure the consistency
* of interfaces used in C and assembler and it contains the ARM-specific
* implementation of _CPU_Initialize(), _CPU_ISR_Get_level(),
- * _CPU_ISR_Set_level(), _CPU_ISR_install_vector(),
- * _CPU_Context_Initialize(), and _CPU_Fatal_halt().
+ * _CPU_ISR_Set_level(), _CPU_Context_Initialize(), and _CPU_Fatal_halt().
*/
/*
@@ -160,31 +159,6 @@ uint32_t _CPU_ISR_Get_level( void )
return ( level & ARM_PSR_I ) != 0;
}
-void _CPU_ISR_install_vector(
- uint32_t vector,
- CPU_ISR_handler new_handler,
- CPU_ISR_handler *old_handler
-)
-{
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Warray-bounds"
- /* Redirection table starts at the end of the vector table */
- CPU_ISR_handler volatile *table = (CPU_ISR_handler *) (MAX_EXCEPTIONS * 4);
-
- CPU_ISR_handler current_handler = table [vector];
-
- /* The current handler is now the old one */
- if (old_handler != NULL) {
- *old_handler = current_handler;
- }
-
- /* Write only if necessary to avoid writes to a maybe read-only memory */
- if (current_handler != new_handler) {
- table [vector] = new_handler;
- }
-#pragma GCC diagnostic pop
-}
-
void _CPU_Initialize( void )
{
/* Do nothing */
diff --git a/cpukit/score/cpu/arm/include/libcpu/arm-cp15.h b/cpukit/score/cpu/arm/include/libcpu/arm-cp15.h
index 333cd7c8a0..c239eaccc8 100644
--- a/cpukit/score/cpu/arm/include/libcpu/arm-cp15.h
+++ b/cpukit/score/cpu/arm/include/libcpu/arm-cp15.h
@@ -1309,15 +1309,17 @@ arm_cp15_data_cache_test_and_clean(void)
);
}
-/* In DDI0301H_arm1176jzfs_r0p7_trm
- * 'MCR p15, 0, <Rd>, c7, c14, 0' means
- * Clean and Invalidate Entire Data Cache
- */
ARM_CP15_TEXT_SECTION static inline void
arm_cp15_data_cache_clean_and_invalidate(void)
{
ARM_SWITCH_REGISTERS;
+#if __ARM_ARCH >= 6
+ /*
+ * In DDI0301H_arm1176jzfs_r0p7_trm
+ * 'MCR p15, 0, <Rd>, c7, c14, 0' means
+ * Clean and Invalidate Entire Data Cache
+ */
uint32_t sbz = 0;
__asm__ volatile (
@@ -1328,6 +1330,22 @@ arm_cp15_data_cache_clean_and_invalidate(void)
: [sbz] "r" (sbz)
: "memory"
);
+#else
+ /*
+ * Assume this is an ARM926EJ-S. Use the test, clean, and invalidate DCache
+ * operation.
+ */
+ __asm__ volatile (
+ ARM_SWITCH_TO_ARM
+ "1:\n"
+ "mrc p15, 0, r15, c7, c14, 3\n"
+ "bne 1b\n"
+ ARM_SWITCH_BACK
+ : ARM_SWITCH_OUTPUT
+ :
+ : "memory"
+ );
+#endif
}
ARM_CP15_TEXT_SECTION static inline void
diff --git a/cpukit/score/cpu/arm/include/rtems/score/armv7m.h b/cpukit/score/cpu/arm/include/rtems/score/armv7m.h
index 0f129f1d2e..7fa48b3aa5 100644
--- a/cpukit/score/cpu/arm/include/rtems/score/armv7m.h
+++ b/cpukit/score/cpu/arm/include/rtems/score/armv7m.h
@@ -159,8 +159,19 @@ typedef struct {
#define ARMV7M_SCB_SHCSR_MEMFAULTENA (1U << 16)
uint32_t shcsr;
+#define ARMV7M_SCB_CFSR_MMFSR_MASK 0xff
+#define ARMV7M_SCB_CFSR_MMFSR_GET(n) (n & ARMV7M_SCB_CFSR_MMFSR_MASK)
+#define ARMV7M_SCB_CFSR_BFSR_MASK 0xff00
+#define ARMV7M_SCB_CFSR_BFSR_GET(n) (n & ARMV7M_SCB_CFSR_BFSR_MASK)
+#define ARMV7M_SCB_CFSR_UFSR_MASK 0xffff0000
+#define ARMV7M_SCB_CFSR_UFSR_GET(n) (n & ARMV7M_SCB_CFSR_UFSR_MASK)
uint32_t cfsr;
+
+#define ARMV7M_SCB_HFSR_VECTTBL_MASK 0x2
+#define ARMV7M_SCB_HFSR_FORCED_MASK (1U << 30)
+#define ARMV7M_SCB_HFSR_DEBUGEVT_MASK (1U << 31)
uint32_t hfsr;
+
uint32_t dfsr;
uint32_t mmfar;
uint32_t bfar;
diff --git a/cpukit/score/cpu/arm/include/rtems/score/cpu.h b/cpukit/score/cpu/arm/include/rtems/score/cpu.h
index 3cd43970b1..a462b48cf1 100644
--- a/cpukit/score/cpu/arm/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/arm/include/rtems/score/cpu.h
@@ -585,7 +585,7 @@ typedef enum {
ARM_EXCEPTION_IRQ = 6,
ARM_EXCEPTION_FIQ = 7,
MAX_EXCEPTIONS = 8,
- ARM_EXCEPTION_MAKE_ENUM_32_BIT = 0xffffffff
+ ARM_EXCEPTION_MAKE_ENUM_32_BIT = 0x7fffffff
} Arm_symbolic_exception_name;
#endif /* defined(ARM_MULTILIB_ARCH_V4) */
diff --git a/cpukit/score/cpu/arm/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/arm/include/rtems/score/cpuatomic.h
deleted file mode 100644
index 01bb99cda3..0000000000
--- a/cpukit/score/cpu/arm/include/rtems/score/cpuatomic.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/*
- * COPYRIGHT (c) 2012-2013 Deng Hengyi.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
-
-#include <rtems/score/cpustdatomic.h>
-
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/arm/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/arm/include/rtems/score/cpuimpl.h
index f9b40889f5..04d23f0ea7 100644
--- a/cpukit/score/cpu/arm/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/arm/include/rtems/score/cpuimpl.h
@@ -178,6 +178,13 @@ static inline void _CPU_Use_thread_local_storage(
#endif
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ return (void *) context->thread_id;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/bfin/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/bfin/include/rtems/score/cpuatomic.h
deleted file mode 100644
index 598ee76b20..0000000000
--- a/cpukit/score/cpu/bfin/include/rtems/score/cpuatomic.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * COPYRIGHT (c) 2012-2013 Deng Hengyi.
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
-
-#include <rtems/score/cpustdatomic.h>
-
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/bfin/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/bfin/include/rtems/score/cpuimpl.h
index 05628a2c0b..5a445d9420 100644
--- a/cpukit/score/cpu/bfin/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/bfin/include/rtems/score/cpuimpl.h
@@ -41,11 +41,15 @@ RTEMS_NO_RETURN void _CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr error );
static inline void _CPU_Context_volatile_clobber( uintptr_t pattern )
{
+ (void) pattern;
+
/* TODO */
}
static inline void _CPU_Context_validate( uintptr_t pattern )
{
+ (void) pattern;
+
while (1) {
/* TODO */
}
@@ -68,6 +72,14 @@ static inline void _CPU_Use_thread_local_storage(
(void) context;
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ (void) context;
+ return NULL;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/i386/cpu_asm.S b/cpukit/score/cpu/i386/cpu_asm.S
index 6b114e94e1..bb5c096e72 100644
--- a/cpukit/score/cpu/i386/cpu_asm.S
+++ b/cpukit/score/cpu/i386/cpu_asm.S
@@ -67,11 +67,13 @@
.p2align 1
PUBLIC (_CPU_Context_switch)
+ PUBLIC (_CPU_Context_switch_no_return)
.set RUNCONTEXT_ARG, 4 /* save context argument */
.set HEIRCONTEXT_ARG, 8 /* restore context argument */
SYM (_CPU_Context_switch):
+SYM (_CPU_Context_switch_no_return):
movl RUNCONTEXT_ARG(esp),eax /* eax = running threads context */
GET_SELF_CPU_CONTROL edx /* edx has address for per_CPU information */
movl PER_CPU_ISR_DISPATCH_DISABLE(edx),ecx
diff --git a/cpukit/score/cpu/i386/include/rtems/score/cpu.h b/cpukit/score/cpu/i386/include/rtems/score/cpu.h
index 6aa97d309e..a12b0f2b92 100644
--- a/cpukit/score/cpu/i386/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/i386/include/rtems/score/cpu.h
@@ -2,9 +2,9 @@
/**
* @file
- *
+ *
* @brief Intel I386 CPU Dependent Source
- *
+ *
* This include file contains information pertaining to the Intel
* i386 processor.
*/
@@ -51,7 +51,7 @@ extern "C" {
#include <rtems/score/paravirt.h>
#endif
#include <rtems/score/i386.h>
-
+
/**
* @defgroup RTEMSScoreCPUi386 i386 Specific Support
*
@@ -163,7 +163,7 @@ typedef struct {
} Context_Control;
#define _CPU_Context_Get_SP( _context ) \
- (_context)->esp
+ (uintptr_t) (_context)->esp
#ifdef RTEMS_SMP
static inline bool _CPU_Context_Get_is_executing(
@@ -572,6 +572,11 @@ void _CPU_Context_switch(
Context_Control *heir
);
+RTEMS_NO_RETURN void _CPU_Context_switch_no_return(
+ Context_Control *executing,
+ Context_Control *heir
+);
+
/*
* _CPU_Context_restore
*
diff --git a/cpukit/score/cpu/i386/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/i386/include/rtems/score/cpuatomic.h
deleted file mode 100644
index 01bb99cda3..0000000000
--- a/cpukit/score/cpu/i386/include/rtems/score/cpuatomic.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/*
- * COPYRIGHT (c) 2012-2013 Deng Hengyi.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
-
-#include <rtems/score/cpustdatomic.h>
-
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/i386/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/i386/include/rtems/score/cpuimpl.h
index f0e4088218..da38ecacf7 100644
--- a/cpukit/score/cpu/i386/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/i386/include/rtems/score/cpuimpl.h
@@ -62,11 +62,15 @@ RTEMS_NO_RETURN void _CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr error );
static inline void _CPU_Context_volatile_clobber( uintptr_t pattern )
{
+ (void) pattern;
+
/* TODO */
}
static inline void _CPU_Context_validate( uintptr_t pattern )
{
+ (void) pattern;
+
while (1) {
/* TODO */
}
@@ -108,6 +112,13 @@ static inline void _CPU_Use_thread_local_storage(
);
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ return (void *) &context->gs;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/lm32/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/lm32/include/rtems/score/cpuatomic.h
deleted file mode 100644
index 598ee76b20..0000000000
--- a/cpukit/score/cpu/lm32/include/rtems/score/cpuatomic.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * COPYRIGHT (c) 2012-2013 Deng Hengyi.
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
-
-#include <rtems/score/cpustdatomic.h>
-
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/lm32/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/lm32/include/rtems/score/cpuimpl.h
index 679ef452f4..70a1db1d4d 100644
--- a/cpukit/score/cpu/lm32/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/lm32/include/rtems/score/cpuimpl.h
@@ -40,11 +40,15 @@ RTEMS_NO_RETURN void _CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr error );
static inline void _CPU_Context_volatile_clobber( uintptr_t pattern )
{
+ (void) pattern;
+
/* TODO */
}
static inline void _CPU_Context_validate( uintptr_t pattern )
{
+ (void) pattern;
+
while (1) {
/* TODO */
}
@@ -67,6 +71,14 @@ static inline void _CPU_Use_thread_local_storage(
(void) context;
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ (void) context;
+ return NULL;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/m68k/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/m68k/include/rtems/score/cpuatomic.h
deleted file mode 100644
index 01bb99cda3..0000000000
--- a/cpukit/score/cpu/m68k/include/rtems/score/cpuatomic.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/*
- * COPYRIGHT (c) 2012-2013 Deng Hengyi.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
-
-#include <rtems/score/cpustdatomic.h>
-
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/m68k/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/m68k/include/rtems/score/cpuimpl.h
index ec90a41ae2..521e9fc4c2 100644
--- a/cpukit/score/cpu/m68k/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/m68k/include/rtems/score/cpuimpl.h
@@ -60,11 +60,15 @@ RTEMS_NO_RETURN void _CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr error );
static inline void _CPU_Context_volatile_clobber( uintptr_t pattern )
{
+ (void) pattern;
+
/* TODO */
}
static inline void _CPU_Context_validate( uintptr_t pattern )
{
+ (void) pattern;
+
while (1) {
/* TODO */
}
@@ -91,6 +95,13 @@ static inline void _CPU_Use_thread_local_storage(
(void) context;
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ return (void *) context->thread_pointer;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/microblaze/include/machine/elf_machdep.h b/cpukit/score/cpu/microblaze/include/machine/elf_machdep.h
new file mode 100644
index 0000000000..e6d661c596
--- /dev/null
+++ b/cpukit/score/cpu/microblaze/include/machine/elf_machdep.h
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2023 On-Line Applications Research Corporation (OAR)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MICROBLAZE_ELF_MACHDEP_H_
+#define _MICROBLAZE_ELF_MACHDEP_H_
+
+#define ELF64_MACHDEP_ID EM_MICROBLAZE
+#define ELF32_MACHDEP_ID EM_MICROBLAZE
+
+#define ELF64_MACHDEP_ENDIANNESS ELFDATA2LSB
+#define ELF32_MACHDEP_ENDIANNESS ELFDATA2LSB
+
+#define ELF32_MACHDEP_ID_CASES \
+ case EM_MICROBLAZE: \
+ break;
+
+#define ELF64_MACHDEP_ID_CASES \
+ case EM_MICROBLAZE: \
+ break;
+
+#define KERN_ELFSIZE 32
+#define ARCH_ELFSIZE 32 /* MD native binary size */
+
+/* Processor specific relocation types */
+
+#define R_MICROBLAZE_NONE 0
+#define R_MICROBLAZE_32 1
+#define R_MICROBLAZE_32_PCREL 2
+#define R_MICROBLAZE_64_PCREL 3
+#define R_MICROBLAZE_32_PCREL_LO 4
+#define R_MICROBLAZE_64 5
+#define R_MICROBLAZE_32_LO 6
+#define R_MICROBLAZE_SRO32 7
+#define R_MICROBLAZE_SRW32 8
+#define R_MICROBLAZE_64_NONE 9
+#define R_MICROBLAZE_32_SYM_OP_SYM 10
+#define R_MICROBLAZE_GNU_VTINHERIT 11
+#define R_MICROBLAZE_GNU_VTENTRY 12
+#define R_MICROBLAZE_GOTPC_64 13
+#define R_MICROBLAZE_GOT_64 14
+#define R_MICROBLAZE_PLT_64 15
+#define R_MICROBLAZE_REL 16
+#define R_MICROBLAZE_JUMP_SLOT 17
+#define R_MICROBLAZE_GLOB_DAT 18
+#define R_MICROBLAZE_GOTOFF_64 19
+#define R_MICROBLAZE_GOTOFF_32 20
+#define R_MICROBLAZE_COPY 21
+#define R_MICROBLAZE_TLS 22
+#define R_MICROBLAZE_TLSGD 23
+#define R_MICROBLAZE_TLSLD 24
+#define R_MICROBLAZE_TLSDTPMOD32 25
+#define R_MICROBLAZE_TLSDTPREL32 26
+#define R_MICROBLAZE_TLSDTPREL64 27
+#define R_MICROBLAZE_TLSGOTTPREL32 28
+#define R_MICROBLAZE_TLSTPREL32 29
+
+#define R_TYPE( name ) R_MICROBLAZE_##name
+
+#endif /* _MICROBLAZE_ELF_MACHDEP_H_ */
diff --git a/cpukit/score/cpu/microblaze/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/microblaze/include/rtems/score/cpuimpl.h
index 4e315e856d..760ebbfbbb 100644
--- a/cpukit/score/cpu/microblaze/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/microblaze/include/rtems/score/cpuimpl.h
@@ -100,6 +100,13 @@ static inline void _CPU_Use_thread_local_storage(
(void) context;
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ return (void *) context->thread_pointer;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/mips/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/mips/include/rtems/score/cpuatomic.h
deleted file mode 100644
index 01bb99cda3..0000000000
--- a/cpukit/score/cpu/mips/include/rtems/score/cpuatomic.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/*
- * COPYRIGHT (c) 2012-2013 Deng Hengyi.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
-
-#include <rtems/score/cpustdatomic.h>
-
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/mips/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/mips/include/rtems/score/cpuimpl.h
index ad6b7ae615..98ed1c492f 100644
--- a/cpukit/score/cpu/mips/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/mips/include/rtems/score/cpuimpl.h
@@ -60,11 +60,15 @@ RTEMS_NO_RETURN void _CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr error );
static inline void _CPU_Context_volatile_clobber( uintptr_t pattern )
{
+ (void) pattern;
+
/* TODO */
}
static inline void _CPU_Context_validate( uintptr_t pattern )
{
+ (void) pattern;
+
while (1) {
/* TODO */
}
@@ -87,6 +91,14 @@ static inline void _CPU_Use_thread_local_storage(
(void) context;
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ (void) context;
+ return NULL;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/moxie/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/moxie/include/rtems/score/cpuatomic.h
deleted file mode 100644
index 01bb99cda3..0000000000
--- a/cpukit/score/cpu/moxie/include/rtems/score/cpuatomic.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/*
- * COPYRIGHT (c) 2012-2013 Deng Hengyi.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
-
-#include <rtems/score/cpustdatomic.h>
-
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/moxie/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/moxie/include/rtems/score/cpuimpl.h
index 8ded8c34e9..44c70cc56d 100644
--- a/cpukit/score/cpu/moxie/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/moxie/include/rtems/score/cpuimpl.h
@@ -60,11 +60,15 @@ RTEMS_NO_RETURN void _CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr error );
static inline void _CPU_Context_volatile_clobber( uintptr_t pattern )
{
+ (void) pattern;
+
/* TODO */
}
static inline void _CPU_Context_validate( uintptr_t pattern )
{
+ (void) pattern;
+
while (1) {
/* TODO */
}
@@ -87,6 +91,14 @@ static inline void _CPU_Use_thread_local_storage(
(void) context;
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ (void) context;
+ return NULL;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/nios2/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/nios2/include/rtems/score/cpuatomic.h
deleted file mode 100644
index 01bb99cda3..0000000000
--- a/cpukit/score/cpu/nios2/include/rtems/score/cpuatomic.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/*
- * COPYRIGHT (c) 2012-2013 Deng Hengyi.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
-
-#include <rtems/score/cpustdatomic.h>
-
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/nios2/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/nios2/include/rtems/score/cpuimpl.h
index e1beaca74c..3c9c6734ec 100644
--- a/cpukit/score/cpu/nios2/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/nios2/include/rtems/score/cpuimpl.h
@@ -84,6 +84,13 @@ static inline void _CPU_Use_thread_local_storage(
__asm__ volatile ( "" : : "r" ( r23 ) );
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ return (void *) context->r23;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/no_cpu/cpuidle.c b/cpukit/score/cpu/no_cpu/cpuidle.c
index bff1309d39..dbaf109905 100644
--- a/cpukit/score/cpu/no_cpu/cpuidle.c
+++ b/cpukit/score/cpu/no_cpu/cpuidle.c
@@ -1,5 +1,14 @@
/* SPDX-License-Identifier: BSD-2-Clause */
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreCPU
+ *
+ * @brief This source file contains the implementation of the
+ * _CPU_Thread_Idle_body().
+ */
+
/*
* Copyright (C) 2013, 2014 embedded brains GmbH & Co. KG
*
@@ -33,6 +42,13 @@
void *_CPU_Thread_Idle_body( uintptr_t ignored )
{
+ /*
+ * This is a workaround for:
+ *
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108658
+ */
+ __asm__ volatile ("");
+
while ( true ) {
/* Do nothing */
}
diff --git a/cpukit/score/cpu/no_cpu/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/no_cpu/include/rtems/score/cpuimpl.h
index 61afcdd014..61f1ab7ba5 100644
--- a/cpukit/score/cpu/no_cpu/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/no_cpu/include/rtems/score/cpuimpl.h
@@ -201,6 +201,22 @@ static inline void _CPU_Use_thread_local_storage(
(void) context;
}
+/**
+ * @brief Gets the thread pointer of the context.
+ *
+ * The thread pointer is used to get the address of thread-local storage
+ * objects associated with a thread.
+ *
+ * @param context is the processor context containing the thread pointer.
+ */
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ (void) context;
+ return NULL;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/or1k/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/or1k/include/rtems/score/cpuatomic.h
deleted file mode 100644
index 01bb99cda3..0000000000
--- a/cpukit/score/cpu/or1k/include/rtems/score/cpuatomic.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/*
- * COPYRIGHT (c) 2012-2013 Deng Hengyi.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
-
-#include <rtems/score/cpustdatomic.h>
-
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/or1k/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/or1k/include/rtems/score/cpuimpl.h
index 5e6865eb1f..9b58b1b77a 100644
--- a/cpukit/score/cpu/or1k/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/or1k/include/rtems/score/cpuimpl.h
@@ -79,6 +79,14 @@ static inline void _CPU_Use_thread_local_storage(
(void) context;
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ (void) context;
+ return NULL;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/powerpc/include/rtems/asm.h b/cpukit/score/cpu/powerpc/include/rtems/asm.h
index 27af64e724..94f54245b4 100644
--- a/cpukit/score/cpu/powerpc/include/rtems/asm.h
+++ b/cpukit/score/cpu/powerpc/include/rtems/asm.h
@@ -75,23 +75,21 @@
#define __PROC_LABEL_PREFIX__ __USER_LABEL_PREFIX__
#endif
-#include <rtems/concat.h>
-
/* Use the right prefix for global labels. */
-#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+#define SYM(x) RTEMS_XCONCAT (__USER_LABEL_PREFIX__, x)
/* Use the right prefix for procedure labels. */
-#define PROC(x) CONCAT1 (__PROC_LABEL_PREFIX__, x)
+#define PROC(x) RTEMS_XCONCAT (__PROC_LABEL_PREFIX__, x)
/* Use the right prefix for registers. */
-#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
+#define REG(x) RTEMS_XCONCAT (__REGISTER_PREFIX__, x)
/* Use the right prefix for floating point registers. */
-#define FREG(x) CONCAT1 (__FLOAT_REGISTER_PREFIX__, x)
+#define FREG(x) RTEMS_XCONCAT (__FLOAT_REGISTER_PREFIX__, x)
/*
* define macros for all of the registers on this CPU
diff --git a/cpukit/score/cpu/powerpc/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/powerpc/include/rtems/score/cpuatomic.h
deleted file mode 100644
index 01bb99cda3..0000000000
--- a/cpukit/score/cpu/powerpc/include/rtems/score/cpuatomic.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/*
- * COPYRIGHT (c) 2012-2013 Deng Hengyi.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
-
-#include <rtems/score/cpustdatomic.h>
-
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/powerpc/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/powerpc/include/rtems/score/cpuimpl.h
index 6d984b92e4..68b7165546 100644
--- a/cpukit/score/cpu/powerpc/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/powerpc/include/rtems/score/cpuimpl.h
@@ -301,6 +301,13 @@ static inline void _CPU_Use_thread_local_storage(
__asm__ volatile ( "" : : "r" ( tp ) );
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ return (void *) ppc_get_context( context )->tp;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/riscv/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/riscv/include/rtems/score/cpuatomic.h
deleted file mode 100644
index 8ee9606b44..0000000000
--- a/cpukit/score/cpu/riscv/include/rtems/score/cpuatomic.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * COPYRIGHT (c) 2012-2013 Deng Hengyi.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
-
-#include <rtems/score/cpustdatomic.h>
-
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h
index 47cf2e338c..13fd60ed8c 100644
--- a/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h
@@ -454,6 +454,13 @@ static inline void _CPU_Use_thread_local_storage(
__asm__ volatile ( "" : : "r" ( tp ) );
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ return (void *) context->tp;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/sh/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/sh/include/rtems/score/cpuatomic.h
deleted file mode 100644
index 598ee76b20..0000000000
--- a/cpukit/score/cpu/sh/include/rtems/score/cpuatomic.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * COPYRIGHT (c) 2012-2013 Deng Hengyi.
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
-
-#include <rtems/score/cpustdatomic.h>
-
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/sh/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/sh/include/rtems/score/cpuimpl.h
index 3e37c8f57d..e5f45eb363 100644
--- a/cpukit/score/cpu/sh/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/sh/include/rtems/score/cpuimpl.h
@@ -41,11 +41,15 @@ RTEMS_NO_RETURN void _CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr error );
static inline void _CPU_Context_volatile_clobber( uintptr_t pattern )
{
+ (void) pattern;
+
/* TODO */
}
static inline void _CPU_Context_validate( uintptr_t pattern )
{
+ (void) pattern;
+
while (1) {
/* TODO */
}
@@ -68,6 +72,14 @@ static inline void _CPU_Use_thread_local_storage(
(void) context;
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ (void) context;
+ return NULL;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/sparc/cpu_asm.S b/cpukit/score/cpu/sparc/cpu_asm.S
index 8947064ff8..fd7186b499 100644
--- a/cpukit/score/cpu/sparc/cpu_asm.S
+++ b/cpukit/score/cpu/sparc/cpu_asm.S
@@ -246,6 +246,14 @@ done_flushing:
mov %g1, %psr ! restore status register and
! **** ENABLE TRAPS ****
+ /*
+ * WARNING: This code does not run with the restored stack pointer. In
+ * SMP configurations, it uses a processor-specific stack. In
+ * uniprocessor configurations, it uses the stack of the caller. In
+ * this case, the caller shall ensure that it is not the interrupt
+ * stack (which is also the system initialization stack).
+ */
+
ld [%o1 + G5_OFFSET], %g5 ! restore the global registers
ld [%o1 + G7_OFFSET], %g7
@@ -266,7 +274,9 @@ done_flushing:
ldd [%o1 + I4_OFFSET], %i4
ldd [%o1 + I6_FP_OFFSET], %i6
- ldd [%o1 + O6_SP_OFFSET], %o6 ! restore the output registers
+ ldd [%o1 + O6_SP_OFFSET], %o6 ! restore the non-volatile output
+ ! registers (stack pointer,
+ ! link register)
jmp %o7 + 8 ! return
nop ! delay slot
@@ -325,6 +335,23 @@ SYM(_CPU_Context_restore):
ba SYM(_CPU_Context_restore_heir)
mov %i0, %o1 ! in the delay slot
+#if !defined(RTEMS_SMP)
+ .align 4
+ PUBLIC(_SPARC_Start_multitasking)
+SYM(_SPARC_Start_multitasking):
+ /*
+ * Restore the stack pointer right now, so that the window flushing and
+ * interrupts during _CPU_Context_restore_heir() use the stack of the
+ * heir thread. This is crucial for the interrupt handling to prevent
+ * a concurrent use of the interrupt stack (which is also the system
+ * initialization stack).
+ */
+ ld [%o0 + O6_SP_OFFSET], %o6
+
+ ba SYM(_CPU_Context_restore)
+ nop
+#endif
+
/*
* void _SPARC_Interrupt_trap()
*
@@ -496,9 +523,7 @@ dont_do_the_window:
bnz dont_switch_stacks ! No, then do not switch stacks
#if defined(RTEMS_PROFILING)
- sethi %hi(_SPARC_Counter), %o5
- ld [%o5 + %lo(_SPARC_Counter)], %l4
- call %l4
+ call SYM(_SPARC_Counter_read_ISR_disabled)
nop
mov %o0, %o5
#else
@@ -577,7 +602,7 @@ dont_switch_stacks:
cmp %l7, 0
bne profiling_not_outer_most_exit
nop
- call %l4 ! Call _SPARC_Counter.counter_read
+ call SYM(_SPARC_Counter_read_ISR_disabled)
mov %g1, %l4 ! Save previous interrupt status
mov %o0, %o2 ! o2 = 3rd arg = interrupt exit instant
mov %l3, %o1 ! o1 = 2nd arg = interrupt entry instant
diff --git a/cpukit/score/cpu/sparc/include/libcpu/grlib-tn-0018.h b/cpukit/score/cpu/sparc/include/libcpu/grlib-tn-0018.h
index bb43234128..10f34c6123 100644
--- a/cpukit/score/cpu/sparc/include/libcpu/grlib-tn-0018.h
+++ b/cpukit/score/cpu/sparc/include/libcpu/grlib-tn-0018.h
@@ -1,5 +1,14 @@
/* SPDX-License-Identifier: BSD-2-Clause */
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreCPUSPARC
+ *
+ * @brief This header file provides interfaces of the GRLIB-TN-0018 LEON3FT
+ * RETT Restart Errata fixes.
+ */
+
/*
* Copyright (C) 2020 Cobham Gaisler AB
*
diff --git a/cpukit/score/cpu/sparc/include/rtems/score/cpu.h b/cpukit/score/cpu/sparc/include/rtems/score/cpu.h
index 43b9b75bec..a21cef371f 100644
--- a/cpukit/score/cpu/sparc/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sparc/include/rtems/score/cpu.h
@@ -993,6 +993,25 @@ RTEMS_NO_RETURN void _CPU_Context_switch_no_return(
*/
RTEMS_NO_RETURN void _CPU_Context_restore( Context_Control *new_context );
+#if !defined(RTEMS_SMP)
+/**
+ * @brief Starts multitasking in uniprocessor configurations.
+ *
+ * This function just sets the stack of the heir thread and then calls
+ * _CPU_Context_restore().
+ *
+ * This is causes that the window flushing and interrupts during
+ * _CPU_Context_restore() use the stack of the heir thread. This is crucial
+ * for the interrupt handling to prevent a concurrent use of the interrupt
+ * stack (which is also the system initialization stack).
+ *
+ * @param[in] heir is the context of the heir thread.
+ */
+RTEMS_NO_RETURN void _SPARC_Start_multitasking( Context_Control *heir );
+
+#define _CPU_Start_multitasking( _heir ) _SPARC_Start_multitasking( _heir )
+#endif
+
#if defined(RTEMS_SMP)
uint32_t _CPU_SMP_Initialize( void );
@@ -1132,31 +1151,7 @@ typedef uint32_t CPU_Counter_ticks;
uint32_t _CPU_Counter_frequency( void );
-typedef CPU_Counter_ticks ( *SPARC_Counter_read )( void );
-
-/*
- * The SPARC processors supported by RTEMS have no built-in CPU counter
- * support. We have to use some hardware counter module for this purpose, for
- * example the GPTIMER instance used by the clock driver. The BSP must provide
- * an implementation of the CPU counter read function. This allows the use of
- * dynamic hardware enumeration.
- */
-typedef struct {
- SPARC_Counter_read read_isr_disabled;
- SPARC_Counter_read read;
- volatile const CPU_Counter_ticks *counter_register;
- volatile const uint32_t *pending_register;
- uint32_t pending_mask;
- CPU_Counter_ticks accumulated;
- CPU_Counter_ticks interval;
-} SPARC_Counter;
-
-extern const SPARC_Counter _SPARC_Counter;
-
-static inline CPU_Counter_ticks _CPU_Counter_read( void )
-{
- return ( *_SPARC_Counter.read )();
-}
+CPU_Counter_ticks _CPU_Counter_read( void );
/** Type that can store a 32-bit integer or a pointer. */
typedef uintptr_t CPU_Uint32ptr;
diff --git a/cpukit/score/cpu/sparc/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/sparc/include/rtems/score/cpuatomic.h
deleted file mode 100644
index 01bb99cda3..0000000000
--- a/cpukit/score/cpu/sparc/include/rtems/score/cpuatomic.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/*
- * COPYRIGHT (c) 2012-2013 Deng Hengyi.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
-
-#include <rtems/score/cpustdatomic.h>
-
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h
index e15be48e9e..9697209a97 100644
--- a/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h
@@ -251,6 +251,20 @@ static inline void _CPU_Use_thread_local_storage(
__asm__ volatile ( "" : : "r" ( g7 ) );
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ return (void *) context->g7;
+}
+
+#if defined(RTEMS_PROFILING)
+/**
+ * @brief Reads the CPU counter while interrupts are disabled.
+ */
+CPU_Counter_ticks _SPARC_Counter_read_ISR_disabled( void );
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h b/cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h
deleted file mode 100644
index d9be984179..0000000000
--- a/cpukit/score/cpu/sparc/include/rtems/score/sparcimpl.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/**
- * @file
- *
- * @ingroup RTEMSScoreCPUSPARC
- *
- * @brief This header file provides interfaces used by the SPARC port of RTEMS.
- */
-
-/*
- * Copyright (C) 2016, 2018 embedded brains GmbH & Co. KG
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTEMS_SCORE_SPARCIMPL_H
-#define _RTEMS_SCORE_SPARCIMPL_H
-
-#include <rtems/score/cpu.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-struct timecounter;
-
-/*
- * Provides a mutable alias to _SPARC_Counter for use in
- * _SPARC_Counter_initialize(). The _SPARC_Counter and _SPARC_Counter_mutable
- * are defined via the SPARC_COUNTER_DEFINITION define.
- */
-extern SPARC_Counter _SPARC_Counter_mutable;
-
-void _SPARC_Counter_at_tick_clock( void );
-
-CPU_Counter_ticks _SPARC_Counter_read_default( void );
-
-CPU_Counter_ticks _SPARC_Counter_read_up( void );
-
-CPU_Counter_ticks _SPARC_Counter_read_down( void );
-
-CPU_Counter_ticks _SPARC_Counter_read_clock_isr_disabled( void );
-
-CPU_Counter_ticks _SPARC_Counter_read_clock( void );
-
-CPU_Counter_ticks _SPARC_Counter_read_asr23( void );
-
-uint32_t _SPARC_Get_timecount_up( struct timecounter * );
-
-uint32_t _SPARC_Get_timecount_down( struct timecounter * );
-
-uint32_t _SPARC_Get_timecount_clock( struct timecounter * );
-
-uint32_t _SPARC_Get_timecount_asr23( struct timecounter * );
-
-/*
- * Defines the _SPARC_Counter and _SPARC_Counter_mutable global variables.
- * Place this define in the global file scope of the CPU counter support file
- * of the BSP.
- */
-#define SPARC_COUNTER_DEFINITION \
- __asm__ ( \
- "\t.global\t_SPARC_Counter\n" \
- "\t.global\t_SPARC_Counter_mutable\n" \
- "\t.section\t.data._SPARC_Counter,\"aw\",@progbits\n" \
- "\t.align\t4\n" \
- "\t.type\t_SPARC_Counter, #object\n" \
- "\t.size\t_SPARC_Counter, 28\n" \
- "_SPARC_Counter:\n" \
- "_SPARC_Counter_mutable:\n" \
- "\t.long\t_SPARC_Counter_read_default\n" \
- "\t.long\t_SPARC_Counter_read_default\n" \
- "\t.long\t0\n" \
- "\t.long\t0\n" \
- "\t.long\t0\n" \
- "\t.long\t0\n" \
- "\t.long\t0\n" \
- "\t.previous\n" \
- )
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _RTEMS_SCORE_SPARCIMPL_H */
diff --git a/cpukit/score/cpu/sparc/sparc-counter-asm.S b/cpukit/score/cpu/sparc/sparc-counter-asm.S
deleted file mode 100644
index 890876eff1..0000000000
--- a/cpukit/score/cpu/sparc/sparc-counter-asm.S
+++ /dev/null
@@ -1,151 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/*
- * Copyright (C) 2016, 2018 embedded brains GmbH & Co. KG
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems/asm.h>
-
- /*
- * All functions except _SPARC_Counter_read_clock() in this module are
- * sometimes called with traps disabled.
- */
-
- .section ".text"
- .align 4
-
- PUBLIC(_SPARC_Counter_read_default)
-SYM(_SPARC_Counter_read_default):
- sethi %hi(_SPARC_Counter + 12), %o1
- ld [%o1 + %lo(_SPARC_Counter + 12)], %o0
- add %o0, 1, %o0
- st %o0, [%o1 + %lo(_SPARC_Counter + 12)]
- jmp %o7 + 8
- nop
-
- PUBLIC(_SPARC_Counter_read_up)
- PUBLIC(_SPARC_Get_timecount_up)
-SYM(_SPARC_Counter_read_up):
-SYM(_SPARC_Get_timecount_up):
- sethi %hi(_SPARC_Counter + 8), %o0
- ld [%o0 + %lo(_SPARC_Counter + 8)], %o0
- jmp %o7 + 8
- ld [%o0], %o0
-
- PUBLIC(_SPARC_Counter_read_down)
- PUBLIC(_SPARC_Get_timecount_down)
-SYM(_SPARC_Counter_read_down):
-SYM(_SPARC_Get_timecount_down):
- sethi %hi(_SPARC_Counter + 8), %o0
- ld [%o0 + %lo(_SPARC_Counter + 8)], %o0
- ld [%o0], %o0
- jmp %o7 + 8
- xnor %g0, %o0, %o0
-
- /*
- * For the corresponding C code is something like this:
- *
- * CPU_Counter_ticks _SPARC_Counter_read_clock_isr_disabled( void )
- * {
- * const SPARC_Counter *ctr;
- * CPU_Counter_ticks ticks;
- * CPU_Counter_ticks accumulated;
- *
- * ctr = &_SPARC_Counter;
- * ticks = *ctr->counter_register;
- * accumulated = ctr->accumulated;
- *
- * if ( ( *ctr->pending_register & ctr->pending_mask ) != 0 ) {
- * ticks = *ctr->counter_register;
- * accumulated += ctr->interval;
- * }
- *
- * return accumulated - ticks;
- * }
- */
- PUBLIC(_SPARC_Counter_read_clock_isr_disabled)
-SYM(_SPARC_Counter_read_clock_isr_disabled):
- sethi %hi(_SPARC_Counter), %o5
- or %o5, %lo(_SPARC_Counter), %o5
- ld [%o5 + 8], %o3
- ld [%o5 + 12], %o4
- ld [%o5 + 16], %o2
- ld [%o3], %o0
- ld [%o4], %o1
- btst %o1, %o2
- bne .Lpending_isr_disabled
- ld [%o5 + 20], %o4
- jmp %o7 + 8
- sub %o4, %o0, %o0
-.Lpending_isr_disabled:
- ld [%o5 + 24], %o5
- ld [%o3], %o0
- add %o4, %o5, %o4
- jmp %o7 + 8
- sub %o4, %o0, %o0
-
- /*
- * For the corresponding C code see
- * _SPARC_Counter_read_clock_isr_disabled() above.
- */
- PUBLIC(_SPARC_Counter_read_clock)
- PUBLIC(_SPARC_Get_timecount_clock)
-SYM(_SPARC_Counter_read_clock):
-SYM(_SPARC_Get_timecount_clock):
- sethi %hi(_SPARC_Counter), %o5
- or %o5, %lo(_SPARC_Counter), %o5
- ta SPARC_SWTRAP_IRQDIS
- ld [%o5 + 8], %o3
- ld [%o5 + 12], %o4
- ld [%o5 + 16], %o2
- ld [%o3], %o0
- ld [%o4], %o1
- btst %o1, %o2
- bne .Lpending
- ld [%o5 + 20], %o4
- ta SPARC_SWTRAP_IRQEN
-#ifdef __FIX_LEON3FT_TN0018
- /* A nop is added to work around the GRLIB-TN-0018 errata */
- nop
-#endif
- jmp %o7 + 8
- sub %o4, %o0, %o0
-.Lpending:
- ld [%o5 + 24], %o5
- ld [%o3], %o0
- ta SPARC_SWTRAP_IRQEN
- add %o4, %o5, %o4
- jmp %o7 + 8
- sub %o4, %o0, %o0
-
- PUBLIC(_SPARC_Counter_read_asr23)
- PUBLIC(_SPARC_Get_timecount_asr23)
-SYM(_SPARC_Counter_read_asr23):
-SYM(_SPARC_Get_timecount_asr23):
- jmp %o7 + 8
- mov %asr23, %o0
diff --git a/cpukit/score/cpu/sparc/sparc-isr-handler.S b/cpukit/score/cpu/sparc/sparc-isr-handler.S
index cb4fb345a3..9ecb44e870 100644
--- a/cpukit/score/cpu/sparc/sparc-isr-handler.S
+++ b/cpukit/score/cpu/sparc/sparc-isr-handler.S
@@ -231,9 +231,7 @@ dont_do_the_window:
bnz dont_switch_stacks ! No, then do not switch stacks
#if defined(RTEMS_PROFILING)
- sethi %hi(_SPARC_Counter), %o5
- ld [%o5 + %lo(_SPARC_Counter)], %l4
- call %l4
+ call SYM(_SPARC_Counter_read_ISR_disabled)
nop
mov %o0, %o5
#else
@@ -335,7 +333,7 @@ pil_fixed:
cmp %l7, 0
bne profiling_not_outer_most_exit
nop
- call %l4 ! Call _SPARC_Counter.counter_read
+ call SYM(_SPARC_Counter_read_ISR_disabled)
mov %g1, %l4 ! Save previous interrupt status
mov %o0, %o2 ! o2 = 3rd arg = interrupt exit instant
mov %l3, %o1 ! o1 = 2nd arg = interrupt entry instant
diff --git a/cpukit/score/cpu/sparc/syscall.S b/cpukit/score/cpu/sparc/syscall.S
index 0beffd4162..ee21c1b005 100644
--- a/cpukit/score/cpu/sparc/syscall.S
+++ b/cpukit/score/cpu/sparc/syscall.S
@@ -44,8 +44,10 @@ SYM(syscall):
ta 0 ! syscall 1, halt with %g1,%g2,%g3 info
PUBLIC(sparc_syscall_exit)
+ PUBLIC(_CPU_Fatal_halt)
SYM(sparc_syscall_exit):
+SYM(_CPU_Fatal_halt):
mov SYS_exit, %g1
mov %o0, %g2 ! Additional exit code 1
diff --git a/cpukit/score/cpu/sparc/syscall.h b/cpukit/score/cpu/sparc/syscall.h
index 2f20886840..6fc8fa3a6f 100644
--- a/cpukit/score/cpu/sparc/syscall.h
+++ b/cpukit/score/cpu/sparc/syscall.h
@@ -1 +1,9 @@
+/**
+ * @file
+ *
+ * @ingroup RTEMSScoreCPUSPARC
+ *
+ * @brief This header file provides system call interfaces.
+ */
+
#define SYS_exit 1
diff --git a/cpukit/score/cpu/sparc64/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/sparc64/include/rtems/score/cpuatomic.h
deleted file mode 100644
index 01bb99cda3..0000000000
--- a/cpukit/score/cpu/sparc64/include/rtems/score/cpuatomic.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/*
- * COPYRIGHT (c) 2012-2013 Deng Hengyi.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
-
-#include <rtems/score/cpustdatomic.h>
-
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/sparc64/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/sparc64/include/rtems/score/cpuimpl.h
index c49c637805..25a362c350 100644
--- a/cpukit/score/cpu/sparc64/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/sparc64/include/rtems/score/cpuimpl.h
@@ -60,11 +60,15 @@ RTEMS_NO_RETURN void _CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr error );
static inline void _CPU_Context_volatile_clobber( uintptr_t pattern )
{
+ (void) pattern;
+
/* TODO */
}
static inline void _CPU_Context_validate( uintptr_t pattern )
{
+ (void) pattern;
+
while (1) {
/* TODO */
}
@@ -87,6 +91,14 @@ static inline void _CPU_Use_thread_local_storage(
(void) context;
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ (void) context;
+ return NULL;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/v850/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/v850/include/rtems/score/cpuatomic.h
deleted file mode 100644
index 01bb99cda3..0000000000
--- a/cpukit/score/cpu/v850/include/rtems/score/cpuatomic.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/*
- * COPYRIGHT (c) 2012-2013 Deng Hengyi.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
-
-#include <rtems/score/cpustdatomic.h>
-
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/v850/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/v850/include/rtems/score/cpuimpl.h
index 5ec528961c..5bc1c42459 100644
--- a/cpukit/score/cpu/v850/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/v850/include/rtems/score/cpuimpl.h
@@ -60,11 +60,15 @@ RTEMS_NO_RETURN void _CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr error );
static inline void _CPU_Context_volatile_clobber( uintptr_t pattern )
{
+ (void) pattern;
+
/* TODO */
}
static inline void _CPU_Context_validate( uintptr_t pattern )
{
+ (void) pattern;
+
while (1) {
/* TODO */
}
@@ -87,6 +91,14 @@ static inline void _CPU_Use_thread_local_storage(
(void) context;
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ (void) context;
+ return NULL;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/cpu/x86_64/include/rtems/score/cpuatomic.h b/cpukit/score/cpu/x86_64/include/rtems/score/cpuatomic.h
deleted file mode 100644
index 598ee76b20..0000000000
--- a/cpukit/score/cpu/x86_64/include/rtems/score/cpuatomic.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * COPYRIGHT (c) 2012-2013 Deng Hengyi.
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#ifndef _RTEMS_SCORE_ATOMIC_CPU_H
-#define _RTEMS_SCORE_ATOMIC_CPU_H
-
-#include <rtems/score/cpustdatomic.h>
-
-#endif /* _RTEMS_SCORE_ATOMIC_CPU_H */
diff --git a/cpukit/score/cpu/x86_64/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/x86_64/include/rtems/score/cpuimpl.h
index e0e301b6bc..d4b7a71009 100644
--- a/cpukit/score/cpu/x86_64/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/x86_64/include/rtems/score/cpuimpl.h
@@ -44,21 +44,25 @@ RTEMS_NO_RETURN void _CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr error );
static inline void _CPU_Context_volatile_clobber( uintptr_t pattern )
{
- /* TODO */
-}
+ (void) pattern;
-static inline void _CPU_Instruction_illegal( void )
-{
- __asm__ volatile ( ".word 0" );
+ /* TODO */
}
static inline void _CPU_Context_validate( uintptr_t pattern )
{
+ (void) pattern;
+
while (1) {
/* TODO */
}
}
+static inline void _CPU_Instruction_illegal( void )
+{
+ __asm__ volatile ( ".word 0" );
+}
+
static inline void _CPU_Instruction_no_operation( void )
{
__asm__ volatile ( "nop" );
@@ -71,6 +75,14 @@ static inline void _CPU_Use_thread_local_storage(
(void) context;
}
+static inline void *_CPU_Get_TLS_thread_pointer(
+ const Context_Control *context
+)
+{
+ (void) context;
+ return NULL;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/score/src/hash.c b/cpukit/score/src/hash.c
index dc9143f4c0..0b9f127e54 100644
--- a/cpukit/score/src/hash.c
+++ b/cpukit/score/src/hash.c
@@ -39,7 +39,7 @@
#include <rtems/score/hash.h>
#include <rtems/score/assert.h>
-#include <rtems/score/io.h>
+#include <rtems/base64.h>
#include <limits.h>
@@ -64,7 +64,7 @@ void _Hash_Finalize( Hash_Context *context, Hash_Control *hash )
context->hash = hash;
context->index = 0;
hash->chars[ sizeof( *hash ) - 1 ] = '\0';
- n = _IO_Base64url(
+ n = _Base64url_Encode(
_Hash_Put_char,
context,
digest,
diff --git a/cpukit/score/src/iobase64.c b/cpukit/score/src/iobase64.c
deleted file mode 100644
index 27b977c8a0..0000000000
--- a/cpukit/score/src/iobase64.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* SPDX-License-Identifier: ISC */
-
-/**
- * @file
- *
- * @ingroup RTEMSScoreIO
- *
- * @brief This source file contains the implementation of
- * _IO_Base64() and _IO_Base64url().
- */
-
-/*
- * Copyright (C) 2020, 2021 embedded brains GmbH & Co. KG
- * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <rtems/score/io.h>
-
-static void
-_IO_Put(int c, void *arg, IO_Put_char put_char)
-{
- (*put_char)(c, arg);
-}
-
-static int
-_IO_Base64_with_encoding(IO_Put_char put_char, void *arg, const void *src,
- size_t srclen, const char *wordbreak, int wordlen, const char *encoding)
-{
- unsigned int loops = 0;
- const unsigned char *in = src;
- int out = 0;
-
- if (wordlen < 4) {
- wordlen = 4;
- }
-
- while (srclen > 2) {
- _IO_Put(encoding[(in[0]>>2)&0x3f], arg, put_char);
- _IO_Put(encoding[((in[0]<<4)&0x30)|
- ((in[1]>>4)&0x0f)], arg, put_char);
- _IO_Put(encoding[((in[1]<<2)&0x3c)|
- ((in[2]>>6)&0x03)], arg, put_char);
- _IO_Put(encoding[in[2]&0x3f], arg, put_char);
- in += 3;
- srclen -= 3;
- out += 4;
-
- loops++;
- if (srclen != 0 &&
- (int)((loops + 1) * 4) >= wordlen)
- {
- const char *w = wordbreak;
- loops = 0;
- while (*w != '\0') {
- _IO_Put(*w, arg, put_char);
- ++w;
- ++out;
- }
- }
- }
- if (srclen == 2) {
- _IO_Put(encoding[(in[0]>>2)&0x3f], arg, put_char);
- _IO_Put(encoding[((in[0]<<4)&0x30)|
- ((in[1]>>4)&0x0f)], arg, put_char);
- _IO_Put(encoding[((in[1]<<2)&0x3c)], arg, put_char);
- _IO_Put('=', arg, put_char);
- out += 4;
- } else if (srclen == 1) {
- _IO_Put(encoding[(in[0]>>2)&0x3f], arg, put_char);
- _IO_Put(encoding[((in[0]<<4)&0x30)], arg, put_char);
- _IO_Put('=', arg, put_char);
- _IO_Put('=', arg, put_char);
- out += 4;
- }
- return out;
-}
-
-static const char base64[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
-
-int
-_IO_Base64(IO_Put_char put_char, void *arg, const void *src, size_t srclen,
- const char *wordbreak, int wordlen)
-{
- return _IO_Base64_with_encoding(put_char, arg, src, srclen, wordbreak,
- wordlen, base64);
-}
-
-static const char base64url[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=";
-
-int
-_IO_Base64url(IO_Put_char put_char, void *arg, const void *src, size_t srclen,
- const char *wordbreak, int wordlen)
-{
- return _IO_Base64_with_encoding(put_char, arg, src, srclen, wordbreak,
- wordlen, base64url);
-}
diff --git a/cpukit/score/src/isr.c b/cpukit/score/src/isr.c
index 75df00e228..7337028b0f 100644
--- a/cpukit/score/src/isr.c
+++ b/cpukit/score/src/isr.c
@@ -44,6 +44,8 @@
#include <rtems/score/percpu.h>
#include <rtems/config.h>
+const char * const volatile _ISR_Stack_size_object = _ISR_Stack_size;
+
void _ISR_Handler_initialization( void )
{
uint32_t cpu_max;
diff --git a/cpukit/score/src/objectextendinformation.c b/cpukit/score/src/objectextendinformation.c
index 414766f219..9a627b1a7c 100644
--- a/cpukit/score/src/objectextendinformation.c
+++ b/cpukit/score/src/objectextendinformation.c
@@ -59,7 +59,7 @@ Objects_Maximum _Objects_Extend_information(
uint32_t index_base;
uint32_t index_end;
uint32_t index;
- Objects_Maximum extend_count;
+ uint32_t extend_count;
Objects_Maximum old_maximum;
uint32_t new_maximum;
size_t object_block_size;
diff --git a/cpukit/score/src/objectinitializeinformation.c b/cpukit/score/src/objectinitializeinformation.c
index 3482f2871e..7c1bfd877f 100644
--- a/cpukit/score/src/objectinitializeinformation.c
+++ b/cpukit/score/src/objectinitializeinformation.c
@@ -42,7 +42,6 @@
#include <rtems/score/objectimpl.h>
#include <rtems/score/address.h>
#include <rtems/score/chainimpl.h>
-#include <rtems/score/interr.h>
#include <rtems/score/sysstate.h>
void _Objects_Initialize_information(
diff --git a/cpukit/score/src/processormaskcopy.c b/cpukit/score/src/processormaskcopy.c
index 863bd1574e..3f1c2cf250 100644
--- a/cpukit/score/src/processormaskcopy.c
+++ b/cpukit/score/src/processormaskcopy.c
@@ -39,7 +39,7 @@
#include "config.h"
#endif
-#include <rtems/score/processormask.h>
+#include <rtems/score/processormaskimpl.h>
const Processor_mask _Processor_mask_The_one_and_only = { .__bits[ 0 ] = 1 };
diff --git a/cpukit/score/src/threadchangepriority.c b/cpukit/score/src/threadchangepriority.c
index ca49f6f417..78291b7798 100644
--- a/cpukit/score/src/threadchangepriority.c
+++ b/cpukit/score/src/threadchangepriority.c
@@ -111,6 +111,7 @@ static void _Thread_Priority_action_change(
void *arg
)
{
+ (void) arg;
_Thread_Set_scheduler_node_priority(
priority_aggregation,
priority_group_order
diff --git a/cpukit/score/src/threadq.c b/cpukit/score/src/threadq.c
index e694029a46..3c6d72bd14 100644
--- a/cpukit/score/src/threadq.c
+++ b/cpukit/score/src/threadq.c
@@ -179,5 +179,7 @@ void _Thread_queue_MP_callout_do_nothing(
)
{
/* Do nothing */
+ (void) the_proxy;
+ (void) mp_id;
}
#endif
diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c
index e43efd925b..038c483f65 100644
--- a/cpukit/score/src/threadqenqueue.c
+++ b/cpukit/score/src/threadqenqueue.c
@@ -400,6 +400,7 @@ void _Thread_queue_Deadlock_status( Thread_Control *the_thread )
void _Thread_queue_Deadlock_fatal( Thread_Control *the_thread )
{
+ (void) the_thread;
_Internal_error( INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK );
}
diff --git a/cpukit/score/src/threadqops.c b/cpukit/score/src/threadqops.c
index 83e00ca3ae..9a09b4c442 100644
--- a/cpukit/score/src/threadqops.c
+++ b/cpukit/score/src/threadqops.c
@@ -156,6 +156,8 @@ static void _Thread_queue_FIFO_do_initialize(
{
Scheduler_Node *scheduler_node;
+ (void) queue;
+ (void) queue_context;
scheduler_node = _Thread_Scheduler_get_home_node( the_thread );
_Chain_Initialize_node( &scheduler_node->Wait.Priority.Node.Node.Chain );
@@ -291,6 +293,7 @@ static Thread_queue_Priority_queue *_Thread_queue_Priority_queue_by_index(
)
{
#if defined(RTEMS_SMP)
+ _Assert( scheduler_index < _Scheduler_Count );
return &heads->Priority[ scheduler_index ];
#else
(void) scheduler_index;
diff --git a/cpukit/score/src/threadqtimeout.c b/cpukit/score/src/threadqtimeout.c
index acb3c1d048..e30a2ffded 100644
--- a/cpukit/score/src/threadqtimeout.c
+++ b/cpukit/score/src/threadqtimeout.c
@@ -53,6 +53,7 @@ void _Thread_queue_Add_timeout_ticks(
{
Watchdog_Interval ticks;
+ (void) queue;
ticks = queue_context->Timeout.ticks;
if ( ticks != WATCHDOG_NO_TIMEOUT ) {
diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c
index 16b09a96eb..72326682ca 100644
--- a/cpukit/score/src/threadrestart.c
+++ b/cpukit/score/src/threadrestart.c
@@ -46,10 +46,8 @@
#include <rtems/score/apimutex.h>
#include <rtems/score/assert.h>
#include <rtems/score/chainimpl.h>
-#include <rtems/score/freechainimpl.h>
#include <rtems/score/isrlock.h>
#include <rtems/score/schedulerimpl.h>
-#include <rtems/score/stackimpl.h>
#include <rtems/score/sysstate.h>
#include <rtems/score/threadqimpl.h>
#include <rtems/score/userextimpl.h>
@@ -85,6 +83,7 @@ static Thread_Control *_Thread_Join_flush_filter(
{
Thread_Join_context *join_context;
+ (void) queue;
join_context = (Thread_Join_context *) queue_context;
the_thread->Wait.return_argument = join_context->exit_value;
diff --git a/cpukit/score/src/tlsallocsize.c b/cpukit/score/src/tlsallocsize.c
index f78239192c..fa28391b83 100644
--- a/cpukit/score/src/tlsallocsize.c
+++ b/cpukit/score/src/tlsallocsize.c
@@ -10,7 +10,7 @@
*/
/*
- * Copyright (C) 2014, 2022 embedded brains GmbH & Co. KG
+ * Copyright (C) 2014, 2023 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -42,14 +42,47 @@
#include <rtems/score/interr.h>
#include <rtems/score/thread.h>
+extern char _TLS_Data_begin[];
+
+extern char _TLS_Data_size[];
+
+extern char _TLS_BSS_begin[];
+
+extern char _TLS_BSS_size[];
+
+extern char _TLS_Size[];
+
+/**
+ * @brief The TLS section alignment.
+ *
+ * This symbol is provided by the linker command file as the maximum alignment
+ * of the .tdata and .tbss sections. The linker ensures that the first TLS
+ * output section is aligned to the maximum alignment of all TLS output
+ * sections, see function _bfd_elf_tls_setup() in bfd/elflink.c of the GNU
+ * Binutils sources. The linker command file must take into account the case
+ * that the .tdata section is empty and the .tbss section is non-empty.
+ */
+extern char _TLS_Alignment[];
+
+const volatile TLS_Configuration _TLS_Configuration = {
+ .data_begin = _TLS_Data_begin,
+ .data_size = _TLS_Data_size,
+ .bss_begin = _TLS_BSS_begin,
+ .bss_size = _TLS_BSS_size,
+ .size = _TLS_Size,
+ .alignment = _TLS_Alignment
+};
+
static uintptr_t _TLS_Allocation_size;
uintptr_t _TLS_Get_allocation_size( void )
{
- uintptr_t size;
- uintptr_t allocation_size;
+ const volatile TLS_Configuration *config;
+ uintptr_t size;
+ uintptr_t allocation_size;
- size = _TLS_Get_size();
+ config = &_TLS_Configuration;
+ size = (uintptr_t) config->size;
if ( size == 0 ) {
return 0;
@@ -66,7 +99,7 @@ uintptr_t _TLS_Get_allocation_size( void )
* shall meet the stack alignment requirement.
*/
stack_align = CPU_STACK_ALIGNMENT;
- tls_align = RTEMS_ALIGN_UP( (uintptr_t) _TLS_Alignment, stack_align );
+ tls_align = RTEMS_ALIGN_UP( (uintptr_t) config->alignment, stack_align );
#ifndef __i386__
/* Reserve space for the dynamic thread vector */
diff --git a/cpukit/score/src/userextiterate.c b/cpukit/score/src/userextiterate.c
index 25f0f9658b..cae76d173c 100644
--- a/cpukit/score/src/userextiterate.c
+++ b/cpukit/score/src/userextiterate.c
@@ -47,8 +47,6 @@
#include <rtems/score/userextimpl.h>
-#include <pthread.h>
-
User_extensions_List _User_extensions_List = {
CHAIN_INITIALIZER_EMPTY( _User_extensions_List.Active ),
CHAIN_ITERATOR_REGISTRY_INITIALIZER( _User_extensions_List.Iterators )
@@ -120,6 +118,8 @@ void _User_extensions_Thread_begin_visitor(
{
User_extensions_thread_begin_extension callout = callouts->thread_begin;
+ (void) arg;
+
if ( callout != NULL ) {
(*callout)( executing );
}