summaryrefslogtreecommitdiffstats
path: root/cpukit/include/rtems
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2017-12-23 18:18:56 +1100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-01-25 08:45:26 +0100
commit2afb22b7e1ebcbe40373ff7e0efae7d207c655a9 (patch)
tree44759efe9374f13200a97e96d91bd9a2b7e5ce2a /cpukit/include/rtems
parentMAINTAINERS: Add myself to Write After Approval. (diff)
downloadrtems-2afb22b7e1ebcbe40373ff7e0efae7d207c655a9.tar.bz2
Remove make preinstall
A speciality of the RTEMS build system was the make preinstall step. It copied header files from arbitrary locations into the build tree. The header files were included via the -Bsome/build/tree/path GCC command line option. This has at least seven problems: * The make preinstall step itself needs time and disk space. * Errors in header files show up in the build tree copy. This makes it hard for editors to open the right file to fix the error. * There is no clear relationship between source and build tree header files. This makes an audit of the build process difficult. * The visibility of all header files in the build tree makes it difficult to enforce API barriers. For example it is discouraged to use BSP-specifics in the cpukit. * An introduction of a new build system is difficult. * Include paths specified by the -B option are system headers. This may suppress warnings. * The parallel build had sporadic failures on some hosts. This patch removes the make preinstall step. All installed header files are moved to dedicated include directories in the source tree. Let @RTEMS_CPU@ be the target architecture, e.g. arm, powerpc, sparc, etc. Let @RTEMS_BSP_FAMILIY@ be a BSP family base directory, e.g. erc32, imx, qoriq, etc. The new cpukit include directories are: * cpukit/include * cpukit/score/cpu/@RTEMS_CPU@/include * cpukit/libnetworking The new BSP include directories are: * bsps/include * bsps/@RTEMS_CPU@/include * bsps/@RTEMS_CPU@/@RTEMS_BSP_FAMILIY@/include There are build tree include directories for generated files. The include directory order favours the most general header file, e.g. it is not possible to override general header files via the include path order. The "bootstrap -p" option was removed. The new "bootstrap -H" option should be used to regenerate the "headers.am" files. Update #3254.
Diffstat (limited to 'cpukit/include/rtems')
-rw-r--r--cpukit/include/rtems/assoc.h204
-rw-r--r--cpukit/include/rtems/bdbuf.h699
-rw-r--r--cpukit/include/rtems/bdpart.h411
-rw-r--r--cpukit/include/rtems/blkdev.h460
-rw-r--r--cpukit/include/rtems/bsd.h141
-rw-r--r--cpukit/include/rtems/bspcmdline.h131
-rw-r--r--cpukit/include/rtems/capture-cli.h53
-rw-r--r--cpukit/include/rtems/capture.h1122
-rw-r--r--cpukit/include/rtems/captureimpl.h185
-rw-r--r--cpukit/include/rtems/cbs.h244
-rw-r--r--cpukit/include/rtems/chain.h789
-rwxr-xr-xcpukit/include/rtems/confdefs.h3587
-rw-r--r--cpukit/include/rtems/config.h397
-rw-r--r--cpukit/include/rtems/counter.h160
-rw-r--r--cpukit/include/rtems/cpuuse.h88
-rw-r--r--cpukit/include/rtems/debugger/rtems-debugger-remote.h72
-rw-r--r--cpukit/include/rtems/debugger/rtems-debugger-server.h217
-rw-r--r--cpukit/include/rtems/devfs.h255
-rw-r--r--cpukit/include/rtems/deviceio.h88
-rw-r--r--cpukit/include/rtems/devnull.h84
-rw-r--r--cpukit/include/rtems/devzero.h92
-rw-r--r--cpukit/include/rtems/diskdevs.h511
-rw-r--r--cpukit/include/rtems/dosfs.h433
-rw-r--r--cpukit/include/rtems/dumpbuf.h52
-rw-r--r--cpukit/include/rtems/error.h135
-rw-r--r--cpukit/include/rtems/extension.h245
-rw-r--r--cpukit/include/rtems/extensionimpl.h53
-rw-r--r--cpukit/include/rtems/fatal.h134
-rw-r--r--cpukit/include/rtems/fb.h101
-rw-r--r--cpukit/include/rtems/flashdisk.h460
-rw-r--r--cpukit/include/rtems/fsmount.h211
-rw-r--r--cpukit/include/rtems/ftpd.h74
-rw-r--r--cpukit/include/rtems/gxx_wrappers.h80
-rw-r--r--cpukit/include/rtems/ide_part_table.h207
-rw-r--r--cpukit/include/rtems/imfs.h946
-rw-r--r--cpukit/include/rtems/init.h69
-rw-r--r--cpukit/include/rtems/io.h254
-rw-r--r--cpukit/include/rtems/ioimpl.h65
-rw-r--r--cpukit/include/rtems/iosupp.h46
-rw-r--r--cpukit/include/rtems/jffs2.h604
-rw-r--r--cpukit/include/rtems/libcsupport.h193
-rw-r--r--cpukit/include/rtems/libi2c.h508
-rw-r--r--cpukit/include/rtems/libio.h1967
-rw-r--r--cpukit/include/rtems/libio_.h1049
-rw-r--r--cpukit/include/rtems/linkersets.h129
-rw-r--r--cpukit/include/rtems/malloc.h201
-rw-r--r--cpukit/include/rtems/media.h517
-rw-r--r--cpukit/include/rtems/monitor.h528
-rw-r--r--cpukit/include/rtems/mouse_parser.h121
-rw-r--r--cpukit/include/rtems/mptables.h32
-rw-r--r--cpukit/include/rtems/mw_uid.h194
-rw-r--r--cpukit/include/rtems/nvdisk-sram.h23
-rw-r--r--cpukit/include/rtems/nvdisk.h211
-rw-r--r--cpukit/include/rtems/passwd.h25
-rw-r--r--cpukit/include/rtems/pipe.h133
-rw-r--r--cpukit/include/rtems/posix/aio_misc.h113
-rw-r--r--cpukit/include/rtems/posix/barrierimpl.h99
-rw-r--r--cpukit/include/rtems/posix/condimpl.h184
-rw-r--r--cpukit/include/rtems/posix/config.h120
-rw-r--r--cpukit/include/rtems/posix/key.h95
-rw-r--r--cpukit/include/rtems/posix/keyimpl.h177
-rw-r--r--cpukit/include/rtems/posix/mmanimpl.h56
-rw-r--r--cpukit/include/rtems/posix/mqueue.h71
-rw-r--r--cpukit/include/rtems/posix/mqueueimpl.h183
-rw-r--r--cpukit/include/rtems/posix/muteximpl.h487
-rw-r--r--cpukit/include/rtems/posix/posixapi.h146
-rw-r--r--cpukit/include/rtems/posix/priorityimpl.h109
-rw-r--r--cpukit/include/rtems/posix/psignal.h35
-rw-r--r--cpukit/include/rtems/posix/psignalimpl.h140
-rw-r--r--cpukit/include/rtems/posix/pthread.h55
-rw-r--r--cpukit/include/rtems/posix/pthreadattrimpl.h95
-rw-r--r--cpukit/include/rtems/posix/pthreadimpl.h129
-rw-r--r--cpukit/include/rtems/posix/ptimer.h88
-rw-r--r--cpukit/include/rtems/posix/rwlockimpl.h64
-rw-r--r--cpukit/include/rtems/posix/semaphore.h56
-rw-r--r--cpukit/include/rtems/posix/semaphoreimpl.h143
-rw-r--r--cpukit/include/rtems/posix/shm.h213
-rw-r--r--cpukit/include/rtems/posix/shmimpl.h135
-rw-r--r--cpukit/include/rtems/posix/sigset.h45
-rw-r--r--cpukit/include/rtems/posix/spinlockimpl.h58
-rw-r--r--cpukit/include/rtems/posix/threadsup.h98
-rw-r--r--cpukit/include/rtems/posix/timer.h60
-rw-r--r--cpukit/include/rtems/posix/timerimpl.h134
-rw-r--r--cpukit/include/rtems/profiling.h333
-rw-r--r--cpukit/include/rtems/pty.h76
-rw-r--r--cpukit/include/rtems/qreslib.h269
-rw-r--r--cpukit/include/rtems/ramdisk.h227
-rw-r--r--cpukit/include/rtems/rbheap.h268
-rw-r--r--cpukit/include/rtems/rbtree.h456
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-bitmaps.h326
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-block-pos.h242
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-block.h344
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-buffer.h283
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-data.h89
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-dir-hash.h36
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-dir.h209
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-file-system-fwd.h29
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-file-system.h410
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-file.h416
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-group.h181
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-inode.h728
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-link.h124
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-mutex.h116
-rw-r--r--cpukit/include/rtems/rfs/rtems-rfs-trace.h135
-rw-r--r--cpukit/include/rtems/ringbuf.h63
-rw-r--r--cpukit/include/rtems/rtems-debugger.h81
-rw-r--r--cpukit/include/rtems/rtems-fdt-shell.h42
-rw-r--r--cpukit/include/rtems/rtems-fdt.h621
-rw-r--r--cpukit/include/rtems/rtems-rfs-format.h90
-rw-r--r--cpukit/include/rtems/rtems-rfs-shell.h48
-rw-r--r--cpukit/include/rtems/rtems-rfs.h38
-rw-r--r--cpukit/include/rtems/rtems/asr.h156
-rw-r--r--cpukit/include/rtems/rtems/asrimpl.h99
-rw-r--r--cpukit/include/rtems/rtems/attr.h191
-rw-r--r--cpukit/include/rtems/rtems/attrimpl.h263
-rw-r--r--cpukit/include/rtems/rtems/barrier.h173
-rw-r--r--cpukit/include/rtems/rtems/barrierimpl.h92
-rw-r--r--cpukit/include/rtems/rtems/cache.h370
-rw-r--r--cpukit/include/rtems/rtems/clock.h318
-rw-r--r--cpukit/include/rtems/rtems/config.h142
-rw-r--r--cpukit/include/rtems/rtems/dpmem.h179
-rw-r--r--cpukit/include/rtems/rtems/dpmemimpl.h85
-rw-r--r--cpukit/include/rtems/rtems/event.h526
-rw-r--r--cpukit/include/rtems/rtems/eventimpl.h146
-rw-r--r--cpukit/include/rtems/rtems/eventmp.h101
-rw-r--r--cpukit/include/rtems/rtems/intr.h373
-rw-r--r--cpukit/include/rtems/rtems/mainpage.h927
-rw-r--r--cpukit/include/rtems/rtems/message.h270
-rw-r--r--cpukit/include/rtems/rtems/messageimpl.h120
-rw-r--r--cpukit/include/rtems/rtems/modes.h132
-rw-r--r--cpukit/include/rtems/rtems/modesimpl.h146
-rw-r--r--cpukit/include/rtems/rtems/mp.h54
-rw-r--r--cpukit/include/rtems/rtems/msgmp.h211
-rw-r--r--cpukit/include/rtems/rtems/object.h370
-rw-r--r--cpukit/include/rtems/rtems/options.h83
-rw-r--r--cpukit/include/rtems/rtems/optionsimpl.h67
-rw-r--r--cpukit/include/rtems/rtems/part.h174
-rw-r--r--cpukit/include/rtems/rtems/partimpl.h223
-rw-r--r--cpukit/include/rtems/rtems/partmp.h144
-rw-r--r--cpukit/include/rtems/rtems/ratemon.h430
-rw-r--r--cpukit/include/rtems/rtems/ratemonimpl.h158
-rw-r--r--cpukit/include/rtems/rtems/region.h298
-rw-r--r--cpukit/include/rtems/rtems/regionimpl.h142
-rw-r--r--cpukit/include/rtems/rtems/sem.h278
-rw-r--r--cpukit/include/rtems/rtems/semimpl.h120
-rw-r--r--cpukit/include/rtems/rtems/semmp.h171
-rw-r--r--cpukit/include/rtems/rtems/signal.h83
-rw-r--r--cpukit/include/rtems/rtems/signalimpl.h51
-rw-r--r--cpukit/include/rtems/rtems/signalmp.h98
-rw-r--r--cpukit/include/rtems/rtems/smp.h78
-rw-r--r--cpukit/include/rtems/rtems/status.h263
-rw-r--r--cpukit/include/rtems/rtems/statusimpl.h64
-rw-r--r--cpukit/include/rtems/rtems/support.h170
-rw-r--r--cpukit/include/rtems/rtems/taskmp.h132
-rw-r--r--cpukit/include/rtems/rtems/tasks.h716
-rw-r--r--cpukit/include/rtems/rtems/tasksimpl.h131
-rw-r--r--cpukit/include/rtems/rtems/timer.h384
-rw-r--r--cpukit/include/rtems/rtems/timerimpl.h209
-rw-r--r--cpukit/include/rtems/rtems/types.h235
-rw-r--r--cpukit/include/rtems/rtemsdialer.h24
-rw-r--r--cpukit/include/rtems/rtemspppd.h49
-rw-r--r--cpukit/include/rtems/rtl/dlfcn-shell.h17
-rw-r--r--cpukit/include/rtems/rtl/rap-shell.h14
-rw-r--r--cpukit/include/rtems/rtl/rap.h115
-rw-r--r--cpukit/include/rtems/rtl/rtl-allocator.h181
-rw-r--r--cpukit/include/rtems/rtl/rtl-fwd.h33
-rw-r--r--cpukit/include/rtems/rtl/rtl-indirect-ptr.h235
-rw-r--r--cpukit/include/rtems/rtl/rtl-obj-cache.h132
-rw-r--r--cpukit/include/rtems/rtl/rtl-obj-comp.h122
-rw-r--r--cpukit/include/rtems/rtl/rtl-obj-fwd.h39
-rw-r--r--cpukit/include/rtems/rtl/rtl-obj.h635
-rw-r--r--cpukit/include/rtems/rtl/rtl-sym.h135
-rw-r--r--cpukit/include/rtems/rtl/rtl-trace.h102
-rw-r--r--cpukit/include/rtems/rtl/rtl-unresolved.h212
-rw-r--r--cpukit/include/rtems/rtl/rtl.h321
-rw-r--r--cpukit/include/rtems/scheduler.h247
-rw-r--r--cpukit/include/rtems/score/address.h200
-rw-r--r--cpukit/include/rtems/score/apimutex.h109
-rw-r--r--cpukit/include/rtems/score/assert.h108
-rw-r--r--cpukit/include/rtems/score/atomic.h156
-rw-r--r--cpukit/include/rtems/score/basedefs.h415
-rw-r--r--cpukit/include/rtems/score/chain.h102
-rw-r--r--cpukit/include/rtems/score/chainimpl.h1123
-rw-r--r--cpukit/include/rtems/score/context.h163
-rw-r--r--cpukit/include/rtems/score/copyrt.h44
-rw-r--r--cpukit/include/rtems/score/corebarrier.h91
-rw-r--r--cpukit/include/rtems/score/corebarrierimpl.h173
-rw-r--r--cpukit/include/rtems/score/coremsg.h185
-rw-r--r--cpukit/include/rtems/score/coremsgimpl.h494
-rw-r--r--cpukit/include/rtems/score/coremutex.h104
-rw-r--r--cpukit/include/rtems/score/coremuteximpl.h447
-rw-r--r--cpukit/include/rtems/score/corerwlockimpl.h182
-rw-r--r--cpukit/include/rtems/score/coresem.h61
-rw-r--r--cpukit/include/rtems/score/coresemimpl.h207
-rw-r--r--cpukit/include/rtems/score/cpustdatomic.h682
-rw-r--r--cpukit/include/rtems/score/freechain.h111
-rw-r--r--cpukit/include/rtems/score/heap.h518
-rw-r--r--cpukit/include/rtems/score/heapimpl.h601
-rw-r--r--cpukit/include/rtems/score/interr.h268
-rw-r--r--cpukit/include/rtems/score/io.h46
-rw-r--r--cpukit/include/rtems/score/isr.h155
-rw-r--r--cpukit/include/rtems/score/isrlevel.h153
-rw-r--r--cpukit/include/rtems/score/isrlock.h439
-rw-r--r--cpukit/include/rtems/score/mpci.h135
-rw-r--r--cpukit/include/rtems/score/mpciimpl.h326
-rw-r--r--cpukit/include/rtems/score/mppkt.h121
-rw-r--r--cpukit/include/rtems/score/mrsp.h79
-rw-r--r--cpukit/include/rtems/score/mrspimpl.h384
-rw-r--r--cpukit/include/rtems/score/muteximpl.h37
-rw-r--r--cpukit/include/rtems/score/object.h469
-rw-r--r--cpukit/include/rtems/score/objectimpl.h1002
-rw-r--r--cpukit/include/rtems/score/objectmp.h197
-rw-r--r--cpukit/include/rtems/score/onceimpl.h52
-rw-r--r--cpukit/include/rtems/score/percpu.h851
-rw-r--r--cpukit/include/rtems/score/priority.h203
-rw-r--r--cpukit/include/rtems/score/prioritybitmap.h79
-rw-r--r--cpukit/include/rtems/score/prioritybitmapimpl.h215
-rw-r--r--cpukit/include/rtems/score/priorityimpl.h435
-rw-r--r--cpukit/include/rtems/score/processormask.h290
-rw-r--r--cpukit/include/rtems/score/profiling.h140
-rw-r--r--cpukit/include/rtems/score/protectedheap.h172
-rw-r--r--cpukit/include/rtems/score/rbtree.h568
-rw-r--r--cpukit/include/rtems/score/rbtreeimpl.h72
-rw-r--r--cpukit/include/rtems/score/scheduler.h556
-rw-r--r--cpukit/include/rtems/score/schedulercbs.h346
-rw-r--r--cpukit/include/rtems/score/schedulercbsimpl.h59
-rw-r--r--cpukit/include/rtems/score/scheduleredf.h197
-rw-r--r--cpukit/include/rtems/score/scheduleredfimpl.h164
-rw-r--r--cpukit/include/rtems/score/scheduleredfsmp.h200
-rw-r--r--cpukit/include/rtems/score/schedulerimpl.h1203
-rw-r--r--cpukit/include/rtems/score/schedulernode.h217
-rw-r--r--cpukit/include/rtems/score/schedulernodeimpl.h146
-rw-r--r--cpukit/include/rtems/score/schedulerpriority.h163
-rw-r--r--cpukit/include/rtems/score/schedulerpriorityaffinitysmp.h181
-rw-r--r--cpukit/include/rtems/score/schedulerpriorityimpl.h241
-rw-r--r--cpukit/include/rtems/score/schedulerprioritysmp.h171
-rw-r--r--cpukit/include/rtems/score/schedulerprioritysmpimpl.h184
-rw-r--r--cpukit/include/rtems/score/schedulersimple.h126
-rw-r--r--cpukit/include/rtems/score/schedulersimpleimpl.h103
-rw-r--r--cpukit/include/rtems/score/schedulersimplesmp.h155
-rw-r--r--cpukit/include/rtems/score/schedulersmp.h127
-rw-r--r--cpukit/include/rtems/score/schedulersmpimpl.h1482
-rw-r--r--cpukit/include/rtems/score/schedulerstrongapa.h171
-rw-r--r--cpukit/include/rtems/score/semaphoreimpl.h73
-rw-r--r--cpukit/include/rtems/score/smp.h64
-rw-r--r--cpukit/include/rtems/score/smpbarrier.h125
-rw-r--r--cpukit/include/rtems/score/smpimpl.h354
-rw-r--r--cpukit/include/rtems/score/smplock.h327
-rw-r--r--cpukit/include/rtems/score/smplockmcs.h262
-rw-r--r--cpukit/include/rtems/score/smplockseq.h176
-rw-r--r--cpukit/include/rtems/score/smplockstats.h277
-rw-r--r--cpukit/include/rtems/score/smplockticket.h187
-rw-r--r--cpukit/include/rtems/score/stack.h69
-rw-r--r--cpukit/include/rtems/score/stackimpl.h99
-rw-r--r--cpukit/include/rtems/score/states.h50
-rw-r--r--cpukit/include/rtems/score/statesimpl.h283
-rw-r--r--cpukit/include/rtems/score/status.h129
-rw-r--r--cpukit/include/rtems/score/sysstate.h119
-rw-r--r--cpukit/include/rtems/score/thread.h935
-rw-r--r--cpukit/include/rtems/score/threaddispatch.h281
-rw-r--r--cpukit/include/rtems/score/threadimpl.h1969
-rw-r--r--cpukit/include/rtems/score/threadmp.h113
-rw-r--r--cpukit/include/rtems/score/threadq.h595
-rw-r--r--cpukit/include/rtems/score/threadqimpl.h1265
-rw-r--r--cpukit/include/rtems/score/timecounter.h244
-rw-r--r--cpukit/include/rtems/score/timecounterimpl.h50
-rw-r--r--cpukit/include/rtems/score/timespec.h272
-rw-r--r--cpukit/include/rtems/score/timestamp.h323
-rw-r--r--cpukit/include/rtems/score/tls.h217
-rw-r--r--cpukit/include/rtems/score/tod.h32
-rw-r--r--cpukit/include/rtems/score/todimpl.h304
-rw-r--r--cpukit/include/rtems/score/userext.h273
-rw-r--r--cpukit/include/rtems/score/userextimpl.h369
-rw-r--r--cpukit/include/rtems/score/watchdog.h166
-rw-r--r--cpukit/include/rtems/score/watchdogimpl.h574
-rw-r--r--cpukit/include/rtems/score/wkspace.h138
-rw-r--r--cpukit/include/rtems/serdbg.h151
-rw-r--r--cpukit/include/rtems/serdbgcnf.h91
-rw-r--r--cpukit/include/rtems/serial_mouse.h169
-rw-r--r--cpukit/include/rtems/seterr.h53
-rw-r--r--cpukit/include/rtems/shell.h385
-rw-r--r--cpukit/include/rtems/shellconfig.h554
-rw-r--r--cpukit/include/rtems/sparse-disk.h137
-rw-r--r--cpukit/include/rtems/spurious.h42
-rw-r--r--cpukit/include/rtems/stackchk.h139
-rw-r--r--cpukit/include/rtems/stdio-redirect.h115
-rw-r--r--cpukit/include/rtems/stringto.h262
-rw-r--r--cpukit/include/rtems/sysinit.h118
-rw-r--r--cpukit/include/rtems/system.h66
-rw-r--r--cpukit/include/rtems/telnetd.h110
-rw-r--r--cpukit/include/rtems/termios_printk.h101
-rw-r--r--cpukit/include/rtems/termios_printk_cnf.h81
-rw-r--r--cpukit/include/rtems/termiostypes.h602
-rw-r--r--cpukit/include/rtems/test.h314
-rw-r--r--cpukit/include/rtems/timecounter.h335
-rw-r--r--cpukit/include/rtems/timespec.h305
-rw-r--r--cpukit/include/rtems/tod.h70
-rw-r--r--cpukit/include/rtems/trace/rtems-trace-buffer-vars.h148
-rw-r--r--cpukit/include/rtems/untar.h260
-rw-r--r--cpukit/include/rtems/version.h77
-rw-r--r--cpukit/include/rtems/vmeintr.h59
301 files changed, 77431 insertions, 0 deletions
diff --git a/cpukit/include/rtems/assoc.h b/cpukit/include/rtems/assoc.h
new file mode 100644
index 0000000000..345761758a
--- /dev/null
+++ b/cpukit/include/rtems/assoc.h
@@ -0,0 +1,204 @@
+/**
+ * @file rtems/assoc.h
+ *
+ * @brief RTEMS Associativity Routines
+ *
+ * RTEMS associativity routines. Mainly used to convert a value from
+ * one space to another (eg: our errno's to host errno's and vice-versa)
+ */
+
+
+#ifndef _RTEMS_RTEMS_ASSOC_H
+#define _RTEMS_RTEMS_ASSOC_H
+
+/**
+ * @defgroup Associativity Associativity Routines
+ */
+/**@{*/
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ const char *name;
+ uint32_t local_value;
+ uint32_t remote_value;
+} rtems_assoc_t;
+
+/*
+ * Flag/marker for optional default value in each table
+ */
+
+#define RTEMS_ASSOC_DEFAULT_NAME "(default)"
+
+/**
+ * @brief RTEMS Associate Pointer by Name
+ */
+const rtems_assoc_t *rtems_assoc_ptr_by_name(
+ const rtems_assoc_t *,
+ const char *
+);
+
+/**
+ * @brief RTEMS Associate Pointer by Remote
+ */
+const rtems_assoc_t *rtems_assoc_ptr_by_remote(
+ const rtems_assoc_t *,
+ uint32_t
+);
+
+uint32_t rtems_assoc_remote_by_local(
+ const rtems_assoc_t *,
+ uint32_t
+);
+
+/**
+ * @brief RTEMS Associate Local by Remote
+ */
+uint32_t rtems_assoc_local_by_remote(
+ const rtems_assoc_t *,
+ uint32_t
+);
+
+/**
+ * @brief RTEMS Associate Remote by Name
+ */
+uint32_t rtems_assoc_remote_by_name(
+ const rtems_assoc_t *,
+ const char *
+);
+
+/**
+ * @brief RTEMS Associate Local by Name
+ */
+uint32_t rtems_assoc_local_by_name(
+ const rtems_assoc_t *,
+ const char *
+);
+
+/**
+ * @brief RTEMS Associate Name by Local
+ */
+const char *rtems_assoc_name_by_local(
+ const rtems_assoc_t *,
+ uint32_t
+);
+
+/**
+ * @brief RTEMS Associate Name by Remote
+ */
+const char *rtems_assoc_name_by_remote(
+ const rtems_assoc_t *,
+ uint32_t
+);
+
+/**
+ * @brief RTEMS Assoc Routines
+ */
+uint32_t rtems_assoc_remote_by_local_bitfield(
+ const rtems_assoc_t *,
+ uint32_t
+);
+
+/**
+ * @brief RTEMS Associate Name by Local Bitfield
+ */
+char *rtems_assoc_name_by_local_bitfield(
+ const rtems_assoc_t *,
+ uint32_t ,
+ char *
+);
+
+/**
+ * @brief RTEMS Associate Name by Remote Bitfield
+ */
+char *rtems_assoc_name_by_remote_bitfield(
+ const rtems_assoc_t *,
+ uint32_t ,
+ char *
+);
+
+uint32_t rtems_assoc_local_by_remote_bitfield(
+ const rtems_assoc_t *,
+ uint32_t
+);
+
+/**
+ * @brief RTEMS Associate Pointer by Local
+ */
+const rtems_assoc_t *rtems_assoc_ptr_by_local(
+ const rtems_assoc_t *ap,
+ uint32_t local_value
+);
+
+#if defined(INSIDE_ASSOC)
+
+#define rtems_assoc_is_default(_ap) \
+ ((_ap)->name && !strcmp((_ap)->name, RTEMS_ASSOC_DEFAULT_NAME))
+
+/**
+ * @brief RTEMS Associate Bad Name
+ *
+ * what to return if a value is not found
+ * this is not reentrant, but it really shouldn't be invoked anyway
+ */
+const char *rtems_assoc_name_bad(
+ uint32_t bad_value
+);
+#endif
+
+typedef struct {
+ uint32_t bits;
+ const char *name;
+} rtems_assoc_32_pair;
+
+/**
+ * @brief Converts the specified value into a text representation.
+ *
+ * @param[in] value The value to convert.
+ * @param[in] buffer The buffer for the text representation.
+ * @param[in] buffer_size The buffer size in characters.
+ * @param[in] pairs Names for particular bits.
+ * @param[in] pair_count Count of pairs.
+ * @param[in] separator Separator between individual names.
+ * @param[in] fallback Fallback value in case no bits contained in the pairs
+ * are set in the value.
+ *
+ * @retval The length of the text representation. May be greater than or equal
+ * to the buffer size if truncation occurred.
+ */
+size_t rtems_assoc_32_to_string(
+ uint32_t value,
+ char *buffer,
+ size_t buffer_size,
+ const rtems_assoc_32_pair *pairs,
+ size_t pair_count,
+ const char *separator,
+ const char *fallback
+);
+
+/**
+ * @brief Converts the specified thread states into a text representation.
+ *
+ * @param[in] states The thread states to convert.
+ * @param[in] buffer The buffer for the text representation.
+ * @param[in] buffer_size The buffer size in characters.
+ *
+ * @retval The length of the text representation. May be greater than or equal
+ * to the buffer size if truncation occurred.
+ */
+size_t rtems_assoc_thread_states_to_string(
+ uint32_t states,
+ char *buffer,
+ size_t buffer_size
+);
+
+#ifdef __cplusplus
+}
+#endif
+/**@}*/
+#endif /* ! _RTEMS_RTEMS_ASSOC_H */
diff --git a/cpukit/include/rtems/bdbuf.h b/cpukit/include/rtems/bdbuf.h
new file mode 100644
index 0000000000..edec05e099
--- /dev/null
+++ b/cpukit/include/rtems/bdbuf.h
@@ -0,0 +1,699 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_bdbuf
+ * @brief Block Device Buffer Management
+ */
+
+/*
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ *
+ * Copyright (C) 2008,2009 Chris Johns <chrisj@rtems.org>
+ * Rewritten to remove score mutex access. Fixes many performance
+ * issues.
+ * Change to support demand driven variable buffer sizes.
+ *
+ * Copyright (c) 2009-2012 embedded brains GmbH.
+ */
+
+#ifndef _RTEMS_BDBUF_H
+#define _RTEMS_BDBUF_H
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/chain.h>
+
+#include <rtems/blkdev.h>
+#include <rtems/diskdevs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup rtems_libblock Block Device Library
+ *
+ * Block device modules.
+ */
+
+/**
+ * @defgroup rtems_bdbuf Block Device Buffer Management
+ *
+ * @ingroup rtems_libblock
+ *
+ * The Block Device Buffer Management implements a cache between the disk
+ * devices and file systems. The code provides read-ahead and write queuing to
+ * the drivers and fast cache look-up using an AVL tree.
+ *
+ * The block size used by a file system can be set at runtime and must be a
+ * multiple of the disk device block size. The disk device's physical block
+ * size is called the media block size. The file system can set the block size
+ * it uses to a larger multiple of the media block size. The driver must be
+ * able to handle buffers sizes larger than one media block.
+ *
+ * The user configures the amount of memory to be used as buffers in the cache,
+ * and the minimum and maximum buffer size. The cache will allocate additional
+ * memory for the buffer descriptors and groups. There are enough buffer
+ * descriptors allocated so all the buffer memory can be used as minimum sized
+ * buffers.
+ *
+ * The cache is a single pool of buffers. The buffer memory is divided into
+ * groups where the size of buffer memory allocated to a group is the maximum
+ * buffer size. A group's memory can be divided down into small buffer sizes
+ * that are a multiple of 2 of the minimum buffer size. A group is the minimum
+ * allocation unit for buffers of a specific size. If a buffer of maximum size
+ * is request the group will have a single buffer. If a buffer of minimum size
+ * is requested the group is divided into minimum sized buffers and the
+ * remaining buffers are held ready for use. A group keeps track of which
+ * buffers are with a file system or driver and groups who have buffer in use
+ * cannot be realloced. Groups with no buffers in use can be taken and
+ * realloced to a new size. This is how buffers of different sizes move around
+ * the cache.
+
+ * The buffers are held in various lists in the cache. All buffers follow this
+ * state machine:
+ *
+ * @dot
+ * digraph state {
+ * size="16,8";
+ * f [label="FREE",style="filled",fillcolor="aquamarine"];
+ * e [label="EMPTY",style="filled",fillcolor="seagreen"];
+ * c [label="CACHED",style="filled",fillcolor="chartreuse"];
+ * ac [label="ACCESS CACHED",style="filled",fillcolor="royalblue"];
+ * am [label="ACCESS MODIFIED",style="filled",fillcolor="royalblue"];
+ * ae [label="ACCESS EMPTY",style="filled",fillcolor="royalblue"];
+ * ap [label="ACCESS PURGED",style="filled",fillcolor="royalblue"];
+ * t [label="TRANSFER",style="filled",fillcolor="red"];
+ * tp [label="TRANSFER PURGED",style="filled",fillcolor="red"];
+ * s [label="SYNC",style="filled",fillcolor="red"];
+ * m [label="MODIFIED",style="filled",fillcolor="gold"];
+ * i [label="INITIAL"];
+ *
+ * legend_transfer [label="Transfer Wake-Up",fontcolor="red",shape="none"];
+ * legend_access [label="Access Wake-Up",fontcolor="royalblue",shape="none"];
+ *
+ * i -> f [label="Init"];
+ * f -> e [label="Buffer Recycle"];
+ * e -> ae [label="Get"];
+ * e -> t [label="Read"];
+ * e -> f [label="Nobody Waits"];
+ * c -> ac [label="Get\nRead"];
+ * c -> e [label="Buffer Recycle\nPurge"];
+ * c -> f [label="Reallocate\nBlock Size Changed"];
+ * t -> c [label="Transfer Done",color="red",fontcolor="red"];
+ * t -> e [label="Transfer Error",color="red",fontcolor="red"];
+ * t -> tp [label="Purge"];
+ * tp -> e [label="Transfer Done\nTransfer Error",color="red",fontcolor="red"];
+ * m -> t [label="Swapout"];
+ * m -> s [label="Block Size Changed"];
+ * m -> am [label="Get\nRead"];
+ * m -> e [label="Purge"];
+ * ac -> m [label="Release Modified",color="royalblue",fontcolor="royalblue"];
+ * ac -> s [label="Sync",color="royalblue",fontcolor="royalblue"];
+ * ac -> c [label="Release",color="royalblue",fontcolor="royalblue"];
+ * ac -> ap [label="Purge"];
+ * am -> m [label="Release\nRelease Modified",color="royalblue",fontcolor="royalblue"];
+ * am -> s [label="Sync",color="royalblue",fontcolor="royalblue"];
+ * am -> ap [label="Purge"];
+ * ae -> m [label="Release Modified",color="royalblue",fontcolor="royalblue"];
+ * ae -> s [label="Sync",color="royalblue",fontcolor="royalblue"];
+ * ae -> e [label="Release",color="royalblue",fontcolor="royalblue"];
+ * ae -> ap [label="Purge"];
+ * ap -> e [label="Release\nRelease Modified\nSync",color="royalblue",fontcolor="royalblue"];
+ * s -> t [label="Swapout"];
+ * s -> e [label="Purge",color="red",fontcolor="red"];
+ * }
+ * @enddot
+ *
+ * Empty or cached buffers are added to the LRU list and removed from this
+ * queue when a caller requests a buffer. This is referred to as getting a
+ * buffer in the code and the event get in the state diagram. The buffer is
+ * assigned to a block and inserted to the AVL based on the block/device key.
+ * If the block is to be read by the user and not in the cache it is transfered
+ * from the disk into memory. If no buffers are on the LRU list the modified
+ * list is checked. If buffers are on the modified the swap out task will be
+ * woken. The request blocks until a buffer is available for recycle.
+ *
+ * A block being accessed is given to the file system layer and not accessible
+ * to another requester until released back to the cache. The same goes to a
+ * buffer in the transfer state. The transfer state means being read or
+ * written. If the file system has modified the block and releases it as
+ * modified it placed on the cache's modified list and a hold timer
+ * initialised. The buffer is held for the hold time before being written to
+ * disk. Buffers are held for a configurable period of time on the modified
+ * list as a write sets the state to transfer and this locks the buffer out
+ * from the file system until the write completes. Buffers are often accessed
+ * and modified in a series of small updates so if sent to the disk when
+ * released as modified the user would have to block waiting until it had been
+ * written. This would be a performance problem.
+ *
+ * The code performs multiple block reads and writes. Multiple block reads or
+ * read-ahead increases performance with hardware that supports it. It also
+ * helps with a large cache as the disk head movement is reduced. It however
+ * is a speculative operation so excessive use can remove valuable and needed
+ * blocks from the cache. The read-ahead is triggered after two misses of
+ * ascending consecutive blocks or a read hit of a block read by the
+ * most-resent read-ahead transfer. The read-ahead works per disk, but all
+ * transfers are issued by the read-ahead task.
+ *
+ * The cache has the following lists of buffers:
+ * - LRU: Accessed or transfered buffers released in least recently used
+ * order. Empty buffers will be placed to the front.
+ * - Modified: Buffers waiting to be written to disk.
+ * - Sync: Buffers to be synchronized with the disk.
+ *
+ * A cache look-up will be performed to find a suitable buffer. A suitable
+ * buffer is one that matches the same allocation size as the device the buffer
+ * is for. The a buffer's group has no buffers in use with the file system or
+ * driver the group is reallocated. This means the buffers in the group are
+ * invalidated, resized and placed on the LRU queue. There is a performance
+ * issue with this design. The reallocation of a group may forced recently
+ * accessed buffers out of the cache when they should not. The design should be
+ * change to have groups on a LRU list if they have no buffers in use.
+ */
+/**@{**/
+
+#if defined(RTEMS_POSIX_API)
+ /*
+ * Use the PTHREAD mutexes and condition variables if available. This helps
+ * on SMP configurations to avoid the home grown condition variables via
+ * disabled preemption.
+ */
+ #define RTEMS_BDBUF_USE_PTHREAD
+#endif
+
+/**
+ * @brief State of a buffer of the cache.
+ *
+ * The state has several implications. Depending on the state a buffer can be
+ * in the AVL tree, in a list, in use by an entity and a group user or not.
+ *
+ * <table>
+ * <tr>
+ * <th>State</th><th>Valid Data</th><th>AVL Tree</th>
+ * <th>LRU List</th><th>Modified List</th><th>Synchronization List</th>
+ * <th>Group User</th><th>External User</th>
+ * </tr>
+ * <tr>
+ * <td>FREE</td><td></td><td></td>
+ * <td>X</td><td></td><td></td><td></td><td></td>
+ * </tr>
+ * <tr>
+ * <td>EMPTY</td><td></td><td>X</td>
+ * <td></td><td></td><td></td><td></td><td></td>
+ * </tr>
+ * <tr>
+ * <td>CACHED</td><td>X</td><td>X</td>
+ * <td>X</td><td></td><td></td><td></td><td></td>
+ * </tr>
+ * <tr>
+ * <td>ACCESS CACHED</td><td>X</td><td>X</td>
+ * <td></td><td></td><td></td><td>X</td><td>X</td>
+ * </tr>
+ * <tr>
+ * <td>ACCESS MODIFIED</td><td>X</td><td>X</td>
+ * <td></td><td></td><td></td><td>X</td><td>X</td>
+ * </tr>
+ * <tr>
+ * <td>ACCESS EMPTY</td><td></td><td>X</td>
+ * <td></td><td></td><td></td><td>X</td><td>X</td>
+ * </tr>
+ * <tr>
+ * <td>ACCESS PURGED</td><td></td><td>X</td>
+ * <td></td><td></td><td></td><td>X</td><td>X</td>
+ * </tr>
+ * <tr>
+ * <td>MODIFIED</td><td>X</td><td>X</td>
+ * <td></td><td>X</td><td></td><td>X</td><td></td>
+ * </tr>
+ * <tr>
+ * <td>SYNC</td><td>X</td><td>X</td>
+ * <td></td><td></td><td>X</td><td>X</td><td></td>
+ * </tr>
+ * <tr>
+ * <td>TRANSFER</td><td>X</td><td>X</td>
+ * <td></td><td></td><td></td><td>X</td><td>X</td>
+ * </tr>
+ * <tr>
+ * <td>TRANSFER PURGED</td><td></td><td>X</td>
+ * <td></td><td></td><td></td><td>X</td><td>X</td>
+ * </tr>
+ * </table>
+ */
+typedef enum
+{
+ /**
+ * @brief Free.
+ */
+ RTEMS_BDBUF_STATE_FREE = 0,
+
+ /**
+ * @brief Empty.
+ */
+ RTEMS_BDBUF_STATE_EMPTY,
+
+ /**
+ * @brief Cached.
+ */
+ RTEMS_BDBUF_STATE_CACHED,
+
+ /**
+ * @brief Accessed by upper layer with cached data.
+ */
+ RTEMS_BDBUF_STATE_ACCESS_CACHED,
+
+ /**
+ * @brief Accessed by upper layer with modified data.
+ */
+ RTEMS_BDBUF_STATE_ACCESS_MODIFIED,
+
+ /**
+ * @brief Accessed by upper layer with invalid data.
+ */
+ RTEMS_BDBUF_STATE_ACCESS_EMPTY,
+
+ /**
+ * @brief Accessed by upper layer with purged data.
+ */
+ RTEMS_BDBUF_STATE_ACCESS_PURGED,
+
+ /**
+ * @brief Modified by upper layer.
+ */
+ RTEMS_BDBUF_STATE_MODIFIED,
+
+ /**
+ * @brief Scheduled for synchronization.
+ */
+ RTEMS_BDBUF_STATE_SYNC,
+
+ /**
+ * @brief In transfer by block device driver.
+ */
+ RTEMS_BDBUF_STATE_TRANSFER,
+
+ /**
+ * @brief In transfer by block device driver and purged.
+ */
+ RTEMS_BDBUF_STATE_TRANSFER_PURGED
+} rtems_bdbuf_buf_state;
+
+/**
+ * Forward reference to the block.
+ */
+struct rtems_bdbuf_group;
+typedef struct rtems_bdbuf_group rtems_bdbuf_group;
+
+/**
+ * To manage buffers we using buffer descriptors (BD). A BD holds a buffer plus
+ * a range of other information related to managing the buffer in the cache. To
+ * speed-up buffer lookup descriptors are organized in AVL-Tree. The fields
+ * 'dd' and 'block' are search keys.
+ */
+typedef struct rtems_bdbuf_buffer
+{
+ rtems_chain_node link; /**< Link the BD onto a number of lists. */
+
+ struct rtems_bdbuf_avl_node
+ {
+ struct rtems_bdbuf_buffer* left; /**< Left Child */
+ struct rtems_bdbuf_buffer* right; /**< Right Child */
+ signed char cache; /**< Cache */
+ signed char bal; /**< The balance of the sub-tree */
+ } avl;
+
+ rtems_disk_device *dd; /**< disk device */
+
+ rtems_blkdev_bnum block; /**< block number on the device */
+
+ unsigned char* buffer; /**< Pointer to the buffer memory area */
+
+ rtems_bdbuf_buf_state state; /**< State of the buffer. */
+
+ uint32_t waiters; /**< The number of threads waiting on this
+ * buffer. */
+ rtems_bdbuf_group* group; /**< Pointer to the group of BDs this BD is
+ * part of. */
+ uint32_t hold_timer; /**< Timer to indicate how long a buffer
+ * has been held in the cache modified. */
+
+ int references; /**< Allow reference counting by owner. */
+ void* user; /**< User data. */
+} rtems_bdbuf_buffer;
+
+/**
+ * A group is a continuous block of buffer descriptors. A group covers the
+ * maximum configured buffer size and is the allocation size for the buffers to
+ * a specific buffer size. If you allocate a buffer to be a specific size, all
+ * buffers in the group, if there are more than 1 will also be that size. The
+ * number of buffers in a group is a multiple of 2, ie 1, 2, 4, 8, etc.
+ */
+struct rtems_bdbuf_group
+{
+ rtems_chain_node link; /**< Link the groups on a LRU list if they
+ * have no buffers in use. */
+ size_t bds_per_group; /**< The number of BD allocated to this
+ * group. This value must be a multiple of
+ * 2. */
+ uint32_t users; /**< How many users the block has. */
+ rtems_bdbuf_buffer* bdbuf; /**< First BD this block covers. */
+};
+
+/**
+ * Buffering configuration definition. See confdefs.h for support on using this
+ * structure.
+ */
+typedef struct rtems_bdbuf_config {
+ uint32_t max_read_ahead_blocks; /**< Number of blocks to read
+ * ahead. */
+ uint32_t max_write_blocks; /**< Number of blocks to write
+ * at once. */
+ rtems_task_priority swapout_priority; /**< Priority of the swap out
+ * task. */
+ uint32_t swapout_period; /**< Period swap-out checks buf
+ * timers. */
+ uint32_t swap_block_hold; /**< Period a buffer is held. */
+ size_t swapout_workers; /**< The number of worker
+ * threads for the swap-out
+ * task. */
+ rtems_task_priority swapout_worker_priority; /**< Priority of the swap out
+ * task. */
+ size_t task_stack_size; /**< Task stack size for swap-out
+ * task and worker threads. */
+ size_t size; /**< Size of memory in the
+ * cache */
+ uint32_t buffer_min; /**< Minimum buffer size. */
+ uint32_t buffer_max; /**< Maximum buffer size
+ * supported. It is also the
+ * allocation size. */
+ rtems_task_priority read_ahead_priority; /**< Priority of the read-ahead
+ * task. */
+} rtems_bdbuf_config;
+
+/**
+ * External reference to the configuration.
+ *
+ * The configuration is provided by the application.
+ */
+extern const rtems_bdbuf_config rtems_bdbuf_configuration;
+
+/**
+ * The default value for the maximum read-ahead blocks disables the read-ahead
+ * feature.
+ */
+#define RTEMS_BDBUF_MAX_READ_AHEAD_BLOCKS_DEFAULT 0
+
+/**
+ * Default maximum number of blocks to write at once.
+ */
+#define RTEMS_BDBUF_MAX_WRITE_BLOCKS_DEFAULT 16
+
+/**
+ * Default swap-out task priority.
+ */
+#define RTEMS_BDBUF_SWAPOUT_TASK_PRIORITY_DEFAULT 15
+
+/**
+ * Default swap-out task swap period in milli seconds.
+ */
+#define RTEMS_BDBUF_SWAPOUT_TASK_SWAP_PERIOD_DEFAULT 250
+
+/**
+ * Default swap-out task block hold time in milli seconds.
+ */
+#define RTEMS_BDBUF_SWAPOUT_TASK_BLOCK_HOLD_DEFAULT 1000
+
+/**
+ * Default swap-out worker tasks. Currently disabled.
+ */
+#define RTEMS_BDBUF_SWAPOUT_WORKER_TASKS_DEFAULT 0
+
+/**
+ * Default swap-out worker task priority. The same as the swap-out task.
+ */
+#define RTEMS_BDBUF_SWAPOUT_WORKER_TASK_PRIORITY_DEFAULT \
+ RTEMS_BDBUF_SWAPOUT_TASK_PRIORITY_DEFAULT
+
+/**
+ * Default read-ahead task priority. The same as the swap-out task.
+ */
+#define RTEMS_BDBUF_READ_AHEAD_TASK_PRIORITY_DEFAULT \
+ RTEMS_BDBUF_SWAPOUT_TASK_PRIORITY_DEFAULT
+
+/**
+ * Default task stack size for swap-out and worker tasks.
+ */
+#define RTEMS_BDBUF_TASK_STACK_SIZE_DEFAULT RTEMS_MINIMUM_STACK_SIZE
+
+/**
+ * Default size of memory allocated to the cache.
+ */
+#define RTEMS_BDBUF_CACHE_MEMORY_SIZE_DEFAULT (64 * 512)
+
+/**
+ * Default minimum size of buffers.
+ */
+#define RTEMS_BDBUF_BUFFER_MIN_SIZE_DEFAULT (512)
+
+/**
+ * Default maximum size of buffers.
+ */
+#define RTEMS_BDBUF_BUFFER_MAX_SIZE_DEFAULT (4096)
+
+/**
+ * Prepare buffering layer to work - initialize buffer descritors and (if it is
+ * neccessary) buffers. After initialization all blocks is placed into the
+ * ready state.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_CALLED_FROM_ISR Called from an interrupt context.
+ * @retval RTEMS_INVALID_NUMBER The buffer maximum is not an integral multiple
+ * of the buffer minimum. The maximum read-ahead blocks count is too large.
+ * @retval RTEMS_RESOURCE_IN_USE Already initialized.
+ * @retval RTEMS_UNSATISFIED Not enough resources.
+ */
+rtems_status_code
+rtems_bdbuf_init (void);
+
+/**
+ * Get block buffer for data to be written into. The buffers is set to the
+ * access or modified access state. If the buffer is in the cache and modified
+ * the state is access modified else the state is access. This buffer contents
+ * are not initialised if the buffer is not already in the cache. If the block
+ * is already resident in memory it is returned how-ever if not in memory the
+ * buffer is not read from disk. This call is used when writing the whole block
+ * on a disk rather than just changing a part of it. If there is no buffers
+ * available this call will block. A buffer obtained with this call will not be
+ * involved in a transfer request and will not be returned to another user
+ * until released. If the buffer is already with a user when this call is made
+ * the call is blocked until the buffer is returned. The highest priority
+ * waiter will obtain the buffer first.
+ *
+ * The block number is the linear block number. This is relative to the start
+ * of the partition on the media.
+ *
+ * Before you can use this function, the rtems_bdbuf_init() routine must be
+ * called at least once to initialize the cache, otherwise a fatal error will
+ * occur.
+ *
+ * @param dd [in] The disk device.
+ * @param block [in] Linear media block number.
+ * @param bd [out] Reference to the buffer descriptor pointer.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID Invalid block number.
+ */
+rtems_status_code
+rtems_bdbuf_get (
+ rtems_disk_device *dd,
+ rtems_blkdev_bnum block,
+ rtems_bdbuf_buffer** bd
+);
+
+/**
+ * Get the block buffer and if not already in the cache read from the disk. If
+ * specified block already cached return. The buffer is set to the access or
+ * modified access state. If the buffer is in the cache and modified the state
+ * is access modified else the state is access. If block is already being read
+ * from disk for being written to disk this call blocks. If the buffer is
+ * waiting to be written it is removed from modified queue and returned to the
+ * user. If the buffer is not in the cache a new buffer is obtained and the
+ * data read from disk. The call may block until these operations complete. A
+ * buffer obtained with this call will not be involved in a transfer request
+ * and will not be returned to another user until released. If the buffer is
+ * already with a user when this call is made the call is blocked until the
+ * buffer is returned. The highest priority waiter will obtain the buffer
+ * first.
+ *
+ * Before you can use this function, the rtems_bdbuf_init() routine must be
+ * called at least once to initialize the cache, otherwise a fatal error will
+ * occur.
+ *
+ * @param dd [in] The disk device.
+ * @param block [in] Linear media block number.
+ * @param bd [out] Reference to the buffer descriptor pointer.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID Invalid block number.
+ * @retval RTEMS_IO_ERROR IO error.
+ */
+rtems_status_code
+rtems_bdbuf_read (
+ rtems_disk_device *dd,
+ rtems_blkdev_bnum block,
+ rtems_bdbuf_buffer** bd
+);
+
+/**
+ * Release the buffer obtained by a read call back to the cache. If the buffer
+ * was obtained by a get call and was not already in the cache the release
+ * modified call should be used. A buffer released with this call obtained by a
+ * get call may not be in sync with the contents on disk. If the buffer was in
+ * the cache and modified before this call it will be returned to the modified
+ * queue. The buffers is returned to the end of the LRU list.
+ *
+ * Before you can use this function, the rtems_bdbuf_init() routine must be
+ * called at least once to initialize the cache, otherwise a fatal error will
+ * occur.
+ *
+ * @param bd [in] Reference to the buffer descriptor. The buffer descriptor
+ * reference must not be @c NULL and must be obtained via rtems_bdbuf_get() or
+ * rtems_bdbuf_read().
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ADDRESS The reference is NULL.
+ */
+rtems_status_code
+rtems_bdbuf_release (rtems_bdbuf_buffer* bd);
+
+/**
+ * Release the buffer allocated with a get or read call placing it on the
+ * modified list. If the buffer was not released modified before the hold
+ * timer is set to the configuration value. If the buffer had been released
+ * modified before but not written to disk the hold timer is not updated. The
+ * buffer will be written to disk when the hold timer has expired, there are
+ * not more buffers available in the cache and a get or read buffer needs one
+ * or a sync call has been made. If the buffer is obtained with a get or read
+ * before the hold timer has expired the buffer will be returned to the user.
+ *
+ * Before you can use this function, the rtems_bdbuf_init() routine must be
+ * called at least once to initialize the cache, otherwise a fatal error will
+ * occur.
+ *
+ * @param bd [in] Reference to the buffer descriptor. The buffer descriptor
+ * reference must not be @c NULL and must be obtained via rtems_bdbuf_get() or
+ * rtems_bdbuf_read().
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ADDRESS The reference is NULL.
+ */
+rtems_status_code
+rtems_bdbuf_release_modified (rtems_bdbuf_buffer* bd);
+
+/**
+ * Release the buffer as modified and wait until it has been synchronized with
+ * the disk by writing it. This buffer will be the first to be transfer to disk
+ * and other buffers may also be written if the maximum number of blocks in a
+ * requests allows it.
+ *
+ * @note This code does not lock the sync mutex and stop additions to the
+ * modified queue.
+ *
+ * Before you can use this function, the rtems_bdbuf_init() routine must be
+ * called at least once to initialize the cache, otherwise a fatal error will
+ * occur.
+ *
+ * @param bd [in] Reference to the buffer descriptor. The buffer descriptor
+ * reference must not be @c NULL and must be obtained via rtems_bdbuf_get() or
+ * rtems_bdbuf_read().
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ADDRESS The reference is NULL.
+ */
+rtems_status_code
+rtems_bdbuf_sync (rtems_bdbuf_buffer* bd);
+
+/**
+ * Synchronize all modified buffers for this device with the disk and wait
+ * until the transfers have completed. The sync mutex for the cache is locked
+ * stopping the addition of any further modified buffers. It is only the
+ * currently modified buffers that are written.
+ *
+ * @note Nesting calls to sync multiple devices will be handled sequentially. A
+ * nested call will be blocked until the first sync request has complete.
+ *
+ * Before you can use this function, the rtems_bdbuf_init() routine must be
+ * called at least once to initialize the cache, otherwise a fatal error will
+ * occur.
+ *
+ * @param dd [in] The disk device.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ */
+rtems_status_code
+rtems_bdbuf_syncdev (rtems_disk_device *dd);
+
+/**
+ * @brief Purges all buffers corresponding to the disk device @a dd.
+ *
+ * This may result in loss of data. The read-ahead state of this device is reset.
+ *
+ * Before you can use this function, the rtems_bdbuf_init() routine must be
+ * called at least once to initialize the cache, otherwise a fatal error will
+ * occur.
+ *
+ * @param dd [in] The disk device.
+ */
+void
+rtems_bdbuf_purge_dev (rtems_disk_device *dd);
+
+/**
+ * @brief Sets the block size of a disk device.
+ *
+ * This will set the block size derived fields of the disk device. If
+ * requested the disk device is synchronized before the block size change
+ * occurs. Since the cache is unlocked during the synchronization operation
+ * some tasks may access the disk device in the meantime. This may result in
+ * loss of data. After the synchronization the disk device is purged to ensure
+ * a consistent cache state and the block size change occurs. This also resets
+ * the read-ahead state of this disk device. Due to the purge operation this
+ * may result in loss of data.
+ *
+ * Before you can use this function, the rtems_bdbuf_init() routine must be
+ * called at least once to initialize the cache, otherwise a fatal error will
+ * occur.
+ *
+ * @param dd [in, out] The disk device.
+ * @param block_size [in] The new block size in bytes.
+ * @param sync [in] If @c true, then synchronize the disk device before the
+ * block size change.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_NUMBER Invalid block size.
+ */
+rtems_status_code
+rtems_bdbuf_set_block_size (rtems_disk_device *dd,
+ uint32_t block_size,
+ bool sync);
+
+/**
+ * @brief Returns the block device statistics.
+ */
+void
+rtems_bdbuf_get_device_stats (const rtems_disk_device *dd,
+ rtems_blkdev_stats *stats);
+
+/**
+ * @brief Resets the block device statistics.
+ */
+void
+rtems_bdbuf_reset_device_stats (rtems_disk_device *dd);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/bdpart.h b/cpukit/include/rtems/bdpart.h
new file mode 100644
index 0000000000..8886c3614d
--- /dev/null
+++ b/cpukit/include/rtems/bdpart.h
@@ -0,0 +1,411 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_bdpart
+ *
+ * @brief Block Device Partition Management
+ */
+
+/*
+ * Copyright (c) 2009-2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_BDPART_H
+#define RTEMS_BDPART_H
+
+#include <uuid/uuid.h>
+
+#include <rtems.h>
+#include <rtems/blkdev.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup rtems_bdpart Block Device Partition Management
+ *
+ * @ingroup rtems_libblock
+ *
+ * @brief This module provides functions to manage partitions of a disk device.
+ *
+ * A @ref rtems_disk "disk" is a set of blocks which are identified by a
+ * consecutive set of non-negative integers starting at zero. There are also
+ * logical disks which contain a subset of consecutive disk blocks. The
+ * logical disks are used to represent the partitions of a disk. The disk
+ * devices are accessed via the @ref rtems_disk "block device buffer module".
+ *
+ * The partition format on the physical disk will be converted to an internal
+ * representation. It is possible to convert the internal representation into
+ * a specific output format and write it to the physical disk. One of the
+ * constrains for the internal representation was to support the GPT format
+ * easily.
+ *
+ * Currently two physical partition formats are supported. These are the MBR
+ * and the GPT format. Please note that the GPT support is not implemented.
+ * With MBR format we mean the partition format of the wide spread IBM
+ * PC-compatible systems. The GPT format is defined in the Extensible Firmware
+ * Interface (EFI).
+ *
+ * The most common task will be to read the partition information of a disk and
+ * register logical disks for each partition. This can be done with the
+ * rtems_bdpart_register_from_disk() function. Afterwards you can
+ * @ref rtems_fsmount "mount" the file systems within the partitions.
+ *
+ * You can read the partition information from a disk with rtems_bdpart_read()
+ * and write it to the disk with rtems_bdpart_write().
+ *
+ * To create a partition table from scratch for a disk use
+ * rtems_bdpart_create().
+ *
+ * You can access some disk functions with the shell command @c fdisk.
+ *
+ * References used to create this module:
+ * - <a href="http://en.wikipedia.org/wiki/UUID">Universally Unique Identifier</a>
+ * - <a href="http://en.wikipedia.org/wiki/Globally_Unique_Identifier">Globally Unique Identifier</a>
+ * - <a href="http://en.wikipedia.org/wiki/Disk_partitioning">Disk Paritioning</a>
+ * - <a href="http://en.wikipedia.org/wiki/GUID_Partition_Table">GUID Partition Table</a>
+ * - <a href="http://en.wikipedia.org/wiki/Master_boot_record">Master Boot Record</a>
+ * - <a href="http://en.wikipedia.org/wiki/Extended_boot_record">Extended Boot Record</a>
+ * - <a href="http://en.wikipedia.org/wiki/Cylinder-head-sector">Cylinder Head Sector</a>
+ * - <a href="http://www.win.tue.nl/~aeb/partitions/partition_types-1.html">Partition Types</a>
+ */
+/**@{**/
+
+/**
+ * @name MBR Partition Types and Flags
+ */
+/**@{**/
+
+#define RTEMS_BDPART_MBR_EMPTY 0x0U
+
+#define RTEMS_BDPART_MBR_FAT_12 0x1U
+
+#define RTEMS_BDPART_MBR_FAT_16 0x4U
+
+#define RTEMS_BDPART_MBR_FAT_16_LBA 0xeU
+
+#define RTEMS_BDPART_MBR_FAT_32 0xbU
+
+#define RTEMS_BDPART_MBR_FAT_32_LBA 0xcU
+
+#define RTEMS_BDPART_MBR_EXTENDED 0x5U
+
+#define RTEMS_BDPART_MBR_DATA 0xdaU
+
+#define RTEMS_BDPART_MBR_GPT 0xeeU
+
+#define RTEMS_BDPART_MBR_FLAG_ACTIVE 0x80U
+
+/** @} */
+
+/**
+ * Recommended maximum partition table size.
+ */
+#define RTEMS_BDPART_PARTITION_NUMBER_HINT 16
+
+/**
+ * Partition description.
+ */
+typedef struct rtems_bdpart_partition {
+ /**
+ * Block index for partition begin.
+ */
+ rtems_blkdev_bnum begin;
+
+ /**
+ * Block index for partition end (this block is not a part of the partition).
+ */
+ rtems_blkdev_bnum end;
+
+ /**
+ * Partition type.
+ */
+ uuid_t type;
+
+ /**
+ * Partition ID.
+ */
+ uuid_t id;
+
+ /**
+ * Partition flags.
+ */
+ uint64_t flags;
+} rtems_bdpart_partition;
+
+/**
+ * Disk format for the partition tables.
+ */
+typedef enum {
+ /**
+ * Type value for MBR format.
+ */
+ RTEMS_BDPART_FORMAT_MBR,
+
+ /**
+ * Type value for GPT format.
+ */
+ RTEMS_BDPART_FORMAT_GPT
+} rtems_bdpart_format_type;
+
+/**
+ * Disk format description.
+ */
+typedef union {
+ /**
+ * Format type.
+ */
+ rtems_bdpart_format_type type;
+
+ /**
+ * MBR format fields.
+ */
+ struct {
+ rtems_bdpart_format_type type;
+
+ /**
+ * Disk ID in MBR at offset 440.
+ */
+ uint32_t disk_id;
+
+ /**
+ * This option is used for partition table creation and validation checks
+ * before a write to the disk. It ensures that the first primary
+ * partition and the logical partitions start at head one and sector one
+ * under the virtual one head and 63 sectors geometry. Each begin and
+ * end of a partition will be aligned to the virtual cylinder boundary.
+ */
+ bool dos_compatibility;
+ } mbr;
+
+ /**
+ * GPT format fields.
+ */
+ struct {
+ rtems_bdpart_format_type type;
+
+ /**
+ * Disk ID in GPT header.
+ */
+ uuid_t disk_id;
+ } gpt;
+} rtems_bdpart_format;
+
+/**
+ * @brief Reads the partition information from the physical disk device with
+ * name @a disk_name.
+ *
+ * The partition information will be stored in the partition table
+ * @a partitions with a maximum of @a count partitions. The number of actual
+ * partitions will be stored in @a count. If there are more partitions than
+ * space for storage an error status will be returned. The partition table
+ * format recognized on the disk will be stored in @a format.
+ */
+rtems_status_code rtems_bdpart_read(
+ const char *disk_name,
+ rtems_bdpart_format *format,
+ rtems_bdpart_partition *partitions,
+ size_t *count
+);
+
+/**
+ * @brief Sorts the partition table @a partitions with @a count partitions to
+ * have ascending begin blocks
+ */
+void rtems_bdpart_sort( rtems_bdpart_partition *partitions, size_t count);
+
+/**
+ * @brief Writes the partition table to the physical disk device with name
+ * @a disk_name.
+ *
+ * The partition table @a partitions with @a count partitions will be written
+ * to the disk. The output format for the partition table on the disk is
+ * specified by @a format. There are some consistency checks applied to the
+ * partition table. The partition table must be sorted such that the begin
+ * blocks are in ascending order. This can be done with the
+ * rtems_bdpart_sort() function. The partitions must not overlap. The
+ * partitions must have a positive size. The partitions must be within the
+ * disk. Depending on the output format there are additional constrains.
+ */
+rtems_status_code rtems_bdpart_write(
+ const char *disk_name,
+ const rtems_bdpart_format *format,
+ const rtems_bdpart_partition *partitions,
+ size_t count
+);
+
+/**
+ * @brief Creates a partition table in @a partitions with @a count partitions
+ * for the physical disk device with name @a disk_name.
+ *
+ * The array of positive integer weights in @a distribution must have exactly
+ * @a count elements. The weights in the distribution array are summed up.
+ * Each weight is then divided by the sum to obtain the disk fraction which
+ * forms the corresponding partition. The partition boundaries are generated
+ * with respect to the output format in @a format.
+ */
+rtems_status_code rtems_bdpart_create(
+ const char *disk_name,
+ const rtems_bdpart_format *format,
+ rtems_bdpart_partition *partitions,
+ const unsigned *distribution,
+ size_t count
+);
+
+/**
+ * @brief Registers the partitions as logical disks for the physical disk
+ * device with name @a disk_name.
+ *
+ * For each partition of the partition table @a partitions with @a count
+ * partitions a logical disk is registered. The partition number equals the
+ * partition table index plus one. The name of the logical disk device is the
+ * concatenation of the physical disk device name and the partition number.
+ *
+ * @see rtems_blkdev_create_partition().
+ */
+rtems_status_code rtems_bdpart_register(
+ const char *disk_name,
+ const rtems_bdpart_partition *partitions,
+ size_t count
+);
+
+/**
+ * @a brief Reads the partition table from the disk device with name @a
+ * disk_name and registers the partitions as logical disks.
+ *
+ * @see rtems_bdpart_register() and rtems_fsmount().
+ */
+rtems_status_code rtems_bdpart_register_from_disk( const char *disk_name);
+
+/**
+ * @brief Deletes the logical disks associated with the partitions of the disk
+ * device with name @a disk_name.
+ *
+ * The partition table @a partitions with @a count partitions will be used to
+ * determine which disks need to be deleted. It may be obtained from
+ * rtems_bdpart_read().
+ */
+rtems_status_code rtems_bdpart_unregister(
+ const char *disk_name,
+ const rtems_bdpart_partition *partitions,
+ size_t count
+);
+
+/**
+ * @brief Mounts all supported file systems inside the logical disks derived
+ * from the partitions of the physical disk device with name @a disk_name.
+ *
+ * For each partition in the partition table @a partitions with @a count
+ * partitions it will be checked if it contains a supported file system. In
+ * this case a mount point derived from the disk name will be created in the
+ * mount base path @a mount_base. The file system will be mounted there. The
+ * partition number equals the partition table index plus one. The mount point
+ * name for each partition will be the concatenation of the mount base path,
+ * the disk device file name and the parition number.
+ *
+ * @see rtems_bdpart_read().
+ */
+rtems_status_code rtems_bdpart_mount(
+ const char *disk_name,
+ const rtems_bdpart_partition *partitions,
+ size_t count,
+ const char *mount_base
+);
+
+/**
+ * @brief Unmounts all file systems mounted with rtems_bdpart_mount().
+ */
+rtems_status_code rtems_bdpart_unmount(
+ const char *disk_name,
+ const rtems_bdpart_partition *partitions,
+ size_t count,
+ const char *mount_base
+);
+
+/**
+ * @brief Prints the partition table @a partitions with @a count partitions to
+ * standard output.
+ */
+void rtems_bdpart_dump( const rtems_bdpart_partition *partitions, size_t count);
+
+/**
+ * @brief Returns the partition type for the MBR partition type value
+ * @a mbr_type in @a type.
+ */
+void rtems_bdpart_to_partition_type( uint8_t mbr_type, uuid_t type);
+
+/**
+ * @brief Converts the partition type in @a type to the MBR partition type.
+ *
+ * The result will be stored in @a mbr_type. Returns @c true in case of a
+ * successful convertion and otherwise @c false. Both arguments must not be
+ * @c NULL.
+ */
+bool rtems_bdpart_to_mbr_partition_type(
+ const uuid_t type,
+ uint8_t *mbr_type
+);
+
+/** @} */
+
+#define RTEMS_BDPART_MBR_CYLINDER_SIZE 63
+
+#define RTEMS_BDPART_NUMBER_SIZE 4
+
+#define RTEMS_BDPART_BLOCK_SIZE 512
+
+#define RTEMS_BDPART_MBR_TABLE_ENTRY_SIZE 16
+
+#define RTEMS_BDPART_MBR_OFFSET_TABLE_0 446
+
+#define RTEMS_BDPART_MBR_OFFSET_TABLE_1 \
+ (RTEMS_BDPART_MBR_OFFSET_TABLE_0 + RTEMS_BDPART_MBR_TABLE_ENTRY_SIZE)
+
+#define RTEMS_BDPART_MBR_OFFSET_DISK_ID 440
+
+#define RTEMS_BDPART_MBR_OFFSET_SIGNATURE_0 510
+
+#define RTEMS_BDPART_MBR_OFFSET_SIGNATURE_1 511
+
+#define RTEMS_BDPART_MBR_SIGNATURE_0 0x55U
+
+#define RTEMS_BDPART_MBR_SIGNATURE_1 0xaaU
+
+#define RTEMS_BDPART_MBR_OFFSET_BEGIN 8
+
+#define RTEMS_BDPART_MBR_OFFSET_SIZE 12
+
+#define RTEMS_BDPART_MBR_OFFSET_TYPE 4
+
+#define RTEMS_BDPART_MBR_OFFSET_FLAGS 0
+
+static inline uint8_t rtems_bdpart_mbr_partition_type(
+ const uuid_t type
+)
+{
+ return type [0];
+}
+
+rtems_status_code rtems_bdpart_get_disk_data(
+ const char *disk_name,
+ int *fd_ptr,
+ rtems_disk_device **dd_ptr,
+ rtems_blkdev_bnum *disk_end
+);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* RTEMS_BDPART_H */
diff --git a/cpukit/include/rtems/blkdev.h b/cpukit/include/rtems/blkdev.h
new file mode 100644
index 0000000000..3f829e6068
--- /dev/null
+++ b/cpukit/include/rtems/blkdev.h
@@ -0,0 +1,460 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_blkdev
+ *
+ * @brief Block Device Management
+ */
+
+/*
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ */
+
+#ifndef _RTEMS_BLKDEV_H
+#define _RTEMS_BLKDEV_H
+
+#include <rtems.h>
+#include <rtems/diskdevs.h>
+#include <rtems/print.h>
+#include <sys/ioccom.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup rtems_blkdev Block Device Management
+ *
+ * @ingroup rtems_libblock
+ *
+ * Interface between device drivers and the
+ * @ref rtems_bdbuf "block device buffer module".
+ *
+ * The heart of the block device driver is the @ref RTEMS_BLKIO_REQUEST IO
+ * control. This call puts IO @ref rtems_blkdev_request "requests" to the block
+ * device for asynchronous processing. When a driver executes a request, it
+ * invokes the request done callback function to finish the request.
+ */
+/**@{**/
+
+/**
+ * @brief Block device request type.
+ *
+ * @warning The sync request is an IO one and only used from the cache. Use the
+ * Block IO when operating at the device level. We need a sync request
+ * to avoid requests looping for ever.
+ */
+typedef enum rtems_blkdev_request_op {
+ RTEMS_BLKDEV_REQ_READ, /**< Read the requested blocks of data. */
+ RTEMS_BLKDEV_REQ_WRITE, /**< Write the requested blocks of data. */
+ RTEMS_BLKDEV_REQ_SYNC /**< Sync any data with the media. */
+} rtems_blkdev_request_op;
+
+struct rtems_blkdev_request;
+
+/**
+ * @brief Block device request done callback function type.
+ */
+typedef void (*rtems_blkdev_request_cb)(
+ struct rtems_blkdev_request *req,
+ rtems_status_code status
+);
+
+/**
+ * @brief Block device scatter or gather buffer structure.
+ */
+typedef struct rtems_blkdev_sg_buffer {
+ /**
+ * Block index.
+ */
+ rtems_blkdev_bnum block;
+
+ /**
+ * Buffer length.
+ */
+ uint32_t length;
+
+ /**
+ * Buffer pointer.
+ */
+ void *buffer;
+
+ /**
+ * User pointer.
+ */
+ void *user;
+} rtems_blkdev_sg_buffer;
+
+/**
+ * @brief The block device transfer request is used to read or write a number
+ * of blocks from or to the device.
+ *
+ * Transfer requests are issued to the disk device driver with the
+ * @ref RTEMS_BLKIO_REQUEST IO control. The transfer request completion status
+ * must be signalled with rtems_blkdev_request_done(). This function must be
+ * called exactly once per request. The return value of the IO control will be
+ * ignored for transfer requests.
+ *
+ * @see rtems_blkdev_create().
+ */
+typedef struct rtems_blkdev_request {
+ /**
+ * Block device operation (read or write).
+ */
+ rtems_blkdev_request_op req;
+
+ /**
+ * Request done callback function.
+ */
+ rtems_blkdev_request_cb done;
+
+ /**
+ * Argument to be passed to callback function.
+ */
+ void *done_arg;
+
+ /**
+ * Last IO operation completion status.
+ */
+ rtems_status_code status;
+
+ /**
+ * Number of blocks for this request.
+ */
+ uint32_t bufnum;
+
+ /**
+ * The task requesting the IO operation.
+ */
+ rtems_id io_task;
+
+ /*
+ * TODO: The use of these req blocks is not a great design. The req is a
+ * struct with a single 'bufs' declared in the req struct and the
+ * others are added in the outer level struct. This relies on the
+ * structs joining as a single array and that assumes the compiler
+ * packs the structs. Why not just place on a list ? The BD has a
+ * node that can be used.
+ */
+
+ /**
+ * List of scatter or gather buffers.
+ */
+ rtems_blkdev_sg_buffer bufs[RTEMS_ZERO_LENGTH_ARRAY];
+} rtems_blkdev_request;
+
+/**
+ * @brief Signals transfer request completion status.
+ *
+ * This function must be called exactly once per request.
+ *
+ * @param[in,out] req The transfer request.
+ * @param[in] status The status of the operation should be
+ * - @c RTEMS_SUCCESSFUL, if the operation was successful,
+ * - @c RTEMS_IO_ERROR, if some sort of input or output error occurred, or
+ * - @c RTEMS_UNSATISFIED, if media is no more present.
+ */
+static inline void rtems_blkdev_request_done(
+ rtems_blkdev_request *req,
+ rtems_status_code status
+)
+{
+ (*req->done)(req, status);
+}
+
+/**
+ * @brief The start block in a request.
+ *
+ * Only valid if the driver has returned the
+ * @ref RTEMS_BLKDEV_CAP_MULTISECTOR_CONT capability.
+ */
+#define RTEMS_BLKDEV_START_BLOCK(req) (req->bufs[0].block)
+
+/**
+ * @name IO Control Request Codes
+ */
+/**@{**/
+
+#define RTEMS_BLKIO_REQUEST _IOWR('B', 1, rtems_blkdev_request)
+#define RTEMS_BLKIO_GETMEDIABLKSIZE _IOR('B', 2, uint32_t)
+#define RTEMS_BLKIO_GETBLKSIZE _IOR('B', 3, uint32_t)
+#define RTEMS_BLKIO_SETBLKSIZE _IOW('B', 4, uint32_t)
+#define RTEMS_BLKIO_GETSIZE _IOR('B', 5, rtems_blkdev_bnum)
+#define RTEMS_BLKIO_SYNCDEV _IO('B', 6)
+#define RTEMS_BLKIO_DELETED _IO('B', 7)
+#define RTEMS_BLKIO_CAPABILITIES _IO('B', 8)
+#define RTEMS_BLKIO_GETDISKDEV _IOR('B', 9, rtems_disk_device *)
+#define RTEMS_BLKIO_PURGEDEV _IO('B', 10)
+#define RTEMS_BLKIO_GETDEVSTATS _IOR('B', 11, rtems_blkdev_stats *)
+#define RTEMS_BLKIO_RESETDEVSTATS _IO('B', 12)
+
+/** @} */
+
+static inline int rtems_disk_fd_get_media_block_size(
+ int fd,
+ uint32_t *media_block_size
+)
+{
+ return ioctl(fd, RTEMS_BLKIO_GETMEDIABLKSIZE, media_block_size);
+}
+
+static inline int rtems_disk_fd_get_block_size(int fd, uint32_t *block_size)
+{
+ return ioctl(fd, RTEMS_BLKIO_GETBLKSIZE, block_size);
+}
+
+static inline int rtems_disk_fd_set_block_size(int fd, uint32_t block_size)
+{
+ return ioctl(fd, RTEMS_BLKIO_SETBLKSIZE, &block_size);
+}
+
+static inline int rtems_disk_fd_get_block_count(
+ int fd,
+ rtems_blkdev_bnum *block_count
+)
+{
+ return ioctl(fd, RTEMS_BLKIO_GETSIZE, block_count);
+}
+
+static inline int rtems_disk_fd_get_disk_device(
+ int fd,
+ rtems_disk_device **dd_ptr
+)
+{
+ return ioctl(fd, RTEMS_BLKIO_GETDISKDEV, dd_ptr);
+}
+
+static inline int rtems_disk_fd_sync(int fd)
+{
+ return ioctl(fd, RTEMS_BLKIO_SYNCDEV);
+}
+
+static inline int rtems_disk_fd_purge(int fd)
+{
+ return ioctl(fd, RTEMS_BLKIO_PURGEDEV);
+}
+
+static inline int rtems_disk_fd_get_device_stats(
+ int fd,
+ rtems_blkdev_stats *stats
+)
+{
+ return ioctl(fd, RTEMS_BLKIO_GETDEVSTATS, stats);
+}
+
+static inline int rtems_disk_fd_reset_device_stats(int fd)
+{
+ return ioctl(fd, RTEMS_BLKIO_RESETDEVSTATS);
+}
+
+/**
+ * @name Block Device Driver Capabilities
+ */
+/**@{**/
+
+/**
+ * @brief Only consecutive multi-sector buffer requests are supported.
+ *
+ * This option means the cache will only supply multiple buffers that are
+ * inorder so the ATA multi-sector command for example can be used. This is a
+ * hack to work around the current ATA driver.
+ */
+#define RTEMS_BLKDEV_CAP_MULTISECTOR_CONT (1 << 0)
+
+/**
+ * @brief The driver will accept a sync call.
+ *
+ * A sync call is made to a driver after a bdbuf cache sync has finished.
+ */
+#define RTEMS_BLKDEV_CAP_SYNC (1 << 1)
+
+/** @} */
+
+/**
+ * @brief Common IO control primitive.
+ *
+ * Use this in all block devices to handle the common set of IO control
+ * requests.
+ */
+int
+rtems_blkdev_ioctl(rtems_disk_device *dd, uint32_t req, void *argp);
+
+/**
+ * @brief Creates a block device.
+ *
+ * The block size is set to the media block size.
+ *
+ * @param[in] device The path for the new block device.
+ * @param[in] media_block_size The media block size in bytes. Must be positive.
+ * @param[in] media_block_count The media block count. Must be positive.
+ * @param[in] handler The block device IO control handler. Must not be @c NULL.
+ * @param[in] driver_data The block device driver data.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_NUMBER Media block size or count is not positive.
+ * @retval RTEMS_NO_MEMORY Not enough memory.
+ * @retval RTEMS_UNSATISFIED Cannot create generic device node.
+ *
+ * @see rtems_blkdev_create_partition(), rtems_bdbuf_set_block_size(), and
+ * rtems_blkdev_request.
+ */
+rtems_status_code rtems_blkdev_create(
+ const char *device,
+ uint32_t media_block_size,
+ rtems_blkdev_bnum media_block_count,
+ rtems_block_device_ioctl handler,
+ void *driver_data
+);
+
+/**
+ * @brief Creates a partition within a parent block device.
+ *
+ * A partition manages a subset of consecutive blocks contained in a parent block
+ * device. The blocks must be within the range of blocks managed by the
+ * associated parent block device. The media block size and IO control
+ * handler are inherited by the parent block device. The block size is set to
+ * the media block size.
+ *
+ * @param[in] partition The path for the new partition device.
+ * @param[in] parent_block_device The parent block device path.
+ * @param[in] media_block_begin The media block begin of the partition within
+ * the parent block device.
+ * @param[in] media_block_count The media block count of the partition.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID Block device node does not exist.
+ * @retval RTEMS_INVALID_NODE File system node is not a block device.
+ * @retval RTEMS_NOT_IMPLEMENTED Block device implementation is incomplete.
+ * @retval RTEMS_INVALID_NUMBER Block begin or block count is invalid.
+ * @retval RTEMS_NO_MEMORY Not enough memory.
+ * @retval RTEMS_UNSATISFIED Cannot create generic device node.
+ *
+ * @see rtems_blkdev_create() and rtems_bdbuf_set_block_size().
+ */
+rtems_status_code rtems_blkdev_create_partition(
+ const char *partition,
+ const char *parent_block_device,
+ rtems_blkdev_bnum media_block_begin,
+ rtems_blkdev_bnum media_block_count
+);
+
+/**
+ * @brief Prints the block device statistics.
+ */
+void rtems_blkdev_print_stats(
+ const rtems_blkdev_stats *stats,
+ uint32_t media_block_size,
+ uint32_t media_block_count,
+ uint32_t block_size,
+ const rtems_printer* printer
+);
+
+/**
+ * @brief Block device statistics command.
+ */
+void rtems_blkstats(
+ const rtems_printer *printer,
+ const char *device,
+ bool reset
+);
+
+/** @} */
+
+/**
+ * @defgroup rtems_blkdev_generic Generic Disk Device
+ *
+ * @ingroup rtems_blkdev
+ *
+ * Generic disk device operations for standard RTEMS IO drivers.
+ */
+/**@{**/
+
+/**
+ * The device driver interface conventions suppose that a driver may contain an
+ * initialize, open, close, read, write and IO control entry points. These
+ * primitives (except initialize) can be implemented in a generic fashion based
+ * upon the supplied block device driver IO control handler. Every block device
+ * driver should provide an initialize entry point, which registers the
+ * appropriate IO control handler.
+ */
+#define RTEMS_GENERIC_BLOCK_DEVICE_DRIVER_ENTRIES \
+ rtems_blkdev_generic_open, \
+ rtems_blkdev_generic_close, \
+ rtems_blkdev_generic_read, \
+ rtems_blkdev_generic_write, \
+ rtems_blkdev_generic_ioctl
+
+/**
+ * Generic block device read primitive.
+ *
+ * Implemented using block device buffer management primitives.
+ */
+rtems_device_driver
+rtems_blkdev_generic_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+);
+
+/**
+ * Generic block device write primitive.
+ *
+ * Implemented using block device buffer management primitives.
+ */
+rtems_device_driver
+rtems_blkdev_generic_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+);
+
+/**
+ * Generic block device open primitive.
+ *
+ * Implemented using block device buffer management primitives.
+ */
+rtems_device_driver
+rtems_blkdev_generic_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+);
+
+/**
+ * Generic block device close primitive.
+ *
+ * Implemented using block device buffer management primitives.
+ */
+rtems_device_driver
+rtems_blkdev_generic_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+);
+
+/**
+ * Generic block device IO control primitive.
+ *
+ * Implemented using block device buffer management primitives.
+ */
+rtems_device_driver
+rtems_blkdev_generic_ioctl(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+);
+
+/**
+ * @brief Generic block operations driver address table.
+ */
+extern const rtems_driver_address_table rtems_blkdev_generic_ops;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/bsd.h b/cpukit/include/rtems/bsd.h
new file mode 100644
index 0000000000..0c44e3787d
--- /dev/null
+++ b/cpukit/include/rtems/bsd.h
@@ -0,0 +1,141 @@
+/**
+ * @file
+ *
+ * @ingroup BSD
+ *
+ * @brief BSD Compatibility API
+ */
+
+/*
+ * Copyright (c) 2015 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_BSD_H
+#define _RTEMS_BSD_H
+
+#include <rtems/score/timecounter.h>
+#include <rtems/score/basedefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup BSD BSD Compatibility Support
+ *
+ * @{
+ */
+
+/**
+ * @copydoc _Timecounter_Bintime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_bintime( struct bintime *bt )
+{
+ _Timecounter_Bintime( bt );
+}
+
+/**
+ * @copydoc _Timecounter_Nanotime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_nanotime( struct timespec *ts )
+{
+ _Timecounter_Nanotime( ts );
+}
+
+/**
+ * @copydoc _Timecounter_Microtime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_microtime( struct timeval *tv )
+{
+ _Timecounter_Microtime( tv );
+}
+
+/**
+ * @copydoc _Timecounter_Binuptime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_binuptime( struct bintime *bt )
+{
+ _Timecounter_Binuptime( bt );
+}
+
+/**
+ * @copydoc _Timecounter_Nanouptime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_nanouptime( struct timespec *ts )
+{
+ _Timecounter_Nanouptime( ts );
+}
+
+/**
+ * @copydoc _Timecounter_Microtime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_microuptime( struct timeval *tv )
+{
+ _Timecounter_Microuptime( tv );
+}
+
+/**
+ * @copydoc _Timecounter_Getbintime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_getbintime( struct bintime *bt )
+{
+ _Timecounter_Getbintime( bt );
+}
+
+/**
+ * @copydoc _Timecounter_Getnanotime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_getnanotime( struct timespec *ts )
+{
+ _Timecounter_Getnanotime( ts );
+}
+
+/**
+ * @copydoc _Timecounter_Getmicrotime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_getmicrotime( struct timeval *tv )
+{
+ _Timecounter_Getmicrotime( tv );
+}
+
+/**
+ * @copydoc _Timecounter_Getbinuptime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_getbinuptime( struct bintime *bt )
+{
+ _Timecounter_Getbinuptime( bt );
+}
+
+/**
+ * @copydoc _Timecounter_Getnanouptime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_getnanouptime( struct timespec *ts )
+{
+ _Timecounter_Getnanouptime( ts );
+}
+
+/**
+ * @copydoc _Timecounter_Getmicrouptime()
+ */
+RTEMS_INLINE_ROUTINE void rtems_bsd_getmicrouptime( struct timeval *tv )
+{
+ _Timecounter_Getmicrouptime( tv );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_BSD_H */
diff --git a/cpukit/include/rtems/bspcmdline.h b/cpukit/include/rtems/bspcmdline.h
new file mode 100644
index 0000000000..51916ff26a
--- /dev/null
+++ b/cpukit/include/rtems/bspcmdline.h
@@ -0,0 +1,131 @@
+/**
+ * @file rtems/bspcmdline.h
+ *
+ * @defgroup BSPCommandLine BSP Command Line Helpers
+ *
+ * @ingroup libmisc
+ * @brief BSP Command Line Handler
+ *
+ * This include file contains all prototypes and specifications
+ * related to the BSP Command Line String and associated helper
+ * routines. The helpers are useful for locating command line
+ * type arguments (e.g. --mode) and their associated right
+ * hand side (e.g. FAST in --mode=FAST).
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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 __BSP_COMMAND_LINE_h
+#define __BSP_COMMAND_LINE_h
+
+/**
+ * @defgroup BSPCommandLine BSP Command Line Helpers
+ *
+ * The BSP Command Line Handler provides a set of routines which assist
+ * in examining and decoding the Command Line String passed to the BSP
+ * at boot time.
+ */
+/**@{*/
+
+#include <stddef.h> /* for size_t */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Obtain Pointer to BSP Boot Command String
+ *
+ * This method returns a pointer to the BSP Boot Command String. It
+ * is as likely to be NULL as point to a string as most BSPs do not
+ * have a start environment that provides a boot string.
+ *
+ * @retval This method returns the pointer to the BSP Boot Command String.
+ */
+const char *rtems_bsp_cmdline_get(void);
+
+/**
+ * @brief Obtain COPY of the Entire Matching Argument
+ *
+ * This method searches for the argument @a name in the BSP Boot Command
+ * String and returns a copy of the entire string associated with it in
+ * @a value up to a string of @a length. This will include the argument
+ * and any right hand side portion of the string. For example, one might
+ * be returned --mode=FAST if
+ * searching for --mode.
+ *
+ * @param[in] name is the arugment to search for
+ * @param[in] value points to where the contents will
+ * be placed if located.
+ * @param[in] length is the maximum length to copy
+ *
+ * @return This method returns NULL if not found and
+ * @a value if found.
+ */
+const char *rtems_bsp_cmdline_get_param(
+ const char *name,
+ char *value,
+ size_t length
+);
+
+
+/**
+ * @brief Obtain COPY of the Right Hand Side of the Matching Argument
+ *
+ * This method searches for the argument @a name in
+ * the BSP Boot Command String and returns the right hand side
+ * associated with it in @a value up to a maximum string @a length.
+ * This will NOT include the argument but only any right hand side
+ * portion of the string. * For example, one might be returned FAST if
+ * searching for --mode.
+ *
+ * @param[in] name is the arugment to search for
+ * @param[in] value points to where the contents will
+ * be placed if located.
+ * @param[in] length is the maximum length to copy
+ *
+ * @retval This method returns NULL if not found and
+ * @a value if found.
+ */
+const char *rtems_bsp_cmdline_get_param_rhs(
+ const char *name,
+ char *value,
+ size_t length
+);
+
+/**
+ * @brief Obtain Pointer to the Entire Matching Argument
+ *
+ * This method searches for the argument @a name in
+ * the BSP Boot Command String and returns a pointer to the
+ * entire string associated with it. This will include the
+ * argument and any right hand side portion of the string.
+ * For example, one might be returned --mode=FAST if
+ * searching for --mode.
+ *
+ * @param[in] name is the arugment to search for
+ *
+ * @retval This method returns NULL if not found and a pointer
+ * into the BSP Boot Command String if found.
+ *
+ * @note The pointer will be to the original BSP Command
+ * Line string. Exercise caution when using this.
+ */
+const char *rtems_bsp_cmdline_get_param_raw(
+ const char *name
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+#endif
diff --git a/cpukit/include/rtems/capture-cli.h b/cpukit/include/rtems/capture-cli.h
new file mode 100644
index 0000000000..55749b7cb1
--- /dev/null
+++ b/cpukit/include/rtems/capture-cli.h
@@ -0,0 +1,53 @@
+/**
+ * @file rtems/capture-cli.h
+ *
+ * This is the Target Interface Command Line Interface. You need
+ * start the RTEMS monitor.
+ */
+
+/*
+ ------------------------------------------------------------------------
+
+ Copyright 2002, 2016 Chris Johns <chrisj@rtems.org>.
+ All rights reserved.
+
+ COPYRIGHT (c) 1989-2014.
+ On-Line Applications Research Corporation (OAR).
+
+ The license and distribution terms for this file may be
+ found in the file LICENSE in this distribution.
+
+ This software with is provided ``as is'' and with NO WARRANTY.
+
+ ------------------------------------------------------------------------
+
+ RTEMS Performance Monitoring and Measurement Framework.
+
+ This is the Target Interface Command Line Interface. You need
+ start the RTEMS monitor.
+
+*/
+
+#ifndef __CAPTURE_CLI_H_
+#define __CAPTURE_CLI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/capture.h>
+
+/**
+ * rtems_capture_cli_init
+ *
+ * This function initialises the command line interface to the capture
+ * engine.
+ */
+rtems_status_code
+rtems_capture_cli_init (rtems_capture_timestamp timestamp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/capture.h b/cpukit/include/rtems/capture.h
new file mode 100644
index 0000000000..f847ee0424
--- /dev/null
+++ b/cpukit/include/rtems/capture.h
@@ -0,0 +1,1122 @@
+/**
+ * @file rtems/capture.h
+ *
+ * @brief Capture Engine Component of the RTEMS Measurement and
+ * Monitoring System
+ *
+ * This is the Capture Engine component of the RTEMS Measurement and
+ * Monitoring system.
+ */
+
+/*
+ ------------------------------------------------------------------------
+
+ Copyright 2002, 2016 Chris Johns <chrisj@rtems.org>.
+ All rights reserved.
+
+ COPYRIGHT (c) 1989-2014
+ On-Line Applications Research Corporation (OAR).
+
+ The license and distribution terms for this file may be
+ found in the file LICENSE in this distribution.
+
+ This software with is provided ``as is'' and with NO WARRANTY.
+
+ ------------------------------------------------------------------------
+
+ RTEMS Performance Monitoring and Measurement Framework.
+ This is the Capture Engine component.
+
+*/
+
+#ifndef __CAPTURE_H_
+#define __CAPTURE_H_
+
+#include <rtems.h>
+#include <rtems/rtems/tasksimpl.h>
+#include <rtems/score/schedulerimpl.h>
+
+/**
+ * @defgroup libmisc_capture RTEMS Capture Engine
+ *
+ * @ingroup libmisc
+ *
+ * Capture Engine Component of the RTEMS Measurement and Monitoring System
+ */
+/**@{*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Global capture flags.
+ */
+#define RTEMS_CAPTURE_INIT (1u << 0)
+#define RTEMS_CAPTURE_ON (1U << 1)
+#define RTEMS_CAPTURE_NO_MEMORY (1U << 2)
+#define RTEMS_CAPTURE_TRIGGERED (1U << 3)
+#define RTEMS_CAPTURE_GLOBAL_WATCH (1U << 4)
+#define RTEMS_CAPTURE_ONLY_MONITOR (1U << 5)
+
+/*
+ * Per-CPU capture flags.
+ */
+#define RTEMS_CAPTURE_OVERFLOW (1U << 0)
+#define RTEMS_CAPTURE_READER_ACTIVE (1U << 1)
+#define RTEMS_CAPTURE_READER_WAITING (1U << 2)
+
+/**
+ * The number of tasks in a trigger group.
+ */
+#define RTEMS_CAPTURE_TRIGGER_TASKS (32)
+
+/**
+ * @brief A capture timestamp.
+ *
+ * This is a nanosecond capture timestamp
+ */
+typedef uint64_t rtems_capture_time;
+
+/**
+ * @brief Task id and mask for the from trigger.
+ *
+ * A from capture is a task id and a mask for the type of
+ * from trigger we are interested in. The mask uses the same
+ * bit maps as the flags field in the control structure. There
+ * will only be a from type trigger if the flags in the control
+ * structure has the specific *_BY bit set.
+ */
+typedef struct rtems_capture_from
+{
+ rtems_name name;
+ rtems_id id;
+ uint32_t trigger;
+} rtems_capture_from;
+
+/**
+ * @brief Capture control structure for a group of tasks.
+ *
+ * RTEMS control holds the trigger and watch configuration for a group of
+ * tasks with the same name. The flags hold global control flags.
+ *
+ * The to_triggers fields holds triggers TO this task. The from_triggers holds
+ * triggers from this task. The by_triggers is an OR or triggers which are
+ * caused BY the task listed TO this task. The by_valid flag which entries
+ * in by are valid.
+ */
+typedef struct rtems_capture_control
+{
+ rtems_name name;
+ rtems_id id;
+ uint32_t flags;
+ uint32_t to_triggers;
+ uint32_t from_triggers;
+ uint32_t by_triggers;
+ uint32_t by_valid;
+ rtems_capture_from by[RTEMS_CAPTURE_TRIGGER_TASKS];
+ struct rtems_capture_control* next;
+} rtems_capture_control;
+
+/**
+ * The from_valid mask.
+ */
+#define RTEMS_CAPTURE_CONTROL_FROM_MASK(_s) \
+ (UINT32_C(1) << (RTEMS_CAPTURE_TRIGGER_TASKS - ((_s) + 1)))
+
+/**
+ * Control flags.
+ */
+#define RTEMS_CAPTURE_WATCH (1U << 0)
+
+/**
+ * Control triggers.
+ */
+#define RTEMS_CAPTURE_SWITCH (1 << 0)
+#define RTEMS_CAPTURE_CREATE (1 << 1)
+#define RTEMS_CAPTURE_START (1 << 2)
+#define RTEMS_CAPTURE_RESTART (1 << 3)
+#define RTEMS_CAPTURE_DELETE (1 << 4)
+#define RTEMS_CAPTURE_BEGIN (1 << 5)
+#define RTEMS_CAPTURE_EXITTED (1 << 6)
+#define RTEMS_CAPTURE_TERMINATED (1 << 7)
+
+#define RTEMS_CAPTURE_FROM_TRIGS (RTEMS_CAPTURE_SWITCH | \
+ RTEMS_CAPTURE_CREATE | \
+ RTEMS_CAPTURE_START | \
+ RTEMS_CAPTURE_RESTART | \
+ RTEMS_CAPTURE_DELETE)
+
+#define RTEMS_CAPTURE_TO_TRIGS (RTEMS_CAPTURE_SWITCH | \
+ RTEMS_CAPTURE_CREATE | \
+ RTEMS_CAPTURE_START | \
+ RTEMS_CAPTURE_RESTART | \
+ RTEMS_CAPTURE_DELETE | \
+ RTEMS_CAPTURE_BEGIN | \
+ RTEMS_CAPTURE_EXITTED)
+
+/**
+ * Task flags.
+ */
+#define RTEMS_CAPTURE_TRACED (1U << 0)
+#define RTEMS_CAPTURE_INIT_TASK (1U << 1)
+#define RTEMS_CAPTURE_RECORD_TASK (1U << 2)
+
+/*
+ * @brief Capture record.
+ *
+ * This is a record that is written into
+ * the buffer. The events includes the priority of the task
+ * at the time of the context switch.
+ */
+typedef struct rtems_capture_record
+{
+ size_t size;
+ uint32_t events;
+ rtems_id task_id;
+ rtems_capture_time time;
+} RTEMS_PACKED rtems_capture_record;
+
+/*
+ * @brief Capture task record.
+ *
+ * This is a record that is written into
+ * the buffer. The events includes the priority of the task
+ * at the time of the context switch.
+ */
+typedef struct rtems_capture_task_record
+{
+ rtems_name name;
+ rtems_task_priority start_priority;
+ uint32_t stack_size;
+} RTEMS_PACKED rtems_capture_task_record;
+
+/**
+ * The capture record event flags.
+ */
+#define RTEMS_CAPTURE_REAL_PRI_EVENT_MASK UINT32_C (0x000000ff)
+#define RTEMS_CAPTURE_CURR_PRI_EVENT_MASK UINT32_C (0x0000ff00)
+#define RTEMS_CAPTURE_REAL_PRIORITY_EVENT (0)
+#define RTEMS_CAPTURE_CURR_PRIORITY_EVENT (8)
+#define RTEMS_CAPTURE_EVENT_START (16)
+#define RTEMS_CAPTURE_CREATED_BY_EVENT UINT32_C (0x00010000)
+#define RTEMS_CAPTURE_CREATED_EVENT UINT32_C (0x00020000)
+#define RTEMS_CAPTURE_STARTED_BY_EVENT UINT32_C (0x00040000)
+#define RTEMS_CAPTURE_STARTED_EVENT UINT32_C (0x00080000)
+#define RTEMS_CAPTURE_RESTARTED_BY_EVENT UINT32_C (0x00100000)
+#define RTEMS_CAPTURE_RESTARTED_EVENT UINT32_C (0x00200000)
+#define RTEMS_CAPTURE_DELETED_BY_EVENT UINT32_C (0x00400000)
+#define RTEMS_CAPTURE_DELETED_EVENT UINT32_C (0x00800000)
+#define RTEMS_CAPTURE_TERMINATED_EVENT UINT32_C (0x01000000)
+#define RTEMS_CAPTURE_BEGIN_EVENT UINT32_C (0x02000000)
+#define RTEMS_CAPTURE_EXITTED_EVENT UINT32_C (0x04000000)
+#define RTEMS_CAPTURE_SWITCHED_OUT_EVENT UINT32_C (0x08000000)
+#define RTEMS_CAPTURE_SWITCHED_IN_EVENT UINT32_C (0x10000000)
+#define RTEMS_CAPTURE_TIMESTAMP UINT32_C (0x20000000)
+#define RTEMS_CAPTURE_EVENT_END (29)
+
+/**
+ * @brief Capture trigger modes
+ *
+ * The types of trigger modes that exist.
+ */
+typedef enum rtems_capture_trigger_mode
+{
+ rtems_capture_to_any,
+ rtems_capture_from_any,
+ rtems_capture_from_to
+} rtems_capture_trigger_mode;
+
+/**
+ * @brief Capture trigger.
+ *
+ * The types of triggers that exist.
+ */
+typedef enum rtems_capture_trigger
+{
+ rtems_capture_switch,
+ rtems_capture_create,
+ rtems_capture_start,
+ rtems_capture_restart,
+ rtems_capture_delete,
+ rtems_capture_begin,
+ rtems_capture_exitted,
+ rtems_capture_terminated
+} rtems_capture_trigger;
+
+/**
+ * @brief Capture timestamp callout handler.
+ *
+ * This defines the callout handler to obtain a time stamp. The
+ * value returned is time count since the last read.
+ *
+ */
+
+typedef void (*rtems_capture_timestamp)(rtems_capture_time* time);
+
+/**
+ * @brief Capture record lock context.
+ *
+ * This structure is used to lock a per CPU buffer when opeining recording. The
+ * per CPU buffer is held locked until the record close is called. Locking
+ * masks interrupts so use this lock only when needed and do not hold it for
+ * long.
+ *
+ * The lock first masks the CPU interrupt before taking the interrupt
+ * lock. This stops a thread context taking the lock and then an interrupt on
+ * the same CPU attempting to take the lock so creating a deadlock.
+ *
+ */
+typedef struct {
+ rtems_interrupt_lock_context lock_context;
+ rtems_interrupt_lock* lock;
+} rtems_capture_record_lock_context;
+
+/**
+ * @brief Capture open
+ *
+ * This function initialises the realtime trace manager allocating the
+ * capture buffer. It is assumed we have a working heap at stage of
+ * initialisation.
+ *
+ * @param[in] size The number of capture records to define.
+ * @param[in] timestamp The timestamp callout handler to use. If the
+ * the handler is NULL a default nano-second timestamp
+ * will be used.
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_capture_open (uint32_t size,
+ rtems_capture_timestamp timestamp);
+
+/**
+ * @brief Capture close
+ *
+ * This function shutdowns the tracer and release any claimed
+ * resources.
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_capture_close (void);
+
+/**
+ * @brief Capture control trace enable/disable.
+ *
+ * This function allows control of tracing at a global level.
+ *
+ * @param[in] enable The trace enable/disable flag.
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_capture_set_control (bool enable);
+
+/**
+ * @brief Capture monitor enable/disable.
+ *
+ * This function enable the monitor mode. When in the monitor mode
+ * the tasks are monitored but no data is saved. This can be used
+ * to profile the load on a system.
+ *
+ * @param[in] enable The monitor enable/disable flag.
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_capture_set_monitor (bool enable);
+
+/*
+ * @brief Capture flush trace buffer.
+ *
+ * This function flushes the trace buffer. The prime parameter allows the
+ * capture engine to also be primed again.
+ *
+ * @param[in] prime The prime after flush flag.
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_capture_flush (bool prime);
+
+/**
+ * @brief Capture add watch
+ *
+ * This function defines a watch for a specific task given a name. A watch
+ * causes it to be traced either in or out of context. The watch can be
+ * optionally enabled or disabled with the set routine. It is disabled by
+ * default.
+ *
+ * @param[in] name The name of the @a capture_controls entry
+ * @param[in] id The id of the @a capture_controls entry.
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_capture_watch_add (rtems_name name, rtems_id id);
+
+/**
+ * @brief Capture delete watch.
+ *
+ * This function removes a watch for a specific task given a name. The task
+ * description will still exist if referenced by a trace record in the trace
+ * buffer or a global watch is defined.
+ *
+ * @param[in] name The name of the @a capture_controls entry
+ * @param[in] id The id of the @a capture_controls entry.
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_capture_watch_del (rtems_name name, rtems_id id);
+
+/**
+ * @brief Capture enable/disable watch.
+ *
+ * This function allows control of a watch. The watch can be enabled or
+ * disabled.
+ *
+ * @param[in] name The name of the @a capture_controls entry
+ * @param[in] id The id of the @a capture_controls entry.
+ * @param[in] enable The enable/disable flag for the watch.
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_capture_watch_ctrl (rtems_name name,
+ rtems_id id,
+ bool enable);
+
+/**
+ * @brief Capture enable/disable global watch.
+ *
+ * This function allows control of a global watch. The watch can
+ * be enabled or disabled. A global watch configures all tasks below
+ * the ceiling and above the floor to be traced.
+ *
+ * @param[in] enable The enable/disable flag for the watch.
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_capture_watch_global (bool enable);
+
+/**
+ * @brief Get global watch state
+ *
+ * This function returns the global watch state.
+ *
+ * @retval This method returns true if the global watch
+ * is on. Otherwise, it returns false.
+ */
+bool rtems_capture_watch_global_on (void);
+
+/**
+ * @brief Set watch ceiling.
+ *
+ * This function sets a watch ceiling. Events from tasks at or greater
+ * than the ceiling priority are ignored. This is a simple way to
+ * monitor an application and exclude system tasks running at a higher
+ * priority level.
+ *
+ * @param[in] ceiling specifies the priority level immediately above
+ * that at which events from tasks are not captured.
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_capture_watch_ceiling (rtems_task_priority ceiling);
+
+/**
+ * @brief Get watch ceiling.
+ *
+ * This function gets the watch ceiling.
+ *
+ * @retval The priority level immediately above that at which events
+ * from tasks are not captured.
+ */
+rtems_task_priority rtems_capture_watch_get_ceiling (void);
+
+/**
+ * @brief Capture set watch floor.
+ *
+ * This function sets a watch floor. Tasks at or less than the
+ * floor priority are not watched. This is a simple way to monitor
+ * an application and exclude system tasks running at a lower
+ * priority level.
+ *
+ * @param[in] floor specifies the priority level immediately below
+ * that at which events from tasks are not captured.
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_capture_watch_floor (rtems_task_priority floor);
+
+/**
+ * @brief Capture set watch floor
+ *
+ * This function gets the watch floor.
+ *
+ * @retval The priority level immediately below
+ * that at which events from tasks are not captured.
+ */
+rtems_task_priority rtems_capture_watch_get_floor (void);
+
+/**
+ * @brief Capture set trigger
+ *
+ * This function sets a trigger.
+ *
+ * This set trigger routine will create a trace control for the
+ * target task. The task list is searched and any existing tasks
+ * are linked to the new control.
+ *
+ * We can have a number of tasks that have the same name so we
+ * search using names. This means a number of tasks can be
+ * linked to single control.
+ *
+ * Some events captured such as context switch include two
+ * tasks. These are referred to as being "from" and "to"
+ * Some events may only have one task specified.
+ *
+ * @param[in] from_name specifies the name of the from task.
+ * @param[in] from_id specifies the id of the from task.
+ * @param[in] to_name specifies the name of the to task.
+ * @param[in] to_id specifies the id of the to task.
+ * @param[in] mode specifies the trigger mode.
+ * @param[in] trigger specifies the type of trigger.
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code
+rtems_capture_set_trigger (rtems_name from_name,
+ rtems_id from_id,
+ rtems_name to_name,
+ rtems_id to_id,
+ rtems_capture_trigger_mode mode,
+ rtems_capture_trigger trigger);
+
+/**
+ * @brief Capture clear trigger.
+ *
+ * This function clears a trigger.
+ *
+ * This clear trigger routine will not clear a watch.
+ *
+ * @param[in] from_name specifies the name of the from task.
+ * @param[in] from_id specifies the id of the from task.
+ * @param[in] to_name specifies the name of the to task.
+ * @param[in] to_id specifies the id of the to task.
+ * @param[in] mode specifies the trigger mode.
+ * @param[in] trigger specifies the type of trigger.
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code
+rtems_capture_clear_trigger (rtems_name from_name,
+ rtems_id from_id,
+ rtems_name to_name,
+ rtems_id to_id,
+ rtems_capture_trigger_mode mode,
+ rtems_capture_trigger trigger);
+
+/**
+ * @brief Capture read records from capture buffer
+ *
+ * This function reads a number of records from the capture buffer.
+ *
+ * The function returns the number of record that is has that are
+ * in a continous block of memory. If the number of available records
+ * wrap then only those records are provided. This removes the need for
+ * caller to be concerned about buffer wrappings. If the number of
+ * requested records cannot be met due to the wrapping of the records
+ * less than the specified number will be returned.
+ *
+ * The user must release the records. This is achieved with a call to
+ * rtems_capture_release. Calls this function without a release will
+ * result in at least the same number of records being released.
+ *
+ * @param[in] cpu The cpu number that the records were recorded on
+ * @param[out] read will contain the number of records read
+ * @param[out] recs The capture records that are read.
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_capture_read (uint32_t cpu,
+ size_t* read,
+ const void** recs);
+
+/**
+ * @brief Capture release records.
+ *
+ * This function releases the requested number of record slots back
+ * to the capture engine. The count must match the number read.
+ *
+ * @param[in] count The number of record slots to release
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_capture_release (uint32_t cpu, uint32_t count);
+
+/**
+ * @brief Capture filter
+ *
+ * This function this function specifies if the given task and events should be
+ * logged.
+ *
+ * @param[in] task specifies the capture task control block
+ * @param[in] events specifies the events
+ *
+ * @retval This method returns true if this data should be filtered from the
+ * log. It returns false if this data should be logged.
+ */
+bool rtems_capture_filter (rtems_tcb* task, uint32_t events);
+
+/**
+ * @brief Capture returns the current time.
+ *
+ * This function returns the current time. If a handler is provided
+ * by the user the time is gotten from that.
+ *
+ * @param[in] time specifies the capture time
+ *
+ * @retval This method returns a nano-second time if no user handler
+ * is provided. Otherwise, it returns a resolution defined by the handler.
+ */
+void rtems_capture_get_time (rtems_capture_time* time);
+
+/**
+ * @brief Capture get event text.
+ *
+ * This function returns a string for an event based on the bit in the
+ * event. The functions takes the bit offset as a number not the bit
+ * set in a bit map.
+ *
+ * @param[in] event specifies the event to describe
+ *
+ * @retval This method returns a string description of the given event.
+ */
+const char* rtems_capture_event_text (int event);
+
+/**
+ * @brief Capture initialize task
+ *
+ * This function initializes capture control in the tcb.
+ *
+ * @param[in] tcb is the task control block for the task
+ */
+void rtems_capture_initialize_task (rtems_tcb* tcb);
+
+/**
+ * @brief Capture record task.
+ *
+ * This function records a new capture task record.
+ *
+ * @param[in] tcb is the task control block for the task
+ */
+void rtems_capture_record_task (rtems_tcb* tcb);
+
+/**
+ * @brief Capture record lock.
+ *
+ * This does a lock acquire which will remain in effect until
+ * rtems_capture_record_unlock is called.
+ *
+ * @param[out] context specifies the record context
+ */
+void rtems_capture_record_lock (rtems_capture_record_lock_context* context);
+
+/**
+ * @brief Capture record unlock.
+ *
+ * This unlocks the record lock.
+ *
+ * @param[in] context specifies the record context
+ */
+void rtems_capture_record_unlock (rtems_capture_record_lock_context* context);
+
+/**
+ * @brief Capture record open.
+ *
+ * This function allocates a record and fills in the header information. It
+ * does a lock acquire which will remain in effect until
+ * rtems_capture_record_close is called. The size is the amount of user data
+ * being recorded. The record header is internally managed.
+ *
+ * @param[in] task specifies the caputre task block
+ * @param[in] events specifies the events
+ * @param[in] size specifies the user's capture data size
+ * @param[out] context specifies the record context
+ *
+ * @retval This method returns a pointer to the next location in
+ * the capture record to store data.
+ */
+void* rtems_capture_record_open (rtems_tcb* task,
+ uint32_t events,
+ size_t size,
+ rtems_capture_record_lock_context* context);
+
+/**
+ * @brief Capture record close.
+ *
+ * This function closes writing to capure record and releases the lock that was
+ * held on the per CPU buffer.
+ *
+ * @param[out] context specifies the record context
+ */
+void rtems_capture_record_close (rtems_capture_record_lock_context* context);
+
+/**
+ * @brief Capture append to record to the per CPU buffer.
+ *
+ * This function appends data of a specifed size into a capture buffer.
+ *
+ * @param[in] rec specifies the next write point in the capture record
+ * @param[in] data specifies the data to write
+ * @param[in] size specifies the size of the data
+ *
+ * @retval This method returns the next write point in the capture record.
+ */
+static inline void*
+rtems_capture_record_append (void* rec, const void* data, size_t size)
+{
+ memcpy (rec, data, size);
+ return ((uint8_t*) rec) + size;
+}
+
+/**
+ * @brief Capture read a record from the per CPU buffer.
+ *
+ * This function reads data of a specifed size from a capture buffer.
+ *
+ * @param[in] rec specifies the next read point in the capture record
+ * @param[in] data specifies where to write the data
+ * @param[in] size specifies the size of the data
+ *
+ * @retval This method returns the next write point in the capture record.
+ */
+static inline void*
+rtems_capture_record_extract (const void* rec, void* data, size_t size)
+{
+ memcpy (data, rec, size);
+ return ((uint8_t*) rec) + size;
+}
+
+/**
+ * @brief Capture task recorded
+ *
+ * This function returns true if this task information has been
+ * recorded.
+ *
+ * @param[in] tcb is the task control block for the task
+ */
+static inline bool rtems_capture_task_recorded (rtems_tcb* tcb) {
+ return ((tcb->Capture.flags & RTEMS_CAPTURE_RECORD_TASK) != 0);
+}
+
+/**
+ * @brief Capture task initialized
+ *
+ * This function returns true if this task information has been
+ * initialized.
+ *
+ * @param[in] tcb is the task control block for the task
+ */
+static inline bool rtems_capture_task_initialized (rtems_tcb* tcb) {
+ return ((tcb->Capture.flags & RTEMS_CAPTURE_INIT_TASK) != 0);
+}
+
+/**
+ * @brief Capture get task id.
+ *
+ * This function returns the task id.
+ *
+ * @param[in] task The capture task.
+ *
+ * @retval This function returns the task id.
+ */
+static inline rtems_id
+rtems_capture_task_id (rtems_tcb* tcb)
+{
+ return tcb->Object.id;
+}
+
+/**
+ * @brief Capture get task API.
+ *
+ * This function returns the task API as an int.
+ *
+ * @param[in] task The capture task.
+ *
+ * @retval This function returns the task API as an int.
+ */
+static inline int
+rtems_capture_task_api (rtems_id id)
+{
+ return _Objects_Get_API (id);
+}
+
+/**
+ * @brief Capture get task state.
+ *
+ * This function returns the task state.
+ *
+ * @param[in] task The capture task.
+ *
+ * @retval This function returns the task state.
+ */
+static inline States_Control
+rtems_capture_task_state (rtems_tcb* tcb)
+{
+ if (tcb)
+ return tcb->current_state;
+ return 0;
+}
+
+/**
+ * @brief Capture get task name.
+ *
+ * This function returns the task name.
+ *
+ * @param[in] task The capture task.
+ *
+ * @retval This function returns the task name.
+ */
+static inline rtems_name
+rtems_capture_task_name (rtems_tcb* tcb)
+{
+ rtems_name name;
+ rtems_object_get_classic_name( tcb->Object.id, &name );
+ return name;
+}
+
+/**
+ * @brief Capture get task flags.
+ *
+ * This function returns the task flags.
+ *
+ * @param[in] task The capture task.
+ *
+ * @retval This function returns the task flags.
+ */
+static inline uint32_t
+rtems_capture_task_flags (rtems_tcb* tcb)
+{
+ return tcb->Capture.flags;
+}
+
+/**
+ * @brief Capture get task control
+ *
+ * This function returns the task control if present.
+ *
+ * @param[in] task The capture task.
+ *
+ * @retval This function returns the task control if present.
+ */
+static inline rtems_capture_control*
+rtems_capture_task_control (rtems_tcb* tcb)
+{
+ return tcb->Capture.control;
+}
+
+/**
+ * @brief Capture get task control flags.
+ *
+ * This function returns the task control flags if a control is present.
+ *
+ * @param[in] task The capture task.
+ *
+ * @retval This function returns the task control flags if a control is present.
+ */
+static inline uint32_t
+rtems_capture_task_control_flags (rtems_tcb* tcb)
+{
+ rtems_capture_control* control = tcb->Capture.control;
+ if (!control)
+ return 0;
+ return control->flags;
+}
+
+/**
+ * @brief Capture get task start priority.
+ *
+ * This function returns the tasks start priority. The tracer needs this
+ * to track where the task's priority goes.
+ *
+ * @param[in] task The capture task.
+ *
+ * @retval This function returns the tasks start priority. The tracer needs this
+ * to track where the task's priority goes.
+ */
+static inline rtems_task_priority
+rtems_capture_task_start_priority (rtems_tcb* tcb)
+{
+ return _RTEMS_Priority_From_core (_Thread_Scheduler_get_home( tcb ),
+ tcb->Start.initial_priority);
+}
+
+/**
+ * @brief Capture get task real priority.
+ *
+ * This function returns the tasks real priority.
+ *
+ * @param[in] task The capture task.
+ *
+ * @retval This function returns the tasks real priority.
+ */
+static inline rtems_task_priority
+rtems_capture_task_real_priority (rtems_tcb* tcb)
+{
+ return tcb->Real_priority.priority;
+}
+
+/**
+ * @brief Capture get task current priority.
+ *
+ * This function returns the tasks current priority.
+ *
+ * @param[in] task The capture task.
+ *
+ * @retval This function returns the tasks current priority.
+ */
+static inline rtems_task_priority
+rtems_capture_task_curr_priority (rtems_tcb* tcb)
+{
+ return _Thread_Get_priority (tcb);
+}
+
+/**
+ * @brief Capture get control list.
+ *
+ * This function returns the head of the list of controls in the
+ * capture engine.
+ *
+ * @retval This function returns the head of the list of controls in the
+ * capture engine.
+ */
+rtems_capture_control*
+rtems_capture_get_control_list (void);
+
+/**
+ * @brief Capture get next capture control.
+ *
+ * This function returns the pointer to the next control in the list. The
+ * pointer NULL terminates the list.
+ *
+ * @param[in] control the current capture control.
+ *
+ * @retval This function returns the pointer to the next control in the list. The
+ * pointer NULL terminates the list.
+ */
+static inline rtems_capture_control*
+rtems_capture_next_control (rtems_capture_control* control)
+{
+ return control->next;
+}
+
+/**
+ * @brief Capture get capture control id.
+ *
+ * This function returns the control id.
+ *
+ * @param[in] control the capture control.
+ *
+ * @retval This function returns the control id.
+ */
+static inline rtems_id
+rtems_capture_control_id (rtems_capture_control* control)
+{
+ return control->id;
+}
+
+/**
+ * @brief Capture get capture control name.
+ *
+ * This function returns the control name.
+ *
+ * @param[in] control the capture control.
+ *
+ * @retval This function returns the control name.
+ */
+static inline rtems_name
+rtems_capture_control_name (rtems_capture_control* control)
+{
+ return control->name;
+}
+
+/**
+ * @brief Capture get capture control flags.
+ *
+ * This function returns the control flags.
+ *
+ * @param[in] control the capture control.
+ *
+ * @retval This function returns the control flags.
+ */
+static inline uint32_t
+rtems_capture_control_flags (rtems_capture_control* control)
+{
+ return control->flags;
+}
+
+/**
+ * @brief Capture get capture control to triggers.
+ *
+ * This function returns the task control to triggers.
+ *
+ * @param[in] control the capture control.
+ *
+ * @retval This function returns the task control to triggers.
+ */
+static inline uint32_t
+rtems_capture_control_to_triggers (rtems_capture_control* control)
+{
+ return control->to_triggers;
+}
+
+/**
+ * @brief Capture get capture control from triggers.
+ *
+ * This function returns the task control from triggers.
+ *
+ * @param[in] control the capture control.
+ *
+ * @retval This function returns the task control from triggers.
+ */
+static inline uint32_t
+rtems_capture_control_from_triggers (rtems_capture_control* control)
+{
+ return control->from_triggers;
+}
+
+/**
+ * @brief Capture get capture control by triggers.
+ *
+ * This function returns the task control by triggers.
+ *
+ * @param[in] control the capture control.
+ *
+ * @retval This function returns the task control by triggers.
+ */
+static inline uint32_t
+rtems_capture_control_all_by_triggers (rtems_capture_control* control)
+{
+ return control->by_triggers;
+}
+
+/**
+ * @brief Capture get capture control valid by flags.
+ *
+ * This function returns the control valid BY flags.
+ *
+ * @param[in] control The capture control.
+ * @param[in] slot The slot.
+ *
+ * @retval This function returns the control valid BY flags.
+ */
+static inline int
+rtems_capture_control_by_valid (rtems_capture_control* control, int slot)
+{
+ return control->by_valid & RTEMS_CAPTURE_CONTROL_FROM_MASK (slot);
+}
+
+/**
+ * @brief Capture get capture control by task name.
+ *
+ * This function returns the control @a by task name.
+ *
+ * @param[in] control The capture control.
+ * @param[in] by The by index.
+ *
+ * @retval This function returns the control @a by task name.
+ */
+static inline rtems_name
+rtems_capture_control_by_name (rtems_capture_control* control, int by)
+{
+ if (by < RTEMS_CAPTURE_TRIGGER_TASKS)
+ return control->by[by].name;
+ return control->by[0].name;
+}
+
+/**
+ * @brief Capture get capture control by task id.
+ *
+ * This function returns the control @a by task id
+ *
+ * @retval This function returns the control @a by task id.
+ */
+static inline rtems_id
+rtems_capture_control_by_id (rtems_capture_control* control, int by)
+{
+ if (by < RTEMS_CAPTURE_TRIGGER_TASKS)
+ return control->by[by].id;
+ return control->by[0].id;
+}
+
+/**
+ * @brief Capture get capture control by task triggers.
+ *
+ * This function returns the control @a by task triggers.
+ *
+ * @retval This function returns the control @a by task triggers.
+ */
+static inline uint32_t
+rtems_capture_control_by_triggers (rtems_capture_control* control,
+ int by)
+{
+ if (by < RTEMS_CAPTURE_TRIGGER_TASKS)
+ return control->by[by].trigger;
+ return control->by[0].trigger;
+}
+
+/**
+ * @brief Capture get capture control count.
+ *
+ * This function returns the number of controls the capture
+ * engine has.
+ *
+ * @retval This function returns the number of controls the capture
+ * engine has.
+ */
+static inline uint32_t
+rtems_capture_control_count (void)
+{
+ rtems_capture_control* control = rtems_capture_get_control_list ();
+ uint32_t count = 0;
+
+ while (control)
+ {
+ count++;
+ control = rtems_capture_next_control (control);
+ }
+
+ return count;
+}
+
+#ifdef __cplusplus
+}
+#endif
+/**@}*/
+
+#endif
diff --git a/cpukit/include/rtems/captureimpl.h b/cpukit/include/rtems/captureimpl.h
new file mode 100644
index 0000000000..4c4cbe66c3
--- /dev/null
+++ b/cpukit/include/rtems/captureimpl.h
@@ -0,0 +1,185 @@
+/**
+ * @file rtems/captureimpl.h
+ *
+ * @brief Capture Implementation file
+ *
+ * This file contains an interface between the capture engine and
+ * capture user extension methods.
+ */
+
+/*
+ ------------------------------------------------------------------------
+
+ Copyright 2002, 2016 Chris Johns <chrisj@rtems.org>.
+ All rights reserved.
+
+ COPYRIGHT (c) 1989-2014.
+ On-Line Applications Research Corporation (OAR).
+
+ The license and distribution terms for this file may be
+ found in the file LICENSE in this distribution.
+
+ This software with is provided ``as is'' and with NO WARRANTY.
+
+ ------------------------------------------------------------------------
+
+ RTEMS Performance Monitoring and Measurement Framework.
+ This is the Capture Engine component.
+
+*/
+
+#ifndef __CAPTUREIMPL_H_
+#define __CAPTUREIMPL_H_
+
+#include "capture.h"
+
+/**@{*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Capture set extension index.
+ *
+ * This function is used to set the extension index
+ * for the capture engine.
+ *
+ * @param[in] index specifies the extension index to be
+ * used for capture engine data.
+ */
+void rtems_capture_set_extension_index(int index);
+
+/**
+ * @brief Capture get extension index.
+ *
+ * This function rturns the extension index for the
+ * capture engine.
+ *
+ * @retval This method returns the extension index.
+ */
+int rtems_capture_get_extension_index(void);
+
+/**
+ * @brief Capture get flags.
+ *
+ * This function gets the current flag settings
+ * for the capture engine.
+ *
+ * @retval This method returns the global capture
+ * flags.
+ *
+ */
+uint32_t rtems_capture_get_flags(void);
+
+/**
+ * @brief Capture set flags.
+ *
+ * This function sets a flag in the capture engine
+ *
+ * @param[in] mask specifies the flag to set
+ */
+void rtems_capture_set_flags(uint32_t mask);
+
+/**
+ * @brief Capture user extension open.
+ *
+ * This function creates the capture user extensions.
+ *
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL upon successful
+ * creation of the user extensions.
+ */
+rtems_status_code rtems_capture_user_extension_open(void);
+
+/**
+ * @brief Capture user extension close.
+ *
+ * This function closes the capture user extensions.
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL upon a successful
+ * delete of the user extensions.
+ */
+rtems_status_code rtems_capture_user_extension_close(void);
+
+/**
+ * @brief Capture check trigger.
+ *
+ * This function checks if we have triggered or if this event is a
+ * cause of a trigger.
+ *
+ * @param[in] ft specifies specifices the capture from task
+ * @param[in] tt specifies specifices the capture to task
+ * @param[in] events specifies the events
+ *
+ * @retval This method returns true if we have triggered or
+ * if the event is a cause of a trigger.
+ */
+bool rtems_capture_trigger_fired (rtems_tcb* ft,
+ rtems_tcb* tt,
+ uint32_t events);
+
+/**
+ * @brief Capture print trace records.
+ *
+ * This function reads, prints and releases up to
+ * total trace records in either a csv format or an
+ * ascii table format.
+ *
+ * @param[in] total specifies the number of records to print
+ * @param[in] csv specifies a comma seperated value format
+ */
+void rtems_capture_print_trace_records ( int total, bool csv );
+
+/**
+ * @brief Capture print timestamp.
+ *
+ * This function prints uptime in a timestamp format.
+ *
+ * @param[in] uptime specifies the timestamp to print
+ */
+void rtems_capture_print_timestamp (uint64_t uptime);
+
+/**
+ * @brief Capture print record task.
+ *
+ * This function prints a capture record task. This
+ * record contains information to identify a task. It
+ * is refrenced in other records by the task id.
+ *
+ * @param[in] cpu specifies the cpu the cpu the record was logged on.
+ * @param[in] rec specifies the task record.
+ */
+void rtems_capture_print_record_task(int cpu,
+ const rtems_capture_record* rec,
+ const rtems_capture_task_record* task_rec);
+
+/**
+ * @brief Capture print capture record.
+ *
+ * This function prints a user extension
+ * capture record.
+ *
+ * @param[in] cpu specifies the cpu the cpu the record was logged on.
+ * @param[in] rec specifies the record.
+ * @param[in] diff specifies the time between this and the last capture record.
+ * @param[in] name specifies the name of the task, NULL if none.
+ * @param[in] task_count number of tasks to search for.
+ */
+void rtems_capture_print_record_capture(int cpu,
+ const rtems_capture_record* rec,
+ uint64_t diff,
+ const rtems_name* name);
+
+/**
+ * @brief Capture print watch list
+ *
+ * This function prints a capture watch list
+ */
+void rtems_capture_print_watch_list (void);
+
+#ifdef __cplusplus
+}
+#endif
+/**@}*/
+
+#endif
diff --git a/cpukit/include/rtems/cbs.h b/cpukit/include/rtems/cbs.h
new file mode 100644
index 0000000000..a42061ddc0
--- /dev/null
+++ b/cpukit/include/rtems/cbs.h
@@ -0,0 +1,244 @@
+/**
+ * @file
+ *
+ * @brief Constants and Structures Associated
+ * with the CBS library in RTEMS
+ *
+ * This include file contains all the constants and structures associated
+ * with the CBS library in RTEMS.
+ */
+
+/*
+ * Copyright (C) 2011 Petr Benes.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * 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 CONFIGURE_SCHEDULER_CBS
+ #error "cbs.h available only with CONFIGURE_SCHEDULER_CBS"
+#endif
+
+#ifndef _RTEMS_CBS_H
+#define _RTEMS_CBS_H
+
+#include <rtems/score/schedulercbs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Return codes. */
+#define RTEMS_CBS_OK SCHEDULER_CBS_OK
+#define RTEMS_CBS_ERROR_GENERIC SCHEDULER_CBS_ERROR_GENERIC
+#define RTEMS_CBS_ERROR_NO_MEMORY SCHEDULER_CBS_ERROR_NO_MEMORY
+#define RTEMS_CBS_ERROR_INVALID_PARAMETER SCHEDULER_CBS_ERROR_INVALID_PARAM
+#define RTEMS_CBS_ERROR_UNAUTHORIZED SCHEDULER_CBS_ERROR_UNAUTHORIZED
+#define RTEMS_CBS_ERROR_UNIMPLEMENTED SCHEDULER_CBS_ERROR_UNIMPLEMENTED
+#define RTEMS_CBS_ERROR_MISSING_COMPONENT SCHEDULER_CBS_ERROR_MISSING_COMPONENT
+#define RTEMS_CBS_ERROR_INCONSISTENT_STATE SCHEDULER_CBS_ERROR_INCONSISTENT_STATE
+#define RTEMS_CBS_ERROR_SYSTEM_OVERLOAD SCHEDULER_CBS_ERROR_SYSTEM_OVERLOAD
+#define RTEMS_CBS_ERROR_INTERNAL_ERROR SCHEDULER_CBS_ERROR_INTERNAL_ERROR
+#define RTEMS_CBS_ERROR_NOT_FOUND SCHEDULER_CBS_ERROR_NOT_FOUND
+#define RTEMS_CBS_ERROR_FULL SCHEDULER_CBS_ERROR_FULL
+#define RTEMS_CBS_ERROR_EMPTY SCHEDULER_CBS_ERROR_EMPTY
+#define RTEMS_CBS_ERROR_NOSERVER SCHEDULER_CBS_ERROR_NOSERVER
+
+/** Callback function invoked when a budget overrun of a task occurs. */
+typedef Scheduler_CBS_Budget_overrun rtems_cbs_budget_overrun;
+
+/** Server id. */
+typedef Scheduler_CBS_Server_id rtems_cbs_server_id;
+
+/** Server parameters. */
+typedef Scheduler_CBS_Parameters rtems_cbs_parameters;
+
+/**
+ * @brief Initialize the CBS library.
+ *
+ * Initializes the CBS library.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE int rtems_cbs_initialize ( void )
+{
+ return _Scheduler_CBS_Initialize();
+}
+
+/**
+ * @brief Cleanup resources associated to the CBS Library
+ *
+ * Cleanup resources associated to the CBS Library.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE int rtems_cbs_cleanup ( void )
+{
+ return _Scheduler_CBS_Cleanup();
+}
+
+/**
+ * @brief Create a new server with specified parameters.
+ *
+ * Create a new server with specified parameters.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE int rtems_cbs_create_server (
+ rtems_cbs_parameters *params,
+ rtems_cbs_budget_overrun budget_overrun_callback,
+ rtems_cbs_server_id *server_id
+)
+{
+ return _Scheduler_CBS_Create_server(
+ params,
+ budget_overrun_callback,
+ server_id
+ );
+}
+
+/**
+ * @brief Attach a task to an already existing server.
+ *
+ * Attach a task to an already existing server.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE int rtems_cbs_attach_thread (
+ rtems_cbs_server_id server_id,
+ rtems_id task_id
+)
+{
+ return _Scheduler_CBS_Attach_thread( server_id, task_id );
+}
+
+/**
+ * @brief Detach from the CBS server.
+ *
+ * Detach from the CBS Server.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE int rtems_cbs_detach_thread (
+ rtems_cbs_server_id server_id,
+ rtems_id task_id
+)
+{
+ return _Scheduler_CBS_Detach_thread( server_id, task_id );
+}
+
+/**
+ * @brief Detach all tasks from a server and destroy it.
+ *
+ * Detach all tasks from a server and destroy it.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE int rtems_cbs_destroy_server (
+ rtems_cbs_server_id server_id
+)
+{
+ return _Scheduler_CBS_Destroy_server( server_id );
+}
+
+/**
+ * @brief Get CBS server id.
+ *
+ * Get a thread server id, or RTEMS_CBS_E_NOT_FOUND if it is not
+ * attached to any server.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE int rtems_cbs_get_server_id (
+ rtems_id task_id,
+ rtems_cbs_server_id *server_id
+)
+{
+ return _Scheduler_CBS_Get_server_id( task_id, server_id );
+}
+
+/**
+ * @brief Get CBS parameters.
+ *
+ * Retrieve CBS scheduling parameters.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE int rtems_cbs_get_parameters (
+ rtems_cbs_server_id server_id,
+ rtems_cbs_parameters *params
+)
+{
+ return _Scheduler_CBS_Get_parameters( server_id, params );
+}
+
+/**
+ * @brief Set CBS parameters.
+ *
+ * Change CBS scheduling parameters.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE int rtems_cbs_set_parameters (
+ rtems_cbs_server_id server_id,
+ rtems_cbs_parameters *params
+)
+{
+ return _Scheduler_CBS_Set_parameters( server_id, params );
+}
+
+/**
+ * @brief Get the CBS get execution time.
+ *
+ * Retrieve time info relative to the current server.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE int rtems_cbs_get_execution_time (
+ rtems_cbs_server_id server_id,
+ time_t *exec_time,
+ time_t *abs_time
+)
+{
+ return _Scheduler_CBS_Get_execution_time( server_id, exec_time, abs_time );
+}
+
+/**
+ * @brief Get the remaining CBS budget.
+ *
+ * Retrieve remaining budget for the current server instance.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE int rtems_cbs_get_remaining_budget (
+ rtems_cbs_server_id server_id,
+ time_t *remaining_budget
+)
+{
+ return _Scheduler_CBS_Get_remaining_budget( server_id, remaining_budget );
+}
+
+/**
+ * @brief Get the approved CBS budget.
+ *
+ * Retrieve the budget that has been approved for the subsequent
+ * server instances.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE int rtems_cbs_get_approved_budget (
+ rtems_cbs_server_id server_id,
+ time_t *appr_budget
+)
+{
+ return _Scheduler_CBS_Get_approved_budget( server_id, appr_budget );
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/chain.h b/cpukit/include/rtems/chain.h
new file mode 100644
index 0000000000..f0e7ee4f40
--- /dev/null
+++ b/cpukit/include/rtems/chain.h
@@ -0,0 +1,789 @@
+/**
+ * @file
+ *
+ * @brief Chain API
+ */
+
+/*
+ * Copyright (c) 2010-2014 embedded brains GmbH.
+ *
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_CHAIN_H
+#define _RTEMS_CHAIN_H
+
+#include <rtems/score/chainimpl.h>
+#include <rtems/rtems/event.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicChains Chains
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * @brief Chain API
+ */
+/**@{**/
+
+typedef Chain_Node rtems_chain_node;
+
+typedef Chain_Control rtems_chain_control;
+
+/**
+ * @brief Chain initializer for an empty chain with designator @a name.
+ */
+#define RTEMS_CHAIN_INITIALIZER_EMPTY( name ) \
+ CHAIN_INITIALIZER_EMPTY( name )
+
+/**
+ * @brief Chain initializer for a chain with one @a node.
+ *
+ * @see RTEMS_CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN().
+ */
+#define RTEMS_CHAIN_INITIALIZER_ONE_NODE( node ) \
+ CHAIN_INITIALIZER_ONE_NODE( node )
+
+/**
+ * @brief Chain node initializer for a @a chain containing exactly this node.
+ *
+ * @see RTEMS_CHAIN_INITIALIZER_ONE_NODE().
+ */
+#define RTEMS_CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( chain ) \
+ CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( chain )
+
+/**
+ * @brief Chain definition for an empty chain with designator @a name.
+ */
+#define RTEMS_CHAIN_DEFINE_EMPTY( name ) \
+ rtems_chain_control name = RTEMS_CHAIN_INITIALIZER_EMPTY( name )
+
+/**
+ * @brief Appends the @a node to the @a chain and sends the @a events to the
+ * @a task if the @a chain was empty before the append.
+ *
+ * @see rtems_chain_append_with_empty_check() and rtems_event_send().
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID No such task.
+ */
+rtems_status_code rtems_chain_append_with_notification(
+ rtems_chain_control *chain,
+ rtems_chain_node *node,
+ rtems_id task,
+ rtems_event_set events
+);
+
+/**
+ * @brief Prepends the @a node to the @a chain and sends the @a events to the
+ * @a task if the @a chain was empty before the prepend.
+ *
+ * @see rtems_chain_prepend_with_empty_check() and rtems_event_send().
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID No such task.
+ */
+rtems_status_code rtems_chain_prepend_with_notification(
+ rtems_chain_control *chain,
+ rtems_chain_node *node,
+ rtems_id task,
+ rtems_event_set events
+);
+
+/**
+ * @brief Gets the first @a node of the @a chain and sends the @a events to the
+ * @a task if the @a chain is empty after the get.
+ *
+ * @see rtems_chain_get_with_empty_check() and rtems_event_send().
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID No such task.
+ */
+rtems_status_code rtems_chain_get_with_notification(
+ rtems_chain_control *chain,
+ rtems_id task,
+ rtems_event_set events,
+ rtems_chain_node **node
+);
+
+/**
+ * @brief Gets the first @a node of the @a chain and sends the @a events to the
+ * @a task if the @a chain is empty afterwards.
+ *
+ * @see rtems_chain_get() and rtems_event_receive().
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_TIMEOUT Timeout.
+ */
+rtems_status_code rtems_chain_get_with_wait(
+ rtems_chain_control *chain,
+ rtems_event_set events,
+ rtems_interval timeout,
+ rtems_chain_node **node
+);
+
+/**
+ * @brief Initialize a chain Header.
+ *
+ * This routine initializes @a the_chain structure to manage the
+ * contiguous array of @a number_nodes nodes which starts at
+ * @a starting_address. Each node is of @a node_size bytes.
+ *
+ * @param[in] the_chain specifies the chain to initialize
+ * @param[in] starting_address is the starting address of the array
+ * of elements
+ * @param[in] number_nodes is the number of nodes that will be in the chain
+ * @param[in] node_size is the size of each node
+ */
+RTEMS_INLINE_ROUTINE void rtems_chain_initialize(
+ rtems_chain_control *the_chain,
+ void *starting_address,
+ size_t number_nodes,
+ size_t node_size
+)
+{
+ _Chain_Initialize(
+ the_chain,
+ starting_address,
+ number_nodes,
+ node_size
+ );
+}
+
+/**
+ * @brief Initialize this chain as empty.
+ *
+ * This routine initializes the specified chain to contain zero nodes.
+ *
+ * @param[in] the_chain is the chain to be initialized.
+ */
+RTEMS_INLINE_ROUTINE void rtems_chain_initialize_empty(
+ rtems_chain_control *the_chain
+)
+{
+ _Chain_Initialize_empty( the_chain );
+}
+
+/**
+ * @brief Set off chain.
+ *
+ * This function sets the next and previous fields of the @a node to NULL
+ * indicating the @a node is not part of a chain.
+ *
+ * @param[in] node the node set to off chain.
+ */
+RTEMS_INLINE_ROUTINE void rtems_chain_set_off_chain(
+ rtems_chain_node *node
+)
+{
+ _Chain_Set_off_chain( node );
+}
+
+/**
+ * @brief Initializes a chain node.
+ *
+ * In debug configurations, the node is set off chain. In all other
+ * configurations, this function does nothing.
+ *
+ * @param[in] the_node The chain node to initialize.
+ */
+RTEMS_INLINE_ROUTINE void rtems_chain_initialize_node(
+ rtems_chain_node *node
+)
+{
+ _Chain_Initialize_node( node );
+}
+
+/**
+ * @brief Is the node off chain.
+ *
+ * This function returns true if the @a node is not on a chain. A @a node is
+ * off chain if the next and previous fields are set to NULL.
+ *
+ * @param[in] node is the node off chain.
+ *
+ * @retval true The node is off chain.
+ * @retval false The node is not off chain.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_chain_is_node_off_chain(
+ const rtems_chain_node *node
+)
+{
+ return _Chain_Is_node_off_chain( node );
+}
+
+/**
+ * @brief Is the chain node pointer NULL.
+ *
+ * This function returns true if the_node is NULL and false otherwise.
+ *
+ * @param[in] the_node is the node pointer to check.
+ *
+ * @retval true The chain node pointer is NULL.
+ * @retval false The chain node pointer is not NULL.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_chain_is_null_node(
+ const rtems_chain_node *the_node
+)
+{
+ return _Chain_Is_null_node( the_node );
+}
+
+/**
+ * @brief Return pointer to Chain Head
+ *
+ * This function returns a pointer to the first node on the chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the permanent node of the chain.
+ */
+RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_head(
+ rtems_chain_control *the_chain
+)
+{
+ return _Chain_Head( the_chain );
+}
+
+/**
+ * @brief Return pointer to immutable Chain Head
+ *
+ * This function returns a pointer to the head node on the chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the permanent head node of the chain.
+ */
+RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_head(
+ const rtems_chain_control *the_chain
+)
+{
+ return _Chain_Immutable_head( the_chain );
+}
+
+/**
+ * @brief Return pointer to Chain Tail
+ *
+ * This function returns a pointer to the tail node on the chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the permanent tail node of the chain.
+ */
+RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_tail(
+ rtems_chain_control *the_chain
+)
+{
+ return _Chain_Tail( the_chain );
+}
+
+/**
+ * @brief Return pointer to immutable Chain Tail
+ *
+ * This function returns a pointer to the tail node on the chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the permanent tail node of the chain.
+ */
+RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_tail(
+ const rtems_chain_control *the_chain
+)
+{
+ return _Chain_Immutable_tail( the_chain );
+}
+
+/**
+ * @brief Return pointer to Chain's First node after the permanent head.
+ *
+ * This function returns a pointer to the first node on the chain after the
+ * head.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the first node of the chain.
+ */
+RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_first(
+ const rtems_chain_control *the_chain
+)
+{
+ return _Chain_First( the_chain );
+}
+
+/**
+ * @brief Return pointer to immutable Chain's First node
+ *
+ * This function returns a pointer to the first node on the chain after the
+ * head.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the first node of the chain.
+ */
+RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_first(
+ const rtems_chain_control *the_chain
+)
+{
+ return _Chain_Immutable_first( the_chain );
+}
+
+/**
+ * @brief Return pointer to Chain's Last node before the permanent tail.
+ *
+ * This function returns a pointer to the last node on the chain just before
+ * the tail.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the last node of the chain.
+ */
+RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_last(
+ const rtems_chain_control *the_chain
+)
+{
+ return _Chain_Last( the_chain );
+}
+
+/**
+ * @brief Return pointer to immutable Chain's Last node
+ *
+ * This function returns a pointer to the last node on the chain just before
+ * the tail.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the last node of the chain.
+ */
+RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_last(
+ const rtems_chain_control *the_chain
+)
+{
+ return _Chain_Immutable_last( the_chain );
+}
+
+/**
+ * @brief Return pointer the next node from this node
+ *
+ * This function returns a pointer to the next node after this node.
+ *
+ * @param[in] the_node is the node to be operated upon.
+ *
+ * @return This method returns the next node on the chain.
+ */
+RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_next(
+ const rtems_chain_node *the_node
+)
+{
+ return _Chain_Next( the_node );
+}
+
+/**
+ * @brief Return pointer the immutable next node from this node
+ *
+ * This function returns a pointer to the next node after this node.
+ *
+ * @param[in] the_node is the node to be operated upon.
+ *
+ * @return This method returns the next node on the chain.
+ */
+RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_next(
+ const rtems_chain_node *the_node
+)
+{
+ return _Chain_Immutable_next( the_node );
+}
+
+/**
+ * @brief Return pointer the previous node from this node
+ *
+ * This function returns a pointer to the previous node on this chain.
+ *
+ * @param[in] the_node is the node to be operated upon.
+ *
+ * @return This method returns the previous node on the chain.
+ */
+RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_previous(
+ const rtems_chain_node *the_node
+)
+{
+ return _Chain_Previous( the_node );
+}
+
+/**
+ * @brief Return pointer the immutable previous node from this node.
+ *
+ * This function returns a pointer to the previous node on this chain.
+ *
+ * @param[in] the_node is the node to be operated upon.
+ *
+ * @return This method returns the previous node on the chain.
+ */
+RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_previous(
+ const rtems_chain_node *the_node
+)
+{
+ return _Chain_Immutable_previous( the_node );
+}
+
+/**
+ * @brief Are Two nodes equal.
+ *
+ * This function returns true if @a left and @a right are equal,
+ * and false otherwise.
+ *
+ * @param[in] left is the node on the left hand side of the comparison.
+ * @param[in] right is the node on the left hand side of the comparison.
+ *
+ * @retval true @a left is equal to @a right.
+ * @retval false @a left is not equal to @a right
+ */
+RTEMS_INLINE_ROUTINE bool rtems_chain_are_nodes_equal(
+ const rtems_chain_node *left,
+ const rtems_chain_node *right
+)
+{
+ return _Chain_Are_nodes_equal( left, right );
+}
+
+/**
+ * @brief Is the chain empty
+ *
+ * This function returns true if there a no nodes on @a the_chain and
+ * false otherwise.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @retval true The chain is empty.
+ * @retval false The chain is not empty.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_chain_is_empty(
+ const rtems_chain_control *the_chain
+)
+{
+ return _Chain_Is_empty( the_chain );
+}
+
+/**
+ * @brief Is this the first node on the chain.
+ *
+ * This function returns true if the_node is the first node on a chain and
+ * false otherwise.
+ *
+ * @param[in] the_node is the node the caller wants to know if it is
+ * the first node on a chain.
+ *
+ * @retval true @a the_node is the first node on a chain.
+ * @retval false @a the_node is not the first node on a chain.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_chain_is_first(
+ const rtems_chain_node *the_node
+)
+{
+ return _Chain_Is_first( the_node );
+}
+
+/**
+ * @brief Is this the last node on the chain.
+ *
+ * This function returns true if @a the_node is the last node on a chain and
+ * false otherwise.
+ *
+ * @param[in] the_node is the node to check as the last node.
+ *
+ * @retval true @a the_node is the last node on a chain.
+ * @retval false @a the_node is not the last node on a chain
+ */
+RTEMS_INLINE_ROUTINE bool rtems_chain_is_last(
+ const rtems_chain_node *the_node
+)
+{
+ return _Chain_Is_last( the_node );
+}
+
+/**
+ * @brief Does this chain have only one node.
+ *
+ * This function returns true if there is only one node on @a the_chain and
+ * false otherwise.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @retval true The chain has only one node.
+ * @retval false The chain has more than one nodes.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_chain_has_only_one_node(
+ const rtems_chain_control *the_chain
+)
+{
+ return _Chain_Has_only_one_node( the_chain );
+}
+
+/**
+ * @brief Is this node the chain head.
+ *
+ * This function returns true if @a the_node is the head of the_chain and
+ * false otherwise.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ * @param[in] the_node is the node to check for being the Chain Head.
+ *
+ * @retval true @a the_node is the head of @a the_chain.
+ * @retval false @a the_node is not the head of @a the_chain.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_chain_is_head(
+ const rtems_chain_control *the_chain,
+ const rtems_chain_node *the_node
+)
+{
+ return _Chain_Is_head( the_chain, the_node );
+}
+
+/**
+ * @brief Is this node the chain tail.
+ *
+ * This function returns true if the_node is the tail of the_chain and
+ * false otherwise.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ * @param[in] the_node is the node to check for being the Chain Tail.
+ *
+ * @retval true @a the_node is the tail of @a the_chain.
+ * @retval false @a the_node is not the tail of @a the_chain.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_chain_is_tail(
+ const rtems_chain_control *the_chain,
+ const rtems_chain_node *the_node
+)
+{
+ return _Chain_Is_tail( the_chain, the_node );
+}
+
+/**
+ * @brief Extract the specified node from a chain.
+ *
+ * This routine extracts @a the_node from the chain on which it resides.
+ * It disables interrupts to ensure the atomicity of the
+ * extract operation.
+ *
+ * @arg the_node specifies the node to extract
+ */
+void rtems_chain_extract(
+ rtems_chain_node *the_node
+);
+
+/**
+ * @brief Extract the specified node from a chain (unprotected).
+ *
+ * This routine extracts @a the_node from the chain on which it resides.
+ *
+ * NOTE: It does NOT disable interrupts to ensure the atomicity of the
+ * append operation.
+ */
+RTEMS_INLINE_ROUTINE void rtems_chain_extract_unprotected(
+ rtems_chain_node *the_node
+)
+{
+ _Chain_Extract_unprotected( the_node );
+}
+
+/**
+ * @brief Obtain the first node on a chain.
+ *
+ * This function removes the first node from @a the_chain and returns
+ * a pointer to that node. If @a the_chain is empty, then NULL is returned.
+ *
+ * @return This method returns a pointer a node. If a node was removed,
+ * then a pointer to that node is returned. If @a the_chain was
+ * empty, then NULL is returned.
+ *
+ * NOTE: It disables interrupts to ensure the atomicity of the get operation.
+ */
+rtems_chain_node *rtems_chain_get(
+ rtems_chain_control *the_chain
+);
+
+/**
+ * @brief See _Chain_Get_unprotected().
+ */
+RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_get_unprotected(
+ rtems_chain_control *the_chain
+)
+{
+ return _Chain_Get_unprotected( the_chain );
+}
+
+/**
+ * @brief See _Chain_Get_first_unprotected().
+ */
+RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_get_first_unprotected(
+ rtems_chain_control *the_chain
+)
+{
+ return _Chain_Get_first_unprotected( the_chain );
+}
+
+/**
+ * @brief Insert a node on a chain
+ *
+ * This routine inserts @a the_node on a chain immediately following
+ * @a after_node.
+ *
+ * NOTE: It disables interrupts to ensure the atomicity
+ * of the extract operation.
+ */
+void rtems_chain_insert(
+ rtems_chain_node *after_node,
+ rtems_chain_node *the_node
+);
+
+/**
+ * @brief See _Chain_Insert_unprotected().
+ */
+RTEMS_INLINE_ROUTINE void rtems_chain_insert_unprotected(
+ rtems_chain_node *after_node,
+ rtems_chain_node *the_node
+)
+{
+ _Chain_Insert_unprotected( after_node, the_node );
+}
+
+/**
+ * @brief Append a node on the end of a chain.
+ *
+ * This routine appends @a the_node onto the end of @a the_chain.
+ *
+ * NOTE: It disables interrupts to ensure the atomicity of the
+ * append operation.
+ */
+void rtems_chain_append(
+ rtems_chain_control *the_chain,
+ rtems_chain_node *the_node
+);
+
+/**
+ * @brief Append a node on the end of a chain (unprotected).
+ *
+ * This routine appends @a the_node onto the end of @a the_chain.
+ *
+ * NOTE: It does NOT disable interrupts to ensure the atomicity of the
+ * append operation.
+ */
+RTEMS_INLINE_ROUTINE void rtems_chain_append_unprotected(
+ rtems_chain_control *the_chain,
+ rtems_chain_node *the_node
+)
+{
+ _Chain_Append_unprotected( the_chain, the_node );
+}
+
+/**
+ * @brief Prepend a node.
+ *
+ * This routine prepends the_node onto the front of the_chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ * @param[in] the_node is the node to be prepended.
+ *
+ * NOTE: It disables interrupts to ensure the atomicity of the
+ * prepend operation.
+ */
+void rtems_chain_prepend(
+ rtems_chain_control *the_chain,
+ rtems_chain_node *the_node
+);
+
+/**
+ * @brief Prepend a node (unprotected).
+ *
+ * This routine prepends the_node onto the front of the_chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ * @param[in] the_node is the node to be prepended.
+ *
+ * NOTE: It does NOT disable interrupts to ensure the atomicity of the
+ * prepend operation.
+ */
+RTEMS_INLINE_ROUTINE void rtems_chain_prepend_unprotected(
+ rtems_chain_control *the_chain,
+ rtems_chain_node *the_node
+)
+{
+ _Chain_Prepend_unprotected( the_chain, the_node );
+}
+
+/**
+ * @brief Checks if the @a chain is empty and appends the @a node.
+ *
+ * Interrupts are disabled to ensure the atomicity of the operation.
+ *
+ * @retval true The chain was empty before the append.
+ * @retval false The chain contained at least one node before the append.
+ */
+bool rtems_chain_append_with_empty_check(
+ rtems_chain_control *chain,
+ rtems_chain_node *node
+);
+
+/**
+ * @brief Checks if the @a chain is empty and prepends the @a node.
+ *
+ * Interrupts are disabled to ensure the atomicity of the operation.
+ *
+ * @retval true The chain was empty before the prepend.
+ * @retval false The chain contained at least one node before the prepend.
+ */
+bool rtems_chain_prepend_with_empty_check(
+ rtems_chain_control *chain,
+ rtems_chain_node *node
+);
+
+/**
+ * @brief Tries to get the first @a node and check if the @a chain is empty
+ * afterwards.
+ *
+ * This function removes the first node from the @a chain and returns a pointer
+ * to that node in @a node. If the @a chain is empty, then @c NULL is returned.
+ *
+ * Interrupts are disabled to ensure the atomicity of the operation.
+ *
+ * @retval true The chain is empty after the node removal.
+ * @retval false The chain contained at least one node after the node removal.
+ */
+bool rtems_chain_get_with_empty_check(
+ rtems_chain_control *chain,
+ rtems_chain_node **node
+);
+
+/**
+ * @brief Returns the node count of the chain.
+ *
+ * @param[in] chain The chain.
+ *
+ * @note It does NOT disable interrupts to ensure the atomicity of the
+ * operation.
+ *
+ * @return The node count of the chain.
+ */
+RTEMS_INLINE_ROUTINE size_t rtems_chain_node_count_unprotected(
+ const rtems_chain_control *chain
+)
+{
+ return _Chain_Node_count_unprotected( chain );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/confdefs.h b/cpukit/include/rtems/confdefs.h
new file mode 100755
index 0000000000..1c993dd099
--- /dev/null
+++ b/cpukit/include/rtems/confdefs.h
@@ -0,0 +1,3587 @@
+/**
+ * @file
+ *
+ * @brief Configuration Table Template that will be Instantiated
+ * by an Application
+ *
+ * This include file contains the configuration table template that will
+ * be instantiated by an application based on the setting of a number
+ * of macros. The macros are documented in the Configuring a System
+ * chapter of the Classic API User's Guide
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2015.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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 __CONFIGURATION_TEMPLATE_h
+#define __CONFIGURATION_TEMPLATE_h
+
+/*
+ * Include the executive's configuration
+ */
+#include <rtems.h>
+#include <rtems/ioimpl.h>
+#include <rtems/sysinit.h>
+#include <rtems/score/apimutex.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/userextimpl.h>
+#include <rtems/score/wkspace.h>
+
+#ifdef CONFIGURE_DISABLE_BSP_SETTINGS
+ #undef BSP_DEFAULT_UNIFIED_WORK_AREAS
+ #undef BSP_IDLE_TASK_BODY
+ #undef BSP_IDLE_TASK_STACK_SIZE
+ #undef BSP_INITIAL_EXTENSION
+ #undef BSP_INTERRUPT_STACK_SIZE
+ #undef BSP_MAXIMUM_DEVICES
+ #undef BSP_ZERO_WORKSPACE_AUTOMATICALLY
+ #undef CONFIGURE_BSP_PREREQUISITE_DRIVERS
+ #undef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK
+#else
+ #include <bsp.h>
+#endif
+
+#ifdef RTEMS_NEWLIB
+ #include <sys/reent.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Internal defines must be prefixed with _CONFIGURE to distinguish them from
+ * user-provided options which use a CONFIGURE prefix.
+ */
+
+/**
+ * @defgroup Configuration RTEMS Configuration
+ *
+ * This module contains all RTEMS Configuration parameters.
+ *
+ * The model is to estimate the memory required for each configured item
+ * and sum those estimates. The estimate can be too high or too low for
+ * a variety of reasons:
+ *
+ * Reasons estimate is too high:
+ * + FP contexts (not all tasks are FP)
+ *
+ * Reasons estimate is too low:
+ * + stacks greater than minimum size
+ * + messages
+ * + application must account for device driver resources
+ * + application must account for add-on library resource requirements
+ *
+ * NOTE: Eventually this may be able to take into account some of
+ * the above. This procedure has evolved from just enough to
+ * support the RTEMS Test Suites into something that can be
+ * used remarkably reliably by most applications.
+ */
+
+/**
+ * This is the Classic API initialization tasks table.
+ */
+extern rtems_initialization_tasks_table Initialization_tasks[];
+
+#if defined(RTEMS_MULTIPROCESSING)
+ /**
+ * This it the distributed multiprocessing configuration table.
+ */
+ extern rtems_multiprocessing_table Multiprocessing_configuration;
+#endif
+
+#ifdef RTEMS_POSIX_API
+ /**
+ * This it the POSIX API configuration table.
+ */
+ extern posix_api_configuration_table Configuration_POSIX_API;
+#endif
+
+/**
+ * This macro determines whether the RTEMS reentrancy support for
+ * the Newlib C Library is enabled.
+ */
+#ifdef RTEMS_SCHEDSIM
+ #undef RTEMS_NEWLIB
+#endif
+
+#if (defined(RTEMS_NEWLIB) && !defined(CONFIGURE_DISABLE_NEWLIB_REENTRANCY))
+ #define _CONFIGURE_NEWLIB_EXTENSION 1
+#else
+ #define _CONFIGURE_NEWLIB_EXTENSION 0
+#endif
+
+#ifndef RTEMS_SCHEDSIM
+#include <rtems/libio_.h>
+
+#ifdef CONFIGURE_INIT
+ #ifndef CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+ RTEMS_SYSINIT_ITEM(
+ rtems_filesystem_initialize,
+ RTEMS_SYSINIT_ROOT_FILESYSTEM,
+ RTEMS_SYSINIT_ORDER_MIDDLE
+ );
+ #endif
+#endif
+#endif
+
+/**
+ * This macro defines the number of POSIX file descriptors allocated
+ * and managed by libio. These are the "integer" file descriptors that
+ * are used by calls like open(2) and read(2).
+ */
+#ifndef CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS
+ #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 3
+#endif
+
+/*
+ * POSIX key count used by the IO library.
+ */
+#define _CONFIGURE_LIBIO_POSIX_KEYS 1
+
+#ifdef CONFIGURE_INIT
+ rtems_libio_t rtems_libio_iops[CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS];
+
+ /**
+ * When instantiating the configuration tables, this variable is
+ * initialized to specify the maximum number of file descriptors.
+ */
+ const uint32_t rtems_libio_number_iops = RTEMS_ARRAY_SIZE(rtems_libio_iops);
+#endif
+
+/*
+ * This macro determines if termios is disabled by this application.
+ * This only means that resources will not be reserved. If you end
+ * up using termios, it will fail.
+ */
+#ifdef CONFIGURE_TERMIOS_DISABLED
+ #define _CONFIGURE_TERMIOS_SEMAPHORES 0
+#else
+ /**
+ * This macro specifies the number of serial or PTY ports that will
+ * use termios.
+ */
+ #ifndef CONFIGURE_NUMBER_OF_TERMIOS_PORTS
+ #define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 1
+ #endif
+
+ /*
+ * This macro reserves the number of semaphores required by termios
+ * based upon the number of communication ports that will use it.
+ */
+ #define _CONFIGURE_TERMIOS_SEMAPHORES \
+ ((CONFIGURE_NUMBER_OF_TERMIOS_PORTS * 4) + 1)
+#endif
+
+/**
+ * This macro specifies the number of PTYs that can be concurrently
+ * active.
+ */
+#ifndef CONFIGURE_MAXIMUM_PTYS
+ #define CONFIGURE_MAXIMUM_PTYS 0
+#endif
+
+/**
+ * This variable contains the maximum number of PTYs that can be
+ * concurrently active.
+ */
+#ifdef CONFIGURE_INIT
+ int rtems_telnetd_maximum_ptys = CONFIGURE_MAXIMUM_PTYS;
+#else
+ extern int rtems_telnetd_maximum_ptys;
+#endif
+
+#ifdef CONFIGURE_SMP_MAXIMUM_PROCESSORS
+ #warning "CONFIGURE_SMP_MAXIMUM_PROCESSORS has been renamed to CONFIGURE_MAXIMUM_PROCESSORS since RTEMS 5.1"
+ #define CONFIGURE_MAXIMUM_PROCESSORS CONFIGURE_SMP_MAXIMUM_PROCESSORS
+#endif
+
+#ifndef CONFIGURE_MAXIMUM_PROCESSORS
+ #define CONFIGURE_MAXIMUM_PROCESSORS 1
+#endif
+
+/*
+ * An internal define to indicate that this is an SMP application
+ * configuration.
+ */
+#ifdef RTEMS_SMP
+ #if !defined(CONFIGURE_DISABLE_SMP_CONFIGURATION)
+ #define _CONFIGURE_SMP_APPLICATION
+ #elif CONFIGURE_MAXIMUM_PROCESSORS > 1
+ #error "CONFIGURE_DISABLE_SMP_CONFIGURATION and CONFIGURE_MAXIMUM_PROCESSORS > 1 makes no sense"
+ #endif
+#endif
+
+#ifdef CONFIGURE_SMP_APPLICATION
+ #warning "CONFIGURE_SMP_APPLICATION is obsolete since RTEMS 5.1"
+#endif
+
+/*
+ * This sets up the resources for the FIFOs/pipes.
+ */
+
+/**
+ * This is specified to configure the maximum number of POSIX FIFOs.
+ */
+#if !defined(CONFIGURE_MAXIMUM_FIFOS)
+ #define CONFIGURE_MAXIMUM_FIFOS 0
+#endif
+
+/**
+ * This is specified to configure the maximum number of POSIX named pipes.
+ */
+#if !defined(CONFIGURE_MAXIMUM_PIPES)
+ #define CONFIGURE_MAXIMUM_PIPES 0
+#endif
+
+/*
+ * This specifies the number of barriers required for the configured
+ * number of FIFOs and named pipes.
+ */
+#if CONFIGURE_MAXIMUM_FIFOS > 0 || CONFIGURE_MAXIMUM_PIPES > 0
+ #define _CONFIGURE_BARRIERS_FOR_FIFOS \
+ (2 * (CONFIGURE_MAXIMUM_FIFOS + CONFIGURE_MAXIMUM_PIPES))
+#else
+ #define _CONFIGURE_BARRIERS_FOR_FIFOS 0
+#endif
+
+/*
+ * This specifies the number of semaphores required for the configured
+ * number of FIFOs and named pipes.
+ */
+#if CONFIGURE_MAXIMUM_FIFOS > 0 || CONFIGURE_MAXIMUM_PIPES > 0
+ #define _CONFIGURE_SEMAPHORES_FOR_FIFOS \
+ (1 + (CONFIGURE_MAXIMUM_FIFOS + CONFIGURE_MAXIMUM_PIPES))
+#else
+ #define _CONFIGURE_SEMAPHORES_FOR_FIFOS 0
+#endif
+
+/**
+ * @defgroup ConfigFilesystems Filesystems and Mount Table Configuration
+ *
+ * @ingroup Configuration
+ *
+ * Defines to control the file system:
+ *
+ * - CONFIGURE_APPLICATION_DISABLE_FILESYSTEM:
+ * Disable the RTEMS filesystems. You get an empty DEVFS.
+ *
+ * - CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM:
+ * Use the DEVFS as the root file system. Limited functions are
+ * provided when this is used.
+ *
+ * - CONFIGURE_FILESYSTEM_ALL:
+ * Add file filesystems to the default filesystem table.
+ *
+ * List of available file systems. You can define as many as you like:
+ * - CONFIGURE_FILESYSTEM_IMFS - In Memory File System (IMFS)
+ * - CONFIGURE_FILESYSTEM_DEVFS - Device File System (DSVFS)
+ * - CONFIGURE_FILESYSTEM_TFTPFS - TFTP File System, networking enabled
+ * - CONFIGURE_FILESYSTEM_FTPFS - FTP File System, networking enabled
+ * - CONFIGURE_FILESYSTEM_NFS - Network File System, networking enabled
+ * - CONFIGURE_FILESYSTEM_DOSFS - DOS File System, uses libblock
+ * - CONFIGURE_FILESYSTEM_RFS - RTEMS File System (RFS), uses libblock
+ * - CONFIGURE_FILESYSTEM_JFFS2 - Journalling Flash File System, Version 2
+ *
+ * Combinations:
+ *
+ * - If nothing is defined the base file system is the IMFS.
+ *
+ * - If CONFIGURE_APPLICATION_DISABLE_FILESYSTEM is defined all filesystems
+ * are disabled by force.
+ *
+ * - If CONFIGURE_USE_DEV_AS_BASE_FILESYSTEM is defined all filesystems
+ * are disabled by force and DEVFS is defined.
+ */
+/**@{*/
+
+#ifdef CONFIGURE_INIT
+
+ /*
+ * Include all file systems. Do this before checking if the filesystem has
+ * been disabled.
+ */
+ #ifdef CONFIGURE_FILESYSTEM_ALL
+ #define CONFIGURE_FILESYSTEM_IMFS
+ #define CONFIGURE_FILESYSTEM_DEVFS
+ #define CONFIGURE_FILESYSTEM_TFTPFS
+ #define CONFIGURE_FILESYSTEM_FTPFS
+ #define CONFIGURE_FILESYSTEM_NFS
+ #define CONFIGURE_FILESYSTEM_DOSFS
+ #define CONFIGURE_FILESYSTEM_RFS
+ #define CONFIGURE_FILESYSTEM_JFFS2
+ #endif
+
+ /*
+ * If disabling the file system, give a compile error if the user has
+ * configured other filesystem parameters.
+ */
+ #if defined(CONFIGURE_APPLICATION_DISABLE_FILESYSTEM)
+ #if defined(CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM)
+ #error "Filesystem disabled and a base filesystem configured."
+ #endif
+
+ #if defined(CONFIGURE_FILESYSTEM_IMFS) || \
+ defined(CONFIGURE_FILESYSTEM_DEVFS) || \
+ defined(CONFIGURE_FILESYSTEM_TFTPFS) || \
+ defined(CONFIGURE_FILESYSTEM_FTPFS) || \
+ defined(CONFIGURE_FILESYSTEM_NFS) || \
+ defined(CONFIGURE_FILESYSTEM_DOSFS) || \
+ defined(CONFIGURE_FILESYSTEM_RFS) || \
+ defined(CONFIGURE_FILESYSTEM_JFFS2)
+ #error "Filesystem disabled and a filesystem configured."
+ #endif
+ #endif
+
+ /*
+ * If the base filesystem is DEVFS define it else define IMFS.
+ * We will have either DEVFS or IMFS defined after this.
+ */
+ #if !defined(CONFIGURE_APPLICATION_DISABLE_FILESYSTEM)
+ #if defined(CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM)
+ #define CONFIGURE_FILESYSTEM_DEVFS
+ #endif
+ #endif
+
+#endif
+
+#ifndef RTEMS_SCHEDSIM
+/**
+ * IMFS
+ */
+#include <rtems/imfs.h>
+
+/**
+ * This specifies the number of bytes per block for files within the IMFS.
+ * There are a maximum number of blocks per file so this dictates the maximum
+ * size of a file. This has to be balanced with the unused portion of each
+ * block that might be wasted.
+ */
+#ifndef CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK
+ #define CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK \
+ IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK
+#endif
+
+/**
+ * This defines the IMFS file system table entry.
+ */
+#if !defined(CONFIGURE_FILESYSTEM_ENTRY_IMFS) && \
+ defined(CONFIGURE_FILESYSTEM_IMFS)
+ #define CONFIGURE_FILESYSTEM_ENTRY_IMFS \
+ { RTEMS_FILESYSTEM_TYPE_IMFS, IMFS_initialize }
+#endif
+#endif
+
+#ifdef CONFIGURE_USE_MINIIMFS_AS_BASE_FILESYSTEM
+ #define CONFIGURE_IMFS_DISABLE_CHMOD
+ #define CONFIGURE_IMFS_DISABLE_CHOWN
+ #define CONFIGURE_IMFS_DISABLE_UTIME
+ #define CONFIGURE_IMFS_DISABLE_LINK
+ #define CONFIGURE_IMFS_DISABLE_SYMLINK
+ #define CONFIGURE_IMFS_DISABLE_READLINK
+ #define CONFIGURE_IMFS_DISABLE_RENAME
+ #define CONFIGURE_IMFS_DISABLE_UNMOUNT
+#endif
+
+/**
+ * DEVFS
+ */
+#if !defined(CONFIGURE_FILESYSTEM_ENTRY_DEVFS) && \
+ defined(CONFIGURE_FILESYSTEM_DEVFS)
+#include <rtems/devfs.h>
+ #define CONFIGURE_FILESYSTEM_ENTRY_DEVFS \
+ { RTEMS_FILESYSTEM_TYPE_DEVFS, devFS_initialize }
+#endif
+
+/**
+ * FTPFS
+ */
+#if !defined(CONFIGURE_FILESYSTEM_ENTRY_FTPFS) && \
+ defined(CONFIGURE_FILESYSTEM_FTPFS)
+ #include <rtems/ftpfs.h>
+ #define CONFIGURE_FILESYSTEM_ENTRY_FTPFS \
+ { RTEMS_FILESYSTEM_TYPE_FTPFS, rtems_ftpfs_initialize }
+#endif
+
+/**
+ * TFTPFS
+ */
+#if !defined(CONFIGURE_FILESYSTEM_ENTRY_TFTPFS) && \
+ defined(CONFIGURE_FILESYSTEM_TFTPFS)
+ #include <rtems/tftp.h>
+ #define CONFIGURE_FILESYSTEM_ENTRY_TFTPFS \
+ { RTEMS_FILESYSTEM_TYPE_TFTPFS, rtems_tftpfs_initialize }
+#endif
+
+/**
+ * NFS
+ */
+#if !defined(CONFIGURE_FILESYSTEM_ENTRY_NFS) && \
+ defined(CONFIGURE_FILESYSTEM_NFS)
+ #include <librtemsNfs.h>
+ #if !defined(CONFIGURE_MAXIMUM_NFS_MOUNTS)
+ #define CONFIGURE_MAXIMUM_NFS_MOUNTS 1
+ #endif
+ #define CONFIGURE_FILESYSTEM_ENTRY_NFS \
+ { RTEMS_FILESYSTEM_TYPE_NFS, rtems_nfs_initialize }
+ #define _CONFIGURE_SEMAPHORES_FOR_NFS ((CONFIGURE_MAXIMUM_NFS_MOUNTS * 2) + 1)
+#else
+ #define _CONFIGURE_SEMAPHORES_FOR_NFS 0
+#endif
+
+/**
+ * DOSFS
+ */
+#if !defined(CONFIGURE_FILESYSTEM_ENTRY_DOSFS) && \
+ defined(CONFIGURE_FILESYSTEM_DOSFS)
+ #include <rtems/dosfs.h>
+ #if !defined(CONFIGURE_MAXIMUM_DOSFS_MOUNTS)
+ #define CONFIGURE_MAXIMUM_DOSFS_MOUNTS 1
+ #endif
+ #define CONFIGURE_FILESYSTEM_ENTRY_DOSFS \
+ { RTEMS_FILESYSTEM_TYPE_DOSFS, rtems_dosfs_initialize }
+ #define _CONFIGURE_SEMAPHORES_FOR_DOSFS CONFIGURE_MAXIMUM_DOSFS_MOUNTS
+#else
+ #define _CONFIGURE_SEMAPHORES_FOR_DOSFS 0
+#endif
+
+/**
+ * RFS
+ */
+#if !defined(CONFIGURE_FILESYSTEM_ENTRY_RFS) && \
+ defined(CONFIGURE_FILESYSTEM_RFS)
+ #include <rtems/rtems-rfs.h>
+ #if !defined(CONFIGURE_MAXIMUM_RFS_MOUNTS)
+ #define CONFIGURE_MAXIMUM_RFS_MOUNTS 1
+ #endif
+ #define CONFIGURE_FILESYSTEM_ENTRY_RFS \
+ { RTEMS_FILESYSTEM_TYPE_RFS, rtems_rfs_rtems_initialise }
+ #define _CONFIGURE_SEMAPHORES_FOR_RFS CONFIGURE_MAXIMUM_RFS_MOUNTS
+#else
+ #define _CONFIGURE_SEMAPHORES_FOR_RFS 0
+#endif
+
+/**
+ * JFFS2
+ */
+#if !defined(CONFIGURE_FILESYSTEM_ENTRY_JFFS2) && \
+ defined(CONFIGURE_FILESYSTEM_JFFS2)
+ #include <rtems/jffs2.h>
+ #if !defined(CONFIGURE_MAXIMUM_JFFS2_MOUNTS)
+ #define CONFIGURE_MAXIMUM_JFFS2_MOUNTS 1
+ #endif
+ #define CONFIGURE_FILESYSTEM_ENTRY_JFFS2 \
+ { RTEMS_FILESYSTEM_TYPE_JFFS2, rtems_jffs2_initialize }
+ #define _CONFIGURE_SEMAPHORES_FOR_JFFS2 CONFIGURE_MAXIMUM_JFFS2_MOUNTS
+#else
+ #define _CONFIGURE_SEMAPHORES_FOR_JFFS2 0
+#endif
+
+/**
+ * This computes the number of semaphores required for the various
+ * file systems including the FIFO plugin to the IMFS.
+ */
+#define _CONFIGURE_SEMAPHORES_FOR_FILE_SYSTEMS \
+ (_CONFIGURE_SEMAPHORES_FOR_FIFOS + \
+ _CONFIGURE_SEMAPHORES_FOR_NFS + \
+ _CONFIGURE_SEMAPHORES_FOR_DOSFS + \
+ _CONFIGURE_SEMAPHORES_FOR_RFS + \
+ _CONFIGURE_SEMAPHORES_FOR_JFFS2)
+
+#ifdef CONFIGURE_INIT
+
+ /**
+ * DEVFS variables.
+ *
+ * The number of individual devices that may be registered
+ * in the system or the CONFIGURE_MAXIMUM_DEVICES variable
+ * is defaulted to 4 when a filesystem is enabled, unless
+ * the bsp overwrides this. In which case the value is set
+ * to BSP_MAXIMUM_DEVICES.
+ */
+ #ifdef CONFIGURE_FILESYSTEM_DEVFS
+ #ifndef CONFIGURE_MAXIMUM_DEVICES
+ #if defined(BSP_MAXIMUM_DEVICES)
+ #define CONFIGURE_MAXIMUM_DEVICES BSP_MAXIMUM_DEVICES
+ #else
+ #define CONFIGURE_MAXIMUM_DEVICES 4
+ #endif
+ #endif
+ #include <rtems/devfs.h>
+ #endif
+
+ /**
+ * Table termination record.
+ */
+ #define CONFIGURE_FILESYSTEM_NULL { NULL, NULL }
+
+#ifndef RTEMS_SCHEDSIM
+ #if !defined(CONFIGURE_APPLICATION_DISABLE_FILESYSTEM) && \
+ !defined(CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM)
+ int imfs_rq_memfile_bytes_per_block =
+ CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK;
+ #endif
+
+ /**
+ * The default file system table. Must be terminated with the NULL entry if
+ * you provide your own.
+ */
+ #if !defined(CONFIGURE_HAS_OWN_FILESYSTEM_TABLE) && \
+ !defined(CONFIGURE_APPLICATION_DISABLE_FILESYSTEM)
+ const rtems_filesystem_table_t rtems_filesystem_table[] = {
+ #if !defined(CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM)
+ { "/", IMFS_initialize_support },
+ #endif
+ #if defined(CONFIGURE_FILESYSTEM_IMFS) && \
+ defined(CONFIGURE_FILESYSTEM_ENTRY_IMFS)
+ CONFIGURE_FILESYSTEM_ENTRY_IMFS,
+ #endif
+ #if defined(CONFIGURE_FILESYSTEM_DEVFS) && \
+ defined(CONFIGURE_FILESYSTEM_ENTRY_DEVFS)
+ CONFIGURE_FILESYSTEM_ENTRY_DEVFS,
+ #endif
+ #if defined(CONFIGURE_FILESYSTEM_TFTPFS) && \
+ defined(CONFIGURE_FILESYSTEM_ENTRY_TFTPFS)
+ CONFIGURE_FILESYSTEM_ENTRY_TFTPFS,
+ #endif
+ #if defined(CONFIGURE_FILESYSTEM_FTPFS) && \
+ defined(CONFIGURE_FILESYSTEM_ENTRY_FTPFS)
+ CONFIGURE_FILESYSTEM_ENTRY_FTPFS,
+ #endif
+ #if defined(CONFIGURE_FILESYSTEM_NFS) && \
+ defined(CONFIGURE_FILESYSTEM_ENTRY_NFS)
+ CONFIGURE_FILESYSTEM_ENTRY_NFS,
+ #endif
+ #if defined(CONFIGURE_FILESYSTEM_DOSFS) && \
+ defined(CONFIGURE_FILESYSTEM_ENTRY_DOSFS)
+ CONFIGURE_FILESYSTEM_ENTRY_DOSFS,
+ #endif
+ #if defined(CONFIGURE_FILESYSTEM_RFS) && \
+ defined(CONFIGURE_FILESYSTEM_ENTRY_RFS)
+ CONFIGURE_FILESYSTEM_ENTRY_RFS,
+ #endif
+ #if defined(CONFIGURE_FILESYSTEM_JFFS2) && \
+ defined(CONFIGURE_FILESYSTEM_ENTRY_JFFS2)
+ CONFIGURE_FILESYSTEM_ENTRY_JFFS2,
+ #endif
+ CONFIGURE_FILESYSTEM_NULL
+ };
+ #endif
+
+ #if !defined(CONFIGURE_HAS_OWN_MOUNT_TABLE) && \
+ !defined(CONFIGURE_APPLICATION_DISABLE_FILESYSTEM)
+ #if defined(CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM)
+ static devFS_node devFS_root_filesystem_nodes [CONFIGURE_MAXIMUM_DEVICES];
+ static const devFS_data devFS_root_filesystem_data = {
+ devFS_root_filesystem_nodes,
+ CONFIGURE_MAXIMUM_DEVICES
+ };
+ #else
+ static IMFS_fs_info_t _Configure_IMFS_fs_info;
+
+ static const rtems_filesystem_operations_table _Configure_IMFS_ops = {
+ rtems_filesystem_default_lock,
+ rtems_filesystem_default_unlock,
+ IMFS_eval_path,
+ #ifdef CONFIGURE_IMFS_DISABLE_LINK
+ rtems_filesystem_default_link,
+ #else
+ IMFS_link,
+ #endif
+ rtems_filesystem_default_are_nodes_equal,
+ #ifdef CONFIGURE_IMFS_DISABLE_MKNOD
+ rtems_filesystem_default_mknod,
+ #else
+ IMFS_mknod,
+ #endif
+ #ifdef CONFIGURE_IMFS_DISABLE_RMNOD
+ rtems_filesystem_default_rmnod,
+ #else
+ IMFS_rmnod,
+ #endif
+ #ifdef CONFIGURE_IMFS_DISABLE_CHMOD
+ rtems_filesystem_default_fchmod,
+ #else
+ IMFS_fchmod,
+ #endif
+ #ifdef CONFIGURE_IMFS_DISABLE_CHOWN
+ rtems_filesystem_default_chown,
+ #else
+ IMFS_chown,
+ #endif
+ IMFS_node_clone,
+ IMFS_node_free,
+ #ifdef CONFIGURE_IMFS_DISABLE_MOUNT
+ rtems_filesystem_default_mount,
+ #else
+ IMFS_mount,
+ #endif
+ #ifdef CONFIGURE_IMFS_DISABLE_UNMOUNT
+ rtems_filesystem_default_unmount,
+ #else
+ IMFS_unmount,
+ #endif
+ rtems_filesystem_default_fsunmount,
+ #ifdef CONFIGURE_IMFS_DISABLE_UTIME
+ rtems_filesystem_default_utime,
+ #else
+ IMFS_utime,
+ #endif
+ #ifdef CONFIGURE_IMFS_DISABLE_SYMLINK
+ rtems_filesystem_default_symlink,
+ #else
+ IMFS_symlink,
+ #endif
+ #ifdef CONFIGURE_IMFS_DISABLE_READLINK
+ rtems_filesystem_default_readlink,
+ #else
+ IMFS_readlink,
+ #endif
+ #ifdef CONFIGURE_IMFS_DISABLE_RENAME
+ rtems_filesystem_default_rename,
+ #else
+ IMFS_rename,
+ #endif
+ rtems_filesystem_default_statvfs
+ };
+
+ static const IMFS_mknod_controls _Configure_IMFS_mknod_controls = {
+ #ifdef CONFIGURE_IMFS_DISABLE_READDIR
+ &IMFS_mknod_control_dir_minimal,
+ #else
+ &IMFS_mknod_control_dir_default,
+ #endif
+ &IMFS_mknod_control_device,
+ #ifdef CONFIGURE_IMFS_DISABLE_MKNOD_FILE
+ &IMFS_mknod_control_enosys,
+ #else
+ &IMFS_mknod_control_memfile,
+ #endif
+ #if CONFIGURE_MAXIMUM_FIFOS > 0 || CONFIGURE_MAXIMUM_PIPES > 0
+ &IMFS_mknod_control_fifo
+ #else
+ &IMFS_mknod_control_enosys
+ #endif
+ };
+
+ static const IMFS_mount_data _Configure_IMFS_mount_data = {
+ &_Configure_IMFS_fs_info,
+ &_Configure_IMFS_ops,
+ &_Configure_IMFS_mknod_controls
+ };
+ #endif
+
+ const rtems_filesystem_mount_configuration
+ rtems_filesystem_root_configuration = {
+ NULL,
+ NULL,
+ #if defined(CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM)
+ RTEMS_FILESYSTEM_TYPE_DEVFS,
+ #else
+ "/",
+ #endif
+ RTEMS_FILESYSTEM_READ_WRITE,
+ #if defined(CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM)
+ &devFS_root_filesystem_data
+ #else
+ &_Configure_IMFS_mount_data
+ #endif
+ };
+ #endif
+
+#endif
+#endif
+/**@}*/ /* end of file system group */
+
+/*
+ * STACK_CHECKER_ON was still available in 4.9 so give a warning for now.
+ */
+#if defined(STACK_CHECKER_ON)
+ #define CONFIGURE_STACK_CHECKER_ENABLED
+ #warning "STACK_CHECKER_ON deprecated -- use CONFIGURE_STACK_CHECKER_ENABLED"
+#endif
+
+/**
+ * This configures the stack checker user extension.
+ */
+#ifdef CONFIGURE_STACK_CHECKER_ENABLED
+ #define _CONFIGURE_STACK_CHECKER_EXTENSION 1
+#else
+ #define _CONFIGURE_STACK_CHECKER_EXTENSION 0
+#endif
+
+/**
+ * @brief Maximum priority configuration.
+ *
+ * This configures the maximum priority value that
+ * a task may have.
+ *
+ * The following applies to the data space requirements
+ * of the Priority Scheduler.
+ *
+ * By reducing the number of priorities in a system,
+ * the amount of RAM required by RTEMS can be significantly
+ * reduced. RTEMS allocates a Chain_Control structure per
+ * priority and this structure contains 3 pointers. So
+ * the default is (256 * 12) = 3K on 32-bit architectures.
+ *
+ * This must be one less than a power of 2 between
+ * 4 and 256. Valid values along with the application
+ * priority levels and memory saved when pointers are
+ * 32-bits in size are:
+ *
+ * + 3, 2 application priorities, 3024 bytes saved
+ * + 7, 5 application priorities, 2976 bytes saved
+ * + 15, 13 application priorities, 2880 bytes saved
+ * + 31, 29 application priorities, 2688 bytes saved
+ * + 63, 61 application priorities, 2304 bytes saved
+ * + 127, 125 application priorities, 1536 bytes saved
+ * + 255, 253 application priorities, 0 bytes saved
+ *
+ * It is specified in terms of Classic API priority values.
+ */
+#ifndef CONFIGURE_MAXIMUM_PRIORITY
+ #define CONFIGURE_MAXIMUM_PRIORITY PRIORITY_DEFAULT_MAXIMUM
+#endif
+
+/**
+ * @defgroup ConfigScheduler Scheduler configuration
+ *
+ * @ingroup Configuration
+ *
+ * The scheduler configuration allows an application to select the
+ * scheduling policy to use. The supported configurations are:
+ *
+ * - CONFIGURE_SCHEDULER_PRIORITY - Deterministic Priority Scheduler
+ * - CONFIGURE_SCHEDULER_PRIORITY_SMP - Deterministic Priority SMP Scheduler
+ * - CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP - Deterministic
+ * Priority SMP Affinity Scheduler
+ * - CONFIGURE_SCHEDULER_STRONG_APA - Strong APA Scheduler
+ * - CONFIGURE_SCHEDULER_SIMPLE - Light-weight Priority Scheduler
+ * - CONFIGURE_SCHEDULER_SIMPLE_SMP - Simple SMP Priority Scheduler
+ * - CONFIGURE_SCHEDULER_EDF - EDF Scheduler
+ * - CONFIGURE_SCHEDULER_EDF_SMP - EDF SMP Scheduler
+ * - CONFIGURE_SCHEDULER_CBS - CBS Scheduler
+ * - CONFIGURE_SCHEDULER_USER - user provided scheduler
+ *
+ * If no configuration is specified by the application in a uniprocessor
+ * configuration, then CONFIGURE_SCHEDULER_PRIORITY is the default.
+ *
+ * If no configuration is specified by the application in SMP
+ * configuration, then CONFIGURE_SCHEDULER_PRIORITY_SMP is the default.
+ *
+ * An application can define its own scheduling policy by defining
+ * CONFIGURE_SCHEDULER_USER and the following:
+ *
+ * - CONFIGURE_SCHEDULER_CONTEXT
+ * - CONFIGURE_SCHEDULER_CONTROLS
+ * - CONFIGURE_SCHEDULER_USER_PER_THREAD
+ */
+
+#if !defined(CONFIGURE_SCHEDULER_USER) && \
+ !defined(CONFIGURE_SCHEDULER_PRIORITY) && \
+ !defined(CONFIGURE_SCHEDULER_PRIORITY_SMP) && \
+ !defined(CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP) && \
+ !defined(CONFIGURE_SCHEDULER_STRONG_APA) && \
+ !defined(CONFIGURE_SCHEDULER_SIMPLE) && \
+ !defined(CONFIGURE_SCHEDULER_SIMPLE_SMP) && \
+ !defined(CONFIGURE_SCHEDULER_EDF) && \
+ !defined(CONFIGURE_SCHEDULER_EDF_SMP) && \
+ !defined(CONFIGURE_SCHEDULER_CBS)
+ #if defined(RTEMS_SMP) && CONFIGURE_MAXIMUM_PROCESSORS > 1
+ /**
+ * If no scheduler is specified in an SMP configuration, the
+ * EDF scheduler is default.
+ */
+ #define CONFIGURE_SCHEDULER_EDF_SMP
+ #else
+ /**
+ * If no scheduler is specified in a uniprocessor configuration, the
+ * priority scheduler is default.
+ */
+ #define CONFIGURE_SCHEDULER_PRIORITY
+ #endif
+#endif
+
+#include <rtems/scheduler.h>
+
+/*
+ * If the Priority Scheduler is selected, then configure for it.
+ */
+#if defined(CONFIGURE_SCHEDULER_PRIORITY)
+ #if !defined(CONFIGURE_SCHEDULER_NAME)
+ /** Configure the name of the scheduler instance */
+ #define CONFIGURE_SCHEDULER_NAME rtems_build_name('U', 'P', 'D', ' ')
+ #endif
+
+ #if !defined(CONFIGURE_SCHEDULER_CONTROLS)
+ /** Configure the context needed by the scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTEXT \
+ RTEMS_SCHEDULER_CONTEXT_PRIORITY( \
+ dflt, \
+ CONFIGURE_MAXIMUM_PRIORITY + 1 \
+ )
+
+ /** Configure the controls for this scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTROLS \
+ RTEMS_SCHEDULER_CONTROL_PRIORITY(dflt, CONFIGURE_SCHEDULER_NAME)
+ #endif
+#endif
+
+/*
+ * If the Deterministic Priority SMP Scheduler is selected, then configure for
+ * it.
+ */
+#if defined(CONFIGURE_SCHEDULER_PRIORITY_SMP)
+ #if !defined(CONFIGURE_SCHEDULER_NAME)
+ /** Configure the name of the scheduler instance */
+ #define CONFIGURE_SCHEDULER_NAME rtems_build_name('M', 'P', 'D', ' ')
+ #endif
+
+ #if !defined(CONFIGURE_SCHEDULER_CONTROLS)
+ /** Configure the context needed by the scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTEXT \
+ RTEMS_SCHEDULER_CONTEXT_PRIORITY_SMP( \
+ dflt, \
+ CONFIGURE_MAXIMUM_PRIORITY + 1 \
+ )
+
+ /** Configure the controls for this scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTROLS \
+ RTEMS_SCHEDULER_CONTROL_PRIORITY_SMP(dflt, CONFIGURE_SCHEDULER_NAME)
+ #endif
+#endif
+
+/*
+ * If the Deterministic Priority Affinity SMP Scheduler is selected, then configure for
+ * it.
+ */
+#if defined(CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP)
+ #if !defined(CONFIGURE_SCHEDULER_NAME)
+ /** Configure the name of the scheduler instance */
+ #define CONFIGURE_SCHEDULER_NAME rtems_build_name('M', 'P', 'A', ' ')
+ #endif
+
+ #if !defined(CONFIGURE_SCHEDULER_CONTROLS)
+ /** Configure the context needed by the scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTEXT \
+ RTEMS_SCHEDULER_CONTEXT_PRIORITY_AFFINITY_SMP( \
+ dflt, \
+ CONFIGURE_MAXIMUM_PRIORITY + 1 \
+ )
+
+ /** Configure the controls for this scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTROLS \
+ RTEMS_SCHEDULER_CONTROL_PRIORITY_AFFINITY_SMP( \
+ dflt, \
+ CONFIGURE_SCHEDULER_NAME \
+ )
+ #endif
+#endif
+
+/*
+ * If the Strong APA Scheduler is selected, then configure for
+ * it.
+ */
+#if defined(CONFIGURE_SCHEDULER_STRONG_APA)
+ #if !defined(CONFIGURE_SCHEDULER_NAME)
+ /** Configure the name of the scheduler instance */
+ #define CONFIGURE_SCHEDULER_NAME rtems_build_name('M', 'A', 'P', 'A')
+ #endif
+
+ #if !defined(CONFIGURE_SCHEDULER_CONTROLS)
+ /** Configure the context needed by the scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTEXT \
+ RTEMS_SCHEDULER_CONTEXT_STRONG_APA( \
+ dflt, \
+ CONFIGURE_MAXIMUM_PRIORITY + 1 \
+ )
+
+ /** Configure the controls for this scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTROLS \
+ RTEMS_SCHEDULER_CONTROL_STRONG_APA(dflt, CONFIGURE_SCHEDULER_NAME)
+ #endif
+#endif
+
+/*
+ * If the Simple Priority Scheduler is selected, then configure for it.
+ */
+#if defined(CONFIGURE_SCHEDULER_SIMPLE)
+ #if !defined(CONFIGURE_SCHEDULER_NAME)
+ /** Configure the name of the scheduler instance */
+ #define CONFIGURE_SCHEDULER_NAME rtems_build_name('U', 'P', 'S', ' ')
+ #endif
+
+ #if !defined(CONFIGURE_SCHEDULER_CONTROLS)
+ /** Configure the context needed by the scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTEXT RTEMS_SCHEDULER_CONTEXT_SIMPLE(dflt)
+
+ /** Configure the controls for this scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTROLS \
+ RTEMS_SCHEDULER_CONTROL_SIMPLE(dflt, CONFIGURE_SCHEDULER_NAME)
+ #endif
+#endif
+
+/*
+ * If the Simple SMP Priority Scheduler is selected, then configure for it.
+ */
+#if defined(CONFIGURE_SCHEDULER_SIMPLE_SMP)
+ #if !defined(CONFIGURE_SCHEDULER_NAME)
+ /** Configure the name of the scheduler instance */
+ #define CONFIGURE_SCHEDULER_NAME rtems_build_name('M', 'P', 'S', ' ')
+ #endif
+
+ #if !defined(CONFIGURE_SCHEDULER_CONTROLS)
+ /** Configure the context needed by the scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTEXT \
+ RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(dflt)
+
+ /** Configure the controls for this scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTROLS \
+ RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(dflt, CONFIGURE_SCHEDULER_NAME)
+ #endif
+#endif
+
+/*
+ * If the EDF Scheduler is selected, then configure for it.
+ */
+#if defined(CONFIGURE_SCHEDULER_EDF)
+ #if !defined(CONFIGURE_SCHEDULER_NAME)
+ /** Configure the name of the scheduler instance */
+ #define CONFIGURE_SCHEDULER_NAME rtems_build_name('U', 'E', 'D', 'F')
+ #endif
+
+ #if !defined(CONFIGURE_SCHEDULER_CONTROLS)
+ /** Configure the context needed by the scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTEXT RTEMS_SCHEDULER_CONTEXT_EDF(dflt)
+
+ /** Configure the controls for this scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTROLS \
+ RTEMS_SCHEDULER_CONTROL_EDF(dflt, CONFIGURE_SCHEDULER_NAME)
+ #endif
+#endif
+
+/*
+ * If the EDF SMP Scheduler is selected, then configure for it.
+ */
+#if defined(CONFIGURE_SCHEDULER_EDF_SMP)
+ #if !defined(CONFIGURE_SCHEDULER_NAME)
+ /** Configure the name of the scheduler instance */
+ #define CONFIGURE_SCHEDULER_NAME rtems_build_name('M', 'E', 'D', 'F')
+ #endif
+
+ #if !defined(CONFIGURE_SCHEDULER_CONTROLS)
+ /** Configure the context needed by the scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTEXT \
+ RTEMS_SCHEDULER_CONTEXT_EDF_SMP(dflt, CONFIGURE_MAXIMUM_PROCESSORS)
+
+ /** Configure the controls for this scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTROLS \
+ RTEMS_SCHEDULER_CONTROL_EDF_SMP(dflt, CONFIGURE_SCHEDULER_NAME)
+ #endif
+#endif
+
+/*
+ * If the CBS Scheduler is selected, then configure for it.
+ */
+#if defined(CONFIGURE_SCHEDULER_CBS)
+ #if !defined(CONFIGURE_SCHEDULER_NAME)
+ /** Configure the name of the scheduler instance */
+ #define CONFIGURE_SCHEDULER_NAME rtems_build_name('U', 'C', 'B', 'S')
+ #endif
+
+ #if !defined(CONFIGURE_SCHEDULER_CONTROLS)
+ /** Configure the context needed by the scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTEXT RTEMS_SCHEDULER_CONTEXT_CBS(dflt)
+
+ /** Configure the controls for this scheduler instance */
+ #define CONFIGURE_SCHEDULER_CONTROLS \
+ RTEMS_SCHEDULER_CONTROL_CBS(dflt, CONFIGURE_SCHEDULER_NAME)
+ #endif
+
+ #ifndef CONFIGURE_CBS_MAXIMUM_SERVERS
+ #define CONFIGURE_CBS_MAXIMUM_SERVERS CONFIGURE_MAXIMUM_TASKS
+ #endif
+
+ #ifdef CONFIGURE_INIT
+ const uint32_t _Scheduler_CBS_Maximum_servers =
+ CONFIGURE_CBS_MAXIMUM_SERVERS;
+
+ Scheduler_CBS_Server
+ _Scheduler_CBS_Server_list[ CONFIGURE_CBS_MAXIMUM_SERVERS ];
+ #endif
+#endif
+
+/*
+ * Set up the scheduler entry points table. The scheduling code uses
+ * this code to know which scheduler is configured by the user.
+ */
+#ifdef CONFIGURE_INIT
+ #if defined(CONFIGURE_SCHEDULER_CONTEXT)
+ CONFIGURE_SCHEDULER_CONTEXT;
+ #endif
+
+ const Scheduler_Control _Scheduler_Table[] = {
+ CONFIGURE_SCHEDULER_CONTROLS
+ };
+
+ #define CONFIGURE_SCHEDULER_COUNT RTEMS_ARRAY_SIZE( _Scheduler_Table )
+
+ #if defined(RTEMS_SMP)
+ const size_t _Scheduler_Count = CONFIGURE_SCHEDULER_COUNT;
+
+ const Scheduler_Assignment _Scheduler_Initial_assignments[] = {
+ #if defined(CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS)
+ CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS
+ #else
+ #define _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT \
+ RTEMS_SCHEDULER_ASSIGN( \
+ 0, \
+ RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL \
+ )
+ _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 2
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 3
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 4
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 5
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 6
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 7
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 8
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 9
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 10
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 11
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 12
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 13
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 14
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 15
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 16
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 17
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 18
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 19
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 20
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 21
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 22
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 23
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 24
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 25
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 26
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 27
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 28
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 29
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 30
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 31
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #if CONFIGURE_MAXIMUM_PROCESSORS >= 32
+ , _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ #undef _CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
+ #endif
+ };
+
+ RTEMS_STATIC_ASSERT(
+ CONFIGURE_MAXIMUM_PROCESSORS
+ == RTEMS_ARRAY_SIZE( _Scheduler_Initial_assignments ),
+ _Scheduler_Initial_assignments
+ );
+ #endif
+#endif
+/**@}*/ /* end of Scheduler Configuration */
+
+/**
+ * @defgroup ConfigurationIdle IDLE Thread Configuration
+ *
+ * @addtogroup Configuration
+ *
+ * This module contains configuration parameters related to the
+ * set of IDLE threads. On a uniprocessor system, there is one
+ * IDLE thread. On an SMP system, there is one for each core.
+ */
+
+/*
+ * If you said the IDLE task was going to do application initialization
+ * and didn't override the IDLE body, then something is amiss.
+ */
+#if (defined(CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION) && \
+ !defined(CONFIGURE_IDLE_TASK_BODY))
+ #error "CONFIGURE_ERROR: You did not override the IDLE task body."
+#endif
+
+/**
+ * @brief Idle task body configuration.
+ *
+ * There is a default IDLE thread body provided by RTEMS which
+ * has the possibility of being CPU specific. There may be a
+ * BSP specific override of the RTEMS default body and in turn,
+ * the application may override and provide its own.
+ */
+#ifndef CONFIGURE_IDLE_TASK_BODY
+ #if defined(BSP_IDLE_TASK_BODY)
+ #define CONFIGURE_IDLE_TASK_BODY BSP_IDLE_TASK_BODY
+ #elif (CPU_PROVIDES_IDLE_THREAD_BODY == TRUE)
+ #define CONFIGURE_IDLE_TASK_BODY _CPU_Thread_Idle_body
+ #else
+ /* only instantiate and compile if used */
+ #ifdef CONFIGURE_INIT
+ void *_Thread_Idle_body(uintptr_t ignored)
+ {
+ for( ; ; ) ;
+ return 0; /* to avoid warning */
+ }
+ #endif
+ #define CONFIGURE_IDLE_TASK_BODY _Thread_Idle_body
+ #endif
+#endif
+/**@}*/ /* end of IDLE thread configuration */
+
+/**
+ * @defgroup ConfigurationStackSize Configuration Thread Stack Size
+ *
+ * @addtogroup Configuration
+ *
+ * This module contains parameters related to thread aand interrupt stacks.
+ */
+
+/**
+ * By default, use the minimum stack size requested by this port.
+ */
+#ifndef CONFIGURE_MINIMUM_TASK_STACK_SIZE
+ #define CONFIGURE_MINIMUM_TASK_STACK_SIZE CPU_STACK_MINIMUM_SIZE
+#endif
+
+/**
+ * This specifies the default POSIX thread stack size. By default, it is
+ * twice that recommended for the port.
+ */
+#define CONFIGURE_MINIMUM_POSIX_THREAD_STACK_SIZE \
+ (2 * CONFIGURE_MINIMUM_TASK_STACK_SIZE)
+
+/**
+ * @brief Idle task stack size configuration.
+ *
+ * By default, the IDLE task will have a stack of minimum size.
+ * The BSP or application may override this value.
+ */
+#ifndef CONFIGURE_IDLE_TASK_STACK_SIZE
+ #ifdef BSP_IDLE_TASK_STACK_SIZE
+ #define CONFIGURE_IDLE_TASK_STACK_SIZE BSP_IDLE_TASK_STACK_SIZE
+ #else
+ #define CONFIGURE_IDLE_TASK_STACK_SIZE CONFIGURE_MINIMUM_TASK_STACK_SIZE
+ #endif
+#endif
+#if CONFIGURE_IDLE_TASK_STACK_SIZE < CONFIGURE_MINIMUM_TASK_STACK_SIZE
+ #error "CONFIGURE_IDLE_TASK_STACK_SIZE less than CONFIGURE_MINIMUM_TASK_STACK_SIZE"
+#endif
+
+/**
+ * @brief Interrupt stack size configuration.
+ *
+ * By default, the interrupt stack will be of minimum size.
+ * The BSP or application may override this value.
+ */
+#ifndef CONFIGURE_INTERRUPT_STACK_SIZE
+ #ifdef BSP_INTERRUPT_STACK_SIZE
+ #define CONFIGURE_INTERRUPT_STACK_SIZE BSP_INTERRUPT_STACK_SIZE
+ #else
+ #define CONFIGURE_INTERRUPT_STACK_SIZE CONFIGURE_MINIMUM_TASK_STACK_SIZE
+ #endif
+#endif
+
+/**
+ * This reserves memory for the interrupt stack if it is to be allocated
+ * by RTEMS rather than the BSP.
+ *
+ * @todo Try to get to the point where all BSPs support allocating the
+ * memory from the Workspace.
+ */
+#if (CPU_ALLOCATE_INTERRUPT_STACK == 0)
+ #define _CONFIGURE_INTERRUPT_STACK_MEMORY 0
+#else
+ #define _CONFIGURE_INTERRUPT_STACK_MEMORY \
+ _Configure_From_workspace( CONFIGURE_INTERRUPT_STACK_SIZE )
+#endif
+
+/**
+ * Configure the very much optional task stack allocator initialization
+ */
+#ifndef CONFIGURE_TASK_STACK_ALLOCATOR_INIT
+ #define CONFIGURE_TASK_STACK_ALLOCATOR_INIT NULL
+#endif
+
+/*
+ * Configure the very much optional task stack allocator and deallocator.
+ */
+#if !defined(CONFIGURE_TASK_STACK_ALLOCATOR) \
+ && !defined(CONFIGURE_TASK_STACK_DEALLOCATOR)
+ /**
+ * This specifies the task stack allocator method.
+ */
+ #define CONFIGURE_TASK_STACK_ALLOCATOR _Workspace_Allocate
+ /**
+ * This specifies the task stack deallocator method.
+ */
+ #define CONFIGURE_TASK_STACK_DEALLOCATOR _Workspace_Free
+#elif (defined(CONFIGURE_TASK_STACK_ALLOCATOR) \
+ && !defined(CONFIGURE_TASK_STACK_DEALLOCATOR)) \
+ || (!defined(CONFIGURE_TASK_STACK_ALLOCATOR) \
+ && defined(CONFIGURE_TASK_STACK_DEALLOCATOR))
+ #error "CONFIGURE_TASK_STACK_ALLOCATOR and CONFIGURE_TASK_STACK_DEALLOCATOR must be both defined or both undefined"
+#endif
+/**@}*/ /* end of thread/interrupt stack configuration */
+
+/**
+ * @addtogroup Configuration
+ */
+/**@{*/
+
+/**
+ * Should the RTEMS Workspace and C Program Heap be cleared automatically
+ * at system start up?
+ */
+#ifndef CONFIGURE_ZERO_WORKSPACE_AUTOMATICALLY
+ #ifdef BSP_ZERO_WORKSPACE_AUTOMATICALLY
+ #define CONFIGURE_ZERO_WORKSPACE_AUTOMATICALLY \
+ BSP_ZERO_WORKSPACE_AUTOMATICALLY
+ #else
+ #define CONFIGURE_ZERO_WORKSPACE_AUTOMATICALLY FALSE
+ #endif
+#endif
+/**@}*/ /* end of add to group Configuration */
+
+/**
+ * @defgroup ConfigurationMalloc RTEMS Malloc configuration
+ *
+ * This module contains parameters related to configuration of the RTEMS
+ * Malloc implementation.
+ */
+/**@{*/
+#include <rtems/malloc.h>
+
+#ifdef CONFIGURE_INIT
+ /**
+ * By default, RTEMS uses separate heaps for the RTEMS Workspace and
+ * the C Program Heap. The application can choose optionally to combine
+ * these to provide one larger memory pool. This is particularly
+ * useful in combination with the unlimited objects configuration.
+ */
+ #ifdef CONFIGURE_UNIFIED_WORK_AREAS
+ Heap_Control *RTEMS_Malloc_Heap = &_Workspace_Area;
+ #else
+ Heap_Control RTEMS_Malloc_Area;
+ Heap_Control *RTEMS_Malloc_Heap = &RTEMS_Malloc_Area;
+ #endif
+#endif
+
+#ifdef CONFIGURE_INIT
+ /**
+ * This configures the sbrk() support for the malloc family.
+ * By default it is assumed that the BSP provides all available
+ * RAM to the malloc family implementation so sbrk()'ing to get
+ * more memory would always fail anyway.
+ */
+ const rtems_heap_extend_handler rtems_malloc_extend_handler =
+ #ifdef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK
+ rtems_heap_extend_via_sbrk;
+ #else
+ rtems_heap_null_extend;
+ #endif
+#endif
+
+#ifdef CONFIGURE_INIT
+ /**
+ * This configures the malloc family plugin which dirties memory
+ * allocated. This is helpful for finding unitialized data structure
+ * problems.
+ */
+ rtems_malloc_dirtier_t rtems_malloc_dirty_helper =
+ #if defined(CONFIGURE_MALLOC_DIRTY)
+ rtems_malloc_dirty_memory;
+ #else
+ NULL;
+ #endif
+#endif
+/**@}*/ /* end of Malloc Configuration */
+
+/**
+ * @defgroup ConfigurationHelpers Configuration Helpers
+ *
+ * @ingroup Configuration
+ *
+ * This module contains items which are used internally to ease
+ * the configuration calculations.
+ */
+/**@{*/
+
+/**
+ * Zero of one returns 0 if the parameter is 0 else 1 is returned.
+ */
+#define _Configure_Zero_or_One(_number) ((_number) ? 1 : 0)
+
+/**
+ * General helper to align up a value.
+ */
+#define _Configure_Align_up(_val, _align) \
+ (((_val) + (_align) - 1) - ((_val) + (_align) - 1) % (_align))
+
+#define _CONFIGURE_HEAP_MIN_BLOCK_SIZE \
+ _Configure_Align_up(sizeof(Heap_Block), CPU_HEAP_ALIGNMENT)
+
+/**
+ * This is a helper macro used in calculations in this file. It is used
+ * to noted when an element is allocated from the RTEMS Workspace and adds
+ * a factor to account for heap overhead plus an alignment factor that
+ * may be applied.
+ */
+#define _Configure_From_workspace(_size) \
+ (ssize_t) (_Configure_Zero_or_One(_size) * \
+ _Configure_Align_up(_size + HEAP_BLOCK_HEADER_SIZE, \
+ _CONFIGURE_HEAP_MIN_BLOCK_SIZE))
+
+/**
+ * This is a helper macro used in stack space calculations in this file. It
+ * may be provided by the application in case a special task stack allocator
+ * is used. The default is allocation from the RTEMS Workspace.
+ */
+#ifdef CONFIGURE_TASK_STACK_FROM_ALLOCATOR
+ #define _Configure_From_stackspace(_stack_size) \
+ CONFIGURE_TASK_STACK_FROM_ALLOCATOR(_stack_size)
+#else
+ #define _Configure_From_stackspace(_stack_size) \
+ _Configure_From_workspace(_stack_size)
+#endif
+
+/**
+ * Do not use the unlimited bit as part of the multiplication
+ * for memory usage.
+ */
+#define _Configure_Max_Objects(_max) \
+ (_Configure_Zero_or_One(_max) * rtems_resource_maximum_per_allocation(_max))
+
+/**
+ * This macro accounts for how memory for a set of configured objects is
+ * allocated from the Executive Workspace.
+ *
+ * NOTE: It does NOT attempt to address the more complex case of unlimited
+ * objects.
+ */
+#define _Configure_Object_RAM(_number, _size) ( \
+ _Configure_From_workspace(_Configure_Max_Objects(_number) * (_size)) + \
+ _Configure_From_workspace( \
+ _Configure_Zero_or_One(_number) * ( \
+ (_Configure_Max_Objects(_number) + 1) * sizeof(Objects_Control *) + \
+ _Configure_Align_up(sizeof(void *), CPU_ALIGNMENT) + \
+ _Configure_Align_up(sizeof(uint32_t), CPU_ALIGNMENT) \
+ ) \
+ ) \
+ )
+/**@}*/
+
+/**
+ * @defgroup ConfigurationInitTasksTable Initialization Tasks Configuration
+ *
+ * @addtogroup Configuration
+ *
+ * This group contains the elements needed to define the Classic API
+ * Initialization Tasks Table.
+ *
+ * Default User Initialization Task Table. This table guarantees that
+ * one user initialization table is defined.
+ */
+#ifdef CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#ifdef CONFIGURE_HAS_OWN_INIT_TASK_TABLE
+
+/*
+ * The user is defining their own table information and setting the
+ * appropriate variables.
+ */
+
+#else
+
+/**
+ * When using the default Classic API Initialization Tasks Table, this is
+ * used to specify the name of the single Classic API task.
+ */
+#ifndef CONFIGURE_INIT_TASK_NAME
+ #define CONFIGURE_INIT_TASK_NAME rtems_build_name('U', 'I', '1', ' ')
+#endif
+
+/**
+ * When using the default Classic API Initialization Tasks Table, this is
+ * used to specify the stack size of the single Classic API task.
+ */
+#ifndef CONFIGURE_INIT_TASK_STACK_SIZE
+ #define CONFIGURE_INIT_TASK_STACK_SIZE CONFIGURE_MINIMUM_TASK_STACK_SIZE
+#endif
+
+/**
+ * When using the default Classic API Initialization Tasks Table, this is
+ * used to specify the priority of the single Classic API task.
+ */
+#ifndef CONFIGURE_INIT_TASK_PRIORITY
+ #define CONFIGURE_INIT_TASK_PRIORITY 1
+#endif
+
+/**
+ * When using the default Classic API Initialization Tasks Table, this is
+ * used to specify the attributes size of the single Classic API task.
+ */
+#ifndef CONFIGURE_INIT_TASK_ATTRIBUTES
+ #define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES
+#endif
+
+/**
+ * When using the default Classic API Initialization Tasks Table, this is
+ * used to specify the entry point of the single Classic API task.
+ */
+#ifndef CONFIGURE_INIT_TASK_ENTRY_POINT
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+ rtems_task Init (rtems_task_argument );
+ #ifdef __cplusplus
+ }
+ #endif
+ #define CONFIGURE_INIT_TASK_ENTRY_POINT Init
+ extern const char* bsp_boot_cmdline;
+ #define CONFIGURE_INIT_TASK_ARGUMENTS ((rtems_task_argument) &bsp_boot_cmdline)
+#endif
+
+/**
+ * When using the default Classic API Initialization Tasks Table, this is
+ * used to specify the initial execution mode of the single Classic API task.
+ */
+#ifndef CONFIGURE_INIT_TASK_INITIAL_MODES
+ #ifdef _CONFIGURE_SMP_APPLICATION
+ #define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+ #else
+ #define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_NO_PREEMPT
+ #endif
+#endif
+
+/**
+ * When using the default Classic API Initialization Tasks Table, this is
+ * used to specify the initial argument to the single Classic API task.
+ */
+#ifndef CONFIGURE_INIT_TASK_ARGUMENTS
+ #define CONFIGURE_INIT_TASK_ARGUMENTS 0
+#endif
+
+#ifdef CONFIGURE_INIT
+ rtems_initialization_tasks_table Initialization_tasks[] = {
+ { CONFIGURE_INIT_TASK_NAME,
+ CONFIGURE_INIT_TASK_STACK_SIZE,
+ CONFIGURE_INIT_TASK_PRIORITY,
+ CONFIGURE_INIT_TASK_ATTRIBUTES,
+ CONFIGURE_INIT_TASK_ENTRY_POINT,
+ CONFIGURE_INIT_TASK_INITIAL_MODES,
+ CONFIGURE_INIT_TASK_ARGUMENTS
+ }
+ };
+#endif
+
+/**
+ * This is the name of the Initialization Tasks Table generated.
+ */
+#define CONFIGURE_INIT_TASK_TABLE Initialization_tasks
+
+/*
+ * This is the size of the Initialization Tasks Table generated.
+ */
+#define CONFIGURE_INIT_TASK_TABLE_SIZE \
+ RTEMS_ARRAY_SIZE(CONFIGURE_INIT_TASK_TABLE)
+
+#endif /* CONFIGURE_HAS_OWN_INIT_TASK_TABLE */
+
+#else /* CONFIGURE_RTEMS_INIT_TASKS_TABLE */
+
+/*
+ * This is the name of the Initialization Task when none is configured.
+ */
+#define CONFIGURE_INIT_TASK_TABLE NULL
+
+/*
+ * This is the size of the Initialization Task when none is configured.
+ */
+#define CONFIGURE_INIT_TASK_TABLE_SIZE 0
+
+/*
+ * This is the stack size of the Initialization Task when none is configured.
+ */
+#define CONFIGURE_INIT_TASK_STACK_SIZE 0
+
+#endif
+/**@}*/ /* end of Classic API Initialization Tasks Table */
+
+/**
+ * @defgroup ConfigurationDriverTable Device Driver Table Configuration
+ *
+ * @addtogroup Configuration
+ *
+ * This group contains parameters related to generating a Device Driver
+ * Table.
+ *
+ * Default Device Driver Table. Each driver needed by the test is explicitly
+ * choosen by the application. There is always a null driver entry.
+ */
+/**@{*/
+
+/**
+ * This is an empty device driver slot.
+ */
+#define NULL_DRIVER_TABLE_ENTRY \
+ { NULL, NULL, NULL, NULL, NULL, NULL }
+
+#if defined(CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER) && \
+ defined(CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER)
+#error "CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER and CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER are mutually exclusive"
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+ #include <rtems/console.h>
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
+ #include <rtems/console.h>
+
+ #ifdef CONFIGURE_INIT
+ RTEMS_SYSINIT_ITEM(
+ _Console_simple_Initialize,
+ RTEMS_SYSINIT_DEVICE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_SECOND
+ );
+ #endif
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+ #include <rtems/clockdrv.h>
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
+ #include <rtems/btimer.h>
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER
+ #include <rtems/rtc.h>
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_WATCHDOG_DRIVER
+ #include <rtems/watchdogdrv.h>
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_FRAME_BUFFER_DRIVER
+ #include <rtems/framebuffer.h>
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER
+ #include <rtems/devnull.h>
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER
+ #include <rtems/devzero.h>
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER
+ /* the ide driver needs the ATA driver */
+ #ifndef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER
+ #define CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER
+ #endif
+ #include <libchip/ide_ctrl.h>
+#endif
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER
+ #include <libchip/ata.h>
+#endif
+
+#ifndef CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE
+
+/**
+ * This specifies the maximum number of device drivers that
+ * can be installed in the system at one time. It must account
+ * for both the statically and dynamically installed drivers.
+ */
+#ifndef CONFIGURE_MAXIMUM_DRIVERS
+ #define CONFIGURE_MAXIMUM_DRIVERS
+#endif
+
+#ifdef CONFIGURE_INIT
+ rtems_driver_address_table
+ _IO_Driver_address_table[ CONFIGURE_MAXIMUM_DRIVERS ] = {
+ #ifdef CONFIGURE_BSP_PREREQUISITE_DRIVERS
+ CONFIGURE_BSP_PREREQUISITE_DRIVERS,
+ #endif
+ #ifdef CONFIGURE_APPLICATION_PREREQUISITE_DRIVERS
+ CONFIGURE_APPLICATION_PREREQUISITE_DRIVERS,
+ #endif
+ #ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+ CONSOLE_DRIVER_TABLE_ENTRY,
+ #endif
+ #ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+ CLOCK_DRIVER_TABLE_ENTRY,
+ #endif
+ #ifdef CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER
+ RTC_DRIVER_TABLE_ENTRY,
+ #endif
+ #ifdef CONFIGURE_APPLICATION_NEEDS_WATCHDOG_DRIVER
+ WATCHDOG_DRIVER_TABLE_ENTRY,
+ #endif
+ #ifdef CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER
+ DEVNULL_DRIVER_TABLE_ENTRY,
+ #endif
+ #ifdef CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER
+ DEVZERO_DRIVER_TABLE_ENTRY,
+ #endif
+ #ifdef CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER
+ IDE_CONTROLLER_DRIVER_TABLE_ENTRY,
+ #endif
+ #ifdef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER
+ ATA_DRIVER_TABLE_ENTRY,
+ #endif
+ #ifdef CONFIGURE_APPLICATION_NEEDS_FRAME_BUFFER_DRIVER
+ FRAME_BUFFER_DRIVER_TABLE_ENTRY,
+ #endif
+ #ifdef CONFIGURE_APPLICATION_EXTRA_DRIVERS
+ CONFIGURE_APPLICATION_EXTRA_DRIVERS,
+ #endif
+ #ifdef CONFIGURE_APPLICATION_NEEDS_NULL_DRIVER
+ NULL_DRIVER_TABLE_ENTRY
+ #elif !defined(CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER) && \
+ !defined(CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER) && \
+ !defined(CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER) && \
+ !defined(CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER) && \
+ !defined(CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER) && \
+ !defined(CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER) && \
+ !defined(CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER) && \
+ !defined(CONFIGURE_APPLICATION_NEEDS_FRAME_BUFFER_DRIVER) && \
+ !defined(CONFIGURE_APPLICATION_EXTRA_DRIVERS)
+ NULL_DRIVER_TABLE_ENTRY
+ #endif
+ };
+
+ const size_t _IO_Number_of_drivers =
+ RTEMS_ARRAY_SIZE( _IO_Driver_address_table );
+#endif
+
+#endif /* CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE */
+
+#ifdef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER
+ /*
+ * configure the priority of the ATA driver task
+ */
+ #ifndef CONFIGURE_ATA_DRIVER_TASK_PRIORITY
+ #define CONFIGURE_ATA_DRIVER_TASK_PRIORITY ATA_DRIVER_TASK_DEFAULT_PRIORITY
+ #endif
+ #ifdef CONFIGURE_INIT
+ rtems_task_priority rtems_ata_driver_task_priority
+ = CONFIGURE_ATA_DRIVER_TASK_PRIORITY;
+ #endif /* CONFIGURE_INIT */
+#endif
+/**@}*/ /* end of Device Driver Table Configuration */
+
+/**
+ * @defgroup ConfigurationLibBlock Configuration of LIBBLOCK
+ *
+ * @addtogroup Configuration
+ *
+ * This module contains parameters related to the LIBBLOCK buffering
+ * and caching subsystem. It requires tasks to swap out data to be
+ * written to non-volatile storage.
+ */
+/**@{*/
+#ifdef CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
+ #include <rtems/bdbuf.h>
+ /*
+ * configure the bdbuf cache parameters
+ */
+ #ifndef CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS
+ #define CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS \
+ RTEMS_BDBUF_MAX_READ_AHEAD_BLOCKS_DEFAULT
+ #endif
+ #ifndef CONFIGURE_BDBUF_MAX_WRITE_BLOCKS
+ #define CONFIGURE_BDBUF_MAX_WRITE_BLOCKS \
+ RTEMS_BDBUF_MAX_WRITE_BLOCKS_DEFAULT
+ #endif
+ #ifndef CONFIGURE_SWAPOUT_TASK_PRIORITY
+ #define CONFIGURE_SWAPOUT_TASK_PRIORITY \
+ RTEMS_BDBUF_SWAPOUT_TASK_PRIORITY_DEFAULT
+ #endif
+ #ifndef CONFIGURE_SWAPOUT_SWAP_PERIOD
+ #define CONFIGURE_SWAPOUT_SWAP_PERIOD \
+ RTEMS_BDBUF_SWAPOUT_TASK_SWAP_PERIOD_DEFAULT
+ #endif
+ #ifndef CONFIGURE_SWAPOUT_BLOCK_HOLD
+ #define CONFIGURE_SWAPOUT_BLOCK_HOLD \
+ RTEMS_BDBUF_SWAPOUT_TASK_BLOCK_HOLD_DEFAULT
+ #endif
+ #ifndef CONFIGURE_SWAPOUT_WORKER_TASKS
+ #define CONFIGURE_SWAPOUT_WORKER_TASKS \
+ RTEMS_BDBUF_SWAPOUT_WORKER_TASKS_DEFAULT
+ #endif
+ #ifndef CONFIGURE_SWAPOUT_WORKER_TASK_PRIORITY
+ #define CONFIGURE_SWAPOUT_WORKER_TASK_PRIORITY \
+ RTEMS_BDBUF_SWAPOUT_WORKER_TASK_PRIORITY_DEFAULT
+ #endif
+ #ifndef CONFIGURE_BDBUF_TASK_STACK_SIZE
+ #define CONFIGURE_BDBUF_TASK_STACK_SIZE \
+ RTEMS_BDBUF_TASK_STACK_SIZE_DEFAULT
+ #endif
+ #ifndef CONFIGURE_BDBUF_CACHE_MEMORY_SIZE
+ #define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE \
+ RTEMS_BDBUF_CACHE_MEMORY_SIZE_DEFAULT
+ #endif
+ #ifndef CONFIGURE_BDBUF_BUFFER_MIN_SIZE
+ #define CONFIGURE_BDBUF_BUFFER_MIN_SIZE \
+ RTEMS_BDBUF_BUFFER_MIN_SIZE_DEFAULT
+ #endif
+ #ifndef CONFIGURE_BDBUF_BUFFER_MAX_SIZE
+ #define CONFIGURE_BDBUF_BUFFER_MAX_SIZE \
+ RTEMS_BDBUF_BUFFER_MAX_SIZE_DEFAULT
+ #endif
+ #ifndef CONFIGURE_BDBUF_READ_AHEAD_TASK_PRIORITY
+ #define CONFIGURE_BDBUF_READ_AHEAD_TASK_PRIORITY \
+ RTEMS_BDBUF_READ_AHEAD_TASK_PRIORITY_DEFAULT
+ #endif
+ #ifdef CONFIGURE_INIT
+ const rtems_bdbuf_config rtems_bdbuf_configuration = {
+ CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS,
+ CONFIGURE_BDBUF_MAX_WRITE_BLOCKS,
+ CONFIGURE_SWAPOUT_TASK_PRIORITY,
+ CONFIGURE_SWAPOUT_SWAP_PERIOD,
+ CONFIGURE_SWAPOUT_BLOCK_HOLD,
+ CONFIGURE_SWAPOUT_WORKER_TASKS,
+ CONFIGURE_SWAPOUT_WORKER_TASK_PRIORITY,
+ CONFIGURE_BDBUF_TASK_STACK_SIZE,
+ CONFIGURE_BDBUF_CACHE_MEMORY_SIZE,
+ CONFIGURE_BDBUF_BUFFER_MIN_SIZE,
+ CONFIGURE_BDBUF_BUFFER_MAX_SIZE,
+ CONFIGURE_BDBUF_READ_AHEAD_TASK_PRIORITY
+ };
+ #endif
+
+ #define _CONFIGURE_LIBBLOCK_TASKS \
+ (1 + CONFIGURE_SWAPOUT_WORKER_TASKS + \
+ (CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS != 0))
+
+ #define _CONFIGURE_LIBBLOCK_TASK_EXTRA_STACKS \
+ (_CONFIGURE_LIBBLOCK_TASKS * \
+ (CONFIGURE_BDBUF_TASK_STACK_SIZE <= CONFIGURE_MINIMUM_TASK_STACK_SIZE ? \
+ 0 : CONFIGURE_BDBUF_TASK_STACK_SIZE - CONFIGURE_MINIMUM_TASK_STACK_SIZE))
+
+ #ifdef RTEMS_BDBUF_USE_PTHREAD
+ /*
+ * Semaphores:
+ * o disk lock
+ */
+ #define _CONFIGURE_LIBBLOCK_SEMAPHORES 1
+ #else
+ /*
+ * Semaphores:
+ * o disk lock
+ * o bdbuf lock
+ * o bdbuf sync lock
+ * o bdbuf access condition
+ * o bdbuf transfer condition
+ * o bdbuf buffer condition
+ */
+ #define _CONFIGURE_LIBBLOCK_SEMAPHORES 6
+ #endif
+
+ #if defined(CONFIGURE_HAS_OWN_BDBUF_TABLE) || \
+ defined(CONFIGURE_BDBUF_BUFFER_SIZE) || \
+ defined(CONFIGURE_BDBUF_BUFFER_COUNT)
+ #error BDBUF Cache does not use a buffer configuration table. Please remove.
+ #endif
+#else
+ /** This specifies the number of libblock tasks. */
+ #define _CONFIGURE_LIBBLOCK_TASKS 0
+ /** This specifies the extra stack space configured for libblock tasks. */
+ #define _CONFIGURE_LIBBLOCK_TASK_EXTRA_STACKS 0
+ /** This specifies the number of Classic API semaphores needed by libblock. */
+ #define _CONFIGURE_LIBBLOCK_SEMAPHORES 0
+#endif /* CONFIGURE_APPLICATION_NEEDS_LIBBLOCK */
+/**@}*/
+
+/**
+ * @defgroup ConfigurationMultiprocessing Multiprocessing Configuration
+ *
+ * @addtogroup Configuration
+ *
+ * This module contains the parameters related to the Multiprocessing
+ * configuration of RTEMS.
+ *
+ * In a single processor or SMP configuration, only two parameters are
+ * needed and they are defaulted. The user should not have to specify
+ * any parameters.
+ */
+/**@{*/
+
+/**
+ * This defines the extra stack space required for the MPCI server thread.
+ */
+#ifndef CONFIGURE_EXTRA_MPCI_RECEIVE_SERVER_STACK
+ #define CONFIGURE_EXTRA_MPCI_RECEIVE_SERVER_STACK 0
+#endif
+
+/**
+ * This defines the timers required for the shared memory driver in
+ * a multiprocessing configuration.
+ */
+#ifndef _CONFIGURE_TIMER_FOR_SHARED_MEMORY_DRIVER
+ #define _CONFIGURE_TIMER_FOR_SHARED_MEMORY_DRIVER 0
+#endif
+
+
+#if defined(RTEMS_MULTIPROCESSING)
+ /*
+ * Default Multiprocessing Configuration Table. The defaults are
+ * appropriate for most of the RTEMS Multiprocessor Test Suite. Each
+ * value may be overridden within each test to customize the environment.
+ */
+
+ #ifdef CONFIGURE_MP_APPLICATION
+ #define _CONFIGURE_TIMER_FOR_SHARED_MEMORY_DRIVER 1
+
+ #ifndef CONFIGURE_HAS_OWN_MULTIPROCESSING_TABLE
+
+ #ifndef CONFIGURE_MP_NODE_NUMBER
+ #define CONFIGURE_MP_NODE_NUMBER NODE_NUMBER
+ #endif
+
+ #ifndef CONFIGURE_MP_MAXIMUM_NODES
+ #define CONFIGURE_MP_MAXIMUM_NODES 2
+ #endif
+
+ #ifndef CONFIGURE_MP_MAXIMUM_GLOBAL_OBJECTS
+ #define CONFIGURE_MP_MAXIMUM_GLOBAL_OBJECTS 32
+ #endif
+ #define _CONFIGURE_MEMORY_FOR_GLOBAL_OBJECTS(_global_objects) \
+ _Configure_From_workspace( \
+ (_global_objects) * sizeof(Objects_MP_Control) \
+ )
+
+ #ifndef CONFIGURE_MP_MAXIMUM_PROXIES
+ #define CONFIGURE_MP_MAXIMUM_PROXIES 32
+ #endif
+ #define _CONFIGURE_MEMORY_FOR_PROXIES(_proxies) \
+ _Configure_From_workspace((_proxies) \
+ * (sizeof(Thread_Proxy_control) \
+ + THREAD_QUEUE_HEADS_SIZE(CONFIGURE_SCHEDULER_COUNT)))
+
+ #ifndef CONFIGURE_MP_MPCI_TABLE_POINTER
+ #include <mpci.h>
+ #define CONFIGURE_MP_MPCI_TABLE_POINTER &MPCI_table
+ #endif
+
+ #ifdef CONFIGURE_INIT
+ rtems_multiprocessing_table Multiprocessing_configuration = {
+ CONFIGURE_MP_NODE_NUMBER, /* local node number */
+ CONFIGURE_MP_MAXIMUM_NODES, /* maximum # nodes */
+ CONFIGURE_MP_MAXIMUM_GLOBAL_OBJECTS, /* maximum # global objects */
+ CONFIGURE_MP_MAXIMUM_PROXIES, /* maximum # proxies */
+ CONFIGURE_EXTRA_MPCI_RECEIVE_SERVER_STACK, /* MPCI stack > minimum */
+ CONFIGURE_MP_MPCI_TABLE_POINTER /* ptr to MPCI config table */
+ };
+ #endif
+
+ #define CONFIGURE_MULTIPROCESSING_TABLE &Multiprocessing_configuration
+
+ #define _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT 1
+
+ #endif /* CONFIGURE_HAS_OWN_MULTIPROCESSING_TABLE */
+
+ #else
+
+ #define CONFIGURE_MULTIPROCESSING_TABLE NULL
+
+ #define _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT 0
+
+ #endif /* CONFIGURE_MP_APPLICATION */
+#else
+ #define _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT 0
+#endif /* RTEMS_MULTIPROCESSING */
+/**@}*/ /* end of Multiprocessing Configuration */
+
+/**
+ * This macro specifies that the user wants to use unlimited objects for any
+ * classic or posix objects that have not already been given resource limits.
+ */
+#if defined(CONFIGURE_UNLIMITED_OBJECTS)
+ #if !defined(CONFIGURE_UNIFIED_WORK_AREAS) && \
+ !defined(CONFIGURE_EXECUTIVE_RAM_SIZE) && \
+ !defined(CONFIGURE_MEMORY_OVERHEAD)
+ #error "CONFIGURE_UNLIMITED_OBJECTS requires a unified work area, an executive RAM size, or a defined workspace memory overhead"
+ #endif
+
+ #if !defined(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ /**
+ * This macro specifies a default allocation size for when auto-extending
+ * unlimited objects if none was given by the user.
+ */
+ #define CONFIGURE_UNLIMITED_ALLOCATION_SIZE 8
+ #endif
+ #if !defined(CONFIGURE_MAXIMUM_TASKS)
+ #define CONFIGURE_MAXIMUM_TASKS \
+ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ #endif
+ #if !defined(CONFIGURE_MAXIMUM_TIMERS)
+ #define CONFIGURE_MAXIMUM_TIMERS \
+ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ #endif
+ #if !defined(CONFIGURE_MAXIMUM_SEMAPHORES)
+ #define CONFIGURE_MAXIMUM_SEMAPHORES \
+ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ #endif
+ #if !defined(CONFIGURE_MAXIMUM_MESSAGE_QUEUES)
+ #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES \
+ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ #endif
+ #if !defined(CONFIGURE_MAXIMUM_PARTITIONS)
+ #define CONFIGURE_MAXIMUM_PARTITIONS \
+ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ #endif
+ #if !defined(CONFIGURE_MAXIMUM_REGIONS)
+ #define CONFIGURE_MAXIMUM_REGIONS \
+ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ #endif
+ #if !defined(CONFIGURE_MAXIMUM_PORTS)
+ #define CONFIGURE_MAXIMUM_PORTS \
+ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ #endif
+ #if !defined(CONFIGURE_MAXIMUM_PERIODS)
+ #define CONFIGURE_MAXIMUM_PERIODS \
+ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ #endif
+ #if !defined(CONFIGURE_MAXIMUM_BARRIERS)
+ #define CONFIGURE_MAXIMUM_BARRIERS \
+ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ #endif
+ #if !defined(CONFIGURE_MAXIMUM_POSIX_KEYS)
+ #define CONFIGURE_MAXIMUM_POSIX_KEYS \
+ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ #endif
+ #if !defined(CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS)
+ #define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS \
+ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ #endif
+
+ #ifdef RTEMS_POSIX_API
+ #if !defined(CONFIGURE_MAXIMUM_POSIX_THREADS)
+ #define CONFIGURE_MAXIMUM_POSIX_THREADS \
+ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ #endif
+ #if !defined(CONFIGURE_MAXIMUM_POSIX_TIMERS)
+ #define CONFIGURE_MAXIMUM_POSIX_TIMERS \
+ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ #endif
+/*
+ #if !defined(CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS)
+ #define CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS \
+ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ #endif
+*/
+ #if !defined(CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES)
+ #define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES \
+ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ #endif
+ #if !defined(CONFIGURE_MAXIMUM_POSIX_SEMAPHORES)
+ #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES \
+ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ #endif
+ #if !defined(CONFIGURE_MAXIMUM_POSIX_SHMS)
+ #define CONFIGURE_MAXIMUM_POSIX_SHMS \
+ rtems_resource_unlimited(CONFIGURE_UNLIMITED_ALLOCATION_SIZE)
+ #endif
+ #endif /* RTEMS_POSIX_API */
+#endif /* CONFIGURE_UNLIMITED_OBJECTS */
+
+
+/**
+ * @defgroup ConfigurationClassicAPI Classic API Configuration
+ *
+ * @ingroup Configuration
+ *
+ * This module contains the parameters related to configuration
+ * of the Classic API services.
+ */
+/**@{*/
+#ifndef CONFIGURE_HAS_OWN_CONFIGURATION_TABLE
+
+ /** This configures the maximum number of Classic API tasks. */
+ #ifndef CONFIGURE_MAXIMUM_TASKS
+ #define CONFIGURE_MAXIMUM_TASKS 0
+ #endif
+
+ /*
+ * This is calculated to account for the maximum number of Classic API
+ * tasks used by the application and configured RTEMS capabilities.
+ */
+ #define _CONFIGURE_TASKS \
+ (CONFIGURE_MAXIMUM_TASKS + _CONFIGURE_LIBBLOCK_TASKS)
+
+ #ifndef CONFIGURE_MAXIMUM_TIMERS
+ /** This specifies the maximum number of Classic API timers. */
+ #define CONFIGURE_MAXIMUM_TIMERS 0
+ /*
+ * This macro is calculated to specify the memory required for
+ * Classic API timers.
+ */
+ #define _CONFIGURE_MEMORY_FOR_TIMERS(_timers) 0
+ #else
+ #define _CONFIGURE_MEMORY_FOR_TIMERS(_timers) \
+ _Configure_Object_RAM(_timers, sizeof(Timer_Control) )
+ #endif
+
+ #ifndef CONFIGURE_MAXIMUM_SEMAPHORES
+ /** This specifies the maximum number of Classic API semaphores. */
+ #define CONFIGURE_MAXIMUM_SEMAPHORES 0
+ #endif
+
+ /*
+ * This specifies the number of Classic API semaphores required
+ */
+ #ifdef RTEMS_NETWORKING
+ #define _CONFIGURE_NETWORKING_SEMAPHORES 1
+ #else
+ #define _CONFIGURE_NETWORKING_SEMAPHORES 0
+ #endif
+
+ /*
+ * This macro is calculated to specify the number of Classic API
+ * semaphores required by the application and configured RTEMS
+ * capabilities.
+ */
+ #define _CONFIGURE_SEMAPHORES \
+ (CONFIGURE_MAXIMUM_SEMAPHORES + \
+ _CONFIGURE_TERMIOS_SEMAPHORES + _CONFIGURE_LIBBLOCK_SEMAPHORES + \
+ _CONFIGURE_SEMAPHORES_FOR_FILE_SYSTEMS + \
+ _CONFIGURE_NETWORKING_SEMAPHORES)
+
+ /*
+ * This macro is calculated to specify the memory required for
+ * Classic API Semaphores using MRSP. This is only available in
+ * SMP configurations.
+ */
+ #if !defined(RTEMS_SMP) || \
+ !defined(CONFIGURE_MAXIMUM_MRSP_SEMAPHORES)
+ #define _CONFIGURE_MEMORY_FOR_MRSP_SEMAPHORES 0
+ #else
+ #define _CONFIGURE_MEMORY_FOR_MRSP_SEMAPHORES \
+ CONFIGURE_MAXIMUM_MRSP_SEMAPHORES * \
+ _Configure_From_workspace( \
+ RTEMS_ARRAY_SIZE(_Scheduler_Table) * sizeof(Priority_Control) \
+ )
+ #endif
+
+ /*
+ * This macro is calculated to specify the memory required for
+ * Classic API Semaphores.
+ *
+ * If there are no user or support semaphores defined, then we can assume
+ * that no memory need be allocated at all for semaphores.
+ */
+ #if _CONFIGURE_SEMAPHORES == 0
+ #define _CONFIGURE_MEMORY_FOR_SEMAPHORES(_semaphores) 0
+ #else
+ #define _CONFIGURE_MEMORY_FOR_SEMAPHORES(_semaphores) \
+ _Configure_Object_RAM(_semaphores, sizeof(Semaphore_Control) ) + \
+ _CONFIGURE_MEMORY_FOR_MRSP_SEMAPHORES
+ #endif
+
+ #ifndef CONFIGURE_MAXIMUM_MESSAGE_QUEUES
+ /**
+ * This configuration parameter specifies the maximum number of
+ * Classic API Message Queues.
+ */
+ #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 0
+ /*
+ * This macro is calculated to specify the RTEMS Workspace required for
+ * the Classic API Message Queues.
+ */
+ #define _CONFIGURE_MEMORY_FOR_MESSAGE_QUEUES(_queues) 0
+ #else
+ #define _CONFIGURE_MEMORY_FOR_MESSAGE_QUEUES(_queues) \
+ _Configure_Object_RAM(_queues, sizeof(Message_queue_Control) )
+ #endif
+
+ #ifndef CONFIGURE_MAXIMUM_PARTITIONS
+ /**
+ * This configuration parameter specifies the maximum number of
+ * Classic API Partitions.
+ */
+ #define CONFIGURE_MAXIMUM_PARTITIONS 0
+ /*
+ * This macro is calculated to specify the memory required for
+ * Classic API
+ */
+ #define _CONFIGURE_MEMORY_FOR_PARTITIONS(_partitions) 0
+ #else
+ #define _CONFIGURE_MEMORY_FOR_PARTITIONS(_partitions) \
+ _Configure_Object_RAM(_partitions, sizeof(Partition_Control) )
+ #endif
+
+ #ifndef CONFIGURE_MAXIMUM_REGIONS
+ /**
+ * This configuration parameter specifies the maximum number of
+ * Classic API Regions.
+ */
+ #define CONFIGURE_MAXIMUM_REGIONS 0
+ /*
+ * This macro is calculated to specify the memory required for
+ * Classic API Regions.
+ */
+ #define _CONFIGURE_MEMORY_FOR_REGIONS(_regions) 0
+ #else
+ #define _CONFIGURE_MEMORY_FOR_REGIONS(_regions) \
+ _Configure_Object_RAM(_regions, sizeof(Region_Control) )
+ #endif
+
+ #ifndef CONFIGURE_MAXIMUM_PORTS
+ /**
+ * This configuration parameter specifies the maximum number of
+ * Classic API Dual-Ported Memory Ports.
+ */
+ #define CONFIGURE_MAXIMUM_PORTS 0
+ /**
+ * This macro is calculated to specify the memory required for
+ * Classic API Dual-Ported Memory Ports.
+ */
+ #define _CONFIGURE_MEMORY_FOR_PORTS(_ports) 0
+ #else
+ #define _CONFIGURE_MEMORY_FOR_PORTS(_ports) \
+ _Configure_Object_RAM(_ports, sizeof(Dual_ported_memory_Control) )
+ #endif
+
+ #ifndef CONFIGURE_MAXIMUM_PERIODS
+ /**
+ * This configuration parameter specifies the maximum number of
+ * Classic API Rate Monotonic Periods.
+ */
+ #define CONFIGURE_MAXIMUM_PERIODS 0
+ /*
+ * This macro is calculated to specify the memory required for
+ * Classic API Rate Monotonic Periods.
+ */
+ #define _CONFIGURE_MEMORY_FOR_PERIODS(_periods) 0
+#else
+ #define _CONFIGURE_MEMORY_FOR_PERIODS(_periods) \
+ _Configure_Object_RAM(_periods, sizeof(Rate_monotonic_Control) )
+ #endif
+
+ /**
+ * This configuration parameter specifies the maximum number of
+ * Classic API Barriers.
+ */
+ #ifndef CONFIGURE_MAXIMUM_BARRIERS
+ #define CONFIGURE_MAXIMUM_BARRIERS 0
+ #endif
+
+ /*
+ * This macro is calculated to specify the number of Classic API
+ * Barriers required by the application and configured capabilities.
+ */
+ #define _CONFIGURE_BARRIERS \
+ (CONFIGURE_MAXIMUM_BARRIERS + _CONFIGURE_BARRIERS_FOR_FIFOS)
+
+ /*
+ * This macro is calculated to specify the memory required for
+ * Classic API Barriers.
+ */
+ #if _CONFIGURE_BARRIERS == 0
+ #define _CONFIGURE_MEMORY_FOR_BARRIERS(_barriers) 0
+ #else
+ #define _CONFIGURE_MEMORY_FOR_BARRIERS(_barriers) \
+ _Configure_Object_RAM(_barriers, sizeof(Barrier_Control) )
+ #endif
+
+ #ifndef CONFIGURE_MAXIMUM_USER_EXTENSIONS
+ /**
+ * This configuration parameter specifies the maximum number of
+ * Classic API User Extensions.
+ */
+ #define CONFIGURE_MAXIMUM_USER_EXTENSIONS 0
+ /*
+ * This macro is calculated to specify the memory required for
+ * Classic API User Extensions.
+ */
+ #define _CONFIGURE_MEMORY_FOR_USER_EXTENSIONS(_extensions) 0
+ #else
+ #define _CONFIGURE_MEMORY_FOR_USER_EXTENSIONS(_extensions) \
+ _Configure_Object_RAM(_extensions, sizeof(Extension_Control) )
+ #endif
+ /**@}*/ /* end of Classic API Configuration */
+
+ /**
+ * @defgroup ConfigurationGeneral General System Configuration
+ *
+ * @ingroup Configuration
+ *
+ * This module contains configuration parameters that are independent
+ * of any API but impact general system configuration.
+ */
+ /**@{*/
+
+ /** The configures the number of microseconds per clock tick. */
+ #ifndef CONFIGURE_MICROSECONDS_PER_TICK
+ #define CONFIGURE_MICROSECONDS_PER_TICK \
+ RTEMS_MILLISECONDS_TO_MICROSECONDS(10)
+ #endif
+
+ #if 1000000 % CONFIGURE_MICROSECONDS_PER_TICK != 0
+ #warning "The clock ticks per second is not an integer"
+ #endif
+
+ #if CONFIGURE_MICROSECONDS_PER_TICK <= 0
+ #error "The CONFIGURE_MICROSECONDS_PER_TICK must be positive"
+ #endif
+
+ #define _CONFIGURE_TICKS_PER_SECOND (1000000 / CONFIGURE_MICROSECONDS_PER_TICK)
+
+ /** The configures the number of clock ticks per timeslice. */
+ #ifndef CONFIGURE_TICKS_PER_TIMESLICE
+ #define CONFIGURE_TICKS_PER_TIMESLICE 50
+ #endif
+
+/**@}*/ /* end of General Configuration */
+
+/*
+ * Initial Extension Set
+ */
+
+#ifdef CONFIGURE_INIT
+#ifdef CONFIGURE_STACK_CHECKER_ENABLED
+#include <rtems/stackchk.h>
+#endif
+#include <rtems/libcsupport.h>
+
+#if defined(BSP_INITIAL_EXTENSION) || \
+ defined(CONFIGURE_INITIAL_EXTENSIONS) || \
+ defined(CONFIGURE_STACK_CHECKER_ENABLED) || \
+ (defined(RTEMS_NEWLIB) && !defined(CONFIGURE_DISABLE_NEWLIB_REENTRANCY))
+ static const rtems_extensions_table Configuration_Initial_Extensions[] = {
+ #if !defined(CONFIGURE_DISABLE_NEWLIB_REENTRANCY)
+ RTEMS_NEWLIB_EXTENSION,
+ #endif
+ #if defined(CONFIGURE_STACK_CHECKER_ENABLED)
+ RTEMS_STACK_CHECKER_EXTENSION,
+ #endif
+ #if defined(CONFIGURE_INITIAL_EXTENSIONS)
+ CONFIGURE_INITIAL_EXTENSIONS,
+ #endif
+ #if defined(BSP_INITIAL_EXTENSION)
+ BSP_INITIAL_EXTENSION
+ #endif
+ };
+
+ #define CONFIGURE_INITIAL_EXTENSION_TABLE Configuration_Initial_Extensions
+ #define _CONFIGURE_NUMBER_OF_INITIAL_EXTENSIONS \
+ RTEMS_ARRAY_SIZE(Configuration_Initial_Extensions)
+
+ RTEMS_SYSINIT_ITEM(
+ _User_extensions_Handler_initialization,
+ RTEMS_SYSINIT_INITIAL_EXTENSIONS,
+ RTEMS_SYSINIT_ORDER_MIDDLE
+ );
+#else
+ #define CONFIGURE_INITIAL_EXTENSION_TABLE NULL
+ #define _CONFIGURE_NUMBER_OF_INITIAL_EXTENSIONS 0
+#endif
+
+#if defined(RTEMS_NEWLIB)
+ struct _reent *__getreent(void)
+ {
+ #ifdef CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+ return _GLOBAL_REENT;
+ #else
+ return _Thread_Get_executing()->libc_reent;
+ #endif
+ }
+#endif
+
+#endif
+
+/**
+ * @defgroup ConfigurationPOSIXAPI POSIX API Configuration Parameters
+ *
+ * This module contains the parameters related to configuration
+ * of the POSIX API services.
+ */
+/**@{*/
+
+#include <rtems/posix/key.h>
+
+/**
+ * This configuration parameter specifies the maximum number of
+ * POSIX API keys.
+ *
+ * POSIX Keys are available whether or not the POSIX API is enabled.
+ */
+#ifndef CONFIGURE_MAXIMUM_POSIX_KEYS
+ #define CONFIGURE_MAXIMUM_POSIX_KEYS 0
+#endif
+
+/*
+ * This macro is calculated to specify the memory required for
+ * POSIX API key/value pairs.
+ */
+#ifndef CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS
+ #define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS \
+ (CONFIGURE_MAXIMUM_POSIX_KEYS * \
+ (CONFIGURE_MAXIMUM_POSIX_THREADS + CONFIGURE_MAXIMUM_TASKS))
+#endif
+
+/*
+ * This macro is calculated to specify the total number of
+ * POSIX API keys required by the application and configured
+ * system capabilities.
+ */
+#define _CONFIGURE_POSIX_KEYS \
+ (CONFIGURE_MAXIMUM_POSIX_KEYS + _CONFIGURE_LIBIO_POSIX_KEYS)
+
+/*
+ * This macro is calculated to specify the memory required for
+ * POSIX API keys.
+ */
+#define _CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys, _key_value_pairs) \
+ (_Configure_Object_RAM(_keys, sizeof(POSIX_Keys_Control) ) \
+ + _Configure_From_workspace( \
+ _Configure_Max_Objects(_key_value_pairs) \
+ * sizeof(POSIX_Keys_Key_value_pair)))
+
+/*
+ * The rest of the POSIX threads API features are only available when
+ * POSIX is enabled.
+ */
+#ifdef RTEMS_POSIX_API
+ #include <sys/types.h>
+ #include <signal.h>
+ #include <limits.h>
+ #include <mqueue.h>
+ #include <rtems/posix/mqueue.h>
+ #include <rtems/posix/psignal.h>
+ #include <rtems/posix/pthread.h>
+ #include <rtems/posix/semaphore.h>
+ #include <rtems/posix/shm.h>
+ #include <rtems/posix/threadsup.h>
+ #include <rtems/posix/timer.h>
+
+ /*
+ * Account for the object control structures plus the name
+ * of the object to be duplicated.
+ */
+ #define _Configure_POSIX_Named_Object_RAM(_number, _size) \
+ (_Configure_Object_RAM(_number, _size) \
+ + _Configure_Max_Objects(_number) \
+ * _Configure_From_workspace(_POSIX_PATH_MAX + 1))
+
+ /**
+ * This configuration parameter specifies the maximum number of
+ * POSIX API threads.
+ */
+ #ifndef CONFIGURE_MAXIMUM_POSIX_THREADS
+ #define CONFIGURE_MAXIMUM_POSIX_THREADS 0
+ #endif
+
+ /**
+ * This configuration parameter specifies the maximum number of
+ * POSIX API timers.
+ */
+ #ifndef CONFIGURE_MAXIMUM_POSIX_TIMERS
+ #define CONFIGURE_MAXIMUM_POSIX_TIMERS 0
+ #endif
+
+ /*
+ * This macro is calculated to specify the memory required for
+ * POSIX API timers.
+ */
+ #define _CONFIGURE_MEMORY_FOR_POSIX_TIMERS(_timers) \
+ _Configure_Object_RAM(_timers, sizeof(POSIX_Timer_Control) )
+
+ /**
+ * This configuration parameter specifies the maximum number of
+ * POSIX API queued signals.
+ */
+ #ifndef CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS
+ #define CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS 0
+ #endif
+
+ /*
+ * This macro is calculated to specify the memory required for
+ * POSIX API queued signals.
+ */
+ #define _CONFIGURE_MEMORY_FOR_POSIX_QUEUED_SIGNALS(_queued_signals) \
+ _Configure_From_workspace( \
+ (_queued_signals) * (sizeof(POSIX_signals_Siginfo_node)) )
+
+ /**
+ * This configuration parameter specifies the maximum number of
+ * POSIX API message queues.
+ */
+ #ifndef CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES
+ #define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES 0
+ #endif
+
+ /*
+ * This macro is calculated to specify the memory required for
+ * POSIX API message queues.
+ */
+ #define _CONFIGURE_MEMORY_FOR_POSIX_MESSAGE_QUEUES(_message_queues) \
+ _Configure_POSIX_Named_Object_RAM( \
+ _message_queues, sizeof(POSIX_Message_queue_Control) )
+
+ /**
+ * This configuration parameter specifies the maximum number of
+ * POSIX API semaphores.
+ */
+ #ifndef CONFIGURE_MAXIMUM_POSIX_SEMAPHORES
+ #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 0
+ #endif
+
+ /*
+ * This macro is calculated to specify the memory required for
+ * POSIX API semaphores.
+ */
+ #define _CONFIGURE_MEMORY_FOR_POSIX_SEMAPHORES(_semaphores) \
+ _Configure_POSIX_Named_Object_RAM( \
+ _semaphores, sizeof(POSIX_Semaphore_Control) )
+
+ /**
+ * Configure the maximum number of POSIX shared memory objects.
+ */
+ #if !defined(CONFIGURE_MAXIMUM_POSIX_SHMS)
+ #define CONFIGURE_MAXIMUM_POSIX_SHMS 0
+ #else
+ #ifdef CONFIGURE_INIT
+ #if !defined(CONFIGURE_HAS_OWN_POSIX_SHM_OBJECT_OPERATIONS)
+ const POSIX_Shm_Object_operations _POSIX_Shm_Object_operations = {
+ _POSIX_Shm_Object_create_from_workspace,
+ _POSIX_Shm_Object_resize_from_workspace,
+ _POSIX_Shm_Object_delete_from_workspace,
+ _POSIX_Shm_Object_read_from_workspace,
+ _POSIX_Shm_Object_mmap_from_workspace
+ };
+ #endif
+ #endif
+ #endif
+
+ /*
+ * This macro is calculated to specify the memory required for
+ * POSIX API shared memory.
+ */
+ #define _CONFIGURE_MEMORY_FOR_POSIX_SHMS(_shms) \
+ _Configure_POSIX_Named_Object_RAM(_shms, sizeof(POSIX_Shm_Control) )
+
+
+ #ifdef CONFIGURE_POSIX_INIT_THREAD_TABLE
+
+ #ifdef CONFIGURE_POSIX_HAS_OWN_INIT_THREAD_TABLE
+
+ /*
+ * The user is defining their own table information and setting the
+ * appropriate variables for the POSIX Initialization Thread Table.
+ */
+
+ #else
+
+ #ifndef CONFIGURE_POSIX_INIT_THREAD_ENTRY_POINT
+ #define CONFIGURE_POSIX_INIT_THREAD_ENTRY_POINT POSIX_Init
+ #endif
+
+ #ifndef CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE
+ #define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE \
+ CONFIGURE_MINIMUM_POSIX_THREAD_STACK_SIZE
+ #endif
+
+ #ifdef CONFIGURE_INIT
+ posix_initialization_threads_table POSIX_Initialization_threads[] = {
+ { CONFIGURE_POSIX_INIT_THREAD_ENTRY_POINT, \
+ CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE }
+ };
+ #endif
+
+ #define CONFIGURE_POSIX_INIT_THREAD_TABLE_NAME \
+ POSIX_Initialization_threads
+
+ #define CONFIGURE_POSIX_INIT_THREAD_TABLE_SIZE \
+ RTEMS_ARRAY_SIZE(CONFIGURE_POSIX_INIT_THREAD_TABLE_NAME)
+
+ #endif /* CONFIGURE_POSIX_HAS_OWN_INIT_TASK_TABLE */
+
+ #else /* CONFIGURE_POSIX_INIT_THREAD_TABLE */
+
+ #define CONFIGURE_POSIX_INIT_THREAD_TABLE_NAME NULL
+ #define CONFIGURE_POSIX_INIT_THREAD_TABLE_SIZE 0
+
+ #endif
+
+#else
+
+ /**
+ * This configuration parameter specifies the maximum number of
+ * POSIX API threads.
+ */
+ #define CONFIGURE_MAXIMUM_POSIX_THREADS 0
+
+#endif /* RTEMS_POSIX_API */
+
+/**
+ * This configuration parameter specifies the stack size of the
+ * POSIX API Initialization thread (if used).
+ */
+#ifndef CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE
+ #define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE 0
+#endif
+/**@}*/ /* end of POSIX API Configuration */
+
+/**
+ * @defgroup ConfigurationGNAT GNAT/RTEMS Configuration
+ *
+ * @addtogroup Configuration
+ *
+ * This modules includes configuration parameters for applications which
+ * use GNAT/RTEMS. GNAT implements each Ada task as a POSIX thread.
+ */
+/**@{*/
+#ifdef CONFIGURE_GNAT_RTEMS
+ /**
+ * This is the maximum number of Ada tasks which can be concurrently
+ * in existence. Twenty (20) are required to run all tests in the
+ * ACATS (formerly ACVC).
+ */
+ #ifndef CONFIGURE_MAXIMUM_ADA_TASKS
+ #define CONFIGURE_MAXIMUM_ADA_TASKS 20
+ #endif
+
+ /**
+ * This is the number of non-Ada tasks which invoked Ada code.
+ */
+ #ifndef CONFIGURE_MAXIMUM_FAKE_ADA_TASKS
+ #define CONFIGURE_MAXIMUM_FAKE_ADA_TASKS 0
+ #endif
+#else
+ /** This defines he number of POSIX mutexes GNAT needs. */
+ /** This defines he number of Ada tasks needed by the application. */
+ #define CONFIGURE_MAXIMUM_ADA_TASKS 0
+ /**
+ * This defines he number of non-Ada tasks/threads that will invoke
+ * Ada subprograms or functions.
+ */
+ #define CONFIGURE_MAXIMUM_FAKE_ADA_TASKS 0
+#endif
+/**@}*/ /* end of GNAT Configuration */
+
+/**
+ * @defgroup ConfigurationGo GCC Go Configuration
+ *
+ * @addtogroup Configuration
+ *
+ * This modules includes configuration parameters for applications which
+ * use GCC Go.
+ */
+/**@{*/
+#ifdef CONFIGURE_ENABLE_GO
+
+ #ifndef CONFIGURE_MAXIMUM_POSIX_THREADS
+ #define CONFIGURE_MAXIMUM_POSIX_THREADS 1
+ #endif
+
+ #ifndef CONFIGURE_MAXIMUM_GOROUTINES
+ #define CONFIGURE_MAXIMUM_GOROUTINES 400
+ #endif
+
+ #ifndef CONFIGURE_MAXIMUM_GO_CHANNELS
+ #define CONFIGURE_MAXIMUM_GO_CHANNELS 500
+ #endif
+
+#else
+ /** This specifies the maximum number of Go co-routines. */
+ #define CONFIGURE_MAXIMUM_GOROUTINES 0
+
+ /** This specifies the maximum number of Go channels required. */
+ #define CONFIGURE_MAXIMUM_GO_CHANNELS 0
+#endif
+/**@}*/ /* end of Go Configuration */
+
+/**
+ * This is so we can account for tasks with stacks greater than minimum
+ * size. This is in bytes.
+ */
+#ifndef CONFIGURE_EXTRA_TASK_STACKS
+ #define CONFIGURE_EXTRA_TASK_STACKS 0
+#endif
+
+/**
+ * This macro provides a summation of the various POSIX thread requirements.
+ */
+#define _CONFIGURE_POSIX_THREADS \
+ (CONFIGURE_MAXIMUM_POSIX_THREADS + \
+ CONFIGURE_MAXIMUM_ADA_TASKS + \
+ CONFIGURE_MAXIMUM_GOROUTINES)
+
+#ifdef RTEMS_POSIX_API
+ /*
+ * This macro is calculated to specify the memory required for
+ * the POSIX API in its entirety.
+ */
+ #define _CONFIGURE_MEMORY_FOR_POSIX \
+ (_CONFIGURE_MEMORY_FOR_POSIX_QUEUED_SIGNALS( \
+ CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS) + \
+ _CONFIGURE_MEMORY_FOR_POSIX_MESSAGE_QUEUES( \
+ CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES) + \
+ _CONFIGURE_MEMORY_FOR_POSIX_SEMAPHORES( \
+ CONFIGURE_MAXIMUM_POSIX_SEMAPHORES) + \
+ _CONFIGURE_MEMORY_FOR_POSIX_SHMS( \
+ CONFIGURE_MAXIMUM_POSIX_SHMS) + \
+ _CONFIGURE_MEMORY_FOR_POSIX_TIMERS(CONFIGURE_MAXIMUM_POSIX_TIMERS))
+#else
+ /*
+ * This macro is calculated to specify the memory required for
+ * the POSIX API in its entirety.
+ */
+ #define _CONFIGURE_MEMORY_FOR_POSIX 0
+#endif
+
+/*
+ * We must be able to split the free block used for the second last allocation
+ * into two parts so that we have a free block for the last allocation. See
+ * _Heap_Block_split().
+ */
+#define _CONFIGURE_HEAP_HANDLER_OVERHEAD \
+ _Configure_Align_up( HEAP_BLOCK_HEADER_SIZE, CPU_HEAP_ALIGNMENT )
+
+/*
+ * Calculate the RAM size based on the maximum number of objects configured.
+ */
+#ifndef CONFIGURE_EXECUTIVE_RAM_SIZE
+
+/*
+ * Account for allocating the following per object
+ * + array of object control structures
+ * + local pointer table -- pointer per object plus a zero'th
+ * entry in the local pointer table.
+ */
+#define _CONFIGURE_MEMORY_FOR_TASKS(_tasks, _number_FP_tasks) \
+ ( \
+ _Configure_Object_RAM(_tasks, sizeof(Configuration_Thread_control)) \
+ + _Configure_From_workspace(_Configure_Max_Objects(_tasks) \
+ * THREAD_QUEUE_HEADS_SIZE(CONFIGURE_SCHEDULER_COUNT)) \
+ + _Configure_Max_Objects(_number_FP_tasks) \
+ * _Configure_From_workspace(CONTEXT_FP_SIZE) \
+ )
+
+/*
+ * This defines the amount of memory configured for the multiprocessing
+ * support required by this application.
+ */
+#ifdef CONFIGURE_MP_APPLICATION
+ #define _CONFIGURE_MEMORY_FOR_MP \
+ (_CONFIGURE_MEMORY_FOR_PROXIES(CONFIGURE_MP_MAXIMUM_PROXIES) + \
+ _CONFIGURE_MEMORY_FOR_GLOBAL_OBJECTS(CONFIGURE_MP_MAXIMUM_GLOBAL_OBJECTS))
+#else
+ #define _CONFIGURE_MEMORY_FOR_MP 0
+#endif
+
+/**
+ * The following macro is used to calculate the memory allocated by RTEMS
+ * for the message buffers associated with a particular message queue.
+ * There is a fixed amount of overhead per message.
+ */
+#define CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE(_messages, _size) \
+ _Configure_From_workspace( \
+ (_messages) * (_Configure_Align_up(_size, sizeof(uintptr_t)) \
+ + sizeof(CORE_message_queue_Buffer_control)))
+
+/*
+ * This macro is set to the amount of memory required for pending message
+ * buffers in bytes. It should be constructed by adding together a
+ * set of values determined by CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE.
+ */
+#ifndef CONFIGURE_MESSAGE_BUFFER_MEMORY
+ #define CONFIGURE_MESSAGE_BUFFER_MEMORY 0
+#endif
+
+/**
+ * This macro is available just in case the confdefs.h file underallocates
+ * memory for a particular application. This lets the user add some extra
+ * memory in case something broken and underestimates.
+ *
+ * It is also possible for cases where confdefs.h overallocates memory,
+ * you could substract memory from the allocated. The estimate is just
+ * that, an estimate, and assumes worst case alignment and padding on
+ * each allocated element. So in some cases it could be too conservative.
+ *
+ * NOTE: Historically this was used for message buffers.
+ */
+#ifndef CONFIGURE_MEMORY_OVERHEAD
+ #define CONFIGURE_MEMORY_OVERHEAD 0
+#endif
+
+/**
+ * This calculates the amount of memory reserved for the IDLE tasks.
+ * In an SMP system, each CPU core has its own idle task.
+ */
+#define _CONFIGURE_IDLE_TASKS_COUNT CONFIGURE_MAXIMUM_PROCESSORS
+
+/**
+ * This defines the formula used to compute the amount of memory
+ * reserved for internal task control structures.
+ */
+#if CPU_IDLE_TASK_IS_FP == TRUE
+ #define _CONFIGURE_MEMORY_FOR_INTERNAL_TASKS \
+ _CONFIGURE_MEMORY_FOR_TASKS( \
+ _CONFIGURE_IDLE_TASKS_COUNT + _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT, \
+ _CONFIGURE_IDLE_TASKS_COUNT + _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT \
+ )
+#else
+ #define _CONFIGURE_MEMORY_FOR_INTERNAL_TASKS \
+ _CONFIGURE_MEMORY_FOR_TASKS( \
+ _CONFIGURE_IDLE_TASKS_COUNT + _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT, \
+ _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT \
+ )
+#endif
+
+/**
+ * This macro accounts for general RTEMS system overhead.
+ */
+#define _CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD \
+ ( _CONFIGURE_MEMORY_FOR_INTERNAL_TASKS + \
+ _CONFIGURE_INTERRUPT_STACK_MEMORY \
+ )
+
+/**
+ * This macro reserves the memory required by the statically configured
+ * user extensions.
+ */
+#define _CONFIGURE_MEMORY_FOR_STATIC_EXTENSIONS \
+ (_CONFIGURE_NUMBER_OF_INITIAL_EXTENSIONS == 0 ? 0 : \
+ _Configure_From_workspace( \
+ _CONFIGURE_NUMBER_OF_INITIAL_EXTENSIONS \
+ * sizeof(User_extensions_Switch_control) \
+ ))
+
+/**
+ * This macro provides a summation of the memory required by the
+ * Classic API as configured.
+ */
+#define _CONFIGURE_MEMORY_FOR_CLASSIC \
+ (_CONFIGURE_MEMORY_FOR_TIMERS(CONFIGURE_MAXIMUM_TIMERS + \
+ _CONFIGURE_TIMER_FOR_SHARED_MEMORY_DRIVER ) + \
+ _CONFIGURE_MEMORY_FOR_SEMAPHORES(_CONFIGURE_SEMAPHORES) + \
+ _CONFIGURE_MEMORY_FOR_MESSAGE_QUEUES(CONFIGURE_MAXIMUM_MESSAGE_QUEUES) + \
+ _CONFIGURE_MEMORY_FOR_PARTITIONS(CONFIGURE_MAXIMUM_PARTITIONS) + \
+ _CONFIGURE_MEMORY_FOR_REGIONS( CONFIGURE_MAXIMUM_REGIONS ) + \
+ _CONFIGURE_MEMORY_FOR_PORTS(CONFIGURE_MAXIMUM_PORTS) + \
+ _CONFIGURE_MEMORY_FOR_PERIODS(CONFIGURE_MAXIMUM_PERIODS) + \
+ _CONFIGURE_MEMORY_FOR_BARRIERS(_CONFIGURE_BARRIERS) + \
+ _CONFIGURE_MEMORY_FOR_USER_EXTENSIONS(CONFIGURE_MAXIMUM_USER_EXTENSIONS) \
+ )
+
+/*
+ * This macro provides a summation of the memory required by SMP as configured.
+ */
+#if defined(RTEMS_SMP)
+ #define _CONFIGURE_MEMORY_FOR_SMP \
+ (CONFIGURE_MAXIMUM_PROCESSORS * \
+ _Configure_From_workspace( CONFIGURE_INTERRUPT_STACK_SIZE ) \
+ )
+#else
+ #define _CONFIGURE_MEMORY_FOR_SMP 0
+#endif
+
+/**
+ * This calculates the memory required for the executive workspace.
+ *
+ * This is an internal parameter.
+ */
+#define CONFIGURE_EXECUTIVE_RAM_SIZE \
+( \
+ _CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD + \
+ _CONFIGURE_MEMORY_FOR_TASKS( \
+ _CONFIGURE_TASKS, _CONFIGURE_TASKS) + \
+ _CONFIGURE_MEMORY_FOR_TASKS( \
+ _CONFIGURE_POSIX_THREADS, _CONFIGURE_POSIX_THREADS) + \
+ _CONFIGURE_MEMORY_FOR_CLASSIC + \
+ _CONFIGURE_MEMORY_FOR_POSIX_KEYS( \
+ _CONFIGURE_POSIX_KEYS, \
+ CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS ) + \
+ _CONFIGURE_MEMORY_FOR_POSIX + \
+ _CONFIGURE_MEMORY_FOR_STATIC_EXTENSIONS + \
+ _CONFIGURE_MEMORY_FOR_MP + \
+ _CONFIGURE_MEMORY_FOR_SMP + \
+ CONFIGURE_MESSAGE_BUFFER_MEMORY + \
+ (CONFIGURE_MEMORY_OVERHEAD * 1024) + \
+ _CONFIGURE_HEAP_HANDLER_OVERHEAD \
+)
+
+/*
+ * Now account for any extra memory that initialization tasks or threads
+ * may have requested.
+ */
+
+/*
+ * This accounts for any extra memory required by the Classic API
+ * Initialization Task.
+ */
+#if (CONFIGURE_INIT_TASK_STACK_SIZE > CONFIGURE_MINIMUM_TASK_STACK_SIZE)
+ #define _CONFIGURE_INITIALIZATION_THREADS_STACKS_CLASSIC_PART \
+ (CONFIGURE_INIT_TASK_STACK_SIZE - CONFIGURE_MINIMUM_TASK_STACK_SIZE)
+#else
+ #define _CONFIGURE_INITIALIZATION_THREADS_STACKS_CLASSIC_PART 0
+#endif
+
+/*
+ * This accounts for any extra memory required by the POSIX API
+ * Initialization Thread.
+ */
+#if defined(RTEMS_POSIX_API) && \
+ (CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE > \
+ CONFIGURE_MINIMUM_POSIX_THREAD_STACK_SIZE)
+ #define _CONFIGURE_INITIALIZATION_THREADS_STACKS_POSIX_PART \
+ (CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE - \
+ CONFIGURE_MINIMUM_POSIX_THREAD_STACK_SIZE)
+#else
+ #define _CONFIGURE_INITIALIZATION_THREADS_STACKS_POSIX_PART 0
+#endif
+
+/*
+ * This macro provides a summation of the various initialization task
+ * and thread stack requirements.
+ */
+#define _CONFIGURE_INITIALIZATION_THREADS_EXTRA_STACKS \
+ (_CONFIGURE_INITIALIZATION_THREADS_STACKS_CLASSIC_PART + \
+ _CONFIGURE_INITIALIZATION_THREADS_STACKS_POSIX_PART)
+
+/*
+ * This macro is calculated to specify the memory required for
+ * the Idle tasks(s) stack.
+ */
+#define _CONFIGURE_IDLE_TASKS_STACK \
+ (_CONFIGURE_IDLE_TASKS_COUNT * \
+ _Configure_From_stackspace( CONFIGURE_IDLE_TASK_STACK_SIZE ) )
+
+/*
+ * This macro is calculated to specify the stack memory required for the MPCI
+ * task.
+ */
+#define _CONFIGURE_MPCI_RECEIVE_SERVER_STACK \
+ (_CONFIGURE_MPCI_RECEIVE_SERVER_COUNT * \
+ _Configure_From_stackspace(CONFIGURE_MINIMUM_TASK_STACK_SIZE))
+
+/*
+ * This macro is calculated to specify the memory required for
+ * the stacks of all tasks.
+ */
+#define _CONFIGURE_TASKS_STACK \
+ (_Configure_Max_Objects( _CONFIGURE_TASKS ) * \
+ _Configure_From_stackspace( CONFIGURE_MINIMUM_TASK_STACK_SIZE ) )
+
+/*
+ * This macro is calculated to specify the memory required for
+ * the stacks of all POSIX threads.
+ */
+#define _CONFIGURE_POSIX_THREADS_STACK \
+ (_Configure_Max_Objects( CONFIGURE_MAXIMUM_POSIX_THREADS ) * \
+ _Configure_From_stackspace( CONFIGURE_MINIMUM_POSIX_THREAD_STACK_SIZE ) )
+
+/*
+ * This macro is calculated to specify the memory required for
+ * the stacks of all Ada tasks.
+ */
+#define _CONFIGURE_ADA_TASKS_STACK \
+ (_Configure_Max_Objects( CONFIGURE_MAXIMUM_ADA_TASKS ) * \
+ _Configure_From_stackspace( CONFIGURE_MINIMUM_POSIX_THREAD_STACK_SIZE ) )
+
+/*
+ * This macro is calculated to specify the memory required for
+ * the stacks of all Go routines.
+ */
+#define _CONFIGURE_GOROUTINES_STACK \
+ (_Configure_Max_Objects( CONFIGURE_MAXIMUM_GOROUTINES ) * \
+ _Configure_From_stackspace( CONFIGURE_MINIMUM_POSIX_THREAD_STACK_SIZE ) )
+
+#else /* CONFIGURE_EXECUTIVE_RAM_SIZE */
+
+#define _CONFIGURE_IDLE_TASKS_STACK 0
+#define _CONFIGURE_MPCI_RECEIVE_SERVER_STACK 0
+#define _CONFIGURE_INITIALIZATION_THREADS_EXTRA_STACKS 0
+#define _CONFIGURE_TASKS_STACK 0
+#define _CONFIGURE_POSIX_THREADS_STACK 0
+#define _CONFIGURE_GOROUTINES_STACK 0
+#define _CONFIGURE_ADA_TASKS_STACK 0
+
+#if CONFIGURE_EXTRA_MPCI_RECEIVE_SERVER_STACK != 0
+ #error "CONFIGURE_EXECUTIVE_RAM_SIZE defined with request for CONFIGURE_EXTRA_MPCI_RECEIVE_SERVER_STACK"
+#endif
+
+#if CONFIGURE_EXTRA_TASK_STACKS != 0
+ #error "CONFIGURE_EXECUTIVE_RAM_SIZE defined with request for CONFIGURE_EXTRA_TASK_STACKS"
+#endif
+
+#endif /* CONFIGURE_EXECUTIVE_RAM_SIZE */
+
+/*
+ * This macro is calculated to specify the memory required for
+ * all tasks and threads of all varieties.
+ */
+#define _CONFIGURE_STACK_SPACE_SIZE \
+ ( \
+ _CONFIGURE_IDLE_TASKS_STACK + \
+ _CONFIGURE_MPCI_RECEIVE_SERVER_STACK + \
+ _CONFIGURE_INITIALIZATION_THREADS_EXTRA_STACKS + \
+ _CONFIGURE_TASKS_STACK + \
+ _CONFIGURE_POSIX_THREADS_STACK + \
+ _CONFIGURE_GOROUTINES_STACK + \
+ _CONFIGURE_ADA_TASKS_STACK + \
+ CONFIGURE_EXTRA_MPCI_RECEIVE_SERVER_STACK + \
+ _CONFIGURE_LIBBLOCK_TASK_EXTRA_STACKS + \
+ CONFIGURE_EXTRA_TASK_STACKS + \
+ _CONFIGURE_HEAP_HANDLER_OVERHEAD \
+ )
+
+#ifndef CONFIGURE_MAXIMUM_THREAD_NAME_SIZE
+ #define CONFIGURE_MAXIMUM_THREAD_NAME_SIZE 16
+#endif
+
+#ifdef CONFIGURE_INIT
+ typedef union {
+ Scheduler_Node Base;
+ #ifdef CONFIGURE_SCHEDULER_CBS
+ Scheduler_CBS_Node CBS;
+ #endif
+ #ifdef CONFIGURE_SCHEDULER_EDF
+ Scheduler_EDF_Node EDF;
+ #endif
+ #ifdef CONFIGURE_SCHEDULER_EDF_SMP
+ Scheduler_EDF_SMP_Node EDF_SMP;
+ #endif
+ #ifdef CONFIGURE_SCHEDULER_PRIORITY
+ Scheduler_priority_Node Priority;
+ #endif
+ #ifdef CONFIGURE_SCHEDULER_SIMPLE_SMP
+ Scheduler_SMP_Node Simple_SMP;
+ #endif
+ #ifdef CONFIGURE_SCHEDULER_PRIORITY_SMP
+ Scheduler_priority_SMP_Node Priority_SMP;
+ #endif
+ #ifdef CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP
+ Scheduler_priority_affinity_SMP_Node Priority_affinity_SMP;
+ #endif
+ #ifdef CONFIGURE_SCHEDULER_STRONG_APA
+ Scheduler_strong_APA_Node Strong_APA;
+ #endif
+ #ifdef CONFIGURE_SCHEDULER_USER_PER_THREAD
+ CONFIGURE_SCHEDULER_USER_PER_THREAD User;
+ #endif
+ } Configuration_Scheduler_node;
+
+ #ifdef RTEMS_SMP
+ const size_t _Scheduler_Node_size = sizeof( Configuration_Scheduler_node );
+ #endif
+
+ const size_t _Thread_Maximum_name_size = CONFIGURE_MAXIMUM_THREAD_NAME_SIZE;
+
+ typedef struct {
+ Thread_Control Control;
+ #if CONFIGURE_MAXIMUM_USER_EXTENSIONS > 0
+ void *extensions[ CONFIGURE_MAXIMUM_USER_EXTENSIONS + 1 ];
+ #endif
+ Configuration_Scheduler_node Scheduler_nodes[ CONFIGURE_SCHEDULER_COUNT ];
+ RTEMS_API_Control API_RTEMS;
+ #ifdef RTEMS_POSIX_API
+ POSIX_API_Control API_POSIX;
+ #endif
+ #if CONFIGURE_MAXIMUM_THREAD_NAME_SIZE > 1
+ char name[ CONFIGURE_MAXIMUM_THREAD_NAME_SIZE ];
+ #endif
+ #if !defined(RTEMS_SCHEDSIM) \
+ && defined(RTEMS_NEWLIB) \
+ && !defined(CONFIGURE_DISABLE_NEWLIB_REENTRANCY)
+ struct _reent Newlib;
+ #else
+ struct { /* Empty */ } Newlib;
+ #endif
+ } Configuration_Thread_control;
+
+ const size_t _Thread_Control_size = sizeof( Configuration_Thread_control );
+
+ const Thread_Control_add_on _Thread_Control_add_ons[] = {
+ {
+ offsetof( Configuration_Thread_control, Control.Scheduler.nodes ),
+ offsetof( Configuration_Thread_control, Scheduler_nodes )
+ }, {
+ offsetof(
+ Configuration_Thread_control,
+ Control.API_Extensions[ THREAD_API_RTEMS ]
+ ),
+ offsetof( Configuration_Thread_control, API_RTEMS )
+ }, {
+ offsetof(
+ Configuration_Thread_control,
+ Control.libc_reent
+ ),
+ offsetof( Configuration_Thread_control, Newlib )
+ }
+ #if CONFIGURE_MAXIMUM_THREAD_NAME_SIZE > 1
+ , {
+ offsetof(
+ Configuration_Thread_control,
+ Control.Join_queue.Queue.name
+ ),
+ offsetof( Configuration_Thread_control, name )
+ }
+ #endif
+ #ifdef RTEMS_POSIX_API
+ , {
+ offsetof(
+ Configuration_Thread_control,
+ Control.API_Extensions[ THREAD_API_POSIX ]
+ ),
+ offsetof( Configuration_Thread_control, API_POSIX )
+ }
+ #endif
+ };
+
+ const size_t _Thread_Control_add_on_count =
+ RTEMS_ARRAY_SIZE( _Thread_Control_add_ons );
+
+ const uint32_t _Watchdog_Nanoseconds_per_tick =
+ 1000 * CONFIGURE_MICROSECONDS_PER_TICK;
+
+ const uint32_t _Watchdog_Ticks_per_second = _CONFIGURE_TICKS_PER_SECOND;
+
+ const uint64_t _Watchdog_Monotonic_max_seconds =
+ UINT64_MAX / _CONFIGURE_TICKS_PER_SECOND;
+
+ /**
+ * This is the Classic API Configuration Table.
+ */
+ rtems_api_configuration_table Configuration_RTEMS_API = {
+ _CONFIGURE_TASKS,
+ CONFIGURE_MAXIMUM_TIMERS + _CONFIGURE_TIMER_FOR_SHARED_MEMORY_DRIVER,
+ _CONFIGURE_SEMAPHORES,
+ CONFIGURE_MAXIMUM_MESSAGE_QUEUES,
+ CONFIGURE_MAXIMUM_PARTITIONS,
+ CONFIGURE_MAXIMUM_REGIONS,
+ CONFIGURE_MAXIMUM_PORTS,
+ CONFIGURE_MAXIMUM_PERIODS,
+ _CONFIGURE_BARRIERS,
+ CONFIGURE_INIT_TASK_TABLE_SIZE,
+ CONFIGURE_INIT_TASK_TABLE
+ };
+
+ #ifdef RTEMS_POSIX_API
+ /**
+ * This is the POSIX API Configuration Table.
+ */
+ posix_api_configuration_table Configuration_POSIX_API = {
+ _CONFIGURE_POSIX_THREADS,
+ CONFIGURE_MAXIMUM_POSIX_TIMERS,
+ CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS,
+ CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES,
+ CONFIGURE_MAXIMUM_POSIX_SEMAPHORES,
+ CONFIGURE_MAXIMUM_POSIX_SHMS,
+ CONFIGURE_POSIX_INIT_THREAD_TABLE_SIZE,
+ CONFIGURE_POSIX_INIT_THREAD_TABLE_NAME
+ };
+ #endif
+
+ /**
+ * This variable specifies the minimum stack size for tasks in an RTEMS
+ * application.
+ *
+ * NOTE: This is left as a simple uint32_t so it can be externed as
+ * needed without requring being high enough logical to
+ * include the full configuration table.
+ */
+ uint32_t rtems_minimum_stack_size =
+ CONFIGURE_MINIMUM_TASK_STACK_SIZE;
+
+ /**
+ * This is the primary Configuration Table for this application.
+ */
+ const rtems_configuration_table Configuration = {
+ CONFIGURE_EXECUTIVE_RAM_SIZE, /* required RTEMS workspace */
+ _CONFIGURE_STACK_SPACE_SIZE, /* required stack space */
+ CONFIGURE_MAXIMUM_USER_EXTENSIONS, /* maximum dynamic extensions */
+ _CONFIGURE_POSIX_KEYS, /* POSIX keys are always */
+ CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS, /* enabled */
+ CONFIGURE_MICROSECONDS_PER_TICK, /* microseconds per clock tick */
+ CONFIGURE_TICKS_PER_TIMESLICE, /* ticks per timeslice quantum */
+ CONFIGURE_IDLE_TASK_BODY, /* user's IDLE task */
+ CONFIGURE_IDLE_TASK_STACK_SIZE, /* IDLE task stack size */
+ CONFIGURE_INTERRUPT_STACK_SIZE, /* interrupt stack size */
+ CONFIGURE_TASK_STACK_ALLOCATOR_INIT, /* stack allocator init */
+ CONFIGURE_TASK_STACK_ALLOCATOR, /* stack allocator */
+ CONFIGURE_TASK_STACK_DEALLOCATOR, /* stack deallocator */
+ CONFIGURE_ZERO_WORKSPACE_AUTOMATICALLY, /* true to clear memory */
+ #ifdef CONFIGURE_UNIFIED_WORK_AREAS /* true for unified work areas */
+ true,
+ #else
+ false,
+ #endif
+ #ifdef CONFIGURE_TASK_STACK_ALLOCATOR_AVOIDS_WORK_SPACE /* true to avoid
+ work space for thread stack
+ allocation */
+ true,
+ #else
+ false,
+ #endif
+ #ifdef RTEMS_SMP
+ #ifdef _CONFIGURE_SMP_APPLICATION
+ true,
+ #else
+ false,
+ #endif
+ #endif
+ _CONFIGURE_NUMBER_OF_INITIAL_EXTENSIONS, /* number of static extensions */
+ CONFIGURE_INITIAL_EXTENSION_TABLE, /* pointer to static extensions */
+ #if defined(RTEMS_MULTIPROCESSING)
+ CONFIGURE_MULTIPROCESSING_TABLE, /* pointer to MP config table */
+ #endif
+ #ifdef RTEMS_SMP
+ CONFIGURE_MAXIMUM_PROCESSORS,
+ #endif
+ };
+#endif
+
+#endif /* CONFIGURE_HAS_OWN_CONFIGURATION_TABLE */
+
+#if defined(RTEMS_SMP)
+ /*
+ * Instantiate the Per CPU information based upon the user configuration.
+ */
+ #if defined(CONFIGURE_INIT)
+ Per_CPU_Control_envelope _Per_CPU_Information[CONFIGURE_MAXIMUM_PROCESSORS];
+ #endif
+
+#endif
+
+/*
+ * If the user has configured a set of Classic API Initialization Tasks,
+ * then we need to install the code that runs that loop.
+ */
+#ifdef CONFIGURE_INIT
+ #if defined(CONFIGURE_RTEMS_INIT_TASKS_TABLE) || \
+ defined(CONFIGURE_HAS_OWN_INIT_TASK_TABLE)
+ RTEMS_SYSINIT_ITEM(
+ _RTEMS_tasks_Initialize_user_tasks_body,
+ RTEMS_SYSINIT_CLASSIC_USER_TASKS,
+ RTEMS_SYSINIT_ORDER_MIDDLE
+ );
+ #endif
+#endif
+
+/*
+ * If the user has configured a set of POSIX Initialization Threads,
+ * then we need to install the code that runs that loop.
+ */
+#ifdef RTEMS_POSIX_API
+ #ifdef CONFIGURE_INIT
+ #if defined(CONFIGURE_POSIX_INIT_THREAD_TABLE) || \
+ defined(CONFIGURE_POSIX_HAS_OWN_INIT_THREAD_TABLE)
+ RTEMS_SYSINIT_ITEM(
+ _POSIX_Threads_Initialize_user_threads_body,
+ RTEMS_SYSINIT_POSIX_USER_THREADS,
+ RTEMS_SYSINIT_ORDER_MIDDLE
+ );
+ #endif
+ #endif
+#endif
+
+/*
+ * Select PCI Configuration Library
+ */
+#ifdef RTEMS_PCI_CONFIG_LIB
+ #ifdef CONFIGURE_INIT
+ #define PCI_LIB_NONE 0
+ #define PCI_LIB_AUTO 1
+ #define PCI_LIB_STATIC 2
+ #define PCI_LIB_READ 3
+ #define PCI_LIB_PERIPHERAL 4
+ #if CONFIGURE_PCI_LIB == PCI_LIB_AUTO
+ #define PCI_CFG_AUTO_LIB
+ #include <pci/cfg.h>
+ struct pci_bus pci_hb;
+ #define PCI_LIB_INIT pci_config_auto
+ #define PCI_LIB_CONFIG pci_config_auto_register
+ #elif CONFIGURE_PCI_LIB == PCI_LIB_STATIC
+ #define PCI_CFG_STATIC_LIB
+ #include <pci/cfg.h>
+ #define PCI_LIB_INIT pci_config_static
+ #define PCI_LIB_CONFIG NULL
+ /* Let user define PCI configuration (struct pci_bus pci_hb) */
+ #elif CONFIGURE_PCI_LIB == PCI_LIB_READ
+ #define PCI_CFG_READ_LIB
+ #include <pci/cfg.h>
+ #define PCI_LIB_INIT pci_config_read
+ #define PCI_LIB_CONFIG NULL
+ struct pci_bus pci_hb;
+ #elif CONFIGURE_PCI_LIB == PCI_LIB_PERIPHERAL
+ #define PCI_LIB_INIT pci_config_peripheral
+ #define PCI_LIB_CONFIG NULL
+ /* Let user define PCI configuration (struct pci_bus pci_hb) */
+ #elif CONFIGURE_PCI_LIB == PCI_LIB_NONE
+ #define PCI_LIB_INIT NULL
+ #define PCI_LIB_CONFIG NULL
+ /* No PCI Configuration at all, user can use/debug access routines */
+ #else
+ #error NO PCI LIBRARY DEFINED
+ #endif
+
+ const int pci_config_lib_type = CONFIGURE_PCI_LIB;
+ int (*pci_config_lib_init)(void) = PCI_LIB_INIT;
+ void (*pci_config_lib_register)(void *config) = PCI_LIB_CONFIG;
+ #endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/******************************************************************
+ ******************************************************************
+ ******************************************************************
+ * CONFIGURATION WARNINGS AND ERROR CHECKING *
+ ******************************************************************
+ ******************************************************************
+ ******************************************************************
+ */
+
+#if defined(CONFIGURE_CONFDEFS_DEBUG) && defined(CONFIGURE_INIT)
+ /**
+ * This is a debug mechanism, so if you need to, the executable will
+ * have a structure with various partial values. Add to this as you
+ * need to. Viewing this structure in gdb combined with dumping
+ * the Configuration structures generated should help a lot in tracing
+ * down errors and analyzing where over and under allocations are.
+ */
+ typedef struct {
+ uint32_t SYSTEM_OVERHEAD;
+ uint32_t STATIC_EXTENSIONS;
+ uint32_t INITIALIZATION_THREADS_STACKS;
+
+ uint32_t PER_INTEGER_TASK;
+ uint32_t FP_OVERHEAD;
+ uint32_t CLASSIC;
+ uint32_t POSIX;
+
+ /* System overhead pieces */
+ uint32_t INTERRUPT_STACK_MEMORY;
+ uint32_t MEMORY_FOR_IDLE_TASK;
+
+ /* Classic API Pieces */
+ uint32_t CLASSIC_TASKS;
+ uint32_t TIMERS;
+ uint32_t SEMAPHORES;
+ uint32_t MESSAGE_QUEUES;
+ uint32_t PARTITIONS;
+ uint32_t REGIONS;
+ uint32_t PORTS;
+ uint32_t PERIODS;
+ uint32_t BARRIERS;
+ uint32_t USER_EXTENSIONS;
+
+ /* POSIX API managers that are always enabled */
+ uint32_t POSIX_KEYS;
+
+#ifdef RTEMS_POSIX_API
+ /* POSIX API Pieces */
+ uint32_t POSIX_TIMERS;
+ uint32_t POSIX_QUEUED_SIGNALS;
+ uint32_t POSIX_MESSAGE_QUEUES;
+ uint32_t POSIX_SEMAPHORES;
+ uint32_t POSIX_SHMS;
+#endif
+
+ /* Stack space sizes */
+ uint32_t IDLE_TASKS_STACK;
+ uint32_t INITIALIZATION_THREADS_EXTRA_STACKS;
+ uint32_t TASKS_STACK;
+ uint32_t POSIX_THREADS_STACK;
+ uint32_t GOROUTINES_STACK;
+ uint32_t ADA_TASKS_STACK;
+ uint32_t EXTRA_MPCI_RECEIVE_SERVER_STACK;
+ uint32_t EXTRA_TASK_STACKS;
+ } Configuration_Debug_t;
+
+ Configuration_Debug_t Configuration_Memory_Debug = {
+ /* General Information */
+ _CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD,
+ _CONFIGURE_MEMORY_FOR_STATIC_EXTENSIONS,
+ _CONFIGURE_INITIALIZATION_THREADS_EXTRA_STACKS,
+ _CONFIGURE_MEMORY_FOR_TASKS(1, 0),
+ _CONFIGURE_MEMORY_FOR_TASKS(0, 1),
+ _CONFIGURE_MEMORY_FOR_CLASSIC,
+ _CONFIGURE_MEMORY_FOR_POSIX,
+
+ /* System overhead pieces */
+ _CONFIGURE_INTERRUPT_STACK_MEMORY,
+ _CONFIGURE_MEMORY_FOR_INTERNAL_TASKS,
+
+ /* Classic API Pieces */
+ _CONFIGURE_MEMORY_FOR_TASKS(CONFIGURE_MAXIMUM_TASKS, 0),
+ _CONFIGURE_MEMORY_FOR_TIMERS(CONFIGURE_MAXIMUM_TIMERS),
+ _CONFIGURE_MEMORY_FOR_SEMAPHORES(_CONFIGURE_SEMAPHORES),
+ _CONFIGURE_MEMORY_FOR_MESSAGE_QUEUES(CONFIGURE_MAXIMUM_MESSAGE_QUEUES),
+ _CONFIGURE_MEMORY_FOR_PARTITIONS(CONFIGURE_MAXIMUM_PARTITIONS),
+ _CONFIGURE_MEMORY_FOR_REGIONS( CONFIGURE_MAXIMUM_REGIONS ),
+ _CONFIGURE_MEMORY_FOR_PORTS(CONFIGURE_MAXIMUM_PORTS),
+ _CONFIGURE_MEMORY_FOR_PERIODS(CONFIGURE_MAXIMUM_PERIODS),
+ _CONFIGURE_MEMORY_FOR_BARRIERS(_CONFIGURE_BARRIERS),
+ _CONFIGURE_MEMORY_FOR_USER_EXTENSIONS(CONFIGURE_MAXIMUM_USER_EXTENSIONS),
+ _CONFIGURE_MEMORY_FOR_POSIX_KEYS( _CONFIGURE_POSIX_KEYS, \
+ CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS ),
+
+#ifdef RTEMS_POSIX_API
+ /* POSIX API Pieces */
+ _CONFIGURE_MEMORY_FOR_POSIX_QUEUED_SIGNALS(
+ CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS ),
+ _CONFIGURE_MEMORY_FOR_POSIX_MESSAGE_QUEUES(
+ CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES ),
+ _CONFIGURE_MEMORY_FOR_POSIX_SEMAPHORES( CONFIGURE_MAXIMUM_POSIX_SEMAPHORES ),
+ _CONFIGURE_MEMORY_FOR_POSIX_SHMS( CONFIGURE_MAXIMUM_POSIX_SHMS ),
+ _CONFIGURE_MEMORY_FOR_POSIX_TIMERS( CONFIGURE_MAXIMUM_POSIX_TIMERS ),
+#endif
+
+ /* Stack space sizes */
+ _CONFIGURE_IDLE_TASKS_STACK,
+ _CONFIGURE_INITIALIZATION_THREADS_EXTRA_STACKS,
+ _CONFIGURE_TASKS_STACK,
+ _CONFIGURE_POSIX_THREADS_STACK,
+ _CONFIGURE_GOROUTINES_STACK,
+ _CONFIGURE_ADA_TASKS_STACK,
+ CONFIGURE_EXTRA_MPCI_RECEIVE_SERVER_STACK,
+ CONFIGURE_EXTRA_TASK_STACKS
+ };
+#endif
+
+/*
+ * Make sure a task/thread of some sort is configured.
+ *
+ * When analyzing RTEMS to find the smallest possible of memory
+ * that must be allocated, you probably do want to configure 0
+ * tasks/threads so there is a smaller set of calls to _Workspace_Allocate
+ * to analyze.
+ */
+#if !defined(CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION)
+ #if (CONFIGURE_MAXIMUM_TASKS == 0) && \
+ (CONFIGURE_MAXIMUM_POSIX_THREADS == 0) && \
+ (CONFIGURE_MAXIMUM_ADA_TASKS == 0) && \
+ (CONFIGURE_MAXIMUM_GOROUTINES == 0)
+ #error "CONFIGURATION ERROR: No tasks or threads configured!!"
+ #endif
+#endif
+
+#ifndef RTEMS_SCHEDSIM
+/*
+ * Make sure at least one of the initialization task/thread
+ * tables was defined.
+ */
+#if !defined(CONFIGURE_RTEMS_INIT_TASKS_TABLE) && \
+ !defined(CONFIGURE_POSIX_INIT_THREAD_TABLE) && \
+ !defined(CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION)
+#error "CONFIGURATION ERROR: No initialization tasks or threads configured!!"
+#endif
+#endif
+
+/*
+ * If the user is trying to configure a multiprocessing application and
+ * RTEMS was not configured and built multiprocessing, then error out.
+ */
+#if defined(CONFIGURE_MP_APPLICATION) && \
+ !defined(RTEMS_MULTIPROCESSING)
+#error "CONFIGURATION ERROR: RTEMS not configured for multiprocessing!!"
+#endif
+
+/*
+ * If an attempt was made to configure POSIX objects and
+ * the POSIX API was not configured into RTEMS, error out.
+ *
+ * @note POSIX Keys are always available so the parameters
+ * CONFIGURE_MAXIMUM_POSIX_KEYS and
+ * CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS are not in this list.
+ */
+#if !defined(RTEMS_POSIX_API)
+ #if ((CONFIGURE_MAXIMUM_POSIX_THREADS != 0) || \
+ (CONFIGURE_MAXIMUM_POSIX_TIMERS != 0) || \
+ (CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS != 0) || \
+ (CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES != 0) || \
+ (CONFIGURE_MAXIMUM_POSIX_SEMAPHORES != 0) || \
+ (CONFIGURE_MAXIMUM_POSIX_SHMS != 0) || \
+ defined(CONFIGURE_POSIX_INIT_THREAD_TABLE))
+ #error "CONFIGURATION ERROR: POSIX API support not configured!!"
+ #endif
+#endif
+
+#if !defined(RTEMS_SCHEDSIM)
+ #if !defined(CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE)
+ /*
+ * You must either explicity include or exclude the clock driver.
+ * It is such a common newbie error to leave it out. Maybe this
+ * will put an end to it.
+ *
+ * NOTE: If you are using the timer driver, it is considered
+ * mutually exclusive with the clock driver because the
+ * drivers are assumed to use the same "timer" hardware
+ * on many boards.
+ */
+ #if !defined(CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER) && \
+ !defined(CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER) && \
+ !defined(CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER)
+ #error "CONFIGURATION ERROR: Do you want the clock driver or not?!?"
+ #endif
+
+ /*
+ * Only one of the following three configuration parameters should be
+ * defined at a time.
+ */
+ #if ((defined(CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER) + \
+ defined(CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER) + \
+ defined(CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER)) > 1)
+ #error "CONFIGURATION ERROR: More than one clock/timer driver configuration parameter specified?!?"
+ #endif
+ #endif /* !defined(CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE) */
+#endif /* !defined(RTEMS_SCHEDSIM) */
+
+/*
+ * These names have been obsoleted so make the user application stop compiling
+ */
+#if defined(CONFIGURE_TEST_NEEDS_TIMER_DRIVER) || \
+ defined(CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER) || \
+ defined(CONFIGURE_TEST_NEEDS_CLOCK_DRIVER) || \
+ defined(CONFIGURE_TEST_NEEDS_RTC_DRIVER) || \
+ defined(CONFIGURE_TEST_NEEDS_STUB_DRIVER)
+#error "CONFIGURATION ERROR: CONFIGURE_TEST_XXX constants are obsolete"
+#endif
+
+/*
+ * Validate the configured maximum priority
+ */
+#if ((CONFIGURE_MAXIMUM_PRIORITY != 3) && \
+ (CONFIGURE_MAXIMUM_PRIORITY != 7) && \
+ (CONFIGURE_MAXIMUM_PRIORITY != 15) && \
+ (CONFIGURE_MAXIMUM_PRIORITY != 31) && \
+ (CONFIGURE_MAXIMUM_PRIORITY != 63) && \
+ (CONFIGURE_MAXIMUM_PRIORITY != 127) && \
+ (CONFIGURE_MAXIMUM_PRIORITY != 255))
+ #error "Maximum priority is not 1 less than a power of 2 between 4 and 256"
+#endif
+
+#if (CONFIGURE_MAXIMUM_PRIORITY > PRIORITY_DEFAULT_MAXIMUM)
+ #error "Maximum priority configured higher than supported by target."
+#endif
+
+#ifdef CONFIGURE_MAXIMUM_POSIX_BARRIERS
+ #warning "The CONFIGURE_MAXIMUM_POSIX_BARRIERS configuration option is obsolete since RTEMS 5.1"
+#endif
+
+#ifdef CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES
+ #warning "The CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES configuration option is obsolete since RTEMS 5.1"
+#endif
+
+#ifdef CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUE_DESCRIPTORS
+ #warning "The CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUE_DESCRIPTORS configuration option is obsolete since RTEMS 5.1"
+#endif
+
+#ifdef CONFIGURE_MAXIMUM_POSIX_MUTEXES
+ #warning "The CONFIGURE_MAXIMUM_POSIX_MUTEXES configuration option is obsolete since RTEMS 5.1"
+#endif
+
+#ifdef CONFIGURE_MAXIMUM_POSIX_RWLOCKS
+ #warning "The CONFIGURE_MAXIMUM_POSIX_RWLOCKS configuration option is obsolete since RTEMS 5.1"
+#endif
+
+#ifdef CONFIGURE_MAXIMUM_POSIX_SPINLOCKS
+ #warning "The CONFIGURE_MAXIMUM_POSIX_SPINLOCKS configuration option is obsolete since RTEMS 5.1"
+#endif
+
+/*
+ * POSIX Key pair shouldn't be less than POSIX Key, which is highly
+ * likely to be error.
+ */
+#if (CONFIGURE_MAXIMUM_POSIX_KEYS != 0) && \
+ (CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS != 0)
+ #if (CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS < CONFIGURE_MAXIMUM_POSIX_KEYS)
+ #error "Fewer POSIX Key pairs than POSIX Key!"
+ #endif
+#endif
+
+/*
+ * IMFS block size for in memory files (memfiles) must be a power of
+ * two between 16 and 512 inclusive.
+ */
+#if ((CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK != 16) && \
+ (CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK != 32) && \
+ (CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK != 64) && \
+ (CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK != 128) && \
+ (CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK != 256) && \
+ (CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK != 512))
+ #error "IMFS Memfile block size must be a power of 2 between 16 and 512"
+#endif
+
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/config.h b/cpukit/include/rtems/config.h
new file mode 100644
index 0000000000..6b97376511
--- /dev/null
+++ b/cpukit/include/rtems/config.h
@@ -0,0 +1,397 @@
+/**
+ * @file
+ *
+ * @brief Table of User Defined Configuration Parameters
+ *
+ * This include file contains the table of user defined configuration
+ * parameters.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_CONFIG_H
+#define _RTEMS_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Unlimited object support. Changes the configuration table entry for POSIX
+ * or RTEMS APIs to bounded only by the memory of the work-space.
+ *
+ * Use the macro to define the resource unlimited before placing in
+ * the configuration table.
+ */
+
+#include <rtems/score/object.h>
+#define RTEMS_UNLIMITED_OBJECTS OBJECTS_UNLIMITED_OBJECTS
+
+#define rtems_resource_unlimited(resource) \
+ ( resource | RTEMS_UNLIMITED_OBJECTS )
+
+#define rtems_resource_is_unlimited(resource) \
+ _Objects_Is_unlimited(resource)
+
+#define rtems_resource_maximum_per_allocation(resource) \
+ _Objects_Maximum_per_allocation(resource)
+
+#include <rtems/score/watchdog.h>
+
+/*
+ * This is kind of kludgy but it allows targets to totally ignore the
+ * optional APIs like POSIX safely.
+ */
+
+#ifdef RTEMS_POSIX_API
+#include <rtems/posix/config.h>
+#else
+typedef void *posix_api_configuration_table;
+#endif
+
+#include <rtems/rtems/config.h>
+
+#include <rtems/extension.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+
+#if defined(RTEMS_MULTIPROCESSING)
+/*
+ * The following records define the Multiprocessor Configuration
+ * Table. This table defines the multiprocessor system
+ * characteristics which must be known by RTEMS in a multiprocessor
+ * system.
+ */
+typedef struct {
+ /** This is the local node number. */
+ uint32_t node;
+ /** This is the maximum number of nodes in system. */
+ uint32_t maximum_nodes;
+ /** This is the maximum number of global objects. */
+ uint32_t maximum_global_objects;
+ /** This is the maximum number of proxies. */
+ uint32_t maximum_proxies;
+
+ /**
+ * The MPCI Receive server is assumed to have a stack of at least
+ * minimum stack size. This field specifies the amount of extra
+ * stack this task will be given in bytes.
+ */
+ uint32_t extra_mpci_receive_server_stack;
+
+ /** This is a pointer to User/BSP provided MPCI Table. */
+ rtems_mpci_table *User_mpci_table;
+} rtems_multiprocessing_table;
+#endif
+
+/**
+ * @brief Task stack allocator initialization hook.
+ *
+ * @param[in] stack_space_size is the size of the stack space in bytes.
+ */
+typedef void (*rtems_stack_allocate_init_hook)( size_t stack_space_size );
+
+/**
+ * @brief Task stack allocator hook.
+ *
+ * @param[in] stack_size is the Size of the task stack in bytes.
+ *
+ * @retval NULL Not enough memory.
+ * @retval other Pointer to task stack.
+ */
+typedef void *(*rtems_stack_allocate_hook)( size_t stack_size );
+
+/**
+ * @brief Task stack deallocator hook.
+ *
+ * @param[in] addr is a pointer to previously allocated task stack.
+ */
+typedef void (*rtems_stack_free_hook)( void *addr );
+
+/*
+ * The following records define the Configuration Table. The
+ * information contained in this table is required in all
+ * RTEMS systems, whether single or multiprocessor. This
+ * table primarily defines the following:
+ *
+ * + location and size of the RTEMS Workspace
+ * + microseconds per clock tick
+ * + clock ticks per task timeslice
+ * + required number of each object type for each API configured
+ */
+typedef struct {
+ /**
+ * This field specifies the size in bytes of the RTEMS Workspace.
+ */
+ uintptr_t work_space_size;
+
+ /**
+ * This field specifies the size in bytes of the RTEMS thread stack space.
+ */
+ uintptr_t stack_space_size;
+
+ /**
+ * This field specifies the maximum number of dynamically installed
+ * used extensions.
+ */
+ uint32_t maximum_extensions;
+
+ /**
+ * This field contains the maximum number of POSIX API
+ * keys which are configured for this application.
+ */
+ uint32_t maximum_keys;
+
+ /**
+ * This field contains the maximum number of POSIX API
+ * key value pairs which are configured for this application.
+ *
+ * @note There can be potentially be a key/value pair for
+ * every thread to use every key. But normally this
+ * many are not needed in a system.
+ */
+ uint32_t maximum_key_value_pairs;
+
+ /**
+ * This field specifies the number of microseconds which elapse
+ * between clock ticks. This is the basis for RTEMS timing.
+ */
+ uint32_t microseconds_per_tick;
+
+ /**
+ * This field specifies the number of ticks in each task's timeslice.
+ */
+ uint32_t ticks_per_timeslice;
+
+ /**
+ * This element points to the BSP's optional idle task which may override
+ * the default one provided with RTEMS.
+ */
+ void *(*idle_task)( uintptr_t );
+
+ /**
+ * This field specifies the size of the IDLE task's stack. If less than or
+ * equal to the minimum stack size, then the IDLE task will have the minimum
+ * stack size.
+ */
+ uint32_t idle_task_stack_size;
+
+ /**
+ * This field specifies the size of the interrupt stack. If less than or
+ * equal to the minimum stack size, then the interrupt stack will be of
+ * minimum stack size.
+ */
+ uint32_t interrupt_stack_size;
+
+ /**
+ * @brief Optional task stack allocator initialization hook.
+ */
+ rtems_stack_allocate_init_hook stack_allocate_init_hook;
+
+ /**
+ * @brief Optional task stack allocator hook.
+ */
+ rtems_stack_allocate_hook stack_allocate_hook;
+
+ /**
+ * @brief Optional task stack free hook.
+ */
+ rtems_stack_free_hook stack_free_hook;
+
+ /**
+ * If this element is TRUE, then RTEMS will zero the Executive Workspace.
+ * When this element is FALSE, it is assumed that the BSP or invoking
+ * environment has ensured that memory was cleared before RTEMS was
+ * invoked.
+ */
+ bool do_zero_of_workspace;
+
+ /**
+ * @brief Specifies if a unified work area is used or not.
+ *
+ * If this element is @a true, then the RTEMS Workspace and the C Program
+ * Heap use the same heap, otherwise they use separate heaps.
+ */
+ bool unified_work_area;
+
+ /**
+ * @brief Specifies if the stack allocator avoids the work space.
+ *
+ * If this element is @a true, then the stack allocator must not allocate the
+ * thread stacks from the RTEMS Workspace, otherwise it should allocate the
+ * thread stacks from the RTEMS Workspace.
+ */
+ bool stack_allocator_avoids_work_space;
+
+ #ifdef RTEMS_SMP
+ bool smp_enabled;
+ #endif
+
+ uint32_t number_of_initial_extensions;
+ const rtems_extensions_table *User_extension_table;
+ #if defined(RTEMS_MULTIPROCESSING)
+ rtems_multiprocessing_table *User_multiprocessing_table;
+ #endif
+ #ifdef RTEMS_SMP
+ uint32_t maximum_processors;
+ #endif
+} rtems_configuration_table;
+
+/**
+ * This is the configuration table generated by confdefs.h.
+ */
+extern const rtems_configuration_table Configuration;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ /**
+ * This points to the multiprocessing configuration table.
+ */
+ extern rtems_multiprocessing_table *_Configuration_MP_table;
+#endif
+
+#if defined(RTEMS_MULTIPROCESSING)
+ /**
+ * @brief RTEMS multiprocessing configuration table.
+ *
+ * This is the RTEMS Multiprocessing Configuration Table expected to
+ * be generated by confdefs.h.
+ */
+ extern rtems_multiprocessing_table Multiprocessing_configuration;
+
+ /*
+ * This is the default Multiprocessing Configuration Table.
+ * It is used in single processor configurations.
+ */
+ extern const rtems_multiprocessing_table
+ _Initialization_Default_multiprocessing_table;
+#endif
+
+
+/*
+ * Some handy macros to avoid dependencies on either the BSP
+ * or the exact format of the configuration table.
+ */
+
+#define rtems_configuration_get_unified_work_area() \
+ (Configuration.unified_work_area)
+
+#define rtems_configuration_get_stack_allocator_avoids_work_space() \
+ (Configuration.stack_allocator_avoids_work_space)
+
+#define rtems_configuration_get_stack_space_size() \
+ (Configuration.stack_space_size)
+
+#define rtems_configuration_get_work_space_size() \
+ (Configuration.work_space_size + \
+ (rtems_configuration_get_stack_allocator_avoids_work_space() ? \
+ 0 : rtems_configuration_get_stack_space_size()))
+
+#define rtems_configuration_get_maximum_extensions() \
+ (Configuration.maximum_extensions)
+
+#define rtems_configuration_get_microseconds_per_tick() \
+ (Configuration.microseconds_per_tick)
+#define rtems_configuration_get_milliseconds_per_tick() \
+ (Configuration.microseconds_per_tick / 1000)
+#define rtems_configuration_get_nanoseconds_per_tick() \
+ (_Watchdog_Nanoseconds_per_tick)
+
+#define rtems_configuration_get_ticks_per_timeslice() \
+ (Configuration.ticks_per_timeslice)
+
+#define rtems_configuration_get_idle_task() \
+ (Configuration.idle_task)
+
+#define rtems_configuration_get_idle_task_stack_size() \
+ (Configuration.idle_task_stack_size)
+
+#define rtems_configuration_get_interrupt_stack_size() \
+ (Configuration.interrupt_stack_size)
+
+#define rtems_configuration_get_stack_allocate_init_hook() \
+ (Configuration.stack_allocate_init_hook)
+
+#define rtems_configuration_get_stack_allocate_hook() \
+ (Configuration.stack_allocate_hook)
+
+#define rtems_configuration_get_stack_free_hook() \
+ (Configuration.stack_free_hook)
+
+ /**
+ * This macro assists in accessing the field which indicates whether
+ * RTEMS is responsible for zeroing the Executive Workspace.
+ */
+#define rtems_configuration_get_do_zero_of_workspace() \
+ (Configuration.do_zero_of_workspace)
+
+#define rtems_configuration_get_number_of_initial_extensions() \
+ (Configuration.number_of_initial_extensions)
+
+#define rtems_configuration_get_user_extension_table() \
+ (Configuration.User_extension_table)
+
+#if defined(RTEMS_MULTIPROCESSING)
+ #define rtems_configuration_get_user_multiprocessing_table() \
+ (Configuration.User_multiprocessing_table)
+#else
+ #define rtems_configuration_get_user_multiprocessing_table() \
+ NULL
+#endif
+
+/**
+ * @brief Returns true if the SMP mode of operation is enabled, and false
+ * otherwise.
+ *
+ * In uni-processor configurations this is a compile-time constant which
+ * evaluates to false.
+ *
+ * @retval true SMP mode of operation is enabled.
+ * @retval false Otherwise.
+ */
+#ifdef RTEMS_SMP
+ #define rtems_configuration_is_smp_enabled() \
+ (Configuration.smp_enabled)
+#else
+ #define rtems_configuration_is_smp_enabled() \
+ false
+#endif
+
+/**
+ * @brief Returns the configured maximum count of processors.
+ *
+ * The actual number of processors available for the application will be less
+ * than or equal to the configured maximum count of processors.
+ *
+ * On single-processor configurations this is a compile time constant which
+ * evaluates to one.
+ *
+ * @return The configured maximum count of processors.
+ */
+#ifdef RTEMS_SMP
+ #define rtems_configuration_get_maximum_processors() \
+ (Configuration.maximum_processors)
+#else
+ #define rtems_configuration_get_maximum_processors() \
+ 1
+#endif
+
+#define rtems_configuration_get_rtems_api_configuration() \
+ (&Configuration_RTEMS_API)
+
+#define rtems_configuration_get_posix_api_configuration() \
+ (&Configuration_POSIX_API)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/counter.h b/cpukit/include/rtems/counter.h
new file mode 100644
index 0000000000..3b428402a8
--- /dev/null
+++ b/cpukit/include/rtems/counter.h
@@ -0,0 +1,160 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicCounter
+ *
+ * @brief Free-Running Counter and Busy Wait Delay API
+ */
+
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_SAPI_COUNTER_H
+#define _RTEMS_SAPI_COUNTER_H
+
+#include <rtems/score/cpu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ClassicCounter Free-Running Counter and Busy Wait Delay
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * @brief Free-running counter and busy wait delay functions.
+ *
+ * The RTEMS counter is some free-running counter. It ticks usually with a
+ * frequency close to the CPU or system bus clock.
+ *
+ * The counter can be used in case the overhead of the
+ * rtems_clock_get_uptime_nanoseconds() is too high. The step from counter
+ * ticks to/from nanoseconds is explicit in this API unlike to
+ * rtems_clock_get_uptime_nanoseconds() which performs the conversion on each
+ * invocation.
+ *
+ * This counter works without a clock driver and during system initialization.
+ *
+ * The counter can be used to profile low-level operations like SMP locks or
+ * interrupt disabled critical sections. The counter can act also as an
+ * entropy source for a random number generator.
+ *
+ * The period of the counter depends on the actual hardware.
+ *
+ * @{
+ */
+
+/**
+ * @brief Unsigned integer type for counter values.
+ */
+typedef CPU_Counter_ticks rtems_counter_ticks;
+
+/**
+ * @brief Reads the current counter values.
+ *
+ * @return The current counter values.
+ */
+static inline rtems_counter_ticks rtems_counter_read( void )
+{
+ return _CPU_Counter_read();
+}
+
+/**
+ * @brief Returns the difference between the second and first CPU counter
+ * value.
+ *
+ * This operation may be carried out as a modulo operation depending on the
+ * range of the CPU counter device.
+ *
+ * @param[in] second The second CPU counter value.
+ * @param[in] first The first CPU counter value.
+ *
+ * @return Returns second minus first modulo counter period.
+ */
+static inline rtems_counter_ticks rtems_counter_difference(
+ rtems_counter_ticks second,
+ rtems_counter_ticks first
+)
+{
+ return _CPU_Counter_difference( second, first );
+}
+
+/**
+ * @brief Converts counter ticks into nanoseconds.
+ *
+ * @param[in] ticks Some counter ticks.
+ *
+ * @return The nanoseconds corresponding to the counter ticks. The value is
+ * rounded up.
+ */
+uint64_t rtems_counter_ticks_to_nanoseconds(
+ rtems_counter_ticks ticks
+);
+
+/**
+ * @brief Converts nanoseconds into counter ticks.
+ *
+ * @param[in] nanoseconds Some nanoseconds.
+ *
+ * @return The counter ticks corresponding to the nanoseconds. The value is
+ * rounded up.
+ */
+rtems_counter_ticks rtems_counter_nanoseconds_to_ticks(
+ uint32_t nanoseconds
+);
+
+/**
+ * @brief Initializes the counter ticks to/from nanoseconds converter functions.
+ *
+ * This function must be used to initialize the
+ * rtems_counter_ticks_to_nanoseconds() and
+ * rtems_counter_nanoseconds_to_ticks() functions. It should be called during
+ * system initialization by the board support package.
+ *
+ * @param[in] frequency The current counter frequency in Hz.
+ */
+void rtems_counter_initialize_converter( uint32_t frequency );
+
+/**
+ * @brief Busy wait for some counter ticks.
+ *
+ * This function does not disable interrupts. Thus task switches and
+ * interrupts can interfere with this busy wait may prolong the delay. This
+ * function busy waits at least the specified time. Due to some overhead the
+ * actual delay may be longer.
+ *
+ * @param[in] ticks The minimum busy wait time in counter ticks.
+ */
+void rtems_counter_delay_ticks( rtems_counter_ticks ticks );
+
+/**
+ * @brief Busy wait for some nanoseconds.
+ *
+ * This function does not disable interrupts. Thus task switches and
+ * interrupts can interfere with this busy wait may prolong the delay. This
+ * function busy waits at least the specified time. Due to some overhead the
+ * actual delay may be longer.
+ *
+ * @param[in] nanoseconds The minimum busy wait time in nanoseconds.
+ */
+void rtems_counter_delay_nanoseconds( uint32_t nanoseconds );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SAPI_COUNTER_H */
diff --git a/cpukit/include/rtems/cpuuse.h b/cpukit/include/rtems/cpuuse.h
new file mode 100644
index 0000000000..23f58faf1b
--- /dev/null
+++ b/cpukit/include/rtems/cpuuse.h
@@ -0,0 +1,88 @@
+/**
+ * @file rtems/cpuuse.h
+ *
+ * @defgroup libmisc_cpuuse CPU Usage
+ *
+ * @ingroup libmisc
+ * @brief CPU Usage Report
+ *
+ * This include file contains information necessary to utilize
+ * and install the cpu usage reporting mechanism.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_CPUUSE_h
+#define __RTEMS_CPUUSE_h
+
+#include <rtems.h>
+#include <rtems/print.h>
+
+/**
+ * @defgroup libmisc_cpuuse CPU Usage
+ *
+ * @ingroup libmisc
+ */
+/**@{*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * rtems_cpu_usage_report_with_handler
+ */
+
+void rtems_cpu_usage_report_with_plugin( const rtems_printer *printer );
+
+/**
+ * @brief Report CPU usage.
+ *
+ * CPU Usage Reporter
+ */
+
+void rtems_cpu_usage_report( void );
+
+/**
+ * @brief CPU usage Top plugin
+ *
+ * Report CPU Usage in top format to
+ * to a print plugin.
+ */
+void rtems_cpu_usage_top_with_plugin( const rtems_printer *printer );
+
+/**
+ * @brief CPU usage top.
+ *
+ * CPU Usage top
+ */
+
+void rtems_cpu_usage_top( void );
+
+/**
+ * @brief Reset CPU usage.
+ *
+ * CPU Usage Reporter
+ */
+
+void rtems_cpu_usage_reset( void );
+
+/**
+ * @brief Reports per-processor information.
+ *
+ * @return The number of characters printed.
+ */
+int rtems_cpu_info_report( const rtems_printer *printer );
+
+#ifdef __cplusplus
+}
+#endif
+/**@}*/
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/debugger/rtems-debugger-remote.h b/cpukit/include/rtems/debugger/rtems-debugger-remote.h
new file mode 100644
index 0000000000..34ad9ee6d2
--- /dev/null
+++ b/cpukit/include/rtems/debugger/rtems-debugger-remote.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+/*
+ * Debugger for RTEMS.
+ */
+
+#ifndef _RTEMS_DEBUGGER_REMOTE_h
+#define _RTEMS_DEBUGGER_REMOTE_h
+
+#include <rtems/rtems-debugger.h>
+#include <rtems/debugger/rtems-debugger-server.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Debugger remote.
+ */
+struct rtems_debugger_remote
+{
+ const char* name;
+ int (*begin)(rtems_debugger_remote* remote, const char* device);
+ int (*end)(rtems_debugger_remote* remote);
+ int (*connect)(rtems_debugger_remote* remote);
+ int (*disconnect)(rtems_debugger_remote* remote);
+ bool (*isconnected)(rtems_debugger_remote* remote);
+ ssize_t (*read)(rtems_debugger_remote* remote, void* buf, size_t nbytes);
+ ssize_t (*write)(rtems_debugger_remote* remote, const void* buf, size_t nbytes);
+ void* data;
+};
+
+/**
+ * Register a remote with the server.
+ */
+int rtems_debugger_remote_register(rtems_debugger_remote* remote);
+
+/**
+ * Find a remote by name.
+ */
+rtems_debugger_remote* rtems_debugger_remote_find(const char* name);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif
diff --git a/cpukit/include/rtems/debugger/rtems-debugger-server.h b/cpukit/include/rtems/debugger/rtems-debugger-server.h
new file mode 100644
index 0000000000..a345d7649e
--- /dev/null
+++ b/cpukit/include/rtems/debugger/rtems-debugger-server.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2016-2017 Chris Johns <chrisj@rtems.org>.
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+/*
+ * Debugger for RTEMS.
+ */
+
+#ifndef _RTEMS_DEBUGGER_SERVER_h
+#define _RTEMS_DEBUGGER_SERVER_h
+
+#include <rtems.h>
+#include <rtems/printer.h>
+
+#include <rtems/rtems-debugger.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Debugger NUMOF macro.
+ */
+#define RTEMS_DEBUGGER_NUMOF(_d) (sizeof(_d) / sizeof(_d[0]))
+
+/**
+ * Machine specific size. Here for 64bit support.
+ */
+#define DB_UINT uint32_t
+
+/*
+ * Debugger signals.
+ */
+#define RTEMS_DEBUGGER_SIGNAL_HUP 1 /* Hangup */
+#define RTEMS_DEBUGGER_SIGNAL_INT 2 /* Interrupt */
+#define RTEMS_DEBUGGER_SIGNAL_QUIT 3 /* Quit */
+#define RTEMS_DEBUGGER_SIGNAL_ILL 4 /* Illegal instruction */
+#define RTEMS_DEBUGGER_SIGNAL_TRAP 5 /* Trace/breakpoint trap */
+#define RTEMS_DEBUGGER_SIGNAL_ABRT 6 /* Aborted */
+#define RTEMS_DEBUGGER_SIGNAL_EMT 7 /* Emulation trap */
+#define RTEMS_DEBUGGER_SIGNAL_FPE 8 /* Arithmetic exception */
+#define RTEMS_DEBUGGER_SIGNAL_KILL 9 /* Killed */
+#define RTEMS_DEBUGGER_SIGNAL_BUS 10 /* Bus error */
+#define RTEMS_DEBUGGER_SIGNAL_SEGV 11 /* Segmentation fault */
+#define RTEMS_DEBUGGER_SIGNAL_SYS 12 /* Bad system call */
+#define RTEMS_DEBUGGER_SIGNAL_PIPE 13 /* Broken pipe */
+#define RTEMS_DEBUGGER_SIGNAL_ALRM 14 /* Alarm clock */
+#define RTEMS_DEBUGGER_SIGNAL_TERM 15 /* Terminated */
+#define RTEMS_DEBUGGER_SIGNAL_URG 16 /* Urgent I/O condition */
+#define RTEMS_DEBUGGER_SIGNAL_STOP 17 /* Stopped (signal) */
+#define RTEMS_DEBUGGER_SIGNAL_TSTP 18 /* Stopped (user) */
+#define RTEMS_DEBUGGER_SIGNAL_CONT 19 /* Continued */
+
+/**
+ * Timeout period for the Debugger task to stop in usecs.
+ */
+#define RTEMS_DEBUGGER_TIMEOUT_STOP (5 * 1000 * 1000)
+
+/**
+ * Debugger poll wait timeout in usecs.
+ */
+#define RTEMS_DEBUGGER_POLL_WAIT (10000)
+
+/**
+ * Debugger task stack size.
+ */
+#define RTEMS_DEBUGGER_STACKSIZE (16 * 1024)
+
+/**
+ * Debugger output buffer size.
+ */
+#define RTEMS_DEBUGGER_BUFFER_SIZE (4 * 1024)
+
+/**
+ * Debugger flags.
+ */
+#define RTEMS_DEBUGGER_FLAG_VERBOSE (1 << 0)
+#define RTEMS_DEBUGGER_FLAG_RESET (1 << 1)
+#define RTEMS_DEBUGGER_FLAG_NON_STOP (1 << 2)
+#define RTEMS_DEBUGGER_FLAG_VCONT (1 << 3)
+#define RTEMS_DEBUGGER_FLAG_MULTIPROCESS (1 << 4)
+#define RTEMS_DEBUGGER_FLAG_VERBOSE_LOCK (1 << 5)
+#define RTEMS_DEBUGGER_FLAG_VERBOSE_CMDS (1 << 6)
+
+/**
+ * Forward decl for the threads and targets.
+ */
+typedef struct rtems_debugger_remote rtems_debugger_remote;
+typedef struct rtems_debugger_threads rtems_debugger_threads;
+typedef struct rtems_debugger_target rtems_debugger_target;
+
+/**
+ * Local types for the RTEMS-X interface.
+ */
+typedef struct _Condition_Control rtems_rx_cond;
+typedef struct _Mutex_recursive_Control rtems_rx_mutex;
+
+/**
+ * Debugger data.
+ */
+typedef struct
+{
+ int port;
+ int timeout;
+ rtems_task_priority priority;
+ rtems_rx_mutex lock;
+ rtems_debugger_remote* remote;
+ rtems_id server_task;
+ rtems_rx_cond server_cond;
+ volatile bool server_running;
+ volatile bool server_finished;
+ rtems_id events_task;
+ volatile bool events_running;
+ volatile bool events_finished;
+ rtems_printer printer;
+ uint32_t flags;
+ pid_t pid;
+ bool remote_debug;
+ bool ack_pending;
+ size_t output_level;
+ uint8_t input[RTEMS_DEBUGGER_BUFFER_SIZE];
+ uint8_t output[RTEMS_DEBUGGER_BUFFER_SIZE];
+ rtems_debugger_threads* threads;
+ rtems_chain_control exception_threads;
+ int signal;
+ rtems_debugger_target* target;
+} rtems_debugger_server;
+
+/**
+ * Debugger global variable.
+ */
+extern rtems_debugger_server* rtems_debugger;
+
+/**
+ * Debug server printer.
+ */
+extern int rtems_debugger_printf(const char* format, ...) RTEMS_PRINTFLIKE(1, 2);
+extern int rtems_debugger_clean_printf(const char* format, ...) RTEMS_PRINTFLIKE(1, 2);
+extern void rtems_debugger_printk_lock(rtems_interrupt_lock_context* lock_context);
+extern void rtems_debugger_printk_unlock(rtems_interrupt_lock_context* lock_context);
+
+/**
+ * Lock the Debugger.
+ */
+extern void rtems_debugger_lock(void);
+
+/**
+ * Unlock the Debugger.
+ */
+extern void rtems_debugger_unlock(void);
+
+/**
+ * Is the server still running?
+ */
+extern bool rtems_debugger_server_running(void);
+
+/**
+ * Get the remote handle from the debugger.
+ */
+extern rtems_debugger_remote* rtems_debugger_remote_handle(void);
+
+/**
+ * Is the debugger connected?
+ */
+extern bool rtems_debugger_connected(void);
+
+/**
+ * Is the debugger events thread runnins?
+ */
+extern bool rtems_debugger_server_events_running(void);
+
+/**
+ * Signal events thread in the debug server to run.
+ */
+extern void rtems_debugger_server_events_signal(void);
+
+/**
+ * Check if verbose is on.
+ */
+extern bool rtems_debugger_verbose(void);
+
+/**
+ * Check a flag.
+ */
+static inline bool rtems_debugger_server_flag(uint32_t mask)
+{
+ return (rtems_debugger->flags & mask) != 0;
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif
diff --git a/cpukit/include/rtems/devfs.h b/cpukit/include/rtems/devfs.h
new file mode 100644
index 0000000000..b0a9197eca
--- /dev/null
+++ b/cpukit/include/rtems/devfs.h
@@ -0,0 +1,255 @@
+/**
+* @file
+*
+* @brief Device Only File System
+*
+* This include file contains all constants and structures associated
+* with the 'device-only' filesystem.
+*/
+
+#ifndef _RTEMS_DEVFS_H
+#define _RTEMS_DEVFS_H
+
+#include <rtems/libio_.h>
+
+/**
+ * @defgroup DevFsDeviceTable Device Only File System
+ *
+ * @ingroup FileSystemTypesAndMount
+ *
+ * @brief This structure defines the type of device table
+ */
+/**@{*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Per Device Node Control Structure
+ *
+ * This structure is instanced per device node and contains all information
+ * used by this file system implementation to manage that device node.
+ */
+typedef struct {
+ /** This member points to device name which is not a null-terminated string */
+ const char *name;
+ /** This member is the name length of a device */
+ size_t namelen;
+ /** major number of a device */
+ rtems_device_major_number major;
+ /** minor number of a device */
+ rtems_device_minor_number minor;
+ /** device creation mode, only device file can be created */
+ mode_t mode;
+} devFS_node;
+
+typedef struct {
+ devFS_node *nodes;
+ size_t count;
+} devFS_data;
+
+/**
+ * The following defines the device-only filesystem operating
+ * operations.
+ */
+extern const rtems_filesystem_operations_table devFS_ops;
+
+/**
+ * The following defines the device-only filesystem operating
+ * handlers.
+ */
+extern const rtems_filesystem_file_handlers_r devFS_file_handlers;
+
+/**
+ * @brief Obtain Immutable Pointer to Immutable File System Data
+ *
+ * This methods returns the immutable file system specific information
+ * associated with this file.
+ */
+static inline const devFS_data *devFS_get_data(
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ return (const devFS_data *) loc->mt_entry->immutable_fs_info;
+}
+
+/**
+ * @brief Evaluate Path
+ */
+extern void devFS_eval_path(
+ rtems_filesystem_eval_path_context_t *ctx
+);
+
+/**
+ * @brief Maps Open Operation to rtems_io_open
+ *
+ * This handler maps open operation to rtems_io_open.
+ *
+ * @param iop This is the RTEMS's internal representation of file.
+ * @param pathname a null-terminated string that starts with /dev.
+ * @param oflag access flags
+ * @param mode access mode
+ *
+ * @retval the same as open
+ */
+extern int devFS_open(
+ rtems_libio_t *iop,
+ const char *pathname,
+ int oflag,
+ mode_t mode
+);
+
+
+/**
+ * @brief Maps Close Operation to rtems_io_close
+ *
+ * This handler maps close operation to rtems_io_close.
+ *
+ * @param iop This is the RTEMS's internal representation of file
+ *
+ * @retval the same as close
+ */
+extern int devFS_close(
+ rtems_libio_t *iop
+);
+
+/**
+ * @brief Maps Read Operation to rtems_io_read
+ *
+ * This handler maps read operation to rtems_io_read.
+ *
+ * @param iop This is the RTEMS's internal representation of file
+ * @param buffer memory location to store read data
+ * @param count how many bytes to read
+ *
+ * @retval On successful, this routine returns total bytes read. On error
+ * it returns -1 and errno is set to proper value.
+ */
+extern ssize_t devFS_read(
+ rtems_libio_t *iop,
+ void *buffer,
+ size_t count
+);
+
+/**
+ * @brief Writes Operation to rtems_io_write
+ *
+ * This handler maps write operation to rtems_io_write.
+ *
+ * @param iop This is the RTEMS's internal representation of file
+ * @param buffer data to be written
+ * @param count how many bytes to write
+ *
+ * @retval On successful, this routine returns total bytes written. On error
+ * it returns -1 and errno is set to proper value.
+ */
+extern ssize_t devFS_write(
+ rtems_libio_t *iop,
+ const void *buffer,
+ size_t count
+);
+
+/**
+ * @brief Maps ioctl Operation to rtems_io_ioctl
+ *
+ * This handler maps ioctl operation to rtems_io_ioctl.
+ *
+ * @param iop This is the RTEMS's internal representation of file
+ * @param command io control command
+ * @param buffer io control parameters
+ *
+ * @retval On successful, this routine returns total bytes written. On error
+ * it returns -1 and errno is set to proper value.
+ */
+extern int devFS_ioctl(
+ rtems_libio_t *iop,
+ ioctl_command_t command,
+ void *buffer
+);
+
+/**
+ * @brief Gets the Device File Information
+ *
+ * This handler gets the device file information. This routine only
+ * set the following member of struct stat:
+ *
+ * - st_dev: device number
+ * - st_mode: device file creation mode, only two mode are accepted:
+ * + S_IFCHR: character device file
+ * + S_IFBLK: block device file
+ *
+ * @param loc contains filesystem access information
+ * @param buf buffer to hold the device file's information
+ *
+ * @retval On successful, this routine returns 0. On error
+ * it returns -1 and errno is set to proper value.
+ */
+extern int devFS_stat(
+ const rtems_filesystem_location_info_t *loc,
+ struct stat *buf
+);
+
+/**
+ * @brief Creates an item in the main device table.
+ *
+ * This routine is invoked upon registration of a new device
+ * file. It is responsible for creating a item in the main
+ * device table. This routine searches the device table in
+ * sequential order, when found a empty slot, it fills the slot
+ * with proper values.
+ *
+ * @see rtems_filesystem_mknod_t.
+ */
+extern int devFS_mknod(
+ const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ mode_t mode,
+ dev_t dev
+);
+
+/**
+ * @brief Creates the Main Device Table
+ *
+ * This routine is invoked upon rtems filesystem initialization.
+ * It is responsible for creating the main device table,
+ * initializing it to a known state, and set device file operation
+ * handlers. After this, the device-only filesytem is ready for use
+ *
+ * @param mt_entry The filesystem mount table entry.
+ * @param data Filesystem specific data.
+ *
+ * @retval upon success, this routine returns 0; otherwise it returns
+ * -1 and errno is set to proper value. The only error is when malloc
+ * failed, and errno is set to NOMEM.
+ */
+extern int devFS_initialize(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ const void *data
+);
+
+/**
+ * @brief Retrieves and Prints all the Device Registered in System
+ *
+ * This routine retrieves all the device registered in system, and
+ * prints out their detail information. For example, on one system,
+ * devFS_show will print out following message:
+ *
+ * @code
+ * /dev/console 0 0
+ * /dev/clock 1 0
+ * /dev/tty0 0 0
+ * /flash 2 0
+ * @endcode
+ *
+ * This routine is intended for debugging, and can be used by shell
+ * program to provide user with the system information.
+ */
+extern void devFS_Show(void);
+
+#ifdef __cplusplus
+}
+#endif
+/**@}*/
+#endif
+
diff --git a/cpukit/include/rtems/deviceio.h b/cpukit/include/rtems/deviceio.h
new file mode 100644
index 0000000000..a448fc7bb4
--- /dev/null
+++ b/cpukit/include/rtems/deviceio.h
@@ -0,0 +1,88 @@
+/**
+ * @file
+ *
+ * @brief Operations on IMFS Device Nodes
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2012.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_DEVICEIO_H
+#define _RTEMS_DEVICEIO_H
+
+#include <rtems/libio.h>
+
+/**
+ * @defgroup IMFSDevices IMFS Device IO Handler
+ *
+ * @ingroup IMFS
+ *
+ * This contains the interface to device drivers using the RTEMS Classic API.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @brief IMFS device node handlers.
+ *
+ * IMFS Device Node Handlers
+ *
+ * This file contains the set of handlers used to map operations on
+ * IMFS device nodes onto calls to the RTEMS Classic API IO Manager.
+ */
+int rtems_deviceio_open(
+ rtems_libio_t *iop,
+ const char *path,
+ int oflag,
+ mode_t mode,
+ rtems_device_major_number major,
+ rtems_device_minor_number minor
+);
+
+int rtems_deviceio_close(
+ rtems_libio_t *iop,
+ rtems_device_major_number major,
+ rtems_device_minor_number minor
+);
+
+ssize_t rtems_deviceio_read(
+ rtems_libio_t *iop,
+ void *buf,
+ size_t nbyte,
+ rtems_device_major_number major,
+ rtems_device_minor_number minor
+);
+
+ssize_t rtems_deviceio_write(
+ rtems_libio_t *iop,
+ const void *buf,
+ size_t nbyte,
+ rtems_device_major_number major,
+ rtems_device_minor_number minor
+);
+
+int rtems_deviceio_control(
+ rtems_libio_t *iop,
+ ioctl_command_t command,
+ void *buffer,
+ rtems_device_major_number major,
+ rtems_device_minor_number minor
+);
+
+#ifdef __cplusplus
+}
+#endif
+/* __cplusplus */
+
+/**@}*/
+
+#endif /* _RTEMS_DEVICEIO_H */
diff --git a/cpukit/include/rtems/devnull.h b/cpukit/include/rtems/devnull.h
new file mode 100644
index 0000000000..39081f478b
--- /dev/null
+++ b/cpukit/include/rtems/devnull.h
@@ -0,0 +1,84 @@
+/**
+ * @file
+ *
+ * @brief RTEMS /dev/null Device Driver
+ *
+ * This include file defines the interface to the RTEMS /dev/null
+ * device driver.
+ */
+
+/*
+ * Author: Ralf Corsepius (corsepiu@faw.uni-ulm.de)
+ *
+ * COPYRIGHT (c) 1989-2000.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_DEVNULL_H
+#define _RTEMS_DEVNULL_H
+
+#include <rtems/io.h>
+
+/**
+ * @defgroup libmisc_devnull Null Device Driver
+ *
+ * @ingroup libmisc
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DEVNULL_DRIVER_TABLE_ENTRY \
+ { null_initialize, null_open, null_close, null_read, \
+ null_write, null_control }
+
+#define NULL_SUCCESSFUL RTEMS_SUCCESSFUL
+
+rtems_device_driver null_initialize(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver null_open(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver null_close(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver null_read(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver null_write(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+rtems_device_driver null_control(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+#ifdef __cplusplus
+}
+#endif
+/**@}*/
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/devzero.h b/cpukit/include/rtems/devzero.h
new file mode 100644
index 0000000000..bc47d3ea09
--- /dev/null
+++ b/cpukit/include/rtems/devzero.h
@@ -0,0 +1,92 @@
+/**
+ * @file rtems/devzero.h
+ *
+ * @brief RTEMS /dev/zero Device Driver
+ *
+ * This include file defines the interface to the RTEMS /dev/zero
+ * device driver.
+ */
+
+/*
+ * Copyright (c) 2011 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_DEVZERO_H
+#define _RTEMS_DEVZERO_H
+
+#include <rtems/io.h>
+
+/**
+ * @defgroup libmisc_devzero Zero Device Driver
+ *
+ * @ingroup libmisc
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define DEVZERO_DEVICE_NAME "/dev/zero"
+
+#define DEVZERO_DRIVER_TABLE_ENTRY \
+ { \
+ dev_zero_initialize, \
+ dev_zero_open, \
+ dev_zero_close, \
+ dev_zero_read, \
+ dev_zero_write, \
+ dev_zero_control \
+ }
+
+rtems_device_driver dev_zero_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+);
+
+rtems_device_driver dev_zero_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+);
+
+rtems_device_driver dev_zero_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+);
+
+rtems_device_driver dev_zero_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+);
+
+rtems_device_driver dev_zero_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+);
+
+rtems_device_driver dev_zero_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+/**@}*/
+#endif /* _RTEMS_DEVZERO_H */
diff --git a/cpukit/include/rtems/diskdevs.h b/cpukit/include/rtems/diskdevs.h
new file mode 100644
index 0000000000..0be766afa3
--- /dev/null
+++ b/cpukit/include/rtems/diskdevs.h
@@ -0,0 +1,511 @@
+/**
+ * @file
+ *
+ * @brief Block Device Disk Management API
+ *
+ * @ingroup rtems_disk
+ */
+
+/*
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ */
+
+#ifndef _RTEMS_DISKDEVS_H
+#define _RTEMS_DISKDEVS_H
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/chain.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct rtems_disk_device rtems_disk_device;
+
+/**
+ * @defgroup rtems_disk Block Device Disk Management
+ *
+ * @ingroup rtems_libblock
+ *
+ * @brief This module provides functions to manage disk devices.
+ *
+ * A disk is a set of blocks which are identified by a consecutive set of
+ * non-negative integers starting at zero. There are also logical disks which
+ * contain a subset of consecutive disk blocks. The logical disks are used to
+ * represent the partitions of a disk. The disk devices are accessed via the
+ * @ref rtems_bdbuf "block device buffer module".
+ */
+/**@{**/
+
+/**
+ * @brief Block device block index type.
+ */
+typedef uint32_t rtems_blkdev_bnum;
+
+/**
+ * @brief Block device IO control handler type.
+ */
+typedef int (*rtems_block_device_ioctl)(
+ rtems_disk_device *dd,
+ uint32_t req,
+ void *argp
+);
+
+/**
+ * @brief Trigger value to disable further read-ahead requests.
+ */
+#define RTEMS_DISK_READ_AHEAD_NO_TRIGGER ((rtems_blkdev_bnum) -1)
+
+/**
+ * @brief Block device read-ahead control.
+ */
+typedef struct {
+ /**
+ * @brief Chain node for the read-ahead request queue of the read-ahead task.
+ */
+ rtems_chain_node node;
+
+ /**
+ * @brief Block value to trigger the read-ahead request.
+ *
+ * A value of @ref RTEMS_DISK_READ_AHEAD_NO_TRIGGER will disable further
+ * read-ahead requests since no valid block can have this value.
+ */
+ rtems_blkdev_bnum trigger;
+
+ /**
+ * @brief Start block for the next read-ahead request.
+ *
+ * In case the trigger value is out of range of valid blocks, this value my
+ * be arbitrary.
+ */
+ rtems_blkdev_bnum next;
+} rtems_blkdev_read_ahead;
+
+/**
+ * @brief Block device statistics.
+ *
+ * Integer overflows in the statistic counters may happen.
+ */
+typedef struct {
+ /**
+ * @brief Read hit count.
+ *
+ * A read hit occurs in the rtems_bdbuf_read() function in case the block is
+ * in the cached or modified state.
+ */
+ uint32_t read_hits;
+
+ /**
+ * @brief Read miss count.
+ *
+ * A read miss occurs in the rtems_bdbuf_read() function in case the block is
+ * in the empty state and a read transfer must be initiated to read the data
+ * from the device.
+ */
+ uint32_t read_misses;
+
+ /**
+ * @brief Read-ahead transfer count.
+ *
+ * Each read-ahead transfer may read multiple blocks.
+ */
+ uint32_t read_ahead_transfers;
+
+ /**
+ * @brief Count of blocks transfered from the device.
+ */
+ uint32_t read_blocks;
+
+ /**
+ * @brief Read error count.
+ *
+ * Error count of transfers issued by the read or read-ahead requests.
+ */
+ uint32_t read_errors;
+
+ /**
+ * @brief Write transfer count.
+ *
+ * Each write transfer may write multiple blocks.
+ */
+ uint32_t write_transfers;
+
+ /**
+ * @brief Count of blocks transfered to the device.
+ */
+ uint32_t write_blocks;
+
+ /**
+ * @brief Write error count.
+ *
+ * Error count of transfers issued by write requests.
+ */
+ uint32_t write_errors;
+} rtems_blkdev_stats;
+
+/**
+ * @brief Description of a disk device (logical and physical disks).
+ *
+ * An array of pointer tables to rtems_disk_device structures is maintained.
+ * The first table will be indexed by the major number and the second table
+ * will be indexed by the minor number. This allows quick lookup using a data
+ * structure of moderated size.
+ */
+struct rtems_disk_device {
+ /**
+ * @brief Device identifier (concatenation of major and minor number).
+ */
+ dev_t dev;
+
+ /**
+ * @brief Physical device identifier (equals the @c dev entry if it specifies a
+ * physical device).
+ */
+ rtems_disk_device *phys_dev;
+
+ /**
+ * @brief Driver capabilities.
+ */
+ uint32_t capabilities;
+
+ /**
+ * @brief Disk device name.
+ */
+ char *name;
+
+ /**
+ * @brief Usage counter.
+ *
+ * Devices cannot be deleted if they are in use.
+ */
+ unsigned uses;
+
+ /**
+ * @brief Start media block number.
+ *
+ * Equals zero for physical devices. It is a media block offset to the
+ * related physical device for logical device.
+ */
+ rtems_blkdev_bnum start;
+
+ /**
+ * @brief Size of the physical or logical disk in media blocks.
+ */
+ rtems_blkdev_bnum size;
+
+ /**
+ * @brief Media block size in bytes.
+ *
+ * This is the media transfer unit the hardware defaults to.
+ */
+ uint32_t media_block_size;
+
+ /**
+ * @brief Block size in bytes.
+ *
+ * This is the minimum transfer unit. It may be a multiple of the media
+ * block size. It must be positive.
+ *
+ * @see rtems_bdbuf_set_block_size().
+ */
+ uint32_t block_size;
+
+ /**
+ * @brief Block count.
+ *
+ * @see rtems_bdbuf_set_block_size().
+ */
+ rtems_blkdev_bnum block_count;
+
+ /**
+ * @brief Media blocks per device blocks.
+ *
+ * @see rtems_bdbuf_set_block_size().
+ */
+ uint32_t media_blocks_per_block;
+
+ /**
+ * @brief Block to media block shift.
+ *
+ * In case this value is non-negative the media block of a block can be
+ * calculated as media block = block << block_to_media_block_shift, otherwise
+ * a 64-bit operation will be used.
+ *
+ * @see rtems_bdbuf_set_block_size().
+ */
+ int block_to_media_block_shift;
+
+ /**
+ * @brief Buffer descriptors per group count.
+ *
+ * @see rtems_bdbuf_set_block_size().
+ */
+ size_t bds_per_group;
+
+ /**
+ * @brief IO control handler for this disk.
+ */
+ rtems_block_device_ioctl ioctl;
+
+ /**
+ * @brief Private data for the disk driver.
+ */
+ void *driver_data;
+
+ /**
+ * @brief Indicates that this disk should be deleted as soon as the last user
+ * releases this disk.
+ */
+ bool deleted;
+
+ /**
+ * @brief Device statistics for this disk.
+ */
+ rtems_blkdev_stats stats;
+
+ /**
+ * @brief Read-ahead control for this disk.
+ */
+ rtems_blkdev_read_ahead read_ahead;
+};
+
+/**
+ * @name Disk Device Data
+ */
+/**@{**/
+
+static inline dev_t rtems_disk_get_device_identifier(
+ const rtems_disk_device *dd
+)
+{
+ return dd->dev;
+}
+
+static inline rtems_device_major_number rtems_disk_get_major_number(
+ const rtems_disk_device *dd
+)
+{
+ return rtems_filesystem_dev_major_t(dd->dev);
+}
+
+static inline rtems_device_minor_number rtems_disk_get_minor_number(
+ const rtems_disk_device *dd
+)
+{
+ return rtems_filesystem_dev_minor_t(dd->dev);
+}
+
+static inline void *rtems_disk_get_driver_data(
+ const rtems_disk_device *dd
+)
+{
+ return dd->driver_data;
+}
+
+static inline uint32_t rtems_disk_get_media_block_size(
+ const rtems_disk_device *dd
+)
+{
+ return dd->media_block_size;
+}
+
+static inline uint32_t rtems_disk_get_block_size(
+ const rtems_disk_device *dd
+)
+{
+ return dd->block_size;
+}
+
+static inline rtems_blkdev_bnum rtems_disk_get_block_begin(
+ const rtems_disk_device *dd
+)
+{
+ return dd->start;
+}
+
+static inline rtems_blkdev_bnum rtems_disk_get_block_count(
+ const rtems_disk_device *dd
+)
+{
+ return dd->size;
+}
+
+/** @} */
+
+/**
+ * @name Disk Device Maintainance
+ */
+/**@{**/
+
+/**
+ * @brief Creates a physical disk with device identifier @a dev.
+ *
+ * The block size @a block_size must be positive. The disk will have
+ * @a block_count blocks. The block index starts with zero. The associated disk
+ * device driver will be invoked via the IO control handler @a handler. A
+ * device node will be registered in the file system with absolute path @a
+ * name, if @a name is not @c NULL. This function is usually invoked from a
+ * block device driver during initialization when a physical device is detected
+ * in the system. The device driver provides an IO control handler to allow
+ * block device operations.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_NOT_CONFIGURED Cannot lock disk device operation mutex.
+ * @retval RTEMS_INVALID_ADDRESS IO control handler is @c NULL.
+ * @retval RTEMS_INVALID_NUMBER Block size is invalid.
+ * @retval RTEMS_NO_MEMORY Not enough memory.
+ * @retval RTEMS_RESOURCE_IN_USE Disk device descriptor is already in use.
+ * @retval RTEMS_UNSATISFIED Cannot create device node.
+ */
+rtems_status_code rtems_disk_create_phys(
+ dev_t dev,
+ uint32_t block_size,
+ rtems_blkdev_bnum block_count,
+ rtems_block_device_ioctl handler,
+ void *driver_data,
+ const char *name
+);
+
+/**
+ * @brief Creates a logical disk with device identifier @a dev.
+ *
+ * A logical disk manages a subset of consecutive blocks contained in the
+ * physical disk with identifier @a phys. The start block index of the logical
+ * disk device is @a block_begin. The block count of the logcal disk will be
+ * @a block_count. The blocks must be within the range of blocks managed by
+ * the associated physical disk device. A device node will be registered in
+ * the file system with absolute path @a name, if @a name is not @c NULL. The
+ * block size and IO control handler are inherited by the physical disk.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_NOT_CONFIGURED Cannot lock disk device operation mutex.
+ * @retval RTEMS_INVALID_ID Specified physical disk identifier does not
+ * correspond to a physical disk.
+ * @retval RTEMS_INVALID_NUMBER Begin block or block count are out of range.
+ * @retval RTEMS_NO_MEMORY Not enough memory.
+ * @retval RTEMS_RESOURCE_IN_USE Disk device descriptor for logical disk
+ * identifier is already in use.
+ * @retval RTEMS_UNSATISFIED Cannot create device node.
+ */
+rtems_status_code rtems_disk_create_log(
+ dev_t dev,
+ dev_t phys,
+ rtems_blkdev_bnum block_begin,
+ rtems_blkdev_bnum block_count,
+ const char *name
+);
+
+/**
+ * @brief Deletes a physical or logical disk device with identifier @a dev.
+ *
+ * Marks the disk device as deleted. When a physical disk device is deleted,
+ * all corresponding logical disk devices will marked as deleted too. Disks
+ * that are marked as deleted and have a usage counter of zero will be deleted.
+ * The corresponding device nodes will be removed from the file system. In
+ * case of a physical disk deletion the IO control handler will be invoked with
+ * a RTEMS_BLKIO_DELETED request. Disks that are still in use will be deleted
+ * upon release.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_NOT_CONFIGURED Cannot lock disk device operation mutex.
+ * @retval RTEMS_INVALID_ID No disk for specified device identifier.
+ */
+rtems_status_code rtems_disk_delete(dev_t dev);
+
+/**
+ * @brief Returns the disk device descriptor for the device identifier @a dev.
+ *
+ * Increments usage counter by one. You should release the disk device
+ * descriptor with rtems_disk_release().
+ *
+ * @return Pointer to the disk device descriptor or @c NULL if no corresponding
+ * disk exists.
+ */
+rtems_disk_device *rtems_disk_obtain(dev_t dev);
+
+/**
+ * @brief Releases the disk device descriptor @a dd.
+ *
+ * Decrements usage counter by one.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ */
+rtems_status_code rtems_disk_release(rtems_disk_device *dd);
+
+/** @} */
+
+/**
+ * @name Disk Management
+ */
+/**@{**/
+
+/**
+ * @brief Initializes the disk device management.
+ *
+ * This functions returns successful if the disk device management is already
+ * initialized. There is no protection against concurrent access.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful initialization.
+ * @retval RTEMS_NO_MEMORY Not enough memory or no semaphore available.
+ * @retval RTEMS_UNSATISFIED Block device buffer initialization failed.
+ */
+rtems_status_code rtems_disk_io_initialize(void);
+
+/**
+ * @brief Releases all resources allocated for disk device management.
+ *
+ * There is no protection against concurrent access. If parts of the system
+ * are still in use the behaviour is undefined.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ */
+rtems_status_code rtems_disk_io_done(void);
+
+/** @} */
+
+/** @} */
+
+/**
+ * @brief Disk device iterator.
+ *
+ * Returns the next disk device descriptor with a device identifier larger than
+ * @a dev. If there is no such device, @c NULL will be returned. Use minus
+ * one to start the search.
+ *
+ * @code
+ * rtems_status_code sc = RTEMS_SUCCESSFUL;
+ * rtems_disk_device *dd = (dev_t) -1;
+ *
+ * while (sc == RTEMS_SUCCESSFUL && (dd = rtems_disk_next(dev)) != NULL) {
+ * dev = rtems_disk_get_device_identifier(dd);
+ * sc = rtems_disk_release(dd);
+ * }
+ * @endcode
+ */
+rtems_disk_device *rtems_disk_next(dev_t dev);
+
+/* Internal function, do not use */
+rtems_status_code rtems_disk_init_phys(
+ rtems_disk_device *dd,
+ uint32_t block_size,
+ rtems_blkdev_bnum block_count,
+ rtems_block_device_ioctl handler,
+ void *driver_data
+);
+
+/* Internal function, do not use */
+rtems_status_code rtems_disk_init_log(
+ rtems_disk_device *dd,
+ rtems_disk_device *phys_dd,
+ rtems_blkdev_bnum block_begin,
+ rtems_blkdev_bnum block_count
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/dosfs.h b/cpukit/include/rtems/dosfs.h
new file mode 100644
index 0000000000..7691ed7e43
--- /dev/null
+++ b/cpukit/include/rtems/dosfs.h
@@ -0,0 +1,433 @@
+/**
+ * @file
+ *
+ * @brief Application Interface to FAT Filesystem
+ *
+ * @ingroup DOSFS
+ */
+
+/*
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
+ *
+ * Modifications to support UTF-8 in the file system are
+ * Copyright (c) 2013 embedded brains GmbH.
+ *
+ * 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_DOSFS_H
+#define _RTEMS_DOSFS_H
+
+#include <rtems.h>
+#include <rtems/libio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct rtems_dosfs_convert_control rtems_dosfs_convert_control;
+
+/**
+ * @brief Converts from UTF-8 into a specific code page.
+ *
+ * @param[in,out] self The convert control.
+ * @param[in] src A well-formed UTF-8 string to be converted.
+ * @param[in] src_size The size of the string in bytes (inludes '\\0' if any).
+ * @param[out] dst The address the converted string will get copied to.
+ * @param[in,out] dst_size The size of the buffer in bytes respectively the
+ * number of bytes written to the buffer.
+ *
+ * @retval 0 Successful operation.
+ * @retval EINVAL Conversion was successful, but is not reversible.
+ * @retval ENOMEM Conversion failed (possibly due to insufficient buffer size).
+ */
+typedef int (*rtems_dosfs_utf8_to_codepage)(
+ rtems_dosfs_convert_control *self,
+ const uint8_t *src,
+ size_t src_size,
+ char *dst,
+ size_t *dst_size
+);
+
+/**
+ * @brief Converts from a specific code page into UTF-8
+ *
+ * @param[in,out] self The convert control.
+ * @param[in] src A well-formed string in code page format.
+ * @param[in] src_size The size of the string in bytes (inludes '\\0' if any).
+ * @param[out] dst The address the converted string will get copied to.
+ * @param[in,out] dst_size The size of the buffer in bytes respectively the
+ * number of bytes written to the buffer.
+ *
+ * @retval 0 Successful operation.
+ * @retval EINVAL Conversion was successful, but is not reversible.
+ * @retval ENOMEM Conversion failed (possibly due to insufficient buffer size).
+ */
+typedef int (*rtems_dosfs_codepage_to_utf8)(
+ rtems_dosfs_convert_control *self,
+ const char *src,
+ size_t src_size,
+ uint8_t *dst,
+ size_t *dst_size
+);
+
+/**
+ * @brief Converts from UTF-8 to UTF-16
+ *
+ * @param[in,out] self The convert control.
+ * @param[in] src A well-formed UTF-8 string to be converted.
+ * @param[in] src_size The size of the string in bytes (inludes '\\0' if any).
+ * @param[out] dst The address the converted string will get copied to
+ * @param[in,out] dst_size The size of the buffer in bytes respectively the
+ * number of bytes written to the buffer.
+ *
+ * @retval 0 Successful operation.
+ * @retval EINVAL Conversion was successful, but is not reversible.
+ * @retval ENOMEM Conversion failed (possibly due to insufficient buffer size).
+ */
+typedef int (*rtems_dosfs_utf8_to_utf16)(
+ rtems_dosfs_convert_control *self,
+ const uint8_t *src,
+ size_t src_size,
+ uint16_t *dst,
+ size_t *dst_size
+);
+
+/**
+ * @brief Converts from UTF-16 to UTF-8.
+ *
+ * @param[in,out] self The convert control.
+ * @param[in] src A well-formed UTF-16 string to be converted.
+ * @param[in] src_size The size of the string in bytes (inludes '\\0' if any).
+ * @param[out] dst The address the converted string will get copied to.
+ * @param[in,out] dst_size The size of the buffer in bytes respectively the
+ * number of bytes written to the buffer
+ *
+ * @retval 0 Successful operation.
+ * @retval EINVAL Conversion was successful, but is not reversible.
+ * @retval ENOMEM Conversion failed (possibly due to insufficient buffer size).
+ */
+typedef int (*rtems_dosfs_utf16_to_utf8)(
+ rtems_dosfs_convert_control *self,
+ const uint16_t *src,
+ size_t src_size,
+ uint8_t *dst,
+ size_t *dst_size
+);
+
+/**
+ * @brief Converts from UTF-8 to Normalized Form Canonical Decomposition.
+ *
+ * Does canonical decomposition of the UTF-8 string and in addition
+ * also converts upper case alphabetic characters to lower case characters
+ *
+ * @param[in,out] self The convert control.
+ * @param[in] src A well-formed UTF-8 string to be normalized and fold.
+ * @param[in] src_size The size of the string in bytes (inludes '\\0' if any).
+ * @param[out] dst The address the normalized and fold string will get
+ * copied to.
+ * @param[in,out] dst_size The size of the buffer in bytes respectively the
+ * number of bytes written to the buffer.
+ *
+ * @retval 0 Successful operation.
+ * @retval EINVAL Conversion failed.
+ * @retval ENOMEM Conversion failed (possibly due to insufficient buffer size).
+ * @retval EOVERFLOW Conversion failed.
+ * @retval ENOENT Conversion failed.
+ */
+typedef int (*rtems_dosfs_utf8_normalize_and_fold)(
+ rtems_dosfs_convert_control *self,
+ const uint8_t *src,
+ size_t src_size,
+ uint8_t *dst,
+ size_t *dst_size
+);
+
+/**
+ * @brief Destroys a convert control structure.
+ *
+ * @param[in,out] self The convert control for destruction.
+ */
+typedef void (*rtems_dosfs_convert_destroy)(
+ rtems_dosfs_convert_control *self
+);
+
+/**
+ * @brief FAT filesystem convert handler.
+ */
+typedef struct {
+ rtems_dosfs_utf8_to_codepage utf8_to_codepage;
+ rtems_dosfs_codepage_to_utf8 codepage_to_utf8;
+ rtems_dosfs_utf8_to_utf16 utf8_to_utf16;
+ rtems_dosfs_utf16_to_utf8 utf16_to_utf8;
+ rtems_dosfs_utf8_normalize_and_fold utf8_normalize_and_fold;
+ rtems_dosfs_convert_destroy destroy;
+} rtems_dosfs_convert_handler;
+
+typedef struct {
+ void *data;
+ size_t size;
+} rtems_dosfs_buffer;
+
+/**
+ * @brief FAT filesystem convert control.
+ *
+ * Short file names are stored in the code page format. Long file names are
+ * stored as little-endian UTF-16. The convert control determines the format
+ * conversions to and from the POSIX file name strings.
+ */
+struct rtems_dosfs_convert_control {
+ const rtems_dosfs_convert_handler *handler;
+ rtems_dosfs_buffer buffer;
+};
+
+/**
+ * @defgroup DOSFS FAT Filesystem Support
+ *
+ * @ingroup FileSystemTypesAndMount
+ *
+ * @brief FAT file system configuration support, format and mount options.
+ *
+ * A block device can be formatted with a FAT file system with the
+ * msdos_format() function.
+ *
+ * The FAT file system mount operation can be controlled with FAT file system
+ * specific mount options, see @ref rtems_dosfs_mount_options.
+ *
+ * @{
+ */
+
+/**
+ * @brief Semaphore count per FAT filesystem instance.
+ *
+ * This can be used for system configuration via <rtems/confdefs.h>.
+ */
+#define RTEMS_DOSFS_SEMAPHORES_PER_INSTANCE 1
+
+/**
+ * @brief FAT filesystem mount options.
+ */
+typedef struct {
+ /**
+ * @brief Converter implementation for new file system instance.
+ *
+ * Before converters have been added to the RTEMS implementation of the FAT
+ * file system, the implementation was:
+ * - Short names were saved in code page format (as is still the case).
+ * - Long names were not saved in UTF-16 format as mandated by the FAT file
+ * system specification. Instead the character in the local encoding was
+ * stored to the low byte directly and the high byte was set to zero.
+ *
+ * There are a few compatibility issues due to a non-standard conform
+ * implementation of the FAT file system before the UTF-8 support was added.
+ * These following issues affect the default converter and the UTF-8
+ * converter:
+ * - Before UTF-8 support was added, it was possible to create files with the
+ * the same short name in single case and mixed case in a directory. It
+ * was for example possible to have files "ABC" and "aBc" in a single
+ * directory. Now this bug is fixed.
+ * - Before UTF-8 support was added, it was possible to create files with a
+ * name length of slightly more than 255 characters. Now the
+ * implementation adheres exactly to the 255 character limit.
+ * - Long file names saved before UTF-8 support was added could contain
+ * non-ASCII characters in the low byte which was saved for a long name
+ * character. With the default converter this means such files can be read
+ * only by their short file name. With the UTF-8 converter file names will
+ * be read correctly as long as the characters written with the old
+ * implementation were Latin-1 characters.
+ *
+ * The following sample code demonstrates how to mount a file
+ * system with UTF-8 support:
+ * @code
+ * #include <errno.h>
+ * #include <assert.h>
+ * #include <rtems/dosfs.h>
+ * #include <rtems/libio.h>
+ *
+ * static int mount_with_utf8(
+ * const char *device_file,
+ * const char *mount_point
+ * )
+ * {
+ * rtems_dosfs_convert_control *convert_ctrl;
+ * int rv;
+ *
+ * convert_ctrl = rtems_dosfs_create_utf8_converter( "CP850" );
+ *
+ * if ( convert_ctrl != NULL ) {
+ * rtems_dosfs_mount_options mount_opts;
+ *
+ * memset( &mount_opts, 0, sizeof( mount_opts ) );
+ * mount_opts.converter = convert_ctrl;
+ *
+ * rv = mount_and_make_target_path(
+ * device_file,
+ * mount_point,
+ * RTEMS_FILESYSTEM_TYPE_DOSFS,
+ * RTEMS_FILESYSTEM_READ_WRITE,
+ * &mount_opts
+ * );
+ * } else {
+ * rv = -1;
+ * errno = ENOMEM;
+ * }
+ *
+ * return rv;
+ * }
+ * @endcode
+ *
+ * In case you do not want UTF-8 support, you can simply pass a NULL pointer
+ * to mount_and_make_target_path() respectively to mount() instead of the
+ * mount_opts address.
+ *
+ * @see rtems_dosfs_create_default_converter() and
+ * rtems_dosfs_create_utf8_converter().
+ */
+ rtems_dosfs_convert_control *converter;
+} rtems_dosfs_mount_options;
+
+/**
+ * @brief Allocates and initializes a default converter.
+ *
+ * This default converter will accept only POSIX file names with pure ASCII
+ * characters. This largely corresponds to the file name handling before the
+ * optional UTF-8 support was added to the RTEMS implementation of the FAT file
+ * system. This handling is mostly backwards compatible to the previous RTEMS
+ * implementation of the FAT file system.
+ *
+ * For backwards compatibility and the previous RTEMS implementation of the FAT
+ * file system please see also @ref rtems_dosfs_mount_options and mount().
+ *
+ * @retval NULL Something failed.
+ * @retval other Pointer to initialized converter.
+ */
+rtems_dosfs_convert_control *rtems_dosfs_create_default_converter(void);
+
+/**
+ * @brief Allocates and initializes a UTF-8 converter.
+ *
+ * This converter will assume that all file names passed to POSIX file handling
+ * methods are UTF-8 strings and will convert them to the selected code page
+ * for short file names and to UTF-16 for long file names. This conversion
+ * will be done during reading and writing. These conversions correspond to
+ * the specification of the FAT file system. This handling is mostly backwards
+ * compatible to the previous RTEMS implementation of the FAT file system.
+ *
+ * For backwards compatibility and the previous RTEMS implementation of the FAT
+ * file system please see also @ref rtems_dosfs_mount_options and mount().
+ *
+ * One possible issue with this converter is: When reading file names which
+ * have been created with other implementations of the FAT file system, it can
+ * happen that during the conversion to UTF-8 a long file name becomes longer
+ * and exceeds the 255 bytes limit. In such a case only the short file name
+ * will get read.
+ *
+ * @param[in] codepage The iconv() identification string for the used code
+ * page.
+ *
+ * @retval NULL Something failed.
+ * @retval other Pointer to initialized converter.
+ */
+rtems_dosfs_convert_control *rtems_dosfs_create_utf8_converter(
+ const char *codepage
+);
+
+#define MSDOS_FMT_INFO_LEVEL_NONE (0)
+#define MSDOS_FMT_INFO_LEVEL_INFO (1)
+#define MSDOS_FMT_INFO_LEVEL_DETAIL (2)
+#define MSDOS_FMT_INFO_LEVEL_DEBUG (3)
+
+/**
+ * @brief FAT file system format request parameters.
+ */
+typedef struct {
+ /**
+ * @brief OEM name string or NULL.
+ */
+ const char *OEMName;
+
+ /**
+ * @brief Volume label string or NULL.
+ */
+ const char *VolLabel;
+
+ /**
+ * @brief Sectors per cluster hint.
+ *
+ * The format procedure may choose another value. Use 0 as default value.
+ */
+ uint32_t sectors_per_cluster;
+
+ /**
+ * @brief Number of FATs hint.
+ *
+ * Use 0 as default value.
+ */
+ uint32_t fat_num;
+
+ /**
+ * @brief Minimum files in root directory for FAT12 and FAT16.
+ *
+ * The format procedure may choose a greater value. Use 0 as default value.
+ */
+ uint32_t files_per_root_dir;
+
+ /**
+ * @brief Media code.
+ *
+ * Use 0 as default value. The default media code is 0xf8.
+ */
+ uint8_t media;
+
+ /**
+ * @brief Quick format.
+ *
+ * If set to true, then do not clear data sectors to zero.
+ */
+ bool quick_format;
+
+ /**
+ * @brief Do not align FAT, data cluster, and root directory to a cluster
+ * boundary.
+ */
+ bool skip_alignment;
+
+ /**
+ * @brief Synchronize device after write operations.
+ */
+ bool sync_device;
+
+ /**
+ * @brief The amount of info to output.
+ */
+ int info_level;
+} msdos_format_request_param_t;
+
+/**
+ * @brief Formats a block device with a FAT file system.
+ *
+ * @param[in] devname The block device path.
+ * @param[in] rqdata The FAT file system format request data. Use NULL for
+ * default parameters.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The @c errno indicates the error.
+ */
+int msdos_format (
+ const char *devname,
+ const msdos_format_request_param_t *rqdata
+);
+
+/** @} */
+
+int rtems_dosfs_initialize(rtems_filesystem_mount_table_entry_t *mt_entry,
+ const void *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/dumpbuf.h b/cpukit/include/rtems/dumpbuf.h
new file mode 100644
index 0000000000..d714879ab4
--- /dev/null
+++ b/cpukit/include/rtems/dumpbuf.h
@@ -0,0 +1,52 @@
+/**
+ * @file
+ *
+ * @brief Print a Memory Buffer
+ *
+ * This file defines the interface to the RTEMS methods to print a
+ * memory buffer in a style similar to many ROM monitors and debuggers.
+ */
+
+/*
+ * COPYRIGHT (c) 1997-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef __DUMP_BUFFER_h
+#define __DUMP_BUFFER_h
+
+/**
+ * @defgroup libmisc_dumpbuf Print Memory Buffer
+ *
+ * @ingroup libmisc
+ */
+/**@{*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Print memory buffer.
+ *
+ * This method prints @a length bytes beginning at @a buffer in
+ * a nice format similar to what one would expect from a debugger
+ * or ROM monitor.
+ *
+ * @param[in] buffer is the address of the buffer
+ * @param[in] length is the length of the buffer
+ */
+void rtems_print_buffer(
+ const unsigned char *buffer,
+ int length
+);
+
+#ifdef __cplusplus
+}
+#endif
+/**@}*/
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/error.h b/cpukit/include/rtems/error.h
new file mode 100644
index 0000000000..617f59642b
--- /dev/null
+++ b/cpukit/include/rtems/error.h
@@ -0,0 +1,135 @@
+/**
+ * @file rtems/error.h
+ *
+ * @brief RTEMS Error Reporting
+ *
+ * Defines and externs for rtems error reporting
+ *
+ * These routines provide general purpose error reporting.
+ * rtems_error reports an error to stderr and allows use of
+ * printf style formatting. A newline is appended to all messages.
+ *
+ * error_flag can be specified as any of the following:
+ *
+ * RTEMS_ERROR_ERRNO -- include errno text in output
+ * RTEMS_ERROR_PANIC -- halts local system after output
+ * RTEMS_ERROR_ABORT -- abort after output
+ *
+ * It can also include a rtems_status value which can be OR'd
+ * with the above flags. *
+ *
+ * Example 1:
+ * @code
+ * #include <rtems.h>
+ * #include <rtems/error.h>
+ * rtems_error(0, "stray interrupt %d", intr);
+ * @endcode
+ *
+ * Example 2:
+ * @code
+ * if ((status = rtems_task_create(...)) != RTEMS_SUCCCESSFUL)
+ * {
+ * rtems_error(status | RTEMS_ERROR_ABORT,
+ * "could not create task");
+ * }
+ * @endcode
+ *
+ * Example 3:
+ * @code
+ * if ((fd = open(pathname, O_RDNLY)) < 0)
+ * {
+ * rtems_error(RTEMS_ERROR_ERRNO, "open of '%s' failed", pathname);
+ * goto failed;
+ * }
+ * @endcode
+ */
+
+#ifndef _RTEMS_RTEMS_ERROR_H
+#define _RTEMS_RTEMS_ERROR_H
+
+#include <rtems/rtems/status.h>
+#include <rtems/fatal.h>
+
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ErrorPanicSupport Error And Panic Support
+ *
+ * @ingroup libcsupport
+ *
+ * @brief Defines and externs for rtems error reporting
+ *
+ */
+typedef Internal_errors_t rtems_error_code_t;
+
+/*
+ * rtems_error(), rtems_verror() and rtems_panic() support
+ */
+
+#if 0
+/* not 16bit-int host clean */
+#define RTEMS_ERROR_ERRNO (1<<((sizeof(rtems_error_code_t) * CHAR_BIT) - 2)) /* hi bit; use 'errno' */
+#define RTEMS_ERROR_PANIC (RTEMS_ERROR_ERRNO / 2) /* err fatal; no return */
+#define RTEMS_ERROR_ABORT (RTEMS_ERROR_ERRNO / 4) /* err is fatal; panic */
+#else
+#define RTEMS_ERROR_ERRNO (0x40000000) /* hi bit; use 'errno' */
+#define RTEMS_ERROR_PANIC (0x20000000) /* err fatal; no return */
+#define RTEMS_ERROR_ABORT (0x10000000) /* err is fatal; panic */
+#endif
+
+#define RTEMS_ERROR_MASK \
+ (RTEMS_ERROR_ERRNO | RTEMS_ERROR_ABORT | RTEMS_ERROR_PANIC) /* all */
+
+/**
+ * @brief Report an Error
+ *
+ * @param[in] error_code can be specified as any of the following:
+ * RTEMS_ERROR_ERRNO -- include errno text in output
+ * RTEMS_ERROR_PANIC -- halts local system after output
+ * RTEMS_ERROR_ABORT -- abort after output
+ *
+ * @param[in] printf_format is a normal printf(3) format string,
+ * with its concommitant arguments
+ *
+ * @return the number of characters written.
+ */
+int rtems_error(
+ rtems_error_code_t error_code,
+ const char *printf_format,
+ ...
+);
+
+/**
+ * @brief Report an Error
+ *
+ * @param[in] error_code can be specified as any of the following:
+ * RTEMS_ERROR_ERRNO -- include errno text in output
+ * RTEMS_ERROR_PANIC -- halts local system after output
+ * RTEMS_ERROR_ABORT -- abort after output
+ *
+ * @param[in] printf_format is a normal printf(3) format string,
+ * with its concommitant arguments
+ * @param[in] arglist is a varargs list corresponding to
+ * printf_format
+ *
+ * @return the number of characters written.
+ */
+int rtems_verror(
+ rtems_error_code_t error_code,
+ const char *printf_format,
+ va_list arglist
+);
+
+extern int rtems_panic_in_progress;
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/extension.h b/cpukit/include/rtems/extension.h
new file mode 100644
index 0000000000..f22abf7f18
--- /dev/null
+++ b/cpukit/include/rtems/extension.h
@@ -0,0 +1,245 @@
+/**
+ * @file
+ *
+ * @brief User Extensions API.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_EXTENSION_H
+#define _RTEMS_EXTENSION_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/object.h>
+#include <rtems/score/userext.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/types.h>
+
+typedef struct {
+ Objects_Control Object;
+ User_extensions_Control Extension;
+} Extension_Control;
+
+typedef User_extensions_routine
+ rtems_extension RTEMS_DEPRECATED;
+
+/**
+ * @defgroup ClassicUserExtensions User Extensions
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * @brief The User Extensions Manager allows the application developer to
+ * augment the executive by allowing them to supply extension routines which
+ * are invoked at critical system events.
+ *
+ * @section ClassicUserExtensionsSets Extension Sets
+ *
+ * An @ref User_extensions_Table "extension set" is defined as a set of
+ * routines which are invoked at each of the critical system events at which
+ * user extension routines are invoked. Together a set of these routines
+ * typically perform a specific functionality such as performance monitoring or
+ * debugger support.
+ *
+ * RTEMS allows the user to have multiple extension sets active at the same
+ * time. First, a single static extension set may be defined as the
+ * application's User Extension Table which is included as part of the
+ * Configuration Table. This extension set is active for the entire life of the
+ * system and may not be deleted. This extension set is especially important
+ * because it is the only way the application can provided a fatal error
+ * extension which is invoked if RTEMS fails during the
+ * rtems_initialize_data_structures() directive. The static extension set is
+ * optional and may be configured as @c NULL if no static extension set is
+ * required.
+ *
+ * Second, the user can install dynamic extensions using the
+ * rtems_extension_create() directive. These extensions are RTEMS objects in
+ * that they have a name, an ID, and can be dynamically created and deleted. In
+ * contrast to the static extension set, these extensions can only be created
+ * and installed after the rtems_initialize_data_structures() directive
+ * successfully completes execution. Dynamic extensions are useful for
+ * encapsulating the functionality of an extension set. For example, the
+ * application could use extensions to manage a special coprocessor, do
+ * performance monitoring, and to do stack bounds checking. Each of these
+ * extension sets could be written and installed independently of the others.
+ *
+ * All user extensions are optional and RTEMS places no naming restrictions on
+ * the user. The user extension entry points are copied into an internal RTEMS
+ * structure. This means the user does not need to keep the table after
+ * creating it, and changing the handler entry points dynamically in a table
+ * once created has no effect. Creating a table local to a function can save
+ * space in space limited applications.
+ *
+ * Extension switches do not effect the context switch overhead if no switch
+ * handler is installed.
+ *
+ * @section ClassicUserExtensionsTCB Task Control Block Area
+ *
+ * RTEMS provides for a pointer to a user-defined data area for each extension
+ * set to be linked to each task's control block (TCB). This area is only
+ * available for the dynamic extensions. This set of pointers is an extension
+ * of the TCB and can be used to store additional data required by the user's
+ * extension functions.
+ *
+ * The TCB extension is an array of pointers in the TCB. The index into the
+ * table can be obtained from the extension identifier returned when the
+ * extension is created:
+ *
+ * @code
+ * rtems_tcb *task = some_task;
+ * size_t index = rtems_object_id_get_index(extension_id);
+ * void *extension_data = task->extensions [index];
+ * @endcode
+ *
+ * The number of pointers in the area is the same as the number of user
+ * extension sets configured. This allows an application to augment the TCB
+ * with user-defined information. For example, an application could implement
+ * task profiling by storing timing statistics in the TCB's extended memory
+ * area. When a task context switch is being executed, the task switch
+ * extension could read a real-time clock to calculate how long the task being
+ * swapped out has run as well as timestamp the starting time for the task
+ * being swapped in.
+ *
+ * If used, the extended memory area for the TCB should be allocated and the
+ * TCB extension pointer should be set at the time the task is created or
+ * started by either the task create or task start extension. The application
+ * is responsible for managing this extended memory area for the TCBs. The
+ * memory may be reinitialized by the task restart extension and should be
+ * deallocated by the task delete extension when the task is deleted. Since the
+ * TCB extension buffers would most likely be of a fixed size, the RTEMS
+ * partition manager could be used to manage the application's extended memory
+ * area. The application could create a partition of fixed size TCB extension
+ * buffers and use the partition manager's allocation and deallocation
+ * directives to obtain and release the extension buffers.
+ *
+ * @section ClassicUserExtensionsOrder Order of Invokation
+ *
+ * When one of the critical system events occur, the user extensions are
+ * invoked in either @a forward or @a reverse order. Forward order indicates
+ * that the static extension set is invoked followed by the dynamic extension
+ * sets in the order in which they were created. Reverse order means that the
+ * dynamic extension sets are invoked in the opposite of the order in which
+ * they were created followed by the static extension set. By invoking the
+ * extension sets in this order, extensions can be built upon one another. At
+ * the following system events, the extensions are invoked in forward order:
+ *
+ * - Task creation
+ * - Task start
+ * - Task restart
+ * - Task context switch
+ * - Post task context switch
+ * - Task begins to execute
+ *
+ * At the following system events, the extensions are invoked in reverse order:
+ *
+ * - Task exit
+ * - Task deletion
+ * - Fatal error detection
+ *
+ * At these system events, the extensions are invoked in reverse order to
+ * insure that if an extension set is built upon another, the more complicated
+ * extension is invoked before the extension set it is built upon. For example,
+ * by invoking the static extension set last it is known that the "system"
+ * fatal error extension will be the last fatal error extension executed.
+ * Another example is use of the task delete extension by the Standard C
+ * Library. Extension sets which are installed after the Standard C Library
+ * will operate correctly even if they utilize the C Library because the C
+ * Library's task delete extension is invoked after that of the other
+ * extensions.
+ */
+/**@{**/
+
+typedef User_extensions_thread_create_extension rtems_task_create_extension;
+typedef User_extensions_thread_delete_extension rtems_task_delete_extension;
+typedef User_extensions_thread_start_extension rtems_task_start_extension;
+typedef User_extensions_thread_restart_extension rtems_task_restart_extension;
+typedef User_extensions_thread_switch_extension rtems_task_switch_extension;
+typedef User_extensions_thread_begin_extension rtems_task_begin_extension;
+typedef User_extensions_thread_exitted_extension rtems_task_exitted_extension;
+typedef User_extensions_fatal_extension rtems_fatal_extension;
+typedef User_extensions_thread_terminate_extension rtems_task_terminate_extension;
+
+typedef User_extensions_Table rtems_extensions_table;
+
+typedef Internal_errors_Source rtems_fatal_source;
+
+typedef Internal_errors_t rtems_fatal_code;
+
+/**
+ * @brief Creates an extension set object.
+ *
+ * This directive creates a extension set object from the extension table
+ * @a extension_table. The assigned extension set identifier is returned in
+ * @a id. The identifier is used to access this extension set in other
+ * extension set related directives. The name @a name will be assigned to the
+ * extension set object.
+ *
+ * Newly created extension sets are immediately installed and are invoked upon
+ * the next system event supporting an extension.
+ *
+ * This directive will not cause the calling task to be preempted.
+ *
+ * @retval RTEMS_SUCCESSFUL Extension set created successfully.
+ * @retval RTEMS_INVALID_ADDRESS Identifier pointer is @c NULL.
+ * @retval RTEMS_INVALID_NAME Invalid extension set name.
+ * @retval RTEMS_TOO_MANY Too many extension sets created.
+ */
+rtems_status_code rtems_extension_create(
+ rtems_name name,
+ const rtems_extensions_table *extension_table,
+ rtems_id *id
+);
+
+/**
+ * @brief Identifies an extension set object by a name.
+ *
+ * This directive obtains an extension set identifier in @a id associated with
+ * the extension set name @a name. If the extension set name is not unique,
+ * then the extension set identifier will match one of the extension sets with
+ * that name. However, this extension set identifier is not guaranteed to
+ * correspond to the desired extension set. The extension set identifier is
+ * used to access this extension set in other extension set related directives.
+ *
+ * This directive will not cause the calling task to be preempted.
+ *
+ * @retval RTEMS_SUCCESSFUL Extension set identified successfully.
+ * @retval RTEMS_INVALID_ADDRESS Identifier pointer is @c NULL.
+ * @retval RTEMS_INVALID_NAME Extension set name not found or invalid name.
+ */
+rtems_status_code rtems_extension_ident(
+ rtems_name name,
+ rtems_id *id
+);
+
+/**
+ * @brief Deletes an extension set object specified by the identifier @a id.
+ *
+ * Any subsequent references to the extension's name and identifier are
+ * invalid.
+ *
+ * This directive will not cause the calling task to be preempted.
+ *
+ * @retval RTEMS_SUCCESSFUL Extension set deleted successfully.
+ * @retval RTEMS_INVALID_ID Invalid extension set identifier.
+ */
+rtems_status_code rtems_extension_delete(
+ rtems_id id
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/extensionimpl.h b/cpukit/include/rtems/extensionimpl.h
new file mode 100644
index 0000000000..fb4eeaff7c
--- /dev/null
+++ b/cpukit/include/rtems/extensionimpl.h
@@ -0,0 +1,53 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicUserExtensions
+ *
+ * @brief User Extensions API
+ */
+
+/*
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_EXTENSIONIMPL_H
+#define _RTEMS_EXTENSIONIMPL_H
+
+#include <rtems/extension.h>
+#include <rtems/score/objectimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern Objects_Information _Extension_Information;
+
+RTEMS_INLINE_ROUTINE Extension_Control *_Extension_Allocate( void )
+{
+ return (Extension_Control *) _Objects_Allocate( &_Extension_Information );
+}
+
+RTEMS_INLINE_ROUTINE void _Extension_Free (
+ Extension_Control *the_extension
+)
+{
+ _Objects_Free( &_Extension_Information, &the_extension->Object );
+}
+
+RTEMS_INLINE_ROUTINE Extension_Control *_Extension_Get( Objects_Id id )
+{
+ return (Extension_Control *)
+ _Objects_Get_no_protection( id, &_Extension_Information );
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/fatal.h b/cpukit/include/rtems/fatal.h
new file mode 100644
index 0000000000..291af42c6e
--- /dev/null
+++ b/cpukit/include/rtems/fatal.h
@@ -0,0 +1,134 @@
+/**
+ * @file
+ *
+ * @brief Fatal API.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_FATAL_H
+#define _RTEMS_FATAL_H
+
+#include <rtems/score/basedefs.h> /* RTEMS_NO_RETURN */
+#include <rtems/extension.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicFatal Fatal
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * @brief The Fatal Manager provides functions for fatal system states and or
+ * irrecoverable errors.
+ */
+/**@{**/
+
+/**
+ * @brief Assert context.
+ */
+typedef struct {
+ const char *file;
+ int line;
+ const char *function;
+ const char *failed_expression;
+} rtems_assert_context;
+
+/**
+ * @brief Exception frame.
+ */
+typedef CPU_Exception_frame rtems_exception_frame;
+
+/**
+ * @brief Prints the exception frame via printk().
+ *
+ * @see rtems_fatal() and RTEMS_FATAL_SOURCE_EXCEPTION.
+ */
+static inline void rtems_exception_frame_print(
+ const rtems_exception_frame *frame
+)
+{
+ _CPU_Exception_frame_print( frame );
+}
+
+/**
+ * @brief Invokes the internal error handler with a source of
+ * INTERNAL_ERROR_RTEMS_API and is internal set to false.
+ *
+ * @param[in] the_error is a 32-bit fatal error code.
+ *
+ * @see _Terminate().
+ */
+void rtems_fatal_error_occurred(
+ uint32_t the_error
+) RTEMS_NO_RETURN;
+
+/**
+ * @brief Terminates the system.
+ *
+ * @param[in] fatal_source The fatal source.
+ * @param[in] error_code The error code.
+ *
+ * @see _Terminate().
+ */
+RTEMS_NO_RETURN RTEMS_INLINE_ROUTINE void rtems_fatal(
+ rtems_fatal_source fatal_source,
+ rtems_fatal_code error_code
+)
+{
+ _Terminate( fatal_source, error_code );
+}
+
+/**
+ * @brief Prints the specified message via printk() and terminates the system.
+ *
+ * @param[in] fmt The message format.
+ * @param[in] ... The message parameters.
+ *
+ * @see _Terminate().
+ */
+RTEMS_NO_RETURN void rtems_panic(
+ const char *fmt, ...
+) RTEMS_PRINTFLIKE( 1, 2 );
+
+/**
+ * @brief Returns a text for a fatal source.
+ *
+ * The text for each fatal source is the enumerator constant.
+ *
+ * @param[in] source is the fatal source.
+ *
+ * @retval text The fatal source text.
+ * @retval "?" The passed fatal source is invalid.
+ */
+const char *rtems_fatal_source_text( rtems_fatal_source source );
+
+/**
+ * @brief Returns a text for an internal error code.
+ *
+ * The text for each internal error code is the enumerator constant.
+ *
+ * @param[in] error is the error code.
+ *
+ * @retval text The error code text.
+ * @retval "?" The passed error code is invalid.
+ */
+const char *rtems_internal_error_text( rtems_fatal_code error );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/fb.h b/cpukit/include/rtems/fb.h
new file mode 100644
index 0000000000..bb5cb23805
--- /dev/null
+++ b/cpukit/include/rtems/fb.h
@@ -0,0 +1,101 @@
+/**
+ * @file rtems/fb.h
+ *
+ * @brief Frame Buffer Device Driver
+ *
+ * This file defines the interface to a frame buffer device driver.
+ */
+
+/*
+ * Copyright (c) 2000 - Rosimildo da Silva
+ */
+
+#ifndef _MW_FB_H
+#define _MW_FB_H
+
+#include <stdint.h>
+
+/**
+ * @defgroup libmisc_fb Frame Buffer Device Driver Interface
+ *
+ * @ingroup Device Drivers and Frameworks
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ioctls
+ 0x46 is 'F' */
+#define FBIOGET_VSCREENINFO 0x4600
+#define FBIOPUT_VSCREENINFO 0x4601
+#define FBIOGET_FSCREENINFO 0x4602
+#define FBIOGETCMAP 0x4604
+#define FBIOPUTCMAP 0x4605
+#define FB_EXEC_FUNCTION 0x4606
+#define FBIOSWAPBUFFERS 0x4607
+#define FBIOSETBUFFERMODE 0x4608
+#define FBIOSETVIDEOMODE 0x4609
+
+#define FB_SINGLE_BUFFERED 0
+#define FB_TRIPLE_BUFFERED 1
+
+#define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
+#define FB_TYPE_PLANES 1 /* Non interleaved planes */
+#define FB_TYPE_INTERLEAVED_PLANES 2 /* Interleaved planes */
+#define FB_TYPE_TEXT 3 /* Text/attributes */
+#define FB_TYPE_VGA_PLANES 4 /* EGA/VGA planes */
+#define FB_TYPE_VIRTUAL_BUFFER 5 /* Virtual Buffer */
+
+
+#define FB_VISUAL_MONO01 0 /* Monochr. 1=Black 0=White */
+#define FB_VISUAL_MONO10 1 /* Monochr. 1=White 0=Black */
+#define FB_VISUAL_TRUECOLOR 2 /* True color */
+#define FB_VISUAL_PSEUDOCOLOR 3 /* Pseudo color (like atari) */
+#define FB_VISUAL_DIRECTCOLOR 4 /* Direct color */
+#define FB_VISUAL_STATIC_PSEUDOCOLOR 5 /* Pseudo color readonly */
+
+#define FB_ACCEL_NONE 0 /* no hardware accelerator */
+
+struct fb_bitfield {
+ uint32_t offset; /* beginning of bitfield */
+ uint32_t length; /* length of bitfield */
+ uint32_t msb_right; /* != 0 : Most significant bit is */
+ /* right */
+};
+
+struct fb_var_screeninfo {
+ uint32_t xres; /* visible resolution */
+ uint32_t yres;
+ uint32_t bits_per_pixel; /* guess what */
+ struct fb_bitfield red; /* bitfield in fb mem if true color, */
+ struct fb_bitfield green; /* else only length is significant */
+ struct fb_bitfield blue;
+ struct fb_bitfield transp; /* transparency */
+};
+
+struct fb_fix_screeninfo {
+ volatile char *smem_start; /* Start of frame buffer mem */
+ /* (physical address) */
+ uint32_t smem_len; /* Length of frame buffer mem */
+ uint32_t type; /* see FB_TYPE_* */
+ uint32_t visual; /* see FB_VISUAL_* */
+ uint32_t line_length; /* number of chars per line */
+};
+
+struct fb_cmap {
+ uint32_t start; /* First entry */
+ uint32_t len; /* Number of entries */
+ uint16_t *red; /* Red values */
+ uint16_t *green;
+ uint16_t *blue;
+ uint16_t *transp; /* transparency, can be NULL */
+};
+
+#ifdef __cplusplus
+}
+#endif
+/**@}*/
+
+#endif /* _MW_FB_H */
diff --git a/cpukit/include/rtems/flashdisk.h b/cpukit/include/rtems/flashdisk.h
new file mode 100644
index 0000000000..ec353096ad
--- /dev/null
+++ b/cpukit/include/rtems/flashdisk.h
@@ -0,0 +1,460 @@
+/**
+ * @file
+ *
+ * @ingroup RTEMSFDisk
+ *
+ * @brief Interface to a Flash Disk Block Device
+ *
+ * This file defines the interface to a flash disk block device.
+ */
+
+/*
+ * Copyright (C) 2007 Chris Johns
+ *
+ * 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.
+ */
+
+#if !defined (_RTEMS_FLASHDISK_H_)
+#define _RTEMS_FLASHDISK_H_
+
+#include <stdint.h>
+#include <sys/ioctl.h>
+
+#include <rtems.h>
+
+/**
+ * @defgroup RTEMSFDisk Flash Disk Device
+ *
+ * @ingroup rtems_blkdev
+ *
+ * Flash disk driver for RTEMS provides support for block based
+ * file systems on flash devices. The driver is not a flash file
+ * system nor does it try to compete with flash file systems. It
+ * currently does not journal how-ever block sequence numbering
+ * could be added to allow recovery of a past positions if
+ * a power down occurred while being updated.
+ *
+ * This flash driver provides block device support for most flash
+ * devices. The driver has been tested on NOR type devices such
+ * as the AMLV160 or M28W160. Support for NAND type devices may
+ * require driver changes to allow speedy recover of the block
+ * mapping data and to also handle the current use of word programming.
+ * Currently the page descriptors are stored in the first few pages
+ * of each segment.
+ *
+ * The driver supports devices, segments and pages. You provide
+ * to the driver the device descriptions as a table of device
+ * descriptors. Each device descriptor contain a table of
+ * segment descriptions or segment descriptors. The driver uses
+ * this information to manage the devices.
+ *
+ * A device is made up of segments. These are also called
+ * sectors or blocks. It is the smallest erasable part of a device.
+ * A device can have differing size segments at different
+ * offsets in the device. The segment descriptors support repeating
+ * segments that are continuous in the device. The driver breaks the
+ * segments up into pages. The first pages of a segment contain
+ * the page descriptors. A page descriptor hold the page flags,
+ * a CRC for the page of data and the block number the page
+ * holds. The block can appear in any order in the devices. A
+ * page is active if it hold a current block of data. If the
+ * used bit is set the page is counted as used. A page moves
+ * from erased to active to used then back to erased. If a block
+ * is written that is already in a page, the block is written to
+ * a new page the old page is flagged as used.
+ *
+ * At initialization time each segment's page descriptors are
+ * read into memory and scanned to determine the active pages,
+ * the used pages and the bad pages. If a segment has any erased
+ * pages it is queue on the available queue. If the segment has
+ * no erased pages it is queue on the used queue.
+ *
+ * The available queue is sorted from the least number available
+ * to the most number of available pages. A segment that has just
+ * been erased will placed at the end of the queue. A segment that
+ * has only a few available pages will be used sooner and once
+ * there are no available pages it is queued on the used queue.
+ * The used queue hold segments that have no available pages and
+ * is sorted from the least number of active pages to the most
+ * number of active pages.
+ *
+ * The driver is required to compact segments. Compacting takes
+ * the segment with the most number of available pages from the
+ * available queue then takes segments with the least number of
+ * active pages from the used queue until it has enough pages
+ * to fill the empty segment. As the active pages are moved
+ * they flagged as used and once the segment has only used pages
+ * it is erased.
+ *
+ * A flash block driver like this never knows if a page is not
+ * being used by the file-system. A typical file system is not
+ * design with the idea of erasing a block on a disk once it is
+ * not being used. The file-system will normally use a flag
+ * or a location as a marker to say that part of the disk is
+ * no longer in use. This means a number of blocks could be
+ * held in active pages but are no in use by the file system.
+ * The file system may also read blocks that have never been
+ * written to disk. This complicates the driver and may make
+ * the wear, usage and erase patterns harsher than a flash
+ * file system. The driver may also suffer from problems if
+ * power is lost.
+ *
+ * There are some flash disk specific IO control request types.
+ * To use open the device and issue the ioctl() call.
+ *
+ * @code
+ * int fd = open ("/dev/flashdisk0", O_WRONLY, 0);
+ * if (fd < 0)
+ * {
+ * printf ("driver open failed: %s\n", strerror (errno));
+ * exit (1);
+ * }
+ * if (ioctl (fd, RTEMS_FDISK_IOCTL_ERASE_DISK) < 0)
+ * {
+ * printf ("driver erase failed: %s\n", strerror (errno));
+ * exit (1);
+ * }
+ * close (fd);
+ * @endcode
+ */
+/**@{**/
+
+/**
+ * @brief The base name of the flash disks.
+ */
+#define RTEMS_FLASHDISK_DEVICE_BASE_NAME "/dev/fdd"
+
+#define RTEMS_FDISK_IOCTL_ERASE_DISK _IO('B', 128)
+#define RTEMS_FDISK_IOCTL_COMPACT _IO('B', 129)
+#define RTEMS_FDISK_IOCTL_ERASE_USED _IO('B', 130)
+#define RTEMS_FDISK_IOCTL_MONITORING _IO('B', 131)
+#define RTEMS_FDISK_IOCTL_INFO_LEVEL _IO('B', 132)
+#define RTEMS_FDISK_IOCTL_PRINT_STATUS _IO('B', 133)
+
+/**
+ * @brief Flash Disk Monitoring Data allows a user to obtain
+ * the current status of the disk.
+ */
+typedef struct rtems_fdisk_monitor_data
+{
+ uint32_t block_size;
+ uint32_t block_count;
+ uint32_t unavail_blocks;
+ uint32_t device_count;
+ uint32_t segment_count;
+ uint32_t page_count;
+ uint32_t blocks_used;
+ uint32_t segs_available;
+ uint32_t segs_used;
+ uint32_t segs_failed;
+ uint32_t seg_erases;
+ uint32_t pages_desc;
+ uint32_t pages_active;
+ uint32_t pages_used;
+ uint32_t pages_bad;
+ uint32_t info_level;
+} rtems_fdisk_monitor_data;
+
+/**
+ * @brief Flash Segment Descriptor holds, number of continuous segments in the
+ * device of this type, the base segment number in the device, the address
+ * offset of the base segment in the device, and the size of segment.
+ *
+ * Typically this structure is part of a table of segments in the
+ * device which is referenced in the flash disk configuration table.
+ * The reference is kept in the driver and used all the time to
+ * manage the flash device, therefore it must always exist.
+ */
+typedef struct rtems_fdisk_segment_desc
+{
+ uint16_t count; /**< Number of segments of this type in a row. */
+ uint16_t segment; /**< The base segment number. */
+ uint32_t offset; /**< Address offset of base segment in device. */
+ uint32_t size; /**< Size of the segment in bytes. */
+} rtems_fdisk_segment_desc;
+
+/**
+ * @brief Return the number of kilo-bytes.
+ */
+#define RTEMS_FDISK_KBYTES(_k) (UINT32_C(1024) * (_k))
+
+/**
+ * Forward declaration of the device descriptor.
+ */
+struct rtems_fdisk_device_desc;
+
+/**
+ * @brief Flash Low Level driver handlers.
+ *
+ * Typically this structure is part of a table of handlers in the
+ * device which is referenced in the flash disk configuration table.
+ * The reference is kept in the driver and used all the time to
+ * manage the flash device, therefore it must always exist.
+ */
+typedef struct rtems_fdisk_driver_handlers
+{
+ /**
+ * Read data from the device into the buffer. Return an errno
+ * error number if the device cannot be read. A segment descriptor
+ * can describe more than one segment in a device if the device has
+ * repeating segments. The segment number is the device segment to
+ * access and the segment descriptor must reference the segment
+ * being requested. For example the segment number must resided in
+ * the range [base, base + count).
+ *
+ * @param sd The segment descriptor.
+ * @param device The device to read data from.
+ * @param segment The segment within the device to read.
+ * @param offset The offset in the segment to read.
+ * @param buffer The buffer to read the data into.
+ * @param size The amount of data to read.
+ * @retval 0 No error.
+ * @retval EIO The read did not complete.
+ */
+ int (*read) (const rtems_fdisk_segment_desc* sd,
+ uint32_t device,
+ uint32_t segment,
+ uint32_t offset,
+ void* buffer,
+ uint32_t size);
+
+ /**
+ * Write data from the buffer to the device. Return an errno
+ * error number if the device cannot be written to. A segment
+ * descriptor can describe more than segment in a device if the
+ * device has repeating segments. The segment number is the device
+ * segment to access and the segment descriptor must reference
+ * the segment being requested. For example the segment number must
+ * resided in the range [base, base + count).
+ *
+ * @param sd The segment descriptor.
+ * @param device The device to write data from.
+ * @param segment The segment within the device to write to.
+ * @param offset The offset in the segment to write.
+ * @param buffer The buffer to write the data from.
+ * @param size The amount of data to write.
+ * @retval 0 No error.
+ * @retval EIO The write did not complete or verify.
+ */
+ int (*write) (const rtems_fdisk_segment_desc* sd,
+ uint32_t device,
+ uint32_t segment,
+ uint32_t offset,
+ const void* buffer,
+ uint32_t size);
+
+ /**
+ * Blank a segment in the device. Return an errno error number
+ * if the device cannot be read or is not blank. A segment descriptor
+ * can describe more than segment in a device if the device has
+ * repeating segments. The segment number is the device segment to
+ * access and the segment descriptor must reference the segment
+ * being requested. For example the segment number must resided in
+ * the range [base, base + count).
+ *
+ * @param sd The segment descriptor.
+ * @param device The device to read data from.
+ * @param segment The segment within the device to read.
+ * @param offset The offset in the segment to checl.
+ * @param size The amount of data to check.
+ * @retval 0 No error.
+ * @retval EIO The segment is not blank.
+ */
+ int (*blank) (const rtems_fdisk_segment_desc* sd,
+ uint32_t device,
+ uint32_t segment,
+ uint32_t offset,
+ uint32_t size);
+
+ /**
+ * Verify data in the buffer to the data in the device. Return an
+ * errno error number if the device cannot be read. A segment
+ * descriptor can describe more than segment in a device if the
+ * device has repeating segments. The segment number is the
+ * segment to access and the segment descriptor must reference
+ * the device segment being requested. For example the segment number
+ * must resided in the range [base, base + count).
+ *
+ * @param sd The segment descriptor.
+ * @param device The device to verify data in.
+ * @param segment The segment within the device to verify.
+ * @param offset The offset in the segment to verify.
+ * @param buffer The buffer to verify the data in the device with.
+ * @param size The amount of data to verify.
+ * @retval 0 No error.
+ * @retval EIO The data did not verify.
+ */
+ int (*verify) (const rtems_fdisk_segment_desc* sd,
+ uint32_t device,
+ uint32_t segment,
+ uint32_t offset,
+ const void* buffer,
+ uint32_t size);
+
+ /**
+ * Erase the segment. Return an errno error number if the
+ * segment cannot be erased. A segment descriptor can describe
+ * more than segment in a device if the device has repeating
+ * segments. The segment number is the device segment to access and
+ * the segment descriptor must reference the segment being requested.
+ *
+ * @param sd The segment descriptor.
+ * @param device The device to erase the segment of.
+ * @param segment The segment within the device to erase.
+ * @retval 0 No error.
+ * @retval EIO The segment was not erased.
+ */
+ int (*erase) (const rtems_fdisk_segment_desc* sd,
+ uint32_t device,
+ uint32_t segment);
+
+ /**
+ * Erase the device. Return an errno error number if the
+ * segment cannot be erased. A segment descriptor can describe
+ * more than segment in a device if the device has repeating
+ * segments. The segment number is the segment to access and
+ * the segment descriptor must reference the segment being requested.
+ *
+ * @param sd The segment descriptor.
+ * @param device The device to erase.
+ * @retval 0 No error.
+ * @retval EIO The device was not erased.
+ */
+ int (*erase_device) (const struct rtems_fdisk_device_desc* dd,
+ uint32_t device);
+
+} rtems_fdisk_driver_handlers;
+
+/**
+ * @brief Flash Device Descriptor holds the segments in a device.
+ *
+ * The placing of the segments in a device decriptor allows the low level
+ * driver to share the segment descriptors for a number of devices.
+ *
+ * Typically this structure is part of a table of segments in the
+ * device which is referenced in the flash disk configuration table.
+ * The reference is kept in the driver and used all the time to
+ * manage the flash device, therefore it must always exist.
+ */
+typedef struct rtems_fdisk_device_desc
+{
+ uint32_t segment_count; /**< Number of segments. */
+ const rtems_fdisk_segment_desc* segments; /**< Array of segments. */
+ const rtems_fdisk_driver_handlers* flash_ops; /**< Device handlers. */
+} rtems_fdisk_device_desc;
+
+/**
+ * @brief RTEMS Flash Disk configuration table used to initialise the
+ * driver.
+ *
+ * The unavailable blocks count is the number of blocks less than the
+ * available number of blocks the file system is given. This means there
+ * will always be that number of blocks available when the file system
+ * thinks the disk is full. The compaction code needs blocks to compact
+ * with so you will never be able to have all the blocks allocated to the
+ * file system and be able to full the disk.
+ *
+ * The compacting segment count is the number of segments that are
+ * moved into a new segment. A high number will mean more segments with
+ * low active page counts and high used page counts will be moved into
+ * avaliable pages how-ever this extends the compaction time due to
+ * time it takes the erase the pages. There is no pont making this number
+ * greater than the maximum number of pages in a segment.
+ *
+ * The available compacting segment count is the level when compaction occurs
+ * when writing. If you set this to 0 then compaction will fail because
+ * there will be no segments to compact into.
+ *
+ * The info level can be 0 for off with error, and abort messages allowed.
+ * Level 1 is warning messages, level 1 is informational messages, and level 3
+ * is debugging type prints. The info level can be turned off with a compile
+ * time directive on the command line to the compiler of:
+ *
+ * -DRTEMS_FDISK_TRACE=0
+ */
+typedef struct rtems_flashdisk_config
+{
+ uint32_t block_size; /**< The block size. */
+ uint32_t device_count; /**< The number of devices. */
+ const rtems_fdisk_device_desc* devices; /**< The device descriptions. */
+ uint32_t flags; /**< Set of flags to control
+ driver. */
+ /**
+ * Number of blocks not available to the file system. This number must be
+ * greater than or equal to the number of blocks in the largest segment to
+ * avoid starvation of erased blocks.
+ */
+ uint32_t unavail_blocks;
+
+ uint32_t compact_segs; /**< Max number of segs to
+ compact in one pass. */
+ /**
+ * The number of segments when compaction occurs when writing. In case the
+ * number of segments in the available queue is less than or equal to this
+ * number the compaction process will be triggered. The available queue
+ * contains all segments with erased blocks.
+ */
+ uint32_t avail_compact_segs;
+ uint32_t info_level; /**< Default info level. */
+} rtems_flashdisk_config;
+
+/*
+ * Driver flags.
+ */
+
+/**
+ * Leave the erasing of used segment to the background handler.
+ */
+#define RTEMS_FDISK_BACKGROUND_ERASE (1 << 0)
+
+/**
+ * Leave the compacting of of used segment to the background handler.
+ */
+#define RTEMS_FDISK_BACKGROUND_COMPACT (1 << 1)
+
+/**
+ * Check the pages during initialisation to see which pages are
+ * valid and which are not. This could slow down initialising the
+ * disk driver.
+ */
+#define RTEMS_FDISK_CHECK_PAGES (1 << 2)
+
+/**
+ * Blank check the flash device before writing to them. This is needed if
+ * you think you have a driver or device problem.
+ */
+#define RTEMS_FDISK_BLANK_CHECK_BEFORE_WRITE (1 << 3)
+
+/**
+ * Flash disk device driver initialization. Place in a table as the
+ * initialisation entry and remainder of the entries are the
+ * RTEMS block device generic handlers.
+ *
+ * @param major Flash disk major device number.
+ * @param minor Minor device number, not applicable.
+ * @param arg Initialization argument, not applicable.
+ * @return The rtems_device_driver is actually just
+ * rtems_status_code.
+ */
+rtems_device_driver
+rtems_fdisk_initialize (rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void* arg);
+
+/**
+ * @brief External reference to the configuration. Please supply.
+ * Support is present in confdefs.h for providing this variable.
+ */
+extern const rtems_flashdisk_config rtems_flashdisk_configuration[];
+
+/**
+ * @brief External reference to the number of configurations. Please supply.
+ * Support is present in confdefs.h for providing this variable.
+ */
+extern uint32_t rtems_flashdisk_configuration_size;
+
+/** @} */
+
+#endif
diff --git a/cpukit/include/rtems/fsmount.h b/cpukit/include/rtems/fsmount.h
new file mode 100644
index 0000000000..441b0d68ef
--- /dev/null
+++ b/cpukit/include/rtems/fsmount.h
@@ -0,0 +1,211 @@
+/**
+ * @file rtems/fsmount.h
+ *
+ * @defgroup rtems_fstab File System Mount Support
+ *
+ * @ingroup FileSystemTypesAndMount
+ * @brief File System Mount Functions
+ *
+ * This file contains the fsmount functions. These functions
+ * are used to mount a list of filesystems (and create their mount
+ * points before).
+ */
+
+/*
+ * Copyright (c) 2003 IMD
+ *
+ * Ingenieurbuero fuer Microcomputertechnik Th. Doerfler
+ * <Thomas.Doerfler@imd-systems.de>
+ * all rights reserved
+ *
+ * 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 _FSMOUNT_H
+#define _FSMOUNT_H
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/libcsupport.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup rtems_fstab File System Mount Support
+ *
+ * @ingroup FileSystemTypesAndMount
+ */
+/**@{**/
+
+/**
+ * File system mount report and abort condition flags.
+ *
+ * The flags define, which conditions will cause a report during the mount
+ * process (via printf()) or abort the mount process.
+ *
+ * @see rtems_fstab_entry and rtems_fsmount().
+ */
+typedef enum {
+ /**
+ * No conditions.
+ */
+ RTEMS_FSTAB_NONE = 0U,
+
+ /**
+ * Complete mount process was successful.
+ */
+ RTEMS_FSTAB_OK = 0x1U,
+
+ /**
+ * Mount point creation failed.
+ */
+ RTEMS_FSTAB_ERROR_MOUNT_POINT = 0x2U,
+
+ /**
+ * File system mount failed.
+ */
+ RTEMS_FSTAB_ERROR_MOUNT = 0x4U,
+
+ /**
+ * Something failed.
+ */
+ RTEMS_FSTAB_ERROR = RTEMS_FSTAB_ERROR_MOUNT_POINT | RTEMS_FSTAB_ERROR_MOUNT,
+
+ /**
+ * Any condition.
+ */
+ RTEMS_FSTAB_ANY = RTEMS_FSTAB_OK | RTEMS_FSTAB_ERROR
+} rtems_fstab_conditions;
+
+/**
+ * File system table entry.
+ */
+typedef struct {
+ /**
+ * Source for the mount.
+ */
+ const char *source;
+
+ /**
+ * Target for the mount.
+ */
+ const char *target;
+
+ /**
+ * File system operations.
+ */
+ const char *type;
+
+ /**
+ * File system mount options.
+ */
+ rtems_filesystem_options_t options;
+
+ /**
+ * Report @ref rtems_fstab_conditions "condition flags".
+ */
+ uint16_t report_reasons;
+
+ /**
+ * Abort @ref rtems_fstab_conditions "condition flags".
+ */
+ uint16_t abort_reasons;
+} rtems_fstab_entry;
+
+/**
+ * @brief Mounts the file systems listed in the file system mount table.
+ *
+ * Mounts the file systems listed in the file system mount table @a fstab of
+ * size @a size.
+ *
+ * Each file system will be mounted according to its table entry parameters.
+ * In case of an abort condition the corresponding table index will be reported
+ * in @a abort_index. The pointer @a abort_index may be @c NULL. The mount
+ * point paths will be created with rtems_mkdir() and need not exist
+ * beforehand.
+ *
+ * On success, zero is returned. On error, -1 is returned, and @c errno is set
+ * appropriately.
+ *
+ * @see rtems_bdpart_register_from_disk().
+ *
+ * The following example code tries to mount a FAT file system within a SD
+ * Card. Some cards do not have a partition table so at first it tries to find
+ * a file system inside the hole disk. If this is successful the mount process
+ * will be aborted because the @ref RTEMS_FSTAB_OK condition is true. If this
+ * did not work it tries to mount the file system inside the first partition.
+ * If this fails the mount process will not be aborted (this is already the
+ * last entry), but the last error status will be returned.
+ *
+ * @code
+ * #include <stdio.h>
+ * #include <string.h>
+ * #include <errno.h>
+ *
+ * #include <rtems.h>
+ * #include <rtems/bdpart.h>
+ * #include <rtems/error.h>
+ * #include <rtems/fsmount.h>
+ *
+ * static const rtems_fstab_entry fstab [] = {
+ * {
+ * .source = "/dev/sd-card-a",
+ * .target = "/mnt",
+ * .type = "dosfs",
+ * .options = RTEMS_FILESYSTEM_READ_WRITE,
+ * .report_reasons = RTEMS_FSTAB_ANY,
+ * .abort_reasons = RTEMS_FSTAB_OK
+ * }, {
+ * .source = "/dev/sd-card-a1",
+ * .target = "/mnt",
+ * .type = "dosfs",
+ * .options = RTEMS_FILESYSTEM_READ_WRITE,
+ * .report_reasons = RTEMS_FSTAB_ANY,
+ * .abort_reasons = RTEMS_FSTAB_NONE
+ * }
+ * };
+ *
+ * static void my_mount(void)
+ * {
+ * rtems_status_code sc = RTEMS_SUCCESSFUL;
+ * int rv = 0;
+ * size_t abort_index = 0;
+ *
+ * sc = rtems_bdpart_register_from_disk("/dev/sd-card-a");
+ * if (sc != RTEMS_SUCCESSFUL) {
+ * printf("read partition table failed: %s\n", rtems_status_text(sc));
+ * }
+ *
+ * rv = rtems_fsmount(fstab, sizeof(fstab) / sizeof(fstab [0]), &abort_index);
+ * if (rv != 0) {
+ * printf("mount failed: %s\n", strerror(errno));
+ * }
+ * printf("mount aborted at %zu\n", abort_index);
+ * }
+ * @endcode
+ */
+int rtems_fsmount(
+ const rtems_fstab_entry *fstab,
+ size_t size,
+ size_t *abort_index
+);
+
+/** @} */
+
+typedef rtems_fstab_entry fstab_t;
+
+#define FSMOUNT_MNT_OK RTEMS_FSTAB_OK
+
+#define FSMOUNT_MNTPNT_CRTERR RTEMS_FSTAB_ERROR_MOUNT_POINT
+
+#define FSMOUNT_MNT_FAILED RTEMS_FSTAB_ERROR_MOUNT
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FSMOUNT_H */
diff --git a/cpukit/include/rtems/ftpd.h b/cpukit/include/rtems/ftpd.h
new file mode 100644
index 0000000000..f33ca59d3a
--- /dev/null
+++ b/cpukit/include/rtems/ftpd.h
@@ -0,0 +1,74 @@
+/*
+ * FTP Server Information
+ */
+
+#ifndef _RTEMS_FTPD_H
+#define _RTEMS_FTPD_H
+
+#include <rtems/rtems/tasks.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FTPD_CONTROL_PORT 21
+
+/* Various buffer sizes */
+enum {
+ FTPD_BUFSIZE = 256, /* Size for temporary buffers */
+ FTPD_DATASIZE = 4 * 1024, /* Size for file transfer buffers */
+ FTPD_STACKSIZE = RTEMS_MINIMUM_STACK_SIZE + FTPD_DATASIZE /* Tasks stack size */
+};
+
+/* FTPD access control flags */
+enum
+{
+ FTPD_NO_WRITE = 0x1,
+ FTPD_NO_READ = 0x2,
+ FTPD_NO_RW = FTPD_NO_WRITE | FTPD_NO_READ
+};
+
+typedef int (*rtems_ftpd_hookfunction)(char *, size_t);
+
+#include <rtems/shell.h>
+
+struct rtems_ftpd_hook
+{
+ char *filename;
+ rtems_ftpd_hookfunction hook_function;
+};
+
+struct rtems_ftpd_configuration
+{
+ rtems_task_priority priority; /* FTPD task priority */
+ unsigned long max_hook_filesize; /* Maximum buffersize */
+ /* for hooks */
+ int port; /* Well-known port */
+ struct rtems_ftpd_hook *hooks; /* List of hooks */
+ char const *root; /* Root for FTPD or 0 for / */
+ int tasks_count; /* Max. connections */
+ int idle; /* Idle timeout in seoconds
+ or 0 for no (inf) timeout */
+ int access; /* 0 - r/w, 1 - read-only,
+ 2 - write-only,
+ 3 - browse-only */
+ rtems_shell_login_check_t login; /* Login check or 0 to ignore
+ user/passwd. */
+};
+
+/*
+ * Reply codes.
+ */
+#define PRELIM 1 /* positive preliminary */
+#define COMPLETE 2 /* positive completion */
+#define CONTINUE 3 /* positive intermediate */
+#define TRANSIENT 4 /* transient negative completion */
+#define ERROR 5 /* permanent negative completion */
+
+int rtems_initialize_ftpd(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_FTPD_H */
diff --git a/cpukit/include/rtems/gxx_wrappers.h b/cpukit/include/rtems/gxx_wrappers.h
new file mode 100644
index 0000000000..94502b937f
--- /dev/null
+++ b/cpukit/include/rtems/gxx_wrappers.h
@@ -0,0 +1,80 @@
+/**
+ * @file rtems/gxx_wrappers.h
+ *
+ * RTEMS threads compatibility routines for libgcc2.
+ */
+
+/*
+ * by: Rosimildo da Silva (rdasilva@connecttel.com)
+ *
+ * Used ideas from:
+ * W. Eric Norum
+ * Canadian Light Source
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@cls.usask.ca
+ *
+ * Eric sent some e-mail in the rtems-list as a start point for this
+ * module implementation.
+ */
+
+#ifndef __GCC_WRAPPERS_h
+#define __GCC_WRAPPERS_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup GxxWrappersSupport Gxx Wrappers Support
+ *
+ * @ingroup libcsupport
+ *
+ * @brief RTEMS Threads Compatibility Routines for Libgcc2
+ */
+
+/*
+ * These typedefs should match with the ones defined in the file
+ * gcc/gthr-rtems.h in the gcc distribution.
+ */
+typedef void *__gthread_key_t;
+typedef int __gthread_once_t;
+typedef void *__gthread_mutex_t;
+typedef void *__gthread_recursive_mutex_t;
+
+int rtems_gxx_once(__gthread_once_t *once, void (*func) (void));
+
+int rtems_gxx_key_create (__gthread_key_t *key, void (*dtor) (void *));
+
+int rtems_gxx_key_delete (__gthread_key_t key);
+
+void *rtems_gxx_getspecific(__gthread_key_t key);
+
+int rtems_gxx_setspecific(__gthread_key_t key, const void *ptr);
+
+/*
+ * MUTEX support
+ */
+void rtems_gxx_mutex_init (__gthread_mutex_t *mutex);
+
+int rtems_gxx_mutex_lock (__gthread_mutex_t *mutex);
+
+int rtems_gxx_mutex_destroy (__gthread_mutex_t *mutex);
+
+int rtems_gxx_mutex_trylock (__gthread_mutex_t *mutex);
+
+int rtems_gxx_mutex_unlock (__gthread_mutex_t *mutex);
+
+void rtems_gxx_recursive_mutex_init(__gthread_recursive_mutex_t *mutex);
+
+int rtems_gxx_recursive_mutex_lock(__gthread_recursive_mutex_t *mutex);
+
+int rtems_gxx_recursive_mutex_trylock(__gthread_recursive_mutex_t *mutex);
+
+int rtems_gxx_recursive_mutex_unlock(__gthread_recursive_mutex_t *mutex);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GCC_WRAPPERS_h */
diff --git a/cpukit/include/rtems/ide_part_table.h b/cpukit/include/rtems/ide_part_table.h
new file mode 100644
index 0000000000..8b683b3ff5
--- /dev/null
+++ b/cpukit/include/rtems/ide_part_table.h
@@ -0,0 +1,207 @@
+/**
+ * @file
+ *
+ * @brief "MS-DOS-style" Partition Tables Support
+ */
+
+/*
+ * Copyright (C) 2002 OKTET Ltd., St.-Petersburg, Russia
+ *
+ * Author: Konstantin Abramenko <Konstantin.Abramenko@oktet.ru>
+ * Alexander Kukuta <Alexander.Kukuta@oktet.ru>
+ *
+ * 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_IDE_PART_TABLE_H
+#define _RTEMS_IDE_PART_TABLE_H
+
+#include <rtems/chain.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/endian.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <rtems.h>
+#include <rtems/blkdev.h>
+#include <rtems/libio.h>
+#include <rtems/libio_.h>
+#include <rtems/bdbuf.h>
+#include <rtems/seterr.h>
+
+/* Minor base number for all logical devices */
+#define RTEMS_IDE_SECTOR_BITS 9
+#define RTEMS_IDE_SECTOR_SIZE 512
+#define RTEMS_IDE_PARTITION_DESCRIPTOR_SIZE 16
+#define RTEMS_IDE_PARTITION_MAX_PARTITION_NUMBER 63
+#define RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER 4
+#define RTEMS_IDE_PARTITION_DEV_NAME_LENGTH_MAX 16
+
+#define RTEMS_IDE_PARTITION_MSDOS_SIGNATURE_DATA1 0x55
+#define RTEMS_IDE_PARTITION_MSDOS_SIGNATURE_DATA2 0xaa
+#define RTEMS_IDE_PARTITION_MSDOS_SIGNATURE_OFFSET 0x1fe
+#define RTEMS_IDE_PARTITION_TABLE_OFFSET 0x1be
+#define RTEMS_IDE_PARTITION_TABLE_SIZE (4 * 16)
+#define RTEMS_IDE_PARTITION_BOOTABLE_OFFSET 0
+#define RTEMS_IDE_PARTITION_SYS_TYPE_OFFSET 4
+#define RTEMS_IDE_PARTITION_START_OFFSET 8
+#define RTEMS_IDE_PARTITION_SIZE_OFFSET 12
+
+/*
+ * Conversion from and to little-endian byte order. (no-op on i386/i486)
+ */
+#define LE_TO_CPU_U16(v) le16toh(v)
+#define LE_TO_CPU_U32(v) le32toh(v)
+#define CPU_TO_LE_U16(v) htole16(v)
+#define CPU_TO_LE_U32(v) htole32(v)
+
+/*
+ * sector_data_t --
+ * corresponds to the sector on the device
+ */
+typedef struct rtems_sector_data_s
+{
+ uint32_t sector_num; /* sector number on the device */
+ uint8_t data[RTEMS_ZERO_LENGTH_ARRAY]; /* raw sector data */
+} rtems_sector_data_t;
+
+
+/*
+ * Enum partition types
+ * see list at http://ata-atapi.com/hiwtab.htm
+ *
+ * @todo Should these have RTEMS before them.
+ */
+enum {
+ EMPTY_PARTITION = 0x00,
+ DOS_FAT12_PARTITION = 0x01,
+ DOS_FAT16_PARTITION = 0x04,
+ EXTENDED_PARTITION = 0x05,
+ DOS_P32MB_PARTITION = 0x06,
+ FAT32_PARTITION = 0x0B,
+ FAT32_LBA_PARTITION = 0x0C,
+ FAT16_LBA_PARTITION = 0x0E,
+ DM6_PARTITION = 0x54,
+ EZD_PARTITION = 0x55,
+ DM6_AUX1PARTITION = 0x51,
+ DM6_AUX3PARTITION = 0x53,
+ LINUX_SWAP = 0x82,
+ LINUX_NATIVE = 0x83,
+ LINUX_EXTENDED = 0x85
+};
+
+
+/* Forward declaration */
+struct rtems_disk_desc_s;
+
+/*
+ * part_desc_t --
+ * contains all neccessary information about partition
+ */
+typedef struct rtems_part_desc_s {
+ uint8_t bootable; /* is the partition active */
+ uint8_t sys_type; /* type of partition */
+ uint8_t log_id; /* logical number of partition */
+ uint32_t start; /* first partition sector, in absolute
+ * numeration */
+ uint32_t size; /* size in sectors */
+ uint32_t end; /* last partition sector, end = start + size - 1 */
+ struct rtems_disk_desc_s *disk_desc; /* descriptor of disk, partition
+ * contains in */
+ struct rtems_part_desc_s *ext_part; /* extended partition containing this
+ * one */
+
+ /* partitions, containing in this one */
+ struct rtems_part_desc_s *sub_part[RTEMS_IDE_PARTITION_MAX_SUB_PARTITION_NUMBER];
+} rtems_part_desc_t;
+
+
+
+typedef struct rtems_disk_desc_s {
+ dev_t dev; /* device number */
+
+ /* device name in /dev filesystem */
+ char dev_name[RTEMS_IDE_PARTITION_DEV_NAME_LENGTH_MAX];
+
+ uint32_t sector_size; /* size of sector */
+ uint32_t sector_bits; /* the base-2 logarithm of sector_size */
+ uint32_t lba_size; /* total amount of sectors in lba address mode */
+ int last_log_id; /* used for logical disks enumerating */
+
+ /* primary partition descriptors */
+ rtems_part_desc_t *partitions[RTEMS_IDE_PARTITION_MAX_PARTITION_NUMBER];
+} rtems_disk_desc_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * rtems_ide_part_table_free --
+ * frees disk descriptor structure
+ *
+ * PARAMETERS:
+ * disk_desc - disc descriptor structure to free
+ *
+ * RETURNS:
+ * N/A
+ */
+/**
+ * @deprecated Use the @ref rtems_bdpart "block device partition module" instead.
+ */
+void rtems_ide_part_table_free(
+ rtems_disk_desc_t *disk_desc
+) RTEMS_DEPRECATED;
+
+
+/*
+ * rtems_ide_part_table_get --
+ * reads partition table structure from the device
+ * and creates disk description structure
+ *
+ * PARAMETERS:
+ * dev_name - path to physical device in /dev filesystem
+ * disk_desc - returned disc description structure
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if success, or -1 and corresponding errno else
+ */
+/**
+ * @deprecated Use the @ref rtems_bdpart "block device partition module" instead.
+ */
+rtems_status_code rtems_ide_part_table_get(
+ const char *dev_name,
+ rtems_disk_desc_t *disk_desc
+) RTEMS_DEPRECATED;
+
+
+/*
+ * rtems_ide_part_table_initialize --
+ * initializes logical devices on the physical IDE drive
+ *
+ * PARAMETERS:
+ * dev_name - path to physical device in /dev filesystem
+ *
+ * RETURNS:
+ * RTEMS_SUCCESSFUL if success, or -1 and corresponding errno else
+ */
+/**
+ * @deprecated Use the @ref rtems_bdpart "block device partition module" instead.
+ */
+rtems_status_code rtems_ide_part_table_initialize(
+ const char *dev_name
+) RTEMS_DEPRECATED;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_IDE_PART_TABLE_H */
diff --git a/cpukit/include/rtems/imfs.h b/cpukit/include/rtems/imfs.h
new file mode 100644
index 0000000000..fe3c5b12a9
--- /dev/null
+++ b/cpukit/include/rtems/imfs.h
@@ -0,0 +1,946 @@
+/**
+ * @file
+ *
+ * @brief Header File for the In-Memory File System
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_IMFS_H
+#define _RTEMS_IMFS_H
+
+#include <limits.h>
+
+#include <rtems/libio_.h>
+#include <rtems/pipe.h>
+
+/**
+ * @brief In-Memory File System Support.
+ *
+ * @defgroup IMFS In-Memory File System Support
+ *
+ * @ingroup FileSystemTypesAndMount
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Data types
+ */
+
+struct IMFS_jnode_tt;
+typedef struct IMFS_jnode_tt IMFS_jnode_t;
+
+/**
+ * IMFS "memfile" information
+ *
+ * The data structure for the in-memory "memfiles" is based on classic UNIX.
+ *
+ * block_ptr is a pointer to a block of IMFS_MEMFILE_BYTES_PER_BLOCK in
+ * length which could be data or a table of pointers to blocks.
+ *
+ * Setting IMFS_MEMFILE_BYTES_PER_BLOCK to different values has a significant
+ * impact on the maximum file size supported as well as the amount of
+ * memory wasted due to internal file fragmentation. The following
+ * is a list of maximum file sizes based on various settings
+ *
+ * @code
+ * max_filesize with blocks of 16 is 1,328
+ * max_filesize with blocks of 32 is 18,656
+ * max_filesize with blocks of 64 is 279,488
+ * max_filesize with blocks of 128 is 4,329,344
+ * max_filesize with blocks of 256 is 68,173,568
+ * max_filesize with blocks of 512 is 1,082,195,456
+ * @endcode
+ */
+#define IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK 128
+ extern int imfs_rq_memfile_bytes_per_block;
+ extern int imfs_memfile_bytes_per_block;
+
+#define IMFS_MEMFILE_BYTES_PER_BLOCK imfs_memfile_bytes_per_block
+#define IMFS_MEMFILE_BLOCK_SLOTS \
+ (IMFS_MEMFILE_BYTES_PER_BLOCK / sizeof(void *))
+
+typedef uint8_t *block_p;
+typedef block_p *block_ptr;
+
+/*
+ * Important block numbers for "memfiles"
+ */
+#define FIRST_INDIRECT (0)
+#define LAST_INDIRECT (IMFS_MEMFILE_BLOCK_SLOTS - 1)
+
+#define FIRST_DOUBLY_INDIRECT (LAST_INDIRECT + 1)
+#define LAST_DOUBLY_INDIRECT \
+ (LAST_INDIRECT + \
+ (IMFS_MEMFILE_BLOCK_SLOTS * IMFS_MEMFILE_BLOCK_SLOTS))
+
+#define FIRST_TRIPLY_INDIRECT (LAST_DOUBLY_INDIRECT + 1)
+#define LAST_TRIPLY_INDIRECT \
+ (LAST_DOUBLY_INDIRECT +\
+ (IMFS_MEMFILE_BLOCK_SLOTS * \
+ IMFS_MEMFILE_BLOCK_SLOTS * IMFS_MEMFILE_BLOCK_SLOTS))
+
+#define IMFS_MEMFILE_MAXIMUM_SIZE \
+ (LAST_TRIPLY_INDIRECT * IMFS_MEMFILE_BYTES_PER_BLOCK)
+
+/** @} */
+
+/**
+ * @addtogroup IMFSGenericNodes
+ */
+/**@{*/
+
+/**
+ * @brief Initializes an IMFS node.
+ *
+ * @param[in] node The IMFS node.
+ * @param[in] arg The user provided argument pointer. It may contain node
+ * specific initialization information.
+ *
+ * @retval node Successful operation.
+ * @retval NULL An error occurred. The @c errno indicates the error. This
+ * will abort the make operation.
+ *
+ * @see IMFS_node_control, IMFS_node_initialize_default(), and
+ * IMFS_node_initialize_generic().
+ */
+typedef IMFS_jnode_t *(*IMFS_node_control_initialize)(
+ IMFS_jnode_t *node,
+ void *arg
+);
+
+/**
+ * @brief Returns the node and does nothing else.
+ *
+ * @param[in] node The IMFS node.
+ * @param[in] arg The user provided argument pointer. It is not used.
+ *
+ * @retval node Returns always the node passed as parameter.
+ *
+ * @see IMFS_node_control.
+ */
+IMFS_jnode_t *IMFS_node_initialize_default(
+ IMFS_jnode_t *node,
+ void *arg
+);
+
+IMFS_jnode_t *IMFS_node_initialize_directory(
+ IMFS_jnode_t *node,
+ void *arg
+);
+
+/**
+ * @brief Returns the node and sets the generic node context.
+ *
+ * @param[in] node The IMFS node.
+ * @param[in] arg The user provided argument pointer. It must contain the
+ * generic context.
+ *
+ * @retval node Returns always the node passed as parameter.
+ *
+ * @see IMFS_node_control.
+ */
+IMFS_jnode_t *IMFS_node_initialize_generic(
+ IMFS_jnode_t *node,
+ void *arg
+);
+
+/**
+ * @brief Prepares the removal of an IMFS node from its parent directory.
+ *
+ * @param[in] node The IMFS node.
+ *
+ * @retval node Successful operation.
+ * @retval NULL An error occurred. The @c errno indicates the error. This
+ * will abort the removal operation.
+ *
+ * @see IMFS_node_control and IMFS_node_remove_default().
+ */
+typedef IMFS_jnode_t *(*IMFS_node_control_remove)(
+ IMFS_jnode_t *node
+);
+
+/**
+ * @brief Returns the node and does nothing else.
+ *
+ * @param[in] node The IMFS node.
+ *
+ * @retval node Returns always the node passed as parameter.
+ *
+ * @see IMFS_node_control.
+ */
+IMFS_jnode_t *IMFS_node_remove_default(
+ IMFS_jnode_t *node
+);
+
+IMFS_jnode_t *IMFS_node_remove_directory( IMFS_jnode_t *node );
+
+/**
+ * @brief Destroys an IMFS node.
+ *
+ * @param[in] node The IMFS node.
+ *
+ * @see IMFS_node_control and IMFS_node_destroy_default().
+ */
+typedef void (*IMFS_node_control_destroy)( IMFS_jnode_t *node );
+
+/**
+ * @brief Frees the node.
+ *
+ * @param[in] node The IMFS node.
+ *
+ * @see IMFS_node_control.
+ */
+void IMFS_node_destroy_default( IMFS_jnode_t *node );
+
+/**
+ * @brief IMFS node control.
+ */
+typedef struct {
+ const rtems_filesystem_file_handlers_r *handlers;
+ IMFS_node_control_initialize node_initialize;
+ IMFS_node_control_remove node_remove;
+ IMFS_node_control_destroy node_destroy;
+} IMFS_node_control;
+
+typedef struct {
+ IMFS_node_control node_control;
+ size_t node_size;
+} IMFS_mknod_control;
+
+/** @} */
+
+/**
+ * @addtogroup IMFS
+ */
+/**@{*/
+
+/*
+ * Maximum length of a "basename" of an IMFS file/node.
+ */
+
+#define IMFS_NAME_MAX _POSIX_NAME_MAX
+
+/*
+
+ * The control structure for an IMFS jnode.
+ */
+
+struct IMFS_jnode_tt {
+ rtems_chain_node Node; /* for chaining them together */
+ IMFS_jnode_t *Parent; /* Parent node */
+ const char *name; /* "basename" (not \0 terminated) */
+ uint16_t namelen; /* Length of "basename" */
+ uint16_t flags; /* Node flags */
+ mode_t st_mode; /* File mode */
+ unsigned short reference_count;
+ nlink_t st_nlink; /* Link count */
+
+ uid_t st_uid; /* User ID of owner */
+ gid_t st_gid; /* Group ID of owner */
+
+ time_t stat_atime; /* Time of last access */
+ time_t stat_mtime; /* Time of last modification */
+ time_t stat_ctime; /* Time of last status change */
+ const IMFS_node_control *control;
+};
+
+#define IMFS_NODE_FLAG_NAME_ALLOCATED 0x1
+
+typedef struct {
+ IMFS_jnode_t Node;
+ rtems_chain_control Entries;
+ rtems_filesystem_mount_table_entry_t *mt_fs;
+} IMFS_directory_t;
+
+typedef struct {
+ IMFS_jnode_t Node;
+ rtems_device_major_number major;
+ rtems_device_minor_number minor;
+} IMFS_device_t;
+
+typedef struct {
+ IMFS_jnode_t Node;
+ IMFS_jnode_t *link_node;
+} IMFS_link_t;
+
+typedef struct {
+ IMFS_jnode_t Node;
+ char *name;
+} IMFS_sym_link_t;
+
+typedef struct {
+ IMFS_jnode_t Node;
+ size_t size; /* size of file in bytes */
+} IMFS_filebase_t;
+
+typedef struct {
+ IMFS_filebase_t File;
+ block_ptr indirect; /* array of 128 data blocks pointers */
+ block_ptr doubly_indirect; /* 128 indirect blocks */
+ block_ptr triply_indirect; /* 128 doubly indirect blocks */
+} IMFS_memfile_t;
+
+typedef struct {
+ IMFS_filebase_t File;
+ block_p direct; /* pointer to file image */
+} IMFS_linearfile_t;
+
+/* Support copy on write for linear files */
+typedef union {
+ IMFS_jnode_t Node;
+ IMFS_filebase_t File;
+ IMFS_memfile_t Memfile;
+ IMFS_linearfile_t Linearfile;
+} IMFS_file_t;
+
+typedef struct {
+ IMFS_jnode_t Node;
+ pipe_control_t *pipe;
+} IMFS_fifo_t;
+
+typedef struct {
+ IMFS_jnode_t Node;
+ void *context;
+} IMFS_generic_t;
+
+static inline IMFS_directory_t *IMFS_iop_to_directory(
+ const rtems_libio_t *iop
+)
+{
+ return (IMFS_directory_t *) iop->pathinfo.node_access;
+}
+
+static inline IMFS_device_t *IMFS_iop_to_device( const rtems_libio_t *iop )
+{
+ return (IMFS_device_t *) iop->pathinfo.node_access;
+}
+
+static inline IMFS_file_t *IMFS_iop_to_file( const rtems_libio_t *iop )
+{
+ return (IMFS_file_t *) iop->pathinfo.node_access;
+}
+
+static inline IMFS_memfile_t *IMFS_iop_to_memfile( const rtems_libio_t *iop )
+{
+ return (IMFS_memfile_t *) iop->pathinfo.node_access;
+}
+
+static inline void IMFS_update_atime( IMFS_jnode_t *jnode )
+{
+ struct timeval now;
+
+ gettimeofday( &now, 0 );
+
+ jnode->stat_atime = now.tv_sec;
+}
+
+static inline void IMFS_update_mtime( IMFS_jnode_t *jnode )
+{
+ struct timeval now;
+
+ gettimeofday( &now, 0 );
+
+ jnode->stat_mtime = now.tv_sec;
+}
+
+static inline void IMFS_update_ctime( IMFS_jnode_t *jnode )
+{
+ struct timeval now;
+
+ gettimeofday( &now, 0 );
+
+ jnode->stat_ctime = now.tv_sec;
+}
+
+static inline void IMFS_mtime_ctime_update( IMFS_jnode_t *jnode )
+{
+ struct timeval now;
+
+ gettimeofday( &now, 0 );
+
+ jnode->stat_mtime = now.tv_sec;
+ jnode->stat_ctime = now.tv_sec;
+}
+
+typedef struct {
+ const IMFS_mknod_control *directory;
+ const IMFS_mknod_control *device;
+ const IMFS_mknod_control *file;
+ const IMFS_mknod_control *fifo;
+} IMFS_mknod_controls;
+
+typedef struct {
+ IMFS_directory_t Root_directory;
+ const IMFS_mknod_controls *mknod_controls;
+} IMFS_fs_info_t;
+
+typedef struct {
+ IMFS_fs_info_t *fs_info;
+ const rtems_filesystem_operations_table *ops;
+ const IMFS_mknod_controls *mknod_controls;
+} IMFS_mount_data;
+
+/*
+ * Shared Data
+ */
+
+extern const IMFS_mknod_control IMFS_mknod_control_dir_default;
+extern const IMFS_mknod_control IMFS_mknod_control_dir_minimal;
+extern const IMFS_mknod_control IMFS_mknod_control_device;
+extern const IMFS_mknod_control IMFS_mknod_control_memfile;
+extern const IMFS_node_control IMFS_node_control_linfile;
+extern const IMFS_mknod_control IMFS_mknod_control_fifo;
+extern const IMFS_mknod_control IMFS_mknod_control_enosys;
+
+extern const rtems_filesystem_limits_and_options_t IMFS_LIMITS_AND_OPTIONS;
+
+/*
+ * Routines
+ */
+
+extern int IMFS_initialize(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ const void *data
+);
+
+extern int IMFS_initialize_support(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ const void *data
+);
+
+/**
+ * @brief Unmount this instance of IMFS.
+ */
+extern void IMFS_fsunmount(
+ rtems_filesystem_mount_table_entry_t *mt_entry
+);
+
+/**
+ * @brief RTEMS load tarfs.
+ *
+ * This file implements the "mount" procedure for tar-based IMFS
+ * extensions. The TAR is not actually mounted under the IMFS.
+ * Directories from the TAR file are created as usual in the IMFS.
+ * File entries are created as IMFS_LINEAR_FILE nodes with their nods
+ * pointing to addresses in the TAR image.
+ *
+ * Here we create the mountpoint directory and load the tarfs at
+ * that node. Once the IMFS has been mounted, we work through the
+ * tar image and perform as follows:
+ * - For directories, simply call mkdir(). The IMFS creates nodes as
+ * needed.
+ * - For files, we make our own calls to IMFS eval_for_make and
+ * create_node.
+ *
+ * TAR file format:
+ *
+ * @code
+ * Offset Length Contents
+ * 0 100 bytes File name ('\0' terminated, 99 maxmum length)
+ * 100 8 bytes File mode (in octal ascii)
+ * 108 8 bytes User ID (in octal ascii)
+ * 116 8 bytes Group ID (in octal ascii)
+ * 124 12 bytes File size (s) (in octal ascii)
+ * 136 12 bytes Modify time (in octal ascii)
+ * 148 8 bytes Header checksum (in octal ascii)
+ * 156 1 bytes Link flag
+ * 157 100 bytes Linkname ('\0' terminated, 99 maxmum length)
+ * 257 8 bytes Magic PAX ("ustar\0" + 2 bytes padding)
+ * 257 8 bytes Magic GNU tar ("ustar \0")
+ * 265 32 bytes User name ('\0' terminated, 31 maxmum length)
+ * 297 32 bytes Group name ('\0' terminated, 31 maxmum length)
+ * 329 8 bytes Major device ID (in octal ascii)
+ * 337 8 bytes Minor device ID (in octal ascii)
+ * 345 167 bytes Padding
+ * 512 (s+p) bytes File contents (s+p) := (((s) + 511) & ~511),
+ * round up to 512 bytes
+ * @endcode
+ *
+ * Checksum:
+ * @code
+ * int i, sum;
+ * char *header = tar_header_pointer;
+ *
+ * sum = 0;
+ * for (i = 0; i < 512; i++)
+ * sum += 0xFF & header[i];
+ * @endcode
+ */
+extern int rtems_tarfs_load(
+ const char *mountpoint,
+ uint8_t *tar_image,
+ size_t tar_size
+);
+
+/**
+ * @brief Destroy an IMFS node.
+ */
+extern void IMFS_node_destroy( IMFS_jnode_t *node );
+
+/**
+ * @brief Clone an IMFS node.
+ */
+extern int IMFS_node_clone( rtems_filesystem_location_info_t *loc );
+
+/**
+ * @brief Free an IMFS node.
+ */
+extern void IMFS_node_free( const rtems_filesystem_location_info_t *loc );
+
+/**
+ * @brief Perform a status processing for the IMFS.
+ *
+ * This routine provides a stat for the IMFS file system.
+ */
+extern int IMFS_stat(
+ const rtems_filesystem_location_info_t *loc,
+ struct stat *buf
+);
+
+extern int IMFS_stat_file(
+ const rtems_filesystem_location_info_t *loc,
+ struct stat *buf
+);
+
+/**
+ * @brief IMFS evaluation node support.
+ */
+extern void IMFS_eval_path(
+ rtems_filesystem_eval_path_context_t *ctx
+);
+
+/**
+ * @brief Create a new IMFS link node.
+ *
+ * The following rouine creates a new link node under parent with the
+ * name given in name. The link node is set to point to the node at
+ * to_loc.
+ */
+extern int IMFS_link(
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *targetloc,
+ const char *name,
+ size_t namelen
+);
+
+/**
+ * @brief Change the owner of IMFS.
+ *
+ * This routine is the implementation of the chown() system
+ * call for the IMFS.
+ */
+extern int IMFS_chown(
+ const rtems_filesystem_location_info_t *loc,
+ uid_t owner,
+ gid_t group
+);
+
+/**
+ * @brief Create an IMFS node.
+ *
+ * Routine to create a node in the IMFS file system.
+ */
+extern int IMFS_mknod(
+ const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ mode_t mode,
+ dev_t dev
+);
+
+extern IMFS_jnode_t *IMFS_initialize_node(
+ IMFS_jnode_t *node,
+ const IMFS_node_control *node_control,
+ const char *name,
+ size_t namelen,
+ mode_t mode,
+ void *arg
+);
+
+/**
+ * @brief Create an IMFS node.
+ *
+ * Create an IMFS filesystem node of an arbitrary type that is NOT
+ * the root directory node.
+ */
+extern IMFS_jnode_t *IMFS_create_node(
+ const rtems_filesystem_location_info_t *parentloc,
+ const IMFS_node_control *node_control,
+ size_t node_size,
+ const char *name,
+ size_t namelen,
+ mode_t mode,
+ void *arg
+);
+
+static inline bool IMFS_is_imfs_instance(
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ return loc->mt_entry->ops->clonenod_h == IMFS_node_clone;
+}
+
+/** @} */
+
+/**
+ * @defgroup IMFSGenericNodes IMFS Generic Nodes
+ *
+ * @ingroup LibIO
+ *
+ * @brief Generic nodes are an alternative to standard drivers in RTEMS.
+ *
+ * The handlers of a generic node are called with less overhead compared to the
+ * standard driver operations. The usage of file system node handlers enable
+ * more features like support for fsync() and fdatasync(). The generic nodes
+ * use the reference counting of the IMFS. This provides automatic node
+ * destruction when the last reference vanishes.
+ *
+ * @{
+ */
+
+/**
+ * @brief Initializer for a generic node control.
+ *
+ * @param[in] handlers The file system node handlers.
+ * @param[in] init The node initialization method.
+ * @param[in] destroy The node destruction method.
+ */
+#define IMFS_GENERIC_INITIALIZER( handlers, init, destroy ) \
+ { \
+ ( handlers ), \
+ ( init ), \
+ IMFS_node_remove_default, \
+ ( destroy ) \
+ }
+
+/**
+ * @brief Makes a generic IMFS node.
+ *
+ * @param[in] path The path to the new generic IMFS node.
+ * @param[in] mode The node mode.
+ * @param[in] node_control The node control.
+ * @param[in] context The node control handler context.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The @c errno indicates the error.
+ *
+ * @code
+ * #include <sys/stat.h>
+ * #include <assert.h>
+ * #include <fcntl.h>
+ *
+ * #include <rtems/imfs.h>
+ *
+ * static const rtems_filesystem_file_handlers_r some_node_handlers = {
+ * ...
+ * };
+ *
+ * static IMFS_jnode_t *some_node_init(IMFS_jnode_t *node, void *arg)
+ * {
+ * void *context;
+ *
+ * node = IMFS_node_initialize_generic(node, arg);
+ * context = IMFS_generic_get_context_by_node(node);
+ *
+ * return node;
+ * }
+ *
+ * static void some_node_destroy(IMFS_jnode_t *node)
+ * {
+ * void *context = IMFS_generic_get_context_by_node(node);
+ *
+ * IMFS_node_destroy_default(node);
+ * }
+ *
+ * static const IMFS_node_control some_node_control = IMFS_GENERIC_INITIALIZER(
+ * &some_node_handlers,
+ * some_node_init,
+ * some_node_destroy
+ * );
+ *
+ * void example(void *some_node_context)
+ * {
+ * int rv;
+ *
+ * rv = IMFS_make_generic_node(
+ * "/path/to/some/generic/node",
+ * S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
+ * &some_node_control,
+ * some_node_context
+ * );
+ * assert(rv == 0);
+ * }
+ * @endcode
+ */
+extern int IMFS_make_generic_node(
+ const char *path,
+ mode_t mode,
+ const IMFS_node_control *node_control,
+ void *context
+);
+
+/** @} */
+
+/**
+ * @addtogroup IMFS
+ */
+/**@{*/
+
+/**
+ * @brief Mount an IMFS.
+ */
+extern int IMFS_mount(
+ rtems_filesystem_mount_table_entry_t *mt_entry /* IN */
+);
+
+/**
+ * @brief Unmount an IMFS.
+ */
+extern int IMFS_unmount(
+ rtems_filesystem_mount_table_entry_t *mt_entry /* IN */
+);
+
+/**
+ * @name IMFS Memory File Handlers
+ *
+ * This section contains the set of handlers used to process operations on
+ * IMFS memory file nodes. The memory files are created in memory using
+ * malloc'ed memory. Thus any data stored in one of these files is lost
+ * at system shutdown unless special arrangements to copy the data to
+ * some type of non-volailte storage are made by the application.
+ */
+/**@{*/
+
+extern ssize_t IMFS_memfile_write(
+ IMFS_memfile_t *memfile,
+ off_t start,
+ const unsigned char *source,
+ unsigned int length
+);
+
+/** @} */
+
+/**
+ * @name IMFS Device Node Handlers
+ *
+ * This section contains the set of handlers used to map operations on
+ * IMFS device nodes onto calls to the RTEMS Classic API IO Manager.
+ */
+/**@{*/
+
+extern int device_open(
+ rtems_libio_t *iop, /* IN */
+ const char *pathname, /* IN */
+ int oflag, /* IN */
+ mode_t mode /* IN */
+);
+
+extern int device_close(
+ rtems_libio_t *iop /* IN */
+);
+
+extern ssize_t device_read(
+ rtems_libio_t *iop, /* IN */
+ void *buffer, /* IN */
+ size_t count /* IN */
+);
+
+extern ssize_t device_write(
+ rtems_libio_t *iop, /* IN */
+ const void *buffer, /* IN */
+ size_t count /* IN */
+);
+
+extern int device_ioctl(
+ rtems_libio_t *iop,
+ ioctl_command_t command,
+ void *buffer
+);
+
+extern int device_ftruncate(
+ rtems_libio_t *iop, /* IN */
+ off_t length /* IN */
+);
+
+/** @} */
+
+/**
+ * @brief Set IMFS file access and modification times.
+ *
+ *
+ * This routine is the implementation of the utime() system
+ * call for the IMFS.
+ */
+extern int IMFS_utime(
+ const rtems_filesystem_location_info_t *loc,
+ time_t actime,
+ time_t modtime
+);
+
+/**
+ * @brief Change the IMFS file mode.
+ */
+extern int IMFS_fchmod(
+ const rtems_filesystem_location_info_t *loc,
+ mode_t mode
+);
+
+/**
+ * @brief Create a new IMFS symbolic link node.
+ *
+ * The following rouine creates a new symbolic link node under parent
+ * with the name given in name. The node is set to point to the node at
+ * to_loc.
+ */
+extern int IMFS_symlink(
+ const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ const char *target
+);
+
+/**
+ * @brief Put IMFS symbolic link into buffer.
+ *
+ * The following rouine puts the symbolic links destination name into
+ * buff.
+ *
+ */
+extern ssize_t IMFS_readlink(
+ const rtems_filesystem_location_info_t *loc,
+ char *buf,
+ size_t bufsize
+);
+
+/**
+ * @brief Rename the IMFS.
+ *
+ * The following rouine creates a new link node under parent with the
+ * name given in name and removes the old.
+ */
+extern int IMFS_rename(
+ const rtems_filesystem_location_info_t *oldparentloc,
+ const rtems_filesystem_location_info_t *oldloc,
+ const rtems_filesystem_location_info_t *newparentloc,
+ const char *name,
+ size_t namelen
+);
+/**
+ * @brief IMFS node removal handler.
+ *
+ * This file contains the handler used to remove a node when a file type
+ * does not require special actions.
+ */
+extern int IMFS_rmnod(
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *loc
+);
+
+/*
+ * Turn on IMFS assertions when RTEMS_DEBUG is defined.
+ */
+#ifdef RTEMS_DEBUG
+ #include <assert.h>
+
+ #define IMFS_assert(_x) assert(_x)
+#else
+ #define IMFS_assert(_x)
+#endif
+
+static inline void IMFS_Set_handlers( rtems_filesystem_location_info_t *loc )
+{
+ IMFS_jnode_t *node = (IMFS_jnode_t *) loc->node_access;
+
+ loc->handlers = node->control->handlers;
+}
+
+static inline void IMFS_add_to_directory(
+ IMFS_jnode_t *dir_node,
+ IMFS_jnode_t *entry_node
+)
+{
+ IMFS_directory_t *dir = (IMFS_directory_t *) dir_node;
+
+ entry_node->Parent = dir_node;
+ rtems_chain_append_unprotected( &dir->Entries, &entry_node->Node );
+}
+
+static inline void IMFS_remove_from_directory( IMFS_jnode_t *node )
+{
+ IMFS_assert( node->Parent != NULL );
+ node->Parent = NULL;
+ rtems_chain_extract_unprotected( &node->Node );
+}
+
+static inline bool IMFS_is_directory( const IMFS_jnode_t *node )
+{
+ return S_ISDIR( node->st_mode );
+}
+
+#define IMFS_STAT_FMT_HARD_LINK 0
+
+static inline bool IMFS_is_hard_link( mode_t mode )
+{
+ return ( mode & S_IFMT ) == IMFS_STAT_FMT_HARD_LINK;
+}
+
+static inline ino_t IMFS_node_to_ino( const IMFS_jnode_t *node )
+{
+ return (ino_t) ((uintptr_t) node);
+}
+
+/** @} */
+
+/**
+ * @addtogroup IMFSGenericNodes
+ */
+/**@{*/
+
+static inline void *IMFS_generic_get_context_by_node(
+ const IMFS_jnode_t *node
+)
+{
+ const IMFS_generic_t *generic = (const IMFS_generic_t *) node;
+
+ return generic->context;
+}
+
+static inline void *IMFS_generic_get_context_by_location(
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ return loc->node_access_2;
+}
+
+static inline void *IMFS_generic_get_context_by_iop(
+ const rtems_libio_t *iop
+)
+{
+ return IMFS_generic_get_context_by_location( &iop->pathinfo );
+}
+
+static inline dev_t IMFS_generic_get_device_identifier_by_node(
+ const IMFS_jnode_t *node
+)
+{
+ return rtems_filesystem_make_dev_t_from_pointer( node );
+}
+
+#ifdef __cplusplus
+}
+#endif
+/** @} */
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/init.h b/cpukit/include/rtems/init.h
new file mode 100644
index 0000000000..fa3108ea50
--- /dev/null
+++ b/cpukit/include/rtems/init.h
@@ -0,0 +1,69 @@
+/**
+ * @file
+ *
+ * @brief Constants and Structures Associated
+ * with the Initialization Manager
+ *
+ * This include file contains all the constants and structures associated
+ * with the Initialization Manager. This manager is responsible for
+ * initializing RTEMS, creating and starting all configured initialization
+ * tasks, invoking the initialization routine for each user-supplied device
+ * driver, and initializing the optional multiprocessor layer.
+ *
+ * This manager provides directives to:
+ *
+ * + initialize the RTEMS executive
+ * + shutdown the RTEMS executive
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_INIT_H
+#define _RTEMS_INIT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/rtems/types.h>
+#include <rtems/config.h>
+#include <rtems/rtems/intr.h>
+
+/**
+ * @brief Initializes the system and starts multitasking.
+ *
+ * Iterates through the system initialization linker set and invokes the
+ * registered handlers. The final step is to start multitasking.
+ *
+ * This directive should be called by boot_card() only.
+ *
+ * This directive does not return.
+ */
+void rtems_initialize_executive(void)
+ RTEMS_NO_RETURN;
+
+/**
+ * @brief Shutdown the RTEMS environment.
+ *
+ * This routine implements the rtems_shutdown_executive directive. The
+ * invocation of this directive results in the RTEMS environment being
+ * shutdown and multitasking halted. The system is terminated with a fatal
+ * source of RTEMS_FATAL_SOURCE_EXIT and the specified result code.
+ */
+void rtems_shutdown_executive(
+ uint32_t result
+) RTEMS_NO_RETURN;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/io.h b/cpukit/include/rtems/io.h
new file mode 100644
index 0000000000..760d412bb8
--- /dev/null
+++ b/cpukit/include/rtems/io.h
@@ -0,0 +1,254 @@
+/**
+ * @file
+ *
+ * @brief Classic Input/Output Manager API
+ *
+ * This file emulates the old Classic RTEMS IO manager directives
+ * which register and lookup names using the in-memory filesystem.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_IO_H
+#define _RTEMS_IO_H
+
+#include <rtems/rtems/status.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicIO Input/Output
+ *
+ * @ingroup ClassicRTEMS
+ *
+ */
+/**@{**/
+
+typedef uint32_t rtems_device_major_number;
+
+typedef uint32_t rtems_device_minor_number;
+
+typedef rtems_status_code rtems_device_driver;
+
+typedef rtems_device_driver (*rtems_device_driver_entry)(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *
+);
+
+typedef struct {
+ rtems_device_driver_entry initialization_entry;
+ rtems_device_driver_entry open_entry;
+ rtems_device_driver_entry close_entry;
+ rtems_device_driver_entry read_entry;
+ rtems_device_driver_entry write_entry;
+ rtems_device_driver_entry control_entry;
+} rtems_driver_address_table;
+
+/**
+ * @name Device Driver Maintainance
+ */
+/**@{**/
+
+/**
+ * @brief Returns @c RTEMS_IO_ERROR.
+ *
+ * @retval RTEMS_IO_ERROR Only this one.
+ */
+rtems_status_code rtems_io_driver_io_error(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+);
+
+/**
+ * @brief Registers and initializes the device with the device driver table
+ * @a driver_table and major number @a major.
+ *
+ * If the major number equals zero a major number will be obtained. The major
+ * number of the registered driver will be returned in @a registered_major.
+ *
+ * After a successful registration rtems_io_initialize() will be called to
+ * initialize the device.
+ *
+ * @retval RTEMS_SUCCESSFUL Device successfully registered and initialized.
+ * @retval RTEMS_INVALID_ADDRESS Pointer to driver table or to registered
+ * major number are invalid. Device driver table is empty.
+ * @retval RTEMS_INVALID_NUMBER Invalid major number.
+ * @retval RTEMS_TOO_MANY No major number available.
+ * @retval RTEMS_RESOURCE_IN_USE Major number in use.
+ * @retval RTEMS_CALLED_FROM_ISR Called from interrupt context.
+ * @retval * Status code depends on rtems_io_initialize().
+ */
+rtems_status_code rtems_io_register_driver(
+ rtems_device_major_number major,
+ const rtems_driver_address_table *driver_table,
+ rtems_device_major_number *registered_major
+);
+
+/**
+ * @brief Unregister a driver from the device driver table.
+ *
+ * @param[in] major is the device major number.
+ *
+ * @retval RTEMS_SUCCESSFUL Device driver successfully unregistered.
+ * @retval RTEMS_UNSATISFIED Invalid major number.
+ * @retval RTEMS_CALLED_FROM_ISR Called from interrupt context.
+ */
+rtems_status_code rtems_io_unregister_driver(
+ rtems_device_major_number major
+);
+
+/**
+ * @brief Registers the name @a device_name in the file system for the device
+ * with number tuple @a major and @a minor.
+ *
+ * This assumes that all registered devices are character devices.
+ *
+ * @retval RTEMS_SUCCESSFUL Name successfully registered.
+ * @retval RTEMS_TOO_MANY Name already in use or other errors.
+ */
+rtems_status_code rtems_io_register_name(
+ const char *device_name,
+ rtems_device_major_number major,
+ rtems_device_minor_number minor
+);
+
+/** @} */
+
+/**
+ * @brief IO driver initialization.
+ *
+ * This routine is the initialization directive of the IO manager.
+ *
+ * @param[in] major is the device drive number
+ * @param[in] minor is the device number
+ * @param[in] argument is the pointer to the argument(s)
+ *
+ * @return status code
+ */
+rtems_status_code rtems_io_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+);
+
+/**
+ * @brief Opening for the IO manager.
+ *
+ * Opens a device driver with the number @a major.
+ *
+ * @param[in] major is the device driver number.
+ * @param[in] minor is the device number.
+ * @param[in] argument is the pointer to the argument(s).
+ *
+ * @return Status code.
+ */
+rtems_status_code rtems_io_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+);
+
+/**
+ * @brief Closing for the IO manager.
+ *
+ * This routine is the close directive of the IO manager.
+ *
+ * @param[in] major is the device driver number.
+ * @param[in] minor is the device number.
+ * @param[in] argument is the pointer to the argument(s).
+ *
+ * @return Status code.
+ */
+rtems_status_code rtems_io_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+);
+
+/**
+ * @brief Reading for the IO manager.
+ *
+ * This routine is the read directive of the IO manager.
+ *
+ * @param[in] major is the device driver number.
+ * @param[in] minor is the device number.
+ * @param[in] argument is the pointer to the argument(s).
+ *
+ * @return Status code.
+ */
+rtems_status_code rtems_io_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+);
+
+/**
+ * @brief Writing for the IO manager.
+ *
+ * This routine is the write directive of the IO manager.
+ *
+ * @param[in] major is the device driver number.
+ * @param[in] minor is the device number.
+ * @param[in] argument is the pointer to the argument(s).
+ *
+ * @return Status code.
+ */
+rtems_status_code rtems_io_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+);
+
+/**
+ * @brief Control for the IO manager.
+ *
+ * This routine is the control directive of the IO manager.
+ *
+ * @param[in] major is the device driver number.
+ * @param[in] minor is the device number.
+ * @param[in] argument is the pointer to the argument(s).
+ *
+ * @return Status code.
+ */
+rtems_status_code rtems_io_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *argument
+);
+
+/** @} */
+
+/** @} */
+
+typedef struct {
+ const char *device_name;
+ size_t device_name_length;
+ rtems_device_major_number major;
+ rtems_device_minor_number minor;
+} rtems_driver_name_t;
+
+/**
+ * @deprecated Use stat() instead.
+ */
+rtems_status_code rtems_io_lookup_name(
+ const char *name,
+ rtems_driver_name_t *device_info
+) RTEMS_DEPRECATED;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/ioimpl.h b/cpukit/include/rtems/ioimpl.h
new file mode 100644
index 0000000000..5c4a82eea6
--- /dev/null
+++ b/cpukit/include/rtems/ioimpl.h
@@ -0,0 +1,65 @@
+/**
+ * @file
+ *
+ * @brief Classic Input/Output Manager Implementation API
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_IOIMPL_H
+#define _RTEMS_IOIMPL_H
+
+#include <rtems/io.h>
+#include <rtems/score/isrlock.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+extern const size_t _IO_Number_of_drivers;
+
+extern rtems_driver_address_table _IO_Driver_address_table[];
+
+extern bool _IO_All_drivers_initialized;
+
+/**
+ * @brief Initialization of all device drivers.
+ *
+ * Initializes all device drivers.
+ */
+void _IO_Initialize_all_drivers( void );
+
+ISR_LOCK_DECLARE( extern, _IO_Driver_registration_lock )
+
+RTEMS_INLINE_ROUTINE void _IO_Driver_registration_acquire(
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_ISR_disable_and_acquire(
+ &_IO_Driver_registration_lock,
+ lock_context
+ );
+}
+
+RTEMS_INLINE_ROUTINE void _IO_Driver_registration_release(
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Release_and_ISR_enable(
+ &_IO_Driver_registration_lock,
+ lock_context
+ );
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_IOIMPL_H */
diff --git a/cpukit/include/rtems/iosupp.h b/cpukit/include/rtems/iosupp.h
new file mode 100644
index 0000000000..9fe8a6ab1d
--- /dev/null
+++ b/cpukit/include/rtems/iosupp.h
@@ -0,0 +1,46 @@
+/**
+ * @file rtems/iosupp.h
+ *
+ * This include file defines some special characters of interest.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_IOSUPP_H
+#define _RTEMS_IOSUPP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* character constants */
+
+#define BS 0x08 /* backspace */
+#define LF 0x0a /* line feed */
+#define CR 0x0d /* carriage return */
+#define XON 0x11 /* control-Q */
+#define XOFF 0x13 /* control-S */
+
+/* structures */
+
+#ifdef IOSUPP_INIT
+#define IOSUPP_EXTERN
+#else
+#undef IOSUPP_EXTERN
+#define IOSUPP_EXTERN extern
+#endif
+
+/* functions */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/jffs2.h b/cpukit/include/rtems/jffs2.h
new file mode 100644
index 0000000000..a856c46c41
--- /dev/null
+++ b/cpukit/include/rtems/jffs2.h
@@ -0,0 +1,604 @@
+/*
+ * Copyright (c) 2013, 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_JFFS2_H
+#define RTEMS_JFFS2_H
+
+#include <rtems/fs.h>
+#include <sys/param.h>
+#include <sys/ioccom.h>
+#include <zlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct rtems_jffs2_flash_control rtems_jffs2_flash_control;
+
+/**
+ * @defgroup JFFS2 Journalling Flash File System Version 2 (JFFS2) Support
+ *
+ * @ingroup FileSystemTypesAndMount
+ *
+ * @brief Mount options for the Journalling Flash File System, Version 2
+ * (JFFS2).
+ *
+ * The application must provide flash device geometry information and flash
+ * device operations in the flash control structure
+ * @ref rtems_jffs2_flash_control.
+ *
+ * The application can optionally provide a compressor control structure to
+ * enable data compression using the selected compression algorithm.
+ *
+ * The application must enable JFFS2 support with rtems_filesystem_register()
+ * or CONFIGURE_FILESYSTEM_JFFS2 via <rtems/confdefs.h>.
+ *
+ * An example mount with a simple memory based flash device simulation follows.
+ * The zlib is used for as the compressor.
+ *
+ * @code
+ * #include <string.h>
+ *
+ * #include <rtems/jffs2.h>
+ * #include <rtems/libio.h>
+ *
+ * #define BLOCK_SIZE (32UL * 1024UL)
+ *
+ * #define FLASH_SIZE (32UL * BLOCK_SIZE)
+ *
+ * typedef struct {
+ * rtems_jffs2_flash_control super;
+ * unsigned char area[FLASH_SIZE];
+ * } flash_control;
+ *
+ * static flash_control *get_flash_control(rtems_jffs2_flash_control *super)
+ * {
+ * return (flash_control *) super;
+ * }
+ *
+ * static int flash_read(
+ * rtems_jffs2_flash_control *super,
+ * uint32_t offset,
+ * unsigned char *buffer,
+ * size_t size_of_buffer
+ * )
+ * {
+ * flash_control *self = get_flash_control(super);
+ * unsigned char *chunk = &self->area[offset];
+ *
+ * memcpy(buffer, chunk, size_of_buffer);
+ *
+ * return 0;
+ * }
+ *
+ * static int flash_write(
+ * rtems_jffs2_flash_control *super,
+ * uint32_t offset,
+ * const unsigned char *buffer,
+ * size_t size_of_buffer
+ * )
+ * {
+ * flash_control *self = get_flash_control(super);
+ * unsigned char *chunk = &self->area[offset];
+ * size_t i;
+ *
+ * for (i = 0; i < size_of_buffer; ++i) {
+ * chunk[i] &= buffer[i];
+ * }
+ *
+ * return 0;
+ * }
+ *
+ * static int flash_erase(
+ * rtems_jffs2_flash_control *super,
+ * uint32_t offset
+ * )
+ * {
+ * flash_control *self = get_flash_control(super);
+ * unsigned char *chunk = &self->area[offset];
+ *
+ * memset(chunk, 0xff, BLOCK_SIZE);
+ *
+ * return 0;
+ * }
+ *
+ * static flash_control flash_instance = {
+ * .super = {
+ * .block_size = BLOCK_SIZE,
+ * .flash_size = FLASH_SIZE,
+ * .read = flash_read,
+ * .write = flash_write,
+ * .erase = flash_erase,
+ * .device_identifier = 0xc01dc0fe
+ * }
+ * };
+ *
+ * static rtems_jffs2_compressor_zlib_control compressor_instance = {
+ * .super = {
+ * .compress = rtems_jffs2_compressor_zlib_compress,
+ * .decompress = rtems_jffs2_compressor_zlib_decompress
+ * }
+ * };
+ *
+ * static const rtems_jffs2_mount_data mount_data = {
+ * .flash_control = &flash_instance.super,
+ * .compressor_control = &compressor_instance.super
+ * };
+ *
+ * static void erase_all(void)
+ * {
+ * memset(&flash_instance.area[0], 0xff, FLASH_SIZE);
+ * }
+ *
+ * void example_jffs2_mount(const char *mount_dir)
+ * {
+ * int rv;
+ *
+ * erase_all();
+ *
+ * rv = mount_and_make_target_path(
+ * NULL,
+ * mount_dir,
+ * RTEMS_FILESYSTEM_TYPE_JFFS2,
+ * RTEMS_FILESYSTEM_READ_WRITE,
+ * &mount_data
+ * );
+ * assert(rv == 0);
+ * }
+ * @endcode
+ *
+ * @{
+ */
+
+/**
+ * @brief Read from flash operation.
+ *
+ * @param[in, out] self The flash control.
+ * @param[in] offset The offset to read from the flash begin in bytes.
+ * @param[out] buffer The buffer receiving the data.
+ * @param[in] size_of_buffer The size of the buffer in bytes.
+ *
+ * @retval 0 Successful operation.
+ * @retval -EIO An error occurred. Please note that the value is negative.
+ * @retval other All other values are reserved and must not be used.
+ */
+typedef int (*rtems_jffs2_flash_read)(
+ rtems_jffs2_flash_control *self,
+ uint32_t offset,
+ unsigned char *buffer,
+ size_t size_of_buffer
+);
+
+/**
+ * @brief Write to flash operation.
+ *
+ * @param[in, out] self The flash control.
+ * @param[in] offset The offset to write from the flash begin in bytes.
+ * @param[in] buffer The buffer containing the data to write.
+ * @param[in] size_of_buffer The size of the buffer in bytes.
+ *
+ * @retval 0 Successful operation.
+ * @retval -EIO An error occurred. Please note that the value is negative.
+ * @retval other All other values are reserved and must not be used.
+ */
+typedef int (*rtems_jffs2_flash_write)(
+ rtems_jffs2_flash_control *self,
+ uint32_t offset,
+ const unsigned char *buffer,
+ size_t size_of_buffer
+);
+
+/**
+ * @brief Flash erase operation.
+ *
+ * This operation must erase one block specified by the offset.
+ *
+ * @param[in, out] self The flash control.
+ * @param[in] offset The offset to erase from the flash begin in bytes.
+ *
+ * @retval 0 Successful operation.
+ * @retval -EIO An error occurred. Please note that the value is negative.
+ * @retval other All other values are reserved and must not be used.
+ */
+typedef int (*rtems_jffs2_flash_erase)(
+ rtems_jffs2_flash_control *self,
+ uint32_t offset
+);
+
+/**
+ * @brief Flash destroy operation.
+ *
+ * The flash destroy operation is called during unmount of the file system
+ * instance. It can be used to free the resources associated with the now
+ * unused flash control
+ *
+ * @param[in, out] self The flash control.
+ */
+typedef void (*rtems_jffs2_flash_destroy)(
+ rtems_jffs2_flash_control *self
+);
+
+/**
+ * @brief Trigger garbage collection operation.
+ *
+ * An optional garbage collection thread may perform now a garbage collection
+ * using the RTEMS_JFFS2_ON_DEMAND_GARBAGE_COLLECTION IO control.
+ *
+ * The garbage collection must not run in the executing context.
+ *
+ * @param[in] self The flash control.
+ */
+typedef void (*rtems_jffs2_trigger_garbage_collection)(
+ rtems_jffs2_flash_control *self
+);
+
+/**
+ * @brief JFFS2 flash device control.
+ */
+struct rtems_jffs2_flash_control {
+ /**
+ * @brief The size in bytes of the erasable unit of the flash device.
+ */
+ uint32_t block_size;
+
+ /**
+ * @brief The size in bytes of the flash device.
+ *
+ * It must be an integral multiple of the block size. The flash device must
+ * have at least five blocks.
+ */
+ uint32_t flash_size;
+
+ /**
+ * @brief Read from flash operation.
+ */
+ rtems_jffs2_flash_read read;
+
+ /**
+ * @brief Write to flash operation.
+ */
+ rtems_jffs2_flash_write write;
+
+ /**
+ * @brief Flash erase operation.
+ */
+ rtems_jffs2_flash_erase erase;
+
+ /**
+ * @brief Flash destroy operation.
+ *
+ * This operation is optional and the pointer may be @c NULL.
+ */
+ rtems_jffs2_flash_destroy destroy;
+
+ /**
+ * @brief The device identifier of the flash device.
+ *
+ * It is used in combination with the inode number to uniquely identify a
+ * file system node in the system.
+ */
+ dev_t device_identifier;
+
+ /**
+ * @brief Trigger garbage collection operation.
+ *
+ * This operation is optional and may be NULL. This operation should wake up
+ * a garbage collection thread. The garbage collection thread should use the
+ * RTEMS_JFFS2_ON_DEMAND_GARBAGE_COLLECTION IO control to carry out the work.
+ */
+ rtems_jffs2_trigger_garbage_collection trigger_garbage_collection;
+};
+
+typedef struct rtems_jffs2_compressor_control rtems_jffs2_compressor_control;
+
+/**
+ * @brief Compress operation.
+ *
+ * @param[in, out] self The compressor control.
+ * @param[in] data_in The uncompressed data.
+ * @param[out] cdata_out Pointer to buffer with the compressed data.
+ * @param[in, out] datalen On entry, the size in bytes of the uncompressed
+ * data. On exit, the size in bytes of uncompressed data which was actually
+ * compressed.
+ * @param[in, out] cdatalen On entry, the size in bytes available for
+ * compressed data. On exit, the size in bytes of the actually compressed
+ * data.
+ *
+ * @return The compressor type.
+ */
+typedef uint16_t (*rtems_jffs2_compressor_compress)(
+ rtems_jffs2_compressor_control *self,
+ unsigned char *data_in,
+ unsigned char *cdata_out,
+ uint32_t *datalen,
+ uint32_t *cdatalen
+);
+
+/**
+ * @brief Decompress operation.
+ *
+ * @param[in, out] self The compressor control.
+ * @param[in] comprtype The compressor type.
+ * @param[in] cdata_in The compressed data.
+ * @param[out] data_out The uncompressed data.
+ * @param[in] cdatalen The size in bytes of the compressed data.
+ * @param[in] datalen The size in bytes of the uncompressed data.
+ *
+ * @retval 0 Successful operation.
+ * @retval -EIO An error occurred. Please note that the value is negative.
+ * @retval other All other values are reserved and must not be used.
+ */
+typedef int (*rtems_jffs2_compressor_decompress)(
+ rtems_jffs2_compressor_control *self,
+ uint16_t comprtype,
+ unsigned char *cdata_in,
+ unsigned char *data_out,
+ uint32_t cdatalen,
+ uint32_t datalen
+);
+
+/**
+ * @brief Compressor destroy operation.
+ *
+ * The compressor destroy operation is called during unmount of the file system
+ * instance. It can be used to free the resources associated with the now
+ * unused compressor operations.
+ *
+ * @param[in, out] self The compressor control.
+ */
+typedef void (*rtems_jffs2_compressor_destroy)(
+ rtems_jffs2_compressor_control *self
+);
+
+/**
+ * @brief JFFS2 compressor control.
+ */
+struct rtems_jffs2_compressor_control {
+ /**
+ * @brief Compress operation.
+ */
+ rtems_jffs2_compressor_compress compress;
+
+ /**
+ * @brief Decompress operation.
+ */
+ rtems_jffs2_compressor_decompress decompress;
+
+ /**
+ * @brief Compressor destroy operation.
+ *
+ * This operation is optional and the pointer may be @c NULL.
+ */
+ rtems_jffs2_compressor_destroy destroy;
+
+ /**
+ * @brief Compression buffer.
+ */
+ unsigned char buffer[PAGE_SIZE];
+};
+
+/**
+ * @brief RTIME compressor compress operation.
+ */
+uint16_t rtems_jffs2_compressor_rtime_compress(
+ rtems_jffs2_compressor_control *self,
+ unsigned char *data_in,
+ unsigned char *cdata_out,
+ uint32_t *datalen,
+ uint32_t *cdatalen
+);
+
+/**
+ * @brief RTIME compressor decompress operation.
+ */
+int rtems_jffs2_compressor_rtime_decompress(
+ rtems_jffs2_compressor_control *self,
+ uint16_t comprtype,
+ unsigned char *cdata_in,
+ unsigned char *data_out,
+ uint32_t cdatalen,
+ uint32_t datalen
+);
+
+/**
+ * @brief ZLIB compressor control structure.
+ */
+typedef struct {
+ rtems_jffs2_compressor_control super;
+ z_stream stream;
+} rtems_jffs2_compressor_zlib_control;
+
+/**
+ * @brief ZLIB compressor compress operation.
+ */
+uint16_t rtems_jffs2_compressor_zlib_compress(
+ rtems_jffs2_compressor_control *self,
+ unsigned char *data_in,
+ unsigned char *cdata_out,
+ uint32_t *datalen,
+ uint32_t *cdatalen
+);
+
+/**
+ * @brief ZLIB compressor decompress operation.
+ */
+int rtems_jffs2_compressor_zlib_decompress(
+ rtems_jffs2_compressor_control *self,
+ uint16_t comprtype,
+ unsigned char *cdata_in,
+ unsigned char *data_out,
+ uint32_t cdatalen,
+ uint32_t datalen
+);
+
+/**
+ * @brief JFFS2 mount options.
+ *
+ * For JFFS2 the mount options are mandatory.
+ */
+typedef struct {
+ /**
+ * @brief Flash control.
+ */
+ rtems_jffs2_flash_control *flash_control;
+
+ /**
+ * @brief Compressor control.
+ *
+ * The compressor is optional and this pointer may be @c NULL.
+ */
+ rtems_jffs2_compressor_control *compressor_control;
+} rtems_jffs2_mount_data;
+
+/**
+ * @brief Initialization handler of the JFFS2 file system.
+ *
+ * @param[in, out] mt_entry The mount table entry.
+ * @param[in] data The mount options are mandatory for JFFS2 and data must
+ * point to a valid @ref rtems_jffs2_mount_data structure used for this file
+ * system instance.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The @c errno indicates the error.
+ *
+ * @see mount().
+ */
+int rtems_jffs2_initialize(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ const void *data
+);
+
+/**
+ * @brief JFFS2 filesystem instance information.
+ *
+ * @see RTEMS_JFFS2_GET_INFO.
+ */
+typedef struct {
+ /**
+ * @brief Flash size in bytes.
+ */
+ uint32_t flash_size;
+
+ /**
+ * @brief Count of flash blocks (erasable units).
+ */
+ uint32_t flash_blocks;
+
+ /**
+ * @brief Size of a flash block in bytes.
+ */
+ uint32_t flash_block_size;
+
+ /**
+ * @brief Used size in bytes.
+ *
+ * Used areas contain valid data.
+ */
+ uint32_t used_size;
+
+ /**
+ * @brief Dirty size in bytes.
+ *
+ * Used areas contain no longer used data.
+ */
+ uint32_t dirty_size;
+
+ /**
+ * @brief Wasted size in bytes.
+ *
+ * Wasted areas are unusable.
+ */
+ uint32_t wasted_size;
+
+ /**
+ * @brief Free size in bytes.
+ *
+ * Free areas may be used to store new data.
+ */
+ uint32_t free_size;
+
+ /**
+ * @brief Bad size in bytes.
+ *
+ * Bad areas indicate damaged flash blocks.
+ */
+ uint32_t bad_size;
+
+ /**
+ * @brief Count of clean blocks.
+ *
+ * Clean blocks contain only used areas.
+ */
+ uint32_t clean_blocks;
+
+ /**
+ * @brief Count of dirty blocks.
+ *
+ * Dirty blocks contain dirty and used areas.
+ */
+ uint32_t dirty_blocks;
+
+ /**
+ * @brief Count of erasable blocks.
+ *
+ * Erase blocks contain only dirty or wasted areas.
+ */
+ uint32_t erasable_blocks;
+
+ /**
+ * @brief Count of free blocks.
+ *
+ * Free blocks contain a free area.
+ */
+ uint32_t free_blocks;
+
+ /**
+ * @brief Count of bad blocks.
+ *
+ * Bad blocks are damaged.
+ */
+ uint32_t bad_blocks;
+} rtems_jffs2_info;
+
+/**
+ * @brief IO control to get the JFFS2 filesystem instance information.
+ *
+ * @see rtems_jffs2_info.
+ */
+#define RTEMS_JFFS2_GET_INFO _IOR('F', 1, rtems_jffs2_info)
+
+/**
+ * @brief IO control to perform an on demand garbage collection in a JFFS2
+ * filesystem instance.
+ *
+ * This operation is intended to be used by an optional garbage collection
+ * thread. See rtems_jffs2_flash_control::trigger_garbage_collection.
+ */
+#define RTEMS_JFFS2_ON_DEMAND_GARBAGE_COLLECTION _IO('F', 2)
+
+/**
+ * @brief IO control to force a garbage collection in a JFFS2 filesystem
+ * instance.
+ *
+ * Use this operation with care since it may wear out your flash.
+ */
+#define RTEMS_JFFS2_FORCE_GARBAGE_COLLECTION _IO('F', 3)
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* RTEMS_JFFS2_H */
diff --git a/cpukit/include/rtems/libcsupport.h b/cpukit/include/rtems/libcsupport.h
new file mode 100644
index 0000000000..51607f9ea1
--- /dev/null
+++ b/cpukit/include/rtems/libcsupport.h
@@ -0,0 +1,193 @@
+/**
+ * @file
+ *
+ * @brief Standard C Library Support
+ *
+ * This include file contains the information regarding the
+ * RTEMS specific support for the standard C library.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_LIBCSUPPORT_H
+#define _RTEMS_RTEMS_LIBCSUPPORT_H
+
+#include <sys/types.h>
+#include <stdint.h>
+
+#include <rtems/score/heap.h>
+#include <rtems/rtems/tasks.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup libcsupport Standard C Library Support
+ *
+ * @brief RTEMS Specific Support for the Standard C Library
+ *
+ */
+/**@{**/
+
+extern void malloc_dump(void);
+
+/**
+ * @brief Malloc walk.
+ */
+extern bool malloc_walk(int source, bool printf_enabled);
+
+/**
+ * @brief Set malloc heap pointer.
+ *
+ * This routine is primarily used for debugging.
+ */
+void malloc_set_heap_pointer(Heap_Control *new_heap);
+
+/**
+ * @brief Get malloc heap pointer.
+ *
+ * This routine is primarily used for debugging.
+ */
+Heap_Control *malloc_get_heap_pointer( void );
+
+/**
+ * @brief Get free malloc information.
+ *
+ * Find amount of free heap remaining
+ */
+extern size_t malloc_free_space(void);
+
+/**
+ * @brief Get malloc status information.
+ *
+ * Find amount of free heap remaining.
+ */
+extern int malloc_info(Heap_Information_block *the_info);
+
+/*
+ * Prototypes required to install newlib reentrancy user extension
+ */
+bool newlib_create_hook(
+ rtems_tcb *current_task,
+ rtems_tcb *creating_task
+);
+
+void newlib_terminate_hook(
+ rtems_tcb *current_task
+);
+
+#define RTEMS_NEWLIB_EXTENSION \
+{ \
+ newlib_create_hook, /* rtems_task_create */ \
+ 0, /* rtems_task_start */ \
+ 0, /* rtems_task_restart */ \
+ 0, /* rtems_task_delete */ \
+ 0, /* task_switch */ \
+ 0, /* task_begin */ \
+ 0, /* task_exitted */ \
+ 0, /* fatal */ \
+ newlib_terminate_hook /* thread terminate */ \
+}
+
+typedef struct {
+ uint32_t active_barriers;
+ uint32_t active_extensions;
+ uint32_t active_message_queues;
+ uint32_t active_partitions;
+ uint32_t active_periods;
+ uint32_t active_ports;
+ uint32_t active_regions;
+ uint32_t active_semaphores;
+ uint32_t active_tasks;
+ uint32_t active_timers;
+} rtems_resource_rtems_api;
+
+typedef struct {
+ uint32_t active_message_queues;
+ uint32_t active_semaphores;
+ uint32_t active_threads;
+ uint32_t active_timers;
+} rtems_resource_posix_api;
+
+typedef struct {
+ Heap_Information_block workspace_info;
+ Heap_Information_block heap_info;
+ uint32_t active_posix_key_value_pairs;
+ uint32_t active_posix_keys;
+ rtems_resource_rtems_api rtems_api;
+ rtems_resource_posix_api posix_api;
+ int open_files;
+} rtems_resource_snapshot;
+
+/**
+ * @brief Tasks a snapshot of the resource usage of the system.
+ *
+ * @param[out] snapshot The snapshot of used resources.
+ *
+ * @see rtems_resource_snapshot_equal() and rtems_resource_snapshot_check().
+ *
+ * @code
+ * #include <assert.h>
+ *
+ * #include <rtems/libcsupport.h>
+ *
+ * void example(void)
+ * {
+ * rtems_resource_snapshot before;
+ *
+ * test_setup();
+ * rtems_resource_snapshot_take(&before);
+ * test();
+ * assert(rtems_resource_snapshot_check(&before));
+ * test_cleanup();
+ * }
+ * @endcode
+ */
+void rtems_resource_snapshot_take(rtems_resource_snapshot *snapshot);
+
+/**
+ * @brief Compares two resource snapshots for equality.
+ *
+ * @param[in] a One resource snapshot.
+ * @param[in] b Another resource snapshot.
+ *
+ * @retval true The resource snapshots are equal.
+ * @retval false Otherwise.
+ *
+ * @see rtems_resource_snapshot_take().
+ */
+bool rtems_resource_snapshot_equal(
+ const rtems_resource_snapshot *a,
+ const rtems_resource_snapshot *b
+);
+
+/**
+ * @brief Takes a new resource snapshot and checks that it is equal to the
+ * given resource snapshot.
+ *
+ * @param[in] snapshot The resource snapshot used for comparison with the new
+ * resource snapshot.
+ *
+ * @retval true The resource snapshots are equal.
+ * @retval false Otherwise.
+ *
+ * @see rtems_resource_snapshot_take().
+ */
+bool rtems_resource_snapshot_check(const rtems_resource_snapshot *snapshot);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/libi2c.h b/cpukit/include/rtems/libi2c.h
new file mode 100644
index 0000000000..341e390760
--- /dev/null
+++ b/cpukit/include/rtems/libi2c.h
@@ -0,0 +1,508 @@
+/**
+ * @file
+ *
+ * @ingroup libi2c
+ *
+ * @brief I2C Library
+ */
+
+#ifndef _RTEMS_LIBI2C_H
+#define _RTEMS_LIBI2C_H
+
+/*
+ * Authorship
+ * ----------
+ * This software was created by
+ * Till Straumann <strauman@slac.stanford.edu>, 2005,
+ * Stanford Linear Accelerator Center, Stanford University.
+ *
+ * Acknowledgement of sponsorship
+ * ------------------------------
+ * This software was produced by
+ * the Stanford Linear Accelerator Center, Stanford University,
+ * under Contract DE-AC03-76SFO0515 with the Department of Energy.
+ *
+ * Government disclaimer of liability
+ * ----------------------------------
+ * Neither the United States nor the United States Department of Energy,
+ * nor any of their employees, makes any warranty, express or implied, or
+ * assumes any legal liability or responsibility for the accuracy,
+ * completeness, or usefulness of any data, apparatus, product, or process
+ * disclosed, or represents that its use would not infringe privately owned
+ * rights.
+ *
+ * Stanford disclaimer of liability
+ * --------------------------------
+ * Stanford University makes no representations or warranties, express or
+ * implied, nor assumes any liability for the use of this software.
+ *
+ * Stanford disclaimer of copyright
+ * --------------------------------
+ * Stanford University, owner of the copyright, hereby disclaims its
+ * copyright and all other rights in this software. Hence, anyone may
+ * freely use it for any purpose without restriction.
+ *
+ * Maintenance of notices
+ * ----------------------
+ * In the interest of clarity regarding the origin and status of this
+ * SLAC software, this and all the preceding Stanford University notices
+ * are to remain affixed to any copy or derivative of this software made
+ * or distributed by the recipient and are to be affixed to any copy of
+ * software made or distributed by the recipient that contains a copy or
+ * derivative of this software.
+ *
+ * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
+ */
+
+#include <rtems.h>
+
+#include <rtems/io.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup libi2c I2C Library
+ *
+ * @brief I2C library.
+ *
+ */
+/**@{**/
+
+/* Simple I2C driver API */
+
+/* Initialize the libary - may fail if no semaphore or no driver slot is available */
+extern int rtems_libi2c_initialize (void);
+
+/* Alternatively to rtems_libi2c_initialize() the library can also be
+ * initialized by means of a traditional driver table entry containing
+ * the following entry points:
+ */
+extern rtems_status_code
+rtems_i2c_init (
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg);
+
+extern rtems_status_code
+rtems_i2c_open (
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg);
+
+extern rtems_status_code
+rtems_i2c_close (
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg);
+
+extern rtems_status_code
+rtems_i2c_read (
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg);
+
+extern rtems_status_code
+rtems_i2c_write (
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg);
+
+extern rtems_status_code
+rtems_i2c_ioctl (
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg);
+
+extern const rtems_driver_address_table rtems_libi2c_io_ops;
+
+/* Unfortunately, if you want to add this driver to
+ * a RTEMS configuration table then you need all the
+ * members explicitly :-( (Device_driver_table should
+ * hold pointers to rtems_driver_address_tables rather
+ * than full structs).
+ *
+ * The difficulty is that adding this driver to the
+ * configuration table is not enough; you still need
+ * to populate the framework with low-level bus-driver(s)
+ * and high-level drivers and/or device-files...
+ *
+ * Currently the preferred way is having the BSP
+ * call 'rtems_libi2c_initialize' followed by
+ * 'rtems_libi2c_register_bus' and
+ * 'rtems_libi2c_register_drv' and/or
+ * 'mknod' (for 'raw' device nodes)
+ * from the 'bsp_predriver_hook'.
+ */
+#define RTEMS_LIBI2C_DRIVER_TABLE_ENTRY \
+{ \
+ initialization_entry: rtems_i2c_init, \
+ open_entry: rtems_i2c_open, \
+ close_entry: rtems_i2c_close, \
+ read_entry: rtems_i2c_read, \
+ write_entry: rtems_i2c_write, \
+ control_entry: rtems_i2c_ioctl, \
+}
+
+/* Bus Driver API
+ *
+ * Bus drivers provide access to low-level i2c functions
+ * such as 'send start', 'send address', 'get bytes' etc.
+ */
+
+/* first field must be a pointer to ops; driver
+ * may add its own fields after this.
+ * the struct that is registered with the library
+ * is not copied; a pointer will we passed
+ * to the callback functions (ops).
+ */
+typedef struct rtems_libi2c_bus_t_
+{
+ const struct rtems_libi2c_bus_ops_ *ops;
+ int size; /* size of whole structure */
+} rtems_libi2c_bus_t;
+
+/* Access functions a low level driver must provide;
+ *
+ * All of these, except read_bytes and write_bytes
+ * return RTEMS_SUCCESSFUL on success and an error status
+ * otherwise. The read and write ops return the number
+ * of chars read/written or -(status code) on error.
+ */
+typedef struct rtems_libi2c_bus_ops_
+{
+ /* Initialize the bus; might be called again to reset the bus driver */
+ rtems_status_code (*init) (rtems_libi2c_bus_t * bushdl);
+ /* Send start condition */
+ rtems_status_code (*send_start) (rtems_libi2c_bus_t * bushdl);
+ /* Send stop condition */
+ rtems_status_code (*send_stop) (rtems_libi2c_bus_t * bushdl);
+ /* initiate transfer from (rw!=0) or to a device */
+ rtems_status_code (*send_addr) (rtems_libi2c_bus_t * bushdl,
+ uint32_t addr, int rw);
+ /* read a number of bytes */
+ int (*read_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes,
+ int nbytes);
+ /* write a number of bytes */
+ int (*write_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes,
+ int nbytes);
+ /* ioctl misc functions */
+ int (*ioctl) (rtems_libi2c_bus_t * bushdl,
+ int cmd,
+ void *buffer
+ );
+} rtems_libi2c_bus_ops_t;
+
+
+/*
+ * Register a lowlevel driver
+ *
+ * TODO: better description
+ *
+ * This allocates a major number identifying *this* driver
+ * (i.e., libi2c) and the minor number encodes a bus# and a i2c address.
+ *
+ * The name will be registered in the filesystem (parent
+ * directories must exist, also IMFS filesystem must exist). It may be NULL in
+ * which case the library will pick a default.
+ *
+ * RETURNS: bus # (>=0) or -1 on error (errno set).
+ */
+
+extern int rtems_libi2c_register_bus (const char *name, rtems_libi2c_bus_t * bus);
+
+extern rtems_device_major_number rtems_libi2c_major;
+
+#define RTEMS_LIBI2C_MAKE_MINOR(busno, i2caddr) \
+ ((((busno)&((1<<3)-1))<<10) | ((i2caddr)&((1<<10)-1)))
+
+/* After the library is initialized, a major number is available.
+ * As soon as a low-level bus driver is registered (above routine
+ * returns a 'busno'), a device node can be created in the filesystem
+ * with a major/minor number pair of
+ *
+ * rtems_libi2c_major / RTEMS_LIBI2C_MAKE_MINOR(busno, i2caddr)
+ *
+ * and a 'raw' hi-level driver is then attached to this device
+ * node.
+ * This 'raw' driver has very simple semantics:
+ *
+ * 'open' sends a start condition
+ * 'read'/'write' address the device identified by the i2c bus# and address
+ * encoded in the minor number and read or write, respectively
+ * a stream of bytes from or to the device. Every time the
+ * direction is changed, a 're-start' condition followed by
+ * an 'address' cycle is generated on the i2c bus.
+ * 'close' sends a stop condition.
+ *
+ * Hence, using the 'raw' driver, e.g., 100 bytes at offset 0x200 can be
+ * read from an EEPROM by the following pseudo-code:
+ *
+ * mknod("/dev/i2c-54", mode, MKDEV(rtems_libi2c_major, RTEMS_LIBI2C_MAKE_MINOR(0,0x54)))
+ *
+ * int fd;
+ * char off[2]={0x02,0x00};
+ *
+ * fd = open("/dev/i2c-54",O_RDWR);
+ * write(fd,off,2);
+ * read(fd,buf,100);
+ * close(fd);
+ *
+ */
+
+/* Higher Level Driver API
+ *
+ * Higher level drivers know how to deal with specific i2c
+ * devices (independent of the bus interface chip) and provide
+ * an abstraction, i.e., the usual read/write/ioctl access.
+ *
+ * Using the above example, such a high level driver could
+ * prevent the user from issuing potentially destructive write
+ * operations (the aforementioned EEPROM interprets any 3rd
+ * and following byte written to the device as data, i.e., the
+ * contents could easily be changed!).
+ * The correct 'read-pointer offset' programming could be
+ * implemented in 'open' and 'ioctl' of a high-level driver and
+ * the user would then only have to perform harmless read
+ * operations, e.g.,
+ *
+ * fd = open("/dev/i2c.eeprom",O_RDONLY) / * opens and sets EEPROM read pointer * /
+ * ioctl(fd, IOCTL_SEEK, 0x200) / * repositions the read pointer * /
+ * read(fd, buf, 100)
+ * close(fd)
+ *
+ */
+
+/* struct provided at driver registration. The driver may store
+ * private data behind the mandatory first fields but the size
+ * must be set to the size of the entire struct, e.g.,
+ *
+ * struct driver_pvt {
+ * rtems_libi2c_drv_t pub;
+ * struct { ... } pvt;
+ * } my_driver = {
+ * { ops: my_ops,
+ * size: sizeof(my_driver)
+ * },
+ * { ...};
+ * };
+ *
+ * A pointer to this struct is passed to the callback ops.
+ */
+
+typedef struct rtems_libi2c_drv_t_
+{
+ const rtems_driver_address_table *ops; /* the driver ops */
+ int size; /* size of whole structure (including appended private data) */
+} rtems_libi2c_drv_t;
+
+/*
+ * The high level driver must be registered with a particular
+ * bus number and i2c address.
+ *
+ * The registration procedure also creates a filesystem node,
+ * i.e., the returned minor number is not really needed.
+ *
+ * If the 'name' argument is NULL, no filesystem node is
+ * created (but this can be done 'manually' using rtems_libi2c_major
+ * and the return value of this routine).
+ *
+ * RETURNS minor number (FYI) or -1 on failure
+ */
+extern int
+rtems_libi2c_register_drv (const char *name, rtems_libi2c_drv_t * drvtbl,
+ unsigned bus, unsigned i2caddr);
+
+/* Operations available to high level drivers */
+
+/* NOTES: The bus a device is attached to is LOCKED from the first send_start
+ * until send_stop is executed!
+ *
+ * Bus tenure MUST NOT span multiple system calls - otherwise, a single
+ * thread could get into the protected sections (or would deadlock if the
+ * mutex was not nestable).
+ * E.g., consider what happens if 'open' sends a 'start' and 'close'
+ * sends a 'stop' (i.e., the bus mutex would be locked in 'open' and
+ * released in 'close'. A single thread could try to open two devices
+ * on the same bus and would either deadlock or nest into the bus mutex
+ * and potentially mess up the i2c messages.
+ *
+ * The correct way is to *always* relinquish the i2c bus (i.e., send 'stop'
+ * from any driver routine prior to returning control to the caller.
+ * Consult the implementation of the generic driver routines (open, close, ...)
+ * below or the examples in i2c-2b-eeprom.c and i2c-2b-ds1621.c
+ *
+ * Drivers just pass the minor number on to these routines...
+ */
+extern rtems_status_code rtems_libi2c_send_start (rtems_device_minor_number minor);
+
+extern rtems_status_code rtems_libi2c_send_stop (rtems_device_minor_number minor);
+
+extern rtems_status_code
+rtems_libi2c_send_addr (rtems_device_minor_number minor, int rw);
+
+/* the read/write routines return the number of bytes transferred
+ * or -(status_code) on error.
+ */
+extern int
+rtems_libi2c_read_bytes (rtems_device_minor_number minor,
+ unsigned char *bytes, int nbytes);
+
+extern int
+rtems_libi2c_write_bytes (rtems_device_minor_number minor,
+ const unsigned char *bytes, int nbytes);
+
+/* Send start, send address and read bytes */
+extern int
+rtems_libi2c_start_read_bytes (rtems_device_minor_number minor,
+ unsigned char *bytes,
+ int nbytes);
+
+/* Send start, send address and write bytes */
+extern int
+rtems_libi2c_start_write_bytes (rtems_device_minor_number minor,
+ const unsigned char *bytes,
+ int nbytes);
+
+
+/* call misc iocontrol function */
+extern int
+rtems_libi2c_ioctl (rtems_device_minor_number minor,
+ int cmd,
+ ...);
+/*
+ * NOTE: any low-level driver ioctl returning a negative
+ * result for release the bus (perform a STOP condition)
+ */
+/*******************************
+ * defined IOCTLs:
+ *******************************/
+#define RTEMS_LIBI2C_IOCTL_READ_WRITE 1
+/*
+ * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
+ * RTEMS_LIBI2C_IOCTL_READ_WRITE,
+ * rtems_libi2c_read_write_t *arg);
+ *
+ * This call performs a simultanous read/write transfer,
+ * which is possible (and sometimes needed) for SPI devices
+ *
+ * arg is a pointer to a rd_wr info data structure
+ *
+ * This call is only needed for SPI devices
+ */
+#define RTEMS_LIBI2C_IOCTL_START_TFM_READ_WRITE 2
+/*
+ * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
+ * RTEMS_LIBI2C_IOCTL_START_READ_WRITE,
+ * unsigned char *rd_buffer,
+ * const unsigned char *wr_buffer,
+ * int byte_cnt,
+ * const rtems_libi2c_tfr_mode_t *tfr_mode_ptr);
+ *
+ * This call addresses a slave and then:
+ * - sets the proper transfer mode,
+ * - performs a simultanous read/write transfer,
+ * (which is possible and sometimes needed for SPI devices)
+ * NOTE: - if rd_buffer is NULL, receive data will be dropped
+ * - if wr_buffer is NULL, bytes with content 0 will transmitted
+ *
+ * rd_buffer is a pointer to a receive buffer (or NULL)
+ * wr_buffer is a pointer to the data to be sent (or NULL)
+ *
+ * This call is only needed for SPI devices
+ */
+
+#define RTEMS_LIBI2C_IOCTL_SET_TFRMODE 3
+/*
+ * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
+ * RTEMS_LIBI2C_IOCTL_SET_TFRMODE,
+ * const rtems_libi2c_tfr_mode_t *tfr_mode_ptr);
+ *
+ * This call sets an SPI device to the transfer mode needed (baudrate etc.)
+ *
+ * tfr_mode is a pointer to a structure defining the SPI transfer mode needed
+ * (see below).
+ *
+ * This call is only needed for SPI devices
+ */
+
+#define RTEMS_LIBI2C_IOCTL_GET_DRV_T 4
+
+/*
+ * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
+ * RTEMS_LIBI2C_IOCTL_GET_DRV_T,
+ * const rtems_libi2c_drv_t *drv_t_ptr);
+ *
+ * This call allows the a high-level driver to query its driver table entry,
+ * including its private data appended to it during creation of the entry
+ *
+ */
+
+/**
+ * @brief IO control command for asynchronous read and write.
+ *
+ * @see rtems_libi2c_read_write_done_t and rtems_libi2c_read_write_async_t.
+ *
+ * @warning This is work in progress!
+ */
+#define RTEMS_LIBI2C_IOCTL_READ_WRITE_ASYNC 5
+
+/*
+ * argument data structures for IOCTLs defined above
+ */
+typedef struct {
+ unsigned char *rd_buf;
+ const unsigned char *wr_buf;
+ int byte_cnt;
+} rtems_libi2c_read_write_t;
+
+typedef struct {
+ uint32_t baudrate; /* maximum bits per second */
+ /* only valid for SPI drivers: */
+ uint8_t bits_per_char; /* how many bits per byte/word/longword? */
+ bool lsb_first; /* true: send LSB first */
+ bool clock_inv; /* true: inverted clock (high active) */
+ bool clock_phs; /* true: clock starts toggling at start of data tfr */
+ uint32_t idle_char; /* This character will be continuously transmitted in read only functions */
+} rtems_libi2c_tfr_mode_t;
+
+typedef struct {
+ rtems_libi2c_tfr_mode_t tfr_mode;
+ rtems_libi2c_read_write_t rd_wr;
+} rtems_libi2c_tfm_read_write_t;
+
+/**
+ * @brief Notification function type for asynchronous read and write.
+ *
+ * @see RTEMS_LIBI2C_IOCTL_READ_WRITE_ASYNC and
+ * rtems_libi2c_read_write_async_t.
+ *
+ * @warning This is work in progress!
+ */
+typedef void (*rtems_libi2c_read_write_done_t) \
+ ( int /* return value */, int /* nbytes */, void * /* arg */);
+
+/**
+ * @brief IO command data for asynchronous read and write.
+ *
+ * @see RTEMS_LIBI2C_IOCTL_READ_WRITE_ASYNC and
+ * rtems_libi2c_read_write_done_t.
+ *
+ * @warning This is work in progress!
+ */
+typedef struct {
+ unsigned char *rd_buf;
+ const unsigned char *wr_buf;
+ int byte_cnt;
+ rtems_libi2c_read_write_done_t done;
+ void *arg;
+} rtems_libi2c_read_write_async_t;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/libio.h b/cpukit/include/rtems/libio.h
new file mode 100644
index 0000000000..9d30dafddf
--- /dev/null
+++ b/cpukit/include/rtems/libio.h
@@ -0,0 +1,1967 @@
+/**
+ * @file
+ *
+ * @ingroup LibIO
+ *
+ * @brief Basic IO API
+ *
+ * This file contains the support infrastructure used to manage the
+ * table of integer style file descriptors used by the low level
+ * POSIX system calls like open(), read, fstat(), etc.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Modifications to support reference counting in the file system are
+ * Copyright (c) 2012 embedded brains GmbH.
+ *
+ * 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_RTEMS_LIBIO_H
+#define _RTEMS_RTEMS_LIBIO_H
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioccom.h>
+#include <sys/statvfs.h>
+#include <sys/uio.h>
+
+#include <unistd.h>
+#include <termios.h>
+
+#include <rtems.h>
+#include <rtems/fs.h>
+#include <rtems/chain.h>
+#include <rtems/score/atomic.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct knote;
+
+/**
+ * @defgroup LibIOFSOps File System Operations
+ *
+ * @ingroup LibIO
+ *
+ * @brief File system operations.
+ */
+/**@{**/
+
+/**
+ * @brief Locks a file system instance.
+ *
+ * This lock must allow nesting.
+ *
+ * @param[in, out] mt_entry The mount table entry of the file system instance.
+ *
+ * @see rtems_filesystem_default_lock().
+ */
+typedef void (*rtems_filesystem_mt_entry_lock_t)(
+ const rtems_filesystem_mount_table_entry_t *mt_entry
+);
+
+/**
+ * @brief Unlocks a file system instance.
+ *
+ * @param[in, out] mt_entry The mount table entry of the file system instance.
+ *
+ * @see rtems_filesystem_default_unlock().
+ */
+typedef void (*rtems_filesystem_mt_entry_unlock_t)(
+ const rtems_filesystem_mount_table_entry_t *mt_entry
+);
+
+/**
+ * @brief Path evaluation context.
+ */
+typedef struct {
+ /**
+ * The contents of the remaining path to be evaluated.
+ */
+ const char *path;
+
+ /**
+ * The length of the remaining path to be evaluated.
+ */
+ size_t pathlen;
+
+ /**
+ * The contents of the token to be evaluated with respect to the current
+ * location.
+ */
+ const char *token;
+
+ /**
+ * The length of the token to be evaluated with respect to the current
+ * location.
+ */
+ size_t tokenlen;
+
+ /**
+ * The path evaluation is controlled by the following flags
+ * - RTEMS_FS_PERMS_READ,
+ * - RTEMS_FS_PERMS_WRITE,
+ * - RTEMS_FS_PERMS_EXEC,
+ * - RTEMS_FS_FOLLOW_HARD_LINK,
+ * - RTEMS_FS_FOLLOW_SYM_LINK,
+ * - RTEMS_FS_MAKE,
+ * - RTEMS_FS_EXCLUSIVE,
+ * - RTEMS_FS_ACCEPT_RESIDUAL_DELIMITERS, and
+ * - RTEMS_FS_REJECT_TERMINAL_DOT.
+ */
+ int flags;
+
+ /**
+ * Symbolic link evaluation is a recursive operation. This field helps to
+ * limit the recursion level and thus prevents a stack overflow. The
+ * recursion level is limited by RTEMS_FILESYSTEM_SYMLOOP_MAX.
+ */
+ int recursionlevel;
+
+ /**
+ * This is the current file system location of the evaluation process.
+ * Tokens are evaluated with respect to the current location. The token
+ * interpretation may change the current location. The purpose of the path
+ * evaluation is to change the start location into a final current location
+ * according to the path.
+ */
+ rtems_filesystem_location_info_t currentloc;
+
+ /**
+ * The location of the root directory of the user environment during the
+ * evaluation start.
+ */
+ rtems_filesystem_global_location_t *rootloc;
+
+ /**
+ * The start location of the evaluation process. The start location my
+ * change during symbolic link evaluation.
+ */
+ rtems_filesystem_global_location_t *startloc;
+} rtems_filesystem_eval_path_context_t;
+
+/**
+ * @brief Path evaluation.
+ *
+ * @param[in, out] ctx The path evaluation context.
+ *
+ * @see rtems_filesystem_default_eval_path().
+ */
+typedef void (*rtems_filesystem_eval_path_t)(
+ rtems_filesystem_eval_path_context_t *ctx
+);
+
+/**
+ * @brief Creates a new link for the existing file.
+ *
+ * @param[in] parentloc The location of the parent of the new link.
+ * @param[in] targetloc The location of the target file.
+ * @param[in] name Name for the new link.
+ * @param[in] namelen Length of the name for the new link in characters.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_link().
+ */
+typedef int (*rtems_filesystem_link_t)(
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *targetloc,
+ const char *name,
+ size_t namelen
+);
+
+/**
+ * @brief Changes the mode of a node.
+ *
+ * @param[in] loc The location of the node.
+ * @param[in] mode The new mode of the node
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_fchmod().
+ */
+typedef int (*rtems_filesystem_fchmod_t)(
+ const rtems_filesystem_location_info_t *loc,
+ mode_t mode
+);
+
+/**
+ * @brief Changes owner and group of a node.
+ *
+ * @param[in] loc The location of the node.
+ * @param[in] owner User ID for the node.
+ * @param[in] group Group ID for the node.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_chown().
+ */
+typedef int (*rtems_filesystem_chown_t)(
+ const rtems_filesystem_location_info_t *loc,
+ uid_t owner,
+ gid_t group
+);
+
+/**
+ * @brief Clones a location.
+ *
+ * The location is initialized with a bitwise copy of an existing location.
+ * The caller must ensure that this location is protected from a release during
+ * the clone operation. After a successful clone operation the clone will be
+ * added to the location chain of the corresponding mount table entry.
+ *
+ * @param[in, out] loc Location to clone.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_clonenode().
+ */
+typedef int (*rtems_filesystem_clonenode_t)(
+ rtems_filesystem_location_info_t *loc
+);
+
+/**
+ * @brief Frees the location of a node.
+ *
+ * @param[in] loc The location of the node.
+ *
+ * @see rtems_filesystem_default_freenode().
+ */
+typedef void (*rtems_filesystem_freenode_t)(
+ const rtems_filesystem_location_info_t *loc
+);
+
+/**
+ * @brief Mounts a file system instance in a mount point (directory).
+ *
+ * The mount point belongs to the file system instance of the handler and is
+ * specified by a field of the mount table entry. The handler must check that
+ * the mount point is capable of mounting a file system instance. This is the
+ * last step during the mount process. The file system instance is fully
+ * initialized at this point.
+ *
+ * @param[in] mt_entry The mount table entry.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_mount().
+ */
+typedef int (*rtems_filesystem_mount_t) (
+ rtems_filesystem_mount_table_entry_t *mt_entry
+);
+
+/**
+ * @brief Initializes a file system instance.
+ *
+ * This function must initialize the file system root node in the mount table
+ * entry.
+ *
+ * @param[in] mt_entry The mount table entry.
+ * @param[in] data The data provided by the user.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ */
+typedef int (*rtems_filesystem_fsmount_me_t)(
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ const void *data
+);
+
+/**
+ * @brief Unmounts a file system instance in a mount point (directory).
+ *
+ * In case this function is successful the file system instance will be marked
+ * as unmounted. The file system instance will be destroyed when the last
+ * reference to it vanishes.
+ *
+ * @param[in] mt_entry The mount table entry.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_unmount().
+ */
+typedef int (*rtems_filesystem_unmount_t) (
+ rtems_filesystem_mount_table_entry_t *mt_entry
+);
+
+/**
+ * @brief Destroys a file system instance.
+ *
+ * The mount point node location of the mount table entry is invalid. This
+ * handler must free the file system root location and all remaining resources
+ * of the file system instance.
+ *
+ * @param[in] mt_entry The mount table entry.
+ *
+ * @see rtems_filesystem_default_fsunmount().
+ */
+typedef void (*rtems_filesystem_fsunmount_me_t)(
+ rtems_filesystem_mount_table_entry_t *mt_entry
+);
+
+/**
+ * @brief Tests if the node of one location is equal to the node of the other
+ * location.
+ *
+ * The caller ensures that both nodes are within the same file system instance.
+ *
+ * @param[in] a The one location.
+ * @param[in] b The other location.
+ *
+ * @retval true The nodes of the locations are equal.
+ * @retval false Otherwise.
+ *
+ * @see rtems_filesystem_default_are_nodes_equal().
+ */
+typedef bool (*rtems_filesystem_are_nodes_equal_t)(
+ const rtems_filesystem_location_info_t *a,
+ const rtems_filesystem_location_info_t *b
+);
+
+/**
+ * @brief Creates a new node.
+ *
+ * This handler should create a new node according to the parameters.
+ *
+ * @param[in] parentloc The location of the parent of the new node.
+ * @param[in] name Name for the new node.
+ * @param[in] namelen Length of the name for the new node in characters.
+ * @param[in] mode Mode for the new node.
+ * @param[in] dev Optional device identifier for the new node.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_mknod().
+ */
+typedef int (*rtems_filesystem_mknod_t)(
+ const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ mode_t mode,
+ dev_t dev
+);
+
+/**
+ * @brief Removes a node.
+ *
+ * @param[in] parentloc The location of the parent of the node.
+ * @param[in] loc The location of the node.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_rmnod().
+ */
+typedef int (*rtems_filesystem_rmnod_t)(
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *loc
+);
+
+/**
+ * @brief Set node access and modification times.
+ *
+ * @param[in] loc The location of the node.
+ * @param[in] actime Access time for the node.
+ * @param[in] modtime Modification for the node.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_utime().
+ */
+typedef int (*rtems_filesystem_utime_t)(
+ const rtems_filesystem_location_info_t *loc,
+ time_t actime,
+ time_t modtime
+);
+
+/**
+ * @brief Makes a symbolic link to a node.
+ *
+ * @param[in] parentloc The location of the parent of the new symbolic link.
+ * @param[in] name Name for the new symbolic link.
+ * @param[in] namelen Length of the name for the new symbolic link in
+ * characters.
+ * @param[in] target Contents for the symbolic link.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_symlink().
+ */
+typedef int (*rtems_filesystem_symlink_t)(
+ const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ const char *target
+);
+
+/**
+ * @brief Reads the contents of a symbolic link.
+ *
+ * @param[in] loc The location of the symbolic link.
+ * @param[out] buf The buffer for the contents.
+ * @param[in] bufsize The size of the buffer in characters.
+ *
+ * @retval non-negative Size of the actual contents in characters.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_readlink().
+ */
+typedef ssize_t (*rtems_filesystem_readlink_t)(
+ const rtems_filesystem_location_info_t *loc,
+ char *buf,
+ size_t bufsize
+);
+
+/**
+ * @brief Renames a node.
+ *
+ * @param[in] oldparentloc The location of the parent of the old node.
+ * @param[in] oldloc The location of the old node.
+ * @param[in] newparentloc The location of the parent of the new node.
+ * @param[in] name Name for the new node.
+ * @param[in] namelen Length of the name for the new node in characters.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_rename().
+ */
+typedef int (*rtems_filesystem_rename_t)(
+ const rtems_filesystem_location_info_t *oldparentloc,
+ const rtems_filesystem_location_info_t *oldloc,
+ const rtems_filesystem_location_info_t *newparentloc,
+ const char *name,
+ size_t namelen
+);
+
+/**
+ * @brief Gets file system information.
+ *
+ * @param[in] loc The location of a node.
+ * @param[out] buf Buffer for file system information.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_statvfs().
+ */
+typedef int (*rtems_filesystem_statvfs_t)(
+ const rtems_filesystem_location_info_t *loc,
+ struct statvfs *buf
+);
+
+/**
+ * @brief File system operations table.
+ */
+struct _rtems_filesystem_operations_table {
+ rtems_filesystem_mt_entry_lock_t lock_h;
+ rtems_filesystem_mt_entry_unlock_t unlock_h;
+ rtems_filesystem_eval_path_t eval_path_h;
+ rtems_filesystem_link_t link_h;
+ rtems_filesystem_are_nodes_equal_t are_nodes_equal_h;
+ rtems_filesystem_mknod_t mknod_h;
+ rtems_filesystem_rmnod_t rmnod_h;
+ rtems_filesystem_fchmod_t fchmod_h;
+ rtems_filesystem_chown_t chown_h;
+ rtems_filesystem_clonenode_t clonenod_h;
+ rtems_filesystem_freenode_t freenod_h;
+ rtems_filesystem_mount_t mount_h;
+ rtems_filesystem_unmount_t unmount_h;
+ rtems_filesystem_fsunmount_me_t fsunmount_me_h;
+ rtems_filesystem_utime_t utime_h;
+ rtems_filesystem_symlink_t symlink_h;
+ rtems_filesystem_readlink_t readlink_h;
+ rtems_filesystem_rename_t rename_h;
+ rtems_filesystem_statvfs_t statvfs_h;
+};
+
+/**
+ * @brief File system operations table with default operations.
+ */
+extern const rtems_filesystem_operations_table
+ rtems_filesystem_operations_default;
+
+/**
+ * @brief Obtains the IO library mutex.
+ *
+ * @see rtems_filesystem_mt_entry_lock_t.
+ */
+void rtems_filesystem_default_lock(
+ const rtems_filesystem_mount_table_entry_t *mt_entry
+);
+
+/**
+ * @brief Releases the IO library mutex.
+ *
+ * @see rtems_filesystem_mt_entry_unlock_t.
+ */
+void rtems_filesystem_default_unlock(
+ const rtems_filesystem_mount_table_entry_t *mt_entry
+);
+
+/**
+ * @brief Terminates the path evaluation and replaces the current location with
+ * the null location.
+ *
+ * @see rtems_filesystem_eval_path_t.
+ */
+void rtems_filesystem_default_eval_path(
+ rtems_filesystem_eval_path_context_t *ctx
+);
+
+/**
+ * @retval -1 Always. The errno is set to ENOTSUP.
+ *
+ * @see rtems_filesystem_link_t.
+ */
+int rtems_filesystem_default_link(
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *targetloc,
+ const char *name,
+ size_t namelen
+);
+
+/**
+ * @brief Tests if the node access pointer of one location is equal to
+ * the node access pointer of the other location.
+ *
+ * @param[in] a The one location.
+ * @param[in] b The other location.
+ *
+ * @retval true The node access pointers of the locations are equal.
+ * @retval false Otherwise.
+ *
+ * @see rtems_filesystem_are_nodes_equal_t.
+ */
+bool rtems_filesystem_default_are_nodes_equal(
+ const rtems_filesystem_location_info_t *a,
+ const rtems_filesystem_location_info_t *b
+);
+
+/**
+ * @retval -1 Always. The errno is set to ENOTSUP.
+ *
+ * @see rtems_filesystem_mknod_t.
+ */
+int rtems_filesystem_default_mknod(
+ const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ mode_t mode,
+ dev_t dev
+);
+
+/**
+ * @retval -1 Always. The errno is set to ENOTSUP.
+ *
+ * @see rtems_filesystem_rmnod_t.
+ */
+int rtems_filesystem_default_rmnod(
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *loc
+);
+
+/**
+ * @retval -1 Always. The errno is set to ENOTSUP.
+ *
+ * @see rtems_filesystem_fchmod_t.
+ */
+int rtems_filesystem_default_fchmod(
+ const rtems_filesystem_location_info_t *loc,
+ mode_t mode
+);
+
+/**
+ * @retval -1 Always. The errno is set to ENOTSUP.
+ *
+ * @see rtems_filesystem_chown_t.
+ */
+int rtems_filesystem_default_chown(
+ const rtems_filesystem_location_info_t *loc,
+ uid_t owner,
+ gid_t group
+);
+
+/**
+ * @retval 0 Always.
+ *
+ * @see rtems_filesystem_clonenode_t.
+ */
+int rtems_filesystem_default_clonenode(
+ rtems_filesystem_location_info_t *loc
+);
+
+/**
+ * @see rtems_filesystem_freenode_t.
+ */
+void rtems_filesystem_default_freenode(
+ const rtems_filesystem_location_info_t *loc
+);
+
+/**
+ * @retval -1 Always. The errno is set to ENOTSUP.
+ *
+ * @see rtems_filesystem_mount_t.
+ */
+int rtems_filesystem_default_mount (
+ rtems_filesystem_mount_table_entry_t *mt_entry /* IN */
+);
+
+/**
+ * @retval -1 Always. The errno is set to ENOTSUP.
+ *
+ * @see rtems_filesystem_unmount_t.
+ */
+int rtems_filesystem_default_unmount(
+ rtems_filesystem_mount_table_entry_t *mt_entry /* IN */
+);
+
+/**
+ * @retval -1 Always. The errno is set to ENOTSUP.
+ *
+ * @see rtems_filesystem_fsunmount_me_t.
+ */
+void rtems_filesystem_default_fsunmount(
+ rtems_filesystem_mount_table_entry_t *mt_entry /* IN */
+);
+
+/**
+ * @retval -1 Always. The errno is set to ENOTSUP.
+ *
+ * @see rtems_filesystem_utime_t.
+ */
+int rtems_filesystem_default_utime(
+ const rtems_filesystem_location_info_t *loc,
+ time_t actime,
+ time_t modtime
+);
+
+/**
+ * @retval -1 Always. The errno is set to ENOTSUP.
+ *
+ * @see rtems_filesystem_symlink_t.
+ */
+int rtems_filesystem_default_symlink(
+ const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ const char *target
+);
+
+/**
+ * @retval -1 Always. The errno is set to ENOTSUP.
+ *
+ * @see rtems_filesystem_readlink_t.
+ */
+ssize_t rtems_filesystem_default_readlink(
+ const rtems_filesystem_location_info_t *loc,
+ char *buf,
+ size_t bufsize
+);
+
+/**
+ * @retval -1 Always. The errno is set to ENOTSUP.
+ *
+ * @see rtems_filesystem_rename_t.
+ */
+int rtems_filesystem_default_rename(
+ const rtems_filesystem_location_info_t *oldparentloc,
+ const rtems_filesystem_location_info_t *oldloc,
+ const rtems_filesystem_location_info_t *newparentloc,
+ const char *name,
+ size_t namelen
+);
+
+/**
+ * @retval -1 Always. The errno is set to ENOTSUP.
+ *
+ * @see rtems_filesystem_statvfs_t.
+ */
+int rtems_filesystem_default_statvfs(
+ const rtems_filesystem_location_info_t *loc,
+ struct statvfs *buf
+);
+
+/** @} */
+
+/**
+ * @defgroup LibIOFSHandler File System Node Handler
+ *
+ * @ingroup LibIO
+ *
+ * @brief File system node handler.
+ */
+/**@{**/
+
+/**
+ * @brief Opens a node.
+ *
+ * @param[in, out] iop The IO pointer.
+ * @param[in] path The path.
+ * @param[in] oflag The open flags.
+ * @param[in] mode Optional mode for node creation.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_open().
+ */
+typedef int (*rtems_filesystem_open_t)(
+ rtems_libio_t *iop,
+ const char *path,
+ int oflag,
+ mode_t mode
+);
+
+/**
+ * @brief Closes a node.
+ *
+ * @param[in, out] iop The IO pointer.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_close().
+ */
+typedef int (*rtems_filesystem_close_t)(
+ rtems_libio_t *iop
+);
+
+/**
+ * @brief Reads from a node.
+ *
+ * This handler is responsible to update the offset field of the IO descriptor.
+ *
+ * @param[in, out] iop The IO pointer.
+ * @param[out] buffer The buffer for read data.
+ * @param[in] count The size of the buffer in characters.
+ *
+ * @retval non-negative Count of read characters.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_read().
+ */
+typedef ssize_t (*rtems_filesystem_read_t)(
+ rtems_libio_t *iop,
+ void *buffer,
+ size_t count
+);
+
+/**
+ * @brief Reads an IO vector from a node.
+ *
+ * This handler is responsible to update the offset field of the IO descriptor.
+ *
+ * @param[in, out] iop The IO pointer.
+ * @param[in] iov The IO vector with buffer for read data. The caller must
+ * ensure that the IO vector values are valid.
+ * @param[in] iovcnt The count of buffers in the IO vector.
+ * @param[in] total The total count of bytes in the buffers in the IO vector.
+ *
+ * @retval non-negative Count of read characters.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_readv().
+ */
+typedef ssize_t (*rtems_filesystem_readv_t)(
+ rtems_libio_t *iop,
+ const struct iovec *iov,
+ int iovcnt,
+ ssize_t total
+);
+
+/**
+ * @brief Writes to a node.
+ *
+ * This handler is responsible to update the offset field of the IO descriptor.
+ *
+ * @param[in, out] iop The IO pointer.
+ * @param[out] buffer The buffer for write data.
+ * @param[in] count The size of the buffer in characters.
+ *
+ * @retval non-negative Count of written characters.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_write().
+ */
+typedef ssize_t (*rtems_filesystem_write_t)(
+ rtems_libio_t *iop,
+ const void *buffer,
+ size_t count
+);
+
+/**
+ * @brief Writes an IO vector to a node.
+ *
+ * This handler is responsible to update the offset field of the IO descriptor.
+ *
+ * @param[in, out] iop The IO pointer.
+ * @param[in] iov The IO vector with buffer for write data. The caller must
+ * ensure that the IO vector values are valid.
+ * @param[in] iovcnt The count of buffers in the IO vector.
+ * @param[in] total The total count of bytes in the buffers in the IO vector.
+ *
+ * @retval non-negative Count of written characters.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_writev().
+ */
+typedef ssize_t (*rtems_filesystem_writev_t)(
+ rtems_libio_t *iop,
+ const struct iovec *iov,
+ int iovcnt,
+ ssize_t total
+);
+
+/**
+ * @brief IO control of a node.
+ *
+ * @param[in, out] iop The IO pointer.
+ * @param[in] request The IO control request.
+ * @param[in, out] buffer The buffer for IO control request data.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_ioctl().
+ */
+typedef int (*rtems_filesystem_ioctl_t)(
+ rtems_libio_t *iop,
+ ioctl_command_t request,
+ void *buffer
+);
+
+/**
+ * @brief Moves the read/write file offset.
+ *
+ * @param[in, out] iop The IO pointer.
+ * @param[in] offset The offset.
+ * @param[in] whence The reference position for the offset.
+ *
+ * @retval non-negative The new offset from the beginning of the file.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_lseek(),
+ * rtems_filesystem_default_lseek_file(), and
+ * rtems_filesystem_default_lseek_directory().
+ */
+typedef off_t (*rtems_filesystem_lseek_t)(
+ rtems_libio_t *iop,
+ off_t offset,
+ int whence
+);
+
+/**
+ * @brief Gets a node status.
+ *
+ * @param[in, out] iop The IO pointer.
+ * @param[out] stat The buffer to status information.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_fstat().
+ */
+typedef int (*rtems_filesystem_fstat_t)(
+ const rtems_filesystem_location_info_t *loc,
+ struct stat *buf
+);
+
+/**
+ * @brief Truncates a file to a specified length.
+ *
+ * @param[in, out] iop The IO pointer.
+ * @param[in] length The new length in characters.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_ftruncate() and
+ * rtems_filesystem_default_ftruncate_directory().
+ */
+typedef int (*rtems_filesystem_ftruncate_t)(
+ rtems_libio_t *iop,
+ off_t length
+);
+
+/**
+ * @brief Synchronizes changes to a file.
+ *
+ * @param[in, out] iop The IO pointer.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_fsync_or_fdatasync() and
+ * rtems_filesystem_default_fsync_or_fdatasync_success().
+ */
+typedef int (*rtems_filesystem_fsync_t)(
+ rtems_libio_t *iop
+);
+
+/**
+ * @brief Synchronizes the data of a file.
+ *
+ * @param[in, out] iop The IO pointer.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The errno is set to indicate the error.
+ *
+ * @see rtems_filesystem_default_fsync_or_fdatasync() and
+ * rtems_filesystem_default_fsync_or_fdatasync_success().
+ */
+typedef int (*rtems_filesystem_fdatasync_t)(
+ rtems_libio_t *iop
+);
+
+/**
+ * @brief File control.
+ *
+ * @param[in, out] iop The IO pointer.
+ * @param[in] cmd Control command.
+ *
+ * @retval 0 Successful operation.
+ * @retval errno An error occurred. This value is assigned to errno.
+ *
+ * @see rtems_filesystem_default_fcntl().
+ */
+typedef int (*rtems_filesystem_fcntl_t)(
+ rtems_libio_t *iop,
+ int cmd
+);
+
+/**
+ * @brief Poll and select support.
+ *
+ * @param[in, out] iop The IO pointer.
+ * @param[in] events The poll events.
+ *
+ * @return The poll return events.
+ *
+ * @see rtems_filesystem_default_poll().
+ */
+typedef int (*rtems_filesystem_poll_t)(
+ rtems_libio_t *iop,
+ int events
+);
+
+/**
+ * @brief Kernel event filter support.
+ *
+ * @param[in, out] iop The IO pointer.
+ * @param[in] kn The kernel event note.
+ *
+ * @retval 0 Successful operation.
+ * @retval error An error occurred. This is usually EINVAL.
+ *
+ * @see rtems_filesystem_default_kqfilter().
+ */
+typedef int (*rtems_filesystem_kqfilter_t)(
+ rtems_libio_t *iop,
+ struct knote *kn
+);
+
+/**
+ * @brief MMAP support.
+ *
+ * @param[in, out] iop The IO pointer.
+ * @param[in, out] addr The starting address of the mapped memory.
+ * @param[in] len The maximum number of bytes to map.
+ * @param[in] prot The desired memory protection.
+ * @param[in] off The offset within the file descriptor to map.
+ *
+ * @retval 0 Successful operation.
+ * @retval error An error occurred. This is usually EINVAL.
+ *
+ * @see rtems_filesystem_default_mmap().
+ */
+typedef int (*rtems_filesystem_mmap_t)(
+ rtems_libio_t *iop,
+ void **addr,
+ size_t len,
+ int prot,
+ off_t off
+);
+
+/**
+ * @brief File system node operations table.
+ */
+struct _rtems_filesystem_file_handlers_r {
+ rtems_filesystem_open_t open_h;
+ rtems_filesystem_close_t close_h;
+ rtems_filesystem_read_t read_h;
+ rtems_filesystem_write_t write_h;
+ rtems_filesystem_ioctl_t ioctl_h;
+ rtems_filesystem_lseek_t lseek_h;
+ rtems_filesystem_fstat_t fstat_h;
+ rtems_filesystem_ftruncate_t ftruncate_h;
+ rtems_filesystem_fsync_t fsync_h;
+ rtems_filesystem_fdatasync_t fdatasync_h;
+ rtems_filesystem_fcntl_t fcntl_h;
+ rtems_filesystem_poll_t poll_h;
+ rtems_filesystem_kqfilter_t kqfilter_h;
+ rtems_filesystem_readv_t readv_h;
+ rtems_filesystem_writev_t writev_h;
+ rtems_filesystem_mmap_t mmap_h;
+};
+
+/**
+ * @brief File system node handler table with default node handlers.
+ */
+extern const rtems_filesystem_file_handlers_r
+ rtems_filesystem_handlers_default;
+
+/**
+ * @retval 0 Always.
+ *
+ * @see rtems_filesystem_open_t.
+ */
+int rtems_filesystem_default_open(
+ rtems_libio_t *iop,
+ const char *path,
+ int oflag,
+ mode_t mode
+);
+
+/**
+ * @retval 0 Always.
+ *
+ * @see rtems_filesystem_close_t.
+ */
+int rtems_filesystem_default_close(
+ rtems_libio_t *iop
+);
+
+/**
+ * @retval -1 Always. The errno is set to ENOTSUP.
+ *
+ * @see rtems_filesystem_read_t.
+ */
+ssize_t rtems_filesystem_default_read(
+ rtems_libio_t *iop,
+ void *buffer,
+ size_t count
+);
+
+/**
+ * @brief Calls the read handler for each IO vector entry.
+ *
+ * @see rtems_filesystem_readv_t.
+ */
+ssize_t rtems_filesystem_default_readv(
+ rtems_libio_t *iop,
+ const struct iovec *iov,
+ int iovcnt,
+ ssize_t total
+);
+
+/**
+ * @retval -1 Always. The errno is set to ENOTSUP.
+ *
+ * @see rtems_filesystem_write_t.
+ */
+ssize_t rtems_filesystem_default_write(
+ rtems_libio_t *iop,
+ const void *buffer,
+ size_t count
+);
+
+/**
+ * @brief Calls the write handler for each IO vector entry.
+ *
+ * @see rtems_filesystem_write_t.
+ */
+ssize_t rtems_filesystem_default_writev(
+ rtems_libio_t *iop,
+ const struct iovec *iov,
+ int iovcnt,
+ ssize_t total
+);
+
+/**
+ * @retval -1 Always. The errno is set to ENOTTY.
+ *
+ * @see rtems_filesystem_ioctl_t.
+ */
+int rtems_filesystem_default_ioctl(
+ rtems_libio_t *iop,
+ ioctl_command_t request,
+ void *buffer
+);
+
+/**
+ * @retval -1 Always. The errno is set to ESPIPE.
+ *
+ * @see rtems_filesystem_lseek_t.
+ */
+off_t rtems_filesystem_default_lseek(
+ rtems_libio_t *iop,
+ off_t offset,
+ int whence
+);
+
+/**
+ * @brief An offset 0 with a whence of SEEK_SET will perform a directory rewind
+ * operation.
+ *
+ * This function has no protection against concurrent access.
+ *
+ * @retval -1 The offset is not zero or the whence is not SEEK_SET.
+ * @retval 0 Successful rewind operation.
+ *
+ * @see rtems_filesystem_lseek_t.
+ */
+off_t rtems_filesystem_default_lseek_directory(
+ rtems_libio_t *iop,
+ off_t offset,
+ int whence
+);
+
+/**
+ * @brief Default lseek() handler for files.
+ *
+ * The fstat() handler will be used to obtain the file size in case whence is
+ * SEEK_END.
+ *
+ * This function has no protection against concurrent access.
+ *
+ * @retval -1 An error occurred. In case an integer overflow occurred, then the
+ * errno will be set to EOVERFLOW. In case the new offset is negative, then
+ * the errno will be set to EINVAL. In case the whence is SEEK_END and the
+ * fstat() handler to obtain the current file size returned an error status,
+ * then the errno will be set by the fstat() handler.
+ * @retval offset The new offset.
+ *
+ * @see rtems_filesystem_lseek_t.
+ */
+off_t rtems_filesystem_default_lseek_file(
+ rtems_libio_t *iop,
+ off_t offset,
+ int whence
+);
+
+/**
+ * @brief Sets the mode to S_IRWXU | S_IRWXG | S_IRWXO.
+ *
+ * @retval 0 Always.
+ *
+ * @see rtems_filesystem_fstat_t.
+ */
+int rtems_filesystem_default_fstat(
+ const rtems_filesystem_location_info_t *loc,
+ struct stat *buf
+);
+
+/**
+ * @retval -1 Always. The errno is set to EINVAL.
+ *
+ * @see rtems_filesystem_ftruncate_t.
+ */
+int rtems_filesystem_default_ftruncate(
+ rtems_libio_t *iop,
+ off_t length
+);
+
+/**
+ * @retval -1 Always. The errno is set to EISDIR.
+ *
+ * @see rtems_filesystem_ftruncate_t.
+ */
+int rtems_filesystem_default_ftruncate_directory(
+ rtems_libio_t *iop,
+ off_t length
+);
+
+/**
+ * @retval -1 Always. The errno is set to EINVAL.
+ *
+ * @see rtems_filesystem_fsync_t and rtems_filesystem_fdatasync_t.
+ */
+int rtems_filesystem_default_fsync_or_fdatasync(
+ rtems_libio_t *iop
+);
+
+/**
+ * @retval 0 Always.
+ *
+ * @see rtems_filesystem_fsync_t and rtems_filesystem_fdatasync_t.
+ */
+int rtems_filesystem_default_fsync_or_fdatasync_success(
+ rtems_libio_t *iop
+);
+
+/**
+ * @retval 0 Always.
+ *
+ * @see rtems_filesystem_fcntl_t.
+ */
+int rtems_filesystem_default_fcntl(
+ rtems_libio_t *iop,
+ int cmd
+);
+
+/**
+ * @brief Default poll handler.
+ *
+ * @retval POLLERR Always.
+ *
+ * @see rtems_filesystem_poll_t.
+ */
+int rtems_filesystem_default_poll(
+ rtems_libio_t *iop,
+ int events
+);
+
+/**
+ * @brief Default kernel event filter handler.
+ *
+ * @retval EINVAL Always.
+ *
+ * @see rtems_filesystem_kqfilter_t.
+ */
+int rtems_filesystem_default_kqfilter(
+ rtems_libio_t *iop,
+ struct knote *kn
+);
+
+/**
+ * @brief Default MMAP handler.
+ *
+ * @retval ENOTSUP Always.
+ *
+ * @see rtems_filesystem_mmap_t.
+ */
+int rtems_filesystem_default_mmap(
+ rtems_libio_t *iop,
+ void **addr,
+ size_t len,
+ int prot,
+ off_t off
+);
+
+/** @} */
+
+/**
+ * @defgroup LibIO IO Library
+ *
+ * @brief Provides system call and file system interface definitions.
+ *
+ * General purpose communication channel for RTEMS to allow UNIX/POSIX
+ * system call behavior under RTEMS. Initially this supported only
+ * IO to devices but has since been enhanced to support networking
+ * and support for mounted file systems.
+ */
+/**@{**/
+
+typedef off_t rtems_off64_t __attribute__((deprecated));
+
+/**
+ * @brief Gets the mount handler for the file system @a type.
+ *
+ * @return The file system mount handler associated with the @a type, or
+ * @c NULL if no such association exists.
+ */
+rtems_filesystem_fsmount_me_t
+rtems_filesystem_get_mount_handler(
+ const char *type
+);
+
+/**
+ * @brief Contain file system specific information which is required to support
+ * fpathconf().
+ */
+typedef struct {
+ int link_max; /* count */
+ int max_canon; /* max formatted input line size */
+ int max_input; /* max input line size */
+ int name_max; /* max name length */
+ int path_max; /* max path */
+ int pipe_buf; /* pipe buffer size */
+ int posix_async_io; /* async IO supported on fs, 0=no, 1=yes */
+ int posix_chown_restrictions; /* can chown: 0=no, 1=yes */
+ int posix_no_trunc; /* error on names > max name, 0=no, 1=yes */
+ int posix_prio_io; /* priority IO, 0=no, 1=yes */
+ int posix_sync_io; /* file can be sync'ed, 0=no, 1=yes */
+ int posix_vdisable; /* special char processing, 0=no, 1=yes */
+} rtems_filesystem_limits_and_options_t;
+
+/**
+ * @brief Default pathconf settings.
+ *
+ * Override in a filesystem.
+ */
+extern const rtems_filesystem_limits_and_options_t
+ rtems_filesystem_default_pathconf;
+
+/**
+ * @brief An open file data structure.
+ *
+ * It will be indexed by 'fd'.
+ *
+ * @todo Should really have a separate per/file data structure that this points
+ * to (eg: offset, driver, pathname should be in that)
+ */
+struct rtems_libio_tt {
+ off_t offset; /* current offset into file */
+ Atomic_Uint flags;
+ rtems_filesystem_location_info_t pathinfo;
+ uint32_t data0; /* private to "driver" */
+ void *data1; /* ... */
+};
+
+/**
+ * @brief Paramameter block for read/write.
+ *
+ * It must include 'offset' instead of using iop's offset since we can have
+ * multiple outstanding i/o's on a device.
+ */
+typedef struct {
+ rtems_libio_t *iop;
+ off_t offset;
+ char *buffer;
+ uint32_t count;
+ uint32_t flags;
+ uint32_t bytes_moved;
+} rtems_libio_rw_args_t;
+
+/**
+ * @brief Parameter block for open/close.
+ */
+typedef struct {
+ rtems_libio_t *iop;
+ uint32_t flags;
+ uint32_t mode;
+} rtems_libio_open_close_args_t;
+
+/**
+ * @brief Parameter block for ioctl.
+ */
+typedef struct {
+ rtems_libio_t *iop;
+ ioctl_command_t command;
+ void *buffer;
+ int ioctl_return;
+} rtems_libio_ioctl_args_t;
+
+/**
+ * @name Flag Values
+ */
+/**@{**/
+
+#define LIBIO_FLAGS_NO_DELAY 0x0001U /* return immediately if no data */
+#define LIBIO_FLAGS_READ 0x0002U /* reading */
+#define LIBIO_FLAGS_WRITE 0x0004U /* writing */
+#define LIBIO_FLAGS_OPEN 0x0100U /* device is open */
+#define LIBIO_FLAGS_APPEND 0x0200U /* all writes append */
+#define LIBIO_FLAGS_CLOSE_ON_EXEC 0x0800U /* close on process exec() */
+#define LIBIO_FLAGS_READ_WRITE (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE)
+#define LIBIO_FLAGS_REFERENCE_INC 0x1000U
+
+/** @} */
+
+static inline unsigned int rtems_libio_iop_flags( const rtems_libio_t *iop )
+{
+ return _Atomic_Load_uint( &iop->flags, ATOMIC_ORDER_RELAXED );
+}
+
+/**
+ * @brief Returns true if this is a no delay iop, otherwise returns false.
+ *
+ * @param[in] iop The iop.
+ */
+static inline bool rtems_libio_iop_is_no_delay( const rtems_libio_t *iop )
+{
+ return ( rtems_libio_iop_flags( iop ) & LIBIO_FLAGS_NO_DELAY ) != 0;
+}
+
+/**
+ * @brief Returns true if this is a readable iop, otherwise returns false.
+ *
+ * @param[in] iop The iop.
+ */
+static inline bool rtems_libio_iop_is_readable( const rtems_libio_t *iop )
+{
+ return ( rtems_libio_iop_flags( iop ) & LIBIO_FLAGS_READ ) != 0;
+}
+
+/**
+ * @brief Returns true if this is a writeable iop, otherwise returns false.
+ *
+ * @param[in] iop The iop.
+ */
+static inline bool rtems_libio_iop_is_writeable( const rtems_libio_t *iop )
+{
+ return ( rtems_libio_iop_flags( iop ) & LIBIO_FLAGS_WRITE ) != 0;
+}
+
+/**
+ * @brief Returns true if this is an append iop, otherwise returns false.
+ *
+ * @param[in] iop The iop.
+ */
+static inline bool rtems_libio_iop_is_append( const rtems_libio_t *iop )
+{
+ return ( rtems_libio_iop_flags( iop ) & LIBIO_FLAGS_APPEND ) != 0;
+}
+
+/**
+ * @name External I/O Handlers
+ */
+/**@{**/
+
+typedef int (*rtems_libio_open_t)(
+ const char *pathname,
+ uint32_t flag,
+ uint32_t mode
+);
+
+typedef int (*rtems_libio_close_t)(
+ int fd
+);
+
+typedef ssize_t (*rtems_libio_read_t)(
+ int fd,
+ void *buffer,
+ size_t count
+);
+
+typedef ssize_t (*rtems_libio_write_t)(
+ int fd,
+ const void *buffer,
+ size_t count
+);
+
+typedef int (*rtems_libio_ioctl_t)(
+ int fd,
+ uint32_t command,
+ void *buffer
+);
+
+typedef off_t (*rtems_libio_lseek_t)(
+ int fd,
+ off_t offset,
+ int whence
+);
+
+/** @} */
+
+/**
+ * @name Permission Macros
+ */
+/**@{**/
+
+/*
+ * The following macros are used to build up the permissions sets
+ * used to check permissions. These are similar in style to the
+ * mode_t bits and should stay compatible with them.
+ */
+#define RTEMS_FS_PERMS_READ 0x4
+#define RTEMS_FS_PERMS_WRITE 0x2
+#define RTEMS_FS_PERMS_EXEC 0x1
+#define RTEMS_FS_PERMS_RWX \
+ (RTEMS_FS_PERMS_READ | RTEMS_FS_PERMS_WRITE | RTEMS_FS_PERMS_EXEC)
+#define RTEMS_FS_FOLLOW_HARD_LINK 0x8
+#define RTEMS_FS_FOLLOW_SYM_LINK 0x10
+#define RTEMS_FS_FOLLOW_LINK \
+ (RTEMS_FS_FOLLOW_HARD_LINK | RTEMS_FS_FOLLOW_SYM_LINK)
+#define RTEMS_FS_MAKE 0x20
+#define RTEMS_FS_EXCLUSIVE 0x40
+#define RTEMS_FS_ACCEPT_RESIDUAL_DELIMITERS 0x80
+#define RTEMS_FS_REJECT_TERMINAL_DOT 0x100
+
+/** @} */
+
+union __rtems_dev_t {
+ dev_t device;
+ struct {
+ rtems_device_major_number major;
+ rtems_device_minor_number minor;
+ } __overlay;
+};
+
+static inline dev_t rtems_filesystem_make_dev_t(
+ rtems_device_major_number _major,
+ rtems_device_minor_number _minor
+)
+{
+ union __rtems_dev_t temp;
+
+ temp.__overlay.major = _major;
+ temp.__overlay.minor = _minor;
+ return temp.device;
+}
+
+static inline dev_t rtems_filesystem_make_dev_t_from_pointer(
+ const void *pointer
+)
+{
+ uint64_t temp = (((uint64_t) 1) << 63) | (((uintptr_t) pointer) >> 1);
+
+ return rtems_filesystem_make_dev_t((uint32_t) (temp >> 32), (uint32_t) temp);
+}
+
+static inline rtems_device_major_number rtems_filesystem_dev_major_t(
+ dev_t device
+)
+{
+ union __rtems_dev_t temp;
+
+ temp.device = device;
+ return temp.__overlay.major;
+}
+
+
+static inline rtems_device_minor_number rtems_filesystem_dev_minor_t(
+ dev_t device
+)
+{
+ union __rtems_dev_t temp;
+
+ temp.device = device;
+ return temp.__overlay.minor;
+}
+
+#define rtems_filesystem_split_dev_t( _dev, _major, _minor ) \
+ do { \
+ (_major) = rtems_filesystem_dev_major_t ( _dev ); \
+ (_minor) = rtems_filesystem_dev_minor_t( _dev ); \
+ } while(0)
+
+/*
+ * Prototypes for filesystem
+ */
+
+/**
+ * @brief Base File System Initialization
+ *
+ * Initialize the foundation of the file system. This is specified
+ * by the structure rtems_filesystem_mount_table. The usual
+ * configuration is a single instantiation of the IMFS or miniIMFS with
+ * a single "/dev" directory in it.
+ */
+void rtems_filesystem_initialize( void );
+
+void rtems_libio_post_driver(void);
+
+void rtems_libio_exit(void);
+
+/**
+ * @brief Creates a directory and all its parent directories according to
+ * @a path.
+ *
+ * The @a mode value selects the access permissions of the directory.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The @c errno indicates the error.
+ */
+extern int rtems_mkdir(const char *path, mode_t mode);
+
+/** @} */
+
+/**
+ * @defgroup FileSystemTypesAndMount File System Types and Mount
+ *
+ * @ingroup LibIO
+ *
+ * @brief File system types and mount.
+ */
+/**@{**/
+
+/**
+ * @name File System Types
+ */
+/**@{**/
+
+#define RTEMS_FILESYSTEM_TYPE_IMFS "imfs"
+#define RTEMS_FILESYSTEM_TYPE_MINIIMFS "mimfs"
+#define RTEMS_FILESYSTEM_TYPE_DEVFS "devfs"
+#define RTEMS_FILESYSTEM_TYPE_FTPFS "ftpfs"
+#define RTEMS_FILESYSTEM_TYPE_TFTPFS "tftpfs"
+#define RTEMS_FILESYSTEM_TYPE_NFS "nfs"
+#define RTEMS_FILESYSTEM_TYPE_DOSFS "dosfs"
+#define RTEMS_FILESYSTEM_TYPE_RFS "rfs"
+#define RTEMS_FILESYSTEM_TYPE_JFFS2 "jffs2"
+
+/** @} */
+
+/**
+ * @brief Mount table entry.
+ */
+struct rtems_filesystem_mount_table_entry_tt {
+ rtems_chain_node mt_node;
+ void *fs_info;
+ const rtems_filesystem_operations_table *ops;
+ const void *immutable_fs_info;
+ rtems_chain_control location_chain;
+ rtems_filesystem_global_location_t *mt_point_node;
+ rtems_filesystem_global_location_t *mt_fs_root;
+ bool mounted;
+ bool writeable;
+ const rtems_filesystem_limits_and_options_t *pathconf_limits_and_options;
+
+ /*
+ * The target or mount point of the file system.
+ */
+ const char *target;
+
+ /*
+ * The type of filesystem or the name of the filesystem.
+ */
+ const char *type;
+
+ /*
+ * When someone adds a mounted filesystem on a real device,
+ * this will need to be used.
+ *
+ * The lower layers can manage how this is managed. Leave as a
+ * string.
+ */
+ char *dev;
+
+ /**
+ * The task that initiated the unmount process. After unmount process
+ * completion this task will be notified via the transient event.
+ *
+ * @see ClassicEventTransient.
+ */
+ rtems_id unmount_task;
+};
+
+/**
+ * @brief File system options.
+ */
+typedef enum {
+ RTEMS_FILESYSTEM_READ_ONLY,
+ RTEMS_FILESYSTEM_READ_WRITE,
+ RTEMS_FILESYSTEM_BAD_OPTIONS
+} rtems_filesystem_options_t;
+
+/**
+ * @brief File system table entry.
+ */
+typedef struct rtems_filesystem_table_t {
+ const char *type;
+ rtems_filesystem_fsmount_me_t mount_h;
+} rtems_filesystem_table_t;
+
+/**
+ * @brief Static table of file systems.
+ *
+ * Externally defined by confdefs.h or the user.
+ */
+extern const rtems_filesystem_table_t rtems_filesystem_table [];
+
+extern rtems_chain_control rtems_filesystem_mount_table;
+
+/**
+ * @brief Registers a file system @a type.
+ *
+ * The @a mount_h handler will be used to mount a file system of this @a type.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The @c errno indicates the error.
+ */
+int rtems_filesystem_register(
+ const char *type,
+ rtems_filesystem_fsmount_me_t mount_h
+);
+
+/**
+ * @brief Unregisters a file system @a type.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The @c errno indicates the error.
+ */
+int rtems_filesystem_unregister(
+ const char *type
+);
+
+/**
+ * @brief Unmounts the file system instance at the specified mount path.
+ *
+ * The function waits for the unmount process completion. In case the calling
+ * thread uses resources of the unmounted file system the function may never
+ * return. In case the calling thread has its root or current directory in the
+ * unmounted file system the function returns with an error status and errno is
+ * set to EBUSY.
+ *
+ * The unmount process completion notification uses the transient event. It is
+ * a fatal error to terminate the calling thread while waiting for this event.
+ *
+ * A concurrent unmount request for the same file system instance has
+ * unpredictable effects.
+ *
+ * @param[in] mount_path The path to the file system instance mount point.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The @c errno indicates the error.
+ *
+ * @see ClassicEventTransient.
+ */
+int unmount(
+ const char *mount_path
+);
+
+/**
+ * @brief Mounts a file system instance at the specified target path.
+ *
+ * To mount a standard file system instance one of the following defines should
+ * be used to select the file system type
+ * - RTEMS_FILESYSTEM_TYPE_DEVFS,
+ * - RTEMS_FILESYSTEM_TYPE_DOSFS,
+ * - RTEMS_FILESYSTEM_TYPE_FTPFS,
+ * - RTEMS_FILESYSTEM_TYPE_IMFS,
+ * - RTEMS_FILESYSTEM_TYPE_JFFS2,
+ * - RTEMS_FILESYSTEM_TYPE_MINIIMFS,
+ * - RTEMS_FILESYSTEM_TYPE_NFS,
+ * - RTEMS_FILESYSTEM_TYPE_RFS, or
+ * - RTEMS_FILESYSTEM_TYPE_TFTPFS.
+ *
+ * Only configured or registered file system types are available. You can add
+ * file system types to your application configuration with the following
+ * configuration options
+ * - CONFIGURE_FILESYSTEM_DEVFS,
+ * - CONFIGURE_FILESYSTEM_DOSFS,
+ * - CONFIGURE_FILESYSTEM_FTPFS,
+ * - CONFIGURE_FILESYSTEM_IMFS,
+ * - CONFIGURE_FILESYSTEM_JFFS2,
+ * - CONFIGURE_FILESYSTEM_MINIIMFS,
+ * - CONFIGURE_FILESYSTEM_NFS,
+ * - CONFIGURE_FILESYSTEM_RFS, and
+ * - CONFIGURE_FILESYSTEM_TFTPFS.
+ *
+ * In addition to these configuration options file system types can be
+ * registered with rtems_filesystem_register().
+ *
+ * @param[in] source The source parameter will be forwarded to the file system
+ * initialization handler. Usually the source is a path to the corresponding
+ * device file, or @c NULL in case the file system does not use a device file.
+ * @param[in] target The target path must lead to an existing directory, or
+ * must be @c NULL. In case the target is @c NULL, the root file system will
+ * be mounted.
+ * @param[in] filesystemtype This string selects the file system type.
+ * @param[in] options The options specify if the file system instance allows
+ * read-write or read-only access.
+ * @param[in] data The data parameter will be forwarded to the file system
+ * initialization handler. It can be used to pass file system specific mount
+ * options. The data structure for mount options is file system specific. See
+ * also in the corresponding file system documentation.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The @c errno indicates the error.
+ *
+ * @see rtems_filesystem_register(), mount_and_make_target_path(), @ref DOSFS
+ * and @ref JFFS2.
+ */
+int mount(
+ const char *source,
+ const char *target,
+ const char *filesystemtype,
+ rtems_filesystem_options_t options,
+ const void *data
+);
+
+/**
+ * @brief Mounts a file system and makes the @a target path.
+ *
+ * The @a target path will be created with rtems_mkdir() and must not be
+ * @c NULL.
+ *
+ * @see mount().
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred. The @c errno indicates the error.
+ */
+int mount_and_make_target_path(
+ const char *source,
+ const char *target,
+ const char *filesystemtype,
+ rtems_filesystem_options_t options,
+ const void *data
+);
+
+/**
+ * @brief Per file system type routine.
+ *
+ * @see rtems_filesystem_iterate().
+ *
+ * @retval true Stop the iteration.
+ * @retval false Continue the iteration.
+ */
+typedef bool (*rtems_per_filesystem_routine)(
+ const rtems_filesystem_table_t *fs_entry,
+ void *arg
+);
+
+/**
+ * @brief Iterates over all file system types.
+ *
+ * For each file system type the @a routine will be called with the entry and
+ * the @a routine_arg parameter.
+ *
+ * Do not register or unregister file system types in @a routine.
+ *
+ * The iteration is protected by the IO library mutex.
+ *
+ * @retval true Iteration stopped due to @a routine return status.
+ * @retval false Iteration through all entries.
+ */
+bool rtems_filesystem_iterate(
+ rtems_per_filesystem_routine routine,
+ void *routine_arg
+);
+
+/**
+ * @brief Mount table entry visitor.
+ *
+ * @retval true Stop the iteration.
+ * @retval false Continue the iteration.
+ *
+ * @see rtems_filesystem_mount_iterate().
+ */
+typedef bool (*rtems_filesystem_mt_entry_visitor)(
+ const rtems_filesystem_mount_table_entry_t *mt_entry,
+ void *arg
+);
+
+/**
+ * @brief Iterates over all file system mount entries.
+ *
+ * The iteration is protected by the IO library mutex. Do not mount or unmount
+ * file systems in the visitor function.
+ *
+ * @param[in] visitor For each file system mount entry the visitor function
+ * will be called with the entry and the visitor argument as parameters.
+ * @param[in] visitor_arg The second parameter for the visitor function.
+ *
+ * @retval true Iteration stopped due to visitor function return status.
+ * @retval false Iteration through all entries.
+ */
+bool rtems_filesystem_mount_iterate(
+ rtems_filesystem_mt_entry_visitor visitor,
+ void *visitor_arg
+);
+
+typedef struct {
+ const char *source;
+ const char *target;
+ const char *filesystemtype;
+ rtems_filesystem_options_t options;
+ const void *data;
+} rtems_filesystem_mount_configuration;
+
+extern const rtems_filesystem_mount_configuration
+ rtems_filesystem_root_configuration;
+
+/** @} */
+
+/**
+ * @defgroup Termios Termios
+ *
+ * @ingroup LibIO
+ *
+ * @brief Termios
+ */
+/**@{**/
+
+typedef struct rtems_termios_callbacks {
+ int (*firstOpen)(int major, int minor, void *arg);
+ int (*lastClose)(int major, int minor, void *arg);
+ int (*pollRead)(int minor);
+ ssize_t (*write)(int minor, const char *buf, size_t len);
+ int (*setAttributes)(int minor, const struct termios *t);
+ int (*stopRemoteTx)(int minor);
+ int (*startRemoteTx)(int minor);
+ int outputUsesInterrupts;
+} rtems_termios_callbacks;
+
+void rtems_termios_initialize (void);
+
+/*
+ * CCJ: Change before opening a tty. Newer code from Eric is coming
+ * so extra work to handle an open tty is not worth it. If the tty
+ * is open, close then open it again.
+ */
+rtems_status_code rtems_termios_bufsize (
+ size_t cbufsize, /* cooked buffer size */
+ size_t raw_input, /* raw input buffer size */
+ size_t raw_output /* raw output buffer size */
+);
+
+rtems_status_code rtems_termios_open (
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg,
+ const rtems_termios_callbacks *callbacks
+);
+
+rtems_status_code rtems_termios_close(
+ void *arg
+);
+
+rtems_status_code rtems_termios_read(
+ void *arg
+);
+
+rtems_status_code rtems_termios_write(
+ void *arg
+);
+
+rtems_status_code rtems_termios_ioctl(
+ void *arg
+);
+
+int rtems_termios_enqueue_raw_characters(
+ void *ttyp,
+ const char *buf,
+ int len
+);
+
+int rtems_termios_dequeue_characters(
+ void *ttyp,
+ int len
+);
+
+/** @} */
+
+/**
+ * @brief The pathconf setting for a file system.
+ */
+#define rtems_filesystem_pathconf(_mte) ((_mte)->pathconf_limits_and_options)
+
+/**
+ * @brief The type of file system. Its name.
+ */
+#define rtems_filesystem_type(_mte) ((_mte)->type)
+
+/**
+ * @brief The mount point of a file system.
+ */
+#define rtems_filesystem_mount_point(_mte) ((_mte)->target)
+
+/**
+ * @brief The device entry of a file system.
+ */
+#define rtems_filesystem_mount_device(_mte) ((_mte)->dev)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_LIBIO_H */
diff --git a/cpukit/include/rtems/libio_.h b/cpukit/include/rtems/libio_.h
new file mode 100644
index 0000000000..414e8a20fc
--- /dev/null
+++ b/cpukit/include/rtems/libio_.h
@@ -0,0 +1,1049 @@
+/**
+ * @file
+ *
+ * @brief LibIO Internal Interface
+ *
+ * This file is the libio internal interface.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Modifications to support reference counting in the file system are
+ * Copyright (c) 2012 embedded brains GmbH.
+ *
+ * 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_RTEMS_LIBIO__H
+#define _RTEMS_RTEMS_LIBIO__H
+
+#include <sys/uio.h>
+#include <errno.h>
+#include <limits.h>
+#include <pthread.h>
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/seterr.h>
+#include <rtems/score/assert.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup LibIOInternal IO Internal Library
+ *
+ * @brief Internal IO library API and implementation.
+ *
+ */
+/**@{**/
+
+#define RTEMS_FILESYSTEM_SYMLOOP_MAX 32
+
+/*
+ * Not defined in newlib so provide here. Users should use dup2 and
+ * not this non-portable fcntl command. Provided here to allow the
+ * RTEMS implementation to work.
+ */
+#define F_DUP2FD 20
+
+/*
+ * File descriptor Table Information
+ */
+
+extern const uint32_t rtems_libio_number_iops;
+extern rtems_libio_t rtems_libio_iops[];
+extern void *rtems_libio_iop_free_head;
+extern void **rtems_libio_iop_free_tail;
+
+extern const rtems_filesystem_file_handlers_r rtems_filesystem_null_handlers;
+
+extern rtems_filesystem_mount_table_entry_t rtems_filesystem_null_mt_entry;
+
+/**
+ * @brief The global null location.
+ *
+ * Every operation and the open and fstat handlers of this location returns an
+ * error status. The errno is not touched by these operations and handlers.
+ * The purpose of this location is to deliver the error return status for a
+ * previous error condition which must set the errno accordingly.
+ *
+ * The usage of this null location instead of the NULL pointer eliminates
+ * a lot of branches.
+ *
+ * The user environment root and current directory are statically initialized
+ * with the null location. Due to that all file system services are in a
+ * defined state even if no root file system was mounted.
+ */
+extern rtems_filesystem_global_location_t rtems_filesystem_global_location_null;
+
+/**
+ * @brief Sets the iop flags to the specified flags together with
+ * LIBIO_FLAGS_OPEN.
+ *
+ * Use this once a file descriptor allocated via rtems_libio_allocate() is
+ * fully initialized.
+ *
+ * @param[in] iop The iop.
+ * @param[in] flags The flags.
+ */
+static inline void rtems_libio_iop_flags_initialize(
+ rtems_libio_t *iop,
+ uint32_t flags
+)
+{
+ _Atomic_Store_uint(
+ &iop->flags,
+ LIBIO_FLAGS_OPEN | flags,
+ ATOMIC_ORDER_RELEASE
+ );
+}
+
+/**
+ * @brief Sets the specified flags in the iop.
+ *
+ * @param[in] iop The iop.
+ * @param[in] set The flags to set.
+ *
+ * @return The previous flags.
+ */
+static inline unsigned int rtems_libio_iop_flags_set(
+ rtems_libio_t *iop,
+ unsigned int set
+)
+{
+ return _Atomic_Fetch_or_uint( &iop->flags, set, ATOMIC_ORDER_RELAXED );
+}
+
+/**
+ * @brief Clears the specified flags in the iop.
+ *
+ * @param[in] iop The iop.
+ * @param[in] clear The flags to clear.
+ *
+ * @return The previous flags.
+ */
+static inline unsigned int rtems_libio_iop_flags_clear(
+ rtems_libio_t *iop,
+ unsigned int clear
+)
+{
+ return _Atomic_Fetch_and_uint( &iop->flags, ~clear, ATOMIC_ORDER_RELAXED );
+}
+
+/**
+ * @brief Maps a file descriptor to the iop.
+ *
+ * The file descriptor must be a valid index into the iop table.
+ *
+ * @param[in] fd The file descriptor.
+ *
+ * @return The iop corresponding to the specified file descriptor.
+ */
+static inline rtems_libio_t *rtems_libio_iop( int fd )
+{
+ return &rtems_libio_iops[ fd ];
+}
+
+/**
+ * @brief Holds a refernece to the iop.
+ *
+ * @param[in] iop The iop.
+ *
+ * @return The flags corresponding to the specified iop.
+ */
+static inline unsigned int rtems_libio_iop_hold( rtems_libio_t *iop )
+{
+ return _Atomic_Fetch_add_uint(
+ &iop->flags,
+ LIBIO_FLAGS_REFERENCE_INC,
+ ATOMIC_ORDER_ACQUIRE
+ );
+}
+
+/**
+ * @brief Drops a refernece to the iop.
+ *
+ * @param[in] iop The iop.
+ */
+static inline void rtems_libio_iop_drop( rtems_libio_t *iop )
+{
+#if defined(RTEMS_DEBUG)
+ unsigned int flags;
+ bool success;
+
+ flags = _Atomic_Load_uint( &iop->flags, ATOMIC_ORDER_RELAXED );
+
+ do {
+ unsigned int desired;
+
+ _Assert( flags >= LIBIO_FLAGS_REFERENCE_INC );
+
+ desired = flags - LIBIO_FLAGS_REFERENCE_INC;
+ success = _Atomic_Compare_exchange_uint(
+ &iop->flags,
+ &flags,
+ desired,
+ ATOMIC_ORDER_RELEASE,
+ ATOMIC_ORDER_RELAXED
+ );
+ } while ( !success );
+#else
+ _Atomic_Fetch_sub_uint(
+ &iop->flags,
+ LIBIO_FLAGS_REFERENCE_INC,
+ ATOMIC_ORDER_RELEASE
+ );
+#endif
+}
+
+/*
+ * rtems_libio_iop_to_descriptor
+ *
+ * Macro to convert an internal file descriptor pointer (iop) into
+ * the integer file descriptor used by the "section 2" system calls.
+ */
+
+#define rtems_libio_iop_to_descriptor(_iop) \
+ ((_iop) - &rtems_libio_iops[0])
+
+/*
+ * rtems_libio_check_is_open
+ *
+ * Macro to check if a file descriptor is actually open.
+ */
+
+#define rtems_libio_check_is_open(_iop) \
+ do { \
+ if (((_iop)->flags & LIBIO_FLAGS_OPEN) == 0) { \
+ errno = EBADF; \
+ return -1; \
+ } \
+ } while (0)
+
+/**
+ * @brief Macro to get the iop for the specified file descriptor.
+ *
+ * Checks that the file descriptor is in the valid range and open.
+ */
+#define LIBIO_GET_IOP( _fd, _iop ) \
+ do { \
+ unsigned int _flags; \
+ if ( (uint32_t) ( _fd ) >= rtems_libio_number_iops ) { \
+ rtems_set_errno_and_return_minus_one( EBADF ); \
+ } \
+ _iop = rtems_libio_iop( _fd ); \
+ _flags = rtems_libio_iop_hold( _iop ); \
+ if ( ( _flags & LIBIO_FLAGS_OPEN ) == 0 ) { \
+ rtems_libio_iop_drop( _iop ); \
+ rtems_set_errno_and_return_minus_one( EBADF ); \
+ } \
+ } while ( 0 )
+
+/**
+ * @brief Macro to get the iop for the specified file descriptor with access
+ * flags and error.
+ *
+ * Checks that the file descriptor is in the valid range and open.
+ */
+#define LIBIO_GET_IOP_WITH_ACCESS( _fd, _iop, _access_flags, _access_error ) \
+ do { \
+ unsigned int _flags; \
+ unsigned int _mandatory; \
+ if ( (uint32_t) ( _fd ) >= rtems_libio_number_iops ) { \
+ rtems_set_errno_and_return_minus_one( EBADF ); \
+ } \
+ _iop = rtems_libio_iop( _fd ); \
+ _flags = rtems_libio_iop_hold( _iop ); \
+ _mandatory = LIBIO_FLAGS_OPEN | ( _access_flags ); \
+ if ( ( _flags & _mandatory ) != _mandatory ) { \
+ int _error; \
+ rtems_libio_iop_drop( _iop ); \
+ if ( ( _flags & LIBIO_FLAGS_OPEN ) == 0 ) { \
+ _error = EBADF; \
+ } else { \
+ _error = _access_error; \
+ } \
+ rtems_set_errno_and_return_minus_one( _error ); \
+ } \
+ } while ( 0 )
+
+/*
+ * rtems_libio_check_buffer
+ *
+ * Macro to check if a buffer pointer is valid.
+ */
+
+#define rtems_libio_check_buffer(_buffer) \
+ do { \
+ if ((_buffer) == 0) { \
+ errno = EINVAL; \
+ return -1; \
+ } \
+ } while (0)
+
+/*
+ * rtems_libio_check_count
+ *
+ * Macro to check if a count or length is valid.
+ */
+
+#define rtems_libio_check_count(_count) \
+ do { \
+ if ((_count) == 0) { \
+ return 0; \
+ } \
+ } while (0)
+
+/**
+ * @brief Clones a node.
+ *
+ * The caller must hold the file system instance lock.
+ *
+ * @param[out] clone The cloned location.
+ * @param[in] master The master location.
+ *
+ * @see rtems_filesystem_instance_lock().
+ */
+void rtems_filesystem_location_clone(
+ rtems_filesystem_location_info_t *clone,
+ const rtems_filesystem_location_info_t *master
+);
+
+/**
+ * @brief Releases all resources of a location.
+ *
+ * This function may block on a mutex and may complete an unmount process.
+ *
+ * @param[in] loc The location to free.
+ *
+ * @note The file system root location is released by the file system
+ * instance destruction handler (see @ref rtems_filesystem_fsunmount_me_t).
+ *
+ * @see rtems_filesystem_freenode_t.
+ */
+void rtems_filesystem_location_free( rtems_filesystem_location_info_t *loc );
+
+/*
+ * External structures
+ */
+#include <rtems/userenv.h>
+
+void rtems_libio_free_user_env( void *env );
+
+extern pthread_key_t rtems_current_user_env_key;
+
+void rtems_libio_lock( void );
+
+void rtems_libio_unlock( void );
+
+static inline void rtems_filesystem_mt_lock( void )
+{
+ rtems_libio_lock();
+}
+
+static inline void rtems_filesystem_mt_unlock( void )
+{
+ rtems_libio_unlock();
+}
+
+extern rtems_interrupt_lock rtems_filesystem_mt_entry_lock_control;
+
+#define rtems_filesystem_mt_entry_declare_lock_context( ctx ) \
+ rtems_interrupt_lock_context ctx
+
+#define rtems_filesystem_mt_entry_lock( ctx ) \
+ rtems_interrupt_lock_acquire( &rtems_filesystem_mt_entry_lock_control, &ctx )
+
+#define rtems_filesystem_mt_entry_unlock( ctx ) \
+ rtems_interrupt_lock_release( &rtems_filesystem_mt_entry_lock_control, &ctx )
+
+static inline void rtems_filesystem_instance_lock(
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
+
+ (*mt_entry->ops->lock_h)( mt_entry );
+}
+
+static inline void rtems_filesystem_instance_unlock(
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
+
+ (*mt_entry->ops->unlock_h)( mt_entry );
+}
+
+/*
+ * File Descriptor Routine Prototypes
+ */
+
+/**
+ * This routine searches the IOP Table for an unused entry. If it
+ * finds one, it returns it. Otherwise, it returns NULL.
+ */
+rtems_libio_t *rtems_libio_allocate(void);
+
+/**
+ * Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand
+ */
+unsigned int rtems_libio_fcntl_flags( int fcntl_flags );
+
+/**
+ * Convert RTEMS internal flags to UNIX fnctl(2) flags
+ */
+int rtems_libio_to_fcntl_flags( unsigned int flags );
+
+/**
+ * This routine frees the resources associated with an IOP (file descriptor)
+ * and clears the slot in the IOP Table.
+ */
+void rtems_libio_free(
+ rtems_libio_t *iop
+);
+
+/*
+ * File System Routine Prototypes
+ */
+
+rtems_filesystem_location_info_t *
+rtems_filesystem_eval_path_start(
+ rtems_filesystem_eval_path_context_t *ctx,
+ const char *path,
+ int eval_flags
+);
+
+rtems_filesystem_location_info_t *
+rtems_filesystem_eval_path_start_with_parent(
+ rtems_filesystem_eval_path_context_t *ctx,
+ const char *path,
+ int eval_flags,
+ rtems_filesystem_location_info_t *parentloc,
+ int parent_eval_flags
+);
+
+rtems_filesystem_location_info_t *
+rtems_filesystem_eval_path_start_with_root_and_current(
+ rtems_filesystem_eval_path_context_t *ctx,
+ const char *path,
+ size_t pathlen,
+ int eval_flags,
+ rtems_filesystem_global_location_t *const *global_root_ptr,
+ rtems_filesystem_global_location_t *const *global_current_ptr
+);
+
+void rtems_filesystem_eval_path_continue(
+ rtems_filesystem_eval_path_context_t *ctx
+);
+
+void rtems_filesystem_eval_path_cleanup(
+ rtems_filesystem_eval_path_context_t *ctx
+);
+
+void rtems_filesystem_eval_path_recursive(
+ rtems_filesystem_eval_path_context_t *ctx,
+ const char *path,
+ size_t pathlen
+);
+
+void rtems_filesystem_eval_path_cleanup_with_parent(
+ rtems_filesystem_eval_path_context_t *ctx,
+ rtems_filesystem_location_info_t *parentloc
+);
+
+/**
+ * @brief Requests a path evaluation restart.
+ *
+ * Sets the start and current location to the new start location. The caller
+ * must terminate its current evaluation process. The path evaluation
+ * continues in the next loop iteration within
+ * rtems_filesystem_eval_path_continue(). This avoids recursive invocations.
+ * The function obtains the new start location and clones it to set the new
+ * current location. The previous start and current locations are released.
+ *
+ * @param[in, out] ctx The path evaluation context.
+ * @param[in, out] newstartloc_ptr Pointer to the new start location.
+ */
+void rtems_filesystem_eval_path_restart(
+ rtems_filesystem_eval_path_context_t *ctx,
+ rtems_filesystem_global_location_t **newstartloc_ptr
+);
+
+typedef enum {
+ RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE,
+ RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE,
+ RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY
+} rtems_filesystem_eval_path_generic_status;
+
+/**
+ * @brief Tests if the current location is a directory.
+ *
+ * @param[in, out] ctx The path evaluation context.
+ * @param[in, out] arg The handler argument.
+ *
+ * @retval true The current location is a directory.
+ * @retval false Otherwise.
+ *
+ * @see rtems_filesystem_eval_path_generic().
+ */
+typedef bool (*rtems_filesystem_eval_path_is_directory)(
+ rtems_filesystem_eval_path_context_t *ctx,
+ void *arg
+);
+
+/**
+ * @brief Evaluates a token.
+ *
+ * @param[in, out] ctx The path evaluation context.
+ * @param[in, out] arg The handler argument.
+ * @param[in] token The token contents.
+ * @param[in] tokenlen The token length in characters.
+ *
+ * @retval status The generic path evaluation status.
+ *
+ * @see rtems_filesystem_eval_path_generic().
+ */
+typedef rtems_filesystem_eval_path_generic_status
+(*rtems_filesystem_eval_path_eval_token)(
+ rtems_filesystem_eval_path_context_t *ctx,
+ void *arg,
+ const char *token,
+ size_t tokenlen
+);
+
+typedef struct {
+ rtems_filesystem_eval_path_is_directory is_directory;
+ rtems_filesystem_eval_path_eval_token eval_token;
+} rtems_filesystem_eval_path_generic_config;
+
+void rtems_filesystem_eval_path_generic(
+ rtems_filesystem_eval_path_context_t *ctx,
+ void *arg,
+ const rtems_filesystem_eval_path_generic_config *config
+);
+
+void rtems_filesystem_initialize(void);
+
+/**
+ * @brief Copies a location.
+ *
+ * A bitwise copy is performed. The destination location will be added to the
+ * corresponding mount entry.
+ *
+ * @param[out] dst The destination location.
+ * @param[in] src The source location.
+ *
+ * @retval dst The destination location.
+ *
+ * @see rtems_filesystem_location_clone().
+ */
+rtems_filesystem_location_info_t *rtems_filesystem_location_copy(
+ rtems_filesystem_location_info_t *dst,
+ const rtems_filesystem_location_info_t *src
+);
+
+static inline rtems_filesystem_location_info_t *
+rtems_filesystem_location_initialize_to_null(
+ rtems_filesystem_location_info_t *loc
+)
+{
+ return rtems_filesystem_location_copy(
+ loc,
+ &rtems_filesystem_global_location_null.location
+ );
+}
+
+rtems_filesystem_global_location_t *
+rtems_filesystem_location_transform_to_global(
+ rtems_filesystem_location_info_t *loc
+);
+
+/**
+ * @brief Assigns a global file system location.
+ *
+ * @param[in, out] lhs_global_loc_ptr Pointer to the global left hand side file
+ * system location. The current left hand side location will be released.
+ * @param[in] rhs_global_loc The global right hand side file system location.
+ */
+void rtems_filesystem_global_location_assign(
+ rtems_filesystem_global_location_t **lhs_global_loc_ptr,
+ rtems_filesystem_global_location_t *rhs_global_loc
+);
+
+/**
+ * @brief Obtains a global file system location.
+ *
+ * Deferred releases will be processed in this function.
+ *
+ * This function must be called from normal thread context and may block on a
+ * mutex. Thread dispatching is disabled to protect some critical sections.
+ *
+ * @param[in] global_loc_ptr Pointer to the global file system location.
+ *
+ * @return A global file system location. It returns always a valid object.
+ * In case of an error, the global null location will be returned. Each
+ * operation or handler of the null location returns an error status. The
+ * errno indicates the error. The NULL pointer is never returned.
+ *
+ * @see rtems_filesystem_location_transform_to_global(),
+ * rtems_filesystem_global_location_obtain_null(), and
+ * rtems_filesystem_global_location_release().
+ */
+rtems_filesystem_global_location_t *rtems_filesystem_global_location_obtain(
+ rtems_filesystem_global_location_t *const *global_loc_ptr
+);
+
+/**
+ * @brief Releases a global file system location.
+ *
+ * In case the reference count reaches zero, all associated resources will be
+ * released. This may include the complete unmount of the corresponding file
+ * system instance.
+ *
+ * This function may block on a mutex. It may be called within critical
+ * sections of the operating system. In this case the release will be
+ * deferred. The next obtain call will do the actual release.
+ *
+ * @param[in] global_loc The global file system location. It must not be NULL.
+ * @param[in] deferred If true, then do a deferred release, otherwise release
+ * it immediately.
+ *
+ * @see rtems_filesystem_global_location_obtain().
+ */
+void rtems_filesystem_global_location_release(
+ rtems_filesystem_global_location_t *global_loc,
+ bool deferred
+);
+
+void rtems_filesystem_location_detach(
+ rtems_filesystem_location_info_t *detach
+);
+
+void rtems_filesystem_location_copy_and_detach(
+ rtems_filesystem_location_info_t *copy,
+ rtems_filesystem_location_info_t *detach
+);
+
+static inline rtems_filesystem_global_location_t *
+rtems_filesystem_global_location_obtain_null(void)
+{
+ rtems_filesystem_global_location_t *global_loc = NULL;
+
+ return rtems_filesystem_global_location_obtain( &global_loc );
+}
+
+static inline bool rtems_filesystem_location_is_null(
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ return loc->handlers == &rtems_filesystem_null_handlers;
+}
+
+static inline bool rtems_filesystem_global_location_is_null(
+ const rtems_filesystem_global_location_t *global_loc
+)
+{
+ return rtems_filesystem_location_is_null( &global_loc->location );
+}
+
+static inline void rtems_filesystem_location_error(
+ const rtems_filesystem_location_info_t *loc,
+ int eno
+)
+{
+ if ( !rtems_filesystem_location_is_null( loc ) ) {
+ errno = eno;
+ }
+}
+
+int rtems_filesystem_mknod(
+ const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ mode_t mode,
+ dev_t dev
+);
+
+int rtems_filesystem_chdir( rtems_filesystem_location_info_t *loc );
+
+int rtems_filesystem_chmod(
+ const rtems_filesystem_location_info_t *loc,
+ mode_t mode
+);
+
+int rtems_filesystem_chown(
+ const rtems_filesystem_location_info_t *loc,
+ uid_t owner,
+ gid_t group
+);
+
+static inline bool rtems_filesystem_is_ready_for_unmount(
+ rtems_filesystem_mount_table_entry_t *mt_entry
+)
+{
+ bool ready = !mt_entry->mounted
+ && rtems_chain_has_only_one_node( &mt_entry->location_chain )
+ && mt_entry->mt_fs_root->reference_count == 1;
+
+ if ( ready ) {
+ rtems_chain_initialize_empty( &mt_entry->location_chain );
+ }
+
+ return ready;
+}
+
+static inline void rtems_filesystem_location_add_to_mt_entry(
+ rtems_filesystem_location_info_t *loc
+)
+{
+ rtems_filesystem_mt_entry_declare_lock_context( lock_context );
+
+ rtems_filesystem_mt_entry_lock( lock_context );
+ rtems_chain_append_unprotected(
+ &loc->mt_entry->location_chain,
+ &loc->mt_entry_node
+ );
+ rtems_filesystem_mt_entry_unlock( lock_context );
+}
+
+void rtems_filesystem_location_remove_from_mt_entry(
+ rtems_filesystem_location_info_t *loc
+);
+
+void rtems_filesystem_do_unmount(
+ rtems_filesystem_mount_table_entry_t *mt_entry
+);
+
+static inline bool rtems_filesystem_location_is_instance_root(
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
+
+ return (*mt_entry->ops->are_nodes_equal_h)(
+ loc,
+ &mt_entry->mt_fs_root->location
+ );
+}
+
+static inline const char *rtems_filesystem_eval_path_get_path(
+ rtems_filesystem_eval_path_context_t *ctx
+)
+{
+ return ctx->path;
+}
+
+static inline size_t rtems_filesystem_eval_path_get_pathlen(
+ rtems_filesystem_eval_path_context_t *ctx
+)
+{
+ return ctx->pathlen;
+}
+
+static inline void rtems_filesystem_eval_path_set_path(
+ rtems_filesystem_eval_path_context_t *ctx,
+ const char *path,
+ size_t pathlen
+)
+{
+ ctx->path = path;
+ ctx->pathlen = pathlen;
+}
+
+static inline void rtems_filesystem_eval_path_clear_path(
+ rtems_filesystem_eval_path_context_t *ctx
+)
+{
+ ctx->pathlen = 0;
+}
+
+static inline const char *rtems_filesystem_eval_path_get_token(
+ rtems_filesystem_eval_path_context_t *ctx
+)
+{
+ return ctx->token;
+}
+
+static inline size_t rtems_filesystem_eval_path_get_tokenlen(
+ rtems_filesystem_eval_path_context_t *ctx
+)
+{
+ return ctx->tokenlen;
+}
+
+static inline void rtems_filesystem_eval_path_set_token(
+ rtems_filesystem_eval_path_context_t *ctx,
+ const char *token,
+ size_t tokenlen
+)
+{
+ ctx->token = token;
+ ctx->tokenlen = tokenlen;
+}
+
+static inline void rtems_filesystem_eval_path_clear_token(
+ rtems_filesystem_eval_path_context_t *ctx
+)
+{
+ ctx->tokenlen = 0;
+}
+
+static inline void rtems_filesystem_eval_path_put_back_token(
+ rtems_filesystem_eval_path_context_t *ctx
+)
+{
+ size_t tokenlen = ctx->tokenlen;
+
+ ctx->path -= tokenlen;
+ ctx->pathlen += tokenlen;
+ ctx->tokenlen = 0;
+}
+
+void rtems_filesystem_eval_path_eat_delimiter(
+ rtems_filesystem_eval_path_context_t *ctx
+);
+
+void rtems_filesystem_eval_path_next_token(
+ rtems_filesystem_eval_path_context_t *ctx
+);
+
+static inline void rtems_filesystem_eval_path_get_next_token(
+ rtems_filesystem_eval_path_context_t *ctx,
+ const char **token,
+ size_t *tokenlen
+)
+{
+ rtems_filesystem_eval_path_next_token(ctx);
+ *token = ctx->token;
+ *tokenlen = ctx->tokenlen;
+}
+
+static inline rtems_filesystem_location_info_t *
+rtems_filesystem_eval_path_get_currentloc(
+ rtems_filesystem_eval_path_context_t *ctx
+)
+{
+ return &ctx->currentloc;
+}
+
+static inline bool rtems_filesystem_eval_path_has_path(
+ const rtems_filesystem_eval_path_context_t *ctx
+)
+{
+ return ctx->pathlen > 0;
+}
+
+static inline bool rtems_filesystem_eval_path_has_token(
+ const rtems_filesystem_eval_path_context_t *ctx
+)
+{
+ return ctx->tokenlen > 0;
+}
+
+static inline int rtems_filesystem_eval_path_get_flags(
+ const rtems_filesystem_eval_path_context_t *ctx
+)
+{
+ return ctx->flags;
+}
+
+static inline void rtems_filesystem_eval_path_set_flags(
+ rtems_filesystem_eval_path_context_t *ctx,
+ int flags
+)
+{
+ ctx->flags = flags;
+}
+
+static inline void rtems_filesystem_eval_path_clear_and_set_flags(
+ rtems_filesystem_eval_path_context_t *ctx,
+ int clear,
+ int set
+)
+{
+ int flags = ctx->flags;
+
+ flags &= ~clear;
+ flags |= set;
+
+ ctx->flags = flags;
+}
+
+static inline void rtems_filesystem_eval_path_extract_currentloc(
+ rtems_filesystem_eval_path_context_t *ctx,
+ rtems_filesystem_location_info_t *get
+)
+{
+ rtems_filesystem_location_copy_and_detach(
+ get,
+ &ctx->currentloc
+ );
+}
+
+void rtems_filesystem_eval_path_error(
+ rtems_filesystem_eval_path_context_t *ctx,
+ int eno
+);
+
+/**
+ * @brief Checks that the locations exist in the same file system instance.
+ *
+ * @retval 0 The locations exist and are in the same file system instance.
+ * @retval -1 An error occurred. The @c errno indicates the error.
+ */
+int rtems_filesystem_location_exists_in_same_instance_as(
+ const rtems_filesystem_location_info_t *a,
+ const rtems_filesystem_location_info_t *b
+);
+
+/**
+ * @brief Checks if access to an object is allowed for the current user.
+ *
+ * If the effective UID is zero or equals the UID of the object, then the user
+ * permission flags of the object will be used. Otherwise if the effective GID
+ * is zero or equals the GID of the object or one of the supplementary group
+ * IDs is equal to the GID of the object, then the group permission flags of
+ * the object will be used. Otherwise the other permission flags of the object
+ * will be used.
+ *
+ * @param[in] flags The flags determining the access type. It can be
+ * RTEMS_FS_PERMS_READ, RTEMS_FS_PERMS_WRITE or RTEMS_FS_PERMS_EXEC.
+ * @param[in] object_mode The mode of the object specifying the permission flags.
+ * @param[in] object_uid The UID of the object.
+ * @param[in] object_gid The GID of the object.
+ *
+ * @retval true Access is allowed.
+ * @retval false Otherwise.
+ */
+bool rtems_filesystem_check_access(
+ int flags,
+ mode_t object_mode,
+ uid_t object_uid,
+ gid_t object_gid
+);
+
+bool rtems_filesystem_eval_path_check_access(
+ rtems_filesystem_eval_path_context_t *ctx,
+ int eval_flags,
+ mode_t node_mode,
+ uid_t node_uid,
+ gid_t node_gid
+);
+
+static inline bool rtems_filesystem_is_delimiter(char c)
+{
+ return c == '/' || c == '\\';
+}
+
+static inline bool rtems_filesystem_is_current_directory(
+ const char *token,
+ size_t tokenlen
+)
+{
+ return tokenlen == 1 && token [0] == '.';
+}
+
+static inline bool rtems_filesystem_is_parent_directory(
+ const char *token,
+ size_t tokenlen
+)
+{
+ return tokenlen == 2 && token [0] == '.' && token [1] == '.';
+}
+
+typedef ssize_t ( *rtems_libio_iovec_adapter )(
+ rtems_libio_t *iop,
+ const struct iovec *iov,
+ int iovcnt,
+ ssize_t total
+);
+
+static inline ssize_t rtems_libio_iovec_eval(
+ int fd,
+ const struct iovec *iov,
+ int iovcnt,
+ unsigned int flags,
+ rtems_libio_iovec_adapter adapter
+)
+{
+ ssize_t total;
+ int v;
+ rtems_libio_t *iop;
+
+ /*
+ * Argument validation on IO vector
+ */
+ if ( iov == NULL )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ if ( iovcnt <= 0 )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ if ( iovcnt > IOV_MAX )
+ rtems_set_errno_and_return_minus_one( EINVAL );
+
+ /*
+ * OpenGroup says that you are supposed to return EINVAL if the
+ * sum of the iov_len values in the iov array would overflow a
+ * ssize_t.
+ */
+ total = 0;
+ for ( v = 0 ; v < iovcnt ; ++v ) {
+ size_t len = iov[ v ].iov_len;
+
+ if ( len > ( size_t ) ( SSIZE_MAX - total ) ) {
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+
+ total += ( ssize_t ) len;
+
+ if ( iov[ v ].iov_base == NULL && len != 0 ) {
+ rtems_set_errno_and_return_minus_one( EINVAL );
+ }
+ }
+
+ LIBIO_GET_IOP_WITH_ACCESS( fd, iop, flags, EBADF );
+
+ if ( total > 0 ) {
+ total = ( *adapter )( iop, iov, iovcnt, total );
+ }
+
+ rtems_libio_iop_drop( iop );
+ return total;
+}
+
+/**
+ * @brief Returns the file type of the file referenced by the filesystem
+ * location.
+ *
+ * @brief[in] loc The filesystem location.
+ *
+ * @return The type of the file or an invalid file type in case of an error.
+ */
+static inline mode_t rtems_filesystem_location_type(
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ struct stat st;
+
+ st.st_mode = 0;
+ (void) ( *loc->handlers->fstat_h )( loc, &st );
+
+ return st.st_mode;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/linkersets.h b/cpukit/include/rtems/linkersets.h
new file mode 100644
index 0000000000..bad046999c
--- /dev/null
+++ b/cpukit/include/rtems/linkersets.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2015, 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_LINKERSET_H
+#define _RTEMS_LINKERSET_H
+
+#include <rtems/score/basedefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define RTEMS_LINKER_SET_BEGIN( set ) \
+ _Linker_set_##set##_begin
+
+#define RTEMS_LINKER_SET_END( set ) \
+ _Linker_set_##set##_end
+
+#define RTEMS_LINKER_ROSET_DECLARE( set, type ) \
+ extern type const RTEMS_LINKER_SET_BEGIN( set )[0]; \
+ extern type const RTEMS_LINKER_SET_END( set )[0]
+
+#define RTEMS_LINKER_ROSET( set, type ) \
+ type const RTEMS_LINKER_SET_BEGIN( set )[0] \
+ RTEMS_SECTION( ".rtemsroset." #set ".begin" ) RTEMS_USED; \
+ type const RTEMS_LINKER_SET_END( set )[0] \
+ RTEMS_SECTION( ".rtemsroset." #set ".end" ) RTEMS_USED
+
+#define RTEMS_LINKER_ROSET_ITEM_DECLARE( set, type, item ) \
+ extern type const _Linker_set_##set##_##item
+
+#define RTEMS_LINKER_ROSET_ITEM_REFERENCE( set, type, item ) \
+ static type const * const _Set_reference_##set##_##item \
+ RTEMS_SECTION( ".rtemsroset.reference" ) RTEMS_USED = \
+ &_Linker_set_##set##_##item
+
+#define RTEMS_LINKER_ROSET_ITEM_ORDERED( set, type, item, order ) \
+ type const _Linker_set_##set##_##item \
+ RTEMS_SECTION( ".rtemsroset." #set ".content.0." RTEMS_XSTRING( order ) ) \
+ RTEMS_USED
+
+#define RTEMS_LINKER_ROSET_ITEM( set, type, item ) \
+ type const _Linker_set_##set##_##item \
+ RTEMS_SECTION( ".rtemsroset." #set ".content.1" ) RTEMS_USED
+
+#define RTEMS_LINKER_ROSET_CONTENT( set, decl ) \
+ decl \
+ RTEMS_SECTION( ".rtemsroset." #set ".content" )
+
+#define RTEMS_LINKER_RWSET_DECLARE( set, type ) \
+ extern type RTEMS_LINKER_SET_BEGIN( set )[0]; \
+ extern type RTEMS_LINKER_SET_END( set )[0]
+
+#define RTEMS_LINKER_RWSET( set, type ) \
+ type RTEMS_LINKER_SET_BEGIN( set )[0] \
+ RTEMS_SECTION( ".rtemsrwset." #set ".begin" ) RTEMS_USED; \
+ type RTEMS_LINKER_SET_END( set )[0] \
+ RTEMS_SECTION( ".rtemsrwset." #set ".end" ) RTEMS_USED
+
+#define RTEMS_LINKER_RWSET_ITEM_DECLARE( set, type, item ) \
+ extern type _Linker_set_##set##_##item
+
+/*
+ * The .rtemsroset is here not a typo. We must ensure that the references are
+ * not a victim of the garbage collection of the linker. Thus, we place them
+ * in a dedicated area of the RTEMS read-only linker set section.
+ */
+#define RTEMS_LINKER_RWSET_ITEM_REFERENCE( set, type, item ) \
+ static type * const _Set_reference_##set##_##item \
+ RTEMS_SECTION( ".rtemsroset.reference" ) RTEMS_USED = \
+ &_Linker_set_##set##_##item
+
+#define RTEMS_LINKER_RWSET_ITEM_ORDERED( set, type, item, order ) \
+ type _Linker_set_##set##_##item \
+ RTEMS_SECTION( ".rtemsrwset." #set ".content.0." RTEMS_XSTRING( order ) ) \
+ RTEMS_USED
+
+#define RTEMS_LINKER_RWSET_ITEM( set, type, item ) \
+ type _Linker_set_##set##_##item \
+ RTEMS_SECTION( ".rtemsrwset." #set ".content.1" ) RTEMS_USED
+
+#define RTEMS_LINKER_RWSET_CONTENT( set, decl ) \
+ decl \
+ RTEMS_SECTION( ".rtemsrwset." #set ".content" )
+
+RTEMS_INLINE_ROUTINE 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 ) ) )
+
+#define RTEMS_LINKER_SET_ITEM_COUNT( set ) \
+ ( RTEMS_LINKER_SET_SIZE( set ) \
+ / sizeof( RTEMS_LINKER_SET_BEGIN( set )[ 0 ] ) )
+
+#define RTEMS_LINKER_SET_IS_EMPTY( set ) \
+ ( RTEMS_LINKER_SET_SIZE( set ) == 0 )
+
+#define RTEMS_LINKER_SET_FOREACH( set, item ) \
+ for ( \
+ item = (void *) _Linker_set_Obfuscate( RTEMS_LINKER_SET_BEGIN( set ) ) ; \
+ item != RTEMS_LINKER_SET_END( set ) ; \
+ ++item \
+ )
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_LINKERSET_H */
diff --git a/cpukit/include/rtems/malloc.h b/cpukit/include/rtems/malloc.h
new file mode 100644
index 0000000000..7c00f21e77
--- /dev/null
+++ b/cpukit/include/rtems/malloc.h
@@ -0,0 +1,201 @@
+/**
+ * @file rtems/malloc.h
+ *
+ * This file defines the interface to RTEMS extensions to the Malloc Family.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_MALLOC_H
+#define _RTEMS_MALLOC_H
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <rtems/libcsupport.h> /* for malloc_walk() */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup MallocSupport Malloc Support
+ *
+ * @ingroup libcsupport
+ *
+ * @brief RTEMS extensions to the Malloc Family
+ */
+
+/**
+ * @brief C program heap control.
+ *
+ * This is the pointer to the heap control structure used to manage the C
+ * program heap.
+ */
+extern Heap_Control *RTEMS_Malloc_Heap;
+
+void RTEMS_Malloc_Initialize(
+ const Heap_Area *areas,
+ size_t area_count,
+ Heap_Initialization_or_extend_handler extend
+);
+
+extern ptrdiff_t RTEMS_Malloc_Sbrk_amount;
+
+static inline void rtems_heap_set_sbrk_amount( ptrdiff_t sbrk_amount )
+{
+ RTEMS_Malloc_Sbrk_amount = sbrk_amount;
+}
+
+typedef void *(*rtems_heap_extend_handler)(
+ Heap_Control *heap,
+ size_t alloc_size
+);
+
+/**
+ * @brief RTEMS Extend Heap via Sbrk
+ */
+void *rtems_heap_extend_via_sbrk(
+ Heap_Control *heap,
+ size_t alloc_size
+);
+
+void *rtems_heap_null_extend(
+ Heap_Control *heap,
+ size_t alloc_size
+);
+
+extern const rtems_heap_extend_handler rtems_malloc_extend_handler;
+
+/*
+ * Malloc Plugin to Dirty Memory at Allocation Time
+ */
+typedef void (*rtems_malloc_dirtier_t)(void *, size_t);
+extern rtems_malloc_dirtier_t rtems_malloc_dirty_helper;
+
+/**
+ * @brief Dirty Memory Function
+ *
+ * This method fills the specified area with a non-zero pattern
+ * to aid in debugging programs which do not initialize their
+ * memory allocated from the heap.
+ */
+void rtems_malloc_dirty_memory(
+ void *start,
+ size_t size
+);
+
+/**
+ * @brief RTEMS Variation on Aligned Memory Allocation
+ *
+ * This method is a help memalign implementation which does all
+ * error checking done by posix_memalign() EXCEPT it does NOT
+ * place numeric restrictions on the alignment value.
+ *
+ * @param[in] pointer points to the user pointer
+ * @param[in] alignment is the desired alignment
+ * @param[in] size is the allocation request size in bytes
+ *
+ * @return This methods returns zero on success and a POSIX errno
+ * value to indicate the failure condition. On success
+ * *pointer will contain the address of the allocated memory.
+ */
+int rtems_memalign(
+ void **pointer,
+ size_t alignment,
+ size_t size
+);
+
+/**
+ * @brief Allocates a memory area of size @a size bytes from the heap.
+ *
+ * If the alignment parameter @a alignment is not equal to zero, the allocated
+ * memory area will begin at an address aligned by this value.
+ *
+ * If the boundary parameter @a boundary is not equal to zero, the allocated
+ * memory area will comply with a boundary constraint. The boundary value
+ * specifies the set of addresses which are aligned by the boundary value. The
+ * interior of the allocated memory area will not contain an element of this
+ * set. The begin or end address of the area may be a member of the set.
+ *
+ * A size value of zero will return a unique address which may be freed with
+ * free().
+ *
+ * The memory allocated by this function can be released with a call to free().
+ *
+ * @return A pointer to the begin of the allocated memory area, or @c NULL if
+ * no memory is available or the parameters are inconsistent.
+ */
+void *rtems_heap_allocate_aligned_with_boundary(
+ size_t size,
+ uintptr_t alignment,
+ uintptr_t boundary
+);
+
+/**
+ * @brief Extends the memory available for the heap using the memory area
+ * starting at @a area_begin of size @a area_size bytes.
+ *
+ * There are no alignment requirements. The memory area must be big enough to
+ * contain some maintenance blocks. It must not overlap parts of the current
+ * heap areas. Disconnected subordinate heap areas will lead to used blocks
+ * which cover the gaps. Extending with an inappropriate memory area will
+ * corrupt the heap.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ADDRESS Invalid memory area.
+ */
+rtems_status_code rtems_heap_extend(
+ void *area_begin,
+ uintptr_t area_size
+);
+
+/**
+ * @brief Greedy allocate that empties the heap.
+ *
+ * Afterwards the heap has at most @a block_count allocatable blocks of sizes
+ * specified by @a block_sizes. The @a block_sizes must point to an array with
+ * @a block_count members. All other blocks are used.
+ *
+ * @see rtems_heap_greedy_free().
+ */
+void *rtems_heap_greedy_allocate(
+ const uintptr_t *block_sizes,
+ size_t block_count
+);
+
+/**
+ * @brief Greedy allocate all blocks except the largest free block.
+ *
+ * Afterwards the heap has at most one allocatable block. This block is the
+ * largest free block if it exists. The allocatable size of this block is
+ * stored in @a allocatable_size. All other blocks are used.
+ *
+ * @see rtems_heap_greedy_free().
+ */
+void *rtems_heap_greedy_allocate_all_except_largest(
+ uintptr_t *allocatable_size
+);
+
+/**
+ * @brief Frees space of a greedy allocation.
+ *
+ * The @a opaque argument must be the return value of
+ * rtems_heap_greedy_allocate() or
+ * rtems_heap_greedy_allocate_all_except_largest().
+ */
+void rtems_heap_greedy_free( void *opaque );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/media.h b/cpukit/include/rtems/media.h
new file mode 100644
index 0000000000..77a1aa8348
--- /dev/null
+++ b/cpukit/include/rtems/media.h
@@ -0,0 +1,517 @@
+/**
+ * @file
+ *
+ * @ingroup RTEMSMedia
+ *
+ * @brief Media API.
+ */
+
+/*
+ * Copyright (c) 2009, 2010 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_MEDIA_H
+#define RTEMS_MEDIA_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup RTEMSMedia Media Manager
+ *
+ * @brief Removable media support.
+ *
+ * The media manager may be used to maintain the life cycle of a removable
+ * media. Currently only disk devices are supported. The initiator posts an
+ * event to the media manager and it will respond with appropriate default
+ * actions. For example a disk attach will lead to inspection of the partition
+ * table and mounted file systems. Clients can register listeners to react to
+ * events.
+ */
+/**@{**/
+
+#define RTEMS_MEDIA_MOUNT_BASE "/media"
+
+#define RTEMS_MEDIA_DELIMITER '-'
+
+/**
+ * Disk life cycle events:
+ * @dot
+ * digraph disk_events {
+ * "DISK ATTACH" -> "PARTITION INQUIRY";
+ * "DISK ATTACH" -> "MOUNT";
+ * "PARTITION INQUIRY" -> "PARTITION ATTACH";
+ * "PARTITION INQUIRY" -> "DISK DETACH";
+ * "PARTITION ATTACH" -> "MOUNT";
+ * "MOUNT" -> "UNMOUNT";
+ * "UNMOUNT" -> "PARTITION DETACH";
+ * "UNMOUNT" -> "DISK DETACH";
+ * "PARTITION DETACH" -> "DISK DETACH";
+ * }
+ * @enddot
+ */
+typedef enum {
+ RTEMS_MEDIA_EVENT_DISK_ATTACH,
+ RTEMS_MEDIA_EVENT_DISK_DETACH,
+ RTEMS_MEDIA_EVENT_MOUNT,
+ RTEMS_MEDIA_EVENT_UNMOUNT,
+ RTEMS_MEDIA_EVENT_PARTITION_INQUIRY,
+ RTEMS_MEDIA_EVENT_PARTITION_ATTACH,
+ RTEMS_MEDIA_EVENT_PARTITION_DETACH,
+ RTEMS_MEDIA_EVENT_ERROR
+} rtems_media_event;
+
+/**
+ * Normal state transition:
+ * @dot
+ * digraph state {
+ * INQUIRY -> READY [label="all listeners\nreturned successful"];
+ * INQUIRY -> ABORTED [label="otherwise"];
+ * READY -> SUCCESS [label="the worker\nreturned successful"];
+ * READY -> FAILED [label="otherwise"];
+ * }
+ * @enddot
+ */
+typedef enum {
+ RTEMS_MEDIA_STATE_INQUIRY,
+ RTEMS_MEDIA_STATE_READY,
+ RTEMS_MEDIA_STATE_ABORTED,
+ RTEMS_MEDIA_STATE_SUCCESS,
+ RTEMS_MEDIA_STATE_FAILED,
+ RTEMS_MEDIA_ERROR_DISK_UNKNOWN,
+ RTEMS_MEDIA_ERROR_DISK_EXISTS,
+ RTEMS_MEDIA_ERROR_DISK_OR_PARTITION_UNKNOWN,
+ RTEMS_MEDIA_ERROR_DISK_OR_PARTITION_EXISTS,
+ RTEMS_MEDIA_ERROR_PARTITION_UNKNOWN,
+ RTEMS_MEDIA_ERROR_PARTITION_ORPHAN,
+ RTEMS_MEDIA_ERROR_PARTITION_DETACH_WITH_MOUNT,
+ RTEMS_MEDIA_ERROR_PARTITION_WITH_UNKNOWN_DISK,
+ RTEMS_MEDIA_ERROR_MOUNT_POINT_UNKNOWN,
+ RTEMS_MEDIA_ERROR_MOUNT_POINT_EXISTS,
+ RTEMS_MEDIA_ERROR_MOUNT_POINT_ORPHAN
+} rtems_media_state;
+
+/**
+ * @brief Event listener.
+ *
+ * The listener will be called with the @a listener_arg passed to
+ * rtems_media_listener_add().
+ *
+ * Source and destination values for each event and state:
+ * <table>
+ * <tr><th>Event</th><th>State</th><th>Source</th><th>Destination</th></tr>
+ * <tr>
+ * <td rowspan="5">RTEMS_MEDIA_EVENT_DISK_ATTACH</td>
+ * <td>RTEMS_MEDIA_STATE_INQUIRY</td><td>driver name</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_READY</td><td>driver name</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_ABORTED</td><td>driver name</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_SUCCESS</td><td>driver name</td><td>disk path</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_FAILED</td><td>driver name</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="5">RTEMS_MEDIA_EVENT_DISK_DETACH</td>
+ * <td>RTEMS_MEDIA_STATE_INQUIRY</td><td>disk path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_READY</td><td>disk path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_ABORTED</td><td>disk path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_SUCCESS</td><td>disk path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_FAILED</td><td>disk path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="5">RTEMS_MEDIA_EVENT_PARTITION_INQUIRY</td>
+ * <td>RTEMS_MEDIA_STATE_INQUIRY</td><td>disk path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_READY</td><td>disk path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_ABORTED</td><td>disk path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_SUCCESS</td><td>disk path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_FAILED</td><td>disk path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="5">RTEMS_MEDIA_EVENT_PARTITION_ATTACH</td>
+ * <td>RTEMS_MEDIA_STATE_INQUIRY</td><td>disk path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_READY</td><td>disk path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_ABORTED</td><td>disk path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_SUCCESS</td>
+ * <td>disk path</td><td>partition path</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_FAILED</td><td>disk path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="5">RTEMS_MEDIA_EVENT_PARTITION_DETACH</td>
+ * <td>RTEMS_MEDIA_STATE_INQUIRY</td><td>partition path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_READY</td><td>partition path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_ABORTED</td><td>partition path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_SUCCESS</td><td>partition path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_FAILED</td><td>partition path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="5">RTEMS_MEDIA_EVENT_MOUNT</td>
+ * <td>RTEMS_MEDIA_STATE_INQUIRY</td>
+ * <td>disk or partition path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_READY</td>
+ * <td>disk or partition path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_ABORTED</td>
+ * <td>disk or partition path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_SUCCESS</td>
+ * <td>disk or partition path</td><td>mount path</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_FAILED</td>
+ * <td>disk or partition path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="5">RTEMS_MEDIA_EVENT_UNMOUNT</td>
+ * <td>RTEMS_MEDIA_STATE_INQUIRY</td><td>mount path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_READY</td><td>mount path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_ABORTED</td><td>mount path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_SUCCESS</td><td>mount path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_STATE_FAILED</td><td>mount path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="11">RTEMS_MEDIA_EVENT_ERROR</td>
+ * <td>RTEMS_MEDIA_ERROR_DISK_UNKNOWN</td><td>disk path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_ERROR_DISK_EXISTS</td><td>disk path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_ERROR_DISK_OR_PARTITION_UNKNOWN</td>
+ * <td>disk or partition path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_ERROR_DISK_OR_PARTITION_EXISTS</td>
+ * <td>disk or partition path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_ERROR_PARTITION_UNKNOWN</td>
+ * <td>partition path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_ERROR_PARTITION_ORPHAN</td>
+ * <td>partition path</td><td>disk path</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_ERROR_PARTITION_DETACH_WITH_MOUNT</td>
+ * <td>partition path</td><td>mount path</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_ERROR_PARTITION_WITH_UNKNOWN_DISK</td>
+ * <td>partition path</td><td>disk path</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_ERROR_MOUNT_POINT_UNKNOWN</td>
+ * <td>mount path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_ERROR_MOUNT_POINT_EXISTS</td>
+ * <td>mount path</td><td>NULL</td>
+ * </tr>
+ * <tr>
+ * <td>RTEMS_MEDIA_ERROR_MOUNT_POINT_ORPHAN</td>
+ * <td>mount path</td><td>disk path</td>
+ * </tr>
+ * </table>
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_IO_ERROR In the inquiry state this will abort the action.
+ */
+typedef rtems_status_code (*rtems_media_listener)(
+ rtems_media_event event,
+ rtems_media_state state,
+ const char *src,
+ const char *dest,
+ void *listener_arg
+);
+
+/**
+ * @brief Do the work corresponding to an event.
+ *
+ * The @a state will be
+ * - RTEMS_MEDIA_STATE_READY, or
+ * - RTEMS_MEDIA_STATE_ABORTED.
+ *
+ * It will be called with the @a src and @a worker_arg arguments passed to
+ * rtems_media_post_event().
+ *
+ * The destination shall be returned in @a dest in case of success. It shall
+ * be allocated with malloc().
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_IO_ERROR Failure.
+ */
+typedef rtems_status_code (*rtems_media_worker)(
+ rtems_media_state state,
+ const char *src,
+ char **dest,
+ void *worker_arg
+);
+
+/**
+ * @name Base
+ */
+/**@{**/
+
+/**
+ * @brief Initializes the media manager.
+ *
+ * Calling this function more than once will have no effects. There is no
+ * protection against concurrent access.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_NO_MEMORY Not enough resources.
+ */
+rtems_status_code rtems_media_initialize(void);
+
+/**
+ * @brief Adds the @a listener with argument @a listener_arg.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_NO_MEMORY Not enough memory.
+ * @retval RTEMS_TOO_MANY Such a listener is already present.
+ */
+rtems_status_code rtems_media_listener_add(
+ rtems_media_listener listener,
+ void *listener_arg
+);
+
+/**
+ * @brief Removes the @a listener with argument @a listener_arg.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID No such listener is present.
+ */
+rtems_status_code rtems_media_listener_remove(
+ rtems_media_listener listener,
+ void *listener_arg
+);
+
+/**
+ * @brief Posts the @a event with source @a src.
+ *
+ * The @a worker will be called with the @a worker_arg argument.
+ *
+ * The destination will be returned in @a dest in case of success. It will be
+ * allocated with malloc() and should be freed if not needed anymore.
+ *
+ * The work will be done by the calling thread. You can avoid this if you use
+ * the media server via rtems_media_server_post_event().
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_UNSATISFIED One or more listeners aborted the action.
+ * @retval RTEMS_IO_ERROR The worker returned with an error status.
+ */
+rtems_status_code rtems_media_post_event(
+ rtems_media_event event,
+ const char *src,
+ char **dest,
+ rtems_media_worker worker,
+ void *worker_arg
+);
+
+/** @} */
+
+/**
+ * @name Server
+ */
+/**@{**/
+
+/**
+ * @brief Initializes the media manager and media server.
+ *
+ * It creates a server task with the @a priority, @a stack_size, @a modes, and
+ * @a attributes parameters.
+ *
+ * Calling this function more than once will have no effects. There is no
+ * protection against concurrent access.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_NO_MEMORY Not enough resources.
+ */
+rtems_status_code rtems_media_server_initialize(
+ rtems_task_priority priority,
+ size_t stack_size,
+ rtems_mode modes,
+ rtems_attribute attributes
+);
+
+/**
+ * @brief Sends an event message to the media server.
+ *
+ * @see See rtems_media_post_event().
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_NO_MEMORY Not enough resources to notify the media server.
+ * @retval RTEMS_NOT_CONFIGURED Media server is not initialized.
+ */
+rtems_status_code rtems_media_server_post_event(
+ rtems_media_event event,
+ const char *src,
+ rtems_media_worker worker,
+ void *worker_arg
+);
+
+/**
+ * @brief See rtems_media_server_post_event().
+ */
+static inline rtems_status_code rtems_media_server_disk_attach(
+ const char *driver_name,
+ rtems_media_worker worker,
+ void *worker_arg
+)
+{
+ return rtems_media_server_post_event(
+ RTEMS_MEDIA_EVENT_DISK_ATTACH,
+ driver_name,
+ worker,
+ worker_arg
+ );
+}
+
+/**
+ * @brief See rtems_media_server_post_event().
+ */
+static inline rtems_status_code rtems_media_server_disk_detach(
+ const char *disk_path
+)
+{
+ return rtems_media_server_post_event(
+ RTEMS_MEDIA_EVENT_DISK_DETACH,
+ disk_path,
+ NULL,
+ NULL
+ );
+}
+
+/** @} */
+
+/**
+ * @name Path Construction
+ */
+/**@{**/
+
+/**
+ * @brief Creates a new path as "prefix/name-major".
+ *
+ * @return New string, or @c NULL if no memory is available.
+ */
+char *rtems_media_create_path(
+ const char *prefix,
+ const char *name,
+ rtems_device_major_number major
+);
+
+/**
+ * @brief Replaces the prefix of the @a path with @a new_prefix.
+ *
+ * The prefix is everything up to the last '/'.
+ *
+ * @return New string, or @c NULL if no memory is available.
+ */
+char *rtems_media_replace_prefix(const char *new_prefix, const char *path);
+
+/**
+ * @brief Appends the @a minor number to the @a path resulting in "path-minor".
+ *
+ * @return New string, or @c NULL if no memory is available.
+ */
+char *rtems_media_append_minor(
+ const char *path,
+ rtems_device_minor_number minor
+);
+
+/** @} */
+
+/**
+ * @name Support
+ */
+/**@{**/
+
+/**
+ * @brief Returns the device identifier for the device located at
+ * @a device_path in @a device_identifier.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID No device at this path.
+ */
+rtems_status_code rtems_media_get_device_identifier(
+ const char *device_path,
+ dev_t *device_identifier
+);
+
+const char *rtems_media_event_description(rtems_media_event event);
+
+const char *rtems_media_state_description(rtems_media_state state);
+
+/** @} */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* RTEMS_MEDIA_H */
diff --git a/cpukit/include/rtems/monitor.h b/cpukit/include/rtems/monitor.h
new file mode 100644
index 0000000000..6ecd903c63
--- /dev/null
+++ b/cpukit/include/rtems/monitor.h
@@ -0,0 +1,528 @@
+/**
+ * @file rtems/monitor.h
+ *
+ * @brief The RTEMS Monitor Task
+ */
+
+
+#ifndef __MONITOR_H
+#define __MONITOR_H
+
+#include <rtems/score/objectimpl.h>
+#include <rtems/error.h> /* rtems_error() */
+#include <rtems/config.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Forward decls from symbols.h */
+typedef struct _rtems_symbol_t rtems_symbol_t;
+typedef struct _rtems_symbol_table_t rtems_symbol_table_t;
+
+/*
+ * Monitor types are derived from rtems object classes
+ */
+
+typedef enum {
+ RTEMS_MONITOR_OBJECT_INVALID = OBJECTS_CLASSIC_NO_CLASS,
+ RTEMS_MONITOR_OBJECT_TASK = OBJECTS_RTEMS_TASKS,
+ RTEMS_MONITOR_OBJECT_EXTENSION = OBJECTS_RTEMS_EXTENSIONS,
+ RTEMS_MONITOR_OBJECT_QUEUE = OBJECTS_RTEMS_MESSAGE_QUEUES,
+ RTEMS_MONITOR_OBJECT_SEMAPHORE = OBJECTS_RTEMS_SEMAPHORES,
+ RTEMS_MONITOR_OBJECT_PARTITION = OBJECTS_RTEMS_PARTITIONS,
+ RTEMS_MONITOR_OBJECT_REGION = OBJECTS_RTEMS_REGIONS,
+ RTEMS_MONITOR_OBJECT_PORT = OBJECTS_RTEMS_PORTS,
+
+ /* following monitor objects are not known to RTEMS, but
+ * we like to have "types" for them anyway */
+
+ RTEMS_MONITOR_OBJECT_DRIVER = OBJECTS_RTEMS_CLASSES_LAST+1,
+ RTEMS_MONITOR_OBJECT_DNAME,
+ RTEMS_MONITOR_OBJECT_CONFIG,
+ RTEMS_MONITOR_OBJECT_INIT_TASK,
+ RTEMS_MONITOR_OBJECT_MPCI,
+ RTEMS_MONITOR_OBJECT_SYMBOL,
+ #if defined(RTEMS_POSIX_API)
+ RTEMS_MONITOR_OBJECT_PTHREAD,
+ #endif
+} rtems_monitor_object_type_t;
+
+/*
+ * rtems_monitor_init() flags
+ */
+
+#define RTEMS_MONITOR_SUSPEND 0x0001 /* suspend monitor on startup */
+#define RTEMS_MONITOR_GLOBAL 0x0002 /* monitor should be global */
+#define RTEMS_MONITOR_NOTASK 0x0004 /* do not start monitor task */
+#define RTEMS_MONITOR_NOSYMLOAD 0x0008 /* do not load symbols */
+#define RTEMS_MONITOR_WAITQUIT 0x0010 /* wait for monitor task to terminate */
+
+/*
+ * Public interfaces for RTEMS data structures monitor is aware of.
+ * These are only used by the monitor.
+ *
+ * NOTE:
+ * All the canonical objects that correspond to RTEMS managed "objects"
+ * must have an identical first portion with 'id' and 'name' fields.
+ *
+ * Others do not have that restriction, even tho we would like them to.
+ * This is because some of the canonical structures are almost too big
+ * for shared memory driver (eg: mpci) and we are nickel and diming it.
+ */
+
+/*
+ * Type of a pointer that may be a symbol
+ */
+
+#define MONITOR_SYMBOL_LEN 20
+typedef struct {
+ char name[MONITOR_SYMBOL_LEN];
+ uint32_t value;
+ uint32_t offset;
+} rtems_monitor_symbol_t;
+
+typedef struct {
+ rtems_id id;
+ rtems_name name;
+ /* end of common portion */
+} rtems_monitor_generic_t;
+
+/*
+ * Task
+ */
+typedef struct {
+ rtems_id id;
+ rtems_name name;
+ /* end of common portion */
+ char short_name[5];
+ char long_name[16];
+ Thread_Entry_information entry;
+ void *stack;
+ uint32_t stack_size;
+ char scheduler_name[5];
+ rtems_task_priority priority;
+ States_Control state;
+ rtems_event_set events;
+ rtems_mode modes;
+ rtems_attribute attributes;
+ char wait[17];
+ uint32_t ticks;
+} rtems_monitor_task_t;
+
+/*
+ * Init task
+ */
+
+typedef struct {
+ rtems_id id; /* not really an id */
+ rtems_name name;
+ /* end of common portion */
+ rtems_monitor_symbol_t entry;
+ uint32_t argument;
+ uint32_t stack_size;
+ rtems_task_priority priority;
+ rtems_mode modes;
+ rtems_attribute attributes;
+} rtems_monitor_init_task_t;
+
+
+/*
+ * Message queue
+ */
+typedef struct {
+ rtems_id id;
+ rtems_name name;
+ /* end of common portion */
+ rtems_attribute attributes;
+ uint32_t number_of_pending_messages;
+ uint32_t maximum_pending_messages;
+ size_t maximum_message_size;
+} rtems_monitor_queue_t;
+
+/*
+ * Semaphore
+ */
+typedef struct {
+ rtems_id id;
+ rtems_name name;
+ /* end of common portion */
+ rtems_attribute attribute;
+ rtems_task_priority priority_ceiling;
+ uint32_t max_count;
+ uint32_t cur_count;
+ rtems_id holder_id;
+} rtems_monitor_sema_t;
+
+/*
+ * Extension
+ */
+typedef struct {
+ rtems_id id;
+ rtems_name name;
+ /* end of common portion */
+ rtems_monitor_symbol_t e_create;
+ rtems_monitor_symbol_t e_start;
+ rtems_monitor_symbol_t e_restart;
+ rtems_monitor_symbol_t e_delete;
+ rtems_monitor_symbol_t e_tswitch;
+ rtems_monitor_symbol_t e_begin;
+ rtems_monitor_symbol_t e_exitted;
+ rtems_monitor_symbol_t e_fatal;
+} rtems_monitor_extension_t;
+
+ /*
+ * Region
+ */
+typedef struct {
+ rtems_id id;
+ rtems_name name;
+ /* end of common portion */
+ rtems_attribute attribute;
+ void * start_addr;
+ uint32_t length;
+ uint32_t page_size;
+ uint32_t max_seg_size;
+ uint32_t used_blocks;
+} rtems_monitor_region_t;
+
+/*
+ * Partition
+ */
+typedef struct {
+ rtems_id id;
+ rtems_name name;
+ /* end of common portion */
+ rtems_attribute attribute;
+ void * start_addr;
+ uint32_t length;
+ uint32_t buf_size;
+ uint32_t used_blocks;
+} rtems_monitor_part_t;
+
+/*
+ * Device driver
+ */
+
+typedef struct {
+ rtems_id id; /* not really an id (should be tho) */
+ rtems_name name; /* ditto */
+ /* end of common portion */
+ rtems_monitor_symbol_t initialization; /* initialization procedure */
+ rtems_monitor_symbol_t open; /* open request procedure */
+ rtems_monitor_symbol_t close; /* close request procedure */
+ rtems_monitor_symbol_t read; /* read request procedure */
+ rtems_monitor_symbol_t write; /* write request procedure */
+ rtems_monitor_symbol_t control; /* special functions procedure */
+} rtems_monitor_driver_t;
+
+/*
+ * System config
+ */
+
+typedef struct {
+ void *work_space_start;
+ uint32_t work_space_size;
+ uint32_t maximum_tasks;
+ uint32_t maximum_timers;
+ uint32_t maximum_semaphores;
+ uint32_t maximum_message_queues;
+ uint32_t maximum_partitions;
+ uint32_t maximum_regions;
+ uint32_t maximum_ports;
+ uint32_t maximum_periods;
+ uint32_t maximum_extensions;
+ uint32_t microseconds_per_tick;
+ uint32_t ticks_per_timeslice;
+ uint32_t number_of_initialization_tasks;
+} rtems_monitor_config_t;
+
+/*
+ * MPCI config
+ */
+
+#if defined(RTEMS_MULTIPROCESSING)
+typedef struct {
+ uint32_t node; /* local node number */
+ uint32_t maximum_nodes; /* maximum # nodes in system */
+ uint32_t maximum_global_objects; /* maximum # global objects */
+ uint32_t maximum_proxies; /* maximum # proxies */
+
+ uint32_t default_timeout; /* in ticks */
+ size_t maximum_packet_size;
+ rtems_monitor_symbol_t initialization;
+ rtems_monitor_symbol_t get_packet;
+ rtems_monitor_symbol_t return_packet;
+ rtems_monitor_symbol_t send_packet;
+ rtems_monitor_symbol_t receive_packet;
+} rtems_monitor_mpci_t;
+#endif
+
+/*
+ * The generic canonical information union
+ */
+
+typedef union {
+ rtems_monitor_generic_t generic;
+ rtems_monitor_task_t task;
+ rtems_monitor_queue_t queue;
+ rtems_monitor_sema_t sema;
+ rtems_monitor_extension_t extension;
+ rtems_monitor_driver_t driver;
+ rtems_monitor_config_t config;
+ rtems_monitor_region_t region;
+ rtems_monitor_part_t part;
+#if defined(RTEMS_MULTIPROCESSING)
+ rtems_monitor_mpci_t mpci;
+#endif
+ rtems_monitor_init_task_t itask;
+} rtems_monitor_union_t;
+
+/*
+ * Support for talking to other monitors
+ */
+
+/*
+ * Names of other monitors
+ */
+
+#define RTEMS_MONITOR_NAME (rtems_build_name('R', 'M', 'O', 'N'))
+#define RTEMS_MONITOR_SERVER_NAME (rtems_build_name('R', 'M', 'S', 'V'))
+#define RTEMS_MONITOR_QUEUE_NAME (rtems_build_name('R', 'M', 'S', 'Q'))
+#define RTEMS_MONITOR_RESPONSE_QUEUE_NAME (rtems_build_name('R', 'M', 'R', 'Q'))
+
+#define RTEMS_MONITOR_SERVER_RESPONSE 0x0001
+#define RTEMS_MONITOR_SERVER_CANONICAL 0x0002
+
+typedef struct
+{
+ uint32_t command;
+ rtems_id return_id;
+ uint32_t argument0;
+ uint32_t argument1;
+ uint32_t argument2;
+ uint32_t argument3;
+ uint32_t argument4;
+ uint32_t argument5;
+} rtems_monitor_server_request_t;
+
+typedef struct
+{
+ uint32_t command;
+ uint32_t result0;
+ uint32_t result1;
+ rtems_monitor_union_t payload;
+} rtems_monitor_server_response_t;
+
+extern rtems_id rtems_monitor_task_id;
+
+extern uint32_t rtems_monitor_node; /* our node number */
+extern uint32_t rtems_monitor_default_node; /* current default for commands */
+
+/*
+ * Monitor command function and table entry
+ */
+
+typedef struct rtems_monitor_command_entry_s rtems_monitor_command_entry_t;
+typedef union _rtems_monitor_command_arg_t rtems_monitor_command_arg_t;
+
+typedef void (*rtems_monitor_command_function_t)(
+ int argc,
+ char **argv,
+ const rtems_monitor_command_arg_t *command_arg,
+ bool verbose
+);
+
+union _rtems_monitor_command_arg_t {
+ rtems_monitor_object_type_t monitor_object;
+ rtems_status_code status_code;
+ rtems_symbol_table_t **symbol_table;
+ const rtems_monitor_command_entry_t *monitor_command_entry;
+};
+
+struct rtems_monitor_command_entry_s {
+ const char *command; /* command name */
+ const char *usage; /* usage string for the command */
+ uint32_t arguments_required; /* # of required args */
+ rtems_monitor_command_function_t command_function;
+ /* Some argument for the command */
+ rtems_monitor_command_arg_t command_arg;
+ const rtems_monitor_command_entry_t *next;
+};
+
+
+typedef const void *(*rtems_monitor_object_next_fn)(void *, void *, rtems_id *);
+typedef void (*rtems_monitor_object_canonical_fn)(void *, const void *);
+typedef void (*rtems_monitor_object_dump_header_fn)(bool);
+typedef void (*rtems_monitor_object_dump_fn)(void *, bool);
+
+typedef struct {
+ rtems_monitor_object_type_t type;
+ void *object_information;
+ int size; /* of canonical object */
+ rtems_monitor_object_next_fn next;
+ rtems_monitor_object_canonical_fn canonical;
+ rtems_monitor_object_dump_header_fn dump_header;
+ rtems_monitor_object_dump_fn dump;
+} rtems_monitor_object_info_t;
+
+typedef bool (*rtems_monitor_per_command_routine)(const rtems_monitor_command_entry_t *, void *);
+
+/* monitor.c */
+void rtems_monitor_pause_cmd(int, char **, const rtems_monitor_command_arg_t*, bool);
+void rtems_monitor_fatal_cmd(int, char **, const rtems_monitor_command_arg_t*, bool);
+void rtems_monitor_continue_cmd(int, char **, const rtems_monitor_command_arg_t*, bool);
+void rtems_monitor_debugger_cmd(int, char **, const rtems_monitor_command_arg_t*, bool);
+void rtems_monitor_reset_cmd(int, char **, const rtems_monitor_command_arg_t*, bool);
+void rtems_monitor_node_cmd(int, char **, const rtems_monitor_command_arg_t*, bool);
+void rtems_monitor_symbols_loadup(void);
+int rtems_monitor_insert_cmd(rtems_monitor_command_entry_t *);
+void rtems_monitor_wakeup(void);
+void rtems_monitor_command_iterate(rtems_monitor_per_command_routine routine, void *arg);
+rtems_status_code rtems_monitor_suspend(rtems_interval timeout);
+
+/* editor.c */
+void rtems_monitor_kill(void);
+void rtems_monitor_init(uint32_t);
+void rtems_monitor_task(rtems_task_argument);
+
+/* server.c */
+void rtems_monitor_server_kill(void);
+rtems_status_code rtems_monitor_server_request(uint32_t , rtems_monitor_server_request_t *, rtems_monitor_server_response_t *);
+void rtems_monitor_server_task(rtems_task_argument);
+void rtems_monitor_server_init(uint32_t);
+
+/* command.c */
+int rtems_monitor_make_argv(char *, int *, char **);
+int rtems_monitor_command_read(char *, int *, char **);
+void rtems_monitor_command_usage(const rtems_monitor_command_entry_t *, const char *);
+void rtems_monitor_help_cmd(int, char **, const rtems_monitor_command_arg_t *, bool);
+const rtems_monitor_command_entry_t *rtems_monitor_command_lookup(const char *name);
+
+/* prmisc.c */
+void rtems_monitor_separator(void);
+uint32_t rtems_monitor_pad(uint32_t dest_col, uint32_t curr_col);
+int rtems_monitor_dump_decimal(uint32_t num);
+int rtems_monitor_dump_hex(uint32_t num);
+int rtems_monitor_dump_addr(const void *addr);
+int rtems_monitor_dump_id(rtems_id id);
+int rtems_monitor_dump_name(rtems_id id);
+int rtems_monitor_dump_priority(rtems_task_priority priority);
+int rtems_monitor_dump_state(States_Control state);
+int rtems_monitor_dump_modes(rtems_mode modes);
+int rtems_monitor_dump_attributes(rtems_attribute attributes);
+int rtems_monitor_dump_events(rtems_event_set events);
+
+/* object.c */
+rtems_id rtems_monitor_id_fixup(rtems_id, uint32_t , rtems_monitor_object_type_t);
+const rtems_monitor_object_info_t *rtems_monitor_object_lookup(rtems_monitor_object_type_t type);
+rtems_id rtems_monitor_object_canonical_get(rtems_monitor_object_type_t, rtems_id, void *, size_t *size_p);
+rtems_id rtems_monitor_object_canonical_next(const rtems_monitor_object_info_t *, rtems_id, void *);
+const void *rtems_monitor_object_next(void *, void *, rtems_id, rtems_id *);
+rtems_id rtems_monitor_object_canonical(rtems_id, const void *);
+void rtems_monitor_object_cmd(int, char **, const rtems_monitor_command_arg_t*, bool);
+
+/* manager.c */
+const void *rtems_monitor_manager_next(void *, void *, rtems_id *);
+
+/* config.c */
+void rtems_monitor_config_canonical(rtems_monitor_config_t *, const void *);
+const void *rtems_monitor_config_next(void *, rtems_monitor_config_t *, rtems_id *);
+void rtems_monitor_config_dump_header(bool);
+int rtems_monitor_config_dump(rtems_monitor_config_t *, bool verbose);
+
+/* mpci.c */
+#if defined(RTEMS_MULTIPROCESSING)
+void rtems_monitor_mpci_canonical(rtems_monitor_mpci_t *, const void *);
+const void *rtems_monitor_mpci_next(void *, rtems_monitor_mpci_t *, rtems_id *);
+void rtems_monitor_mpci_dump_header(bool);
+void rtems_monitor_mpci_dump(rtems_monitor_mpci_t *, bool verbose);
+#endif
+
+/* itask.c */
+void rtems_monitor_init_task_canonical(rtems_monitor_init_task_t *, const void *);
+const void *rtems_monitor_init_task_next(void *, rtems_monitor_init_task_t *, rtems_id *);
+void rtems_monitor_init_task_dump_header(bool);
+void rtems_monitor_init_task_dump(rtems_monitor_init_task_t *, bool verbose);
+
+/* extension.c */
+void rtems_monitor_extension_canonical(rtems_monitor_extension_t *, const void *);
+void rtems_monitor_extension_dump_header(bool verbose);
+void rtems_monitor_extension_dump(rtems_monitor_extension_t *, bool);
+
+/* task.c */
+void rtems_monitor_task_canonical(rtems_monitor_task_t *, const void *);
+void rtems_monitor_task_dump_header(bool verbose);
+void rtems_monitor_task_dump(rtems_monitor_task_t *, bool);
+
+/* sema.c */
+void rtems_monitor_sema_canonical(rtems_monitor_sema_t *, const void *);
+void rtems_monitor_sema_dump_header(bool verbose);
+void rtems_monitor_sema_dump(rtems_monitor_sema_t *, bool);
+
+/* queue.c */
+void rtems_monitor_queue_canonical(rtems_monitor_queue_t *, const void *);
+void rtems_monitor_queue_dump_header(bool verbose);
+void rtems_monitor_queue_dump(rtems_monitor_queue_t *, bool);
+
+/* region.c */
+void rtems_monitor_region_canonical(rtems_monitor_region_t *, const void *);
+void rtems_monitor_region_dump_header(bool verbose);
+void rtems_monitor_region_dump(rtems_monitor_region_t *, bool);
+
+/* partition.c */
+void rtems_monitor_part_canonical(rtems_monitor_part_t *, const void *);
+void rtems_monitor_part_dump_header(bool verbose);
+void rtems_monitor_part_dump(rtems_monitor_part_t *, bool);
+
+/* driver.c */
+const void *rtems_monitor_driver_next(void *, rtems_monitor_driver_t *, rtems_id *);
+void rtems_monitor_driver_canonical(rtems_monitor_driver_t *, const void *);
+void rtems_monitor_driver_dump_header(bool);
+void rtems_monitor_driver_dump(rtems_monitor_driver_t *, bool);
+
+/* symbols.c */
+rtems_symbol_table_t *rtems_symbol_table_create(void);
+void rtems_symbol_table_destroy(rtems_symbol_table_t *table);
+
+rtems_symbol_t *rtems_symbol_create(rtems_symbol_table_t *, const char *, uint32_t);
+rtems_symbol_t *rtems_symbol_value_lookup(rtems_symbol_table_t *, uint32_t);
+const rtems_symbol_t *rtems_symbol_value_lookup_exact(rtems_symbol_table_t *, uint32_t);
+rtems_symbol_t *rtems_symbol_name_lookup(rtems_symbol_table_t *, const char *);
+const void *rtems_monitor_symbol_next(void *object_info, rtems_monitor_symbol_t *, rtems_id *);
+void rtems_monitor_symbol_canonical(rtems_monitor_symbol_t *, rtems_symbol_t *);
+void rtems_monitor_symbol_canonical_by_name(rtems_monitor_symbol_t *, const char *);
+void rtems_monitor_symbol_canonical_by_value(rtems_monitor_symbol_t *, void *);
+uint32_t rtems_monitor_symbol_dump(rtems_monitor_symbol_t *, bool);
+void rtems_monitor_symbol_cmd(int, char **, const rtems_monitor_command_arg_t*, bool);
+
+#if defined(RTEMS_NETWORKING)
+void mon_ifconfig(
+ int argc,
+ char *argv[],
+ uint32_t command_arg,
+ bool verbose
+);
+void mon_route(
+ int argc,
+ char *argv[],
+ uint32_t command_arg,
+ bool verbose
+);
+#endif
+
+/* mon-object.c */
+const rtems_monitor_object_info_t *rtems_monitor_object_lookup(
+ rtems_monitor_object_type_t type
+);
+
+/* shared data */
+extern rtems_symbol_table_t *rtems_monitor_symbols;
+
+#define MONITOR_WAKEUP_EVENT RTEMS_EVENT_0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! __MONITOR_H */
diff --git a/cpukit/include/rtems/mouse_parser.h b/cpukit/include/rtems/mouse_parser.h
new file mode 100644
index 0000000000..27bea1bbbc
--- /dev/null
+++ b/cpukit/include/rtems/mouse_parser.h
@@ -0,0 +1,121 @@
+/**
+ * @file rtems/mouse_parser.h
+ *
+ * @brief Initialize Mouse Parser Engine
+ *
+ * This file is the header file for the Mouse Parser Engine.
+ */
+
+/*
+ * This file is derived from a UNIX Serial Port Mouse Driver with the
+ * following notice:
+ *
+ * ==================================================================
+ * Copyright (c) 1999 Greg Haerr <greg@censoft.com>
+ * Portions Copyright (c) 1991 David I. Bell
+ * Permission is granted to use, distribute, or modify this source,
+ * provided that this copyright notice remains intact.
+ *
+ * UNIX Serial Port Mouse Driver
+ *
+ * This driver opens a serial port directly, and interprets serial data.
+ * Microsoft, PC, Logitech and PS/2 mice are supported. The PS/2 mouse
+ * is only supported if the OS runs the mouse byte codes through the
+ * serial port.
+ *
+ * Mouse Types Supported: pc ms, logi, ps2
+ * ==================================================================
+ *
+ * It has been modified to support the concept of being just a parser
+ * fed data from an arbitrary source. It is independent of either
+ * a PS/2 driver or a serial port.
+ *
+ * It was moved to cpukit/libmisc/mouse by Joel Sherrill.
+ */
+
+#ifndef __MOUSE_PARSER_h__
+#define __MOUSE_PARSER_h__
+
+#include <rtems/mw_uid.h>
+
+/**
+ * @defgroup libmisc_mouseparser Mouse Parser Engine
+ * @ingroup libmisc_mouse
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This is the mask for the right button.
+ *
+ * @note Use the same definitions as the user interface.
+ */
+#define RBUTTON MV_BUTTON_RIGHT
+
+/**
+ * This is the mask for the center button.
+ *
+ * @note Use the same definitions as the user interface.
+ */
+#define MBUTTON MV_BUTTON_CENTER
+
+/**
+ * This is the mask for the left button.
+ *
+ * @note Use the same definitions as the user interface.
+ */
+#define LBUTTON MV_BUTTON_LEFT
+
+/**
+ * This type is the device coordinates.
+ */
+typedef int COORD;
+
+/**
+ * This type is the mouse button mask.
+ */
+typedef unsigned int BUTTON;
+
+/**
+ * This type defines a pointer to the enqueue method. It is
+ * available since some device drivers keep pointers to the method
+ * to know when to enqueue or not.
+ */
+typedef void (*mouse_parser_enqueue_handler)(unsigned char *, size_t);
+
+/**
+ * @brief Initialize the mouse parser engine.
+ *
+ * This method initializes the Mouse Parser Engine for the mouse
+ * of @a type. The @a type should be one of the following strings:
+ * pc ms, logi, ps2.
+ *
+ * @a param[in] type indicates the type of mouse.
+ *
+ * @retval This method returns 0 on success and -1 on error.
+ */
+int mouse_parser_initialize(const char *type);
+
+/**
+ * @brief Enqueue input to the mouse parser engine.
+ *
+ * This method is used to pass mouse input to the Mouse Parser Engine.
+ *
+ * @a param[in] buffer is the data to enqueue
+ * @a param[in] size is the amount of data to enqueue
+ */
+void mouse_parser_enqueue(
+ unsigned char *buffer,
+ size_t size
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
diff --git a/cpukit/include/rtems/mptables.h b/cpukit/include/rtems/mptables.h
new file mode 100644
index 0000000000..01e5b653b4
--- /dev/null
+++ b/cpukit/include/rtems/mptables.h
@@ -0,0 +1,32 @@
+/**
+ * @file
+ *
+ * @brief Executive's Pre-Initialized Tables used in a
+ * Multiprocessor Configuration
+ *
+ * This include file contains the executive's pre-initialized tables
+ * used in a multiprocessor configuration.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_MPTABLES_H
+#define _RTEMS_MPTABLES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/mw_uid.h b/cpukit/include/rtems/mw_uid.h
new file mode 100644
index 0000000000..aa88392d26
--- /dev/null
+++ b/cpukit/include/rtems/mw_uid.h
@@ -0,0 +1,194 @@
+/**
+ * @file rtems/mw_uid.h
+ *
+ * @defgroup libmisc_fb_mw Input Devices for MicroWindows
+ *
+ * @ingroup libmisc
+ * @brief Input Devices for MicroWindows
+ *
+ * This file defines the interface for input devices used by MicroWindows
+ * in an embedded system environment.
+ */
+
+/*
+ * Copyright (c) 2000 - Rosimildo da Silva
+ */
+
+#ifndef _MW_UID_H
+#define _MW_UID_H
+
+#include <sys/types.h>
+#include <rtems/print.h>
+
+/**
+ * @defgroup libmisc_fb_mw Input Devices for MicroWindows
+ *
+ * @ingroup libmisc
+ */
+/**@{*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 0x41XX -- IOCTL functions for the Micro Input Devices commands */
+#define MW_UID_REGISTER_DEVICE 0x4100
+#define MW_UID_UNREGISTER_DEVICE 0x4101
+
+/* devices supported by MicroWindows */
+enum MW_INPUT_DEVICE_TYPE {
+ MV_UID_INVALID = 0,
+ MV_UID_REL_POS = 1, /* mouse */
+ MV_UID_ABS_POS = 2, /* touch-screen */
+ MV_UID_KBD = 3, /* keyboard */
+ MV_UID_TIMER = 4 /* timer -- not used */
+};
+
+/* matching MicroWindows */
+#define MV_BUTTON_RIGHT 0x01
+#define MV_BUTTON_CENTER 0x02
+#define MV_BUTTON_LEFT 0x04
+
+/* modifiers of the keyboard type devices */
+#define MV_KEY_MODIFIER_SHIFT_DOWN 0x10
+#define MV_KEY_MODIFIER_ALT_DOWN 0x20
+
+/* indication of the LEDS */
+#define MV_KEY_MODIFIER_CAPS_ON 0x04
+#define MV_KEY_MODIFIER_NUN_LOCK_ON 0x02
+#define MV_KEY_SCROLL_LOCK_ON 0x01
+
+/* keyboard modes -- default ASCII */
+#define MV_KEY_MODE_ASCII 0x01
+/*
+ * This mode one event is sent when a key is pressed,
+ * and another one is send when a key is released.
+ */
+#define MV_KEY_MODE_SCANCODE 0x00
+
+/* these defines match with the linux keyboard range
+ * for ioctls functions for the keyboard interface.
+ * 0x4BXX --- keyboard related functions
+ */
+#define MV_KDGKBMODE 0x4B44 /* gets current keyboard mode */
+#define MV_KDSKBMODE 0x4B45 /* sets current keyboard mode */
+
+/*
+ * Message generated by input devices controlled by MicroWindows.
+ */
+struct MW_UID_MESSAGE {
+ enum MW_INPUT_DEVICE_TYPE type; /* device type */
+ union {
+ /* fired when keyboard events are raised */
+ struct kbd_t {
+ unsigned short code; /* keycode or scancode */
+ unsigned char modifiers; /* key modifiers */
+ unsigned char mode; /* current Kbd mode */
+ } kbd;
+
+ /* fired when position events are raised, mouse, touch screen, etc */
+ struct pos_t {
+ unsigned short btns; /* indicates which buttons are pressed */
+ short x; /* x location */
+ short y; /* y location */
+ short z; /* z location, 0 for 2D */
+ } pos;
+
+ /* fired by a timer device periodically */
+ struct timer_t {
+ unsigned long frt; /* free running timer */
+ unsigned long seq; /* sequence number */
+ } tmr;
+ } m;
+};
+
+
+/*
+ * API for creating/closing/accessing the message queue used by the micro
+ * input device interface. All functions in this interface returns a
+ * zero ( 0 ) on success. One exception for that is the "read" routine
+ * that returns the number of bytes read. Negaive numbers indicate errors
+ *
+ * The implementation of the message queue for RTEMS uses a POSIX message
+ * queue interface. It should be very portable among systems with a POSIX
+ * support.
+ */
+
+/**
+ * This method creates the message queue that holds events from the
+ * input devices.
+ *
+ * @param[in] q_name is the name of the message queue
+ * @param[in] flags controls the behaviour of the queue
+ * @param[in] max_msgs specifies the maximum number of pending messages
+ *
+ * @note The message queue is from the Classic API.
+ *
+ * @retval This method returns 0 on success and -1 on error.
+ */
+extern int uid_open_queue( const char *q_name, int flags, size_t max_msgs );
+
+/**
+ * This method closes the message queue and deletes it.
+ *
+ * @retval This method returns 0 on success and -1 on error.
+ */
+extern int uid_close_queue( void );
+
+/**
+ * This method reads a message from the queue. It waits up to the specified
+ * timeout in miliseconds. A @a timeout of 0 is a poll.
+ *
+ * @param[in] m will be filled in with the received message
+ * @param[in] timeout is the maximum number of mulliseconds to wait
+ *
+ * @retval This method returns 0 on success and -1 on error.
+ */
+extern int uid_read_message( struct MW_UID_MESSAGE *m, unsigned long timeout );
+
+/**
+ * This methods writes a message to the queue.
+ *
+ * @param[in] m is the message to send
+ *
+ * @retval This method returns 0 on success and -1 on error.
+ */
+extern int uid_send_message( struct MW_UID_MESSAGE *m );
+
+/**
+ * This method registers the device associated with @a fd to
+ * to insert data to the queue
+ */
+extern int uid_register_device( int fd, const char *q_name );
+
+/* unregister device to stop adding messages to the queue */
+extern int uid_unregister_device( int fd );
+
+/* set the keyboard */
+extern int uid_set_kbd_mode( int fd, int mode, int *old_mode );
+
+/**
+ * This methods prints the specified UID message using printk
+ *
+ * @param[in] uid points to the message to print
+ */
+void uid_print_message(
+ struct MW_UID_MESSAGE *uid
+);
+
+/**
+ * This methods prints the specified UID message using your fprintf
+ * style method of choice.
+ *
+ * @param[in] RTEMS printer
+ * @param[in] uid points to the message to print
+ */
+void uid_print_message_with_plugin(
+ const rtems_printer *printer,
+ struct MW_UID_MESSAGE *uid
+);
+
+#ifdef __cplusplus
+}
+#endif
+/**@}*/
+#endif /* _MW_UID_H */
diff --git a/cpukit/include/rtems/nvdisk-sram.h b/cpukit/include/rtems/nvdisk-sram.h
new file mode 100644
index 0000000000..3acaf600b6
--- /dev/null
+++ b/cpukit/include/rtems/nvdisk-sram.h
@@ -0,0 +1,23 @@
+/**
+ * @file rtems/nvdisk-sram.h
+ *
+ * This driver maps an NV disk to static RAM. You can use this
+ */
+
+/*
+ * RTEMS Project (http://www.rtems.org/)
+ *
+ * Copyright 2007 Chris Johns (chrisj@rtems.org)
+ */
+
+#if !defined (_RTEMS_NVDISK_SRAM_H_)
+#define _RTEMS_NVDISK_SRAM_H_
+
+#include <rtems/nvdisk.h>
+
+/**
+ * The handlers for the NV Disk SRAM driver.
+ */
+extern const rtems_nvdisk_driver_handlers rtems_nvdisk_sram_handlers;
+
+#endif
diff --git a/cpukit/include/rtems/nvdisk.h b/cpukit/include/rtems/nvdisk.h
new file mode 100644
index 0000000000..5570fb8c6b
--- /dev/null
+++ b/cpukit/include/rtems/nvdisk.h
@@ -0,0 +1,211 @@
+/**
+ * @file rtems/nvdisk.h
+ *
+ * @brief Non-volatile Disk Block Device Implementation
+ */
+
+/*
+ * Copyright (C) 2007 Chris Johns
+ *
+ * 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.
+ */
+
+/**
+ * The Non-volatile disk provides a simple directly mapped disk
+ * driver with checksums for each. It is designed to provied a
+ * disk that can survive a restart. Examples are EEPROM devices
+ * which have byte writeable locations, or a battery backed up
+ * RAM disk.
+ *
+ * The low level driver provides the physical access to the
+ * hardware.
+ */
+#if !defined (_RTEMS_NVDISK_H_)
+#define _RTEMS_NVDISK_H_
+
+#include <stdint.h>
+#include <sys/ioctl.h>
+
+#include <rtems.h>
+
+/**
+ * The base name of the nv disks.
+ */
+#define RTEMS_NVDISK_DEVICE_BASE_NAME "/dev/nvd"
+
+/**
+ * NV disk specific ioctl request types. To use open the
+ * device and issue the ioctl call.
+ *
+ * @code
+ * int fd = open ("/dev/nvdisk0", O_WRONLY, 0);
+ * if (fd < 0)
+ * {
+ * printf ("driver open failed: %s\n", strerror (errno));
+ * exit (1);
+ * }
+ * if (ioctl (fd, RTEMS_NVDISK_IOCTL_ERASE_DISK) < 0)
+ * {
+ * printf ("driver erase failed: %s\n", strerror (errno));
+ * exit (1);
+ * }
+ * close (fd);
+ * @endcode
+ */
+#define RTEMS_NVDISK_IOCTL_ERASE_DISK _IO('B', 128)
+#define RTEMS_NVDISK_IOCTL_MONITORING _IO('B', 129)
+#define RTEMS_NVDISK_IOCTL_INFO_LEVEL _IO('B', 130)
+#define RTEMS_NVDISK_IOCTL_PRINT_STATUS _IO('B', 131)
+
+/**
+ * NV Disk Monitoring Data allows a user to obtain
+ * the current status of the disk.
+ */
+typedef struct rtems_nvdisk_monitor_data
+{
+ uint32_t block_size;
+ uint32_t block_count;
+ uint32_t page_count;
+ uint32_t pages_available;
+ uint32_t pages_used;
+ uint32_t info_level;
+} rtems_nvdisk_monitor_data;
+
+/**
+ * Return the number of kilo-bytes.
+ */
+#define RTEMS_NVDISK_KBYTES(_k) ((_k) * 1024)
+
+/**
+ * NV Low Level driver handlers.
+
+ * Typically this structure is part of a table of handlers in the
+ * device which is referenced in the nvdisk configuration table.
+ * The reference is kept in the driver and used all the time to
+ * manage the nv device, therefore it must always exist.
+ */
+typedef struct rtems_nvdisk_driver_handlers
+{
+ /**
+ * Read data from the device into the buffer. Return an errno
+ * error number if the data cannot be read.
+ *
+ * @param device The device to read data from.
+ * @param flags Device specific flags for the driver.
+ * @param base The base address of the device.
+ * @param offset The offset in the segment to read.
+ * @param buffer The buffer to read the data into.
+ * @param size The amount of data to read.
+ * @retval 0 No error.
+ * @retval EIO The read did not complete.
+ */
+ int (*read) (uint32_t device, uint32_t flags, void* base,
+ uint32_t offset, void* buffer, size_t size);
+
+ /**
+ * Write data from the buffer to the device. Return an errno
+ * error number if the device cannot be written to.
+ *
+ * @param device The device to write data to.
+ * @param flags Device specific flags for the driver.
+ * @param base The base address of the device.
+ * @param offset The offset in the device to write to.
+ * @param buffer The buffer to write the data from.
+ * @param size The amount of data to write.
+ * @retval 0 No error.
+ * @retval EIO The write did not complete or verify.
+ */
+ int (*write) (uint32_t device, uint32_t flags, void* base,
+ uint32_t offset, const void* buffer, size_t size);
+
+ /**
+ * Verify data in the buffer to the data in the device. Return an
+ * errno error number if the device cannot be read or the data verified.
+ *
+ * @param device The device to verify the data with.
+ * @param flags Device specific flags for the driver.
+ * @param base The base address of the device.
+ * @param offset The offset in the device to verify.
+ * @param buffer The buffer to verify the data in the device with.
+ * @param size The amount of data to verify.
+ * @retval 0 No error.
+ * @retval EIO The data did not verify.
+ */
+ int (*verify) (uint32_t device, uint32_t flags, void* base,
+ uint32_t offset, const void* buffer, size_t size);
+
+} rtems_nvdisk_driver_handlers;
+
+/**
+ * NV Device Descriptor holds the description of a device that is
+ * part of the NV disk.
+ *
+ * Typically this structure is part of a table of the device which
+ * is referenced in the nvdisk configuration table.
+ * The reference is kept in the driver and used all the time to
+ * manage the nv device, therefore it must always exist.
+ */
+typedef struct rtems_nvdisk_device_desc
+{
+ uint32_t flags; /**< Private user flags. */
+ void* base; /**< Base address of the device. */
+ uint32_t size; /**< Size of the device. */
+ const rtems_nvdisk_driver_handlers* nv_ops; /**< Device handlers. */
+} rtems_nvdisk_device_desc;
+
+/**
+ * RTEMS Non-Volatile Disk configuration table used to initialise the
+ * driver.
+ */
+typedef struct rtems_nvdisk_config
+{
+ uint32_t block_size; /**< The block size. */
+ uint32_t device_count; /**< The number of devices. */
+ const rtems_nvdisk_device_desc* devices; /**< The device descriptions. */
+ uint32_t flags; /**< Set of flags to control
+ driver. */
+ uint32_t info_level; /**< Default info level. */
+} rtems_nvdisk_config;
+
+/*
+ * Driver flags.
+ */
+
+/**
+ * Check the pages during initialisation to see which pages are
+ * valid and which are not. This could slow down initialising the
+ * disk driver.
+ */
+#define RTEMS_NVDISK_CHECK_PAGES (1 << 0)
+
+/**
+ * Non-volatile disk device driver initialization. Place in a table as the
+ * initialisation entry and remainder of the entries are the RTEMS block
+ * device generic handlers.
+ *
+ * @param major NV disk major device number.
+ * @param minor Minor device number, not applicable.
+ * @param arg Initialization argument, not applicable.
+ * @return The rtems_device_driver is actually just
+ * rtems_status_code.
+ */
+rtems_device_driver
+rtems_nvdisk_initialize (rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void* arg);
+
+/**
+ * External reference to the configuration. Please supply.
+ * Support is present in confdefs.h for providing this variable.
+ */
+extern const rtems_nvdisk_config rtems_nvdisk_configuration[];
+
+/**
+ * External reference to the number of configurations. Please supply.
+ * Support is present in confdefs.h for providing this variable.
+ */
+extern uint32_t rtems_nvdisk_configuration_size;
+
+#endif
diff --git a/cpukit/include/rtems/passwd.h b/cpukit/include/rtems/passwd.h
new file mode 100644
index 0000000000..8d5c299a5e
--- /dev/null
+++ b/cpukit/include/rtems/passwd.h
@@ -0,0 +1,25 @@
+/* Define a default password for telnetd here.
+ * NOTES:
+ * - this can be overridden at run-time by setting
+ * the "TELNETD_PASSWD" environment variable.
+ * As soon as that variable is set, the new password
+ * is effective - no need to restart telnetd.
+ * - this must be set to an _encrypted_ password, NOT
+ * the cleartext. Use the 'genpw' utility to generate
+ * a password string:
+ *
+ * 1) Compile 'genpw.c' for the HOST, i.e.
+ * cc -o genpw genpw.c -lcrypt
+ * 1) delete an old password definition from this file.
+ * 2) run './genpw >> passwd.h'. This will append
+ * a new definition to this file.
+ *
+ * - if no password is defined here, no authentication
+ * is needed, i.e. telnet is open to the world.
+ *
+ * T. Straumann <strauman@slac.stanford.edu>
+ */
+
+/* #undef TELNETD_DEFAULT_PASSWD */
+/* Default password: 'rtems' */
+#define TELNETD_DEFAULT_PASSWD "tduDcyLX12owo"
diff --git a/cpukit/include/rtems/pipe.h b/cpukit/include/rtems/pipe.h
new file mode 100644
index 0000000000..7c6566ad50
--- /dev/null
+++ b/cpukit/include/rtems/pipe.h
@@ -0,0 +1,133 @@
+/**
+ * @file
+ *
+ * @brief POSIX FIFO/pipe File System Support
+ *
+ * This include file defines the interface to the POSIX FIFO/pipe file system
+ * support.
+ */
+
+/*
+ * Author: Wei Shen <cquark@gmail.com>
+ *
+ * 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_PIPE_H
+#define _RTEMS_PIPE_H
+
+#include <rtems/libio.h>
+
+/**
+ * @defgroup FIFO_PIPE FIFO/Pipe File System Support
+ *
+ * @ingroup FileSystemTypesAndMount
+ *
+ * @brief Interface to the POSIX FIFO/Pipe File System
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Control block to manage each pipe */
+typedef struct pipe_control {
+ char *Buffer;
+ unsigned int Size;
+ unsigned int Start;
+ unsigned int Length;
+ unsigned int Readers;
+ unsigned int Writers;
+ unsigned int waitingReaders;
+ unsigned int waitingWriters;
+ unsigned int readerCounter; /* incremental counters */
+ unsigned int writerCounter; /* for differentiation of successive opens */
+ rtems_id Semaphore;
+ rtems_id readBarrier; /* wait queues */
+ rtems_id writeBarrier;
+#if 0
+ boolean Anonymous; /* anonymous pipe or FIFO */
+#endif
+} pipe_control_t;
+
+/**
+ * @brief Create an anonymous pipe.
+ *
+ * Called by pipe() to create an anonymous pipe.
+ */
+extern int pipe_create(
+ int filsdes[2]
+);
+
+/**
+ * @brief Release a pipe.
+ *
+ * Interface to file system close.
+ *
+ * *pipep points to pipe control structure. When the last user releases pipe,
+ * it will be set to NULL.
+ */
+extern void pipe_release(
+ pipe_control_t **pipep,
+ rtems_libio_t *iop
+);
+
+/**
+ * @brief File system open.
+ * Interface to file system open.
+ *
+ * *pipep points to pipe control structure. If called with *pipep = NULL,
+ * fifo_open will try allocating and initializing a control structure. If the
+ * call succeeds, *pipep will be set to address of new control structure.
+ */
+extern int fifo_open(
+ pipe_control_t **pipep,
+ rtems_libio_t *iop
+);
+
+/**
+ * @brief File system read.
+ *
+ * Interface to file system read.
+ */
+extern ssize_t pipe_read(
+ pipe_control_t *pipe,
+ void *buffer,
+ size_t count,
+ rtems_libio_t *iop
+);
+
+/**
+ * @brief File system write.
+ *
+ * Interface to file system write.
+ */
+extern ssize_t pipe_write(
+ pipe_control_t *pipe,
+ const void *buffer,
+ size_t count,
+ rtems_libio_t *iop
+);
+
+/**
+ * @brief File system Input/Output control.
+ *
+ * Interface to file system ioctl.
+ */
+extern int pipe_ioctl(
+ pipe_control_t *pipe,
+ ioctl_command_t cmd,
+ void *buffer,
+ rtems_libio_t *iop
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/posix/aio_misc.h b/cpukit/include/rtems/posix/aio_misc.h
new file mode 100644
index 0000000000..aeccbad98f
--- /dev/null
+++ b/cpukit/include/rtems/posix/aio_misc.h
@@ -0,0 +1,113 @@
+/**
+ * @file
+ *
+ * @brief POSIX Asynchronous Input and Output Private Support
+ *
+ * This defines private information for the AIO implementation.
+ */
+
+/*
+ * Copyright 2010, Alin Rus <alin.codejunkie@gmail.com>
+ *
+ * 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 _AIO_MISC_H
+#define _AIO_MISC_H
+
+#include <stdio.h>
+#include <string.h>
+#include <aio.h>
+#include <pthread.h>
+#include <rtems.h>
+#include <rtems/chain.h>
+#include <rtems/system.h>
+#include <rtems/seterr.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /* Actual request being processed */
+ typedef struct
+ {
+ rtems_chain_node next_prio; /* chain requests in order of priority */
+ int policy; /* If _POSIX_PRIORITIZED_IO and
+ _POSIX_PRIORITY_SCHEDULING are defined */
+ int priority; /* see above */
+ pthread_t caller_thread; /* used for notification */
+ struct aiocb *aiocbp; /* aio control block */
+ } rtems_aio_request;
+
+ typedef struct
+ {
+ rtems_chain_node next_fd; /* order fd chains in queue */
+ rtems_chain_control perfd; /* chain of requests for this fd */
+ int fildes; /* file descriptor to be processed */
+ int new_fd; /* if this is a newly created chain */
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+
+ } rtems_aio_request_chain;
+
+ typedef struct
+ {
+ pthread_mutex_t mutex;
+ pthread_cond_t new_req;
+ pthread_attr_t attr;
+
+ rtems_chain_control work_req; /* chains being worked by active threads */
+ rtems_chain_control idle_req; /* fd chains waiting to be processed */
+ unsigned int initialized; /* specific value if queue is initialized */
+ int active_threads; /* the number of active threads */
+ int idle_threads; /* number of idle threads */
+
+ } rtems_aio_queue;
+
+extern rtems_aio_queue aio_request_queue;
+
+#define AIO_QUEUE_INITIALIZED 0xB00B
+
+#ifndef AIO_MAX_THREADS
+#define AIO_MAX_THREADS 5
+#endif
+
+#ifndef AIO_MAX_QUEUE_SIZE
+#define AIO_MAX_QUEUE_SIZE 30
+#endif
+
+int rtems_aio_init (void);
+int rtems_aio_enqueue (rtems_aio_request *req);
+rtems_aio_request_chain *rtems_aio_search_fd
+(
+ rtems_chain_control *chain,
+ int fildes,
+ int create
+);
+void rtems_aio_remove_fd (rtems_aio_request_chain *r_chain);
+int rtems_aio_remove_req (rtems_chain_control *chain,
+ struct aiocb *aiocbp);
+
+#ifdef RTEMS_DEBUG
+#include <assert.h>
+
+#define AIO_assert(_x) assert(_x)
+#define AIO_printf(_x) printf(_x)
+#else
+#define AIO_assert(_x)
+#define AIO_printf(_x)
+#endif
+
+#define rtems_aio_set_errno_return_minus_one( _error, _aiocbp ) \
+ do { (_aiocbp)->error_code = (_error); \
+ (_aiocbp)->return_value = -1; \
+ rtems_set_errno_and_return_minus_one (_error);} while(0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/posix/barrierimpl.h b/cpukit/include/rtems/posix/barrierimpl.h
new file mode 100644
index 0000000000..a1794b82fd
--- /dev/null
+++ b/cpukit/include/rtems/posix/barrierimpl.h
@@ -0,0 +1,99 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines from the POSIX Barrier Manager
+ *
+ * This file contains the static inlin implementation of the inlined
+ * routines from the POSIX Barrier Manager.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Copyright (c) 2017 embedded brains GmbH
+ *
+ * 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_POSIX_BARRIERIMPL_H
+#define _RTEMS_POSIX_BARRIERIMPL_H
+
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/score/percpu.h>
+#include <rtems/score/threadqimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define POSIX_BARRIER_MAGIC 0x1cf03773UL
+
+#define POSIX_BARRIER_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
+
+typedef struct {
+ unsigned long flags;
+ Thread_queue_Syslock_queue Queue;
+ unsigned int count;
+ unsigned int waiting_threads;
+} POSIX_Barrier_Control;
+
+static inline POSIX_Barrier_Control *_POSIX_Barrier_Get(
+ pthread_barrier_t *_barrier
+)
+{
+ return (POSIX_Barrier_Control *) _barrier;
+}
+
+static inline Thread_Control *_POSIX_Barrier_Queue_acquire(
+ POSIX_Barrier_Control *barrier,
+ Thread_queue_Context *queue_context
+)
+{
+ ISR_Level level;
+ Thread_Control *executing;
+
+ _Thread_queue_Context_initialize( queue_context );
+ _Thread_queue_Context_ISR_disable( queue_context, level );
+ _Thread_queue_Context_set_ISR_level( queue_context, level );
+ executing = _Thread_Executing;
+ _Thread_queue_Queue_acquire_critical(
+ &barrier->Queue.Queue,
+ &executing->Potpourri_stats,
+ &queue_context->Lock_context.Lock_context
+ );
+
+ return executing;
+}
+
+static inline void _POSIX_Barrier_Queue_release(
+ POSIX_Barrier_Control *barrier,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Queue_release(
+ &barrier->Queue.Queue,
+ &queue_context->Lock_context.Lock_context
+ );
+}
+
+#define POSIX_BARRIER_VALIDATE_OBJECT( bar ) \
+ do { \
+ if ( \
+ ( bar ) == NULL \
+ || ( (uintptr_t) ( bar ) ^ POSIX_BARRIER_MAGIC ) != ( bar )->_flags \
+ ) { \
+ return EINVAL; \
+ } \
+ } while ( 0 )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/posix/condimpl.h b/cpukit/include/rtems/posix/condimpl.h
new file mode 100644
index 0000000000..66e09bf6d8
--- /dev/null
+++ b/cpukit/include/rtems/posix/condimpl.h
@@ -0,0 +1,184 @@
+/**
+ * @file
+ *
+ * This include file contains the static inline implementation of the private
+ * inlined routines for POSIX condition variables.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_CONDIMPL_H
+#define _RTEMS_POSIX_CONDIMPL_H
+
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/score/percpu.h>
+#include <rtems/score/threadqimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ unsigned long flags;
+ Thread_queue_Syslock_queue Queue;
+ pthread_mutex_t *mutex;
+} POSIX_Condition_variables_Control;
+
+#define POSIX_CONDITION_VARIABLES_CLOCK_MONOTONIC 0x1UL
+
+#define POSIX_CONDITION_VARIABLES_FLAGS_MASK 0x1UL
+
+#define POSIX_CONDITION_VARIABLES_MAGIC 0x18dfb1feUL
+
+/**
+ * Constant to indicate condition variable does not currently have
+ * a mutex assigned to it.
+ */
+#define POSIX_CONDITION_VARIABLES_NO_MUTEX NULL
+
+#define POSIX_CONDITION_VARIABLES_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
+
+#define POSIX_CONDITION_VARIABLE_OF_THREAD_QUEUE_QUEUE( queue ) \
+ RTEMS_CONTAINER_OF( \
+ queue, POSIX_Condition_variables_Control, Queue.Queue )
+
+/**
+ * The default condition variable attributes structure.
+ */
+extern const pthread_condattr_t _POSIX_Condition_variables_Default_attributes;
+
+static inline POSIX_Condition_variables_Control *_POSIX_Condition_variables_Get(
+ pthread_cond_t *cond
+)
+{
+ return (POSIX_Condition_variables_Control *) cond;
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Condition_variables_Initialize(
+ POSIX_Condition_variables_Control *the_cond,
+ const pthread_condattr_t *the_attr
+)
+{
+ unsigned long flags;
+
+ _Thread_queue_Queue_initialize( &the_cond->Queue.Queue, NULL );
+ the_cond->mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX;
+
+ flags = (uintptr_t) the_cond ^ POSIX_CONDITION_VARIABLES_MAGIC;
+ flags &= ~POSIX_CONDITION_VARIABLES_FLAGS_MASK;
+
+ if ( the_attr->clock == CLOCK_MONOTONIC ) {
+ flags |= POSIX_CONDITION_VARIABLES_CLOCK_MONOTONIC;
+ }
+
+ the_cond->flags = flags;
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Condition_variables_Destroy(
+ POSIX_Condition_variables_Control *the_cond
+)
+{
+ the_cond->flags = ~the_cond->flags;
+}
+
+RTEMS_INLINE_ROUTINE clockid_t _POSIX_Condition_variables_Get_clock(
+ unsigned long flags
+)
+{
+ if ( ( flags & POSIX_CONDITION_VARIABLES_CLOCK_MONOTONIC ) != 0 ) {
+ return CLOCK_MONOTONIC;
+ }
+
+ return CLOCK_REALTIME;
+}
+
+RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Condition_variables_Acquire(
+ POSIX_Condition_variables_Control *the_cond,
+ Thread_queue_Context *queue_context
+)
+{
+ ISR_Level level;
+ Thread_Control *executing;
+
+ _Thread_queue_Context_ISR_disable( queue_context, level );
+ _Thread_queue_Context_set_ISR_level( queue_context, level );
+ executing = _Thread_Executing;
+ _Thread_queue_Queue_acquire_critical(
+ &the_cond->Queue.Queue,
+ &executing->Potpourri_stats,
+ &queue_context->Lock_context.Lock_context
+ );
+
+ return executing;
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Condition_variables_Release(
+ POSIX_Condition_variables_Control *the_cond,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Queue_release(
+ &the_cond->Queue.Queue,
+ &queue_context->Lock_context.Lock_context
+ );
+}
+
+/**
+ * @brief Implements wake up version of the "signal" operation.
+ *
+ * A support routine which implements guts of the broadcast and single task
+ * wake up version of the "signal" operation.
+ */
+int _POSIX_Condition_variables_Signal_support(
+ pthread_cond_t *cond,
+ bool is_broadcast
+);
+
+/**
+ * @brief POSIX condition variables wait support.
+ *
+ * A support routine which implements guts of the blocking, non-blocking, and
+ * timed wait version of condition variable wait routines.
+ */
+int _POSIX_Condition_variables_Wait_support(
+ pthread_cond_t *cond,
+ pthread_mutex_t *mutex,
+ const struct timespec *abstime
+);
+
+bool _POSIX_Condition_variables_Auto_initialization(
+ POSIX_Condition_variables_Control *the_cond
+);
+
+#define POSIX_CONDITION_VARIABLES_VALIDATE_OBJECT( the_cond, flags ) \
+ do { \
+ if ( ( the_cond ) == NULL ) { \
+ return EINVAL; \
+ } \
+ flags = ( the_cond )->flags; \
+ if ( \
+ ( ( (uintptr_t) ( the_cond ) ^ POSIX_CONDITION_VARIABLES_MAGIC ) \
+ & ~POSIX_CONDITION_VARIABLES_FLAGS_MASK ) \
+ != ( flags & ~POSIX_CONDITION_VARIABLES_FLAGS_MASK ) \
+ ) { \
+ if ( !_POSIX_Condition_variables_Auto_initialization( the_cond ) ) { \
+ return EINVAL; \
+ } \
+ } \
+ } while ( 0 )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/posix/config.h b/cpukit/include/rtems/posix/config.h
new file mode 100644
index 0000000000..e90dc27011
--- /dev/null
+++ b/cpukit/include/rtems/posix/config.h
@@ -0,0 +1,120 @@
+/**
+ * @file
+ *
+ * @brief User Defined Configuration Parameters Specific For The POSIX API
+ *
+ * This include file contains the table of user defined configuration
+ * parameters specific for the POSIX API.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_CONFIG_H
+#define _RTEMS_POSIX_CONFIG_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicConfig Configuration
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality related to the application's configuration
+ * of the Classic API including the maximum number of each class of objects.
+ */
+/**@{*/
+
+/**
+ * For now, we are only allowing the user to specify the entry point
+ * and stack size for POSIX initialization threads.
+ */
+typedef struct {
+ /** This is the entry point for a POSIX initialization thread. */
+ void *(*thread_entry)(void *);
+ /** This is the stack size for a POSIX initialization thread. */
+ int stack_size;
+} posix_initialization_threads_table;
+
+/**
+ * The following records define the POSIX Configuration Table.
+ * The information contained in this table is required in all
+ * RTEMS systems which include POSIX threads support, whether
+ * single or multiprocessor. This table primarily defines the
+ * following:
+ *
+ * + required number of each object type
+ */
+typedef struct {
+ /**
+ * This field contains the maximum number of POSIX API
+ * threads which are configured for this application.
+ */
+ uint32_t maximum_threads;
+
+ /**
+ * This field contains the maximum number of POSIX API
+ * timers which are configured for this application.
+ */
+ uint32_t maximum_timers;
+
+ /**
+ * This field contains the maximum number of POSIX API
+ * queued signals which are configured for this application.
+ */
+ uint32_t maximum_queued_signals;
+
+ /**
+ * This field contains the maximum number of POSIX API
+ * message queues which are configured for this application.
+ */
+ uint32_t maximum_message_queues;
+
+ /**
+ * This field contains the maximum number of POSIX API
+ * semaphores which are configured for this application.
+ */
+ uint32_t maximum_semaphores;
+
+ /**
+ * Maximum configured number of POSIX Shared memory objects.
+ */
+ uint32_t maximum_shms;
+
+ /**
+ * This field contains the number of POSIX API Initialization
+ * threads listed in @a User_initialization_thread_table.
+ */
+ uint32_t number_of_initialization_threads;
+
+ /**
+ * This field contains the list of POSIX API Initialization threads.
+ */
+ posix_initialization_threads_table *User_initialization_threads_table;
+} posix_api_configuration_table;
+
+/**
+ * @brief POSIX API configuration table.
+ *
+ * This is the POSIX API Configuration Table expected to be generated
+ * by confdefs.h.
+ */
+extern posix_api_configuration_table Configuration_POSIX_API;
+
+/**@}*/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/posix/key.h b/cpukit/include/rtems/posix/key.h
new file mode 100644
index 0000000000..1f09916f06
--- /dev/null
+++ b/cpukit/include/rtems/posix/key.h
@@ -0,0 +1,95 @@
+/**
+ * @file
+ *
+ * @brief POSIX Key Private Support
+ *
+ * This include file contains all the private support information for
+ * POSIX key.
+ */
+
+/*
+ * Copyright (c) 2012 Zhongwei Yao.
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright (c) 2016 embedded brains GmbH.
+ *
+ * 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_POSIX_KEY_H
+#define _RTEMS_POSIX_KEY_H
+
+#include <pthread.h>
+
+#include <rtems/score/chain.h>
+#include <rtems/score/object.h>
+#include <rtems/score/rbtree.h>
+#include <rtems/score/thread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup POSIX_KEY POSIX Key
+ *
+ * @ingroup POSIXAPI
+ *
+ */
+/**@{**/
+
+/**
+ * @brief Represents POSIX key and value pair.
+ */
+typedef struct {
+ /**
+ * @brief The chain node for the key value pairs chain in POSIX_Keys_Control.
+ */
+ Chain_Node Key_node;
+
+ /**
+ * @brief The tree node for the lookup tree in Thread_Keys_information.
+ */
+ RBTree_Node Lookup_node;
+
+ /**
+ * @brief The POSIX key identifier used as the tree key.
+ */
+ pthread_key_t key;
+
+ /**
+ * @brief The corresponding thread.
+ */
+ Thread_Control *thread;
+
+ /**
+ * @brief The thread specific POSIX key value.
+ */
+ void *value;
+} POSIX_Keys_Key_value_pair;
+
+/**
+ * @brief The data structure used to manage a POSIX key.
+ */
+typedef struct {
+ /** This field is the Object control structure. */
+ Objects_Control Object;
+ /** This field is the data destructor. */
+ void (*destructor) (void *);
+
+ /**
+ * @brief Key value pairs of this key.
+ */
+ Chain_Control Key_value_pairs;
+ } POSIX_Keys_Control;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/posix/keyimpl.h b/cpukit/include/rtems/posix/keyimpl.h
new file mode 100644
index 0000000000..1148123638
--- /dev/null
+++ b/cpukit/include/rtems/posix/keyimpl.h
@@ -0,0 +1,177 @@
+/**
+ * @file
+ *
+ * @brief Private Inlined Routines for POSIX Key's
+ *
+ * This include file contains the static inline implementation of the private
+ * inlined routines for POSIX key's.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright (c) 2016 embedded brains GmbH.
+ *
+ * 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.
+ */
+
+#include <rtems/posix/key.h>
+#include <rtems/score/chainimpl.h>
+#include <rtems/score/freechain.h>
+#include <rtems/score/objectimpl.h>
+#include <rtems/score/percpu.h>
+
+#ifndef _RTEMS_POSIX_KEYIMPL_H
+#define _RTEMS_POSIX_KEYIMPL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup POSIX_KEY
+ *
+ * @{
+ */
+
+/**
+ * @brief The information control block used to manage this class of objects.
+ */
+extern Objects_Information _POSIX_Keys_Information;
+
+/**
+ * @brief This freechain is used as a memory pool for POSIX_Keys_Key_value_pair.
+ */
+extern Freechain_Control _POSIX_Keys_Keypool;
+
+#define POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( node ) \
+ RTEMS_CONTAINER_OF( node, POSIX_Keys_Key_value_pair, Lookup_node )
+
+/**
+ * @brief Allocate a keys control block.
+ *
+ * This function allocates a keys control block from
+ * the inactive chain of free keys control blocks.
+ */
+
+RTEMS_INLINE_ROUTINE POSIX_Keys_Control *_POSIX_Keys_Allocate( void )
+{
+ return (POSIX_Keys_Control *) _Objects_Allocate( &_POSIX_Keys_Information );
+}
+
+/**
+ * @brief Free a keys control block.
+ *
+ * This routine frees a keys control block to the
+ * inactive chain of free keys control blocks.
+ */
+RTEMS_INLINE_ROUTINE void _POSIX_Keys_Free(
+ POSIX_Keys_Control *the_key
+)
+{
+ _Objects_Free( &_POSIX_Keys_Information, &the_key->Object );
+}
+
+RTEMS_INLINE_ROUTINE POSIX_Keys_Control *_POSIX_Keys_Get( pthread_key_t key )
+{
+ return (POSIX_Keys_Control *)
+ _Objects_Get_no_protection( (Objects_Id) key, &_POSIX_Keys_Information );
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Keys_Key_value_acquire(
+ Thread_Control *the_thread,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_ISR_disable_and_acquire( &the_thread->Keys.Lock, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Keys_Key_value_release(
+ Thread_Control *the_thread,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Release_and_ISR_enable( &the_thread->Keys.Lock, lock_context );
+}
+
+POSIX_Keys_Key_value_pair * _POSIX_Keys_Key_value_allocate( void );
+
+RTEMS_INLINE_ROUTINE void _POSIX_Keys_Key_value_free(
+ POSIX_Keys_Key_value_pair *key_value_pair
+)
+{
+ _Chain_Extract_unprotected( &key_value_pair->Key_node );
+ _Freechain_Put( &_POSIX_Keys_Keypool, key_value_pair );
+}
+
+RTEMS_INLINE_ROUTINE bool _POSIX_Keys_Key_value_equal(
+ const void *left,
+ const RBTree_Node *right
+)
+{
+ const pthread_key_t *the_left;
+ const POSIX_Keys_Key_value_pair *the_right;
+
+ the_left = left;
+ the_right = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( right );
+
+ return *the_left == the_right->key;
+}
+
+RTEMS_INLINE_ROUTINE bool _POSIX_Keys_Key_value_less(
+ const void *left,
+ const RBTree_Node *right
+)
+{
+ const pthread_key_t *the_left;
+ const POSIX_Keys_Key_value_pair *the_right;
+
+ the_left = left;
+ the_right = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( right );
+
+ return *the_left < the_right->key;
+}
+
+RTEMS_INLINE_ROUTINE void *_POSIX_Keys_Key_value_map( RBTree_Node *node )
+{
+ return POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( node );
+}
+
+RTEMS_INLINE_ROUTINE POSIX_Keys_Key_value_pair *_POSIX_Keys_Key_value_find(
+ pthread_key_t key,
+ const Thread_Control *the_thread
+)
+{
+ return _RBTree_Find_inline(
+ &the_thread->Keys.Key_value_pairs,
+ &key,
+ _POSIX_Keys_Key_value_equal,
+ _POSIX_Keys_Key_value_less,
+ _POSIX_Keys_Key_value_map
+ );
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Keys_Key_value_insert(
+ pthread_key_t key,
+ POSIX_Keys_Key_value_pair *key_value_pair,
+ Thread_Control *the_thread
+)
+{
+ _RBTree_Insert_inline(
+ &the_thread->Keys.Key_value_pairs,
+ &key_value_pair->Lookup_node,
+ &key,
+ _POSIX_Keys_Key_value_less
+ );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/posix/mmanimpl.h b/cpukit/include/rtems/posix/mmanimpl.h
new file mode 100644
index 0000000000..e1cc672331
--- /dev/null
+++ b/cpukit/include/rtems/posix/mmanimpl.h
@@ -0,0 +1,56 @@
+/**
+ * @file
+ *
+ * @brief Internal Support for POSIX 1003.1b 6.3.1 - map pages of memory
+ *
+ */
+
+/*
+ * Copyright (c) 2012 Chris Johns
+ *
+ * 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_POSIX_MMANIMPL_H
+#define _RTEMS_POSIX_MMANIMPL_H
+
+#include <rtems/libio_.h>
+#include <rtems/chain.h> /* FIXME: use score chains for proper layering? */
+#include <rtems/posix/shm.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* FIXME: add Doxygen */
+
+/**
+ * Every mmap'ed region has a mapping.
+ */
+typedef struct mmap_mappings_s {
+ rtems_chain_node node; /**< The mapping chain's node */
+ void* addr; /**< The address of the mapped memory */
+ size_t len; /**< The length of memory mapped */
+ int flags; /**< The mapping flags */
+ POSIX_Shm_Control *shm; /**< The shared memory object or NULL */
+} mmap_mapping;
+
+extern rtems_chain_control mmap_mappings;
+
+static inline void mmap_mappings_lock_obtain( void )
+{
+ rtems_libio_lock();
+}
+
+static inline void mmap_mappings_lock_release( void )
+{
+ rtems_libio_unlock();
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/posix/mqueue.h b/cpukit/include/rtems/posix/mqueue.h
new file mode 100644
index 0000000000..cdf94514af
--- /dev/null
+++ b/cpukit/include/rtems/posix/mqueue.h
@@ -0,0 +1,71 @@
+/**
+ * @file
+ *
+ * @brief POSIX Message Queues Private Private Support
+ *
+ * This include file contains all the private support information for
+ * POSIX Message Queues.
+ *
+ * The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open
+ * time.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_MQUEUE_H
+#define _RTEMS_POSIX_MQUEUE_H
+
+#include <signal.h>
+#include <mqueue.h> /* struct mq_attr */
+#include <rtems/score/coremsg.h>
+#include <rtems/score/object.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup POSIX_MQUEUE_P Message Queues Private Support
+ *
+ * @ingroup POSIXAPI
+ *
+ */
+/**@{**/
+
+/*
+ * Data Structure used to manage a POSIX message queue
+ */
+
+typedef struct {
+ Objects_Control Object;
+ CORE_message_queue_Control Message_queue;
+ bool linked;
+ uint32_t open_count;
+ struct sigevent notification;
+ int oflag;
+} POSIX_Message_queue_Control;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/posix/mqueueimpl.h b/cpukit/include/rtems/posix/mqueueimpl.h
new file mode 100644
index 0000000000..6813a3ef88
--- /dev/null
+++ b/cpukit/include/rtems/posix/mqueueimpl.h
@@ -0,0 +1,183 @@
+/**
+ * @file
+ *
+ * @brief Private Inlined Routines for POSIX Message Queue
+ *
+ * This include file contains the static inline implementation of the private
+ * inlined routines for POSIX Message Queue.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_MQUEUE_INL
+#define _RTEMS_POSIX_MQUEUE_INL
+
+#include <rtems/posix/mqueue.h>
+#include <rtems/posix/posixapi.h>
+#include <rtems/score/coremsgimpl.h>
+#include <rtems/score/threadqimpl.h>
+
+#include <rtems/seterr.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This defines the information control block used to manage
+ * this class of objects.
+ */
+extern Objects_Information _POSIX_Message_queue_Information;
+
+/**
+ * @brief Delete a POSIX Message Queue
+ *
+ * This routine supports the mq_unlink and mq_close routines by
+ * doing most of the work involved with removing a message queue.
+ */
+void _POSIX_Message_queue_Delete(
+ POSIX_Message_queue_Control *the_mq,
+ Thread_queue_Context *queue_context
+);
+
+/*@
+ * @brief POSIX Message Queue Receive Support
+ *
+ * This routine supports the various flavors of receiving a message.
+ *
+ * @note The structure of the routines is identical to that of POSIX
+ * Message_queues to leave the option of having unnamed message
+ * queues at a future date. They are currently not part of the
+ * POSIX standard but unnamed message_queues are. This is also
+ * the reason for the apparently unnecessary tracking of
+ * the process_shared attribute. [In addition to the fact that
+ * it would be trivial to add pshared to the mq_attr structure
+ * and have process private message queues.]
+ *
+ * @note This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open time.
+ */
+ssize_t _POSIX_Message_queue_Receive_support(
+ mqd_t mqdes,
+ char *msg_ptr,
+ size_t msg_len,
+ unsigned int *msg_prio,
+ const struct timespec *abstime,
+ Thread_queue_Enqueue_callout enqueue_callout
+);
+
+/**
+ * @brief POSIX Message Queue Send Support
+ *
+ * This routine posts a message to a specified message queue.
+ */
+int _POSIX_Message_queue_Send_support(
+ mqd_t mqdes,
+ const char *msg_ptr,
+ size_t msg_len,
+ unsigned int msg_prio,
+ const struct timespec *abstime,
+ Thread_queue_Enqueue_callout enqueue_callout
+);
+
+RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control *
+ _POSIX_Message_queue_Allocate_unprotected( void )
+{
+ return (POSIX_Message_queue_Control *)
+ _Objects_Allocate_unprotected( &_POSIX_Message_queue_Information );
+}
+
+/**
+ * @brief POSIX Message Queue Free
+ *
+ * This routine frees a message queue control block to the
+ * inactive chain of free message queue control blocks.
+ */
+RTEMS_INLINE_ROUTINE void _POSIX_Message_queue_Free(
+ POSIX_Message_queue_Control *the_mq
+)
+{
+ _Objects_Free( &_POSIX_Message_queue_Information, &the_mq->Object );
+}
+
+
+RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control *_POSIX_Message_queue_Get(
+ Objects_Id id,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Context_initialize( queue_context );
+ return (POSIX_Message_queue_Control *) _Objects_Get(
+ id,
+ &queue_context->Lock_context.Lock_context,
+ &_POSIX_Message_queue_Information
+ );
+}
+
+/*
+ * @brief POSIX Message Queue Convert Message Priority to Score
+ *
+ * This method converts a POSIX message priority to the priorities used
+ * by the Score.
+ */
+RTEMS_INLINE_ROUTINE CORE_message_queue_Submit_types
+ _POSIX_Message_queue_Priority_to_core(
+ unsigned int priority
+)
+{
+ return (CORE_message_queue_Submit_types) priority * -1;
+}
+
+
+/*
+ * @brief POSIX Message Queue Convert Message Priority from Score
+ *
+ * This method converts a POSIX message priority from the priorities used
+ * by the Score.
+ */
+RTEMS_INLINE_ROUTINE unsigned int _POSIX_Message_queue_Priority_from_core(
+ CORE_message_queue_Submit_types priority
+)
+{
+ /* absolute value without a library dependency */
+ return (unsigned int) ((priority >= 0) ? priority : -priority);
+}
+
+/**
+ * @brief POSIX Message Queue Remove from Namespace
+ */
+RTEMS_INLINE_ROUTINE void _POSIX_Message_queue_Namespace_remove (
+ POSIX_Message_queue_Control *the_mq
+)
+{
+ _Objects_Namespace_remove(
+ &_POSIX_Message_queue_Information, &the_mq->Object );
+}
+
+RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control *
+_POSIX_Message_queue_Get_by_name(
+ const char *name,
+ size_t *name_length_p,
+ Objects_Get_by_name_error *error
+)
+{
+ return (POSIX_Message_queue_Control *) _Objects_Get_by_name(
+ &_POSIX_Message_queue_Information,
+ name,
+ name_length_p,
+ error
+ );
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/posix/muteximpl.h b/cpukit/include/rtems/posix/muteximpl.h
new file mode 100644
index 0000000000..435b43634d
--- /dev/null
+++ b/cpukit/include/rtems/posix/muteximpl.h
@@ -0,0 +1,487 @@
+/**
+ * @file
+ *
+ * @brief Private Inlined Routines for POSIX Mutex's.
+ *
+ * This include file contains the static inline implementation of the private
+ * inlined routines for POSIX mutex's.
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_MUTEXIMPL_H
+#define _RTEMS_POSIX_MUTEXIMPL_H
+
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/score/percpu.h>
+#include <rtems/score/muteximpl.h>
+#include <rtems/score/threadimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ unsigned long flags;
+ Mutex_recursive_Control Recursive;
+ Priority_Node Priority_ceiling;
+ const Scheduler_Control *scheduler;
+} POSIX_Mutex_Control;
+
+#define POSIX_MUTEX_PROTOCOL_MASK 0x3UL
+
+#define POSIX_MUTEX_RECURSIVE 0x4UL
+
+#define POSIX_MUTEX_FLAGS_MASK 0x7UL
+
+#define POSIX_MUTEX_MAGIC 0x961c13b8UL
+
+#define POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
+
+#define POSIX_MUTEX_PRIORITY_INHERIT_TQ_OPERATIONS \
+ &_Thread_queue_Operations_priority_inherit
+
+#define POSIX_MUTEX_PRIORITY_CEILING_TQ_OPERATIONS \
+ &_Thread_queue_Operations_priority
+
+/**
+ * @brief Supported POSIX mutex protocols.
+ *
+ * Must be in synchronization with POSIX_Mutex_Control::protocol.
+ */
+typedef enum {
+ POSIX_MUTEX_NO_PROTOCOL,
+ POSIX_MUTEX_PRIORITY_INHERIT,
+ POSIX_MUTEX_PRIORITY_CEILING
+} POSIX_Mutex_Protocol;
+
+/**
+ * The default mutex attributes structure.
+ */
+extern const pthread_mutexattr_t _POSIX_Mutex_Default_attributes;
+
+RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Mutex_Acquire(
+ POSIX_Mutex_Control *the_mutex,
+ Thread_queue_Context *queue_context
+)
+{
+ ISR_Level level;
+ Thread_Control *executing;
+
+ _Thread_queue_Context_initialize( queue_context );
+ _Thread_queue_Context_ISR_disable( queue_context, level );
+ _Thread_queue_Context_set_ISR_level( queue_context, level );
+ executing = _Thread_Executing;
+ _Thread_queue_Queue_acquire_critical(
+ &the_mutex->Recursive.Mutex.Queue.Queue,
+ &executing->Potpourri_stats,
+ &queue_context->Lock_context.Lock_context
+ );
+
+ return executing;
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Release(
+ POSIX_Mutex_Control *the_mutex,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Queue_release(
+ &the_mutex->Recursive.Mutex.Queue.Queue,
+ &queue_context->Lock_context.Lock_context
+ );
+}
+
+RTEMS_INLINE_ROUTINE POSIX_Mutex_Protocol _POSIX_Mutex_Get_protocol(
+ unsigned long flags
+)
+{
+ return flags & POSIX_MUTEX_PROTOCOL_MASK;
+}
+
+RTEMS_INLINE_ROUTINE bool _POSIX_Mutex_Is_recursive(
+ unsigned long flags
+)
+{
+ return ( flags & POSIX_MUTEX_RECURSIVE ) != 0;
+}
+
+RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Mutex_Get_owner(
+ const POSIX_Mutex_Control *the_mutex
+)
+{
+ return the_mutex->Recursive.Mutex.Queue.Queue.owner;
+}
+
+RTEMS_INLINE_ROUTINE bool _POSIX_Mutex_Is_locked(
+ const POSIX_Mutex_Control *the_mutex
+)
+{
+ return _POSIX_Mutex_Get_owner( the_mutex ) != NULL;
+}
+
+Status_Control _POSIX_Mutex_Seize_slow(
+ POSIX_Mutex_Control *the_mutex,
+ const Thread_queue_Operations *operations,
+ Thread_Control *executing,
+ const struct timespec *abstime,
+ Thread_queue_Context *queue_context
+);
+
+RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Set_owner(
+ POSIX_Mutex_Control *the_mutex,
+ Thread_Control *owner
+)
+{
+ the_mutex->Recursive.Mutex.Queue.Queue.owner = owner;
+}
+
+RTEMS_INLINE_ROUTINE bool _POSIX_Mutex_Is_owner(
+ const POSIX_Mutex_Control *the_mutex,
+ const Thread_Control *the_thread
+)
+{
+ return _POSIX_Mutex_Get_owner( the_mutex ) == the_thread;
+}
+
+static Status_Control _POSIX_Mutex_Lock_nested(
+ POSIX_Mutex_Control *the_mutex,
+ unsigned long flags
+)
+{
+
+ if ( _POSIX_Mutex_Is_recursive( flags ) ) {
+ ++the_mutex->Recursive.nest_level;
+ return STATUS_SUCCESSFUL;
+ } else {
+ return STATUS_NESTING_NOT_ALLOWED;
+ }
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Seize(
+ POSIX_Mutex_Control *the_mutex,
+ unsigned long flags,
+ const Thread_queue_Operations *operations,
+ Thread_Control *executing,
+ const struct timespec *abstime,
+ Thread_queue_Context *queue_context
+)
+{
+ Thread_Control *owner;
+
+ owner = _POSIX_Mutex_Get_owner( the_mutex );
+
+ if ( owner == NULL ) {
+ _POSIX_Mutex_Set_owner( the_mutex, executing );
+ _Thread_Resource_count_increment( executing );
+ _POSIX_Mutex_Release( the_mutex, queue_context );
+ return STATUS_SUCCESSFUL;
+ }
+
+ if ( owner == executing ) {
+ Status_Control status;
+
+ status = _POSIX_Mutex_Lock_nested( the_mutex, flags );
+ _POSIX_Mutex_Release( the_mutex, queue_context );
+ return status;
+ }
+
+ return _POSIX_Mutex_Seize_slow(
+ the_mutex,
+ operations,
+ executing,
+ abstime,
+ queue_context
+ );
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Surrender(
+ POSIX_Mutex_Control *the_mutex,
+ const Thread_queue_Operations *operations,
+ Thread_Control *executing,
+ Thread_queue_Context *queue_context
+)
+{
+ unsigned int nest_level;
+ Thread_queue_Heads *heads;
+
+ if ( !_POSIX_Mutex_Is_owner( the_mutex, executing ) ) {
+ _POSIX_Mutex_Release( the_mutex, queue_context );
+ return STATUS_NOT_OWNER;
+ }
+
+ nest_level = the_mutex->Recursive.nest_level;
+
+ if ( nest_level > 0 ) {
+ the_mutex->Recursive.nest_level = nest_level - 1;
+ _POSIX_Mutex_Release( the_mutex, queue_context );
+ return STATUS_SUCCESSFUL;
+ }
+
+ _Thread_Resource_count_decrement( executing );
+ _POSIX_Mutex_Set_owner( the_mutex, NULL );
+
+ heads = the_mutex->Recursive.Mutex.Queue.Queue.heads;
+
+ if ( heads == NULL ) {
+ _POSIX_Mutex_Release( the_mutex, queue_context );
+ return STATUS_SUCCESSFUL;
+ }
+
+ _Thread_queue_Surrender(
+ &the_mutex->Recursive.Mutex.Queue.Queue,
+ heads,
+ executing,
+ queue_context,
+ operations
+ );
+ return STATUS_SUCCESSFUL;
+}
+
+RTEMS_INLINE_ROUTINE const Scheduler_Control *_POSIX_Mutex_Get_scheduler(
+ const POSIX_Mutex_Control *the_mutex
+)
+{
+#if defined(RTEMS_SMP)
+ return the_mutex->scheduler;
+#else
+ return &_Scheduler_Table[ 0 ];
+#endif
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Set_priority(
+ POSIX_Mutex_Control *the_mutex,
+ Priority_Control priority_ceiling,
+ Thread_queue_Context *queue_context
+)
+{
+ Thread_Control *owner;
+
+ owner = _POSIX_Mutex_Get_owner( the_mutex );
+
+ if ( owner != NULL ) {
+ _Thread_Wait_acquire( owner, queue_context );
+ _Thread_Priority_change(
+ owner,
+ &the_mutex->Priority_ceiling,
+ priority_ceiling,
+ false,
+ queue_context
+ );
+ _Thread_Wait_release( owner, queue_context );
+ } else {
+ the_mutex->Priority_ceiling.priority = priority_ceiling;
+ }
+}
+
+RTEMS_INLINE_ROUTINE Priority_Control _POSIX_Mutex_Get_priority(
+ const POSIX_Mutex_Control *the_mutex
+)
+{
+ return the_mutex->Priority_ceiling.priority;
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Ceiling_set_owner(
+ POSIX_Mutex_Control *the_mutex,
+ Thread_Control *owner,
+ Thread_queue_Context *queue_context
+)
+{
+ ISR_lock_Context lock_context;
+ Scheduler_Node *scheduler_node;
+ Per_CPU_Control *cpu_self;
+
+ _Thread_Wait_acquire_default_critical( owner, &lock_context );
+
+ scheduler_node = _Thread_Scheduler_get_home_node( owner );
+
+ if (
+ _Priority_Get_priority( &scheduler_node->Wait.Priority )
+ < the_mutex->Priority_ceiling.priority
+ ) {
+ _Thread_Wait_release_default_critical( owner, &lock_context );
+ _POSIX_Mutex_Release( the_mutex, queue_context );
+ return STATUS_MUTEX_CEILING_VIOLATED;
+ }
+
+ _POSIX_Mutex_Set_owner( the_mutex, owner );
+ _Thread_Resource_count_increment( owner );
+ _Thread_Priority_add(
+ owner,
+ &the_mutex->Priority_ceiling,
+ queue_context
+ );
+ _Thread_Wait_release_default_critical( owner, &lock_context );
+
+ cpu_self = _Thread_queue_Dispatch_disable( queue_context );
+ _POSIX_Mutex_Release( the_mutex, queue_context );
+ _Thread_Priority_update( queue_context );
+ _Thread_Dispatch_enable( cpu_self );
+ return STATUS_SUCCESSFUL;
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Ceiling_seize(
+ POSIX_Mutex_Control *the_mutex,
+ unsigned long flags,
+ Thread_Control *executing,
+ const struct timespec *abstime,
+ Thread_queue_Context *queue_context
+)
+{
+ Thread_Control *owner;
+
+ owner = _POSIX_Mutex_Get_owner( the_mutex );
+
+ if ( owner == NULL ) {
+#if defined(RTEMS_SMP)
+ if (
+ _Thread_Scheduler_get_home( executing )
+ != _POSIX_Mutex_Get_scheduler( the_mutex )
+ ) {
+ _POSIX_Mutex_Release( the_mutex, queue_context );
+ return STATUS_NOT_DEFINED;
+ }
+#endif
+
+ _Thread_queue_Context_clear_priority_updates( queue_context );
+ return _POSIX_Mutex_Ceiling_set_owner(
+ the_mutex,
+ executing,
+ queue_context
+ );
+ }
+
+ if ( owner == executing ) {
+ Status_Control status;
+
+ status = _POSIX_Mutex_Lock_nested( the_mutex, flags );
+ _POSIX_Mutex_Release( the_mutex, queue_context );
+ return status;
+ }
+
+ return _POSIX_Mutex_Seize_slow(
+ the_mutex,
+ POSIX_MUTEX_PRIORITY_CEILING_TQ_OPERATIONS,
+ executing,
+ abstime,
+ queue_context
+ );
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Ceiling_surrender(
+ POSIX_Mutex_Control *the_mutex,
+ Thread_Control *executing,
+ Thread_queue_Context *queue_context
+)
+{
+ unsigned int nest_level;
+ ISR_lock_Context lock_context;
+ Per_CPU_Control *cpu_self;
+ Thread_queue_Heads *heads;
+
+ if ( !_POSIX_Mutex_Is_owner( the_mutex, executing ) ) {
+ _POSIX_Mutex_Release( the_mutex, queue_context );
+ return STATUS_NOT_OWNER;
+ }
+
+ nest_level = the_mutex->Recursive.nest_level;
+
+ if ( nest_level > 0 ) {
+ the_mutex->Recursive.nest_level = nest_level - 1;
+ _POSIX_Mutex_Release( the_mutex, queue_context );
+ return STATUS_SUCCESSFUL;
+ }
+
+ _Thread_Resource_count_decrement( executing );
+
+ _Thread_queue_Context_clear_priority_updates( queue_context );
+ _Thread_Wait_acquire_default_critical( executing, &lock_context );
+ _Thread_Priority_remove(
+ executing,
+ &the_mutex->Priority_ceiling,
+ queue_context
+ );
+ _Thread_Wait_release_default_critical( executing, &lock_context );
+
+ cpu_self = _Thread_queue_Dispatch_disable( queue_context );
+
+ heads = the_mutex->Recursive.Mutex.Queue.Queue.heads;
+
+ if ( heads != NULL ) {
+ const Thread_queue_Operations *operations;
+ Thread_Control *new_owner;
+
+ operations = POSIX_MUTEX_PRIORITY_CEILING_TQ_OPERATIONS;
+ new_owner = ( *operations->first )( heads );
+ _POSIX_Mutex_Set_owner( the_mutex, new_owner );
+ _Thread_Resource_count_increment( new_owner );
+ _Thread_Priority_add(
+ new_owner,
+ &the_mutex->Priority_ceiling,
+ queue_context
+ );
+ _Thread_queue_Extract_critical(
+ &the_mutex->Recursive.Mutex.Queue.Queue,
+ operations,
+ new_owner,
+ queue_context
+ );
+ } else {
+ _POSIX_Mutex_Set_owner( the_mutex, NULL );
+ _POSIX_Mutex_Release( the_mutex, queue_context );
+ }
+
+ _Thread_Priority_update( queue_context );
+ _Thread_Dispatch_enable( cpu_self );
+ return STATUS_SUCCESSFUL;
+}
+
+#define POSIX_MUTEX_ABSTIME_TRY_LOCK ((uintptr_t) 1)
+
+int _POSIX_Mutex_Lock_support(
+ pthread_mutex_t *mutex,
+ const struct timespec *abstime,
+ Thread_queue_Enqueue_callout enqueue_callout
+);
+
+static inline POSIX_Mutex_Control *_POSIX_Mutex_Get(
+ pthread_mutex_t *mutex
+)
+{
+ return (POSIX_Mutex_Control *) mutex;
+}
+
+bool _POSIX_Mutex_Auto_initialization( POSIX_Mutex_Control *the_mutex );
+
+#define POSIX_MUTEX_VALIDATE_OBJECT( the_mutex, flags ) \
+ do { \
+ if ( ( the_mutex ) == NULL ) { \
+ return EINVAL; \
+ } \
+ flags = ( the_mutex )->flags; \
+ if ( \
+ ( ( (uintptr_t) ( the_mutex ) ^ POSIX_MUTEX_MAGIC ) \
+ & ~POSIX_MUTEX_FLAGS_MASK ) \
+ != ( flags & ~POSIX_MUTEX_FLAGS_MASK ) \
+ ) { \
+ if ( !_POSIX_Mutex_Auto_initialization( the_mutex ) ) { \
+ return EINVAL; \
+ } \
+ } \
+ } while ( 0 )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
+
diff --git a/cpukit/include/rtems/posix/posixapi.h b/cpukit/include/rtems/posix/posixapi.h
new file mode 100644
index 0000000000..29394ab94e
--- /dev/null
+++ b/cpukit/include/rtems/posix/posixapi.h
@@ -0,0 +1,146 @@
+/**
+ * @file
+ *
+ * @brief POSIX API Implementation
+ *
+ * This include file defines the top level interface to the POSIX API
+ * implementation in RTEMS.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_POSIXAPI_H
+#define _RTEMS_POSIX_POSIXAPI_H
+
+#include <rtems/config.h>
+#include <rtems/score/assert.h>
+#include <rtems/score/objectimpl.h>
+#include <rtems/score/onceimpl.h>
+#include <rtems/score/threadimpl.h>
+#include <rtems/seterr.h>
+
+#include <pthread.h>
+
+/**
+ * @defgroup POSIXAPI RTEMS POSIX API
+ *
+ * RTEMS POSIX API definitions and modules.
+ *
+ */
+/**@{**/
+
+/**
+ * @brief POSIX API Fatal domains.
+ */
+typedef enum {
+ POSIX_FD_PTHREAD, /**< A pthread thread error. */
+ POSIX_FD_PTHREAD_ONCE /**< A pthread once error. */
+} POSIX_Fatal_domain;
+
+/**
+ * @brief POSIX API Fatal error.
+ *
+ * A common method of rasing a POSIX API fatal error.
+ *
+ * @param[in] domain The POSIX error domain.
+ * @param[in] eno The error number as defined in errno.h.
+ */
+void _POSIX_Fatal_error( POSIX_Fatal_domain domain, int eno );
+
+extern const int _POSIX_Get_by_name_error_table[ 3 ];
+
+RTEMS_INLINE_ROUTINE int _POSIX_Get_by_name_error(
+ Objects_Get_by_name_error error
+)
+{
+ _Assert( (size_t) error < RTEMS_ARRAY_SIZE( _POSIX_Get_by_name_error_table ) );
+ return _POSIX_Get_by_name_error_table[ error ];
+}
+
+RTEMS_INLINE_ROUTINE int _POSIX_Get_error( Status_Control status )
+{
+ return STATUS_GET_POSIX( status );
+}
+
+RTEMS_INLINE_ROUTINE int _POSIX_Get_error_after_wait(
+ const Thread_Control *executing
+)
+{
+ return _POSIX_Get_error( _Thread_Wait_get_status( executing ) );
+}
+
+RTEMS_INLINE_ROUTINE int _POSIX_Zero_or_minus_one_plus_errno(
+ Status_Control status
+)
+{
+ if ( status == STATUS_SUCCESSFUL ) {
+ return 0;
+ }
+
+ rtems_set_errno_and_return_minus_one( _POSIX_Get_error( status ) );
+}
+
+/**
+ * @brief Macro to generate a function body to get a POSIX object by
+ * identifier.
+ *
+ * Generates a function body to get the object for the specified identifier.
+ * Performs automatic initialization if requested and necessary. This is an
+ * ugly macro, since C lacks support for templates.
+ */
+#define _POSIX_Get_object_body( \
+ type, \
+ id, \
+ queue_context, \
+ info, \
+ initializer, \
+ init \
+) \
+ Objects_Control *the_object; \
+ if ( id == NULL ) { \
+ return NULL; \
+ } \
+ _Thread_queue_Context_initialize( queue_context ); \
+ the_object = _Objects_Get( \
+ (Objects_Id) *id, \
+ &queue_context->Lock_context.Lock_context, \
+ info \
+ ); \
+ if ( the_object == NULL ) { \
+ _Once_Lock(); \
+ if ( *id == initializer ) { \
+ init( id, NULL ); \
+ } \
+ _Once_Unlock(); \
+ the_object = _Objects_Get( \
+ (Objects_Id) *id, \
+ &queue_context->Lock_context.Lock_context, \
+ info \
+ ); \
+ } \
+ return (type *) the_object
+
+/*
+ * See also The Open Group Base Specifications Issue 7, IEEE Std 1003.1-2008,
+ * 2016 Edition, subsection 2.9.9, Synchronization Object Copies and
+ * Alternative Mappings.
+ *
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_09
+ */
+RTEMS_INLINE_ROUTINE bool _POSIX_Is_valid_pshared( int pshared )
+{
+ return pshared == PTHREAD_PROCESS_PRIVATE ||
+ pshared == PTHREAD_PROCESS_SHARED;
+}
+
+/** @} */
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/posix/priorityimpl.h b/cpukit/include/rtems/posix/priorityimpl.h
new file mode 100644
index 0000000000..eb2e3e059f
--- /dev/null
+++ b/cpukit/include/rtems/posix/priorityimpl.h
@@ -0,0 +1,109 @@
+/**
+ * @file
+ *
+ * @brief POSIX Priority Support
+ *
+ * This include file defines the interface to the POSIX priority
+ * implementation.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_PRIORITYIMPL_H
+#define _RTEMS_POSIX_PRIORITYIMPL_H
+
+#include <rtems/score/scheduler.h>
+#include <rtems/score/assert.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup POSIX_PRIORITY POSIX Priority Support
+ *
+ * @ingroup POSIXAPI
+ *
+ * @brief Interface to the POSIX Priority Implementation.
+ *
+ * @{
+ */
+
+/**
+ * This is the numerically least important POSIX priority.
+ */
+#define POSIX_SCHEDULER_MINIMUM_PRIORITY (1)
+
+/**
+ * @brief Gets the maximum POSIX API priority for this scheduler instance.
+ *
+ * Such a priority is valid. A scheduler instance may support priority values
+ * that are not representable as an integer.
+ *
+ * @return The maximum POSIX API priority for this scheduler instance.
+ */
+RTEMS_INLINE_ROUTINE int _POSIX_Priority_Get_maximum(
+ const Scheduler_Control *scheduler
+)
+{
+ _Assert( (int) scheduler->maximum_priority > 1 );
+ return (int) scheduler->maximum_priority - 1;
+}
+
+/**
+ * @brief Converts the POSIX API priority to the corresponding SuperCore
+ * priority and validates it.
+ *
+ * According to POSIX, numerically higher values represent higher priorities.
+ * Thus, SuperCore has priorities run in the opposite sense of the POSIX API.
+ *
+ * Let N be the maximum priority of this scheduler instance. The SuperCore
+ * priority zero is system reserved (PRIORITY_PSEUDO_ISR). There are only
+ * N - 1 POSIX API priority levels since a thread at SuperCore priority N would
+ * never run because of the idle threads. This is necessary because GNAT maps
+ * the lowest Ada task priority to the lowest thread priority. The lowest
+ * priority Ada task should get to run, so there is a fundamental conflict with
+ * having N priorities.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] priority The POSIX API priority to convert and validate.
+ * @param[out] valid Indicates if the POSIX API priority is valid and a
+ * corresponding SuperCore priority in the specified scheduler instance
+ * exists.
+ *
+ * @return The corresponding SuperCore priority.
+ */
+Priority_Control _POSIX_Priority_To_core(
+ const Scheduler_Control *scheduler,
+ int priority,
+ bool *valid
+);
+
+/**
+ * @brief Converts the SuperCore priority to the corresponding POSIX API
+ * priority.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] priority The SuperCore priority to convert.
+ *
+ * @return The corresponding POSIX API priority.
+ */
+int _POSIX_Priority_From_core(
+ const Scheduler_Control *scheduler,
+ Priority_Control priority
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/posix/psignal.h b/cpukit/include/rtems/posix/psignal.h
new file mode 100644
index 0000000000..ed98442e32
--- /dev/null
+++ b/cpukit/include/rtems/posix/psignal.h
@@ -0,0 +1,35 @@
+/**
+ * @file
+ *
+ * @brief Internal Information about POSIX Signals
+ *
+ * This include file defines internal information about POSIX signals.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_PSIGNAL_H
+#define _RTEMS_POSIX_PSIGNAL_H
+
+#include <sys/signal.h>
+
+#include <rtems/score/chain.h>
+
+/*
+ * POSIX internal siginfo structure
+ */
+
+typedef struct {
+ Chain_Node Node;
+ siginfo_t Info;
+} POSIX_signals_Siginfo_node;
+
+#endif
+/* end of file */
diff --git a/cpukit/include/rtems/posix/psignalimpl.h b/cpukit/include/rtems/posix/psignalimpl.h
new file mode 100644
index 0000000000..cccc3dafc9
--- /dev/null
+++ b/cpukit/include/rtems/posix/psignalimpl.h
@@ -0,0 +1,140 @@
+/**
+ * @file
+ *
+ * @brief POSIX Signals Support
+ *
+ * This include file defines internal information about POSIX signals.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_PSIGNALIMPL_H
+#define _RTEMS_POSIX_PSIGNALIMPL_H
+
+/**
+ * @defgroup POSIX_SIGNALS POSIX Signals Support
+ *
+ * @ingroup POSIXAPI
+ *
+ * @brief Internal Information about POSIX Signals
+ *
+ */
+/**@{**/
+
+#include <rtems/posix/psignal.h>
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/sigset.h>
+#include <rtems/score/isrlock.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/threadqimpl.h>
+
+#define POSIX_SIGNALS_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
+
+#define _States_Is_interruptible_signal( _states ) \
+ ( ((_states) & \
+ (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) == \
+ (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL))
+
+#define SIGACTION_TERMINATE \
+ { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Abnormal_termination_handler} }
+#define SIGACTION_IGNORE \
+ { 0, SIGNAL_ALL_MASK, {SIG_IGN} }
+#define SIGACTION_STOP \
+ { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Stop_handler} }
+#define SIGACTION_CONTINUE \
+ { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Continue_handler} }
+
+#define SIG_ARRAY_MAX (SIGRTMAX + 1)
+
+/*
+ * Variables
+ */
+
+extern sigset_t _POSIX_signals_Pending;
+
+extern const struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ];
+
+extern struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ];
+
+extern Thread_queue_Control _POSIX_signals_Wait_queue;
+
+extern Chain_Control _POSIX_signals_Inactive_siginfo;
+
+extern Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ];
+
+/*
+ * Internal routines
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_signals_Acquire(
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Acquire( &_POSIX_signals_Wait_queue, queue_context );
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_signals_Release(
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Release( &_POSIX_signals_Wait_queue, queue_context );
+}
+
+/**
+ * @brief Unlock POSIX signals thread.
+ */
+bool _POSIX_signals_Unblock_thread(
+ Thread_Control *the_thread,
+ int signo,
+ siginfo_t *info
+);
+
+/**
+ * @brief Clear POSIX signals.
+ */
+bool _POSIX_signals_Clear_signals(
+ POSIX_API_Control *api,
+ int signo,
+ siginfo_t *info,
+ bool is_global,
+ bool check_blocked,
+ bool do_signals_acquire_release
+);
+
+int _POSIX_signals_Send(
+ pid_t pid,
+ int sig,
+ const union sigval *value
+);
+
+/**
+ * @brief Set POSIX process signals.
+ */
+void _POSIX_signals_Set_process_signals(
+ sigset_t mask
+);
+
+void _POSIX_signals_Clear_process_signals(
+ int signo
+);
+
+/*
+ * Default signal handlers
+ */
+
+#define _POSIX_signals_Stop_handler NULL
+#define _POSIX_signals_Continue_handler NULL
+
+void _POSIX_signals_Abnormal_termination_handler( int signo );
+
+/** @} */
+
+#endif
+/* end of file */
diff --git a/cpukit/include/rtems/posix/pthread.h b/cpukit/include/rtems/posix/pthread.h
new file mode 100644
index 0000000000..05783ff4ad
--- /dev/null
+++ b/cpukit/include/rtems/posix/pthread.h
@@ -0,0 +1,55 @@
+/**
+ * @file
+ *
+ * @brief POSIX Threads Private Support
+ *
+ * This include file contains all the private support information for
+ * POSIX threads.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_PTHREAD_H
+#define _RTEMS_POSIX_PTHREAD_H
+
+#include <rtems/posix/config.h>
+#include <rtems/posix/threadsup.h>
+#include <rtems/score/thread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup POSIX_PTHREAD POSIX Threads Support
+ *
+ * @ingroup POSIXAPI
+ *
+ * @brief Private Support Information for POSIX Threads
+ *
+ */
+/**@{**/
+
+/**
+ * @brief POSIX threads initialize user threads body.
+ *
+ * This routine creates and starts all configured user
+ * initialization threads.
+ */
+extern void _POSIX_Threads_Initialize_user_threads_body(void);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/posix/pthreadattrimpl.h b/cpukit/include/rtems/posix/pthreadattrimpl.h
new file mode 100644
index 0000000000..12b8559181
--- /dev/null
+++ b/cpukit/include/rtems/posix/pthreadattrimpl.h
@@ -0,0 +1,95 @@
+/**
+ * @file
+ *
+ * @brief POSIX Threads Private Support
+ *
+ * This include file contains all the private support information for
+ * POSIX threads.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_PTHREADATTRIMPL_H
+#define _RTEMS_POSIX_PTHREADATTRIMPL_H
+
+#include <errno.h>
+#include <pthread.h>
+
+#include <rtems/score/basedefs.h>
+#include <rtems/score/assert.h>
+#include <rtems/posix/priorityimpl.h>
+#if defined(RTEMS_POSIX_API)
+#include <rtems/posix/threadsup.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup POSIX_PTHREAD
+ */
+/**@{**/
+
+/**
+ * This variable contains the default POSIX Thread attributes.
+ */
+extern const pthread_attr_t _POSIX_Threads_Default_attributes;
+
+RTEMS_INLINE_ROUTINE void _POSIX_Threads_Copy_attributes(
+ pthread_attr_t *dst_attr,
+ const pthread_attr_t *src_attr
+)
+{
+ *dst_attr = *src_attr;
+ _Assert(
+ dst_attr->affinitysetsize == sizeof(dst_attr->affinitysetpreallocated)
+ );
+ dst_attr->affinityset = &dst_attr->affinitysetpreallocated;
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Threads_Initialize_attributes(
+ pthread_attr_t *attr
+)
+{
+ _POSIX_Threads_Copy_attributes(
+ attr,
+ &_POSIX_Threads_Default_attributes
+ );
+}
+
+#if defined(RTEMS_POSIX_API)
+RTEMS_INLINE_ROUTINE void _POSIX_Threads_Get_sched_param_sporadic(
+ const Thread_Control *the_thread,
+ const Scheduler_Control *scheduler,
+ struct sched_param *param
+)
+{
+ const POSIX_API_Control *api;
+
+ api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+ param->sched_ss_low_priority = _POSIX_Priority_From_core(
+ scheduler,
+ api->Sporadic.Low_priority.priority
+ );
+ param->sched_ss_repl_period = api->Sporadic.sched_ss_repl_period;
+ param->sched_ss_init_budget = api->Sporadic.sched_ss_init_budget;
+ param->sched_ss_max_repl = api->Sporadic.sched_ss_max_repl;
+}
+#endif
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/posix/pthreadimpl.h b/cpukit/include/rtems/posix/pthreadimpl.h
new file mode 100644
index 0000000000..3e2351e57e
--- /dev/null
+++ b/cpukit/include/rtems/posix/pthreadimpl.h
@@ -0,0 +1,129 @@
+/**
+ * @file
+ *
+ * @brief POSIX Threads Private Support
+ *
+ * This include file contains all the private support information for
+ * POSIX threads.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_PTHREADIMPL_H
+#define _RTEMS_POSIX_PTHREADIMPL_H
+
+#include <rtems/posix/pthread.h>
+#include <rtems/posix/config.h>
+#include <rtems/posix/threadsup.h>
+#include <rtems/score/assert.h>
+#include <rtems/score/objectimpl.h>
+#include <rtems/score/timespec.h>
+#include <rtems/score/threadimpl.h>
+#include <rtems/score/watchdogimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup POSIX_PTHREAD
+ */
+/**@{**/
+
+/**
+ * The following sets the minimum stack size for POSIX threads.
+ */
+#define PTHREAD_MINIMUM_STACK_SIZE (_Stack_Minimum() * 2)
+
+/**
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+extern Thread_Information _POSIX_Threads_Information;
+
+RTEMS_INLINE_ROUTINE void _POSIX_Threads_Sporadic_timer_insert(
+ Thread_Control *the_thread,
+ POSIX_API_Control *api
+)
+{
+ the_thread->cpu_time_budget =
+ _Timespec_To_ticks( &api->Sporadic.sched_ss_init_budget );
+
+ _Watchdog_Per_CPU_insert_ticks(
+ &api->Sporadic.Timer,
+ _Per_CPU_Get(),
+ _Timespec_To_ticks( &api->Sporadic.sched_ss_repl_period )
+ );
+}
+
+void _POSIX_Threads_Sporadic_timer( Watchdog_Control *watchdog );
+
+/**
+ * @brief POSIX threads sporadic budget callout.
+ *
+ * This routine handles the sporadic scheduling algorithm.
+ *
+ * @param[in] the_thread is a pointer to the thread whose budget
+ * has been exceeded.
+ */
+void _POSIX_Threads_Sporadic_budget_callout(
+ Thread_Control *the_thread
+);
+
+int _POSIX_Thread_Translate_to_sched_policy(
+ Thread_CPU_budget_algorithms budget_algorithm
+);
+
+/**
+ * @brief Translate sched_param into SuperCore terms.
+ *
+ * This method translates the POSIX API sched_param into the corresponding
+ * SuperCore settings.
+ *
+ * @param[in] policy is the POSIX scheduling policy
+ * @param[in] param points to the scheduling parameter structure
+ * @param[in] budget_algorithm points to the output CPU Budget algorithm
+ * @param[in] budget_callout points to the output CPU Callout
+ *
+ * @retval 0 Indicates success.
+ * @retval error_code POSIX error code indicating failure.
+ */
+int _POSIX_Thread_Translate_sched_param(
+ int policy,
+ struct sched_param *param,
+ Thread_CPU_budget_algorithms *budget_algorithm,
+ Thread_CPU_budget_algorithm_callout *budget_callout
+);
+
+RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Allocate(void)
+{
+ _Objects_Allocator_lock();
+
+ _Thread_Kill_zombies();
+
+ return (Thread_Control *)
+ _Objects_Allocate_unprotected( &_POSIX_Threads_Information.Objects );
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Threads_Free (
+ Thread_Control *the_pthread
+)
+{
+ _Objects_Free( &_POSIX_Threads_Information.Objects, &the_pthread->Object );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/posix/ptimer.h b/cpukit/include/rtems/posix/ptimer.h
new file mode 100644
index 0000000000..f6de4ccb57
--- /dev/null
+++ b/cpukit/include/rtems/posix/ptimer.h
@@ -0,0 +1,88 @@
+/**
+ * @file
+ *
+ * @brief POSIX Timers Private Support
+ *
+ * This include file contains all the private support information for
+ * POSIX timers.
+ */
+
+/*
+ * Initial Implementation:
+ * COPYRIGHT (c) 1998. Alfonso Escalera Piña
+ * Largely rewritten by Joel Sherrill (1999).
+ *
+ * COPYRIGHT (c) 1999-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_PTIMER_H
+#define _RTEMS_POSIX_PTIMER_H
+
+/**
+ * @defgroup POSIX_PRIV_TIMERS POSIX Timers
+ *
+ * @ingroup POSIXAPI
+ */
+/**@{**/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/posix/config.h>
+
+/**
+ * @brief Create a Per-Process Timer
+ */
+int timer_create(
+ clockid_t clock_id,
+ struct sigevent *evp,
+ timer_t *timerid
+);
+
+/**
+ * @brief Delete a Per-Process Timer
+ */
+int timer_delete(
+ timer_t timerid
+);
+
+/**
+ * @brief Set a Per-Process Timer
+ */
+int timer_settime(
+ timer_t timerid,
+ int flags,
+ const struct itimerspec *value,
+ struct itimerspec *ovalue
+);
+
+/**
+ * @brief Set a Per-Process Timer
+ */
+int timer_gettime(
+ timer_t timerid,
+ struct itimerspec *value
+);
+
+/**
+ * @brief Get overrun count for a Per-Process Timer
+ *
+ * The expiration of a timer must increase by one a counter.
+ * After the signal handler associated to the timer finishes
+ * its execution, _POSIX_Timer_TSR will have to set this counter to 0.
+ */
+int timer_getoverrun(
+ timer_t timerid
+);
+
+#ifdef __cplusplus
+}
+#endif
+/** @} */
+
+#endif /* _RTEMS_POSIX_PTIMER_H */
diff --git a/cpukit/include/rtems/posix/rwlockimpl.h b/cpukit/include/rtems/posix/rwlockimpl.h
new file mode 100644
index 0000000000..b92ca9d04c
--- /dev/null
+++ b/cpukit/include/rtems/posix/rwlockimpl.h
@@ -0,0 +1,64 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines from the POSIX RWLock Manager
+ *
+ * This file contains the static inlin implementation of the inlined
+ * routines from the POSIX RWLock Manager.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_RWLOCKIMPL_H
+#define _RTEMS_POSIX_RWLOCKIMPL_H
+
+#include <rtems/score/corerwlockimpl.h>
+
+#include <errno.h>
+#include <pthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define POSIX_RWLOCK_MAGIC 0x9621dabdUL
+
+typedef struct {
+ unsigned long flags;
+ CORE_RWLock_Control RWLock;
+} POSIX_RWLock_Control;
+
+RTEMS_INLINE_ROUTINE POSIX_RWLock_Control *_POSIX_RWLock_Get(
+ pthread_rwlock_t *rwlock
+)
+{
+ return (POSIX_RWLock_Control *) rwlock;
+}
+
+bool _POSIX_RWLock_Auto_initialization( POSIX_RWLock_Control *the_rwlock );
+
+#define POSIX_RWLOCK_VALIDATE_OBJECT( rw ) \
+ do { \
+ if ( ( rw ) == NULL ) { \
+ return EINVAL; \
+ } \
+ if ( ( (uintptr_t) ( rw ) ^ POSIX_RWLOCK_MAGIC ) != ( rw )->flags ) { \
+ if ( !_POSIX_RWLock_Auto_initialization( rw ) ) { \
+ return EINVAL; \
+ } \
+ } \
+ } while ( 0 )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/posix/semaphore.h b/cpukit/include/rtems/posix/semaphore.h
new file mode 100644
index 0000000000..9133db22be
--- /dev/null
+++ b/cpukit/include/rtems/posix/semaphore.h
@@ -0,0 +1,56 @@
+/**
+ * @file
+ *
+ * @brief Private Support Information for POSIX Semaphores
+ *
+ * This include file contains all the private support information for
+ * POSIX Semaphores.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_SEMAPHORE_H
+#define _RTEMS_POSIX_SEMAPHORE_H
+
+#include <semaphore.h>
+#include <rtems/score/object.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup POSIXSemaphorePrivate POSIX Semaphore Private Support
+ *
+ * @ingroup POSIXAPI
+ *
+ * This defines the internal implementation support for POSIX semaphores.
+ */
+/**@{*/
+
+/*
+ * Data Structure used to manage a POSIX semaphore
+ */
+
+typedef struct {
+ Objects_Control Object;
+ sem_t Semaphore;
+ bool linked;
+ uint32_t open_count;
+} POSIX_Semaphore_Control;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/posix/semaphoreimpl.h b/cpukit/include/rtems/posix/semaphoreimpl.h
new file mode 100644
index 0000000000..fd17743699
--- /dev/null
+++ b/cpukit/include/rtems/posix/semaphoreimpl.h
@@ -0,0 +1,143 @@
+/**
+ * @file
+ *
+ * @brief Private Inlined Routines for POSIX Semaphores
+ *
+ * This include file contains the static inline implementation of the private
+ * inlined routines for POSIX Semaphores.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_SEMAPHOREIMPL_H
+#define _RTEMS_POSIX_SEMAPHOREIMPL_H
+
+#include <rtems/posix/semaphore.h>
+#include <rtems/posix/posixapi.h>
+#include <rtems/score/semaphoreimpl.h>
+#include <rtems/seterr.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief This is a random number used to check if a semaphore object is
+ * properly initialized.
+ */
+#define POSIX_SEMAPHORE_MAGIC 0x5d367fe7UL
+
+/**
+ * This defines the information control block used to manage
+ * this class of objects.
+ */
+extern Objects_Information _POSIX_Semaphore_Information;
+
+RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *
+ _POSIX_Semaphore_Allocate_unprotected( void )
+{
+ return (POSIX_Semaphore_Control *)
+ _Objects_Allocate_unprotected( &_POSIX_Semaphore_Information );
+}
+
+/**
+ * @brief POSIX Semaphore Free
+ *
+ * This routine frees a semaphore control block to the
+ * inactive chain of free semaphore control blocks.
+ */
+RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Free (
+ POSIX_Semaphore_Control *the_semaphore
+)
+{
+ _Objects_Free( &_POSIX_Semaphore_Information, &the_semaphore->Object );
+}
+
+RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get(
+ sem_t *sem
+)
+{
+ return RTEMS_CONTAINER_OF( sem, POSIX_Semaphore_Control, Semaphore );
+}
+
+RTEMS_INLINE_ROUTINE bool _POSIX_Semaphore_Is_named( const sem_t *sem )
+{
+ return sem->_Semaphore._Queue._name != NULL;
+}
+
+RTEMS_INLINE_ROUTINE bool _POSIX_Semaphore_Is_busy( const sem_t *sem )
+{
+ return sem->_Semaphore._Queue._heads != NULL;
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Initialize(
+ sem_t *sem,
+ const char *name,
+ unsigned int value
+)
+{
+ sem->_flags = (uintptr_t) sem ^ POSIX_SEMAPHORE_MAGIC;
+ _Semaphore_Initialize_named( &sem->_Semaphore, name, value );
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Destroy( sem_t *sem )
+{
+ sem->_flags = 0;
+ _Semaphore_Destroy( &sem->_Semaphore );
+}
+
+/**
+ * @brief POSIX Semaphore Delete
+ *
+ * This routine supports the sem_close and sem_unlink routines.
+ */
+void _POSIX_Semaphore_Delete( POSIX_Semaphore_Control *the_semaphore );
+
+/**
+ * @brief POSIX Semaphore Namespace Remove
+ */
+RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Namespace_remove (
+ POSIX_Semaphore_Control *the_semaphore
+)
+{
+ _Objects_Namespace_remove(
+ &_POSIX_Semaphore_Information, &the_semaphore->Object );
+}
+
+RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get_by_name(
+ const char *name,
+ size_t *name_length_p,
+ Objects_Get_by_name_error *error
+)
+{
+ return (POSIX_Semaphore_Control *) _Objects_Get_by_name(
+ &_POSIX_Semaphore_Information,
+ name,
+ name_length_p,
+ error
+ );
+}
+
+#define POSIX_SEMAPHORE_VALIDATE_OBJECT( sem ) \
+ do { \
+ if ( \
+ ( sem ) == NULL \
+ || ( (uintptr_t) ( sem ) ^ POSIX_SEMAPHORE_MAGIC ) != ( sem )->_flags \
+ ) { \
+ rtems_set_errno_and_return_minus_one( EINVAL ); \
+ } \
+ } while ( 0 )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/posix/shm.h b/cpukit/include/rtems/posix/shm.h
new file mode 100644
index 0000000000..d2b6036493
--- /dev/null
+++ b/cpukit/include/rtems/posix/shm.h
@@ -0,0 +1,213 @@
+/**
+ * @file
+ *
+ * @brief Internal Support for POSIX Shared Memory
+ */
+
+/*
+ * Copyright (c) 2016 Gedare Bloom.
+ *
+ * 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_POSIX_SHM_H
+#define _RTEMS_POSIX_SHM_H
+
+#include <rtems/score/object.h>
+#include <rtems/score/threadq.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup POSIXShmPrivate POSIX Shared Memory Private Support
+ *
+ * @ingroup POSIXAPI
+ *
+ * Internal implementation support for POSIX shared memory.
+ * @{
+ */
+typedef struct POSIX_Shm_Object_operations POSIX_Shm_Object_operations;
+extern const POSIX_Shm_Object_operations _POSIX_Shm_Object_operations;
+
+/**
+ * @brief Encapsulation for the storage and manipulation of shm objects.
+ */
+typedef struct {
+ /**
+ * @brief The handle is private for finding object storage.
+ */
+ void *handle;
+
+ /**
+ * @brief The number of bytes allocated to the object. A size of 0 with
+ * a handle of NULL means no object is allocated.
+ */
+ size_t size;
+
+ /**
+ * @brief Implementation-specific operations on shm objects.
+ */
+ const POSIX_Shm_Object_operations *ops;
+} POSIX_Shm_Object;
+
+/**
+ * @brief Operations on POSIX Shared Memory Objects.
+ */
+struct POSIX_Shm_Object_operations {
+ /**
+ * @brief Allocates a new @a shm_obj with initial @a size.
+ *
+ * New shared memory is initialized to zeroes.
+ *
+ * Returns 0 for success.
+ */
+ int ( *object_create ) ( POSIX_Shm_Object *shm_obj, size_t size );
+
+ /**
+ * @brief Changes the @a shm_obj size to @a size.
+ *
+ * Zeroes out the portion of the shared memory object that shrinks or grows.
+ *
+ * Returns 0 for success.
+ */
+ int ( *object_resize ) ( POSIX_Shm_Object *shm_obj, size_t size );
+
+ /**
+ * @brief Deletes the @a shm_obj.
+ *
+ * Zeroes out the memory.
+ *
+ * Returns 0 for success.
+ */
+ int ( *object_delete ) ( POSIX_Shm_Object *shm_obj );
+
+ /**
+ * @brief Copies up to @count bytes of the @a shm_obj data into @a buf.
+ *
+ * Returns the number of bytes read (copied) into @a buf.
+ */
+ int ( *object_read ) ( POSIX_Shm_Object *shm_obj, void *buf, size_t count );
+
+ /**
+ * @brief Maps a shared memory object.
+ *
+ * Establishes a memory mapping between the shared memory object and the
+ * caller.
+ *
+ * Returns the mapped address of the object.
+ */
+ void * ( *object_mmap ) ( POSIX_Shm_Object *shm_obj, size_t len, int prot, off_t off);
+};
+
+/**
+ * @brief Control for a POSIX Shared Memory Object
+ */
+typedef struct {
+ Objects_Control Object;
+ Thread_queue_Control Wait_queue;
+
+ int reference_count;
+
+ POSIX_Shm_Object shm_object;
+
+ uid_t uid;
+ gid_t gid;
+ mode_t mode;
+ int oflag;
+
+ time_t atime;
+ time_t mtime;
+ time_t ctime;
+} POSIX_Shm_Control;
+
+/**
+ * @brief object_create operation for shm objects stored in RTEMS Workspace.
+ */
+extern int _POSIX_Shm_Object_create_from_workspace(
+ POSIX_Shm_Object *shm_obj,
+ size_t size
+);
+
+/**
+ * @brief object_delete operation for shm objects stored in RTEMS Workspace.
+ */
+extern int _POSIX_Shm_Object_delete_from_workspace( POSIX_Shm_Object *shm_obj );
+
+/**
+ * @brief object_resize operation for shm objects stored in RTEMS Workspace.
+ */
+extern int _POSIX_Shm_Object_resize_from_workspace(
+ POSIX_Shm_Object *shm_obj,
+ size_t size
+);
+
+/**
+ * @brief object_read operation for shm objects stored in RTEMS Workspace.
+ */
+extern int _POSIX_Shm_Object_read_from_workspace(
+ POSIX_Shm_Object *shm_obj,
+ void *buf,
+ size_t count
+);
+
+/**
+ * @brief object_mmap operation for shm objects stored in RTEMS Workspace.
+ */
+extern void * _POSIX_Shm_Object_mmap_from_workspace(
+ POSIX_Shm_Object *shm_obj,
+ size_t len,
+ int prot,
+ off_t off
+);
+
+/**
+ * @brief object_create operation for shm objects stored in C program heap.
+ */
+extern int _POSIX_Shm_Object_create_from_heap(
+ POSIX_Shm_Object *shm_obj,
+ size_t size
+);
+
+/**
+ * @brief object_delete operation for shm objects stored in C program heap.
+ */
+extern int _POSIX_Shm_Object_delete_from_heap( POSIX_Shm_Object *shm_obj );
+
+/**
+ * @brief object_resize operation for shm objects stored in C program heap.
+ */
+extern int _POSIX_Shm_Object_resize_from_heap(
+ POSIX_Shm_Object *shm_obj,
+ size_t size
+);
+
+/**
+ * @brief object_read operation for shm objects stored in C program heap.
+ */
+extern int _POSIX_Shm_Object_read_from_heap(
+ POSIX_Shm_Object *shm_obj,
+ void *buf,
+ size_t count
+);
+
+/**
+ * @brief object_mmap operation for shm objects stored in C program heap.
+ */
+extern void * _POSIX_Shm_Object_mmap_from_heap(
+ POSIX_Shm_Object *shm_obj,
+ size_t len,
+ int prot,
+ off_t off
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/posix/shmimpl.h b/cpukit/include/rtems/posix/shmimpl.h
new file mode 100644
index 0000000000..f16af8123d
--- /dev/null
+++ b/cpukit/include/rtems/posix/shmimpl.h
@@ -0,0 +1,135 @@
+/**
+ * @file
+ *
+ * @brief Private Support Information for POSIX Shared Memory
+ *
+ */
+
+/*
+ * Copyright (c) 2016 Gedare Bloom.
+ *
+ * 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_POSIX_SHMIMPL_H
+#define _RTEMS_POSIX_SHMIMPL_H
+
+#include <rtems/fs.h>
+#include <rtems/libio.h>
+#include <rtems/posix/posixapi.h>
+#include <rtems/posix/shm.h>
+#include <rtems/score/objectimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup POSIXShmPrivate
+ * @{
+ */
+
+extern Objects_Information _POSIX_Shm_Information;
+
+RTEMS_INLINE_ROUTINE POSIX_Shm_Control *_POSIX_Shm_Allocate_unprotected( void )
+{
+ return (POSIX_Shm_Control *)
+ _Objects_Allocate_unprotected( &_POSIX_Shm_Information );
+}
+
+/**
+ * @brief POSIX Shared Memory Free
+ *
+ * This routine frees a shm control block.
+ */
+RTEMS_INLINE_ROUTINE void _POSIX_Shm_Free (
+ POSIX_Shm_Control *the_shm
+)
+{
+ _Objects_Free( &_POSIX_Shm_Information, &the_shm->Object );
+}
+
+RTEMS_INLINE_ROUTINE POSIX_Shm_Control *_POSIX_Shm_Get_by_name(
+ const char *name,
+ size_t *name_length_p,
+ Objects_Get_by_name_error *error
+)
+{
+ return (POSIX_Shm_Control *) _Objects_Get_by_name(
+ &_POSIX_Shm_Information,
+ name,
+ name_length_p,
+ error
+ );
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Shm_Update_atime(
+ POSIX_Shm_Control *shm
+)
+{
+ struct timeval now;
+ gettimeofday( &now, 0 );
+ shm->atime = now.tv_sec;
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Shm_Update_mtime_ctime(
+ POSIX_Shm_Control *shm
+)
+{
+ struct timeval now;
+ gettimeofday( &now, 0 );
+ shm->mtime = now.tv_sec;
+ shm->ctime = now.tv_sec;
+}
+
+static inline POSIX_Shm_Control* iop_to_shm( rtems_libio_t *iop )
+{
+ return (POSIX_Shm_Control*) iop->data1;
+}
+
+static inline POSIX_Shm_Control* loc_to_shm(
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ return (POSIX_Shm_Control*) loc->node_access;
+}
+
+static inline int POSIX_Shm_Attempt_delete(
+ POSIX_Shm_Control* shm
+)
+{
+ Objects_Control *obj;
+ ISR_lock_Context lock_ctx;
+ int err;
+
+ err = 0;
+
+ _Objects_Allocator_lock();
+ --shm->reference_count;
+ if ( shm->reference_count == 0 ) {
+ if ( (*shm->shm_object.ops->object_delete)( &shm->shm_object ) != 0 ) {
+ err = EIO;
+ }
+ }
+ /* check if the object has been unlinked yet. */
+ obj = _Objects_Get( shm->Object.id, &lock_ctx, &_POSIX_Shm_Information );
+ if ( obj == NULL ) {
+ /* if it was unlinked, then it can be freed. */
+ _POSIX_Shm_Free( shm );
+ } else {
+ /* it will be freed when it is unlinked. */
+ _ISR_lock_ISR_enable( &lock_ctx );
+ }
+ _Objects_Allocator_unlock();
+ return err;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/posix/sigset.h b/cpukit/include/rtems/posix/sigset.h
new file mode 100644
index 0000000000..96bcc086ba
--- /dev/null
+++ b/cpukit/include/rtems/posix/sigset.h
@@ -0,0 +1,45 @@
+/**
+ * @file
+ *
+ * @brief POSIX Signal Sets Management Helper
+ *
+ * This file defines the interface to implementation helper for management
+ * of POSIX Signal Sets.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_SIGSET_H
+#define _RTEMS_POSIX_SIGSET_H
+
+#include <signal.h> // sigset_t
+
+/*
+ * Currently 32 signals numbered 1-32 are defined
+ */
+
+#define SIGNAL_EMPTY_MASK 0x00000000L
+#define SIGNAL_ALL_MASK 0xffffffffL
+
+static inline sigset_t signo_to_mask(
+ uint32_t sig
+)
+{
+ return 1u << (sig - 1);
+}
+
+static inline bool is_valid_signo(
+ int signo
+)
+{
+ return ((signo) >= 1 && (signo) <= 32 );
+}
+
+#endif
diff --git a/cpukit/include/rtems/posix/spinlockimpl.h b/cpukit/include/rtems/posix/spinlockimpl.h
new file mode 100644
index 0000000000..d28e0391fc
--- /dev/null
+++ b/cpukit/include/rtems/posix/spinlockimpl.h
@@ -0,0 +1,58 @@
+/**
+ * @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.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Copyright (c) 2016 embedded brains GmbH
+ *
+ * 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_POSIX_SPINLOCKIMPL_H
+#define _RTEMS_POSIX_SPINLOCKIMPL_H
+
+#include <pthread.h>
+
+#include <rtems/score/isrlevel.h>
+
+#if defined(RTEMS_SMP)
+#include <rtems/score/percpu.h>
+#include <rtems/score/smplockticket.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+#if defined(RTEMS_SMP)
+ SMP_ticket_lock_Control Lock;
+#else
+ unsigned int reserved[ 2 ];
+#endif
+ ISR_Level interrupt_state;
+} POSIX_Spinlock_Control;
+
+RTEMS_INLINE_ROUTINE POSIX_Spinlock_Control *_POSIX_Spinlock_Get(
+ pthread_spinlock_t *lock
+)
+{
+ return (POSIX_Spinlock_Control *) lock;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/posix/threadsup.h b/cpukit/include/rtems/posix/threadsup.h
new file mode 100644
index 0000000000..d3ee5b28bb
--- /dev/null
+++ b/cpukit/include/rtems/posix/threadsup.h
@@ -0,0 +1,98 @@
+/**
+ * @file
+ *
+ * @brief POSIX Thread API Support
+ *
+ * This defines the POSIX thread API extension.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_THREADSUP_H
+#define _RTEMS_POSIX_THREADSUP_H
+
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+
+#include <pthread.h>
+#include <signal.h>
+
+/**
+ * @defgroup POSIX_THREAD POSIX Thread API Extension
+ *
+ * @ingroup POSIXAPI
+ *
+ */
+/**@{**/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This defines the POSIX API support structure associated with
+ * each thread in a system with POSIX configured.
+ */
+typedef struct {
+ /**
+ * @brief Control block for the sporadic server scheduling policy.
+ */
+ struct {
+ /** The thread of this sporadic control block */
+ Thread_Control *thread;
+
+ /**
+ * @brief This is the timer which controls when the thread executes at high
+ * and low priority when using the sporadic server scheduling policy.
+ */
+ Watchdog_Control Timer;
+
+ /**
+ * @brief The low priority when using the sporadic server scheduling
+ * policy.
+ */
+ Priority_Node Low_priority;
+
+ /**
+ * @brief Replenishment period for sporadic server.
+ */
+ struct timespec sched_ss_repl_period;
+
+ /**
+ * @brief Initial budget for sporadic server.
+ */
+ struct timespec sched_ss_init_budget;
+
+ /**
+ * @brief Maximum pending replenishments.
+ *
+ * Only used by pthread_getschedparam() and pthread_getattr_np().
+ */
+ int sched_ss_max_repl;
+ } Sporadic;
+
+ /** This is the set of signals which are currently unblocked. */
+ sigset_t signals_unblocked;
+ /** This is the set of signals which are currently pending. */
+ sigset_t signals_pending;
+
+ /**
+ * @brief Signal post-switch action in case signals are pending.
+ */
+ Thread_Action Signal_action;
+} POSIX_API_Control;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/posix/timer.h b/cpukit/include/rtems/posix/timer.h
new file mode 100644
index 0000000000..79fe093219
--- /dev/null
+++ b/cpukit/include/rtems/posix/timer.h
@@ -0,0 +1,60 @@
+/**
+ * @file
+ *
+ * @brief POSIX Timers Internal Support
+ *
+ * This include files defines the internal support for implementation of
+ * POSIX Timers.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_TIMER_H
+#define _RTEMS_POSIX_TIMER_H
+
+#include <rtems/score/object.h>
+#include <rtems/score/watchdog.h>
+
+#include <pthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup POSIX_INTERNAL_TIMERS POSIX Timer Private Support
+ *
+ * @ingroup POSIXAPI
+ */
+/**@{*/
+
+/*
+ * Data for a timer
+ */
+typedef struct {
+ Objects_Control Object;
+ Watchdog_Control Timer; /* Internal Timer */
+ pthread_t thread_id; /* Thread identifier */
+ char state; /* State of the timer */
+ struct sigevent inf; /* Information associated to the timer */
+ struct itimerspec timer_data; /* Timing data of the timer */
+ uint32_t ticks; /* Number of ticks of the initialization */
+ uint32_t overrun; /* Number of expirations of the timer */
+ struct timespec time; /* Time at which the timer was started */
+} POSIX_Timer_Control;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/posix/timerimpl.h b/cpukit/include/rtems/posix/timerimpl.h
new file mode 100644
index 0000000000..42a814c992
--- /dev/null
+++ b/cpukit/include/rtems/posix/timerimpl.h
@@ -0,0 +1,134 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines from the POSIX Timer Manager
+ *
+ * This file contains the static inline implementation of the inlined routines
+ * from the POSIX Timer Manager.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_POSIX_TIMERIMPL_H
+#define _RTEMS_POSIX_TIMERIMPL_H
+
+#include <rtems/posix/timer.h>
+#include <rtems/score/objectimpl.h>
+#include <rtems/score/watchdogimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Timer is free */
+#define POSIX_TIMER_STATE_FREE 0x01
+
+/** Created timer but not running */
+#define POSIX_TIMER_STATE_CREATE_NEW 0x02
+
+/** Created timer and running */
+#define POSIX_TIMER_STATE_CREATE_RUN 0x03
+
+/** Created, ran and stopped timer */
+#define POSIX_TIMER_STATE_CREATE_STOP 0x04
+
+/** Indicates that the fire time is relative to the current one */
+#define POSIX_TIMER_RELATIVE 0
+
+/*
+ * POSIX defines TIMER_ABSTIME but no constant for relative. So
+ * we have one internally but we need to be careful it has a different
+ * value.
+ */
+#if (POSIX_TIMER_RELATIVE == TIMER_ABSTIME)
+#error "POSIX_TIMER_RELATIVE == TIMER_ABSTIME"
+#endif
+
+/**
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+extern Objects_Information _POSIX_Timer_Information;
+
+/**
+ * @brief POSIX Timer Allocate
+ *
+ * This function allocates a timer control block from
+ * the inactive chain of free timer control blocks.
+ */
+RTEMS_INLINE_ROUTINE POSIX_Timer_Control *_POSIX_Timer_Allocate( void )
+{
+ return (POSIX_Timer_Control *) _Objects_Allocate( &_POSIX_Timer_Information );
+}
+
+/**
+ * @brief POSIX Timer Free
+ *
+ * This routine frees a timer control block to the
+ * inactive chain of free timer control blocks.
+ */
+RTEMS_INLINE_ROUTINE void _POSIX_Timer_Free (
+ POSIX_Timer_Control *the_timer
+)
+{
+ _Objects_Free( &_POSIX_Timer_Information, &the_timer->Object );
+}
+
+void _POSIX_Timer_TSR( Watchdog_Control *the_watchdog );
+
+/**
+ * @brief POSIX Timer Get
+ *
+ * This function maps timer IDs to timer control blocks.
+ * If ID corresponds to a local timer, then it returns
+ * the timer control pointer which maps to ID and location
+ * is set to OBJECTS_LOCAL. Otherwise, location is set
+ * to OBJECTS_ERROR and the returned value is undefined.
+ */
+RTEMS_INLINE_ROUTINE POSIX_Timer_Control *_POSIX_Timer_Get (
+ timer_t id,
+ ISR_lock_Context *lock_context
+)
+{
+ return (POSIX_Timer_Control *) _Objects_Get(
+ (Objects_Id) id,
+ lock_context,
+ &_POSIX_Timer_Information
+ );
+}
+
+RTEMS_INLINE_ROUTINE Per_CPU_Control *_POSIX_Timer_Acquire_critical(
+ POSIX_Timer_Control *ptimer,
+ ISR_lock_Context *lock_context
+)
+{
+ Per_CPU_Control *cpu;
+
+ cpu = _Watchdog_Get_CPU( &ptimer->Timer );
+ _Watchdog_Per_CPU_acquire_critical( cpu, lock_context );
+
+ return cpu;
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Timer_Release(
+ Per_CPU_Control *cpu,
+ ISR_lock_Context *lock_context
+)
+{
+ _Watchdog_Per_CPU_release_critical( cpu, lock_context );
+ _ISR_lock_ISR_enable( lock_context );
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/profiling.h b/cpukit/include/rtems/profiling.h
new file mode 100644
index 0000000000..9e434b2a3c
--- /dev/null
+++ b/cpukit/include/rtems/profiling.h
@@ -0,0 +1,333 @@
+/**
+ * @file
+ *
+ * @ingroup Profiling
+ *
+ * @brief Profiling API
+ */
+
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_PROFILING_H
+#define _RTEMS_PROFILING_H
+
+#include <stdint.h>
+
+#include <rtems/print.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup Profiling Profiling Support
+ *
+ * @brief The profiling support offers functions to report profiling
+ * information available in the system.
+ *
+ * Profiling support is by default disabled. It must be enabled via the
+ * configure command line with the <tt>--enable-profiling</tt> option. In this
+ * case the RTEMS_PROFILING pre-processor symbol is defined and profiling
+ * statistics will be gathered during system run-time. The profiling support
+ * increases the time of critical sections and has some memory overhead. The
+ * overhead should be acceptable for most applications. The aim of the
+ * profiling implementation is to be available even for production systems so
+ * that verification is simplified.
+ *
+ * Profiling information includes critical timing values such as the maximum
+ * time of disabled thread dispatching which is a measure for the thread
+ * dispatch latency. On SMP configurations statistics of all SMP locks in the
+ * system are available.
+ *
+ * Profiling information can be retrieved via rtems_profiling_iterate() and
+ * reported as an XML dump via rtems_profiling_report_xml(). These functions
+ * are always available, but actual profiling data is only available if enabled
+ * at build configuration time.
+ *
+ * @{
+ */
+
+/**
+ * @brief Type of profiling data.
+ */
+typedef enum {
+ /**
+ * @brief Type of per-CPU profiling data.
+ *
+ * @see rtems_profiling_per_cpu.
+ */
+ RTEMS_PROFILING_PER_CPU,
+
+ /**
+ * @brief Type of SMP lock profiling data.
+ *
+ * @see rtems_profiling_smp_lock.
+ */
+ RTEMS_PROFILING_SMP_LOCK
+} rtems_profiling_type;
+
+/**
+ * @brief The profiling data header.
+ */
+typedef struct {
+ /**
+ * @brief The profiling data type.
+ */
+ rtems_profiling_type type;
+} rtems_profiling_header;
+
+/**
+ * @brief Per-CPU profiling data.
+ *
+ * Theoretically all values in this structure can overflow, but the integer
+ * types are chosen so that they cannot overflow in practice. On systems with
+ * a 1GHz CPU counter, the 64-bit integers can overflow in about 58 years.
+ * Since the system should not spend most of the time in critical sections the
+ * actual system run-time is much longer. Several other counters in the system
+ * will overflow before we get a problem in the profiling area.
+ */
+typedef struct {
+ /**
+ * @brief The profiling data header.
+ */
+ rtems_profiling_header header;
+
+ /**
+ * @brief The processor index of this profiling data.
+ */
+ uint32_t processor_index;
+
+ /**
+ * @brief The maximum time of disabled thread dispatching in nanoseconds.
+ */
+ uint32_t max_thread_dispatch_disabled_time;
+
+ /**
+ * @brief Count of times when the thread dispatch disable level changes from
+ * zero to one in thread context.
+ *
+ * This value may overflow.
+ */
+ uint64_t thread_dispatch_disabled_count;
+
+ /**
+ * @brief Total time of disabled thread dispatching in nanoseconds.
+ *
+ * The average time of disabled thread dispatching is the total time of
+ * disabled thread dispatching divided by the thread dispatch disabled
+ * count.
+ *
+ * This value may overflow.
+ */
+ uint64_t total_thread_dispatch_disabled_time;
+
+ /**
+ * @brief The maximum interrupt delay in nanoseconds if supported by the
+ * hardware.
+ *
+ * The interrupt delay is the time interval from the recognition of an
+ * interrupt signal by the hardware up to the execution start of the
+ * corresponding high-level handler. The interrupt delay is the main
+ * contributor to the interrupt latency. To measure this time hardware
+ * support is required. A time stamp unit must capture the interrupt signal
+ * recognition time. If no hardware support is available, then this field
+ * will have a constant value of zero.
+ */
+ uint32_t max_interrupt_delay;
+
+ /**
+ * @brief The maximum time spent to process a single sequence of nested
+ * interrupts in nanoseconds.
+ *
+ * This is the time interval between the change of the interrupt nest level
+ * from zero to one and the change back from one to zero. It is the measured
+ * worst-case execution time of interrupt service routines. Please note that
+ * in case of nested interrupts this time includes the combined execution
+ * time and not the maximum time of an individual interrupt service routine.
+ */
+ uint32_t max_interrupt_time;
+
+ /**
+ * @brief Count of times when the interrupt nest level changes from zero to
+ * one.
+ *
+ * This value may overflow.
+ */
+ uint64_t interrupt_count;
+
+ /**
+ * @brief Total time of interrupt processing in nanoseconds.
+ *
+ * The average time of interrupt processing is the total time of interrupt
+ * processing divided by the interrupt count.
+ *
+ * This value may overflow.
+ */
+ uint64_t total_interrupt_time;
+} rtems_profiling_per_cpu;
+
+/**
+ * @brief Count of lock contention counters for SMP lock profiling.
+ */
+#define RTEMS_PROFILING_SMP_LOCK_CONTENTION_COUNTS 4
+
+/**
+ * @brief SMP lock profiling data.
+ *
+ * The lock acquire attempt instant is the point in time right after the
+ * interrupt disable action in the lock acquire sequence.
+ *
+ * The lock acquire instant is the point in time right after the lock
+ * acquisition. This is the begin of the critical section code execution.
+ *
+ * The lock acquire time is the time elapsed between the lock acquire attempt
+ * instant and the lock acquire instant.
+ *
+ * The lock release instant is the point in time right before the interrupt
+ * enable action in the lock release sequence.
+ *
+ * The lock section time is the time elapsed between the lock acquire instant
+ * and the lock release instant.
+ */
+typedef struct {
+ /**
+ * @brief The profiling data header.
+ */
+ rtems_profiling_header header;
+
+ /**
+ * @brief The lock name.
+ */
+ const char *name;
+
+ /**
+ * @brief The maximum lock acquire time in nanoseconds.
+ */
+ uint32_t max_acquire_time;
+
+ /**
+ * @brief The maximum lock section time in nanoseconds.
+ */
+ uint32_t max_section_time;
+
+ /**
+ * @brief The count of lock uses.
+ *
+ * This value may overflow.
+ */
+ uint64_t usage_count;
+
+ /**
+ * @brief Total lock acquire time in nanoseconds.
+ *
+ * The average lock acquire time is the total acquire time divided by the
+ * lock usage count. The ration of the total section and total acquire times
+ * gives a measure for the lock contention.
+ *
+ * This value may overflow.
+ */
+ uint64_t total_acquire_time;
+
+ /**
+ * @brief Total lock section time in nanoseconds.
+ *
+ * The average lock section time is the total section time divided by the
+ * lock usage count.
+ *
+ * This value may overflow.
+ */
+ uint64_t total_section_time;
+
+ /**
+ * @brief The counts of lock acquire operations by contention.
+ *
+ * The contention count for index N corresponds to a lock acquire attempt
+ * with an initial queue length of N. The last index corresponds to all
+ * lock acquire attempts with an initial queue length greater than or equal
+ * to RTEMS_PROFILING_SMP_LOCK_CONTENTION_COUNTS minus one.
+ *
+ * The values may overflow.
+ */
+ uint64_t contention_counts[RTEMS_PROFILING_SMP_LOCK_CONTENTION_COUNTS];
+} rtems_profiling_smp_lock;
+
+/**
+ * @brief Collection of profiling data.
+ */
+typedef union {
+ /**
+ * @brief Header to specify the actual profiling data.
+ */
+ rtems_profiling_header header;
+
+ /**
+ * @brief Per-CPU profiling data if indicated by the header.
+ */
+ rtems_profiling_per_cpu per_cpu;
+
+ /**
+ * @brief SMP lock profiling data if indicated by the header.
+ */
+ rtems_profiling_smp_lock smp_lock;
+} rtems_profiling_data;
+
+/**
+ * @brief Visitor function for the profiling iteration.
+ *
+ * @param[in, out] arg The visitor argument.
+ * @param[in] data The current profiling data.
+ *
+ * @see rtems_profiling_iterate().
+ */
+typedef void (*rtems_profiling_visitor)(
+ void *arg,
+ const rtems_profiling_data *data
+);
+
+/**
+ * @brief Iterates through all profiling data of the system.
+ *
+ * @param[in] visitor The visitor.
+ * @param[in, out] visitor_arg The visitor argument.
+ */
+void rtems_profiling_iterate(
+ rtems_profiling_visitor visitor,
+ void *visitor_arg
+);
+
+/**
+ * @brief Reports profiling data as XML.
+ *
+ * @param[in] name The name of the profiling report.
+ * @param[in] printer The RTEMS printer to send the output too.
+ * @param[in] indentation_level The current indentation level.
+ * @param[in] indentation The string used for indentation.
+ *
+ * @returns As specified by printf().
+ */
+int rtems_profiling_report_xml(
+ const char *name,
+ const rtems_printer *printer,
+ uint32_t indentation_level,
+ const char *indentation
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_PROFILING_H */
diff --git a/cpukit/include/rtems/pty.h b/cpukit/include/rtems/pty.h
new file mode 100644
index 0000000000..392bfd0969
--- /dev/null
+++ b/cpukit/include/rtems/pty.h
@@ -0,0 +1,76 @@
+/*
+ * /dev/ptyXX (A first version for pseudo-terminals)
+ *
+ * Author: Fernando RUIZ CASAS (fernando.ruiz@ctv.es)
+ * May 2001
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _RTEMS_PTY_H
+#define _RTEMS_PTY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems.h>
+
+/* Number of ptys to setup */
+extern size_t rtems_pty_maximum_ptys;
+
+/* Return the devname for a free pty slot.
+ * If no slot available (socket>=0)
+ * then the socket argument is closed
+ */
+char * rtems_pty_get(int socket);
+
+
+/* OBSOLETE */
+#define get_pty rtems_pty_get
+
+rtems_device_driver pty_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg);
+rtems_device_driver pty_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg);
+rtems_device_driver pty_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg);
+rtems_device_driver pty_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg);
+rtems_device_driver pty_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg);
+rtems_device_driver pty_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg);
+
+
+#define PTY_DRIVER_TABLE_ENTRY \
+ { pty_initialize , pty_open , pty_close , \
+ pty_read , pty_write , pty_control }
+
+/* Internal functions */
+
+int telnet_pty_initialize(void);
+
+int telnet_pty_finalize(void);
+
+char *telnet_get_pty(int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/qreslib.h b/cpukit/include/rtems/qreslib.h
new file mode 100644
index 0000000000..3de8668fdb
--- /dev/null
+++ b/cpukit/include/rtems/qreslib.h
@@ -0,0 +1,269 @@
+/**
+ * @file qreslib.h
+ *
+ * @brief Constants and Structures Associated
+ * with the QoS RES library in RTEMS
+ *
+ * This include file contains all the constants and structures
+ * associated with the QoS RES library in RTEMS.
+ *
+ * @note The library is available only together with CBS scheduler.
+ */
+
+/*
+ * Copyright (C) 2011 Petr Benes.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * 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 CONFIGURE_SCHEDULER_CBS
+ #error "qreslib.h available only with CONFIGURE_SCHEDULER_CBS"
+#endif
+
+#ifndef _QRESLIB_H
+#define _QRESLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <rtems/score/schedulercbs.h>
+
+/** Return values. */
+typedef int qos_rv;
+
+/* Return codes. */
+#define QOS_OK SCHEDULER_CBS_OK
+#define QOS_E_GENERIC SCHEDULER_CBS_ERROR_GENERIC
+#define QOS_E_NO_MEMORY SCHEDULER_CBS_ERROR_NO_MEMORY
+#define QOS_E_INVALID_PARAM SCHEDULER_CBS_ERROR_INVALID_PARAMETER
+#define QOS_E_UNAUTHORIZED SCHEDULER_CBS_ERROR_UNAUTHORIZED
+#define QOS_E_UNIMPLEMENTED SCHEDULER_CBS_ERROR_UNIMPLEMENTED
+#define QOS_E_MISSING_COMPONENT SCHEDULER_CBS_ERROR_MISSING_COMPONENT
+#define QOS_E_INCONSISTENT_STATE SCHEDULER_CBS_ERROR_INCONSISTENT_STATE
+#define QOS_E_SYSTEM_OVERLOAD SCHEDULER_CBS_ERROR_SYSTEM_OVERLOAD
+#define QOS_E_INTERNAL_ERROR SCHEDULER_CBS_ERROR_INTERNAL_ERROR
+#define QOS_E_NOT_FOUND SCHEDULER_CBS_ERROR_NOT_FOUND
+#define QOS_E_FULL SCHEDULER_CBS_ERROR_FULL
+#define QOS_E_EMPTY SCHEDULER_CBS_ERROR_EMPTY
+#define QOS_E_NOSERVER SCHEDULER_CBS_ERROR_NOSERVER
+
+/** Server id. */
+typedef Scheduler_CBS_Server_id qres_sid_t;
+
+/** Task id. */
+typedef rtems_id tid_t;
+
+/** Time value. */
+typedef time_t qres_time_t;
+
+/** Absolute time value */
+typedef time_t qres_atime_t;
+
+/** Server parameters. */
+typedef struct {
+ /** Relative deadline of the server. */
+ qres_time_t P;
+ /** Budget (computation time) of the server. */
+ qres_time_t Q;
+} qres_params_t;
+
+/**
+ * @brief qres init
+ *
+ * Initializes the QoS RES library.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_init ( void )
+{
+ return _Scheduler_CBS_Initialize();
+}
+
+/**
+ * @brief qres cleanup
+ *
+ * Cleanup resources associated to the QoS RES Library.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_cleanup ( void )
+{
+ return _Scheduler_CBS_Cleanup();
+}
+
+/**
+ * @brief qres create server
+ *
+ * Create a new server with specified parameters.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_create_server (
+ qres_params_t *params,
+ qres_sid_t *server_id
+)
+{
+ return _Scheduler_CBS_Create_server(
+ (Scheduler_CBS_Parameters *) params,
+ NULL,
+ server_id
+ );
+}
+
+/**
+ * @brief qres attach thread
+ *
+ * Attach a task to an already existing server.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_attach_thread (
+ qres_sid_t server_id,
+ pid_t pid,
+ tid_t task_id
+)
+{
+ return _Scheduler_CBS_Attach_thread( server_id, task_id );
+}
+
+/**
+ * @brief qres detach thread
+ *
+ * Detach from the QoS Server.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_detach_thread (
+ qres_sid_t server_id,
+ pid_t pid,
+ tid_t task_id
+)
+{
+ return _Scheduler_CBS_Detach_thread( server_id, task_id );
+}
+
+/**
+ * @brief qres destroy server
+ *
+ * Detach all tasks from a server and destroy it.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_destroy_server (
+ qres_sid_t server_id
+)
+{
+ return _Scheduler_CBS_Destroy_server( server_id );
+}
+
+/**
+ * @brief qres get server id
+ *
+ * Get a thread server id, or QOS_E_NOT_FOUND if it is not
+ * attached to any server.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_get_sid (
+ pid_t pid,
+ tid_t task_id,
+ qres_sid_t *server_id
+)
+{
+ return _Scheduler_CBS_Get_server_id( task_id, server_id );
+}
+
+/**
+ * @brief qres get params
+ *
+ * Retrieve QoS scheduling parameters.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_get_params (
+ qres_sid_t server_id,
+ qres_params_t *params
+)
+{
+ return _Scheduler_CBS_Get_parameters(
+ server_id,
+ (Scheduler_CBS_Parameters *) params
+ );
+}
+
+/**
+ * @brief qres set params
+ *
+ * Change QoS scheduling parameters.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_set_params (
+ qres_sid_t server_id,
+ qres_params_t *params
+)
+{
+ return _Scheduler_CBS_Set_parameters(
+ server_id,
+ (Scheduler_CBS_Parameters *) params
+ );
+}
+
+/**
+ * @brief qres get execution time
+ *
+ * Retrieve time info relative to the current server.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_get_exec_time (
+ qres_sid_t server_id,
+ qres_time_t *exec_time,
+ qres_atime_t *abs_time
+)
+{
+ return _Scheduler_CBS_Get_execution_time( server_id, exec_time, abs_time );
+}
+
+/**
+ * @brief qres get current budget
+ *
+ * Retrieve remaining budget for the current server instance.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_get_curr_budget (
+ qres_sid_t server_id,
+ qres_time_t *current_budget
+)
+{
+ return _Scheduler_CBS_Get_remaining_budget( server_id, current_budget );
+}
+
+/**
+ * @brief qres get approved budget
+ *
+ * Retrieve the budget that has been approved for the subsequent
+ * server instances.
+ *
+ * @return status code.
+ */
+RTEMS_INLINE_ROUTINE qos_rv qres_get_appr_budget (
+ qres_sid_t server_id,
+ qres_time_t *appr_budget
+)
+{
+ return _Scheduler_CBS_Get_approved_budget( server_id, appr_budget );
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/ramdisk.h b/cpukit/include/rtems/ramdisk.h
new file mode 100644
index 0000000000..727efddbe8
--- /dev/null
+++ b/cpukit/include/rtems/ramdisk.h
@@ -0,0 +1,227 @@
+/**
+ * @file
+ *
+ * @brief RAM Disk Block Device API
+ */
+
+/*
+ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
+ * Author: Victor V. Vengerov <vvv@oktet.ru>
+ */
+
+#ifndef _RTEMS_RAMDISK_H
+#define _RTEMS_RAMDISK_H
+
+
+#include <rtems.h>
+#include <rtems/blkdev.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup rtems_ramdisk RAM Disk Device
+ *
+ * @ingroup rtems_blkdev
+ *
+ */
+/**@{**/
+
+/**
+ * @name Static Configuration
+ */
+/**@{**/
+
+/**
+ * @brief RAM disk configuration table entry.
+ */
+typedef struct rtems_ramdisk_config {
+ /**
+ * @brief RAM disk block size.
+ */
+ uint32_t block_size;
+
+ /**
+ * @brief Number of blocks on this RAM disk.
+ */
+ rtems_blkdev_bnum block_num;
+
+ /**
+ * @brief RAM disk location or @c NULL if RAM disk memory should be allocated
+ * dynamically.
+ */
+ void *location;
+} rtems_ramdisk_config;
+
+/**
+ * @brief External reference to the RAM disk configuration table describing
+ * each RAM disk in the system.
+ *
+ * The configuration table is provided by the application.
+ */
+extern rtems_ramdisk_config rtems_ramdisk_configuration [];
+
+/**
+ * @brief External reference the size of the RAM disk configuration table
+ * @ref rtems_ramdisk_configuration.
+ *
+ * The configuration table size is provided by the application.
+ */
+extern size_t rtems_ramdisk_configuration_size;
+
+/**
+ * @brief RAM disk driver initialization entry point.
+ */
+rtems_device_driver ramdisk_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+);
+
+/**
+ * RAM disk driver table entry.
+ */
+#define RAMDISK_DRIVER_TABLE_ENTRY \
+ { \
+ .initialization_entry = ramdisk_initialize, \
+ RTEMS_GENERIC_BLOCK_DEVICE_DRIVER_ENTRIES \
+ }
+
+#define RAMDISK_DEVICE_BASE_NAME "/dev/rd"
+
+/** @} */
+
+/**
+ * @name Runtime Configuration
+ */
+/**@{**/
+
+/**
+ * @brief RAM disk descriptor.
+ */
+typedef struct ramdisk {
+ /**
+ * @brief RAM disk block size, the media size.
+ */
+ uint32_t block_size;
+
+ /**
+ * @brief Number of blocks on this RAM disk.
+ */
+ rtems_blkdev_bnum block_num;
+
+ /**
+ * @brief RAM disk memory area.
+ */
+ void *area;
+
+ /**
+ * @brief RAM disk is initialized.
+ */
+ bool initialized;
+
+ /**
+ * @brief Indicates if memory is allocated by malloc() for this RAM disk.
+ */
+ bool malloced;
+
+ /**
+ * @brief Trace enable.
+ */
+ bool trace;
+
+ /**
+ * @brief Free the RAM disk at the block device delete request.
+ */
+ bool free_at_delete_request;
+} ramdisk;
+
+extern const rtems_driver_address_table ramdisk_ops;
+
+int ramdisk_ioctl(rtems_disk_device *dd, uint32_t req, void *argp);
+
+/**
+ * @brief Allocates and initializes a RAM disk descriptor.
+ *
+ * The block size will be @a media_block_size. The block count will be
+ * @a media_block_count. The disk storage area begins at @a area_begin. If
+ * @a area_begin is @c NULL, the memory will be allocated and zeroed. Sets the
+ * trace enable to @a trace.
+ *
+ * @return Pointer to allocated and initialized ramdisk structure, or @c NULL
+ * if no memory is available.
+ *
+ * @note
+ * Runtime configuration example:
+ * @code
+ * #include <rtems/ramdisk.h>
+ *
+ * rtems_status_code create_ramdisk(
+ * const char *device,
+ * uint32_t media_block_size,
+ * rtems_blkdev_bnum media_block_count
+ * )
+ * {
+ * rtems_status_code sc;
+ * ramdisk *rd;
+ *
+ * rd = ramdisk_allocate(NULL, media_block_size, media_block_count, false);
+ * if (rd != NULL) {
+ * sc = rtems_blkdev_create(
+ * device,
+ * media_block_size,
+ * media_block_count,
+ * ramdisk_ioctl,
+ * rd
+ * );
+ * } else {
+ * sc = RTEMS_UNSATISFIED;
+ * }
+ *
+ * return sc;
+ * }
+ * @endcode
+ */
+ramdisk *ramdisk_allocate(
+ void *area_begin,
+ uint32_t media_block_size,
+ rtems_blkdev_bnum media_block_count,
+ bool trace
+);
+
+void ramdisk_free(ramdisk *rd);
+
+static inline void ramdisk_enable_free_at_delete_request(ramdisk *rd)
+{
+ rd->free_at_delete_request = true;
+}
+
+/**
+ * @brief Allocates, initializes and registers a RAM disk.
+ *
+ * The block size will be @a media_block_size. The block count will be
+ * @a media_block_count. The disk storage will be allocated. Sets the trace
+ * enable to @a trace. Registers a device node with disk name path @a disk.
+ * The registered device number will be returned in @a dev.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_UNSATISFIED Something is wrong.
+ */
+rtems_status_code ramdisk_register(
+ uint32_t media_block_size,
+ rtems_blkdev_bnum media_block_count,
+ bool trace,
+ const char *disk,
+ dev_t *dev
+);
+
+/** @} */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/rbheap.h b/cpukit/include/rtems/rbheap.h
new file mode 100644
index 0000000000..735aa6c8fd
--- /dev/null
+++ b/cpukit/include/rtems/rbheap.h
@@ -0,0 +1,268 @@
+/**
+ * @file
+ *
+ * @brief Red-Black Tree Heap API
+ */
+
+/*
+ * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_RBHEAP_H
+#define _RTEMS_RBHEAP_H
+
+#include <rtems.h>
+#include <rtems/chain.h>
+#include <rtems/rbtree.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup RBHeap Red-Black Tree Heap
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * @brief Red-Black Tree Heap API.
+ *
+ * The red-black tree heap provides a memory allocator suitable to implement
+ * the malloc() and free() interface. It uses a first-fit allocation strategy.
+ * In the red-black tree heap the administration data structures are not
+ * contained in the managed memory area. Thus writing beyond the boundaries of
+ * a chunk does not damage the data to maintain the heap. This can be used for
+ * example in a task stack allocator which protects the task stacks from access
+ * by other tasks. The allocated and free memory parts of the managed area are
+ * called chunks. Each chunk needs a descriptor which is stored outside of the
+ * managed area.
+ */
+/**@{*/
+
+/**
+ * @brief Red-black heap chunk descriptor.
+ */
+typedef struct {
+ /**
+ * This chain node can be used in two chains
+ * - the chain of spare chunk descriptors and
+ * - the chain of free chunks in the managed memory area.
+ *
+ * In case this chain node is not part of a chain, the chunk represents a
+ * used chunk in the managed memory area.
+ */
+ rtems_chain_node chain_node;
+
+ /**
+ * Tree node for chunks that represent a part of the managed memory area.
+ * These chunks are either free or used.
+ */
+ rtems_rbtree_node tree_node;
+
+ /**
+ * Begin address of the chunk. The address alignment it specified in the
+ * @ref rtems_rbheap_control.
+ */
+ uintptr_t begin;
+
+ /**
+ * Size of the chunk in bytes.
+ */
+ uintptr_t size;
+} rtems_rbheap_chunk;
+
+typedef struct rtems_rbheap_control rtems_rbheap_control;
+
+/**
+ * @brief Handler to extend the available chunk descriptors.
+ *
+ * This handler is called when no more chunk descriptors are available. An
+ * example implementation is this:
+ *
+ * @code
+ * void extend_descriptors_with_malloc(rtems_rbheap_control *control)
+ * {
+ * rtems_rbheap_chunk *chunk = malloc(sizeof(*chunk));
+ *
+ * if (chunk != NULL) {
+ * rtems_rbheap_add_to_spare_descriptor_chain(control, chunk);
+ * }
+ * }
+ * @endcode
+ *
+ * @see rtems_rbheap_extend_descriptors_never() and
+ * rtems_rbheap_extend_descriptors_with_malloc().
+ */
+typedef void (*rtems_rbheap_extend_descriptors)(rtems_rbheap_control *control);
+
+/**
+ * @brief Red-black heap control.
+ */
+struct rtems_rbheap_control {
+ /**
+ * Chain of free chunks in the managed memory area.
+ */
+ rtems_chain_control free_chunk_chain;
+
+ /**
+ * Chain of free chunk descriptors. Descriptors are consumed during
+ * allocation and may be produced during free if contiguous chunks can be
+ * coalesced. In case of descriptor starvation the @ref extend_descriptors
+ * handler will be called.
+ */
+ rtems_chain_control spare_descriptor_chain;
+
+ /**
+ * Tree of chunks representing the state of the managed memory area.
+ */
+ rtems_rbtree_control chunk_tree;
+
+ /**
+ * Minimum chunk begin alignment in bytes.
+ */
+ uintptr_t alignment;
+
+ /**
+ * Handler to extend the available chunk descriptors.
+ */
+ rtems_rbheap_extend_descriptors extend_descriptors;
+
+ /**
+ * User specified argument handler for private handler data.
+ */
+ void *handler_arg;
+};
+
+/**
+ * @brief Initializes the red-black tree heap @a control.
+ *
+ * @param[in, out] control The red-black tree heap.
+ * @param[in] area_begin The managed memory area begin.
+ * @param[in] area_size The managed memory area size.
+ * @param[in] alignment The minimum chunk alignment.
+ * @param[in] extend_descriptors The handler to extend the available chunk
+ * descriptors.
+ * @param[in] handler_arg The handler argument.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ADDRESS The memory area is invalid.
+ * @retval RTEMS_NO_MEMORY Not enough chunk descriptors.
+ */
+rtems_status_code rtems_rbheap_initialize(
+ rtems_rbheap_control *control,
+ void *area_begin,
+ uintptr_t area_size,
+ uintptr_t alignment,
+ rtems_rbheap_extend_descriptors extend_descriptors,
+ void *handler_arg
+);
+
+/**
+ * @brief Allocates a chunk of memory of at least @a size bytes from the
+ * red-black tree heap @a control.
+ *
+ * The chunk begin is aligned by the value specified in
+ * rtems_rbheap_initialize().
+ *
+ * @param[in, out] control The red-black tree heap.
+ * @param[in] size The requested chunk size in bytes.
+ *
+ * @retval NULL Not enough free space in the heap.
+ * @retval otherwise Pointer to allocated chunk of memory.
+ */
+void *rtems_rbheap_allocate(rtems_rbheap_control *control, size_t size);
+
+/**
+ * @brief Frees a chunk of memory @a ptr allocated from the red-black tree heap
+ * @a control.
+ *
+ * @param[in, out] control The red-black tree heap.
+ * @param[in] ptr The pointer to the chunk of memory.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID The chunk of memory is not a valid chunk in the
+ * red-black tree heap.
+ * @retval RTEMS_INCORRECT_STATE The chunk of memory is not in the right state.
+ */
+rtems_status_code rtems_rbheap_free(rtems_rbheap_control *control, void *ptr);
+
+static inline rtems_chain_control *rtems_rbheap_get_spare_descriptor_chain(
+ rtems_rbheap_control *control
+)
+{
+ return &control->spare_descriptor_chain;
+}
+
+static inline void rtems_rbheap_add_to_spare_descriptor_chain(
+ rtems_rbheap_control *control,
+ rtems_rbheap_chunk *chunk
+)
+{
+ rtems_chain_control *chain =
+ rtems_rbheap_get_spare_descriptor_chain(control);
+
+ rtems_chain_initialize_node(&chunk->chain_node);
+ rtems_chain_prepend_unprotected(chain, &chunk->chain_node);
+}
+
+static inline void rtems_rbheap_set_extend_descriptors(
+ rtems_rbheap_control *control,
+ rtems_rbheap_extend_descriptors extend_descriptors
+)
+{
+ control->extend_descriptors = extend_descriptors;
+}
+
+static inline void *rtems_rbheap_get_handler_arg(
+ const rtems_rbheap_control *control
+)
+{
+ return control->handler_arg;
+}
+
+static inline void rtems_rbheap_set_handler_arg(
+ rtems_rbheap_control *control,
+ void *handler_arg
+)
+{
+ control->handler_arg = handler_arg;
+}
+
+/**
+ * @brief Chunk descriptor extend handler that does nothing.
+ */
+void rtems_rbheap_extend_descriptors_never(rtems_rbheap_control *control);
+
+/**
+ * @brief Chunk descriptor extend handler that uses malloc().
+ */
+void rtems_rbheap_extend_descriptors_with_malloc(
+ rtems_rbheap_control *control
+);
+
+/** @} */
+
+/* Private API */
+
+#define rtems_rbheap_chunk_of_node(node) \
+ RTEMS_CONTAINER_OF(node, rtems_rbheap_chunk, tree_node)
+
+static inline bool rtems_rbheap_is_chunk_free(const rtems_rbheap_chunk *chunk)
+{
+ return !rtems_chain_is_node_off_chain(&chunk->chain_node);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_RBHEAP_H */
diff --git a/cpukit/include/rtems/rbtree.h b/cpukit/include/rtems/rbtree.h
new file mode 100644
index 0000000000..57821cf31d
--- /dev/null
+++ b/cpukit/include/rtems/rbtree.h
@@ -0,0 +1,456 @@
+/**
+ * @file
+ *
+ * @brief Constants and Structures Associated with the RBTree API in RTEMS
+ *
+ * This include file contains all the constants and structures associated
+ * with the RBTree API in RTEMS. The rbtree is a Red Black Tree that
+ * is part of the Super Core. This is the published interface to that
+ * code.
+ */
+
+/*
+ * Copyright (c) 2010 Gedare Bloom.
+ *
+ * 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_RBTREE_H
+#define _RTEMS_RBTREE_H
+
+#include <rtems/score/rbtree.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicRBTrees Red-Black Trees
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * @brief A Red-Black Tree container.
+ *
+ * The red-black tree container offers no internal protection against
+ * concurrent access. The user must ensure that at most one thread at once can
+ * access a red-black tree instance.
+ *
+ * @{
+ */
+
+/**
+ * @typedef rtems_rbtree_node
+ *
+ * A node that can be manipulated in the rbtree.
+ */
+typedef RBTree_Node rtems_rbtree_node;
+
+/**
+ * @typedef rtems_rbtree_control
+ *
+ * The rbtree's control anchors the rbtree.
+ */
+typedef RBTree_Control rtems_rbtree_control;
+
+/**
+ * @brief Integer type for compare results.
+ *
+ * The type is large enough to represent pointers and 32-bit signed integers.
+ *
+ * @see rtems_rbtree_compare.
+ */
+typedef long rtems_rbtree_compare_result;
+
+/**
+ * @brief Compares two red-black tree nodes.
+ *
+ * @param[in] first The first node.
+ * @param[in] second The second node.
+ *
+ * @retval positive The key value of the first node is greater than the one of
+ * the second node.
+ * @retval 0 The key value of the first node is equal to the one of the second
+ * node.
+ * @retval negative The key value of the first node is less than the one of the
+ * second node.
+ */
+typedef rtems_rbtree_compare_result ( *rtems_rbtree_compare )(
+ const RBTree_Node *first,
+ const RBTree_Node *second
+);
+
+/**
+ * @brief RBTree initializer for an empty rbtree with designator @a name.
+ */
+#define RTEMS_RBTREE_INITIALIZER_EMPTY(name) \
+ RBTREE_INITIALIZER_EMPTY(name)
+
+/**
+ * @brief RBTree definition for an empty rbtree with designator @a name.
+ */
+#define RTEMS_RBTREE_DEFINE_EMPTY(name) \
+ RBTREE_DEFINE_EMPTY(name)
+
+/**
+ * @brief Initialize a RBTree header.
+ *
+ * This routine initializes @a the_rbtree structure to manage the
+ * contiguous array of @a number_nodes nodes which starts at
+ * @a starting_address. Each node is of @a node_size bytes.
+ *
+ * @param[in] the_rbtree is the pointer to rbtree header
+ * @param[in] compare The node compare function.
+ * @param[in] starting_address is the starting address of first node
+ * @param[in] number_nodes is the number of nodes in rbtree
+ * @param[in] node_size is the size of node in bytes
+ * @param[in] is_unique If true, then reject nodes with a duplicate key, else
+ * otherwise.
+ */
+void rtems_rbtree_initialize(
+ rtems_rbtree_control *the_rbtree,
+ rtems_rbtree_compare compare,
+ void *starting_address,
+ size_t number_nodes,
+ size_t node_size,
+ bool is_unique
+);
+
+/**
+ * @brief Initialize this RBTree as Empty
+ *
+ * This routine initializes @a the_rbtree to contain zero nodes.
+ */
+RTEMS_INLINE_ROUTINE void rtems_rbtree_initialize_empty(
+ rtems_rbtree_control *the_rbtree
+)
+{
+ _RBTree_Initialize_empty( the_rbtree );
+}
+
+/**
+ * @brief Set off RBtree.
+ *
+ * This function sets the next and previous fields of the @a node to NULL
+ * indicating the @a node is not part of any rbtree.
+ */
+RTEMS_INLINE_ROUTINE void rtems_rbtree_set_off_tree(
+ rtems_rbtree_node *node
+)
+{
+ _RBTree_Set_off_tree( node );
+}
+
+/**
+ * @brief Is the Node off RBTree.
+ *
+ * This function returns true if the @a node is not on a rbtree. A @a node is
+ * off rbtree if the next and previous fields are set to NULL.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_rbtree_is_node_off_tree(
+ const rtems_rbtree_node *node
+)
+{
+ return _RBTree_Is_node_off_tree( node );
+}
+
+/**
+ * @brief Return pointer to RBTree root.
+ *
+ * This function returns a pointer to the root node of @a the_rbtree.
+ */
+RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_root(
+ const rtems_rbtree_control *the_rbtree
+)
+{
+ return _RBTree_Root( the_rbtree );
+}
+
+/**
+ * @copydoc _RBTree_Minimum()
+ */
+RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_min(
+ const rtems_rbtree_control *the_rbtree
+)
+{
+ return _RBTree_Minimum( the_rbtree );
+}
+
+/**
+ * @copydoc _RBTree_Maximum()
+ */
+RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_max(
+ const rtems_rbtree_control *the_rbtree
+)
+{
+ return _RBTree_Maximum( the_rbtree );
+}
+
+/**
+ * @brief Return pointer to the left child node from this node.
+ *
+ * This function returns a pointer to the left child node of @a the_node.
+ */
+RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_left(
+ const rtems_rbtree_node *the_node
+)
+{
+ return _RBTree_Left( the_node );
+}
+
+/**
+ * @brief Return pointer to the right child node from this node.
+ *
+ * This function returns a pointer to the right child node of @a the_node.
+ */
+RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_right(
+ const rtems_rbtree_node *the_node
+)
+{
+ return _RBTree_Right( the_node );
+}
+
+/**
+ * @copydoc _RBTree_Parent()
+ */
+RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_parent(
+ const rtems_rbtree_node *the_node
+)
+{
+ return _RBTree_Parent( the_node );
+}
+
+/**
+ * @brief Is the RBTree empty.
+ *
+ * This function returns true if there a no nodes on @a the_rbtree and
+ * false otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_rbtree_is_empty(
+ const rtems_rbtree_control *the_rbtree
+)
+{
+ return _RBTree_Is_empty( the_rbtree );
+}
+
+/**
+ * @brief Is this the minimum node on the RBTree.
+ *
+ * This function returns true if @a the_node is the min node on @a the_rbtree
+ * and false otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_rbtree_is_min(
+ const rtems_rbtree_control *the_rbtree,
+ const rtems_rbtree_node *the_node
+)
+{
+ return rtems_rbtree_min( the_rbtree ) == the_node;
+}
+
+/**
+ * @brief Is this the maximum node on the RBTree.
+ *
+ * This function returns true if @a the_node is the max node on @a the_rbtree
+ * and false otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_rbtree_is_max(
+ const rtems_rbtree_control *the_rbtree,
+ const rtems_rbtree_node *the_node
+)
+{
+ return rtems_rbtree_max( the_rbtree ) == the_node;
+}
+
+/**
+ * @copydoc _RBTree_Is_root()
+ */
+RTEMS_INLINE_ROUTINE bool rtems_rbtree_is_root(
+ const rtems_rbtree_node *the_node
+)
+{
+ return _RBTree_Is_root( the_node );
+}
+
+RTEMS_INLINE_ROUTINE bool rtems_rbtree_is_equal(
+ rtems_rbtree_compare_result compare_result
+)
+{
+ return compare_result == 0;
+}
+
+RTEMS_INLINE_ROUTINE bool rtems_rbtree_is_greater(
+ rtems_rbtree_compare_result compare_result
+)
+{
+ return compare_result > 0;
+}
+
+RTEMS_INLINE_ROUTINE bool rtems_rbtree_is_lesser(
+ rtems_rbtree_compare_result compare_result
+)
+{
+ return compare_result < 0;
+}
+
+/**
+ * @brief Tries to find a node for the specified key in the tree.
+ *
+ * @param[in] the_rbtree The red-black tree control.
+ * @param[in] the_node A node specifying the key.
+ * @param[in] compare The node compare function.
+ * @param[in] is_unique If true, then return the first node with a key equal to
+ * the one of the node specified if it exits, else return the last node if it
+ * exists.
+ *
+ * @retval node A node corresponding to the key. If the tree is not unique
+ * and contains duplicate keys, the set of duplicate keys acts as FIFO.
+ * @retval NULL No node exists in the tree for the key.
+ */
+rtems_rbtree_node* rtems_rbtree_find(
+ const rtems_rbtree_control *the_rbtree,
+ const rtems_rbtree_node *the_node,
+ rtems_rbtree_compare compare,
+ bool is_unique
+);
+
+/**
+ * @copydoc _RBTree_Predecessor()
+ */
+RTEMS_INLINE_ROUTINE rtems_rbtree_node* rtems_rbtree_predecessor(
+ const rtems_rbtree_node *node
+)
+{
+ return _RBTree_Predecessor( node );
+}
+
+/**
+ * @copydoc _RBTree_Successor()
+ */
+RTEMS_INLINE_ROUTINE rtems_rbtree_node* rtems_rbtree_successor(
+ const rtems_rbtree_node *node
+)
+{
+ return _RBTree_Successor( node );
+}
+
+/**
+ * @copydoc _RBTree_Extract()
+ */
+RTEMS_INLINE_ROUTINE void rtems_rbtree_extract(
+ rtems_rbtree_control *the_rbtree,
+ rtems_rbtree_node *the_node
+)
+{
+ _RBTree_Extract( the_rbtree, the_node );
+}
+
+/**
+ * @brief Gets a node with the minimum key value from the red-black tree.
+ *
+ * This function extracts a node with the minimum key value from
+ * tree and returns a pointer to that node if it exists. In case multiple
+ * nodes with a minimum key value exist, then they are extracted in FIFO order.
+ *
+ * @param[in] the_rbtree The red-black tree control.
+ *
+ * @retval NULL The tree is empty.
+ * @retval node A node with the minimal key value on the tree.
+ */
+RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_get_min(
+ rtems_rbtree_control *the_rbtree
+)
+{
+ rtems_rbtree_node *the_node = rtems_rbtree_min( the_rbtree );
+
+ if ( the_node != NULL ) {
+ rtems_rbtree_extract( the_rbtree, the_node );
+ }
+
+ return the_node;
+}
+
+/**
+ * @brief Gets a node with the maximal key value from the red-black tree.
+ *
+ * This function extracts a node with the maximum key value from tree and
+ * returns a pointer to that node if it exists. In case multiple nodes with a
+ * maximum key value exist, then they are extracted in LIFO order.
+ *
+ * @param[in] the_rbtree The red-black tree control.
+ *
+ * @retval NULL The tree is empty.
+ * @retval node A node with the maximal key value on the tree.
+ */
+RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_get_max(
+ rtems_rbtree_control *the_rbtree
+)
+{
+ rtems_rbtree_node *the_node = rtems_rbtree_max( the_rbtree );
+
+ if ( the_node != NULL ) {
+ rtems_rbtree_extract( the_rbtree, the_node );
+ }
+
+ return the_node;
+}
+
+/**
+ * @brief Peek at the min node on a rbtree.
+ *
+ * This function returns a pointer to the min node from @a the_rbtree
+ * without changing the tree. If @a the_rbtree is empty,
+ * then NULL is returned.
+ */
+RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_peek_min(
+ const rtems_rbtree_control *the_rbtree
+)
+{
+ return rtems_rbtree_min( the_rbtree );
+}
+
+/**
+ * @brief Peek at the max node on a rbtree.
+ *
+ * This function returns a pointer to the max node from @a the_rbtree
+ * without changing the tree. If @a the_rbtree is empty,
+ * then NULL is returned.
+ */
+RTEMS_INLINE_ROUTINE rtems_rbtree_node *rtems_rbtree_peek_max(
+ const rtems_rbtree_control *the_rbtree
+)
+{
+ return rtems_rbtree_max( the_rbtree );
+}
+
+/**
+ * @brief Inserts the node into the red-black tree.
+ *
+ * In case the node is already a node of a tree, then this function yields
+ * unpredictable results.
+ *
+ * @param[in] the_rbtree The red-black tree control.
+ * @param[in] the_node The node to insert.
+ * @param[in] compare The node compare function.
+ * @param[in] is_unique If true, then reject nodes with a duplicate key, else
+ * insert nodes in FIFO order in case the key value is equal to existing nodes.
+ *
+ * @retval NULL Successfully inserted.
+ * @retval existing_node This is a unique insert and there exists a node with
+ * an equal key in the tree already.
+ */
+rtems_rbtree_node *rtems_rbtree_insert(
+ RBTree_Control *the_rbtree,
+ RBTree_Node *the_node,
+ rtems_rbtree_compare compare,
+ bool is_unique
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-bitmaps.h b/cpukit/include/rtems/rfs/rtems-rfs-bitmaps.h
new file mode 100644
index 0000000000..5574339421
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-bitmaps.h
@@ -0,0 +1,326 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File Systems Bitmap Routines
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File Systems Bitmap Routines.
+ *
+ * These functions manage bit maps. A bit map consists of the map of bit
+ * allocated in a block and a search map where a bit represents 32 actual
+ * bits. The search map allows for a faster search for an available bit as 32
+ * search bits can checked in a test.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+
+#if !defined (_RTEMS_RFS_BITMAPS_H_)
+#define _RTEMS_RFS_BITMAPS_H_
+
+#include <rtems/rfs/rtems-rfs-buffer.h>
+#include <rtems/rfs/rtems-rfs-file-system-fwd.h>
+#include <rtems/rfs/rtems-rfs-trace.h>
+
+/**
+ * Define the way the bits are configured. We can have them configured as clear
+ * being 0 or clear being 1. This does not effect how masks are defined. A mask
+ * always has a 1 for set and 0 for clear.
+ */
+#define RTEMS_RFS_BITMAP_CLEAR_ZERO 0
+
+#if RTEMS_RFS_BITMAP_CLEAR_ZERO
+/*
+ * Bit set is a 1 and clear is 0.
+ */
+#define RTEMS_RFS_BITMAP_BIT_CLEAR 0
+#define RTEMS_RFS_BITMAP_BIT_SET 1
+#define RTEMS_RFS_BITMAP_ELEMENT_SET (RTEMS_RFS_BITMAP_ELEMENT_FULL_MASK)
+#define RTEMS_RFS_BITMAP_ELEMENT_CLEAR (0)
+#define RTEMS_RFS_BITMAP_SET_BITS(_t, _b) ((_t) | (_b))
+#define RTEMS_RFS_BITMAP_CLEAR_BITS(_t, _b) ((_t) & ~(_b))
+#define RTEMS_RFS_BITMAP_TEST_BIT(_t, _b) (((_t) & (1 << (_b))) != 0 ? true : false)
+#else
+/*
+ * Bit set is a 0 and clear is 1.
+ */
+#define RTEMS_RFS_BITMAP_BIT_CLEAR 1
+#define RTEMS_RFS_BITMAP_BIT_SET 0
+#define RTEMS_RFS_BITMAP_ELEMENT_SET (0)
+#define RTEMS_RFS_BITMAP_ELEMENT_CLEAR (RTEMS_RFS_BITMAP_ELEMENT_FULL_MASK)
+#define RTEMS_RFS_BITMAP_SET_BITS(_t, _b) ((_t) & ~(_b))
+#define RTEMS_RFS_BITMAP_CLEAR_BITS(_t, _b) ((_t) | (_b))
+#define RTEMS_RFS_BITMAP_TEST_BIT(_t, _b) (((_t) & (1 << (_b))) == 0 ? true : false)
+#endif
+
+/**
+ * Invert a mask. Masks are always 1 for set and 0 for clear.
+ */
+#define RTEMS_RFS_BITMAP_INVERT_MASK(_mask) (~(_mask))
+
+/**
+ * This is the full mask of the length of the element. A mask is always a 1 for
+ * set and 0 for clear. It is not effected by the state of
+ * RTEMS_RFS_BITMAP_CLEAR_ZERO.
+ */
+#define RTEMS_RFS_BITMAP_ELEMENT_FULL_MASK (0xffffffffUL)
+
+/**
+ * The bitmap search window. Searches occur around a seed in either direction
+ * for half the window.
+ */
+#define RTEMS_RFS_BITMAP_SEARCH_WINDOW (rtems_rfs_bitmap_element_bits () * 64)
+
+/**
+ * A bit in a map.
+ */
+typedef int32_t rtems_rfs_bitmap_bit;
+
+/**
+ * The basic element of a bitmap. A bitmap is manipulated by elements.
+ */
+typedef uint32_t rtems_rfs_bitmap_element;
+
+/**
+ * The power of 2 number of bits in the element.
+ */
+#define RTEMS_RFS_ELEMENT_BITS_POWER_2 (5)
+
+/**
+ * A bitmap or map is an array of bitmap elements.
+ */
+typedef rtems_rfs_bitmap_element* rtems_rfs_bitmap_map;
+
+/**
+ * The bitmap control is a simple way to manage the various parts of a bitmap.
+ */
+typedef struct rtems_rfs_bitmap_control_s
+{
+ rtems_rfs_buffer_handle* buffer; //< Handle the to buffer with the bit
+ //map.
+ rtems_rfs_file_system* fs; //< The map's file system.
+ rtems_rfs_buffer_block block; //< The map's block number on disk.
+ size_t size; //< Number of bits in the map. Passed
+ //to create.
+ size_t free; //< Number of bits in the map that are
+ //free (clear).
+ rtems_rfs_bitmap_map search_bits; //< The search bit map memory.
+} rtems_rfs_bitmap_control;
+
+/**
+ * Return the number of bits for the number of bytes provided.
+ */
+#define rtems_rfs_bitmap_numof_bits(_bytes) (8 * (_bytes))
+
+/**
+ * Return the number of bits for the number of bytes provided. The search
+ * element and the element must have the same number of bits.
+ */
+#define rtems_rfs_bitmap_element_bits() \
+ rtems_rfs_bitmap_numof_bits (sizeof (rtems_rfs_bitmap_element))
+
+/**
+ * Return the number of bits a search element covers.
+ */
+#define rtems_rfs_bitmap_search_element_bits() \
+ (rtems_rfs_bitmap_element_bits() * rtems_rfs_bitmap_element_bits())
+
+/**
+ * Return the number of elements for a given number of bits.
+ */
+#define rtems_rfs_bitmap_elements(_bits) \
+ ((((_bits) - 1) / rtems_rfs_bitmap_element_bits()) + 1)
+
+/**
+ * Release the bitmap buffer back to the buffer pool or cache.
+ */
+#define rtems_rfs_bitmap_release_buffer(_fs, _bm) \
+ rtems_rfs_buffer_handle_release (_fs, (_bm)->buffer)
+
+/**
+ * Return the element index for a given bit. We use a macro to hide any
+ * implementation assuptions. Typically this would be calculated by dividing
+ * the bit index by the number of bits in an element. Given we have a power of
+ * 2 as the number of bits we can avoid the division by using a shift. A good
+ * compiler should figure this out but I would rather enforce this than rely on
+ * the specific backend of a compiler to do the right thing.
+ */
+#define rtems_rfs_bitmap_map_index(_b) \
+ ((_b) >> RTEMS_RFS_ELEMENT_BITS_POWER_2)
+
+/**
+ * Return the bit offset for a given bit in an element in a map. See @ref
+ * rtems_rfs_bitmap_map_index for a detailed reason why.
+ */
+#define rtems_rfs_bitmap_map_offset(_b) \
+ ((_b) & ((1 << RTEMS_RFS_ELEMENT_BITS_POWER_2) - 1))
+
+/**
+ * Return the size of the bitmap.
+ */
+#define rtems_rfs_bitmap_map_size(_c) ((_c)->size)
+
+/**
+ * Return the number of free bits in the bitmap.
+ */
+#define rtems_rfs_bitmap_map_free(_c) ((_c)->free)
+
+/**
+ * Return the buffer handle.
+ */
+#define rtems_rfs_bitmap_map_handle(_c) ((_c)->buffer)
+
+/**
+ * Return the bitmap map block.
+ */
+#define rtems_rfs_bitmap_map_block(_c) ((_c)->block)
+
+/**
+ * Create a bit mask with the specified number of bits up to an element's
+ * size. The mask is aligned to bit 0 of the element.
+ *
+ * @param[in] size is the number of bits in the mask.
+ *
+ * @return The mask of the argument size number of bits.
+ */
+rtems_rfs_bitmap_element rtems_rfs_bitmap_mask (unsigned int size);
+
+/**
+ * Create a bit mask section. A mask section is a mask that is not aligned to
+ * an end of the element.
+ *
+ * @param[in] start is the first bit of the mask numbered from 0.
+ * @param[in] end is the end bit of the mask numbered from 0.
+ *
+ * @return Mask section as defined by the start and end arguments.
+ */
+rtems_rfs_bitmap_element rtems_rfs_bitmap_mask_section (unsigned int start,
+ unsigned int end);
+
+/**
+ * Set a bit in a map and if all the bits are set, set the search map bit as
+ * well.
+ *
+ * @param[in] control is the control for the map.
+ * @param[in] bit is the bit in the map to set.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_bitmap_map_set (rtems_rfs_bitmap_control* control,
+ rtems_rfs_bitmap_bit bit);
+
+/**
+ * Clear a bit in a map and make sure the search map bit is clear so a search
+ * will find this bit available.
+ *
+ * @param[in] control is the control for the map.
+ * @param[in] bit is the bit in the map to clear.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_bitmap_map_clear (rtems_rfs_bitmap_control* control,
+ rtems_rfs_bitmap_bit bit);
+
+/**
+ * Test a bit in the map.
+ *
+ * @param[in] control is the bitmap control.
+ * @param[in] bit is the bit to test.
+ * @param[in] state is the state of the bit if no error is returned.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int
+rtems_rfs_bitmap_map_test (rtems_rfs_bitmap_control* control,
+ rtems_rfs_bitmap_bit bit,
+ bool* state);
+
+/**
+ * Set all bits in the bitmap and set the dirty bit.
+ *
+ * @param[in] control is the bitmap control.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_bitmap_map_set_all (rtems_rfs_bitmap_control* control);
+
+/**
+ * Clear all bits in the bitmap and set the dirty bit.
+ *
+ * @param[in] control is the bitmap control.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_bitmap_map_clear_all (rtems_rfs_bitmap_control* control);
+
+/**
+ * Find a free bit searching from the seed up and down until found. The search
+ * is performing by moving up from the seed for the window distance then to
+ * search down from the seed for the window distance. This is repeated out
+ * from the seed for each window until a free bit is found. The search is
+ * performed by checking the search map to see if the map has a free bit.
+ *
+ * @param[in] control is the map control.
+ * @param[in] seed is the bit to search out from.
+ * @param[out] allocate A bit was allocated.
+ * @param[out] bit will contain the bit found free if true is returned.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_bitmap_map_alloc (rtems_rfs_bitmap_control* control,
+ rtems_rfs_bitmap_bit seed,
+ bool* allocate,
+ rtems_rfs_bitmap_bit* bit);
+
+/**
+ * Create a search bit map from the actual bit map.
+ *
+ * @param[in] control is the map control.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_bitmap_create_search (rtems_rfs_bitmap_control* control);
+
+/**
+ * Open a bitmap control with a map and search map.
+ *
+ * @param[in] control is the map control.
+ * @param[in] fs is the file system data.
+ * @param[in] buffer is a pointer to the buffer handle the map is
+ * stored in.
+ * @param[in] size is the number of bits in the map.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_bitmap_open (rtems_rfs_bitmap_control* control,
+ rtems_rfs_file_system* fs,
+ rtems_rfs_buffer_handle* buffer,
+ size_t size,
+ rtems_rfs_buffer_block block);
+
+/**
+ * Close a bitmap.
+ *
+ * @param[in] control is the bit map control.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_bitmap_close (rtems_rfs_bitmap_control* control);
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-block-pos.h b/cpukit/include/rtems/rfs/rtems-rfs-block-pos.h
new file mode 100644
index 0000000000..7d0f0693be
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-block-pos.h
@@ -0,0 +1,242 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File Systems Block Position and Size Management
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File Systems Block Position and Size Management.
+ *
+ * These functions manage the position in a block map as well as a size of data
+ * held in a block map. The position is the block count plus the offset into
+ * the last block where a block position of 0 and an offset of 0 is the start
+ * of a map. The size has a block count plus an offset, but the offset into the
+ * last block gives the actual size of the data in the map. This means a size
+ * will always have a block count greater than 0 when the file is not empty. A
+ * size offset of 0 and a non-zero block count means the length if aligned to
+ * the end of the block. For this reason there are 2 similar types so we know
+ * which set of rules are in use and the reason for this file.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+#if !defined (_RTEMS_RFS_BLOCK_POS_H_)
+#define _RTEMS_RFS_BLOCK_POS_H_
+
+#include <rtems/rfs/rtems-rfs-file-system.h>
+#include <rtems/rfs/rtems-rfs-inode.h>
+
+/**
+ * The block number is the same type as the inode block number. This makes sure
+ * the sizes of the types match.
+ */
+typedef rtems_rfs_inode_block rtems_rfs_block_no;
+
+/**
+ * The offset into a block.
+ */
+typedef uint32_t rtems_rfs_block_off;
+
+/**
+ * A block position is a block number times the block size plus the offset. The
+ * block field can be used hold a block number for the position as a look up
+ * cache.
+ */
+typedef struct rtems_rfs_block_pos_s
+{
+ /**
+ * The block index in the map. Range is from 0 to the maps block count minus
+ * 1.
+ */
+ rtems_rfs_block_no bno;
+
+ /**
+ * The offset into the block. Must be less than the block size.
+ */
+ rtems_rfs_block_off boff;
+
+ /**
+ * The block number that the bpos + boff map to. The 0 value is invalid and
+ * means no block number has been set.
+ */
+ rtems_rfs_block_no block;
+
+} rtems_rfs_block_pos;
+
+/**
+ * Copy a block position.
+ *
+ * @param[in] _lhs is the left hand side.
+ * @param[in] _rhs is the right hand side.
+ */
+#define rtems_rfs_block_copy_bpos(_lhs, _rhs) \
+ do { (_lhs)->bno = (_rhs)->bno; \
+ (_lhs)->boff = (_rhs)->boff; \
+ (_lhs)->block = (_rhs)->block; } while (0)
+
+/**
+ * Zero a block position.
+ *
+ * @param[in] bpos is a pointer to the block position.
+ */
+static inline void
+rtems_rfs_block_set_bpos_zero (rtems_rfs_block_pos* bpos)
+{
+ bpos->bno = 0;
+ bpos->boff = 0;
+ bpos->block = 0;
+}
+
+/**
+ * Given a position compute the block number and block offset.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] pos is the position as an absolute offset from the start.
+ * @param[out] bpos is a pointer to the block position to fill in.
+ */
+void rtems_rfs_block_get_bpos (rtems_rfs_file_system* fs,
+ rtems_rfs_pos pos,
+ rtems_rfs_block_pos* bpos);
+
+/**
+ * Given a block position compute the absolute offset.
+ *
+ * @param[in] fs is the file system data.
+ * @param[out] bpos is a pointer to the block position to fill in.
+ *
+ * @retval offset The absolute offset.
+ */
+rtems_rfs_pos rtems_rfs_block_get_pos (rtems_rfs_file_system* fs,
+ rtems_rfs_block_pos* bpos);
+
+/**
+ * Add the relative position to the block position. The relative position is
+ * signed.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] offset is the relative offset add to the block position.
+ * @param[out] bpos is a pointer to the block position to fill in.
+ */
+static inline void
+rtems_rfs_block_add_pos (rtems_rfs_file_system* fs,
+ rtems_rfs_pos_rel offset,
+ rtems_rfs_block_pos* bpos)
+{
+ rtems_rfs_block_get_bpos (fs,
+ rtems_rfs_block_get_pos (fs, bpos) + offset,
+ bpos);
+ bpos->block = 0;
+}
+
+/**
+ * A block size is the number of blocks less one plus the offset where the
+ * offset must be less than the block size.
+ */
+typedef struct rtems_rfs_block_size_s
+{
+ /**
+ * The count of blocks in a map. A 0 means no blocks and a zero length and
+ * the offset should also be 0.
+ */
+ rtems_rfs_block_no count;
+
+ /**
+ * The offset into the block. An offset of 0 means block size, ie the first
+ * byte of the next block which is not allocated.
+ */
+ rtems_rfs_block_off offset;
+
+} rtems_rfs_block_size;
+
+/**
+ * Copy a block size.
+ *
+ * @param[in] _lhs is the left hand side.
+ * @param[in] _rhs is the right hand side.
+ */
+#define rtems_rfs_block_copy_size(_lhs, _rhs) \
+ do { (_lhs)->count = (_rhs)->count; \
+ (_lhs)->offset = (_rhs)->offset; } while (0)
+
+/**
+ * Last block ?
+ */
+#define rtems_rfs_block_pos_last_block(_p, _s) \
+ ((((_p)->bno == 0) && ((_s)->count == 0)) || ((_p)->bno == ((_s)->count - 1)))
+
+/**
+ * Last block ?
+ */
+#define rtems_rfs_block_pos_past_end(_p, _s) \
+ (((_p)->bno && ((_s)->count == 0)) || \
+ ((_p)->bno >= (_s)->count) || \
+ (((_p)->bno == ((_s)->count - 1)) && ((_p)->boff > (_s)->offset)))
+
+/**
+ * Is the block position past the end.
+ */
+#define rtems_rfs_block_pos_block_past_end(_p, _s) \
+ (((_p)->bno && ((_s)->count == 0)) || ((_p)->bno >= (_s)->count))
+
+/**
+ * Copy the size to the block position. Note the block position and the size
+ * have different block counts.
+ */
+#define rtems_rfs_block_size_get_bpos(_s, _b) \
+ do { (_b)->bno = (_s)->count; \
+ (_b)->boff = (_s)->offset; \
+ (_b)->block = 0; \
+ if ((_b)->boff) --(_b)->bno; } while (0)
+
+/**
+ * Do the sizes match ?
+ */
+#define rtems_rfs_block_size_equal(_lhs, _rhs) \
+ (((_lhs)->count == (_rhs)->count) && ((_lhs)->offset == (_rhs)->offset))
+
+/**
+ * Zero a block size.
+ *
+ * @param[in] size is a pointer to the block size.
+ */
+static inline void
+rtems_rfs_block_set_size_zero (rtems_rfs_block_size* size)
+{
+ size->count = 0;
+ size->offset = 0;
+}
+
+/**
+ * Set the size given a position.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] pos is the position as an absolute offset from the start.
+ * @param[out] size is a pointer to the block size to fill in.
+ */
+void rtems_rfs_block_get_block_size (rtems_rfs_file_system* fs,
+ rtems_rfs_pos pos,
+ rtems_rfs_block_size* size);
+
+/**
+ * Calculate the position given the number of blocks and the offset. If the
+ * block count is 0 the size is 0. If the block is greater than 0 and the
+ * offset is 0 the size is number of blocks multipled by the block size and if
+ * the offset is not 0 it is the offset into the last block. For example if
+ * blocks is 1 and offset is 0 the size is the block size. If the block count
+ * is 1 and size is 100 the size is 100.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] size The size in blocks and offset.
+ *
+ * @retval size The size in bytes.
+ */
+rtems_rfs_pos rtems_rfs_block_get_size (rtems_rfs_file_system* fs,
+ rtems_rfs_block_size* size);
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-block.h b/cpukit/include/rtems/rfs/rtems-rfs-block.h
new file mode 100644
index 0000000000..394853b7ad
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-block.h
@@ -0,0 +1,344 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File Systems Block Management
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File Systems Block Management.
+ *
+ * These functions manage the blocks used in the file system.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+
+#if !defined (_RTEMS_RFS_BLOCK_H_)
+#define _RTEMS_RFS_BLOCK_H_
+
+#include <rtems/rfs/rtems-rfs-block-pos.h>
+#include <rtems/rfs/rtems-rfs-buffer.h>
+#include <rtems/rfs/rtems-rfs-data.h>
+#include <rtems/rfs/rtems-rfs-file-system.h>
+
+/**
+ * Get a block number in the media format and return it in the host format.
+ *
+ * @param[in] _h is the buffer handle of the block.
+ * @param[in] _b is the block number index.
+ *
+ * @retval block The block number.
+ */
+#define rtems_rfs_block_get_number(_h, _b) \
+ ((rtems_rfs_block_no) \
+ (rtems_rfs_read_u32 (rtems_rfs_buffer_data (_h) + \
+ ((_b) * sizeof (rtems_rfs_block_no)))))
+
+/**
+ * Set a block number in the media format given a number in the host format.
+ *
+ * @param[in] _h is the buffer handle of the block.
+ * @param[in] _b is the block number index, ie the number of block number not the
+ * buffer offset.
+ * @param[in] _n is the block number.
+ */
+#define rtems_rfs_block_set_number(_h, _b, _n) \
+ do { \
+ rtems_rfs_write_u32 (rtems_rfs_buffer_data (_h) + \
+ ((_b) * sizeof (rtems_rfs_block_no)), (_n)); \
+ rtems_rfs_buffer_mark_dirty (_h); \
+ } while (0)
+
+/**
+ * A block map manges the block lists that originate from an inode. The inode
+ * contains a number of block numbers. A block map takes those block numbers
+ * and manages them.
+ *
+ * The blocks cannot have all ones as a block number nor block 0. The block map
+ * is series of block numbers in a blocks. The size of the map determines the
+ * way the block numbers are stored. The map uses the following:
+ *
+ * @li @e Direct Access,
+ * @li @e Single Indirect Access, and
+ * @li @e Double Indirect Access.
+ *
+ * Direct access has the blocks numbers in the inode slots. The Single Indirect
+ * Access has block numbers in the inode slots that pointer to a table of block
+ * numbers that point to data blocks. The Double Indirect Access has block
+ * numbers in the inode that point to Single Indirect block tables.
+ *
+ * The inode can hold a number of Direct, Single Indirect, and Double Indirect
+ * block tables. The move from Direct to Single occurs then the block count in
+ * the map is above the number of slots in the inode. The move from Single to
+ * Double occurs when the map block count is greated than the block numbers per
+ * block multipled by the slots in the inode. The move from Single to Double
+ * occurs when the map block count is over the block numbers per block squared
+ * multipled by the number of slots in the inode.
+ *
+ * The block map can managed files of the follow size verses block size with 5
+ * inode slots:
+ *
+ * @li 41,943,040 bytes for a 512 byte block size,
+ * @li 335,544,320 bytes for a 1024 byte block size,
+ * @li 2,684,354,560 bytes for a 2048 byte block size, and
+ * @li 21,474,836,480 bytes for a 4096 byte block size.
+ */
+typedef struct rtems_rfs_block_map_s
+{
+ /**
+ * Is the map dirty ?
+ */
+ bool dirty;
+
+ /**
+ * The inode this map is attached to.
+ */
+ rtems_rfs_inode_handle* inode;
+
+ /**
+ * The size of the map.
+ */
+ rtems_rfs_block_size size;
+
+ /**
+ * The block map position. Used to navigate the map when seeking. The find
+ * call is to a position in the file/directory and is a block number plus
+ * offset. The block find only needs to locate a block and not worry about
+ * the offset while a seek can be less than a block size yet move across a
+ * block boundary. Therefore the position a block map has to maintain must
+ * include the offset so seeks work.
+ */
+ rtems_rfs_block_pos bpos;
+
+ /**
+ * The last map block allocated. This is used as the goal when allocating a
+ * new map block.
+ */
+ rtems_rfs_block_no last_map_block;
+
+ /**
+ * The last data block allocated. This is used as the goal when allocating a
+ * new data block.
+ */
+ rtems_rfs_block_no last_data_block;
+
+ /**
+ * The block map.
+ */
+ uint32_t blocks[RTEMS_RFS_INODE_BLOCKS];
+
+ /**
+ * Singly Buffer handle.
+ */
+ rtems_rfs_buffer_handle singly_buffer;
+
+ /**
+ * Doubly Buffer handle.
+ */
+ rtems_rfs_buffer_handle doubly_buffer;
+
+} rtems_rfs_block_map;
+
+/**
+ * Is the map dirty ?
+ */
+#define rtems_rfs_block_map_is_dirty(_m) ((_m)->dirty)
+
+/**
+ * Return the block count in the map.
+ */
+#define rtems_rfs_block_map_count(_m) ((_m)->size.count)
+
+/**
+ * Return the map's size element.
+ */
+#define rtems_rfs_block_map_size(_m) (&((_m)->size))
+
+/**
+ * Return the size offset for the map.
+ */
+#define rtems_rfs_block_map_size_offset(_m) ((_m)->size.offset)
+
+/**
+ * Are we at the last block in the map ?
+ */
+#define rtems_rfs_block_map_last(_m) \
+ rtems_rfs_block_pos_last_block (&(_m)->bpos, &(_m)->size)
+
+/**
+ * Is the position past the end of the block ?
+ */
+#define rtems_rfs_block_map_past_end(_m, _p) \
+ rtems_rfs_block_pos_past_end (_p, &(_m)->size)
+
+/**
+ * Return the current position in the map.
+ */
+#define rtems_rfs_block_map_pos(_f, _m) \
+ rtems_rfs_block_get_pos (_f, &(_m)->bpos)
+
+/**
+ * Return the map's current block number.
+ */
+#define rtems_rfs_block_map_block(_m) ((_m)->bpos.bno)
+
+/**
+ * Return the map's current block offset.
+ */
+#define rtems_rfs_block_map_block_offset(_m) ((_m)->bpos.boff)
+
+/**
+ * Set the size offset for the map. The map is tagged as dirty.
+ *
+ * @param[in] map is a pointer to the open map to set the offset in.
+ * @param[in] offset is the offset to set in the map's size.
+ */
+static inline void
+rtems_rfs_block_map_set_size_offset (rtems_rfs_block_map* map,
+ rtems_rfs_block_off offset)
+{
+ map->size.offset = offset;
+ map->dirty = true;
+}
+
+/**
+ * Set the map's size. The map is tagged as dirty.
+ *
+ * @param[in] map is a pointer to the open map to set the offset in.
+ * @param[in] size is the size to set in the map's size.
+ */
+static inline void
+rtems_rfs_block_map_set_size (rtems_rfs_block_map* map,
+ rtems_rfs_block_size* size)
+{
+ rtems_rfs_block_copy_size (&map->size, size);
+ map->dirty = true;
+}
+/**
+ * Open a block map. The block map data in the inode is copied into the
+ * map. The buffer handles are opened. The block position is set to the start
+ * so a seek of offset 0 will return the first block.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] inode is a pointer to the inode the map belongs to.
+ * @param[in] map is a pointer to the map that is opened.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_block_map_open (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* inode,
+ rtems_rfs_block_map* map);
+
+/**
+ * Close the map. The buffer handles are closed and any help buffers are
+ * released.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] map is a pointer to the map that is opened.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_block_map_close (rtems_rfs_file_system* fs,
+ rtems_rfs_block_map* map);
+
+/**
+ * Find a block number in the map from the position provided.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] map is a pointer to the map to search.
+ * @param[in] bpos is a pointer to the block position to find.
+ * @param[out] block will contain the block in when found.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_block_map_find (rtems_rfs_file_system* fs,
+ rtems_rfs_block_map* map,
+ rtems_rfs_block_pos* bpos,
+ rtems_rfs_buffer_block* block);
+
+/**
+ * Seek around the map.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] map is a pointer to the map to search.
+ * @param[in] offset is the distance to seek. It is signed.
+ * @param[out] block will contain the block in when found.
+ *
+ * @retval 0 Successful operation.
+ * @retval ENXIO Failed to seek because it is outside the block map.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_block_map_seek (rtems_rfs_file_system* fs,
+ rtems_rfs_block_map* map,
+ rtems_rfs_pos_rel offset,
+ rtems_rfs_buffer_block* block);
+
+/**
+ * Seek to the next block.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] map is a pointer to the map to search.
+ * @param[out] block will contain the block in when found.
+ *
+ * @retval 0 Successful operation.
+ * @retval ENXIO Failed to seek because it is outside the block map.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_block_map_next_block (rtems_rfs_file_system* fs,
+ rtems_rfs_block_map* map,
+ rtems_rfs_buffer_block* block);
+
+/**
+ * Grow the block map by the specified number of blocks.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] map is a pointer to the open map to grow.
+ * @param[in] blocks is the number of blocks to grow the map by.
+ * @param[out] new_block will contain first of the blocks allocated
+ * to the map.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_block_map_grow (rtems_rfs_file_system* fs,
+ rtems_rfs_block_map* map,
+ size_t blocks,
+ rtems_rfs_block_no* new_block);
+
+/**
+ * Grow the block map by the specified number of blocks.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] map is a pointer to the open map to shrink.
+ * @param[in] blocks is the number of blocks to shrink the map by. If more
+ * than the number of blocks the map is emptied.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_block_map_shrink (rtems_rfs_file_system* fs,
+ rtems_rfs_block_map* map,
+ size_t blocks);
+
+/**
+ * Free all blocks in the map.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] map is a pointer to the open map to free all blocks from.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_block_map_free_all (rtems_rfs_file_system* fs,
+ rtems_rfs_block_map* map);
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-buffer.h b/cpukit/include/rtems/rfs/rtems-rfs-buffer.h
new file mode 100644
index 0000000000..1c603e1827
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-buffer.h
@@ -0,0 +1,283 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_rfs
+ *
+ * @brief Maps Blocks to the Media Interface Layers
+ *
+ * These functions map blocks to the media interface layers.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+
+#if !defined (_RTEMS_RFS_BUFFER_H_)
+#define _RTEMS_RFS_BUFFER_H_
+
+#include <errno.h>
+
+#include <rtems/rfs/rtems-rfs-file-system-fwd.h>
+#include <rtems/rfs/rtems-rfs-trace.h>
+
+/**
+ * Define the method used to interface to the buffers. It can be libblock or
+ * device I/O. The libblock interface is to the RTEMS cache and block devices
+ * and device I/O accesses the media via a device file handle.
+ */
+#if defined (__rtems__)
+#define RTEMS_RFS_USE_LIBBLOCK 1
+#endif
+
+/**
+ * The RTEMS RFS I/O Layering.
+ */
+#if RTEMS_RFS_USE_LIBBLOCK
+#include <rtems/bdbuf.h>
+#include <rtems/error.h>
+
+typedef rtems_blkdev_bnum rtems_rfs_buffer_block;
+typedef rtems_bdbuf_buffer rtems_rfs_buffer;
+#define rtems_rfs_buffer_io_request rtems_rfs_buffer_bdbuf_request
+#define rtems_rfs_buffer_io_release rtems_rfs_buffer_bdbuf_release
+
+/**
+ * Request a buffer from the RTEMS libblock BD buffer cache.
+ */
+int rtems_rfs_buffer_bdbuf_request (rtems_rfs_file_system* fs,
+ rtems_rfs_buffer_block block,
+ bool read,
+ rtems_rfs_buffer** buffer);
+/**
+ * Release a buffer to the RTEMS libblock BD buffer cache.
+ */
+int rtems_rfs_buffer_bdbuf_release (rtems_rfs_buffer* handle,
+ bool modified);
+#else /* Device I/O */
+typedef uint32_t rtems_rfs_buffer_block;
+typedef struct _rtems_rfs_buffer
+{
+ rtems_chain_node link;
+ rtems_rfs_buffer_block user;
+ void* buffer;
+ size_t size;
+ uint32_t references;
+} rtems_rfs_buffer;
+#define rtems_rfs_buffer_io_request rtems_rfs_buffer_deviceio_request
+#define rtems_rfs_buffer_io_release rtems_rfs_buffer_deviceio_release
+
+/**
+ * Request a buffer from the device I/O.
+ */
+int rtems_rfs_buffer_deviceio_request (rtems_rfs_file_system* fs,
+ rtems_rfs_buffer_block block,
+ bool read,
+ rtems_rfs_buffer* buffer);
+/**
+ * Release a buffer to the RTEMS libblock BD buffer cache.
+ */
+int rtems_rfs_buffer_deviceio_release (rtems_rfs_buffer* handle,
+ bool modified);
+#endif
+
+/**
+ * RFS Buffer handle.
+ */
+typedef struct rtems_rfs_buffer_handle_t
+{
+ /**
+ * Has the buffer been modifed?
+ */
+ bool dirty;
+
+ /**
+ * Block number. The lower layer block number may be absolute and we maybe
+ * relative to an offset in the disk so hold locally.
+ */
+ rtems_rfs_buffer_block bnum;
+
+ /**
+ * Reference the buffer descriptor.
+ */
+ rtems_rfs_buffer* buffer;
+
+} rtems_rfs_buffer_handle;
+
+/**
+ * The buffer linkage.
+ */
+#define rtems_rfs_buffer_link(_h) (&(_h)->buffer->link)
+
+/**
+ * Return the start of the data area of the buffer given a handle.
+ */
+#define rtems_rfs_buffer_data(_h) ((void*)((_h)->buffer->buffer))
+
+/**
+ * Return the size of the buffer given a handle.
+ */
+#define rtems_rfs_buffer_size(_h) ((_h)->buffer->size)
+
+/**
+ * Return the block number.
+ */
+#define rtems_rfs_buffer_bnum(_h) ((_h)->bnum)
+
+/**
+ * Return the buffer dirty status.
+ */
+#define rtems_rfs_buffer_dirty(_h) ((_h)->dirty)
+
+/**
+ * Does the handle have a valid block attached ?
+ */
+#define rtems_rfs_buffer_handle_has_block(_h) ((_h)->buffer ? true : false)
+
+/**
+ * Mark the buffer as dirty.
+ */
+#define rtems_rfs_buffer_mark_dirty(_h) ((_h)->dirty = true)
+
+/**
+ * Return the reference count.
+ */
+#define rtems_rfs_buffer_refs(_h) ((_h)->buffer->references)
+
+/**
+ * Increment the reference count.
+ */
+#define rtems_rfs_buffer_refs_up(_h) ((_h)->buffer->references += 1)
+
+/**
+ * Decrement the reference count.
+ */
+#define rtems_rfs_buffer_refs_down(_h) ((_h)->buffer->references -= 1)
+
+/**
+ * Request a buffer. The buffer can be filled with data from the media
+ * (read == true) or you can request a buffer to fill with data.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] handle is the handle the requested buffer is attached to.
+ * @param[in] block is the block number.
+ * @param[in] read Read the data from the disk.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_buffer_handle_request (rtems_rfs_file_system* fs,
+ rtems_rfs_buffer_handle* handle,
+ rtems_rfs_buffer_block block,
+ bool read);
+
+/**
+ * Release a buffer. If the buffer is dirty the buffer is written to disk. The
+ * result does not indicate if the data was successfully written to the disk as
+ * this operation may be performed in asynchronously to this release.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] handle is the handle the requested buffer is attached to.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_buffer_handle_release (rtems_rfs_file_system* fs,
+ rtems_rfs_buffer_handle* handle);
+
+/**
+ * Open a handle.
+ *
+ * @param[in] fs i the file system data.
+ * @param[in] handle i the buffer handle to open.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+static inline int
+rtems_rfs_buffer_handle_open (rtems_rfs_file_system* fs,
+ rtems_rfs_buffer_handle* handle)
+{
+ handle->dirty = false;
+ handle->bnum = 0;
+ handle->buffer = NULL;
+ return 0;
+}
+
+/**
+ * Close a handle.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] handle is the buffer handle to close.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+static inline int
+rtems_rfs_buffer_handle_close (rtems_rfs_file_system* fs,
+ rtems_rfs_buffer_handle* handle)
+{
+ rtems_rfs_buffer_handle_release (fs, handle);
+ handle->dirty = false;
+ handle->bnum = 0;
+ handle->buffer = NULL;
+ return 0;
+}
+
+/**
+ * Open the buffer interface.
+ *
+ * @param[in] name is a pointer to the device name to the media.
+ * @param[in] fs is the file system data.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_buffer_open (const char* name, rtems_rfs_file_system* fs);
+
+/**
+ * Close the buffer interface.
+ *
+ * @param[in] fs is the file system data.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_buffer_close (rtems_rfs_file_system* fs);
+
+/**
+ * Sync all buffers to the media.
+ *
+ * @param[in] fs is the file system data.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_buffer_sync (rtems_rfs_file_system* fs);
+
+/**
+ * Set the block size of the device.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] size is the new block size.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_buffer_setblksize (rtems_rfs_file_system* fs, uint32_t size);
+
+/**
+ * Release any chained buffers.
+ *
+ * @param[in] fs is the file system data.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_buffers_release (rtems_rfs_file_system* fs);
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-data.h b/cpukit/include/rtems/rfs/rtems-rfs-data.h
new file mode 100644
index 0000000000..6217e74587
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-data.h
@@ -0,0 +1,89 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File System Data
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File System Data.
+ *
+ * Access data in the correct byte order for the specific target we are running
+ * on.
+ *
+ * @todo Make direct access on matching byte ordered targets.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+
+#if !defined (_RTEMS_RFS_DATA_H_)
+#define _RTEMS_RFS_DATA_H_
+
+#include <stdint.h>
+
+/**
+ * Helper function to make sure we have a byte pointer.
+ */
+#define rtems_rfs_data_ptr(_d) ((uint8_t*)(_d))
+
+/**
+ * Helper function to get the data shifted in the correctly sized type.
+ */
+#define rtems_rfs_data_get(_d, _t, _o, _s) \
+ (((_t)(rtems_rfs_data_ptr (_d)[_o])) << (_s))
+
+/**
+ * RFS Read Unsigned 8bit Integer
+ */
+#define rtems_rfs_read_u8(_d) \
+ (*rtems_rfs_data_ptr (_d))
+
+/**
+ * RFS Read Unsigned 16bit Integer
+ */
+#define rtems_rfs_read_u16(_d) \
+ (rtems_rfs_data_get (_d, uint16_t, 0, 8) | \
+ rtems_rfs_data_get (_d, uint16_t, 1, 0))
+
+/**
+ * RFS Read Unsigned 32bit Integer
+ */
+#define rtems_rfs_read_u32(_d) \
+ (rtems_rfs_data_get (_d, uint32_t, 0, 24) | \
+ rtems_rfs_data_get (_d, uint32_t, 1, 16) | \
+ rtems_rfs_data_get (_d, uint32_t, 2, 8) | \
+ rtems_rfs_data_get (_d, uint32_t, 3, 0))
+
+/**
+ * RFS Write Unsigned 8bit Integer
+ */
+#define rtems_rfs_write_u8(_d, _v) \
+ (*rtems_rfs_data_ptr (_d) = (uint8_t)(_v))
+
+/**
+ * RFS Write Unsigned 16bit Integer
+ */
+#define rtems_rfs_write_u16(_d, _v) \
+ do { \
+ rtems_rfs_data_ptr (_d)[0] = (uint8_t)(((uint16_t)(_v)) >> 8); \
+ rtems_rfs_data_ptr (_d)[1] = (uint8_t)((_v)); \
+ } while (0)
+
+/**
+ * RFS Write Unsigned 32bit Integer
+ */
+#define rtems_rfs_write_u32(_d, _v) \
+ do { \
+ rtems_rfs_data_ptr (_d)[0] = (uint8_t)(((uint32_t)(_v)) >> 24); \
+ rtems_rfs_data_ptr (_d)[1] = (uint8_t)(((uint32_t)(_v)) >> 16); \
+ rtems_rfs_data_ptr (_d)[2] = (uint8_t)(((uint32_t)(_v)) >> 8); \
+ rtems_rfs_data_ptr (_d)[3] = (uint8_t)((uint32_t)(_v)); \
+ } while (0)
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-dir-hash.h b/cpukit/include/rtems/rfs/rtems-rfs-dir-hash.h
new file mode 100644
index 0000000000..d9a8a2004f
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-dir-hash.h
@@ -0,0 +1,36 @@
+/**
+ * @file
+ *
+ * @brief Provides a 32bit Hash of a String used to Search a Directory
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File Systems Directory Hash provides a 32bit hash of a string. This is
+ * used to search a directory.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+#if !defined (_RTEMS_RFS_DIR_HASH_H_)
+#define _RTEMS_RFS_DIR_HAS_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+/**
+ * Compute a hash of the key over the length of string.
+ *
+ * @param[in] key is a pointer to the key to calculate the hash of.
+ * @param[in] length is the length of the key in bytes.
+ *
+ * @retval hash The computed uint32_t hash.
+ */
+uint32_t rtems_rfs_dir_hash (const void *key, size_t length);
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-dir.h b/cpukit/include/rtems/rfs/rtems-rfs-dir.h
new file mode 100644
index 0000000000..ae3647d03c
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-dir.h
@@ -0,0 +1,209 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File System Directory Support
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File System Directory Support
+ *
+ * This file provides the directory support functions.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+#if !defined (_RTEMS_RFS_DIR_H_)
+#define _RTEMS_RFS_DIR_H_
+
+#include <dirent.h>
+
+#include <rtems/libio_.h>
+
+#include <rtems/rfs/rtems-rfs-data.h>
+#include <rtems/rfs/rtems-rfs-file-system.h>
+#include <rtems/rfs/rtems-rfs-inode.h>
+
+/**
+ * Define the offsets of the fields of a directory entry.
+ */
+#define RTEMS_RFS_DIR_ENTRY_INO (0) /**< The ino offset in a directory
+ * entry. */
+#define RTEMS_RFS_DIR_ENTRY_HASH (4) /**< The hash offset in a directory
+ * entry. The hash is 32bits. We need at
+ * least 16bits and given the length and
+ * ino field are 4 the extra 2 bytes is
+ * not a big overhead.*/
+#define RTEMS_RFS_DIR_ENTRY_LEN (8) /**< The length offset in a directory
+ * entry. */
+
+/**
+ * The length of the directory entry header.
+ */
+#define RTEMS_RFS_DIR_ENTRY_SIZE (4 + 4 + 2)
+
+/**
+ * The length when the remainder of the directory block is empty.
+ */
+#define RTEMS_RFS_DIR_ENTRY_EMPTY (0xffff)
+
+/**
+ * Return the hash of the entry.
+ *
+ * @param[in] _e is a pointer to the directory entry.
+ *
+ * @retval hash The uint32_t hash of the entry.
+ */
+#define rtems_rfs_dir_entry_hash(_e) \
+ rtems_rfs_read_u32 (_e + RTEMS_RFS_DIR_ENTRY_HASH)
+
+/**
+ * Set the hash of the entry.
+ *
+ * @param[in] _e is a pointer to the directory entry.
+ *
+ * @param[in] _h is the hash of the entry.
+ */
+#define rtems_rfs_dir_set_entry_hash(_e, _h) \
+ rtems_rfs_write_u32 (_e + RTEMS_RFS_DIR_ENTRY_HASH, _h)
+
+/**
+ * Return the ino of the entry.
+ *
+ * @param[in] _e is a pointer to the directory entry.
+ *
+ * @retval ino The ino of the entry.
+ */
+#define rtems_rfs_dir_entry_ino(_e) \
+ rtems_rfs_read_u32 (_e + RTEMS_RFS_DIR_ENTRY_INO)
+
+/**
+ * Set the ino of the entry.
+ *
+ * @param[in] _e is a pointer to the directory entry.
+ *
+ * @param[in] _i is the ino of the entry.
+ */
+#define rtems_rfs_dir_set_entry_ino(_e, _i) \
+ rtems_rfs_write_u32 (_e + RTEMS_RFS_DIR_ENTRY_INO, _i)
+
+/**
+ * Return the length of the entry.
+ *
+ * @param[in] _e Pointer to the directory entry.
+ *
+ * @retval length The length of the entry.
+ */
+#define rtems_rfs_dir_entry_length(_e) \
+ rtems_rfs_read_u16 (_e + RTEMS_RFS_DIR_ENTRY_LEN)
+
+/**
+ * Set the length of the entry.
+ *
+ * @param[in] _e is a pointer to the directory entry.
+ * @param[in] _l is the length.
+ */
+#define rtems_rfs_dir_set_entry_length(_e, _l) \
+ rtems_rfs_write_u16 (_e + RTEMS_RFS_DIR_ENTRY_LEN, _l)
+
+/**
+ * Look up a directory entry in the directory pointed to by the inode. The look
+ * up is local to this directory. No need to decend.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] inode is a pointer to the inode of the directory to search.
+ * @param[in] name is a pointer to the name to look up. The name may not be
+ * nul terminated.
+ * @param[in] length is the length of the name.
+ * @param[out] ino will be filled in with the inode number
+ * if there is no error.
+ * @param[in] offset is the offset in the directory for the entry.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_dir_lookup_ino (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* inode,
+ const char* name,
+ int length,
+ rtems_rfs_ino* ino,
+ uint32_t* offset);
+
+/**
+ * Add an entry to the directory returing the inode number allocated to the
+ * entry.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] dir is a pointer to the directory inode the
+ * entry is to be added too.
+ * @param[in] name is a pointer to the name of the entry to be added.
+ * @param[in] length is the length of the name excluding a terminating 0.
+ * @param[in] ino is the ino of the entry.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_dir_add_entry (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* dir,
+ const char* name,
+ size_t length,
+ rtems_rfs_ino ino);
+
+/**
+ * Del an entry from the directory using an inode number as a key.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] dir is a pointer to the directory inode the
+ * entry is to be deleted from.
+ * @param[in] ino is the ino of the entry.
+ * @param[in] offset is the offset in the directory of the entry
+ * to delete. If 0 search from the start for the ino.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_dir_del_entry (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* dir,
+ rtems_rfs_ino ino,
+ uint32_t offset);
+
+/**
+ * Read the directory entry from offset into the directory entry buffer and
+ * return the length of space this entry uses in the directory table.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] dir is a pointer to the direct inode handler.
+ * @param[in] offset is the offset in the directory to read from.
+ * @param[in] dirent is a ointer to the dirent structure the entry
+ * is written into.
+ * @param[out] length will contain the length this entry
+ * takes in the directory.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_dir_read (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* dir,
+ rtems_rfs_pos_rel offset,
+ struct dirent* dirent,
+ size_t* length);
+
+/**
+ * Check if the directory is empty. The current and parent directory entries
+ * are ignored.
+ *
+ * @param[in] fs is the file system data
+ * @param[in] dir is a pointer to the directory inode to check.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_dir_empty (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* dir);
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-file-system-fwd.h b/cpukit/include/rtems/rfs/rtems-rfs-file-system-fwd.h
new file mode 100644
index 0000000000..e239c25d6f
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-file-system-fwd.h
@@ -0,0 +1,29 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File Systems Data Forward Declaration
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File Systems Data forward decl.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+
+#if !defined (_RTEMS_RFS_FILE_SYSTEM_FWD_H_)
+#define _RTEMS_RFS_FILE_SYSTEM_FWD_H_
+
+/**
+ * Forward reference to the file system data.
+ */
+struct _rtems_rfs_file_system;
+typedef struct _rtems_rfs_file_system rtems_rfs_file_system;
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-file-system.h b/cpukit/include/rtems/rfs/rtems-rfs-file-system.h
new file mode 100644
index 0000000000..e00b142532
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-file-system.h
@@ -0,0 +1,410 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File System Data
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File System Data
+ *
+ * This file defines the file system data.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+#if !defined (_RTEMS_RFS_FILE_SYSTEM_H_)
+#define _RTEMS_RFS_FILE_SYSTEM_H_
+
+#include <rtems/rfs/rtems-rfs-group.h>
+
+/**
+ * Superblock offsets and values.
+ */
+#define RTEMS_RFS_SB_OFFSET_MAGIC (0)
+#define RTEMS_RFS_SB_MAGIC (0x28092001)
+#define RTEMS_RFS_SB_OFFSET_VERSION (RTEMS_RFS_SB_OFFSET_MAGIC + 4)
+#define RTEMS_RFS_SB_OFFSET_BLOCK_SIZE (RTEMS_RFS_SB_OFFSET_VERSION + 4)
+#define RTEMS_RFS_SB_OFFSET_BLOCKS (RTEMS_RFS_SB_OFFSET_BLOCK_SIZE + 4)
+#define RTEMS_RFS_SB_OFFSET_BAD_BLOCKS (RTEMS_RFS_SB_OFFSET_BLOCKS + 4)
+#define RTEMS_RFS_SB_OFFSET_MAX_NAME_LENGTH (RTEMS_RFS_SB_OFFSET_BAD_BLOCKS + 4)
+#define RTEMS_RFS_SB_OFFSET_GROUPS (RTEMS_RFS_SB_OFFSET_MAX_NAME_LENGTH + 4)
+#define RTEMS_RFS_SB_OFFSET_GROUP_BLOCKS (RTEMS_RFS_SB_OFFSET_GROUPS + 4)
+#define RTEMS_RFS_SB_OFFSET_GROUP_INODES (RTEMS_RFS_SB_OFFSET_GROUP_BLOCKS + 4)
+#define RTEMS_RFS_SB_OFFSET_INODE_SIZE (RTEMS_RFS_SB_OFFSET_GROUP_INODES + 4)
+
+/**
+ * RFS Version Number.
+ */
+#define RTEMS_RFS_VERSION (0x00000000)
+
+/**
+ * RFS Version Number Mask. The mask determines which bits of the version
+ * number indicate compatility issues.
+ */
+#define RTEMS_RFS_VERSION_MASK INT32_C(0x00000000)
+
+/**
+ * The root inode number. Do not use 0 as this has special meaning in some
+ * Unix operating systems.
+ */
+#define RTEMS_RFS_ROOT_INO (1)
+
+/**
+ * Empty inode number.
+ */
+#define RTEMS_RFS_EMPTY_INO (0)
+
+/**
+ * The number of blocks in the inode. This number effects the size of the
+ * inode and that effects the overhead of the inode tables in a group.
+ */
+#define RTEMS_RFS_INODE_BLOCKS (5)
+
+/**
+ * The inode overhead is the percentage of space reserved for inodes. It is
+ * calculated as the percentage number of blocks in a group. The number of
+ * blocks in a group is the number of bits a block can hold.
+ */
+#define RTEMS_RFS_INODE_OVERHEAD_PERCENTAGE (1)
+
+/**
+ * Number of blocks in the superblock. Yes I know it is a superblock and not
+ * superblocks but if for any reason this needs to change it is handled.
+ */
+#define RTEMS_RFS_SUPERBLOCK_SIZE (1)
+
+/**
+ * The maximum number of buffers held by the file system at any one time.
+ */
+#define RTEMS_RFS_FS_MAX_HELD_BUFFERS (5)
+
+/**
+ * Absolute position. Make a 64bit value.
+ */
+typedef uint64_t rtems_rfs_pos;
+
+/**
+ * Relative position. Make a 64bit value.
+ */
+typedef int64_t rtems_rfs_pos_rel;
+
+/**
+ * Flags to control the file system.
+ */
+#define RTEMS_RFS_FS_BITMAPS_HOLD (1 << 0) /**< Do not release bitmaps
+ * when finished. Default is
+ * off so they are released. */
+#define RTEMS_RFS_FS_NO_LOCAL_CACHE (1 << 1) /**< Do not cache the buffers
+ * and release directly to the
+ * buffer support layer. The
+ * default is to hold buffers. */
+#define RTEMS_RFS_FS_FORCE_OPEN (1 << 2) /**< Force open and ignore any
+ * errors. */
+#define RTEMS_RFS_FS_READ_ONLY (1 << 3) /**< Make the mount
+ * read-only. Currently not
+ * supported. */
+/**
+ * RFS File System data.
+ */
+struct _rtems_rfs_file_system
+{
+ /**
+ * Flags to control the file system. Some can be controlled via the ioctl.
+ */
+ uint32_t flags;
+
+ /**
+ * The number of blocks in the disk. The size of the disk is the number of
+ * blocks by the block size. This should be within a block size of the size
+ * returned by the media driver.
+ */
+ size_t blocks;
+
+ /**
+ * The size of a block. This must be a multiple of the disk's media block
+ * size.
+ */
+ size_t block_size;
+
+ /**
+ * The file descriptor for device I/O.
+ */
+ int device;
+
+#if RTEMS_RFS_USE_LIBBLOCK
+ /**
+ * The disk device. This is the data about the block device this file system
+ * is mounted on. We access the data held in this structure rather than
+ * making an extra copy in this structure.
+ */
+ rtems_disk_device* disk;
+#else
+ /**
+ * The number of blocks in the file system.
+ */
+ size_t size;
+#endif
+
+ /**
+ * Inode count.
+ */
+ uint32_t inodes;
+
+ /**
+ * Bad block blocks. This is a table of blocks that have been found to be
+ * bad.
+ */
+ uint32_t bad_blocks;
+
+ /**
+ * Maximum length of names supported by this file system.
+ */
+ uint32_t max_name_length;
+
+ /**
+ * A disk is broken down into a series of groups.
+ */
+ rtems_rfs_group* groups;
+
+ /**
+ * Number of groups.
+ */
+ int group_count;
+
+ /**
+ * Number of blocks in a group.
+ */
+ size_t group_blocks;
+
+ /**
+ * Number of inodes in a group.
+ */
+ size_t group_inodes;
+
+ /**
+ * Number of inodes in each block.
+ */
+ size_t inodes_per_block;
+
+ /**
+ * Number of block numbers in a block.
+ */
+ size_t blocks_per_block;
+
+ /**
+ * Block map single indirect count. This is the block number per block
+ * multiplied but the slots in the inode.
+ */
+ size_t block_map_singly_blocks;
+
+ /**
+ * Block map double indirect count. This is the block number per block
+ * squared and multiplied by the slots in the inode. It is the maximum
+ * number of blocks a map (file/directory) can have.
+ */
+ size_t block_map_doubly_blocks;
+
+ /**
+ * Number of buffers held before releasing back to the cache.
+ */
+ uint32_t max_held_buffers;
+
+ /**
+ * List of buffers attached to buffer handles. Allows sharing.
+ */
+ rtems_chain_control buffers;
+
+ /**
+ * Number of buffers held on the buffers list.
+ */
+ uint32_t buffers_count;
+
+ /**
+ * List of buffers that need to be released when the processing of a file
+ * system request has completed.
+ */
+ rtems_chain_control release;
+
+ /**
+ * Number of buffers held on the release list.
+ */
+ uint32_t release_count;
+
+ /**
+ * List of buffers that need to be released modified when the processing of a
+ * file system request has completed.
+ */
+ rtems_chain_control release_modified;
+
+ /**
+ * Number of buffers held on the release modified list.
+ */
+ uint32_t release_modified_count;
+
+ /**
+ * List of open shared file node data. The shared node data such as the inode
+ * and block map allows a single file to be open more than once.
+ */
+ rtems_chain_control file_shares;
+
+ /**
+ * Pointer to user data supplied when opening.
+ */
+ void* user;
+};
+
+/**
+ * Return the flags.
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#define rtems_rfs_fs_flags(_f) ((_f)->flags)
+/**
+ * Should bitmap buffers be released when finished ?
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#define rtems_rfs_fs_release_bitmaps(_f) (!((_f)->flags & RTEMS_RFS_FS_BITMAPS_HOLD))
+
+/**
+ * Are the buffers locally cache or released back to the buffering layer ?
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#define rtems_rfs_fs_no_local_cache(_f) ((_f)->flags & RTEMS_RFS_FS_NO_LOCAL_CACHE)
+
+/**
+ * The disk device number.
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#if RTEMS_RFS_USE_LIBBLOCK
+#define rtems_rfs_fs_device(_fs) ((_fs)->disk)
+#else
+#define rtems_rfs_fs_device(_fs) ((_fs)->device)
+#endif
+
+/**
+ * The size of the disk in blocks.
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#define rtems_rfs_fs_blocks(_fs) ((_fs)->blocks)
+
+/**
+ * The block size.
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#define rtems_rfs_fs_block_size(_fs) ((_fs)->block_size)
+
+/**
+ * The number of inodes.
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#define rtems_rfs_fs_inodes(_fs) ((_fs)->inodes)
+
+/**
+ * Calculate a block in the file system given the group and the block within
+ * the group.
+ *
+ * @param[in] _fs is a pointer to the file system.
+ * @param[in] _grp is the group.
+ * @param[in] _blk is the block within the group.
+ * @return The absolute block number.
+ */
+#define rtems_rfs_fs_block(_fs, _grp, _blk) \
+ ((((_fs)->group_blocks) * (_grp)) + (_blk) + 1)
+
+/**
+ * The media size of the disk in media size blocks.
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#if RTEMS_RFS_USE_LIBBLOCK
+#define rtems_rfs_fs_media_blocks(_fs) ((_fs)->disk->size)
+#else
+#define rtems_rfs_fs_media_blocks(_fs) ((_fs)->media_size)
+#endif
+
+/**
+ * The media block size. This is the size of a block on disk. For a device I/O
+ * this value is 1.
+ *
+ * @param[in] _fs is a pointer to the file system.
+ */
+#if RTEMS_RFS_USE_LIBBLOCK
+#define rtems_rfs_fs_media_block_size(_fs) ((_fs)->disk->media_block_size)
+#else
+#define rtems_rfs_fs_media_block_size(_fs) (1)
+#endif
+
+/**
+ * The maximum length of a name supported by the file system.
+ */
+#define rtems_rfs_fs_max_name(_fs) ((_fs)->max_name_length)
+
+/**
+ * Return the maximum number of blocks in a block map.
+ *
+ * @return uint32_t The maximum number of blocks possible.
+ */
+#define rtems_rfs_fs_max_block_map_blocks(_fs) ((_fs)->block_map_doubly_blocks)
+
+/**
+ * Return the user pointer.
+ */
+#define rtems_rfs_fs_user(_fs) ((_fs)->user)
+
+/**
+ * Return the size of the disk in bytes.
+ *
+ * @param[in] fs is a pointer to the file system.
+ * @return uint64_t The size of the disk in bytes.
+ */
+uint64_t rtems_rfs_fs_size(rtems_rfs_file_system* fs);
+
+/**
+ * The size of the disk in bytes calculated from the media parameters..
+ *
+ * @param[in] fs is a pointer to the file system.
+ * @return uint64_t The size of the disk in bytes.
+ */
+uint64_t rtems_rfs_fs_media_size (rtems_rfs_file_system* fs);
+
+/**
+ * Open the file system given a file path.
+ *
+ * @param[in] name is a pointer to the device to open.
+ * @param[in] fs is the file system data filled in by this call.
+ * @param[in] user is a pointer to the user data.
+ * @param[in] flags is a initial set of user flags for the file system.
+ * @param[in] max_held_buffers is the maximum number of buffers the RFS holds.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 Error. See errno
+ */
+int rtems_rfs_fs_open (const char* name,
+ void* user,
+ uint32_t flags,
+ uint32_t max_held_buffers,
+ rtems_rfs_file_system** fs);
+
+/**
+ * Close the file system.
+ *
+ * @param[in] fs is the file system data.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 Error. See errno
+ */
+int rtems_rfs_fs_close (rtems_rfs_file_system* fs);
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-file.h b/cpukit/include/rtems/rfs/rtems-rfs-file.h
new file mode 100644
index 0000000000..772e846143
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-file.h
@@ -0,0 +1,416 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File System File Support
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File System File Support
+ *
+ * This file provides the support functions.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+#if !defined (_RTEMS_RFS_FILE_H_)
+#define _RTEMS_RFS_FILE_H_
+
+#include <rtems/libio_.h>
+
+#include <rtems/rfs/rtems-rfs-block.h>
+#include <rtems/rfs/rtems-rfs-data.h>
+#include <rtems/rfs/rtems-rfs-file-system.h>
+#include <rtems/rfs/rtems-rfs-inode.h>
+
+/**
+ * File data that is shared by various file handles accessing the same file. We
+ * hold various inode values common to the file that can change frequently so
+ * the inode is not thrashed yet we meet the requirements of the POSIX
+ * standard. The stat call needs to check the shared file data.
+ */
+typedef struct _rtems_rfs_file_shared
+{
+ /**
+ * The shared parts are maintained as a list.
+ */
+ rtems_chain_node link;
+
+ /**
+ * Reference count the users of this data.
+ */
+ int references;
+
+ /**
+ * The inode for the file.
+ */
+ rtems_rfs_inode_handle inode;
+
+ /**
+ * The block map for the file. The handle holds the file's position not the
+ * map.
+ */
+ rtems_rfs_block_map map;
+
+ /**
+ * The size of the file as taken from the inode. The map's size and
+ * this size should be the same.
+ */
+ rtems_rfs_block_size size;
+
+ /**
+ * The access time. The last time the file was read.
+ */
+ rtems_rfs_time atime;
+
+ /**
+ * The modified time. The last time the file was written too.
+ */
+ rtems_rfs_time mtime;
+
+ /**
+ * The change time. The last time the inode was written too.
+ */
+ rtems_rfs_time ctime;
+
+ /**
+ * Hold a pointer to the file system data so users can take the handle and
+ * use it without the needing to hold the file system data pointer.
+ */
+ rtems_rfs_file_system* fs;
+
+} rtems_rfs_file_shared;
+
+/**
+ * Get the atime.
+ *
+ * @param[in] shared is a pointer to the shared file data.
+ *
+ * @retval atime The atime.
+ */
+static inline rtems_rfs_time
+rtems_rfs_file_shared_get_atime (rtems_rfs_file_shared* shared)
+{
+ return shared->atime;
+}
+
+/**
+ * Get the mtime.
+ *
+ * @param[in] shared is a pointer to the shared file data.
+ *
+ * @retval mtime The mtime.
+ */
+static inline rtems_rfs_time
+rtems_rfs_file_shared_get_mtime (rtems_rfs_file_shared* shared)
+{
+ return shared->mtime;
+}
+
+/**
+ * Get the ctime.
+ *
+ * @param[in] shared is a pointer to the shared file data.
+ *
+ * @retval ctime The ctime.
+ */
+static inline rtems_rfs_time
+rtems_rfs_file_shared_get_ctime (rtems_rfs_file_shared* shared)
+{
+ return shared->ctime;
+}
+
+/**
+ * Get the block count.
+ *
+ * @param[in] shared is a pointer to the shared file data.
+ *
+ * @retval count The block count.
+ */
+static inline uint32_t
+rtems_rfs_file_shared_get_block_count (rtems_rfs_file_shared* shared)
+{
+ return shared->size.count;
+}
+
+/**
+ * Get the block offset.
+ *
+ * @param shared is a pointer to the shared file data.
+ *
+ * @retval offset The block offset.
+ */
+static inline uint16_t
+rtems_rfs_file_shared_get_block_offset (rtems_rfs_file_shared* shared)
+{
+ return shared->size.offset;
+}
+
+/**
+ * Calculate the size of data.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] shared is a pointer to the shared file data.
+ *
+ * @retval data The data size in bytes.
+ */
+static inline rtems_rfs_pos
+rtems_rfs_file_shared_get_size (rtems_rfs_file_system* fs,
+ rtems_rfs_file_shared* shared)
+{
+ return rtems_rfs_block_get_size (fs, &shared->size);
+}
+
+/**
+ * File flags.
+ */
+#define RTEMS_RFS_FILE_NO_ATIME_UPDATE (1 << 0) /**< Do not update the atime
+ * field in the inode if
+ * set. */
+#define RTEMS_RFS_FILE_NO_MTIME_UPDATE (1 << 1) /**< Do not update the mtime
+ * field in the inode if
+ * set. */
+#define RTEMS_RFS_FILE_NO_LENGTH_UPDATE (1 << 2) /**< Do not update the position
+ * field in the inode if
+ * set. */
+
+/**
+ * File data used to managed an open file.
+ */
+typedef struct _rtems_rfs_file_handle
+{
+ /**
+ * Special flags that can be controlled by the fctrl call.
+ */
+ int flags;
+
+ /**
+ * The buffer of data at the file's position.
+ */
+ rtems_rfs_buffer_handle buffer;
+
+ /**
+ * The block position of this file handle.
+ */
+ rtems_rfs_block_pos bpos;
+
+ /**
+ * Pointer to the shared file data.
+ */
+ rtems_rfs_file_shared* shared;
+
+} rtems_rfs_file_handle;
+
+/**
+ * Access the data in the buffer.
+ */
+#define rtems_rfs_file_data(_f) \
+ (rtems_rfs_buffer_data (&(_f)->buffer) + (_f)->bpos.boff)
+
+/**
+ * Return the file system data pointer given a file handle.
+ */
+#define rtems_rfs_file_fs(_f) ((_f)->shared->fs)
+
+/**
+ * Return the file's inode handle pointer given a file handle.
+ */
+#define rtems_rfs_file_inode(_f) (&(_f)->shared->inode)
+
+/**
+ * Return the file's block map pointer given a file handle.
+ */
+#define rtems_rfs_file_map(_f) (&(_f)->shared->map)
+
+/**
+ * Return the file's block position pointer given a file handle.
+ */
+#define rtems_rfs_file_bpos(_f) (&(_f)->bpos)
+
+/**
+ * Return the file's block number given a file handle.
+ */
+#define rtems_rfs_file_block(_f) ((_f)->bpos.bno)
+
+/**
+ * Return the file's block offset given a file handle.
+ */
+#define rtems_rfs_file_block_offset(_f) ((_f)->bpos.boff)
+
+/**
+ * Set the file's block position given a file position (absolute).
+ */
+#define rtems_rfs_file_set_bpos(_f, _p) \
+ rtems_rfs_block_get_bpos (rtems_rfs_file_fs (_f), _p, (&(_f)->bpos))
+
+/**
+ * Return the file's buffer handle pointer given a file handle.
+ */
+#define rtems_rfs_file_buffer(_f) (&(_f)->buffer)
+
+/**
+ * Update the access time field of the inode when reading if flagged to do so.
+ */
+#define rtems_rfs_file_update_atime(_f) \
+ (((_f)->flags & RTEMS_RFS_FILE_NO_ATIME_UPDATE) == 0)
+
+/**
+ * Update the modified time field of the inode when writing if flagged to do so.
+ */
+#define rtems_rfs_file_update_mtime(_f) \
+ (((_f)->flags & RTEMS_RFS_FILE_NO_MTIME_UPDATE) == 0)
+
+/**
+ * Update the length field of the inode.
+ */
+#define rtems_rfs_file_update_length(_f) \
+ (((_f)->flags & RTEMS_RFS_FILE_NO_LENGTH_UPDATE) == 0)
+
+/**
+ * Return the shared size varable.
+ */
+#define rtems_rfs_file_get_size(_f) \
+ (&(_f)->shared->size)
+
+/**
+ * Return the size of file.
+ */
+#define rtems_rfs_file_size(_f) \
+ rtems_rfs_file_shared_get_size (rtems_rfs_file_fs (_f), (_f)->shared)
+
+/**
+ * Return the file block count.
+ */
+#define rtems_rfs_file_size_count(_f) \
+ rtems_rfs_file_shared_get_block_count ((_f)->shared)
+
+/**
+ * Return the file block offset.
+ */
+#define rtems_rfs_file_size_offset(_f) \
+ rtems_rfs_file_shared_get_block_offset ((_f)->shared)
+
+/**
+ * Open a file handle.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] ino is the inode number of the file to be opened.
+ * @param[out] handle will be filled in with the handle pointer.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_file_open (rtems_rfs_file_system* fs,
+ rtems_rfs_ino ino,
+ int oflag,
+ rtems_rfs_file_handle** handle);
+
+/**
+ * Close an open file handle.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] handle is the open file handle.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_file_close (rtems_rfs_file_system* fs,
+ rtems_rfs_file_handle* handle);
+
+/**
+ * Start I/O on a block of a file. This call only requests the block from the
+ * media if reading and makes the buffer available to you the via the
+ * rtems_rfs_file_data interface after the call. The available amount data is
+ * taken from the current file position until the end of the block. The file
+ * position is not adujsted until the I/O ends. An I/O request cannot perform
+ * I/O past the end of a block so the call returns the amount of data
+ * available.
+ *
+ * @param[in] handle is the file handle.
+ * @param[in] available is the amount of data available for I/O.
+ * @param[in] read is the I/O operation is a read so the block is read from the media.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_file_io_start (rtems_rfs_file_handle* handle,
+ size_t* available,
+ bool read);
+
+/**
+ * End the I/O. Any buffers held in the file handle and returned to the
+ * cache. If inode updating is not disable and the I/O is a read the atime
+ * field is updated and if a write I/O the mtime is updated.
+ *
+ * If the file's position is updated by the size amount.
+ *
+ * @param[in] handle is the file handle.
+ * @param[in] size is the amount of data read or written.
+ * @param[in] read is the I/O was a read if true else it was a write.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_file_io_end (rtems_rfs_file_handle* handle,
+ size_t size,
+ bool read);
+
+/**
+ * Release the I/O resources without any changes. If data has changed in the
+ * buffer and the buffer was not already released as modified the data will be
+ * lost.
+ *
+ * @param[in] handle is the file handle.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_file_io_release (rtems_rfs_file_handle* handle);
+
+/**
+ * The file to the position returning the old position. The position is
+ * abolute.
+ *
+ * @param[in] handle The file handle.
+ * @param[in] pos is the position to seek to.
+ * @param[out] new_pos will contain the actual position.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_file_seek (rtems_rfs_file_handle* handle,
+ rtems_rfs_pos pos,
+ rtems_rfs_pos* new_pos);
+
+/**
+ * Set the size of the file to the new size. This can extend the file to a new
+ * size.
+ *
+ * @param[in] handle is the file handle.
+ * @param[in] size is the new size of the file.
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_file_set_size (rtems_rfs_file_handle* handle,
+ rtems_rfs_pos size);
+
+/**
+ * Return the shared file data for an ino.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] ino is the inode number to locate the data for.
+ * @return rtems_rfs_file_shared* The shared data or NULL is not located.
+ *
+ * @retval shared The shared data.
+ * @retval NULL No shared file data is located.
+ */
+rtems_rfs_file_shared* rtems_rfs_file_get_shared (rtems_rfs_file_system* fs,
+ rtems_rfs_ino ino);
+
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-group.h b/cpukit/include/rtems/rfs/rtems-rfs-group.h
new file mode 100644
index 0000000000..23e6434b2c
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-group.h
@@ -0,0 +1,181 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File Systems Group Management
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File Systems Group Management.
+ *
+ * These functions manage the groups used in the file system.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+
+#if !defined (_RTEMS_RFS_GROUP_H_)
+#define _RTEMS_RFS_GROUP_H_
+
+/**
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File System Group Management
+ */
+/**@{*/
+
+#include <rtems/rfs/rtems-rfs-trace.h>
+#include <rtems/rfs/rtems-rfs-bitmaps.h>
+#include <rtems/rfs/rtems-rfs-buffer.h>
+
+/**
+ * Block allocations for a group on disk.
+ */
+#define RTEMS_RFS_GROUP_BLOCK_BITMAP_BLOCK (0)
+#define RTEMS_RFS_GROUP_INODE_BITMAP_BLOCK (1)
+#define RTEMS_RFS_GROUP_INODE_BLOCK (2)
+
+/**
+ * @brief Creates bit allocator for blocks in the group simpler.
+ *
+ * A group is a selection of blocks on the disk. Typically the number of blocks
+ * in a group is determined by the number of bits a block holds. This makes the
+ * bit allocator for blocks in the group simpler plus is allows a simple way to
+ * localise access to files and directories.
+ */
+typedef struct _rtems_rfs_group
+{
+ /**
+ * Base block number.
+ */
+ rtems_rfs_buffer_block base;
+
+ /**
+ * The number of blocks in the group. Groups may be different sizes.
+ */
+ size_t size;
+
+ /**
+ * The block bitmap control.
+ */
+ rtems_rfs_bitmap_control block_bitmap;
+
+ /**
+ * The handle to the block bitmap buffer.
+ */
+ rtems_rfs_buffer_handle block_bitmap_buffer;
+
+ /**
+ * The inode bitmap control.
+ */
+ rtems_rfs_bitmap_control inode_bitmap;
+
+ /**
+ * The handle to the inode bitmap buffer.
+ */
+ rtems_rfs_buffer_handle inode_bitmap_buffer;
+
+} rtems_rfs_group;
+
+/**
+ * Return the disk's block for a block in a group.
+ */
+#define rtems_rfs_group_block(_g, _b) (((_g)->base) + (_b))
+
+/**
+ * Return the file system inode for a inode in a group.
+ */
+#define rtems_rfs_group_inode(_f, _g, _i) \
+ (((_f)->group_inodes * (_g)) + (_i) + RTEMS_RFS_ROOT_INO)
+
+/**
+ * @brief Open a group.
+ *
+ * Allocate all the resources including the bitmaps.
+ *
+ * @param fs The file system.
+ * @param base The base block number.
+ * @param size The number of blocks in the group.
+ * @param group Reference to the group to open.
+ * @retval int The error number (errno). No error if 0.
+ */
+int rtems_rfs_group_open (rtems_rfs_file_system* fs,
+ rtems_rfs_buffer_block base,
+ size_t size,
+ size_t inodes,
+ rtems_rfs_group* group);
+
+/**
+ * @brief Close a group.
+ *
+ * Release all resources the group holds.
+ *
+ * @param fs The file system.
+ * @param group The group to close.
+ * @retval int The error number (errno). No error if 0.
+ */
+int rtems_rfs_group_close (rtems_rfs_file_system* fs,
+ rtems_rfs_group* group);
+
+/**
+ * @brief Allocate an inode or block.
+ *
+ * The groups are searched to find the next
+ * available inode or block.
+ *
+ * @param fs The file system data.
+ * @param goal The goal to seed the bitmap search.
+ * @param inode If true allocate an inode else allocate a block.
+ * @param result The allocated bit in the bitmap.
+ * @retval int The error number (errno). No error if 0.
+ */
+int rtems_rfs_group_bitmap_alloc (rtems_rfs_file_system* fs,
+ rtems_rfs_bitmap_bit goal,
+ bool inode,
+ rtems_rfs_bitmap_bit* result);
+
+/**
+ * @brief Free the group allocated bit.
+ *
+ * @param fs The file system data.
+ * @param inode If true the number to free is an inode else it is a block.
+ * @param block The inode or block number to free.
+ * @retval int The error number (errno). No error if 0.
+ */
+int rtems_rfs_group_bitmap_free (rtems_rfs_file_system* fs,
+ bool inode,
+ rtems_rfs_bitmap_bit no);
+
+/**
+ * @brief Test the group allocated bit.
+ *
+ * @param fs The file system data.
+ * @param inode If true the number to free is an inode else it is a block.
+ * @param block The inode or block number to free.
+ * @param state Return the state of the bit.
+ * @retval int The error number (errno). No error if 0.
+ */
+int rtems_rfs_group_bitmap_test (rtems_rfs_file_system* fs,
+ bool inode,
+ rtems_rfs_bitmap_bit no,
+ bool* state);
+
+/**
+ * @brief Determine the number of blocks and inodes used.
+ *
+ * @param fs The file system data.
+ * @param blocks The number of blocks used.
+ * @param inodes The number of inodes used.
+ * @retval int The error number (errno). No error if 0.
+ */
+int rtems_rfs_group_usage (rtems_rfs_file_system* fs,
+ size_t* blocks,
+ size_t* inodes);
+
+/** @} */
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-inode.h b/cpukit/include/rtems/rfs/rtems-rfs-inode.h
new file mode 100644
index 0000000000..95861ea8a7
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-inode.h
@@ -0,0 +1,728 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File System Information Node
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File System Information Node.
+ *
+ * The information nodes hold the data about all nodes in the file system.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+
+#if !defined (_RTEMS_RFS_INODE_H_)
+#define _RTEMS_RFS_INODE_H_
+
+#include <sys/stat.h>
+
+#include <rtems/rfs/rtems-rfs-data.h>
+#include <rtems/rfs/rtems-rfs-file-system.h>
+
+/**
+ * The RFS mode definitions. Currently map to the C library ones.
+ */
+#define RTEMS_RFS_S_ISUID S_ISUID /**< Set user id on execution */
+#define RTEMS_RFS_S_ISGID S_ISGID /**< Set group id on execution */
+#define RTEMS_RFS_S_ISVTX S_ISVTX /**< Save swapped text even after use */
+#define RTEMS_RFS_S_IREAD S_IREAD /**< Read permission, owner */
+#define RTEMS_RFS_S_IWRITE S_IWRITE /**< Write permission, owner */
+#define RTEMS_RFS_S_IEXEC S_IEXEC /**< Execute/search permission, owner */
+#define RTEMS_RFS_S_ENFMT S_ENFMT /**< Enforcement-mode locking */
+#define RTEMS_RFS_S_IFMT S_IFMT /**< Type of file */
+#define RTEMS_RFS_S_IFDIR S_IFDIR /**< Directory */
+#define RTEMS_RFS_S_IFCHR S_IFCHR /**< Character special */
+#define RTEMS_RFS_S_IFBLK S_IFBLK /**< Block special */
+#define RTEMS_RFS_S_IFREG S_IFREG /**< Regular */
+#define RTEMS_RFS_S_IFLNK S_IFLNK /**< Symbolic link */
+#define RTEMS_RFS_S_IFSOCK S_IFSOCK /**< Socket */
+#define RTEMS_RFS_S_IFIFO S_IFIFO /**< Fifo */
+#define RTEMS_RFS_S_IRWXU S_IRWXU
+#define RTEMS_RFS_S_IRUSR S_IRUSR /**< Read permission, owner */
+#define RTEMS_RFS_S_IWUSR S_IWUSR /**< Write permission, owner */
+#define RTEMS_RFS_S_IXUSR S_IXUSR /**< Execute/search permission, owner */
+#define RTEMS_RFS_S_IRWXG S_IRWXG
+#define RTEMS_RFS_S_IRGRP S_IRGRP /**< Read permission, group */
+#define RTEMS_RFS_S_IWGRP S_IWGRP /**< Write permission, grougroup */
+#define RTEMS_RFS_S_IXGRP S_IXGRP /**< Execute/search permission, group */
+#define RTEMS_RFS_S_IRWXO S_IRWXO
+#define RTEMS_RFS_S_IROTH S_IROTH /**< Read permission, other */
+#define RTEMS_RFS_S_IWOTH S_IWOTH /**< Write permission, other */
+#define RTEMS_RFS_S_IXOTH S_IXOTH /**< Execute/search permission, other */
+
+#define RTEMS_RFS_S_ISBLK(m) S_ISBLK(m)
+#define RTEMS_RFS_S_ISCHR(m) S_ISCHR(m)
+#define RTEMS_RFS_S_ISDIR(m) S_ISDIR(m)
+#define RTEMS_RFS_S_ISFIFO(m) S_ISFIFO(m)
+#define RTEMS_RFS_S_ISREG(m) S_ISREG(m)
+#define RTEMS_RFS_S_ISLNK(m) S_ISLNK(m)
+#define RTEMS_RFS_S_ISSOCK(m) S_ISSOCK(m)
+
+/**
+ * Permissions of a symlink.
+ */
+#define RTEMS_RFS_S_SYMLINK \
+ RTEMS_RFS_S_IFLNK | RTEMS_RFS_S_IRWXU | RTEMS_RFS_S_IRWXG | RTEMS_RFS_S_IRWXO
+
+/**
+ * The inode number or ino.
+ */
+typedef uint32_t rtems_rfs_ino;
+
+/**
+ * The time in the file system.
+ */
+typedef uint32_t rtems_rfs_time;
+
+/**
+ * The size of a block value on disk. This include the inodes and indirect
+ * tables.
+ */
+typedef uint32_t rtems_rfs_inode_block;
+
+/**
+ * The size of the data name field in the inode.
+ */
+#define RTEMS_RFS_INODE_DATA_NAME_SIZE \
+ (RTEMS_RFS_INODE_BLOCKS * sizeof (rtems_rfs_inode_block))
+
+/**
+ * The inode.
+ */
+typedef struct _rtems_rfs_inode
+{
+ /**
+ * The number of links to the inode.
+ */
+ uint16_t links;
+
+ /**
+ * The mode of the node.
+ */
+ uint16_t mode;
+
+ /**
+ * The owner of the node.
+ */
+ uint32_t owner;
+
+ /**
+ * Reserved.
+ */
+ uint16_t flags;
+
+ /**
+ * Amount of data held in the last block data.
+ */
+ uint16_t block_offset;
+
+ /**
+ * Number of blocks held by this file.
+ */
+ uint32_t block_count;
+
+ /**
+ * The access time. The last time the file was read.
+ */
+ rtems_rfs_time atime;
+
+ /**
+ * The modified time. The last time the file was written too.
+ */
+ rtems_rfs_time mtime;
+
+ /**
+ * The change time. The last time the inode was written too.
+ */
+ rtems_rfs_time ctime;
+
+ /**
+ * Blocks. These are the block numbers used by the node or table of
+ * nodes. The flags indicate the mode the blocks are being held in. In the
+ * direct table mode the blocks are entries in this table. In the indirect
+ * mode the blocks point to blocks that hold the block numbers. The data can
+ * also be a name if it fits. For example a symbolic link.
+ */
+ union
+ {
+ rtems_rfs_inode_block blocks[RTEMS_RFS_INODE_BLOCKS];
+ uint8_t name[RTEMS_RFS_INODE_DATA_NAME_SIZE];
+ } data;
+
+ /**
+ * The last block map block. Used as the goal when allocating a new block for
+ * use in the map.
+ */
+ rtems_rfs_inode_block last_map_block;
+
+ /**
+ * The last data block. Used as the goal when allocating a new block.
+ */
+ rtems_rfs_inode_block last_data_block;
+
+} rtems_rfs_inode;
+
+/**
+ * The size of an inode.
+ */
+#define RTEMS_RFS_INODE_SIZE (sizeof (rtems_rfs_inode))
+
+/**
+ * RFS Inode Handle.
+ */
+typedef struct _rtems_rfs_inode_handle
+{
+ /**
+ * Handles can be linked as a list for easy processing.
+ */
+ rtems_chain_node link;
+
+ /**
+ * The ino for this handle.
+ */
+ rtems_rfs_ino ino;
+
+ /**
+ * The pointer to the inode.
+ */
+ rtems_rfs_inode* node;
+
+ /**
+ * The buffer that contains this inode.
+ */
+ rtems_rfs_buffer_handle buffer;
+
+ /**
+ * The block number that holds the inode.
+ */
+ rtems_rfs_buffer_block block;
+
+ /**
+ * The offset into the block for the inode.
+ */
+ int offset;
+
+ /**
+ * Number of load requests.
+ */
+ int loads;
+
+} rtems_rfs_inode_handle;
+
+/**
+ * Is the inode loaded ?
+ */
+#define rtems_rfs_inode_is_loaded(_h) ((_h)->node)
+
+/**
+ * Get the inode ino for a handle.
+ */
+#define rtems_rfs_inode_ino(_h) ((_h)->ino)
+
+/**
+ * Get the link count.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval links The link count.
+ */
+static inline uint16_t
+rtems_rfs_inode_get_links (rtems_rfs_inode_handle* handle)
+{
+ uint16_t links;
+ links = rtems_rfs_read_u16 (&handle->node->links);
+ if (links == 0xffff)
+ links = 0;
+ return links;
+}
+
+/**
+ * Set the link count.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] links are the links.
+ */
+static inline void
+rtems_rfs_inode_set_links (rtems_rfs_inode_handle* handle, uint16_t links)
+{
+ rtems_rfs_write_u16 (&handle->node->links, links);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the flags.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval flags The flags.
+ */
+static inline uint16_t
+rtems_rfs_inode_get_flags (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u16 (&handle->node->flags);
+}
+
+/**
+ * Set the flags.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] flags are the flags.
+ */
+static inline void
+rtems_rfs_inode_set_flags (rtems_rfs_inode_handle* handle, uint16_t flags)
+{
+ rtems_rfs_write_u16 (&handle->node->flags, flags);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the mode.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval mode The mode.
+ */
+static inline uint16_t
+rtems_rfs_inode_get_mode (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u16 (&handle->node->mode);
+}
+
+/**
+ * Set the mode.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] mode is the mode.
+ */
+static inline void
+rtems_rfs_inode_set_mode (rtems_rfs_inode_handle* handle, uint16_t mode)
+{
+ rtems_rfs_write_u16 (&handle->node->mode, mode);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the user id.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval uid The used id.
+ */
+static inline uint16_t
+rtems_rfs_inode_get_uid (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u32 (&handle->node->owner) & 0xffff;
+}
+
+/**
+ * Get the group id.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval gid The grpup id.
+ */
+static inline uint16_t
+rtems_rfs_inode_get_gid (rtems_rfs_inode_handle* handle)
+{
+ return (rtems_rfs_read_u32 (&handle->node->owner) >> 16) & 0xffff;
+}
+
+/**
+ * Set the user id and group id.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] uid is the user id (uid).
+ * @param[in] gid is the group id (gid).
+ */
+static inline void
+rtems_rfs_inode_set_uid_gid (rtems_rfs_inode_handle* handle,
+ uint16_t uid, uint16_t gid)
+{
+ rtems_rfs_write_u32 (&handle->node->owner, (((uint32_t) gid) << 16) | uid);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the block offset.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval offset The block offset.
+ */
+static inline uint16_t
+rtems_rfs_inode_get_block_offset (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u16 (&handle->node->block_offset);
+}
+
+/**
+ * Set the block offset.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] block_count is the block offset.
+ */
+static inline void
+rtems_rfs_inode_set_block_offset (rtems_rfs_inode_handle* handle,
+ uint16_t block_offset)
+{
+ rtems_rfs_write_u16 (&handle->node->block_offset, block_offset);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the block count.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval count The block count.
+ */
+static inline uint32_t
+rtems_rfs_inode_get_block_count (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u32 (&handle->node->block_count);
+}
+
+/**
+ * Set the block count.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] block_count is the block count.
+ */
+static inline void
+rtems_rfs_inode_set_block_count (rtems_rfs_inode_handle* handle, uint32_t block_count)
+{
+ rtems_rfs_write_u32 (&handle->node->block_count, block_count);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the atime.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval atime The atime.
+ */
+static inline rtems_rfs_time
+rtems_rfs_inode_get_atime (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u32 (&handle->node->atime);
+}
+
+/**
+ * Set the atime.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] atime The atime.
+ */
+static inline void
+rtems_rfs_inode_set_atime (rtems_rfs_inode_handle* handle,
+ rtems_rfs_time atime)
+{
+ rtems_rfs_write_u32 (&handle->node->atime, atime);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the mtime.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval mtime The mtime.
+ */
+static inline rtems_rfs_time
+rtems_rfs_inode_get_mtime (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u32 (&handle->node->mtime);
+}
+
+/**
+ * Set the mtime.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] mtime The mtime.
+ */
+static inline void
+rtems_rfs_inode_set_mtime (rtems_rfs_inode_handle* handle,
+ rtems_rfs_time mtime)
+{
+ rtems_rfs_write_u32 (&handle->node->mtime, mtime);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the ctime.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval ctime The ctime.
+ */
+static inline rtems_rfs_time
+rtems_rfs_inode_get_ctime (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u32 (&handle->node->ctime);
+}
+
+/**
+ * Set the ctime.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] ctime The ctime.
+ */
+static inline void
+rtems_rfs_inode_set_ctime (rtems_rfs_inode_handle* handle,
+ rtems_rfs_time ctime)
+{
+ rtems_rfs_write_u32 (&handle->node->ctime, ctime);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the block number.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] block is the block number to return.
+ *
+ * @retval block The block number.
+ */
+static inline uint32_t
+rtems_rfs_inode_get_block (rtems_rfs_inode_handle* handle, int block)
+{
+ return rtems_rfs_read_u32 (&handle->node->data.blocks[block]);
+}
+
+/**
+ * Set the block number for a given block index.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] block is the block index.
+ * @param[in] bno is the block number.
+ */
+static inline void
+rtems_rfs_inode_set_block (rtems_rfs_inode_handle* handle, int block, uint32_t bno)
+{
+ rtems_rfs_write_u32 (&handle->node->data.blocks[block], bno);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the last map block from the inode.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval block The last map block number.
+ */
+static inline uint32_t
+rtems_rfs_inode_get_last_map_block (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u32 (&handle->node->last_map_block);
+}
+
+/**
+ * Set the last map block.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] block_count is last map block number.
+ */
+static inline void
+rtems_rfs_inode_set_last_map_block (rtems_rfs_inode_handle* handle, uint32_t last_map_block)
+{
+ rtems_rfs_write_u32 (&handle->node->last_map_block, last_map_block);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Get the last data block from the inode.
+ *
+ * @param[in] handle is the inode handle.
+ *
+ * @retval block The last data block number.
+ *
+ */
+static inline uint32_t
+rtems_rfs_inode_get_last_data_block (rtems_rfs_inode_handle* handle)
+{
+ return rtems_rfs_read_u32 (&handle->node->last_data_block);
+}
+
+/**
+ * Set the last data block.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] block_count is the last data block number.
+ */
+static inline void
+rtems_rfs_inode_set_last_data_block (rtems_rfs_inode_handle* handle, uint32_t last_data_block)
+{
+ rtems_rfs_write_u32 (&handle->node->last_data_block, last_data_block);
+ rtems_rfs_buffer_mark_dirty (&handle->buffer);
+}
+
+/**
+ * Allocate an inode number and return it.
+ *
+ * @param[in] fs is the file system data.
+ * @param[out] ino will contain the ino.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_alloc (rtems_rfs_file_system* fs,
+ rtems_rfs_bitmap_bit goal,
+ rtems_rfs_ino* ino);
+
+/**
+ * Free an inode.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] ino is the ino too free.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_free (rtems_rfs_file_system* fs,
+ rtems_rfs_ino ino);
+
+/**
+ * Open the inode handle. This reads the inode into the buffer and sets the
+ * data pointer. All data is in media byte order and needs to be accessed via
+ * the supporting calls.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] ino is the inode number.
+ * @param[in] handle is the handle to the inode we are opening.
+ * @param[in] load If true load the inode into memory from the media.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_open (rtems_rfs_file_system* fs,
+ rtems_rfs_ino ino,
+ rtems_rfs_inode_handle* handle,
+ bool load);
+
+/**
+ * The close inode handle. All opened inodes need to be closed.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] handle is the handle to close.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_close (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* handle);
+
+/**
+ * Load the inode into memory.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] handle is the inode handle to load.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_load (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* handle);
+
+/**
+ * Unload the inode from memory.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] handle is the inode handle to unload.
+ * @param[in] update_ctime Update the ctime field of the inode.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_unload (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* handle,
+ bool update_ctime);
+
+/**
+ * Create an inode allocating, initialising and adding an entry to the parent
+ * directory.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] parent is the parent inode number to add the directory entry to.
+ * @param[in] name is a pointer to the name of the directory entryinode
+ * to create.
+ *
+ */
+int rtems_rfs_inode_create (rtems_rfs_file_system* fs,
+ rtems_rfs_ino parent,
+ const char* name,
+ size_t length,
+ uint16_t mode,
+ uint16_t links,
+ uid_t uid,
+ gid_t gid,
+ rtems_rfs_ino* ino);
+
+/**
+ * Delete the inode eraseing it and release the buffer to commit the write. You
+ * need to load the inode again if you wish to use it again.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] handle is the inode handle to erase.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_delete (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* handle);
+
+/**
+ * Initialise a new inode.
+ *
+ * @param[in] handle is the inode handle to initialise.
+ * @param[in] links are the number of links to the inode.
+ * @param[in] mode is the inode mode.
+ * @param[in] uid is the user id.
+ * @param[in] gid is the group id.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_initialise (rtems_rfs_inode_handle* handle,
+ uint16_t links,
+ uint16_t mode,
+ uid_t uid,
+ gid_t gid);
+
+/**
+ * Time stamp the inode with the current time. The ctime field is hanlded
+ * automatically.
+ *
+ * @param[in] handle is the inode handle.
+ * @param[in] atime Update the atime field.
+ * @param[in] mtime UPdate the mtime field.
+ *
+ * @retval 0 Successful operation.
+ * @retval ENXIO No inode is loaded.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_inode_time_stamp_now (rtems_rfs_inode_handle* handle,
+ bool atime,
+ bool mtime);
+
+/**
+ * Calculate the size of data attached to the inode.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] handle is the inode handle.
+ *
+ * @retval size The data size in bytes in the block map attched to the inode.
+ */
+rtems_rfs_pos rtems_rfs_inode_get_size (rtems_rfs_file_system* fs,
+ rtems_rfs_inode_handle* handle);
+
+#endif
+
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-link.h b/cpukit/include/rtems/rfs/rtems-rfs-link.h
new file mode 100644
index 0000000000..d30814aaff
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-link.h
@@ -0,0 +1,124 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File System Link Support
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File System Link Support
+ *
+ * This file provides the link support functions.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+
+#if !defined (_RTEMS_RFS_LINK_H_)
+#define _RTEMS_RFS_LINK_H_
+
+#include <dirent.h>
+
+#include <rtems/rfs/rtems-rfs-file-system.h>
+#include <rtems/rfs/rtems-rfs-inode.h>
+
+/**
+ * Directory unlink modes.
+ */
+typedef enum rtems_rfs_unlink_dir_e
+{
+ rtems_rfs_unlink_dir_denied, /**< Not allowed to unlink a directory. */
+ rtems_rfs_unlink_dir_if_empty, /**< Unlink if the directory is empty. */
+ rtems_rfs_unlink_dir_allowed /**< Unlinking of directories is allowed. */
+} rtems_rfs_unlink_dir;
+
+/**
+ * Create a link. Do not link directories unless renaming or you will create
+ * loops in the file system.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] name is a pointer to the name of the link.
+ * @param[in] length is the length of the name.
+ * @param[in] parent is the inode number of the parent directory.
+ * @param[in] target is the inode of the target.
+ * @param[in] link_dir If true directories can be linked. Useful when
+ * renaming.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_link (rtems_rfs_file_system* fs,
+ const char* name,
+ int length,
+ rtems_rfs_ino parent,
+ rtems_rfs_ino target,
+ bool link_dir);
+
+/**
+ * Unlink the node from the parent directory. A directory offset for the
+ * target entry is required because links cause a number of inode numbers to
+ * appear in a single directory so scanning does not work.
+ *
+ * @param[in] fs is the file system.
+ * @param[in] parent is the inode number of the parent directory.
+ * @param[in] target is the inode of the target.
+ * @param[in] doff is the parent directory entry offset for the target entry.
+ * @param[in] dir_mode is the directory unlink mode.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_unlink (rtems_rfs_file_system* fs,
+ rtems_rfs_ino parent,
+ rtems_rfs_ino target,
+ uint32_t doff,
+ rtems_rfs_unlink_dir dir_mode);
+
+/**
+ * Symbolic link is an inode that has a path attached.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] name is a pointer to the name of the node.
+ * @param[in] length is the length of the name of the node.
+ * @param[in] link is a pointer to the link path attached to the
+ * symlink inode.
+ * @param[in] link_length is the length of the link path.
+ * @param[in] parent is the parent inode number.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_symlink (rtems_rfs_file_system* fs,
+ const char* name,
+ int length,
+ const char* link,
+ int link_length,
+ uid_t uid,
+ gid_t gid,
+ rtems_rfs_ino parent);
+
+/**
+ * Read a symbolic link into the provided buffer returning the link of link
+ * name.
+ *
+ * @param[in] fs is the file system data.
+ * @param[in] link is the link inode number to read.
+ * @param[in] path is a pointer to the buffer to write the link path into.
+ * @param[in] size is the size of the buffer.
+ * @param[out] length will contain the length of the link path.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_rfs_symlink_read (rtems_rfs_file_system* fs,
+ rtems_rfs_ino link,
+ char* path,
+ size_t size,
+ size_t* length);
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-mutex.h b/cpukit/include/rtems/rfs/rtems-rfs-mutex.h
new file mode 100644
index 0000000000..606fd53233
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-mutex.h
@@ -0,0 +1,116 @@
+/**
+ * @file
+ *
+ * @brief RTEMS File System Mutex
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File System Mutex.
+ *
+ * It may be suprising we abstract this for the RTEMS file system but this code
+ * is designed to be run on host operating systems.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+#if !defined (_RTEMS_RFS_MUTEX_H_)
+#define _RTEMS_RFS_MUTEX_H_
+
+#include <errno.h>
+
+#include <rtems/rfs/rtems-rfs-trace.h>
+
+#if __rtems__
+#include <rtems.h>
+#include <rtems/error.h>
+#endif
+
+/**
+ * RFS Mutex type.
+ */
+#if __rtems__
+typedef rtems_id rtems_rfs_mutex;
+#else
+typedef uint32_t rtems_rfs_mutex; /* place holder */
+#endif
+
+/**
+ * @brief Create the mutex.
+ *
+ * @param [in] mutex is pointer to the mutex handle returned to the caller.
+ *
+ * @retval 0 Successful operation.
+ * @retval EIO An error occurred.
+ *
+ */
+int rtems_rfs_mutex_create (rtems_rfs_mutex* mutex);
+
+/**
+ * @brief Destroy the mutex.
+ *
+ * @param[in] mutex Reference to the mutex handle returned to the caller.
+ *
+ * @retval 0 Successful operation.
+ * @retval EIO An error occurred.
+ */
+int rtems_rfs_mutex_destroy (rtems_rfs_mutex* mutex);
+
+/**
+ * @brief Lock the mutex.
+ *
+ * @param[in] mutex is a pointer to the mutex to lock.
+ *
+ * @retval 0 Successful operation.
+ * @retval EIO An error occurred.
+ */
+static inline int
+rtems_rfs_mutex_lock (rtems_rfs_mutex* mutex)
+{
+#if __rtems__
+ rtems_status_code sc = rtems_semaphore_obtain (*mutex, RTEMS_WAIT, 0);
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+#if RTEMS_RFS_TRACE
+ if (rtems_rfs_trace (RTEMS_RFS_TRACE_MUTEX))
+ printf ("rtems-rfs: mutex: obtain failed: %s\n",
+ rtems_status_text (sc));
+#endif
+ return EIO;
+ }
+#endif
+ return 0;
+}
+
+/**
+ * @brief Unlock the mutex.
+ *
+ * @param[in] mutex is a pointer to the mutex to unlock.
+ *
+ * @retval 0 Successful operation.
+ * @retval EIO An error occurred.
+ */
+static inline int
+rtems_rfs_mutex_unlock (rtems_rfs_mutex* mutex)
+{
+#if __rtems__
+ rtems_status_code sc = rtems_semaphore_release (*mutex);
+ if (sc != RTEMS_SUCCESSFUL)
+ {
+#if RTEMS_RFS_TRACE
+ if (rtems_rfs_trace (RTEMS_RFS_TRACE_MUTEX))
+ printf ("rtems-rfs: mutex: release failed: %s\n",
+ rtems_status_text (sc));
+#endif
+ return EIO;
+ }
+#endif
+ return 0;
+}
+
+#endif
diff --git a/cpukit/include/rtems/rfs/rtems-rfs-trace.h b/cpukit/include/rtems/rfs/rtems-rfs-trace.h
new file mode 100644
index 0000000000..4d6d0c9ddb
--- /dev/null
+++ b/cpukit/include/rtems/rfs/rtems-rfs-trace.h
@@ -0,0 +1,135 @@
+/**
+ * @file
+ *
+ * @brief Manages the Trace and Debugging Features of the
+ * RTEMS RFS File System
+ *
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File Systems Trace manages the trace and debugging features of the
+ * RTEMS RFS file system. The design allows all tracing code and strings to be
+ * removed from the target code for small footprint systems.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+
+#if !defined (_RTEMS_RFS_TRACE_H_)
+#define _RTEMS_RFS_TRACE_H_
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+
+/**
+ * Is tracing enabled ?
+ */
+#if !defined (RTEMS_RFS_TRACE)
+#define RTEMS_RFS_TRACE 1
+#endif
+
+/**
+ * The type of the mask.
+ */
+typedef uint64_t rtems_rfs_trace_mask;
+
+/**
+ * List of tracing bits for the various parts of the file system.
+ */
+#define RTEMS_RFS_TRACE_ALL (0xffffffffffffffffULL)
+#define RTEMS_RFS_TRACE_OPEN (1ULL << 0)
+#define RTEMS_RFS_TRACE_CLOSE (1ULL << 1)
+#define RTEMS_RFS_TRACE_MUTEX (1ULL << 2)
+#define RTEMS_RFS_TRACE_BUFFER_OPEN (1ULL << 3)
+#define RTEMS_RFS_TRACE_BUFFER_CLOSE (1ULL << 4)
+#define RTEMS_RFS_TRACE_BUFFER_SYNC (1ULL << 5)
+#define RTEMS_RFS_TRACE_BUFFER_RELEASE (1ULL << 6)
+#define RTEMS_RFS_TRACE_BUFFER_CHAINS (1ULL << 7)
+#define RTEMS_RFS_TRACE_BUFFER_HANDLE_REQUEST (1ULL << 8)
+#define RTEMS_RFS_TRACE_BUFFER_HANDLE_RELEASE (1ULL << 9)
+#define RTEMS_RFS_TRACE_BUFFER_SETBLKSIZE (1ULL << 10)
+#define RTEMS_RFS_TRACE_BUFFERS_RELEASE (1ULL << 11)
+#define RTEMS_RFS_TRACE_BLOCK_FIND (1ULL << 12)
+#define RTEMS_RFS_TRACE_BLOCK_MAP_GROW (1ULL << 13)
+#define RTEMS_RFS_TRACE_BLOCK_MAP_SHRINK (1ULL << 14)
+#define RTEMS_RFS_TRACE_GROUP_OPEN (1ULL << 15)
+#define RTEMS_RFS_TRACE_GROUP_CLOSE (1ULL << 16)
+#define RTEMS_RFS_TRACE_GROUP_BITMAPS (1ULL << 17)
+#define RTEMS_RFS_TRACE_INODE_OPEN (1ULL << 18)
+#define RTEMS_RFS_TRACE_INODE_CLOSE (1ULL << 19)
+#define RTEMS_RFS_TRACE_INODE_LOAD (1ULL << 20)
+#define RTEMS_RFS_TRACE_INODE_UNLOAD (1ULL << 21)
+#define RTEMS_RFS_TRACE_INODE_CREATE (1ULL << 22)
+#define RTEMS_RFS_TRACE_INODE_DELETE (1ULL << 23)
+#define RTEMS_RFS_TRACE_LINK (1ULL << 24)
+#define RTEMS_RFS_TRACE_UNLINK (1ULL << 25)
+#define RTEMS_RFS_TRACE_DIR_LOOKUP_INO (1ULL << 26)
+#define RTEMS_RFS_TRACE_DIR_LOOKUP_INO_CHECK (1ULL << 27)
+#define RTEMS_RFS_TRACE_DIR_LOOKUP_INO_FOUND (1ULL << 28)
+#define RTEMS_RFS_TRACE_DIR_ADD_ENTRY (1ULL << 29)
+#define RTEMS_RFS_TRACE_DIR_DEL_ENTRY (1ULL << 30)
+#define RTEMS_RFS_TRACE_DIR_READ (1ULL << 31)
+#define RTEMS_RFS_TRACE_DIR_EMPTY (1ULL << 32)
+#define RTEMS_RFS_TRACE_SYMLINK (1ULL << 33)
+#define RTEMS_RFS_TRACE_SYMLINK_READ (1ULL << 34)
+#define RTEMS_RFS_TRACE_FILE_OPEN (1ULL << 35)
+#define RTEMS_RFS_TRACE_FILE_CLOSE (1ULL << 36)
+#define RTEMS_RFS_TRACE_FILE_IO (1ULL << 37)
+#define RTEMS_RFS_TRACE_FILE_SET (1ULL << 38)
+
+/**
+ * Call to check if this part is bring traced. If RTEMS_RFS_TRACE is defined to
+ * 0 the code is dead code elminiated when built with -Os, -O2, or higher.
+ *
+ * @param[in] mask is the part of the API to trace.
+ *
+ * @retval true Tracing is active for the mask.
+ * @retval false Do not trace.
+ */
+#if RTEMS_RFS_TRACE
+bool rtems_rfs_trace (rtems_rfs_trace_mask mask);
+#else
+#define rtems_rfs_trace(_m) (0)
+#endif
+
+/**
+ * Set the mask.
+ *
+ * @param[in] mask are the mask bits to set.
+ *
+ * @retval mask The previous mask.
+ */
+#if RTEMS_RFS_TRACE
+rtems_rfs_trace_mask rtems_rfs_trace_set_mask (rtems_rfs_trace_mask mask);
+#else
+#define rtems_rfs_trace_set_mask(_m)
+#endif
+
+/**
+ * Clear the mask.
+ *
+ * @param[in] mask are the mask bits to clear.
+ *
+ * @retval mask The previous mask.
+ */
+#if RTEMS_RFS_TRACE
+rtems_rfs_trace_mask rtems_rfs_trace_clear_mask (rtems_rfs_trace_mask mask);
+#else
+#define rtems_rfs_trace_clear_mask(_m)
+#endif
+
+/**
+ * Add shell trace shell command.
+ */
+#if RTEMS_RFS_TRACE
+int rtems_rfs_trace_shell_command (int argc, char *argv[]);
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/ringbuf.h b/cpukit/include/rtems/ringbuf.h
new file mode 100644
index 0000000000..c16a79d1ae
--- /dev/null
+++ b/cpukit/include/rtems/ringbuf.h
@@ -0,0 +1,63 @@
+/**
+ * @file
+ *
+ * @brief Simple Ring Buffer Functionality
+ *
+ * This file provides simple ring buffer functionality.
+ */
+
+
+#ifndef _RTEMS_RINGBUF_H
+#define _RTEMS_RINGBUF_H
+
+#include <rtems.h>
+
+#ifndef RINGBUF_QUEUE_LENGTH
+#define RINGBUF_QUEUE_LENGTH 128
+#endif
+
+typedef struct {
+ uint8_t buffer[RINGBUF_QUEUE_LENGTH];
+ volatile int head;
+ volatile int tail;
+ rtems_interrupt_lock lock;
+} Ring_buffer_t;
+
+#define Ring_buffer_Initialize( _buffer ) \
+ do { \
+ (_buffer)->head = (_buffer)->tail = 0; \
+ rtems_interrupt_lock_initialize(&(_buffer)->lock, "ring buffer"); \
+ } while ( 0 )
+
+#define Ring_buffer_Destory( _buffer ) \
+ do { \
+ rtems_interrupt_lock_destroy(&(_buffer)->lock); \
+ } while ( 0 )
+
+#define Ring_buffer_Is_empty( _buffer ) \
+ ( (_buffer)->head == (_buffer)->tail )
+
+#define Ring_buffer_Is_full( _buffer ) \
+ ( (_buffer)->head == ((_buffer)->tail + 1) % RINGBUF_QUEUE_LENGTH )
+
+#define Ring_buffer_Add_character( _buffer, _ch ) \
+ do { \
+ rtems_interrupt_lock_context lock_context; \
+ \
+ rtems_interrupt_lock_acquire( &(_buffer)->lock, &lock_context ); \
+ (_buffer)->tail = ((_buffer)->tail+1) % RINGBUF_QUEUE_LENGTH; \
+ (_buffer)->buffer[ (_buffer)->tail ] = (_ch); \
+ rtems_interrupt_lock_release( &(_buffer)->lock, &lock_context ); \
+ } while ( 0 )
+
+#define Ring_buffer_Remove_character( _buffer, _ch ) \
+ do { \
+ rtems_interrupt_lock_context lock_context; \
+ \
+ rtems_interrupt_lock_acquire( &(_buffer)->lock, &lock_context ); \
+ (_buffer)->head = ((_buffer)->head+1) % RINGBUF_QUEUE_LENGTH; \
+ (_ch) = (_buffer)->buffer[ (_buffer)->head ]; \
+ rtems_interrupt_lock_release( &(_buffer)->lock, &lock_context ); \
+ } while ( 0 )
+
+#endif
diff --git a/cpukit/include/rtems/rtems-debugger.h b/cpukit/include/rtems/rtems-debugger.h
new file mode 100644
index 0000000000..1fc8b3d522
--- /dev/null
+++ b/cpukit/include/rtems/rtems-debugger.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>. All rights reserved.
+ *
+ * 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.
+ */
+
+/*
+ * Debugger for RTEMS.
+ */
+
+#ifndef _RTEMS_DEBUGGER_h
+#define _RTEMS_DEBUGGER_h
+
+#include <stdbool.h>
+
+#include <rtems.h>
+#include <rtems/printer.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Timeout period for an ack
+ */
+#define RTEMS_DEBUGGER_TIMEOUT (3)
+
+/**
+ * Start the Debugger.
+ */
+extern int rtems_debugger_start(const char* remote,
+ const char* device,
+ int timeout,
+ rtems_task_priority priority,
+ const rtems_printer* printer);
+
+/**
+ * Stop the Debugger.
+ */
+extern int rtems_debugger_stop(void);
+
+/**
+ * Is the Debugger running?.
+ */
+extern bool rtems_debugger_running(void);
+
+/**
+ * Verbose control.
+ */
+extern void rtems_debugger_set_verbose(bool on);
+
+/**
+ * Control remote debug printing.
+ */
+extern int rtems_debugger_remote_debug(bool state);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif
diff --git a/cpukit/include/rtems/rtems-fdt-shell.h b/cpukit/include/rtems/rtems-fdt-shell.h
new file mode 100644
index 0000000000..74e9a44aaf
--- /dev/null
+++ b/cpukit/include/rtems/rtems-fdt-shell.h
@@ -0,0 +1,42 @@
+/*
+ * COPYRIGHT (c) 2013-2017 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_fdt
+ *
+ * @brief RTEMS Flattened Device Tree Shell Command
+ *
+ * Support for loading, managing and accessing FDT blobs in RTEMS.
+ */
+
+#if !defined (_RTEMS_FDT_SHELL_H_)
+#define _RTEMS_FDT_SHELL_H_
+
+#include <rtems/rtems-fdt.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Add a shell command to access memory and registers associated with the DTF.
+ */
+void rtems_fdt_add_shell_command (void);
+
+/**
+ * Get a pointer to the handle. You can use this to load files or register
+ * blobs and have the shell command access them.
+ */
+rtems_fdt_handle* rtems_fdt_get_shell_handle (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtems-fdt.h b/cpukit/include/rtems/rtems-fdt.h
new file mode 100644
index 0000000000..ebc222e4c9
--- /dev/null
+++ b/cpukit/include/rtems/rtems-fdt.h
@@ -0,0 +1,621 @@
+/*
+ * COPYRIGHT (c) 2013-2017 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ *
+ * Interface based on the libdft:
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_fdt
+ *
+ * @brief RTEMS Flattened Device Tree
+ *
+ * Support for loading, managing and accessing FDT blobs in RTEMS.
+ */
+
+#if !defined (_RTEMS_FDT_H_)
+#define _RTEMS_FDT_H_
+
+#include <rtems.h>
+#include <rtems/chain.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * A blob.
+ */
+struct rtems_fdt_blob;
+typedef struct rtems_fdt_blob rtems_fdt_blob;
+
+/**
+ * A blob handle is a way to manage access to the FDT blobs. The blob is
+ * referenced via the handle to allow searches across loaded DTB's to return
+ * the referenced DTB.
+ */
+typedef struct
+{
+ rtems_fdt_blob* blob; /**< The blob the handle references. */
+} rtems_fdt_handle;
+
+/*
+ * The following are mappings to the standard FDT calls.
+ */
+
+/**
+ * RTEMS_FDT_ERR_NOTFOUND: The requested node or property does not exist
+ */
+#define RTEMS_FDT_ERR_NOTFOUND 1
+/**
+ * RTEMS_FDT_ERR_EXISTS: Attemped to create a node or property which already
+ * exists */
+#define RTEMS_FDT_ERR_EXISTS 2
+/**
+ * RTEMS_FDT_ERR_NOSPACE: Operation needed to expand the device tree, but its
+ * buffer did not have sufficient space to contain the expanded tree. Use
+ * rtems_fdt_open_into() to move the device tree to a buffer with more space.
+ */
+#define RTEMS_FDT_ERR_NOSPACE 3
+
+/* Error codes: codes for bad parameters */
+/**
+ * RTEMS_FDT_ERR_BADOFFSET: Function was passed a structure block offset which
+ * is out-of-bounds, or which points to an unsuitable part of the structure for
+ * the operation.
+ */
+#define RTEMS_FDT_ERR_BADOFFSET 4
+/**
+ * RTEMS_FDT_ERR_BADPATH: Function was passed a badly formatted path
+ * (e.g. missing a leading / for a function which requires an absolute path)
+*/
+#define RTEMS_FDT_ERR_BADPATH 5
+/**
+ * RTEMS_FDT_ERR_BADPHANDLE: Function was passed an invalid phandle value.
+ * phandle values of 0 and -1 are not permitted.
+ */
+#define RTEMS_FDT_ERR_BADPHANDLE 6
+/**
+ * RTEMS_FDT_ERR_BADSTATE: Function was passed an incomplete device tree
+ * created by the sequential-write functions, which is not sufficiently
+ * complete for the requested operation.
+ */
+#define RTEMS_FDT_ERR_BADSTATE 7
+
+/* Error codes: codes for bad device tree blobs */
+
+/**
+ * RTEMS_FDT_ERR_TRUNCATED: Structure block of the given device tree ends
+ * without an RTEMS_FDT_END tag.
+ */
+#define RTEMS_FDT_ERR_TRUNCATED 8
+/**
+ * RTEMS_FDT_ERR_BADMAGIC: Given "device tree" appears not to be a device tree
+ * at all - it is missing the flattened device tree magic number.
+ */
+#define RTEMS_FDT_ERR_BADMAGIC 9
+/** RTEMS_FDT_ERR_BADVERSION: Given device tree has a version which can't be
+ * handled by the requested operation. For read-write functions, this may mean
+ * that rtems_fdt_open_into() is required to convert the tree to the expected
+ * version.
+ */
+#define RTEMS_FDT_ERR_BADVERSION 10
+/**
+ * RTEMS_FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt structure block
+ * or other serious error (e.g. misnested nodes, or subnodes preceding
+ * properties).
+ */
+#define RTEMS_FDT_ERR_BADSTRUCTURE 11
+/**
+ * RTEMS_FDT_ERR_BADLAYOUT: For read-write functions, the given device tree has
+ * it's sub-blocks in an order that the function can't handle (memory reserve
+ * map, then structure, then strings). Use rtems_fdt_open_into() to reorganize
+ * the tree into a form suitable for the read-write operations.
+ */
+#define RTEMS_FDT_ERR_BADLAYOUT 12
+/**
+ * "Can't happen" error indicating a bug in libfdt
+ */
+#define RTEMS_FDT_ERR_INTERNAL 13
+
+/* RTEMS error codes. */
+
+/**
+ * Invalid handle.
+ */
+#define RTEMS_FDT_ERR_INVALID_HANDLE 100
+/**
+ * No memory.
+ */
+#define RTEMS_FDT_ERR_NO_MEMORY 101
+/**
+ * File not found.
+ */
+#define RTEMS_FDT_ERR_NOT_FOUND 102
+/**
+ * Cannot read the DTB into memory.
+ */
+#define RTEMS_FDT_ERR_READ_FAIL 103
+/**
+ * The blob cannot be unloaded as it is referenced.
+ */
+#define RTEMS_FDT_ERR_REFERENCED 104
+
+#define RTEMS_FDT_ERR_RTEMS_MIN 100
+#define RTEMS_FDT_ERR_MAX 104
+
+/**
+ * Initialise a handle to a default state.
+ *
+ * @param handle The handle to initialise.
+ */
+void rtems_fdt_init_handle (rtems_fdt_handle* handle);
+
+/**
+ * Duplicate a handle. The copy must be released.
+ *
+ * @param from Duplicate from this handle.
+ * @param to Duplicate to this handle.
+ */
+void rtems_fdt_dup_handle (rtems_fdt_handle* from, rtems_fdt_handle* to);
+
+/**
+ * Release a blob from a handle and clear it.
+ *
+ * @param handle The handle to check.
+ */
+void rtems_fdt_release_handle (rtems_fdt_handle* handle);
+
+/**
+ * Check if a handle had a valid blob assigned.
+ *
+ * @param handle The handle to check.
+ * @retval true The handle has a valid blob.
+ * @retval false The handle does not have a valid blob.
+ */
+bool rtems_fdt_valid_handle (const rtems_fdt_handle* handle);
+
+/**
+ * Find a tree node by its full path looking across of loaded blobs.. Each path
+ * component may omit the unit address portion, but the results of this are
+ * undefined if any such path component is ambiguous (that is if there are
+ * multiple nodes at the relevant level matching the given component,
+ * differentiated only by unit address).
+ *
+ * If the handle points to a valid blob it is release and the search starts
+ * from the first blob.
+ *
+ * @param handle The FDT handle assigned to the blob if found else left invalid.
+ * @param path Full path of the node to locate.
+ * @param int If less than 0 an error code else the node offset is returned.
+ */
+int rtems_fdt_find_path_offset (rtems_fdt_handle* handle, const char* path);
+
+/**
+ * Load a device tree blob or DTB file into memory and register it on the chain
+ * of blobs.
+ *
+ * @param filename The name of the blob file to load.
+ * @param handle The handle returns the reference to the blob once load.
+ * @return int If less than 0 it is an error code else it is the blob descriptor.
+ */
+int rtems_fdt_load (const char* const filename, rtems_fdt_handle* handle);
+
+/**
+ * Register a device tree blob or DTB on to the chain of blobs.
+ *
+ * @param blob_desc A pointer to the blob.
+ * @param handle The handle returns the reference to the blob once load.
+ * @return int If less than 0 it is an error code else it is the blob descriptor.
+ */
+int rtems_fdt_register (const void* blob, rtems_fdt_handle* handle);
+
+/**
+ * Unload a device tree blob or DTB file and release any memory allocated when
+ * loading. The blob is removed from the list of registered.
+ *
+ * @param blob_desc A valid blob descriptor.
+ * @return int If less than 0 it is an error code else 0 is return on success.
+ */
+int rtems_fdt_unload (rtems_fdt_handle* handle);
+
+/**
+ * Returns the number of entries in the device tree blob's memory
+ * reservation map. This does not include the terminating 0,0 entry
+ * or any other (0,0) entries reserved for expansion.
+ *
+ * @param blob_desc A valid blob descriptor.
+ * @return int The number of entries.
+ */
+int rtems_fdt_num_mem_rsv (rtems_fdt_handle* handle);
+
+/**
+ * Retrieve one memory reserve map entry. On success, *address and *size will
+ * contain the address and size of the n-th reserve map entry from the device
+ * tree blob, in native-endian format.
+ *
+ * @param blob_desc A valid blob descriptor.
+ * @param address Pointer to 64-bit variables to hold the addresses.
+ * @param size Pointer to 64-bit variables to hold the size.
+ * @return int If less than 0 it is an error code else 0 is returned on
+ * success.
+ */
+int rtems_fdt_get_mem_rsv (rtems_fdt_handle* handle,
+ int n,
+ uint64_t* address,
+ uint64_t* size);
+
+/**
+ * Find a subnode based on substring. Identical to rtems_fdt_subnode_offset(),
+ * but only examine the first namelen characters of name for matching the
+ * subnode name. This is useful for finding subnodes based on a portion of a
+ * larger string, such as a full path.
+ *
+ * @param blob_desc A valid blob descriptor.
+ * @param arentoffset Structure block offset of a node
+ * @param name Name of the subnode to locate.
+ * @param namelen Number of characters of name to consider.
+ * @return int If less than 0 it is an error code else the node offset is
+ * returned.
+ */
+int rtems_fdt_subnode_offset_namelen (rtems_fdt_handle* handle,
+ int parentoffset,
+ const char* const name,
+ int namelen);
+
+/**
+ * Find a subnode of a given node at structure block offset parentoffset with
+ * the given name. The name may include a unit address, in which case
+ * rtems_fdt_subnode_offset() will find the subnode with that unit address, or
+ * the unit address may be omitted, in which case rtems_fdt_subnode_offset()
+ * will find an arbitrary subnode whose name excluding unit address matches the
+ * given name.
+ *
+ * @param blob_desc A valid blob descriptor.
+ * @param parentoffset Structure block offset of a node.
+ * @param name The name of the subnode to locate.
+ * @return int If less than 0 it is an error code else the subnode offset is
+ * returned.
+ */
+int rtems_fdt_subnode_offset (rtems_fdt_handle* handle,
+ int parentoffset,
+ const char* const name);
+
+/**
+ * Find a tree node by its full path. Each path component may omit the unit
+ * address portion, but the results of this are undefined if any such path
+ * component is ambiguous (that is if there are multiple nodes at the relevant
+ * level matching the given component, differentiated only by unit address).
+ *
+ * @param handle The FDT handle to the current blob.
+ * @param path Full path of the node to locate.
+ * @param int If less than 0 an error code else the node offset is returned.
+ */
+int rtems_fdt_path_offset (rtems_fdt_handle* handle, const char* path);
+
+/**
+ * Retrieve the name of a given node (including unit address) of the device
+ * tree node at structure block offset @nodeoffset. If @length is non-NULL,
+ * the length of this name is also returned, in the integer pointed to by
+ * @length.
+ *
+ * @param handle The FDT handle to the current blob.
+ * @param nodeoffset Structure block offset of the starting node.
+ * @param length Pointer to an integer variable (will be overwritten) or NULL.
+ * @return const char* The node's name on success or NULL on error. The length
+ * if non-NULL will hold the error code.
+ */
+const char* rtems_fdt_get_name (rtems_fdt_handle* handle,
+ int nodeoffset,
+ int* length);
+
+/**
+ * Get property value based on substring. Identical to rtems_fdt_getprop(), but
+ * only examine the first namelen characters of name for matching the property
+ * name.
+ *
+ * @param handle The FDT handle to the current blob.
+ * @param nodeoffset Offset of the node whose property to find
+ * @param name The name of the property to find
+ * @param namelen The number of characters of name to consider
+ * @param length A pointer to an integer variable (will be overwritten) or
+ * NULL.
+ * @return const void* The node's property on success or NULL on error. The
+ * length if non-NULL will hold the error code.
+ */
+const void *rtems_fdt_getprop_namelen (rtems_fdt_handle* handle,
+ int nodeoffset,
+ const char* const name,
+ int namelen,
+ int* length);
+
+/**
+ * Retrieve the value of a given property. Retrieves a pointer to the value of
+ * the property named 'name' of the node at offset nodeoffset (this will be a
+ * pointer to within the device blob itself, not a copy of the value). If lenp
+ * is non-NULL, the length of the property value is also returned, in the
+ * integer pointed to by @length.
+ *
+ * @param handle The FDT handle to the current blob.
+ * @param nodeoffset The offset of the node whose property to find.
+ * @param name The name of the property to find.
+ * @param length A pointer to an integer variable (will be overwritten) or
+ * NULL.
+ * @return const void* The node's property on success or NULL on error. The
+ * length if non-NULL will hold the error code.
+ */
+const void *rtems_fdt_getprop (rtems_fdt_handle* handle,
+ int nodeoffset,
+ const char* const name,
+ int* length);
+
+/**
+ * Retrieve the phandle of a given of the device tree node at structure block
+ * offset nodeoffset.
+ *
+ * @param handle The FDT handle to the current blob.
+ * @oaram nodeoffset The structure block offset of the node.
+ * return uint32_t The phandle of the node at nodeoffset, on success (!= 0, !=
+ * -1) 0, if the node has no phandle, or another error occurs.
+ */
+uint32_t rtems_fdt_get_phandle (rtems_fdt_handle* handle, int nodeoffset);
+
+/**
+ * Get alias based on substring. Identical to rtems_fdt_get_alias(), but only
+ * examine the first namelen characters of name for matching the alias name.
+ *
+ * @param handle The FDT handle to the current blob.
+ * @param name The name of the alias th look up.
+ * @param namelen The number of characters of name to consider.
+ * @return const char* The alias or NULL.
+ */
+const char *rtems_fdt_get_alias_namelen (rtems_fdt_handle* handle,
+ const char* const name,
+ int namelen);
+
+/**
+ * Retreive the path referenced by a given alias. That is, the value of the
+ * property named 'name' in the node /aliases.
+ *
+ * @param handle The FDT handle to the current blob.
+ * @param name The name of the alias to look up.
+ * @return const char* A pointer to the expansion of the alias named 'name', of
+ * it exists NULL, if the given alias or the /aliases node
+ * does not exist
+ */
+const char* rtems_fdt_get_alias (rtems_fdt_handle* handle, const char* name);
+
+/**
+ * Determine the full path of a node. This function is expensive, as it must
+ * scan the device tree structure from the start to nodeoffset. It computes the
+ * full path of the node at offset nodeoffset, and records that path in the
+ * buffer at buf.
+ *
+ * @param handle The FDT handle to the current blob.
+ * @param nodeoffset The offset of the node whose path to find.
+ * @param buf A character buffer to contain the returned path (will be
+ * overwritten)
+ * @param buflen The size of the character buffer at buf.
+ * @return int 0 on success of an error code.
+ */
+int rtems_fdt_get_path (rtems_fdt_handle* handle,
+ int nodeoffset,
+ char* buf,
+ int buflen);
+
+/**
+ * Find a specific ancestor of a node at a specific depth from the root (where
+ * the root itself has depth 0, its immediate subnodes depth 1 and so forth).
+ * So rtems_fdt_supernode_atdepth_offset(blob, nodeoffset, 0, NULL); will
+ * always return 0, the offset of the root node. If the node at nodeoffset has
+ * depth D, then:
+ * rtems_fdt_supernode_atdepth_offset(blob, nodeoffset, D, NULL);
+ * will return nodeoffset itself.
+ *
+ * @param handle The FDT handle to the current blob.
+ * @param nodeoffset The offset of the node whose parent to find.
+ * @param supernodedepth The depth of the ancestor to find.
+ * @oaram nodedepth The pointer to an integer variable (will be overwritten) or
+ * NULL
+ * @return int If less than 0 an error else the node offset.
+ */
+int rtems_fdt_supernode_atdepth_offset (rtems_fdt_handle* handle,
+ int nodeoffset,
+ int supernodedepth,
+ int* nodedepth);
+
+/**
+ * Find the depth of a given node. The root node has depth 0, its immediate
+ * subnodes depth 1 and so forth.
+ *
+ * @note This function is expensive, as it must scan the device tree structure
+ * from the start to nodeoffset.
+ *
+ * @param handle The FDT handle to the current blob.
+ * @param nodeoffset The offset of the node whose parent to find.
+ * @return int If less than 0 an error else the node offset.
+ */
+int rtems_fdt_node_depth (rtems_fdt_handle* handle, int nodeoffset);
+
+/**
+ * Find the parent of a given node. This funciton locates the parent node of a
+ * given node (that is, it finds the offset of the node which contains the node
+ * at nodeoffset as a subnode).
+ *
+ * @note This function is expensive, as it must scan the device tree structure
+ * from the start to nodeoffset, *twice*.
+ *
+ * @param handle The FDT handle to the current blob.
+ * @param nodeoffset The offset of the node whose parent to find.
+ * @return int If less than 0 an error else the node offset.
+ */
+int rtems_fdt_parent_offset (rtems_fdt_handle* handle, int nodeoffset);
+
+/**
+ * Find nodes with a given property value. This funtion returns the offset of
+ * the first node after startoffset, which has a property named propname whose
+ * value is of length proplen and has value equal to propval; or if startoffset
+ * is -1, the very first such node in the tree.
+ *
+ * To iterate through all nodes matching the criterion, the following idiom can
+ * be used:
+ * offset = rtemsfdt_node_offset_by_prop_value(blob, -1, propname,
+ * propval, proplen);
+ * while (offset != -RTEMS_FDT_ERR_NOTFOUND) {
+ * // other code here
+ * offset = rtems_fdt_node_offset_by_prop_value(fdt, offset, propname,
+ * propval, proplen);
+ * }
+ *
+ * @note The -1 in the first call to the function, if 0 is used here
+ * instead, the function will never locate the root node, even if it
+ * matches the criterion.
+ *
+ * @param handle The FDT handle to the current blob.
+ * @param startoffset Only find nodes after this offset.
+ * @param propname The property name to check.
+ * @param propval The property value to search for.
+ * @param proplen The length of the value in propval.
+ * @return int The structure block offset of the located node (>= 0,
+ * >startoffset), on success and an error code is less
+ * than 0.
+ */
+int rtems_fdt_node_offset_by_prop_value (rtems_fdt_handle* handle,
+ int startoffset,
+ const char* const propname,
+ const void* propval,
+ int proplen);
+
+/**
+ * Find the node with a given phandle returning the offset of the node which
+ * has the given phandle value. If there is more than one node in the tree
+ * with the given phandle (an invalid tree), results are undefined.
+ *
+ * @param handle The FDT handle to the current blob.
+ * @param phandle The phandle value.
+ * @return int If less than 0 an error else the node offset.
+ */
+int rtems_fdt_node_offset_by_phandle (rtems_fdt_handle* handle,
+ uint32_t phandle);
+
+/**
+ * Check a node's compatible property returning 0 if the given node contains a
+ * 'compatible' property with the given string as one of its elements, it
+ * returns non-zero otherwise, or on error.
+ *
+ * @param handle The FDT handle to the current blob.
+ * @param nodeoffset The offset of a tree node.
+ * @param compatible The string to match against.
+ * @retval 0, if the node has a 'compatible' property listing the given string.
+ * @retval 1, if the node has a 'compatible' property, but it does not list the
+ * given string
+ */
+int rtems_fdt_node_check_compatible (rtems_fdt_handle* handle,
+ int nodeoffset,
+ const char* const compatible);
+
+/**
+ * Find nodes with a given 'compatible' value returning the offset of the first
+ * node after startoffset, which has a 'compatible' property which lists the
+ * given compatible string; or if startoffset is -1, the very first such node
+ * in the tree.
+ *
+ * To iterate through all nodes matching the criterion, the following idiom can
+ * be used:
+ *
+ * offset = rtems_fdt_node_offset_by_compatible(blob, -1, compatible);
+ * while (offset != -RTEMS_FDT_ERR_NOTFOUND) {
+ * // other code here
+ * offset = rtems_fdt_node_offset_by_compatible(blob, offset, compatible);
+ * }
+ *
+ * @note The -1 in the first call to the function, if 0 is used here instead,
+ * the function will never locate the root node, even if it matches the
+ * criterion.
+ *
+ * @param handle The FDT handle to the current blob.
+ * @param startoffset Only find nodes after this offset.
+ * @param compatible The 'compatible' string to match against.
+ * @return int If less than 0 an error else the node offset.
+ */
+int rtems_fdt_node_offset_by_compatible(rtems_fdt_handle* handle,
+ int startoffset,
+ const char* compatible);
+
+/**
+ * Traverse to the next node.
+ *
+ * @param handle The FDT handle to the current blob.
+ * @param offset The offset in the blob to start looking for the next node.
+ * @param depth Pointer to return the depth the node is.
+ * @return int If less than 0 an error else the node offset.
+ */
+int rtems_fdt_next_node (rtems_fdt_handle* handle, int offset, int* depth);
+
+/**
+ * Return an error string given an error value.
+ *
+ * @param errval The error value.
+ * @return const char* The error string.
+ */
+const char* rtems_fdt_strerror (int errval);
+
+/**
+ * Return a property given a path.
+ */
+int rtems_fdt_prop_value(const char* const path,
+ const char* const propname,
+ void* value,
+ size_t* size);
+
+/**
+ * Create a map given a path the property name and the names of the subnodes of
+ * the path.
+ */
+int rtems_fdt_prop_map (const char* const path,
+ const char* const propname,
+ const char* const names[],
+ uint32_t* values,
+ size_t count);
+
+/*
+ * Get a value given a path and a property.
+ */
+int rtems_fdt_get_value (const char* const path,
+ const char* const property,
+ size_t size,
+ uint32_t* value);
+
+/**
+ * Get the number of entries in an FDT handle.
+ */
+int rtems_fdt_num_entries(rtems_fdt_handle* handle);
+
+/**
+ * Get the numbered entry name. Note that the id isn't the same as
+ * the offset - it's numbered 0, 1, 2 ... num_entries-1
+ */
+const char *rtems_fdt_entry_name(rtems_fdt_handle* handle, int id);
+
+/**
+ * Get the numbered entry offset. Note that the id isn't the same as
+ * the offset - it's numbered 0, 1, 2 ... num_entries-1
+ */
+int rtems_fdt_entry_offset(rtems_fdt_handle* handle, int id);
+
+/*
+ * Helper function to convert the void* property result to a 32bit unsigned int.
+ */
+uint32_t rtems_fdt_get_uint32 (const void* prop);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtems-rfs-format.h b/cpukit/include/rtems/rtems-rfs-format.h
new file mode 100644
index 0000000000..f65cce1789
--- /dev/null
+++ b/cpukit/include/rtems/rtems-rfs-format.h
@@ -0,0 +1,90 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_rfs
+ *
+ * @brief RTEMS File System Format
+ *
+ * This function lets you format a disk in the RFS format.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+#if !defined (_RTEMS_RFS_FORMAT_H_)
+#define _RTEMS_RFS_FORMAT_H_
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/rfs/rtems-rfs-trace.h>
+
+/**
+ * RFS File System Configuration data used to format the file system. For
+ * default values leave the field set to 0.
+ */
+typedef struct _rtems_rfs_format_config
+{
+ /**
+ * The size of a block.
+ */
+ size_t block_size;
+
+ /**
+ * The number of blocks in a group.
+ */
+ size_t group_blocks;
+
+ /**
+ * The number of inodes in a group.
+ */
+ size_t group_inodes;
+
+ /**
+ * The percentage overhead allocated to inodes.
+ */
+ int inode_overhead;
+
+ /**
+ * The maximum length of a name.
+ */
+ size_t max_name_length;
+
+ /**
+ * Initialise the inode tables to all ones.
+ */
+ bool initialise_inodes;
+
+ /**
+ * Is the format verbose.
+ */
+ bool verbose;
+
+} rtems_rfs_format_config;
+
+/**
+ * RFS Format command.
+ *
+ * @param[in] name is the device name to format.
+ * @param[in] config is a pointer to the configuration table.
+ *
+ * @retval -1 Error. See errno.
+ * @retval 0 No error. Format successful.
+ */
+int rtems_rfs_format (const char* name, const rtems_rfs_format_config* config);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/rtems-rfs-shell.h b/cpukit/include/rtems/rtems-rfs-shell.h
new file mode 100644
index 0000000000..c2e1108a47
--- /dev/null
+++ b/cpukit/include/rtems/rtems-rfs-shell.h
@@ -0,0 +1,48 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_rfs
+ * @brief RTEMS File Systems Shell Commands
+ *
+ * RTEMS File Systems Shell commands provide a CLI interface to support and
+ * development of the RFS file system.
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+#if !defined (_RTEMS_RFS_SHELL_H_)
+#define _RTEMS_RFS_SHELL_H_
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+/**
+ * The shell command for the RFS debugger.
+ *
+ * @param[in] argc is the argument count.
+ * @param[in] argv is a pointer to the argument variables.
+ *
+ * @retval 0 Successful operation.
+ * @retval error_code An error occurred.
+ */
+int rtems_shell_debugrfs (int argc, char *argv[]);
+
+/**
+ * The shell command for formatting an RFS file system.
+ *
+ * @param[in] argc is the argument count.
+ * @param[in] argv is a pointer to the argument variables.
+ *
+ * @retval 0 Successful operation.
+ * @retval 1 An error occurred.
+ */
+int rtems_shell_rfs_format (int argc, char* argv[]);
+
+#endif
diff --git a/cpukit/include/rtems/rtems-rfs.h b/cpukit/include/rtems/rtems-rfs.h
new file mode 100644
index 0000000000..958f9a636b
--- /dev/null
+++ b/cpukit/include/rtems/rtems-rfs.h
@@ -0,0 +1,38 @@
+/**
+ * @file
+ *
+ * @brief RFS File system Initialization
+ * @ingroup rtems_rfs
+ *
+ * RTEMS File System
+ *
+ */
+
+/*
+ * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+#if !defined(RTEMS_RFS_DEFINED)
+#define RTEMS_RFS_DEFINED
+
+#include <rtems.h>
+#include <rtems/fs.h>
+
+/**
+ * @defgroup rtems_rfs RTEMS File System Group Management
+ *
+ * @ingroup FileSystemTypesAndMount
+ */
+/**@{*/
+
+/**
+ * Initialise the RFS File system.
+ */
+int rtems_rfs_rtems_initialise (rtems_filesystem_mount_table_entry_t *mt_entry, const void *data);
+
+/**@}*/
+#endif
diff --git a/cpukit/include/rtems/rtems/asr.h b/cpukit/include/rtems/rtems/asr.h
new file mode 100644
index 0000000000..edd5e2fe62
--- /dev/null
+++ b/cpukit/include/rtems/rtems/asr.h
@@ -0,0 +1,156 @@
+/**
+ * @file rtems/rtems/asr.h
+ *
+ * @defgroup ClassicASR ASR Support
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Asynchronous Signal Handler
+ *
+ * This include file contains all the constants and structures associated
+ * with the Asynchronous Signal Handler. This Handler provides the low-level
+ * support required by the Signal Manager.
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_ASR_H
+#define _RTEMS_RTEMS_ASR_H
+
+#include <rtems/rtems/modes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicASR ASR Support
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality related to the Classic API Signal
+ * Manager.
+ */
+/**@{*/
+
+/**
+ * The following type defines the control block used to manage
+ * each signal set.
+ */
+typedef uint32_t rtems_signal_set;
+
+/**
+ * Return type for ASR Handler
+ */
+typedef void rtems_asr;
+
+/**
+ * The following type corresponds to the applications asynchronous
+ * signal processing routine.
+ */
+typedef rtems_asr ( *rtems_asr_entry )(
+ rtems_signal_set
+ );
+
+/**
+ * The following defines the control structure used to manage
+ * signals. Each thread has a copy of this record.
+ */
+typedef struct {
+ /** This field indicates if are ASRs enabled currently. */
+ bool is_enabled;
+ /** This field indicates if address of the signal handler function. */
+ rtems_asr_entry handler;
+ /** This field indicates if the task mode the signal will run with. */
+ Modes_Control mode_set;
+ /** This field indicates the signal set that is posted. */
+ rtems_signal_set signals_posted;
+ /** This field indicates the signal set that is pending. */
+ rtems_signal_set signals_pending;
+ /** This field indicates if nest level of signals being processed */
+ uint32_t nest_level;
+} ASR_Information;
+
+/*
+ * The following constants define the individual signals which may
+ * be used to compose a signal set.
+ */
+
+/** This defines the bit in the signal set associated with signal 0. */
+#define RTEMS_SIGNAL_0 0x00000001
+/** This defines the bit in the signal set associated with signal 1. */
+#define RTEMS_SIGNAL_1 0x00000002
+/** This defines the bit in the signal set associated with signal 2. */
+#define RTEMS_SIGNAL_2 0x00000004
+/** This defines the bit in the signal set associated with signal 3. */
+#define RTEMS_SIGNAL_3 0x00000008
+/** This defines the bit in the signal set associated with signal 4. */
+#define RTEMS_SIGNAL_4 0x00000010
+/** This defines the bit in the signal set associated with signal 5. */
+#define RTEMS_SIGNAL_5 0x00000020
+/** This defines the bit in the signal set associated with signal 6. */
+#define RTEMS_SIGNAL_6 0x00000040
+/** This defines the bit in the signal set associated with signal 7. */
+#define RTEMS_SIGNAL_7 0x00000080
+/** This defines the bit in the signal set associated with signal 8. */
+#define RTEMS_SIGNAL_8 0x00000100
+/** This defines the bit in the signal set associated with signal 9. */
+#define RTEMS_SIGNAL_9 0x00000200
+/** This defines the bit in the signal set associated with signal 10. */
+#define RTEMS_SIGNAL_10 0x00000400
+/** This defines the bit in the signal set associated with signal 11. */
+#define RTEMS_SIGNAL_11 0x00000800
+/** This defines the bit in the signal set associated with signal 12. */
+#define RTEMS_SIGNAL_12 0x00001000
+/** This defines the bit in the signal set associated with signal 13. */
+#define RTEMS_SIGNAL_13 0x00002000
+/** This defines the bit in the signal set associated with signal 14. */
+#define RTEMS_SIGNAL_14 0x00004000
+/** This defines the bit in the signal set associated with signal 15. */
+#define RTEMS_SIGNAL_15 0x00008000
+/** This defines the bit in the signal set associated with signal 16. */
+#define RTEMS_SIGNAL_16 0x00010000
+/** This defines the bit in the signal set associated with signal 17. */
+#define RTEMS_SIGNAL_17 0x00020000
+/** This defines the bit in the signal set associated with signal 18. */
+#define RTEMS_SIGNAL_18 0x00040000
+/** This defines the bit in the signal set associated with signal 19. */
+#define RTEMS_SIGNAL_19 0x00080000
+/** This defines the bit in the signal set associated with signal 20. */
+#define RTEMS_SIGNAL_20 0x00100000
+/** This defines the bit in the signal set associated with signal 21. */
+#define RTEMS_SIGNAL_21 0x00200000
+/** This defines the bit in the signal set associated with signal 22. */
+#define RTEMS_SIGNAL_22 0x00400000
+/** This defines the bit in the signal set associated with signal 23. */
+#define RTEMS_SIGNAL_23 0x00800000
+/** This defines the bit in the signal set associated with signal 24. */
+#define RTEMS_SIGNAL_24 0x01000000
+/** This defines the bit in the signal set associated with signal 25. */
+#define RTEMS_SIGNAL_25 0x02000000
+/** This defines the bit in the signal set associated with signal 26. */
+#define RTEMS_SIGNAL_26 0x04000000
+/** This defines the bit in the signal set associated with signal 27. */
+#define RTEMS_SIGNAL_27 0x08000000
+/** This defines the bit in the signal set associated with signal 28. */
+#define RTEMS_SIGNAL_28 0x10000000
+/** This defines the bit in the signal set associated with signal 29. */
+#define RTEMS_SIGNAL_29 0x20000000
+/** This defines the bit in the signal set associated with signal 30. */
+#define RTEMS_SIGNAL_30 0x40000000
+/** This defines the bit in the signal set associated with signal 31. */
+#define RTEMS_SIGNAL_31 0x80000000
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/asrimpl.h b/cpukit/include/rtems/rtems/asrimpl.h
new file mode 100644
index 0000000000..141c34d4bb
--- /dev/null
+++ b/cpukit/include/rtems/rtems/asrimpl.h
@@ -0,0 +1,99 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicASRImpl
+ *
+ * @brief Classic ASR Implementation
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_ASRIMPL_H
+#define _RTEMS_RTEMS_ASRIMPL_H
+
+#include <rtems/rtems/asr.h>
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicASRImpl Classic ASR Implementation
+ *
+ * @ingroup ClassicASR
+ *
+ * @{
+ */
+
+/**
+ * @brief ASR_Initialize
+ *
+ * This routine initializes the given RTEMS_ASR information record.
+ */
+RTEMS_INLINE_ROUTINE void _ASR_Initialize (
+ ASR_Information *asr
+)
+{
+ memset(asr, 0, sizeof(*asr));
+}
+
+/**
+ * @brief ASR_Is_null_handler
+ *
+ * This function returns TRUE if the given asr_handler is NULL and
+ * FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _ASR_Is_null_handler (
+ rtems_asr_entry asr_handler
+)
+{
+ return asr_handler == NULL;
+}
+
+RTEMS_INLINE_ROUTINE rtems_signal_set _ASR_Swap_signals( ASR_Information *asr )
+{
+ rtems_signal_set new_signals_posted;
+
+ new_signals_posted = asr->signals_pending;
+ asr->signals_pending = asr->signals_posted;
+ asr->signals_posted = new_signals_posted;
+
+ return new_signals_posted;
+}
+
+RTEMS_INLINE_ROUTINE void _ASR_Post_signals(
+ rtems_signal_set signals,
+ rtems_signal_set *signal_set
+)
+{
+ *signal_set |= signals;
+}
+
+RTEMS_INLINE_ROUTINE rtems_signal_set _ASR_Get_posted_signals(
+ ASR_Information *asr
+)
+{
+ rtems_signal_set signal_set;
+
+ signal_set = asr->signals_posted;
+ asr->signals_posted = 0;
+
+ return signal_set;
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/attr.h b/cpukit/include/rtems/rtems/attr.h
new file mode 100644
index 0000000000..7e8fa4818a
--- /dev/null
+++ b/cpukit/include/rtems/rtems/attr.h
@@ -0,0 +1,191 @@
+/**
+ * @file rtems/rtems/attr.h
+ *
+ * @defgroup ClassicAttributes Attributes
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Object Attributes Handler
+ *
+ * This include file contains all information about the Object Attributes
+ * Handler.
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_ATTR_H
+#define _RTEMS_RTEMS_ATTR_H
+
+#include <rtems/score/basedefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicAttributes Attributes
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality which defines and manages the
+ * set of Classic API object attributes.
+ */
+/**@{*/
+
+/**
+ * This defines the type used to contain Classic API attributes. These
+ * are primarily used when creating objects.
+ */
+typedef uint32_t rtems_attribute;
+
+/** This is the default value for an attribute set. */
+
+#define RTEMS_DEFAULT_ATTRIBUTES 0x00000000
+
+/**
+ * This is the attribute constant to indicate local resource.
+ */
+#define RTEMS_LOCAL 0x00000000
+
+/**
+ * This is the attribute constant to indicate global resource.
+ */
+#define RTEMS_GLOBAL 0x00000002
+
+/**
+ * This is the attribute constant which reflects that blocking
+ * tasks will be managed using FIFO discipline.
+ */
+#define RTEMS_FIFO 0x00000000
+
+/**
+ * This is the attribute constant which reflects that blocking
+ * tasks will be managed using task priority discipline.
+ */
+#define RTEMS_PRIORITY 0x00000004
+
+/******************** RTEMS Task Specific Attributes *********************/
+
+/**
+ * This attribute constant indicates that the task will not use the
+ * floating point hardware. If the architecture permits it, then
+ * the FPU will be disabled when the task is executing.
+ */
+#define RTEMS_NO_FLOATING_POINT 0x00000000
+
+/**
+ * This attribute constant indicates that the task will use the
+ * floating point hardware. There will be a floating point
+ * context associated with this task.
+ */
+#define RTEMS_FLOATING_POINT 0x00000001
+
+/***************** RTEMS Semaphore Specific Attributes ********************/
+
+/**
+ * This is the mask for the attribute bits associated with the
+ * Classic API Semaphore Manager.
+ */
+#define RTEMS_SEMAPHORE_CLASS 0x00000030
+
+/**
+ * This attribute constant indicates that the Classic API Semaphore
+ * instance created will be a counting semaphore.
+ */
+#define RTEMS_COUNTING_SEMAPHORE 0x00000000
+
+/**
+ * This attribute constant indicates that the Classic API Semaphore
+ * instance created will be a proper binary semaphore or mutex.
+ */
+#define RTEMS_BINARY_SEMAPHORE 0x00000010
+
+/**
+ * This attribute constant indicates that the Classic API Semaphore
+ * instance created will be a simple binary semaphore.
+ */
+#define RTEMS_SIMPLE_BINARY_SEMAPHORE 0x00000020
+
+/**
+ * This attribute constant indicates that the Classic API Semaphore
+ * instance created will NOT use the Priority Inheritance Protocol.
+ */
+#define RTEMS_NO_INHERIT_PRIORITY 0x00000000
+
+/**
+ * This attribute constant indicates that the Classic API Semaphore
+ * instance created will use the Priority Inheritance Protocol.
+ *
+ * @note The semaphore instance must be a binary semaphore.
+ */
+#define RTEMS_INHERIT_PRIORITY 0x00000040
+
+/**
+ * This attribute constant indicates that the Classic API Semaphore
+ * instance created will NOT use the Priority Ceiling Protocol.
+ */
+#define RTEMS_NO_PRIORITY_CEILING 0x00000000
+
+/**
+ * This attribute constant indicates that the Classic API Semaphore
+ * instance created will use the Priority Ceiling Protocol.
+ *
+ * @note The semaphore instance must be a binary semaphore.
+ */
+#define RTEMS_PRIORITY_CEILING 0x00000080
+
+/**
+ * This attribute constant indicates that the Classic API Semaphore instance
+ * created will NOT use the Multiprocessor Resource Sharing Protocol.
+ */
+#define RTEMS_NO_MULTIPROCESSOR_RESOURCE_SHARING 0x00000000
+
+/**
+ * This attribute constant indicates that the Classic API Semaphore instance
+ * created will use the Multiprocessor Resource Sharing Protocol.
+ *
+ * @note The semaphore instance must be a binary semaphore.
+ */
+#define RTEMS_MULTIPROCESSOR_RESOURCE_SHARING 0x00000100
+
+/******************** RTEMS Barrier Specific Attributes ********************/
+
+/**
+ * This attribute constant indicates that the Classic API Barrier
+ * instance created will use an automatic release protocol.
+ */
+#define RTEMS_BARRIER_AUTOMATIC_RELEASE 0x00000010
+
+/**
+ * This attribute constant indicates that the Classic API Barrier
+ * instance created will use the manual release protocol.
+ */
+#define RTEMS_BARRIER_MANUAL_RELEASE 0x00000000
+
+/**************** RTEMS Internal Task Specific Attributes ****************/
+
+/**
+ * This attribute constant indicates that the task was created
+ * by the application using normal Classic API methods.
+ */
+#define RTEMS_APPLICATION_TASK 0x00000000
+
+/**
+ * This attribute constant indicates that the task was created
+ * by RTEMS as a support task.
+ */
+#define RTEMS_SYSTEM_TASK 0x00008000
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/attrimpl.h b/cpukit/include/rtems/rtems/attrimpl.h
new file mode 100644
index 0000000000..bb8e5f8f58
--- /dev/null
+++ b/cpukit/include/rtems/rtems/attrimpl.h
@@ -0,0 +1,263 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicAttributesImpl
+ *
+ * @brief Classic Attributes Implementation
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_ATTR_INL
+#define _RTEMS_RTEMS_ATTR_INL
+
+#include <rtems/rtems/attr.h>
+#include <rtems/score/cpu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicAttributesImpl Classic Attributes Implementation
+ *
+ * @ingroup ClassicAttributes
+ *
+ * @{
+ */
+
+/****************** Forced Attributes in Configuration ****************/
+
+/**
+ * This attribute constant indicates the attributes that are not
+ * supportable given the hardware configuration.
+ */
+#define ATTRIBUTES_NOT_SUPPORTED 0
+
+/**
+ * This attribute constant indicates the attributes that are
+ * required given the hardware configuration.
+ */
+#if ( CPU_ALL_TASKS_ARE_FP == TRUE )
+#define ATTRIBUTES_REQUIRED RTEMS_FLOATING_POINT
+#else
+#define ATTRIBUTES_REQUIRED 0
+#endif
+
+/**
+ * @brief Sets the requested new_attributes in the attribute_set passed in.
+ *
+ * This function sets the requested new_attributes in the attribute_set
+ * passed in. The result is returned to the user.
+ */
+RTEMS_INLINE_ROUTINE rtems_attribute _Attributes_Set (
+ rtems_attribute new_attributes,
+ rtems_attribute attribute_set
+)
+{
+ return attribute_set | new_attributes;
+}
+
+/**
+ * @brief Clears the requested new_attributes in the attribute_set
+ * passed in.
+ *
+ * This function clears the requested new_attributes in the attribute_set
+ * passed in. The result is returned to the user.
+ */
+RTEMS_INLINE_ROUTINE rtems_attribute _Attributes_Clear (
+ rtems_attribute attribute_set,
+ rtems_attribute mask
+)
+{
+ return attribute_set & ~mask;
+}
+
+/**
+ * @brief Checks if the floating point attribute is
+ * enabled in the attribute_set.
+ *
+ * This function returns TRUE if the floating point attribute is
+ * enabled in the attribute_set and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Attributes_Is_floating_point(
+ rtems_attribute attribute_set
+)
+{
+ return ( attribute_set & RTEMS_FLOATING_POINT ) ? true : false;
+}
+
+#if defined(RTEMS_MULTIPROCESSING)
+/**
+ * @brief Checks if the global object attribute is enabled in
+ * the attribute_set.
+ *
+ * This function returns TRUE if the global object attribute is
+ * enabled in the attribute_set and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Attributes_Is_global(
+ rtems_attribute attribute_set
+)
+{
+ return ( attribute_set & RTEMS_GLOBAL ) ? true : false;
+}
+#endif
+
+/**
+ * @brief Checks if the priority attribute is enabled in the attribute_set.
+ *
+ * This function returns TRUE if the priority attribute is
+ * enabled in the attribute_set and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Attributes_Is_priority(
+ rtems_attribute attribute_set
+)
+{
+ return ( attribute_set & RTEMS_PRIORITY ) ? true : false;
+}
+
+/**
+ * @brief Checks if the binary semaphore attribute is
+ * enabled in the attribute_set.
+ *
+ * This function returns TRUE if the binary semaphore attribute is
+ * enabled in the attribute_set and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Attributes_Is_binary_semaphore(
+ rtems_attribute attribute_set
+)
+{
+ return ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_BINARY_SEMAPHORE);
+}
+
+/**
+ * @brief Checks if the simple binary semaphore attribute is
+ * enabled in the attribute_set
+ *
+ * This function returns TRUE if the simple binary semaphore attribute is
+ * enabled in the attribute_set and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Attributes_Is_simple_binary_semaphore(
+ rtems_attribute attribute_set
+)
+{
+ return
+ ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_SIMPLE_BINARY_SEMAPHORE);
+}
+
+/**
+ * @brief Checks if the counting semaphore attribute is
+ * enabled in the attribute_set
+ *
+ * This function returns TRUE if the counting semaphore attribute is
+ * enabled in the attribute_set and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Attributes_Is_counting_semaphore(
+ rtems_attribute attribute_set
+)
+{
+ return ((attribute_set & RTEMS_SEMAPHORE_CLASS) == RTEMS_COUNTING_SEMAPHORE);
+}
+
+/**
+ * @brief Checks if the priority inheritance attribute
+ * is enabled in the attribute_set
+ *
+ * This function returns TRUE if the priority inheritance attribute
+ * is enabled in the attribute_set and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Attributes_Is_inherit_priority(
+ rtems_attribute attribute_set
+)
+{
+ return ( attribute_set & RTEMS_INHERIT_PRIORITY ) ? true : false;
+}
+
+/**
+ * @brief Returns true if the attribute set has at most one protocol, and false
+ * otherwise.
+ *
+ * The protocols are RTEMS_INHERIT_PRIORITY, RTEMS_PRIORITY_CEILING and
+ * RTEMS_MULTIPROCESSOR_RESOURCE_SHARING.
+ */
+RTEMS_INLINE_ROUTINE bool _Attributes_Has_at_most_one_protocol(
+ rtems_attribute attribute_set
+)
+{
+ attribute_set &= RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY_CEILING
+ | RTEMS_MULTIPROCESSOR_RESOURCE_SHARING;
+
+ return ( attribute_set & ( attribute_set - 1 ) ) == 0;
+}
+
+/**
+ * @brief Checks if the priority ceiling attribute
+ * is enabled in the attribute_set
+ *
+ * This function returns TRUE if the priority ceiling attribute
+ * is enabled in the attribute_set and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Attributes_Is_priority_ceiling(
+ rtems_attribute attribute_set
+)
+{
+ return ( attribute_set & RTEMS_PRIORITY_CEILING ) ? true : false;
+}
+
+/**
+ * @brief Checks if the Multiprocessor Resource Sharing Protocol attribute
+ * is enabled in the attribute_set
+ *
+ * This function returns TRUE if the Multiprocessor Resource Sharing Protocol
+ * attribute is enabled in the attribute_set and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Attributes_Is_multiprocessor_resource_sharing(
+ rtems_attribute attribute_set
+)
+{
+ return ( attribute_set & RTEMS_MULTIPROCESSOR_RESOURCE_SHARING ) != 0;
+}
+
+/**
+ * @brief Checks if the barrier automatic release
+ * attribute is enabled in the attribute_set
+ *
+ * This function returns TRUE if the barrier automatic release
+ * attribute is enabled in the attribute_set and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Attributes_Is_barrier_automatic(
+ rtems_attribute attribute_set
+)
+{
+ return ( attribute_set & RTEMS_BARRIER_AUTOMATIC_RELEASE ) ? true : false;
+}
+
+/**
+ * @brief Checks if the system task attribute
+ * is enabled in the attribute_set.
+ *
+ * This function returns TRUE if the system task attribute
+ * is enabled in the attribute_set and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Attributes_Is_system_task(
+ rtems_attribute attribute_set
+)
+{
+ return ( attribute_set & RTEMS_SYSTEM_TASK ) ? true : false;
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/barrier.h b/cpukit/include/rtems/rtems/barrier.h
new file mode 100644
index 0000000000..2eea90fa41
--- /dev/null
+++ b/cpukit/include/rtems/rtems/barrier.h
@@ -0,0 +1,173 @@
+/**
+ * @file rtems/rtems/barrier.h
+ *
+ * @defgroup ClassicBarrier Barriers
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Classic API Barrier Manager
+ *
+ * This include file contains all the constants and structures associated
+ * with the Barrier Manager.
+ *
+ * Directives provided are:
+ *
+ * - create a barrier
+ * - get an ID of a barrier
+ * - delete a barrier
+ * - wait for a barrier
+ * - signal a barrier
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_BARRIER_H
+#define _RTEMS_RTEMS_BARRIER_H
+
+#include <rtems/rtems/types.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/corebarrier.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicBarrier Barriers
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality which implements the Classic API
+ * Barrier Manager.
+ */
+/**@{*/
+
+/**
+ * This type defines the control block used to manage each barrier.
+ */
+typedef struct {
+ /** This is used to manage a barrier as an object. */
+ Objects_Control Object;
+ /** This is used to implement the barrier. */
+ CORE_barrier_Control Barrier;
+ /** This is used to specify the attributes of a barrier. */
+ rtems_attribute attribute_set;
+} Barrier_Control;
+
+/**
+ * @brief RTEMS Create Barrier
+ *
+ * Barrier Manager -- Create a Barrier Instance
+ *
+ * This routine implements the rtems_barrier_create directive. The
+ * barrier will have the name name. The starting count for
+ * the barrier is count. The attribute_set determines if
+ * the barrier is global or local and the thread queue
+ * discipline. It returns the id of the created barrier in ID.
+ *
+ * @param[in] name is the name of this barrier instance.
+ * @param[in] attribute_set specifies the attributes of this barrier instance.
+ * @param[in] maximum_waiters is the maximum number of threads which will
+ * be allowed to concurrently wait at the barrier.
+ * @param[out] id will contain the id of this barrier.
+ *
+ * @retval a status code indicating success or the reason for failure.
+ */
+rtems_status_code rtems_barrier_create(
+ rtems_name name,
+ rtems_attribute attribute_set,
+ uint32_t maximum_waiters,
+ rtems_id *id
+);
+
+/**
+ * @brief RTEMS Barrier name to Id
+ *
+ * This routine implements the rtems_barrier_ident directive.
+ * This directive returns the barrier ID associated with name.
+ * If more than one barrier is named name, then the barrier
+ * to which the ID belongs is arbitrary. node indicates the
+ * extent of the search for the ID of the barrier named name.
+ * The search can be limited to a particular node or allowed to
+ * encompass all nodes.
+ *
+ * @param[in] name is the name of this barrier instance.
+ * @param[out] id will contain the id of this barrier.
+ *
+ * @retval a status code indicating success or the reason for failure.
+ */
+rtems_status_code rtems_barrier_ident(
+ rtems_name name,
+ rtems_id *id
+);
+
+/**
+ * @brief RTEMS Delete Barrier
+ *
+ * This routine implements the rtems_barrier_delete directive. The
+ * barrier indicated by @a id is deleted. The barrier is freed back to the
+ * inactive barrier chain.
+ *
+ *
+ * @param[in] id indicates the barrier to delete
+ *
+ * @retval a status code indicating success or the reason for failure.
+ */
+rtems_status_code rtems_barrier_delete(
+ rtems_id id
+);
+
+/**
+ * @brief RTEMS Barrier Wait
+ *
+ * This routine implements the rtems_barrier_wait directive. It
+ * attempts to wait at the barrier associated with @a id. The calling task
+ * may block waiting for the barrier with an optional timeout of @a timeout
+ * clock ticks.
+ *
+ * @param[in] id indicates the barrier to wait at.
+ * @param[in] timeout is the maximum length of time in ticks the calling
+ * thread is willing to block.
+ *
+ * @retval a status code indicating success or the reason for failure.
+ */
+rtems_status_code rtems_barrier_wait(
+ rtems_id id,
+ rtems_interval timeout
+);
+
+/**
+ * @brief RTEMS Barrier Release
+ *
+ * Barrier Manager -- Release Tasks Waitng at a Barrier
+ *
+ * This routine implements the rtems_barrier_release directive. It
+ * unblocks all of the threads waiting on the barrier associated with
+ * @a id. The number of threads unblocked is returned in @a released.
+ *
+ *
+ * @param[in] id indicates the barrier to wait at.
+ * @param[out] released will contain the number of threads unblocked.
+ *
+ * @retval a status code indicating success or the reason for failure.
+ */
+rtems_status_code rtems_barrier_release(
+ rtems_id id,
+ uint32_t *released
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/barrierimpl.h b/cpukit/include/rtems/rtems/barrierimpl.h
new file mode 100644
index 0000000000..f0b53e0cab
--- /dev/null
+++ b/cpukit/include/rtems/rtems/barrierimpl.h
@@ -0,0 +1,92 @@
+/**
+ * @file rtems/rtems/barrier.inl
+ *
+ * @defgroup ClassicBarrier Barriers
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Inline Implementation from Barrier Manager
+ *
+ * This file contains the static inlin implementation of the inlined
+ * routines from the Barrier Manager.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_BARRIERIMPL_H
+#define _RTEMS_RTEMS_BARRIERIMPL_H
+
+#include <rtems/rtems/barrier.h>
+#include <rtems/score/corebarrierimpl.h>
+#include <rtems/score/objectimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicBarrierImpl Classic Barrier Implementation
+ *
+ * @ingroup ClassicBarrier
+ *
+ * @{
+ */
+
+/**
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+extern Objects_Information _Barrier_Information;
+
+/**
+ * @brief _Barrier_Allocate
+ *
+ * This function allocates a barrier control block from
+ * the inactive chain of free barrier control blocks.
+ */
+RTEMS_INLINE_ROUTINE Barrier_Control *_Barrier_Allocate( void )
+{
+ return (Barrier_Control *) _Objects_Allocate( &_Barrier_Information );
+}
+
+/**
+ * @brief _Barrier_Free
+ *
+ * This routine frees a barrier control block to the
+ * inactive chain of free barrier control blocks.
+ */
+RTEMS_INLINE_ROUTINE void _Barrier_Free (
+ Barrier_Control *the_barrier
+)
+{
+ _CORE_barrier_Destroy( &the_barrier->Barrier );
+ _Objects_Free( &_Barrier_Information, &the_barrier->Object );
+}
+
+RTEMS_INLINE_ROUTINE Barrier_Control *_Barrier_Get(
+ Objects_Id id,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Context_initialize( queue_context );
+ return (Barrier_Control *) _Objects_Get(
+ id,
+ &queue_context->Lock_context.Lock_context,
+ &_Barrier_Information
+ );
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/cache.h b/cpukit/include/rtems/rtems/cache.h
new file mode 100644
index 0000000000..f1dc9bf03d
--- /dev/null
+++ b/cpukit/include/rtems/rtems/cache.h
@@ -0,0 +1,370 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicCache
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_CACHE_H
+#define _RTEMS_RTEMS_CACHE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/system.h>
+#include <sys/types.h>
+
+/**
+ * @defgroup ClassicCache Cache
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * @brief The Cache Manager provides functions to perform maintenance
+ * operations for data and instruction caches.
+ *
+ * The actual actions of the Cache Manager operations depend on the hardware
+ * and the implementation provided by the CPU architecture port or a board
+ * support package. Cache implementations tend to be highly hardware
+ * dependent.
+ *
+ * @{
+ */
+
+/**
+ * @brief Returns the data cache line size in bytes.
+ *
+ * For multi-level caches this is the maximum of the cache line sizes of all
+ * levels.
+ *
+ * @retval 0 No data cache is present.
+ * @retval positive The data cache line size in bytes.
+ */
+size_t rtems_cache_get_data_line_size( void );
+
+/**
+ * @brief Returns the instruction cache line size in bytes.
+ *
+ * For multi-level caches this is the maximum of the cache line sizes of all
+ * levels.
+ *
+ * @retval 0 No instruction cache is present.
+ * @retval positive The instruction cache line size in bytes.
+ */
+size_t rtems_cache_get_instruction_line_size( void );
+
+/**
+ * @brief Returns the maximal cache line size of all cache kinds in bytes.
+ *
+ * Returns computed or obtained maximal cache line size of all
+ * all caches in the system.
+ *
+ * @retval 0 No cache is present
+ * @retval positive The maximal cache line size in bytes.
+ */
+size_t rtems_cache_get_maximal_line_size( void );
+
+/**
+ * @brief Returns the data cache size in bytes.
+ *
+ * @param[in] level The cache level of interest. The cache level zero
+ * specifies the entire data cache.
+ *
+ * @returns The data cache size in bytes of the specified level.
+ */
+size_t rtems_cache_get_data_cache_size( uint32_t level );
+
+/**
+ * @brief Returns the instruction cache size in bytes.
+ *
+ * @param[in] level The cache level of interest. The cache level zero
+ * specifies the entire instruction cache.
+ *
+ * @returns The instruction cache size in bytes of the specified level.
+ */
+size_t rtems_cache_get_instruction_cache_size( uint32_t level );
+
+/**
+ * @brief Flushes multiple data cache lines.
+ *
+ * Dirty cache lines covering the area are transfered to memory. Depending on
+ * the cache implementation this may mark the lines as invalid.
+ *
+ * @param[in] addr The start address of the area to flush.
+ * @param[in] size The size in bytes of the area to flush.
+ */
+void rtems_cache_flush_multiple_data_lines( const void *addr, size_t size );
+
+/**
+ * @brief Invalidates multiple data cache lines.
+ *
+ * The cache lines covering the area are marked as invalid. A later read
+ * access in the area will load the data from memory.
+ *
+ * In case the area is not aligned on cache line boundaries, then this
+ * operation may destroy unrelated data.
+ *
+ * @param[in] addr The start address of the area to invalidate.
+ * @param[in] size The size in bytes of the area to invalidate.
+ */
+void rtems_cache_invalidate_multiple_data_lines(
+ const void *addr,
+ size_t size
+);
+
+/**
+ * @brief Invalidates multiple instruction cache lines.
+ *
+ * The cache lines covering the area are marked as invalid. A later
+ * instruction fetch from the area will result in a load from memory.
+ * In SMP mode, on processors without instruction cache snooping, this
+ * operation will invalidate the instruction cache lines on all processors.
+ * It should not be called from interrupt context in such case.
+ *
+ * @param[in] addr The start address of the area to invalidate.
+ * @param[in] size The size in bytes of the area to invalidate.
+ */
+void rtems_cache_invalidate_multiple_instruction_lines(
+ const void *addr,
+ size_t size
+);
+
+
+/**
+ * @brief Ensure necessary synchronization required after code changes
+ *
+ * When code is loaded or modified then many Harvard cache equipped
+ * systems require synchronization of main memory and or updated
+ * code in data cache to ensure visibility of change in all
+ * connected CPUs instruction memory view. This operation
+ * should be used by run time loader for example.
+ *
+ * @param[in] addr The start address of the area to invalidate.
+ * @param[in] size The size in bytes of the area to invalidate.
+ */
+void rtems_cache_instruction_sync_after_code_change(
+ const void * code_addr,
+ size_t n_bytes
+);
+
+/**
+ * @brief Flushes the entire data cache.
+ *
+ * @see rtems_cache_flush_multiple_data_lines().
+ */
+void rtems_cache_flush_entire_data( void );
+
+/**
+ * @brief Invalidates the entire instruction cache.
+ *
+ * @see rtems_cache_invalidate_multiple_instruction_lines().
+ */
+void rtems_cache_invalidate_entire_instruction( void );
+
+/**
+ * This function is responsible for performing a data cache
+ * invalidate. It invalidates the entire cache.
+ */
+void rtems_cache_invalidate_entire_data( void );
+
+/**
+ * This function freezes the data cache.
+ */
+void rtems_cache_freeze_data( void );
+
+/**
+ * This function unfreezes the data cache.
+ */
+void rtems_cache_unfreeze_data( void );
+
+/**
+ * This function enables the data cache.
+ */
+void rtems_cache_enable_data( void );
+
+/**
+ * This function disables the data cache.
+ */
+void rtems_cache_disable_data( void );
+
+/**
+ * This function freezes the instruction cache.
+ */
+void rtems_cache_freeze_instruction( void );
+
+/**
+ * This function unfreezes the instruction cache.
+ */
+void rtems_cache_unfreeze_instruction( void );
+
+/**
+ * This function enables the instruction cache.
+ */
+void rtems_cache_enable_instruction( void );
+
+/**
+ * This function disables the instruction cache.
+ */
+void rtems_cache_disable_instruction( void );
+
+/**
+ * This function is used to allocate storage that spans an
+ * integral number of cache blocks.
+ */
+void *rtems_cache_aligned_malloc ( size_t nbytes );
+
+/**
+ * @brief Allocates a memory area of size @a size bytes from cache coherent
+ * memory.
+ *
+ * A size value of zero will return a unique address which may be freed with
+ * rtems_cache_coherent_free().
+ *
+ * The memory allocated by this function can be released with a call to
+ * rtems_cache_coherent_free().
+ *
+ * By default the C program heap allocator is used. In case special memory
+ * areas must be used, then the BSP or the application must add cache coherent
+ * memory areas for the allocator via rtems_cache_coherent_add_area().
+ *
+ * This function must be called from driver initialization or task context
+ * only.
+ *
+ * @param[in] alignment If the alignment parameter is not equal to zero, the
+ * allocated memory area will begin at an address aligned by this value.
+ * @param[in] boundary If the boundary parameter is not equal to zero, the
+ * allocated memory area will comply with a boundary constraint. The
+ * boundary value specifies the set of addresses which are aligned by the
+ * boundary value. The interior of the allocated memory area will not
+ * contain an element of this set. The begin or end address of the area may
+ * be a member of the set.
+ *
+ * @retval NULL If no memory is available or the parameters are inconsistent.
+ * @retval other A pointer to the begin of the allocated memory area.
+ */
+void *rtems_cache_coherent_allocate(
+ size_t size,
+ uintptr_t alignment,
+ uintptr_t boundary
+);
+
+/**
+ * @brief Frees memory allocated by rtems_cache_coherent_allocate().
+ *
+ * This function must be called from driver initialization or task context
+ * only.
+ *
+ * @param[in] ptr A pointer returned by rtems_cache_coherent_allocate().
+ */
+void rtems_cache_coherent_free( void *ptr );
+
+/**
+ * @brief Adds a cache coherent memory area to the cache coherent allocator.
+ *
+ * This function must be called from BSP initialization, driver initialization
+ * or task context only.
+ *
+ * @param[in] area_begin The area begin address.
+ * @param[in] area_size The area size in bytes.
+ *
+ * @see rtems_cache_coherent_allocate().
+ */
+void rtems_cache_coherent_add_area(
+ void *area_begin,
+ uintptr_t area_size
+);
+
+#if defined( RTEMS_SMP )
+
+/**
+ * @brief Flushes multiple data cache lines for a set of processors
+ *
+ * Dirty cache lines covering the area are transferred to memory.
+ * Depending on the cache implementation this may mark the lines as invalid.
+ *
+ * This operation should not be called from interrupt context.
+ *
+ * @param[in] addr The start address of the area to flush.
+ * @param[in] size The size in bytes of the area to flush.
+ * @param[in] setsize The size of the processor set.
+ * @param[in] set The target processor set.
+ */
+void rtems_cache_flush_multiple_data_lines_processor_set(
+ const void *addr,
+ size_t size,
+ const size_t setsize,
+ const cpu_set_t *set
+);
+
+/**
+ * @brief Invalidates multiple data cache lines for a set of processors
+ *
+ * The cache lines covering the area are marked as invalid. A later read
+ * access in the area will load the data from memory.
+ *
+ * In case the area is not aligned on cache line boundaries, then this
+ * operation may destroy unrelated data.
+ *
+ * This operation should not be called from interrupt context.
+ *
+ * @param[in] addr The start address of the area to invalidate.
+ * @param[in] size The size in bytes of the area to invalidate.
+ * @param[in] setsize The size of the processor set.
+ * @param[in] set The target processor set.
+ */
+void rtems_cache_invalidate_multiple_data_lines_processor_set(
+ const void *addr,
+ size_t size,
+ const size_t setsize,
+ const cpu_set_t *set
+);
+
+/**
+ * @brief Flushes the entire data cache for a set of processors
+ *
+ * This operation should not be called from interrupt context.
+ *
+ * @see rtems_cache_flush_multiple_data_lines().
+ *
+ * @param[in] setsize The size of the processor set.
+ * @param[in] set The target processor set.
+ */
+void rtems_cache_flush_entire_data_processor_set(
+ const size_t setsize,
+ const cpu_set_t *set
+);
+
+/**
+ * @brief Invalidates the entire cache for a set of processors
+ *
+ * This function is responsible for performing a data cache
+ * invalidate. It invalidates the entire cache for a set of
+ * processors.
+ *
+ * This operation should not be called from interrupt context.
+ *
+ * @param[in] setsize The size of the processor set.
+ * @param[in] set The target processor set.
+ */
+void rtems_cache_invalidate_entire_data_processor_set(
+ const size_t setsize,
+ const cpu_set_t *set
+);
+
+#endif
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/clock.h b/cpukit/include/rtems/rtems/clock.h
new file mode 100644
index 0000000000..a837b88700
--- /dev/null
+++ b/cpukit/include/rtems/rtems/clock.h
@@ -0,0 +1,318 @@
+/**
+ * @file rtems/rtems/clock.h
+ *
+ * @defgroup ClassicClock Clocks
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Clock Manager API
+ *
+ * This include file contains all the constants and structures associated
+ * with the Clock Manager. This manager provides facilities to set, obtain,
+ * and continually update the current date and time.
+ *
+ * This manager provides directives to:
+ *
+ * - set the current date and time
+ * - obtain the current date and time
+ * - announce a clock tick
+ * - obtain the system uptime
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_CLOCK_H
+#define _RTEMS_RTEMS_CLOCK_H
+
+#include <rtems/score/watchdog.h>
+#include <rtems/score/tod.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/types.h>
+#include <rtems/config.h>
+#include <rtems/score/timecounterimpl.h>
+
+#include <sys/time.h> /* struct timeval */
+
+/**
+ * @defgroup ClassicClock Clocks
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality related to the Classic API Clock
+ * Manager.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Obtain Current Time of Day (Classic TOD)
+ *
+ * This routine implements the rtems_clock_get_tod directive. It returns
+ * the current time of day in the format defined by RTEID.
+ *
+ * Clock Manager - rtems_clock_get_tod
+ *
+ * @param[in] time_buffer points to the time of day structure
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error. If successful, the time_buffer will
+ * be filled in with the current time of day.
+ */
+rtems_status_code rtems_clock_get_tod(
+ rtems_time_of_day *time_buffer
+);
+
+/**
+ * @brief Obtain TOD in struct timeval Format
+ *
+ * This routine implements the rtems_clock_get_tod_timeval
+ * directive.
+ *
+ * @param[in] time points to the struct timeval variable to fill in
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error. If successful, the time will
+ * be filled in with the current time of day.
+ */
+rtems_status_code rtems_clock_get_tod_timeval(
+ struct timeval *time
+);
+
+/**
+ * @brief Obtain Seconds Since Epoch
+ *
+ * This routine implements the rtems_clock_get_seconds_since_epoch
+ * directive.
+ *
+ * @param[in] the_interval points to the interval variable to fill in
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error. If successful, the time_buffer will
+ * be filled in with the current time of day.
+ */
+rtems_status_code rtems_clock_get_seconds_since_epoch(
+ rtems_interval *the_interval
+);
+
+/**
+ * @brief Gets the current ticks counter value.
+ *
+ * @return The current tick counter value. With a 1ms clock tick, this counter
+ * overflows after 50 days since boot.
+ */
+RTEMS_INLINE_ROUTINE rtems_interval rtems_clock_get_ticks_since_boot(void)
+{
+ return _Watchdog_Ticks_since_boot;
+}
+
+/**
+ * @brief Returns the ticks counter value delta ticks in the future.
+ *
+ * @param[in] delta The ticks delta value.
+ *
+ * @return The tick counter value delta ticks in the future.
+ */
+RTEMS_INLINE_ROUTINE rtems_interval rtems_clock_tick_later(
+ rtems_interval delta
+)
+{
+ return _Watchdog_Ticks_since_boot + delta;
+}
+
+/**
+ * @brief Returns the ticks counter value at least delta microseconds in the
+ * future.
+ *
+ * @param[in] delta_in_usec The delta value in microseconds.
+ *
+ * @return The tick counter value at least delta microseconds in the future.
+ */
+RTEMS_INLINE_ROUTINE rtems_interval rtems_clock_tick_later_usec(
+ rtems_interval delta_in_usec
+)
+{
+ rtems_interval us_per_tick = rtems_configuration_get_microseconds_per_tick();
+
+ /*
+ * Add one additional tick, since we don't know the time to the clock next
+ * tick.
+ */
+ return _Watchdog_Ticks_since_boot
+ + (delta_in_usec + us_per_tick - 1) / us_per_tick + 1;
+}
+
+/**
+ * @brief Returns true if the current ticks counter value indicates a time
+ * before the time specified by the tick value and false otherwise.
+ *
+ * @param[in] tick The tick value.
+ *
+ * This can be used to write busy loops with a timeout.
+ *
+ * @code
+ * status busy( void )
+ * {
+ * rtems_interval timeout = rtems_clock_tick_later_usec( 10000 );
+ *
+ * do {
+ * if ( ok() ) {
+ * return success;
+ * }
+ * } while ( rtems_clock_tick_before( timeout ) );
+ *
+ * return timeout;
+ * }
+ * @endcode
+ *
+ * @retval true The current ticks counter value indicates a time before the
+ * time specified by the tick value.
+ * @retval false Otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_clock_tick_before(
+ rtems_interval tick
+)
+{
+ return (int32_t) ( tick - _Watchdog_Ticks_since_boot ) > 0;
+}
+
+/**
+ * @brief Obtain Ticks Per Seconds
+ *
+ * This routine implements the rtems_clock_get_ticks_per_second
+ * directive.
+ *
+ * @retval This method returns the number of ticks per second. It cannot
+ * fail since RTEMS is always configured to know the number of
+ * ticks per second.
+ */
+rtems_interval rtems_clock_get_ticks_per_second(void);
+
+/* Optimized variant for C/C++ without function call overhead */
+#define rtems_clock_get_ticks_per_second() ( _Watchdog_Ticks_per_second )
+
+/**
+ * @brief Set the Current TOD
+ *
+ * This routine implements the rtems_clock_set directive. It sets
+ * the current time of day to that in the time_buffer record.
+ *
+ * @param[in] time_buffer points to the new TOD
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ *
+ * @note Activities scheduled based upon the current time of day
+ * may be executed immediately if the time is moved forward.
+ */
+rtems_status_code rtems_clock_set(
+ const rtems_time_of_day *time_buffer
+);
+
+/**
+ * @brief Announce a Clock Tick
+ *
+ * This routine implements the rtems_clock_tick directive. It is invoked
+ * to inform RTEMS of the occurrence of a clock tick.
+ *
+ * @retval This directive always returns RTEMS_SUCCESSFUL.
+ *
+ * @note This method is typically called from an ISR and is the basis
+ * for all timeouts and delays. This routine only works for leap-years
+ * through 2099.
+ */
+rtems_status_code rtems_clock_tick( void );
+
+/**
+ * @brief Obtain the System Uptime
+ *
+ * This directive returns the system uptime.
+ *
+ * @param[in] uptime is a pointer to the time structure
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error. If successful, the @a uptime will be
+ * filled in.
+ */
+rtems_status_code rtems_clock_get_uptime(
+ struct timespec *uptime
+);
+
+/**
+ * @brief Gets the System Uptime in the Struct Timeval Format
+ *
+ * @param[out] uptime is a pointer to a struct timeval structure.
+ *
+ * @retval This methods returns the system uptime.
+ *
+ * @note Pointer must not be NULL.
+ */
+void rtems_clock_get_uptime_timeval( struct timeval *uptime );
+
+/**
+ * @brief Returns the system uptime in seconds.
+ *
+ * @retval The system uptime in seconds.
+ */
+RTEMS_INLINE_ROUTINE time_t rtems_clock_get_uptime_seconds( void )
+{
+ return _Timecounter_Time_uptime - 1;
+}
+
+/**
+ * @brief Returns the system uptime in nanoseconds.
+ *
+ * @retval The system uptime in nanoseconds.
+ */
+uint64_t rtems_clock_get_uptime_nanoseconds( void );
+
+/**
+ * @brief TOD Validate
+ *
+ * This support function returns true if @a the_tod contains
+ * a valid time of day, and false otherwise.
+ *
+ * @param[in] the_tod is the TOD structure to validate
+ *
+ * @retval This method returns true if the TOD is valid and false otherwise.
+ *
+ * @note This routine only works for leap-years through 2099.
+ */
+bool _TOD_Validate(
+ const rtems_time_of_day *the_tod
+);
+
+/**
+ * @brief TOD to Seconds
+ *
+ * This function returns the number seconds between the epoch and @a the_tod.
+ *
+ * @param[in] the_tod is the TOD structure to convert to seconds
+ *
+ * @retval This method returns the number of seconds since epoch represented
+ * by @a the_tod
+ */
+Watchdog_Interval _TOD_To_seconds(
+ const rtems_time_of_day *the_tod
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/config.h b/cpukit/include/rtems/rtems/config.h
new file mode 100644
index 0000000000..77ee798d74
--- /dev/null
+++ b/cpukit/include/rtems/rtems/config.h
@@ -0,0 +1,142 @@
+/**
+ * @file rtems/rtems/config.h
+ *
+ * @defgroup ClassicConfig Configuration
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Configuration Table
+ *
+ * This include file contains the table of user defined configuration
+ * parameters specific for the RTEMS API.
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_CONFIG_H
+#define _RTEMS_RTEMS_CONFIG_H
+
+#include <rtems/rtems/types.h>
+#include <rtems/rtems/tasks.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicConfig Configuration
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality related to the application's configuration
+ * of the Classic API including the maximum number of each class of objects.
+ */
+/**@{*/
+
+/**
+ * The following records define the Configuration Table. The
+ * information contained in this table is required in all
+ * RTEMS systems, whether single or multiprocessor. This
+ * table primarily defines the following:
+ *
+ * + required number of each object type
+ */
+typedef struct {
+ /**
+ * This field contains the maximum number of Classic API
+ * Tasks which are configured for this application.
+ */
+ uint32_t maximum_tasks;
+
+ /**
+ * This field contains the maximum number of Classic API
+ * Timers which are configured for this application.
+ */
+ uint32_t maximum_timers;
+
+ /**
+ * This field contains the maximum number of Classic API
+ * Semaphores which are configured for this application.
+ */
+ uint32_t maximum_semaphores;
+
+ /**
+ * This field contains the maximum number of Classic API
+ * Message Queues which are configured for this application.
+ */
+ uint32_t maximum_message_queues;
+
+ /**
+ * This field contains the maximum number of Classic API
+ * Partitions which are configured for this application.
+ */
+ uint32_t maximum_partitions;
+
+ /**
+ * This field contains the maximum number of Classic API
+ * Regions which are configured for this application.
+ */
+ uint32_t maximum_regions;
+
+ /**
+ * This field contains the maximum number of Classic API
+ * Dual Ported Memory Areas which are configured for this
+ * application.
+ */
+ uint32_t maximum_ports;
+
+ /**
+ * This field contains the maximum number of Classic API
+ * Rate Monotonic Periods which are configured for this
+ * application.
+ */
+ uint32_t maximum_periods;
+
+ /**
+ * This field contains the maximum number of Classic API
+ * Barriers which are configured for this application.
+ */
+ uint32_t maximum_barriers;
+
+ /**
+ * This field contains the number of Classic API Initialization
+ * Tasks which are configured for this application.
+ */
+ uint32_t number_of_initialization_tasks;
+
+ /**
+ * This field is the set of Classic API Initialization
+ * Tasks which are configured for this application.
+ */
+ rtems_initialization_tasks_table *User_initialization_tasks_table;
+} rtems_api_configuration_table;
+
+/**
+ * @brief RTEMS API Configuration Table
+ *
+ * This is the RTEMS API Configuration Table expected to be generated
+ * by confdefs.h.
+ */
+extern rtems_api_configuration_table Configuration_RTEMS_API;
+
+/**@}*/
+
+/**
+ * This macro returns the number of Classic API semaphores configured.
+ */
+#define rtems_configuration_get_maximum_semaphores() \
+ rtems_configuration_get_rtems_api_configuration()->maximum_semaphores
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/dpmem.h b/cpukit/include/rtems/rtems/dpmem.h
new file mode 100644
index 0000000000..e582d2d359
--- /dev/null
+++ b/cpukit/include/rtems/rtems/dpmem.h
@@ -0,0 +1,179 @@
+/**
+ * @file rtems/rtems/dpmem.h
+ *
+ * @defgroup ClassicDPMEM Dual Ported Memory
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Dual Ported Memory Manager
+ *
+ * This include file contains all the constants and structures associated
+ * with the Dual Ported Memory Manager. This manager provides a mechanism
+ * for converting addresses between internal and external representations
+ * for multiple dual-ported memory areas.
+ *
+ * Directives provided are:
+ *
+ * - create a port
+ * - get ID of a port
+ * - delete a port
+ * - convert external to internal address
+ * - convert internal to external address
+ *
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_DPMEM_H
+#define _RTEMS_RTEMS_DPMEM_H
+
+#include <rtems/rtems/types.h>
+#include <rtems/rtems/status.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicDPMEM Dual Ported Memory
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality related to the
+ * Classic API Dual Ported Memory Manager.
+ */
+/**@{*/
+
+/**
+ * The following structure defines the port control block. Each port
+ * has a control block associated with it. This control block contains
+ * all information required to support the port related operations.
+ */
+typedef struct {
+ /** This field is the object management portion of a Port instance. */
+ Objects_Control Object;
+ /** This field is the base internal address of the port. */
+ void *internal_base;
+ /** This field is the base external address of the port. */
+ void *external_base;
+ /** This field is the length of dual-ported area of the port. */
+ uint32_t length;
+} Dual_ported_memory_Control;
+
+/**
+ * @brief Creates a port into a dual-ported memory area.
+ *
+ * This routine implements the rtems_port_create directive. The port
+ * will have the name @a name. The port maps onto an area of dual ported
+ * memory of length bytes which has internal_start and external_start
+ * as the internal and external starting addresses, respectively.
+ * It returns the id of the created port in ID.
+ *
+ * @param[in] name is the user defined port name
+ * @param[in] internal_start is the internal start address of port
+ * @param[in] external_start is the external start address of port
+ * @param[in] length is the physical length in bytes
+ * @param[out] id is the address of port id to set
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error. If successful, the id will
+ * be filled in with the port id.
+ */
+rtems_status_code rtems_port_create(
+ rtems_name name,
+ void *internal_start,
+ void *external_start,
+ uint32_t length,
+ rtems_id *id
+);
+
+/**
+ * @brief RTEMS Port Name to Id
+ *
+ * This routine implements the rtems_port_ident directive. This directive
+ * returns the port ID associated with name. If more than one port is
+ * named name, then the port to which the ID belongs is arbitrary.
+ *
+ * @param[in] name is the user defined port name
+ * @param[out] id is the pointer to port id
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
+ */
+rtems_status_code rtems_port_ident(
+ rtems_name name,
+ rtems_id *id
+);
+
+/**
+ * @brief RTEMS Delete Port
+ *
+ * This routine implements the rtems_port_delete directive. It deletes
+ * the port associated with ID.
+ *
+ * @param[in] id is the dual-ported memory area id
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_port_delete(
+ rtems_id id
+);
+
+/**
+ * @brief RTEMS Port External to Internal
+ *
+ * This routine implements the rtems_port_external_to_internal directive.
+ * It returns the internal port address which maps to the provided
+ * external port address for the specified port ID. If the given external
+ * address is an invalid dual-ported address, then the internal address is
+ * set to the given external address.
+ *
+ * @param[in] id is the id of dp memory object
+ * @param[in] external is the external address
+ * @param[out] internal is the pointer of internal address to set
+ *
+ * @retval RTEMS_SUCCESSFUL
+ */
+rtems_status_code rtems_port_external_to_internal(
+ rtems_id id,
+ void *external,
+ void **internal
+);
+
+/**
+ * @brief RTEMS Port Internal to External
+ *
+ * This routine implements the Port_internal_to_external directive.
+ * It returns the external port address which maps to the provided
+ * internal port address for the specified port ID. If the given
+ * internal address is an invalid dual-ported address, then the
+ * external address is set to the given internal address.
+ *
+ * @param[in] id is the id of dual-ported memory object
+ * @param[in] internal is the internal address to set
+ * @param[in] external is the pointer to external address
+ *
+ * @retval RTEMS_SUCCESSFUL and the external will be filled in
+ * with the external addresses
+ */
+rtems_status_code rtems_port_internal_to_external(
+ rtems_id id,
+ void *internal,
+ void **external
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/dpmemimpl.h b/cpukit/include/rtems/rtems/dpmemimpl.h
new file mode 100644
index 0000000000..52ac48c8dc
--- /dev/null
+++ b/cpukit/include/rtems/rtems/dpmemimpl.h
@@ -0,0 +1,85 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicDPMEMImpl
+ *
+ * @brief Dual Ported Memory Manager Implementation
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_DPMEM_INL
+#define _RTEMS_RTEMS_DPMEM_INL
+
+#include <rtems/rtems/dpmem.h>
+#include <rtems/score/objectimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicDPMEMImpl Dual Ported Memory Manager Implementation
+ *
+ * @ingroup ClassicDPMEM
+ *
+ * @{
+ */
+
+/**
+ * @brief Define the internal Dual Ported Memory information
+ * The following define the internal Dual Ported Memory information.
+ */
+extern Objects_Information _Dual_ported_memory_Information;
+
+/**
+ * @brief Allocates a port control block from the inactive chain
+ * of free port control blocks.
+ *
+ * This routine allocates a port control block from the inactive chain
+ * of free port control blocks.
+ */
+RTEMS_INLINE_ROUTINE Dual_ported_memory_Control
+ *_Dual_ported_memory_Allocate ( void )
+{
+ return (Dual_ported_memory_Control *)
+ _Objects_Allocate( &_Dual_ported_memory_Information );
+}
+
+/**
+ * @brief Frees a port control block to the inactive chain
+ * of free port control blocks.
+ *
+ * This routine frees a port control block to the inactive chain
+ * of free port control blocks.
+ */
+RTEMS_INLINE_ROUTINE void _Dual_ported_memory_Free (
+ Dual_ported_memory_Control *the_port
+)
+{
+ _Objects_Free( &_Dual_ported_memory_Information, &the_port->Object );
+}
+
+RTEMS_INLINE_ROUTINE Dual_ported_memory_Control *_Dual_ported_memory_Get(
+ Objects_Id id,
+ ISR_lock_Context *lock_context
+)
+{
+ return (Dual_ported_memory_Control *)
+ _Objects_Get( id, lock_context, &_Dual_ported_memory_Information );
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_RTEMS_DPMEM_INL */
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/event.h b/cpukit/include/rtems/rtems/event.h
new file mode 100644
index 0000000000..1cd64c0cfa
--- /dev/null
+++ b/cpukit/include/rtems/rtems/event.h
@@ -0,0 +1,526 @@
+/**
+ * @file rtems/rtems/event.h
+ *
+ * @defgroup ClassicEvent Events
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Information Related to Event Manager
+ *
+ * This include file contains the information pertaining to the Event
+ * Manager. This manager provides a high performance method of communication
+ * and synchronization.
+ *
+ * Directives provided are:
+ *
+ * - send an event set to a task
+ * - receive event condition
+ *
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_EVENT_H
+#define _RTEMS_RTEMS_EVENT_H
+
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/types.h>
+#include <rtems/rtems/options.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicEventSet Event Set
+ *
+ * @ingroup ClassicEvent
+ *
+ * @{
+ */
+
+/**
+ * @brief Integer type to hold an event set of up to 32 events represented as
+ * a bit field.
+ */
+typedef uint32_t rtems_event_set;
+
+/**
+ * @brief Constant used to send or receive all events.
+ */
+#define RTEMS_ALL_EVENTS 0xFFFFFFFF
+
+/** @brief Defines the bit in the event set associated with event 0. */
+#define RTEMS_EVENT_0 0x00000001
+/** @brief Defines the bit in the event set associated with event 1. */
+#define RTEMS_EVENT_1 0x00000002
+/** @brief Defines the bit in the event set associated with event 2. */
+#define RTEMS_EVENT_2 0x00000004
+/** @brief Defines the bit in the event set associated with event 3. */
+#define RTEMS_EVENT_3 0x00000008
+/** @brief Defines the bit in the event set associated with event 4. */
+#define RTEMS_EVENT_4 0x00000010
+/** @brief Defines the bit in the event set associated with event 5. */
+#define RTEMS_EVENT_5 0x00000020
+/** @brief Defines the bit in the event set associated with event 6. */
+#define RTEMS_EVENT_6 0x00000040
+/** @brief Defines the bit in the event set associated with event 7. */
+#define RTEMS_EVENT_7 0x00000080
+/** @brief Defines the bit in the event set associated with event 8. */
+#define RTEMS_EVENT_8 0x00000100
+/** @brief Defines the bit in the event set associated with event 9. */
+#define RTEMS_EVENT_9 0x00000200
+/** @brief Defines the bit in the event set associated with event 10. */
+#define RTEMS_EVENT_10 0x00000400
+/** @brief Defines the bit in the event set associated with event 11. */
+#define RTEMS_EVENT_11 0x00000800
+/** @brief Defines the bit in the event set associated with event 12. */
+#define RTEMS_EVENT_12 0x00001000
+/** @brief Defines the bit in the event set associated with event 13. */
+#define RTEMS_EVENT_13 0x00002000
+/** @brief Defines the bit in the event set associated with event 14. */
+#define RTEMS_EVENT_14 0x00004000
+/** @brief Defines the bit in the event set associated with event 15. */
+#define RTEMS_EVENT_15 0x00008000
+/** @brief Defines the bit in the event set associated with event 16. */
+#define RTEMS_EVENT_16 0x00010000
+/** @brief Defines the bit in the event set associated with event 17. */
+#define RTEMS_EVENT_17 0x00020000
+/** @brief Defines the bit in the event set associated with event 18. */
+#define RTEMS_EVENT_18 0x00040000
+/** @brief Defines the bit in the event set associated with event 19. */
+#define RTEMS_EVENT_19 0x00080000
+/** @brief Defines the bit in the event set associated with event 20. */
+#define RTEMS_EVENT_20 0x00100000
+/** @brief Defines the bit in the event set associated with event 21. */
+#define RTEMS_EVENT_21 0x00200000
+/** @brief Defines the bit in the event set associated with event 22. */
+#define RTEMS_EVENT_22 0x00400000
+/** @brief Defines the bit in the event set associated with event 23. */
+#define RTEMS_EVENT_23 0x00800000
+/** @brief Defines the bit in the event set associated with event 24. */
+#define RTEMS_EVENT_24 0x01000000
+/** @brief Defines the bit in the event set associated with event 25. */
+#define RTEMS_EVENT_25 0x02000000
+/** @brief Defines the bit in the event set associated with event 26. */
+#define RTEMS_EVENT_26 0x04000000
+/** @brief Defines the bit in the event set associated with event 27. */
+#define RTEMS_EVENT_27 0x08000000
+/** @brief Defines the bit in the event set associated with event 29. */
+#define RTEMS_EVENT_28 0x10000000
+/** @brief Defines the bit in the event set associated with event 29. */
+#define RTEMS_EVENT_29 0x20000000
+/** @brief Defines the bit in the event set associated with event 30. */
+#define RTEMS_EVENT_30 0x40000000
+/** @brief Defines the bit in the event set associated with event 31. */
+#define RTEMS_EVENT_31 0x80000000
+
+/** @} */
+
+/**
+ * @defgroup ClassicEvent Events
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * @brief The event manager provides a high performance method of intertask
+ * communication and synchronization.
+ *
+ * An event flag is used by a task (or ISR) to inform another task of the
+ * occurrence of a significant situation. Thirty-two event flags are
+ * associated with each task. A collection of one or more event flags is
+ * referred to as an event set. The data type rtems_event_set is used to
+ * manage event sets.
+ *
+ * The application developer should remember the following key characteristics
+ * of event operations when utilizing the event manager:
+ *
+ * - Events provide a simple synchronization facility.
+ * - Events are aimed at tasks.
+ * - Tasks can wait on more than one event simultaneously.
+ * - Events are independent of one another.
+ * - Events do not hold or transport data.
+ * - Events are not queued. In other words, if an event is sent more than once
+ * to a task before being received, the second and subsequent send
+ * operations to that same task have no effect.
+ *
+ * An event set is posted when it is directed (or sent) to a task. A pending
+ * event is an event that has been posted but not received. An event condition
+ * is used to specify the event set which the task desires to receive and the
+ * algorithm which will be used to determine when the request is satisfied. An
+ * event condition is satisfied based upon one of two algorithms which are
+ * selected by the user. The @ref RTEMS_EVENT_ANY algorithm states that an
+ * event condition is satisfied when at least a single requested event is
+ * posted. The @ref RTEMS_EVENT_ALL algorithm states that an event condition
+ * is satisfied when every requested event is posted.
+ *
+ * An event set or condition is built by a bitwise or of the desired events.
+ * The set of valid events is @ref RTEMS_EVENT_0 through @ref RTEMS_EVENT_31.
+ * If an event is not explicitly specified in the set or condition, then it is
+ * not present. Events are specifically designed to be mutually exclusive,
+ * therefore bitwise or and addition operations are equivalent as long as each
+ * event appears exactly once in the event set list.
+ *
+ * For example, when sending the event set consisting of @ref RTEMS_EVENT_6,
+ * @ref RTEMS_EVENT_15, and @ref RTEMS_EVENT_31, the event parameter to the
+ * rtems_event_send() directive should be @ref RTEMS_EVENT_6 |
+ * @ref RTEMS_EVENT_15 | @ref RTEMS_EVENT_31.
+ *
+ * @{
+ */
+
+/**
+ * @brief Constant used to receive the set of currently pending events in
+ * rtems_event_receive().
+ */
+#define RTEMS_PENDING_EVENTS 0
+
+/**
+ * @brief Sends an Event Set to the Target Task
+ *
+ * This directive sends an event set @a event_in to the task specified by
+ * @a id.
+ *
+ * Based upon the state of the target task, one of the following situations
+ * applies. The target task is
+ * - blocked waiting for events.
+ * If the waiting task's input event condition is
+ * - satisfied, then the task is made ready for execution.
+ * - not satisfied, then the event set is posted but left pending and the
+ * task remains blocked.
+ * - not waiting for events.
+ * - The event set is posted and left pending.
+ *
+ * Identical events sent to a task are not queued. In other words, the second,
+ * and subsequent, posting of an event to a task before it can perform an
+ * rtems_event_receive() has no effect.
+ *
+ * The calling task will be preempted if it has preemption enabled and a
+ * higher priority task is unblocked as the result of this directive.
+ *
+ * Sending an event set to a global task which does not reside on the local
+ * node will generate a request telling the remote node to send the event set
+ * to the appropriate task.
+ *
+ * @param[in] id Identifier of the target task. Specifying @ref RTEMS_SELF
+ * results in the event set being sent to the calling task.
+ * @param[in] event_in Event set sent to the target task.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID Invalid task identifier.
+ */
+rtems_status_code rtems_event_send (
+ rtems_id id,
+ rtems_event_set event_in
+);
+
+/**
+ * @brief Receives pending events.
+ *
+ * This directive attempts to receive the event condition specified in
+ * @a event_in. If @a event_in is set to @ref RTEMS_PENDING_EVENTS, then the
+ * current pending events are returned in @a event_out and left pending. The
+ * @ref RTEMS_WAIT and @ref RTEMS_NO_WAIT options in the @a option_set
+ * parameter are used to specify whether or not the task is willing to wait
+ * for the event condition to be satisfied. The @ref RTEMS_EVENT_ANY and @ref
+ * RTEMS_EVENT_ALL are used in the @a option_set parameter to specify whether
+ * at least a single event or the complete event set is necessary to satisfy
+ * the event condition. The @a event_out parameter is returned to the calling
+ * task with the value that corresponds to the events in @a event_in that were
+ * satisfied.
+ *
+ * A task can determine the pending event set by using a value of
+ * @ref RTEMS_PENDING_EVENTS for the input event set @a event_in. The pending
+ * events are returned to the calling task but the event set is left
+ * unaltered.
+ *
+ * A task can receive all of the currently pending events by using the a value
+ * of @ref RTEMS_ALL_EVENTS for the input event set @a event_in and
+ * @ref RTEMS_NO_WAIT | @ref RTEMS_EVENT_ANY for the option set @a option_set.
+ * The pending events are returned to the calling task and the event set is
+ * cleared. If no events are pending then the @ref RTEMS_UNSATISFIED status
+ * code will be returned.
+ *
+ * If pending events satisfy the event condition, then @a event_out is set to
+ * the satisfied events and the pending events in the event condition are
+ * cleared. If the event condition is not satisfied and @ref RTEMS_NO_WAIT is
+ * specified, then @a event_out is set to the currently satisfied events. If
+ * the calling task chooses to wait, then it will block waiting for the event
+ * condition.
+ *
+ * If the calling task must wait for the event condition to be satisfied, then
+ * the timeout parameter is used to specify the maximum interval to wait. If
+ * it is set to @ref RTEMS_NO_TIMEOUT, then the calling task will wait forever.
+ *
+ * This directive only affects the events specified in @a event_in. Any
+ * pending events that do not correspond to any of the events specified in
+ * @a event_in will be left pending.
+ *
+ * A clock tick is required to support the wait with time out functionality of
+ * this directive.
+ *
+ * @param[in] event_in Set of requested events (input events).
+ * @param[in] option_set Use a bitwise or of the following options
+ * - @ref RTEMS_WAIT - task will wait for event (default),
+ * - @ref RTEMS_NO_WAIT - task should not wait,
+ * - @ref RTEMS_EVENT_ALL - return after all events (default), and
+ * - @ref RTEMS_EVENT_ANY - return after any events.
+ * @param[in] ticks Time out in ticks. Use @ref RTEMS_NO_TIMEOUT to wait
+ * without a time out (potentially forever).
+ * @param[out] event_out Set of received events (output events).
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_UNSATISFIED Input events not satisfied (only with the
+ * @ref RTEMS_NO_WAIT option).
+ * @retval RTEMS_INVALID_ADDRESS The @a event_out pointer is @c NULL.
+ * @retval RTEMS_TIMEOUT Timed out waiting for events.
+ */
+rtems_status_code rtems_event_receive (
+ rtems_event_set event_in,
+ rtems_option option_set,
+ rtems_interval ticks,
+ rtems_event_set *event_out
+);
+
+/** @} */
+
+/**
+ * @defgroup ClassicEventSystem System Events
+ *
+ * @ingroup ClassicEvent
+ *
+ * System events are similar to normal events. They offer a second set of
+ * events. These events are intended for internal RTEMS use and should not be
+ * used by applications (with the exception of the transient system event).
+ *
+ * The event @ref RTEMS_EVENT_SYSTEM_TRANSIENT is used for transient usage.
+ * See also @ref ClassicEventTransient. This event may be used by every entity
+ * that fulfils its usage pattern.
+ */
+/**@{**/
+
+/**
+ * @brief Reserved system event for network SBWAIT usage.
+ */
+#define RTEMS_EVENT_SYSTEM_NETWORK_SBWAIT RTEMS_EVENT_24
+
+/**
+ * @brief Reserved system event for network SOSLEEP usage.
+ */
+#define RTEMS_EVENT_SYSTEM_NETWORK_SOSLEEP RTEMS_EVENT_25
+
+/**
+ * @brief Reserved system event for network socket close.
+ */
+#define RTEMS_EVENT_SYSTEM_NETWORK_CLOSE RTEMS_EVENT_26
+
+/**
+ * @brief Reserved system event to resume server threads, e.g timer or
+ * interrupt server.
+ */
+#define RTEMS_EVENT_SYSTEM_SERVER_RESUME RTEMS_EVENT_29
+
+/**
+ * @brief Reserved system event for the server threads, e.g timer or interrupt
+ * server.
+ */
+#define RTEMS_EVENT_SYSTEM_SERVER RTEMS_EVENT_30
+
+/**
+ * @brief Reserved system event for transient usage.
+ */
+#define RTEMS_EVENT_SYSTEM_TRANSIENT RTEMS_EVENT_31
+
+/**
+ * @brief See rtems_event_send().
+ */
+rtems_status_code rtems_event_system_send(
+ rtems_id id,
+ rtems_event_set event_in
+);
+
+/**
+ * @brief See rtems_event_receive().
+ */
+rtems_status_code rtems_event_system_receive(
+ rtems_event_set event_in,
+ rtems_option option_set,
+ rtems_interval ticks,
+ rtems_event_set *event_out
+);
+
+/** @} */
+
+/**
+ * @defgroup ClassicEventTransient Transient Event
+ *
+ * @ingroup ClassicEvent
+ *
+ * The transient event can be used by a client task to issue a request to
+ * another task or interrupt service (server). The server can send the
+ * transient event to the client task to notify about a request completion, see
+ * rtems_event_transient_send(). The client task can wait for the transient
+ * event reception with rtems_event_transient_receive().
+ *
+ * The user of the transient event must ensure that this event is not pending
+ * once the request is finished or cancelled. A successful reception of the
+ * transient event with rtems_event_transient_receive() will clear the
+ * transient event. If a reception with timeout is used the transient event
+ * state is undefined after a timeout return status. The transient event can
+ * be cleared unconditionally with the non-blocking
+ * rtems_event_transient_clear().
+ *
+ * @msc
+ * hscale="1.6";
+ * M [label="Main Task"], IDLE [label="Idle Task"], S [label="Server"], TIME [label="System Tick Handler"];
+ * |||;
+ * --- [label="sequence with request completion"];
+ * M box M [label="prepare request\nissue request\nrtems_event_transient_receive()"];
+ * M=>>IDLE [label="blocking operation"];
+ * IDLE=>>S [label="request completion"];
+ * S box S [label="rtems_event_transient_send()"];
+ * S=>>M [label="task is ready again"];
+ * M box M [label="finish request"];
+ * |||;
+ * --- [label="sequence with early request completion"];
+ * M box M [label="prepare request\nissue request"];
+ * M=>>S [label="request completion"];
+ * S box S [label="rtems_event_transient_send()"];
+ * S=>>M [label="transient event is now pending"];
+ * M box M [label="rtems_event_transient_receive()\nfinish request"];
+ * |||;
+ * --- [label="sequence with timeout event"];
+ * M box M [label="prepare request\nissue request\nrtems_event_transient_receive()"];
+ * M=>>IDLE [label="blocking operation"];
+ * IDLE=>>TIME [label="timeout expired"];
+ * TIME box TIME [label="cancel blocking operation"];
+ * TIME=>>M [label="task is ready again"];
+ * M box M [label="cancel request\nrtems_event_transient_clear()"];
+ * @endmsc
+ *
+ * Suppose you have a task that wants to issue a certain request and then waits
+ * for request completion. It can create a request structure and store its
+ * task identifier there. Now it can place the request on a work queue of
+ * another task (or interrupt handler). Afterwards the task waits for the
+ * reception of the transient event. Once the server task is finished with the
+ * request it can send the transient event to the waiting task and wake it up.
+ *
+ * @code
+ * #include <assert.h>
+ * #include <rtems.h>
+ *
+ * typedef struct {
+ * rtems_id task_id;
+ * bool work_done;
+ * } request;
+ *
+ * void server(rtems_task_argument arg)
+ * {
+ * rtems_status_code sc;
+ * request *req = (request *) arg;
+ *
+ * req->work_done = true;
+ *
+ * sc = rtems_event_transient_send(req->task_id);
+ * assert(sc == RTEMS_SUCCESSFUL);
+ *
+ * sc = rtems_task_delete(RTEMS_SELF);
+ * assert(sc == RTEMS_SUCCESSFUL);
+ * }
+ *
+ * void issue_request_and_wait_for_completion(void)
+ * {
+ * rtems_status_code sc;
+ * rtems_id id;
+ * request req;
+ *
+ * req.task_id = rtems_task_self();
+ * req.work_done = false;
+ *
+ * sc = rtems_task_create(
+ * rtems_build_name('S', 'E', 'R', 'V'),
+ * 1,
+ * RTEMS_MINIMUM_STACK_SIZE,
+ * RTEMS_DEFAULT_MODES,
+ * RTEMS_DEFAULT_ATTRIBUTES,
+ * &id
+ * );
+ * assert(sc == RTEMS_SUCCESSFUL);
+ *
+ * sc = rtems_task_start(id, server, (rtems_task_argument) &req);
+ * assert(sc == RTEMS_SUCCESSFUL);
+ *
+ * sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ * assert(sc == RTEMS_SUCCESSFUL);
+ *
+ * assert(req.work_done);
+ * }
+ * @endcode
+ */
+/**@{**/
+
+/**
+ * @brief See rtems_event_system_send().
+ *
+ * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be sent.
+ */
+RTEMS_INLINE_ROUTINE rtems_status_code rtems_event_transient_send(
+ rtems_id id
+)
+{
+ return rtems_event_system_send( id, RTEMS_EVENT_SYSTEM_TRANSIENT );
+}
+
+/**
+ * @brief See rtems_event_system_receive().
+ *
+ * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be received.
+ */
+RTEMS_INLINE_ROUTINE rtems_status_code rtems_event_transient_receive(
+ rtems_option option_set,
+ rtems_interval ticks
+)
+{
+ rtems_event_set event_out;
+
+ return rtems_event_system_receive(
+ RTEMS_EVENT_SYSTEM_TRANSIENT,
+ RTEMS_EVENT_ALL | option_set,
+ ticks,
+ &event_out
+ );
+}
+
+/**
+ * @brief See rtems_event_system_receive().
+ *
+ * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be cleared.
+ */
+RTEMS_INLINE_ROUTINE void rtems_event_transient_clear( void )
+{
+ rtems_event_set event_out;
+
+ rtems_event_system_receive(
+ RTEMS_EVENT_SYSTEM_TRANSIENT,
+ RTEMS_EVENT_ALL | RTEMS_NO_WAIT,
+ 0,
+ &event_out
+ );
+}
+
+/** @} */
+
+typedef struct {
+ rtems_event_set pending_events;
+} Event_Control;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/eventimpl.h b/cpukit/include/rtems/rtems/eventimpl.h
new file mode 100644
index 0000000000..933ea0fe2b
--- /dev/null
+++ b/cpukit/include/rtems/rtems/eventimpl.h
@@ -0,0 +1,146 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicEventImpl
+ *
+ * @brief Classic Event Implementation
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_EVENTIMPL_H
+#define _RTEMS_RTEMS_EVENTIMPL_H
+
+#include <rtems/rtems/event.h>
+#include <rtems/score/thread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicEventImpl Classic Event Implementation
+ *
+ * @ingroup ClassicEvent
+ *
+ * @{
+ */
+
+/**
+ * This constant is passed as the event_in to the
+ * rtems_event_receive directive to determine which events are pending.
+ */
+#define EVENT_CURRENT 0
+
+/**
+ * The following constant is the value of an event set which
+ * has no events pending.
+ */
+#define EVENT_SETS_NONE_PENDING 0
+
+rtems_status_code _Event_Seize(
+ rtems_event_set event_in,
+ rtems_option option_set,
+ rtems_interval ticks,
+ rtems_event_set *event_out,
+ Thread_Control *executing,
+ Event_Control *event,
+ Thread_Wait_flags wait_class,
+ States_Control block_state,
+ ISR_lock_Context *lock_context
+);
+
+rtems_status_code _Event_Surrender(
+ Thread_Control *the_thread,
+ rtems_event_set event_in,
+ Event_Control *event,
+ Thread_Wait_flags wait_class,
+ ISR_lock_Context *lock_context
+);
+
+/**
+ * @brief Timeout Event
+ */
+void _Event_Timeout(
+ Objects_Id id,
+ void *arg
+);
+
+RTEMS_INLINE_ROUTINE void _Event_Initialize( Event_Control *event )
+{
+ event->pending_events = EVENT_SETS_NONE_PENDING;
+}
+
+/**
+ * @brief Checks if on events are posted in the event_set.
+ *
+ * This function returns TRUE if on events are posted in the event_set,
+ * and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Event_sets_Is_empty(
+ rtems_event_set the_event_set
+)
+{
+ return ( the_event_set == 0 );
+}
+
+/**
+ * @brief Posts the given new_events into the event_set passed in.
+ *
+ * This routine posts the given new_events into the event_set
+ * passed in. The result is returned to the user in event_set.
+ */
+RTEMS_INLINE_ROUTINE void _Event_sets_Post(
+ rtems_event_set the_new_events,
+ rtems_event_set *the_event_set
+)
+{
+ *the_event_set |= the_new_events;
+}
+
+/**
+ * @brief Returns the events in event_condition that are set in event_set.
+ *
+ * This function returns the events in event_condition which are
+ * set in event_set.
+ */
+RTEMS_INLINE_ROUTINE rtems_event_set _Event_sets_Get(
+ rtems_event_set the_event_set,
+ rtems_event_set the_event_condition
+)
+{
+ return ( the_event_set & the_event_condition );
+}
+
+/**
+ * @brief Removes the events in mask from the event_set passed in.
+ *
+ * This function removes the events in mask from the event_set
+ * passed in. The result is returned to the user in event_set.
+ */
+RTEMS_INLINE_ROUTINE rtems_event_set _Event_sets_Clear(
+ rtems_event_set the_event_set,
+ rtems_event_set the_mask
+)
+{
+ return ( the_event_set & ~(the_mask) );
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/rtems/eventmp.h>
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/eventmp.h b/cpukit/include/rtems/rtems/eventmp.h
new file mode 100644
index 0000000000..a80e60c4e0
--- /dev/null
+++ b/cpukit/include/rtems/rtems/eventmp.h
@@ -0,0 +1,101 @@
+/**
+ * @file rtems/rtems/eventmp.h
+ *
+ * @defgroup ClassicEventMP Event MP Support
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Event Manager MP Support
+ *
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Support in the Event Manager.
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_EVENTMP_H
+#define _RTEMS_RTEMS_EVENTMP_H
+
+#ifndef _RTEMS_RTEMS_EVENTIMPL_H
+# error "Never use <rtems/rtems/eventmp.h> directly; include <rtems/rtems/eventimpl.h> instead."
+#endif
+
+#include <rtems/score/mpciimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicEventMP Event MP Support
+ *
+ * @ingroup ClassicMP
+ *
+ * This encapsulates functionality related to the transparent multiprocessing
+ * support within the Classic API Event Manager.
+ */
+/**@{*/
+
+/*
+ * @brief Event_MP_Send_process_packet
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ *
+ * @note This routine is not needed since there are no process
+ * packets to be sent by this manager.
+ */
+
+/**
+ * @brief Issues a remote rtems_event_send() request.
+ */
+rtems_status_code _Event_MP_Send(
+ rtems_id id,
+ rtems_event_set event_in
+);
+
+/**
+ * @brief Event MP Packet Process
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+void _Event_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+);
+
+/*
+ * @brief Event_MP_Send_object_was_deleted
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed since there are no objects
+ * deleted by this manager.
+ */
+
+/*
+ * @brief Event_MP_Send_extract_proxy
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed since there are no objects
+ * deleted by this manager.
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of file */
diff --git a/cpukit/include/rtems/rtems/intr.h b/cpukit/include/rtems/rtems/intr.h
new file mode 100644
index 0000000000..7f99d93883
--- /dev/null
+++ b/cpukit/include/rtems/rtems/intr.h
@@ -0,0 +1,373 @@
+/**
+ * @file rtems/rtems/intr.h
+ *
+ * @defgroup ClassicINTR Interrupts
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Header file for Interrupt Manager
+ *
+ * This include file contains all the constants and structures associated with
+ * the Interrupt Manager.
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_INTR_H
+#define _RTEMS_RTEMS_INTR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/rtems/status.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/isrlock.h>
+
+/**
+ * @defgroup ClassicINTR Interrupts
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality related to the Classic API Interrupt
+ * Manager.
+ */
+/**@{*/
+
+/**
+ * @brief Interrupt level type.
+ */
+typedef ISR_Level rtems_interrupt_level;
+
+/**
+ * @brief Control block type used to manage the vectors.
+ */
+typedef ISR_Vector_number rtems_vector_number;
+
+/**
+ * @brief Return type for interrupt handler.
+ */
+typedef ISR_Handler rtems_isr;
+
+#if (CPU_SIMPLE_VECTORED_INTERRUPTS == FALSE)
+
+typedef ISR_Handler_entry rtems_isr_entry;
+
+#else
+/**
+ * @brief Interrupt handler type.
+ *
+ * @see rtems_interrupt_catch()
+ */
+typedef rtems_isr ( *rtems_isr_entry )(
+ rtems_vector_number
+ );
+
+/**
+ * @brief RTEMS Interrupt Catch
+ *
+ * This directive installs @a new_isr_handler as the RTEMS interrupt service
+ * routine for the interrupt vector with number @a vector. The previous RTEMS
+ * interrupt service routine is returned in @a old_isr_handler.
+ *
+ * @param[in] new_isr_handler is the address of interrupt service routine
+ * @param[in] vector is the interrupt vector number
+ * @param[in] old_isr_handler address at which to store previous ISR address
+ *
+ * @retval RTEMS_SUCCESSFUL and *old_isr_handler filled with previous ISR
+ * address
+ */
+rtems_status_code rtems_interrupt_catch(
+ rtems_isr_entry new_isr_handler,
+ rtems_vector_number vector,
+ rtems_isr_entry *old_isr_handler
+);
+#endif
+
+#if !defined(RTEMS_SMP)
+
+/**
+ * @brief Disable RTEMS Interrupt
+ *
+ * @note The interrupt level shall be of type @ref rtems_interrupt_level.
+ *
+ * This macro is only available on uni-processor configurations. The macro
+ * rtems_interrupt_local_disable() is available on all configurations.
+ */
+#define rtems_interrupt_disable( _isr_cookie ) \
+ _ISR_Local_disable(_isr_cookie)
+
+/**
+ * @brief Enable RTEMS Interrupt
+ *
+ * @note The interrupt level shall be of type @ref rtems_interrupt_level.
+ *
+ * This macro is only available on uni-processor configurations. The macro
+ * rtems_interrupt_local_enable() is available on all configurations.
+ */
+#define rtems_interrupt_enable( _isr_cookie ) \
+ _ISR_Local_enable(_isr_cookie)
+
+/**
+ * @brief Flash RTEMS Interrupt
+ *
+ * @note The interrupt level shall be of type @ref rtems_interrupt_level.
+ *
+ * This macro is only available on uni-processor configurations. The macro
+ * rtems_interrupt_local_disable() and rtems_interrupt_local_enable() is
+ * available on all configurations.
+ */
+#define rtems_interrupt_flash( _isr_cookie ) \
+ _ISR_Local_flash(_isr_cookie)
+
+#endif /* RTEMS_SMP */
+
+/**
+ * @brief This macro disables the interrupts on the current processor.
+ *
+ * On SMP configurations this will not ensure system wide mutual exclusion.
+ * Use interrupt locks instead.
+ *
+ * @param[in] _isr_cookie The previous interrupt level is returned. The type
+ * of this variable must be rtems_interrupt_level.
+ *
+ * @see rtems_interrupt_local_enable().
+ */
+#define rtems_interrupt_local_disable( _isr_cookie ) \
+ _ISR_Local_disable( _isr_cookie )
+
+/**
+ * @brief This macro restores the previous interrupt level on the current
+ * processor.
+ *
+ * @param[in] _isr_cookie The previous interrupt level returned by
+ * rtems_interrupt_local_disable().
+ */
+#define rtems_interrupt_local_enable( _isr_cookie ) \
+ _ISR_Local_enable( _isr_cookie )
+
+/**
+ * @brief RTEMS Interrupt Is in Progress
+ *
+ * A return value of true indicates that the caller is an interrupt service
+ * routine and @b not a thread. The directives available to an interrupt
+ * service routine are restricted.
+ */
+#define rtems_interrupt_is_in_progress() \
+ _ISR_Is_in_progress()
+
+/**
+ * @brief This routine generates an interrupt.
+ *
+ * @note No implementation.
+ */
+#define rtems_interrupt_cause( _interrupt_to_cause )
+
+/**
+ * @brief This routine clears the specified interrupt.
+ *
+ * @note No implementation.
+ */
+#define rtems_interrupt_clear( _interrupt_to_clear )
+
+/**
+ * @defgroup ClassicINTRLocks Interrupt Locks
+ *
+ * @ingroup ClassicINTR
+ *
+ * @brief Low-level lock to protect critical sections accessed by threads and
+ * interrupt service routines.
+ *
+ * On single processor configurations the interrupt locks degrade to simple
+ * interrupt disable/enable sequences. No additional storage or objects are
+ * required.
+ *
+ * This synchronization primitive is supported on SMP configurations. Here SMP
+ * locks are used.
+ * @{
+ */
+
+/**
+ * @brief Interrupt lock control.
+ */
+typedef ISR_lock_Control rtems_interrupt_lock;
+
+/**
+ * @brief Local interrupt lock context for acquire and release pairs.
+ */
+typedef ISR_lock_Context rtems_interrupt_lock_context;
+
+/**
+ * @brief Defines an interrupt lock member.
+ *
+ * Do not add a ';' after this macro.
+ *
+ * @param _designator The designator for the interrupt lock.
+ */
+#define RTEMS_INTERRUPT_LOCK_MEMBER( _designator ) \
+ ISR_LOCK_MEMBER( _designator )
+
+/**
+ * @brief Declares an interrupt lock variable.
+ *
+ * Do not add a ';' after this macro.
+ *
+ * @param _qualifier The qualifier for the interrupt lock, e.g. extern.
+ * @param _designator The designator for the interrupt lock.
+ */
+#define RTEMS_INTERRUPT_LOCK_DECLARE( _qualifier, _designator ) \
+ ISR_LOCK_DECLARE( _qualifier, _designator )
+
+/**
+ * @brief Defines an interrupt lock variable.
+ *
+ * Do not add a ';' after this macro.
+ *
+ * @param _qualifier The qualifier for the interrupt lock, e.g. static.
+ * @param _designator The designator for the interrupt lock.
+ * @param _name The name for the interrupt lock. It must be a string. The
+ * name is only used if profiling is enabled.
+ */
+#define RTEMS_INTERRUPT_LOCK_DEFINE( _qualifier, _designator, _name ) \
+ ISR_LOCK_DEFINE( _qualifier, _designator, _name )
+
+/**
+ * @brief Defines an interrupt lock variable reference.
+ *
+ * Do not add a ';' after this macro.
+ *
+ * @param _designator The designator for the interrupt lock reference.
+ * @param _target The target for the interrupt lock reference.
+ */
+#define RTEMS_INTERRUPT_LOCK_REFERENCE( _designator, _target ) \
+ ISR_LOCK_REFERENCE( _designator, _target )
+
+/**
+ * @brief Initializer for static initialization of interrupt locks.
+ *
+ * @param _name The name for the interrupt lock. It must be a string. The
+ * name is only used if profiling is enabled.
+ */
+#define RTEMS_INTERRUPT_LOCK_INITIALIZER( _name ) ISR_LOCK_INITIALIZER( _name )
+
+/**
+ * @brief Initializes an interrupt lock.
+ *
+ * Concurrent initialization leads to unpredictable results.
+ *
+ * @param[in,out] _lock The interrupt lock.
+ * @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.
+ */
+#define rtems_interrupt_lock_initialize( _lock, _name ) \
+ _ISR_lock_Initialize( _lock, _name )
+
+/**
+ * @brief Destroys an interrupt lock.
+ *
+ * Concurrent destruction leads to unpredictable results.
+ *
+ * @param[in,out] _lock The interrupt lock control.
+ */
+#define rtems_interrupt_lock_destroy( _lock ) \
+ _ISR_lock_Destroy( _lock )
+
+/**
+ * @brief Disables interrupts on the current processor.
+ *
+ * This function can be used in thread and interrupt context.
+ *
+ * @param[in,out] _lock_context The local interrupt lock context for an acquire
+ * and release pair.
+ *
+ * @see rtems_interrupt_lock_acquire_isr().
+ */
+#define rtems_interrupt_lock_interrupt_disable( _lock_context ) \
+ _ISR_lock_ISR_disable( _lock_context )
+
+/**
+ * @brief Acquires an interrupt lock.
+ *
+ * Interrupts will be disabled. On SMP configurations this function acquires
+ * an SMP lock.
+ *
+ * This function can be used in thread and interrupt context.
+ *
+ * @param[in,out] _lock The interrupt lock.
+ * @param[in,out] _lock_context The local interrupt lock context for an acquire
+ * and release pair.
+ *
+ * @see rtems_interrupt_lock_release().
+ */
+#define rtems_interrupt_lock_acquire( _lock, _lock_context ) \
+ _ISR_lock_ISR_disable_and_acquire( _lock, _lock_context )
+
+/**
+ * @brief Releases an interrupt lock.
+ *
+ * The interrupt status will be restored. On SMP configurations this function
+ * releases an SMP lock.
+ *
+ * This function can be used in thread and interrupt context.
+ *
+ * @param[in,out] _lock The interrupt lock.
+ * @param[in,out] _lock_context The local interrupt lock context for an acquire
+ * and release pair.
+ *
+ * @see rtems_interrupt_lock_acquire().
+ */
+#define rtems_interrupt_lock_release( _lock, _lock_context ) \
+ _ISR_lock_Release_and_ISR_enable( _lock, _lock_context )
+
+/**
+ * @brief Acquires an interrupt lock in the corresponding interrupt service
+ * routine.
+ *
+ * The interrupt status will remain unchanged. On SMP configurations this
+ * function acquires an SMP lock.
+ *
+ * In case the corresponding interrupt service routine can be interrupted by
+ * higher priority interrupts and these interrupts enter the critical section
+ * protected by this lock, then the result is unpredictable.
+ *
+ * @param[in,out] _lock The interrupt lock.
+ * @param[in,out] _lock_context The local interrupt lock context for an acquire
+ * and release pair.
+ *
+ * @see rtems_interrupt_lock_release_isr().
+ */
+#define rtems_interrupt_lock_acquire_isr( _lock, _lock_context ) \
+ _ISR_lock_Acquire( _lock, _lock_context )
+
+/**
+ * @brief Releases an interrupt lock in the corresponding interrupt service
+ * routine.
+ *
+ * The interrupt status will remain unchanged. On SMP configurations this
+ * function releases an SMP lock.
+ *
+ * @param[in,out] _lock The interrupt lock.
+ * @param[in,out] _lock_context The local interrupt lock context for an acquire
+ * and release pair.
+ *
+ * @see rtems_interrupt_lock_acquire_isr().
+ */
+#define rtems_interrupt_lock_release_isr( _lock, _lock_context ) \
+ _ISR_lock_Release( _lock, _lock_context )
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/mainpage.h b/cpukit/include/rtems/rtems/mainpage.h
new file mode 100644
index 0000000000..e2d51328cf
--- /dev/null
+++ b/cpukit/include/rtems/rtems/mainpage.h
@@ -0,0 +1,927 @@
+/**
+ * @file rtems/rtems/mainpage.h
+ *
+ * This file exists to provide a top level description of RTEMS for Doxygen.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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.
+ */
+
+/**
+ * @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 fileystems, 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 ClassicAPI
+ *
+ * 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 eliminatation 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 ClassicTasks
+ *
+ * @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
+ *
+ * @brief Local packages.
+ */
diff --git a/cpukit/include/rtems/rtems/message.h b/cpukit/include/rtems/rtems/message.h
new file mode 100644
index 0000000000..8ae9e156a1
--- /dev/null
+++ b/cpukit/include/rtems/rtems/message.h
@@ -0,0 +1,270 @@
+/**
+ * @file rtems/rtems/message.h
+ *
+ * @defgroup ClassicMessageQueue Message Queues
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Message Queue Manager
+ *
+ * This include file contains all the constants and structures associated
+ * with the Message Queue Manager. This manager provides a mechanism for
+ * communication and synchronization between tasks using messages.
+ *
+ * Directives provided are:
+ *
+ * - create a queue
+ * - get ID of a queue
+ * - delete a queue
+ * - put a message at the rear of a queue
+ * - put a message at the front of a queue
+ * - broadcast N messages to a queue
+ * - receive message from a queue
+ * - flush all messages on a queue
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_MESSAGE_H
+#define _RTEMS_RTEMS_MESSAGE_H
+
+#include <rtems/rtems/types.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/coremsg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup ClassicMessageQueueImpl
+ *
+ * The following records define the control block used to manage
+ * each message queue.
+ */
+typedef struct {
+ /** This field is the inherited object characteristics. */
+ Objects_Control Object;
+ /** This field is the instance of the SuperCore Message Queue. */
+ CORE_message_queue_Control message_queue;
+ /** This field is the attribute set as defined by the API. */
+ rtems_attribute attribute_set;
+} Message_queue_Control;
+
+/**
+ * @defgroup ClassicMessageQueue Message Queues
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality related to the Classic API Message Queue
+ * Manager.
+ */
+/**@{*/
+
+/**
+ * @brief RTEMS Create Message Queue
+ *
+ * This routine implements the rtems_message_queue_create directive. The
+ * message queue will have the @a name. If the @a attribute_set indicates
+ * that the message queue is to be limited in the number of messages
+ * that can be outstanding, then @a count indicates the maximum number of
+ * messages that will be held. It returns the id of the created
+ * message queue in @a id.
+ *
+ * @param[in] name is the user defined queue name
+ * @param[in] count is the maximum message and reserved buffer count
+ * @param[in] max_message_size is the maximum size of each message
+ * @param[in] attribute_set is the process method
+ * @param[in] id is the pointer to queue
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error. If successful, the @a id will
+ * be filled in with the queue id.
+ */
+rtems_status_code rtems_message_queue_create(
+ rtems_name name,
+ uint32_t count,
+ size_t max_message_size,
+ rtems_attribute attribute_set,
+ rtems_id *id
+);
+
+/**
+ * @brief RTEMS Message Queue Name to Id
+ *
+ * This routine implements the rtems_message_queue_ident directive.
+ * This directive returns the message queue ID associated with NAME.
+ * If more than one message queue is named name, then the message
+ * queue to which the ID belongs is arbitrary. node indicates the
+ * extent of the search for the ID of the message queue named name.
+ * The search can be limited to a particular node or allowed to
+ * encompass all nodes.
+ *
+ * @param[in] name is the user defined message queue name
+ * @param[in] node is the node(s) to be searched
+ * @param[in] id is the pointer to message queue id
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful and
+ * *id filled with the message queue id
+ */
+rtems_status_code rtems_message_queue_ident(
+ rtems_name name,
+ uint32_t node,
+ rtems_id *id
+);
+
+/**
+ * @brief RTEMS Delete Message Queue
+ *
+ * This routine implements the rtems_message_queue_delete directive. The
+ * message queue indicated by ID is deleted.
+ *
+ * @param[in] id is the queue id
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
+ */
+rtems_status_code rtems_message_queue_delete(
+ rtems_id id
+);
+
+/**
+ * @brief rtems_message_queue_send
+ *
+ * Message Queue Manager - rtems_message_queue_send
+ *
+ * This routine implements the rtems_message_queue_send directive.
+ * This directive sends the message buffer to the message queue
+ * indicated by ID. If one or more tasks is blocked waiting
+ * to receive a message from this message queue, then one will
+ * receive the message. The task selected to receive the
+ * message is based on the task queue discipline algorithm in
+ * use by this particular message queue. If no tasks are waiting,
+ * then the message buffer will be placed at the REAR of the
+ * chain of pending messages for this message queue.
+ */
+rtems_status_code rtems_message_queue_send(
+ rtems_id id,
+ const void *buffer,
+ size_t size
+);
+
+/**
+ * @brief RTEMS Urgent Message Queue
+ *
+ * This routine implements the rtems_message_queue_urgent directive.
+ * This directive has the same behavior as rtems_message_queue_send
+ * except that if no tasks are waiting, the message buffer will
+ * be placed at the FRONT of the chain of pending messages rather
+ * than at the REAR.
+ *
+ * @param[in] id is the pointer to message queue
+ * @param[in] buffer is the pointer to message buffer
+ * @param[in] size is the size of message to send urgently
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
+ */
+rtems_status_code rtems_message_queue_urgent(
+ rtems_id id,
+ const void *buffer,
+ size_t size
+);
+
+/**
+ * @brief RTEMS Broadcast Message Queue
+ *
+ * This routine implements the rtems_message_queue_broadcast directive.
+ * This directive sends the message buffer to all of the tasks blocked
+ * waiting for a message on the message queue indicated by ID.
+ * If no tasks are waiting, then the message buffer will not be queued.
+ *
+ * @param[in] id is the pointer to message queue
+ * @param[in] buffer is the pointer to message buffer
+ * @param[in] size is the size of message to broadcast
+ * @param[in] count pointer to area to store number of threads made ready
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful and
+ * *count filled in with number of threads made ready
+ */
+rtems_status_code rtems_message_queue_broadcast(
+ rtems_id id,
+ const void *buffer,
+ size_t size,
+ uint32_t *count
+);
+
+/**
+ * @brief RTEMS Message Queue Receive
+ *
+ * This routine implements the rtems_message_queue_receive directive.
+ * This directive is invoked when the calling task wishes to receive
+ * a message from the message queue indicated by ID. The received
+ * message is to be placed in buffer. If no messages are outstanding
+ * and the option_set indicates that the task is willing to block,
+ * then the task will be blocked until a message arrives or until,
+ * optionally, timeout clock ticks have passed.
+ *
+ * @param[in] id is the queue id
+ * @param[in] buffer is the pointer to message buffer
+ * @param[in] size is the size of message receive
+ * @param[in] option_set is the options on receive
+ * @param[in] timeout is the number of ticks to wait
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_message_queue_receive(
+ rtems_id id,
+ void *buffer,
+ size_t *size,
+ rtems_option option_set,
+ rtems_interval timeout
+);
+
+/**
+ * @brief rtems_message_queue_flush
+ *
+ * This routine implements the rtems_message_queue_flush directive.
+ * This directive takes all outstanding messages for the message
+ * queue indicated by ID and returns them to the inactive message
+ * chain. The number of messages flushed is returned in COUNT.
+ *
+ * Message Queue Manager
+ */
+rtems_status_code rtems_message_queue_flush(
+ rtems_id id,
+ uint32_t *count
+);
+
+/**
+ * @brief RTEMS Message Queue Get Number Pending
+ *
+ * Message Queue Manager
+ *
+ * This routine implements the rtems_message_queue_get_number_pending
+ * directive. This directive returns the number of pending
+ * messages for the message queue indicated by ID
+ * chain. The number of messages pending is returned in COUNT.
+ */
+rtems_status_code rtems_message_queue_get_number_pending(
+ rtems_id id,
+ uint32_t *count
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/messageimpl.h b/cpukit/include/rtems/rtems/messageimpl.h
new file mode 100644
index 0000000000..df7cea6829
--- /dev/null
+++ b/cpukit/include/rtems/rtems/messageimpl.h
@@ -0,0 +1,120 @@
+/**
+ * @file rtems/rtems/message.inl
+ *
+ * This include file contains the static inline implementation of all
+ * inlined routines in the Message Manager.
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_MESSAGEIMPL_H
+#define _RTEMS_RTEMS_MESSAGEIMPL_H
+
+#include <rtems/rtems/message.h>
+#include <rtems/score/objectimpl.h>
+#include <rtems/score/coremsgimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicMessageQueueImpl Classic Message Queue Implementation
+ *
+ * @ingroup ClassicMessageQueue
+ *
+ * @{
+ */
+
+/**
+ * The following enumerated type details the modes in which a message
+ * may be submitted to a message queue. The message may be posted
+ * in a send or urgent fashion.
+ */
+typedef enum {
+ /**
+ * This value indicates the user wants to send the message using the
+ * normal message insertion protocol (FIFO or priority).
+ */
+ MESSAGE_QUEUE_SEND_REQUEST = 0,
+ /**
+ * This value indicates the user considers the message to be urgent
+ * and wants it inserted at the head of the pending message queue.
+ */
+ MESSAGE_QUEUE_URGENT_REQUEST = 1
+} Message_queue_Submit_types;
+
+/**
+ * The following defines the information control block used to
+ * manage this class of objects.
+ */
+extern Objects_Information _Message_queue_Information;
+
+/**
+ * @brief Message_queue_Submit
+ *
+ * This routine implements the directives rtems_message_queue_send
+ * and rtems_message_queue_urgent. It processes a message that is
+ * to be submitted to the designated message queue. The message will
+ * either be processed as a send send message which it will be inserted
+ * at the rear of the queue or it will be processed as an urgent message
+ * which will be inserted at the front of the queue.
+ */
+rtems_status_code _Message_queue_Submit(
+ rtems_id id,
+ const void *buffer,
+ size_t size,
+ Message_queue_Submit_types submit_type
+);
+
+/**
+ * @brief Deallocates a message queue control block into
+ * the inactive chain of free message queue control blocks.
+ *
+ * This routine deallocates a message queue control block into
+ * the inactive chain of free message queue control blocks.
+ */
+RTEMS_INLINE_ROUTINE void _Message_queue_Free (
+ Message_queue_Control *the_message_queue
+)
+{
+ _Objects_Free( &_Message_queue_Information, &the_message_queue->Object );
+}
+
+RTEMS_INLINE_ROUTINE Message_queue_Control *_Message_queue_Get(
+ Objects_Id id,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Context_initialize( queue_context );
+ return (Message_queue_Control *) _Objects_Get(
+ id,
+ &queue_context->Lock_context.Lock_context,
+ &_Message_queue_Information
+ );
+}
+
+RTEMS_INLINE_ROUTINE Message_queue_Control *_Message_queue_Allocate( void )
+{
+ return (Message_queue_Control *)
+ _Objects_Allocate( &_Message_queue_Information );
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/rtems/msgmp.h>
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/modes.h b/cpukit/include/rtems/rtems/modes.h
new file mode 100644
index 0000000000..547ae13e05
--- /dev/null
+++ b/cpukit/include/rtems/rtems/modes.h
@@ -0,0 +1,132 @@
+/**
+ * @file rtems/rtems/modes.h
+ *
+ * @defgroup ClassicModes Modes
+ *
+ * @ingroup ClassicRTEMS
+ * @brief RTEMS thread and RTEMS_ASR modes
+ *
+ * This include file contains all constants and structures associated
+ * with the RTEMS thread and RTEMS_ASR modes.
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_MODES_H
+#define _RTEMS_RTEMS_MODES_H
+
+#include <rtems/score/cpu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicModes Modes
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality related to the task modes supported
+ * by the Classic API Task Manager.
+ */
+/**@{*/
+
+/**
+ * The following type defines the control block used to manage
+ * each a mode set.
+ */
+typedef uint32_t Modes_Control;
+
+/**
+ * The following constants define the individual modes and masks
+ * which may be used to compose a mode set and to alter modes.
+ */
+#define RTEMS_ALL_MODE_MASKS 0x0000ffff
+
+/**
+ * This mode constant is the default mode set.
+ */
+#define RTEMS_DEFAULT_MODES 0x00000000
+
+/**
+ * This mode constant is used when the user wishes to obtain their
+ * current execution mode.
+ */
+#define RTEMS_CURRENT_MODE 0
+
+/** This mode constant corresponds to the timeslice enable/disable bit. */
+#define RTEMS_TIMESLICE_MASK 0x00000200
+
+/** This mode constant corresponds to the preemption enable/disable bit. */
+#define RTEMS_PREEMPT_MASK 0x00000100
+
+/** This mode constant corresponds to the signal enable/disable bit. */
+#define RTEMS_ASR_MASK 0x00000400
+
+/** This mode constant corresponds to the interrupt enable/disable bits. */
+#define RTEMS_INTERRUPT_MASK CPU_MODES_INTERRUPT_MASK
+
+/** This mode constant is used to indicate preemption is enabled. */
+#define RTEMS_PREEMPT 0x00000000
+/** This mode constant is used to indicate preemption is disabled. */
+#define RTEMS_NO_PREEMPT 0x00000100
+
+/** This mode constant is used to indicate timeslicing is disabled. */
+#define RTEMS_NO_TIMESLICE 0x00000000
+/** This mode constant is used to indicate timeslicing is enabled. */
+#define RTEMS_TIMESLICE 0x00000200
+
+/** This mode constant is used to indicate signal processing is enabled. */
+#define RTEMS_ASR 0x00000000
+/** This mode constant is used to indicate signal processing is disabled. */
+#define RTEMS_NO_ASR 0x00000400
+
+/**
+ * @brief RTEMS_INTERRUPT_LEVEL
+ *
+ * This function returns the processor dependent interrupt
+ * level which corresponds to the requested interrupt level.
+ *
+ * @note RTEMS supports 256 interrupt levels using the least
+ * significant eight bits of MODES.CONTROL. On any
+ * particular CPU, fewer than 256 levels may be supported.
+ */
+#define RTEMS_INTERRUPT_LEVEL( _mode_set ) \
+ ( (_mode_set) & RTEMS_INTERRUPT_MASK )
+
+/**
+ * @brief Interrupt Mask Variable
+ *
+ * This variable is used by bindings from languages other than C and C++.
+ */
+extern const uint32_t rtems_interrupt_mask;
+
+/**
+ * @brief Body for RTEMS_INTERRUPT_LEVEL Macro
+ *
+ * @param[in] level is the desired interrupt level
+ *
+ * @retval This methods returns a mode with the desired interrupt
+ * @a level in the proper bitfield location.
+ *
+ * @note This variable is used by bindings from languages other than
+ * C and C++.
+ */
+Modes_Control rtems_interrupt_level_body(
+ uint32_t level
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/modesimpl.h b/cpukit/include/rtems/rtems/modesimpl.h
new file mode 100644
index 0000000000..8c1acc7cb9
--- /dev/null
+++ b/cpukit/include/rtems/rtems/modesimpl.h
@@ -0,0 +1,146 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicModesImpl
+ *
+ * @brief Classic Modes Implementation
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_MODESIMPL_H
+#define _RTEMS_RTEMS_MODESIMPL_H
+
+#include <rtems/rtems/modes.h>
+#include <rtems/score/isrlevel.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicModesImpl Classic Modes Implementation
+ *
+ * @ingroup ClassicModes
+ *
+ * @{
+ */
+
+/**
+ * @brief Checks if any of the mode flags in mask are set in mode_set.
+ *
+ * This function returns TRUE if any of the mode flags in mask
+ * are set in mode_set, and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Modes_Mask_changed (
+ Modes_Control mode_set,
+ Modes_Control masks
+)
+{
+ return ( mode_set & masks ) ? true : false;
+}
+
+/**
+ * @brief Checks if mode_set says that Asynchronous Signal Processing is disabled.
+ *
+ * This function returns TRUE if mode_set indicates that Asynchronous
+ * Signal Processing is disabled, and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Modes_Is_asr_disabled (
+ Modes_Control mode_set
+)
+{
+ return (mode_set & RTEMS_ASR_MASK) == RTEMS_NO_ASR;
+}
+
+/**
+ * @brief Checks if mode_set indicates that preemption is enabled.
+ *
+ * This function returns TRUE if mode_set indicates that preemption
+ * is enabled, and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Modes_Is_preempt (
+ Modes_Control mode_set
+)
+{
+ return (mode_set & RTEMS_PREEMPT_MASK) == RTEMS_PREEMPT;
+}
+
+/**
+ * @brief Checks if mode_set indicates that timeslicing is enabled.
+ *
+ * This function returns TRUE if mode_set indicates that timeslicing
+ * is enabled, and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Modes_Is_timeslice (
+ Modes_Control mode_set
+)
+{
+ return (mode_set & RTEMS_TIMESLICE_MASK) == RTEMS_TIMESLICE;
+}
+
+/**
+ * @brief Gets the interrupt level portion of the mode_set.
+ *
+ * This function returns the interrupt level portion of the mode_set.
+ */
+RTEMS_INLINE_ROUTINE ISR_Level _Modes_Get_interrupt_level (
+ Modes_Control mode_set
+)
+{
+ return ( mode_set & RTEMS_INTERRUPT_MASK );
+}
+
+/**
+ * @brief Sets the current interrupt level to that specified in the mode_set.
+ *
+ * This routine sets the current interrupt level to that specified
+ * in the mode_set.
+ */
+RTEMS_INLINE_ROUTINE void _Modes_Set_interrupt_level (
+ Modes_Control mode_set
+)
+{
+ _ISR_Set_level( _Modes_Get_interrupt_level( mode_set ) );
+}
+
+/**
+ * @brief Changes the modes in old_mode_set indicated by
+ * mask to the requested values in new_mode_set.
+ *
+ * This routine changes the modes in old_mode_set indicated by
+ * mask to the requested values in new_mode_set. The resulting
+ * mode set is returned in out_mode_set and the modes that changed
+ * is returned in changed.
+ */
+RTEMS_INLINE_ROUTINE void _Modes_Change (
+ Modes_Control old_mode_set,
+ Modes_Control new_mode_set,
+ Modes_Control mask,
+ Modes_Control *out_mode_set,
+ Modes_Control *changed
+)
+{
+ Modes_Control _out_mode;
+
+ _out_mode = old_mode_set;
+ _out_mode &= ~mask;
+ _out_mode |= new_mode_set & mask;
+ *changed = _out_mode ^ old_mode_set;
+ *out_mode_set = _out_mode;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/mp.h b/cpukit/include/rtems/rtems/mp.h
new file mode 100644
index 0000000000..f1b93b6751
--- /dev/null
+++ b/cpukit/include/rtems/rtems/mp.h
@@ -0,0 +1,54 @@
+/**
+ * @file rtems/rtems/mp.h
+ *
+ * @defgroup ClassicMP Multiprocessing
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Multiprocessing Manager
+ *
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Manager.
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_MP_H
+#define _RTEMS_RTEMS_MP_H
+
+/**
+ * @defgroup ClassicMP Multiprocessing
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality related to the distributed
+ * Multiprocessing support in the Classic API.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief RTEMS Multiprocessing Announce
+ *
+ * This routine implements the MULTIPROCESSING_ANNOUNCE directive.
+ * It is invoked by the MPCI layer to indicate that an MPCI packet
+ * has been received.
+ */
+void rtems_multiprocessing_announce ( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/msgmp.h b/cpukit/include/rtems/rtems/msgmp.h
new file mode 100644
index 0000000000..3dabd8d46b
--- /dev/null
+++ b/cpukit/include/rtems/rtems/msgmp.h
@@ -0,0 +1,211 @@
+/**
+ * @file rtems/rtems/msgmp.h
+ *
+ * @brief Message Manager MP Support
+ *
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Support in the Message Manager.
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_MSGMP_H
+#define _RTEMS_RTEMS_MSGMP_H
+
+#ifndef _RTEMS_RTEMS_MESSAGEIMPL_H
+# error "Never use <rtems/rtems/msgmp.h> directly; include <rtems/rtems/messageimpl.h> instead."
+#endif
+
+#include <rtems/score/mpciimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicMsgMP Message Queue MP Support
+ *
+ * @ingroup ClassicMP
+ *
+ * This encapsulates functionality related to the transparent multiprocessing
+ * support within the Classic API Message Queue Manager.
+ */
+/*{*/
+
+/**
+ * The following enumerated type defines the list of
+ * remote message queue operations.
+ */
+typedef enum {
+ MESSAGE_QUEUE_MP_ANNOUNCE_CREATE = 0,
+ MESSAGE_QUEUE_MP_ANNOUNCE_DELETE = 1,
+ MESSAGE_QUEUE_MP_EXTRACT_PROXY = 2,
+ MESSAGE_QUEUE_MP_RECEIVE_REQUEST = 3,
+ MESSAGE_QUEUE_MP_RECEIVE_RESPONSE = 4,
+ MESSAGE_QUEUE_MP_SEND_REQUEST = 5,
+ MESSAGE_QUEUE_MP_SEND_RESPONSE = 6,
+ MESSAGE_QUEUE_MP_URGENT_REQUEST = 7,
+ MESSAGE_QUEUE_MP_URGENT_RESPONSE = 8,
+ MESSAGE_QUEUE_MP_BROADCAST_REQUEST = 9,
+ MESSAGE_QUEUE_MP_BROADCAST_RESPONSE = 10,
+ MESSAGE_QUEUE_MP_FLUSH_REQUEST = 11,
+ MESSAGE_QUEUE_MP_FLUSH_RESPONSE = 12,
+ MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_REQUEST = 13,
+ MESSAGE_QUEUE_MP_GET_NUMBER_PENDING_RESPONSE = 14
+} Message_queue_MP_Remote_operations;
+
+/**
+ * The following data structure defines the packet used to perform
+ * remote message queue operations.
+ */
+typedef struct {
+ rtems_packet_prefix Prefix;
+ Message_queue_MP_Remote_operations operation;
+ rtems_name name;
+ rtems_option option_set;
+ Objects_Id proxy_id;
+ uint32_t count;
+ size_t size;
+ uint32_t pad0;
+ CORE_message_queue_Buffer Buffer;
+} Message_queue_MP_Packet;
+
+#define MESSAGE_QUEUE_MP_PACKET_SIZE \
+ offsetof(Message_queue_MP_Packet, Buffer.buffer)
+
+RTEMS_INLINE_ROUTINE bool _Message_queue_MP_Is_remote( Objects_Id id )
+{
+ return _Objects_MP_Is_remote( id, &_Message_queue_Information );
+}
+
+/**
+ * @brief Message_queue_Core_message_queue_mp_support
+ *
+ * Input parameters:
+ * the_thread - the remote thread the message was submitted to
+ * id - id of the message queue
+ *
+ * Output parameters: NONE
+ */
+void _Message_queue_Core_message_queue_mp_support (
+ Thread_Control *the_thread,
+ rtems_id id
+);
+
+/**
+ * @brief _Message_queue_MP_Send_process_packet
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ */
+void _Message_queue_MP_Send_process_packet (
+ Message_queue_MP_Remote_operations operation,
+ Objects_Id message_queue_id,
+ rtems_name name,
+ Objects_Id proxy_id
+);
+
+/**
+ * @brief Issues a remote rtems_message_queue_broadcast() request.
+ */
+rtems_status_code _Message_queue_MP_Broadcast(
+ rtems_id id,
+ const void *buffer,
+ size_t size,
+ uint32_t *count
+);
+
+/**
+ * @brief Issues a remote rtems_message_queue_flush() request.
+ */
+rtems_status_code _Message_queue_MP_Flush(
+ rtems_id id,
+ uint32_t *count
+);
+
+/**
+ * @brief Issues a remote rtems_message_queue_get_number_pending() request.
+ */
+rtems_status_code _Message_queue_MP_Get_number_pending(
+ rtems_id id,
+ uint32_t *count
+);
+
+/**
+ * @brief Issues a remote rtems_message_queue_receive() request.
+ */
+rtems_status_code _Message_queue_MP_Receive(
+ rtems_id id,
+ void *buffer,
+ size_t *size,
+ rtems_option option_set,
+ rtems_interval timeout
+);
+
+/**
+ * @brief Issues a remote rtems_message_queue_send() request.
+ */
+rtems_status_code _Message_queue_MP_Send(
+ rtems_id id,
+ const void *buffer,
+ size_t size
+);
+
+/**
+ * @brief Issues a remote rtems_message_queue_urgent() request.
+ */
+rtems_status_code _Message_queue_MP_Urgent(
+ rtems_id id,
+ const void *buffer,
+ size_t size
+);
+
+/**
+ *
+ * @brief _Message_queue_MP_Process_packet
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+void _Message_queue_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+);
+
+/**
+ * @brief _Message_queue_MP_Send_object_was_deleted
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ */
+void _Message_queue_MP_Send_object_was_deleted (
+ Thread_Control *the_proxy,
+ Objects_Id mp_id
+);
+
+/**
+ * @brief _Message_queue_MP_Send_extract_proxy
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ */
+void _Message_queue_MP_Send_extract_proxy (
+ Thread_Control *the_thread,
+ Objects_Id id
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of file */
diff --git a/cpukit/include/rtems/rtems/object.h b/cpukit/include/rtems/rtems/object.h
new file mode 100644
index 0000000000..2652915462
--- /dev/null
+++ b/cpukit/include/rtems/rtems/object.h
@@ -0,0 +1,370 @@
+/**
+ * @file rtems/rtems/object.h
+ *
+ * @defgroup ClassicClassInfo Object Class Information
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Classic API interfaces to Object Services
+ *
+ * This include file defines Classic API interfaces to Object Services.
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_OBJECT_H
+#define _RTEMS_RTEMS_OBJECT_H
+
+#include <stdint.h>
+#include <rtems/score/object.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicClassInfo Object Class Information
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality related to the Classic API Object
+ * Class Services.
+ */
+/**@{*/
+
+/**
+ * This structure is used to return information to the application
+ * about the objects configured for a specific API/Class combination.
+ */
+typedef struct {
+ /** This field is the minimum valid object Id for this class. */
+ rtems_id minimum_id;
+ /** This field is the maximum valid object Id for this class. */
+ rtems_id maximum_id;
+ /** This field is the number of object instances configured for this class. */
+ uint32_t maximum;
+ /** This field indicates if the class is configured for auto-extend. */
+ bool auto_extend;
+ /** This field is the number of currently unallocated objects. */
+ uint32_t unallocated;
+} rtems_object_api_class_information;
+
+/**
+ * @brief Build Object Id
+ *
+ * This function returns an object id composed of the
+ * specified @a api, @a class, @a node,
+ * and @a index.
+ *
+ * @param[in] _api indicates the api to use for the Id
+ * @param[in] _class indicates the class to use for the Id
+ * @param[in] _node indicates the node to use for the Id
+ * @param[in] _index indicates the index to use for the Id
+ *
+ * @retval This method returns an object Id built from the
+ * specified values.
+ *
+ * @note A body is also provided.
+ */
+#define rtems_build_id( _api, _class, _node, _index ) \
+ _Objects_Build_id( _api, _class, _node, _index )
+
+/**
+ * @brief Build Thirty-Two Bit Object Name
+ *
+ * RTEMS Object Helper -- Build an Object Id
+ *
+ * This function returns an object name composed of the four characters
+ * C1, C2, C3, and C4.
+ *
+ * @param[in] _C1 is the first character of the name
+ * @param[in] _C2 is the second character of the name
+ * @param[in] _C3 is the third character of the name
+ * @param[in] _C4 is the fourth character of the name
+ *
+ * @note This must be implemented as a macro for use in
+ * Configuration Tables. A body is also provided.
+ *
+ */
+#define rtems_build_name( _C1, _C2, _C3, _C4 ) \
+ _Objects_Build_name( _C1, _C2, _C3, _C4 )
+
+/**
+ * @brief Obtain Name of Object
+ *
+ * This directive returns the name associated with the specified
+ * object ID.
+ *
+ * @param[in] id is the Id of the object to obtain the name of.
+ * @param[out] name will be set to the name of the object
+ *
+ * @note The object must be have a name of the 32-bit form.
+ *
+ * @retval @a *name will contain user defined object name
+ * @retval @a RTEMS_SUCCESSFUL - if successful
+ * @retval error code - if unsuccessful
+ */
+rtems_status_code rtems_object_get_classic_name(
+ rtems_id id,
+ rtems_name *name
+);
+
+/**
+ * @brief Obtain Object Name as String
+ *
+ * This directive returns the name associated with the specified
+ * object ID.
+ *
+ * @param[in] id is the Id of the object to obtain the name of
+ * @param[in] length is the length of the output name buffer
+ * @param[out] name will be set to the name of the object
+ *
+ * @retval @a *name will contain user defined object name
+ * @retval @a name - if successful
+ * @retval @a NULL - if unsuccessful
+ */
+char *rtems_object_get_name(
+ rtems_id id,
+ size_t length,
+ char *name
+);
+
+/**
+ * @brief Set Name of Object
+ *
+ * This method allows the caller to set the name of an
+ * object. This can be used to set the name of objects
+ * which do not have a naming scheme per their API.
+ *
+ * RTEMS Object Helper -- Set Name of Object as String
+ *
+ * @param[in] id is the Id of the object to obtain the name of
+ * @param[out] name will be set to the name of the object
+ *
+ * @retval @a *name will contain user defined object name
+ * @retval @a RTEMS_SUCCESSFUL - if successful
+ * @retval error code - if unsuccessful
+ */
+rtems_status_code rtems_object_set_name(
+ rtems_id id,
+ const char *name
+);
+
+/**
+ * @brief Get API Portion of Object Id
+ *
+ * RTEMS Object Helper -- Extract API From Id
+ *
+ * This function returns the API portion of the Id.
+ *
+ * @param[in] _id is the Id of the object to obtain the API from
+ *
+ * @retval This method returns the API portion of the provided
+ * @a _id.
+ *
+ * @note This method does NOT validate the @a _id provided.
+ *
+ * @note A body is also provided.
+ */
+#define rtems_object_id_get_api( _id ) \
+ _Objects_Get_API( _id )
+
+/**
+ * @brief Get Class Portion of Object Id
+ *
+ * This function returns the class portion of the @a _id ID.
+ *
+ * @param[in] _id is the Id of the object to obtain the class from
+ *
+ * @retval This method returns the class portion of the provided
+ * @a _id.
+ *
+ * @note This method does NOT validate the @a _id provided.
+ *
+ * @note A body is also provided.
+ */
+#define rtems_object_id_get_class( _id ) \
+ _Objects_Get_class( _id )
+
+/**
+ * @brief Get Node Portion of Object Id
+ *
+ * This function returns the node portion of the ID.
+ *
+ * @param[in] _id is the Id of the object to obtain the node from
+ *
+ * @retval This method returns the node portion of the provided
+ * @a _id.
+ *
+ * @note This method does NOT validate the @a _id provided.
+ *
+ * @note A body is also provided.
+ */
+#define rtems_object_id_get_node( _id ) \
+ _Objects_Get_node( _id )
+
+/**
+ * @brief Get Index Portion of Object Id
+ *
+ * This function returns the index portion of the ID.
+ *
+ * @param[in] _id is the Id of the object to obtain the index from
+ *
+ * @retval This method returns the index portion of the provided
+ * @a _id.
+ *
+ * @note This method does NOT validate the @a _id provided.
+ *
+ * @note A body is also provided.
+ */
+#define rtems_object_id_get_index( _id ) \
+ _Objects_Get_index( _id )
+
+/**
+ * @brief Get Lowest Valid API Index
+ *
+ * This method returns the lowest valid value for the API
+ * portion of an RTEMS object Id.
+ *
+ * @retval This method returns the least valid value for
+ * the API portion of an RTEMS object Id.
+ *
+ * @note A body is also provided.
+ */
+#define rtems_object_id_api_minimum() \
+ OBJECTS_INTERNAL_API
+
+/**
+ * @brief Get Highest Valid API Index
+ *
+ * This method returns the highest valid value for the API
+ * portion of an RTEMS object Id.
+ *
+ * @retval This method returns the greatest valid value for
+ * the API portion of an RTEMS object Id.
+ *
+ * @note A body is also provided.
+ */
+#define rtems_object_id_api_maximum() \
+ OBJECTS_APIS_LAST
+
+/**
+ * @brief Get Lowest Valid Class Value
+ *
+ * This method returns the lowest valid value Class for the
+ * specified @a api. Each API supports a different number
+ * of object classes.
+ *
+ * @param[in] api is the API to obtain the minimum class of
+ *
+ * @retval This method returns the least valid value for
+ * class number for the specified @a api.
+ * RTEMS Object Helper -- Get Least Valid Class for an API
+ */
+int rtems_object_api_minimum_class(
+ int api
+);
+
+/**
+ * @brief Get Highest Valid Class Value
+ *
+ * This method returns the highest valid value Class for the
+ * specified @a api. Each API supports a different number
+ * of object classes.
+ *
+ * @param[in] api is the API to obtain the maximum class of
+ *
+ * @retval This method returns the greatet valid value for
+ * class number for the specified @a api.
+ */
+int rtems_object_api_maximum_class(
+ int api
+);
+
+
+/**
+ * @brief Get Highest Valid Class Value
+ *
+ * This method returns the lowest valid value Class for the
+ * specified @a api. Each API supports a different number
+ * of object classes.
+ *
+ * @param[in] api is the API to obtain the maximum class of
+ *
+ * @retval This method returns the least valid value for
+ * class number for the specified @a api.
+ */
+int rtems_object_id_api_maximum_class(
+ int api
+);
+
+/**
+ * @brief Get API Name
+ *
+ * This method returns a string containing the name of the
+ * specified @a api.
+ *
+ * @param[in] api is the API to obtain the name of
+ *
+ * @retval If successful, this method returns the name of
+ * the specified @a api. Otherwise, it returns
+ * the string "BAD API"
+ */
+const char *rtems_object_get_api_name(
+ int api
+);
+
+/**
+ * @brief Get Class Name
+ *
+ * This method returns a string containing the name of the
+ * @a class from the specified @a api.
+ *
+ * @param[in] the_api is the API for the class
+ * @param[in] the_class is the class to obtain the name of
+ *
+ * @retval If successful, this method returns the name of
+ * the specified @a class. Otherwise, it returns
+ * the string "BAD CLASS"
+ */
+const char *rtems_object_get_api_class_name(
+ int the_api,
+ int the_class
+);
+
+/**
+ * @brief Get Class Information
+ *
+ * This method returns a string containing the name of the
+ * @a the_class from the specified @a api.
+ *
+ * @param[in] the_api is the API for the class
+ * @param[in] the_class is the class to obtain information about
+ * @param[in] info points to the information structure to fill in
+ *
+ * @retval If successful, this method returns the name of
+ * RTEMS_SUCCESSFUL with @a *info filled in. Otherwise,
+ * a status is returned to indicate the error.
+ *
+ */
+rtems_status_code rtems_object_get_class_information(
+ int the_api,
+ int the_class,
+ rtems_object_api_class_information *info
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/options.h b/cpukit/include/rtems/rtems/options.h
new file mode 100644
index 0000000000..752aefda2e
--- /dev/null
+++ b/cpukit/include/rtems/rtems/options.h
@@ -0,0 +1,83 @@
+/**
+ * @file rtems/rtems/options.h
+ *
+ * @defgroup ClassicOptions Classic API Options
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Options Available on Many Directives
+ *
+ * This include file contains information which defines the
+ * options available on many directives.
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_OPTIONS_H
+#define _RTEMS_RTEMS_OPTIONS_H
+
+#include <rtems/score/basedefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicOptions Classic API Options
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality related to the options argument
+ * to Classic API blocking operations. The primary option is whether
+ * or not a task is willing to wait for the operation to complete.
+ */
+/**@{*/
+
+/**
+ * The following type defines the control block used to manage
+ * option sets.
+ */
+typedef uint32_t rtems_option;
+
+/**
+ * The following constants define the individual options which may
+ * be used to compose an option set.
+ */
+#define RTEMS_DEFAULT_OPTIONS 0x00000000
+
+/**
+ * This option constants indicates that the task is to wait on resource.
+ */
+#define RTEMS_WAIT 0x00000000
+/**
+ * This option constants indicates that the task is to not wait on
+ * the resource. If it is not available, return immediately with
+ * a status to indicate unsatisfied.
+ */
+#define RTEMS_NO_WAIT 0x00000001
+
+/**
+ * This option constants indicates that the task wishes to wait until
+ * all events of interest are available.
+ */
+#define RTEMS_EVENT_ALL 0x00000000
+
+/**
+ * This option constants indicates that the task wishes to wait until
+ * ANY events of interest are available.
+ */
+#define RTEMS_EVENT_ANY 0x00000002
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/optionsimpl.h b/cpukit/include/rtems/rtems/optionsimpl.h
new file mode 100644
index 0000000000..0263fcf78d
--- /dev/null
+++ b/cpukit/include/rtems/rtems/optionsimpl.h
@@ -0,0 +1,67 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicOptionsImpl
+ *
+ * @brief Classic Options Implementation
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_OPTIONSIMPL_H
+#define _RTEMS_RTEMS_OPTIONSIMPL_H
+
+#include <rtems/rtems/options.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicOptionsImpl Classic Options Implementation
+ *
+ * @ingroup ClassicOptions
+ *
+ * @{
+ */
+
+/**
+ * @brief Checks if the RTEMS_NO_WAIT option is enabled in option_set.
+ *
+ * This function returns TRUE if the RTEMS_NO_WAIT option is enabled in
+ * option_set, and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Options_Is_no_wait (
+ rtems_option option_set
+)
+{
+ return (option_set & RTEMS_NO_WAIT) ? true : false;
+}
+
+/**
+ * @brief Checks if the RTEMS_EVENT_ANY option is enabled in OPTION_SET.
+ *
+ * This function returns TRUE if the RTEMS_EVENT_ANY option is enabled in
+ * OPTION_SET, and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Options_Is_any (
+ rtems_option option_set
+)
+{
+ return (option_set & RTEMS_EVENT_ANY) ? true : false;
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/part.h b/cpukit/include/rtems/rtems/part.h
new file mode 100644
index 0000000000..5b840cc96c
--- /dev/null
+++ b/cpukit/include/rtems/rtems/part.h
@@ -0,0 +1,174 @@
+/**
+ * @file rtems/rtems/part.h
+ *
+ * @defgroup ClassicPart Partitions
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Partition Manager
+ *
+ * This include file contains all the constants and structures associated
+ * with the Partition Manager. This manager provides facilities to
+ * dynamically allocate memory in fixed-sized units which are returned
+ * as buffers.
+ *
+ * Directives provided are:
+ *
+ * - create a partition
+ * - get an ID of a partition
+ * - delete a partition
+ * - get a buffer from a partition
+ * - return a buffer to a partition
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_PART_H
+#define _RTEMS_RTEMS_PART_H
+
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/types.h>
+#include <rtems/score/isrlock.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicPart Partitions
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality related to the
+ * Classic API Partition Manager.
+ */
+/**@{*/
+
+/**
+ * The following defines the control block used to manage each partition.
+ */
+typedef struct {
+ /** This field is the object management portion of a Partition instance. */
+ Objects_Control Object;
+ /** This field is the lock of the Partition. */
+ ISR_LOCK_MEMBER( Lock )
+ /** This field is the physical starting address of the Partition. */
+ void *starting_address;
+ /** This field is the size of the Partition in bytes. */
+ intptr_t length;
+ /** This field is the size of each buffer in bytes */
+ uint32_t buffer_size;
+ /** This field is the attribute set provided at create time. */
+ rtems_attribute attribute_set;
+ /** This field is the of allocated buffers. */
+ uint32_t number_of_used_blocks;
+ /** This field is the chain used to manage unallocated buffers. */
+ Chain_Control Memory;
+} Partition_Control;
+
+/**
+ * @brief RTEMS Partition Create
+ *
+ * Partition Manager
+ *
+ * This routine implements the rtems_partition_create directive. The
+ * partition will have the name name. The memory area managed by
+ * the partition is of length bytes and starts at starting_address.
+ * The memory area will be divided into as many buffers of
+ * buffer_size bytes as possible. The attribute_set determines if
+ * the partition is global or local. It returns the id of the
+ * created partition in ID.
+ */
+rtems_status_code rtems_partition_create(
+ rtems_name name,
+ void *starting_address,
+ uint32_t length,
+ uint32_t buffer_size,
+ rtems_attribute attribute_set,
+ rtems_id *id
+);
+
+/**
+ * @brief RTEMS Partition Ident
+ *
+ * This routine implements the rtems_partition_ident directive.
+ * This directive returns the partition ID associated with name.
+ * If more than one partition is named name, then the partition
+ * to which the ID belongs is arbitrary. node indicates the
+ * extent of the search for the ID of the partition named name.
+ * The search can be limited to a particular node or allowed to
+ * encompass all nodes.
+ *
+ * @param[in] name is the user defined partition name
+ * @param[in] node is(are) the node(s) to be searched
+ * @param[in] id is the pointer to partition id
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful and
+ * *id filled in with the partition id
+ */
+rtems_status_code rtems_partition_ident(
+ rtems_name name,
+ uint32_t node,
+ rtems_id *id
+);
+
+/**
+ * @brief RTEMS Delete Partition
+ *
+ * This routine implements the rtems_partition_delete directive. The
+ * partition indicated by ID is deleted, provided that none of its buffers
+ * are still allocated.
+ *
+ * @param[in] id is the partition id
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_partition_delete(
+ rtems_id id
+);
+
+/**
+ * @brief RTEMS Get Partition Buffer
+ *
+ * This routine implements the rtems_partition_get_buffer directive. It
+ * attempts to allocate a buffer from the partition associated with ID.
+ * If a buffer is allocated, its address is returned in buffer.
+ *
+ * @param[in] id is the partition id
+ * @param[out] buffer is the pointer to buffer address
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
+ */
+rtems_status_code rtems_partition_get_buffer(
+ rtems_id id,
+ void **buffer
+);
+
+/**
+ * @brief rtems_partition_return_buffer
+ *
+ * This routine implements the rtems_partition_return_buffer directive. It
+ * frees the buffer to the partition associated with ID. The buffer must
+ * have been previously allocated from the same partition.
+ */
+rtems_status_code rtems_partition_return_buffer(
+ rtems_id id,
+ void *buffer
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/partimpl.h b/cpukit/include/rtems/rtems/partimpl.h
new file mode 100644
index 0000000000..13ee86b4c2
--- /dev/null
+++ b/cpukit/include/rtems/rtems/partimpl.h
@@ -0,0 +1,223 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicPartImpl
+ *
+ * @brief Classic Partition Manager Implementation
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_PARTIMPL_H
+#define _RTEMS_RTEMS_PARTIMPL_H
+
+#include <rtems/rtems/part.h>
+#include <rtems/score/chainimpl.h>
+#include <rtems/score/objectimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicPartImpl Classic Partition Manager Implementation
+ *
+ * @ingroup ClassicPart
+ *
+ * @{
+ */
+
+/**
+ * The following defines the information control block used to
+ * manage this class of objects.
+ */
+extern Objects_Information _Partition_Information;
+
+/**
+ * @brief Allocate a buffer from the_partition.
+ *
+ * This function attempts to allocate a buffer from the_partition.
+ * If successful, it returns the address of the allocated buffer.
+ * Otherwise, it returns NULL.
+ */
+RTEMS_INLINE_ROUTINE void *_Partition_Allocate_buffer (
+ Partition_Control *the_partition
+)
+{
+ return _Chain_Get_unprotected( &the_partition->Memory );
+}
+
+/**
+ * @brief Frees the_buffer to the_partition.
+ *
+ * This routine frees the_buffer to the_partition.
+ */
+RTEMS_INLINE_ROUTINE void _Partition_Free_buffer (
+ Partition_Control *the_partition,
+ Chain_Node *the_buffer
+)
+{
+ _Chain_Append_unprotected( &the_partition->Memory, the_buffer );
+}
+
+/**
+ * @brief Checks whether is on a valid buffer boundary for the_partition.
+ *
+ * This function returns TRUE if the_buffer is on a valid buffer
+ * boundary for the_partition, and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Partition_Is_buffer_on_boundary (
+ void *the_buffer,
+ Partition_Control *the_partition
+)
+{
+ uint32_t offset;
+
+ offset = (uint32_t) _Addresses_Subtract(
+ the_buffer,
+ the_partition->starting_address
+ );
+
+ return ((offset % the_partition->buffer_size) == 0);
+}
+
+/**
+ * @brief Checks whether the_buffer is a valid buffer from the_partition.
+ *
+ * This function returns TRUE if the_buffer is a valid buffer from
+ * the_partition, otherwise FALSE is returned.
+ */
+RTEMS_INLINE_ROUTINE bool _Partition_Is_buffer_valid (
+ Chain_Node *the_buffer,
+ Partition_Control *the_partition
+)
+{
+ void *starting;
+ void *ending;
+
+ starting = the_partition->starting_address;
+ ending = _Addresses_Add_offset( starting, the_partition->length );
+
+ return (
+ _Addresses_Is_in_range( the_buffer, starting, ending ) &&
+ _Partition_Is_buffer_on_boundary( the_buffer, the_partition )
+ );
+}
+
+/**
+ * @brief Checks if partition is buffer size aligned.
+ *
+ * This function returns TRUE if the use of the specified buffer_size
+ * will result in the allocation of buffers whose first byte is
+ * properly aligned, and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Partition_Is_buffer_size_aligned (
+ uint32_t buffer_size
+)
+{
+ return ((buffer_size % CPU_PARTITION_ALIGNMENT) == 0);
+}
+
+/**
+ * @brief Allocates a partition control block from the
+ * inactive chain of free partition control blocks.
+ *
+ * This function allocates a partition control block from
+ * the inactive chain of free partition control blocks.
+ */
+RTEMS_INLINE_ROUTINE Partition_Control *_Partition_Allocate ( void )
+{
+ return (Partition_Control *) _Objects_Allocate( &_Partition_Information );
+}
+
+RTEMS_INLINE_ROUTINE void _Partition_Initialize(
+ Partition_Control *the_partition,
+ void *starting_address,
+ uint32_t length,
+ uint32_t buffer_size,
+ rtems_attribute attribute_set
+)
+{
+ the_partition->starting_address = starting_address;
+ the_partition->length = length;
+ the_partition->buffer_size = buffer_size;
+ the_partition->attribute_set = attribute_set;
+ the_partition->number_of_used_blocks = 0;
+
+ _Chain_Initialize(
+ &the_partition->Memory,
+ starting_address,
+ length / buffer_size,
+ buffer_size
+ );
+
+ _ISR_lock_Initialize( &the_partition->Lock, "Partition" );
+}
+
+RTEMS_INLINE_ROUTINE void _Partition_Destroy(
+ Partition_Control *the_partition
+)
+{
+ _ISR_lock_Destroy( &the_partition->Lock );
+}
+
+/**
+ * @brief Frees a partition control block to the
+ * inactive chain of free partition control blocks.
+ *
+ * This routine frees a partition control block to the
+ * inactive chain of free partition control blocks.
+ */
+RTEMS_INLINE_ROUTINE void _Partition_Free (
+ Partition_Control *the_partition
+)
+{
+ _Objects_Free( &_Partition_Information, &the_partition->Object );
+}
+
+RTEMS_INLINE_ROUTINE Partition_Control *_Partition_Get(
+ Objects_Id id,
+ ISR_lock_Context *lock_context
+)
+{
+ return (Partition_Control *) _Objects_Get(
+ id,
+ lock_context,
+ &_Partition_Information
+ );
+}
+
+RTEMS_INLINE_ROUTINE void _Partition_Acquire_critical(
+ Partition_Control *the_partition,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Acquire( &the_partition->Lock, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Partition_Release(
+ Partition_Control *the_partition,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Release_and_ISR_enable( &the_partition->Lock, lock_context );
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/rtems/partmp.h>
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/partmp.h b/cpukit/include/rtems/rtems/partmp.h
new file mode 100644
index 0000000000..b9eaa08b8c
--- /dev/null
+++ b/cpukit/include/rtems/rtems/partmp.h
@@ -0,0 +1,144 @@
+/**
+ * @file rtems/rtems/partmp.h
+ *
+ * @brief MP Support in Partition Manager
+ *
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Support in the Partition Manager.
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_PARTMP_H
+#define _RTEMS_RTEMS_PARTMP_H
+
+#ifndef _RTEMS_RTEMS_PARTIMPL_H
+# error "Never use <rtems/rtems/partmp.h> directly; include <rtems/rtems/partimpl.h> instead."
+#endif
+
+#include <rtems/score/mpciimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicPartMP Partition MP Support
+ *
+ * @ingroup ClassicMP
+ *
+ * This encapsulates functionality related to the transparent multiprocessing
+ * support within the Classic API Partition Manager.
+ */
+/*{*/
+
+/**
+ * The following enumerated type defines the list of
+ * remote partition operations.
+ */
+typedef enum {
+ PARTITION_MP_ANNOUNCE_CREATE = 0,
+ PARTITION_MP_ANNOUNCE_DELETE = 1,
+ PARTITION_MP_EXTRACT_PROXY = 2,
+ PARTITION_MP_GET_BUFFER_REQUEST = 3,
+ PARTITION_MP_GET_BUFFER_RESPONSE = 4,
+ PARTITION_MP_RETURN_BUFFER_REQUEST = 5,
+ PARTITION_MP_RETURN_BUFFER_RESPONSE = 6
+} Partition_MP_Remote_operations;
+
+/**
+ * The following data structure defines the packet used to perform
+ * remote partition operations.
+ */
+typedef struct {
+ rtems_packet_prefix Prefix;
+ Partition_MP_Remote_operations operation;
+ rtems_name name;
+ void *buffer;
+ Objects_Id proxy_id;
+} Partition_MP_Packet;
+
+RTEMS_INLINE_ROUTINE bool _Partition_MP_Is_remote( Objects_Id id )
+{
+ return _Objects_MP_Is_remote( id, &_Partition_Information );
+}
+
+/**
+ * @brief Partition_MP_Send_process_packet
+ *
+ * Multiprocessing Support for the Partition Manager
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ */
+void _Partition_MP_Send_process_packet (
+ Partition_MP_Remote_operations operation,
+ Objects_Id partition_id,
+ rtems_name name,
+ Objects_Id proxy_id
+);
+
+/**
+ * @brief Issues a remote rtems_partition_get_buffer() request.
+ */
+rtems_status_code _Partition_MP_Get_buffer(
+ rtems_id id,
+ void **buffer
+);
+
+/**
+ * @brief Issues a remote rtems_partition_return_buffer() request.
+ */
+rtems_status_code _Partition_MP_Return_buffer(
+ rtems_id id,
+ void *buffer
+);
+
+/**
+ *
+ * @brief Partition_MP_Process_packet
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+void _Partition_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+);
+
+/*
+ * @brief Partition_MP_Send_object_was_deleted
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed by the Partition since a partition
+ * cannot be deleted when buffers are in use.
+ */
+
+/**
+ * @brief Partition_MP_Send_extract_proxy
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ */
+void _Partition_MP_Send_extract_proxy (
+ Thread_Control *the_thread,
+ Objects_Id id
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of file */
diff --git a/cpukit/include/rtems/rtems/ratemon.h b/cpukit/include/rtems/rtems/ratemon.h
new file mode 100644
index 0000000000..ca48a92983
--- /dev/null
+++ b/cpukit/include/rtems/rtems/ratemon.h
@@ -0,0 +1,430 @@
+/**
+ * @file rtems/rtems/ratemon.h
+ *
+ * @defgroup ClassicRateMon Rate Monotonic Scheduler
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Classic API Rate Monotonic Manager.
+ *
+ * This include file contains all the constants, structures, and
+ * prototypes associated with the Rate Monotonic Manager. This manager
+ * provides facilities to implement threads which execute in a periodic
+ * fashion.
+ *
+ * Directives provided are:
+ *
+ * - create a rate monotonic timer
+ * - cancel a period
+ * - delete a rate monotonic timer
+ * - conclude current and start the next period
+ * - obtain status information on a period
+ * - obtain the number of postponed jobs
+ */
+
+/* COPYRIGHT (c) 1989-2009, 2016.
+ * On-Line Applications Research Corporation (OAR).
+ * COPYRIGHT (c) 2016-2017 Kuan-Hsun Chen.
+ *
+ * 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_RTEMS_RATEMON_H
+#define _RTEMS_RTEMS_RATEMON_H
+
+#include <rtems/rtems/types.h>
+#include <rtems/rtems/status.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdog.h>
+
+struct rtems_printer;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicRateMon Rate Monotonic Scheduler
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality related to the Classic API Rate
+ * Monotonic Manager.
+ *
+ * Statistics are kept for each period and can be obtained or printed via
+ * API calls. The statistics kept include minimum, maximum and average times
+ * for both cpu usage and wall time. The statistics indicate the execution
+ * and wall time used by the owning thread between successive calls to
+ * rtems_rate_monotonic_period.
+ */
+/**@{*/
+
+/**
+ * This is the public type used for the rate monotonic timing
+ * statistics.
+ */
+#include <rtems/score/timespec.h>
+
+typedef struct timespec rtems_rate_monotonic_period_time_t;
+
+/**
+ * This is the internal type used for the rate monotonic timing
+ * statistics.
+ */
+#include <rtems/score/timestamp.h>
+
+/**
+ * The following enumerated type defines the states in which a
+ * period may be.
+ */
+typedef enum {
+ /**
+ * This value indicates the period is off the watchdog chain,
+ * and has never been initialized.
+ */
+ RATE_MONOTONIC_INACTIVE,
+
+ /**
+ * This value indicates the period is on the watchdog chain, and
+ * running. The owner should be executed or blocked waiting on
+ * another object.
+ */
+ RATE_MONOTONIC_ACTIVE,
+
+ /**
+ * This value indicates the period is off the watchdog chain, and
+ * has expired. The owner is still executing and has taken too much
+ * all time to complete this iteration of the period.
+ */
+ RATE_MONOTONIC_EXPIRED
+} rtems_rate_monotonic_period_states;
+
+/**
+ * The following constant is the interval passed to the rate_monontonic_period
+ * directive to obtain status information.
+ */
+#define RTEMS_PERIOD_STATUS WATCHDOG_NO_TIMEOUT
+
+/**
+ * The following defines the PUBLIC data structure that has the
+ * statistics kept on each period instance.
+ *
+ * @note The public structure uses struct timespec while the
+ * internal one uses Timestamp_Control.
+ */
+typedef struct {
+ /** This field contains the number of periods executed. */
+ uint32_t count;
+ /** This field contains the number of periods missed. */
+ uint32_t missed_count;
+
+ /** This field contains the least amount of CPU time used in a period. */
+ rtems_thread_cpu_usage_t min_cpu_time;
+ /** This field contains the highest amount of CPU time used in a period. */
+ rtems_thread_cpu_usage_t max_cpu_time;
+ /** This field contains the total amount of wall time used in a period. */
+ rtems_thread_cpu_usage_t total_cpu_time;
+
+ /** This field contains the least amount of wall time used in a period. */
+ rtems_rate_monotonic_period_time_t min_wall_time;
+ /** This field contains the highest amount of wall time used in a period. */
+ rtems_rate_monotonic_period_time_t max_wall_time;
+ /** This field contains the total amount of CPU time used in a period. */
+ rtems_rate_monotonic_period_time_t total_wall_time;
+} rtems_rate_monotonic_period_statistics;
+
+/**
+ * The following defines the INTERNAL data structure that has the
+ * statistics kept on each period instance.
+ */
+typedef struct {
+ /** This field contains the number of periods executed. */
+ uint32_t count;
+ /** This field contains the number of periods missed. */
+ uint32_t missed_count;
+
+ /** This field contains the least amount of CPU time used in a period. */
+ Timestamp_Control min_cpu_time;
+ /** This field contains the highest amount of CPU time used in a period. */
+ Timestamp_Control max_cpu_time;
+ /** This field contains the total amount of wall time used in a period. */
+ Timestamp_Control total_cpu_time;
+
+ /** This field contains the least amount of wall time used in a period. */
+ Timestamp_Control min_wall_time;
+ /** This field contains the highest amount of wall time used in a period. */
+ Timestamp_Control max_wall_time;
+ /** This field contains the total amount of CPU time used in a period. */
+ Timestamp_Control total_wall_time;
+} Rate_monotonic_Statistics;
+
+/**
+ * The following defines the period status structure.
+ */
+typedef struct {
+ /** This is the Id of the thread using this period. */
+ rtems_id owner;
+
+ /** This is the current state of this period. */
+ rtems_rate_monotonic_period_states state;
+
+ /**
+ * This is the length of wall time that has passed since this period
+ * was last initiated. If the period is expired or has not been initiated,
+ * then this field has no meaning.
+ */
+ rtems_rate_monotonic_period_time_t since_last_period;
+
+ /**
+ * This is the amount of CPU time that has been used since this period
+ * was last initiated. If the period is expired or has not been initiated,
+ * then this field has no meaning.
+ */
+ rtems_thread_cpu_usage_t executed_since_last_period;
+
+ /** This is the count of postponed jobs of this period. */
+ uint32_t postponed_jobs_count;
+} rtems_rate_monotonic_period_status;
+
+/**
+ * @brief The following structure defines the control block used to manage each
+ * period.
+ *
+ * State changes are protected by the default thread lock of the owner thread.
+ * The owner thread is the thread that created the period object. The owner
+ * thread field is immutable after object creation.
+ */
+typedef struct {
+ /** This field is the object management portion of a Period instance. */
+ Objects_Control Object;
+
+ /**
+ * @brief Protects the rate monotonic period state.
+ */
+ ISR_LOCK_MEMBER( Lock )
+
+ /** This is the timer used to provide the unblocking mechanism. */
+ Watchdog_Control Timer;
+
+ /** This field indicates the current state of the period. */
+ rtems_rate_monotonic_period_states state;
+
+ /**
+ * @brief A priority node for use by the scheduler job release and cancel
+ * operations.
+ */
+ Priority_Node Priority;
+
+ /**
+ * This field contains the length of the next period to be
+ * executed.
+ */
+ uint32_t next_length;
+
+ /**
+ * This field contains a pointer to the TCB for the thread
+ * which owns and uses this period instance.
+ */
+ Thread_Control *owner;
+
+ /**
+ * This field contains the cpu usage value of the owning thread when
+ * the period was initiated. It is used to compute the period's
+ * statistics.
+ */
+ Timestamp_Control cpu_usage_period_initiated;
+
+ /**
+ * This field contains the wall time value when the period
+ * was initiated. It is used to compute the period's statistics.
+ */
+ Timestamp_Control time_period_initiated;
+
+ /**
+ * This field contains the statistics maintained for the period.
+ */
+ Rate_monotonic_Statistics Statistics;
+
+ /**
+ * This field contains the number of postponed jobs.
+ * When the watchdog timeout, this variable will be increased immediately.
+ */
+ uint32_t postponed_jobs;
+
+ /**
+ * This field contains the tick of the latest deadline decided by the period
+ * watchdog.
+ */
+ uint64_t latest_deadline;
+} Rate_monotonic_Control;
+
+/**
+ * @brief Create a Period
+ *
+ * Rate Monotonic Manager
+ *
+ * This routine implements the rate_monotonic_create directive. The
+ * period will have the name name. It returns the id of the
+ * created period in ID.
+ */
+rtems_status_code rtems_rate_monotonic_create(
+ rtems_name name,
+ rtems_id *id
+);
+
+/**
+ * @brief RTEMS Rate Monotonic Name to Id
+ *
+ * This routine implements the rtems_rate_monotonic_ident directive.
+ * It returns the period ID associated with name. If more than one period
+ * is named name, then the period to which the ID belongs is arbitrary.
+ *
+ * @param[in] name is the user defined period name
+ * @param[in] id is the pointer to period id
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error. If successful, the id will
+ * be filled in with the region id.
+ */
+rtems_status_code rtems_rate_monotonic_ident(
+ rtems_name name,
+ rtems_id *id
+);
+
+/**
+ * @brief RTEMS Rate Monotonic Cancel
+ *
+ * This routine implements the rtems_rate_monotonic_cancel directive. This
+ * directive stops the period associated with ID from continuing to
+ * run.
+ *
+ * @param[in] id is the rate monotonic id
+ *
+ * @retval RTEMS_SUCCESSFUL if successful and caller is not the owning thread
+ * or error code if unsuccessful
+ *
+ */
+rtems_status_code rtems_rate_monotonic_cancel(
+ rtems_id id
+);
+
+/**
+ * @brief RTEMS Delete Rate Monotonic
+ *
+ * This routine implements the rtems_rate_monotonic_delete directive. The
+ * period indicated by ID is deleted.
+ *
+ * @param[in] id is the rate monotonic id
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_rate_monotonic_delete(
+ rtems_id id
+);
+
+/**
+ * @brief RTEMS Rate Monotonic Get Status
+ *
+ * This routine implements the rtems_rate_monotonic_get_status directive.
+ * Information about the period indicated by ID is returned.
+ *
+ * @param[in] id is the rate monotonic id
+ * @param[in] status is the pointer to status control block
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ *
+ */
+rtems_status_code rtems_rate_monotonic_get_status(
+ rtems_id id,
+ rtems_rate_monotonic_period_status *status
+);
+
+/**
+ * @brief RTEMS Rate Monotonic Get Statistics
+ *
+ * This routine implements the rtems_rate_monotonic_get_statistics directive.
+ * Statistics gathered from the use of this period are returned.
+ *
+ * @param[in] id is the rate monotonic id
+ * @param[in] statistics is the pointer to statistics control block
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
+ */
+rtems_status_code rtems_rate_monotonic_get_statistics(
+ rtems_id id,
+ rtems_rate_monotonic_period_statistics *statistics
+);
+
+/**
+ * @brief RTEMS Rate Monotonic Reset Statistics
+ *
+ * Rate Monotonic Manager -- Reset Statistics
+ *
+ * This routine allows a thread to reset the statistics information
+ * on a specific period instance.
+ */
+rtems_status_code rtems_rate_monotonic_reset_statistics(
+ rtems_id id
+);
+
+/**
+ * @brief rtems_rate_monotonic_reset_all_statistics
+ *
+ * This routine allows a thread to reset the statistics information
+ * on ALL period instances.
+ */
+void rtems_rate_monotonic_reset_all_statistics( void );
+
+/**
+ * @brief RTEMS Report Rate Monotonic Statistics
+ *
+ * This routine allows a thread to print the statistics information
+ * on ALL period instances which have non-zero counts using the RTEMS
+ * printer. The implementation of this directive straddles the fence
+ * between inside and outside of RTEMS. It is presented as part of
+ * the Manager but actually uses other services of the Manager.
+ */
+void rtems_rate_monotonic_report_statistics_with_plugin(
+ const struct rtems_printer *printer
+);
+
+/**
+ * @brief RTEMS Report Rate Monotonic Statistics
+ *
+ * This routine allows a thread to print the statistics information
+ * on ALL period instances which have non-zero counts using printk.
+ */
+void rtems_rate_monotonic_report_statistics( void );
+
+/**
+ * @brief RTEMS Rate Monotonic Period
+ *
+ * This routine implements the rtems_rate_monotonic_period directive. When
+ * length is non-zero, this directive initiates the period associated with
+ * ID from continuing for a period of length. If length is zero, then
+ * result is set to indicate the current state of the period.
+ *
+ * @param[in] id is the rate monotonic id
+ * @param[in] length is the length of period (in ticks)
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
+ */
+rtems_status_code rtems_rate_monotonic_period(
+ rtems_id id,
+ rtems_interval length
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/ratemonimpl.h b/cpukit/include/rtems/rtems/ratemonimpl.h
new file mode 100644
index 0000000000..ba38a3e61a
--- /dev/null
+++ b/cpukit/include/rtems/rtems/ratemonimpl.h
@@ -0,0 +1,158 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicRateMonImpl
+ *
+ * @brief Classic Rate Monotonic Scheduler Implementation
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright (c) 2016 embedded brains GmbH.
+ * COPYRIGHT (c) 2016 Kuan-Hsun Chen.
+ *
+ * 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_RTEMS_RATEMONIMPL_H
+#define _RTEMS_RTEMS_RATEMONIMPL_H
+
+#include <rtems/rtems/ratemon.h>
+#include <rtems/score/objectimpl.h>
+#include <rtems/score/schedulerimpl.h>
+#include <rtems/score/threadimpl.h>
+#include <rtems/score/watchdogimpl.h>
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicRateMonImpl Classic Rate Monotonic Scheduler Implementation
+ *
+ * @ingroup ClassicRateMon
+ *
+ * @{
+ */
+
+#define RATE_MONOTONIC_INTEND_TO_BLOCK \
+ ( THREAD_WAIT_CLASS_PERIOD | THREAD_WAIT_STATE_INTEND_TO_BLOCK )
+
+#define RATE_MONOTONIC_BLOCKED \
+ ( THREAD_WAIT_CLASS_PERIOD | THREAD_WAIT_STATE_BLOCKED )
+
+#define RATE_MONOTONIC_READY_AGAIN \
+ ( THREAD_WAIT_CLASS_PERIOD | THREAD_WAIT_STATE_READY_AGAIN )
+
+/**
+ * @brief Rate Monotonic Period Class Management Structure
+ *
+ * This instance of Objects_Information is used to manage the
+ * set of rate monotonic period instances.
+ */
+extern Objects_Information _Rate_monotonic_Information;
+
+/**
+ * @brief Allocates a period control block from
+ * the inactive chain of free period control blocks.
+ *
+ * This function allocates a period control block from
+ * the inactive chain of free period control blocks.
+ */
+RTEMS_INLINE_ROUTINE Rate_monotonic_Control *_Rate_monotonic_Allocate( void )
+{
+ return (Rate_monotonic_Control *)
+ _Objects_Allocate( &_Rate_monotonic_Information );
+}
+
+RTEMS_INLINE_ROUTINE void _Rate_monotonic_Acquire_critical(
+ Rate_monotonic_Control *the_period,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Acquire( &the_period->Lock, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Rate_monotonic_Release(
+ Rate_monotonic_Control *the_period,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Release_and_ISR_enable( &the_period->Lock, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE Rate_monotonic_Control *_Rate_monotonic_Get(
+ Objects_Id id,
+ ISR_lock_Context *lock_context
+)
+{
+ return (Rate_monotonic_Control *)
+ _Objects_Get( id, lock_context, &_Rate_monotonic_Information );
+}
+
+void _Rate_monotonic_Timeout( Watchdog_Control *watchdog );
+
+/**
+ * @brief _Rate_monotonic_Get_status(
+ *
+ * This routine is invoked to compute the elapsed wall time and cpu
+ * time for a period.
+ *
+ * @param[in] the_period points to the period being operated upon.
+ * @param[out] wall_since_last_period is set to the wall time elapsed
+ * since the period was initiated.
+ * @param[out] cpu_since_last_period is set to the cpu time used by the
+ * owning thread since the period was initiated.
+ *
+ * @retval This routine returns true if the status can be determined
+ * and false otherwise.
+ */
+bool _Rate_monotonic_Get_status(
+ const Rate_monotonic_Control *the_period,
+ Timestamp_Control *wall_since_last_period,
+ Timestamp_Control *cpu_since_last_period
+);
+
+void _Rate_monotonic_Restart(
+ Rate_monotonic_Control *the_period,
+ Thread_Control *owner,
+ ISR_lock_Context *lock_context
+);
+
+void _Rate_monotonic_Cancel(
+ Rate_monotonic_Control *the_period,
+ Thread_Control *owner,
+ ISR_lock_Context *lock_context
+);
+
+RTEMS_INLINE_ROUTINE void _Rate_monotonic_Reset_min_time(
+ Timestamp_Control *min_time
+)
+{
+ _Timestamp_Set( min_time, 0x7fffffff, 0x7fffffff );
+}
+
+RTEMS_INLINE_ROUTINE void _Rate_monotonic_Reset_statistics(
+ Rate_monotonic_Control *the_period
+)
+{
+ Rate_monotonic_Statistics *statistics;
+
+ statistics = &the_period->Statistics;
+ memset( statistics, 0, sizeof( *statistics ) );
+ _Rate_monotonic_Reset_min_time( &statistics->min_wall_time );
+ _Rate_monotonic_Reset_min_time( &statistics->min_cpu_time );
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/region.h b/cpukit/include/rtems/rtems/region.h
new file mode 100644
index 0000000000..4772e2835b
--- /dev/null
+++ b/cpukit/include/rtems/rtems/region.h
@@ -0,0 +1,298 @@
+/**
+ * @file rtems/rtems/region.h
+ *
+ * @defgroup ClassicRegion Regions
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Region Manager
+ *
+ * This include file contains all the constants and structures associated
+ * with the Region Manager. This manager provides facilities to dynamically
+ * allocate memory in variable sized units which are returned as segments.
+ *
+ * Directives provided are:
+ *
+ * - create a region
+ * - get an ID of a region
+ * - delete a region
+ * - get a segment from a region
+ * - return a segment to a region
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_REGION_H
+#define _RTEMS_RTEMS_REGION_H
+
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/types.h>
+#include <rtems/score/heap.h>
+#include <rtems/score/threadq.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicRegion Regions
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality related to the Classic API Region
+ * Manager.
+ */
+/**@{*/
+
+/**
+ * The following records define the control block used to manage
+ * each region.
+ */
+
+typedef struct {
+ Objects_Control Object;
+ Thread_queue_Control Wait_queue; /* waiting threads */
+ const Thread_queue_Operations *wait_operations;
+ uintptr_t maximum_segment_size; /* in bytes */
+ rtems_attribute attribute_set;
+ Heap_Control Memory;
+} Region_Control;
+
+/**
+ * @brief rtems_region_create
+ *
+ * Region Manager
+ *
+ * This routine implements the rtems_region_create directive. The
+ * region will have the name name. The memory area managed by
+ * the region is of length bytes and starts at starting_address.
+ * The memory area will be divided into as many allocatable units of
+ * page_size bytes as possible. The attribute_set determines which
+ * thread queue discipline is used by the region. It returns the
+ * id of the created region in ID.
+ */
+rtems_status_code rtems_region_create(
+ rtems_name name,
+ void *starting_address,
+ uintptr_t length,
+ uintptr_t page_size,
+ rtems_attribute attribute_set,
+ rtems_id *id
+);
+
+/**
+ * @brief RTEMS Extend Region
+ *
+ * This routine implements the rtems_region_extend directive. The
+ * region will have the name name. The memory area managed by
+ * the region will be attempted to be grown by length bytes using
+ * the memory starting at starting_address.
+ *
+ * @param[in] id is the id of region to grow
+ * @param[in] starting_address starting address of memory area for extension
+ * @param[in] length is the physical length in bytes to grow the region
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_region_extend(
+ rtems_id id,
+ void *starting_address,
+ uintptr_t length
+);
+
+/**
+ * @brief RTEMS Region Name to Id
+ *
+ * This routine implements the rtems_region_ident directive.
+ * This directive returns the region ID associated with name.
+ * If more than one region is named name, then the region
+ * to which the ID belongs is arbitrary.
+ *
+ * @param[in] name is the user defined region name
+ * @param[in] id is the pointer to region id
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error. If successful, the id will
+ * be filled in with the region id.
+ */
+rtems_status_code rtems_region_ident(
+ rtems_name name,
+ rtems_id *id
+);
+
+/**
+ * @brief RTEMS Get Region Information
+ *
+ * This routine implements the rtems_region_get_information directive.
+ * This directive returns information about the heap associated with
+ * this region.
+ *
+ * @param[in] id is the region id
+ * @param[in] the_info is the pointer to region information block
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful and
+ * *id filled with the region information block
+ */
+rtems_status_code rtems_region_get_information(
+ rtems_id id,
+ Heap_Information_block *the_info
+);
+
+/**
+ * @brief RTEMS Get Region Free Information
+ *
+ * This routine implements the rtems_region_get_free_information directive.
+ * This directive returns information about the free blocks in the
+ * heap associated with this region. Information about the used blocks
+ * will be returned as zero.
+ *
+ * @param[in] id is the region id
+ * @param[in] the_info is the pointer to region information block
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error. If successful, the the_info will
+ * be filled in with the region information block.
+ */
+rtems_status_code rtems_region_get_free_information(
+ rtems_id id,
+ Heap_Information_block *the_info
+);
+
+/**
+ * @brief RTEMS Delete Region
+ *
+ * This routine implements the rtems_region_delete directive. The
+ * region indicated by ID is deleted, provided that none of its segments are
+ * still allocated.
+ *
+ * @param[in] id is the region id
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_region_delete(
+ rtems_id id
+);
+
+/**
+ * @brief RTEMS Get Region Segment
+ *
+ * This routine implements the rtems_region_get_segment directive. It
+ * attempts to allocate a segment from the region associated with @a id.
+ * If a segment of the requested @a size size can be allocated, its address
+ * is returned in @a segment. If no segment is available, then the task
+ * may return immediately or block waiting for a segment with an optional
+ * timeout of @a timeout clock ticks. Whether the task blocks or returns
+ * immediately is based on the no_wait option in the @a option_set.
+ *
+ * @param[in] id is the region id
+ * @param[in] size is the segment size in bytes
+ * @param[in] option_set is the wait option
+ * @param[in] timeout is the number of ticks to wait (0 means wait forever)
+ * @param[in] segment is the pointer to segment address
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error. If successful, the segment will
+ * be filled in with the segment address.
+ */
+rtems_status_code rtems_region_get_segment(
+ rtems_id id,
+ uintptr_t size,
+ rtems_option option_set,
+ rtems_interval timeout,
+ void **segment
+);
+
+/**
+ * @brief RTEMS Get Region Segment Size
+ *
+ * This routine implements the rtems_region_get_segment_size directive. It
+ * returns the size in bytes of the specified user memory area.
+ *
+ * @param[in] id is the region id
+ * @param[in] segment is the segment address
+ * @param[in] size is the pointer to segment size in bytes
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error. If successful, the size will
+ * be filled in with the segment size in bytes.
+ */
+rtems_status_code rtems_region_get_segment_size(
+ rtems_id id,
+ void *segment,
+ uintptr_t *size
+);
+
+/**
+ * @brief RTEMS Return Region Segment
+ *
+ * This routine implements the rtems_region_return_segment directive. It
+ * frees the segment to the region associated with ID. The segment must
+ * have been previously allocated from the same region. If freeing the
+ * segment results in enough memory being available to satisfy the
+ * rtems_region_get_segment of the first blocked task, then that task and as
+ * many subsequent tasks as possible will be unblocked with their requests
+ * satisfied.
+ *
+ * @param[in] id is the region id
+ * @param[in] segment is the pointer to segment address
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
+ */
+rtems_status_code rtems_region_return_segment(
+ rtems_id id,
+ void *segment
+);
+
+/**
+ * @brief Resize RTEMS Region Segment
+ *
+ * This routine implements the rtems_region_resize_segment directive. It
+ * tries to resize segment in the region associated with 'id' to the new size
+ * 'size' in place. The first 'size' or old size bytes of the segment
+ * (whatever is less) are guaranteed to remain unmodified. The segment must
+ * have been previously allocated from the same region. If resizing the
+ * segment results in enough memory being available to satisfy the
+ * rtems_region_get_segment of the first blocked task, then that task and as
+ * many subsequent tasks as possible will be unblocked with their requests
+ * satisfied.
+ *
+ * @param[in] id is the region id
+ * @param[in] segment is the pointer to segment address
+ * @param[in] size is the new required size
+ * @retval RTEMS_SUCCESSFUL if operation successful, RTEMS_UNSATISFIED if the
+ * the segment can't be resized in place or any other code at failure
+ *
+ * @note On RTEMS_SUCCESSFUL or RTEMS_UNSATISFIED exit it returns into the
+ * 'old_size' the old size in bytes of the user memory area of the
+ * specified segment.
+ */
+rtems_status_code rtems_region_resize_segment(
+ rtems_id id,
+ void *segment,
+ uintptr_t size,
+ uintptr_t *old_size
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/regionimpl.h b/cpukit/include/rtems/rtems/regionimpl.h
new file mode 100644
index 0000000000..178b7ea32b
--- /dev/null
+++ b/cpukit/include/rtems/rtems/regionimpl.h
@@ -0,0 +1,142 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicRegionImpl
+ *
+ * @brief Classic Region Manager Implementation
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_REGIONIMPL_H
+#define _RTEMS_RTEMS_REGIONIMPL_H
+
+#include <rtems/rtems/region.h>
+#include <rtems/score/apimutex.h>
+#include <rtems/score/heapimpl.h>
+#include <rtems/score/objectimpl.h>
+#include <rtems/score/threadqimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicRegionImpl Classic Region Manager Implementation
+ *
+ * @ingroup ClassicRegion
+ *
+ * @{
+ */
+
+#define REGION_OF_THREAD_QUEUE_QUEUE( queue ) \
+ RTEMS_CONTAINER_OF( queue, Region_Control, Wait_queue.Queue )
+
+/**
+ * The following defines the information control block used to
+ * manage this class of objects.
+ */
+extern Objects_Information _Region_Information;
+
+/**
+ * @brief Region_Allocate
+ *
+ * This function allocates a region control block from
+ * the inactive chain of free region control blocks.
+ */
+RTEMS_INLINE_ROUTINE Region_Control *_Region_Allocate( void )
+{
+ return (Region_Control *) _Objects_Allocate( &_Region_Information );
+}
+
+/**
+ * @brief Region_Free
+ *
+ * This routine frees a region control block to the
+ * inactive chain of free region control blocks.
+ */
+RTEMS_INLINE_ROUTINE void _Region_Free (
+ Region_Control *the_region
+)
+{
+ _Thread_queue_Destroy( &the_region->Wait_queue );
+ _Objects_Free( &_Region_Information, &the_region->Object );
+}
+
+RTEMS_INLINE_ROUTINE Region_Control *_Region_Get_and_lock( Objects_Id id )
+{
+ Region_Control *the_region;
+
+ _RTEMS_Lock_allocator();
+
+ the_region = (Region_Control *)
+ _Objects_Get_no_protection( id, &_Region_Information );
+
+ if ( the_region != NULL ) {
+ /* Keep allocator lock */
+ return the_region;
+ }
+
+ _RTEMS_Unlock_allocator();
+ return NULL;
+}
+
+RTEMS_INLINE_ROUTINE void _Region_Unlock( Region_Control *the_region )
+{
+ (void) the_region;
+ _RTEMS_Unlock_allocator();
+}
+
+/**
+ * @brief Region_Allocate_segment
+ *
+ * This function attempts to allocate a segment from the_region.
+ * If successful, it returns the address of the allocated segment.
+ * Otherwise, it returns NULL.
+ */
+RTEMS_INLINE_ROUTINE void *_Region_Allocate_segment (
+ Region_Control *the_region,
+ uintptr_t size
+)
+{
+ return _Heap_Allocate( &the_region->Memory, size );
+}
+
+/**
+ * @brief Region_Free_segment
+ *
+ * This function frees the_segment to the_region.
+ */
+RTEMS_INLINE_ROUTINE bool _Region_Free_segment (
+ Region_Control *the_region,
+ void *the_segment
+)
+{
+ return _Heap_Free( &the_region->Memory, the_segment );
+}
+
+/**
+ * @brief Process Region Queue
+ *
+ * This is a helper routine which is invoked any time memory is
+ * freed. It looks at the set of waiting tasks and attempts to
+ * satisfy all outstanding requests.
+ *
+ * @param[in] the_region is the the region
+ */
+extern void _Region_Process_queue(Region_Control *the_region);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/sem.h b/cpukit/include/rtems/rtems/sem.h
new file mode 100644
index 0000000000..41b0061979
--- /dev/null
+++ b/cpukit/include/rtems/rtems/sem.h
@@ -0,0 +1,278 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicSem
+ *
+ * @brief Classic Semaphores API
+ *
+ * This include file contains all the constants and structures associated
+ * with the Semaphore Manager. This manager utilizes standard Dijkstra
+ * counting semaphores to provide synchronization and mutual exclusion
+ * capabilities.
+ *
+ * Directives provided are:
+ *
+ * - create a semaphore
+ * - get an ID of a semaphore
+ * - delete a semaphore
+ * - acquire a semaphore
+ * - release a semaphore
+ * - flush a semaphore
+ * - set ceiling priority for a semaphore
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2008, 2016.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_SEM_H
+#define _RTEMS_RTEMS_SEM_H
+
+#include <rtems/rtems/types.h>
+#include <rtems/rtems/options.h>
+#include <rtems/rtems/support.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/score/coremutex.h>
+#include <rtems/score/object.h>
+#include <rtems/score/coresem.h>
+#include <rtems/score/mrsp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicSem Semaphores
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality related to the Classic API
+ * Semaphore Manager.
+ */
+/**@{*/
+
+/**
+ * The following defines the control block used to manage each semaphore.
+ */
+typedef struct {
+ /** This field is the object management portion of a Semaphore instance. */
+ Objects_Control Object;
+
+ /**
+ * This contains the memory associated with the SuperCore Semaphore or
+ * Mutex instance that provides the primary functionality of each
+ * Classic API Semaphore instance. The structure used is dependent
+ * on the attributes specified by the user on the create directive.
+ *
+ * @note Only one of these has meaning in a particular Classic API
+ * Semaphore instance.
+ */
+ union {
+ /**
+ * @brief The thread queue present in all other variants.
+ */
+ Thread_queue_Control Wait_queue;
+
+ /**
+ * This is the SuperCore Mutex instance associated with this Classic
+ * API Semaphore instance.
+ */
+ CORE_ceiling_mutex_Control Mutex;
+
+ /**
+ * This is the SuperCore Semaphore instance associated with this Classic
+ * API Semaphore instance.
+ */
+ CORE_semaphore_Control Semaphore;
+
+#if defined(RTEMS_SMP)
+ MRSP_Control MRSP;
+#endif
+ } Core_control;
+
+ /**
+ * @brief The semaphore variant.
+ *
+ * @see Semaphore_Variant.
+ */
+ unsigned int variant : 3;
+
+ /**
+ * @brief The semaphore thread queue discipline.
+ *
+ * @see Semaphore_Discipline.
+ */
+ unsigned int discipline : 1;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ unsigned int is_global : 1;
+#endif
+} Semaphore_Control;
+
+/**
+ * @brief rtems_semaphore_create
+ *
+ * This routine implements the rtems_semaphore_create directive. The
+ * semaphore will have the name name. The starting count for
+ * the semaphore is count. The attribute_set determines if
+ * the semaphore is global or local and the thread queue
+ * discipline. It returns the id of the created semaphore in ID.
+ */
+rtems_status_code rtems_semaphore_create(
+ rtems_name name,
+ uint32_t count,
+ rtems_attribute attribute_set,
+ rtems_task_priority priority_ceiling,
+ rtems_id *id
+);
+
+/**
+ * @brief RTEMS Semaphore Name to Id
+ *
+ * This routine implements the rtems_semaphore_ident directive.
+ * This directive returns the semaphore ID associated with name.
+ * If more than one semaphore is named name, then the semaphore
+ * to which the ID belongs is arbitrary. node indicates the
+ * extent of the search for the ID of the semaphore named name.
+ * The search can be limited to a particular node or allowed to
+ * encompass all nodes.
+ *
+ * @param[in] name is the user defined semaphore name
+ * @param[in] node is(are) the node(s) to be searched
+ * @param[in] id is the pointer to semaphore id
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful and
+ * *id filled in with the semaphore id
+ */
+rtems_status_code rtems_semaphore_ident(
+ rtems_name name,
+ uint32_t node,
+ rtems_id *id
+);
+
+/**
+ * @brief RTEMS Delete Semaphore
+ *
+ * This routine implements the rtems_semaphore_delete directive. The
+ * semaphore indicated by ID is deleted.
+ *
+ * @param[in] id is the semaphore id
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_semaphore_delete(
+ rtems_id id
+);
+
+/**
+ * @brief RTEMS Obtain Semaphore
+ *
+ * This routine implements the rtems_semaphore_obtain directive. It
+ * attempts to obtain a unit from the semaphore associated with ID.
+ * If a unit can be allocated, the calling task will return immediately.
+ * If no unit is available, then the task may return immediately or
+ * block waiting for a unit with an optional timeout of timeout
+ * clock ticks. Whether the task blocks or returns immediately
+ * is based on the RTEMS_NO_WAIT option in the option_set.
+ *
+ * @param[in] id is the semaphore id
+ * @param[in] option_set is the wait option
+ * @param[in] timeout is the number of ticks to wait (0 means wait forever)
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_semaphore_obtain(
+ rtems_id id,
+ rtems_option option_set,
+ rtems_interval timeout
+);
+
+/**
+ * @brief RTEMS Semaphore Release
+ *
+ * This routine implements the rtems_semaphore_release directive. It
+ * frees a unit to the semaphore associated with ID. If a task was
+ * blocked waiting for a unit from this semaphore, then that task will
+ * be readied and the unit given to that task. Otherwise, the unit
+ * will be returned to the semaphore.
+ */
+rtems_status_code rtems_semaphore_release(
+ rtems_id id
+);
+
+/**
+ * @brief RTEMS Semaphore Flush
+ *
+ * This method is the implementation of the flush directive
+ * of the Semaphore Manager.
+ *
+ * This directive allows a thread to flush the threads
+ * pending on the semaphore.
+ *
+ * @param[in] id is the semaphore id
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
+ */
+rtems_status_code rtems_semaphore_flush(
+ rtems_id id
+);
+
+/**
+ * @brief Sets the priority value with respect to the specified scheduler of a
+ * semaphore.
+ *
+ * The special priority value @ref RTEMS_CURRENT_PRIORITY can be used to get
+ * the current priority value without changing it.
+ *
+ * The interpretation of the priority value depends on the protocol of the
+ * semaphore object.
+ *
+ * - The Multiprocessor Resource Sharing Protocol needs a ceiling priority per
+ * scheduler instance. This operation can be used to specify these priority
+ * values.
+ * - For the Priority Ceiling Protocol the ceiling priority is used with this
+ * operation.
+ * - For other protocols this operation is not defined.
+ *
+ * @param[in] semaphore_id Identifier of the semaphore.
+ * @param[in] scheduler_id Identifier of the scheduler.
+ * @param[in] new_priority The new priority value. Use
+ * @ref RTEMS_CURRENT_PRIORITY to not set a new priority and only get the
+ * current priority.
+ * @param[out] old_priority Reference to store the old priority value.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID Invalid semaphore or scheduler identifier.
+ * @retval RTEMS_INVALID_ADDRESS The old priority reference is @c NULL.
+ * @retval RTEMS_INVALID_PRIORITY The new priority value is invalid.
+ * @retval RTEMS_NOT_DEFINED The set priority operation is not defined for the
+ * protocol of this semaphore object.
+ * @retval RTEMS_ILLEGAL_ON_REMOTE_OBJECT Not supported for remote semaphores.
+ *
+ * @see rtems_scheduler_ident() and rtems_task_set_priority().
+ */
+rtems_status_code rtems_semaphore_set_priority(
+ rtems_id semaphore_id,
+ rtems_id scheduler_id,
+ rtems_task_priority new_priority,
+ rtems_task_priority *old_priority
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/semimpl.h b/cpukit/include/rtems/rtems/semimpl.h
new file mode 100644
index 0000000000..6d0f156e5c
--- /dev/null
+++ b/cpukit/include/rtems/rtems/semimpl.h
@@ -0,0 +1,120 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicSem
+ *
+ * @brief Classic Semaphores Implementation
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_SEMIMPL_H
+#define _RTEMS_RTEMS_SEMIMPL_H
+
+#include <rtems/rtems/sem.h>
+#include <rtems/score/coremuteximpl.h>
+#include <rtems/score/coresemimpl.h>
+#include <rtems/score/mrspimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Classic semaphore variants.
+ *
+ * Must be in synchronization with Semaphore_Control::variant.
+ */
+typedef enum {
+ SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY,
+ SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING,
+ SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL,
+ SEMAPHORE_VARIANT_SIMPLE_BINARY,
+ SEMAPHORE_VARIANT_COUNTING
+#if defined(RTEMS_SMP)
+ ,
+ SEMAPHORE_VARIANT_MRSP
+#endif
+} Semaphore_Variant;
+
+typedef enum {
+ SEMAPHORE_DISCIPLINE_PRIORITY,
+ SEMAPHORE_DISCIPLINE_FIFO
+} Semaphore_Discipline;
+
+/**
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+extern Objects_Information _Semaphore_Information;
+
+RTEMS_INLINE_ROUTINE const Thread_queue_Operations *_Semaphore_Get_operations(
+ const Semaphore_Control *the_semaphore
+)
+{
+ if ( the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY ) {
+ return &_Thread_queue_Operations_priority_inherit;
+ }
+
+ if ( the_semaphore->discipline == SEMAPHORE_DISCIPLINE_PRIORITY ) {
+ return &_Thread_queue_Operations_priority;
+ }
+
+ return &_Thread_queue_Operations_FIFO;
+}
+
+/**
+ * @brief Allocates a semaphore control block from
+ * the inactive chain of free semaphore control blocks.
+ *
+ * This function allocates a semaphore control block from
+ * the inactive chain of free semaphore control blocks.
+ */
+RTEMS_INLINE_ROUTINE Semaphore_Control *_Semaphore_Allocate( void )
+{
+ return (Semaphore_Control *) _Objects_Allocate( &_Semaphore_Information );
+}
+
+/**
+ * @brief Frees a semaphore control block to the
+ * inactive chain of free semaphore control blocks.
+ *
+ * This routine frees a semaphore control block to the
+ * inactive chain of free semaphore control blocks.
+ */
+RTEMS_INLINE_ROUTINE void _Semaphore_Free (
+ Semaphore_Control *the_semaphore
+)
+{
+ _Objects_Free( &_Semaphore_Information, &the_semaphore->Object );
+}
+
+RTEMS_INLINE_ROUTINE Semaphore_Control *_Semaphore_Get(
+ Objects_Id id,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Context_initialize( queue_context );
+ return (Semaphore_Control *) _Objects_Get(
+ id,
+ &queue_context->Lock_context.Lock_context,
+ &_Semaphore_Information
+ );
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef RTEMS_MULTIPROCESSING
+#include <rtems/rtems/semmp.h>
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/semmp.h b/cpukit/include/rtems/rtems/semmp.h
new file mode 100644
index 0000000000..9d7669f43e
--- /dev/null
+++ b/cpukit/include/rtems/rtems/semmp.h
@@ -0,0 +1,171 @@
+/**
+ * @file rtems/rtems/semmp.h
+ *
+ * @defgroup ClassicSEM Semaphore MP Support
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Semaphore Manager MP Support
+ *
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Support in the Semaphore Manager.
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_SEMMP_H
+#define _RTEMS_RTEMS_SEMMP_H
+
+#ifndef _RTEMS_RTEMS_SEMIMPL_H
+# error "Never use <rtems/rtems/semmp.h> directly; include <rtems/rtems/semimpl.h> instead."
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicSEM Semaphore MP Support
+ *
+ * @ingroup ClassicMP
+ *
+ * This encapsulates functionality related to the transparent multiprocessing
+ * support within the Classic API Semaphore Manager.
+ */
+/**@{*/
+
+/**
+ * The following enumerated type defines the list of
+ * remote semaphore operations.
+ */
+typedef enum {
+ SEMAPHORE_MP_ANNOUNCE_CREATE = 0,
+ SEMAPHORE_MP_ANNOUNCE_DELETE = 1,
+ SEMAPHORE_MP_EXTRACT_PROXY = 2,
+ SEMAPHORE_MP_OBTAIN_REQUEST = 3,
+ SEMAPHORE_MP_OBTAIN_RESPONSE = 4,
+ SEMAPHORE_MP_RELEASE_REQUEST = 5,
+ SEMAPHORE_MP_RELEASE_RESPONSE = 6
+} Semaphore_MP_Remote_operations;
+
+/**
+ * The following data structure defines the packet used to perform
+ * remote semaphore operations.
+ */
+typedef struct {
+ rtems_packet_prefix Prefix;
+ Semaphore_MP_Remote_operations operation;
+ rtems_name name;
+ rtems_option option_set;
+ Objects_Id proxy_id;
+} Semaphore_MP_Packet;
+
+RTEMS_INLINE_ROUTINE bool _Semaphore_MP_Is_remote( Objects_Id id )
+{
+ return _Objects_MP_Is_remote( id, &_Semaphore_Information );
+}
+
+/**
+ * @brief Semaphore MP Send Process Packet
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ */
+void _Semaphore_MP_Send_process_packet (
+ Semaphore_MP_Remote_operations operation,
+ Objects_Id semaphore_id,
+ rtems_name name,
+ Objects_Id proxy_id
+);
+
+/**
+ * @brief Issues a remote rtems_semaphore_obtain() request.
+ */
+rtems_status_code _Semaphore_MP_Obtain(
+ rtems_id id,
+ rtems_option option_set,
+ rtems_interval timeout
+);
+
+/**
+ * @brief Issues a remote rtems_semaphore_release() request.
+ */
+rtems_status_code _Semaphore_MP_Release( rtems_id id );
+
+/**
+ * @brief Semaphore MP Process Packet
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+void _Semaphore_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+);
+
+/**
+ * @brief Semaphore MP Send Object was Deleted
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ */
+void _Semaphore_MP_Send_object_was_deleted (
+ Thread_Control *the_proxy,
+ Objects_Id mp_id
+);
+
+/**
+ * @brief Semaphore MP Send Extract Proxy
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ */
+void _Semaphore_MP_Send_extract_proxy (
+ Thread_Control *the_thread,
+ Objects_Id id
+);
+
+/**
+ * @brief Semaphore Core Mutex MP Support
+ *
+ * This function processes the global actions necessary for remote
+ * accesses to a global semaphore based on a core mutex. This function
+ * is called by the core.
+ *
+ * @param[in] the_thread the remote thread the semaphore was surrendered to
+ * @param[in] id is the id of the surrendered semaphore
+ */
+void _Semaphore_Core_mutex_mp_support (
+ Thread_Control *the_thread,
+ Objects_Id id
+);
+
+/**
+ * @brief Semaphore Core MP Support
+ *
+ * This function processes the global actions necessary for remote
+ * accesses to a global semaphore based on a core semaphore. This function
+ * is called by the core.
+ *
+ * @param[in] the_thread the remote thread the semaphore was surrendered to
+ * @param[in] id is the id of the surrendered semaphore
+ */
+void _Semaphore_Core_semaphore_mp_support (
+ Thread_Control *the_thread,
+ Objects_Id id
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of file */
diff --git a/cpukit/include/rtems/rtems/signal.h b/cpukit/include/rtems/rtems/signal.h
new file mode 100644
index 0000000000..f7b7000d9a
--- /dev/null
+++ b/cpukit/include/rtems/rtems/signal.h
@@ -0,0 +1,83 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicSignal
+ *
+ * @brief Signals API
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_SIGNAL_H
+#define _RTEMS_RTEMS_SIGNAL_H
+
+#include <rtems/rtems/asr.h>
+#include <rtems/rtems/modes.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicSignal Signals
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * Directives provided are:
+ *
+ * + establish an asynchronous signal routine
+ * + send a signal set to a task
+ */
+/**@{*/
+
+/**
+ * @brief RTEMS Catch Signal
+ *
+ * This routine implements the rtems_signal_catch directive. This directive
+ * is used to establish asr_handler as the Asynchronous Signal Routine
+ * (RTEMS_ASR) for the calling task. The asr_handler will execute with a
+ * mode of mode_set.
+ *
+ * @param[in] asr_handler is the address of asynchronous signal routine (asr)
+ * ( NULL indicates asr is invalid )
+ * @param[in] mode_set is the mode value for asr
+ *
+ * @retval RTEMS_SUCCESSFUL
+ */
+rtems_status_code rtems_signal_catch(
+ rtems_asr_entry asr_handler,
+ rtems_mode mode_set
+);
+
+/**
+ * @brief RTEMS Send Signal
+ *
+ * This routine implements the rtems_signal_send directive. This directive
+ * sends the signal_set to the task specified by ID.
+ *
+ * @param[in] id is the thread thread id
+ * @param[in] signal_set is the signal set
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
+ */
+rtems_status_code rtems_signal_send(
+ rtems_id id,
+ rtems_signal_set signal_set
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/signalimpl.h b/cpukit/include/rtems/rtems/signalimpl.h
new file mode 100644
index 0000000000..61848ae95c
--- /dev/null
+++ b/cpukit/include/rtems/rtems/signalimpl.h
@@ -0,0 +1,51 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicSignalImpl
+ *
+ * @brief Signals Implementation
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_SIGNALIMPL_H
+#define _RTEMS_RTEMS_SIGNALIMPL_H
+
+#include <rtems/rtems/signal.h>
+#include <rtems/score/thread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicSignalImpl Signals Implementation
+ *
+ * @ingroup ClassicSignal
+ */
+/**@{*/
+
+void _Signal_Action_handler(
+ Thread_Control *executing,
+ Thread_Action *action,
+ ISR_lock_Context *lock_context
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/rtems/signalmp.h>
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/signalmp.h b/cpukit/include/rtems/rtems/signalmp.h
new file mode 100644
index 0000000000..57b8682c58
--- /dev/null
+++ b/cpukit/include/rtems/rtems/signalmp.h
@@ -0,0 +1,98 @@
+/**
+ * @file rtems/rtems/signalmp.h
+ *
+ * @brief Signal MP Support
+ *
+ * This include file contains all the constants and structures associated
+ * with the Multiprocessing Support in the Signal Manager.
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_SIGNALMP_H
+#define _RTEMS_RTEMS_SIGNALMP_H
+
+#ifndef _RTEMS_RTEMS_SIGNALIMPL_H
+# error "Never use <rtems/rtems/signalmp.h> directly; include <rtems/rtems/signalimpl.h> instead."
+#endif
+
+#include <rtems/score/mpciimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicSignalMP Signal MP Support
+ *
+ * @ingroup ClassicMP
+ *
+ * This encapsulates functionality related to the transparent multiprocessing
+ * support within the Classic API Signal Manager.
+ */
+/*{*/
+
+/*
+ * @brief Signal_MP_Send_process_packet
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ *
+ * This routine is not needed since there are no process
+ * packets to be sent by this manager.
+ */
+
+/**
+ * @brief Issues a remote rtems_signal_send() request.
+ */
+rtems_status_code _Signal_MP_Send(
+ rtems_id id,
+ rtems_signal_set signal_set
+);
+
+/**
+ * @brief Signal MP Process Packet
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+void _Signal_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+);
+
+/*
+ * @brief Signal_MP_Send_object_was_deleted
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed since there are no objects
+ * deleted by this manager.
+ */
+
+/*
+ * @brief Signal_MP_Send_extract_proxy
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed since there are no objects
+ * deleted by this manager.
+ */
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of file */
diff --git a/cpukit/include/rtems/rtems/smp.h b/cpukit/include/rtems/rtems/smp.h
new file mode 100644
index 0000000000..aeb0df6f46
--- /dev/null
+++ b/cpukit/include/rtems/rtems/smp.h
@@ -0,0 +1,78 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicSMP
+ *
+ * @brief SMP Services API
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_SMP_H
+#define _RTEMS_RTEMS_SMP_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicSMP SMP Services
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality which is useful for SMP applications.
+ *
+ * @{
+ */
+
+/**
+ * @brief Returns the count of processors in the system.
+ *
+ * On uni-processor configurations a value of one will be returned.
+ *
+ * On SMP configurations this returns the value of a global variable set during
+ * system initialization to indicate the count of utilized processors. The
+ * processor count depends on the physically or virtually available processors
+ * and application configuration. The value will always be less than or equal
+ * to the maximum count of application configured processors.
+ *
+ * @return The count of processors being utilized.
+ */
+uint32_t rtems_get_processor_count(void);
+
+/**
+ * @brief Returns the index of the current processor.
+ *
+ * On uni-processor configurations a value of zero will be returned.
+ *
+ * On SMP configurations an architecture specific method is used to obtain the
+ * index of the current processor in the system. The set of processor indices
+ * is the range of integers starting with zero up to the processor count minus
+ * one.
+ *
+ * Outside of sections with disabled thread dispatching the current processor
+ * index may change after every instruction since the thread may migrate from
+ * one processor to another. Sections with disabled interrupts are sections
+ * with thread dispatching disabled.
+ *
+ * @return The index of the current processor.
+ */
+uint32_t rtems_get_current_processor(void);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/status.h b/cpukit/include/rtems/rtems/status.h
new file mode 100644
index 0000000000..c54404ba14
--- /dev/null
+++ b/cpukit/include/rtems/rtems/status.h
@@ -0,0 +1,263 @@
+/**
+ * @file rtems/rtems/status.h
+ *
+ * @defgroup ClassicStatus Status Codes
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Status Codes Returned from Executive Directives
+ *
+ * This include file contains the status codes returned from the
+ * executive directives.
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_STATUS_H
+#define _RTEMS_RTEMS_STATUS_H
+
+#include <rtems/score/basedefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicStatus Status Codes
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality related to the status codes returned
+ * by Classic API directives.
+ */
+/**@{*/
+
+/**
+ * @brief Classic API Status
+ *
+ * This enumerates the possible status values returned b
+ * Classic API directives.
+ */
+typedef enum {
+ /**
+ * This is the status to indicate successful completion.
+ */
+ RTEMS_SUCCESSFUL = 0,
+ /**
+ * This is the status to indicate that a thread exited.
+ */
+ RTEMS_TASK_EXITTED = 1,
+ /**
+ * This is the status to indicate multiprocessing is not configured.
+ */
+ RTEMS_MP_NOT_CONFIGURED = 2,
+ /**
+ * This is the status to indicate that the object name was invalid.
+ */
+ RTEMS_INVALID_NAME = 3,
+ /**
+ * This is the status to indicate that the object Id was invalid.
+ */
+ RTEMS_INVALID_ID = 4,
+ /**
+ * This is the status to indicate you have attempted to create too many
+ * instances of a particular object class.
+ */
+ RTEMS_TOO_MANY = 5,
+ /**
+ * This is the status to indicate that a blocking directive timed out.
+ */
+ RTEMS_TIMEOUT = 6,
+ /**
+ * This is the status to indicate the the object was deleted
+ * while the task was blocked waiting.
+ */
+ RTEMS_OBJECT_WAS_DELETED = 7,
+ /**
+ * This is the status to indicate that the specified size was invalid.
+ */
+ RTEMS_INVALID_SIZE = 8,
+ /**
+ * This is the status to indicate that the specified address is invalid.
+ */
+ RTEMS_INVALID_ADDRESS = 9,
+ /**
+ * This is the status to indicate that the specified number was invalid.
+ */
+ RTEMS_INVALID_NUMBER = 10,
+ /**
+ * This is the status to indicate that the item has not been initialized.
+ */
+ RTEMS_NOT_DEFINED = 11,
+ /**
+ * This is the status to indicate that the object still has
+ * resources in use.
+ */
+ RTEMS_RESOURCE_IN_USE = 12,
+ /**
+ * This is the status to indicate that the request was not satisfied.
+ */
+ RTEMS_UNSATISFIED = 13,
+ /**
+ * This is the status to indicate that a thread is in wrong state
+ * was in the wrong execution state for the requested operation.
+ */
+ RTEMS_INCORRECT_STATE = 14,
+ /**
+ * This is the status to indicate thread was already suspended.
+ */
+ RTEMS_ALREADY_SUSPENDED = 15,
+ /**
+ * This is the status to indicate that the operation is illegal
+ * on calling thread.
+ */
+ RTEMS_ILLEGAL_ON_SELF = 16,
+ /**
+ * This is the status to indicate illegal for remote object.
+ */
+ RTEMS_ILLEGAL_ON_REMOTE_OBJECT = 17,
+ /**
+ * This is the status to indicate that the operation should not be
+ * called from from this excecution environment.
+ */
+ RTEMS_CALLED_FROM_ISR = 18,
+ /**
+ * This is the status to indicate that an invalid thread priority
+ * was provided.
+ */
+ RTEMS_INVALID_PRIORITY = 19,
+ /**
+ * This is the status to indicate that the specified date/time was invalid.
+ */
+ RTEMS_INVALID_CLOCK = 20,
+ /**
+ * This is the status to indicate that the specified node Id was invalid.
+ */
+ RTEMS_INVALID_NODE = 21,
+ /**
+ * This is the status to indicate that the directive was not configured.
+ */
+ RTEMS_NOT_CONFIGURED = 22,
+ /**
+ * This is the status to indicate that the caller is not the
+ * owner of the resource.
+ */
+ RTEMS_NOT_OWNER_OF_RESOURCE = 23,
+ /**
+ * This is the status to indicate the the directive or requested
+ * portion of the directive is not implemented. This is a hint
+ * that you have stumbled across an opportunity to submit code
+ * to the RTEMS Project.
+ */
+ RTEMS_NOT_IMPLEMENTED = 24,
+ /**
+ * This is the status to indicate that an internal RTEMS inconsistency
+ * was detected.
+ */
+ RTEMS_INTERNAL_ERROR = 25,
+ /**
+ * This is the status to indicate that the directive attempted to allocate
+ * memory but was unable to do so.
+ */
+ RTEMS_NO_MEMORY = 26,
+ /**
+ * This is the status to indicate an driver IO error.
+ */
+ RTEMS_IO_ERROR = 27,
+ /**
+ * This is the status is used internally to RTEMS when performing
+ * operations on behalf of remote tasks. This is referred to as
+ * proxying operations and this status indicates that the operation
+ * could not be completed immediately and the "proxy is blocking."
+ *
+ * @note This status will @b NOT be returned to the user.
+ */
+ RTEMS_PROXY_BLOCKING = 28
+} rtems_status_code;
+
+/**
+ * This is the lowest valid value for a Classic API status code.
+ */
+#define RTEMS_STATUS_CODES_FIRST RTEMS_SUCCESSFUL
+
+/**
+ * This is the highest valid value for a Classic API status code.
+ */
+#define RTEMS_STATUS_CODES_LAST RTEMS_PROXY_BLOCKING
+
+/**
+ * @brief Checks if the status code is equal to RTEMS_SUCCESSFUL.
+ *
+ * This function returns TRUE if the status code is equal to RTEMS_SUCCESSFUL,
+ * and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_is_status_successful(
+ rtems_status_code code
+)
+{
+ return (code == RTEMS_SUCCESSFUL);
+}
+
+/**
+ * @brief Checks if the status code1 is equal to code2.
+ *
+ * This function returns TRUE if the status code1 is equal to code2,
+ * and FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_are_statuses_equal(
+ rtems_status_code code1,
+ rtems_status_code code2
+)
+{
+ return (code1 == code2);
+}
+
+/**
+ * @brief RTEMS Status Code to Errno Mapping Function
+ *
+ * This function recieves an RTEMS status code and returns an
+ * errno error code. The retval values show the mappings between
+ * rtems_status_codes and errno error codes.
+ *
+ * @retval 0 RTEMS_SUCCESSFUL
+ * @retval EIO RTEMS_TASK_EXITED, RTEMS_MP_NOT_CONFIGURED, RTEMS_INVALID_ID,
+ * RTEMS_TOO_MANY, RTEMS_OBJECT_WAS_DELETED, RTEMS_INVALID_SIZE,
+ * RTEMS_INVALID_ADDRESS, RTEMS_NOT_DEFINED, RTEMS_INCORRECT_STATE,
+ * RTEMS_ILLEGAL_ON_SELF, RTEMS_ILLEGAL_ON_REMOTE_OBJECT,
+ * RTEMS_CALLED_FROM_ISR, RTEMS_INVALID_PRIORITY, RTEMS_INTERNAL_ERROR,
+ * RTEMS_IO_ERROR, RTEMS_PROXY_BLOCKING
+ * @retval EINVAL RTEMS_INVALID_NAME, RTEMS_INVALID_CLOCK, RTEMS_INVALID_NODE
+ * @retval ETIMEDOUT RTEMS_TIMEOUT
+ * @retval EBADF RTEMS_INVALID_NUMBER
+ * @retval EBUSY RTEMS_RESOURCE_IN_USE
+ * @retval ENODEV RTEMS_UNSATISFIED
+ * @retval ENOSYS RTEMS_NOT_IMPLEMENTED, RTEMS_NOT_CONFIGURED
+ * @retval ENOMEM RTEMS_NO_MEMORY
+ */
+int rtems_status_code_to_errno(rtems_status_code sc);
+
+/**
+ * @brief Returns a text for a status code.
+ *
+ * The text for each status code is the enumerator constant.
+ *
+ * @param[in] code The status code.
+ *
+ * @retval text The status code text.
+ * @retval "?" The passed status code is invalid.
+ */
+const char *rtems_status_text( rtems_status_code code );
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/statusimpl.h b/cpukit/include/rtems/rtems/statusimpl.h
new file mode 100644
index 0000000000..8a51bb8b19
--- /dev/null
+++ b/cpukit/include/rtems/rtems/statusimpl.h
@@ -0,0 +1,64 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicStatusImpl
+ *
+ * @brief Classic Status Implementation
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_STATUSIMPL_H
+#define _RTEMS_RTEMS_STATUSIMPL_H
+
+#include <rtems/rtems/status.h>
+#include <rtems/score/threadimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicStatusImpl Classic Status Implementation
+ *
+ * @ingroup ClassicStatus
+ *
+ * @{
+ */
+
+/**
+ * @brief Status Object Name Errors to Status Array
+ *
+ * This array is used to map SuperCore Object Handler return
+ * codes to Classic API status codes.
+ */
+extern const rtems_status_code _Status_Object_name_errors_to_status[];
+
+RTEMS_INLINE_ROUTINE rtems_status_code _Status_Get(
+ Status_Control status
+)
+{
+ return (rtems_status_code) STATUS_GET_CLASSIC( status );
+}
+
+RTEMS_INLINE_ROUTINE rtems_status_code _Status_Get_after_wait(
+ const Thread_Control *executing
+)
+{
+ return _Status_Get( _Thread_Wait_get_status( executing ) );
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/support.h b/cpukit/include/rtems/rtems/support.h
new file mode 100644
index 0000000000..4ebb50cbdf
--- /dev/null
+++ b/cpukit/include/rtems/rtems/support.h
@@ -0,0 +1,170 @@
+/**
+ * @file
+ *
+ * @defgroup ClassicRTEMSWorkspace Workspace
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Classic API support.
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_SUPPORT_H
+#define _RTEMS_RTEMS_SUPPORT_H
+
+#include <rtems/rtems/types.h>
+#include <rtems/config.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ClassicRTEMS
+ */
+/**@{**/
+
+/**
+ * @brief Returns the number of micro seconds for the milli seconds value @a _ms.
+ */
+#define RTEMS_MILLISECONDS_TO_MICROSECONDS(_ms) ((_ms) * 1000UL)
+
+/**
+ * @brief Returns the number of ticks for the milli seconds value @a _ms.
+ */
+#define RTEMS_MILLISECONDS_TO_TICKS(_ms) \
+ (RTEMS_MILLISECONDS_TO_MICROSECONDS(_ms) / \
+ rtems_configuration_get_microseconds_per_tick())
+
+/**
+ * @brief Returns the number of ticks for the micro seconds value @a _us.
+ */
+#define RTEMS_MICROSECONDS_TO_TICKS(_us) \
+ ((_us) / rtems_configuration_get_microseconds_per_tick())
+
+/**
+ * @brief Returns @c true if the name is valid, and @c false otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_is_name_valid (
+ rtems_name name
+)
+{
+ return ( name != 0 );
+}
+
+/**
+ * @brief Breaks the object name into the four component characters @a c1,
+ * @a c2, @a c3, and @a c4.
+ */
+RTEMS_INLINE_ROUTINE void rtems_name_to_characters(
+ rtems_name name,
+ char *c1,
+ char *c2,
+ char *c3,
+ char *c4
+)
+{
+ *c1 = (char) ((name >> 24) & 0xff);
+ *c2 = (char) ((name >> 16) & 0xff);
+ *c3 = (char) ((name >> 8) & 0xff);
+ *c4 = (char) ( name & 0xff);
+}
+
+/** @} */
+
+/**
+ * @defgroup ClassicRTEMSWorkspace Workspace
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * Workspace definitions.
+ */
+/**@{**/
+
+/**
+ * @brief Gets Workspace Information
+ *
+ * Returns information about the heap that is used as the RTEMS Executive
+ * Workspace in @a the_info.
+ *
+ * Returns @c true if successful, and @a false otherwise.
+ */
+bool rtems_workspace_get_information(
+ Heap_Information_block *the_info
+);
+
+/**
+ * @brief Allocates Memory from the Workspace
+ *
+ * A number of @a bytes bytes will be allocated from the RTEMS Executive
+ * Workspace and returned in @a pointer.
+ *
+ * Returns @c true if successful, and @a false otherwise.
+ */
+bool rtems_workspace_allocate(
+ size_t bytes,
+ void **pointer
+);
+
+/**
+ * @brief Frees Memory Allocated from the Workspace
+ *
+ * This frees the memory indicated by @a pointer that was allocated from the
+ * RTEMS Executive Workspace.
+ *
+ * Returns @c true if successful, and @a false otherwise.
+ */
+bool rtems_workspace_free(
+ void *pointer
+);
+
+/**
+ * @brief Greedy allocate that empties the workspace.
+ *
+ * Afterwards the heap has at most @a block_count allocatable blocks of sizes
+ * specified by @a block_sizes. The @a block_sizes must point to an array with
+ * @a block_count members. All other blocks are used.
+ *
+ * @see rtems_workspace_greedy_free().
+ */
+void *rtems_workspace_greedy_allocate(
+ const uintptr_t *block_sizes,
+ size_t block_count
+);
+
+/**
+ * @brief Greedy allocate all blocks except the largest free block.
+ *
+ * Afterwards the heap has at most one allocatable block. This block is the
+ * largest free block if it exists. The allocatable size of this block is
+ * stored in @a allocatable_size. All other blocks are used.
+ *
+ * @see rtems_workspace_greedy_free().
+ */
+void *rtems_workspace_greedy_allocate_all_except_largest(
+ uintptr_t *allocatable_size
+);
+
+/**
+ * @brief Frees space of a greedy allocation.
+ *
+ * The @a opaque argument must be the return value of
+ * rtems_workspace_greedy_allocate() or
+ * rtems_workspace_greedy_allocate_all_except_largest().
+ */
+void rtems_workspace_greedy_free( void *opaque );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/taskmp.h b/cpukit/include/rtems/rtems/taskmp.h
new file mode 100644
index 0000000000..e2d70a924e
--- /dev/null
+++ b/cpukit/include/rtems/rtems/taskmp.h
@@ -0,0 +1,132 @@
+/**
+ * @file rtems/rtems/taskmp.h
+ *
+ * @defgroup ClassicTaskMP Task MP Support
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Task Manager MP Support
+ *
+ * This include file contains all the constants and structures associated
+ * with the multiprocessing support in the task manager.
+ */
+
+/* COPYRIGHT (c) 1989-2013.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_TASKMP_H
+#define _RTEMS_RTEMS_TASKMP_H
+
+#ifndef _RTEMS_RTEMS_TASKSIMPL_H
+# error "Never use <rtems/rtems/taskmp.h> directly; include <rtems/rtems/tasksimpl.h> instead."
+#endif
+
+#include <rtems/score/mpciimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicTaskMP Task MP Support
+ *
+ * @ingroup ClassicMP
+ *
+ * This encapsulates functionality related to the transparent multiprocessing
+ * support within the Classic API Task Manager.
+ */
+/**@{*/
+
+/**
+ * The following enumerated type defines the list of
+ * remote task operations.
+ */
+typedef enum {
+ RTEMS_TASKS_MP_ANNOUNCE_CREATE = 0,
+ RTEMS_TASKS_MP_ANNOUNCE_DELETE = 1,
+ RTEMS_TASKS_MP_SUSPEND_REQUEST = 2,
+ RTEMS_TASKS_MP_SUSPEND_RESPONSE = 3,
+ RTEMS_TASKS_MP_RESUME_REQUEST = 4,
+ RTEMS_TASKS_MP_RESUME_RESPONSE = 5,
+ RTEMS_TASKS_MP_SET_PRIORITY_REQUEST = 6,
+ RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE = 7,
+} RTEMS_tasks_MP_Remote_operations;
+
+/**
+ * @brief RTEMS Tasks MP Send Process Packet
+ *
+ * Multiprocessing Support for the RTEMS Task Manager
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ */
+void _RTEMS_tasks_MP_Send_process_packet (
+ RTEMS_tasks_MP_Remote_operations operation,
+ Objects_Id task_id,
+ rtems_name name
+);
+
+/**
+ * @brief Issues a remote rtems_task_set_priority() request.
+ */
+rtems_status_code _RTEMS_tasks_MP_Set_priority(
+ rtems_id id,
+ rtems_task_priority new_priority,
+ rtems_task_priority *old_priority
+);
+
+/**
+ * @brief Issues a remote rtems_task_suspend() request.
+ */
+rtems_status_code _RTEMS_tasks_MP_Suspend( rtems_id id );
+
+/**
+ * @brief Issues a remote rtems_task_resume() request.
+ */
+rtems_status_code _RTEMS_tasks_MP_Resume( rtems_id id );
+
+/**
+ * @brief _RTEMS_tasks_MP_Process_packet
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+void _RTEMS_tasks_MP_Process_packet (
+ rtems_packet_prefix *the_packet_prefix
+);
+
+/**
+ * @brief _RTEMS_tasks_MP_Send_object_was_deleted
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed by RTEMS_tasks since a task
+ * cannot be deleted when segments are in use.
+ */
+
+/*
+ * _RTEMS_tasks_MP_Send_extract_proxy
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed since there are no objects
+ * deleted by this manager.
+ *
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of file */
diff --git a/cpukit/include/rtems/rtems/tasks.h b/cpukit/include/rtems/rtems/tasks.h
new file mode 100644
index 0000000000..585f4c449c
--- /dev/null
+++ b/cpukit/include/rtems/rtems/tasks.h
@@ -0,0 +1,716 @@
+/**
+ * @file rtems/rtems/tasks.h
+ *
+ * @defgroup ClassicTasks Tasks
+ *
+ * @ingroup ClassicRTEMS
+ * @brief RTEMS Tasks
+ *
+ * This include file contains all constants and structures associated
+ * with RTEMS tasks. This manager provides a comprehensive set of directives
+ * to create, delete, and administer tasks.
+ *
+ * Directives provided are:
+ *
+ * - create a task
+ * - get an ID of a task
+ * - start a task
+ * - restart a task
+ * - delete a task
+ * - suspend a task
+ * - resume a task
+ * - set a task's priority
+ * - change the current task's mode
+ * - wake up after interval
+ * - wake up when specified
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_TASKS_H
+#define _RTEMS_RTEMS_TASKS_H
+
+#include <rtems/score/object.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/thread.h>
+#include <rtems/rtems/types.h>
+#include <rtems/rtems/event.h>
+#include <rtems/rtems/asr.h>
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/status.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicTasks Tasks
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates the functionality of the Classic API Task Manager.
+ * This functionality includes task services such as creation, deletion,
+ * delays, suspend/resume, and manipulation of execution mode and priority.
+ */
+/**@{*/
+
+/**
+ * Constant to be used as the ID of current task
+ */
+#define RTEMS_SELF OBJECTS_ID_OF_SELF
+
+/**
+ * This constant is passed to the rtems_task_wake_after directive as the
+ * interval when a task wishes to yield the CPU.
+ */
+#define RTEMS_YIELD_PROCESSOR WATCHDOG_NO_TIMEOUT
+
+/**
+ * Define the type for an RTEMS API task priority.
+ */
+typedef uint32_t rtems_task_priority;
+
+/**
+ * This is the constant used with the rtems_task_set_priority
+ * directive to indicate that the caller wants to obtain its
+ * current priority rather than set it as the name of the
+ * directive indicates.
+ */
+#define RTEMS_NO_PRIORITY RTEMS_CURRENT_PRIORITY
+
+/**
+ * This constant is the least valid value for a Classic API
+ * task priority.
+ */
+#define RTEMS_MINIMUM_PRIORITY (PRIORITY_MINIMUM + 1)
+
+/**
+ * This constant is the maximum valid value for a Classic API
+ * task priority.
+ *
+ * @note This is actually the priority of the IDLE thread so
+ * using this priority will result in having a task
+ * which never executes. This could be useful if you
+ * want to ensure that a task does not executes during
+ * certain operations such as a system mode change.
+ */
+#define RTEMS_MAXIMUM_PRIORITY ((rtems_task_priority) PRIORITY_MAXIMUM)
+
+/**
+ * The following constant is passed to rtems_task_set_priority when the
+ * caller wants to obtain the current priority.
+ */
+#define RTEMS_CURRENT_PRIORITY PRIORITY_MINIMUM
+
+/**
+ * External API name for Thread_Control
+ */
+typedef Thread_Control rtems_tcb;
+
+/**
+ * The following defines the "return type" of an RTEMS task.
+ */
+typedef void rtems_task;
+
+/**
+ * The following defines the argument to an RTEMS task.
+ */
+typedef Thread_Entry_numeric_type rtems_task_argument;
+
+/**
+ * The following defines the type for the entry point of an RTEMS task.
+ */
+typedef rtems_task ( *rtems_task_entry )(
+ rtems_task_argument
+ );
+
+/**
+ * The following records define the Initialization Tasks Table.
+ * Each entry contains the information required by RTEMS to
+ * create and start a user task automatically at executive
+ * initialization time.
+ */
+typedef struct {
+ /** This is the Initialization Task's name. */
+ rtems_name name;
+ /** This is the Initialization Task's stack size. */
+ size_t stack_size;
+ /** This is the Initialization Task's priority. */
+ rtems_task_priority initial_priority;
+ /** This is the Initialization Task's attributes. */
+ rtems_attribute attribute_set;
+ /** This is the Initialization Task's entry point. */
+ rtems_task_entry entry_point;
+ /** This is the Initialization Task's initial mode. */
+ rtems_mode mode_set;
+ /** This is the Initialization Task's argument. */
+ rtems_task_argument argument;
+} rtems_initialization_tasks_table;
+
+/**
+ * @brief RTEMS Task Create
+ *
+ * This routine implements the rtems_task_create directive. The task
+ * will have the name name. The attribute_set can be used to indicate
+ * that the task will be globally accessible or utilize floating point.
+ * The task's stack will be stack_size bytes. The task will begin
+ * execution with initial_priority and initial_modes. It returns the
+ * id of the created task in ID.
+ *
+ * @param[in] name is the user defined thread name
+ * @param[in] initial_priority is the thread priority
+ * @param[in] stack_size is the stack size in bytes
+ * @param[in] initial_modes is the initial thread mode
+ * @param[in] attribute_set is the thread attributes
+ * @param[in] id is the pointer to thread id
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
+ * and *id thread id filled in
+ */
+rtems_status_code rtems_task_create(
+ rtems_name name,
+ rtems_task_priority initial_priority,
+ size_t stack_size,
+ rtems_mode initial_modes,
+ rtems_attribute attribute_set,
+ rtems_id *id
+);
+
+/**
+ * @brief RTEMS Task Name to Id
+ *
+ * This routine implements the rtems_task_ident directive.
+ * This directive returns the task ID associated with name.
+ * If more than one task is named name, then the task to
+ * which the ID belongs is arbitrary. node indicates the
+ * extent of the search for the ID of the task named name.
+ * The search can be limited to a particular node or allowed to
+ * encompass all nodes.
+ *
+ * @param[in] name is the user defined thread name
+ * @param[in] node is(are) the node(s) to be searched
+ * @param[in] id is the pointer to thread id
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error. If successful, the id will
+ * be filled in with the thread id.
+ */
+rtems_status_code rtems_task_ident(
+ rtems_name name,
+ uint32_t node,
+ rtems_id *id
+);
+
+/**
+ * @brief RTEMS Delete Task
+ *
+ * This routine implements the rtems_task_delete directive. The
+ * task indicated by ID is deleted. The executive halts execution
+ * of the thread and frees the thread control block.
+ *
+ * @param[in] id is the thread id
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error and id is not the requesting thread. Status code is
+ * returned indicating the source of the error. Nothing
+ * is returned if id is the requesting thread (always succeeds).
+ */
+rtems_status_code rtems_task_delete(
+ rtems_id id
+);
+
+/**
+ * @brief RTEMS Task Mode
+ *
+ * This routine implements the rtems_task_mode directive. The current
+ * values of the modes indicated by mask of the calling task are changed
+ * to that indicated in mode_set. The former mode of the task is
+ * returned in mode_set.
+ *
+ * @param[in] mode_set is the new mode
+ * @param[in] mask is the mask
+ * @param[in] previous_mode_set is the address of previous mode set
+ *
+ * @retval RTEMS_SUCCESSFUL and previous_mode_set filled in with the
+ * previous mode set
+ */
+rtems_status_code rtems_task_mode(
+ rtems_mode mode_set,
+ rtems_mode mask,
+ rtems_mode *previous_mode_set
+);
+
+/**
+ * @brief RTEMS Task Restart
+ *
+ * This routine implements the rtems_task_restart directive. The
+ * task associated with ID is restarted at its initial entry
+ * point with the new argument.
+ *
+ * @param[in] id is the thread id
+ * @param[in] arg is the thread argument
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
+ */
+rtems_status_code rtems_task_restart(
+ rtems_id id,
+ uint32_t arg
+);
+
+/**
+ * @brief RTEMS Suspend Task
+ *
+ * This routine implements the rtems_task_suspend directive. The
+ * SUSPENDED state is set for task associated with ID. Note that the
+ * suspended state can be in addition to other waiting states.
+ *
+ * @param[in] id is the thread id
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_task_suspend(
+ rtems_id id
+);
+
+/**
+ * @brief RTEMS Resume Task
+ *
+ * This routine implements the rtems_task_resume Directive. The
+ * SUSPENDED state is cleared for task associated with ID.
+ *
+ * @param[in] id is the thread id
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_task_resume(
+ rtems_id id
+);
+
+/**
+ * @brief RTEMS Set Task Priority
+ *
+ * This routine implements the rtems_task_set_priority directive. The
+ * current priority of the task associated with ID is set to
+ * new_priority. The former priority of that task is returned
+ * in old_priority.
+ *
+ * @param[in] id is the thread to extract
+ * @param[in] new_priority is the thread to extract
+ * @param[in] old_priority is the thread to extract
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful and
+ * and *old_priority filled in with the previous previous priority
+ */
+rtems_status_code rtems_task_set_priority(
+ rtems_id id,
+ rtems_task_priority new_priority,
+ rtems_task_priority *old_priority
+);
+
+/**
+ * @brief Gets the current priority of the specified task with respect to the
+ * specified scheduler instance.
+ *
+ * The current priority reflects temporary priority adjustments due to locking
+ * protocols, the rate-monotonic period objects on some schedulers and other
+ * mechanisms.
+ *
+ * @param[in] task_id Identifier of the task. Use @ref RTEMS_SELF to select
+ * the executing task.
+ * @param[in] scheduler_id Identifier of the scheduler instance.
+ * @param[out] priority Returns the current priority of the specified task with
+ * respect to the specified scheduler instance.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_ILLEGAL_ON_REMOTE_OBJECT Directive is illegal on remote tasks.
+ * @retval RTEMS_INVALID_ADDRESS The priority parameter is @c NULL.
+ * @retval RTEMS_INVALID_ID Invalid task or scheduler identifier.
+ * @retval RTEMS_NOT_DEFINED The task has no priority within the specified
+ * scheduler instance. This error is only possible on SMP configurations.
+ *
+ * @see rtems_scheduler_ident().
+ */
+rtems_status_code rtems_task_get_priority(
+ rtems_id task_id,
+ rtems_id scheduler_id,
+ rtems_task_priority *priority
+);
+
+/**
+ * @brief RTEMS Start Task
+ *
+ * RTEMS Task Manager
+ *
+ * This routine implements the rtems_task_start directive. The
+ * starting execution point of the task associated with ID is
+ * set to entry_point with the initial argument.
+ */
+rtems_status_code rtems_task_start(
+ rtems_id id,
+ rtems_task_entry entry_point,
+ rtems_task_argument argument
+);
+
+/**
+ * @brief RTEMS Task Wake When
+ *
+ * This routine implements the rtems_task_wake_when directive. The
+ * calling task is blocked until the current time of day is
+ * equal to that indicated by time_buffer.
+ *
+ * @param[in] time_buffer is the pointer to the time and date structure
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
+ */
+rtems_status_code rtems_task_wake_when(
+ rtems_time_of_day *time_buffer
+);
+
+/**
+ * @brief RTEMS Task Wake After
+ *
+ * This routine implements the rtems_task_wake_after directive. The
+ * calling task is blocked until the indicated number of clock
+ * ticks have occurred.
+ *
+ * @param[in] ticks is the number of ticks to wait
+ * @retval RTEMS_SUCCESSFUL
+ */
+rtems_status_code rtems_task_wake_after(
+ rtems_interval ticks
+);
+
+/**
+ * @brief rtems_task_is_suspended
+ *
+ * This directive returns a status indicating whether or not
+ * the specified task is suspended.
+ */
+rtems_status_code rtems_task_is_suspended(
+ rtems_id id
+);
+
+/**
+ * @brief Gets the processor affinity set of a task.
+ *
+ * @param[in] id Identifier of the task. Use @ref RTEMS_SELF to select the
+ * executing task.
+ * @param[in] cpusetsize Size of the specified affinity set buffer in
+ * bytes. This value must be positive.
+ * @param[out] cpuset The current processor affinity set of the task. A set
+ * bit in the affinity set means that the task can execute on this processor
+ * and a cleared bit means the opposite.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ADDRESS The @a cpuset parameter is @c NULL.
+ * @retval RTEMS_INVALID_ID Invalid task identifier.
+ * @retval RTEMS_INVALID_NUMBER The affinity set buffer is too small for the
+ * current processor affinity set of the task.
+ */
+rtems_status_code rtems_task_get_affinity(
+ rtems_id id,
+ size_t cpusetsize,
+ cpu_set_t *cpuset
+);
+
+/**
+ * @brief Sets the processor affinity set of a task.
+ *
+ * This function will not change the scheduler of the task. The intersection
+ * of the processor affinity set and the set of processors owned by the
+ * scheduler of the task must be non-empty. It is not an error if the
+ * processor affinity set contains processors that are not part of the set of
+ * processors owned by the scheduler instance of the task. A task will simply
+ * not run under normal circumstances on these processors since the scheduler
+ * ignores them. Some locking protocols may temporarily use processors that
+ * are not included in the processor affinity set of the task. It is also not
+ * an error if the processor affinity set contains processors that are not part
+ * of the system.
+ *
+ * @param[in] id Identifier of the task. Use @ref RTEMS_SELF to select the
+ * executing task.
+ * @param[in] cpusetsize Size of the specified affinity set buffer in
+ * bytes. This value must be positive.
+ * @param[in] cpuset The new processor affinity set for the task. A set bit in
+ * the affinity set means that the task can execute on this processor and a
+ * cleared bit means the opposite.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ADDRESS The @a cpuset parameter is @c NULL.
+ * @retval RTEMS_INVALID_ID Invalid task identifier.
+ * @retval RTEMS_INVALID_NUMBER Invalid processor affinity set.
+ */
+rtems_status_code rtems_task_set_affinity(
+ rtems_id id,
+ size_t cpusetsize,
+ const cpu_set_t *cpuset
+);
+
+/**
+ * @brief Gets the scheduler of a task.
+ *
+ * @param[in] task_id Identifier of the task. Use @ref RTEMS_SELF to select
+ * the executing task.
+ * @param[out] scheduler_id Identifier of the scheduler instance.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ADDRESS The @a scheduler_id parameter is @c NULL.
+ * @retval RTEMS_INVALID_ID Invalid task identifier.
+ */
+rtems_status_code rtems_task_get_scheduler(
+ rtems_id task_id,
+ rtems_id *scheduler_id
+);
+
+/**
+ * @brief Sets the scheduler instance of a task.
+ *
+ * Initially, the scheduler instance of a task is set to the scheduler instance
+ * of the task that created it. This directive allows to move a task from its
+ * current scheduler instance to another specified by the scheduler identifier.
+ *
+ * @param[in] task_id Identifier of the task. Use @ref RTEMS_SELF to select
+ * the executing task.
+ * @param[in] scheduler_id Identifier of the scheduler instance.
+ * @param[in] priority The task priority with respect to the new scheduler
+ * instance. The real and initial priority of the task is set to this value.
+ * The initial priority is used by rtems_task_restart() for example.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_ILLEGAL_ON_REMOTE_OBJECT Directive is illegal on remote tasks.
+ * @retval RTEMS_INVALID_ID Invalid task or scheduler identifier.
+ * @retval RTEMS_INVALID_PRIORITY Invalid priority.
+ * @retval RTEMS_RESOURCE_IN_USE The task owns resources which deny a scheduler
+ * change.
+ *
+ * @see rtems_scheduler_ident().
+ */
+rtems_status_code rtems_task_set_scheduler(
+ rtems_id task_id,
+ rtems_id scheduler_id,
+ rtems_task_priority priority
+);
+
+/**
+ * @brief RTEMS Get Self Task Id
+ *
+ * This directive returns the ID of the currently executing task.
+ */
+rtems_id rtems_task_self(void);
+
+/**
+ * @brief Task visitor.
+ *
+ * @param[in] tcb The task control block.
+ * @param[in] arg The visitor argument.
+ *
+ * @retval true Stop the iteration.
+ * @retval false Otherwise.
+ *
+ * @see rtems_task_iterate().
+ */
+typedef bool ( *rtems_task_visitor )( rtems_tcb *tcb, void *arg );
+
+/**
+ * @brief Iterates over all tasks in the system.
+ *
+ * This operation covers all tasks of all APIs.
+ *
+ * Must be called from task context. This operation obtains and releases the
+ * objects allocator lock. The task visitor is called while owning the objects
+ * allocator lock. It is possible to perform blocking operations in the task
+ * visitor, however, take care that no deadlocks via the object allocator lock
+ * can occur.
+ *
+ * @param[in] visitor The task visitor.
+ * @param[in] arg The visitor argument.
+ */
+void rtems_task_iterate(
+ rtems_task_visitor visitor,
+ void *arg
+);
+
+/**
+ * @brief Identifies a scheduler by its name.
+ *
+ * The scheduler name is determined by the scheduler configuration.
+ *
+ * @param[in] name The scheduler name.
+ * @param[out] id The scheduler identifier associated with the name.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ADDRESS The @a id parameter is @c NULL.
+ * @retval RTEMS_INVALID_NAME Invalid scheduler name.
+ */
+rtems_status_code rtems_scheduler_ident(
+ rtems_name name,
+ rtems_id *id
+);
+
+/**
+ * @brief Identifies a scheduler by a processor index.
+ *
+ * @param[in] cpu_index The processor index.
+ * @param[out] id The scheduler identifier associated with the processor index.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ADDRESS The @a id parameter is @c NULL.
+ * @retval RTEMS_INVALID_NAME Invalid processor index.
+ * @retval RTEMS_INCORRECT_STATE The processor index is valid, however, this
+ * processor is not owned by a scheduler.
+ */
+rtems_status_code rtems_scheduler_ident_by_processor(
+ uint32_t cpu_index,
+ rtems_id *id
+);
+
+/**
+ * @brief Identifies a scheduler by a processor set.
+ *
+ * The scheduler is selected according to the highest numbered online processor
+ * in the specified processor set.
+ *
+ * @param[in] cpusetsize Size of the specified processor set buffer in
+ * bytes. This value must be positive.
+ * @param[out] cpuset The processor set to identify the scheduler.
+ * @param[out] id The scheduler identifier associated with the processor set.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ADDRESS The @a id parameter is @c NULL.
+ * @retval RTEMS_INVALID_SIZE Invalid processor set size.
+ * @retval RTEMS_INVALID_NAME The processor set contains no online processor.
+ * @retval RTEMS_INCORRECT_STATE The processor set is valid, however, the
+ * highest numbered online processor in the specified processor set is not
+ * owned by a scheduler.
+ */
+rtems_status_code rtems_scheduler_ident_by_processor_set(
+ size_t cpusetsize,
+ const cpu_set_t *cpuset,
+ rtems_id *id
+);
+
+/**
+ * @brief Gets the set of processors owned by the specified scheduler instance.
+ *
+ * @param[in] scheduler_id Identifier of the scheduler instance.
+ * @param[in] cpusetsize Size of the specified processor set buffer in
+ * bytes. This value must be positive.
+ * @param[out] cpuset The processor set owned by the scheduler. A set bit in
+ * the processor set means that this processor is owned by the scheduler and a
+ * cleared bit means the opposite.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ADDRESS The @a cpuset parameter is @c NULL.
+ * @retval RTEMS_INVALID_ID Invalid scheduler instance identifier.
+ * @retval RTEMS_INVALID_NUMBER The processor set buffer is too small for the
+ * set of processors owned by the scheduler.
+ */
+rtems_status_code rtems_scheduler_get_processor_set(
+ rtems_id scheduler_id,
+ size_t cpusetsize,
+ cpu_set_t *cpuset
+);
+
+/**
+ * @brief Adds a processor to the set of processors owned by the specified
+ * scheduler instance.
+ *
+ * Must be called from task context. This operation obtains and releases the
+ * objects allocator lock.
+ *
+ * @param[in] scheduler_id Identifier of the scheduler instance.
+ * @param[in] cpu_index Index of the processor to add.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID Invalid scheduler instance identifier.
+ * @retval RTEMS_NOT_CONFIGURED The processor is not configured to be used by
+ * the application.
+ * @retval RTEMS_INCORRECT_STATE The processor is configured to be used by
+ * the application, however, it is not online.
+ * @retval RTEMS_RESOURCE_IN_USE The processor is already assigned to a
+ * scheduler instance.
+ */
+rtems_status_code rtems_scheduler_add_processor(
+ rtems_id scheduler_id,
+ uint32_t cpu_index
+);
+
+/**
+ * @brief Removes a processor from set of processors owned by the specified
+ * scheduler instance.
+ *
+ * Must be called from task context. This operation obtains and releases the
+ * objects allocator lock. Removing a processor from a scheduler is a complex
+ * operation that involves all tasks of the system.
+ *
+ * @param[in] scheduler_id Identifier of the scheduler instance.
+ * @param[in] cpu_index Index of the processor to add.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID Invalid scheduler instance identifier.
+ * @retval RTEMS_INVALID_NUMBER The processor is not owned by the specified
+ * scheduler instance.
+ * @retval RTEMS_RESOURCE_IN_USE The set of processors owned by the specified
+ * scheduler instance would be empty after the processor removal and there
+ * exists a non-idle task that uses this scheduler instance as its home
+ * scheduler instance.
+ */
+rtems_status_code rtems_scheduler_remove_processor(
+ rtems_id scheduler_id,
+ uint32_t cpu_index
+);
+
+/**@}*/
+
+/**
+ * This is the API specific information required by each thread for
+ * the RTEMS API to function correctly.
+ *
+ */
+typedef struct {
+ /** This field contains the event control for this task. */
+ Event_Control Event;
+ /** This field contains the system event control for this task. */
+ Event_Control System_event;
+ /** This field contains the Classic API Signal information for this task. */
+ ASR_Information Signal;
+
+ /**
+ * @brief Signal post-switch action in case signals are pending.
+ */
+ Thread_Action Signal_action;
+} RTEMS_API_Control;
+
+/**
+ * @brief _RTEMS_tasks_Initialize_user_tasks_body
+ *
+ * This routine creates and starts all configured user
+ * initialization threads.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * RTEMS Task Manager
+ */
+
+extern void _RTEMS_tasks_Initialize_user_tasks_body( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/tasksimpl.h b/cpukit/include/rtems/rtems/tasksimpl.h
new file mode 100644
index 0000000000..b0432351f3
--- /dev/null
+++ b/cpukit/include/rtems/rtems/tasksimpl.h
@@ -0,0 +1,131 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicTasksImpl
+ *
+ * @brief Classic Tasks Manager Implementation
+ */
+
+/* COPYRIGHT (c) 1989-2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_TASKSIMPL_H
+#define _RTEMS_RTEMS_TASKSIMPL_H
+
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/objectimpl.h>
+#include <rtems/score/schedulerimpl.h>
+#include <rtems/score/threadimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicTasksImpl Classic Tasks Manager Implementation
+ *
+ * @ingroup ClassicTasks
+ *
+ * @{
+ */
+
+/**
+ * The following instantiates the information control block used to
+ * manage this class of objects.
+ */
+extern Thread_Information _RTEMS_tasks_Information;
+
+/**
+ * @brief RTEMS User Task Initialization
+ *
+ * This routine creates and starts all configured user
+ * initialization threads.
+ */
+void _RTEMS_tasks_Initialize_user_tasks( void );
+
+RTEMS_INLINE_ROUTINE Thread_Control *_RTEMS_tasks_Allocate(void)
+{
+ _Objects_Allocator_lock();
+
+ _Thread_Kill_zombies();
+
+ return (Thread_Control *)
+ _Objects_Allocate_unprotected( &_RTEMS_tasks_Information.Objects );
+}
+
+/**
+ * @brief Frees a task control block.
+ *
+ * This routine frees a task control block to the
+ * inactive chain of free task control blocks.
+ */
+RTEMS_INLINE_ROUTINE void _RTEMS_tasks_Free (
+ Thread_Control *the_task
+)
+{
+ _Objects_Free(
+ _Objects_Get_information_id( the_task->Object.id ),
+ &the_task->Object
+ );
+}
+
+/**
+ * @brief Converts the RTEMS API priority to the corresponding SuperCore
+ * priority and validates it.
+ *
+ * The RTEMS API system priority is accepted as valid.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] priority The RTEMS API priority to convert and validate.
+ * @param[out] valid Indicates if the RTEMS API priority is valid and a
+ * corresponding SuperCore priority in the specified scheduler instance
+ * exists.
+ *
+ * @return The corresponding SuperCore priority.
+ */
+RTEMS_INLINE_ROUTINE Priority_Control _RTEMS_Priority_To_core(
+ const Scheduler_Control *scheduler,
+ rtems_task_priority priority,
+ bool *valid
+)
+{
+ *valid = ( priority <= scheduler->maximum_priority );
+
+ return _Scheduler_Map_priority( scheduler, (Priority_Control) priority );
+}
+
+/**
+ * @brief Converts the SuperCore priority to the corresponding RTEMS API
+ * priority.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] priority The SuperCore priority to convert.
+ *
+ * @return The corresponding RTEMS API priority.
+ */
+RTEMS_INLINE_ROUTINE rtems_task_priority _RTEMS_Priority_From_core(
+ const Scheduler_Control *scheduler,
+ Priority_Control priority
+)
+{
+ return (rtems_task_priority)
+ _Scheduler_Unmap_priority( scheduler, priority );
+}
+
+/**@}*/
+
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/rtems/taskmp.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/timer.h b/cpukit/include/rtems/rtems/timer.h
new file mode 100644
index 0000000000..032c49525a
--- /dev/null
+++ b/cpukit/include/rtems/rtems/timer.h
@@ -0,0 +1,384 @@
+/**
+ * @file rtems/rtems/timer.h
+ *
+ * @defgroup ClassicTimer Timers
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Instantiate RTEMS Timer Data
+ *
+ * This include file contains all the constants, structures, and
+ * prototypes associated with the Timer Manager. This manager provides
+ * facilities to configure, initiate, cancel, and delete timers which will
+ * fire at specified intervals of time.
+ *
+ * Directives provided are:
+ *
+ * - create a timer
+ * - get an ID of a timer
+ * - delete a timer
+ * - set timer to fire in context of clock tick
+ * - after a number of ticks have passed
+ * - when a specified date and time has been reached
+ * - initiate the timer server task
+ * - set timer to fire in context of the timer server task
+ * - after a number of ticks have passed
+ * - when a specified date and time has been reached
+ * - reset a timer
+ * - cancel a time
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Copyright (c) 2009, 2016 embedded brains GmbH.
+ *
+ * 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_RTEMS_TIMER_H
+#define _RTEMS_RTEMS_TIMER_H
+
+#include <rtems/rtems/attr.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/tasks.h>
+#include <rtems/rtems/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicTimer Timers
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * This encapsulates functionality related to the Classic API Timer
+ * Manager. This manager provides functionality which allows the
+ * application to schedule the execution of methods at a specified
+ * time in the future. These methods may be scheduled based upon
+ * interval or wall time and may be executed in either the clock tick
+ * ISR or in a special dedicated timer server task.
+ */
+/**@{*/
+
+#define TIMER_CLASS_BIT_TIME_OF_DAY 0x1
+
+#define TIMER_CLASS_BIT_ON_TASK 0x2
+
+#define TIMER_CLASS_BIT_NOT_DORMANT 0x4
+
+/**
+ * The following enumerated type details the classes to which a timer
+ * may belong.
+ */
+typedef enum {
+ /**
+ * This value indicates the timer is currently not in use.
+ */
+ TIMER_DORMANT,
+
+ /**
+ * This value indicates the timer is currently in use as an interval
+ * timer which will fire in the clock tick ISR.
+ */
+ TIMER_INTERVAL = TIMER_CLASS_BIT_NOT_DORMANT,
+
+ /**
+ * This value indicates the timer is currently in use as an interval
+ * timer which will fire in the timer server task.
+ */
+ TIMER_INTERVAL_ON_TASK =
+ TIMER_CLASS_BIT_NOT_DORMANT | TIMER_CLASS_BIT_ON_TASK,
+
+ /**
+ * This value indicates the timer is currently in use as an time of day
+ * timer which will fire in the clock tick ISR.
+ */
+ TIMER_TIME_OF_DAY =
+ TIMER_CLASS_BIT_NOT_DORMANT | TIMER_CLASS_BIT_TIME_OF_DAY,
+
+ /**
+ * This value indicates the timer is currently in use as an time of day
+ * timer which will fire in the timer server task.
+ */
+ TIMER_TIME_OF_DAY_ON_TASK =
+ TIMER_CLASS_BIT_NOT_DORMANT | TIMER_CLASS_BIT_TIME_OF_DAY |
+ TIMER_CLASS_BIT_ON_TASK
+} Timer_Classes;
+
+/**
+ * The following types define a pointer to a timer service routine.
+ */
+typedef void rtems_timer_service_routine;
+
+/**
+ * This type defines the type used to manage and indirectly invoke
+ * Timer Service Routines (TSRs). This defines the prototype and interface
+ * for a function which is to be used as a TSR.
+ */
+typedef rtems_timer_service_routine ( *rtems_timer_service_routine_entry )(
+ rtems_id,
+ void *
+ );
+
+/**
+ * The following records define the control block used to manage
+ * each timer.
+ */
+typedef struct {
+ /** This field is the object management portion of a Timer instance. */
+ Objects_Control Object;
+ /** This field is the Watchdog instance which will be the scheduled. */
+ Watchdog_Control Ticker;
+ /** This field indicates what type of timer this currently is. */
+ Timer_Classes the_class;
+ /** This field is the timer service routine. */
+ rtems_timer_service_routine_entry routine;
+ /** This field is the timer service routine user data. */
+ void *user_data;
+ /** This field is the timer interval in ticks or seconds. */
+ Watchdog_Interval initial;
+ /** This field is the timer start time point in ticks. */
+ Watchdog_Interval start_time;
+ /** This field is the timer stop time point in ticks. */
+ Watchdog_Interval stop_time;
+} Timer_Control;
+
+/**
+ * @brief RTEMS Create Timer
+ *
+ * This routine implements the rtems_timer_create directive. The
+ * timer will have the name name. It returns the id of the
+ * created timer in ID.
+ *
+ * @param[in] name is the timer name
+ * @param[out] id is the pointer to timer id
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
+ */
+rtems_status_code rtems_timer_create(
+ rtems_name name,
+ rtems_id *id
+);
+
+/**
+ * @brief RTEMS Timer Name to Id
+ *
+ * This routine implements the rtems_timer_ident directive.
+ * This directive returns the timer ID associated with name.
+ * If more than one timer is named name, then the timer
+ * to which the ID belongs is arbitrary.
+ *
+ * @param[in] name is the user defined message queue name
+ * @param[in] id is the pointer to timer id
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful and
+ * id filled with the message queue id
+ */
+rtems_status_code rtems_timer_ident(
+ rtems_name name,
+ rtems_id *id
+);
+
+/**
+ * @brief rtems_timer_cancel
+ *
+ * This routine implements the rtems_timer_cancel directive. It is used
+ * to stop the timer associated with ID from firing.
+ */
+rtems_status_code rtems_timer_cancel(
+ rtems_id id
+);
+
+/**
+ * @brief RTEMS Delete Timer
+ *
+ * This routine implements the rtems_timer_delete directive. The
+ * timer indicated by ID is deleted.
+ *
+ * @param[in] id is the timer id
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_timer_delete(
+ rtems_id id
+);
+
+/**
+ * @brief RTEMS Timer Fire After
+ *
+ * This routine implements the rtems_timer_fire_after directive. It
+ * initiates the timer associated with ID to fire in ticks clock ticks.
+ * When the timer fires, the routine will be invoked in the context
+ * of the rtems_clock_tick directive which is normally invoked as
+ * part of servicing a periodic interupt.
+ *
+ * @param[in] id is the timer id
+ * @param[in] ticks is the interval until routine is fired
+ * @param[in] routine is the routine to schedule
+ * @param[in] user_data is the passed as argument to routine when it is fired
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_timer_fire_after(
+ rtems_id id,
+ rtems_interval ticks,
+ rtems_timer_service_routine_entry routine,
+ void *user_data
+);
+
+/**
+ * @brief RTEMS Timer Server Fire After
+ *
+ * This routine implements the rtems_timer_server_fire_after directive. It
+ * initiates the timer associated with ID to fire in ticks clock
+ * ticks. When the timer fires, the routine will be invoked by the
+ * Timer Server in the context of a task NOT IN THE CONTEXT of the
+ * clock tick interrupt.
+ *
+ * @param[in] id is the timer id
+ * @param[in] ticks is the interval until routine is fired
+ * @param[in] routine is the routine to schedule
+ * @param[in] user_data is the passed as argument to routine when it is fired
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_timer_server_fire_after(
+ rtems_id id,
+ rtems_interval ticks,
+ rtems_timer_service_routine_entry routine,
+ void *user_data
+);
+
+/**
+ * @brief RTEMS Timer Fire When
+ *
+ * This routine implements the rtems_timer_fire_when directive. It
+ * initiates the timer associated with ID to fire at wall_time
+ * When the timer fires, the routine will be invoked in the context
+ * of the rtems_clock_tick directive which is normally invoked as
+ * part of servicing a periodic interupt.
+ *
+ * @param[in] id is the timer id
+ * @param[in] wall_time is the time of day to fire timer
+ * @param[in] routine is the routine to schedule
+ * @param[in] user_data is the passed as argument to routine when it is fired
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL if there was not an
+ * error. Otherwise, a status code is returned indicating the
+ * source of the error.
+ */
+rtems_status_code rtems_timer_fire_when(
+ rtems_id id,
+ rtems_time_of_day *wall_time,
+ rtems_timer_service_routine_entry routine,
+ void *user_data
+);
+
+/**
+ * @brief RTEMS Timer Server Fire When Directive
+ *
+ * Timer Manager - RTEMS Timer Server Fire When Directive
+ *
+ * This routine implements the rtems_timer_server_fire_when directive. It
+ * initiates the timer associated with ID to fire at wall_time
+ * When the timer fires, the routine will be invoked by the
+ * Timer Server in the context of a task NOT IN THE CONTEXT of the
+ * clock tick interrupt.
+ */
+rtems_status_code rtems_timer_server_fire_when(
+ rtems_id id,
+ rtems_time_of_day *wall_time,
+ rtems_timer_service_routine_entry routine,
+ void *user_data
+);
+
+/**
+ * @brief RTEMS Timer Reset
+ *
+ * Timer Manager - RTEMS Timer Reset
+ *
+ * This routine implements the rtems_timer_reset directive. It is used
+ * to reinitialize the interval timer associated with ID just as if
+ * rtems_timer_fire_after were re-invoked with the same arguments that
+ * were used to initiate this timer.
+ */
+rtems_status_code rtems_timer_reset(
+ rtems_id id
+);
+
+/**
+ * @brief Initiates the timer server.
+ *
+ * This directive creates and starts the server for task-based timers.
+ * It must be invoked before any task-based timers can be initiated.
+ *
+ * @param priority The timer server task priority.
+ * @param stack_size The stack size in bytes for the timer server task.
+ * @param attribute_set The timer server task attributes.
+ *
+ * @return This method returns RTEMS_SUCCESSFUL if successful and an
+ * error code otherwise.
+ */
+rtems_status_code rtems_timer_initiate_server(
+ rtems_task_priority priority,
+ size_t stack_size,
+ rtems_attribute attribute_set
+);
+
+/**
+ * This is the default value for the priority of the Timer Server.
+ * When given this priority, a special high priority not accessible
+ * via the Classic API is used.
+ */
+#define RTEMS_TIMER_SERVER_DEFAULT_PRIORITY (uint32_t) -1
+
+/**
+ * This is the structure filled in by the timer get information
+ * service.
+ */
+typedef struct {
+ /** This indicates the current type of the timer. */
+ Timer_Classes the_class;
+ /** This indicates the initial requested interval. */
+ Watchdog_Interval initial;
+ /** This indicates the time the timer was initially scheduled. */
+ Watchdog_Interval start_time;
+ /** This indicates the time the timer is scheduled to fire. */
+ Watchdog_Interval stop_time;
+} rtems_timer_information;
+
+/**
+ * @brief RTEMS Get Timer Information
+ *
+ * This routine implements the rtems_timer_get_information directive.
+ * This directive returns information about the timer.
+ *
+ * @param[in] id is the timer id
+ * @param[in] the_info is the pointer to timer information block
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful and
+ * *the_info region information block filled in
+ */
+rtems_status_code rtems_timer_get_information(
+ rtems_id id,
+ rtems_timer_information *the_info
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/timerimpl.h b/cpukit/include/rtems/rtems/timerimpl.h
new file mode 100644
index 0000000000..d8581bfcd8
--- /dev/null
+++ b/cpukit/include/rtems/rtems/timerimpl.h
@@ -0,0 +1,209 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicTimerImpl
+ *
+ * @brief Classic Timer Implementation
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Copyright (c) 2016 embedded brains GmbH.
+ *
+ * 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_RTEMS_TIMER_INL
+#define _RTEMS_RTEMS_TIMER_INL
+
+#include <rtems/rtems/timer.h>
+#include <rtems/score/objectimpl.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/watchdogimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicTimerImpl Classic Timer Implementation
+ *
+ * @ingroup ClassicTimer
+ *
+ * @{
+ */
+
+typedef struct Timer_server_Control {
+ ISR_LOCK_MEMBER( Lock )
+
+ Chain_Control Pending;
+
+ Objects_Id server_id;
+} Timer_server_Control;
+
+/**
+ * @brief Pointer to default timer server control block.
+ *
+ * This value is @c NULL when the default timer server is not initialized.
+ */
+extern Timer_server_Control *volatile _Timer_server;
+
+/**
+ * The following defines the information control block used to manage
+ * this class of objects.
+ */
+extern Objects_Information _Timer_Information;
+
+/**
+ * @brief Timer_Allocate
+ *
+ * This function allocates a timer control block from
+ * the inactive chain of free timer control blocks.
+ */
+RTEMS_INLINE_ROUTINE Timer_Control *_Timer_Allocate( void )
+{
+ return (Timer_Control *) _Objects_Allocate( &_Timer_Information );
+}
+
+/**
+ * @brief Timer_Free
+ *
+ * This routine frees a timer control block to the
+ * inactive chain of free timer control blocks.
+ */
+RTEMS_INLINE_ROUTINE void _Timer_Free (
+ Timer_Control *the_timer
+)
+{
+ _Objects_Free( &_Timer_Information, &the_timer->Object );
+}
+
+RTEMS_INLINE_ROUTINE Timer_Control *_Timer_Get(
+ Objects_Id id,
+ ISR_lock_Context *lock_context
+)
+{
+ return (Timer_Control *) _Objects_Get(
+ id,
+ lock_context,
+ &_Timer_Information
+ );
+}
+
+RTEMS_INLINE_ROUTINE Per_CPU_Control *_Timer_Acquire_critical(
+ Timer_Control *the_timer,
+ ISR_lock_Context *lock_context
+)
+{
+ Per_CPU_Control *cpu;
+
+ cpu = _Watchdog_Get_CPU( &the_timer->Ticker );
+ _Watchdog_Per_CPU_acquire_critical( cpu, lock_context );
+
+ return cpu;
+}
+
+RTEMS_INLINE_ROUTINE void _Timer_Release(
+ Per_CPU_Control *cpu,
+ ISR_lock_Context *lock_context
+)
+{
+ _Watchdog_Per_CPU_release_critical( cpu, lock_context );
+ _ISR_lock_ISR_enable( lock_context );
+}
+
+RTEMS_INLINE_ROUTINE bool _Timer_Is_interval_class(
+ Timer_Classes the_class
+)
+{
+ Timer_Classes mask =
+ TIMER_CLASS_BIT_NOT_DORMANT | TIMER_CLASS_BIT_TIME_OF_DAY;
+
+ return ( the_class & mask ) == TIMER_CLASS_BIT_NOT_DORMANT;
+}
+
+RTEMS_INLINE_ROUTINE bool _Timer_Is_on_task_class(
+ Timer_Classes the_class
+)
+{
+ Timer_Classes mask =
+ TIMER_CLASS_BIT_NOT_DORMANT | TIMER_CLASS_BIT_ON_TASK;
+
+ return ( the_class & mask ) == mask;
+}
+
+RTEMS_INLINE_ROUTINE Per_CPU_Watchdog_index _Timer_Watchdog_header_index(
+ Timer_Classes the_class
+)
+{
+ return ( the_class & TIMER_CLASS_BIT_TIME_OF_DAY );
+}
+
+RTEMS_INLINE_ROUTINE Watchdog_Interval _Timer_Get_CPU_ticks(
+ const Per_CPU_Control *cpu
+)
+{
+ return (Watchdog_Interval) cpu->Watchdog.ticks;
+}
+
+rtems_status_code _Timer_Fire(
+ rtems_id id,
+ rtems_interval interval,
+ rtems_timer_service_routine_entry routine,
+ void *user_data,
+ Timer_Classes the_class,
+ Watchdog_Service_routine_entry adaptor
+);
+
+rtems_status_code _Timer_Fire_after(
+ rtems_id id,
+ rtems_interval ticks,
+ rtems_timer_service_routine_entry routine,
+ void *user_data,
+ Timer_Classes the_class,
+ Watchdog_Service_routine_entry adaptor
+);
+
+rtems_status_code _Timer_Fire_when(
+ rtems_id id,
+ const rtems_time_of_day *wall_time,
+ rtems_timer_service_routine_entry routine,
+ void *user_data,
+ Timer_Classes the_class,
+ Watchdog_Service_routine_entry adaptor
+);
+
+void _Timer_Cancel( Per_CPU_Control *cpu, Timer_Control *the_timer );
+
+void _Timer_Routine_adaptor( Watchdog_Control *the_watchdog );
+
+void _Timer_server_Routine_adaptor( Watchdog_Control *the_watchdog );
+
+RTEMS_INLINE_ROUTINE void _Timer_server_Acquire_critical(
+ Timer_server_Control *timer_server,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Acquire( &timer_server->Lock, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Timer_server_Release_critical(
+ Timer_server_Control *timer_server,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Release( &timer_server->Lock, lock_context );
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtems/types.h b/cpukit/include/rtems/rtems/types.h
new file mode 100644
index 0000000000..82c0edd3c3
--- /dev/null
+++ b/cpukit/include/rtems/rtems/types.h
@@ -0,0 +1,235 @@
+/**
+ * @file
+ *
+ * @defgroup ClassicTypes Types
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Types used by Classic API.
+ */
+
+/* COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_RTEMS_TYPES_H
+#define _RTEMS_RTEMS_TYPES_H
+
+/*
+ * RTEMS basic type definitions
+ */
+
+#include <stdint.h>
+#include <rtems/score/heap.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/rtems/modes.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mpci.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ClassicRTEMS
+ */
+/**@{**/
+
+#ifdef RTEMS_DEPRECATED_TYPES
+/**
+ * @brief Single precision float type.
+ *
+ * @deprecated Use @c float instead.
+ */
+typedef single_precision rtems_single;
+
+/**
+ * @brief Double precision float type.
+ *
+ * @deprecated Use @c double instead.
+ */
+typedef double_precision rtems_double;
+
+/**
+ * @brief RTEMS boolean type.
+ *
+ * @deprecated Use @c bool instead
+ */
+typedef boolean rtems_boolean;
+#endif
+
+/**
+ * @brief Classic API @ref ClassicRTEMSSubSecObjectNames "object name" type.
+ *
+ * Contains the name of a Classic API object. It is an unsigned 32-bit integer
+ * which can be treated as a numeric value or initialized using
+ * rtems_build_name() to contain four ASCII characters.
+ */
+typedef uint32_t rtems_name;
+
+/**
+ * @brief Used to manage and manipulate
+ * @ref ClassicRTEMSSubSecObjectIdentifiers "RTEMS object identifiers".
+ */
+typedef Objects_Id rtems_id;
+
+/**
+ * @brief Invalid object identifier value.
+ *
+ * No object can have this identifier value.
+ */
+#define RTEMS_ID_NONE OBJECTS_ID_NONE
+
+/**
+ * @brief Public name for task context area.
+ */
+typedef Context_Control rtems_context;
+
+#if (CPU_HARDWARE_FP == TRUE) || (CPU_SOFTWARE_FP == TRUE)
+/**
+ * @brief Public name for task floating point context area.
+ */
+typedef Context_Control_fp rtems_context_fp;
+#endif
+
+#if (CPU_ISR_PASSES_FRAME_POINTER == TRUE)
+/**
+ * @brief Defines the format of the interrupt stack frame as it appears to a
+ * user ISR.
+ *
+ * This data structure is only provided if the interrupt stack frame is passed
+ * to the ISR handler.
+ *
+ * @see rtems_interrupt_catch().
+ */
+typedef CPU_Interrupt_frame rtems_interrupt_frame;
+#endif
+
+/**
+ * @brief Information structure returned by the Heap Handler via the Region
+ * Manager.
+ */
+typedef Heap_Information_block region_information_block;
+
+/**
+ * @brief Used to manage and manipulate intervals specified by
+ * @ref ClassicRTEMSSecTime "clock ticks".
+ */
+typedef Watchdog_Interval rtems_interval;
+
+/**
+ * @brief Represents the CPU usage per thread.
+ *
+ * When using nanoseconds granularity timing, RTEMS may internally use a
+ * variety of representations.
+ */
+typedef struct timespec rtems_thread_cpu_usage_t;
+
+/**
+ * @brief Data structure to manage and manipulate calendar
+ * @ref ClassicRTEMSSecTime "time".
+ */
+typedef struct {
+ /**
+ * @brief Year, A.D.
+ */
+ uint32_t year;
+ /**
+ * @brief Month, 1 .. 12.
+ */
+ uint32_t month;
+ /**
+ * @brief Day, 1 .. 31.
+ */
+ uint32_t day;
+ /**
+ * @brief Hour, 0 .. 23.
+ */
+ uint32_t hour;
+ /**
+ * @brief Minute, 0 .. 59.
+ */
+ uint32_t minute;
+ /**
+ * @brief Second, 0 .. 59.
+ */
+ uint32_t second;
+ /**
+ * @brief Elapsed ticks between seconds.
+ */
+ uint32_t ticks;
+} rtems_time_of_day;
+
+/**
+ * @brief Task mode type.
+ */
+typedef Modes_Control rtems_mode;
+
+/*
+ * MPCI related entries
+ */
+#if defined(RTEMS_MULTIPROCESSING)
+/**
+ * @brief Set of MPCI packet classes which are internally dispatched to the
+ * managers.
+ */
+typedef MP_packet_Classes rtems_mp_packet_classes;
+
+/**
+ * @brief Prefix found at the beginning of each MPCI packet sent between nodes.
+ */
+typedef MP_packet_Prefix rtems_packet_prefix;
+
+/**
+ * @brief Indirect pointer to the initialization entry point for an MPCI
+ * handler.
+ */
+typedef MPCI_initialization_entry rtems_mpci_initialization_entry;
+
+/**
+ * @brief Indirect pointer to the get_packet entry point for an MPCI handler.
+ */
+typedef MPCI_get_packet_entry rtems_mpci_get_packet_entry;
+
+/**
+ * @brief Indirect pointer to the return_packet entry point for an MPCI
+ * handler.
+ */
+typedef MPCI_return_packet_entry rtems_mpci_return_packet_entry;
+
+/**
+ * @brief Indirect pointer to the send_packet entry point for an MPCI handler.
+ */
+typedef MPCI_send_entry rtems_mpci_send_packet_entry;
+
+/**
+ * @brief Indirect pointer to the receive entry point for an MPCI handler.
+ */
+typedef MPCI_receive_entry rtems_mpci_receive_packet_entry;
+
+/**
+ * @brief Return type from every MPCI handler routine.
+ */
+typedef MPCI_Entry rtems_mpci_entry;
+
+/**
+ * @brief Structure which is used to configure an MPCI handler.
+ */
+typedef MPCI_Control rtems_mpci_table;
+
+#endif
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/rtemsdialer.h b/cpukit/include/rtems/rtemsdialer.h
new file mode 100644
index 0000000000..611986b802
--- /dev/null
+++ b/cpukit/include/rtems/rtemsdialer.h
@@ -0,0 +1,24 @@
+
+#ifndef DIALER_H
+#define DIALER_H
+
+/* define constant mode values */
+#define DIALER_INIT 0
+#define DIALER_CONNECT 1
+#define DIALER_WELCOME 2
+#define DIALER_DISCONNECT 3
+
+/* define constant return values */
+#define DIALER_SUCCESS 0
+#define DIALER_INVALIDARG 1
+#define DIALER_UNEXPECTED 2
+#define DIALER_TIMEOUT 3
+#define DIALER_CMDFAILED 4
+
+/* define typedef for dialer function prototype */
+typedef int (*dialerfp)(int tty, int mode, char *pScript);
+
+/* declare default chat program dialer */
+extern int chatmain(int tty, int mode, char *pScript);
+
+#endif
diff --git a/cpukit/include/rtems/rtemspppd.h b/cpukit/include/rtems/rtemspppd.h
new file mode 100644
index 0000000000..a6c8d0b398
--- /dev/null
+++ b/cpukit/include/rtems/rtemspppd.h
@@ -0,0 +1,49 @@
+/*
+ * COPYRIGHT (c) 2001, Michael Siers <mikes@poliac.com>.
+ * Poliac Research, Burnsville, Minnesota USA.
+ * COPYRIGHT (c) 2001, On-Line Applications Research Corporation (OAR).
+ *
+ * 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 RTEMSPPPD_H
+#define RTEMSPPPD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* define hook function identifiers */
+#define RTEMS_PPPD_LINKUP_HOOK 1
+#define RTEMS_PPPD_LINKDOWN_HOOK 2
+#define RTEMS_PPPD_IPUP_HOOK 3
+#define RTEMS_PPPD_IPDOWN_HOOK 4
+#define RTEMS_PPPD_ERROR_HOOK 5
+#define RTEMS_PPPD_EXIT_HOOK 6
+
+/* define hook function pointer prototype */
+typedef void (*rtems_pppd_hookfunction)(void);
+typedef int (*rtems_pppd_dialerfunction)(int tty, int mode, char *pScript);
+
+
+/* define pppd function prototyes */
+int rtems_pppd_initialize(void);
+int rtems_pppd_terminate(void);
+int rtems_pppd_reset_options(void);
+int rtems_pppd_set_hook(int id, rtems_pppd_hookfunction hookfp);
+int rtems_pppd_set_dialer(rtems_pppd_dialerfunction dialerfp);
+int rtems_pppd_set_option(const char *pOption, const char *pValue);
+int rtems_pppd_connect(void);
+int rtems_pppd_disconnect(void);
+
+struct rtems_bsdnet_ifconfig;
+
+int rtems_ppp_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/dlfcn-shell.h b/cpukit/include/rtems/rtl/dlfcn-shell.h
new file mode 100644
index 0000000000..9383577d25
--- /dev/null
+++ b/cpukit/include/rtems/rtl/dlfcn-shell.h
@@ -0,0 +1,17 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+#if !defined(_DLFCN_SHELL_H_)
+#define _DLFCN_SHELL_H_
+
+int shell_dlopen (int argc, char* argv[]);
+int shell_dlclose (int argc, char* argv[]);
+int shell_dlsym (int argc, char* argv[]);
+int shell_dlcall (int argc, char* argv[]);
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rap-shell.h b/cpukit/include/rtems/rtl/rap-shell.h
new file mode 100644
index 0000000000..c2d9112c0f
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rap-shell.h
@@ -0,0 +1,14 @@
+/*
+ * COPYRIGHT (c) 2013 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+#if !defined(_RAP_SHELL_H_)
+#define _RAP_SHELL_H_
+
+int shell_rap (int argc, char* argv[]);
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rap.h b/cpukit/include/rtems/rtl/rap.h
new file mode 100644
index 0000000000..0b86553e2b
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rap.h
@@ -0,0 +1,115 @@
+/*
+ * COPYRIGHT (c) 2013 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rap
+ *
+ * @brief RTEMS Application Loader
+ *
+ * This is the RTEMS Application loader for files in the RAP format.
+ */
+
+#if !defined (_RAP_H_)
+#define _RAP_H_
+
+#include <rtems.h>
+#include <rtems/chain.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup rtems_rap RTEMS Application Loader
+ *
+ * The module implements an application loader for files in the RAP format. The
+ * RAP format is:
+ *
+ * <header>
+ * <compressed container>
+ *
+ * The compressed container is a stream of ELF relocatable object files.
+ *
+ * TBD.
+ */
+
+/**
+ * The module iterator handle.
+ */
+typedef bool (*rtems_rap_iterator_t) (void* handle);
+
+/**
+ * Load an application.
+ *
+ * @param name The name of the application file.
+ * @return bool True if the module loads else an error.
+ */
+bool rtems_rap_load (const char* name, int mode, int argc, const char* argv[]);
+
+/**
+ * Unload an application.
+ *
+ * @param obj The application descriptor.
+ * @retval true The application file has been unloaded.
+ * @retval false The application could not be unloaded.
+ */
+bool rtems_rap_unload (const char* name);
+
+/**
+ * Find the application handle given a file name.
+ *
+ * @param name The name of the application file. It can be absolute or
+ * relative. Relative names can the basename with an extension.
+ * @retval NULL No application file with that name found.
+ * @return void* The application descriptor.
+ */
+void* rtems_rap_find (const char* name);
+
+/**
+ * Run an iterator over the modules calling the iterator function.
+ *
+ * @param iterator The iterator function.
+ * @retval true The iterator function returned did not return false.
+ * @retval false The iterator function returned false..
+ */
+bool rtems_rap_iterate (rtems_rap_iterator_t iterator);
+
+/**
+ * Return the name of the module given a handle.
+ *
+ * @param handle The module handle.
+ * @return const char* The name of the module if the handle is valid else it
+ * is NULL.
+ */
+const char* rtems_rap_name (void* handle);
+
+/**
+ * Return the DL handle used to load the module given the RAP handle.
+ *
+ * @param handle The module handle.
+ * @return void* The DL handle returned by the dlopen call.
+ */
+void* rtems_rap_dl_handle (void* handle);
+
+/**
+ * Get the last error message clearing it. This call is not thread safe is
+ * multiple threads are loading object files at the same time. This call
+ * follows the model provided by the dlopen family of calls.
+ *
+ * @param message Pointer to a buffer to copy the message into.
+ * @param max_message The maximum message that can be copied.
+ * @return int The last error number.
+ */
+int rtems_rap_get_error (char* message, size_t max_message);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-allocator.h b/cpukit/include/rtems/rtl/rtl-allocator.h
new file mode 100644
index 0000000000..e8044ee1e8
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-allocator.h
@@ -0,0 +1,181 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Allocator
+ */
+
+#if !defined (_RTEMS_RTL_ALLOCATOR_H_)
+#define _RTEMS_RTL_ALLOCATOR_H_
+
+#include <stdbool.h>
+
+#include "rtl-indirect-ptr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Define the types of allocation the loader requires.
+ *
+ * @note It is best to use the object tag for general memory allocation and to
+ * leave the tags with specific access properties to the module data
+ */
+enum rtems_rtl_alloc_tags_e {
+ RTEMS_RTL_ALLOC_OBJECT, /**< A generic memory object. */
+ RTEMS_RTL_ALLOC_SYMBOL, /**< Memory used for symbols. */
+ RTEMS_RTL_ALLOC_EXTERNAL, /**< Memory used for external symbols. */
+ RTEMS_RTL_ALLOC_READ, /**< The memory is read only. */
+ RTEMS_RTL_ALLOC_READ_WRITE, /**< The memory is read and write. */
+ RTEMS_RTL_ALLOC_READ_EXEC /**< The memory is read and executable. */
+};
+
+/**
+ * The allocator tag type.
+ */
+typedef enum rtems_rtl_alloc_tags_e rtems_rtl_alloc_tag_t;
+
+/**
+ * The number of tags.
+ */
+#define RTEMS_RTL_ALLOC_TAGS ((size_t) (RTEMS_RTL_ALLOC_READ_EXEC + 1))
+
+/**
+ * Allocator handler handles all RTL allocations. It can be hooked and
+ * overridded for customised allocation schemes or memory maps.
+ *
+ * @param allocation If true the request is to allocate memory else free.
+ * @param tag The type of allocation request.
+ * @param address Pointer to the memory address. If an allocation the value is
+ * unspecific on entry and the allocated address or NULL on
+ * exit. The NULL value means the allocation failed. If a delete
+ * or free request the memory address is the block to free. A
+ * free request of NULL is silently ignored.
+ * @param size The size of the allocation if an allocation request and
+ * not used if deleting or freeing a previous allocation.
+ */
+typedef void (*rtems_rtl_allocator_t)(bool allocate,
+ rtems_rtl_alloc_tag_t tag,
+ void** address,
+ size_t size);
+
+/**
+ * The allocator data.
+ */
+struct rtems_rtl_alloc_data_s {
+ /**< The memory allocator handler. */
+ rtems_rtl_allocator_t allocator;
+ /**< The indirect pointer chains. */
+ rtems_chain_control indirects[RTEMS_RTL_ALLOC_TAGS];
+};
+
+typedef struct rtems_rtl_alloc_data_s rtems_rtl_alloc_data_t;
+
+/**
+ * Initialise the allocate data.
+ *
+ * @param data The data to initialise.
+ */
+void rtems_rtl_alloc_initialise (rtems_rtl_alloc_data_t* data);
+
+/**
+ * The Runtime Loader allocator new allocates new memory and optionally clear
+ * the memory if requested.
+ *
+ * @param tag The type of allocation request.
+ * @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_new (rtems_rtl_alloc_tag_t tag, size_t size, bool zero);
+
+/**
+ * The Runtime Loader allocator delete deletes allocated memory.
+ *
+ * @param tag The type of allocation request.
+ * @param address The memory address to delete. A NULL is ignored.
+ */
+void rtems_rtl_alloc_del (rtems_rtl_alloc_tag_t tag, void* address);
+
+/**
+ * Hook the Runtime Loader allocatior. A handler can call the previous handler
+ * in the chain to use it for specific tags. The default handler uses the
+ * system heap. Do not unhook your handler if memory it allocates has not been
+ * returned.
+ *
+ * @param handler The handler to use as the allocator.
+ * @return rtems_rtl_alloc_handler_t The previous handler.
+ */
+rtems_rtl_allocator_t rtems_rtl_alloc_hook (rtems_rtl_allocator_t handler);
+
+/**
+ * Allocate memory to an indirect handle.
+ *
+ * @param tag The type of allocation request.
+ * @param handle The handle to allocate the memory to.
+ * @param size The size of the allocation.
+ */
+void rtems_rtl_alloc_indirect_new (rtems_rtl_alloc_tag_t tag,
+ rtems_rtl_ptr_t* handle,
+ size_t size);
+
+/**
+ * Free memory from an indirect handle.
+ *
+ * @param tag The type of allocation request.
+ * @param handle The handle to free the memory from.
+ */
+void rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag_t tag,
+ rtems_rtl_ptr_t* handle);
+
+/**
+ * Allocate the memory for a module given the size of the text, const, data and
+ * bss sections. If any part of the allocation fails the no memory is
+ * allocated.
+ *
+ * @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_new (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.
+ * @param const_base Pointer to the const base pointer.
+ * @param eh_base Pointer to the eh base pointer.
+ * @param data_base Pointer to the data base pointer.
+ * @param bss_base Pointer to the bss base pointer.
+ */
+void rtems_rtl_alloc_module_del (void** text_base, void** const_base,
+ void** eh_base, void** data_base,
+ void** bss_base);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-fwd.h b/cpukit/include/rtems/rtl/rtl-fwd.h
new file mode 100644
index 0000000000..4641ad5d5e
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-fwd.h
@@ -0,0 +1,33 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker ELF Headers
+ */
+
+#if !defined (_RTEMS_RTL_FWD_H_)
+#define _RTEMS_RTL_FWD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * The forward declaration of the obj structure.
+ */
+struct rtems_rtl_data_s;
+typedef struct rtems_rtl_data_s rtems_rtl_data_t;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-indirect-ptr.h b/cpukit/include/rtems/rtl/rtl-indirect-ptr.h
new file mode 100644
index 0000000000..81503a3b45
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-indirect-ptr.h
@@ -0,0 +1,235 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Indirect Pointer Management allows memory
+ * compaction in the allocator.
+ */
+
+#if !defined (_RTEMS_RTL_INDIRECT_PTR_H_)
+#define _RTEMS_RTL_INDIRECT_PTR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <rtems/chain.h>
+
+/**
+ * The RTL Indirect pointer.
+ */
+struct rtems_rtl_ptr_s {
+ rtems_chain_node node; /**< Indirect pointers are held on lists. */
+ void* pointer; /**< The actual pointer. */
+};
+
+typedef struct rtems_rtl_ptr_s rtems_rtl_ptr_t;
+
+/**
+ * The RTL Indirect size and pointer.
+ */
+struct rtems_rtl_sptr_s {
+ rtems_rtl_ptr_t ptr; /**< The indirect pointer. */
+ size_t size; /**< The size of the memory block. */
+};
+
+typedef struct rtems_rtl_sptr_s rtems_rtl_sptr_t;
+
+/**
+ * A chain of indirect pointers for users to chain in applications.
+ *
+ * @note The chain the pointer is on is internal to the allocator and cannot be
+ * used by applications.
+ */
+struct rtems_rtl_ptr_chain_s {
+ rtems_chain_node node; /**< Chain of indirect pointers. */
+ rtems_rtl_ptr_t ptr; /**< The indirect pointer. */
+};
+
+typedef struct rtems_rtl_ptr_chain_s rtems_rtl_ptr_chain_t;
+
+/**
+ * A chain of indirect sized pointers for users to chain in applications.
+ *
+ * @note The chain the pointer is on is internal to the allocator and cannot be
+ * used by applications.
+ */
+struct rtems_rtl_sptr_chain_s {
+ rtems_chain_node node; /**< Chain of indirect pointers. */
+ rtems_rtl_sptr_t ptr; /**< The indirect pointer. */
+};
+
+typedef struct rtems_rtl_sptr_chain_s rtems_rtl_sptr_chain_t;
+
+/**
+ * Get the pointer given an indirect handle.
+ *
+ * @param handle The handle the pointer is returned from.
+ * @return void* The pointer held in the handle.
+ */
+static inline void* rtems_rtl_ptr_get (rtems_rtl_ptr_t* handle)
+{
+ return handle->pointer;
+}
+
+/**
+ * Set the pointer given an indirect handle and the pointer.
+ *
+ * @param handle The handle the pointer is returned from.
+ * @param pointer The pointer to set in the handle.
+ */
+static inline void rtems_rtl_ptr_set (rtems_rtl_ptr_t* handle, void* pointer)
+{
+ handle->pointer = pointer;
+}
+
+/**
+ * Initialise the indirect handle.
+ *
+ * @param handle The handle to initialise.
+ */
+static inline void rtems_rtl_ptr_init (rtems_rtl_ptr_t* handle)
+{
+ rtems_chain_set_off_chain (&handle->node);
+ handle->pointer = NULL;
+}
+
+/**
+ * Is the indirect handle NULL ?
+ *
+ * @param handle The handle to test.
+ * @return bool True if the pointer is NULL.
+ */
+static inline bool rtems_rtl_ptr_null (rtems_rtl_ptr_t* handle)
+{
+ return handle->pointer == NULL;
+}
+
+/**
+ * Move the allocated pointer from one handle to another. The source handle is
+ * cleared and removed from the list of handles.
+ *
+ * @param src The source handle to move the pointer from.
+ * @param dst The destination handle to receive the pointer.
+ */
+static inline void rtems_rtl_ptr_move (rtems_rtl_ptr_t* dst, rtems_rtl_ptr_t* src)
+{
+ /*
+ * We do not know which chain the src handle resides on so insert the dst
+ * handle after the src handle then extract the src handle.
+ */
+ rtems_chain_insert_unprotected (&src->node, &dst->node);
+ rtems_chain_extract_unprotected (&src->node);
+ dst->pointer = src->pointer;
+ rtems_rtl_ptr_init (src);
+}
+
+/**
+ * Return the pointer as the type provided.
+ *
+ * @param _h The handle.
+ * @param _t The type.
+ */
+#define rtems_rtl_ptr_type_get(_h, _t) ((_t*) rtems_rtl_ptr_get (_h))
+
+/**
+ * Get the pointer given an indirect handle.
+ *
+ * @param handle The handle the pointer is returned from.
+ * @return void* The pointer held in the handle.
+ */
+static inline void* rtems_rtl_sptr_get (rtems_rtl_sptr_t* handle)
+{
+ return rtems_rtl_ptr_get (&handle->ptr);
+}
+
+/**
+ * Set the pointer given an indirect handle and the pointer.
+ *
+ * @param handle The handle the pointer is returned from.
+ * @param pointer The pointer to set in the handle.
+ */
+static inline void rtems_rtl_sptr_set (rtems_rtl_sptr_t* handle, void* pointer)
+{
+ rtems_rtl_ptr_set (&handle->ptr, pointer);
+}
+
+/**
+ * Initialise the indirect handle.
+ *
+ * @param handle The handle to initialise.
+ */
+static inline void rtems_rtl_sptr_init (rtems_rtl_sptr_t* handle)
+{
+ rtems_rtl_ptr_init (&handle->ptr);
+ handle->size = 0;
+}
+
+/**
+ * Is the indirect handle NULL ?
+ *
+ * @param handle The handle to test.
+ * @return bool True if the pointer is NULL.
+ */
+static inline bool rtems_rtl_sptr_null (rtems_rtl_sptr_t* handle)
+{
+ return rtems_rtl_ptr_null (&handle->ptr);
+}
+
+/**
+ * Move the allocated pointer from one handle to another. The source handle is
+ * cleared and removed from the list of handles.
+ *
+ * @param src The source handle to move the pointer from.
+ * @param dst The destination handle to receive the pointer.
+ */
+static inline void rtems_rtl_sptr_move (rtems_rtl_sptr_t* dst, rtems_rtl_sptr_t* src)
+{
+ rtems_rtl_ptr_move (&dst->ptr, &src->ptr);
+ dst->size = src->size;
+ src->size = 0;
+}
+
+/**
+ * Get the size.
+ *
+ * @param handle The handle to get the size from.
+ * @return size_t The size_t.
+ */
+static inline size_t rtems_rtl_sptr_get_size (rtems_rtl_sptr_t* handle)
+{
+ return handle->size;
+}
+
+/**
+ * Set the size.
+ *
+ * @param handle The handle to set the size.
+ * @param size The size to set..
+ */
+static inline void rtems_rtl_sptr_set_size (rtems_rtl_sptr_t* handle, size_t size)
+{
+ handle->size = size;
+}
+
+/**
+ * Return the pointer as the type provided.
+ *
+ * @param _h The handle.
+ * @param _t The type.
+ */
+#define rtems_rtl_sptr_type_get(_h, _t) ((_t*) rtems_rtl_sptr_get (_h))
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-obj-cache.h b/cpukit/include/rtems/rtl/rtl-obj-cache.h
new file mode 100644
index 0000000000..8eacdd316b
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-obj-cache.h
@@ -0,0 +1,132 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object File cache buffers a section of the
+ * object file in a buffer to localise read performance.
+ *
+ * This is a simple object file cache that holds a buffer of data from the
+ * offset in the file the read is requested from. Writes are not supported.
+ *
+ * The cache holds the file descriptor, the offset into the file and the amount
+ * of valid data in the cache. If the file is ever modified the user of the
+ * cache to responsible for flushing the cache. For example the cache should be
+ * flused if the file is closed.
+ *
+ * The cache can return by reference or by value. By reference allow access to
+ * the cache buffer. Do not modify the cache's data. By value will copy the
+ * requested data into the user supplied buffer.
+ *
+ * The read by reference call allows you to probe the file's data. For example
+ * a string in an object file can be an unknown length. You can request a read
+ * up to the cache's size by reference. The code will attempt to have this data
+ * in the buffer. If there is not enough data in the file the length will be
+ * modifed to reflect this.
+ *
+ * You can have more than one cache for a single file all looking at different
+ * parts of the file.
+ */
+
+#if !defined (_RTEMS_RTL_OBJ_CACHE_H_)
+#define _RTEMS_RTL_OBJ_CACHE_H_
+
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * The buffer cache.
+ */
+typedef struct rtems_rtl_obj_cache_s
+{
+ int fd; /**< The file descriptor of the data in the cache. */
+ size_t file_size; /**< The size of the file. */
+ off_t offset; /**< The base offset of the buffer. */
+ size_t size; /**< The size of the cache. */
+ size_t level; /**< The amount of data in the cache. A file can be
+ * smaller than the cache file. */
+ uint8_t* buffer; /**< The buffer */
+} rtems_rtl_obj_cache_t;
+
+/**
+ * Open a cache allocating a single buffer of the size passed. The default
+ * state of the cache is flushed. No already open checks are made.
+ *
+ * @param cache The cache to initialise.
+ * @param size The size of the cache.
+ * @retval true The cache is open.
+ * @retval false The cache is not open. The RTL error is set.
+ */
+bool rtems_rtl_obj_cache_open (rtems_rtl_obj_cache_t* cache, size_t size);
+
+/**
+ * Close a cache.
+ *
+ * @param cache The cache to close.
+ */
+void rtems_rtl_obj_cache_close (rtems_rtl_obj_cache_t* cache);
+
+/**
+ * Flush the cache. Any further read will read the data from the file.
+ *
+ * @param cache The cache to flush.
+ */
+void rtems_rtl_obj_cache_flush (rtems_rtl_obj_cache_t* cache);
+
+/**
+ * Read data by reference. The length contains the amount of data that should
+ * be available in the cache and referenced by the buffer handle. It must be
+ * less than or equal to the size of the cache. This call will return the
+ * amount of data that is available. It can be less than you ask if the offset
+ * and size is past the end of the file.
+ *
+ * @param cache The cache to reference data from.
+ * @param fd The file descriptor. Must be an open file.
+ * @param offset The offset in the file to reference the data to.
+ * @param buffer The location to reference the data from.
+ * @param length The length of data to reference. Can be modified to a
+ * lesser value and true is still returned so check it.
+ * @retval true The data referenced is in the cache.
+ * @retval false The read failed and the RTL error has been set.
+ */
+bool rtems_rtl_obj_cache_read (rtems_rtl_obj_cache_t* cache,
+ int fd,
+ off_t offset,
+ void** buffer,
+ size_t* length);
+
+/**
+ * Read data by value. The data is copied to the user supplied buffer.
+ *
+ * @param cache The cache to read the data from.
+ * @param fd The file descriptor. Must be an open file.
+ * @param offset The offset in the file to read the data from.
+ * @param buffer The location the data is written into.
+ * @param length The length of data to read.
+ * @retval true The data has been read from the cache.
+ * @retval false The read failed and the RTL error has been set.
+ */
+bool rtems_rtl_obj_cache_read_byval (rtems_rtl_obj_cache_t* cache,
+ int fd,
+ off_t offset,
+ void* buffer,
+ size_t length);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-obj-comp.h b/cpukit/include/rtems/rtl/rtl-obj-comp.h
new file mode 100644
index 0000000000..34bfa6ffa1
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-obj-comp.h
@@ -0,0 +1,122 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object File Compression manages a
+ * compressed stream of data.
+ *
+ * This is a simple interface to the object file cache to stream data from
+ * from a compressed object file. There is no ability to seek with the
+ * data from a compressed file. The module exists to allocate the output
+ * buffer when the loader starts and use the cache buffers will have been
+ * allocated.
+ */
+
+#if !defined (_RTEMS_RTL_OBJ_COMP_H_)
+#define _RTEMS_RTL_OBJ_COMP_H_
+
+#include <rtems/rtl/rtl-obj-cache.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * The amount of input data read at a time from the file.
+ */
+#define RTEMS_RTL_DECOMP_INPUT_SIZE (256)
+
+/**
+ * The types of supported compression.
+ */
+#define RTEMS_RTL_COMP_NONE (0)
+#define RTEMS_RTL_COMP_LZ77 (1)
+
+/**
+ * The compressed file.
+ */
+typedef struct rtems_rtl_obj_cpmp_s
+{
+ rtems_rtl_obj_cache_t* cache; /**< The cache provides the input
+ * buffer. */
+ int fd; /**< The file descriptor. */
+ int compression; /**< The type of compression. */
+ off_t offset; /**< The base offset of the buffer. */
+ size_t size; /**< The size of the output buffer. */
+ size_t level; /**< The amount of data in the buffer. */
+ uint8_t* buffer; /**< The buffer */
+ uint32_t read; /**< The amount of data read. */
+} rtems_rtl_obj_comp_t;
+
+/**
+ * Return the input level.
+ */
+static inline uint32_t rtems_rtl_obj_comp_input (rtems_rtl_obj_comp_t* comp)
+{
+ return comp->read;
+}
+
+/**
+ * Open a compressor allocating the output buffer.
+ *
+ * @param comp The compressor to initialise.
+ * @param size The size of the compressor's output buffer.
+ * @retval true The compressor is open.
+ * @retval false The compressor is not open. The RTL error is set.
+ */
+bool rtems_rtl_obj_comp_open (rtems_rtl_obj_comp_t* comp,
+ size_t size);
+
+/**
+ * Close a compressor.
+ *
+ * @param comp The compressor to close.
+ */
+void rtems_rtl_obj_comp_close (rtems_rtl_obj_comp_t* comp);
+
+/**
+ * Set the cache and offset in the file the compressed stream starts.
+ *
+ * @param comp The compressor to set the offset in.
+ * @param cache The cache to read the file in by.
+ * @param fd The file descriptor. Must be an open file.
+ * @param compression The type of compression being streamed.
+ * @param offset The offset in the file the compressed stream starts.
+ */
+void rtems_rtl_obj_comp_set (rtems_rtl_obj_comp_t* comp,
+ rtems_rtl_obj_cache_t* cache,
+ int fd,
+ int compression,
+ off_t offset);
+
+/**
+ * Read decompressed data. The length contains the amount of data that should
+ * be available in the cache and referenced by the buffer handle. It must be
+ * less than or equal to the size of the cache. This call will return the
+ * amount of data that is available. It can be less than you ask if the offset
+ * and size is past the end of the file.
+ *
+ * @param comp The compressor to read data from.
+ * @param buffer The buffer the output is written too.
+ * @param length The length of data to read. Can be modified to a
+ * lesser value and true is still returned so check it.
+ * @retval true The data referenced is in the cache.
+ * @retval false The read failed and the RTL error has been set.
+ */
+bool rtems_rtl_obj_comp_read (rtems_rtl_obj_comp_t* comp,
+ void* buffer,
+ size_t length);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-obj-fwd.h b/cpukit/include/rtems/rtl/rtl-obj-fwd.h
new file mode 100644
index 0000000000..2c53244316
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-obj-fwd.h
@@ -0,0 +1,39 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker ELF Headers
+ */
+
+#if !defined (_RTEMS_RTL_OBJ_FWD_H_)
+#define _RTEMS_RTL_OBJ_FWD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * The forward declaration of the obj section structure.
+ */
+struct rtems_rtl_obj_sect_s;
+typedef struct rtems_rtl_obj_sect_s rtems_rtl_obj_sect_t;
+
+/**
+ * The forward declaration of the obj structure.
+ */
+struct rtems_rtl_obj_s;
+typedef struct rtems_rtl_obj_s rtems_rtl_obj_t;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-obj.h b/cpukit/include/rtems/rtl/rtl-obj.h
new file mode 100644
index 0000000000..6a35a72822
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-obj.h
@@ -0,0 +1,635 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object Support.
+ */
+
+#if !defined (_RTEMS_RTL_OBJ_H_)
+#define _RTEMS_RTL_OBJ_H_
+
+#include <rtems.h>
+#include <rtems/chain.h>
+#include <rtems/rtl/rtl-sym.h>
+#include <rtems/rtl/rtl-unresolved.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Loader format flags.
+ */
+#define RTEMS_RTL_FMT_ELF (1 << 0)
+#define RTEMS_RTL_FMT_COMP (1 << 1)
+#define RTEMS_RTL_FMT_PRIVATE (1 << 16)
+
+/**
+ * Loader format definition.
+ */
+typedef struct rtems_rtl_loader_format_s
+{
+ /**
+ * The format label. This can be used to determine and manage
+ * specific formats.
+ */
+ const char* label;
+
+ /**
+ * The format flags.
+ */
+ uint32_t flags;
+} rtems_rtl_loader_format_t;
+
+/**
+ * The type of the format loader check handler. This handler checks the format
+ * and if it is detected as suitable it returns true.
+ */
+typedef bool (*rtems_rtl_loader_check) (rtems_rtl_obj_t* obj, int fd);
+
+/**
+ * The type of the format loader load handler. This handler loads the specific
+ * format.
+ */
+typedef bool (*rtems_rtl_loader_load) (rtems_rtl_obj_t* obj, int fd);
+
+/**
+ * The type of the format loader unload handler. This handler unloads the
+ * specific format.
+ */
+typedef bool (*rtems_rtl_loader_unload) (rtems_rtl_obj_t* obj);
+
+/**
+ * The type of the format loader signature handler. This handler checks the
+ * format signature.
+ */
+typedef rtems_rtl_loader_format_t* (*rtems_rtl_loader_sig) (void);
+
+/**
+ * Table for supported loadable formats.
+ */
+typedef struct rtems_rtl_loader_table_s
+{
+ rtems_rtl_loader_check check; /**< The check handler. */
+ rtems_rtl_loader_load load; /**< The loader. */
+ rtems_rtl_loader_unload unload; /**< The unloader. */
+ rtems_rtl_loader_sig signature; /**< The loader's signature. */
+} rtems_rtl_loader_table_t;
+
+/**
+ * Flags for the various section types.
+ */
+#define RTEMS_RTL_OBJ_SECT_TEXT (1 << 0) /**< Section holds program text. */
+#define RTEMS_RTL_OBJ_SECT_CONST (1 << 1) /**< Section holds program text. */
+#define RTEMS_RTL_OBJ_SECT_DATA (1 << 2) /**< Section holds program data. */
+#define RTEMS_RTL_OBJ_SECT_BSS (1 << 3) /**< Section holds program bss. */
+#define RTEMS_RTL_OBJ_SECT_EH (1 << 4) /**< Section holds exception data. */
+#define RTEMS_RTL_OBJ_SECT_REL (1 << 5) /**< Section holds relocation records. */
+#define RTEMS_RTL_OBJ_SECT_RELA (1 << 6) /**< Section holds relocation addend
+ * records. */
+#define RTEMS_RTL_OBJ_SECT_SYM (1 << 7) /**< Section holds symbols. */
+#define RTEMS_RTL_OBJ_SECT_STR (1 << 8) /**< Section holds strings. */
+#define RTEMS_RTL_OBJ_SECT_ALLOC (1 << 9) /**< Section allocates runtime memory. */
+#define RTEMS_RTL_OBJ_SECT_LOAD (1 << 10) /**< Section is loaded from object file. */
+#define RTEMS_RTL_OBJ_SECT_WRITE (1 << 11) /**< Section is writable, ie data. */
+#define RTEMS_RTL_OBJ_SECT_EXEC (1 << 12) /**< Section is executable. */
+#define RTEMS_RTL_OBJ_SECT_ZERO (1 << 13) /**< Section is preset to zero. */
+#define RTEMS_RTL_OBJ_SECT_LINK (1 << 14) /**< Section is link-ordered. */
+#define RTEMS_RTL_OBJ_SECT_CTOR (1 << 15) /**< Section contains constructors. */
+#define RTEMS_RTL_OBJ_SECT_DTOR (1 << 16) /**< Section contains destructors. */
+#define RTEMS_RTL_OBJ_SECT_LOCD (1 << 17) /**< Section has been located. */
+
+/**
+ * Section types mask.
+ */
+#define RTEMS_RTL_OBJ_SECT_TYPES (RTEMS_RTL_OBJ_SECT_TEXT | \
+ RTEMS_RTL_OBJ_SECT_CONST | \
+ RTEMS_RTL_OBJ_SECT_DATA | \
+ RTEMS_RTL_OBJ_SECT_BSS | \
+ RTEMS_RTL_OBJ_SECT_EH)
+
+/**
+ * An object file is made up of sections and the can be more than
+ * one of a specific type of sections. All sections and grouped
+ * together in memory.
+ */
+struct rtems_rtl_obj_sect_s
+{
+ rtems_chain_node node; /**< The node's link in the chain. */
+ int section; /**< The section number. */
+ const char* name; /**< The section's name. */
+ size_t size; /**< The size of the section in memory. */
+ off_t offset; /**< Offset into the object file. Relative to
+ * the start of the object file. */
+ uint32_t alignment; /**< Alignment of this section. */
+ int link; /**< Section link field. */
+ int info; /**< Secfion info field. */
+ uint32_t flags; /**< The section's flags. */
+ void* base; /**< The base address of the section in
+ * memory. */
+ int load_order; /**< Order we load sections. */
+};
+
+/**
+ * Object file descriptor flags.
+ */
+#define RTEMS_RTL_OBJ_LOCKED (1 << 0) /**< Lock the object file so it cannot
+ * be unloaded. */
+#define RTEMS_RTL_OBJ_UNRESOLVED (1 << 1) /**< The object file has unresolved
+ * external symbols. */
+
+/**
+ * RTL Object. There is one for each object module loaded plus one for the base
+ * kernel image.
+ */
+struct rtems_rtl_obj_s
+{
+ rtems_chain_node link; /**< The node's link in the chain. */
+ uint32_t flags; /**< The status of the object file. */
+ uint32_t users; /**< 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_rtl_obj_sym_t* local_table; /**< Local symbol table. */
+ size_t local_syms; /**< Local symbol count. */
+ size_t local_size; /**< Local symbol memory usage. */
+ rtems_rtl_obj_sym_t* global_table; /**< Global symbol table. */
+ size_t global_syms; /**< Global symbol count. */
+ size_t global_size; /**< Global symbol memory usage. */
+ uint32_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. */
+ 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. */
+ 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. */
+ struct link_map* linkmap; /**< For GDB. */
+ void* loader; /**< The file details specific to a loader. */
+};
+
+/**
+ * A section handler is called once for each section that needs to be
+ * processed by this handler.
+ *
+ * @param obj The object file's descriptor the section belongs too.
+ * @param fd The file descriptor of the object file beling loaded.
+ * @param sect The section the handler is being invoked to handle.
+ * @param data A user supplied data variable.
+ * @retval true The operation was successful.
+ * @retval false The operation failed and the RTL has been set.
+ */
+typedef bool (*rtems_rtl_obj_sect_handler_t)(rtems_rtl_obj_t* obj,
+ int fd,
+ rtems_rtl_obj_sect_t* sect,
+ void* data);
+
+/**
+ * Get the file name.
+ *
+ * @param obj The object file.
+ * @return const char* The string.
+ */
+static inline const char* rtems_rtl_obj_fname (const rtems_rtl_obj_t* obj)
+{
+ return obj->fname;
+}
+
+/**
+ * Is the file name valid ?
+ *
+ * @param obj The object file.
+ * @return bool There is a file name
+ */
+static inline bool rtems_rtl_obj_fname_valid (const rtems_rtl_obj_t* obj)
+{
+ return obj->fname;
+}
+
+/**
+ * Get the object name.
+ *
+ * @param obj The object file.
+ * @return const char* The string.
+ */
+static inline const char* rtems_rtl_obj_oname (const rtems_rtl_obj_t* obj)
+{
+ return obj->oname;
+}
+
+/**
+ * Is the object name valid ?
+ *
+ * @param obj The object file.
+ * @return bool There is an object name
+ */
+static inline bool rtems_rtl_obj_oname_valid (const rtems_rtl_obj_t* obj)
+{
+ return obj->oname;
+}
+
+/**
+ * Get the archive name.
+ *
+ * @param obj The object file.
+ * @return const char* The string.
+ */
+static inline const char* rtems_rtl_obj_aname (const rtems_rtl_obj_t* obj)
+{
+ return obj->aname;
+}
+
+/**
+ * Is the archive name valid ?
+ *
+ * @param obj The object file.
+ * @return bool There is an archive name
+ */
+static inline bool rtems_rtl_obj_aname_valid (const rtems_rtl_obj_t* obj)
+{
+ return obj->aname;
+}
+
+/**
+ * Is the address inside the text section?
+ *
+ * @param obj The object file.
+ * @return bool There is an archive name
+ */
+static inline bool rtems_rtl_obj_text_inside (const rtems_rtl_obj_t* obj,
+ const void* address)
+{
+ return
+ (address >= obj->text_base) &&
+ (address < (obj->text_base + obj->text_size));
+}
+
+/**
+ * Allocate an object structure on the heap.
+ *
+ * @retval NULL No memory for the object.
+ */
+rtems_rtl_obj_t* rtems_rtl_obj_alloc (void);
+
+/**
+ * Free the object structure and related resources.
+ *
+ * @param obj The object file's descriptor to free.
+ * @retval false The object has dependences.
+ * @retval true The object has been freed.
+ */
+bool rtems_rtl_obj_free (rtems_rtl_obj_t* obj);
+
+/**
+ * Does the object file have unresolved external references ? If it does the
+ * results of executing code is unpredictable.
+ *
+ * @param obj The object file's descriptor.
+ * @retval true The object file has unresolved externals.
+ * @retval false The object file has all external references resolved.
+ */
+bool rtems_rtl_obj_unresolved (rtems_rtl_obj_t* obj);
+
+/**
+ * Parses a filename and returns newly allocated strings with the archive name,
+ * object name, and the object's offset
+ *
+ * @param name The filename of the object
+ * @param aname Address of a string pointer that holds the archive name
+ * @param oname Address of a string pointer that holds the object name
+ * @param ooffset Address of an int that holds the object offset
+ * @retval true The parsing was successful
+ * @retval false The parsing was unsuccessful
+ */
+bool rtems_rtl_parse_name (const char* name,
+ const char** aname,
+ const char** oname,
+ off_t* ooffset);
+
+/**
+ * Check of the name matches the object file's object name.
+ *
+ * @param obj The object file's descriptor.
+ * @param name The name to match.
+ */
+bool rtems_rtl_match_name (rtems_rtl_obj_t* obj, const char* name);
+
+/**
+ * Find an object file on disk that matches the name. The object descriptor is
+ * fill in with the various parts of a name. A name can have archive, object
+ * file and offset components. The search path in the RTL is searched.
+ *
+ * @param obj The object file's descriptor.
+ * @param name The name to locate on disk.
+ * @retval true The file has been found.
+ * @retval false The file could not be located. The RTL error has been set.
+ */
+bool rtems_rtl_obj_find_file (rtems_rtl_obj_t* obj, const char* name);
+
+/**
+ * Add a section to the object descriptor.
+ *
+ * @param obj The object file's descriptor.
+ * @param section The section's index number.
+ * @param name The name of the section.
+ * @param size The size of the section in memory.
+ * @param offset The offset of the section in the object file.
+ * @param alignment The alignment of the section in memory.
+ * @param link The section's link field (from the ELF format).
+ * @param info The section's info field (from the ELF format).
+ * @param flags The section's flags.
+ * @retval true The section has been added.
+ * @retval false The section has not been added. See the RTL error.
+ */
+bool rtems_rtl_obj_add_section (rtems_rtl_obj_t* obj,
+ int section,
+ const char* name,
+ size_t size,
+ off_t offset,
+ uint32_t alignment,
+ int link,
+ int info,
+ uint32_t flags);
+
+/**
+ * Erase the object file descriptor's sections.
+ *
+ * @param obj The object file's descriptor.
+ */
+void rtems_rtl_obj_erase_sections (rtems_rtl_obj_t* obj);
+
+/**
+ * Find the section given a name.
+ *
+ * @param obj The object file's descriptor.
+ * @param name The name of the section to find.
+ * @retval NULL The section was not found.
+ * @return rtems_rtl_obj_sect_t* The named section.
+ */
+rtems_rtl_obj_sect_t* rtems_rtl_obj_find_section (const rtems_rtl_obj_t* obj,
+ const char* name);
+
+/**
+ * Find a section given a section's index number.
+ *
+ * @param obj The object file's descriptor.
+ * @param index The section's index to find.
+ * @retval NULL The section was not found.
+ * @return rtems_rtl_obj_sect_t* The found section.
+ */
+rtems_rtl_obj_sect_t* rtems_rtl_obj_find_section_by_index (const rtems_rtl_obj_t* obj,
+ int index);
+
+/**
+ * The text section size. Only use once all the sections has been added. It
+ * includes alignments between sections that are part of the object's text
+ * area. The consts sections are included in this section.
+ *
+ * @param obj The object file's descriptor.
+ * @return size_t The size of the text area of the object file.
+ */
+size_t rtems_rtl_obj_text_size (const rtems_rtl_obj_t* obj);
+
+/**
+ * The text section alignment for the object file. Only use once all the
+ * sections has been added. The section alignment is the alignment of the first
+ * text type section loaded the text section.
+ *
+ * You can assume the alignment is a positive integral power of 2 if not 0 or
+ * 1. If 0 or 1 then there is no alignment.
+ *
+ * @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_text_alignment (const rtems_rtl_obj_t* obj);
+
+/**
+ * The const section size. Only use once all the sections has been added. It
+ * includes alignments between sections that are part of the object's const
+ * area. The consts sections are included in this section.
+ *
+ * @param obj The object file's descriptor.
+ * @return size_t The size of the const area of the object file.
+ */
+size_t rtems_rtl_obj_const_size (const rtems_rtl_obj_t* obj);
+
+/**
+ * The const section alignment for the object file. Only use once all the
+ * sections has been added. The section alignment is the alignment of the first
+ * const type section loaded the const section.
+ *
+ * You can assume the alignment is a positive integral power of 2 if not 0 or
+ * 1. If 0 or 1 then there is no alignment.
+ *
+ * @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_const_alignment (const rtems_rtl_obj_t* obj);
+
+/**
+ * The eh section size. Only use once all the sections has been added. It
+ * includes alignments between sections that are part of the object's bss area.
+ *
+ * @param obj The object file's descriptor.
+ * @return size_t The size of the bss area of the object file.
+ */
+size_t rtems_rtl_obj_eh_size (const rtems_rtl_obj_t* obj);
+
+/**
+ * The eh section alignment for the object file. Only use once all the sections
+ * has been added. The section alignment is the alignment of the first bss type
+ * section loaded the bss section.
+ *
+ * You can assume the alignment is a positive integral power of 2 if not 0 or
+ * 1. If 0 or 1 then there is no alignment.
+ *
+ * @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_eh_alignment (const rtems_rtl_obj_t* obj);
+
+/**
+ * The data section size. Only use once all the sections has been added. It
+ * includes alignments between sections that are part of the object's data
+ * area.
+ *
+ * @param obj The object file's descriptor.
+ * @return size_t The size of the data area of the object file.
+ */
+size_t rtems_rtl_obj_data_size (const rtems_rtl_obj_t* obj);
+
+/**
+ * The data section alignment for the object file. Only use once all the
+ * sections has been added. The section alignment is the alignment of the first
+ * data type section loaded the data section.
+ *
+ * You can assume the alignment is a positive integral power of 2 if not 0 or
+ * 1. If 0 or 1 then there is no alignment.
+ *
+ * @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_data_alignment (const rtems_rtl_obj_t* obj);
+
+/**
+ * The bss section size. Only use once all the sections has been added. It
+ * includes alignments between sections that are part of the object's bss area.
+ *
+ * @param obj The object file's descriptor.
+ * @return size_t The size of the bss area of the object file.
+ */
+size_t rtems_rtl_obj_bss_size (const rtems_rtl_obj_t* obj);
+
+/**
+ * The bss section alignment for the object file. Only use once all the
+ * sections has been added. The section alignment is the alignment of the first
+ * bss type section loaded the bss section.
+ *
+ * You can assume the alignment is a positive integral power of 2 if not 0 or
+ * 1. If 0 or 1 then there is no alignment.
+ *
+ * @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_bss_alignment (const rtems_rtl_obj_t* obj);
+
+/**
+ * Relocate the object file. The object file's section are parsed for any
+ * relocation type sections.
+ *
+ * @param obj The object file's descriptor.
+ * @param fd The object file's file descriptor.
+ * @param handler The object file's format specific relocation handler.
+ * @param data User specific data handle.
+ * @retval true The object file was relocated.
+ * @retval false The relocation failed. The RTL error is set.
+ */
+bool rtems_rtl_obj_relocate (rtems_rtl_obj_t* obj,
+ int fd,
+ rtems_rtl_obj_sect_handler_t handler,
+ void* data);
+
+/**
+ * Synchronize caches to make code visible to CPU(s)
+ *
+ * @param obj The object file's descriptor.
+ */
+void rtems_rtl_obj_synchronize_cache (rtems_rtl_obj_t* obj);
+
+/**
+ * Relocate an object file's unresolved reference.
+ *
+ * @param rec The unresolved relocation record.
+ * @param sym The unresolved relocation's referenced symbol.
+ * @retval true The object file record was relocated.
+ * @retval false The relocation failed. The RTL error is set.
+ */
+bool rtems_rtl_obj_relocate_unresolved (rtems_rtl_unresolv_reloc_t* reloc,
+ rtems_rtl_obj_sym_t* sym);
+
+/**
+ * Load the symbols from the object file. Only the exported or public symbols
+ * are read into memory and held in the global symbol table.
+ *
+ * @param obj The object file's descriptor.
+ * @param fd The object file's file descriptor.
+ * @param handler The object file's format specific symbol handler.
+ * @param data User specific data handle.
+ * @retval true The object file's symbol where loaded.
+ * @retval false The symbol loading failed. The RTL error is set.
+ */
+bool rtems_rtl_obj_load_symbols (rtems_rtl_obj_t* obj,
+ int fd,
+ rtems_rtl_obj_sect_handler_t handler,
+ void* data);
+
+/**
+ * Load the sections that have been allocated memory in the target. The bss
+ * type section does not load any data, it is set to 0. The text and data
+ * sections read the detault data from the object file into the target memory.
+ *
+ * @param obj The object file's descriptor.
+ * @param fd The object file's file descriptor.
+ * @param handler The object file's format specific load handler.
+ * @param data User specific data handle.
+ * @retval true The object has been sucessfully loaded.
+ * @retval false The load failed. The RTL error has been set.
+ */
+bool rtems_rtl_obj_load_sections (rtems_rtl_obj_t* obj,
+ int fd,
+ rtems_rtl_obj_sect_handler_t handler,
+ void* data);
+
+/**
+ * Invoke the constructors the object has. Constructors are a table of pointers
+ * to "void (*)(void);" where NULL pointers are skipped. The table's size is
+ * taken from the section's size. The objet ELF specific code is responisble
+ * for flagging which sections contain constructors.
+ *
+ * @param obj The object file's descriptor.
+ */
+void rtems_rtl_obj_run_ctors (rtems_rtl_obj_t* obj);
+
+/**
+ * Invoke the destructors the object has. Destructors are a table of pointers
+ * to "void (*)(void);" where NULL pointers are skipped. The table's size is
+ * taken from the section's size. The objet ELF specific code is responisble
+ * for flagging which sections contain destructors.
+ *
+ * @param obj The object file's descriptor.
+ */
+void rtems_rtl_obj_run_dtors (rtems_rtl_obj_t* obj);
+
+/**
+ * Load the object file, reading all sections into memory, symbols and
+ * performing any relocation fixups.
+ *
+ * @param obj The object file's descriptor.
+ * @retval true The object file has been loaded.
+ * @retval false The load failed. The RTL error has been set.
+ */
+bool rtems_rtl_obj_load (rtems_rtl_obj_t* obj);
+
+/**
+ * Unload the object file, erasing all symbols and releasing all memory.
+ *
+ * @param obj The object file's descriptor.
+ * @retval true The object file has been unloaded.
+ * @retval false The unload failed. The RTL error has been set.
+ */
+bool rtems_rtl_obj_unload (rtems_rtl_obj_t* obj);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-sym.h b/cpukit/include/rtems/rtl/rtl-sym.h
new file mode 100644
index 0000000000..fe00da89d7
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-sym.h
@@ -0,0 +1,135 @@
+/*
+ * COPYRIGHT (c) 2012-2014 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object File Symbol Table.
+ */
+
+#if !defined (_RTEMS_RTL_SYM_H_)
+#define _RTEMS_RTL_SYM_H_
+
+#include <rtems.h>
+#include "rtl-obj-fwd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * An object file symbol.
+ */
+typedef struct rtems_rtl_obj_sym_s
+{
+ rtems_chain_node node; /**< The node's link in the chain. */
+ const char* name; /**< The symbol's name. */
+ void* value; /**< The value of the symbol. */
+ uint32_t data; /**< Format specific data. */
+} rtems_rtl_obj_sym_t;
+
+/**
+ * Table of symbols stored in a hash table.
+ */
+typedef struct rtems_rtl_symbols_s
+{
+ rtems_chain_control* buckets;
+ size_t nbuckets;
+} rtems_rtl_symbols_t;
+
+/**
+ * Open a symbol table with the specified number of buckets.
+ *
+ * @param symbols The symbol table to open.
+ * @param buckets The number of buckets in the hash table.
+ * @retval true The symbol is open.
+ * @retval false The symbol table could not created. The RTL
+ * error has the error.
+ */
+bool rtems_rtl_symbol_table_open (rtems_rtl_symbols_t* symbols,
+ size_t buckets);
+
+/**
+ * Close the table and erase the hash table.
+ *
+ * @param symbols Close the symbol table.
+ */
+void rtems_rtl_symbol_table_close (rtems_rtl_symbols_t* symbols);
+
+/**
+ * Add a table of exported symbols to the symbol table.
+ *
+ * The export table is a series of symbol records and each record has two
+ * fields:
+ *
+ * 1. label
+ * 2. address
+ *
+ * The 'label' is an ASCIIZ string of variable length. The address is of size
+ * of an unsigned long for the target running the link editor. The byte order
+ * is defined by the machine type because the table should be built by the
+ * target compiler.
+ *
+ * The table is terminated with a nul string followed by the bytes 0xDE, 0xAD,
+ * 0xBE, and 0xEF. This avoids alignments issues.
+ *
+ * @param obj The object table the symbols are for.
+ * @param esyms The exported symbol table.
+ * @param size The size of the table in bytes.
+ */
+bool rtems_rtl_symbol_global_add (rtems_rtl_obj_t* obj,
+ const unsigned char* esyms,
+ unsigned int size);
+
+/**
+ * Find a symbol given the symbol label in the global symbol table.
+ *
+ * @param name The name as an ASCIIZ string.
+ * @retval NULL No symbol found.
+ * @return rtems_rtl_obj_sym_t* Reference to the symbol.
+ */
+rtems_rtl_obj_sym_t* rtems_rtl_symbol_global_find (const char* name);
+
+/**
+ * Find a symbol given the symbol label in the local object file.
+ *
+ * @param obj The object file to search.
+ * @param name The name as an ASCIIZ string.
+ * @retval NULL No symbol found.
+ * @return rtems_rtl_obj_sym_t* Reference to the symbol.
+ */
+rtems_rtl_obj_sym_t* rtems_rtl_symbol_obj_find (rtems_rtl_obj_t* obj,
+ const char* name);
+
+/**
+ * Add the object file's symbols to the global table.
+ *
+ * @param obj The object file the symbols are to be added.
+ */
+void rtems_rtl_symbol_obj_add (rtems_rtl_obj_t* obj);
+
+/**
+ * Erase the object file's local symbols.
+ *
+ * @param obj The object file the local symbols are to be erased from.
+ */
+void rtems_rtl_symbol_obj_erase_local (rtems_rtl_obj_t* obj);
+
+/**
+ * Erase the object file's symbols.
+ *
+ * @param obj The object file the symbols are to be erased from.
+ */
+void rtems_rtl_symbol_obj_erase (rtems_rtl_obj_t* obj);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-trace.h b/cpukit/include/rtems/rtl/rtl-trace.h
new file mode 100644
index 0000000000..4b93c8c91c
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-trace.h
@@ -0,0 +1,102 @@
+/*
+ * COPYRIGHT (c) 2012-2014 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker ELF Trace Support.
+ */
+
+#if !defined (_RTEMS_RTL_TRACE_H_)
+#define _RTEMS_RTL_TRACE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+/**
+ * Set to 1 to build trace support in to the RTL code.
+ */
+#define RTEMS_RTL_TRACE 1
+
+/**
+ * The type of the mask.
+ */
+typedef uint32_t rtems_rtl_trace_mask;
+
+/**
+ * List of tracing bits for the various parts of the link editor.
+ */
+#define RTEMS_RTL_TRACE_DETAIL (1UL << 0)
+#define RTEMS_RTL_TRACE_WARNING (1UL << 1)
+#define RTEMS_RTL_TRACE_LOAD (1UL << 2)
+#define RTEMS_RTL_TRACE_UNLOAD (1UL << 3)
+#define RTEMS_RTL_TRACE_SECTION (1UL << 4)
+#define RTEMS_RTL_TRACE_SYMBOL (1UL << 5)
+#define RTEMS_RTL_TRACE_RELOC (1UL << 6)
+#define RTEMS_RTL_TRACE_GLOBAL_SYM (1UL << 7)
+#define RTEMS_RTL_TRACE_LOAD_SECT (1UL << 8)
+#define RTEMS_RTL_TRACE_ALLOCATOR (1UL << 9)
+#define RTEMS_RTL_TRACE_UNRESOLVED (1UL << 10)
+#define RTEMS_RTL_TRACE_CACHE (1UL << 11)
+#define RTEMS_RTL_TRACE_ALL (0xffffffffUL & ~(RTEMS_RTL_TRACE_CACHE))
+
+/**
+ * Call to check if this part is bring traced. If RTEMS_RTL_TRACE is defined to
+ * 0 the code is dead code elminiated when built with -Os, -O2, or higher.
+ *
+ * @param mask The part of the API to trace.
+ * @retval true Tracing is active for the mask.
+ * @retval false Do not trace.
+ */
+#if RTEMS_RTL_TRACE
+bool rtems_rtl_trace (rtems_rtl_trace_mask mask);
+#else
+#define rtems_rtl_trace(_m) (0)
+#endif
+
+/**
+ * Set the mask.
+ *
+ * @param mask The mask bits to set.
+ * @return The previous mask.
+ */
+#if RTEMS_RTL_TRACE
+rtems_rtl_trace_mask rtems_rtl_trace_set_mask (rtems_rtl_trace_mask mask);
+#else
+#define rtems_rtl_trace_set_mask(_m)
+#endif
+
+/**
+ * Clear the mask.
+ *
+ * @param mask The mask bits to clear.
+ * @return The previous mask.
+ */
+#if RTEMS_RTL_TRACE
+rtems_rtl_trace_mask rtems_rtl_trace_clear_mask (rtems_rtl_trace_mask mask);
+#else
+#define rtems_rtl_trace_clear_mask(_m)
+#endif
+
+/**
+ * Add shell trace shell command.
+ */
+#if RTEMS_RTL_TRACE
+int rtems_rtl_trace_shell_command (int argc, char *argv[]);
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl-unresolved.h b/cpukit/include/rtems/rtl/rtl-unresolved.h
new file mode 100644
index 0000000000..bd4ce2a215
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl-unresolved.h
@@ -0,0 +1,212 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker Object File Unresolved Relocations Table.
+ *
+ * The unresolved relocation table holds relocations in a loaded object file
+ * which reference unresolved external symbols. The support is needed to allow
+ * dependent object files to load. In the case of dependent object files one
+ * will have unresolved externals until the dependent object file is also
+ * loaded. There is no load order that resolves this.
+ *
+ * The unresolved relocation table is a single table used by all object files
+ * with unresolved symbols. It made of blocks linked together where blocks are
+ * allocated as requiered. The table is always maintained compacted. That is as
+ * relocations are resolved and removed the table is compacted. The only
+ * pointer in the table is the object file poniter. This is used to identify
+ * which object the relocation belongs to. There are no linking or back
+ * pointers in the unresolved relocations table. The table is scanned for each
+ * object file's relocations. This is not fast but the table should be small
+ * and if it happens to grow large you have other more pressing issues to
+ * resolve in your application.
+ *
+ * The table holds two (2) types of records:
+ *
+ * # Symbol name strings.
+ * # Relocations.
+ *
+ * The symbol name a relocation references is held in a specific symbol name
+ * string record in the table the relocation record references. The record
+ * counts the number of references and the string is removed from the table
+ * when the reference count reaches 0. There can be many relocations
+ * referencing the symbol. The strings are referenced by a single 16bit
+ * unsigned integer which is the count of the string in the table.
+ *
+ * The section the relocation is for in the object is the section number. The
+ * relocation data is series of machine word sized fields:
+ *
+ * # Offset in the section.
+ * # Relocation info (format specific)
+ * # Additional format specific data.
+ */
+
+#if !defined (_RTEMS_RTL_UNRESOLVED_H_)
+#define _RTEMS_RTL_UNRESOLVED_H_
+
+#include <rtems.h>
+#include "rtl-obj-fwd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Hack to work around machine size. This needs to be cleaned up
+ * to better support 64bit targets.
+ */
+typedef uint32_t rtems_rtl_word_t;
+
+/**
+ * The types of records in the blocks.
+ */
+typedef enum rtems_rtl_unresolved_rtype_e
+{
+ rtems_rtl_unresolved_empty = 0, /**< The records is empty. Must always be 0 */
+ rtems_rtl_unresolved_name = 1, /**< The record is a name. */
+ rtems_rtl_unresolved_reloc = 2 /**< The record is a relocation record. */
+} rtems_rtl_unresolved_rtype_t;
+
+/**
+ * Unresolved externals symbol names. The names are reference counted and
+ * separate from the relocation records because a number of records could
+ * reference the same symbol name.
+ */
+typedef struct rtems_rtl_unresolv_name_s
+{
+ uint16_t refs; /**< The number of references to this name. */
+ uint16_t length; /**< The length of this name. */
+ const char name[12]; /**< The symbol name. */
+} rtems_rtl_unresolv_name_t;
+
+/**
+ * Unresolved externals symbols require the relocation records to be held
+ * and references.
+ */
+typedef struct rtems_rtl_unresolv_reloc_s
+{
+ rtems_rtl_obj_t* obj; /**< The relocation's object file. */
+ uint16_t flags; /**< Format specific flags. */
+ uint16_t name; /**< The symbol's name. */
+ uint16_t sect; /**< The target section. */
+ rtems_rtl_word_t rel[3]; /**< Relocation record. */
+} rtems_rtl_unresolv_reloc_t;
+
+/**
+ * Unresolved externals records.
+ */
+typedef struct rtems_rtl_unresolv_rec_s
+{
+ rtems_rtl_unresolved_rtype_t type;
+ union
+ {
+ rtems_rtl_unresolv_name_t name; /**< The name, or */
+ rtems_rtl_unresolv_reloc_t reloc; /**< the relocation record. */
+ } rec;
+} rtems_rtl_unresolv_rec_t;
+
+/**
+ * Unresolved blocks.
+ */
+typedef struct rtems_rtl_unresolv_block_s
+{
+ rtems_chain_node link; /**< Blocks are chained. */
+ uint32_t recs; /**< The number of records in the block. */
+ rtems_rtl_unresolv_rec_t rec; /**< The records. More follow. */
+} rtems_rtl_unresolv_block_t;
+
+/**
+ * Unresolved table holds the names and relocations.
+ */
+typedef struct rtems_rtl_unresolved_s
+{
+ uint32_t marker;
+ size_t block_recs; /**< The records per blocks allocated. */
+ rtems_chain_control blocks; /**< List of blocks. */
+} rtems_rtl_unresolved_t;
+
+/**
+ * The iterator function used to iterate over the unresolved table.
+ *
+ * @param rec The current iterator.
+ * @param data The user data.
+ * @retval true The iterator has finished.
+ * @retval false The iterator has not finished. Keep iterating.
+ */
+typedef bool rtems_rtl_unresolved_iterator_t (rtems_rtl_unresolv_rec_t* rec,
+ void* data);
+
+/**
+ * Open an unresolved relocation table.
+ *
+ * @param unresolv The unresolved table to open.
+ * @param block_records The number of records per block allocated.
+ * @retval true The table is open.
+ * @retval false The unresolved relocation table could not created. The RTL
+ * error has the error.
+ */
+bool rtems_rtl_unresolved_table_open (rtems_rtl_unresolved_t* unresolved,
+ size_t block_records);
+
+/**
+ * Close the table and erase the blocks.
+ *
+ * @param unreolved Close the unresolved table.
+ */
+void rtems_rtl_unresolved_table_close (rtems_rtl_unresolved_t* unresolved);
+
+/**
+ * Iterate over the table of unresolved entries.
+ */
+bool rtems_rtl_unresolved_interate (rtems_rtl_unresolved_iterator_t iterator,
+ void* data);
+
+/**
+ * Add a relocation to the list of unresolved relocations.
+ *
+ * @param unresolved The unresolved symbol table.
+ * @param obj The object table the symbols are for.
+ * @param flags Format specific flags.
+ * @param name The symbol name the relocation references.
+ * @param sect The target section number the relocation references.
+ * @param rel The format specific relocation data.
+ * @retval true The relocation has been added.
+ * @retval false The relocation could not be added.
+ */
+bool rtems_rtl_unresolved_add (rtems_rtl_obj_t* obj,
+ const uint16_t flags,
+ const char* name,
+ const uint16_t sect,
+ const rtems_rtl_word_t* rel);
+
+/**
+ * Resolve the unresolved symbols.
+ */
+void rtems_rtl_unresolved_resolve (void);
+
+/**
+ * Remove a relocation from the list of unresolved relocations.
+ *
+ * @param unresolved The unresolved symbol table.
+ * @param obj The object table the symbols are for.
+ * @param esyms The exported symbol table.
+ * @param size The size of the table in bytes.
+ */
+bool rtems_rtl_unresolved_remove (rtems_rtl_obj_t* obj,
+ const char* name,
+ const uint16_t sect,
+ const rtems_rtl_word_t* rel);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/rtl/rtl.h b/cpukit/include/rtems/rtl/rtl.h
new file mode 100644
index 0000000000..fe9a7df081
--- /dev/null
+++ b/cpukit/include/rtems/rtl/rtl.h
@@ -0,0 +1,321 @@
+/*
+ * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+/**
+ * @file
+ *
+ * @ingroup rtems_rtl
+ *
+ * @brief RTEMS Run-Time Linker
+ *
+ * This is the POSIX interface to run-time loading of code into RTEMS.
+ */
+
+#if !defined (_RTEMS_RTL_H_)
+#define _RTEMS_RTL_H_
+
+#include <link.h>
+#include <rtems.h>
+#include <rtems/chain.h>
+
+#include <rtems/rtl/rtl-allocator.h>
+#include <rtems/rtl/rtl-fwd.h>
+#include <rtems/rtl/rtl-obj.h>
+#include <rtems/rtl/rtl-obj-cache.h>
+#include <rtems/rtl/rtl-obj-comp.h>
+#include <rtems/rtl/rtl-unresolved.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup rtems_rtl RTEMS Runtime Link Editor
+ *
+ * The module implements a runtime link editor with the standard dlopen, and
+ * dlclose family of functions.
+ *
+ * The runtime link editor is different to that found on Unix type systems. The
+ * object modules are compiled for PIC or position indepentent code and
+ * therefore require relocating when loaded.
+ *
+ * The object file format is currently ELF and object files can be separate
+ * files or in an archive. Object files in an archive are referenced by
+ * specifing 'archive:object' format. For example 'libfoo.a:bar.o'.
+ */
+
+/**
+ * Macros to glue two tokens.
+ */
+#ifdef __STDC__
+#define RTL_XGLUE(a,b) a##b
+#else
+#define RTL_XGLUE(a,b) a/**/b
+#endif
+
+#define RTL_GLUE(a,b) RTL_XGLUE(a,b)
+
+/**
+ * The number of buckets in the global symbol table.
+ */
+#define RTEMS_RTL_SYMS_GLOBAL_BUCKETS (32)
+
+/**
+ * The number of relocation record per block in the unresolved table.
+ */
+#define RTEMS_RTL_UNRESOLVED_BLOCK_SIZE (64)
+
+/**
+ * The global debugger interface variable.
+ */
+extern struct r_debug _rtld_debug;
+
+/**
+ * Debugger break function. Call when debugging to have it read the _rtld_debug
+ * variable.
+ */
+extern void _rtld_debug_state (void);
+
+/**
+ * The type of constructor/destructor function.
+ */
+typedef void (*rtems_rtl_cdtor_t)(void);
+
+/**
+ * The global RTL data. This structure is allocated on the heap when the first
+ * call to the RTL is made and never released.
+ *
+ * The global symbol table is a hash table held in this structure and the
+ * actual symbols are part of the object's structure. If this is a problem we
+ * could look at a hash table per object file.
+ */
+struct rtems_rtl_data_s
+{
+ rtems_id lock; /**< The RTL lock id */
+ rtems_rtl_alloc_data_t allocator; /**< The allocator data. */
+ rtems_chain_control objects; /**< List if loaded object files. */
+ const char* paths; /**< Search paths for archives. */
+ rtems_rtl_symbols_t globals; /**< Global symbol table. */
+ rtems_rtl_unresolved_t unresolved; /**< Unresolved symbols. */
+ rtems_rtl_obj_t* base; /**< Base object file. */
+ rtems_rtl_obj_cache_t symbols; /**< Symbols object file cache. */
+ rtems_rtl_obj_cache_t strings; /**< Strings object file cache. */
+ rtems_rtl_obj_cache_t relocs; /**< Relocations object file cache. */
+ rtems_rtl_obj_comp_t decomp; /**< The decompression compressor. */
+ int last_errno; /**< Last error number. */
+ char last_error[64]; /**< Last error string. */
+};
+
+/**
+ * Get the RTL data with out locking. This call assumes the RTL is locked.
+ *
+ * @return rtems_rtl_data_t* The RTL data after being locked.
+ * @retval NULL The RTL data is not initialised.
+ */
+rtems_rtl_data_t* rtems_rtl_data (void);
+
+/**
+ * Get the RTL global symbol table with out locking. This call assmes the RTL
+ * is locked.
+ *
+ * @return rtems_rtl_symbols_t* The RTL global symbols after being locked.
+ * @retval NULL The RTL data is not initialised.
+ */
+rtems_rtl_symbols_t* rtems_rtl_global_symbols (void);
+
+/**
+ * Get the RTL resolved table with out locking. This call assmes the RTL
+ * is locked.
+ *
+ * @return rtems_rtl_unresolv_t* The RTL unresolved symbols and reloc records.
+ * @retval NULL The RTL data is not initialised.
+ */
+rtems_rtl_unresolved_t* rtems_rtl_unresolved (void);
+
+/**
+ * Get the RTL symbols, strings, or relocations object file caches. This call
+ * assmes the RTL is locked.
+ *
+ * @param symbols Pointer to the location to set the cache into. Returns NULL
+ * is rtl is not initialised. If NULL is passed in no value set.
+ * @param strings Pointer to the location to set the cache into. Returns NULL
+ * is rtl is not initialised. If NULL is passed in no value set.
+ * @param relocs Pointer to the location to set the cache into. Returns NULL
+ * is rtl is not initialised. If NULL is passed in no value set.
+ */
+void rtems_rtl_obj_caches (rtems_rtl_obj_cache_t** symbols,
+ rtems_rtl_obj_cache_t** strings,
+ rtems_rtl_obj_cache_t** relocs);
+
+/**
+ * Flush all the object file caches.
+ */
+void rtems_rtl_obj_caches_flush (void);
+
+/**
+ * Get the RTL decompressor setting the cache and the offset in the file the
+ * compressed stream starts. This call assmes the RTL is locked.
+ *
+ * @param decomp Pointer to the location to set the compressor into. Returns
+ * NULL is rtl is not initialised.
+ * @param cache The cache to read the file with. Saves needing an extrs buffer.
+ * @param offset The offset in the file the compressed stream starts.
+ */
+void rtems_rtl_obj_comp (rtems_rtl_obj_comp_t** decomp,
+ rtems_rtl_obj_cache_t* cache,
+ int fd,
+ int compression,
+ off_t offset);
+
+/**
+ * Lock the Run-time Linker.
+ *
+ * @return rtems_rtl_data_t* The RTL data after being locked.
+ * @retval NULL The RTL data could not be initialised or locked. Typically this
+ * means the lock could not be created.
+ */
+rtems_rtl_data_t* rtems_rtl_lock (void);
+
+/**
+ * Unlock the Run-time Linker.
+ *
+ * @return True The RTL is unlocked.
+ * @return False The RTL could not be unlocked. Not much you can do.
+ */
+bool rtems_rtl_unlock (void);
+
+/**
+ * Check a pointer is a valid object file descriptor returning the pointer as
+ * that type.
+ *
+ * Assumes the RTL has been locked.
+ *
+ * @param handle Pointer to the object file to be validated.
+ * @return rtl_obj* The object file descriptor. NULL is returned if invalid.
+ */
+rtems_rtl_obj_t* rtems_rtl_check_handle (void* handle);
+
+/**
+ * Find the object given a file name.
+ *
+ * @param name The name of the object file.
+ * @retval NULL No object file with that name found.
+ * @return rtems_rtl_obj_t* The object file descriptor.
+ */
+rtems_rtl_obj_t* rtems_rtl_find_obj (const char* name);
+
+/**
+ * Load an object file into memory relocating it. It will not be resolved
+ * against other symbols in other object files or the base image.
+ *
+ * The name can be a file name for an object file or it can be encoded to
+ * reference an archive of object modules (static library). This encoding is
+ * specific to RTEMS and allows dependences to specify an archive without the
+ * searching overhead normally incurred by linkers locating object files in an
+ * archive. The file name format rules are:
+ *
+ * 1. Absolute file references a specific object file in the architecture
+ * specific location on the file system.
+ *
+ * 2. Relative file references an object format file in the search path.
+ *
+ * 3. Absolute archive and file reference to a specific location in the file
+ * system. The archive and file are encoded as 'archive:file [@@offset]'
+ * where 'archive' is a valid file at the absolute path in the file system,
+ * and 'file' is a contained in the archive, and optionally an offset to
+ * the 'file' in the 'archive'. If no offset is provided the archive is
+ * searched.
+ *
+ * 4. Relative archive and file in the search path. The encoding is the same
+ * as described in item 3 of this list.
+ *
+ * Assumes the RTL has been locked.
+ *
+ * @param name The name of the object file.
+ * @param mode The mode of the load as defined by the dlopen call.
+ * @return rtl_obj* The object file descriptor. NULL is returned if the load fails.
+ */
+rtems_rtl_obj_t* rtems_rtl_load_object (const char* name, int mode);
+
+/**
+ * Unload an object file. This only happens when the user count is 0.
+ *
+ * Assumes the RTL has been locked.
+ *
+ * @param obj The object file descriptor.
+ * @retval true The object file has been unloaded.
+ * @retval false The object file could not be unloaded.
+ */
+bool rtems_rtl_unload_object (rtems_rtl_obj_t* obj);
+
+/**
+ * Run any constructor functions the object file may contain. This call
+ * assumes the linker is unlocked.
+ *
+ * @param obj The object file.
+ */
+void rtems_rtl_run_ctors (rtems_rtl_obj_t* obj);
+
+/**
+ * Get the last error message clearing it. This operation locks the run time
+ * linker and therefore keeps the RTL thread safe but this call is not thread
+ * safe is multiple threads are loading object files at the same time. This
+ * call is provided to map to the dlopen family of calls.
+ *
+ * @param message Pointer to a buffer to copy the message into.
+ * @param max_message The maximum message that can be copied.
+ * @return int The last error number.
+ */
+int rtems_rtl_get_error (char* message, size_t max_message);
+
+/**
+ * Append the path to the search path.
+ *
+ * @param path The path to append.
+ * @retval false The path could not be appended.
+ * @retval true The path was appended.
+ */
+bool rtems_rtl_path_append (const char* path);
+
+/**
+ * Prepend the path to the search path.
+ *
+ * @param path The path to prepend.
+ * @retval false The path could not be prepended.
+ * @retval true The path was prepended.
+ */
+
+bool rtems_rtl_path_prepend (const char* path);
+
+/**
+ * Add an exported symbol table to the global symbol table. This call is
+ * normally used by an object file when loaded that contains a global symbol
+ * table.
+ *
+ * @param esyms The exported symbol table.
+ * @param count The size of the exported symbol table.
+ */
+void rtems_rtl_base_sym_global_add (const unsigned char* esyms,
+ unsigned int count);
+
+/**
+ * Return the object file descriptor for the base image. The object file
+ * descriptor returned is created when the run time linker is initialised.
+ *
+ * Assumes the RTL has been locked.
+ *
+ * @return rtl_obj* The object file descriptor for the base image. NULL is
+ * returned if the load fails.
+ */
+rtems_rtl_obj_t* rtems_rtl_baseimage (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/scheduler.h b/cpukit/include/rtems/scheduler.h
new file mode 100644
index 0000000000..8684b798f7
--- /dev/null
+++ b/cpukit/include/rtems/scheduler.h
@@ -0,0 +1,247 @@
+/**
+ * @file
+ *
+ * @brief Scheduler Configuration API
+ */
+
+/*
+ * Copyright (c) 2014, 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_SAPI_SCHEDULER_H
+#define _RTEMS_SAPI_SCHEDULER_H
+
+#include <rtems/score/scheduler.h>
+
+#define RTEMS_SCHEDULER_CONTEXT_NAME( name ) \
+ _Configuration_Scheduler_ ## name
+
+#if defined(RTEMS_SMP)
+ /* This object doesn't exist and indicates a configuration error */
+ extern const Scheduler_Control RTEMS_SCHEDULER_INVALID_INDEX;
+
+ #define RTEMS_SCHEDULER_ASSIGN_DEFAULT \
+ SCHEDULER_ASSIGN_DEFAULT
+
+ #define RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL \
+ SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL
+
+ #define RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY \
+ SCHEDULER_ASSIGN_PROCESSOR_MANDATORY
+
+ #define RTEMS_SCHEDULER_ASSIGN( index, attr ) \
+ { \
+ ( index ) < RTEMS_ARRAY_SIZE( _Scheduler_Table ) ? \
+ &_Scheduler_Table[ ( index ) ] : &RTEMS_SCHEDULER_INVALID_INDEX, \
+ ( attr ) \
+ }
+
+ #define RTEMS_SCHEDULER_ASSIGN_NO_SCHEDULER { NULL, 0 }
+#endif
+
+/*
+ * This file should be only included in the context of <rtems/confdefs.h>.
+ * Define the scheduler configuration macros only in case the corresponding
+ * configure symbol is defined. This is necessary to prevent invalid workspace
+ * size estimates since we have to account for the per-thread scheduler
+ * information.
+ */
+
+#ifdef CONFIGURE_SCHEDULER_CBS
+ #include <rtems/score/schedulercbs.h>
+
+ #define RTEMS_SCHEDULER_CONTEXT_CBS_NAME( name ) \
+ RTEMS_SCHEDULER_CONTEXT_NAME( CBS_ ## name )
+
+ #define RTEMS_SCHEDULER_CONTEXT_CBS( name ) \
+ static Scheduler_EDF_Context RTEMS_SCHEDULER_CONTEXT_CBS_NAME( name )
+
+ #define RTEMS_SCHEDULER_CONTROL_CBS( name, obj_name ) \
+ { \
+ &RTEMS_SCHEDULER_CONTEXT_CBS_NAME( name ).Base, \
+ SCHEDULER_CBS_ENTRY_POINTS, \
+ SCHEDULER_CBS_MAXIMUM_PRIORITY, \
+ ( obj_name ) \
+ }
+#endif
+
+#ifdef CONFIGURE_SCHEDULER_EDF
+ #include <rtems/score/scheduleredf.h>
+
+ #define RTEMS_SCHEDULER_CONTEXT_EDF_NAME( name ) \
+ RTEMS_SCHEDULER_CONTEXT_NAME( EDF_ ## name )
+
+ #define RTEMS_SCHEDULER_CONTEXT_EDF( name ) \
+ static Scheduler_EDF_Context RTEMS_SCHEDULER_CONTEXT_EDF_NAME( name )
+
+ #define RTEMS_SCHEDULER_CONTROL_EDF( name, obj_name ) \
+ { \
+ &RTEMS_SCHEDULER_CONTEXT_EDF_NAME( name ).Base, \
+ SCHEDULER_EDF_ENTRY_POINTS, \
+ SCHEDULER_EDF_MAXIMUM_PRIORITY, \
+ ( obj_name ) \
+ }
+#endif
+
+#ifdef CONFIGURE_SCHEDULER_EDF_SMP
+ #include <rtems/score/scheduleredfsmp.h>
+
+ #define RTEMS_SCHEDULER_CONTEXT_EDF_SMP_NAME( name ) \
+ RTEMS_SCHEDULER_CONTEXT_NAME( EDF_SMP_ ## name )
+
+ #define RTEMS_SCHEDULER_CONTEXT_EDF_SMP( name, max_cpu_count ) \
+ static struct { \
+ Scheduler_EDF_SMP_Context Base; \
+ Scheduler_EDF_SMP_Ready_queue Ready[ ( max_cpu_count ) + 1 ]; \
+ } RTEMS_SCHEDULER_CONTEXT_EDF_SMP_NAME( name )
+
+ #define RTEMS_SCHEDULER_CONTROL_EDF_SMP( name, obj_name ) \
+ { \
+ &RTEMS_SCHEDULER_CONTEXT_EDF_SMP_NAME( name ).Base.Base.Base, \
+ SCHEDULER_EDF_SMP_ENTRY_POINTS, \
+ SCHEDULER_EDF_MAXIMUM_PRIORITY, \
+ ( obj_name ) \
+ }
+#endif
+
+#ifdef CONFIGURE_SCHEDULER_PRIORITY
+ #include <rtems/score/schedulerpriority.h>
+
+ #define RTEMS_SCHEDULER_CONTEXT_PRIORITY_NAME( name ) \
+ RTEMS_SCHEDULER_CONTEXT_NAME( priority_ ## name )
+
+ #define RTEMS_SCHEDULER_CONTEXT_PRIORITY( name, prio_count ) \
+ static struct { \
+ Scheduler_priority_Context Base; \
+ Chain_Control Ready[ ( prio_count ) ]; \
+ } RTEMS_SCHEDULER_CONTEXT_PRIORITY_NAME( name )
+
+ #define RTEMS_SCHEDULER_CONTROL_PRIORITY( name, obj_name ) \
+ { \
+ &RTEMS_SCHEDULER_CONTEXT_PRIORITY_NAME( name ).Base.Base, \
+ SCHEDULER_PRIORITY_ENTRY_POINTS, \
+ RTEMS_ARRAY_SIZE( \
+ RTEMS_SCHEDULER_CONTEXT_PRIORITY_NAME( name ).Ready \
+ ) - 1, \
+ ( obj_name ) \
+ }
+#endif
+
+#ifdef CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP
+ #include <rtems/score/schedulerpriorityaffinitysmp.h>
+
+ #define RTEMS_SCHEDULER_CONTEXT_PRIORITY_AFFINITY_SMP_NAME( name ) \
+ RTEMS_SCHEDULER_CONTEXT_NAME( priority_affinity_SMP_ ## name )
+
+ #define RTEMS_SCHEDULER_CONTEXT_PRIORITY_AFFINITY_SMP( name, prio_count ) \
+ static struct { \
+ Scheduler_priority_SMP_Context Base; \
+ Chain_Control Ready[ ( prio_count ) ]; \
+ } RTEMS_SCHEDULER_CONTEXT_PRIORITY_AFFINITY_SMP_NAME( name )
+
+ #define RTEMS_SCHEDULER_CONTROL_PRIORITY_AFFINITY_SMP( name, obj_name ) \
+ { \
+ &RTEMS_SCHEDULER_CONTEXT_PRIORITY_AFFINITY_SMP_NAME( name ).Base.Base.Base, \
+ SCHEDULER_PRIORITY_AFFINITY_SMP_ENTRY_POINTS, \
+ RTEMS_ARRAY_SIZE( \
+ RTEMS_SCHEDULER_CONTEXT_PRIORITY_AFFINITY_SMP_NAME( name ).Ready \
+ ) - 1, \
+ ( obj_name ) \
+ }
+#endif
+
+#ifdef CONFIGURE_SCHEDULER_PRIORITY_SMP
+ #include <rtems/score/schedulerprioritysmp.h>
+
+ #define RTEMS_SCHEDULER_CONTEXT_PRIORITY_SMP_NAME( name ) \
+ RTEMS_SCHEDULER_CONTEXT_NAME( priority_SMP_ ## name )
+
+ #define RTEMS_SCHEDULER_CONTEXT_PRIORITY_SMP( name, prio_count ) \
+ static struct { \
+ Scheduler_priority_SMP_Context Base; \
+ Chain_Control Ready[ ( prio_count ) ]; \
+ } RTEMS_SCHEDULER_CONTEXT_PRIORITY_SMP_NAME( name )
+
+ #define RTEMS_SCHEDULER_CONTROL_PRIORITY_SMP( name, obj_name ) \
+ { \
+ &RTEMS_SCHEDULER_CONTEXT_PRIORITY_SMP_NAME( name ).Base.Base.Base, \
+ SCHEDULER_PRIORITY_SMP_ENTRY_POINTS, \
+ RTEMS_ARRAY_SIZE( \
+ RTEMS_SCHEDULER_CONTEXT_PRIORITY_SMP_NAME( name ).Ready \
+ ) - 1, \
+ ( obj_name ) \
+ }
+#endif
+
+#ifdef CONFIGURE_SCHEDULER_STRONG_APA
+ #include <rtems/score/schedulerstrongapa.h>
+
+ #define RTEMS_SCHEDULER_CONTEXT_STRONG_APA_NAME( name ) \
+ RTEMS_SCHEDULER_CONTEXT_NAME( strong_APA_ ## name )
+
+ #define RTEMS_SCHEDULER_CONTEXT_STRONG_APA( name, prio_count ) \
+ static struct { \
+ Scheduler_strong_APA_Context Base; \
+ Chain_Control Ready[ ( prio_count ) ]; \
+ } RTEMS_SCHEDULER_CONTEXT_STRONG_APA_NAME( name )
+
+ #define RTEMS_SCHEDULER_CONTROL_STRONG_APA( name, obj_name ) \
+ { \
+ &RTEMS_SCHEDULER_CONTEXT_STRONG_APA_NAME( name ).Base.Base.Base, \
+ SCHEDULER_STRONG_APA_ENTRY_POINTS, \
+ RTEMS_ARRAY_SIZE( \
+ RTEMS_SCHEDULER_CONTEXT_STRONG_APA_NAME( name ).Ready \
+ ) - 1, \
+ ( obj_name ) \
+ }
+#endif
+
+#ifdef CONFIGURE_SCHEDULER_SIMPLE
+ #include <rtems/score/schedulersimple.h>
+
+ #define RTEMS_SCHEDULER_CONTEXT_SIMPLE_NAME( name ) \
+ RTEMS_SCHEDULER_CONTEXT_NAME( simple_ ## name )
+
+ #define RTEMS_SCHEDULER_CONTEXT_SIMPLE( name ) \
+ static Scheduler_simple_Context \
+ RTEMS_SCHEDULER_CONTEXT_SIMPLE_NAME( name )
+
+ #define RTEMS_SCHEDULER_CONTROL_SIMPLE( name, obj_name ) \
+ { \
+ &RTEMS_SCHEDULER_CONTEXT_SIMPLE_NAME( name ).Base, \
+ SCHEDULER_SIMPLE_ENTRY_POINTS, \
+ SCHEDULER_SIMPLE_MAXIMUM_PRIORITY, \
+ ( obj_name ) \
+ }
+#endif
+
+#ifdef CONFIGURE_SCHEDULER_SIMPLE_SMP
+ #include <rtems/score/schedulersimplesmp.h>
+
+ #define RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP_NAME( name ) \
+ RTEMS_SCHEDULER_CONTEXT_NAME( simple_SMP_ ## name )
+
+ #define RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP( name ) \
+ static Scheduler_simple_SMP_Context \
+ RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP_NAME( name )
+
+ #define RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP( name, obj_name ) \
+ { \
+ &RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP_NAME( name ).Base.Base, \
+ SCHEDULER_SIMPLE_SMP_ENTRY_POINTS, \
+ SCHEDULER_SIMPLE_SMP_MAXIMUM_PRIORITY, \
+ ( obj_name ) \
+ }
+#endif
+
+#endif /* _RTEMS_SAPI_SCHEDULER_H */
diff --git a/cpukit/include/rtems/score/address.h b/cpukit/include/rtems/score/address.h
new file mode 100644
index 0000000000..8f38f7c2dc
--- /dev/null
+++ b/cpukit/include/rtems/score/address.h
@@ -0,0 +1,200 @@
+/**
+ * @file rtems/score/address.h
+ *
+ * @brief Information Required to Manipulate Physical Addresses
+ *
+ * This include file contains the information required to manipulate
+ * physical addresses.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_ADDRESS_H
+#define _RTEMS_SCORE_ADDRESS_H
+
+#include <rtems/score/cpu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreAddress Address Handler
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality which abstracts address
+ * manipulation in a portable manner.
+ */
+/**@{*/
+
+/**
+ * @brief Add offset to an address.
+ *
+ * This function is used to add an @a offset to a @a base address.
+ * It returns the resulting address. This address is typically
+ * converted to an access type before being used further.
+ *
+ * @param[in] base is the base address.
+ * @param[in] offset is the offset to add to @a base.
+ *
+ * @return This method returns the resulting address.
+ */
+RTEMS_INLINE_ROUTINE void *_Addresses_Add_offset (
+ const void *base,
+ uintptr_t offset
+)
+{
+ return (void *)((uintptr_t)base + offset);
+}
+
+/**
+ * @brief Subtract offset from offset.
+ *
+ * This function is used to subtract an @a offset from a @a base
+ * address. It returns the resulting address. This address is
+ * typically converted to an access type before being used further.
+ *
+ * @param[in] base is the base address.
+ * @param[in] offset is the offset to subtract to @a base.
+ *
+ * @return This method returns the resulting address.
+ */
+
+RTEMS_INLINE_ROUTINE void *_Addresses_Subtract_offset (
+ const void *base,
+ uintptr_t offset
+)
+{
+ return (void *)((uintptr_t)base - offset);
+}
+
+/**
+ * @brief Subtract two offsets.
+ *
+ * This function is used to subtract two addresses. It returns the
+ * resulting offset.
+ *
+ * @param[in] left is the address on the left hand side of the subtraction.
+ * @param[in] right is the address on the right hand side of the subtraction.
+ *
+ * @return This method returns the resulting address.
+ *
+ * @note The cast of an address to an uint32_t makes this code
+ * dependent on an addresses being thirty two bits.
+ */
+RTEMS_INLINE_ROUTINE int32_t _Addresses_Subtract (
+ const void *left,
+ const void *right
+)
+{
+ return (int32_t) ((const char *) left - (const char *) right);
+}
+
+/**
+ * @brief Is address aligned.
+ *
+ * This function returns true if the given address is correctly
+ * aligned for this processor and false otherwise. Proper alignment
+ * is based on correctness and efficiency.
+ *
+ * @param[in] address is the address being checked for alignment.
+ *
+ * @retval true The @a address is aligned.
+ * @retval false The @a address is not aligned.
+ */
+RTEMS_INLINE_ROUTINE bool _Addresses_Is_aligned (
+ const void *address
+)
+{
+#if (CPU_ALIGNMENT == 0)
+ return true;
+#else
+ return (((uintptr_t)address % CPU_ALIGNMENT) == 0);
+#endif
+}
+
+/**
+ * @brief Is address in range.
+ *
+ * This function returns true if the given address is within the
+ * memory range specified and false otherwise. base is the address
+ * of the first byte in the memory range and limit is the address
+ * of the last byte in the memory range. The base address is
+ * assumed to be lower than the limit address.
+ *
+ * @param[in] address is the address to check.
+ * @param[in] base is the lowest address of the range to check against.
+ * @param[in] limit is the highest address of the range to check against.
+ *
+ * @retval true The @a address is within the memory range specified
+ * @retval false The @a address is not within the memory range specified.
+ */
+RTEMS_INLINE_ROUTINE bool _Addresses_Is_in_range (
+ const void *address,
+ const void *base,
+ const void *limit
+)
+{
+ return (address >= base && address <= limit);
+}
+
+/**
+ * @brief Align address to nearest multiple of alignment, rounding up.
+ *
+ * This function returns the given address aligned to the given alignment.
+ * If the address already is aligned, or if alignment is 0, the address is
+ * returned as is. The returned address is greater than or equal to the
+ * given address.
+ *
+ * @param[in] address is the address to align.
+ * @param[in] alignment is the boundary for alignment and must be a power of 2
+ *
+ * @return Returns the aligned address.
+ */
+RTEMS_INLINE_ROUTINE void *_Addresses_Align_up(
+ void *address,
+ size_t alignment
+)
+{
+ uintptr_t mask = alignment - (uintptr_t)1;
+ return (void*)(((uintptr_t)address + mask) & ~mask);
+}
+
+/**
+ * @brief Align address to nearest multiple of alignment, truncating.
+ *
+ * This function returns the given address aligned to the given alignment.
+ * If the address already is aligned, or if alignment is 0, the address is
+ * returned as is. The returned address is less than or equal to the
+ * given address.
+ *
+ * @param[in] address is the address to align.
+ * @param[in] alignment is the boundary for alignment and must be a power of 2.
+ *
+ * @return Returns the aligned address.
+ */
+RTEMS_INLINE_ROUTINE void *_Addresses_Align_down(
+ void *address,
+ size_t alignment
+)
+{
+ uintptr_t mask = alignment - (uintptr_t)1;
+ return (void*)((uintptr_t)address & ~mask);
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/apimutex.h b/cpukit/include/rtems/score/apimutex.h
new file mode 100644
index 0000000000..f43edf23f4
--- /dev/null
+++ b/cpukit/include/rtems/score/apimutex.h
@@ -0,0 +1,109 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreAPIMutex
+ *
+ * @brief API Mutex Handler API
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_APIMUTEX_H
+#define _RTEMS_SCORE_APIMUTEX_H
+
+#include <rtems/score/thread.h>
+
+#include <sys/lock.h>
+
+/**
+ * @defgroup ScoreAPIMutex API Mutex Handler
+ *
+ * @ingroup Score
+ *
+ * @brief Provides routines to ensure mutual exclusion on API level.
+ */
+/**@{**/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Control block used to manage each API mutex.
+ */
+typedef struct {
+ /**
+ * A recursive mutex.
+ */
+ struct _Mutex_recursive_Control Mutex;
+
+ /**
+ * @brief The thread life protection state before the outer-most mutex
+ * obtain.
+ */
+ Thread_Life_state previous_thread_life_state;
+} API_Mutex_Control;
+
+/**
+ * @brief Statically initialize an API mutex.
+ */
+#define API_MUTEX_INITIALIZER( name ) \
+ { _MUTEX_RECURSIVE_NAMED_INITIALIZER( name ), 0 }
+
+/**
+ * @brief Acquires the specified API mutex.
+ *
+ * @param[in] mutex The API mutex.
+ */
+void _API_Mutex_Lock( API_Mutex_Control *mutex );
+
+/**
+ * @brief Releases the specified API mutex.
+ *
+ * @param[in] mutex The API mutex.
+ */
+void _API_Mutex_Unlock( API_Mutex_Control *mutex );
+
+/**
+ * @brief Checks if the specified API mutex is owned by the executing thread.
+ *
+ * @param[in] mutex The API mutex.
+ */
+bool _API_Mutex_Is_owner( const API_Mutex_Control *mutex );
+
+/** @} */
+
+/**
+ * @defgroup ScoreAllocatorMutex RTEMS Allocator Mutex
+ *
+ * @ingroup ScoreAPIMutex
+ *
+ * @brief Protection for all memory allocations and deallocations in RTEMS.
+ *
+ * When the APIs all use this for allocation and deallocation protection, then
+ * this possibly should be renamed and moved to a higher level in the
+ * hierarchy.
+ */
+/**@{**/
+
+void _RTEMS_Lock_allocator( void );
+
+void _RTEMS_Unlock_allocator( void );
+
+bool _RTEMS_Allocator_is_owner( void );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/assert.h b/cpukit/include/rtems/score/assert.h
new file mode 100644
index 0000000000..d4432838ce
--- /dev/null
+++ b/cpukit/include/rtems/score/assert.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_ASSERT_H
+#define _RTEMS_SCORE_ASSERT_H
+
+#include <rtems/score/basedefs.h>
+
+#if defined( RTEMS_DEBUG )
+ #include <assert.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @brief Assertion similar to assert() controlled via RTEMS_DEBUG instead of
+ * NDEBUG.
+ */
+#if defined( RTEMS_DEBUG )
+
+ /**
+ * @brief Macro with method name used in assert output
+ *
+ * Given the variations in compilers and standards, we have to poke a bit.
+ *
+ * @note This is based on the code in newlib's assert.h.
+ */
+ #ifndef __RTEMS_ASSERT_FUNCTION
+ /* Use g++'s demangled names in C++. */
+ #if defined __cplusplus && defined __GNUC__
+ #define __RTEMS_ASSERT_FUNCTION __PRETTY_FUNCTION__
+
+ /* C99 requires the use of __func__. */
+ #elif __STDC_VERSION__ >= 199901L
+ #define __RTEMS_ASSERT_FUNCTION __func__
+
+ /* Older versions of gcc don't have __func__ but can use __FUNCTION__. */
+ #elif __GNUC__ >= 2
+ #define __RTEMS_ASSERT_FUNCTION __FUNCTION__
+
+ /* failed to detect __func__ support. */
+ #else
+ #define __RTEMS_ASSERT_FUNCTION ((char *) 0)
+ #endif
+ #endif /* !__RTEMS_ASSERT_FUNCTION */
+
+ #if !defined( RTEMS_SCHEDSIM )
+ /* normal build is newlib. */
+
+ void __assert_func(const char *, int, const char *, const char *)
+ RTEMS_NO_RETURN;
+
+ #define _Assert( _e ) \
+ ( ( _e ) ? \
+ ( void ) 0 : \
+ __assert_func( __FILE__, __LINE__, __RTEMS_ASSERT_FUNCTION, #_e ) )
+
+ #elif defined(__linux__)
+ /* Scheduler simulator has only beed tested on glibc. */
+ #define _Assert( _e ) \
+ ( ( _e ) ? \
+ ( void ) 0 : \
+ __assert_fail( #_e, __FILE__, __LINE__, __RTEMS_ASSERT_FUNCTION ) )
+ #else
+ #error "Implement RTEMS assert support for this C Library"
+ #endif
+
+#else
+ #define _Assert( _e ) ( ( void ) 0 )
+#endif
+
+/**
+ * @brief Like _Assert(), but only armed if RTEMS_SMP is defined.
+ */
+#if defined( RTEMS_SMP )
+ #define _SMP_Assert( _e ) _Assert( _e )
+#else
+ #define _SMP_Assert( _e ) ( ( void ) 0 )
+#endif
+
+/**
+ * @brief Returns true if thread dispatching is allowed.
+ *
+ * Thread dispatching can be repressed via _Thread_Disable_dispatch() or
+ * _ISR_Local_disable().
+ */
+#if defined( RTEMS_DEBUG )
+ bool _Debug_Is_thread_dispatching_allowed( void );
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_ASSERT_H */
diff --git a/cpukit/include/rtems/score/atomic.h b/cpukit/include/rtems/score/atomic.h
new file mode 100644
index 0000000000..526926926f
--- /dev/null
+++ b/cpukit/include/rtems/score/atomic.h
@@ -0,0 +1,156 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreAtomic
+ *
+ * @brief Atomic Operations API
+ */
+
+/*
+ * 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_H
+#define _RTEMS_SCORE_ATOMIC_H
+
+#include <rtems/score/cpuatomic.h>
+
+/**
+ * @defgroup ScoreAtomic Atomic Operations
+ *
+ * @ingroup Score
+ *
+ * @brief Support for atomic operations.
+ *
+ * Atomic operations can be used to implement low-level synchronization
+ * primitives on SMP systems, like spin locks. All atomic operations are
+ * defined in terms of C11 (ISO/IEC 9899:2011) or C++11 (ISO/IEC 14882:2011).
+ * For documentation use the standard documents.
+ *
+ * @{
+ */
+
+typedef CPU_atomic_Uint Atomic_Uint;
+
+typedef CPU_atomic_Ulong Atomic_Ulong;
+
+typedef CPU_atomic_Uintptr Atomic_Uintptr;
+
+typedef CPU_atomic_Flag Atomic_Flag;
+
+typedef CPU_atomic_Order Atomic_Order;
+
+#define ATOMIC_ORDER_RELAXED CPU_ATOMIC_ORDER_RELAXED
+
+#define ATOMIC_ORDER_ACQUIRE CPU_ATOMIC_ORDER_ACQUIRE
+
+#define ATOMIC_ORDER_RELEASE CPU_ATOMIC_ORDER_RELEASE
+
+#define ATOMIC_ORDER_ACQ_REL CPU_ATOMIC_ORDER_ACQ_REL
+
+#define ATOMIC_ORDER_SEQ_CST CPU_ATOMIC_ORDER_SEQ_CST
+
+#define ATOMIC_INITIALIZER_UINT( value ) CPU_ATOMIC_INITIALIZER_UINT( value )
+
+#define ATOMIC_INITIALIZER_ULONG( value ) CPU_ATOMIC_INITIALIZER_ULONG( value )
+
+#define ATOMIC_INITIALIZER_UINTPTR( value ) CPU_ATOMIC_INITIALIZER_UINTPTR( value )
+
+#define ATOMIC_INITIALIZER_FLAG CPU_ATOMIC_INITIALIZER_FLAG
+
+#define _Atomic_Fence( order ) _CPU_atomic_Fence( order )
+
+#define _Atomic_Init_uint( obj, desired ) \
+ _CPU_atomic_Init_uint( obj, desired )
+
+#define _Atomic_Init_ulong( obj, desired ) \
+ _CPU_atomic_Init_ulong( obj, desired )
+
+#define _Atomic_Init_uintptr( obj, desired ) \
+ _CPU_atomic_Init_uintptr( obj, desired )
+
+#define _Atomic_Load_uint( obj, order ) \
+ _CPU_atomic_Load_uint( obj, order )
+
+#define _Atomic_Load_ulong( obj, order ) \
+ _CPU_atomic_Load_ulong( obj, order )
+
+#define _Atomic_Load_uintptr( obj, order ) \
+ _CPU_atomic_Load_uintptr( obj, order )
+
+#define _Atomic_Store_uint( obj, desr, order ) \
+ _CPU_atomic_Store_uint( obj, desr, order )
+
+#define _Atomic_Store_ulong( obj, desr, order ) \
+ _CPU_atomic_Store_ulong( obj, desr, order )
+
+#define _Atomic_Store_uintptr( obj, desr, order ) \
+ _CPU_atomic_Store_uintptr( obj, desr, order )
+
+#define _Atomic_Fetch_add_uint( obj, arg, order ) \
+ _CPU_atomic_Fetch_add_uint( obj, arg, order )
+
+#define _Atomic_Fetch_add_ulong( obj, arg, order ) \
+ _CPU_atomic_Fetch_add_ulong( obj, arg, order )
+
+#define _Atomic_Fetch_add_uintptr( obj, arg, order ) \
+ _CPU_atomic_Fetch_add_uintptr( obj, arg, order )
+
+#define _Atomic_Fetch_sub_uint( obj, arg, order ) \
+ _CPU_atomic_Fetch_sub_uint( obj, arg, order )
+
+#define _Atomic_Fetch_sub_ulong( obj, arg, order ) \
+ _CPU_atomic_Fetch_sub_ulong( obj, arg, order )
+
+#define _Atomic_Fetch_sub_uintptr( obj, arg, order ) \
+ _CPU_atomic_Fetch_sub_uintptr( obj, arg, order )
+
+#define _Atomic_Fetch_or_uint( obj, arg, order ) \
+ _CPU_atomic_Fetch_or_uint( obj, arg, order )
+
+#define _Atomic_Fetch_or_ulong( obj, arg, order ) \
+ _CPU_atomic_Fetch_or_ulong( obj, arg, order )
+
+#define _Atomic_Fetch_or_uintptr( obj, arg, order ) \
+ _CPU_atomic_Fetch_or_uintptr( obj, arg, order )
+
+#define _Atomic_Fetch_and_uint( obj, arg, order ) \
+ _CPU_atomic_Fetch_and_uint( obj, arg, order )
+
+#define _Atomic_Fetch_and_ulong( obj, arg, order ) \
+ _CPU_atomic_Fetch_and_ulong( obj, arg, order )
+
+#define _Atomic_Fetch_and_uintptr( obj, arg, order ) \
+ _CPU_atomic_Fetch_and_uintptr( obj, arg, order )
+
+#define _Atomic_Exchange_uint( obj, desr, order ) \
+ _CPU_atomic_Exchange_uint( obj, desr, order )
+
+#define _Atomic_Exchange_ulong( obj, desr, order ) \
+ _CPU_atomic_Exchange_ulong( obj, desr, order )
+
+#define _Atomic_Exchange_uintptr( obj, desr, order ) \
+ _CPU_atomic_Exchange_uintptr( obj, desr, order )
+
+#define _Atomic_Compare_exchange_uint( obj, expected, desired, succ, fail ) \
+ _CPU_atomic_Compare_exchange_uint( obj, expected, desired, succ, fail )
+
+#define _Atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail ) \
+ _CPU_atomic_Compare_exchange_ulong( obj, expected, desired, succ, fail )
+
+#define _Atomic_Compare_exchange_uintptr( obj, expected, desired, succ, fail ) \
+ _CPU_atomic_Compare_exchange_uintptr( obj, expected, desired, succ, fail )
+
+#define _Atomic_Flag_clear( obj, order ) \
+ _CPU_atomic_Flag_clear( obj, order )
+
+#define _Atomic_Flag_test_and_set( obj, order ) \
+ _CPU_atomic_Flag_test_and_set( obj, order )
+
+/** @} */
+
+#endif /* _RTEMS_SCORE_ATOMIC_H */
diff --git a/cpukit/include/rtems/score/basedefs.h b/cpukit/include/rtems/score/basedefs.h
new file mode 100644
index 0000000000..4e48d226e8
--- /dev/null
+++ b/cpukit/include/rtems/score/basedefs.h
@@ -0,0 +1,415 @@
+/**
+ * @file
+ *
+ * @ingroup Score
+ *
+ * @brief Basic Definitions
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2007.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Copyright (c) 2010, 2017 embedded brains GmbH.
+ *
+ * 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_BASEDEFS_H
+#define _RTEMS_BASEDEFS_H
+
+/**
+ * @defgroup ScoreBaseDefs Basic Definitions
+ *
+ * @ingroup Score
+ */
+/**@{*/
+
+#include <rtems/score/cpuopts.h>
+
+#ifndef ASM
+ #include <stddef.h>
+ #include <stdbool.h>
+ #include <stdint.h>
+#endif
+
+#ifndef TRUE
+ /**
+ * This ensures that RTEMS has TRUE defined in all situations.
+ */
+ #define TRUE 1
+#endif
+
+#ifndef FALSE
+ /**
+ * This ensures that RTEMS has FALSE defined in all situations.
+ */
+ #define FALSE 0
+#endif
+
+#if TRUE == FALSE
+ #error "TRUE equals FALSE"
+#endif
+
+/**
+ * The following (in conjunction with compiler arguments) are used
+ * to choose between the use of static inline functions and macro
+ * functions. The static inline implementation allows better
+ * type checking with no cost in code size or execution speed.
+ */
+#ifdef __GNUC__
+ #define RTEMS_INLINE_ROUTINE static __inline__
+#else
+ #define RTEMS_INLINE_ROUTINE static inline
+#endif
+
+/**
+ * The following macro is a compiler specific way to ensure that memory
+ * writes are not reordered around certian points. This specifically can
+ * impact interrupt disable and thread dispatching critical sections.
+ */
+#ifdef __GNUC__
+ #define RTEMS_COMPILER_MEMORY_BARRIER() __asm__ volatile("" ::: "memory")
+#else
+ #define RTEMS_COMPILER_MEMORY_BARRIER()
+#endif
+
+/**
+ * The following defines a compiler specific attribute which informs
+ * the compiler that the method must not be inlined.
+ */
+#ifdef __GNUC__
+ #define RTEMS_NO_INLINE __attribute__((__noinline__))
+#else
+ #define RTEMS_NO_INLINE
+#endif
+
+/**
+ * The following macro is a compiler specific way to indicate that
+ * the method will NOT return to the caller. This can assist the
+ * compiler in code generation and avoid unreachable paths. This
+ * can impact the code generated following calls to
+ * rtems_fatal_error_occurred and _Terminate.
+ */
+#if defined(RTEMS_SCHEDSIM)
+ #define RTEMS_NO_RETURN
+#elif defined(__GNUC__) && !defined(RTEMS_DEBUG)
+ #define RTEMS_NO_RETURN __attribute__((__noreturn__))
+#else
+ #define RTEMS_NO_RETURN
+#endif
+
+/* Provided for backward compatibility */
+#define RTEMS_COMPILER_NO_RETURN_ATTRIBUTE RTEMS_NO_RETURN
+
+/**
+ * The following defines a compiler specific attribute which informs
+ * the compiler that the method has no effect except the return value
+ * and that the return value depends only on parameters and/or global
+ * variables.
+ */
+#ifdef __GNUC__
+ #define RTEMS_PURE __attribute__((__pure__))
+#else
+ #define RTEMS_PURE
+#endif
+
+/* Provided for backward compatibility */
+#define RTEMS_COMPILER_PURE_ATTRIBUTE RTEMS_PURE
+
+/**
+ * Instructs the compiler to issue a warning whenever a variable or function
+ * with this attribute will be used.
+ */
+#ifdef __GNUC__
+ #define RTEMS_DEPRECATED __attribute__((__deprecated__))
+#else
+ #define RTEMS_DEPRECATED
+#endif
+
+/* Provided for backward compatibility */
+#define RTEMS_COMPILER_DEPRECATED_ATTRIBUTE RTEMS_DEPRECATED
+
+/**
+ * @brief Instructs the compiler to place a specific variable or function in
+ * the specified section.
+ */
+#if defined(__GNUC__)
+ #define RTEMS_SECTION( _section ) __attribute__((__section__(_section)))
+#else
+ #define RTEMS_SECTION( _section )
+#endif
+
+/**
+ * @brief Instructs the compiler that a specific variable or function is used.
+ */
+#if defined(__GNUC__)
+ #define RTEMS_USED __attribute__((__used__))
+#else
+ #define RTEMS_USED
+#endif
+
+/**
+ * Instructs the compiler that a specific variable is deliberately unused.
+ * This can occur when reading volatile device memory or skipping arguments
+ * in a variable argument method.
+ */
+#if defined(__GNUC__)
+ #define RTEMS_UNUSED __attribute__((__unused__))
+#else
+ #define RTEMS_UNUSED
+#endif
+
+/* Provided for backward compatibility */
+#define RTEMS_COMPILER_UNUSED_ATTRIBUTE RTEMS_UNUSED
+
+/**
+ * Instructs the compiler that a specific structure or union members will be
+ * placed so that the least memory is used.
+ */
+#if defined(__GNUC__)
+ #define RTEMS_PACKED __attribute__((__packed__))
+#else
+ #define RTEMS_PACKED
+#endif
+
+/**
+ * @brief Instructs the compiler to generate an alias to the specified target
+ * function.
+ */
+#if defined(__GNUC__)
+ #define RTEMS_ALIAS( _target ) __attribute__((__alias__(#_target)))
+#else
+ #define RTEMS_ALIAS( _target )
+#endif
+
+/**
+ * @brief Instructs the compiler to generate a weak alias to the specified
+ * target function.
+ */
+#if defined(__GNUC__)
+ #define RTEMS_WEAK_ALIAS( _target ) __attribute__((__weak__, __alias__(#_target)))
+#else
+ #define RTEMS_WEAK_ALIAS( _target )
+#endif
+
+/**
+ * @brief Instructs the compiler to enforce the specified alignment.
+ */
+#if defined(__GNUC__)
+ #define RTEMS_ALIGNED( _alignment ) __attribute__((__aligned__(_alignment)))
+#else
+ #define RTEMS_ALIGNED( _alignment )
+#endif
+
+/* Provided for backward compatibility */
+#define RTEMS_COMPILER_PACKED_ATTRIBUTE RTEMS_PACKED
+
+#if defined(RTEMS_DEBUG) && !defined(RTEMS_SCHEDSIM)
+ #define _Assert_Unreachable() _Assert( 0 )
+#else
+ #define _Assert_Unreachable() do { } while ( 0 )
+#endif
+
+/**
+ * @brief Tells the compiler that this program point is unreachable.
+ */
+#if defined(__GNUC__) && !defined(RTEMS_SCHEDSIM)
+ #define RTEMS_UNREACHABLE() \
+ do { \
+ __builtin_unreachable(); \
+ _Assert_Unreachable(); \
+ } while ( 0 )
+#else
+ #define RTEMS_UNREACHABLE() _Assert_Unreachable()
+#endif
+
+/**
+ * @brief Tells the compiler that this function expects printf()-like
+ * arguments.
+ */
+#if defined(__GNUC__)
+ #define RTEMS_PRINTFLIKE( _format_pos, _ap_pos ) \
+ __attribute__((__format__(__printf__, _format_pos, _ap_pos)))
+#else
+ #define RTEMS_PRINTFLIKE( _format_pos, _ap_pos )
+#endif
+
+/**
+ * @brief Obfuscates the variable so that the compiler cannot perform
+ * optimizations based on the variable value.
+ *
+ * The variable must be simple enough to fit into a register.
+ */
+#if defined(__GNUC__)
+ #define RTEMS_OBFUSCATE_VARIABLE( _var ) __asm__("" : "+r" (_var))
+#else
+ #define RTEMS_OBFUSCATE_VARIABLE( _var ) (void) (_var)
+#endif
+
+#if __cplusplus >= 201103L
+ #define RTEMS_STATIC_ASSERT(cond, msg) \
+ static_assert(cond, # msg)
+#elif __STDC_VERSION__ >= 201112L
+ #define RTEMS_STATIC_ASSERT(cond, msg) \
+ _Static_assert(cond, # msg)
+#else
+ #define RTEMS_STATIC_ASSERT(cond, msg) \
+ typedef int rtems_static_assert_ ## msg [(cond) ? 1 : -1]
+#endif
+
+#define RTEMS_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
+
+/*
+ * Zero-length arrays are valid in C99 as flexible array members. C++11
+ * doesn't allow flexible array members. Use the GNU extension which is also
+ * supported by other compilers.
+ */
+#define RTEMS_ZERO_LENGTH_ARRAY 0
+
+/**
+ * @brief Returns a pointer to the container of a specified member pointer.
+ *
+ * @param[in] _m The pointer to a member of the container.
+ * @param[in] _type The type of the container.
+ * @param[in] _member_name The designator name of the container member.
+ */
+#define RTEMS_CONTAINER_OF( _m, _type, _member_name ) \
+ ( (_type *) ( (uintptr_t) ( _m ) - offsetof( _type, _member_name ) ) )
+
+#ifdef __cplusplus
+#define RTEMS_DEQUALIFY_DEPTHX( _ptr_level, _type, _var ) \
+ (const_cast<_type>( _var ))
+#else /* Standard C code */
+
+/* The reference type idea based on libHX by Jan Engelhardt */
+#define RTEMS_TYPEOF_REFX(_ptr_level, _ptr_type) \
+ typeof(_ptr_level(union { int z; typeof(_ptr_type) x; }){0}.x)
+
+#if defined(__GNUC__) && !defined(ASM)
+#if ((__GNUC__ * 1000 + __GNUC_MINOR__) >= 4004)
+extern void* RTEMS_DEQUALIFY_types_not_compatible(void)
+ __attribute__((error ("RTEMS_DEQUALIFY types differ not only by volatile and const")));
+#else
+extern void RTEMS_DEQUALIFY_types_not_compatible(void);
+#endif
+#define RTEMS_DEQUALIFY_DEPTHX( _ptr_level, _type, _var ) ( \
+ __builtin_choose_expr( __builtin_types_compatible_p ( \
+ RTEMS_TYPEOF_REFX( _ptr_level, _var ), \
+ RTEMS_TYPEOF_REFX( _ptr_level, _type ) \
+ ) || __builtin_types_compatible_p ( _type, void * ), \
+ (_type)(_var), \
+ RTEMS_DEQUALIFY_types_not_compatible() \
+ ) \
+)
+#endif /*__GNUC__*/
+#endif /*__cplusplus*/
+
+#ifndef RTEMS_DECONST
+#ifdef RTEMS_DEQUALIFY_DEPTHX
+#define RTEMS_DECONST( _type, _var ) \
+ RTEMS_DEQUALIFY_DEPTHX( *, _type, _var )
+#else /*RTEMS_DEQUALIFY_DEPTHX*/
+/**
+ * @brief Removes the const qualifier from a type of a variable.
+ *
+ * @param[in] _type The target type for the variable.
+ * @param[in] _var The variable.
+ */
+#define RTEMS_DECONST( _type, _var ) \
+ ((_type)(uintptr_t)(const void *) ( _var ))
+
+#endif /*RTEMS_DEQUALIFY_DEPTHX*/
+#endif /*RTEMS_DECONST*/
+
+#ifndef RTEMS_DEVOLATILE
+#ifdef RTEMS_DEQUALIFY_DEPTHX
+#define RTEMS_DEVOLATILE( _type, _var ) \
+ RTEMS_DEQUALIFY_DEPTHX( *, _type, _var )
+#else /*RTEMS_DEQUALIFY_DEPTHX*/
+/**
+ * @brief Removes the volatile qualifier from a type of a variable.
+ *
+ * @param[in] _type The target type for the variable.
+ * @param[in] _var The variable.
+ */
+#define RTEMS_DEVOLATILE( _type, _var ) \
+ ((_type)(uintptr_t)(volatile void *) ( _var ))
+
+#endif /*RTEMS_DEQUALIFY_DEPTHX*/
+#endif /*RTEMS_DEVOLATILE*/
+
+#ifndef RTEMS_DEQUALIFY
+#ifdef RTEMS_DEQUALIFY_DEPTHX
+#define RTEMS_DEQUALIFY( _type, _var ) \
+ RTEMS_DEQUALIFY_DEPTHX( *, _type, _var )
+#else /*RTEMS_DEQUALIFY_DEPTHX*/
+/**
+ * @brief Removes the all qualifiers from a type of a variable.
+ *
+ * @param[in] _type The target type for the variable.
+ * @param[in] _var The variable.
+ */
+#define RTEMS_DEQUALIFY( _type, _var ) \
+ ((_type)(uintptr_t)(const volatile void *) ( _var ))
+
+#endif /*RTEMS_DEQUALIFY_DEPTHX*/
+#endif /*RTEMS_DEQUALIFY*/
+
+/**
+ * @brief Evaluates to true if the members of two types have the same type.
+ *
+ * @param[in] _t_lhs Left hand side type.
+ * @param[in] _m_lhs Left hand side member.
+ * @param[in] _t_rhs Right hand side type.
+ * @param[in] _m_rhs Right hand side member.
+ */
+#ifdef __GNUC__
+ #define RTEMS_HAVE_MEMBER_SAME_TYPE( _t_lhs, _m_lhs, _t_rhs, _m_rhs ) \
+ __builtin_types_compatible_p( \
+ __typeof( ( (_t_lhs *) 0 )->_m_lhs ), \
+ __typeof( ( (_t_rhs *) 0 )->_m_rhs ) \
+ )
+#else
+ #define RTEMS_HAVE_MEMBER_SAME_TYPE( _t_lhs, _m_lhs, _t_rhs, _m_rhs ) \
+ true
+#endif
+
+/**
+ * @brief Concatenates _x and _y without expanding.
+ */
+#define RTEMS_CONCAT( _x, _y ) _x##_y
+
+/**
+ * @brief Concatenates expansion of _x and expansion of _y.
+ */
+#define RTEMS_XCONCAT( _x, _y ) RTEMS_CONCAT( _x, _y )
+
+/**
+ * @brief Stringifies _x without expanding.
+ */
+#define RTEMS_STRING( _x ) #_x
+
+/**
+ * @brief Stringifies expansion of _x.
+ */
+#define RTEMS_XSTRING( _x ) RTEMS_STRING( _x )
+
+#ifndef ASM
+ #ifdef RTEMS_DEPRECATED_TYPES
+ typedef bool boolean;
+ typedef float single_precision;
+ typedef double double_precision;
+ #endif
+
+ /**
+ * XXX: Eventually proc_ptr needs to disappear!!!
+ */
+ typedef void * proc_ptr;
+#endif
+
+/**@}*/
+
+#endif /* _RTEMS_BASEDEFS_H */
diff --git a/cpukit/include/rtems/score/chain.h b/cpukit/include/rtems/score/chain.h
new file mode 100644
index 0000000000..e358262e6e
--- /dev/null
+++ b/cpukit/include/rtems/score/chain.h
@@ -0,0 +1,102 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreChain
+ *
+ * @brief Chain Handler API
+ */
+
+/*
+ * Copyright (c) 2010 embedded brains GmbH.
+ *
+ * COPYRIGHT (c) 1989-2006.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_CHAIN_H
+#define _RTEMS_SCORE_CHAIN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreChain Chain Handler
+ *
+ * @ingroup Score
+ *
+ * The Chain Handler is used to manage sets of entities. This handler
+ * provides two data structures. The Chain Node data structure is included
+ * as the first part of every data structure that will be placed on
+ * a chain. The second data structure is Chain Control which is used
+ * to manage a set of Chain Nodes.
+ */
+/**@{*/
+
+/**
+ * @typedef Chain_Node
+ *
+ * This type definition promotes the name for the Chain Node used by
+ * all RTEMS code. It is a separate type definition because a forward
+ * reference is required to define it. See @ref Chain_Node_struct for
+ * detailed information.
+ */
+typedef struct Chain_Node_struct Chain_Node;
+
+/**
+ * @struct Chain_Node_struct
+ *
+ * This is used to manage each element (node) which is placed
+ * on a chain.
+ *
+ * @note Typically, a more complicated structure will use the
+ * chain package. The more complicated structure will
+ * include a chain node as the first element in its
+ * control structure. It will then call the chain package
+ * with a pointer to that node element. The node pointer
+ * and the higher level structure start at the same address
+ * so the user can cast the pointers back and forth.
+ *
+ */
+struct Chain_Node_struct {
+ /** This points to the node after this one on this chain. */
+ Chain_Node *next;
+ /** This points to the node immediate prior to this one on this chain. */
+ Chain_Node *previous;
+};
+
+/**
+ * @struct Chain_Control
+ *
+ * This is used to manage a chain. A chain consists of a doubly
+ * linked list of zero or more nodes.
+ *
+ * @note This implementation does not require special checks for
+ * manipulating the first and last elements on the chain.
+ * To accomplish this the @a Chain_Control structure is
+ * treated as two overlapping @ref Chain_Node structures.
+ */
+typedef union {
+ struct {
+ Chain_Node Node;
+ Chain_Node *fill;
+ } Head;
+
+ struct {
+ Chain_Node *fill;
+ Chain_Node Node;
+ } Tail;
+} Chain_Control;
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/chainimpl.h b/cpukit/include/rtems/score/chainimpl.h
new file mode 100644
index 0000000000..c94c051198
--- /dev/null
+++ b/cpukit/include/rtems/score/chainimpl.h
@@ -0,0 +1,1123 @@
+/**
+ * @file
+ *
+ * @brief Chain Handler API
+ */
+
+/*
+ * Copyright (c) 2010 embedded brains GmbH.
+ *
+ * COPYRIGHT (c) 1989-2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_CHAINIMPL_H
+#define _RTEMS_SCORE_CHAINIMPL_H
+
+#include <rtems/score/chain.h>
+#include <rtems/score/address.h>
+#include <rtems/score/assert.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreChain
+ */
+/**@{**/
+
+/**
+ * @brief Chain initializer for an empty chain with designator @a name.
+ */
+#define CHAIN_INITIALIZER_EMPTY(name) \
+ { { { &(name).Tail.Node, NULL }, &(name).Head.Node } }
+
+/**
+ * @brief Chain initializer for a chain with one @a node.
+ *
+ * @see CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN().
+ */
+#define CHAIN_INITIALIZER_ONE_NODE( node ) \
+ { { { (node), NULL }, (node) } }
+
+/**
+ * @brief Chain node initializer for a @a chain containing exactly this node.
+ *
+ * @see CHAIN_INITIALIZER_ONE_NODE().
+ */
+#define CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( chain ) \
+ { &(chain)->Tail.Node, &(chain)->Head.Node }
+
+/**
+ * @brief Chain definition for an empty chain with designator @a name.
+ */
+#define CHAIN_DEFINE_EMPTY(name) \
+ Chain_Control name = CHAIN_INITIALIZER_EMPTY(name)
+
+/**
+ * @brief Initialize a chain header.
+ *
+ * This routine initializes @a the_chain structure to manage the
+ * contiguous array of @a number_nodes nodes which starts at
+ * @a starting_address. Each node is of @a node_size bytes.
+ *
+ * @param[in] the_chain specifies the chain to initialize
+ * @param[in] starting_address is the starting address of the array
+ * of elements
+ * @param[in] number_nodes is the numebr of nodes that will be in the chain
+ * @param[in] node_size is the size of each node
+ */
+void _Chain_Initialize(
+ Chain_Control *the_chain,
+ void *starting_address,
+ size_t number_nodes,
+ size_t node_size
+);
+
+/**
+ * @brief Returns the node count of the chain.
+ *
+ * @param[in] chain The chain.
+ *
+ * @note It does NOT disable interrupts to ensure the atomicity of the
+ * operation.
+ *
+ * @retval The node count of the chain.
+ */
+size_t _Chain_Node_count_unprotected( const Chain_Control *chain );
+
+/**
+ * @brief Set off chain.
+ *
+ * This function sets the next field of the @a node to NULL indicating the @a
+ * node is not part of a chain.
+ *
+ * @param[in] node the node set to off chain.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Set_off_chain(
+ Chain_Node *node
+)
+{
+ node->next = NULL;
+#if defined(RTEMS_DEBUG)
+ node->previous = NULL;
+#endif
+}
+
+/**
+ * @brief Initializes a chain node.
+ *
+ * In debug configurations, the node is set off chain. In all other
+ * configurations, this function does nothing.
+ *
+ * @param[in] the_node The chain node to initialize.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Initialize_node( Chain_Node *the_node )
+{
+#if defined(RTEMS_DEBUG)
+ _Chain_Set_off_chain( the_node );
+#else
+ (void) the_node;
+#endif
+}
+
+/**
+ * @brief Is the node off chain.
+ *
+ * This function returns true if the @a node is not on a chain. A @a node is
+ * off chain if the next field is set to NULL.
+ *
+ * @param[in] node is the node off chain.
+ *
+ * @retval true The @a node is off chain.
+ * @retval false The @a node is not off chain.
+ */
+RTEMS_INLINE_ROUTINE bool _Chain_Is_node_off_chain(
+ const Chain_Node *node
+)
+{
+ return node->next == NULL;
+}
+
+/**
+ * @brief Are two nodes equal.
+ *
+ * This function returns true if @a left and @a right are equal,
+ * and false otherwise.
+ *
+ * @param[in] left is the node on the left hand side of the comparison.
+ * @param[in] right is the node on the left hand side of the comparison.
+ *
+ * @retval true @a left and @a right are equal.
+ * @retval false @a left and @a right are not equal.
+ */
+RTEMS_INLINE_ROUTINE bool _Chain_Are_nodes_equal(
+ const Chain_Node *left,
+ const Chain_Node *right
+)
+{
+ return left == right;
+}
+
+/**
+ * @brief Is the chain node pointer NULL.
+ *
+ * This function returns true if the_node is NULL and false otherwise.
+ *
+ * @param[in] the_node is the node pointer to check.
+ *
+ * @retval true @a the_node is @c NULL.
+ * @retval false @a the_node is not @c NULL.
+ */
+RTEMS_INLINE_ROUTINE bool _Chain_Is_null_node(
+ const Chain_Node *the_node
+)
+{
+ return (the_node == NULL);
+}
+
+/**
+ * @brief Return pointer to chain head.
+ *
+ * This function returns a pointer to the head node on the chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the permanent head node of the chain.
+ */
+RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Head(
+ Chain_Control *the_chain
+)
+{
+ return &the_chain->Head.Node;
+}
+
+/**
+ * @brief Return pointer to immutable chain head.
+ *
+ * This function returns a pointer to the head node on the chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the permanent head node of the chain.
+ */
+RTEMS_INLINE_ROUTINE const Chain_Node *_Chain_Immutable_head(
+ const Chain_Control *the_chain
+)
+{
+ return &the_chain->Head.Node;
+}
+
+/**
+ * @brief Return pointer to chain tail.
+ *
+ * This function returns a pointer to the tail node on the chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the permanent tail node of the chain.
+ */
+RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Tail(
+ Chain_Control *the_chain
+)
+{
+ return &the_chain->Tail.Node;
+}
+
+/**
+ * @brief Return pointer to immutable chain tail.
+ *
+ * This function returns a pointer to the tail node on the chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the permanent tail node of the chain.
+ */
+RTEMS_INLINE_ROUTINE const Chain_Node *_Chain_Immutable_tail(
+ const Chain_Control *the_chain
+)
+{
+ return &the_chain->Tail.Node;
+}
+
+/**
+ * @brief Return pointer to chain's first node.
+ *
+ * This function returns a pointer to the first node on the chain after the
+ * head.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the first node of the chain.
+ */
+RTEMS_INLINE_ROUTINE Chain_Node *_Chain_First(
+ const Chain_Control *the_chain
+)
+{
+ return _Chain_Immutable_head( the_chain )->next;
+}
+
+/**
+ * @brief Return pointer to immutable chain's first node.
+ *
+ * This function returns a pointer to the first node on the chain after the
+ * head.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the first node of the chain.
+ */
+RTEMS_INLINE_ROUTINE const Chain_Node *_Chain_Immutable_first(
+ const Chain_Control *the_chain
+)
+{
+ return _Chain_Immutable_head( the_chain )->next;
+}
+
+/**
+ * @brief Return pointer to chain's last node.
+ *
+ * This function returns a pointer to the last node on the chain just before
+ * the tail.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the last node of the chain.
+ */
+RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Last(
+ const Chain_Control *the_chain
+)
+{
+ return _Chain_Immutable_tail( the_chain )->previous;
+}
+
+/**
+ * @brief Return pointer to immutable chain's last node.
+ *
+ * This function returns a pointer to the last node on the chain just before
+ * the tail.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This method returns the last node of the chain.
+ */
+RTEMS_INLINE_ROUTINE const Chain_Node *_Chain_Immutable_last(
+ const Chain_Control *the_chain
+)
+{
+ return _Chain_Immutable_tail( the_chain )->previous;
+}
+
+/**
+ * @brief Return pointer the next node from this node.
+ *
+ * This function returns a pointer to the next node after this node.
+ *
+ * @param[in] the_node is the node to be operated upon.
+ *
+ * @return This method returns the next node on the chain.
+ */
+RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Next(
+ const Chain_Node *the_node
+)
+{
+ return the_node->next;
+}
+
+/**
+ * @brief Return pointer the immutable next node from this node.
+ *
+ * This function returns a pointer to the next node after this node.
+ *
+ * @param[in] the_node is the node to be operated upon.
+ *
+ * @return This method returns the next node on the chain.
+ */
+RTEMS_INLINE_ROUTINE const Chain_Node *_Chain_Immutable_next(
+ const Chain_Node *the_node
+)
+{
+ return the_node->next;
+}
+
+/**
+ * @brief Return pointer the previous node from this node.
+ *
+ * This function returns a pointer to the previous node on this chain.
+ *
+ * @param[in] the_node is the node to be operated upon.
+ *
+ * @return This method returns the previous node on the chain.
+ */
+RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Previous(
+ const Chain_Node *the_node
+)
+{
+ return the_node->previous;
+}
+
+/**
+ * @brief Return pointer the immutable previous node from this node.
+ *
+ * This function returns a pointer to the previous node on this chain.
+ *
+ * @param[in] the_node is the node to be operated upon.
+ *
+ * @return This method returns the previous node on the chain.
+ */
+RTEMS_INLINE_ROUTINE const Chain_Node *_Chain_Immutable_previous(
+ const Chain_Node *the_node
+)
+{
+ return the_node->previous;
+}
+
+/**
+ * @brief Is the chain empty.
+ *
+ * This function returns true if there a no nodes on @a the_chain and
+ * false otherwise.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @retval true There are no nodes on @a the_chain.
+ * @retval false There are nodes on @a the_chain.
+ */
+RTEMS_INLINE_ROUTINE bool _Chain_Is_empty(
+ const Chain_Control *the_chain
+)
+{
+ return _Chain_Immutable_first( the_chain )
+ == _Chain_Immutable_tail( the_chain );
+}
+
+/**
+ * @brief Is this the first node on the chain.
+ *
+ * This function returns true if the_node is the first node on a chain and
+ * false otherwise.
+ *
+ * @param[in] the_node is the node the caller wants to know if it is
+ * the first node on a chain.
+ *
+ * @retval true @a the_node is the first node on a chain.
+ * @retval false @a the_node is not the first node on a chain.
+ */
+RTEMS_INLINE_ROUTINE bool _Chain_Is_first(
+ const Chain_Node *the_node
+)
+{
+ return (the_node->previous->previous == NULL);
+}
+
+/**
+ * @brief Is this the last node on the chain.
+ *
+ * This function returns true if @a the_node is the last node on a chain and
+ * false otherwise.
+ *
+ * @param[in] the_node is the node to check as the last node.
+ *
+ * @retval true @a the_node is the last node on a chain.
+ * @retval false @a the_node is not the last node on a chain.
+ */
+RTEMS_INLINE_ROUTINE bool _Chain_Is_last(
+ const Chain_Node *the_node
+)
+{
+ return (the_node->next->next == NULL);
+}
+
+/**
+ * @brief Does this chain have only one node.
+ *
+ * This function returns true if there is only one node on @a the_chain and
+ * false otherwise.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ *
+ * @return This function returns true if there is only one node on
+ * @a the_chain and false otherwise.
+ *
+ * @retval true There is only one node on @a the_chain.
+ * @retval false There is more than one node on @a the_chain.
+ */
+RTEMS_INLINE_ROUTINE bool _Chain_Has_only_one_node(
+ const Chain_Control *the_chain
+)
+{
+ return _Chain_Immutable_first( the_chain )
+ == _Chain_Immutable_last( the_chain );
+}
+
+/**
+ * @brief Is this node the chain head.
+ *
+ * This function returns true if @a the_node is the head of @a the_chain and
+ * false otherwise.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ * @param[in] the_node is the node to check for being the Chain Head.
+ *
+ * @retval true @a the_node is the head of @a the_chain.
+ * @retval false @a the_node is not the head of @a the_chain.
+ */
+RTEMS_INLINE_ROUTINE bool _Chain_Is_head(
+ const Chain_Control *the_chain,
+ const Chain_Node *the_node
+)
+{
+ return (the_node == _Chain_Immutable_head( the_chain ));
+}
+
+/**
+ * @brief Is this node the chail tail.
+ *
+ * This function returns true if @a the_node is the tail of @a the_chain and
+ * false otherwise.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ * @param[in] the_node is the node to check for being the Chain Tail.
+ *
+ * @retval true @a the_node is the tail of @a the_chain.
+ * @retval false @a the_node is not the tail of @a the_chain.
+ */
+RTEMS_INLINE_ROUTINE bool _Chain_Is_tail(
+ const Chain_Control *the_chain,
+ const Chain_Node *the_node
+)
+{
+ return (the_node == _Chain_Immutable_tail( the_chain ));
+}
+
+/**
+ * @brief Initialize this chain as empty.
+ *
+ * This routine initializes the specified chain to contain zero nodes.
+ *
+ * @param[in] the_chain is the chain to be initialized.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Initialize_empty(
+ Chain_Control *the_chain
+)
+{
+ Chain_Node *head;
+ Chain_Node *tail;
+
+ _Assert( the_chain != NULL );
+
+ head = _Chain_Head( the_chain );
+ tail = _Chain_Tail( the_chain );
+
+ head->next = tail;
+ head->previous = NULL;
+ tail->previous = head;
+}
+
+/**
+ * @brief Initializes this chain to contain exactly the specified node.
+ *
+ * @param[in] the_chain The chain control.
+ * @param[in] the_node The one and only node.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Initialize_one(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+)
+{
+ Chain_Node *head;
+ Chain_Node *tail;
+
+ _Assert( _Chain_Is_node_off_chain( the_node ) );
+
+ head = _Chain_Head( the_chain );
+ tail = _Chain_Tail( the_chain );
+
+ the_node->next = tail;
+ the_node->previous = head;
+
+ head->next = the_node;
+ head->previous = NULL;
+ tail->previous = the_node;
+}
+
+/**
+ * @brief Extract this node (unprotected).
+ *
+ * This routine extracts the_node from the chain on which it resides.
+ * It does NOT disable interrupts to ensure the atomicity of the
+ * extract operation.
+ *
+ * @param[in] the_node is the node to be extracted.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Extract_unprotected(
+ Chain_Node *the_node
+)
+{
+ Chain_Node *next;
+ Chain_Node *previous;
+
+ next = the_node->next;
+ previous = the_node->previous;
+ next->previous = previous;
+ previous->next = next;
+
+#if defined(RTEMS_DEBUG)
+ _Chain_Set_off_chain( the_node );
+#endif
+}
+
+/**
+ * @brief Get the first node (unprotected).
+ *
+ * This function removes the first node from the_chain and returns
+ * a pointer to that node. It does NOT disable interrupts to ensure
+ * the atomicity of the get operation.
+ *
+ * @param[in] the_chain is the chain to attempt to get the first node from.
+ *
+ * @return This method returns the first node on the chain even if it is
+ * the Chain Tail.
+ *
+ * @note This routine assumes that there is at least one node on the chain
+ * and always returns a node even if it is the Chain Tail.
+ */
+RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Get_first_unprotected(
+ Chain_Control *the_chain
+)
+{
+ Chain_Node *head;
+ Chain_Node *old_first;
+ Chain_Node *new_first;
+
+ _Assert( !_Chain_Is_empty( the_chain ) );
+
+ head = _Chain_Head( the_chain );
+ old_first = head->next;
+ new_first = old_first->next;
+
+ head->next = new_first;
+ new_first->previous = head;
+
+#if defined(RTEMS_DEBUG)
+ _Chain_Set_off_chain( old_first );
+#endif
+
+ return old_first;
+}
+
+/**
+ * @brief Get the first node (unprotected).
+ *
+ * This function removes the first node from the_chain and returns
+ * a pointer to that node. If the_chain is empty, then NULL is returned.
+ *
+ * @param[in] the_chain is the chain to attempt to get the first node from.
+ *
+ * @return This method returns the first node on the chain or NULL if the
+ * chain is empty.
+ *
+ * @note It does NOT disable interrupts to ensure the atomicity of the
+ * get operation.
+ */
+RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Get_unprotected(
+ Chain_Control *the_chain
+)
+{
+ if ( !_Chain_Is_empty(the_chain))
+ return _Chain_Get_first_unprotected(the_chain);
+ else
+ return NULL;
+}
+
+/**
+ * @brief Insert a node (unprotected).
+ *
+ * This routine inserts the_node on a chain immediately following
+ * after_node.
+ *
+ * @param[in] after_node is the node which will precede @a the_node on the
+ * chain.
+ * @param[in] the_node is the node to be inserted.
+ *
+ * @note It does NOT disable interrupts to ensure the atomicity
+ * of the extract operation.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Insert_unprotected(
+ Chain_Node *after_node,
+ Chain_Node *the_node
+)
+{
+ Chain_Node *before_node;
+
+ _Assert( _Chain_Is_node_off_chain( the_node ) );
+
+ the_node->previous = after_node;
+ before_node = after_node->next;
+ after_node->next = the_node;
+ the_node->next = before_node;
+ before_node->previous = the_node;
+}
+
+/**
+ * @brief Append a node (unprotected).
+ *
+ * This routine appends the_node onto the end of the_chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ * @param[in] the_node is the node to be appended.
+ *
+ * @note It does NOT disable interrupts to ensure the atomicity of the
+ * append operation.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Append_unprotected(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+)
+{
+ Chain_Node *tail;
+ Chain_Node *old_last;
+
+ _Assert( _Chain_Is_node_off_chain( the_node ) );
+
+ tail = _Chain_Tail( the_chain );
+ old_last = tail->previous;
+
+ the_node->next = tail;
+ tail->previous = the_node;
+ old_last->next = the_node;
+ the_node->previous = old_last;
+}
+
+/**
+ * @brief Append a node on the end of a chain if the node is in the off chain
+ * state (unprotected).
+ *
+ * @note It does NOT disable interrupts to ensure the atomicity of the
+ * append operation.
+ *
+ * @see _Chain_Append_unprotected() and _Chain_Is_node_off_chain().
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Append_if_is_off_chain_unprotected(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+)
+{
+ if ( _Chain_Is_node_off_chain( the_node ) ) {
+ _Chain_Append_unprotected( the_chain, the_node );
+ }
+}
+
+/**
+ * @brief Prepend a node (unprotected).
+ *
+ * This routine prepends the_node onto the front of the_chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ * @param[in] the_node is the node to be prepended.
+ *
+ * @note It does NOT disable interrupts to ensure the atomicity of the
+ * prepend operation.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Prepend_unprotected(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+)
+{
+ _Chain_Insert_unprotected(_Chain_Head(the_chain), the_node);
+}
+
+/**
+ * @brief Append a node and check if the chain was empty before (unprotected).
+ *
+ * This routine appends the_node onto the end of the_chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ * @param[in] the_node is the node to be appended.
+ *
+ * @note It does NOT disable interrupts to ensure the atomicity of the
+ * append operation.
+ *
+ * @retval true The chain was empty before.
+ * @retval false The chain contained at least one node before.
+ */
+RTEMS_INLINE_ROUTINE bool _Chain_Append_with_empty_check_unprotected(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+)
+{
+ bool was_empty = _Chain_Is_empty( the_chain );
+
+ _Chain_Append_unprotected( the_chain, the_node );
+
+ return was_empty;
+}
+
+/**
+ * @brief Prepend a node and check if the chain was empty before (unprotected).
+ *
+ * This routine prepends the_node onto the front of the_chain.
+ *
+ * @param[in] the_chain is the chain to be operated upon.
+ * @param[in] the_node is the node to be prepended.
+ *
+ * @note It does NOT disable interrupts to ensure the atomicity of the
+ * prepend operation.
+ *
+ * @retval true The chain was empty before.
+ * @retval false The chain contained at least one node before.
+ */
+RTEMS_INLINE_ROUTINE bool _Chain_Prepend_with_empty_check_unprotected(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+)
+{
+ bool was_empty = _Chain_Is_empty( the_chain );
+
+ _Chain_Prepend_unprotected( the_chain, the_node );
+
+ return was_empty;
+}
+
+/**
+ * @brief Get the first node and check if the chain is empty afterwards
+ * (unprotected).
+ *
+ * This function removes the first node from the_chain and returns
+ * a pointer to that node in @a the_node. If the_chain is empty, then NULL is
+ * returned.
+ *
+ * @param[in] the_chain is the chain to attempt to get the first node from.
+ * @param[out] the_node is the first node on the chain or NULL if the chain is
+ * empty.
+ *
+ * @note It does NOT disable interrupts to ensure the atomicity of the
+ * get operation.
+ *
+ * @retval true The chain is empty now.
+ * @retval false The chain contains at least one node now.
+ */
+RTEMS_INLINE_ROUTINE bool _Chain_Get_with_empty_check_unprotected(
+ Chain_Control *the_chain,
+ Chain_Node **the_node
+)
+{
+ bool is_empty_now = true;
+ Chain_Node *head = _Chain_Head( the_chain );
+ Chain_Node *tail = _Chain_Tail( the_chain );
+ Chain_Node *old_first = head->next;
+
+ if ( old_first != tail ) {
+ Chain_Node *new_first = old_first->next;
+
+ head->next = new_first;
+ new_first->previous = head;
+
+ *the_node = old_first;
+
+ is_empty_now = new_first == tail;
+ } else
+ *the_node = NULL;
+
+ return is_empty_now;
+}
+
+/**
+ * @brief Chain node order.
+ *
+ * @param[in] left The left hand side.
+ * @param[in] right The right hand side.
+ *
+ * @retval true According to the order the left node precedes the right node.
+ * @retval false Otherwise.
+ */
+typedef bool ( *Chain_Node_order )(
+ const void *left,
+ const Chain_Node *right
+);
+
+/**
+ * @brief Inserts a node into the chain according to the order relation.
+ *
+ * After the operation the chain contains the node to insert and the order
+ * relation holds for all nodes from the head up to the inserted node. Nodes
+ * after the inserted node are not moved.
+ *
+ * @param[in] the_chain The chain.
+ * @param[in] to_insert The node to insert.
+ * @param[in] left The left hand side passed to the order relation. It must
+ * correspond to the node to insert. The separate left hand side parameter
+ * may help the compiler to generate better code if it is stored in a local
+ * variable.
+ * @param[in] order The order relation.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Insert_ordered_unprotected(
+ Chain_Control *the_chain,
+ Chain_Node *to_insert,
+ const void *left,
+ Chain_Node_order order
+)
+{
+ const Chain_Node *tail = _Chain_Immutable_tail( the_chain );
+ Chain_Node *next = _Chain_First( the_chain );
+
+ while ( next != tail && !( *order )( left, next ) ) {
+ next = _Chain_Next( next );
+ }
+
+ _Chain_Insert_unprotected( _Chain_Previous( next ), to_insert );
+}
+
+/**
+ * @brief The chain iterator direction.
+ */
+typedef enum {
+ /**
+ * @brief Iteration from head to tail.
+ */
+ CHAIN_ITERATOR_FORWARD,
+
+ /**
+ * @brief Iteration from tail to head.
+ */
+ CHAIN_ITERATOR_BACKWARD
+} Chain_Iterator_direction;
+
+/**
+ * @brief A chain iterator which is updated during node extraction if it is
+ * properly registered.
+ *
+ * @see _Chain_Iterator_initialize().
+ */
+typedef struct {
+ /**
+ * @brief Node for registration.
+ *
+ * Used during _Chain_Iterator_initialize() and _Chain_Iterator_destroy().
+ */
+ Chain_Node Registry_node;
+
+ /**
+ * @brief The direction of this iterator.
+ *
+ * Immutable after initialization via _Chain_Iterator_initialize().
+ */
+ Chain_Iterator_direction direction;
+
+ /**
+ * @brief The current position of this iterator.
+ *
+ * The position is initialized via _Chain_Iterator_initialize(). It must be
+ * explicitly set after one valid iteration step, e.g. in case a next node in
+ * the iterator direction existed. It is updated through the registration in
+ * case a node is extracted via _Chain_Iterator_registry_update().
+ */
+ Chain_Node *position;
+} Chain_Iterator;
+
+/**
+ * @brief A registry for chain iterators.
+ *
+ * Should be attached to a chain control to enable safe iteration through a
+ * chain in case of concurrent node extractions.
+ */
+typedef struct {
+ Chain_Control Iterators;
+} Chain_Iterator_registry;
+
+/**
+ * @brief Chain iterator registry initializer for static initialization.
+ *
+ * @param name The designator of the chain iterator registry.
+ */
+#define CHAIN_ITERATOR_REGISTRY_INITIALIZER( name ) \
+ { CHAIN_INITIALIZER_EMPTY( name.Iterators ) }
+
+/**
+ * @brief Initializes a chain iterator registry.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Iterator_registry_initialize(
+ Chain_Iterator_registry *the_registry
+)
+{
+ _Chain_Initialize_empty( &the_registry->Iterators );
+}
+
+/**
+ * @brief Updates all iterators present in the chain iterator registry in case
+ * of a node extraction.
+ *
+ * Must be called before _Chain_Extract_unprotected().
+ *
+ * @warning This function will look at all registered chain iterators to
+ * determine if an update is necessary.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Iterator_registry_update(
+ Chain_Iterator_registry *the_registry,
+ Chain_Node *the_node_to_extract
+)
+{
+ Chain_Node *iter_node;
+ Chain_Node *iter_tail;
+
+ iter_node = _Chain_Head( &the_registry->Iterators );
+ iter_tail = _Chain_Tail( &the_registry->Iterators );
+
+ while ( ( iter_node = _Chain_Next( iter_node ) ) != iter_tail ) {
+ Chain_Iterator *iter;
+
+ iter = (Chain_Iterator *) iter_node;
+
+ if ( iter->position == the_node_to_extract ) {
+ if ( iter->direction == CHAIN_ITERATOR_FORWARD ) {
+ iter->position = _Chain_Previous( the_node_to_extract );
+ } else {
+ iter->position = _Chain_Next( the_node_to_extract );
+ }
+ }
+ }
+}
+
+/**
+ * @brief Initializes the chain iterator.
+ *
+ * In the following example nodes inserted during the iteration are visited in
+ * case they are inserted after the current position in iteration order.
+ *
+ * @code
+ * #include <rtems/score/chainimpl.h>
+ * #include <rtems/score/isrlock.h>
+ *
+ * typedef struct {
+ * Chain_Control Chain;
+ * Chain_Iterator_registry Iterators;
+ * ISR_LOCK_MEMBER( Lock )
+ * } Some_Control;
+ *
+ * void iterate(
+ * Some_Control *the_some,
+ * void ( *visitor )( Chain_Node * )
+ * )
+ * {
+ * ISR_lock_Context lock_context;
+ * Chain_Iterator iter;
+ * Chain_Node *node;
+ * const Chain_Node *end;
+ *
+ * end = _Chain_Immutable_tail( &the_some->Chain );
+ *
+ * _ISR_lock_ISR_disable_and_acquire( &the_some->Lock, &lock_context );
+ *
+ * _Chain_Iterator_initialize(
+ * &the_some->Chain,
+ * &the_some->Iterators,
+ * &iter,
+ * CHAIN_ITERATOR_FORWARD
+ * );
+ *
+ * while ( ( node = _Chain_Iterator_next( &iter ) ) != end ) {
+ * _Chain_Iterator_set_position( &iter, node );
+ * _ISR_lock_Release_and_ISR_enable( &the_some->Lock, &lock_context );
+ * ( *visitor )( node );
+ * _ISR_lock_ISR_disable_and_acquire( &the_some->Lock, &lock_context );
+ * }
+ *
+ * _Chain_Iterator_destroy( &iter );
+ * _ISR_lock_Release_and_ISR_enable( &the_some->Lock, &lock_context );
+ * }
+ * @endcode
+ *
+ * @param the_chain The chain to iterate.
+ * @param the_registry The registry for the chain iterator.
+ * @param the_iterator The chain iterator to initialize.
+ * @param direction The iteration direction.
+ *
+ * @see _Chain_Iterator_next(), _Chain_Iterator_set_position() and
+ * Chain_Iterator_destroy().
+ *
+ * @warning Think twice before you use a chain iterator. Its current
+ * implementation is unfit for use in performance relevant components, due to
+ * the linear time complexity in _Chain_Iterator_registry_update().
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Iterator_initialize(
+ Chain_Control *the_chain,
+ Chain_Iterator_registry *the_registry,
+ Chain_Iterator *the_iterator,
+ Chain_Iterator_direction direction
+)
+{
+ _Chain_Initialize_node( &the_iterator->Registry_node );
+ _Chain_Append_unprotected(
+ &the_registry->Iterators,
+ &the_iterator->Registry_node
+ );
+
+ the_iterator->direction = direction;
+
+ if ( direction == CHAIN_ITERATOR_FORWARD ) {
+ the_iterator->position = _Chain_Head( the_chain );
+ } else {
+ the_iterator->position = _Chain_Tail( the_chain );
+ }
+}
+
+/**
+ * @brief Returns the next node in the iterator direction.
+ *
+ * In case a next node exists, then the iterator should be updated via
+ * _Chain_Iterator_set_position() to continue with the next iteration step.
+ *
+ * @param the_iterator The chain iterator.
+ */
+RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Iterator_next(
+ const Chain_Iterator *the_iterator
+)
+{
+ if ( the_iterator->direction == CHAIN_ITERATOR_FORWARD ) {
+ return _Chain_Next( the_iterator->position );
+ } else {
+ return _Chain_Previous( the_iterator->position );
+ }
+}
+
+/**
+ * @brief Sets the iterator position.
+ *
+ * @param the_iterator The chain iterator.
+ * @param the_node The new iterator position.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Iterator_set_position(
+ Chain_Iterator *the_iterator,
+ Chain_Node *the_node
+)
+{
+ the_iterator->position = the_node;
+}
+
+/**
+ * @brief Destroys the iterator.
+ *
+ * Removes the iterator from its registry.
+ *
+ * @param the_iterator The chain iterator.
+ */
+RTEMS_INLINE_ROUTINE void _Chain_Iterator_destroy(
+ Chain_Iterator *the_iterator
+)
+{
+ _Chain_Extract_unprotected( &the_iterator->Registry_node );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/context.h b/cpukit/include/rtems/score/context.h
new file mode 100644
index 0000000000..990a602396
--- /dev/null
+++ b/cpukit/include/rtems/score/context.h
@@ -0,0 +1,163 @@
+/**
+ * @file rtems/score/context.h
+ *
+ * @brief Information About Each Thread's Context
+ *
+ * This include file contains all information about each thread's context.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_CONTEXT_H
+#define _RTEMS_SCORE_CONTEXT_H
+
+/**
+ * @defgroup ScoreContext Context Handler
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality which abstracts thread context
+ * management in a portable manner.
+ *
+ * The context switch needed variable is contained in the per cpu
+ * data structure.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/cpu.h>
+
+/**
+ * @brief Size of floating point context area.
+ *
+ * This constant defines the number of bytes required
+ * to store a full floating point context.
+ */
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+ #define CONTEXT_FP_SIZE CPU_CONTEXT_FP_SIZE
+#else
+ #define CONTEXT_FP_SIZE 0
+#endif
+
+/**
+ * @brief Initialize context area.
+ *
+ * This routine initializes @a _the_context such that the stack
+ * pointer, interrupt level, and entry point are correct for the
+ * thread's initial state.
+ *
+ * @param[in] _the_context will be initialized
+ * @param[in] _stack is the lowest physical address of the thread's
+ * context
+ * @param[in] _size is the size in octets of the thread's context
+ * @param[in] _isr is the ISR enable level for this thread
+ * @param[in] _entry is this thread's entry point
+ * @param[in] _is_fp is set to true if this thread has floating point
+ * enabled
+ * @param[in] _tls_area The thread-local storage (TLS) area begin.
+ */
+#define _Context_Initialize( _the_context, _stack, _size, _isr, _entry, \
+ _is_fp, _tls_area ) \
+ _CPU_Context_Initialize( _the_context, _stack, _size, _isr, _entry, \
+ _is_fp, _tls_area )
+
+/**
+ * This macro is invoked from _Thread_Handler to do whatever CPU
+ * specific magic is required that must be done in the context of
+ * the thread when it starts.
+ *
+ * If the CPU architecture does not require any magic, then this
+ * macro is empty.
+ */
+
+#if defined(_CPU_Context_Initialization_at_thread_begin)
+ #define _Context_Initialization_at_thread_begin() \
+ _CPU_Context_Initialization_at_thread_begin()
+#else
+ #define _Context_Initialization_at_thread_begin()
+#endif
+
+/**
+ * @brief Perform context switch.
+ *
+ * This routine saves the current context into the @a _executing
+ * context record and restores the context specified by @a _heir.
+ *
+ * @param[in] _executing is the currently executing thread's context
+ * @param[in] _heir is the context of the thread to be switched to
+ */
+#define _Context_Switch( _executing, _heir ) \
+ _CPU_Context_switch( _executing, _heir )
+
+/**
+ * @brief Restart currently executing thread.
+ *
+ * This routine restarts the calling thread by restoring its initial
+ * stack pointer and returning to the thread's entry point.
+ *
+ * @param[in] _the_context is the context of the thread to restart
+ */
+#define _Context_Restart_self( _the_context ) \
+ _CPU_Context_Restart_self( _the_context )
+
+/**
+ * @brief Initialize floating point context area.
+ *
+ * This routine initializes the floating point context save
+ * area to contain an initial known state.
+ *
+ * @param[in] _fp_area is the base address of the floating point
+ * context save area to initialize.
+ */
+#define _Context_Initialize_fp( _fp_area ) \
+ _CPU_Context_Initialize_fp( _fp_area )
+
+/**
+ * @brief Restore floating point context area.
+ *
+ * This routine restores the floating point context contained
+ * in the @a _fp area. It is assumed that the current
+ * floating point context has been saved by a previous invocation
+ * of @a _Context_Save_fp.
+ *
+ * @param[in] _fp points to the floating point context area to restore.
+ */
+#define _Context_Restore_fp( _fp ) \
+ _CPU_Context_restore_fp( _fp )
+
+/**
+ * @brief Save floating point context area.
+ *
+ * This routine saves the current floating point context
+ * in the @a _fp area.
+ *
+ * @param[in] _fp points to the floating point context area to restore.
+ */
+#define _Context_Save_fp( _fp ) \
+ _CPU_Context_save_fp( _fp )
+
+#if defined(_CPU_Context_Destroy)
+ #define _Context_Destroy( _the_thread, _the_context ) \
+ _CPU_Context_Destroy( _the_thread, _the_context )
+#else
+ #define _Context_Destroy( _the_thread, _the_context )
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/copyrt.h b/cpukit/include/rtems/score/copyrt.h
new file mode 100644
index 0000000000..17c925a008
--- /dev/null
+++ b/cpukit/include/rtems/score/copyrt.h
@@ -0,0 +1,44 @@
+/**
+ * @file rtems/score/copyrt.h
+ *
+ * @brief Copyright Notice for RTEMS
+ *
+ * This include file contains the copyright notice for RTEMS
+ * which is included in every binary copy of the executive.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_COPYRT_H
+#define _RTEMS_SCORE_COPYRT_H
+
+/**
+ * @defgroup SuperCoreCopyright RTEMS Copyright Notice
+ *
+ * @ingroup Score
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This is the copyright string for RTEMS.
+ */
+extern const char _Copyright_Notice[];
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/corebarrier.h b/cpukit/include/rtems/score/corebarrier.h
new file mode 100644
index 0000000000..ba706be3e3
--- /dev/null
+++ b/cpukit/include/rtems/score/corebarrier.h
@@ -0,0 +1,91 @@
+/**
+ * @file rtems/score/corebarrier.h
+ *
+ * @brief Constants and Structures Associated with the Barrier Handler
+ *
+ * This include file contains all the constants and structures associated
+ * with the Barrier Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2007.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_COREBARRIER_H
+#define _RTEMS_SCORE_COREBARRIER_H
+
+#include <rtems/score/threadq.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreBarrier Barrier Handler
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality which provides the foundation
+ * Barrier services used in all of the APIs supported by RTEMS.
+ */
+/**@{*/
+
+/**
+ * Flavors of barriers.
+ */
+typedef enum {
+ /** This specifies that the barrier will automatically release when
+ * the user specified number of threads have arrived at the barrier.
+ */
+ CORE_BARRIER_AUTOMATIC_RELEASE,
+ /** This specifies that the user will have to manually release the barrier
+ * in order to release the waiting threads.
+ */
+ CORE_BARRIER_MANUAL_RELEASE
+} CORE_barrier_Disciplines;
+
+/**
+ * The following defines the control block used to manage the
+ * attributes of each barrier.
+ */
+typedef struct {
+ /** This field indicates whether the barrier is automatic or manual.
+ */
+ CORE_barrier_Disciplines discipline;
+ /** This element indicates the number of threads which must arrive at the
+ * barrier to trip the automatic release.
+ */
+ uint32_t maximum_count;
+} CORE_barrier_Attributes;
+
+/**
+ * The following defines the control block used to manage each
+ * barrier.
+ */
+typedef struct {
+ /** This field is the Waiting Queue used to manage the set of tasks
+ * which are blocked waiting for the barrier to be released.
+ */
+ Thread_queue_Control Wait_queue;
+ /** This element is the set of attributes which define this instance's
+ * behavior.
+ */
+ CORE_barrier_Attributes Attributes;
+ /** This element contains the current number of thread waiting for this
+ * barrier to be released. */
+ uint32_t number_of_waiting_threads;
+} CORE_barrier_Control;
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/corebarrierimpl.h b/cpukit/include/rtems/score/corebarrierimpl.h
new file mode 100644
index 0000000000..d5d63659d0
--- /dev/null
+++ b/cpukit/include/rtems/score/corebarrierimpl.h
@@ -0,0 +1,173 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines Associated with the SuperCore Barrier
+ *
+ * This include file contains all of the inlined routines associated
+ * with the SuperCore barrier.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_COREBARRIERIMPL_H
+#define _RTEMS_SCORE_COREBARRIERIMPL_H
+
+#include <rtems/score/corebarrier.h>
+#include <rtems/score/status.h>
+#include <rtems/score/threadqimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreBarrier
+ */
+/**@{**/
+
+#define CORE_BARRIER_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
+
+/**
+ * @brief Initialize core barrier.
+ *
+ * This routine initializes the barrier based on the parameters passed.
+ *
+ * @param[in] the_barrier is the barrier to initialize
+ * @param[in] the_barrier_attributes define the behavior of this instance
+ */
+void _CORE_barrier_Initialize(
+ CORE_barrier_Control *the_barrier,
+ CORE_barrier_Attributes *the_barrier_attributes
+);
+
+RTEMS_INLINE_ROUTINE void _CORE_barrier_Destroy(
+ CORE_barrier_Control *the_barrier
+)
+{
+ _Thread_queue_Destroy( &the_barrier->Wait_queue );
+}
+
+RTEMS_INLINE_ROUTINE void _CORE_barrier_Acquire_critical(
+ CORE_barrier_Control *the_barrier,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Acquire_critical( &the_barrier->Wait_queue, queue_context );
+}
+
+RTEMS_INLINE_ROUTINE void _CORE_barrier_Release(
+ CORE_barrier_Control *the_barrier,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Release( &the_barrier->Wait_queue, queue_context );
+}
+
+/**
+ * @brief Wait for the barrier.
+ *
+ * This routine wait for the barrier to be released. If the barrier
+ * is set to automatic and this is the appropriate thread, then it returns
+ * immediately. Otherwise, the calling thread is blocked until the barrier
+ * is released.
+ *
+ * @param[in] the_barrier is the barrier to wait for
+ * @param[in,out] executing The currently executing thread.
+ * @param[in] wait is true if the calling thread is willing to wait
+ *
+ * @return The method status.
+ */
+Status_Control _CORE_barrier_Seize(
+ CORE_barrier_Control *the_barrier,
+ Thread_Control *executing,
+ bool wait,
+ Thread_queue_Context *queue_context
+);
+
+uint32_t _CORE_barrier_Do_flush(
+ CORE_barrier_Control *the_barrier,
+ Thread_queue_Flush_filter filter,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Manually release the barrier.
+ *
+ * This routine manually releases the barrier. All of the threads waiting
+ * for the barrier will be readied.
+ *
+ * @param[in] the_barrier is the barrier to surrender
+ * @param[in] mp_callout is the routine to invoke if the
+ * thread unblocked is remote
+ *
+ * @retval the number of unblocked threads
+ */
+RTEMS_INLINE_ROUTINE uint32_t _CORE_barrier_Surrender(
+ CORE_barrier_Control *the_barrier,
+ Thread_queue_Context *queue_context
+)
+{
+ return _CORE_barrier_Do_flush(
+ the_barrier,
+ _Thread_queue_Flush_default_filter,
+ queue_context
+ );
+}
+
+RTEMS_INLINE_ROUTINE void _CORE_barrier_Flush(
+ CORE_barrier_Control *the_barrier,
+ Thread_queue_Context *queue_context
+)
+{
+ _CORE_barrier_Do_flush(
+ the_barrier,
+ _Thread_queue_Flush_status_object_was_deleted,
+ queue_context
+ );
+}
+
+/**
+ * This function returns true if the automatic release attribute is
+ * enabled in the @a attribute_set and false otherwise.
+ *
+ * @param[in] the_attribute is the attribute set to test
+ *
+ * @return true if the priority attribute is enabled
+ */
+RTEMS_INLINE_ROUTINE bool _CORE_barrier_Is_automatic(
+ CORE_barrier_Attributes *the_attribute
+)
+{
+ return
+ (the_attribute->discipline == CORE_BARRIER_AUTOMATIC_RELEASE);
+}
+
+/**
+ * This routine returns the number of threads currently waiting at the barrier.
+ *
+ * @param[in] the_barrier is the barrier to obtain the number of blocked
+ * threads for
+ * @return the current count of this barrier
+ */
+RTEMS_INLINE_ROUTINE uint32_t _CORE_barrier_Get_number_of_waiting_threads(
+ CORE_barrier_Control *the_barrier
+)
+{
+ return the_barrier->number_of_waiting_threads;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/coremsg.h b/cpukit/include/rtems/score/coremsg.h
new file mode 100644
index 0000000000..8d25529fdc
--- /dev/null
+++ b/cpukit/include/rtems/score/coremsg.h
@@ -0,0 +1,185 @@
+/**
+ * @file rtems/score/coremsg.h
+ *
+ * @brief Constants and Structures Associated with the Message Queue Handler.
+ *
+ * This include file contains all the constants and structures associated
+ * with the Message queue Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_COREMSG_H
+#define _RTEMS_SCORE_COREMSG_H
+
+#include <rtems/score/chain.h>
+#include <rtems/score/isrlock.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/watchdog.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreMessageQueue Message Queue Handler
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality which provides the foundation
+ * Message Queue services used in all of the APIs supported by RTEMS.
+ */
+/**@{*/
+
+#if defined(RTEMS_POSIX_API)
+ /**
+ * This macro is defined when an API is enabled that requires that the
+ * Message Queue Handler include support for priority based enqueuing
+ * of messages.
+ */
+ #define RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY
+#endif
+
+#if defined(RTEMS_POSIX_API)
+ /**
+ * This macro is defined when an API is enabled that requires that the
+ * Message Queue Handler include support for notification of enqueuing
+ * a message.
+ */
+ #define RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION
+#endif
+
+#if defined(RTEMS_POSIX_API)
+ /**
+ * This macro is defined when an API is enabled that requires the
+ * Message Queue Handler include support for blocking send operations.
+ */
+ #define RTEMS_SCORE_COREMSG_ENABLE_BLOCKING_SEND
+#endif
+
+typedef struct CORE_message_queue_Control CORE_message_queue_Control;
+
+/**
+ * @brief Data types needed to manipulate the contents of message buffers.
+ *
+ * The following defines the data types needed to manipulate
+ * the contents of message buffers.
+ *
+ * @note The buffer field is normally longer than a single uint32_t
+ * but since messages are variable length we just make a ptr to 1.
+ */
+typedef struct {
+ /** This field is the size of this message. */
+ size_t size;
+ /** This field contains the actual message. */
+ uint32_t buffer[1];
+} CORE_message_queue_Buffer;
+
+/**
+ * @brief The organization of a message buffer.
+ *
+ * The following records define the organization of a message
+ * buffer.
+ */
+typedef struct {
+ /** This element allows this structure to be placed on chains. */
+ Chain_Node Node;
+ #if defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY)
+ /** This field is the priority of this message. */
+ int priority;
+ #endif
+ /** This field points to the contents of the message. */
+ CORE_message_queue_Buffer Contents;
+} CORE_message_queue_Buffer_control;
+
+/**
+ * @brief The possible blocking disciplines for a message queue.
+ *
+ * This enumerated types defines the possible blocking disciplines
+ * for a message queue.
+ */
+typedef enum {
+ /** This value indicates that blocking tasks are in FIFO order. */
+ CORE_MESSAGE_QUEUE_DISCIPLINES_FIFO,
+ /** This value indicates that blocking tasks are in priority order. */
+ CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY
+} CORE_message_queue_Disciplines;
+
+#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
+ /**
+ * @brief Type for a notification handler.
+ *
+ * The following defines the type for a Notification handler. A
+ * notification handler is invoked when the message queue makes a
+ * 0->1 transition on pending messages.
+ */
+ typedef void (*CORE_message_queue_Notify_Handler)(
+ CORE_message_queue_Control *,
+ Thread_queue_Context *
+ );
+#endif
+
+/**
+ * @brief Control block used to manage each message queue.
+ *
+ * The following defines the control block used to manage each
+ * Message Queue.
+ */
+struct CORE_message_queue_Control {
+ /** This field is the Waiting Queue used to manage the set of tasks
+ * which are blocked waiting to receive a message from this queue.
+ */
+ Thread_queue_Control Wait_queue;
+
+ /**
+ * @brief The thread queue operations according to the blocking discipline.
+ */
+ const Thread_queue_Operations *operations;
+
+ /** This element is maximum number of messages which may be pending
+ * at any given time.
+ */
+ uint32_t maximum_pending_messages;
+ /** This element is the number of messages which are currently pending.
+ */
+ uint32_t number_of_pending_messages;
+ /** This is the size in bytes of the largest message which may be
+ * sent via this queue.
+ */
+ size_t maximum_message_size;
+ /** This chain is the set of pending messages. It may be ordered by
+ * message priority or in FIFO order.
+ */
+ Chain_Control Pending_messages;
+ /** This is the address of the memory allocated for message buffers.
+ * It is allocated are part of message queue initialization and freed
+ * as part of destroying it.
+ */
+ CORE_message_queue_Buffer *message_buffers;
+ #if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
+ /** This is the routine invoked when the message queue transitions
+ * from zero (0) messages pending to one (1) message pending.
+ */
+ CORE_message_queue_Notify_Handler notify_handler;
+ #endif
+ /** This chain is the set of inactive messages. A message is inactive
+ * when it does not contain a pending message.
+ */
+ Chain_Control Inactive_messages;
+};
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/coremsgimpl.h b/cpukit/include/rtems/score/coremsgimpl.h
new file mode 100644
index 0000000000..e33e3308b2
--- /dev/null
+++ b/cpukit/include/rtems/score/coremsgimpl.h
@@ -0,0 +1,494 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines in the Core Message Handler
+ *
+ * This include file contains the static inline implementation of all
+ * inlined routines in the Core Message Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_COREMSGIMPL_H
+#define _RTEMS_SCORE_COREMSGIMPL_H
+
+#include <rtems/score/coremsg.h>
+#include <rtems/score/status.h>
+#include <rtems/score/chainimpl.h>
+#include <rtems/score/threaddispatch.h>
+#include <rtems/score/threadqimpl.h>
+
+#include <limits.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreMessageQueue
+ */
+/**@{**/
+
+/**
+ * @brief Used when appending messages onto a message queue.
+ *
+ * This is the priority constant used when appending messages onto
+ * a message queue.
+ */
+#define CORE_MESSAGE_QUEUE_SEND_REQUEST INT_MAX
+
+/**
+ * @brief Used when prepending messages onto a message queue.
+ *
+ * This is the priority constant used when prepending messages onto
+ * a message queue.
+ */
+#define CORE_MESSAGE_QUEUE_URGENT_REQUEST INT_MIN
+
+/**
+ * @brief The modes in which a message may be submitted to a message queue.
+ *
+ * The following type details the modes in which a message
+ * may be submitted to a message queue. The message may be posted
+ * in a send or urgent fashion.
+ *
+ * @note All other values are message priorities. Numerically smaller
+ * priorities indicate higher priority messages.
+ */
+typedef int CORE_message_queue_Submit_types;
+
+/**
+ * @brief Initialize a message queue.
+ *
+ * This package is the implementation of the CORE Message Queue Handler.
+ * This core object provides task synchronization and communication functions
+ * via messages passed to queue objects.
+ *
+ * This routine initializes @a the_message_queue
+ * based on the parameters passed.
+ *
+ * @param[in] the_message_queue points to the message queue to initialize
+ * @param[in] discipline the blocking discipline
+ * @param[in] maximum_pending_messages is the maximum number of messages
+ * that will be allowed to pend at any given time
+ * @param[in] maximum_message_size is the size of largest message that
+ * may be sent to this message queue instance
+ *
+ * @retval true if the message queue can be initialized. In general,
+ * false will only be returned if memory for the pending
+ * messages cannot be allocated.
+ */
+bool _CORE_message_queue_Initialize(
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Disciplines discipline,
+ uint32_t maximum_pending_messages,
+ size_t maximum_message_size
+);
+
+/**
+ * @brief Close a message queue.
+ *
+ * This package is the implementation of the CORE Message Queue Handler.
+ * This core object provides task synchronization and communication functions
+ * via messages passed to queue objects
+ *
+ * This function closes a message by returning all allocated space and
+ * flushing @a the_message_queue's task wait queue.
+ *
+ * @param[in] the_message_queue points to the message queue to close
+ * @param[in] queue_context The thread queue context used for
+ * _CORE_message_queue_Acquire() or _CORE_message_queue_Acquire_critical().
+ */
+void _CORE_message_queue_Close(
+ CORE_message_queue_Control *the_message_queue,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Flush pending messages.
+ *
+ * This package is the implementation of the CORE Message Queue Handler.
+ * This core object provides task synchronization and communication functions
+ * via messages passed to queue objects.
+ *
+ * This function flushes @a the_message_queue's pending message queue. The
+ * number of messages flushed from the queue is returned.
+ *
+ * @param[in] the_message_queue points to the message queue to flush
+ * @param[in] queue_context The thread queue context with interrupts disabled.
+ *
+ * @retval This method returns the number of message pending messages flushed.
+ */
+uint32_t _CORE_message_queue_Flush(
+ CORE_message_queue_Control *the_message_queue,
+ Thread_queue_Context *queue_context
+);
+
+#if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API)
+/**
+ * @brief Flush waiting threads.
+ *
+ * This function flushes the threads which are blocked on
+ * @a the_message_queue's pending message queue. They are
+ * unblocked whether blocked sending or receiving. It returns
+ * the number of messages flushed from the queue.
+ *
+ * @param[in] the_message_queue points to the message queue to flush
+ * @retval number of messages flushed from the queue
+ */
+ void _CORE_message_queue_Flush_waiting_threads(
+ CORE_message_queue_Control *the_message_queue
+ );
+#endif
+
+/**
+ * @brief Broadcast a message to the message queue.
+ *
+ * This package is the implementation of the CORE Message Queue Handler.
+ * This core object provides task synchronization and communication functions
+ * via messages passed to queue objects.
+ *
+ * This function sends a message for every thread waiting on the queue and
+ * returns the number of threads made ready by the message.
+ *
+ * @param[in] the_message_queue points to the message queue
+ * @param[in] buffer is the starting address of the message to broadcast
+ * @param[in] size is the size of the message being broadcast
+ * @param[out] count points to the variable that will contain the
+ * number of tasks that are sent this message
+ * @param[in] queue_context The thread queue context used for
+ * _CORE_message_queue_Acquire() or _CORE_message_queue_Acquire_critical().
+ * @retval @a *count will contain the number of messages sent
+ * @retval indication of the successful completion or reason for failure
+ */
+Status_Control _CORE_message_queue_Broadcast(
+ CORE_message_queue_Control *the_message_queue,
+ const void *buffer,
+ size_t size,
+ uint32_t *count,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Submit a message to the message queue.
+ *
+ * This routine implements the send and urgent message functions. It
+ * processes a message that is to be submitted to the designated
+ * message queue. The message will either be processed as a
+ * send message which it will be inserted at the rear of the queue
+ * or it will be processed as an urgent message which will be inserted
+ * at the front of the queue.
+ *
+ * @param[in] the_message_queue points to the message queue
+ * @param[in] buffer is the starting address of the message to send
+ * @param[in] size is the size of the message being send
+ * @param[in] submit_type determines whether the message is prepended,
+ * appended, or enqueued in priority order.
+ * @param[in] wait indicates whether the calling thread is willing to block
+ * if the message queue is full.
+ * @param[in] queue_context The thread queue context used for
+ * _CORE_message_queue_Acquire() or _CORE_message_queue_Acquire_critical().
+ * @retval indication of the successful completion or reason for failure
+ */
+Status_Control _CORE_message_queue_Submit(
+ CORE_message_queue_Control *the_message_queue,
+ Thread_Control *executing,
+ const void *buffer,
+ size_t size,
+ CORE_message_queue_Submit_types submit_type,
+ bool wait,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Size a message from the message queue.
+ *
+ * This package is the implementation of the CORE Message Queue Handler.
+ * This core object provides task synchronization and communication functions
+ * via messages passed to queue objects.
+ *
+ * This kernel routine dequeues a message, copies the message buffer to
+ * a given destination buffer, and frees the message buffer to the
+ * inactive message pool. The thread will be blocked if wait is true,
+ * otherwise an error will be given to the thread if no messages are available.
+ *
+ * @param[in] the_message_queue points to the message queue
+ * @param[in] buffer is the starting address of the message buffer to
+ * to be filled in with a message
+ * @param[in] size_p is a pointer to the size of the @a buffer and
+ * indicates the maximum size message that the caller can receive.
+ * @param[in] wait indicates whether the calling thread is willing to block
+ * if the message queue is empty.
+ * @param[in] queue_context The thread queue context used for
+ * _CORE_message_queue_Acquire() or _CORE_message_queue_Acquire_critical().
+ *
+ * @retval indication of the successful completion or reason for failure.
+ * On success, the location pointed to @a size_p will contain the
+ * size of the received message.
+ *
+ * @note Returns message priority via return area in TCB.
+ *
+ * - INTERRUPT LATENCY:
+ * + available
+ * + wait
+ */
+Status_Control _CORE_message_queue_Seize(
+ CORE_message_queue_Control *the_message_queue,
+ Thread_Control *executing,
+ void *buffer,
+ size_t *size_p,
+ bool wait,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Insert a message into the message queue.
+ *
+ * Copies the specified content into the message storage space and then
+ * inserts the message into the message queue according to the submit type.
+ *
+ * @param[in] the_message_queue points to the message queue
+ * @param[in] the_message is the message to enqueue
+ * @param[in] content_source the message content source
+ * @param[in] content_size the message content size in bytes
+ * @param[in] submit_type determines whether the message is prepended,
+ * appended, or enqueued in priority order.
+ */
+void _CORE_message_queue_Insert_message(
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Buffer_control *the_message,
+ const void *content_source,
+ size_t content_size,
+ CORE_message_queue_Submit_types submit_type
+);
+
+RTEMS_INLINE_ROUTINE Status_Control _CORE_message_queue_Send(
+ CORE_message_queue_Control *the_message_queue,
+ const void *buffer,
+ size_t size,
+ bool wait,
+ Thread_queue_Context *queue_context
+)
+{
+ return _CORE_message_queue_Submit(
+ the_message_queue,
+ _Thread_Executing,
+ buffer,
+ size,
+ CORE_MESSAGE_QUEUE_SEND_REQUEST,
+ wait,
+ queue_context
+ );
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _CORE_message_queue_Urgent(
+ CORE_message_queue_Control *the_message_queue,
+ const void *buffer,
+ size_t size,
+ bool wait,
+ Thread_queue_Context *queue_context
+)
+{
+ return _CORE_message_queue_Submit(
+ the_message_queue,
+ _Thread_Executing,
+ buffer,
+ size,
+ CORE_MESSAGE_QUEUE_URGENT_REQUEST,
+ wait,
+ queue_context
+ );
+}
+
+RTEMS_INLINE_ROUTINE void _CORE_message_queue_Acquire(
+ CORE_message_queue_Control *the_message_queue,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Acquire( &the_message_queue->Wait_queue, queue_context );
+}
+
+RTEMS_INLINE_ROUTINE void _CORE_message_queue_Acquire_critical(
+ CORE_message_queue_Control *the_message_queue,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Acquire_critical( &the_message_queue->Wait_queue, queue_context );
+}
+
+RTEMS_INLINE_ROUTINE void _CORE_message_queue_Release(
+ CORE_message_queue_Control *the_message_queue,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Release( &the_message_queue->Wait_queue, queue_context );
+}
+
+/**
+ * This routine copies the contents of the source message buffer
+ * to the destination message buffer.
+ */
+RTEMS_INLINE_ROUTINE void _CORE_message_queue_Copy_buffer (
+ const void *source,
+ void *destination,
+ size_t size
+)
+{
+ memcpy(destination, source, size);
+}
+
+/**
+ * This function allocates a message buffer from the inactive
+ * message buffer chain.
+ */
+RTEMS_INLINE_ROUTINE CORE_message_queue_Buffer_control *
+_CORE_message_queue_Allocate_message_buffer (
+ CORE_message_queue_Control *the_message_queue
+)
+{
+ return (CORE_message_queue_Buffer_control *)
+ _Chain_Get_unprotected( &the_message_queue->Inactive_messages );
+}
+
+/**
+ * This routine frees a message buffer to the inactive
+ * message buffer chain.
+ */
+RTEMS_INLINE_ROUTINE void _CORE_message_queue_Free_message_buffer (
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Buffer_control *the_message
+)
+{
+ _Chain_Append_unprotected( &the_message_queue->Inactive_messages, &the_message->Node );
+}
+
+/**
+ * This function returns the priority of @a the_message.
+ *
+ * @note It encapsulates the optional behavior that message priority is
+ * disabled if no API requires it.
+ */
+RTEMS_INLINE_ROUTINE int _CORE_message_queue_Get_message_priority (
+ const CORE_message_queue_Buffer_control *the_message
+)
+{
+ #if defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY)
+ return the_message->priority;
+ #else
+ return 0;
+ #endif
+}
+
+/**
+ * This function removes the first message from the_message_queue
+ * and returns a pointer to it.
+ */
+RTEMS_INLINE_ROUTINE
+ CORE_message_queue_Buffer_control *_CORE_message_queue_Get_pending_message (
+ CORE_message_queue_Control *the_message_queue
+)
+{
+ return (CORE_message_queue_Buffer_control *)
+ _Chain_Get_unprotected( &the_message_queue->Pending_messages );
+}
+
+#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
+ /**
+ * This function returns true if notification is enabled on this message
+ * queue and false otherwise.
+ */
+ RTEMS_INLINE_ROUTINE bool _CORE_message_queue_Is_notify_enabled (
+ CORE_message_queue_Control *the_message_queue
+ )
+ {
+ return (the_message_queue->notify_handler != NULL);
+ }
+#endif
+
+/**
+ * This routine initializes the notification information for
+ * @a the_message_queue.
+ */
+#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
+ RTEMS_INLINE_ROUTINE void _CORE_message_queue_Set_notify (
+ CORE_message_queue_Control *the_message_queue,
+ CORE_message_queue_Notify_Handler the_handler
+ )
+ {
+ the_message_queue->notify_handler = the_handler;
+ }
+#else
+ /* turn it into nothing if not enabled */
+ #define _CORE_message_queue_Set_notify( the_message_queue, the_handler ) \
+ do { } while ( 0 )
+#endif
+
+RTEMS_INLINE_ROUTINE Thread_Control *_CORE_message_queue_Dequeue_receiver(
+ CORE_message_queue_Control *the_message_queue,
+ const void *buffer,
+ size_t size,
+ CORE_message_queue_Submit_types submit_type,
+ Thread_queue_Context *queue_context
+)
+{
+ Thread_Control *the_thread;
+
+ /*
+ * If there are pending messages, then there can't be threads
+ * waiting for us to send them a message.
+ *
+ * NOTE: This check is critical because threads can block on
+ * send and receive and this ensures that we are broadcasting
+ * the message to threads waiting to receive -- not to send.
+ */
+ if ( the_message_queue->number_of_pending_messages != 0 ) {
+ return NULL;
+ }
+
+ /*
+ * There must be no pending messages if there is a thread waiting to
+ * receive a message.
+ */
+ the_thread = _Thread_queue_First_locked(
+ &the_message_queue->Wait_queue,
+ the_message_queue->operations
+ );
+ if ( the_thread == NULL ) {
+ return NULL;
+ }
+
+ *(size_t *) the_thread->Wait.return_argument = size;
+ the_thread->Wait.count = (uint32_t) submit_type;
+
+ _CORE_message_queue_Copy_buffer(
+ buffer,
+ the_thread->Wait.return_argument_second.mutable_object,
+ size
+ );
+
+ _Thread_queue_Extract_critical(
+ &the_message_queue->Wait_queue.Queue,
+ the_message_queue->operations,
+ the_thread,
+ queue_context
+ );
+
+ return the_thread;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/coremutex.h b/cpukit/include/rtems/score/coremutex.h
new file mode 100644
index 0000000000..fd1f27c697
--- /dev/null
+++ b/cpukit/include/rtems/score/coremutex.h
@@ -0,0 +1,104 @@
+/**
+ * @file
+ *
+ * @brief CORE Mutex API
+ *
+ * This include file contains all the constants and structures associated with
+ * the Mutex Handler. A mutex is an enhanced version of the standard Dijkstra
+ * binary semaphore used to provide synchronization and mutual exclusion
+ * capabilities.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_COREMUTEX_H
+#define _RTEMS_SCORE_COREMUTEX_H
+
+#include <rtems/score/thread.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/watchdog.h>
+#include <rtems/score/interr.h>
+
+struct _Scheduler_Control;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreMutex Mutex Handler
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality which provides the foundation
+ * Mutex services used in all of the APIs supported by RTEMS.
+ */
+/**@{*/
+
+/**
+ * @brief Control block used to manage each mutex.
+ *
+ * The following defines the control block used to manage each mutex.
+ */
+typedef struct {
+ /**
+ * @brief The thread queue of this mutex.
+ *
+ * The owner of the thread queue indicates the mutex owner.
+ */
+ Thread_queue_Control Wait_queue;
+} CORE_mutex_Control;
+
+/**
+ * @brief The recursive mutex control.
+ */
+typedef struct {
+ /**
+ * @brief The plain non-recursive mutex.
+ */
+ CORE_mutex_Control Mutex;
+
+ /**
+ * @brief The nest level in case of a recursive seize.
+ */
+ unsigned int nest_level;
+} CORE_recursive_mutex_Control;
+
+/**
+ * @brief The recursive mutex control with priority ceiling protocol support.
+ */
+typedef struct {
+ /**
+ * @brief The plain recursive mutex.
+ */
+ CORE_recursive_mutex_Control Recursive;
+
+ /**
+ * @brief The priority ceiling node for the mutex owner.
+ */
+ Priority_Node Priority_ceiling;
+
+#if defined(RTEMS_SMP)
+ /**
+ * @brief The scheduler instance for this priority ceiling mutex.
+ */
+ const struct _Scheduler_Control *scheduler;
+#endif
+} CORE_ceiling_mutex_Control;
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/coremuteximpl.h b/cpukit/include/rtems/score/coremuteximpl.h
new file mode 100644
index 0000000000..78fafca6e1
--- /dev/null
+++ b/cpukit/include/rtems/score/coremuteximpl.h
@@ -0,0 +1,447 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreMutex
+ *
+ * @brief CORE Mutex Implementation
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_COREMUTEXIMPL_H
+#define _RTEMS_SCORE_COREMUTEXIMPL_H
+
+#include <rtems/score/coremutex.h>
+#include <rtems/score/chainimpl.h>
+#include <rtems/score/schedulerimpl.h>
+#include <rtems/score/status.h>
+#include <rtems/score/threadimpl.h>
+#include <rtems/score/threadqimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreMutex
+ */
+/**@{**/
+
+#define CORE_MUTEX_TQ_OPERATIONS &_Thread_queue_Operations_priority
+
+#define CORE_MUTEX_TQ_PRIORITY_INHERIT_OPERATIONS \
+ &_Thread_queue_Operations_priority_inherit
+
+RTEMS_INLINE_ROUTINE void _CORE_mutex_Initialize(
+ CORE_mutex_Control *the_mutex
+)
+{
+ _Thread_queue_Object_initialize( &the_mutex->Wait_queue );
+}
+
+RTEMS_INLINE_ROUTINE void _CORE_mutex_Destroy( CORE_mutex_Control *the_mutex )
+{
+ _Thread_queue_Destroy( &the_mutex->Wait_queue );
+}
+
+RTEMS_INLINE_ROUTINE void _CORE_mutex_Acquire_critical(
+ CORE_mutex_Control *the_mutex,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Acquire_critical( &the_mutex->Wait_queue, queue_context );
+}
+
+RTEMS_INLINE_ROUTINE void _CORE_mutex_Release(
+ CORE_mutex_Control *the_mutex,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Release( &the_mutex->Wait_queue, queue_context );
+}
+
+RTEMS_INLINE_ROUTINE Thread_Control *_CORE_mutex_Get_owner(
+ const CORE_mutex_Control *the_mutex
+)
+{
+ return the_mutex->Wait_queue.Queue.owner;
+}
+
+/**
+ * @brief Is mutex locked.
+ *
+ * This routine returns true if the mutex specified is locked and false
+ * otherwise.
+ *
+ * @param[in] the_mutex is the mutex to check.
+ *
+ * @retval true The mutex is locked.
+ * @retval false The mutex is not locked.
+ */
+RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_locked(
+ const CORE_mutex_Control *the_mutex
+)
+{
+ return _CORE_mutex_Get_owner( the_mutex ) != NULL;
+}
+
+Status_Control _CORE_mutex_Seize_slow(
+ CORE_mutex_Control *the_mutex,
+ const Thread_queue_Operations *operations,
+ Thread_Control *executing,
+ bool wait,
+ Thread_queue_Context *queue_context
+);
+
+RTEMS_INLINE_ROUTINE void _CORE_mutex_Set_owner(
+ CORE_mutex_Control *the_mutex,
+ Thread_Control *owner
+)
+{
+ the_mutex->Wait_queue.Queue.owner = owner;
+}
+
+RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_owner(
+ const CORE_mutex_Control *the_mutex,
+ const Thread_Control *the_thread
+)
+{
+ return _CORE_mutex_Get_owner( the_mutex ) == the_thread;
+}
+
+RTEMS_INLINE_ROUTINE void _CORE_recursive_mutex_Initialize(
+ CORE_recursive_mutex_Control *the_mutex
+)
+{
+ _CORE_mutex_Initialize( &the_mutex->Mutex );
+ the_mutex->nest_level = 0;
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Seize_nested(
+ CORE_recursive_mutex_Control *the_mutex
+)
+{
+ ++the_mutex->nest_level;
+ return STATUS_SUCCESSFUL;
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Seize(
+ CORE_recursive_mutex_Control *the_mutex,
+ const Thread_queue_Operations *operations,
+ Thread_Control *executing,
+ bool wait,
+ Status_Control ( *nested )( CORE_recursive_mutex_Control * ),
+ Thread_queue_Context *queue_context
+)
+{
+ Thread_Control *owner;
+
+ _CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
+
+ owner = _CORE_mutex_Get_owner( &the_mutex->Mutex );
+
+ if ( owner == NULL ) {
+ _CORE_mutex_Set_owner( &the_mutex->Mutex, executing );
+ _Thread_Resource_count_increment( executing );
+ _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
+ return STATUS_SUCCESSFUL;
+ }
+
+ if ( owner == executing ) {
+ Status_Control status;
+
+ status = ( *nested )( the_mutex );
+ _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
+ return status;
+ }
+
+ return _CORE_mutex_Seize_slow(
+ &the_mutex->Mutex,
+ operations,
+ executing,
+ wait,
+ queue_context
+ );
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Surrender(
+ CORE_recursive_mutex_Control *the_mutex,
+ const Thread_queue_Operations *operations,
+ Thread_Control *executing,
+ Thread_queue_Context *queue_context
+)
+{
+ unsigned int nest_level;
+ Thread_queue_Heads *heads;
+
+ _CORE_mutex_Acquire_critical( &the_mutex->Mutex, queue_context );
+
+ if ( !_CORE_mutex_Is_owner( &the_mutex->Mutex, executing ) ) {
+ _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
+ return STATUS_NOT_OWNER;
+ }
+
+ nest_level = the_mutex->nest_level;
+
+ if ( nest_level > 0 ) {
+ the_mutex->nest_level = nest_level - 1;
+ _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
+ return STATUS_SUCCESSFUL;
+ }
+
+ _Thread_Resource_count_decrement( executing );
+ _CORE_mutex_Set_owner( &the_mutex->Mutex, NULL );
+
+ heads = the_mutex->Mutex.Wait_queue.Queue.heads;
+
+ if ( heads == NULL ) {
+ _CORE_mutex_Release( &the_mutex->Mutex, queue_context );
+ return STATUS_SUCCESSFUL;
+ }
+
+ _Thread_queue_Surrender(
+ &the_mutex->Mutex.Wait_queue.Queue,
+ heads,
+ executing,
+ queue_context,
+ operations
+ );
+ return STATUS_SUCCESSFUL;
+}
+
+RTEMS_INLINE_ROUTINE void _CORE_ceiling_mutex_Initialize(
+ CORE_ceiling_mutex_Control *the_mutex,
+ const Scheduler_Control *scheduler,
+ Priority_Control priority_ceiling
+)
+{
+ _CORE_recursive_mutex_Initialize( &the_mutex->Recursive );
+ _Priority_Node_initialize( &the_mutex->Priority_ceiling, priority_ceiling );
+#if defined(RTEMS_SMP)
+ the_mutex->scheduler = scheduler;
+#endif
+}
+
+RTEMS_INLINE_ROUTINE const Scheduler_Control *
+_CORE_ceiling_mutex_Get_scheduler(
+ const CORE_ceiling_mutex_Control *the_mutex
+)
+{
+#if defined(RTEMS_SMP)
+ return the_mutex->scheduler;
+#else
+ return &_Scheduler_Table[ 0 ];
+#endif
+}
+
+RTEMS_INLINE_ROUTINE void _CORE_ceiling_mutex_Set_priority(
+ CORE_ceiling_mutex_Control *the_mutex,
+ Priority_Control priority_ceiling,
+ Thread_queue_Context *queue_context
+)
+{
+ Thread_Control *owner;
+
+ owner = _CORE_mutex_Get_owner( &the_mutex->Recursive.Mutex );
+
+ if ( owner != NULL ) {
+ _Thread_Wait_acquire( owner, queue_context );
+ _Thread_Priority_change(
+ owner,
+ &the_mutex->Priority_ceiling,
+ priority_ceiling,
+ false,
+ queue_context
+ );
+ _Thread_Wait_release( owner, queue_context );
+ } else {
+ the_mutex->Priority_ceiling.priority = priority_ceiling;
+ }
+}
+
+RTEMS_INLINE_ROUTINE Priority_Control _CORE_ceiling_mutex_Get_priority(
+ const CORE_ceiling_mutex_Control *the_mutex
+)
+{
+ return the_mutex->Priority_ceiling.priority;
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Set_owner(
+ CORE_ceiling_mutex_Control *the_mutex,
+ Thread_Control *owner,
+ Thread_queue_Context *queue_context
+)
+{
+ ISR_lock_Context lock_context;
+ Scheduler_Node *scheduler_node;
+ Per_CPU_Control *cpu_self;
+
+ _Thread_Wait_acquire_default_critical( owner, &lock_context );
+
+ scheduler_node = _Thread_Scheduler_get_home_node( owner );
+
+ if (
+ _Priority_Get_priority( &scheduler_node->Wait.Priority )
+ < the_mutex->Priority_ceiling.priority
+ ) {
+ _Thread_Wait_release_default_critical( owner, &lock_context );
+ _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
+ return STATUS_MUTEX_CEILING_VIOLATED;
+ }
+
+ _CORE_mutex_Set_owner( &the_mutex->Recursive.Mutex, owner );
+ _Thread_Resource_count_increment( owner );
+ _Thread_Priority_add(
+ owner,
+ &the_mutex->Priority_ceiling,
+ queue_context
+ );
+ _Thread_Wait_release_default_critical( owner, &lock_context );
+
+ cpu_self = _Thread_queue_Dispatch_disable( queue_context );
+ _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
+ _Thread_Priority_update( queue_context );
+ _Thread_Dispatch_enable( cpu_self );
+ return STATUS_SUCCESSFUL;
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Seize(
+ CORE_ceiling_mutex_Control *the_mutex,
+ Thread_Control *executing,
+ bool wait,
+ Status_Control ( *nested )( CORE_recursive_mutex_Control * ),
+ Thread_queue_Context *queue_context
+)
+{
+ Thread_Control *owner;
+
+ _CORE_mutex_Acquire_critical( &the_mutex->Recursive.Mutex, queue_context );
+
+ owner = _CORE_mutex_Get_owner( &the_mutex->Recursive.Mutex );
+
+ if ( owner == NULL ) {
+#if defined(RTEMS_SMP)
+ if (
+ _Thread_Scheduler_get_home( executing )
+ != _CORE_ceiling_mutex_Get_scheduler( the_mutex )
+ ) {
+ _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
+ return STATUS_NOT_DEFINED;
+ }
+#endif
+
+ _Thread_queue_Context_clear_priority_updates( queue_context );
+ return _CORE_ceiling_mutex_Set_owner(
+ the_mutex,
+ executing,
+ queue_context
+ );
+ }
+
+ if ( owner == executing ) {
+ Status_Control status;
+
+ status = ( *nested )( &the_mutex->Recursive );
+ _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
+ return status;
+ }
+
+ return _CORE_mutex_Seize_slow(
+ &the_mutex->Recursive.Mutex,
+ CORE_MUTEX_TQ_OPERATIONS,
+ executing,
+ wait,
+ queue_context
+ );
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Surrender(
+ CORE_ceiling_mutex_Control *the_mutex,
+ Thread_Control *executing,
+ Thread_queue_Context *queue_context
+)
+{
+ unsigned int nest_level;
+ ISR_lock_Context lock_context;
+ Per_CPU_Control *cpu_self;
+ Thread_Control *new_owner;
+
+ _CORE_mutex_Acquire_critical( &the_mutex->Recursive.Mutex, queue_context );
+
+ if ( !_CORE_mutex_Is_owner( &the_mutex->Recursive.Mutex, executing ) ) {
+ _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
+ return STATUS_NOT_OWNER;
+ }
+
+ nest_level = the_mutex->Recursive.nest_level;
+
+ if ( nest_level > 0 ) {
+ the_mutex->Recursive.nest_level = nest_level - 1;
+ _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
+ return STATUS_SUCCESSFUL;
+ }
+
+ _Thread_Resource_count_decrement( executing );
+
+ _Thread_queue_Context_clear_priority_updates( queue_context );
+ _Thread_Wait_acquire_default_critical( executing, &lock_context );
+ _Thread_Priority_remove(
+ executing,
+ &the_mutex->Priority_ceiling,
+ queue_context
+ );
+ _Thread_Wait_release_default_critical( executing, &lock_context );
+
+ new_owner = _Thread_queue_First_locked(
+ &the_mutex->Recursive.Mutex.Wait_queue,
+ CORE_MUTEX_TQ_OPERATIONS
+ );
+ _CORE_mutex_Set_owner( &the_mutex->Recursive.Mutex, new_owner );
+
+ cpu_self = _Thread_Dispatch_disable_critical(
+ &queue_context->Lock_context.Lock_context
+ );
+
+ if ( new_owner != NULL ) {
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( _Objects_Is_local_id( new_owner->Object.id ) )
+#endif
+ {
+ _Thread_Resource_count_increment( new_owner );
+ _Thread_Priority_add(
+ new_owner,
+ &the_mutex->Priority_ceiling,
+ queue_context
+ );
+ }
+
+ _Thread_queue_Extract_critical(
+ &the_mutex->Recursive.Mutex.Wait_queue.Queue,
+ CORE_MUTEX_TQ_OPERATIONS,
+ new_owner,
+ queue_context
+ );
+ } else {
+ _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context );
+ }
+
+ _Thread_Priority_update( queue_context );
+ _Thread_Dispatch_enable( cpu_self );
+ return STATUS_SUCCESSFUL;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/corerwlockimpl.h b/cpukit/include/rtems/score/corerwlockimpl.h
new file mode 100644
index 0000000000..942e8c8d75
--- /dev/null
+++ b/cpukit/include/rtems/score/corerwlockimpl.h
@@ -0,0 +1,182 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines Associated with the SuperCore RWLock
+ *
+ * This include file contains all of the inlined routines associated
+ * with the SuperCore RWLock.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_CORERWLOCKIMPL_H
+#define _RTEMS_SCORE_CORERWLOCKIMPL_H
+
+#include <rtems/score/percpu.h>
+#include <rtems/score/status.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threadqimpl.h>
+#include <rtems/score/watchdog.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreRWLock
+ */
+/**@{**/
+
+#define CORE_RWLOCK_TQ_OPERATIONS &_Thread_queue_Operations_FIFO
+
+/**
+ * This is used to denote that a thread is blocking waiting for
+ * read-only access to the RWLock.
+ */
+#define CORE_RWLOCK_THREAD_WAITING_FOR_READ 0
+
+/**
+ * This is used to denote that a thread is blocking waiting for
+ * write-exclusive access to the RWLock.
+ */
+#define CORE_RWLOCK_THREAD_WAITING_FOR_WRITE 1
+
+/**
+ * RWLock State.
+ */
+typedef enum {
+ /** This indicates the the RWLock is not currently locked.
+ */
+ CORE_RWLOCK_UNLOCKED,
+ /** This indicates the the RWLock is currently locked for reading.
+ */
+ CORE_RWLOCK_LOCKED_FOR_READING,
+ /** This indicates the the RWLock is currently locked for reading.
+ */
+ CORE_RWLOCK_LOCKED_FOR_WRITING
+} CORE_RWLock_States;
+
+/**
+ * The following defines the control block used to manage each
+ * RWLock.
+ */
+typedef struct {
+ /** This field is the Waiting Queue used to manage the set of tasks
+ * which are blocked waiting for the RWLock to be released.
+ */
+ Thread_queue_Syslock_queue Queue;
+
+ /** This element is the current state of the RWLock.
+ */
+ CORE_RWLock_States current_state;
+
+ /** This element contains the current number of thread waiting for this
+ * RWLock to be released. */
+ unsigned int number_of_readers;
+} CORE_RWLock_Control;
+
+/**
+ * @brief Initialize a RWlock.
+ *
+ * This routine initializes the RWLock based on the parameters passed.
+ *
+ * @param[in] the_rwlock is the RWLock to initialize
+ */
+void _CORE_RWLock_Initialize(
+ CORE_RWLock_Control *the_rwlock
+);
+
+RTEMS_INLINE_ROUTINE void _CORE_RWLock_Destroy(
+ CORE_RWLock_Control *the_rwlock
+)
+{
+ (void) the_rwlock;
+}
+
+RTEMS_INLINE_ROUTINE Thread_Control *_CORE_RWLock_Acquire(
+ CORE_RWLock_Control *the_rwlock,
+ Thread_queue_Context *queue_context
+)
+{
+ ISR_Level level;
+ Thread_Control *executing;
+
+ _Thread_queue_Context_ISR_disable( queue_context, level );
+ _Thread_queue_Context_set_ISR_level( queue_context, level );
+ executing = _Thread_Executing;
+ _Thread_queue_Queue_acquire_critical(
+ &the_rwlock->Queue.Queue,
+ &executing->Potpourri_stats,
+ &queue_context->Lock_context.Lock_context
+ );
+
+ return executing;
+}
+
+RTEMS_INLINE_ROUTINE void _CORE_RWLock_Release(
+ CORE_RWLock_Control *the_rwlock,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Queue_release(
+ &the_rwlock->Queue.Queue,
+ &queue_context->Lock_context.Lock_context
+ );
+}
+
+/**
+ * @brief Obtain RWLock for reading.
+ *
+ * This routine attempts to obtain the RWLock for read access.
+ *
+ * @param[in] the_rwlock is the RWLock to wait for
+ * @param[in] wait is true if the calling thread is willing to wait
+ */
+
+Status_Control _CORE_RWLock_Seize_for_reading(
+ CORE_RWLock_Control *the_rwlock,
+ bool wait,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Obtain RWLock for writing.
+ *
+ * This routine attempts to obtain the RWLock for write exclusive access.
+ *
+ * @param[in] the_rwlock is the RWLock to wait for
+ * @param[in] wait is true if the calling thread is willing to wait
+ */
+Status_Control _CORE_RWLock_Seize_for_writing(
+ CORE_RWLock_Control *the_rwlock,
+ bool wait,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Release the RWLock.
+ *
+ * This routine manually releases @a the_rwlock. All of the threads waiting
+ * for the RWLock will be readied.
+ *
+ * @param[in] the_rwlock is the RWLock to surrender
+ *
+ * @retval Status is returned to indicate successful or failure.
+ */
+Status_Control _CORE_RWLock_Surrender( CORE_RWLock_Control *the_rwlock );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/coresem.h b/cpukit/include/rtems/score/coresem.h
new file mode 100644
index 0000000000..f9d3ac8fd5
--- /dev/null
+++ b/cpukit/include/rtems/score/coresem.h
@@ -0,0 +1,61 @@
+/**
+ * @file rtems/score/coresem.h
+ *
+ * @brief Data Associated with the Counting Semaphore Handler
+ *
+ * This include file contains all the constants and structures associated
+ * with the Counting Semaphore Handler. A counting semaphore is the
+ * standard Dijkstra binary semaphore used to provide synchronization
+ * and mutual exclusion capabilities.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_CORESEM_H
+#define _RTEMS_SCORE_CORESEM_H
+
+#include <rtems/score/threadq.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreSemaphore Semaphore Handler
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality which provides the foundation
+ * Semaphore services used in all of the APIs supported by RTEMS.
+ */
+/**@{*/
+
+/**
+ * The following defines the control block used to manage each
+ * counting semaphore.
+ */
+typedef struct {
+ /** This field is the Waiting Queue used to manage the set of tasks
+ * which are blocked waiting to obtain the semaphore.
+ */
+ Thread_queue_Control Wait_queue;
+
+ /** This element contains the current count of this semaphore. */
+ uint32_t count;
+} CORE_semaphore_Control;
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/coresemimpl.h b/cpukit/include/rtems/score/coresemimpl.h
new file mode 100644
index 0000000000..00f77e61dd
--- /dev/null
+++ b/cpukit/include/rtems/score/coresemimpl.h
@@ -0,0 +1,207 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines Associated with the SuperCore Semaphore
+ *
+ * This include file contains all of the inlined routines associated
+ * with the SuperCore semaphore.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_CORESEMIMPL_H
+#define _RTEMS_SCORE_CORESEMIMPL_H
+
+#include <rtems/score/coresem.h>
+#include <rtems/score/objectimpl.h>
+#include <rtems/score/threaddispatch.h>
+#include <rtems/score/threadimpl.h>
+#include <rtems/score/threadqimpl.h>
+#include <rtems/score/statesimpl.h>
+#include <rtems/score/status.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreSemaphore
+ */
+/**@{**/
+
+/**
+ * @brief Initialize the semaphore based on the parameters passed.
+ *
+ * This package is the implementation of the CORE Semaphore Handler.
+ * This core object utilizes standard Dijkstra counting semaphores to provide
+ * synchronization and mutual exclusion capabilities.
+ *
+ * This routine initializes the semaphore based on the parameters passed.
+ *
+ * @param[in] the_semaphore is the semaphore to initialize
+ * @param[in] initial_value is the initial count of the semaphore
+ */
+void _CORE_semaphore_Initialize(
+ CORE_semaphore_Control *the_semaphore,
+ uint32_t initial_value
+);
+
+RTEMS_INLINE_ROUTINE void _CORE_semaphore_Acquire_critical(
+ CORE_semaphore_Control *the_semaphore,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Acquire_critical( &the_semaphore->Wait_queue, queue_context );
+}
+
+RTEMS_INLINE_ROUTINE void _CORE_semaphore_Release(
+ CORE_semaphore_Control *the_semaphore,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Release( &the_semaphore->Wait_queue, queue_context );
+}
+
+RTEMS_INLINE_ROUTINE void _CORE_semaphore_Destroy(
+ CORE_semaphore_Control *the_semaphore,
+ const Thread_queue_Operations *operations,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Flush_critical(
+ &the_semaphore->Wait_queue.Queue,
+ operations,
+ _Thread_queue_Flush_status_object_was_deleted,
+ queue_context
+ );
+ _Thread_queue_Destroy( &the_semaphore->Wait_queue );
+}
+
+/**
+ * @brief Surrender a unit to a semaphore.
+ *
+ * This routine frees a unit to the semaphore. If a task was blocked waiting
+ * for a unit from this semaphore, then that task will be readied and the unit
+ * given to that task. Otherwise, the unit will be returned to the semaphore.
+ *
+ * @param[in] the_semaphore is the semaphore to surrender
+ * @param[in] operations The thread queue operations.
+ * @param[in] queue_context is a temporary variable used to contain the ISR
+ * disable level cookie
+ *
+ * @retval an indication of whether the routine succeeded or failed
+ */
+RTEMS_INLINE_ROUTINE Status_Control _CORE_semaphore_Surrender(
+ CORE_semaphore_Control *the_semaphore,
+ const Thread_queue_Operations *operations,
+ uint32_t maximum_count,
+ Thread_queue_Context *queue_context
+)
+{
+ Thread_Control *the_thread;
+ Status_Control status;
+
+ status = STATUS_SUCCESSFUL;
+
+ _CORE_semaphore_Acquire_critical( the_semaphore, queue_context );
+
+ the_thread = _Thread_queue_First_locked(
+ &the_semaphore->Wait_queue,
+ operations
+ );
+ if ( the_thread != NULL ) {
+ _Thread_queue_Extract_critical(
+ &the_semaphore->Wait_queue.Queue,
+ operations,
+ the_thread,
+ queue_context
+ );
+ } else {
+ if ( the_semaphore->count < maximum_count )
+ the_semaphore->count += 1;
+ else
+ status = STATUS_MAXIMUM_COUNT_EXCEEDED;
+
+ _CORE_semaphore_Release( the_semaphore, queue_context );
+ }
+
+ return status;
+}
+
+/**
+ * This routine returns the current count associated with the semaphore.
+ *
+ * @param[in] the_semaphore is the semaphore to obtain the count of
+ *
+ * @return the current count of this semaphore
+ */
+RTEMS_INLINE_ROUTINE uint32_t _CORE_semaphore_Get_count(
+ const CORE_semaphore_Control *the_semaphore
+)
+{
+ return the_semaphore->count;
+}
+
+/**
+ * This routine attempts to receive a unit from the_semaphore.
+ * If a unit is available or if the wait flag is false, then the routine
+ * returns. Otherwise, the calling task is blocked until a unit becomes
+ * available.
+ *
+ * @param[in] the_semaphore is the semaphore to obtain
+ * @param[in] operations The thread queue operations.
+ * @param[in] executing The currently executing thread.
+ * @param[in] wait is true if the thread is willing to wait
+ * @param[in] queue_context is a temporary variable used to contain the ISR
+ * disable level cookie
+ */
+RTEMS_INLINE_ROUTINE Status_Control _CORE_semaphore_Seize(
+ CORE_semaphore_Control *the_semaphore,
+ const Thread_queue_Operations *operations,
+ Thread_Control *executing,
+ bool wait,
+ Thread_queue_Context *queue_context
+)
+{
+ _Assert( _ISR_Get_level() != 0 );
+
+ _CORE_semaphore_Acquire_critical( the_semaphore, queue_context );
+ if ( the_semaphore->count != 0 ) {
+ the_semaphore->count -= 1;
+ _CORE_semaphore_Release( the_semaphore, queue_context );
+ return STATUS_SUCCESSFUL;
+ }
+
+ if ( !wait ) {
+ _CORE_semaphore_Release( the_semaphore, queue_context );
+ return STATUS_UNSATISFIED;
+ }
+
+ _Thread_queue_Context_set_thread_state(
+ queue_context,
+ STATES_WAITING_FOR_SEMAPHORE
+ );
+ _Thread_queue_Enqueue(
+ &the_semaphore->Wait_queue.Queue,
+ operations,
+ executing,
+ queue_context
+ );
+ return _Thread_Wait_get_status( executing );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/cpustdatomic.h b/cpukit/include/rtems/score/cpustdatomic.h
new file mode 100644
index 0000000000..6c6db8d279
--- /dev/null
+++ b/cpukit/include/rtems/score/cpustdatomic.h
@@ -0,0 +1,682 @@
+/**
+ * @file
+ *
+ * @brief Atomic Operations CPU API
+ */
+
+/*
+ * COPYRIGHT (c) 2013 Deng Hengyi.
+ * Copyright (c) 2015 embedded brains GmbH.
+ *
+ * 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_CPUSTDATOMIC_H
+#define _RTEMS_SCORE_CPUSTDATOMIC_H
+
+#include <rtems/score/basedefs.h>
+
+#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
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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 );
+#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
+ atomic_store_explicit( obj, desired, order );
+#else
+ (void) order;
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ *obj = desired;
+#endif
+}
+
+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 );
+#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
+ atomic_store_explicit( obj, desired, order );
+#else
+ (void) order;
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ *obj = desired;
+#endif
+}
+
+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 );
+#elif defined(_RTEMS_SCORE_CPUSTDATOMIC_USE_STDATOMIC)
+ atomic_store_explicit( obj, desired, order );
+#else
+ (void) order;
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ *obj = desired;
+#endif
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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
+}
+
+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/freechain.h b/cpukit/include/rtems/score/freechain.h
new file mode 100644
index 0000000000..1540c0e2a1
--- /dev/null
+++ b/cpukit/include/rtems/score/freechain.h
@@ -0,0 +1,111 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreFreechain
+ *
+ * @brief Freechain Handler API
+ */
+/*
+ * Copyright (c) 2013 Gedare Bloom.
+ *
+ * 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_FREECHAIN_H
+#define _RTEMS_SCORE_FREECHAIN_H
+
+#include <rtems/score/basedefs.h>
+#include <rtems/score/chain.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreFreechain Freechain Handler
+ *
+ * @ingroup Score
+ *
+ * The Freechain Handler is used to manage a chain of nodes, of which size can
+ * automatically increase when there is no free node left. This handler
+ * provides one data structure: Freechain_Control.
+ *
+ * @{
+ */
+
+/**
+ * @brief Allocator function.
+ */
+typedef void *( *Freechain_Allocator )( size_t size );
+
+/**
+ * @brief The freechain control.
+ */
+typedef struct {
+ /**
+ * @brief Chain of free nodes.
+ */
+ Chain_Control Free;
+} Freechain_Control;
+
+/**
+ * @brief Initializes a freechain.
+ *
+ * This routine initializes the freechain control structure to manage a chain
+ * of nodes. In case the freechain is empty the extend handler is called to
+ * get more nodes.
+ *
+ * @param[in] freechain The freechain control to initialize.
+ * @param[in] allocator The allocator function.
+ * @param[in] number_nodes The initial number of nodes.
+ * @param[in] node_size The node size.
+ */
+void _Freechain_Initialize(
+ Freechain_Control *freechain,
+ Freechain_Allocator allocator,
+ size_t number_nodes,
+ size_t node_size
+);
+
+/**
+ * @brief Gets a node from the freechain.
+ *
+ * @param[in] freechain The freechain control.
+ * @param[in] allocator The allocator function.
+ * @param[in] number_nodes_to_extend The number of nodes in case an extend is
+ * necessary due to an empty freechain.
+ * @param[in] node_size The node size.
+ *
+ * @retval NULL The freechain is empty and the extend operation failed.
+ * @retval otherwise Pointer to a node. The node ownership passes to the
+ * caller.
+ */
+void *_Freechain_Get(
+ Freechain_Control *freechain,
+ Freechain_Allocator allocator,
+ size_t number_nodes_to_extend,
+ size_t node_size
+);
+
+/**
+ * @brief Puts a node back onto the freechain.
+ *
+ * @param[in] freechain The freechain control.
+ * @param[in] node The node to put back. The node may be @c NULL, in this case
+ * the function does nothing.
+ */
+void _Freechain_Put(
+ Freechain_Control *freechain,
+ void *node
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/heap.h b/cpukit/include/rtems/score/heap.h
new file mode 100644
index 0000000000..60cb3be99d
--- /dev/null
+++ b/cpukit/include/rtems/score/heap.h
@@ -0,0 +1,518 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreHeap
+ *
+ * @brief Heap Handler API
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_HEAP_H
+#define _RTEMS_SCORE_HEAP_H
+
+#include <rtems/score/cpu.h>
+#include <rtems/score/thread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef RTEMS_DEBUG
+ #define HEAP_PROTECTION
+#endif
+
+/**
+ * @defgroup ScoreHeap Heap Handler
+ *
+ * @ingroup Score
+ *
+ * @brief The Heap Handler provides a heap.
+ *
+ * A heap is a doubly linked list of variable size blocks which are allocated
+ * using the first fit method. Garbage collection is performed each time a
+ * block is returned to the heap by coalescing neighbor blocks. Control
+ * information for both allocated and free blocks is contained in the heap
+ * area. A heap control structure contains control information for the heap.
+ *
+ * The alignment routines could be made faster should we require only powers of
+ * two to be supported for page size, alignment and boundary arguments. The
+ * minimum alignment requirement for pages is currently CPU_ALIGNMENT and this
+ * value is only required to be multiple of two and explicitly not required to
+ * be a power of two.
+ *
+ * There are two kinds of blocks. One sort describes a free block from which
+ * we can allocate memory. The other blocks are used and provide an allocated
+ * memory area. The free blocks are accessible via a list of free blocks.
+ *
+ * Blocks or areas cover a continuous set of memory addresses. They have a
+ * begin and end address. The end address is not part of the set. The size of
+ * a block or area equals the distance between the begin and end address in
+ * units of bytes.
+ *
+ * Free blocks look like:
+ * <table>
+ * <tr>
+ * <td rowspan=4>@ref Heap_Block</td><td>previous block size in case the
+ * previous block is free, <br> otherwise it may contain data used by
+ * the previous block</td>
+ * </tr>
+ * <tr>
+ * <td>block size and a flag which indicates if the previous block is free
+ * or used, <br> this field contains always valid data regardless of the
+ * block usage</td>
+ * </tr>
+ * <tr><td>pointer to next block (this field is page size aligned)</td></tr>
+ * <tr><td>pointer to previous block</td></tr>
+ * <tr><td colspan=2>free space</td></tr>
+ * </table>
+ *
+ * Used blocks look like:
+ * <table>
+ * <tr>
+ * <td rowspan=4>@ref Heap_Block</td><td>previous block size in case the
+ * previous block is free,<br>otherwise it may contain data used by
+ * the previous block</td>
+ * </tr>
+ * <tr>
+ * <td>block size and a flag which indicates if the previous block is free
+ * or used, <br> this field contains always valid data regardless of the
+ * block usage</td>
+ * </tr>
+ * <tr><td>begin of allocated area (this field is page size aligned)</td></tr>
+ * <tr><td>allocated space</td></tr>
+ * <tr><td colspan=2>allocated space</td></tr>
+ * </table>
+ *
+ * The heap area after initialization contains two blocks and looks like:
+ * <table>
+ * <tr><th>Label</th><th colspan=2>Content</th></tr>
+ * <tr><td>heap->area_begin</td><td colspan=2>heap area begin address</td></tr>
+ * <tr>
+ * <td>first_block->prev_size</td>
+ * <td colspan=2>
+ * subordinate heap area end address (this will be used to maintain a
+ * linked list of scattered heap areas)
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>first_block->size</td>
+ * <td colspan=2>size available for allocation
+ * | @c HEAP_PREV_BLOCK_USED</td>
+ * </tr>
+ * <tr>
+ * <td>first_block->next</td><td>_Heap_Free_list_tail(heap)</td>
+ * <td rowspan=3>memory area available for allocation</td>
+ * </tr>
+ * <tr><td>first_block->prev</td><td>_Heap_Free_list_head(heap)</td></tr>
+ * <tr><td>...</td></tr>
+ * <tr>
+ * <td>last_block->prev_size</td><td colspan=2>size of first block</td>
+ * </tr>
+ * <tr>
+ * <td>last_block->size</td>
+ * <td colspan=2>first block begin address - last block begin address</td>
+ * </tr>
+ * <tr><td>heap->area_end</td><td colspan=2>heap area end address</td></tr>
+ * </table>
+ * The next block of the last block is the first block. Since the first
+ * block indicates that the previous block is used, this ensures that the
+ * last block appears as used for the _Heap_Is_used() and _Heap_Is_free()
+ * functions.
+ */
+/**@{**/
+
+typedef struct Heap_Control Heap_Control;
+
+typedef struct Heap_Block Heap_Block;
+
+#ifndef HEAP_PROTECTION
+ #define HEAP_PROTECTION_HEADER_SIZE 0
+#else
+ #define HEAP_PROTECTOR_COUNT 2
+
+ #define HEAP_BEGIN_PROTECTOR_0 ((uintptr_t) 0xfd75a98f)
+ #define HEAP_BEGIN_PROTECTOR_1 ((uintptr_t) 0xbfa1f177)
+ #define HEAP_END_PROTECTOR_0 ((uintptr_t) 0xd6b8855e)
+ #define HEAP_END_PROTECTOR_1 ((uintptr_t) 0x13a44a5b)
+
+ #define HEAP_FREE_PATTERN ((uintptr_t) 0xe7093cdf)
+
+ #define HEAP_PROTECTION_OBOLUS ((Heap_Block *) 1)
+
+ typedef void (*_Heap_Protection_handler)(
+ Heap_Control *heap,
+ Heap_Block *block
+ );
+
+ typedef struct {
+ _Heap_Protection_handler block_initialize;
+ _Heap_Protection_handler block_check;
+ _Heap_Protection_handler block_error;
+ void *handler_data;
+ Heap_Block *first_delayed_free_block;
+ Heap_Block *last_delayed_free_block;
+ uintptr_t delayed_free_block_count;
+ uintptr_t delayed_free_fraction;
+ } Heap_Protection;
+
+ typedef struct {
+ uintptr_t protector [HEAP_PROTECTOR_COUNT];
+ Heap_Block *next_delayed_free_block;
+ Thread_Control *task;
+ void *tag;
+ } Heap_Protection_block_begin;
+
+ typedef struct {
+ uintptr_t protector [HEAP_PROTECTOR_COUNT];
+ } Heap_Protection_block_end;
+
+ #define HEAP_PROTECTION_HEADER_SIZE \
+ (sizeof(Heap_Protection_block_begin) + sizeof(Heap_Protection_block_end))
+#endif
+
+/**
+ * @brief The block header consists of the two size fields
+ * (@ref Heap_Block.prev_size and @ref Heap_Block.size_and_flag).
+ */
+#define HEAP_BLOCK_HEADER_SIZE \
+ (2 * sizeof(uintptr_t) + HEAP_PROTECTION_HEADER_SIZE)
+
+/**
+ * @brief Description for free or used blocks.
+ */
+struct Heap_Block {
+ /**
+ * @brief Size of the previous block or part of the allocated area of the
+ * previous block.
+ *
+ * This field is only valid if the previous block is free. This case is
+ * indicated by a cleared @c HEAP_PREV_BLOCK_USED flag in the
+ * @a size_and_flag field of the current block.
+ *
+ * In a used block only the @a size_and_flag field needs to be valid. The
+ * @a prev_size field of the current block is maintained by the previous
+ * block. The current block can use the @a prev_size field in the next block
+ * for allocation.
+ */
+ uintptr_t prev_size;
+
+ #ifdef HEAP_PROTECTION
+ Heap_Protection_block_begin Protection_begin;
+ #endif
+
+ /**
+ * @brief Contains the size of the current block and a flag which indicates
+ * if the previous block is free or used.
+ *
+ * If the flag @c HEAP_PREV_BLOCK_USED is set, then the previous block is
+ * used, otherwise the previous block is free. A used previous block may
+ * claim the @a prev_size field for allocation. This trick allows to
+ * decrease the overhead in the used blocks by the size of the @a prev_size
+ * field. As sizes are required to be multiples of two, the least
+ * significant bits would be always zero. We use this bit to store the flag.
+ *
+ * This field is always valid.
+ */
+ uintptr_t size_and_flag;
+
+ #ifdef HEAP_PROTECTION
+ Heap_Protection_block_end Protection_end;
+ #endif
+
+ /**
+ * @brief Pointer to the next free block or part of the allocated area.
+ *
+ * This field is page size aligned and begins of the allocated area in case
+ * the block is used.
+ *
+ * This field is only valid if the block is free and thus part of the free
+ * block list.
+ */
+ Heap_Block *next;
+
+ /**
+ * @brief Pointer to the previous free block or part of the allocated area.
+ *
+ * This field is only valid if the block is free and thus part of the free
+ * block list.
+ */
+ Heap_Block *prev;
+};
+
+/**
+ * @brief Run-time heap statistics.
+ *
+ * The value @a searches / @a allocs gives the mean number of searches per
+ * allocation, while @a max_search gives maximum number of searches ever
+ * performed on a single allocation call.
+ */
+typedef struct {
+ /**
+ * @brief Lifetime number of bytes allocated from this heap.
+ *
+ * This value is an integral multiple of the page size.
+ */
+ uint64_t lifetime_allocated;
+
+ /**
+ * @brief Lifetime number of bytes freed to this heap.
+ *
+ * This value is an integral multiple of the page size.
+ */
+ uint64_t lifetime_freed;
+
+ /**
+ * @brief Size of the allocatable area in bytes.
+ *
+ * This value is an integral multiple of the page size.
+ */
+ uintptr_t size;
+
+ /**
+ * @brief Current free size in bytes.
+ *
+ * This value is an integral multiple of the page size.
+ */
+ uintptr_t free_size;
+
+ /**
+ * @brief Minimum free size ever in bytes.
+ *
+ * This value is an integral multiple of the page size.
+ */
+ uintptr_t min_free_size;
+
+ /**
+ * @brief Current number of free blocks.
+ */
+ uint32_t free_blocks;
+
+ /**
+ * @brief Maximum number of free blocks ever.
+ */
+ uint32_t max_free_blocks;
+
+ /**
+ * @brief Current number of used blocks.
+ */
+ uint32_t used_blocks;
+
+ /**
+ * @brief Maximum number of blocks searched ever.
+ */
+ uint32_t max_search;
+
+ /**
+ * @brief Total number of searches.
+ */
+ uint32_t searches;
+
+ /**
+ * @brief Total number of successful allocations.
+ */
+ uint32_t allocs;
+
+ /**
+ * @brief Total number of failed allocations.
+ */
+ uint32_t failed_allocs;
+
+ /**
+ * @brief Total number of successful frees.
+ */
+ uint32_t frees;
+
+ /**
+ * @brief Total number of successful resizes.
+ */
+ uint32_t resizes;
+} Heap_Statistics;
+
+/**
+ * @brief Control block used to manage a heap.
+ */
+struct Heap_Control {
+ Heap_Block free_list;
+ uintptr_t page_size;
+ uintptr_t min_block_size;
+ uintptr_t area_begin;
+ uintptr_t area_end;
+ Heap_Block *first_block;
+ Heap_Block *last_block;
+ Heap_Statistics stats;
+ #ifdef HEAP_PROTECTION
+ Heap_Protection Protection;
+ #endif
+};
+
+/**
+ * @brief Information about blocks.
+ */
+typedef struct {
+ /**
+ * @brief Number of blocks of this type.
+ */
+ uintptr_t number;
+
+ /**
+ * @brief Largest block of this type.
+ */
+ uintptr_t largest;
+
+ /**
+ * @brief Total size of the blocks of this type.
+ */
+ uintptr_t total;
+} Heap_Information;
+
+/**
+ * @brief Information block returned by _Heap_Get_information().
+ */
+typedef struct {
+ Heap_Information Free;
+ Heap_Information Used;
+ Heap_Statistics Stats;
+} Heap_Information_block;
+
+/**
+ * @brief Heap area structure for table based heap initialization and
+ * extension.
+ *
+ * @see Heap_Initialization_or_extend_handler.
+ */
+typedef struct {
+ void *begin;
+ uintptr_t size;
+} Heap_Area;
+
+/**
+ * @brief Heap initialization and extend handler type.
+ *
+ * This helps to do a table based heap initialization and extension. Create a
+ * table of Heap_Area elements and iterate through it. Set the handler to
+ * _Heap_Initialize() in the first iteration and then to _Heap_Extend().
+ *
+ * @see Heap_Area, _Heap_Initialize(), _Heap_Extend(), or _Heap_No_extend().
+ */
+typedef uintptr_t (*Heap_Initialization_or_extend_handler)(
+ Heap_Control *heap,
+ void *area_begin,
+ uintptr_t area_size,
+ uintptr_t page_size_or_unused
+);
+
+/**
+ * @brief Extends the memory available for the heap @a heap using the memory
+ * area starting at @a area_begin of size @a area_size bytes.
+ *
+ * There are no alignment requirements for the memory area. The memory area
+ * must be big enough to contain some maintenance blocks. It must not overlap
+ * parts of the current heap memory areas. Disconnected memory areas added to
+ * the heap will lead to used blocks which cover the gaps. Extending with an
+ * inappropriate memory area will corrupt the heap resulting in undefined
+ * behaviour.
+ *
+ * The unused fourth parameter is provided to have the same signature as
+ * _Heap_Initialize().
+ *
+ * Returns the extended space available for allocation, or zero in case of failure.
+ *
+ * @see Heap_Initialization_or_extend_handler.
+ */
+uintptr_t _Heap_Extend(
+ Heap_Control *heap,
+ void *area_begin,
+ uintptr_t area_size,
+ uintptr_t unused
+);
+
+/**
+ * @brief This function returns always zero.
+ *
+ * This function only returns zero and does nothing else.
+ *
+ * Returns always zero.
+ *
+ * @see Heap_Initialization_or_extend_handler.
+ */
+uintptr_t _Heap_No_extend(
+ Heap_Control *unused_0,
+ void *unused_1,
+ uintptr_t unused_2,
+ uintptr_t unused_3
+);
+
+RTEMS_INLINE_ROUTINE uintptr_t _Heap_Align_up(
+ uintptr_t value,
+ uintptr_t alignment
+)
+{
+ uintptr_t remainder = value % alignment;
+
+ if ( remainder != 0 ) {
+ return value - remainder + alignment;
+ } else {
+ return value;
+ }
+}
+
+RTEMS_INLINE_ROUTINE uintptr_t _Heap_Min_block_size( uintptr_t page_size )
+{
+ return _Heap_Align_up( sizeof( Heap_Block ), page_size );
+}
+
+/**
+ * @brief Returns the worst case overhead to manage a memory area.
+ */
+RTEMS_INLINE_ROUTINE uintptr_t _Heap_Area_overhead(
+ uintptr_t page_size
+)
+{
+ if ( page_size != 0 ) {
+ page_size = _Heap_Align_up( page_size, CPU_ALIGNMENT );
+ } else {
+ page_size = CPU_ALIGNMENT;
+ }
+
+ return 2 * (page_size - 1) + HEAP_BLOCK_HEADER_SIZE;
+}
+
+/**
+ * @brief Returns the size with administration and alignment overhead for one
+ * allocation.
+ */
+RTEMS_INLINE_ROUTINE uintptr_t _Heap_Size_with_overhead(
+ uintptr_t page_size,
+ uintptr_t size,
+ uintptr_t alignment
+)
+{
+ if ( page_size != 0 ) {
+ page_size = _Heap_Align_up( page_size, CPU_ALIGNMENT );
+ } else {
+ page_size = CPU_ALIGNMENT;
+ }
+
+ if ( page_size < alignment ) {
+ page_size = alignment;
+ }
+
+ return HEAP_BLOCK_HEADER_SIZE + page_size - 1 + size;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/heapimpl.h b/cpukit/include/rtems/score/heapimpl.h
new file mode 100644
index 0000000000..a8948edd6f
--- /dev/null
+++ b/cpukit/include/rtems/score/heapimpl.h
@@ -0,0 +1,601 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreHeap
+ *
+ * @brief Heap Handler Implementation
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_HEAPIMPL_H
+#define _RTEMS_SCORE_HEAPIMPL_H
+
+#include <rtems/score/heap.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreHeap
+ */
+/**@{**/
+
+/**
+ * @brief See also @ref Heap_Block.size_and_flag.
+ */
+#define HEAP_PREV_BLOCK_USED ((uintptr_t) 1)
+
+/**
+ * @brief Size of the part at the block begin which may be used for allocation
+ * in charge of the previous block.
+ */
+#define HEAP_ALLOC_BONUS sizeof(uintptr_t)
+
+/**
+ * @brief See _Heap_Resize_block().
+ */
+typedef enum {
+ HEAP_RESIZE_SUCCESSFUL,
+ HEAP_RESIZE_UNSATISFIED,
+ HEAP_RESIZE_FATAL_ERROR
+} Heap_Resize_status;
+
+/**
+ * @brief Gets the first and last block for the heap area with begin
+ * @a heap_area_begin and size @a heap_area_size.
+ *
+ * A page size of @a page_size and minimal block size of @a min_block_size will
+ * be used for calculation.
+ *
+ * Nothing will be written to this area.
+ *
+ * In case of success the pointers to the first and last block will be returned
+ * via @a first_block_ptr and @a last_block_ptr.
+ *
+ * Returns @c true if the area is big enough, and @c false otherwise.
+ */
+bool _Heap_Get_first_and_last_block(
+ uintptr_t heap_area_begin,
+ uintptr_t heap_area_size,
+ uintptr_t page_size,
+ uintptr_t min_block_size,
+ Heap_Block **first_block_ptr,
+ Heap_Block **last_block_ptr
+);
+
+/**
+ * @brief Initializes the heap control block @a heap to manage the area
+ * starting at @a area_begin of size @a area_size bytes.
+ *
+ * Blocks of memory are allocated from the heap in multiples of @a page_size
+ * byte units. If the @a page_size is equal to zero or is not multiple of
+ * @c CPU_ALIGNMENT, it is aligned up to the nearest @c CPU_ALIGNMENT boundary.
+ *
+ * Returns the maximum memory available, or zero in case of failure.
+ *
+ * @see Heap_Initialization_or_extend_handler.
+ */
+uintptr_t _Heap_Initialize(
+ Heap_Control *heap,
+ void *area_begin,
+ uintptr_t area_size,
+ uintptr_t page_size
+);
+
+/**
+ * @brief Allocates a memory area of size @a size bytes from the heap @a heap.
+ *
+ * If the alignment parameter @a alignment is not equal to zero, the allocated
+ * memory area will begin at an address aligned by this value.
+ *
+ * If the boundary parameter @a boundary is not equal to zero, the allocated
+ * memory area will fulfill a boundary constraint. The boundary value
+ * specifies the set of addresses which are aligned by the boundary value. The
+ * interior of the allocated memory area will not contain an element of this
+ * set. The begin or end address of the area may be a member of the set.
+ *
+ * A size value of zero will return a unique address which may be freed with
+ * _Heap_Free().
+ *
+ * Returns a pointer to the begin of the allocated memory area, or @c NULL if
+ * no memory is available or the parameters are inconsistent.
+ */
+void *_Heap_Allocate_aligned_with_boundary(
+ Heap_Control *heap,
+ uintptr_t size,
+ uintptr_t alignment,
+ uintptr_t boundary
+);
+
+/**
+ * @brief See _Heap_Allocate_aligned_with_boundary() with boundary equals zero.
+ */
+RTEMS_INLINE_ROUTINE void *_Heap_Allocate_aligned(
+ Heap_Control *heap,
+ uintptr_t size,
+ uintptr_t alignment
+)
+{
+ return _Heap_Allocate_aligned_with_boundary( heap, size, alignment, 0 );
+}
+
+/**
+ * @brief See _Heap_Allocate_aligned_with_boundary() with alignment and
+ * boundary equals zero.
+ */
+RTEMS_INLINE_ROUTINE void *_Heap_Allocate( Heap_Control *heap, uintptr_t size )
+{
+ return _Heap_Allocate_aligned_with_boundary( heap, size, 0, 0 );
+}
+
+/**
+ * @brief Frees the allocated memory area starting at @a addr in the heap
+ * @a heap.
+ *
+ * Inappropriate values for @a addr may corrupt the heap.
+ *
+ * Returns @c true in case of success, and @c false otherwise.
+ */
+bool _Heap_Free( Heap_Control *heap, void *addr );
+
+/**
+ * @brief Walks the heap @a heap to verify its integrity.
+ *
+ * If @a dump is @c true, then diagnostic messages will be printed to standard
+ * output. In this case @a source is used to mark the output lines.
+ *
+ * Returns @c true if no errors occurred, and @c false if the heap is corrupt.
+ */
+bool _Heap_Walk(
+ Heap_Control *heap,
+ int source,
+ bool dump
+);
+
+/**
+ * @brief Heap block visitor.
+ *
+ * @see _Heap_Iterate().
+ *
+ * @retval true Stop the iteration.
+ * @retval false Continue the iteration.
+ */
+typedef bool (*Heap_Block_visitor)(
+ const Heap_Block *block,
+ uintptr_t block_size,
+ bool block_is_used,
+ void *visitor_arg
+);
+
+/**
+ * @brief Iterates over all blocks of the heap.
+ *
+ * For each block the @a visitor with the argument @a visitor_arg will be
+ * called.
+ */
+void _Heap_Iterate(
+ Heap_Control *heap,
+ Heap_Block_visitor visitor,
+ void *visitor_arg
+);
+
+/**
+ * @brief Greedy allocate that empties the heap.
+ *
+ * Afterwards the heap has at most @a block_count allocatable blocks of sizes
+ * specified by @a block_sizes. The @a block_sizes must point to an array with
+ * @a block_count members. All other blocks are used.
+ *
+ * @see _Heap_Greedy_free().
+ */
+Heap_Block *_Heap_Greedy_allocate(
+ Heap_Control *heap,
+ const uintptr_t *block_sizes,
+ size_t block_count
+);
+
+/**
+ * @brief Greedy allocate all blocks except the largest free block.
+ *
+ * Afterwards the heap has at most one allocatable block. This block is the
+ * largest free block if it exists. The allocatable size of this block is
+ * stored in @a allocatable_size. All other blocks are used.
+ *
+ * @see _Heap_Greedy_free().
+ */
+Heap_Block *_Heap_Greedy_allocate_all_except_largest(
+ Heap_Control *heap,
+ uintptr_t *allocatable_size
+);
+
+/**
+ * @brief Frees blocks of a greedy allocation.
+ *
+ * The @a blocks must be the return value of _Heap_Greedy_allocate().
+ */
+void _Heap_Greedy_free(
+ Heap_Control *heap,
+ Heap_Block *blocks
+);
+
+/**
+ * @brief Returns information about used and free blocks for the heap @a heap
+ * in @a info.
+ */
+void _Heap_Get_information(
+ Heap_Control *heap,
+ Heap_Information_block *info
+);
+
+/**
+ * @brief Returns information about free blocks for the heap @a heap in
+ * @a info.
+ */
+void _Heap_Get_free_information(
+ Heap_Control *heap,
+ Heap_Information *info
+);
+
+/**
+ * @brief Returns the size of the allocatable memory area starting at @a addr
+ * in @a size.
+ *
+ * The size value may be greater than the initially requested size in
+ * _Heap_Allocate_aligned_with_boundary().
+ *
+ * Inappropriate values for @a addr will not corrupt the heap, but may yield
+ * invalid size values.
+ *
+ * Returns @a true if successful, and @c false otherwise.
+ */
+bool _Heap_Size_of_alloc_area(
+ Heap_Control *heap,
+ void *addr,
+ uintptr_t *size
+);
+
+/**
+ * @brief Resizes the block of the allocated memory area starting at @a addr.
+ *
+ * The new memory area will have a size of at least @a size bytes. A resize
+ * may be impossible and depends on the current heap usage.
+ *
+ * The size available for allocation in the current block before the resize
+ * will be returned in @a old_size. The size available for allocation in
+ * the resized block will be returned in @a new_size. If the resize was not
+ * successful, then a value of zero will be returned in @a new_size.
+ *
+ * Inappropriate values for @a addr may corrupt the heap.
+ */
+Heap_Resize_status _Heap_Resize_block(
+ Heap_Control *heap,
+ void *addr,
+ uintptr_t size,
+ uintptr_t *old_size,
+ uintptr_t *new_size
+);
+
+/**
+ * @brief Allocates the memory area starting at @a alloc_begin of size
+ * @a alloc_size bytes in the block @a block.
+ *
+ * The block may be split up into multiple blocks. The previous and next block
+ * may be used or free. Free block parts which form a vaild new block will be
+ * inserted into the free list or merged with an adjacent free block. If the
+ * block is used, they will be inserted after the free list head. If the block
+ * is free, they will be inserted after the previous block in the free list.
+ *
+ * Inappropriate values for @a alloc_begin or @a alloc_size may corrupt the
+ * heap.
+ *
+ * Returns the block containing the allocated memory area.
+ */
+Heap_Block *_Heap_Block_allocate(
+ Heap_Control *heap,
+ Heap_Block *block,
+ uintptr_t alloc_begin,
+ uintptr_t alloc_size
+);
+
+#ifndef HEAP_PROTECTION
+ #define _Heap_Protection_block_initialize( heap, block ) ((void) 0)
+ #define _Heap_Protection_block_check( heap, block ) ((void) 0)
+ #define _Heap_Protection_block_error( heap, block ) ((void) 0)
+ #define _Heap_Protection_free_all_delayed_blocks( heap ) ((void) 0)
+#else
+ static inline void _Heap_Protection_block_initialize(
+ Heap_Control *heap,
+ Heap_Block *block
+ )
+ {
+ (*heap->Protection.block_initialize)( heap, block );
+ }
+
+ static inline void _Heap_Protection_block_check(
+ Heap_Control *heap,
+ Heap_Block *block
+ )
+ {
+ (*heap->Protection.block_check)( heap, block );
+ }
+
+ static inline void _Heap_Protection_block_error(
+ Heap_Control *heap,
+ Heap_Block *block
+ )
+ {
+ (*heap->Protection.block_error)( heap, block );
+ }
+
+ static inline void _Heap_Protection_free_all_delayed_blocks( Heap_Control *heap )
+ {
+ uintptr_t large = 0
+ - (uintptr_t) HEAP_BLOCK_HEADER_SIZE
+ - (uintptr_t) HEAP_ALLOC_BONUS
+ - (uintptr_t) 1;
+ void *p = _Heap_Allocate( heap, large );
+ _Heap_Free( heap, p );
+ }
+#endif
+
+/**
+ * @brief Sets the fraction of delayed free blocks that is actually freed
+ * during memory shortage.
+ *
+ * The default is to free half the delayed free blocks. This is equal to a
+ * fraction value of two.
+ *
+ * @param[in] heap The heap control.
+ * @param[in] fraction The fraction is one divided by this fraction value.
+ */
+RTEMS_INLINE_ROUTINE void _Heap_Protection_set_delayed_free_fraction(
+ Heap_Control *heap,
+ uintptr_t fraction
+)
+{
+#ifdef HEAP_PROTECTION
+ heap->Protection.delayed_free_fraction = fraction;
+#else
+ (void) heap;
+ (void) fraction;
+#endif
+}
+
+RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Free_list_head( Heap_Control *heap )
+{
+ return &heap->free_list;
+}
+
+RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Free_list_tail( Heap_Control *heap )
+{
+ return &heap->free_list;
+}
+
+RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Free_list_first( Heap_Control *heap )
+{
+ return _Heap_Free_list_head(heap)->next;
+}
+
+RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Free_list_last( Heap_Control *heap )
+{
+ return _Heap_Free_list_tail(heap)->prev;
+}
+
+RTEMS_INLINE_ROUTINE void _Heap_Free_list_remove( Heap_Block *block )
+{
+ Heap_Block *next = block->next;
+ Heap_Block *prev = block->prev;
+
+ prev->next = next;
+ next->prev = prev;
+}
+
+RTEMS_INLINE_ROUTINE void _Heap_Free_list_replace(
+ Heap_Block *old_block,
+ Heap_Block *new_block
+)
+{
+ Heap_Block *next = old_block->next;
+ Heap_Block *prev = old_block->prev;
+
+ new_block->next = next;
+ new_block->prev = prev;
+
+ next->prev = new_block;
+ prev->next = new_block;
+}
+
+RTEMS_INLINE_ROUTINE void _Heap_Free_list_insert_after(
+ Heap_Block *block_before,
+ Heap_Block *new_block
+)
+{
+ Heap_Block *next = block_before->next;
+
+ new_block->next = next;
+ new_block->prev = block_before;
+ block_before->next = new_block;
+ next->prev = new_block;
+}
+
+RTEMS_INLINE_ROUTINE void _Heap_Free_list_insert_before(
+ Heap_Block *block_next,
+ Heap_Block *new_block
+)
+{
+ Heap_Block *prev = block_next->prev;
+
+ new_block->next = block_next;
+ new_block->prev = prev;
+ prev->next = new_block;
+ block_next->prev = new_block;
+}
+
+RTEMS_INLINE_ROUTINE bool _Heap_Is_aligned(
+ uintptr_t value,
+ uintptr_t alignment
+)
+{
+ return (value % alignment) == 0;
+}
+
+RTEMS_INLINE_ROUTINE uintptr_t _Heap_Align_down(
+ uintptr_t value,
+ uintptr_t alignment
+)
+{
+ return value - (value % alignment);
+}
+
+/**
+ * @brief Returns the block which is @a offset away from @a block.
+ */
+RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Block_at(
+ const Heap_Block *block,
+ uintptr_t offset
+)
+{
+ return (Heap_Block *) ((uintptr_t) block + offset);
+}
+
+RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Prev_block(
+ const Heap_Block *block
+)
+{
+ return (Heap_Block *) ((uintptr_t) block - block->prev_size);
+}
+
+RTEMS_INLINE_ROUTINE uintptr_t _Heap_Alloc_area_of_block(
+ const Heap_Block *block
+)
+{
+ return (uintptr_t) block + HEAP_BLOCK_HEADER_SIZE;
+}
+
+RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Block_of_alloc_area(
+ uintptr_t alloc_begin,
+ uintptr_t page_size
+)
+{
+ return (Heap_Block *) (_Heap_Align_down( alloc_begin, page_size )
+ - HEAP_BLOCK_HEADER_SIZE);
+}
+
+RTEMS_INLINE_ROUTINE uintptr_t _Heap_Block_size( const Heap_Block *block )
+{
+ return block->size_and_flag & ~HEAP_PREV_BLOCK_USED;
+}
+
+RTEMS_INLINE_ROUTINE void _Heap_Block_set_size(
+ Heap_Block *block,
+ uintptr_t size
+)
+{
+ uintptr_t flag = block->size_and_flag & HEAP_PREV_BLOCK_USED;
+
+ block->size_and_flag = size | flag;
+}
+
+RTEMS_INLINE_ROUTINE bool _Heap_Is_prev_used( const Heap_Block *block )
+{
+ return block->size_and_flag & HEAP_PREV_BLOCK_USED;
+}
+
+RTEMS_INLINE_ROUTINE bool _Heap_Is_used(
+ const Heap_Block *block
+)
+{
+ const Heap_Block *const next_block =
+ _Heap_Block_at( block, _Heap_Block_size( block ) );
+
+ return _Heap_Is_prev_used( next_block );
+}
+
+RTEMS_INLINE_ROUTINE bool _Heap_Is_free(
+ const Heap_Block *block
+)
+{
+ return !_Heap_Is_used( block );
+}
+
+RTEMS_INLINE_ROUTINE bool _Heap_Is_block_in_heap(
+ const Heap_Control *heap,
+ const Heap_Block *block
+)
+{
+ return (uintptr_t) block >= (uintptr_t) heap->first_block
+ && (uintptr_t) block <= (uintptr_t) heap->last_block;
+}
+
+/**
+ * @brief Sets the size of the last block for heap @a heap.
+ *
+ * The next block of the last block will be the first block. Since the first
+ * block indicates that the previous block is used, this ensures that the last
+ * block appears as used for the _Heap_Is_used() and _Heap_Is_free()
+ * functions.
+ *
+ * This feature will be used to terminate the scattered heap area list. See
+ * also _Heap_Extend().
+ */
+RTEMS_INLINE_ROUTINE void _Heap_Set_last_block_size( Heap_Control *heap )
+{
+ _Heap_Block_set_size(
+ heap->last_block,
+ (uintptr_t) heap->first_block - (uintptr_t) heap->last_block
+ );
+}
+
+/**
+ * @brief Returns the size of the allocatable area in bytes.
+ *
+ * This value is an integral multiple of the page size.
+ */
+RTEMS_INLINE_ROUTINE uintptr_t _Heap_Get_size( const Heap_Control *heap )
+{
+ return heap->stats.size;
+}
+
+RTEMS_INLINE_ROUTINE uintptr_t _Heap_Max( uintptr_t a, uintptr_t b )
+{
+ return a > b ? a : b;
+}
+
+RTEMS_INLINE_ROUTINE uintptr_t _Heap_Min( uintptr_t a, uintptr_t b )
+{
+ return a < b ? a : b;
+}
+
+#ifdef RTEMS_DEBUG
+ #define RTEMS_HEAP_DEBUG
+#endif
+
+#ifdef RTEMS_HEAP_DEBUG
+ #include <assert.h>
+ #define _HAssert( cond ) \
+ do { \
+ if ( !(cond) ) { \
+ __assert( __FILE__, __LINE__, #cond ); \
+ } \
+ } while (0)
+#else
+ #define _HAssert( cond ) ((void) 0)
+#endif
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/interr.h b/cpukit/include/rtems/score/interr.h
new file mode 100644
index 0000000000..3144952716
--- /dev/null
+++ b/cpukit/include/rtems/score/interr.h
@@ -0,0 +1,268 @@
+/**
+ * @file rtems/score/interr.h
+ *
+ * @brief Constants and Prototypes Related to the Internal Error Handler
+ *
+ * This include file contains constants and prototypes related
+ * to the Internal Error Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_INTERR_H
+#define _RTEMS_SCORE_INTERR_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <rtems/system.h>
+
+/**
+ * @defgroup ScoreIntErr Internal Error Handler
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality which provides the foundation
+ * Semaphore services used in all of the APIs supported by RTEMS.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief This type lists the possible sources from which an error
+ * can be reported.
+ */
+typedef enum {
+ /**
+ * @brief Errors of the core system.
+ *
+ * @see Internal_errors_Core_list.
+ */
+ INTERNAL_ERROR_CORE = 0,
+
+ /**
+ * @brief Errors of the RTEMS API.
+ */
+ INTERNAL_ERROR_RTEMS_API = 1,
+
+ /**
+ * @brief Errors of the POSIX API.
+ */
+ INTERNAL_ERROR_POSIX_API = 2,
+
+ /**
+ * @brief Fatal source for the block device cache.
+ *
+ * @see rtems_bdbuf_fatal_code.
+ */
+ RTEMS_FATAL_SOURCE_BDBUF = 3,
+
+ /**
+ * @brief Fatal source for application specific errors.
+ *
+ * The fatal code is application specific.
+ */
+ RTEMS_FATAL_SOURCE_APPLICATION = 4,
+
+ /**
+ * @brief Fatal source of exit().
+ *
+ * The fatal code is the exit() status code.
+ */
+ RTEMS_FATAL_SOURCE_EXIT = 5,
+
+ /**
+ * @brief Fatal source for BSP errors.
+ *
+ * The fatal codes are defined in <bsp/fatal.h>. Examples are interrupt and
+ * exception initialization.
+ *
+ * @see bsp_fatal_code and bsp_fatal().
+ */
+ RTEMS_FATAL_SOURCE_BSP = 6,
+
+ /**
+ * @brief Fatal source of assert().
+ *
+ * The fatal code is the pointer value of the assert context.
+ *
+ * @see rtems_assert_context.
+ */
+ RTEMS_FATAL_SOURCE_ASSERT = 7,
+
+ /**
+ * @brief Fatal source of the stack checker.
+ *
+ * The fatal code is the object name of the executing task.
+ */
+ RTEMS_FATAL_SOURCE_STACK_CHECKER = 8,
+
+ /**
+ * @brief Fatal source of the exceptions.
+ *
+ * The fatal code is the pointer value of the exception frame pointer.
+ *
+ * @see rtems_exception_frame and rtems_exception_frame_print().
+ */
+ RTEMS_FATAL_SOURCE_EXCEPTION = 9,
+
+ /**
+ * @brief Fatal source of SMP domain.
+ *
+ * @see SMP_Fatal_code.
+ */
+ RTEMS_FATAL_SOURCE_SMP = 10,
+
+ /**
+ * @brief Fatal source of rtems_panic().
+ *
+ * @see rtem
+ */
+ RTEMS_FATAL_SOURCE_PANIC = 11,
+
+ /**
+ * @brief The last available fatal source.
+ *
+ * This enum value ensures that the enum type needs at least 32-bits for
+ * architectures with short enums.
+ */
+ RTEMS_FATAL_SOURCE_LAST = 0xffffffff
+} Internal_errors_Source;
+
+/**
+ * @brief A list of errors which are generated internally by the executive
+ * core.
+ *
+ * Do not re-use numbers of obsolete error codes. Uncomment no longer used
+ * error codes.
+ */
+typedef enum {
+ /* INTERNAL_ERROR_NO_CONFIGURATION_TABLE = 0, */
+ /* INTERNAL_ERROR_NO_CPU_TABLE = 1, */
+ INTERNAL_ERROR_TOO_LITTLE_WORKSPACE = 2,
+ INTERNAL_ERROR_WORKSPACE_ALLOCATION = 3,
+ INTERNAL_ERROR_INTERRUPT_STACK_TOO_SMALL = 4,
+ INTERNAL_ERROR_THREAD_EXITTED = 5,
+ INTERNAL_ERROR_INCONSISTENT_MP_INFORMATION = 6,
+ INTERNAL_ERROR_INVALID_NODE = 7,
+ INTERNAL_ERROR_NO_MPCI = 8,
+ INTERNAL_ERROR_BAD_PACKET = 9,
+ INTERNAL_ERROR_OUT_OF_PACKETS = 10,
+ INTERNAL_ERROR_OUT_OF_GLOBAL_OBJECTS = 11,
+ INTERNAL_ERROR_OUT_OF_PROXIES = 12,
+ INTERNAL_ERROR_INVALID_GLOBAL_ID = 13,
+ INTERNAL_ERROR_BAD_STACK_HOOK = 14,
+ /* INTERNAL_ERROR_BAD_ATTRIBUTES = 15, */
+ /* INTERNAL_ERROR_IMPLEMENTATION_KEY_CREATE_INCONSISTENCY = 16, */
+ /* INTERNAL_ERROR_IMPLEMENTATION_BLOCKING_OPERATION_CANCEL = 17, */
+ /* INTERNAL_ERROR_THREAD_QUEUE_ENQUEUE_FROM_BAD_STATE = 18, */
+ INTERNAL_ERROR_UNLIMITED_AND_MAXIMUM_IS_0 = 19,
+ /* INTERNAL_ERROR_SHUTDOWN_WHEN_NOT_UP = 20, */
+ INTERNAL_ERROR_GXX_KEY_ADD_FAILED = 21,
+ INTERNAL_ERROR_GXX_MUTEX_INIT_FAILED = 22,
+ INTERNAL_ERROR_NO_MEMORY_FOR_HEAP = 23,
+ INTERNAL_ERROR_CPU_ISR_INSTALL_VECTOR = 24,
+ INTERNAL_ERROR_RESOURCE_IN_USE = 25,
+ INTERNAL_ERROR_RTEMS_INIT_TASK_ENTRY_IS_NULL = 26,
+ /* INTERNAL_ERROR_POSIX_INIT_THREAD_ENTRY_IS_NULL = 27, */
+ INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK = 28,
+ INTERNAL_ERROR_THREAD_QUEUE_ENQUEUE_STICKY_FROM_BAD_STATE = 29,
+ INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL = 30,
+ INTERNAL_ERROR_BAD_THREAD_DISPATCH_ENVIRONMENT = 31,
+ INTERNAL_ERROR_RTEMS_INIT_TASK_CREATE_FAILED = 32,
+ INTERNAL_ERROR_POSIX_INIT_THREAD_CREATE_FAILED = 33,
+ INTERNAL_ERROR_LIBIO_USER_ENV_KEY_CREATE_FAILED = 34,
+ /* INTERNAL_ERROR_LIBIO_SEM_CREATE_FAILED = 35, */
+ INTERNAL_ERROR_LIBIO_STDOUT_FD_OPEN_FAILED = 36,
+ INTERNAL_ERROR_LIBIO_STDERR_FD_OPEN_FAILED = 37,
+ INTERNAL_ERROR_ILLEGAL_USE_OF_FLOATING_POINT_UNIT = 38,
+ INTERNAL_ERROR_ARC4RANDOM_GETENTROPY_FAIL = 39
+} Internal_errors_Core_list;
+
+typedef CPU_Uint32ptr Internal_errors_t;
+
+/**
+ * This type holds the fatal error information.
+ */
+typedef struct {
+ /** This is the source of the error. */
+ Internal_errors_Source the_source;
+ /** This is the error code. */
+ Internal_errors_t the_error;
+} Internal_errors_Information;
+
+/**
+ * When a fatal error occurs, the error information is stored here.
+ */
+extern Internal_errors_Information _Internal_errors_What_happened;
+
+/**
+ * @brief Initiates system termination.
+ *
+ * This routine is invoked when the application or the executive itself
+ * determines that a fatal error has occurred or a final system state is
+ * reached (for example after exit()).
+ *
+ * The first action of this function is to call the fatal handler of the user
+ * extensions. For the initial extensions the following conditions are
+ * required
+ * - a valid stack pointer and enough stack space,
+ * - a valid code memory, and
+ * - valid read-only data.
+ *
+ * For the initial extensions the read-write data (including BSS segment) is
+ * not required on single processor configurations. On SMP configurations
+ * however the read-write data must be initialized since this function must
+ * determine the state of the other processors and request them to shut-down if
+ * necessary.
+ *
+ * Non-initial extensions require in addition valid read-write data. The BSP
+ * may install an initial extension that performs a system reset. In this case
+ * the non-initial extensions will be not called.
+ *
+ * Once all fatal handler executed the error information will be stored to
+ * _Internal_errors_What_happened and the system state is set to
+ * SYSTEM_STATE_TERMINATED.
+ *
+ * The final step is to call the CPU specific _CPU_Fatal_halt().
+ *
+ * @param[in] the_source The fatal source indicating the subsystem the fatal
+ * condition originated in.
+ * @param[in] the_error The fatal error code. This value must be interpreted
+ * with respect to the source.
+ *
+ * @see rtems_fatal() and _Internal_error().
+ */
+void _Terminate(
+ Internal_errors_Source the_source,
+ Internal_errors_t the_error
+) RTEMS_NO_RETURN;
+
+/**
+ * @brief Terminates the system with an INTERNAL_ERROR_CORE fatal source and
+ * the specified core error code.
+ *
+ * @param[in] core_error The core error code.
+ *
+ * @see _Terminate().
+ */
+void _Internal_error( Internal_errors_Core_list core_error ) RTEMS_NO_RETURN;
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/io.h b/cpukit/include/rtems/score/io.h
new file mode 100644
index 0000000000..ae3c57f031
--- /dev/null
+++ b/cpukit/include/rtems/score/io.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_IO_H
+#define _RTEMS_SCORE_IO_H
+
+#include <rtems/score/basedefs.h>
+
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+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 );
+
+int _IO_Vprintf(
+ IO_Put_char put_char,
+ void *arg,
+ char const *fmt,
+ va_list ap
+);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_IO_H */
diff --git a/cpukit/include/rtems/score/isr.h b/cpukit/include/rtems/score/isr.h
new file mode 100644
index 0000000000..d9c03b807f
--- /dev/null
+++ b/cpukit/include/rtems/score/isr.h
@@ -0,0 +1,155 @@
+/**
+ * @file rtems/score/isr.h
+ *
+ * @brief Data Related to the Management of Processor Interrupt Levels
+ *
+ * This include file contains all the constants and structures associated
+ * with the management of processor interrupt levels. This handler
+ * supports interrupt critical sections, vectoring of user interrupt
+ * handlers, nesting of interrupts, and manipulating interrupt levels.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2012.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_ISR_H
+#define _RTEMS_SCORE_ISR_H
+
+#include <rtems/score/isrlevel.h>
+
+/**
+ * @defgroup ScoreISR ISR Handler
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality which provides the foundation
+ * ISR services used in all of the APIs supported by RTEMS.
+ *
+ * The ISR Nest level counter variable is maintained as part of the
+ * per cpu data structure.
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The following type defines the type used to manage the vectors.
+ */
+typedef uint32_t ISR_Vector_number;
+
+/**
+ * Return type for ISR Handler
+ */
+typedef void ISR_Handler;
+
+#if (CPU_SIMPLE_VECTORED_INTERRUPTS == FALSE)
+
+typedef void * ISR_Handler_entry;
+
+#else
+/**
+ * Pointer to an ISR Handler
+ */
+#if (CPU_ISR_PASSES_FRAME_POINTER == TRUE)
+typedef ISR_Handler ( *ISR_Handler_entry )(
+ ISR_Vector_number,
+ CPU_Interrupt_frame *
+ );
+#else
+typedef ISR_Handler ( *ISR_Handler_entry )(
+ ISR_Vector_number
+ );
+#endif
+
+/**
+ * The following declares the Vector Table. Application
+ * interrupt service routines are vectored by the ISR Handler via this table.
+ */
+extern ISR_Handler_entry _ISR_Vector_table[ CPU_INTERRUPT_NUMBER_OF_VECTORS ];
+#endif
+
+/**
+ * @brief Initialize the ISR handler.
+ *
+ * This routine performs the initialization necessary for the ISR handler.
+ */
+void _ISR_Handler_initialization ( void );
+
+/**
+ * @brief Install interrupt handler vector.
+ *
+ * This routine installs new_handler as the interrupt service routine
+ * for the specified vector. The previous interrupt service routine is
+ * returned as old_handler.
+ *
+ * LM32 Specific Information:
+ * XXX document implementation including references if appropriate
+ *
+ * @param[in] _vector is the vector number
+ * @param[in] _new_handler is ISR handler to install
+ * @param[in] _old_handler is a pointer to a variable which will be set
+ * to the old handler
+ *
+ * @retval *_old_handler will be set to the old ISR handler
+ */
+#define _ISR_Install_vector( _vector, _new_handler, _old_handler ) \
+ _CPU_ISR_install_vector( _vector, _new_handler, _old_handler )
+
+/**
+ * @brief ISR interrupt dispatcher.
+ *
+ * This routine is the interrupt dispatcher. ALL interrupts
+ * are vectored to this routine so that minimal context can be saved
+ * and setup performed before the application's high-level language
+ * interrupt service routine is invoked. After the application's
+ * interrupt service routine returns control to this routine, it
+ * will determine if a thread dispatch is necessary. If so, it will
+ * ensure that the necessary thread scheduling operations are
+ * performed when the outermost interrupt service routine exits.
+ *
+ * @note Typically implemented in assembly language.
+ */
+void _ISR_Handler( void );
+
+/**
+ * @brief ISR wrapper for thread dispatcher.
+ *
+ * This routine provides a wrapper so that the routine
+ * @ref _Thread_Dispatch can be invoked when a reschedule is necessary
+ * at the end of the outermost interrupt service routine. This
+ * wrapper is necessary to establish the processor context needed
+ * by _Thread_Dispatch and to save the processor context which is
+ * corrupted by _Thread_Dispatch. This context typically consists
+ * of registers which are not preserved across routine invocations.
+ *
+ * @note Typically mplemented in assembly language.
+ */
+void _ISR_Dispatch( void );
+
+/**
+ * @brief Checks if an ISR in progress.
+ *
+ * This function returns true if the processor is currently servicing
+ * and interrupt and false otherwise. A return value of true indicates
+ * that the caller is an interrupt service routine, NOT a thread.
+ *
+ * @retval This methods returns true when called from an ISR.
+ */
+bool _ISR_Is_in_progress( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/isrlevel.h b/cpukit/include/rtems/score/isrlevel.h
new file mode 100644
index 0000000000..abfb1b67fc
--- /dev/null
+++ b/cpukit/include/rtems/score/isrlevel.h
@@ -0,0 +1,153 @@
+/**
+ * @file rtems/score/isrlevel.h
+ *
+ * @brief ISR Level Type
+ *
+ * This include file defines the ISR Level type. It exists to
+ * simplify include dependencies. It is part of the ISR Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_ISR_LEVEL_h
+#define _RTEMS_SCORE_ISR_LEVEL_h
+
+#include <rtems/score/cpu.h>
+#include <rtems/score/assert.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreISR ISR Handler
+ *
+ * @ingroup Score
+ *
+ * @addtogroup ScoreISR ISR Handler
+ */
+/**@{*/
+
+/**
+ * The following type defines the control block used to manage
+ * the interrupt level portion of the status register.
+ */
+typedef uint32_t ISR_Level;
+
+/**
+ * @brief Disables interrupts on this processor.
+ *
+ * This macro disables all interrupts on this processor so that a critical
+ * section of code is protected from concurrent access by interrupts of this
+ * processor. Disabling of interrupts disables thread dispatching on the
+ * processor as well.
+ *
+ * On SMP configurations other processors can enter such sections if not
+ * protected by other means.
+ *
+ * @param[out] _level The argument @a _level will contain the previous
+ * interrupt mask level.
+ */
+#define _ISR_Local_disable( _level ) \
+ do { \
+ _CPU_ISR_Disable( _level ); \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ } while (0)
+
+/**
+ * @brief Enables interrupts on this processor.
+ *
+ * This macro restores the interrupt status on the processor with the
+ * interrupt level value obtained by _ISR_Local_disable(). It is used at the end of
+ * a critical section of code to enable interrupts so they can be processed
+ * again.
+ *
+ * @param[in] _level The interrupt level previously obtained by
+ * _ISR_Local_disable().
+ */
+#define _ISR_Local_enable( _level ) \
+ do { \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ _CPU_ISR_Enable( _level ); \
+ } while (0)
+
+/**
+ * @brief Temporarily enables interrupts on this processor.
+ *
+ * This macro temporarily enables interrupts to the previous
+ * interrupt mask level and then disables all interrupts so that
+ * the caller can continue into the second part of a critical
+ * section.
+ *
+ * This routine is used to temporarily enable interrupts
+ * during a long critical section. It is used in long sections of
+ * critical code when a point is reached at which interrupts can
+ * be temporarily enabled. Deciding where to flash interrupts
+ * in a long critical section is often difficult and the point
+ * must be selected with care to ensure that the critical section
+ * properly protects itself.
+ *
+ * @param[in] _level The interrupt level previously obtained by
+ * _ISR_Local_disable().
+ */
+#define _ISR_Local_flash( _level ) \
+ do { \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ _CPU_ISR_Flash( _level ); \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ } while (0)
+
+/**
+ * @brief Returns true if interrupts are enabled in the specified interrupt
+ * level, otherwise returns false.
+ *
+ * @param[in] _level The ISR level.
+ *
+ * @retval true Interrupts are enabled in the interrupt level.
+ * @retval false Otherwise.
+ */
+#define _ISR_Is_enabled( _level ) \
+ _CPU_ISR_Is_enabled( _level )
+
+/**
+ * @brief Return current interrupt level.
+ *
+ * This routine returns the current interrupt level.
+ *
+ * LM32 Specific Information:
+ * XXX document implementation including references if appropriate
+ *
+ * @retval This method returns the current level.
+ */
+#define _ISR_Get_level() \
+ _CPU_ISR_Get_level()
+
+/**
+ * @brief Set current interrupt level.
+ *
+ * This routine sets the current interrupt level to that specified
+ * by @a _new_level. The new interrupt level is effective when the
+ * routine exits.
+ *
+ * @param[in] _new_level contains the desired interrupt level.
+ */
+#define _ISR_Set_level( _new_level ) \
+ do { \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ _CPU_ISR_Set_level( _new_level ); \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ } while (0)
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/cpukit/include/rtems/score/isrlock.h b/cpukit/include/rtems/score/isrlock.h
new file mode 100644
index 0000000000..7dd2f29000
--- /dev/null
+++ b/cpukit/include/rtems/score/isrlock.h
@@ -0,0 +1,439 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreISRLocks
+ *
+ * @brief ISR Locks
+ */
+
+/*
+ * Copyright (c) 2013-2015 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_ISR_LOCK_H
+#define _RTEMS_SCORE_ISR_LOCK_H
+
+#include <rtems/score/isrlevel.h>
+#include <rtems/score/smplock.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreISRLocks ISR Locks
+ *
+ * @ingroup ScoreISR
+ *
+ * @brief Low-level lock to protect critical sections accessed by threads and
+ * interrupt service routines.
+ *
+ * On single processor configurations the ISR locks degrade to simple ISR
+ * disable/enable sequences. No additional storage or objects are required.
+ *
+ * This synchronization primitive is supported on SMP configurations. Here SMP
+ * locks are used.
+ *
+ * @{
+ */
+
+/**
+ * @brief ISR lock control.
+ *
+ * @warning Empty structures are implementation-defined in C. GCC gives them a
+ * size of zero. In C++ empty structures have a non-zero size.
+ */
+typedef struct {
+#if defined( RTEMS_SMP )
+ SMP_lock_Control Lock;
+#endif
+} ISR_lock_Control;
+
+/**
+ * @brief Local ISR lock context for acquire and release pairs.
+ */
+typedef struct {
+#if defined( RTEMS_SMP )
+ SMP_lock_Context Lock_context;
+#else
+ ISR_Level isr_level;
+#endif
+#if defined( RTEMS_PROFILING )
+ /**
+ * @brief The last interrupt disable instant in CPU counter ticks.
+ */
+ CPU_Counter_ticks ISR_disable_instant;
+#endif
+} ISR_lock_Context;
+
+/**
+ * @brief Defines an ISR lock member.
+ *
+ * Do not add a ';' after this macro.
+ *
+ * @param _designator The designator for the interrupt lock.
+ */
+#if defined( RTEMS_SMP )
+ #define ISR_LOCK_MEMBER( _designator ) ISR_lock_Control _designator;
+#else
+ #define ISR_LOCK_MEMBER( _designator )
+#endif
+
+/**
+ * @brief Declares an ISR lock variable.
+ *
+ * Do not add a ';' after this macro.
+ *
+ * @param _qualifier The qualifier for the interrupt lock, e.g. extern.
+ * @param _designator The designator for the interrupt lock.
+ */
+#if defined( RTEMS_SMP )
+ #define ISR_LOCK_DECLARE( _qualifier, _designator ) \
+ _qualifier ISR_lock_Control _designator;
+#else
+ #define ISR_LOCK_DECLARE( _qualifier, _designator )
+#endif
+
+/**
+ * @brief Defines an ISR lock variable.
+ *
+ * Do not add a ';' after this macro.
+ *
+ * @param _qualifier The qualifier for the interrupt lock, e.g. static.
+ * @param _designator The designator for the interrupt lock.
+ * @param _name The name for the interrupt lock. It must be a string. The
+ * name is only used if profiling is enabled.
+ */
+#if defined( RTEMS_SMP )
+ #define ISR_LOCK_DEFINE( _qualifier, _designator, _name ) \
+ _qualifier ISR_lock_Control _designator = { SMP_LOCK_INITIALIZER( _name ) };
+#else
+ #define ISR_LOCK_DEFINE( _qualifier, _designator, _name )
+#endif
+
+/**
+ * @brief Defines an ISR lock variable reference.
+ *
+ * Do not add a ';' after this macro.
+ *
+ * @param _designator The designator for the interrupt lock reference.
+ * @param _target The target for the interrupt lock reference.
+ */
+#if defined( RTEMS_SMP )
+ #define ISR_LOCK_REFERENCE( _designator, _target ) \
+ ISR_lock_Control *_designator = _target;
+#else
+ #define ISR_LOCK_REFERENCE( _designator, _target )
+#endif
+
+/**
+ * @brief Initializer for static initialization of ISR locks.
+ *
+ * @param _name The name for the interrupt lock. It must be a string. The
+ * name is only used if profiling is enabled.
+ */
+#if defined( RTEMS_SMP )
+ #define ISR_LOCK_INITIALIZER( _name ) \
+ { SMP_LOCK_INITIALIZER( _name ) }
+#else
+ #define ISR_LOCK_INITIALIZER( _name ) \
+ { }
+#endif
+
+/**
+ * @brief Sets the ISR level in the ISR lock context.
+ *
+ * @param[in] context The ISR lock context.
+ * @param[in] level The ISR level.
+ */
+RTEMS_INLINE_ROUTINE void _ISR_lock_Context_set_level(
+ ISR_lock_Context *context,
+ ISR_Level level
+)
+{
+#if defined( RTEMS_SMP )
+ context->Lock_context.isr_level = level;
+#else
+ context->isr_level = level;
+#endif
+}
+
+/**
+ * @brief Initializes an ISR lock.
+ *
+ * Concurrent initialization leads to unpredictable results.
+ *
+ * @param[in] _lock The ISR lock control.
+ * @param[in] _name The name for the ISR lock. This name must be a
+ * string persistent throughout the life time of this lock. The name is only
+ * used if profiling is enabled.
+ */
+#if defined( RTEMS_SMP )
+ #define _ISR_lock_Initialize( _lock, _name ) \
+ _SMP_lock_Initialize( &( _lock )->Lock, _name )
+#else
+ #define _ISR_lock_Initialize( _lock, _name )
+#endif
+
+/**
+ * @brief Destroys an ISR lock.
+ *
+ * Concurrent destruction leads to unpredictable results.
+ *
+ * @param[in] _lock The ISR lock control.
+ */
+#if defined( RTEMS_SMP )
+ #define _ISR_lock_Destroy( _lock ) \
+ _SMP_lock_Destroy( &( _lock )->Lock )
+#else
+ #define _ISR_lock_Destroy( _lock )
+#endif
+
+/**
+ * @brief Acquires an ISR lock.
+ *
+ * Interrupts will be disabled. On SMP configurations this function acquires
+ * an SMP lock.
+ *
+ * This function can be used in thread and interrupt context.
+ *
+ * @param[in] _lock The ISR lock control.
+ * @param[in] _context The local ISR lock context for an acquire and release
+ * pair.
+ *
+ * @see _ISR_lock_Release_and_ISR_enable().
+ */
+#if defined( RTEMS_SMP )
+ #define _ISR_lock_ISR_disable_and_acquire( _lock, _context ) \
+ _SMP_lock_ISR_disable_and_acquire( \
+ &( _lock )->Lock, \
+ &( _context )->Lock_context \
+ )
+#else
+ #define _ISR_lock_ISR_disable_and_acquire( _lock, _context ) \
+ _ISR_Local_disable( ( _context )->isr_level )
+#endif
+
+/**
+ * @brief Releases an ISR lock.
+ *
+ * The interrupt status will be restored. On SMP configurations this function
+ * releases an SMP lock.
+ *
+ * This function can be used in thread and interrupt context.
+ *
+ * @param[in] _lock The ISR lock control.
+ * @param[in] _context The local ISR lock context for an acquire and release
+ * pair.
+ *
+ * @see _ISR_lock_ISR_disable_and_acquire().
+ */
+#if defined( RTEMS_SMP )
+ #define _ISR_lock_Release_and_ISR_enable( _lock, _context ) \
+ _SMP_lock_Release_and_ISR_enable( \
+ &( _lock )->Lock, \
+ &( _context )->Lock_context \
+ )
+#else
+ #define _ISR_lock_Release_and_ISR_enable( _lock, _context ) \
+ _ISR_Local_enable( ( _context )->isr_level )
+#endif
+
+/**
+ * @brief Acquires an ISR lock inside an ISR disabled section.
+ *
+ * The interrupt status will remain unchanged. On SMP configurations this
+ * function acquires an SMP lock.
+ *
+ * In case the executing context can be interrupted by higher priority
+ * interrupts and these interrupts enter the critical section protected by this
+ * lock, then the result is unpredictable.
+ *
+ * @param[in] _lock The ISR lock control.
+ * @param[in] _context The local ISR lock context for an acquire and release
+ * pair.
+ *
+ * @see _ISR_lock_Release().
+ */
+#if defined( RTEMS_SMP )
+ #define _ISR_lock_Acquire( _lock, _context ) \
+ _SMP_lock_Acquire( \
+ &( _lock )->Lock, \
+ &( _context )->Lock_context \
+ )
+#else
+ #define _ISR_lock_Acquire( _lock, _context ) \
+ (void) _context;
+#endif
+
+/**
+ * @brief Releases an ISR lock inside an ISR disabled section.
+ *
+ * The interrupt status will remain unchanged. On SMP configurations this
+ * function releases an SMP lock.
+ *
+ * @param[in] _lock The ISR lock control.
+ * @param[in] _context The local ISR lock context for an acquire and release
+ * pair.
+ *
+ * @see _ISR_lock_Acquire().
+ */
+#if defined( RTEMS_SMP )
+ #define _ISR_lock_Release( _lock, _context ) \
+ _SMP_lock_Release( \
+ &( _lock )->Lock, \
+ &( _context )->Lock_context \
+ )
+#else
+ #define _ISR_lock_Release( _lock, _context ) \
+ (void) _context;
+#endif
+
+/**
+ * @brief Acquires an ISR lock inside an ISR disabled section (inline).
+ *
+ * @see _ISR_lock_Acquire().
+ */
+#if defined( RTEMS_SMP )
+ #define _ISR_lock_Acquire_inline( _lock, _context ) \
+ _SMP_lock_Acquire_inline( \
+ &( _lock )->Lock, \
+ &( _context )->Lock_context \
+ )
+#else
+ #define _ISR_lock_Acquire_inline( _lock, _context ) \
+ (void) _context;
+#endif
+
+/**
+ * @brief Releases an ISR lock inside an ISR disabled section (inline).
+ *
+ * @see _ISR_lock_Release().
+ */
+#if defined( RTEMS_SMP )
+ #define _ISR_lock_Release_inline( _lock, _context ) \
+ _SMP_lock_Release_inline( \
+ &( _lock )->Lock, \
+ &( _context )->Lock_context \
+ )
+#else
+ #define _ISR_lock_Release_inline( _lock, _context ) \
+ (void) _context;
+#endif
+
+#if defined( RTEMS_DEBUG )
+ /**
+ * @brief Returns true, if the ISR lock is owned by the current processor,
+ * otherwise false.
+ *
+ * On uni-processor configurations, this function returns true, if interrupts
+ * are disabled, otherwise false.
+ *
+ * @param[in] _lock The ISR lock control.
+ */
+ #if defined( RTEMS_SMP )
+ #define _ISR_lock_Is_owner( _lock ) \
+ _SMP_lock_Is_owner( &( _lock )->Lock )
+ #else
+ #define _ISR_lock_Is_owner( _lock ) \
+ ( _ISR_Get_level() != 0 )
+ #endif
+#endif
+
+/**
+ * @brief Flashes an ISR lock.
+ *
+ * On uni-processor configurations this a simple _ISR_Local_flash(). On SMP
+ * configurations this function releases an SMP lock, restores the interrupt
+ * status, then disables interrupts and acquires the SMP lock again.
+ *
+ * This function can be used in thread and interrupt context.
+ *
+ * @param[in] _lock The ISR lock control.
+ * @param[in] _context The local ISR lock context for an acquire and release
+ * pair.
+ *
+ * @see _ISR_lock_ISR_disable_and_acquire() and
+ * _ISR_lock_Release_and_ISR_enable().
+ */
+#if defined( RTEMS_SMP )
+ #define _ISR_lock_Flash( _lock, _context ) \
+ _SMP_lock_Release_and_ISR_enable( \
+ &( _lock )->Lock, \
+ &( _context )->Lock_context \
+ ); \
+ _SMP_lock_ISR_disable_and_acquire( \
+ &( _lock )->Lock, \
+ &( _context )->Lock_context \
+ )
+#else
+ #define _ISR_lock_Flash( _lock, _context ) \
+ _ISR_Local_flash( ( _context )->isr_level )
+#endif
+
+#if defined( RTEMS_PROFILING )
+ #define _ISR_lock_ISR_disable_profile( _context ) \
+ ( _context )->ISR_disable_instant = _CPU_Counter_read();
+#else
+ #define _ISR_lock_ISR_disable_profile( _context )
+#endif
+
+/**
+ * @brief Disables interrupts and saves the previous interrupt state in the ISR
+ * lock context.
+ *
+ * This function can be used in thread and interrupt context.
+ *
+ * @param[in] _context The local ISR lock context to store the interrupt state.
+ *
+ * @see _ISR_lock_ISR_enable().
+ */
+#if defined( RTEMS_SMP )
+ #define _ISR_lock_ISR_disable( _context ) \
+ do { \
+ _ISR_Local_disable( ( _context )->Lock_context.isr_level ); \
+ _ISR_lock_ISR_disable_profile( _context ) \
+ } while ( 0 )
+#else
+ #define _ISR_lock_ISR_disable( _context ) \
+ do { \
+ _ISR_Local_disable( ( _context )->isr_level ); \
+ _ISR_lock_ISR_disable_profile( _context ) \
+ } while ( 0 )
+#endif
+
+/**
+ * @brief Restores the saved interrupt state of the ISR lock context.
+ *
+ * This function can be used in thread and interrupt context.
+ *
+ * @param[in] _context The local ISR lock context containing the saved
+ * interrupt state.
+ *
+ * @see _ISR_lock_ISR_disable().
+ */
+#if defined( RTEMS_SMP )
+ #define _ISR_lock_ISR_enable( _context ) \
+ _ISR_Local_enable( ( _context )->Lock_context.isr_level )
+#else
+ #define _ISR_lock_ISR_enable( _context ) \
+ _ISR_Local_enable( ( _context )->isr_level )
+#endif
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_SCORE_ISR_LOCK_H */
diff --git a/cpukit/include/rtems/score/mpci.h b/cpukit/include/rtems/score/mpci.h
new file mode 100644
index 0000000000..c20b45c3e1
--- /dev/null
+++ b/cpukit/include/rtems/score/mpci.h
@@ -0,0 +1,135 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreMPCI
+ *
+ * @brief MPCI Layer API
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_MPCI_H
+#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" {
+#endif
+
+/**
+ * @defgroup ScoreMPCI MPCI Handler
+ *
+ * @ingroup Score
+ *
+ * The MPCI Handler encapsulates functionality which is related to the
+ * generation, receipt, and processing of remote operations in a
+ * multiprocessor system. This handler contains the message passing
+ * support for making remote service calls as well as the server thread
+ * which processes requests from remote nodes.
+*/
+/**@{*/
+
+/**
+ * The following defines the node number used when a broadcast is desired.
+ */
+#define MPCI_ALL_NODES 0
+
+/**
+ * This type is returned by all user provided MPCI routines.
+ */
+typedef void MPCI_Entry;
+
+/**
+ * This type defines the prototype for the initization entry point
+ * in an Multiprocessor Communications Interface.
+ */
+typedef MPCI_Entry ( *MPCI_initialization_entry )( void );
+
+/**
+ * This type defines the prototype for the get packet entry point
+ * in an Multiprocessor Communications Interface. The single
+ * parameter will point to the packet allocated.
+ */
+typedef MPCI_Entry ( *MPCI_get_packet_entry )(
+ MP_packet_Prefix **
+ );
+
+/**
+ * This type defines the prototype for the return packet entry point
+ * in an Multiprocessor Communications Interface. The single
+ * parameter will point to a packet previously allocated by the
+ * get packet MPCI entry.
+ */
+typedef MPCI_Entry ( *MPCI_return_packet_entry )(
+ MP_packet_Prefix *
+ );
+
+/**
+ * This type defines the prototype for send get packet entry point
+ * in an Multiprocessor Communications Interface. The single
+ * parameter will point to a packet previously allocated by the
+ * get packet entry point that has been filled in by the caller.
+ */
+typedef MPCI_Entry ( *MPCI_send_entry )(
+ uint32_t,
+ MP_packet_Prefix *
+ );
+
+/**
+ * This type defines the prototype for the receive packet entry point
+ * in an Multiprocessor Communications Interface. The single
+ * parameter will point to a packet allocated and filled in by the
+ * receive packet handler. The caller will block until a packet is
+ * received.
+ */
+typedef MPCI_Entry ( *MPCI_receive_entry )(
+ MP_packet_Prefix **
+ );
+
+/**
+ * This type defines the Multiprocessor Communications
+ * Interface (MPCI) Table. This table defines the user-provided
+ * MPCI which is a required part of a multiprocessor system.
+ *
+ * For non-blocking local operations that become remote operations,
+ * we need a timeout. This is a per-driver timeout: default_timeout
+ */
+typedef struct {
+ /** This fields contains the timeout for MPCI operations in ticks. */
+ uint32_t default_timeout;
+ /** This field contains the maximum size of a packet supported by this
+ * MPCI layer. This size places a limit on the size of a message
+ * which can be transmitted over this interface.
+ **/
+ size_t maximum_packet_size;
+ /** This field points to the MPCI initialization entry point. */
+ MPCI_initialization_entry initialization;
+ /** This field points to the MPCI get packet entry point. */
+ MPCI_get_packet_entry get_packet;
+ /** This field points to the MPCI return packet entry point. */
+ MPCI_return_packet_entry return_packet;
+ /** This field points to the MPCI send packet entry point. */
+ MPCI_send_entry send_packet;
+ /** This field points to the MPCI receive packet entry point. */
+ MPCI_receive_entry receive_packet;
+} MPCI_Control;
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/mpciimpl.h b/cpukit/include/rtems/score/mpciimpl.h
new file mode 100644
index 0000000000..eb03a1d7b3
--- /dev/null
+++ b/cpukit/include/rtems/score/mpciimpl.h
@@ -0,0 +1,326 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreMPCI
+ *
+ * @brief MPCI Layer Implementation
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_MPCIIMPL_H
+#define _RTEMS_SCORE_MPCIIMPL_H
+
+#include <rtems/score/mpci.h>
+#include <rtems/score/status.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreMPCI
+ *
+ * @{
+ */
+
+/**
+ * For packets associated with requests that don't already have a timeout,
+ * use the one specified by this MPCI driver. The value specified by
+ * the MPCI driver sets an upper limit on how long a remote request
+ * should take to complete.
+ */
+#define MPCI_DEFAULT_TIMEOUT 0xFFFFFFFF
+
+/**
+ * The following defines the type for packet processing routines
+ * invoked by the MPCI Receive server.
+ */
+typedef void (*MPCI_Packet_processor)( MP_packet_Prefix * );
+
+/**
+ * The following enumerated type defines the list of
+ * internal MP operations.
+ */
+typedef enum {
+ MPCI_PACKETS_SYSTEM_VERIFY = 0
+} MPCI_Internal_Remote_operations;
+
+/**
+ * The following data structure defines the packet used to perform
+ * remote event operations.
+ */
+typedef struct {
+ /** This field is the general header for all packets. */
+ MP_packet_Prefix Prefix;
+ /** This value specifies the operation. */
+ MPCI_Internal_Remote_operations operation;
+ /** This is the maximum number of nodes in the system. It must agree
+ * on all nodes.
+ */
+ uint32_t maximum_nodes;
+ /** This field is the maximum number of concurrently existent
+ * globally offered objects.
+ */
+ uint32_t maximum_global_objects;
+} MPCI_Internal_packet;
+
+/**
+ * The following thread queue is used to maintain a list of tasks
+ * which currently have outstanding remote requests.
+ */
+extern Thread_queue_Control _MPCI_Remote_blocked_threads;
+
+/**
+ * The following define the internal pointers to the user's
+ * configuration information.
+ */
+extern MPCI_Control *_MPCI_table;
+
+/**
+ * @brief Pointer to MP thread control block.
+ *
+ * The following is used to determine when the multiprocessing receive
+ * thread is executing so that a proxy can be allocated instead of
+ * blocking the multiprocessing receive thread.
+ */
+extern Thread_Control *_MPCI_Receive_server_tcb;
+
+/**
+ * The following table contains the process packet routines provided
+ * by each object that supports MP operations.
+ */
+extern MPCI_Packet_processor
+_MPCI_Packet_processors[ MP_PACKET_CLASSES_LAST + 1 ];
+
+/**
+ * This routine registers the MPCI packet processor for the
+ * designated object class.
+ *
+ * @param[in] the_class is the class indicator for packets which will
+ * be processed by @a the_packet_processor method.
+ * @param[in] the_packet_processor is a pointer to a method which is
+ * invoked when packets with @a the_class are received.
+ */
+void _MPCI_Register_packet_processor(
+ MP_packet_Classes the_class,
+ MPCI_Packet_processor the_packet_processor
+
+);
+
+/**
+ * This function obtains a packet by invoking the user provided
+ * MPCI get packet callout.
+ *
+ * @retval This method returns a pointer to a MPCI packet which can be
+ * filled in by the caller and used to perform a subsequent
+ * remote operation.
+ */
+MP_packet_Prefix *_MPCI_Get_packet ( void );
+
+/**
+ * @brief Deallocate a packet.
+ *
+ * This routine deallocates a packet by invoking the user provided
+ * MPCI return packet callout.
+ *
+ * @param[in] the_packet is the MP packet to deallocate.
+ */
+void _MPCI_Return_packet (
+ MP_packet_Prefix *the_packet
+);
+
+/**
+ * @brief Send a process packet.
+ *
+ * This routine sends a process packet by invoking the user provided
+ * MPCI send callout.
+ *
+ * @param[in] destination is the node which should receive this packet.
+ * @param[in] the_packet is the packet to be sent.
+ */
+void _MPCI_Send_process_packet (
+ uint32_t destination,
+ MP_packet_Prefix *the_packet
+);
+
+/**
+ * @brief Send a request packet.
+ *
+ * This routine sends a request packet by invoking the user provided
+ * MPCI send callout.
+ *
+ * @param[in] destination is the node which should receive this packet.
+ * @param[in] the_packet is the packet to be sent.
+ * @param[in] extra_state is the extra thread state bits which should be
+ * set in addition to the remote operation pending state. It
+ * may indicate the caller is blocking on a message queue
+ * operation.
+ *
+ * @retval This method returns the operation status from the remote node.
+ */
+Status_Control _MPCI_Send_request_packet(
+ uint32_t destination,
+ MP_packet_Prefix *the_packet,
+ States_Control extra_state
+);
+
+/**
+ * @brief Send a response packet.
+ *
+ * This routine sends a response packet by invoking the user provided
+ * MPCI send callout.
+ *
+ * @param[in] destination is the node which should receive this packet.
+ * @param[in] the_packet is the packet to be sent.
+ */
+void _MPCI_Send_response_packet (
+ uint32_t destination,
+ MP_packet_Prefix *the_packet
+);
+
+/**
+ * @brief Receive a packet.
+ *
+ * This routine receives a packet by invoking the user provided
+ * MPCI receive callout.
+ *
+ * @retval This method returns the packet received.
+ */
+MP_packet_Prefix *_MPCI_Receive_packet ( void );
+
+/**
+ * @brief Pass a packet to the thread.
+ *
+ * This routine is responsible for passing @a the_packet to the thread
+ * waiting on the remote operation to complete. The unblocked thread is
+ * responsible for eventually freeing @a the_packet.
+ *
+ * @param[in] the_packet is the response packet to be processed.
+ *
+ * @retval This method returns a pointer to the thread which was if unblocked
+ * or NULL if the waiting thread no longer exists.
+ */
+Thread_Control *_MPCI_Process_response (
+ MP_packet_Prefix *the_packet
+);
+
+/**
+ * @brief Receive and process all packets.
+ *
+ * This is the server thread which receives and processes all MCPI packets.
+ *
+ * @param[in] ignored is the thread argument. It is not used.
+ */
+void _MPCI_Receive_server(
+ Thread_Entry_numeric_type ignored
+);
+
+/**
+ * @brief Announce the availability of a packet.
+ *
+ * This routine informs RTEMS of the availability of an MPCI packet.
+ */
+void _MPCI_Announce ( void );
+
+/**
+ * @brief Perform a process on another node.
+ *
+ * This routine performs a remote procedure call so that a
+ * process operation can be performed on another node.
+ *
+ * @param[in] operation is the remote operation to perform.
+ */
+void _MPCI_Internal_packets_Send_process_packet (
+ MPCI_Internal_Remote_operations operation
+);
+
+/**
+ * _MPCI_Internal_packets_Send_request_packet
+ *
+ * This routine performs a remote procedure call so that a
+ * directive operation can be initiated on another node.
+ *
+ * This routine is not needed since there are no request
+ * packets to be sent by this manager.
+ */
+
+/**
+ * _MPCI_Internal_packets_Send_response_packet
+ *
+ * This routine performs a remote procedure call so that a
+ * directive can be performed on another node.
+ *
+ * This routine is not needed since there are no response
+ * packets to be sent by this manager.
+ */
+
+/**
+ * @brief Perform requested action from another node.
+ *
+ * This routine performs the actions specific to this package for
+ * the request from another node.
+ */
+void _MPCI_Internal_packets_Process_packet (
+ MP_packet_Prefix *the_packet_prefix
+);
+
+/**
+ * _MPCI_Internal_packets_Send_object_was_deleted
+ *
+ * This routine is invoked indirectly by the thread queue
+ * when a proxy has been removed from the thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed since there are no objects
+ * deleted by this manager.
+ */
+
+/**
+ * _MPCI_Internal_packets_Send_extract_proxy
+ *
+ * This routine is invoked when a task is deleted and it
+ * has a proxy which must be removed from a thread queue and
+ * the remote node must be informed of this.
+ *
+ * This routine is not needed since there are no objects
+ * deleted by this manager.
+ */
+
+/**
+ * @brief Obtain an internal thread.
+ *
+ * This routine is used to obtain an internal threads MP packet.
+ */
+MPCI_Internal_packet *_MPCI_Internal_packets_Get_packet ( void );
+
+/**
+ * This function returns true if the the_packet_class is valid,
+ * and false otherwise.
+ *
+ * @note Check for lower bounds (MP_PACKET_CLASSES_FIRST ) is unnecessary
+ * because this enum starts at lower bound of zero.
+ */
+
+RTEMS_INLINE_ROUTINE bool _Mp_packet_Is_valid_packet_class (
+ MP_packet_Classes the_packet_class
+)
+{
+ return ( the_packet_class <= MP_PACKET_CLASSES_LAST );
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/mppkt.h b/cpukit/include/rtems/score/mppkt.h
new file mode 100644
index 0000000000..573abf574b
--- /dev/null
+++ b/cpukit/include/rtems/score/mppkt.h
@@ -0,0 +1,121 @@
+/**
+ * @file rtems/score/mppkt.h
+ *
+ * @brief Specification for the Packet Handler
+ *
+ * This package is the specification for the Packet Handler.
+ * This handler defines the basic packet and provides
+ * mechanisms to utilize packets based on this prefix.
+ * Packets are the fundamental basis for messages passed between
+ * nodes in an MP system.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_MPPKT_H
+#define _RTEMS_SCORE_MPPKT_H
+
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/watchdog.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreMPPacket MP Packet Handler
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates the primary definition of MPCI packets. This
+ * handler defines the part of the packet that is common to all remote
+ * operations.
+ */
+/**@{*/
+
+/**
+ * The following enumerated type defines the packet classes.
+ *
+ * @note In general, each class corresponds to a manager
+ * which supports global operations. Each manager
+ * defines the set of supported operations.
+ */
+typedef enum {
+ MP_PACKET_MPCI_INTERNAL = 0,
+ MP_PACKET_TASKS = 1,
+ MP_PACKET_MESSAGE_QUEUE = 2,
+ MP_PACKET_SEMAPHORE = 3,
+ MP_PACKET_PARTITION = 4,
+ MP_PACKET_REGION = 5,
+ MP_PACKET_EVENT = 6,
+ MP_PACKET_SIGNAL = 7
+} MP_packet_Classes;
+
+/**
+ * This constant defines the first entry in the MP_packet_Classes enumeration.
+ */
+#define MP_PACKET_CLASSES_FIRST MP_PACKET_MPCI_INTERNAL
+
+/**
+ * This constant defines the last entry in the MP_packet_Classes enumeration.
+ */
+#define MP_PACKET_CLASSES_LAST MP_PACKET_SIGNAL
+
+/**
+ * The following record contains the prefix for every packet
+ * passed between nodes in an MP system.
+ *
+ * @note This structure is padded to ensure that anything following it
+ * is on a 16 byte boundary. This is the most stringent structure
+ * alignment rule encountered yet.
+ */
+typedef struct {
+ /** This field indicates the API class of the operation being performed. */
+ MP_packet_Classes the_class;
+ /** This field is the id of the object to be acted upon. */
+ Objects_Id id;
+ /** This field is the ID of the originating thread. */
+ Objects_Id source_tid;
+ /** This field is the priority of the originating thread. */
+ uint32_t source_priority;
+ /** This field is where the status of the operation will be returned. */
+ uint32_t return_code;
+ /** This field is the length of the data following the prefix. */
+ uint32_t length;
+ /** This field is the length of the data which required network conversion. */
+ uint32_t to_convert;
+ /** This field is the requested timeout for this operation. */
+ Watchdog_Interval timeout;
+} MP_packet_Prefix;
+
+/**
+ * An MPCI must support packets of at least this size.
+ */
+#define MP_PACKET_MINIMUM_PACKET_SIZE 64
+
+/**
+ * The following constant defines the number of uint32_t's
+ * in a packet which must be converted to native format in a
+ * heterogeneous system. In packets longer than
+ * MP_PACKET_MINIMUN_HETERO_CONVERSION uint32_t's, some of the "extra" data
+ * may a user message buffer which is not automatically endian swapped.
+ */
+#define MP_PACKET_MINIMUN_HETERO_CONVERSION \
+ ( sizeof( MP_packet_Prefix ) / sizeof( uint32_t ) )
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/mrsp.h b/cpukit/include/rtems/score/mrsp.h
new file mode 100644
index 0000000000..85cbff784f
--- /dev/null
+++ b/cpukit/include/rtems/score/mrsp.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_MRSP_H
+#define _RTEMS_SCORE_MRSP_H
+
+#include <rtems/score/cpuopts.h>
+
+#if defined(RTEMS_SMP)
+
+#include <rtems/score/threadq.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ScoreMRSP Multiprocessor Resource Sharing Protocol Handler
+ *
+ * @ingroup Score
+ *
+ * @brief Multiprocessor Resource Sharing Protocol (MrsP).
+ *
+ * The Multiprocessor Resource Sharing Protocol (MrsP) is defined in A. Burns
+ * and A.J. Wellings, A Schedulability Compatible Multiprocessor Resource
+ * Sharing Protocol - MrsP, Proceedings of the 25th Euromicro Conference on
+ * Real-Time Systems (ECRTS 2013), July 2013. It is a generalization of the
+ * Priority Ceiling Protocol to SMP systems. Each MrsP semaphore uses a
+ * ceiling priority per scheduler instance. A task obtaining or owning a MrsP
+ * semaphore will execute with the ceiling priority for its scheduler instance
+ * as specified by the MrsP semaphore object. Tasks waiting to get ownership
+ * of a MrsP semaphore will not relinquish the processor voluntarily. In case
+ * the owner of a MrsP semaphore gets preempted it can ask all tasks waiting
+ * for this semaphore to help out and temporarily borrow the right to execute
+ * on one of their assigned processors.
+ *
+ * @{
+ */
+
+/**
+ * @brief MrsP control block.
+ */
+typedef struct {
+ /**
+ * @brief The thread queue to manage ownership and waiting threads.
+ */
+ Thread_queue_Control Wait_queue;
+
+ /**
+ * @brief The ceiling priority used by the owner thread.
+ */
+ Priority_Node Ceiling_priority;
+
+ /**
+ * @brief One ceiling priority per scheduler instance.
+ */
+ Priority_Control *ceiling_priorities;
+} MRSP_Control;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* RTEMS_SMP */
+
+#endif /* _RTEMS_SCORE_MRSP_H */
diff --git a/cpukit/include/rtems/score/mrspimpl.h b/cpukit/include/rtems/score/mrspimpl.h
new file mode 100644
index 0000000000..b9c7441401
--- /dev/null
+++ b/cpukit/include/rtems/score/mrspimpl.h
@@ -0,0 +1,384 @@
+/*
+ * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_MRSPIMPL_H
+#define _RTEMS_SCORE_MRSPIMPL_H
+
+#include <rtems/score/mrsp.h>
+
+#if defined(RTEMS_SMP)
+
+#include <rtems/score/assert.h>
+#include <rtems/score/status.h>
+#include <rtems/score/threadqimpl.h>
+#include <rtems/score/watchdogimpl.h>
+#include <rtems/score/wkspace.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @addtogroup ScoreMRSP
+ *
+ * @{
+ */
+
+#define MRSP_TQ_OPERATIONS &_Thread_queue_Operations_priority_inherit
+
+RTEMS_INLINE_ROUTINE void _MRSP_Acquire_critical(
+ MRSP_Control *mrsp,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Acquire_critical( &mrsp->Wait_queue, queue_context );
+}
+
+RTEMS_INLINE_ROUTINE void _MRSP_Release(
+ MRSP_Control *mrsp,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Release( &mrsp->Wait_queue, queue_context );
+}
+
+RTEMS_INLINE_ROUTINE Thread_Control *_MRSP_Get_owner(
+ const MRSP_Control *mrsp
+)
+{
+ return mrsp->Wait_queue.Queue.owner;
+}
+
+RTEMS_INLINE_ROUTINE void _MRSP_Set_owner(
+ MRSP_Control *mrsp,
+ Thread_Control *owner
+)
+{
+ mrsp->Wait_queue.Queue.owner = owner;
+}
+
+RTEMS_INLINE_ROUTINE Priority_Control _MRSP_Get_priority(
+ const MRSP_Control *mrsp,
+ const Scheduler_Control *scheduler
+)
+{
+ uint32_t scheduler_index;
+
+ scheduler_index = _Scheduler_Get_index( scheduler );
+ return mrsp->ceiling_priorities[ scheduler_index ];
+}
+
+RTEMS_INLINE_ROUTINE void _MRSP_Set_priority(
+ MRSP_Control *mrsp,
+ const Scheduler_Control *scheduler,
+ Priority_Control new_priority
+)
+{
+ uint32_t scheduler_index;
+
+ scheduler_index = _Scheduler_Get_index( scheduler );
+ mrsp->ceiling_priorities[ scheduler_index ] = new_priority;
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _MRSP_Raise_priority(
+ MRSP_Control *mrsp,
+ Thread_Control *thread,
+ Priority_Node *priority_node,
+ Thread_queue_Context *queue_context
+)
+{
+ Status_Control status;
+ ISR_lock_Context lock_context;
+ const Scheduler_Control *scheduler;
+ Priority_Control ceiling_priority;
+ Scheduler_Node *scheduler_node;
+
+ _Thread_queue_Context_clear_priority_updates( queue_context );
+ _Thread_Wait_acquire_default_critical( thread, &lock_context );
+
+ scheduler = _Thread_Scheduler_get_home( thread );
+ scheduler_node = _Thread_Scheduler_get_home_node( thread );
+ ceiling_priority = _MRSP_Get_priority( mrsp, scheduler );
+
+ if (
+ ceiling_priority
+ <= _Priority_Get_priority( &scheduler_node->Wait.Priority )
+ ) {
+ _Priority_Node_initialize( priority_node, ceiling_priority );
+ _Thread_Priority_add( thread, priority_node, queue_context );
+ status = STATUS_SUCCESSFUL;
+ } else {
+ status = STATUS_MUTEX_CEILING_VIOLATED;
+ }
+
+ _Thread_Wait_release_default_critical( thread, &lock_context );
+ return status;
+}
+
+RTEMS_INLINE_ROUTINE void _MRSP_Remove_priority(
+ Thread_Control *thread,
+ Priority_Node *priority_node,
+ Thread_queue_Context *queue_context
+)
+{
+ ISR_lock_Context lock_context;
+
+ _Thread_queue_Context_clear_priority_updates( queue_context );
+ _Thread_Wait_acquire_default_critical( thread, &lock_context );
+ _Thread_Priority_remove( thread, priority_node, queue_context );
+ _Thread_Wait_release_default_critical( thread, &lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _MRSP_Replace_priority(
+ MRSP_Control *mrsp,
+ Thread_Control *thread,
+ Priority_Node *ceiling_priority
+)
+{
+ ISR_lock_Context lock_context;
+
+ _Thread_Wait_acquire_default( thread, &lock_context );
+ _Thread_Priority_replace(
+ thread,
+ ceiling_priority,
+ &mrsp->Ceiling_priority
+ );
+ _Thread_Wait_release_default( thread, &lock_context );
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _MRSP_Claim_ownership(
+ MRSP_Control *mrsp,
+ Thread_Control *executing,
+ Thread_queue_Context *queue_context
+)
+{
+ Status_Control status;
+ Per_CPU_Control *cpu_self;
+
+ status = _MRSP_Raise_priority(
+ mrsp,
+ executing,
+ &mrsp->Ceiling_priority,
+ queue_context
+ );
+
+ if ( status != STATUS_SUCCESSFUL ) {
+ _MRSP_Release( mrsp, queue_context );
+ return status;
+ }
+
+ _MRSP_Set_owner( mrsp, executing );
+ cpu_self = _Thread_queue_Dispatch_disable( queue_context );
+ _MRSP_Release( mrsp, queue_context );
+ _Thread_Priority_and_sticky_update( executing, 1 );
+ _Thread_Dispatch_enable( cpu_self );
+ return STATUS_SUCCESSFUL;
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _MRSP_Initialize(
+ MRSP_Control *mrsp,
+ const Scheduler_Control *scheduler,
+ Priority_Control ceiling_priority,
+ Thread_Control *executing,
+ bool initially_locked
+)
+{
+ uint32_t scheduler_count = _Scheduler_Count;
+ uint32_t i;
+
+ if ( initially_locked ) {
+ return STATUS_INVALID_NUMBER;
+ }
+
+ mrsp->ceiling_priorities = _Workspace_Allocate(
+ sizeof( *mrsp->ceiling_priorities ) * scheduler_count
+ );
+ if ( mrsp->ceiling_priorities == NULL ) {
+ return STATUS_NO_MEMORY;
+ }
+
+ for ( i = 0 ; i < scheduler_count ; ++i ) {
+ const Scheduler_Control *scheduler_of_index;
+
+ scheduler_of_index = &_Scheduler_Table[ i ];
+
+ if ( scheduler != scheduler_of_index ) {
+ mrsp->ceiling_priorities[ i ] =
+ _Scheduler_Map_priority( scheduler_of_index, 0 );
+ } else {
+ mrsp->ceiling_priorities[ i ] = ceiling_priority;
+ }
+ }
+
+ _Thread_queue_Object_initialize( &mrsp->Wait_queue );
+ return STATUS_SUCCESSFUL;
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _MRSP_Wait_for_ownership(
+ MRSP_Control *mrsp,
+ Thread_Control *executing,
+ Thread_queue_Context *queue_context
+)
+{
+ Status_Control status;
+ Priority_Node ceiling_priority;
+
+ status = _MRSP_Raise_priority(
+ mrsp,
+ executing,
+ &ceiling_priority,
+ queue_context
+ );
+
+ if ( status != STATUS_SUCCESSFUL ) {
+ _MRSP_Release( mrsp, queue_context );
+ return status;
+ }
+
+ _Thread_queue_Context_set_deadlock_callout(
+ queue_context,
+ _Thread_queue_Deadlock_status
+ );
+ status = _Thread_queue_Enqueue_sticky(
+ &mrsp->Wait_queue.Queue,
+ MRSP_TQ_OPERATIONS,
+ executing,
+ queue_context
+ );
+
+ if ( status == STATUS_SUCCESSFUL ) {
+ _MRSP_Replace_priority( mrsp, executing, &ceiling_priority );
+ } else {
+ Thread_queue_Context queue_context;
+ Per_CPU_Control *cpu_self;
+ int sticky_level_change;
+
+ if ( status != STATUS_DEADLOCK ) {
+ sticky_level_change = -1;
+ } else {
+ sticky_level_change = 0;
+ }
+
+ _ISR_lock_ISR_disable( &queue_context.Lock_context.Lock_context );
+ _MRSP_Remove_priority( executing, &ceiling_priority, &queue_context );
+ cpu_self = _Thread_Dispatch_disable_critical(
+ &queue_context.Lock_context.Lock_context
+ );
+ _ISR_lock_ISR_enable( &queue_context.Lock_context.Lock_context );
+ _Thread_Priority_and_sticky_update( executing, sticky_level_change );
+ _Thread_Dispatch_enable( cpu_self );
+ }
+
+ return status;
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _MRSP_Seize(
+ MRSP_Control *mrsp,
+ Thread_Control *executing,
+ bool wait,
+ Thread_queue_Context *queue_context
+)
+{
+ Status_Control status;
+ Thread_Control *owner;
+
+ _MRSP_Acquire_critical( mrsp, queue_context );
+
+ owner = _MRSP_Get_owner( mrsp );
+
+ if ( owner == NULL ) {
+ status = _MRSP_Claim_ownership( mrsp, executing, queue_context );
+ } else if ( owner == executing ) {
+ _MRSP_Release( mrsp, queue_context );
+ status = STATUS_UNAVAILABLE;
+ } else if ( wait ) {
+ status = _MRSP_Wait_for_ownership( mrsp, executing, queue_context );
+ } else {
+ _MRSP_Release( mrsp, queue_context );
+ status = STATUS_UNAVAILABLE;
+ }
+
+ return status;
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _MRSP_Surrender(
+ MRSP_Control *mrsp,
+ Thread_Control *executing,
+ Thread_queue_Context *queue_context
+)
+{
+ Thread_queue_Heads *heads;
+
+ if ( _MRSP_Get_owner( mrsp ) != executing ) {
+ _ISR_lock_ISR_enable( &queue_context->Lock_context.Lock_context );
+ return STATUS_NOT_OWNER;
+ }
+
+ _MRSP_Acquire_critical( mrsp, queue_context );
+
+ _MRSP_Set_owner( mrsp, NULL );
+ _MRSP_Remove_priority( executing, &mrsp->Ceiling_priority, queue_context );
+
+ heads = mrsp->Wait_queue.Queue.heads;
+
+ if ( heads == NULL ) {
+ Per_CPU_Control *cpu_self;
+
+ cpu_self = _Thread_Dispatch_disable_critical(
+ &queue_context->Lock_context.Lock_context
+ );
+ _MRSP_Release( mrsp, queue_context );
+ _Thread_Priority_and_sticky_update( executing, -1 );
+ _Thread_Dispatch_enable( cpu_self );
+ return STATUS_SUCCESSFUL;
+ }
+
+ _Thread_queue_Surrender_sticky(
+ &mrsp->Wait_queue.Queue,
+ heads,
+ executing,
+ queue_context,
+ MRSP_TQ_OPERATIONS
+ );
+ return STATUS_SUCCESSFUL;
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _MRSP_Can_destroy( MRSP_Control *mrsp )
+{
+ if ( _MRSP_Get_owner( mrsp ) != NULL ) {
+ return STATUS_RESOURCE_IN_USE;
+ }
+
+ return STATUS_SUCCESSFUL;
+}
+
+RTEMS_INLINE_ROUTINE void _MRSP_Destroy(
+ MRSP_Control *mrsp,
+ Thread_queue_Context *queue_context
+)
+{
+ _MRSP_Release( mrsp, queue_context );
+ _Thread_queue_Destroy( &mrsp->Wait_queue );
+ _Workspace_Free( mrsp->ceiling_priorities );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* RTEMS_SMP */
+
+#endif /* _RTEMS_SCORE_MRSPIMPL_H */
diff --git a/cpukit/include/rtems/score/muteximpl.h b/cpukit/include/rtems/score/muteximpl.h
new file mode 100644
index 0000000000..5fd4f5e8be
--- /dev/null
+++ b/cpukit/include/rtems/score/muteximpl.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015, 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_MUTEXIMPL_H
+#define _RTEMS_SCORE_MUTEXIMPL_H
+
+#include <rtems/score/threadqimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct {
+ Thread_queue_Syslock_queue Queue;
+} Mutex_Control;
+
+typedef struct {
+ Mutex_Control Mutex;
+ unsigned int nest_level;
+} Mutex_recursive_Control;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_MUTEXIMPL_H */
diff --git a/cpukit/include/rtems/score/object.h b/cpukit/include/rtems/score/object.h
new file mode 100644
index 0000000000..6789c61fea
--- /dev/null
+++ b/cpukit/include/rtems/score/object.h
@@ -0,0 +1,469 @@
+/**
+ * @file rtems/score/object.h
+ *
+ * @brief Constants and Structures Associated with the Object Handler
+ *
+ * This include file contains all the constants and structures associated
+ * with the Object Handler. This Handler provides mechanisms which
+ * can be used to initialize and manipulate all objects which have ids.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_OBJECT_H
+#define _RTEMS_SCORE_OBJECT_H
+
+#include <rtems/score/basedefs.h>
+#include <rtems/score/cpu.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/rbtree.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup Score SuperCore
+ *
+ * @brief Provides services for all APIs.
+ */
+/**@{*/
+
+#if defined(RTEMS_POSIX_API)
+ /**
+ * This macro is defined when an API is enabled that requires the
+ * use of strings for object names. Since the Classic API uses
+ * 32-bit unsigned integers and not strings, this allows us to
+ * disable this in the smallest RTEMS configuratinos.
+ */
+ #define RTEMS_SCORE_OBJECT_ENABLE_STRING_NAMES
+#endif
+
+/**
+ * @defgroup ScoreCPU CPU Architecture Support
+ *
+ * @ingroup Score
+ *
+ * @brief Provides CPU architecture dependent services.
+ */
+/**@{*/
+
+/**
+ * @defgroup ScoreObject Object Handler
+ *
+ * @ingroup Score
+ */
+/**@{*/
+
+/**
+ * The following type defines the control block used to manage
+ * object names.
+ */
+typedef union {
+ #if defined(RTEMS_SCORE_OBJECT_ENABLE_STRING_NAMES)
+ /** This is a pointer to a string name. */
+ const char *name_p;
+ #endif
+ /** This is the actual 32-bit "raw" integer name. */
+ uint32_t name_u32;
+} Objects_Name;
+
+#if defined(RTEMS_USE_16_BIT_OBJECT)
+/**
+ * The following type defines the control block used to manage
+ * object IDs. The format is as follows (0=LSB):
+ *
+ * Bits 0 .. 7 = index (up to 254 objects of a type)
+ * Bits 8 .. 10 = API (up to 7 API classes)
+ * Bits 11 .. 15 = class (up to 31 object types per API)
+ */
+typedef uint16_t Objects_Id;
+
+/**
+ * This type is used to store the maximum number of allowed objects
+ * of each type.
+ */
+typedef uint8_t Objects_Maximum;
+
+#define OBJECTS_INDEX_START_BIT 0U
+#define OBJECTS_API_START_BIT 8U
+#define OBJECTS_CLASS_START_BIT 11U
+
+#define OBJECTS_INDEX_MASK (Objects_Id)0x00ffU
+#define OBJECTS_API_MASK (Objects_Id)0x0700U
+#define OBJECTS_CLASS_MASK (Objects_Id)0xF800U
+
+#define OBJECTS_INDEX_VALID_BITS (Objects_Id)0x00ffU
+#define OBJECTS_API_VALID_BITS (Objects_Id)0x0007U
+/* OBJECTS_NODE_VALID_BITS should not be used with 16 bit Ids */
+#define OBJECTS_CLASS_VALID_BITS (Objects_Id)0x001fU
+
+#define OBJECTS_UNLIMITED_OBJECTS 0x8000U
+
+#define OBJECTS_ID_INITIAL_INDEX (0)
+#define OBJECTS_ID_FINAL_INDEX (0xff)
+
+#else
+/**
+ * The following type defines the control block used to manage
+ * object IDs. The format is as follows (0=LSB):
+ *
+ * Bits 0 .. 15 = index (up to 65535 objects of a type)
+ * Bits 16 .. 23 = node (up to 255 nodes)
+ * Bits 24 .. 26 = API (up to 7 API classes)
+ * Bits 27 .. 31 = class (up to 31 object types per API)
+ */
+typedef uint32_t Objects_Id;
+
+/**
+ * This type is used to store the maximum number of allowed objects
+ * of each type.
+ */
+typedef uint16_t Objects_Maximum;
+
+/**
+ * This is the bit position of the starting bit of the index portion of
+ * the object Id.
+ */
+#define OBJECTS_INDEX_START_BIT 0U
+/**
+ * This is the bit position of the starting bit of the node portion of
+ * the object Id.
+ */
+#define OBJECTS_NODE_START_BIT 16U
+
+/**
+ * This is the bit position of the starting bit of the API portion of
+ * the object Id.
+ */
+#define OBJECTS_API_START_BIT 24U
+
+/**
+ * This is the bit position of the starting bit of the class portion of
+ * the object Id.
+ */
+#define OBJECTS_CLASS_START_BIT 27U
+
+/**
+ * This mask is used to extract the index portion of an object Id.
+ */
+#define OBJECTS_INDEX_MASK (Objects_Id)0x0000ffffU
+
+/**
+ * This mask is used to extract the node portion of an object Id.
+ */
+#define OBJECTS_NODE_MASK (Objects_Id)0x00ff0000U
+
+/**
+ * This mask is used to extract the API portion of an object Id.
+ */
+#define OBJECTS_API_MASK (Objects_Id)0x07000000U
+
+/**
+ * This mask is used to extract the class portion of an object Id.
+ */
+#define OBJECTS_CLASS_MASK (Objects_Id)0xf8000000U
+
+/**
+ * This mask represents the bits that is used to ensure no extra bits
+ * are set after shifting to extract the index portion of an object Id.
+ */
+#define OBJECTS_INDEX_VALID_BITS (Objects_Id)0x0000ffffU
+
+/**
+ * This mask represents the bits that is used to ensure no extra bits
+ * are set after shifting to extract the node portion of an object Id.
+ */
+#define OBJECTS_NODE_VALID_BITS (Objects_Id)0x000000ffU
+
+/**
+ * This mask represents the bits that is used to ensure no extra bits
+ * are set after shifting to extract the API portion of an object Id.
+ */
+#define OBJECTS_API_VALID_BITS (Objects_Id)0x00000007U
+
+/**
+ * This mask represents the bits that is used to ensure no extra bits
+ * are set after shifting to extract the class portion of an object Id.
+ */
+#define OBJECTS_CLASS_VALID_BITS (Objects_Id)0x0000001fU
+
+/**
+ * Mask to enable unlimited objects. This is used in the configuration
+ * table when specifying the number of configured objects.
+ */
+#define OBJECTS_UNLIMITED_OBJECTS 0x80000000U
+
+/**
+ * This is the lowest value for the index portion of an object Id.
+ */
+#define OBJECTS_ID_INITIAL_INDEX (0)
+
+/**
+ * This is the highest value for the index portion of an object Id.
+ */
+#define OBJECTS_ID_FINAL_INDEX (0xffffU)
+#endif
+
+/**
+ * This enumerated type is used in the class field of the object ID.
+ */
+typedef enum {
+ OBJECTS_NO_API = 0,
+ OBJECTS_INTERNAL_API = 1,
+ OBJECTS_CLASSIC_API = 2,
+ OBJECTS_POSIX_API = 3,
+ OBJECTS_FAKE_OBJECTS_API = 7
+} Objects_APIs;
+
+/** This macro is used to generically specify the last API index. */
+#define OBJECTS_APIS_LAST OBJECTS_POSIX_API
+
+/**
+ * The following defines the Object Control Block used to manage
+ * each object local to this node.
+ */
+typedef struct {
+ /** This is the chain node portion of an object. */
+ Chain_Node Node;
+ /** This is the object's ID. */
+ Objects_Id id;
+ /** This is the object's name. */
+ Objects_Name name;
+} Objects_Control;
+
+#if defined( RTEMS_MULTIPROCESSING )
+/**
+ * @brief This defines the Global Object Control Block used to manage objects
+ * resident on other nodes.
+ */
+typedef struct {
+ /**
+ * @brief Nodes to manage active and inactive global objects.
+ */
+ union {
+ /**
+ * @brief Inactive global objects reside on a chain.
+ */
+ Chain_Node Inactive;
+
+ struct {
+ /**
+ * @brief Node to lookup an active global object by identifier.
+ */
+ RBTree_Node Id_lookup;
+
+ /**
+ * @brief Node to lookup an active global object by name.
+ */
+ RBTree_Node Name_lookup;
+ } Active;
+ } Nodes;
+
+ /**
+ * @brief The global object identifier.
+ */
+ Objects_Id id;
+
+ /**
+ * @brief The global object name.
+ *
+ * Using an unsigned thirty two bit value is broken but works. If any API is
+ * MP with variable length names .. BOOM!!!!
+ */
+ uint32_t name;
+} Objects_MP_Control;
+#endif
+
+/**
+ * No object can have this ID.
+ */
+#define OBJECTS_ID_NONE 0
+
+/**
+ * The following defines the constant which may be used
+ * to manipulate the calling task.
+ */
+#define OBJECTS_ID_OF_SELF ((Objects_Id) 0)
+
+/**
+ * The following constant is used to specify that a name to ID search
+ * should search through all nodes.
+ */
+#define OBJECTS_SEARCH_ALL_NODES 0
+
+/**
+ * The following constant is used to specify that a name to ID search
+ * should search through all nodes except the current node.
+ */
+#define OBJECTS_SEARCH_OTHER_NODES 0x7FFFFFFE
+
+/**
+ * The following constant is used to specify that a name to ID search
+ * should search only on this node.
+ */
+#define OBJECTS_SEARCH_LOCAL_NODE 0x7FFFFFFF
+
+/**
+ * The following constant is used to specify that a name to ID search
+ * is being asked for the ID of the currently executing task.
+ */
+#define OBJECTS_WHO_AM_I 0
+
+/**
+ * This macros calculates the lowest ID for the specified api, class,
+ * and node.
+ */
+#define OBJECTS_ID_INITIAL(_api, _class, _node) \
+ _Objects_Build_id( (_api), (_class), (_node), OBJECTS_ID_INITIAL_INDEX )
+
+/**
+ * This macro specifies the highest object ID value
+ */
+#define OBJECTS_ID_FINAL ((Objects_Id)~0)
+
+/**
+ * This macro is used to build a thirty-two bit style name from
+ * four characters. The most significant byte will be the
+ * character @a _C1.
+ *
+ * @param[in] _C1 is the first character of the name
+ * @param[in] _C2 is the second character of the name
+ * @param[in] _C3 is the third character of the name
+ * @param[in] _C4 is the fourth character of the name
+ */
+#define _Objects_Build_name( _C1, _C2, _C3, _C4 ) \
+ ( (uint32_t)(_C1) << 24 | \
+ (uint32_t)(_C2) << 16 | \
+ (uint32_t)(_C3) << 8 | \
+ (uint32_t)(_C4) )
+
+/**
+ * This function returns the API portion of the ID.
+ *
+ * @param[in] id is the object Id to be processed.
+ *
+ * @return This method returns an object Id constructed from the arguments.
+ */
+RTEMS_INLINE_ROUTINE Objects_APIs _Objects_Get_API(
+ Objects_Id id
+)
+{
+ return (Objects_APIs) ((id >> OBJECTS_API_START_BIT) & OBJECTS_API_VALID_BITS);
+}
+
+/**
+ * This function returns the class portion of the ID.
+ *
+ * @param[in] id is the object Id to be processed
+ */
+RTEMS_INLINE_ROUTINE uint32_t _Objects_Get_class(
+ Objects_Id id
+)
+{
+ return (uint32_t)
+ ((id >> OBJECTS_CLASS_START_BIT) & OBJECTS_CLASS_VALID_BITS);
+}
+
+/**
+ * This function returns the node portion of the ID.
+ *
+ * @param[in] id is the object Id to be processed
+ *
+ * @return This method returns the node portion of an object ID.
+ */
+RTEMS_INLINE_ROUTINE uint32_t _Objects_Get_node(
+ Objects_Id id
+)
+{
+ /*
+ * If using 16-bit Ids, then there is no node field and it MUST
+ * be a single processor system.
+ */
+ #if defined(RTEMS_USE_16_BIT_OBJECT)
+ return 1;
+ #else
+ return (id >> OBJECTS_NODE_START_BIT) & OBJECTS_NODE_VALID_BITS;
+ #endif
+}
+
+/**
+ * This function returns the index portion of the ID.
+ *
+ * @param[in] id is the Id to be processed
+ *
+ * @return This method returns the class portion of the specified object ID.
+ */
+RTEMS_INLINE_ROUTINE Objects_Maximum _Objects_Get_index(
+ Objects_Id id
+)
+{
+ return
+ (Objects_Maximum)((id >> OBJECTS_INDEX_START_BIT) &
+ OBJECTS_INDEX_VALID_BITS);
+}
+
+/**
+ * This function builds an object's id from the processor node and index
+ * values specified.
+ *
+ * @param[in] the_api indicates the API associated with this Id.
+ * @param[in] the_class indicates the class of object.
+ * It is specific to @a the_api.
+ * @param[in] node is the node where this object resides.
+ * @param[in] index is the instance number of this object.
+ *
+ * @return This method returns an object Id constructed from the arguments.
+ */
+RTEMS_INLINE_ROUTINE Objects_Id _Objects_Build_id(
+ Objects_APIs the_api,
+ uint16_t the_class,
+ uint8_t node,
+ uint16_t index
+)
+{
+ return (( (Objects_Id) the_api ) << OBJECTS_API_START_BIT) |
+ (( (Objects_Id) the_class ) << OBJECTS_CLASS_START_BIT) |
+ #if !defined(RTEMS_USE_16_BIT_OBJECT)
+ (( (Objects_Id) node ) << OBJECTS_NODE_START_BIT) |
+ #endif
+ (( (Objects_Id) index ) << OBJECTS_INDEX_START_BIT);
+}
+
+/**
+ * Returns if the object maximum specifies unlimited objects.
+ *
+ * @param[in] maximum The object maximum specification.
+ *
+ * @retval true Unlimited objects are available.
+ * @retval false The object count is fixed.
+ */
+RTEMS_INLINE_ROUTINE bool _Objects_Is_unlimited( uint32_t maximum )
+{
+ return (maximum & OBJECTS_UNLIMITED_OBJECTS) != 0;
+}
+
+/*
+ * We cannot use an inline function for this since it may be evaluated at
+ * compile time.
+ */
+#define _Objects_Maximum_per_allocation( maximum ) \
+ ((Objects_Maximum) ((maximum) & ~OBJECTS_UNLIMITED_OBJECTS))
+
+/**@}*/
+/**@}*/
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/objectimpl.h b/cpukit/include/rtems/score/objectimpl.h
new file mode 100644
index 0000000000..cc5820785c
--- /dev/null
+++ b/cpukit/include/rtems/score/objectimpl.h
@@ -0,0 +1,1002 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines in the Object Handler
+ *
+ * This include file contains the static inline implementation of all
+ * of the inlined routines in the Object Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_OBJECTIMPL_H
+#define _RTEMS_SCORE_OBJECTIMPL_H
+
+#include <rtems/score/object.h>
+#include <rtems/score/apimutex.h>
+#include <rtems/score/isrlock.h>
+#include <rtems/score/threaddispatch.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreObject
+ *
+ * @{
+ */
+
+/**
+ * Functions which compare names are prototyped like this.
+ */
+typedef bool (*Objects_Name_comparators)(
+ void * /* name_1 */,
+ void * /* name_2 */,
+ uint16_t /* length */
+);
+
+/**
+ * This enumerated type is used in the class field of the object ID
+ * for RTEMS internal object classes.
+ */
+typedef enum {
+ OBJECTS_INTERNAL_NO_CLASS = 0,
+ OBJECTS_INTERNAL_THREADS = 1
+} Objects_Internal_API;
+
+/** This macro is used to generically specify the last API index. */
+#define OBJECTS_INTERNAL_CLASSES_LAST OBJECTS_INTERNAL_THREADS
+
+/**
+ * This enumerated type is used in the class field of the object ID
+ * for the RTEMS Classic API.
+ */
+typedef enum {
+ OBJECTS_CLASSIC_NO_CLASS = 0,
+ OBJECTS_RTEMS_TASKS = 1,
+ OBJECTS_RTEMS_TIMERS = 2,
+ OBJECTS_RTEMS_SEMAPHORES = 3,
+ OBJECTS_RTEMS_MESSAGE_QUEUES = 4,
+ OBJECTS_RTEMS_PARTITIONS = 5,
+ OBJECTS_RTEMS_REGIONS = 6,
+ OBJECTS_RTEMS_PORTS = 7,
+ OBJECTS_RTEMS_PERIODS = 8,
+ OBJECTS_RTEMS_EXTENSIONS = 9,
+ OBJECTS_RTEMS_BARRIERS = 10
+} Objects_Classic_API;
+
+/** This macro is used to generically specify the last API index. */
+#define OBJECTS_RTEMS_CLASSES_LAST OBJECTS_RTEMS_BARRIERS
+
+/**
+ * This enumerated type is used in the class field of the object ID
+ * for the POSIX API.
+ */
+typedef enum {
+ OBJECTS_POSIX_NO_CLASS = 0,
+ OBJECTS_POSIX_THREADS = 1,
+ OBJECTS_POSIX_KEYS = 2,
+ OBJECTS_POSIX_INTERRUPTS = 3,
+ OBJECTS_POSIX_MESSAGE_QUEUES = 5,
+ OBJECTS_POSIX_SEMAPHORES = 7,
+ OBJECTS_POSIX_TIMERS = 9,
+ OBJECTS_POSIX_SHMS = 12
+} Objects_POSIX_API;
+
+/** This macro is used to generically specify the last API index. */
+#define OBJECTS_POSIX_CLASSES_LAST OBJECTS_POSIX_SHMS
+
+/*
+ * For fake objects, which have an object identifier, but no objects
+ * information block.
+ */
+typedef enum {
+ OBJECTS_FAKE_OBJECTS_NO_CLASS = 0,
+ OBJECTS_FAKE_OBJECTS_SCHEDULERS = 1
+} Objects_Fake_objects_API;
+
+#if defined(RTEMS_MULTIPROCESSING)
+/**
+ * The following type defines the callout used when a local task
+ * is extracted from a remote thread queue (i.e. it's proxy must
+ * extracted from the remote queue).
+ */
+typedef void ( *Objects_Thread_queue_Extract_callout )(
+ Thread_Control *,
+ Objects_Id
+);
+#endif
+
+/**
+ * The following defines the structure for the information used to
+ * manage each class of objects.
+ */
+typedef struct {
+ /** This field indicates the API of this object class. */
+ Objects_APIs the_api;
+ /** This is the class of this object set. */
+ uint16_t the_class;
+ /** This is the minimum valid id of this object class. */
+ Objects_Id minimum_id;
+ /** This is the maximum valid id of this object class. */
+ Objects_Id maximum_id;
+ /** This is the maximum number of objects in this class. */
+ Objects_Maximum maximum;
+ /** This is the true if unlimited objects in this class. */
+ bool auto_extend;
+ /** This is the number of objects in a block. */
+ Objects_Maximum allocation_size;
+ /** This is the size in bytes of each object instance. */
+ size_t size;
+ /** This points to the table of local objects. */
+ Objects_Control **local_table;
+ /** This is the chain of inactive control blocks. */
+ Chain_Control Inactive;
+ /** This is the number of objects on the Inactive list. */
+ Objects_Maximum inactive;
+ /** This is the number of inactive objects per block. */
+ uint32_t *inactive_per_block;
+ /** This is a table to the chain of inactive object memory blocks. */
+ void **object_blocks;
+ #if defined(RTEMS_SCORE_OBJECT_ENABLE_STRING_NAMES)
+ /** This is true if names are strings. */
+ bool is_string;
+ #endif
+ /** This is the maximum length of names. */
+ uint16_t name_length;
+ #if defined(RTEMS_MULTIPROCESSING)
+ /** This is this object class' method called when extracting a thread. */
+ Objects_Thread_queue_Extract_callout extract;
+
+ /**
+ * @brief The global objects of this object information sorted by object
+ * identifier.
+ */
+ RBTree_Control Global_by_id;
+
+ /**
+ * @brief The global objects of this object information sorted by object
+ * name.
+ *
+ * Objects with the same name are sorted according to their identifier.
+ */
+ RBTree_Control Global_by_name;
+ #endif
+} Objects_Information;
+
+/**
+ * The following is referenced to the node number of the local node.
+ */
+#if defined(RTEMS_MULTIPROCESSING)
+extern uint16_t _Objects_Local_node;
+#else
+#define _Objects_Local_node ((uint16_t)1)
+#endif
+
+/**
+ * The following is referenced to the number of nodes in the system.
+ */
+#if defined(RTEMS_MULTIPROCESSING)
+extern uint16_t _Objects_Maximum_nodes;
+#else
+#define _Objects_Maximum_nodes 1
+#endif
+
+/**
+ * The following is the list of information blocks per API for each object
+ * class. From the ID, we can go to one of these information blocks,
+ * and obtain a pointer to the appropriate object control block.
+ */
+extern Objects_Information ** const
+_Objects_Information_table[ OBJECTS_APIS_LAST + 1 ];
+
+/**
+ * This function extends an object class information record.
+ *
+ * @param[in] information points to an object class information block.
+ */
+void _Objects_Extend_information(
+ Objects_Information *information
+);
+
+/**
+ * @brief Shrink an object class information record
+ *
+ * This function shrink an object class information record.
+ * The object's name and object space are released. The local_table
+ * etc block does not shrink. The InActive list needs to be scanned
+ * to find the objects are remove them.
+ *
+ * @param[in] information points to an object class information block.
+ */
+void _Objects_Shrink_information(
+ Objects_Information *information
+);
+
+void _Objects_Do_initialize_information(
+ Objects_Information *information,
+ Objects_APIs the_api,
+ uint16_t the_class,
+ uint32_t maximum,
+ uint16_t size,
+ bool is_string,
+ uint32_t maximum_name_length
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ Objects_Thread_queue_Extract_callout extract
+#endif
+);
+
+/**
+ * @brief Initialize object Information
+ *
+ * This function initializes an object class information record.
+ * SUPPORTS_GLOBAL is true if the object class supports global
+ * objects, and false otherwise. Maximum indicates the number
+ * of objects required in this class and size indicates the size
+ * in bytes of each control block for this object class. The
+ * name length and string designator are also set. In addition,
+ * the class may be a task, therefore this information is also included.
+ *
+ * @param[in] information points to an object class information block.
+ * @param[in] the_api indicates the API associated with this information block.
+ * @param[in] the_class indicates the class of object being managed
+ * by this information block. It is specific to @a the_api.
+ * @param[in] maximum is the maximum number of instances of this object
+ * class which may be concurrently active.
+ * @param[in] size is the size of the data structure for this class.
+ * @param[in] is_string is true if this object uses string style names.
+ * @param[in] maximum_name_length is the maximum length of object names.
+ */
+#if defined(RTEMS_MULTIPROCESSING)
+ #define _Objects_Initialize_information( \
+ information, \
+ the_api, \
+ the_class, \
+ maximum, \
+ size, \
+ is_string, \
+ maximum_name_length, \
+ extract \
+ ) \
+ _Objects_Do_initialize_information( \
+ information, \
+ the_api, \
+ the_class, \
+ maximum, \
+ size, \
+ is_string, \
+ maximum_name_length, \
+ extract \
+ )
+#else
+ #define _Objects_Initialize_information( \
+ information, \
+ the_api, \
+ the_class, \
+ maximum, \
+ size, \
+ is_string, \
+ maximum_name_length, \
+ extract \
+ ) \
+ _Objects_Do_initialize_information( \
+ information, \
+ the_api, \
+ the_class, \
+ maximum, \
+ size, \
+ is_string, \
+ maximum_name_length \
+ )
+#endif
+
+/**
+ * @brief Object API Maximum Class
+ *
+ * This function returns the highest numeric value of a valid
+ * API for the specified @a api.
+ *
+ * @param[in] api is the API of interest
+ *
+ * @retval A positive integer on success and 0 otherwise.
+ */
+unsigned int _Objects_API_maximum_class(
+ uint32_t api
+);
+
+/**
+ * @brief Allocates an object without locking the allocator mutex.
+ *
+ * This function can be called in two contexts
+ * - the executing thread is the owner of the object allocator mutex, or
+ * - in case the system state is not up, e.g. during sequential system
+ * initialization.
+ *
+ * @param[in] information The object information block.
+ *
+ * @retval NULL No object available.
+ * @retval object The allocated object.
+ *
+ * @see _Objects_Allocate() and _Objects_Free().
+ */
+Objects_Control *_Objects_Allocate_unprotected(
+ Objects_Information *information
+);
+
+/**
+ * @brief Allocates an object.
+ *
+ * This function locks the object allocator mutex via
+ * _Objects_Allocator_lock(). The caller must later unlock the object
+ * allocator mutex via _Objects_Allocator_unlock(). The caller must unlock the
+ * mutex in any case, even if the allocation failed due to resource shortage.
+ *
+ * A typical object allocation code looks like this:
+ * @code
+ * rtems_status_code some_create( rtems_id *id )
+ * {
+ * rtems_status_code sc;
+ * Some_Control *some;
+ *
+ * // The object allocator mutex protects the executing thread from
+ * // asynchronous thread restart and deletion.
+ * some = (Some_Control *) _Objects_Allocate( &_Some_Information );
+ *
+ * if ( some != NULL ) {
+ * _Some_Initialize( some );
+ * sc = RTEMS_SUCCESSFUL;
+ * } else {
+ * sc = RTEMS_TOO_MANY;
+ * }
+ *
+ * _Objects_Allocator_unlock();
+ *
+ * return sc;
+ * }
+ * @endcode
+ *
+ * @param[in] information The object information block.
+ *
+ * @retval NULL No object available.
+ * @retval object The allocated object.
+ *
+ * @see _Objects_Free().
+ */
+Objects_Control *_Objects_Allocate( Objects_Information *information );
+
+/**
+ * @brief Frees an object.
+ *
+ * Appends the object to the chain of inactive objects.
+ *
+ * @param[in] information The object information block.
+ * @param[in] the_object The object to free.
+ *
+ * @see _Objects_Allocate().
+ *
+ * A typical object deletion code looks like this:
+ * @code
+ * rtems_status_code some_delete( rtems_id id )
+ * {
+ * Some_Control *some;
+ *
+ * // The object allocator mutex protects the executing thread from
+ * // asynchronous thread restart and deletion.
+ * _Objects_Allocator_lock();
+ *
+ * // Get the object under protection of the object allocator mutex.
+ * some = (Semaphore_Control *)
+ * _Objects_Get_no_protection( id, &_Some_Information );
+ *
+ * if ( some == NULL ) {
+ * _Objects_Allocator_unlock();
+ * return RTEMS_INVALID_ID;
+ * }
+ *
+ * // After the object close an object get with this identifier will
+ * // fail.
+ * _Objects_Close( &_Some_Information, &some->Object );
+ *
+ * _Some_Delete( some );
+ *
+ * // Thread dispatching is enabled. The object free is only protected
+ * // by the object allocator mutex.
+ * _Objects_Free( &_Some_Information, &some->Object );
+ *
+ * _Objects_Allocator_unlock();
+ * return RTEMS_SUCCESSFUL;
+ * }
+ * @endcode
+ */
+void _Objects_Free(
+ Objects_Information *information,
+ Objects_Control *the_object
+);
+
+/**
+ * This function implements the common portion of the object
+ * identification directives. This directive returns the object
+ * id associated with name. If more than one object of this class
+ * is named name, then the object to which the id belongs is
+ * arbitrary. Node indicates the extent of the search for the
+ * id of the object named name. If the object class supports global
+ * objects, then the search can be limited to a particular node
+ * or allowed to encompass all nodes.
+ */
+typedef enum {
+ OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL,
+ OBJECTS_INVALID_NAME,
+ OBJECTS_INVALID_ADDRESS,
+ OBJECTS_INVALID_ID,
+ OBJECTS_INVALID_NODE
+} Objects_Name_or_id_lookup_errors;
+
+/**
+ * This macro defines the first entry in the
+ * @ref Objects_Name_or_id_lookup_errors enumerated list.
+ */
+#define OBJECTS_NAME_ERRORS_FIRST OBJECTS_NAME_OR_ID_LOOKUP_SUCCESSFUL
+
+/**
+ * This macro defines the last entry in the
+ * @ref Objects_Name_or_id_lookup_errors enumerated list.
+ */
+#define OBJECTS_NAME_ERRORS_LAST OBJECTS_INVALID_NODE
+
+/**
+ * @brief Converts an object name to an Id.
+ *
+ * This method converts an object name to an Id. It performs a look up
+ * using the object information block for this object class.
+ *
+ * @param[in] information points to an object class information block.
+ * @param[in] name is the name of the object to find.
+ * @param[in] node is the set of nodes to search.
+ * @param[in] id will contain the Id if the search is successful.
+ *
+ * @retval This method returns one of the values from the
+ * @ref Objects_Name_or_id_lookup_errors enumeration to indicate
+ * successful or failure. On success @a id will contain the Id of
+ * the requested object.
+ */
+Objects_Name_or_id_lookup_errors _Objects_Name_to_id_u32(
+ Objects_Information *information,
+ uint32_t name,
+ uint32_t node,
+ Objects_Id *id
+);
+
+typedef enum {
+ OBJECTS_GET_BY_NAME_INVALID_NAME,
+ OBJECTS_GET_BY_NAME_NAME_TOO_LONG,
+ OBJECTS_GET_BY_NAME_NO_OBJECT
+} Objects_Get_by_name_error;
+
+/**
+ * @brief Gets an object control block identified by its name.
+ *
+ * The object information must use string names.
+ *
+ * @param information The object information. Must not be NULL.
+ * @param name The object name.
+ * @param name_length_p Optional parameter to return the name length.
+ * @param error The error indication in case of failure. Must not be NULL.
+ *
+ * @retval NULL No object exists for this name or invalid parameters.
+ * @retval other The first object according to object index associated with
+ * this name.
+ */
+Objects_Control *_Objects_Get_by_name(
+ const Objects_Information *information,
+ const char *name,
+ size_t *name_length_p,
+ Objects_Get_by_name_error *error
+);
+
+/**
+ * @brief Implements the common portion of the object Id to name directives.
+ *
+ * This function implements the common portion of the object Id
+ * to name directives. This function returns the name
+ * associated with object id.
+ *
+ * @param[in] id is the Id of the object whose name we are locating.
+ * @param[in] name will contain the name of the object, if found.
+ *
+ * @retval This method returns one of the values from the
+ * @ref Objects_Name_or_id_lookup_errors enumeration to indicate
+ * successful or failure. On success @a name will contain the name of
+ * the requested object.
+ *
+ * @note This function currently does not support string names.
+ */
+Objects_Name_or_id_lookup_errors _Objects_Id_to_name (
+ Objects_Id id,
+ Objects_Name *name
+);
+
+/**
+ * @brief Maps the specified object identifier to the associated local object
+ * control block.
+ *
+ * In this function interrupts are disabled during the object lookup. In case
+ * an associated object exists, then interrupts remain disabled, otherwise the
+ * previous interrupt state is restored.
+ *
+ * @param id The object identifier. This is the first parameter since usual
+ * callers get the object identifier as the first parameter themself.
+ * @param lock_context The interrupt lock context. This is the second
+ * parameter since usual callers get the interrupt lock context as the second
+ * parameter themself.
+ * @param information The object class information block.
+ *
+ * @retval NULL No associated object exists.
+ * @retval other The pointer to the associated object control block.
+ * Interrupts are now disabled and must be restored using the specified lock
+ * context via _ISR_lock_ISR_enable() or _ISR_lock_Release_and_ISR_enable().
+ */
+Objects_Control *_Objects_Get(
+ Objects_Id id,
+ ISR_lock_Context *lock_context,
+ const Objects_Information *information
+);
+
+/**
+ * @brief Maps object ids to object control blocks.
+ *
+ * This function maps object ids to object control blocks.
+ * If id corresponds to a local object, then it returns
+ * the_object control pointer which maps to id and location
+ * is set to OBJECTS_LOCAL. If the object class supports global
+ * objects and the object id is global and resides on a remote
+ * node, then location is set to OBJECTS_REMOTE, and the_object
+ * is undefined. Otherwise, location is set to OBJECTS_ERROR
+ * and the_object is undefined.
+ *
+ * @param[in] id is the Id of the object whose name we are locating.
+ * This is the first parameter since usual callers get the object identifier
+ * as the first parameter themself.
+ * @param[in] information points to an object class information block.
+ *
+ * @retval This method returns one of the values from the
+ * @ref Objects_Name_or_id_lookup_errors enumeration to indicate
+ * successful or failure. On success @a id will contain the Id of
+ * the requested object.
+ */
+Objects_Control *_Objects_Get_no_protection(
+ Objects_Id id,
+ const Objects_Information *information
+);
+
+/**
+ * Gets the next open object after the specified object identifier.
+ *
+ * Locks the object allocator mutex in case a next object exists.
+ *
+ * @param[in] id is the Id of the object whose name we are locating.
+ * This is the first parameter since usual callers get the object identifier
+ * as the first parameter themself.
+ * @param[in] information points to an object class information block.
+ * @param[in] next_id_p is the Id of the next object we will look at.
+ *
+ * @retval This method returns the pointer to the object located or
+ * NULL on error.
+ */
+Objects_Control *_Objects_Get_next(
+ Objects_Id id,
+ const Objects_Information *information,
+ Objects_Id *next_id_p
+);
+
+/**
+ * @brief Get object information.
+ *
+ * This function return the information structure given
+ * an the API and Class. This can be done independent of
+ * the existence of any objects created by the API.
+ *
+ * @param[in] the_api indicates the API for the information we want
+ * @param[in] the_class indicates the Class for the information we want
+ *
+ * @retval This method returns a pointer to the Object Information Table
+ * for the class of objects which corresponds to this object ID.
+ */
+Objects_Information *_Objects_Get_information(
+ Objects_APIs the_api,
+ uint16_t the_class
+);
+
+/**
+ * @brief Get information of an object from an ID.
+ *
+ * This function return the information structure given
+ * an @a id of an object.
+ *
+ * @param[in] id is the object ID to get the information from
+ *
+ * @retval This method returns a pointer to the Object Information Table
+ * for the class of objects which corresponds to this object ID.
+ */
+Objects_Information *_Objects_Get_information_id(
+ Objects_Id id
+);
+
+/**
+ * @brief Gets object name in the form of a C string.
+ *
+ * This method objects the name of an object and returns its name
+ * in the form of a C string. It attempts to be careful about
+ * overflowing the user's string and about returning unprintable characters.
+ *
+ * @param[in] id is the object to obtain the name of
+ * @param[in] length indicates the length of the caller's buffer
+ * @param[in] name points a string which will be filled in.
+ *
+ * @retval This method returns @a name or NULL on error. @a *name will
+ * contain the name if successful.
+ */
+char *_Objects_Get_name_as_string(
+ Objects_Id id,
+ size_t length,
+ char *name
+);
+
+/**
+ * @brief Converts the specified object name to a text representation.
+ *
+ * Non-printable characters according to isprint() are converted to '*'.
+ *
+ * @param[in] name The object name.
+ * @param[in] is_string Indicates if the object name is a string or a four
+ * character array (32-bit unsigned integer).
+ * @param[in] buffer The string buffer for the text representation.
+ * @param[in] buffer_size The buffer size in characters.
+ *
+ * @retval The length of the text representation. May be greater than or equal
+ * to the buffer size if truncation occurred.
+ */
+size_t _Objects_Name_to_string(
+ Objects_Name name,
+ bool is_string,
+ char *buffer,
+ size_t buffer_size
+);
+
+/**
+ * @brief Set objects name.
+ *
+ * This method sets the object name to either a copy of a string
+ * or up to the first four characters of the string based upon
+ * whether this object class uses strings for names.
+ *
+ * @param[in] information points to the object information structure
+ * @param[in] the_object is the object to operate upon
+ * @param[in] name is a pointer to the name to use
+ *
+ * @retval If successful, true is returned. Otherwise false is returned.
+ */
+bool _Objects_Set_name(
+ Objects_Information *information,
+ Objects_Control *the_object,
+ const char *name
+);
+
+/**
+ * @brief Removes object from namespace.
+ *
+ * This function removes @a the_object from the namespace.
+ *
+ * @param[in] information points to an Object Information Table.
+ * @param[in] the_object is a pointer to an object.
+ */
+void _Objects_Namespace_remove(
+ Objects_Information *information,
+ Objects_Control *the_object
+);
+
+/**
+ * @brief Close object.
+ *
+ * This function removes the_object control pointer and object name
+ * in the Local Pointer and Local Name Tables.
+ *
+ * @param[in] information points to an Object Information Table
+ * @param[in] the_object is a pointer to an object
+ */
+void _Objects_Close(
+ Objects_Information *information,
+ Objects_Control *the_object
+);
+
+/**
+ * @brief Returns the count of active objects.
+ *
+ * @param[in] information The object information table.
+ *
+ * @retval The count of active objects.
+ */
+Objects_Maximum _Objects_Active_count(
+ const Objects_Information *information
+);
+
+RTEMS_INLINE_ROUTINE Objects_Maximum _Objects_Extend_size(
+ const Objects_Information *information
+)
+{
+ return information->auto_extend ? information->allocation_size : 0;
+}
+
+/**
+ * This function returns true if the api is valid.
+ *
+ * @param[in] the_api is the api portion of an object ID.
+ *
+ * @return This method returns true if the specified api value is valid
+ * and false otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Objects_Is_api_valid(
+ uint32_t the_api
+)
+{
+ if ( !the_api || the_api > OBJECTS_APIS_LAST )
+ return false;
+ return true;
+}
+
+/**
+ * This function returns true if the node is of the local object, and
+ * false otherwise.
+ *
+ * @param[in] node is the node number and corresponds to the node number
+ * portion of an object ID.
+ *
+ * @return This method returns true if the specified node is the local node
+ * and false otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Objects_Is_local_node(
+ uint32_t node
+)
+{
+ return ( node == _Objects_Local_node );
+}
+
+/**
+ * This function returns true if the id is of a local object, and
+ * false otherwise.
+ *
+ * @param[in] id is an object ID
+ *
+ * @return This method returns true if the specified object Id is local
+ * and false otherwise.
+ *
+ * @note On a single processor configuration, this always returns true.
+ */
+RTEMS_INLINE_ROUTINE bool _Objects_Is_local_id(
+#if defined(RTEMS_MULTIPROCESSING)
+ Objects_Id id
+#else
+ Objects_Id id RTEMS_UNUSED
+#endif
+)
+{
+#if defined(RTEMS_MULTIPROCESSING)
+ return _Objects_Is_local_node( _Objects_Get_node(id) );
+#else
+ return true;
+#endif
+}
+
+/**
+ * This function returns true if left and right are equal,
+ * and false otherwise.
+ *
+ * @param[in] left is the Id on the left hand side of the comparison
+ * @param[in] right is the Id on the right hand side of the comparison
+ *
+ * @return This method returns true if the specified object IDs are equal
+ * and false otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Objects_Are_ids_equal(
+ Objects_Id left,
+ Objects_Id right
+)
+{
+ return ( left == right );
+}
+
+/**
+ * This function sets the pointer to the local_table object
+ * referenced by the index.
+ *
+ * @param[in] information points to an Object Information Table
+ * @param[in] index is the index of the object the caller wants to access
+ * @param[in] the_object is the local object pointer
+ *
+ * @note This routine is ONLY to be called in places where the
+ * index portion of the Id is known to be good. This is
+ * OK since it is normally called from object create/init
+ * or delete/destroy operations.
+ */
+
+RTEMS_INLINE_ROUTINE void _Objects_Set_local_object(
+ Objects_Information *information,
+ uint32_t index,
+ Objects_Control *the_object
+)
+{
+ /*
+ * This routine is ONLY to be called from places in the code
+ * where the Id is known to be good. Therefore, this should NOT
+ * occur in normal situations.
+ */
+ #if defined(RTEMS_DEBUG)
+ if ( index > information->maximum )
+ return;
+ #endif
+
+ information->local_table[ index ] = the_object;
+}
+
+/**
+ * This function sets the pointer to the local_table object
+ * referenced by the index to a NULL so the object Id is invalid
+ * after this call.
+ *
+ * @param[in] information points to an Object Information Table
+ * @param[in] the_object is the local object pointer
+ *
+ * @note This routine is ONLY to be called in places where the
+ * index portion of the Id is known to be good. This is
+ * OK since it is normally called from object create/init
+ * or delete/destroy operations.
+ */
+
+RTEMS_INLINE_ROUTINE void _Objects_Invalidate_Id(
+ Objects_Information *information,
+ Objects_Control *the_object
+)
+{
+ _Assert( information != NULL );
+ _Assert( the_object != NULL );
+
+ _Objects_Set_local_object(
+ information,
+ _Objects_Get_index( the_object->id ),
+ NULL
+ );
+}
+
+/**
+ * This function places the_object control pointer and object name
+ * in the Local Pointer and Local Name Tables, respectively.
+ *
+ * @param[in] information points to an Object Information Table
+ * @param[in] the_object is a pointer to an object
+ * @param[in] name is the name of the object to make accessible
+ */
+RTEMS_INLINE_ROUTINE void _Objects_Open(
+ Objects_Information *information,
+ Objects_Control *the_object,
+ Objects_Name name
+)
+{
+ _Assert( information != NULL );
+ _Assert( the_object != NULL );
+
+ the_object->name = name;
+
+ _Objects_Set_local_object(
+ information,
+ _Objects_Get_index( the_object->id ),
+ the_object
+ );
+}
+
+/**
+ * This function places the_object control pointer and object name
+ * in the Local Pointer and Local Name Tables, respectively.
+ *
+ * @param[in] information points to an Object Information Table
+ * @param[in] the_object is a pointer to an object
+ * @param[in] name is the name of the object to make accessible
+ */
+RTEMS_INLINE_ROUTINE void _Objects_Open_u32(
+ Objects_Information *information,
+ Objects_Control *the_object,
+ uint32_t name
+)
+{
+ /* ASSERT: information->is_string == false */
+ the_object->name.name_u32 = name;
+
+ _Objects_Set_local_object(
+ information,
+ _Objects_Get_index( the_object->id ),
+ the_object
+ );
+}
+
+/**
+ * This function places the_object control pointer and object name
+ * in the Local Pointer and Local Name Tables, respectively.
+ *
+ * @param[in] information points to an Object Information Table
+ * @param[in] the_object is a pointer to an object
+ * @param[in] name is the name of the object to make accessible
+ */
+RTEMS_INLINE_ROUTINE void _Objects_Open_string(
+ Objects_Information *information,
+ Objects_Control *the_object,
+ const char *name
+)
+{
+ #if defined(RTEMS_SCORE_OBJECT_ENABLE_STRING_NAMES)
+ /* ASSERT: information->is_string */
+ the_object->name.name_p = name;
+ #endif
+
+ _Objects_Set_local_object(
+ information,
+ _Objects_Get_index( the_object->id ),
+ the_object
+ );
+}
+
+/**
+ * @brief Locks the object allocator mutex.
+ *
+ * While holding the allocator mutex the executing thread is protected from
+ * asynchronous thread restart and deletion.
+ *
+ * The usage of the object allocator mutex with the thread life protection
+ * makes it possible to allocate and free objects without thread dispatching
+ * disabled. The usage of a unified workspace and unlimited objects may lead
+ * to heap fragmentation. Thus the execution time of the _Objects_Allocate()
+ * function may increase during system run-time.
+ *
+ * @see _Objects_Allocator_unlock() and _Objects_Allocate().
+ */
+RTEMS_INLINE_ROUTINE void _Objects_Allocator_lock( void )
+{
+ _RTEMS_Lock_allocator();
+}
+
+/**
+ * @brief Unlocks the object allocator mutex.
+ *
+ * In case the mutex is fully unlocked, then this function restores the
+ * previous thread life protection state and thus may not return if the
+ * executing thread was restarted or deleted in the mean-time.
+ */
+RTEMS_INLINE_ROUTINE void _Objects_Allocator_unlock( void )
+{
+ _RTEMS_Unlock_allocator();
+}
+
+RTEMS_INLINE_ROUTINE bool _Objects_Allocator_is_owner( void )
+{
+ return _RTEMS_Allocator_is_owner();
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/objectmp.h>
+#endif
+
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/objectmp.h b/cpukit/include/rtems/score/objectmp.h
new file mode 100644
index 0000000000..5c9f4f74e3
--- /dev/null
+++ b/cpukit/include/rtems/score/objectmp.h
@@ -0,0 +1,197 @@
+/**
+ * @file rtems/score/objectmp.h
+ *
+ * @brief Data Associated with the Manipulation of Global RTEMS Objects
+ *
+ * This include file contains all the constants and structures associated
+ * with the manipulation of Global RTEMS Objects.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_OBJECTMP_H
+#define _RTEMS_SCORE_OBJECTMP_H
+
+#ifndef _RTEMS_SCORE_OBJECTIMPL_H
+# error "Never use <rtems/rtems/objectmp.h> directly; include <rtems/rtems/objectimpl.h> instead."
+#endif
+
+#include <rtems/score/chainimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreObjectMP Object Handler Multiprocessing Support
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality which is used to manage
+ * objects which have been declared to be globally visible. This handler
+ * knows objects from all of the nodes in the system.
+ */
+/**@{*/
+
+/**
+ * @brief Intializes the inactive global object chain
+ * based on the maximum number of global objects configured.
+ *
+ * This routine intializes the inactive global object chain
+ * based on the maximum number of global objects configured.
+ */
+void _Objects_MP_Handler_initialization(void);
+
+/**
+ * @brief Intializes the global object node number
+ * used in the ID field of all objects.
+ *
+ * This routine intializes the global object node number
+ * used in the ID field of all objects.
+ */
+void _Objects_MP_Handler_early_initialization(void);
+
+/**
+ * @brief Place the specified global object in the
+ * specified information table.
+ *
+ * This routine place the specified global object in the
+ * specified information table.
+ *
+ * @param[in] information points to the object information table for this
+ * object class.
+ * @param[in] the_global_object points to the object being opened.
+ * @param[in] the_name is the name of the object being opened.
+ * @param[in] the_id is the Id of the object being opened.
+ *
+ * @todo This method only works for object types with 4 byte object names.
+ * It does not support variable length object names.
+ */
+void _Objects_MP_Open (
+ Objects_Information *information,
+ Objects_MP_Control *the_global_object,
+ uint32_t the_name,
+ Objects_Id the_id
+);
+
+/**
+ * @brief Allocates a global object control block
+ * and places it in the specified information table.
+ *
+ * This routine allocates a global object control block
+ * and places it in the specified information table. If the
+ * allocation fails, then is_fatal_error determines the
+ * error processing actions taken.
+ *
+ * @param[in] information points to the object information table for this
+ * object class.
+ * @param[in] the_name is the name of the object being opened.
+ * @param[in] the_id is the Id of the object being opened.
+ * @param[in] is_fatal_error is true if not being able to allocate the
+ * object is considered a fatal error.
+ *
+ * @todo This method only works for object types with 4 byte object names.
+ * It does not support variable length object names.
+ */
+bool _Objects_MP_Allocate_and_open (
+ Objects_Information *information,
+ uint32_t the_name,
+ Objects_Id the_id,
+ bool is_fatal_error
+);
+
+/**
+ * @brief Removes a global object from the specified information table.
+ *
+ * This routine removes a global object from the specified
+ * information table and deallocates the global object control block.
+ */
+void _Objects_MP_Close (
+ Objects_Information *information,
+ Objects_Id the_id
+);
+
+/**
+ * @brief Look for the object with the_name in the global
+ * object tables indicated by information.
+ *
+ * This routine looks for the object with the_name in the global
+ * object tables indicated by information. It returns the ID of the
+ * object with that name if one is found.
+ *
+ * @param[in] information points to the object information table for this
+ * object class.
+ * @param[in] the_name is the name of the object being searched for.
+ * @param[in] nodes_to_search indicates the set of nodes to search.
+ * @param[in] the_id will contain the Id of the object if found.
+ *
+ * @retval This method returns one of the
+ * @ref Objects_Name_or_id_lookup_errors. If successful, @a the_id
+ * will contain the Id of the object.
+ */
+Objects_Name_or_id_lookup_errors _Objects_MP_Global_name_search (
+ Objects_Information *information,
+ Objects_Name the_name,
+ uint32_t nodes_to_search,
+ Objects_Id *the_id
+);
+
+/**
+ * @brief Returns true, if the object identifier is in the global object
+ * identifier cache of the specified object information, otherwise false.
+ *
+ * @param id The object identifier.
+ * @param information The object information.
+ *
+ * @retval true A remote objects with this object identifier exits in the
+ * global object identifier cache of the specified information.
+ * @retval false Otherwise.
+ */
+bool _Objects_MP_Is_remote(
+ Objects_Id id,
+ const Objects_Information *information
+);
+
+/**
+ * This is the maximum number of global objects configured.
+ */
+extern uint32_t _Objects_MP_Maximum_global_objects;
+
+/**
+ * This function allocates a Global Object control block.
+ */
+
+Objects_MP_Control *_Objects_MP_Allocate_global_object( void );
+
+/**
+ * This routine deallocates a Global Object control block.
+ */
+
+void _Objects_MP_Free_global_object( Objects_MP_Control *the_object );
+
+/**
+ * This function returns whether the global object is NULL or not.
+ */
+
+RTEMS_INLINE_ROUTINE bool _Objects_MP_Is_null_global_object (
+ Objects_MP_Control *the_object
+)
+{
+ return( the_object == NULL );
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/onceimpl.h b/cpukit/include/rtems/score/onceimpl.h
new file mode 100644
index 0000000000..60f1378506
--- /dev/null
+++ b/cpukit/include/rtems/score/onceimpl.h
@@ -0,0 +1,52 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreOnce
+ *
+ * @brief Once API
+ */
+
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_ONCE_H
+#define _RTEMS_ONCE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ScoreOnce Once Functions.
+ *
+ * @ingroup Score
+ *
+ * @brief The _Once() function for pthread_once() and rtems_gxx_once().
+ *
+ * @{
+ */
+
+int _Once( unsigned char *once_state, void (*init_routine)(void) );
+
+void _Once_Lock( void );
+
+void _Once_Unlock( void );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_ONCE_H */
diff --git a/cpukit/include/rtems/score/percpu.h b/cpukit/include/rtems/score/percpu.h
new file mode 100644
index 0000000000..00528b5ce3
--- /dev/null
+++ b/cpukit/include/rtems/score/percpu.h
@@ -0,0 +1,851 @@
+/**
+ * @file rtems/score/percpu.h
+ *
+ * This include file defines the per CPU information required
+ * by RTEMS.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Copyright (c) 2012, 2016 embedded brains GmbH
+ *
+ * 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_PERCPU_H
+#define _RTEMS_PERCPU_H
+
+#include <rtems/score/cpuimpl.h>
+
+#if defined( ASM )
+ #include <rtems/asm.h>
+#else
+ #include <rtems/score/assert.h>
+ #include <rtems/score/chain.h>
+ #include <rtems/score/isrlock.h>
+ #include <rtems/score/smp.h>
+ #include <rtems/score/smplock.h>
+ #include <rtems/score/timestamp.h>
+ #include <rtems/score/watchdog.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(RTEMS_SMP)
+ #if defined(RTEMS_PROFILING)
+ #define PER_CPU_CONTROL_SIZE_APPROX ( 512 + CPU_INTERRUPT_FRAME_SIZE )
+ #elif defined(RTEMS_DEBUG)
+ #define PER_CPU_CONTROL_SIZE_APPROX ( 256 + CPU_INTERRUPT_FRAME_SIZE )
+ #else
+ #define PER_CPU_CONTROL_SIZE_APPROX ( 128 + CPU_INTERRUPT_FRAME_SIZE )
+ #endif
+
+ /*
+ * This ensures that on SMP configurations the individual per-CPU controls
+ * are on different cache lines to prevent false sharing. This define can be
+ * used in assembler code to easily get the per-CPU control for a particular
+ * processor.
+ */
+ #if PER_CPU_CONTROL_SIZE_APPROX > 1024
+ #define PER_CPU_CONTROL_SIZE_LOG2 11
+ #elif PER_CPU_CONTROL_SIZE_APPROX > 512
+ #define PER_CPU_CONTROL_SIZE_LOG2 10
+ #elif PER_CPU_CONTROL_SIZE_APPROX > 256
+ #define PER_CPU_CONTROL_SIZE_LOG2 9
+ #elif PER_CPU_CONTROL_SIZE_APPROX > 128
+ #define PER_CPU_CONTROL_SIZE_LOG2 8
+ #else
+ #define PER_CPU_CONTROL_SIZE_LOG2 7
+ #endif
+
+ #define PER_CPU_CONTROL_SIZE ( 1 << PER_CPU_CONTROL_SIZE_LOG2 )
+#endif
+
+#if !defined( ASM )
+
+struct _Thread_Control;
+
+struct Scheduler_Context;
+
+/**
+ * @defgroup PerCPU RTEMS Per CPU Information
+ *
+ * @ingroup Score
+ *
+ * This defines the per CPU state information required by RTEMS
+ * and the BSP. In an SMP configuration, there will be multiple
+ * instances of this data structure -- one per CPU -- and the
+ * current CPU number will be used as the index.
+ */
+
+/**@{*/
+
+#if defined( RTEMS_SMP )
+
+/**
+ * @brief State of a processor.
+ *
+ * The processor state controls the life cycle of processors at the lowest
+ * level. No multi-threading or other high-level concepts matter here.
+ *
+ * State changes must be initiated via _Per_CPU_State_change(). This function
+ * may not return in case someone requested a shutdown. The
+ * _SMP_Send_message() function will be used to notify other processors about
+ * state changes if the other processor is in the up state.
+ *
+ * Due to the sequential nature of the basic system initialization one
+ * processor has a special role. It is the processor executing the boot_card()
+ * function. This processor is called the boot processor. All other
+ * processors are called secondary.
+ *
+ * @dot
+ * digraph states {
+ * i [label="PER_CPU_STATE_INITIAL"];
+ * rdy [label="PER_CPU_STATE_READY_TO_START_MULTITASKING"];
+ * reqsm [label="PER_CPU_STATE_REQUEST_START_MULTITASKING"];
+ * u [label="PER_CPU_STATE_UP"];
+ * s [label="PER_CPU_STATE_SHUTDOWN"];
+ * i -> rdy [label="processor\ncompleted initialization"];
+ * rdy -> reqsm [label="boot processor\ncompleted initialization"];
+ * reqsm -> u [label="processor\nstarts multitasking"];
+ * i -> s;
+ * rdy -> s;
+ * reqsm -> s;
+ * u -> s;
+ * }
+ * @enddot
+ */
+typedef enum {
+ /**
+ * @brief The per CPU controls are initialized to zero.
+ *
+ * The boot processor executes the sequential boot code in this state. The
+ * secondary processors should perform their basic initialization now and
+ * change into the PER_CPU_STATE_READY_TO_START_MULTITASKING state once this
+ * is complete.
+ */
+ PER_CPU_STATE_INITIAL,
+
+ /**
+ * @brief Processor is ready to start multitasking.
+ *
+ * The secondary processor performed its basic initialization and is ready to
+ * receive inter-processor interrupts. Interrupt delivery must be disabled
+ * in this state, but requested inter-processor interrupts must be recorded
+ * and must be delivered once the secondary processor enables interrupts for
+ * the first time. The boot processor will wait for all secondary processors
+ * to change into this state. In case a secondary processor does not reach
+ * this state the system will not start. The secondary processors wait now
+ * for a change into the PER_CPU_STATE_REQUEST_START_MULTITASKING state set
+ * by the boot processor once all secondary processors reached the
+ * PER_CPU_STATE_READY_TO_START_MULTITASKING state.
+ */
+ PER_CPU_STATE_READY_TO_START_MULTITASKING,
+
+ /**
+ * @brief Multitasking start of processor is requested.
+ *
+ * The boot processor completed system initialization and is about to perform
+ * a context switch to its heir thread. Secondary processors should now
+ * issue a context switch to the heir thread. This normally enables
+ * interrupts on the processor for the first time.
+ */
+ PER_CPU_STATE_REQUEST_START_MULTITASKING,
+
+ /**
+ * @brief Normal multitasking state.
+ */
+ PER_CPU_STATE_UP,
+
+ /**
+ * @brief This is the terminal state.
+ */
+ PER_CPU_STATE_SHUTDOWN
+} Per_CPU_State;
+
+#endif /* defined( RTEMS_SMP ) */
+
+/**
+ * @brief Per-CPU statistics.
+ */
+typedef struct {
+#if defined( RTEMS_PROFILING )
+ /**
+ * @brief The thread dispatch disabled begin instant in CPU counter ticks.
+ *
+ * This value is used to measure the time of disabled thread dispatching.
+ */
+ CPU_Counter_ticks thread_dispatch_disabled_instant;
+
+ /**
+ * @brief The maximum time of disabled thread dispatching in CPU counter
+ * ticks.
+ */
+ CPU_Counter_ticks max_thread_dispatch_disabled_time;
+
+ /**
+ * @brief The maximum time spent to process a single sequence of nested
+ * interrupts in CPU counter ticks.
+ *
+ * This is the time interval between the change of the interrupt nest level
+ * from zero to one and the change back from one to zero.
+ */
+ CPU_Counter_ticks max_interrupt_time;
+
+ /**
+ * @brief The maximum interrupt delay in CPU counter ticks if supported by
+ * the hardware.
+ */
+ CPU_Counter_ticks max_interrupt_delay;
+
+ /**
+ * @brief Count of times when the thread dispatch disable level changes from
+ * zero to one in thread context.
+ *
+ * This value may overflow.
+ */
+ uint64_t thread_dispatch_disabled_count;
+
+ /**
+ * @brief Total time of disabled thread dispatching in CPU counter ticks.
+ *
+ * The average time of disabled thread dispatching is the total time of
+ * disabled thread dispatching divided by the thread dispatch disabled
+ * count.
+ *
+ * This value may overflow.
+ */
+ uint64_t total_thread_dispatch_disabled_time;
+
+ /**
+ * @brief Count of times when the interrupt nest level changes from zero to
+ * one.
+ *
+ * This value may overflow.
+ */
+ uint64_t interrupt_count;
+
+ /**
+ * @brief Total time of interrupt processing in CPU counter ticks.
+ *
+ * The average time of interrupt processing is the total time of interrupt
+ * processing divided by the interrupt count.
+ *
+ * This value may overflow.
+ */
+ uint64_t total_interrupt_time;
+#endif /* defined( RTEMS_PROFILING ) */
+} Per_CPU_Stats;
+
+/**
+ * @brief Per-CPU watchdog header index.
+ */
+typedef enum {
+ /**
+ * @brief Index for monotonic clock per-CPU watchdog header.
+ *
+ * The reference time point for the monotonic clock is the system start. The
+ * clock resolution is one system clock tick. It is used for the system
+ * clock tick based time services and the POSIX services using
+ * CLOCK_MONOTONIC.
+ */
+ PER_CPU_WATCHDOG_MONOTONIC,
+
+ /**
+ * @brief Index for realtime clock per-CPU watchdog header.
+ *
+ * The reference time point for the realtime clock is the POSIX Epoch. The
+ * clock resolution is one nanosecond. It is used for the time of day
+ * services and the POSIX services using CLOCK_REALTIME.
+ */
+ PER_CPU_WATCHDOG_REALTIME,
+
+ /**
+ * @brief Count of per-CPU watchdog headers.
+ */
+ PER_CPU_WATCHDOG_COUNT
+} Per_CPU_Watchdog_index;
+
+/**
+ * @brief Per CPU Core Structure
+ *
+ * This structure is used to hold per core state information.
+ */
+typedef struct Per_CPU_Control {
+ #if CPU_PER_CPU_CONTROL_SIZE > 0
+ /**
+ * @brief CPU port specific control.
+ */
+ CPU_Per_CPU_control cpu_per_cpu;
+ #endif
+
+ #if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) || \
+ (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
+ /**
+ * This contains a pointer to the lower range of the interrupt stack for
+ * this CPU. This is the address allocated and freed.
+ */
+ void *interrupt_stack_low;
+
+ /**
+ * This contains a pointer to the interrupt stack pointer for this CPU.
+ * It will be loaded at the beginning on an ISR.
+ */
+ void *interrupt_stack_high;
+ #endif
+
+ /**
+ * This contains the current interrupt nesting level on this
+ * CPU.
+ */
+ uint32_t isr_nest_level;
+
+ /**
+ * @brief Indicetes if an ISR thread dispatch is disabled.
+ *
+ * This flag is context switched with each thread. It indicates that this
+ * thread has an interrupt stack frame on its stack. By using this flag, we
+ * can avoid nesting more interrupt dispatching attempts on a previously
+ * interrupted thread's stack.
+ */
+ uint32_t isr_dispatch_disable;
+
+ /**
+ * @brief The thread dispatch critical section nesting counter which is used
+ * to prevent context switches at inopportune moments.
+ */
+ volatile uint32_t thread_dispatch_disable_level;
+
+ /**
+ * @brief This is set to true when this processor needs to run the thread
+ * dispatcher.
+ *
+ * It is volatile since interrupts may alter this flag.
+ *
+ * This field is not protected by a lock and must be accessed only by this
+ * processor. Code (e.g. scheduler and post-switch action requests) running
+ * on another processors must use an inter-processor interrupt to set the
+ * thread dispatch necessary indicator to true.
+ *
+ * @see _Thread_Get_heir_and_make_it_executing().
+ */
+ volatile bool dispatch_necessary;
+
+ /*
+ * Ensure that the executing member is at least 4-byte aligned, see
+ * PER_CPU_OFFSET_EXECUTING. This is necessary on CPU ports with relaxed
+ * alignment restrictions, e.g. type alignment is less than the type size.
+ */
+ bool reserved_for_executing_alignment[ 3 ];
+
+ /**
+ * @brief This is the thread executing on this processor.
+ *
+ * This field is not protected by a lock. The only writer is this processor.
+ *
+ * On SMP configurations a thread may be registered as executing on more than
+ * one processor in case a thread migration is in progress. On SMP
+ * configurations use _Thread_Is_executing_on_a_processor() to figure out if
+ * a thread context is executing on a processor.
+ */
+ struct _Thread_Control *executing;
+
+ /**
+ * @brief This is the heir thread for this processor.
+ *
+ * This field is not protected by a lock. The only writer after multitasking
+ * start is the scheduler owning this processor. It is assumed that stores
+ * to pointers are atomic on all supported SMP architectures. The CPU port
+ * specific code (inter-processor interrupt handling and
+ * _CPU_SMP_Send_interrupt()) must guarantee that this processor observes the
+ * last value written.
+ *
+ * A thread can be a heir on at most one processor in the system.
+ *
+ * @see _Thread_Get_heir_and_make_it_executing().
+ */
+ struct _Thread_Control *heir;
+
+#if defined(RTEMS_SMP)
+ CPU_Interrupt_frame Interrupt_frame;
+#endif
+
+ /**
+ * @brief The CPU usage timestamp contains the time point of the last heir
+ * thread change or last CPU usage update of the executing thread of this
+ * processor.
+ *
+ * Protected by the scheduler lock.
+ *
+ * @see _Scheduler_Update_heir(), _Thread_Dispatch_update_heir() and
+ * _Thread_Get_CPU_time_used().
+ */
+ Timestamp_Control cpu_usage_timestamp;
+
+ /**
+ * @brief Watchdog state for this processor.
+ */
+ struct {
+ /**
+ * @brief Protects all watchdog operations on this processor.
+ */
+ ISR_LOCK_MEMBER( Lock )
+
+ /**
+ * @brief Watchdog ticks on this processor used for monotonic clock
+ * watchdogs.
+ */
+ uint64_t ticks;
+
+ /**
+ * @brief Header for watchdogs.
+ *
+ * @see Per_CPU_Watchdog_index.
+ */
+ Watchdog_Header Header[ PER_CPU_WATCHDOG_COUNT ];
+ } Watchdog;
+
+ #if defined( RTEMS_SMP )
+ /**
+ * @brief This lock protects some parts of the low-level thread dispatching.
+ *
+ * We must use a ticket lock here since we cannot transport a local context
+ * through the context switch.
+ *
+ * @see _Thread_Dispatch().
+ */
+ SMP_ticket_lock_Control Lock;
+
+ #if defined( RTEMS_PROFILING )
+ /**
+ * @brief Lock statistics for the per-CPU lock.
+ */
+ SMP_lock_Stats Lock_stats;
+
+ /**
+ * @brief Lock statistics context for the per-CPU lock.
+ */
+ SMP_lock_Stats_context Lock_stats_context;
+ #endif
+
+ /**
+ * @brief Chain of threads in need for help.
+ *
+ * This field is protected by the Per_CPU_Control::Lock lock.
+ */
+ Chain_Control Threads_in_need_for_help;
+
+ /**
+ * @brief Bit field for SMP messages.
+ *
+ * This bit field is not protected locks. Atomic operations are used to
+ * set and get the message bits.
+ */
+ Atomic_Ulong message;
+
+ struct {
+ /**
+ * @brief The scheduler control of the scheduler owning this processor.
+ *
+ * This pointer is NULL in case this processor is currently not used by a
+ * scheduler instance.
+ */
+ const struct _Scheduler_Control *control;
+
+ /**
+ * @brief The scheduler context of the scheduler owning this processor.
+ *
+ * This pointer is NULL in case this processor is currently not used by a
+ * scheduler instance.
+ */
+ const struct Scheduler_Context *context;
+
+ /**
+ * @brief The idle thread for this processor in case it is online and
+ * currently not used by a scheduler instance.
+ */
+ struct _Thread_Control *idle_if_online_and_unused;
+ } Scheduler;
+
+ /**
+ * @brief Indicates the current state of the CPU.
+ *
+ * This field is protected by the _Per_CPU_State_lock lock.
+ *
+ * @see _Per_CPU_State_change().
+ */
+ Per_CPU_State state;
+
+ /**
+ * @brief Action to be executed by this processor in the
+ * SYSTEM_STATE_BEFORE_MULTITASKING state on behalf of the boot processor.
+ *
+ * @see _SMP_Before_multitasking_action().
+ */
+ Atomic_Uintptr before_multitasking_action;
+
+ /**
+ * @brief Indicates if the processor has been successfully started via
+ * _CPU_SMP_Start_processor().
+ */
+ bool online;
+
+ /**
+ * @brief Indicates if the processor is the one that performed the initial
+ * system initialization.
+ */
+ bool boot;
+ #endif
+
+ Per_CPU_Stats Stats;
+} Per_CPU_Control;
+
+#if defined( RTEMS_SMP )
+typedef struct {
+ Per_CPU_Control per_cpu;
+ char unused_space_for_cache_line_alignment
+ [ PER_CPU_CONTROL_SIZE - sizeof( Per_CPU_Control ) ];
+} Per_CPU_Control_envelope;
+#else
+typedef struct {
+ Per_CPU_Control per_cpu;
+} Per_CPU_Control_envelope;
+#endif
+
+/**
+ * @brief Set of Per CPU Core Information
+ *
+ * This is an array of per CPU core information.
+ */
+extern Per_CPU_Control_envelope _Per_CPU_Information[] CPU_STRUCTURE_ALIGNMENT;
+
+#if defined( RTEMS_SMP )
+#define _Per_CPU_Acquire( cpu ) \
+ _SMP_ticket_lock_Acquire( \
+ &( cpu )->Lock, \
+ &( cpu )->Lock_stats, \
+ &( cpu )->Lock_stats_context \
+ )
+#else
+#define _Per_CPU_Acquire( cpu ) \
+ do { \
+ (void) ( cpu ); \
+ } while ( 0 )
+#endif
+
+#if defined( RTEMS_SMP )
+#define _Per_CPU_Release( cpu ) \
+ _SMP_ticket_lock_Release( \
+ &( cpu )->Lock, \
+ &( cpu )->Lock_stats_context \
+ )
+#else
+#define _Per_CPU_Release( cpu ) \
+ do { \
+ (void) ( cpu ); \
+ } while ( 0 )
+#endif
+
+#if defined( RTEMS_SMP )
+#define _Per_CPU_ISR_disable_and_acquire( cpu, isr_cookie ) \
+ do { \
+ _ISR_Local_disable( isr_cookie ); \
+ _Per_CPU_Acquire( cpu ); \
+ } while ( 0 )
+#else
+#define _Per_CPU_ISR_disable_and_acquire( cpu, isr_cookie ) \
+ do { \
+ _ISR_Local_disable( isr_cookie ); \
+ (void) ( cpu ); \
+ } while ( 0 )
+#endif
+
+#if defined( RTEMS_SMP )
+#define _Per_CPU_Release_and_ISR_enable( cpu, isr_cookie ) \
+ do { \
+ _Per_CPU_Release( cpu ); \
+ _ISR_Local_enable( isr_cookie ); \
+ } while ( 0 )
+#else
+#define _Per_CPU_Release_and_ISR_enable( cpu, isr_cookie ) \
+ do { \
+ (void) ( cpu ); \
+ _ISR_Local_enable( isr_cookie ); \
+ } while ( 0 )
+#endif
+
+#if defined( RTEMS_SMP )
+#define _Per_CPU_Acquire_all( isr_cookie ) \
+ do { \
+ uint32_t ncpus = _SMP_Get_processor_count(); \
+ uint32_t cpu; \
+ _ISR_Local_disable( isr_cookie ); \
+ for ( cpu = 0 ; cpu < ncpus ; ++cpu ) { \
+ _Per_CPU_Acquire( _Per_CPU_Get_by_index( cpu ) ); \
+ } \
+ } while ( 0 )
+#else
+#define _Per_CPU_Acquire_all( isr_cookie ) \
+ _ISR_Local_disable( isr_cookie )
+#endif
+
+#if defined( RTEMS_SMP )
+#define _Per_CPU_Release_all( isr_cookie ) \
+ do { \
+ uint32_t ncpus = _SMP_Get_processor_count(); \
+ uint32_t cpu; \
+ for ( cpu = 0 ; cpu < ncpus ; ++cpu ) { \
+ _Per_CPU_Release( _Per_CPU_Get_by_index( cpu ) ); \
+ } \
+ _ISR_Local_enable( isr_cookie ); \
+ } while ( 0 )
+#else
+#define _Per_CPU_Release_all( isr_cookie ) \
+ _ISR_Local_enable( isr_cookie )
+#endif
+
+/*
+ * If we get the current processor index in a context which allows thread
+ * dispatching, then we may already run on another processor right after the
+ * read instruction. There are very few cases in which this makes sense (here
+ * we can use _Per_CPU_Get_snapshot()). All other places must use
+ * _Per_CPU_Get() so that we can add checks for RTEMS_DEBUG.
+ */
+#if defined( _CPU_Get_current_per_CPU_control )
+ #define _Per_CPU_Get_snapshot() _CPU_Get_current_per_CPU_control()
+#else
+ #define _Per_CPU_Get_snapshot() \
+ ( &_Per_CPU_Information[ _SMP_Get_current_processor() ].per_cpu )
+#endif
+
+#if defined( RTEMS_SMP )
+static inline Per_CPU_Control *_Per_CPU_Get( void )
+{
+ Per_CPU_Control *cpu_self = _Per_CPU_Get_snapshot();
+
+ _Assert(
+ cpu_self->thread_dispatch_disable_level != 0 || _ISR_Get_level() != 0
+ );
+
+ return cpu_self;
+}
+#else
+#define _Per_CPU_Get() _Per_CPU_Get_snapshot()
+#endif
+
+static inline Per_CPU_Control *_Per_CPU_Get_by_index( uint32_t index )
+{
+ return &_Per_CPU_Information[ index ].per_cpu;
+}
+
+static inline uint32_t _Per_CPU_Get_index( const Per_CPU_Control *cpu )
+{
+ const Per_CPU_Control_envelope *per_cpu_envelope =
+ ( const Per_CPU_Control_envelope * ) cpu;
+
+ return ( uint32_t ) ( per_cpu_envelope - &_Per_CPU_Information[ 0 ] );
+}
+
+static inline struct _Thread_Control *_Per_CPU_Get_executing(
+ const Per_CPU_Control *cpu
+)
+{
+ return cpu->executing;
+}
+
+static inline bool _Per_CPU_Is_processor_online(
+ const Per_CPU_Control *cpu
+)
+{
+#if defined( RTEMS_SMP )
+ return cpu->online;
+#else
+ (void) cpu;
+
+ return true;
+#endif
+}
+
+static inline bool _Per_CPU_Is_boot_processor(
+ const Per_CPU_Control *cpu
+)
+{
+#if defined( RTEMS_SMP )
+ return cpu->boot;
+#else
+ (void) cpu;
+
+ return true;
+#endif
+}
+
+#if defined( RTEMS_SMP )
+
+/**
+ * @brief Allocate and Initialize Per CPU Structures
+ *
+ * This method allocates and initialize the per CPU structure.
+ */
+void _Per_CPU_Initialize(void);
+
+void _Per_CPU_State_change(
+ Per_CPU_Control *cpu,
+ Per_CPU_State new_state
+);
+
+/**
+ * @brief Waits for a processor to change into a non-initial state.
+ *
+ * This function should be called only in _CPU_SMP_Start_processor() if
+ * required by the CPU port or BSP.
+ *
+ * @code
+ * bool _CPU_SMP_Start_processor(uint32_t cpu_index)
+ * {
+ * uint32_t timeout = 123456;
+ *
+ * start_the_processor(cpu_index);
+ *
+ * return _Per_CPU_State_wait_for_non_initial_state(cpu_index, timeout);
+ * }
+ * @endcode
+ *
+ * @param[in] cpu_index The processor index.
+ * @param[in] timeout_in_ns The timeout in nanoseconds. Use a value of zero to
+ * wait forever if necessary.
+ *
+ * @retval true The processor is in a non-initial state.
+ * @retval false The timeout expired before the processor reached a non-initial
+ * state.
+ */
+bool _Per_CPU_State_wait_for_non_initial_state(
+ uint32_t cpu_index,
+ uint32_t timeout_in_ns
+);
+
+#endif /* defined( RTEMS_SMP ) */
+
+/*
+ * On a non SMP system, the _SMP_Get_current_processor() is defined to 0.
+ * Thus when built for non-SMP, there should be no performance penalty.
+ */
+#define _Thread_Dispatch_disable_level \
+ _Per_CPU_Get()->thread_dispatch_disable_level
+#define _Thread_Heir \
+ _Per_CPU_Get()->heir
+
+#if defined(_CPU_Get_thread_executing)
+#define _Thread_Executing \
+ _CPU_Get_thread_executing()
+#else
+#define _Thread_Executing \
+ _Per_CPU_Get_executing( _Per_CPU_Get() )
+#endif
+
+#define _ISR_Nest_level \
+ _Per_CPU_Get()->isr_nest_level
+#define _CPU_Interrupt_stack_low \
+ _Per_CPU_Get()->interrupt_stack_low
+#define _CPU_Interrupt_stack_high \
+ _Per_CPU_Get()->interrupt_stack_high
+#define _Thread_Dispatch_necessary \
+ _Per_CPU_Get()->dispatch_necessary
+
+/**
+ * @brief Returns the thread control block of the executing thread.
+ *
+ * This function can be called in any thread context. On SMP configurations,
+ * interrupts are disabled to ensure that the processor index is used
+ * consistently if no CPU port specific method is available to get the
+ * executing thread.
+ *
+ * @return The thread control block of the executing thread.
+ */
+RTEMS_INLINE_ROUTINE struct _Thread_Control *_Thread_Get_executing( void )
+{
+ struct _Thread_Control *executing;
+
+ #if defined(RTEMS_SMP) && !defined(_CPU_Get_thread_executing)
+ ISR_Level level;
+
+ _ISR_Local_disable( level );
+ #endif
+
+ executing = _Thread_Executing;
+
+ #if defined(RTEMS_SMP) && !defined(_CPU_Get_thread_executing)
+ _ISR_Local_enable( level );
+ #endif
+
+ return executing;
+}
+
+/**@}*/
+
+#endif /* !defined( ASM ) */
+
+#if defined( ASM ) || defined( _RTEMS_PERCPU_DEFINE_OFFSETS )
+
+#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE) || \
+ (CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE)
+ /*
+ * If this CPU target lets RTEMS allocates the interrupt stack, then
+ * we need to have places in the per CPU table to hold them.
+ */
+ #define PER_CPU_INTERRUPT_STACK_LOW \
+ CPU_PER_CPU_CONTROL_SIZE
+ #define PER_CPU_INTERRUPT_STACK_HIGH \
+ PER_CPU_INTERRUPT_STACK_LOW + CPU_SIZEOF_POINTER
+ #define PER_CPU_END_STACK \
+ PER_CPU_INTERRUPT_STACK_HIGH + CPU_SIZEOF_POINTER
+
+ #define INTERRUPT_STACK_LOW \
+ (SYM(_Per_CPU_Information) + PER_CPU_INTERRUPT_STACK_LOW)
+ #define INTERRUPT_STACK_HIGH \
+ (SYM(_Per_CPU_Information) + PER_CPU_INTERRUPT_STACK_HIGH)
+#else
+ #define PER_CPU_END_STACK \
+ CPU_PER_CPU_CONTROL_SIZE
+#endif
+
+/*
+ * These are the offsets of the required elements in the per CPU table.
+ */
+#define PER_CPU_ISR_NEST_LEVEL \
+ PER_CPU_END_STACK
+#define PER_CPU_ISR_DISPATCH_DISABLE \
+ PER_CPU_ISR_NEST_LEVEL + 4
+#define PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL \
+ PER_CPU_ISR_DISPATCH_DISABLE + 4
+#define PER_CPU_DISPATCH_NEEDED \
+ PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL + 4
+#define PER_CPU_OFFSET_EXECUTING \
+ PER_CPU_DISPATCH_NEEDED + 4
+#define PER_CPU_OFFSET_HEIR \
+ PER_CPU_OFFSET_EXECUTING + CPU_SIZEOF_POINTER
+#if defined(RTEMS_SMP)
+#define PER_CPU_INTERRUPT_FRAME_AREA \
+ PER_CPU_OFFSET_HEIR + CPU_SIZEOF_POINTER
+#endif
+
+#define THREAD_DISPATCH_DISABLE_LEVEL \
+ (SYM(_Per_CPU_Information) + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL)
+#define ISR_NEST_LEVEL \
+ (SYM(_Per_CPU_Information) + PER_CPU_ISR_NEST_LEVEL)
+#define DISPATCH_NEEDED \
+ (SYM(_Per_CPU_Information) + PER_CPU_DISPATCH_NEEDED)
+
+#endif /* defined( ASM ) || defined( _RTEMS_PERCPU_DEFINE_OFFSETS ) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/priority.h b/cpukit/include/rtems/score/priority.h
new file mode 100644
index 0000000000..7a8ddba763
--- /dev/null
+++ b/cpukit/include/rtems/score/priority.h
@@ -0,0 +1,203 @@
+/**
+ * @file
+ *
+ * @brief Priority Handler API
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Copyright (c) 2016, 2017 embedded brains GmbH.
+ *
+ * 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_PRIORITY_H
+#define _RTEMS_SCORE_PRIORITY_H
+
+#include <rtems/score/chain.h>
+#include <rtems/score/cpu.h>
+#include <rtems/score/rbtree.h>
+
+struct _Scheduler_Control;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScorePriority Priority Handler
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality which is used to manage thread
+ * priorities. The actual priority of a thread is an aggregation of priority
+ * nodes. The thread priority aggregation for the home scheduler instance of a
+ * thread consists of at least one priority node, which is normally the real
+ * priority of the thread. The locking protocols (e.g. priority ceiling and
+ * priority inheritance), rate-monotonic period objects and the POSIX sporadic
+ * server add, change and remove priority nodes.
+ *
+ * @{
+ */
+
+/**
+ * @brief The thread priority control.
+ *
+ * Lower values represent higher priorities. So, a priority value of zero
+ * represents the highest priority thread. This value is reserved for internal
+ * threads and the priority ceiling protocol.
+ *
+ * The format of the thread priority control depends on the context. A thread
+ * priority control may contain a user visible priority for API import/export.
+ * It may also contain a scheduler internal priority value. Values are
+ * translated via the scheduler map/unmap priority operations. The format of
+ * scheduler interal values depend on the particular scheduler implementation.
+ * It may for example encode a deadline in case of the EDF scheduler.
+ *
+ * The thread priority control value contained in the scheduler node
+ * (Scheduler_Node::Priority::value) uses the least-significant bit to indicate
+ * if the thread should be appended or prepended to its priority group, see
+ * SCHEDULER_PRIORITY_APPEND().
+ */
+typedef uint64_t Priority_Control;
+
+/**
+ * @brief The highest (most important) thread priority value.
+ */
+#define PRIORITY_MINIMUM 0
+
+/**
+ * @brief The priority value of pseudo-ISR threads.
+ *
+ * Examples are the MPCI and timer server threads.
+ */
+#define PRIORITY_PSEUDO_ISR PRIORITY_MINIMUM
+
+/**
+ * @brief The default lowest (least important) thread priority value.
+ *
+ * This value is CPU port dependent.
+ */
+#if defined (CPU_PRIORITY_MAXIMUM)
+ #define PRIORITY_DEFAULT_MAXIMUM CPU_PRIORITY_MAXIMUM
+#else
+ #define PRIORITY_DEFAULT_MAXIMUM 255
+#endif
+
+/**
+ * @brief The priority node to build up a priority aggregation.
+ */
+typedef struct {
+ /**
+ * @brief Node component for a chain or red-black tree.
+ */
+ union {
+ Chain_Node Chain;
+ RBTree_Node RBTree;
+ } Node;
+
+ /**
+ * @brief The priority value of this node.
+ */
+ Priority_Control priority;
+} Priority_Node;
+
+/**
+ * @brief The priority action type.
+ */
+typedef enum {
+ PRIORITY_ACTION_ADD,
+ PRIORITY_ACTION_CHANGE,
+ PRIORITY_ACTION_REMOVE,
+ PRIORITY_ACTION_INVALID
+} Priority_Action_type;
+
+typedef struct Priority_Aggregation Priority_Aggregation;
+
+/**
+ * @brief The priority aggregation.
+ *
+ * This structure serves two purposes. Firstly, it provides a place to
+ * register priority nodes and reflects the overall priority of its
+ * contributors. Secondly, it provides an action block to signal addition,
+ * change and removal of a priority node.
+ */
+struct Priority_Aggregation {
+ /**
+ * @brief This priority node reflects the overall priority of the aggregation.
+ *
+ * The overall priority of the aggregation is the minimum priority of the
+ * priority nodes in the contributors tree.
+ *
+ * This priority node may be used to add this aggregation to another
+ * aggregation to build up a recursive priority scheme.
+ *
+ * In case priority nodes of the contributors tree are added, changed or
+ * removed the priority of this node may change. To signal such changes to a
+ * priority aggregation the action block may be used.
+ */
+ Priority_Node Node;
+
+ /**
+ * @brief A red-black tree to contain priority nodes contributing to the
+ * overall priority of this priority aggregation.
+ */
+ RBTree_Control Contributors;
+
+#if defined(RTEMS_SMP)
+ /**
+ * @brief The scheduler instance of this priority aggregation.
+ */
+ const struct _Scheduler_Control *scheduler;
+#endif
+
+ /**
+ * @brief A priority action block to manage priority node additions, changes
+ * and removals.
+ */
+ struct {
+#if defined(RTEMS_SMP)
+ /**
+ * @brief The next priority aggregation in the action list.
+ */
+ Priority_Aggregation *next;
+#endif
+
+ /**
+ * @brief The priority node of the action.
+ */
+ Priority_Node *node;
+
+ /**
+ * @brief The type of the action.
+ */
+ Priority_Action_type type;
+ } Action;
+};
+
+/**
+ * @brief A list of priority actions.
+ *
+ * Actions are only added to the list. The action lists reside on the stack
+ * and have a short life-time. They are moved, processed or destroyed as a
+ * whole.
+ */
+typedef struct {
+ /**
+ * @brief The first action of a priority action list.
+ */
+ Priority_Aggregation *actions;
+} Priority_Actions;
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/prioritybitmap.h b/cpukit/include/rtems/score/prioritybitmap.h
new file mode 100644
index 0000000000..40638dd628
--- /dev/null
+++ b/cpukit/include/rtems/score/prioritybitmap.h
@@ -0,0 +1,79 @@
+/**
+ * @file rtems/score/prioritybitmap.h
+ *
+ * @brief Manipulation Routines for the Bitmap Priority Queue Implementation
+ *
+ * This include file contains all thread priority manipulation routines for
+ * the bit map priority queue implementation.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2010.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_PRIORITYBITMAP_H
+#define _RTEMS_SCORE_PRIORITYBITMAP_H
+
+#include <rtems/score/cpu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScorePriorityBitmap Bitmap Priority Thread Routines
+ *
+ * @ingroup Score
+ */
+/**@{*/
+
+typedef uint16_t Priority_bit_map_Word;
+
+typedef struct {
+ /**
+ * @brief Each sixteen bit entry in this word is associated with one of the
+ * sixteen entries in the bit map.
+ */
+ Priority_bit_map_Word major_bit_map;
+
+ /**
+ * @brief Each bit in the bit map indicates whether or not there are threads
+ * ready at a particular priority.
+ *
+ * The mapping of individual priority levels to particular bits is processor
+ * dependent as is the value of each bit used to indicate that threads are
+ * ready at that priority.
+ */
+ Priority_bit_map_Word bit_map[ 16 ];
+} Priority_bit_map_Control;
+
+/**
+ * The following record defines the information associated with
+ * each thread to manage its interaction with the priority bit maps.
+ */
+typedef struct {
+ /** This is the address of minor bit map slot. */
+ Priority_bit_map_Word *minor;
+ /** This is the priority bit map ready mask. */
+ Priority_bit_map_Word ready_major;
+ /** This is the priority bit map ready mask. */
+ Priority_bit_map_Word ready_minor;
+ /** This is the priority bit map block mask. */
+ Priority_bit_map_Word block_major;
+ /** This is the priority bit map block mask. */
+ Priority_bit_map_Word block_minor;
+} Priority_bit_map_Information;
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/prioritybitmapimpl.h b/cpukit/include/rtems/score/prioritybitmapimpl.h
new file mode 100644
index 0000000000..82c92eb5d6
--- /dev/null
+++ b/cpukit/include/rtems/score/prioritybitmapimpl.h
@@ -0,0 +1,215 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines in the Priority Handler Bit Map Implementation
+ *
+ * This file contains the static inline implementation of all inlined
+ * routines in the Priority Handler bit map implementation
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2010.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_PRIORITYBITMAPIMPL_H
+#define _RTEMS_SCORE_PRIORITYBITMAPIMPL_H
+
+#include <rtems/score/prioritybitmap.h>
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScorePriority
+ */
+/**@{**/
+
+/**
+ * This table is used by the generic bitfield routines to perform
+ * a highly optimized bit scan without the use of special CPU
+ * instructions.
+ */
+extern const unsigned char _Bitfield_Leading_zeros[256];
+
+/**
+ * @brief Returns the bit number of the first bit set in the specified value.
+ *
+ * The correspondence between the bit number and actual bit position is CPU
+ * architecture dependent. The search for the first bit set may run from most
+ * to least significant bit or vice-versa.
+ *
+ * @param value The value to bit scan.
+ *
+ * @return The bit number of the first bit set.
+ *
+ * @see _Priority_Bits_index() and _Priority_Mask().
+ */
+RTEMS_INLINE_ROUTINE unsigned int _Bitfield_Find_first_bit(
+ unsigned int value
+)
+{
+ unsigned int bit_number;
+
+#if ( CPU_USE_GENERIC_BITFIELD_CODE == FALSE )
+ _CPU_Bitfield_Find_first_bit( value, bit_number );
+#elif defined(__GNUC__)
+ bit_number = (unsigned int) __builtin_clz( value )
+ - __SIZEOF_INT__ * __CHAR_BIT__ + 16;
+#else
+ if ( value < 0x100 ) {
+ bit_number = _Bitfield_Leading_zeros[ value ] + 8;
+ } else { \
+ bit_number = _Bitfield_Leading_zeros[ value >> 8 ];
+ }
+#endif
+
+ return bit_number;
+}
+
+/**
+ * @brief Returns the priority bit mask for the specified major or minor bit
+ * number.
+ *
+ * @param bit_number The bit number for which we need a mask.
+ *
+ * @return The priority bit mask.
+ */
+RTEMS_INLINE_ROUTINE Priority_bit_map_Word _Priority_Mask(
+ unsigned int bit_number
+)
+{
+#if ( CPU_USE_GENERIC_BITFIELD_CODE == FALSE )
+ return _CPU_Priority_Mask( bit_number );
+#else
+ return (Priority_bit_map_Word) ( 0x8000u >> bit_number );
+#endif
+}
+
+/**
+ * @brief Returns the bit index position for the specified major or minor bit
+ * number.
+ *
+ * @param bit_number The bit number for which we need an index.
+ *
+ * @return The corresponding array index into the priority bit map.
+ */
+RTEMS_INLINE_ROUTINE unsigned int _Priority_Bits_index(
+ unsigned int bit_number
+)
+{
+#if ( CPU_USE_GENERIC_BITFIELD_CODE == FALSE )
+ return _CPU_Priority_bits_index( bit_number );
+#else
+ return bit_number;
+#endif
+}
+
+/**
+ * This function returns the major portion of the_priority.
+ */
+
+RTEMS_INLINE_ROUTINE unsigned int _Priority_Major( unsigned int the_priority )
+{
+ return the_priority / 16;
+}
+
+/**
+ * This function returns the minor portion of the_priority.
+ */
+
+RTEMS_INLINE_ROUTINE unsigned int _Priority_Minor( unsigned int the_priority )
+{
+ return the_priority % 16;
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_bit_map_Initialize(
+ Priority_bit_map_Control *bit_map
+)
+{
+ memset( bit_map, 0, sizeof( *bit_map ) );
+}
+
+/**
+ * Priority Queue implemented by bit map
+ */
+
+RTEMS_INLINE_ROUTINE void _Priority_bit_map_Add (
+ Priority_bit_map_Control *bit_map,
+ Priority_bit_map_Information *bit_map_info
+)
+{
+ *bit_map_info->minor |= bit_map_info->ready_minor;
+ bit_map->major_bit_map |= bit_map_info->ready_major;
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_bit_map_Remove (
+ Priority_bit_map_Control *bit_map,
+ Priority_bit_map_Information *bit_map_info
+)
+{
+ *bit_map_info->minor &= bit_map_info->block_minor;
+ if ( *bit_map_info->minor == 0 )
+ bit_map->major_bit_map &= bit_map_info->block_major;
+}
+
+RTEMS_INLINE_ROUTINE unsigned int _Priority_bit_map_Get_highest(
+ const Priority_bit_map_Control *bit_map
+)
+{
+ unsigned int minor;
+ unsigned int major;
+
+ major = _Bitfield_Find_first_bit( bit_map->major_bit_map );
+ minor = _Bitfield_Find_first_bit( bit_map->bit_map[ major ] );
+
+ return (_Priority_Bits_index( major ) << 4) +
+ _Priority_Bits_index( minor );
+}
+
+RTEMS_INLINE_ROUTINE bool _Priority_bit_map_Is_empty(
+ const Priority_bit_map_Control *bit_map
+)
+{
+ return bit_map->major_bit_map == 0;
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_bit_map_Initialize_information(
+ Priority_bit_map_Control *bit_map,
+ Priority_bit_map_Information *bit_map_info,
+ unsigned int new_priority
+)
+{
+ unsigned int major;
+ unsigned int minor;
+ Priority_bit_map_Word mask;
+
+ major = _Priority_Major( new_priority );
+ minor = _Priority_Minor( new_priority );
+
+ bit_map_info->minor = &bit_map->bit_map[ _Priority_Bits_index( major ) ];
+
+ mask = _Priority_Mask( major );
+ bit_map_info->ready_major = mask;
+ bit_map_info->block_major = (Priority_bit_map_Word) ~mask;
+
+ mask = _Priority_Mask( minor );
+ bit_map_info->ready_minor = mask;
+ bit_map_info->block_minor = (Priority_bit_map_Word) ~mask;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/priorityimpl.h b/cpukit/include/rtems/score/priorityimpl.h
new file mode 100644
index 0000000000..3380983cb7
--- /dev/null
+++ b/cpukit/include/rtems/score/priorityimpl.h
@@ -0,0 +1,435 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_PRIORITYIMPL_H
+#define _RTEMS_SCORE_PRIORITYIMPL_H
+
+#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+RTEMS_INLINE_ROUTINE void _Priority_Actions_initialize_empty(
+ Priority_Actions *actions
+)
+{
+ actions->actions = NULL;
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Actions_initialize_one(
+ Priority_Actions *actions,
+ Priority_Aggregation *aggregation,
+ Priority_Node *node,
+ Priority_Action_type type
+)
+{
+#if defined(RTEMS_SMP)
+ aggregation->Action.next = NULL;
+#endif
+ aggregation->Action.node = node;
+ aggregation->Action.type = type;
+
+ actions->actions = aggregation;
+}
+
+RTEMS_INLINE_ROUTINE bool _Priority_Actions_is_empty(
+ const Priority_Actions *actions
+)
+{
+ return actions->actions == NULL;
+}
+
+RTEMS_INLINE_ROUTINE bool _Priority_Actions_is_valid(
+ const Priority_Aggregation *aggregation
+)
+{
+#if defined(RTEMS_SMP)
+ return aggregation != NULL;
+#else
+ (void) aggregation;
+ return false;
+#endif
+}
+
+RTEMS_INLINE_ROUTINE Priority_Aggregation *_Priority_Actions_move(
+ Priority_Actions *actions
+)
+{
+ Priority_Aggregation *aggregation;
+
+ aggregation = actions->actions;
+ actions->actions = NULL;
+
+ return aggregation;
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Actions_add(
+ Priority_Actions *actions,
+ Priority_Aggregation *aggregation
+)
+{
+#if defined(RTEMS_SMP)
+ /*
+ * Priority aggregations are only added to action lists, so do not care about
+ * the current next pointer value.
+ */
+ aggregation->Action.next = actions->actions;
+#endif
+ actions->actions = aggregation;
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Node_initialize(
+ Priority_Node *node,
+ Priority_Control priority
+)
+{
+ node->priority = priority;
+ _RBTree_Initialize_node( &node->Node.RBTree );
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Node_set_priority(
+ Priority_Node *node,
+ Priority_Control priority
+)
+{
+ node->priority = priority;
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Node_set_inactive(
+ Priority_Node *node
+)
+{
+ _RBTree_Set_off_tree( &node->Node.RBTree );
+}
+
+RTEMS_INLINE_ROUTINE bool _Priority_Node_is_active(
+ const Priority_Node *node
+)
+{
+ return !_RBTree_Is_node_off_tree( &node->Node.RBTree );
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Initialize_empty(
+ Priority_Aggregation *aggregation
+)
+{
+#if defined(RTEMS_DEBUG)
+#if defined(RTEMS_SMP)
+ aggregation->Action.next = NULL;
+#endif
+ aggregation->Action.node = NULL;
+ aggregation->Action.type = PRIORITY_ACTION_INVALID;
+#endif
+ _RBTree_Initialize_node( &aggregation->Node.Node.RBTree );
+ _RBTree_Initialize_empty( &aggregation->Contributors );
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Initialize_one(
+ Priority_Aggregation *aggregation,
+ Priority_Node *node
+)
+{
+#if defined(RTEMS_DEBUG)
+#if defined(RTEMS_SMP)
+ aggregation->Action.next = NULL;
+#endif
+ aggregation->Action.node = NULL;
+ aggregation->Action.type = PRIORITY_ACTION_INVALID;
+#endif
+ _Priority_Node_initialize( &aggregation->Node, node->priority );
+ _RBTree_Initialize_one( &aggregation->Contributors, &node->Node.RBTree );
+}
+
+RTEMS_INLINE_ROUTINE bool _Priority_Is_empty(
+ const Priority_Aggregation *aggregation
+)
+{
+ return _RBTree_Is_empty( &aggregation->Contributors );
+}
+
+RTEMS_INLINE_ROUTINE Priority_Control _Priority_Get_priority(
+ const Priority_Aggregation *aggregation
+)
+{
+ return aggregation->Node.priority;
+}
+
+RTEMS_INLINE_ROUTINE const Scheduler_Control *_Priority_Get_scheduler(
+ const Priority_Aggregation *aggregation
+)
+{
+#if defined(RTEMS_SMP)
+ return aggregation->scheduler;
+#else
+ return &_Scheduler_Table[ 0 ];
+#endif
+}
+
+RTEMS_INLINE_ROUTINE Priority_Node *_Priority_Get_minimum_node(
+ const Priority_Aggregation *aggregation
+)
+{
+ return (Priority_Node *) _RBTree_Minimum( &aggregation->Contributors );
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Set_action_node(
+ Priority_Aggregation *aggregation,
+ Priority_Node *node
+)
+{
+ aggregation->Action.node = node;
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Set_action_type(
+ Priority_Aggregation *aggregation,
+ Priority_Action_type type
+)
+{
+ aggregation->Action.type = type;
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Set_action(
+ Priority_Aggregation *aggregation,
+ Priority_Node *node,
+ Priority_Action_type type
+)
+{
+ aggregation->Action.node = node;
+ aggregation->Action.type = type;
+}
+
+RTEMS_INLINE_ROUTINE Priority_Aggregation *_Priority_Get_next_action(
+ const Priority_Aggregation *aggregation
+)
+{
+#if defined(RTEMS_SMP)
+ return aggregation->Action.next;
+#else
+ (void) aggregation;
+ return NULL;
+#endif
+}
+
+RTEMS_INLINE_ROUTINE bool _Priority_Less(
+ const void *left,
+ const RBTree_Node *right
+)
+{
+ const Priority_Control *the_left;
+ const Priority_Node *the_right;
+
+ the_left = left;
+ the_right = RTEMS_CONTAINER_OF( right, Priority_Node, Node.RBTree );
+
+ return *the_left < the_right->priority;
+}
+
+RTEMS_INLINE_ROUTINE bool _Priority_Plain_insert(
+ Priority_Aggregation *aggregation,
+ Priority_Node *node,
+ Priority_Control priority
+)
+{
+ return _RBTree_Insert_inline(
+ &aggregation->Contributors,
+ &node->Node.RBTree,
+ &priority,
+ _Priority_Less
+ );
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Plain_extract(
+ Priority_Aggregation *aggregation,
+ Priority_Node *node
+)
+{
+ _RBTree_Extract( &aggregation->Contributors, &node->Node.RBTree );
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Plain_changed(
+ Priority_Aggregation *aggregation,
+ Priority_Node *node
+)
+{
+ _Priority_Plain_extract( aggregation, node );
+ _Priority_Plain_insert( aggregation, node, node->priority );
+}
+
+typedef void ( *Priority_Add_handler )(
+ Priority_Aggregation *aggregation,
+ Priority_Actions *actions,
+ void *arg
+);
+
+typedef void ( *Priority_Change_handler )(
+ Priority_Aggregation *aggregation,
+ bool prepend_it,
+ Priority_Actions *actions,
+ void *arg
+);
+
+typedef void ( *Priority_Remove_handler )(
+ Priority_Aggregation *aggregation,
+ Priority_Actions *actions,
+ void *arg
+);
+
+RTEMS_INLINE_ROUTINE void _Priority_Change_nothing(
+ Priority_Aggregation *aggregation,
+ bool prepend_it,
+ Priority_Actions *actions,
+ void *arg
+)
+{
+ (void) aggregation;
+ (void) prepend_it;
+ (void) actions;
+ (void) arg;
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Remove_nothing(
+ Priority_Aggregation *aggregation,
+ Priority_Actions *actions,
+ void *arg
+)
+{
+ (void) aggregation;
+ (void) actions;
+ (void) arg;
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Non_empty_insert(
+ Priority_Aggregation *aggregation,
+ Priority_Node *node,
+ Priority_Actions *actions,
+ Priority_Change_handler change,
+ void *arg
+)
+{
+ bool is_new_minimum;
+
+ _Assert( !_Priority_Is_empty( aggregation ) );
+ is_new_minimum = _Priority_Plain_insert( aggregation, node, node->priority );
+
+ if ( is_new_minimum ) {
+ aggregation->Node.priority = node->priority;
+ ( *change )( aggregation, false, actions, arg );
+ }
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Insert(
+ Priority_Aggregation *aggregation,
+ Priority_Node *node,
+ Priority_Actions *actions,
+ Priority_Add_handler add,
+ Priority_Change_handler change,
+ void *arg
+)
+{
+ if ( _Priority_Is_empty( aggregation ) ) {
+ _Priority_Initialize_one( aggregation, node );
+ ( *add )( aggregation, actions, arg );
+ } else {
+ _Priority_Non_empty_insert( aggregation, node, actions, change, arg );
+ }
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Extract(
+ Priority_Aggregation *aggregation,
+ Priority_Node *node,
+ Priority_Actions *actions,
+ Priority_Remove_handler remove,
+ Priority_Change_handler change,
+ void *arg
+)
+{
+ _Priority_Plain_extract( aggregation, node );
+
+ if ( _Priority_Is_empty( aggregation ) ) {
+ ( *remove )( aggregation, actions, arg );
+ } else {
+ Priority_Node *min;
+
+ min = _Priority_Get_minimum_node( aggregation );
+
+ if ( node->priority < min->priority ) {
+ aggregation->Node.priority = min->priority;
+ ( *change )( aggregation, true, actions, arg );
+ }
+ }
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Extract_non_empty(
+ Priority_Aggregation *aggregation,
+ Priority_Node *node,
+ Priority_Actions *actions,
+ Priority_Change_handler change,
+ void *arg
+)
+{
+ Priority_Node *min;
+
+ _Priority_Plain_extract( aggregation, node );
+ _Assert( !_Priority_Is_empty( aggregation ) );
+
+ min = _Priority_Get_minimum_node( aggregation );
+
+ if ( node->priority < min->priority ) {
+ aggregation->Node.priority = min->priority;
+ ( *change )( aggregation, true, actions, arg );
+ }
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Changed(
+ Priority_Aggregation *aggregation,
+ Priority_Node *node,
+ bool prepend_it,
+ Priority_Actions *actions,
+ Priority_Change_handler change,
+ void *arg
+)
+{
+ Priority_Node *min;
+
+ _Priority_Plain_changed( aggregation, node );
+
+ min = _Priority_Get_minimum_node( aggregation );
+
+ if ( min->priority != aggregation->Node.priority ) {
+ aggregation->Node.priority = min->priority;
+ ( *change )( aggregation, prepend_it, actions, arg );
+ }
+}
+
+RTEMS_INLINE_ROUTINE void _Priority_Replace(
+ Priority_Aggregation *aggregation,
+ Priority_Node *victim,
+ Priority_Node *replacement
+)
+{
+ replacement->priority = victim->priority;
+ _RBTree_Replace_node(
+ &aggregation->Contributors,
+ &victim->Node.RBTree,
+ &replacement->Node.RBTree
+ );
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_PRIORITYIMPL_H */
diff --git a/cpukit/include/rtems/score/processormask.h b/cpukit/include/rtems/score/processormask.h
new file mode 100644
index 0000000000..a06aa2a56b
--- /dev/null
+++ b/cpukit/include/rtems/score/processormask.h
@@ -0,0 +1,290 @@
+/**
+ * @file
+ *
+ * @brief Processor Mask API
+ *
+ * @ingroup ScoreProcessorMask
+ */
+
+/*
+ * Copyright (c) 2016, 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_PROCESSORMASK_H
+#define _RTEMS_SCORE_PROCESSORMASK_H
+
+#include <rtems/score/cpu.h>
+
+#include <sys/cpuset.h>
+
+#include <strings.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ScoreProcessorMask Processor Mask
+ *
+ * @ingroup Score
+ *
+ * The processor mask provides a bit map large enough to provide one bit for
+ * each processor in the system. It is a fixed size internal data type
+ * provided for efficiency in addition to the API level cpu_set_t.
+ *
+ * @{
+ */
+
+/**
+ * @brief A bit map which is large enough to provide one bit for each processor
+ * in the system.
+ */
+typedef BITSET_DEFINE( Processor_mask, CPU_MAXIMUM_PROCESSORS ) Processor_mask;
+
+RTEMS_INLINE_ROUTINE void _Processor_mask_Zero( Processor_mask *mask )
+{
+ BIT_ZERO( CPU_MAXIMUM_PROCESSORS, mask );
+}
+
+RTEMS_INLINE_ROUTINE bool _Processor_mask_Is_zero( const Processor_mask *mask )
+{
+ return BIT_EMPTY( CPU_MAXIMUM_PROCESSORS, mask );
+}
+
+RTEMS_INLINE_ROUTINE void _Processor_mask_Fill( Processor_mask *mask )
+{
+ BIT_FILL( CPU_MAXIMUM_PROCESSORS, mask );
+}
+
+RTEMS_INLINE_ROUTINE void _Processor_mask_Assign(
+ Processor_mask *dst, const Processor_mask *src
+)
+{
+ BIT_COPY( CPU_MAXIMUM_PROCESSORS, src, dst );
+}
+
+RTEMS_INLINE_ROUTINE void _Processor_mask_Set(
+ Processor_mask *mask,
+ uint32_t index
+)
+{
+ BIT_SET( CPU_MAXIMUM_PROCESSORS, index, mask );
+}
+
+RTEMS_INLINE_ROUTINE void _Processor_mask_Clear(
+ Processor_mask *mask,
+ uint32_t index
+)
+{
+ BIT_CLR( CPU_MAXIMUM_PROCESSORS, index, mask );
+}
+
+RTEMS_INLINE_ROUTINE bool _Processor_mask_Is_set(
+ const Processor_mask *mask,
+ uint32_t index
+)
+{
+ return BIT_ISSET( CPU_MAXIMUM_PROCESSORS, index, mask );
+}
+
+/**
+ * @brief Returns true if the processor sets a and b are equal, and false
+ * otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Processor_mask_Is_equal(
+ const Processor_mask *a,
+ const Processor_mask *b
+)
+{
+ return !BIT_CMP( CPU_MAXIMUM_PROCESSORS, a, b );
+}
+
+/**
+ * @brief Returns true if the intersection of the processor sets a and b is
+ * non-empty, and false otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Processor_mask_Has_overlap(
+ const Processor_mask *a,
+ const Processor_mask *b
+)
+{
+ return BIT_OVERLAP( CPU_MAXIMUM_PROCESSORS, a, b );
+}
+
+/**
+ * @brief Returns true if the processor set small is a subset of processor set
+ * big, and false otherwise.
+ */
+RTEMS_INLINE_ROUTINE 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.
+ */
+RTEMS_INLINE_ROUTINE 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.
+ */
+RTEMS_INLINE_ROUTINE void _Processor_mask_Nand(
+ Processor_mask *a,
+ const Processor_mask *b,
+ const Processor_mask *c
+)
+{
+ BIT_NAND2( CPU_MAXIMUM_PROCESSORS, a, b, c );
+}
+
+/**
+ * @brief Performs a bitwise a = b | c.
+ */
+RTEMS_INLINE_ROUTINE 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.
+ */
+RTEMS_INLINE_ROUTINE void _Processor_mask_Xor(
+ Processor_mask *a,
+ const Processor_mask *b,
+ const Processor_mask *c
+)
+{
+ BIT_XOR2( CPU_MAXIMUM_PROCESSORS, a, b, c );
+}
+
+RTEMS_INLINE_ROUTINE uint32_t _Processor_mask_Count( const Processor_mask *a )
+{
+ return (uint32_t) BIT_COUNT( CPU_MAXIMUM_PROCESSORS, a );
+}
+
+RTEMS_INLINE_ROUTINE 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.
+ */
+RTEMS_INLINE_ROUTINE uint32_t _Processor_mask_To_uint32_t(
+ const Processor_mask *mask,
+ uint32_t index
+)
+{
+ long bits = mask->__bits[ __bitset_words( index ) ];
+
+ 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.
+ */
+RTEMS_INLINE_ROUTINE 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.
+ */
+RTEMS_INLINE_ROUTINE 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;
+
+RTEMS_INLINE_ROUTINE bool _Processor_mask_Is_at_most_partial_loss(
+ Processor_mask_Copy_status status
+)
+{
+ return (unsigned int) status <= PROCESSOR_MASK_COPY_PARTIAL_LOSS;
+}
+
+Processor_mask_Copy_status _Processor_mask_Copy(
+ long *dst,
+ size_t dst_size,
+ const long *src,
+ size_t src_size
+);
+
+RTEMS_INLINE_ROUTINE 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 )
+ );
+}
+
+RTEMS_INLINE_ROUTINE 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_PROCESSORMASK_H */
diff --git a/cpukit/include/rtems/score/profiling.h b/cpukit/include/rtems/score/profiling.h
new file mode 100644
index 0000000000..6ba5d2987f
--- /dev/null
+++ b/cpukit/include/rtems/score/profiling.h
@@ -0,0 +1,140 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreProfiling
+ *
+ * @brief Profiling Support API
+ */
+
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_PROFILING
+#define _RTEMS_SCORE_PROFILING
+
+#include <rtems/score/percpu.h>
+#include <rtems/score/isrlock.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ScoreProfiling Profiling Support
+ *
+ * @brief Profiling support.
+ *
+ * @{
+ */
+
+static inline void _Profiling_Thread_dispatch_disable(
+ Per_CPU_Control *cpu,
+ uint32_t previous_thread_dispatch_disable_level
+)
+{
+#if defined( RTEMS_PROFILING )
+ if ( previous_thread_dispatch_disable_level == 0 ) {
+ Per_CPU_Stats *stats = &cpu->Stats;
+
+ stats->thread_dispatch_disabled_instant = _CPU_Counter_read();
+ ++stats->thread_dispatch_disabled_count;
+ }
+#else
+ (void) cpu;
+ (void) previous_thread_dispatch_disable_level;
+#endif
+}
+
+static inline void _Profiling_Thread_dispatch_disable_critical(
+ Per_CPU_Control *cpu,
+ uint32_t previous_thread_dispatch_disable_level,
+ const ISR_lock_Context *lock_context
+)
+{
+#if defined( RTEMS_PROFILING )
+ if ( previous_thread_dispatch_disable_level == 0 ) {
+ Per_CPU_Stats *stats = &cpu->Stats;
+
+ stats->thread_dispatch_disabled_instant = lock_context->ISR_disable_instant;
+ ++stats->thread_dispatch_disabled_count;
+ }
+#else
+ (void) cpu;
+ (void) previous_thread_dispatch_disable_level;
+ (void) lock_context;
+#endif
+}
+
+static inline void _Profiling_Thread_dispatch_enable(
+ Per_CPU_Control *cpu,
+ uint32_t new_thread_dispatch_disable_level
+)
+{
+#if defined( RTEMS_PROFILING )
+ if ( new_thread_dispatch_disable_level == 0 ) {
+ Per_CPU_Stats *stats = &cpu->Stats;
+ CPU_Counter_ticks now = _CPU_Counter_read();
+ CPU_Counter_ticks delta = _CPU_Counter_difference(
+ now,
+ stats->thread_dispatch_disabled_instant
+ );
+
+ stats->total_thread_dispatch_disabled_time += delta;
+
+ if ( stats->max_thread_dispatch_disabled_time < delta ) {
+ stats->max_thread_dispatch_disabled_time = delta;
+ }
+ }
+#else
+ (void) cpu;
+ (void) new_thread_dispatch_disable_level;
+#endif
+}
+
+static inline void _Profiling_Update_max_interrupt_delay(
+ Per_CPU_Control *cpu,
+ CPU_Counter_ticks interrupt_delay
+)
+{
+#if defined( RTEMS_PROFILING )
+ Per_CPU_Stats *stats = &cpu->Stats;
+
+ if ( stats->max_interrupt_delay < interrupt_delay ) {
+ stats->max_interrupt_delay = interrupt_delay;
+ }
+#else
+ (void) cpu;
+ (void) interrupt_delay;
+#endif
+}
+
+/**
+ * @brief Updates the interrupt profiling statistics.
+ *
+ * Must be called with the interrupt stack and before the thread dispatch
+ * disable level is decremented.
+ */
+void _Profiling_Outer_most_interrupt_entry_and_exit(
+ Per_CPU_Control *cpu,
+ CPU_Counter_ticks interrupt_entry_instant,
+ CPU_Counter_ticks interrupt_exit_instant
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_PROFILING */
diff --git a/cpukit/include/rtems/score/protectedheap.h b/cpukit/include/rtems/score/protectedheap.h
new file mode 100644
index 0000000000..a08fa36cf3
--- /dev/null
+++ b/cpukit/include/rtems/score/protectedheap.h
@@ -0,0 +1,172 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreProtHeap
+ *
+ * @brief Protected Heap Handler API
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2007.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_PROTECTED_HEAP_H
+#define _RTEMS_SCORE_PROTECTED_HEAP_H
+
+#include <rtems/score/heapimpl.h>
+#include <rtems/score/apimutex.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreProtHeap Protected Heap Handler
+ *
+ * @ingroup ScoreHeap
+ *
+ * @brief Provides protected heap services.
+ *
+ * The @ref ScoreAllocatorMutex is used to protect the heap accesses.
+ *
+ */
+/**@{**/
+
+/**
+ * @brief See _Heap_Initialize().
+ */
+RTEMS_INLINE_ROUTINE uintptr_t _Protected_heap_Initialize(
+ Heap_Control *heap,
+ void *area_begin,
+ uintptr_t area_size,
+ uintptr_t page_size
+)
+{
+ return _Heap_Initialize( heap, area_begin, area_size, page_size );
+}
+
+/**
+ * @brief See _Heap_Extend().
+ *
+ * Returns @a true in case of success, and @a false otherwise.
+ */
+bool _Protected_heap_Extend(
+ Heap_Control *heap,
+ void *area_begin,
+ uintptr_t area_size
+);
+
+/**
+ * @brief See _Heap_Allocate_aligned_with_boundary().
+ */
+void *_Protected_heap_Allocate_aligned_with_boundary(
+ Heap_Control *heap,
+ uintptr_t size,
+ uintptr_t alignment,
+ uintptr_t boundary
+);
+
+/**
+ * @brief See _Heap_Allocate_aligned_with_boundary() with boundary equals zero.
+ */
+RTEMS_INLINE_ROUTINE void *_Protected_heap_Allocate_aligned(
+ Heap_Control *heap,
+ uintptr_t size,
+ uintptr_t alignment
+)
+{
+ return
+ _Protected_heap_Allocate_aligned_with_boundary( heap, size, alignment, 0 );
+}
+
+/**
+ * @brief See _Heap_Allocate_aligned_with_boundary() with alignment and
+ * boundary equals zero.
+ */
+RTEMS_INLINE_ROUTINE void *_Protected_heap_Allocate(
+ Heap_Control *heap,
+ uintptr_t size
+)
+{
+ return _Protected_heap_Allocate_aligned_with_boundary( heap, size, 0, 0 );
+}
+
+/**
+ * @brief See _Heap_Size_of_alloc_area().
+ */
+bool _Protected_heap_Get_block_size(
+ Heap_Control *heap,
+ void *addr,
+ uintptr_t *size
+);
+
+/**
+ * @brief See _Heap_Resize_block().
+ *
+ * Returns @a true in case of success, and @a false otherwise.
+ */
+bool _Protected_heap_Resize_block(
+ Heap_Control *heap,
+ void *addr,
+ uintptr_t size
+);
+
+/**
+ * @brief See _Heap_Free().
+ *
+ * Returns @a true in case of success, and @a false otherwise.
+ */
+bool _Protected_heap_Free( Heap_Control *heap, void *addr );
+
+/**
+ * @brief See _Heap_Walk().
+ */
+bool _Protected_heap_Walk( Heap_Control *heap, int source, bool dump );
+
+/**
+ * @brief See _Heap_Iterate().
+ */
+void _Protected_heap_Iterate(
+ Heap_Control *heap,
+ Heap_Block_visitor visitor,
+ void *visitor_arg
+);
+
+/**
+ * @brief See _Heap_Get_information().
+ *
+ * Returns @a true in case of success, and @a false otherwise.
+ */
+bool _Protected_heap_Get_information(
+ Heap_Control *heap,
+ Heap_Information_block *info
+);
+
+/**
+ * @brief See _Heap_Get_free_information().
+ *
+ * Returns @a true in case of success, and @a false otherwise.
+ */
+bool _Protected_heap_Get_free_information(
+ Heap_Control *heap,
+ Heap_Information *info
+);
+
+/**
+ * @brief See _Heap_Get_size().
+ */
+uintptr_t _Protected_heap_Get_size( Heap_Control *heap );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/rbtree.h b/cpukit/include/rtems/score/rbtree.h
new file mode 100644
index 0000000000..15a3bc8913
--- /dev/null
+++ b/cpukit/include/rtems/score/rbtree.h
@@ -0,0 +1,568 @@
+/**
+ * @file rtems/score/rbtree.h
+ *
+ * @brief Constants and Structures Associated with the Red-Black Tree Handler
+ *
+ * This include file contains all the constants and structures associated
+ * with the Red-Black Tree Handler.
+ */
+
+/*
+ * Copyright (c) 2010 Gedare Bloom.
+ *
+ * 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_RBTREE_H
+#define _RTEMS_SCORE_RBTREE_H
+
+#include <sys/tree.h>
+#include <rtems/score/basedefs.h>
+#include <rtems/score/assert.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreRBTree Red-Black Tree Handler
+ *
+ * @ingroup Score
+ *
+ * The Red-Black Tree Handler is used to manage sets of entities. This handler
+ * provides two data structures. The rbtree Node data structure is included
+ * as the first part of every data structure that will be placed on
+ * a RBTree. The second data structure is rbtree Control which is used
+ * to manage a set of rbtree Nodes.
+ */
+/**@{*/
+
+struct RBTree_Control;
+
+/**
+ * @brief Red-black tree node.
+ *
+ * This is used to manage each node (element) which is placed on a red-black
+ * tree.
+ */
+typedef struct RBTree_Node {
+ RB_ENTRY(RBTree_Node) Node;
+} RBTree_Node;
+
+/**
+ * @brief Red-black tree control.
+ *
+ * This is used to manage a red-black tree. A red-black tree consists of a
+ * tree of zero or more nodes.
+ */
+typedef RB_HEAD(RBTree_Control, RBTree_Node) RBTree_Control;
+
+/**
+ * @brief Initializer for an empty red-black tree with designator @a name.
+ */
+#define RBTREE_INITIALIZER_EMPTY( name ) \
+ RB_INITIALIZER( name )
+
+/**
+ * @brief Definition for an empty red-black tree with designator @a name.
+ */
+#define RBTREE_DEFINE_EMPTY( name ) \
+ RBTree_Control name = RBTREE_INITIALIZER_EMPTY( name )
+
+/**
+ * @brief Sets a red-black tree node as off-tree.
+ *
+ * Do not use this function on nodes which are a part of a tree.
+ *
+ * @param[in] the_node The node to set off-tree.
+ *
+ * @see _RBTree_Is_node_off_tree().
+ */
+RTEMS_INLINE_ROUTINE void _RBTree_Set_off_tree( RBTree_Node *the_node )
+{
+ RB_COLOR( the_node, Node ) = -1;
+}
+
+/**
+ * @brief Returns true, if this red-black tree node is off-tree, and false
+ * otherwise.
+ *
+ * @param[in] the_node The node to test.
+ *
+ * @retval true The node is not a part of a tree (off-tree).
+ * @retval false Otherwise.
+ *
+ * @see _RBTree_Set_off_tree().
+ */
+RTEMS_INLINE_ROUTINE bool _RBTree_Is_node_off_tree(
+ const RBTree_Node *the_node
+)
+{
+ return RB_COLOR( the_node, Node ) == -1;
+}
+
+/**
+ * @brief Rebalances the red-black tree after insertion of the node.
+ *
+ * @param[in] the_rbtree The red-black tree control.
+ * @param[in] the_node The most recently inserted node.
+ */
+void _RBTree_Insert_color(
+ RBTree_Control *the_rbtree,
+ RBTree_Node *the_node
+);
+
+/**
+ * @brief Initializes a red-black tree node.
+ *
+ * In debug configurations, the node is set off tree. In all other
+ * configurations, this function does nothing.
+ *
+ * @param[in] the_node The red-black tree node to initialize.
+ */
+RTEMS_INLINE_ROUTINE void _RBTree_Initialize_node( RBTree_Node *the_node )
+{
+#if defined(RTEMS_DEBUG)
+ _RBTree_Set_off_tree( the_node );
+#else
+ (void) the_node;
+#endif
+}
+
+/**
+ * @brief Adds a child node to a parent node.
+ *
+ * @param[in] child The child node.
+ * @param[in] parent The parent node.
+ * @param[in] link The child node link of the parent node.
+ */
+RTEMS_INLINE_ROUTINE void _RBTree_Add_child(
+ RBTree_Node *child,
+ RBTree_Node *parent,
+ RBTree_Node **link
+)
+{
+ _Assert( _RBTree_Is_node_off_tree( child ) );
+ RB_SET( child, parent, Node );
+ *link = child;
+}
+
+/**
+ * @brief Inserts the node into the red-black tree using the specified parent
+ * node and link.
+ *
+ * @param[in] the_rbtree The red-black tree control.
+ * @param[in] the_node The node to insert.
+ * @param[in] parent The parent node.
+ * @param[in] link The child node link of the parent node.
+ *
+ * @code
+ * #include <rtems/score/rbtree.h>
+ *
+ * typedef struct {
+ * int value;
+ * RBTree_Node Node;
+ * } Some_Node;
+ *
+ * bool _Some_Less(
+ * const RBTree_Node *a,
+ * const RBTree_Node *b
+ * )
+ * {
+ * const Some_Node *aa = RTEMS_CONTAINER_OF( a, Some_Node, Node );
+ * const Some_Node *bb = RTEMS_CONTAINER_OF( b, Some_Node, Node );
+ *
+ * return aa->value < bb->value;
+ * }
+ *
+ * void _Some_Insert(
+ * RBTree_Control *the_rbtree,
+ * Some_Node *the_node
+ * )
+ * {
+ * RBTree_Node **link = _RBTree_Root_reference( the_rbtree );
+ * RBTree_Node *parent = NULL;
+ *
+ * while ( *link != NULL ) {
+ * parent = *link;
+ *
+ * if ( _Some_Less( &the_node->Node, parent ) ) {
+ * link = _RBTree_Left_reference( parent );
+ * } else {
+ * link = _RBTree_Right_reference( parent );
+ * }
+ * }
+ *
+ * _RBTree_Insert_with_parent( the_rbtree, &the_node->Node, parent, link );
+ * }
+ * @endcode
+ */
+RTEMS_INLINE_ROUTINE void _RBTree_Insert_with_parent(
+ RBTree_Control *the_rbtree,
+ RBTree_Node *the_node,
+ RBTree_Node *parent,
+ RBTree_Node **link
+)
+{
+ _RBTree_Add_child( the_node, parent, link );
+ _RBTree_Insert_color( the_rbtree, the_node );
+}
+
+/**
+ * @brief Extracts (removes) the node from the red-black tree.
+ *
+ * This function does not set the node off-tree. In case this is desired, then
+ * call _RBTree_Set_off_tree() after the extraction.
+ *
+ * In case the node to extract is not a node of the tree, then this function
+ * yields unpredictable results.
+ *
+ * @param[in] the_rbtree The red-black tree control.
+ * @param[in] the_node The node to extract.
+ */
+void _RBTree_Extract(
+ RBTree_Control *the_rbtree,
+ RBTree_Node *the_node
+);
+
+/**
+ * @brief Returns a pointer to root node of the red-black tree.
+ *
+ * The root node may change after insert or extract operations.
+ *
+ * @param[in] the_rbtree The red-black tree control.
+ *
+ * @retval NULL The tree is empty.
+ * @retval root The root node.
+ *
+ * @see _RBTree_Is_root().
+ */
+RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Root(
+ const RBTree_Control *the_rbtree
+)
+{
+ return RB_ROOT( the_rbtree );
+}
+
+/**
+ * @brief Returns a reference to the root pointer of the red-black tree.
+ */
+RTEMS_INLINE_ROUTINE RBTree_Node **_RBTree_Root_reference(
+ RBTree_Control *the_rbtree
+)
+{
+ return &RB_ROOT( the_rbtree );
+}
+
+/**
+ * @brief Returns a constant reference to the root pointer of the red-black tree.
+ */
+RTEMS_INLINE_ROUTINE RBTree_Node * const *_RBTree_Root_const_reference(
+ const RBTree_Control *the_rbtree
+)
+{
+ return &RB_ROOT( the_rbtree );
+}
+
+/**
+ * @brief Returns a pointer to the parent of this node.
+ *
+ * The node must have a parent, thus it is invalid to use this function for the
+ * root node or a node that is not part of a tree. To test for the root node
+ * compare with _RBTree_Root() or use _RBTree_Is_root().
+ *
+ * @param[in] the_node The node of interest.
+ *
+ * @retval parent The parent of this node.
+ * @retval undefined The node is the root node or not part of a tree.
+ */
+RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Parent(
+ const RBTree_Node *the_node
+)
+{
+ return RB_PARENT( the_node, Node );
+}
+
+/**
+ * @brief Return pointer to the left of this node.
+ *
+ * This function returns a pointer to the left node of this node.
+ *
+ * @param[in] the_node is the node to be operated upon.
+ *
+ * @return This method returns the left node on the rbtree.
+ */
+RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Left(
+ const RBTree_Node *the_node
+)
+{
+ return RB_LEFT( the_node, Node );
+}
+
+/**
+ * @brief Returns a reference to the left child pointer of the red-black tree
+ * node.
+ */
+RTEMS_INLINE_ROUTINE RBTree_Node **_RBTree_Left_reference(
+ RBTree_Node *the_node
+)
+{
+ return &RB_LEFT( the_node, Node );
+}
+
+/**
+ * @brief Return pointer to the right of this node.
+ *
+ * This function returns a pointer to the right node of this node.
+ *
+ * @param[in] the_node is the node to be operated upon.
+ *
+ * @return This method returns the right node on the rbtree.
+ */
+RTEMS_INLINE_ROUTINE RBTree_Node *_RBTree_Right(
+ const RBTree_Node *the_node
+)
+{
+ return RB_RIGHT( the_node, Node );
+}
+
+/**
+ * @brief Returns a reference to the right child pointer of the red-black tree
+ * node.
+ */
+RTEMS_INLINE_ROUTINE RBTree_Node **_RBTree_Right_reference(
+ RBTree_Node *the_node
+)
+{
+ return &RB_RIGHT( the_node, Node );
+}
+
+/**
+ * @brief Is the RBTree empty.
+ *
+ * This function returns true if there are no nodes on @a the_rbtree and
+ * false otherwise.
+ *
+ * @param[in] the_rbtree is the rbtree to be operated upon.
+ *
+ * @retval true There are no nodes on @a the_rbtree.
+ * @retval false There are nodes on @a the_rbtree.
+ */
+RTEMS_INLINE_ROUTINE bool _RBTree_Is_empty(
+ const RBTree_Control *the_rbtree
+)
+{
+ return RB_EMPTY( the_rbtree );
+}
+
+/**
+ * @brief Returns true if this node is the root node of a red-black tree, and
+ * false otherwise.
+ *
+ * The root node may change after insert or extract operations. In case the
+ * node is not a node of a tree, then this function yields unpredictable
+ * results.
+ *
+ * @param[in] the_node The node of interest.
+ *
+ * @retval true The node is the root node.
+ * @retval false Otherwise.
+ *
+ * @see _RBTree_Root().
+ */
+RTEMS_INLINE_ROUTINE bool _RBTree_Is_root(
+ const RBTree_Node *the_node
+)
+{
+ return _RBTree_Parent( the_node ) == NULL;
+}
+
+/**
+ * @brief Initialize this RBTree as empty.
+ *
+ * This routine initializes @a the_rbtree to contain zero nodes.
+ */
+RTEMS_INLINE_ROUTINE void _RBTree_Initialize_empty(
+ RBTree_Control *the_rbtree
+)
+{
+ RB_INIT( the_rbtree );
+}
+
+/**
+ * @brief Initializes this red-black tree to contain exactly the specified
+ * node.
+ *
+ * @param[in] the_rbtree The red-black tree control.
+ * @param[in] the_node The one and only node.
+ */
+RTEMS_INLINE_ROUTINE void _RBTree_Initialize_one(
+ RBTree_Control *the_rbtree,
+ RBTree_Node *the_node
+)
+{
+ _Assert( _RBTree_Is_node_off_tree( the_node ) );
+ RB_ROOT( the_rbtree ) = the_node;
+ RB_PARENT( the_node, Node ) = NULL;
+ RB_LEFT( the_node, Node ) = NULL;
+ RB_RIGHT( the_node, Node ) = NULL;
+ RB_COLOR( the_node, Node ) = RB_BLACK;
+}
+
+/**
+ * @brief Returns the minimum node of the red-black tree.
+ *
+ * @param[in] the_rbtree The red-black tree control.
+ *
+ * @retval NULL The red-black tree is empty.
+ * @retval node The minimum node.
+ */
+RBTree_Node *_RBTree_Minimum( const RBTree_Control *the_rbtree );
+
+/**
+ * @brief Returns the maximum node of the red-black tree.
+ *
+ * @param[in] the_rbtree The red-black tree control.
+ *
+ * @retval NULL The red-black tree is empty.
+ * @retval node The maximum node.
+ */
+RBTree_Node *_RBTree_Maximum( const RBTree_Control *the_rbtree );
+
+/**
+ * @brief Returns the predecessor of a node.
+ *
+ * @param[in] node is the node.
+ *
+ * @retval NULL The predecessor does not exist. Otherwise it returns
+ * the predecessor node.
+ */
+RBTree_Node *_RBTree_Predecessor( const RBTree_Node *node );
+
+/**
+ * @brief Returns the successor of a node.
+ *
+ * @param[in] node is the node.
+ *
+ * @retval NULL The successor does not exist. Otherwise the successor node.
+ */
+RBTree_Node *_RBTree_Successor( const RBTree_Node *node );
+
+/**
+ * @brief Replaces a node in the red-black tree without a rebalance.
+ *
+ * @param[in] the_rbtree The red-black tree control.
+ * @param[in] victim The victim node.
+ * @param[in] replacement The replacement node.
+ */
+void _RBTree_Replace_node(
+ RBTree_Control *the_rbtree,
+ RBTree_Node *victim,
+ RBTree_Node *replacement
+);
+
+/**
+ * @brief Inserts the node into the red-black tree.
+ *
+ * @param the_rbtree The red-black tree control.
+ * @param the_node The node to insert.
+ * @param key The key of the node to insert. This key must be equal to the key
+ * stored in the node to insert. The separate key parameter is provided for
+ * two reasons. Firstly, it allows to share the less operator with
+ * _RBTree_Find_inline(). Secondly, the compiler may generate better code if
+ * the key is stored in a local variable.
+ * @param less Must return true if the specified key is less than the key of
+ * the node, otherwise false.
+ *
+ * @retval true The inserted node is the new minimum node according to the
+ * specified less order function.
+ * @retval false Otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _RBTree_Insert_inline(
+ RBTree_Control *the_rbtree,
+ RBTree_Node *the_node,
+ const void *key,
+ bool ( *less )( const void *, const RBTree_Node * )
+)
+{
+ RBTree_Node **link;
+ RBTree_Node *parent;
+ bool is_new_minimum;
+
+ link = _RBTree_Root_reference( the_rbtree );
+ parent = NULL;
+ is_new_minimum = true;
+
+ while ( *link != NULL ) {
+ parent = *link;
+
+ if ( ( *less )( key, parent ) ) {
+ link = _RBTree_Left_reference( parent );
+ } else {
+ link = _RBTree_Right_reference( parent );
+ is_new_minimum = false;
+ }
+ }
+
+ _RBTree_Add_child( the_node, parent, link );
+ _RBTree_Insert_color( the_rbtree, the_node );
+ return is_new_minimum;
+}
+
+/**
+ * @brief Finds an object in the red-black tree with the specified key.
+ *
+ * @param the_rbtree The red-black tree control.
+ * @param key The key to look after.
+ * @param equal Must return true if the specified key equals the key of the
+ * node, otherwise false.
+ * @param less Must return true if the specified key is less than the key of
+ * the node, otherwise false.
+ * @param map In case a node with the specified key is found, then this
+ * function is called to map the node to the object returned. Usually it
+ * performs some offset operation via RTEMS_CONTAINER_OF() to map the node to
+ * its containing object. Thus, the return type is a void pointer and not a
+ * red-black tree node.
+ *
+ * @retval object An object with the specified key.
+ * @retval NULL No object with the specified key exists in the red-black tree.
+ */
+RTEMS_INLINE_ROUTINE void *_RBTree_Find_inline(
+ const RBTree_Control *the_rbtree,
+ const void *key,
+ bool ( *equal )( const void *, const RBTree_Node * ),
+ bool ( *less )( const void *, const RBTree_Node * ),
+ void *( *map )( RBTree_Node * )
+)
+{
+ RBTree_Node * const *link;
+ RBTree_Node *parent;
+
+ link = _RBTree_Root_const_reference( the_rbtree );
+ parent = NULL;
+
+ while ( *link != NULL ) {
+ parent = *link;
+
+ if ( ( *equal )( key, parent ) ) {
+ return ( *map )( parent );
+ } else if ( ( *less )( key, parent ) ) {
+ link = _RBTree_Left_reference( parent );
+ } else {
+ link = _RBTree_Right_reference( parent );
+ }
+ }
+
+ return NULL;
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/rbtreeimpl.h b/cpukit/include/rtems/score/rbtreeimpl.h
new file mode 100644
index 0000000000..bf92e29228
--- /dev/null
+++ b/cpukit/include/rtems/score/rbtreeimpl.h
@@ -0,0 +1,72 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines Associated with Red-Black Trees
+ *
+ * This include file contains the bodies of the routines which are
+ * associated with Red-Black Trees and inlined.
+ *
+ * @note The routines in this file are ordered from simple
+ * to complex. No other RBTree Handler routine is referenced
+ * unless it has already been defined.
+ */
+
+/*
+ * Copyright (c) 2010-2012 Gedare Bloom.
+ *
+ * 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_RBTREEIMPL_H
+#define _RTEMS_SCORE_RBTREEIMPL_H
+
+#include <rtems/score/rbtree.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreRBTree
+ */
+/**@{**/
+
+/**
+ * @brief Red-black tree visitor.
+ *
+ * @param[in] node The node.
+ * @param[in] visitor_arg The visitor argument.
+ *
+ * @retval true Stop the iteration.
+ * @retval false Continue the iteration.
+ *
+ * @see _RBTree_Iterate().
+ */
+typedef bool (*RBTree_Visitor)(
+ const RBTree_Node *node,
+ void *visitor_arg
+);
+
+/**
+ * @brief Red-black tree iteration.
+ *
+ * @param[in] rbtree The red-black tree.
+ * @param[in] visitor The visitor.
+ * @param[in] visitor_arg The visitor argument.
+ */
+void _RBTree_Iterate(
+ const RBTree_Control *rbtree,
+ RBTree_Visitor visitor,
+ void *visitor_arg
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/scheduler.h b/cpukit/include/rtems/score/scheduler.h
new file mode 100644
index 0000000000..a6066c8e4a
--- /dev/null
+++ b/cpukit/include/rtems/score/scheduler.h
@@ -0,0 +1,556 @@
+/**
+ * @file rtems/score/scheduler.h
+ *
+ * @brief Constants and Structures Associated with the Scheduler
+ *
+ * This include file contains all the constants and structures associated
+ * with the scheduler.
+ */
+
+/*
+ * Copyright (C) 2010 Gedare Bloom.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * 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_SCHEDULER_H
+#define _RTEMS_SCORE_SCHEDULER_H
+
+#include <rtems/score/thread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Per_CPU_Control;
+
+/**
+ * @defgroup ScoreScheduler Scheduler Handler
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality related to managing sets of threads
+ * that are ready for execution.
+ */
+/**@{*/
+
+typedef struct _Scheduler_Control Scheduler_Control;
+
+/**
+ * @brief The scheduler operations.
+ */
+typedef struct {
+ /** @see _Scheduler_Handler_initialization() */
+ void ( *initialize )( const Scheduler_Control * );
+
+ /** @see _Scheduler_Schedule() */
+ void ( *schedule )( const Scheduler_Control *, Thread_Control *);
+
+ /** @see _Scheduler_Yield() */
+ void ( *yield )(
+ const Scheduler_Control *,
+ Thread_Control *,
+ Scheduler_Node *
+ );
+
+ /** @see _Scheduler_Block() */
+ void ( *block )(
+ const Scheduler_Control *,
+ Thread_Control *,
+ Scheduler_Node *
+ );
+
+ /** @see _Scheduler_Unblock() */
+ void ( *unblock )(
+ const Scheduler_Control *,
+ Thread_Control *,
+ Scheduler_Node *
+ );
+
+ /** @see _Scheduler_Update_priority() */
+ void ( *update_priority )(
+ const Scheduler_Control *,
+ Thread_Control *,
+ Scheduler_Node *
+ );
+
+ /** @see _Scheduler_Map_priority() */
+ Priority_Control ( *map_priority )(
+ const Scheduler_Control *,
+ Priority_Control
+ );
+
+ /** @see _Scheduler_Unmap_priority() */
+ Priority_Control ( *unmap_priority )(
+ const Scheduler_Control *,
+ Priority_Control
+ );
+
+#if defined(RTEMS_SMP)
+ /**
+ * @brief Ask for help operation.
+ *
+ * @param[in] scheduler The scheduler instance to ask for help.
+ * @param[in] the_thread The thread needing help.
+ * @param[in] node The scheduler node.
+ *
+ * @retval true Ask for help was successful.
+ * @retval false Otherwise.
+ */
+ bool ( *ask_for_help )(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+ );
+
+ /**
+ * @brief Reconsider help operation.
+ *
+ * @param[in] scheduler The scheduler instance to reconsider the help
+ * request.
+ * @param[in] the_thread The thread reconsidering a help request.
+ * @param[in] node The scheduler node.
+ */
+ void ( *reconsider_help_request )(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+ );
+
+ /**
+ * @brief Withdraw node operation.
+ *
+ * @param[in] scheduler The scheduler instance to withdraw the node.
+ * @param[in] the_thread The thread using the node.
+ * @param[in] node The scheduler node to withdraw.
+ * @param[in] next_state The next thread scheduler state in case the node is
+ * scheduled.
+ */
+ void ( *withdraw_node )(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node,
+ Thread_Scheduler_state next_state
+ );
+
+ /**
+ * @brief Add processor operation.
+ *
+ * @param[in] scheduler The scheduler instance to add the processor.
+ * @param[in] idle The idle thread of the processor to add.
+ */
+ void ( *add_processor )(
+ const Scheduler_Control *scheduler,
+ Thread_Control *idle
+ );
+
+ /**
+ * @brief Remove processor operation.
+ *
+ * @param[in] scheduler The scheduler instance to remove the processor.
+ * @param[in] cpu The processor to remove.
+ *
+ * @return The idle thread of the removed processor.
+ */
+ Thread_Control *( *remove_processor )(
+ const Scheduler_Control *scheduler,
+ struct Per_CPU_Control *cpu
+ );
+#endif
+
+ /** @see _Scheduler_Node_initialize() */
+ void ( *node_initialize )(
+ const Scheduler_Control *,
+ Scheduler_Node *,
+ Thread_Control *,
+ Priority_Control
+ );
+
+ /** @see _Scheduler_Node_destroy() */
+ void ( *node_destroy )( const Scheduler_Control *, Scheduler_Node * );
+
+ /** @see _Scheduler_Release_job() */
+ void ( *release_job ) (
+ const Scheduler_Control *,
+ Thread_Control *,
+ Priority_Node *,
+ uint64_t,
+ Thread_queue_Context *
+ );
+
+ /** @see _Scheduler_Cancel_job() */
+ void ( *cancel_job ) (
+ const Scheduler_Control *,
+ Thread_Control *,
+ Priority_Node *,
+ Thread_queue_Context *
+ );
+
+ /** @see _Scheduler_Tick() */
+ void ( *tick )( const Scheduler_Control *, Thread_Control * );
+
+ /** @see _Scheduler_Start_idle() */
+ void ( *start_idle )(
+ const Scheduler_Control *,
+ Thread_Control *,
+ struct Per_CPU_Control *
+ );
+
+#if defined(RTEMS_SMP)
+ /** @see _Scheduler_Set_affinity() */
+ bool ( *set_affinity )(
+ const Scheduler_Control *,
+ Thread_Control *,
+ Scheduler_Node *,
+ const Processor_mask *
+ );
+#endif
+} Scheduler_Operations;
+
+/**
+ * @brief Scheduler context.
+ *
+ * The scheduler context of a particular scheduler implementation must place
+ * this structure at the begin of its context structure.
+ */
+typedef struct Scheduler_Context {
+ /**
+ * @brief Lock to protect this scheduler instance.
+ */
+ ISR_LOCK_MEMBER( Lock )
+
+#if defined(RTEMS_SMP)
+ /**
+ * @brief The set of processors owned by this scheduler instance.
+ */
+ Processor_mask Processors;
+#endif
+} Scheduler_Context;
+
+/**
+ * @brief Scheduler control.
+ */
+struct _Scheduler_Control {
+ /**
+ * @brief Reference to a statically allocated scheduler context.
+ */
+ Scheduler_Context *context;
+
+ /**
+ * @brief The scheduler operations.
+ */
+ Scheduler_Operations Operations;
+
+ /**
+ * @brief The maximum priority value of this scheduler.
+ *
+ * It defines the lowest (least important) thread priority for this
+ * scheduler. For example the idle threads have this priority.
+ */
+ Priority_Control maximum_priority;
+
+ /**
+ * @brief The scheduler name.
+ */
+ uint32_t name;
+};
+
+/**
+ * @brief Registered schedulers.
+ *
+ * Application provided via <rtems/confdefs.h>.
+ *
+ * @see _Scheduler_Count.
+ */
+extern const Scheduler_Control _Scheduler_Table[];
+
+/**
+ * @brief Count of registered schedulers.
+ *
+ * Application provided via <rtems/confdefs.h> on SMP configurations.
+ *
+ * It is very important that this is a compile-time constant on uni-processor
+ * configurations (in this case RTEMS_SMP is not defined) so that the compiler
+ * can optimize the some loops away
+ *
+ * @see _Scheduler_Table.
+ */
+#if defined(RTEMS_SMP)
+ extern const size_t _Scheduler_Count;
+#else
+ #define _Scheduler_Count ( (size_t) 1 )
+#endif
+
+#if defined(RTEMS_SMP)
+ /**
+ * @brief The scheduler assignment default attributes.
+ */
+ #define SCHEDULER_ASSIGN_DEFAULT UINT32_C(0x0)
+
+ /**
+ * @brief The presence of this processor is optional.
+ */
+ #define SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL SCHEDULER_ASSIGN_DEFAULT
+
+ /**
+ * @brief The presence of this processor is mandatory.
+ */
+ #define SCHEDULER_ASSIGN_PROCESSOR_MANDATORY UINT32_C(0x1)
+
+ /**
+ * @brief Scheduler assignment.
+ */
+ typedef struct {
+ /**
+ * @brief The scheduler for this processor.
+ */
+ const Scheduler_Control *scheduler;
+
+ /**
+ * @brief The scheduler assignment attributes.
+ *
+ * Use @ref SCHEDULER_ASSIGN_DEFAULT to select default attributes.
+ *
+ * The presence of a processor can be
+ * - @ref SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL, or
+ * - @ref SCHEDULER_ASSIGN_PROCESSOR_MANDATORY.
+ */
+ uint32_t attributes;
+ } Scheduler_Assignment;
+
+ /**
+ * @brief The scheduler assignments.
+ *
+ * The length of this array must be equal to the maximum processors.
+ *
+ * Application provided via <rtems/confdefs.h>.
+ *
+ * @see _Scheduler_Table and rtems_configuration_get_maximum_processors().
+ */
+ extern const Scheduler_Assignment _Scheduler_Initial_assignments[];
+#endif
+
+/**
+ * @brief Returns the scheduler internal thread priority mapped by
+ * SCHEDULER_PRIORITY_MAP().
+ *
+ * @param[in] scheduler Unused.
+ * @param[in] priority The user visible thread priority.
+ *
+ * @return priority The scheduler internal thread priority.
+ */
+Priority_Control _Scheduler_default_Map_priority(
+ const Scheduler_Control *scheduler,
+ Priority_Control priority
+);
+
+/**
+ * @brief Returns the user visible thread priority unmapped by
+ * SCHEDULER_PRIORITY_UNMAP().
+ *
+ * @param[in] scheduler Unused.
+ * @param[in] priority The scheduler internal thread priority.
+ *
+ * @return priority The user visible thread priority.
+ */
+Priority_Control _Scheduler_default_Unmap_priority(
+ const Scheduler_Control *scheduler,
+ Priority_Control priority
+);
+
+#if defined(RTEMS_SMP)
+ /**
+ * @brief Does nothing.
+ *
+ * @param[in] scheduler Unused.
+ * @param[in] the_thread Unused.
+ * @param[in] node Unused.
+ *
+ * @retval false Always.
+ */
+ bool _Scheduler_default_Ask_for_help(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+ );
+
+ /**
+ * @brief Does nothing.
+ *
+ * @param[in] scheduler Unused.
+ * @param[in] the_thread Unused.
+ * @param[in] node Unused.
+ */
+ void _Scheduler_default_Reconsider_help_request(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+ );
+
+ /**
+ * @brief Does nothing.
+ *
+ * @param[in] scheduler Unused.
+ * @param[in] the_thread Unused.
+ * @param[in] node Unused.
+ * @param[in] next_state Unused.
+ */
+ void _Scheduler_default_Withdraw_node(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node,
+ Thread_Scheduler_state next_state
+ );
+
+ #define SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
+ _Scheduler_default_Ask_for_help, \
+ _Scheduler_default_Reconsider_help_request, \
+ _Scheduler_default_Withdraw_node, \
+ NULL, \
+ NULL,
+#else
+ #define SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP
+#endif
+
+/**
+ * @brief Does nothing.
+ *
+ * @param[in] scheduler Unused.
+ * @param[in] the_thread Unused.
+ */
+void _Scheduler_default_Schedule(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+);
+
+/**
+ * @brief Performs the scheduler base node initialization.
+ *
+ * @param[in] scheduler Unused.
+ * @param[in] node The node to initialize.
+ * @param[in] the_thread Unused.
+ * @param[in] priority The thread priority.
+ */
+void _Scheduler_default_Node_initialize(
+ const Scheduler_Control *scheduler,
+ Scheduler_Node *node,
+ Thread_Control *the_thread,
+ Priority_Control priority
+);
+
+/**
+ * @brief Does nothing.
+ *
+ * @param[in] scheduler Unused.
+ * @param[in] node Unused.
+ */
+void _Scheduler_default_Node_destroy(
+ const Scheduler_Control *scheduler,
+ Scheduler_Node *node
+);
+
+/**
+ * @brief Does nothing.
+ *
+ * @param[in] scheduler Unused.
+ * @param[in] the_thread Unused.
+ * @param[in] priority_node Unused.
+ * @param[in] deadline Unused.
+ * @param[in] queue_context Unused.
+ *
+ * @retval NULL Always.
+ */
+void _Scheduler_default_Release_job(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Priority_Node *priority_node,
+ uint64_t deadline,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Does nothing.
+ *
+ * @param[in] scheduler Unused.
+ * @param[in] the_thread Unused.
+ * @param[in] priority_node Unused.
+ * @param[in] queue_context Unused.
+ *
+ * @retval NULL Always.
+ */
+void _Scheduler_default_Cancel_job(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Priority_Node *priority_node,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Performs tick operations depending on the CPU budget algorithm for
+ * each executing thread.
+ *
+ * This routine is invoked as part of processing each clock tick.
+ *
+ * @param[in] scheduler The scheduler.
+ * @param[in] executing An executing thread.
+ */
+void _Scheduler_default_Tick(
+ const Scheduler_Control *scheduler,
+ Thread_Control *executing
+);
+
+/**
+ * @brief Starts an idle thread.
+ *
+ * @param[in] scheduler The scheduler.
+ * @param[in] the_thread An idle thread.
+ * @param[in] cpu This parameter is unused.
+ */
+void _Scheduler_default_Start_idle(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ struct Per_CPU_Control *cpu
+);
+
+#if defined(RTEMS_SMP)
+ /**
+ * @brief Default implementation of the set affinity scheduler operation.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] thread The associated thread.
+ * @param[in] node The home scheduler node of the associated thread.
+ * @param[in] affinity The new processor affinity set for the thread.
+ *
+ * @retval true The processor set of the scheduler is a subset of the affinity set.
+ * @retval false Otherwise.
+ */
+ bool _Scheduler_default_Set_affinity(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node,
+ const Processor_mask *affinity
+ );
+
+ #define SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY \
+ , _Scheduler_default_Set_affinity
+#else
+ #define SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY
+#endif
+
+/**
+ * @brief This defines the lowest (least important) thread priority of the
+ * first scheduler instance.
+ */
+#define PRIORITY_MAXIMUM ( _Scheduler_Table[ 0 ].maximum_priority )
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/schedulercbs.h b/cpukit/include/rtems/score/schedulercbs.h
new file mode 100644
index 0000000000..635abce125
--- /dev/null
+++ b/cpukit/include/rtems/score/schedulercbs.h
@@ -0,0 +1,346 @@
+/**
+ * @file rtems/score/schedulercbs.h
+ *
+ * @brief Thread manipulation for the CBS scheduler
+ *
+ * This include file contains all the constants and structures associated
+ * with the manipulation of threads for the CBS scheduler.
+ */
+
+/*
+ * Copryight (c) 2011 Petr Benes.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * 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_SCHEDULERCBS_H
+#define _RTEMS_SCORE_SCHEDULERCBS_H
+
+#include <rtems/score/chain.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/rbtree.h>
+#include <rtems/score/scheduleredf.h>
+#include <rtems/rtems/signal.h>
+#include <rtems/rtems/timer.h>
+#include <rtems/score/thread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreSchedulerCBS CBS Scheduler
+ *
+ * @ingroup ScoreScheduler
+ */
+/**@{*/
+
+#define SCHEDULER_CBS_MAXIMUM_PRIORITY SCHEDULER_EDF_MAXIMUM_PRIORITY
+
+/**
+ * Entry points for the Constant Bandwidth Server Scheduler.
+ *
+ * @note: The CBS scheduler is an enhancement of EDF scheduler,
+ * therefor some routines are similar.
+ */
+#define SCHEDULER_CBS_ENTRY_POINTS \
+ { \
+ _Scheduler_EDF_Initialize, /* initialize entry point */ \
+ _Scheduler_EDF_Schedule, /* schedule entry point */ \
+ _Scheduler_EDF_Yield, /* yield entry point */ \
+ _Scheduler_EDF_Block, /* block entry point */ \
+ _Scheduler_CBS_Unblock, /* unblock entry point */ \
+ _Scheduler_EDF_Update_priority, /* update priority entry point */ \
+ _Scheduler_EDF_Map_priority, /* map priority entry point */ \
+ _Scheduler_EDF_Unmap_priority, /* unmap priority entry point */ \
+ SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
+ _Scheduler_CBS_Node_initialize, /* node initialize entry point */ \
+ _Scheduler_default_Node_destroy, /* node destroy entry point */ \
+ _Scheduler_CBS_Release_job, /* new period of task */ \
+ _Scheduler_CBS_Cancel_job, /* cancel period of task */ \
+ _Scheduler_default_Tick, /* tick entry point */ \
+ _Scheduler_default_Start_idle /* start idle entry point */ \
+ SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY \
+ }
+
+/* Return values for CBS server. */
+#define SCHEDULER_CBS_OK 0
+#define SCHEDULER_CBS_ERROR_GENERIC -16
+#define SCHEDULER_CBS_ERROR_NO_MEMORY -17
+#define SCHEDULER_CBS_ERROR_INVALID_PARAMETER -18
+#define SCHEDULER_CBS_ERROR_UNAUTHORIZED -19
+#define SCHEDULER_CBS_ERROR_UNIMPLEMENTED -20
+#define SCHEDULER_CBS_ERROR_MISSING_COMPONENT -21
+#define SCHEDULER_CBS_ERROR_INCONSISTENT_STATE -22
+#define SCHEDULER_CBS_ERROR_SYSTEM_OVERLOAD -23
+#define SCHEDULER_CBS_ERROR_INTERNAL_ERROR -24
+#define SCHEDULER_CBS_ERROR_NOT_FOUND -25
+#define SCHEDULER_CBS_ERROR_FULL -26
+#define SCHEDULER_CBS_ERROR_EMPTY -27
+#define SCHEDULER_CBS_ERROR_NOSERVER SCHEDULER_CBS_ERROR_NOT_FOUND
+
+/** Maximum number of simultaneous servers. */
+extern const uint32_t _Scheduler_CBS_Maximum_servers;
+
+/** Server id. */
+typedef uint32_t Scheduler_CBS_Server_id;
+
+/** Callback function invoked when a budget overrun of a task occurs. */
+typedef void (*Scheduler_CBS_Budget_overrun)(
+ Scheduler_CBS_Server_id server_id
+);
+
+/**
+ * This structure handles server parameters.
+ */
+typedef struct {
+ /** Relative deadline of the server. */
+ time_t deadline;
+ /** Budget (computation time) of the server. */
+ time_t budget;
+} Scheduler_CBS_Parameters;
+
+/**
+ * This structure represents a time server.
+ */
+typedef struct {
+ /**
+ * Task id.
+ *
+ * @note: The current implementation of CBS handles only one task per server.
+ */
+ rtems_id task_id;
+ /** Server paramenters. */
+ Scheduler_CBS_Parameters parameters;
+ /** Callback function invoked when a budget overrun occurs. */
+ Scheduler_CBS_Budget_overrun cbs_budget_overrun;
+
+ /**
+ * @brief Indicates if this CBS server is initialized.
+ *
+ * @see _Scheduler_CBS_Create_server() and _Scheduler_CBS_Destroy_server().
+ */
+ bool initialized;
+} Scheduler_CBS_Server;
+
+/**
+ * This structure handles CBS specific data of a thread.
+ */
+typedef struct {
+ /** EDF scheduler specific data of a task. */
+ Scheduler_EDF_Node Base;
+ /** CBS server specific data of a task. */
+ Scheduler_CBS_Server *cbs_server;
+
+ Priority_Node *deadline_node;
+} Scheduler_CBS_Node;
+
+
+/**
+ * List of servers. The @a Scheduler_CBS_Server is the index to the array
+ * of pointers to @a _Scheduler_CBS_Server_list.
+ */
+extern Scheduler_CBS_Server _Scheduler_CBS_Server_list[];
+
+void _Scheduler_CBS_Unblock(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_CBS_Release_job(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Priority_Node *priority_node,
+ uint64_t deadline,
+ Thread_queue_Context *queue_context
+);
+
+void _Scheduler_CBS_Cancel_job(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Priority_Node *priority_node,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief _Scheduler_CBS_Initialize
+ *
+ * Initializes the CBS library.
+ *
+ * @retval status code.
+ */
+int _Scheduler_CBS_Initialize(void);
+
+/**
+ * @brief Attach a task to an already existing server.
+ *
+ * Attach a task to an already existing server.
+ *
+ * @retval status code.
+ */
+int _Scheduler_CBS_Attach_thread (
+ Scheduler_CBS_Server_id server_id,
+ rtems_id task_id
+);
+
+/**
+ * @brief Detach from the CBS Server.
+ *
+ * Detach from the CBS Server.
+ *
+ * @retval status code.
+ */
+int _Scheduler_CBS_Detach_thread (
+ Scheduler_CBS_Server_id server_id,
+ rtems_id task_id
+);
+
+/**
+ * @brief Cleanup resources associated to the CBS Library.
+ *
+ * Cleanup resources associated to the CBS Library.
+ *
+ * @retval status code.
+ */
+int _Scheduler_CBS_Cleanup (void);
+
+/**
+ * @brief Create a new server with specified parameters.
+ *
+ * Create a new server with specified parameters.
+ *
+ * @retval status code.
+ */
+int _Scheduler_CBS_Create_server (
+ Scheduler_CBS_Parameters *params,
+ Scheduler_CBS_Budget_overrun budget_overrun_callback,
+ rtems_id *server_id
+);
+
+/**
+ * @brief Detach all tasks from a server and destroy it.
+ *
+ * Detach all tasks from a server and destroy it.
+ *
+ * @param[in] server_id is the ID of the server
+ *
+ * @retval status code.
+ */
+int _Scheduler_CBS_Destroy_server (
+ Scheduler_CBS_Server_id server_id
+);
+
+/**
+ * @brief Retrieve the approved budget.
+ *
+ * Retrieve the budget that has been approved for the subsequent
+ * server instances.
+ *
+ * @retval status code.
+ */
+int _Scheduler_CBS_Get_approved_budget (
+ Scheduler_CBS_Server_id server_id,
+ time_t *approved_budget
+);
+
+/**
+ * @brief Retrieve remaining budget for the current server instance.
+ *
+ * Retrieve remaining budget for the current server instance.
+ *
+ * @retval status code.
+ */
+int _Scheduler_CBS_Get_remaining_budget (
+ Scheduler_CBS_Server_id server_id,
+ time_t *remaining_budget
+);
+
+/**
+ * @brief Get relative time info.
+ *
+ * Retrieve time info relative to @a server_id. The server status code is returned.
+ *
+ * @param[in] server_id is the server to get the status code from.
+ * @param[in] exec_time is the execution time.
+ * @param[in] abs_time is not apparently used.
+ *
+ * @retval status code.
+ */
+int _Scheduler_CBS_Get_execution_time (
+ Scheduler_CBS_Server_id server_id,
+ time_t *exec_time,
+ time_t *abs_time
+);
+
+/**
+ * @brief Retrieve CBS scheduling parameters.
+ *
+ * Retrieve CBS scheduling parameters.
+ *
+ * @retval status code.
+ */
+int _Scheduler_CBS_Get_parameters (
+ Scheduler_CBS_Server_id server_id,
+ Scheduler_CBS_Parameters *params
+);
+
+/**
+ * @brief Get a thread server id.
+ *
+ * Get a thread server id, or SCHEDULER_CBS_ERROR_NOT_FOUND if it is not
+ * attached to any server.
+ *
+ * @retval status code.
+ */
+int _Scheduler_CBS_Get_server_id (
+ rtems_id task_id,
+ Scheduler_CBS_Server_id *server_id
+);
+
+/**
+ * @brief Set parameters for CBS scheduling.
+ *
+ * Change CBS scheduling parameters.
+ *
+ * @param[in] server_id is the ID of the server.
+ * @param[in] parameters are the parameters to set.
+ *
+ * @retval status code.
+ */
+int _Scheduler_CBS_Set_parameters (
+ Scheduler_CBS_Server_id server_id,
+ Scheduler_CBS_Parameters *parameters
+);
+
+/**
+ * @brief Invoked when a limited time quantum is exceeded.
+ *
+ * This routine is invoked when a limited time quantum is exceeded.
+ */
+void _Scheduler_CBS_Budget_callout(
+ Thread_Control *the_thread
+);
+
+/**
+ * @brief Initializes a CBS specific scheduler node of @a the_thread.
+ */
+void _Scheduler_CBS_Node_initialize(
+ const Scheduler_Control *scheduler,
+ Scheduler_Node *node,
+ Thread_Control *the_thread,
+ Priority_Control priority
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/schedulercbsimpl.h b/cpukit/include/rtems/score/schedulercbsimpl.h
new file mode 100644
index 0000000000..ed75979f75
--- /dev/null
+++ b/cpukit/include/rtems/score/schedulercbsimpl.h
@@ -0,0 +1,59 @@
+/**
+ * @file
+ *
+ * @brief CBS Scheduler Implementation
+ *
+ * @ingroup ScoreSchedulerCBS
+ */
+
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_SCHEDULERCBSIMPL_H
+#define _RTEMS_SCORE_SCHEDULERCBSIMPL_H
+
+#include <rtems/score/schedulercbs.h>
+#include <rtems/score/schedulerimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @addtogroup ScoreSchedulerCBS
+ *
+ * @{
+ */
+
+RTEMS_INLINE_ROUTINE Scheduler_CBS_Node *_Scheduler_CBS_Thread_get_node(
+ Thread_Control *the_thread
+)
+{
+ return (Scheduler_CBS_Node *) _Thread_Scheduler_get_home_node( the_thread );
+}
+
+RTEMS_INLINE_ROUTINE Scheduler_CBS_Node *_Scheduler_CBS_Node_downcast(
+ Scheduler_Node *node
+)
+{
+ return (Scheduler_CBS_Node *) node;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_SCHEDULERCBSIMPL_H */
diff --git a/cpukit/include/rtems/score/scheduleredf.h b/cpukit/include/rtems/score/scheduleredf.h
new file mode 100644
index 0000000000..91c303ca56
--- /dev/null
+++ b/cpukit/include/rtems/score/scheduleredf.h
@@ -0,0 +1,197 @@
+/**
+ * @file rtems/score/scheduleredf.h
+ *
+ * @brief Data Related to the Manipulation of Threads for the EDF Scheduler
+ *
+ * This include file contains all the constants and structures associated
+ * with the manipulation of threads for the EDF scheduler.
+ */
+
+/*
+ * Copryight (c) 2011 Petr Benes.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * 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_SCHEDULEREDF_H
+#define _RTEMS_SCORE_SCHEDULEREDF_H
+
+#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/rbtree.h>
+
+#include <limits.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreSchedulerEDF EDF Scheduler
+ *
+ * @ingroup ScoreScheduler
+ */
+/**@{*/
+
+/*
+ * Actually the EDF scheduler supports a maximum priority of
+ * 0x7fffffffffffffff, but the user API is limited to uint32_t or int for
+ * thread priorities. Ignore ILP64 targets for now.
+ */
+#define SCHEDULER_EDF_MAXIMUM_PRIORITY INT_MAX
+
+/**
+ * Entry points for the Earliest Deadline First Scheduler.
+ */
+#define SCHEDULER_EDF_ENTRY_POINTS \
+ { \
+ _Scheduler_EDF_Initialize, /* initialize entry point */ \
+ _Scheduler_EDF_Schedule, /* schedule entry point */ \
+ _Scheduler_EDF_Yield, /* yield entry point */ \
+ _Scheduler_EDF_Block, /* block entry point */ \
+ _Scheduler_EDF_Unblock, /* unblock entry point */ \
+ _Scheduler_EDF_Update_priority, /* update priority entry point */ \
+ _Scheduler_EDF_Map_priority, /* map priority entry point */ \
+ _Scheduler_EDF_Unmap_priority, /* unmap priority entry point */ \
+ SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
+ _Scheduler_EDF_Node_initialize, /* node initialize entry point */ \
+ _Scheduler_default_Node_destroy, /* node destroy entry point */ \
+ _Scheduler_EDF_Release_job, /* new period of task */ \
+ _Scheduler_EDF_Cancel_job, /* cancel period of task */ \
+ _Scheduler_default_Tick, /* tick entry point */ \
+ _Scheduler_default_Start_idle /* start idle entry point */ \
+ SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY \
+ }
+
+typedef struct {
+ /**
+ * @brief Basic scheduler context.
+ */
+ Scheduler_Context Base;
+
+ /**
+ * Top of the ready queue.
+ */
+ RBTree_Control Ready;
+} Scheduler_EDF_Context;
+
+/**
+ * @brief Scheduler node specialization for EDF schedulers.
+ */
+typedef struct {
+ /**
+ * @brief Basic scheduler node.
+ */
+ Scheduler_Node Base;
+
+ /**
+ * Rbtree node related to this thread.
+ */
+ RBTree_Node Node;
+
+ /**
+ * @brief The thread priority currently used for this scheduler instance.
+ */
+ Priority_Control priority;
+} Scheduler_EDF_Node;
+
+/**
+ * @brief Initialize EDF scheduler.
+ *
+ * This routine initializes the EDF scheduler.
+ *
+ * @param[in] scheduler The scheduler instance.
+ */
+void _Scheduler_EDF_Initialize( const Scheduler_Control *scheduler );
+
+void _Scheduler_EDF_Block(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+/**
+ * @brief Sets the heir thread to be the next ready thread
+ * in the rbtree ready queue.
+ *
+ * This kernel routine sets the heir thread to be the next ready thread
+ * in the rbtree ready queue.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] the_thread being scheduled.
+ */
+void _Scheduler_EDF_Schedule(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+);
+
+/**
+ * @brief Initializes an EDF specific scheduler node of @a the_thread.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] node being initialized.
+ * @param[in] the_thread the thread of the node.
+ * @param[in] priority The thread priority.
+ */
+void _Scheduler_EDF_Node_initialize(
+ const Scheduler_Control *scheduler,
+ Scheduler_Node *node,
+ Thread_Control *the_thread,
+ Priority_Control priority
+);
+
+void _Scheduler_EDF_Unblock(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_EDF_Update_priority(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+Priority_Control _Scheduler_EDF_Map_priority(
+ const Scheduler_Control *scheduler,
+ Priority_Control priority
+);
+
+Priority_Control _Scheduler_EDF_Unmap_priority(
+ const Scheduler_Control *scheduler,
+ Priority_Control priority
+);
+
+void _Scheduler_EDF_Yield(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_EDF_Release_job(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Priority_Node *priority_node,
+ uint64_t deadline,
+ Thread_queue_Context *queue_context
+);
+
+void _Scheduler_EDF_Cancel_job(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Priority_Node *priority_node,
+ Thread_queue_Context *queue_context
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/scheduleredfimpl.h b/cpukit/include/rtems/score/scheduleredfimpl.h
new file mode 100644
index 0000000000..f6bd7d8384
--- /dev/null
+++ b/cpukit/include/rtems/score/scheduleredfimpl.h
@@ -0,0 +1,164 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSchedulerEDF
+ *
+ * @brief EDF Scheduler Implementation
+ */
+
+/*
+ * Copryight (c) 2011 Petr Benes.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * 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_SCHEDULEREDFIMPL_H
+#define _RTEMS_SCORE_SCHEDULEREDFIMPL_H
+
+#include <rtems/score/scheduleredf.h>
+#include <rtems/score/schedulerimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreSchedulerEDF
+ *
+ * @{
+ */
+
+/**
+ * This is just a most significant bit of Priority_Control type. It
+ * distinguishes threads which are deadline driven (priority
+ * represented by a lower number than @a SCHEDULER_EDF_PRIO_MSB) from those
+ * ones who do not have any deadlines and thus are considered background
+ * tasks.
+ */
+#define SCHEDULER_EDF_PRIO_MSB 0x8000000000000000
+
+RTEMS_INLINE_ROUTINE Scheduler_EDF_Context *
+ _Scheduler_EDF_Get_context( const Scheduler_Control *scheduler )
+{
+ return (Scheduler_EDF_Context *) _Scheduler_Get_context( scheduler );
+}
+
+RTEMS_INLINE_ROUTINE Scheduler_EDF_Node *_Scheduler_EDF_Thread_get_node(
+ Thread_Control *the_thread
+)
+{
+ return (Scheduler_EDF_Node *) _Thread_Scheduler_get_home_node( the_thread );
+}
+
+RTEMS_INLINE_ROUTINE Scheduler_EDF_Node * _Scheduler_EDF_Node_downcast(
+ Scheduler_Node *node
+)
+{
+ return (Scheduler_EDF_Node *) node;
+}
+
+RTEMS_INLINE_ROUTINE bool _Scheduler_EDF_Less(
+ const void *left,
+ const RBTree_Node *right
+)
+{
+ const Priority_Control *the_left;
+ const Scheduler_EDF_Node *the_right;
+ Priority_Control prio_left;
+ Priority_Control prio_right;
+
+ the_left = left;
+ the_right = RTEMS_CONTAINER_OF( right, Scheduler_EDF_Node, Node );
+
+ prio_left = *the_left;
+ prio_right = the_right->priority;
+
+ return prio_left < prio_right;
+}
+
+RTEMS_INLINE_ROUTINE bool _Scheduler_EDF_Priority_less_equal(
+ const void *left,
+ const RBTree_Node *right
+)
+{
+ const Priority_Control *the_left;
+ const Scheduler_EDF_Node *the_right;
+ Priority_Control prio_left;
+ Priority_Control prio_right;
+
+ the_left = left;
+ the_right = RTEMS_CONTAINER_OF( right, Scheduler_EDF_Node, Node );
+
+ prio_left = *the_left;
+ prio_right = the_right->priority;
+
+ return prio_left <= prio_right;
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Enqueue(
+ Scheduler_EDF_Context *context,
+ Scheduler_EDF_Node *node,
+ Priority_Control insert_priority
+)
+{
+ _RBTree_Insert_inline(
+ &context->Ready,
+ &node->Node,
+ &insert_priority,
+ _Scheduler_EDF_Priority_less_equal
+ );
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Extract(
+ Scheduler_EDF_Context *context,
+ Scheduler_EDF_Node *node
+)
+{
+ _RBTree_Extract( &context->Ready, &node->Node );
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Extract_body(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+)
+{
+ Scheduler_EDF_Context *context;
+ Scheduler_EDF_Node *the_node;
+
+ context = _Scheduler_EDF_Get_context( scheduler );
+ the_node = _Scheduler_EDF_Node_downcast( node );
+
+ _Scheduler_EDF_Extract( context, the_node );
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Schedule_body(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ bool force_dispatch
+)
+{
+ Scheduler_EDF_Context *context;
+ RBTree_Node *first;
+ Scheduler_EDF_Node *node;
+
+ (void) the_thread;
+
+ context = _Scheduler_EDF_Get_context( scheduler );
+ first = _RBTree_Minimum( &context->Ready );
+ node = RTEMS_CONTAINER_OF( first, Scheduler_EDF_Node, Node );
+
+ _Scheduler_Update_heir( node->Base.owner, force_dispatch );
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/scheduleredfsmp.h b/cpukit/include/rtems/score/scheduleredfsmp.h
new file mode 100644
index 0000000000..018568190e
--- /dev/null
+++ b/cpukit/include/rtems/score/scheduleredfsmp.h
@@ -0,0 +1,200 @@
+/**
+ * @file
+ *
+ * @brief EDF SMP Scheduler API
+ *
+ * @ingroup ScoreSchedulerSMPEDF
+ */
+
+/*
+ * Copyright (c) 2017 embedded brains GmbH.
+ *
+ * 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_SCHEDULEREDFSMP_H
+#define _RTEMS_SCORE_SCHEDULEREDFSMP_H
+
+#include <rtems/score/scheduler.h>
+#include <rtems/score/scheduleredf.h>
+#include <rtems/score/schedulersmp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreSchedulerSMPEDF EDF Priority SMP Scheduler
+ *
+ * @ingroup ScoreSchedulerSMP
+ *
+ * @{
+ */
+
+typedef struct {
+ Scheduler_SMP_Node Base;
+
+ /**
+ * @brief Generation number to ensure FIFO/LIFO order for threads of the same
+ * priority across different ready queues.
+ */
+ int64_t generation;
+
+ /**
+ * @brief The ready queue index depending on the processor affinity of the thread.
+ *
+ * The ready queue index zero is used for threads with a one-to-all thread
+ * processor affinity. Threads with a one-to-one processor affinity use the
+ * processor index plus one as the ready queue index.
+ */
+ uint32_t ready_queue_index;
+} Scheduler_EDF_SMP_Node;
+
+typedef struct {
+ /**
+ * @brief Chain node for Scheduler_SMP_Context::Affine_queues.
+ */
+ Chain_Node Node;
+
+ /**
+ * @brief The ready threads of the corresponding affinity.
+ */
+ RBTree_Control Queue;
+
+ /**
+ * @brief The scheduled thread of the corresponding processor.
+ */
+ Scheduler_EDF_SMP_Node *scheduled;
+} Scheduler_EDF_SMP_Ready_queue;
+
+typedef struct {
+ Scheduler_SMP_Context Base;
+
+ /**
+ * @brief Current generation for LIFO (index 0) and FIFO (index 1) ordering.
+ */
+ int64_t generations[ 2 ];
+
+ /**
+ * @brief Chain of ready queues with affine threads to determine the highest
+ * priority ready thread.
+ */
+ Chain_Control Affine_queues;
+
+ /**
+ * @brief A table with ready queues.
+ *
+ * The index zero queue is used for threads with a one-to-all processor
+ * affinity. Index one corresponds to processor index zero, and so on.
+ */
+ Scheduler_EDF_SMP_Ready_queue Ready[ RTEMS_ZERO_LENGTH_ARRAY ];
+} Scheduler_EDF_SMP_Context;
+
+#define SCHEDULER_EDF_SMP_ENTRY_POINTS \
+ { \
+ _Scheduler_EDF_SMP_Initialize, \
+ _Scheduler_default_Schedule, \
+ _Scheduler_EDF_SMP_Yield, \
+ _Scheduler_EDF_SMP_Block, \
+ _Scheduler_EDF_SMP_Unblock, \
+ _Scheduler_EDF_SMP_Update_priority, \
+ _Scheduler_EDF_Map_priority, \
+ _Scheduler_EDF_Unmap_priority, \
+ _Scheduler_EDF_SMP_Ask_for_help, \
+ _Scheduler_EDF_SMP_Reconsider_help_request, \
+ _Scheduler_EDF_SMP_Withdraw_node, \
+ _Scheduler_EDF_SMP_Add_processor, \
+ _Scheduler_EDF_SMP_Remove_processor, \
+ _Scheduler_EDF_SMP_Node_initialize, \
+ _Scheduler_default_Node_destroy, \
+ _Scheduler_EDF_Release_job, \
+ _Scheduler_EDF_Cancel_job, \
+ _Scheduler_default_Tick, \
+ _Scheduler_EDF_SMP_Start_idle, \
+ _Scheduler_EDF_SMP_Set_affinity \
+ }
+
+void _Scheduler_EDF_SMP_Initialize( const Scheduler_Control *scheduler );
+
+void _Scheduler_EDF_SMP_Node_initialize(
+ const Scheduler_Control *scheduler,
+ Scheduler_Node *node,
+ Thread_Control *the_thread,
+ Priority_Control priority
+);
+
+void _Scheduler_EDF_SMP_Block(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_EDF_SMP_Unblock(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_EDF_SMP_Update_priority(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+bool _Scheduler_EDF_SMP_Ask_for_help(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_EDF_SMP_Reconsider_help_request(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_EDF_SMP_Withdraw_node(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node,
+ Thread_Scheduler_state next_state
+);
+
+void _Scheduler_EDF_SMP_Add_processor(
+ const Scheduler_Control *scheduler,
+ Thread_Control *idle
+);
+
+Thread_Control *_Scheduler_EDF_SMP_Remove_processor(
+ const Scheduler_Control *scheduler,
+ struct Per_CPU_Control *cpu
+);
+
+void _Scheduler_EDF_SMP_Yield(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_EDF_SMP_Start_idle(
+ const Scheduler_Control *scheduler,
+ Thread_Control *idle,
+ struct Per_CPU_Control *cpu
+);
+
+bool _Scheduler_EDF_SMP_Set_affinity(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node,
+ const Processor_mask *affinity
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTEMS_SCORE_SCHEDULEREDFSMP_H */
diff --git a/cpukit/include/rtems/score/schedulerimpl.h b/cpukit/include/rtems/score/schedulerimpl.h
new file mode 100644
index 0000000000..10c12242a9
--- /dev/null
+++ b/cpukit/include/rtems/score/schedulerimpl.h
@@ -0,0 +1,1203 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines Associated with the Manipulation of the Scheduler
+ *
+ * This inline file contains all of the inlined routines associated with
+ * the manipulation of the scheduler.
+ */
+
+/*
+ * Copyright (C) 2010 Gedare Bloom.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ * Copyright (c) 2014, 2017 embedded brains GmbH
+ *
+ * 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_SCHEDULERIMPL_H
+#define _RTEMS_SCORE_SCHEDULERIMPL_H
+
+#include <rtems/score/scheduler.h>
+#include <rtems/score/assert.h>
+#include <rtems/score/priorityimpl.h>
+#include <rtems/score/smpimpl.h>
+#include <rtems/score/status.h>
+#include <rtems/score/threadimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreScheduler
+ */
+/**@{**/
+
+/**
+ * @brief Maps a priority value to support the append indicator.
+ */
+#define SCHEDULER_PRIORITY_MAP( priority ) ( ( priority ) << 1 )
+
+/**
+ * @brief Returns the plain priority value.
+ */
+#define SCHEDULER_PRIORITY_UNMAP( priority ) ( ( priority ) >> 1 )
+
+/**
+ * @brief Clears the priority append indicator bit.
+ */
+#define SCHEDULER_PRIORITY_PURIFY( priority ) \
+ ( ( priority ) & ~( (Priority_Control) SCHEDULER_PRIORITY_APPEND_FLAG ) )
+
+/**
+ * @brief Returns the priority control with the append indicator bit set.
+ */
+#define SCHEDULER_PRIORITY_APPEND( priority ) \
+ ( ( priority ) | SCHEDULER_PRIORITY_APPEND_FLAG )
+
+/**
+ * @brief Returns true, if the item should be appended to its priority group,
+ * otherwise returns false and the item should be prepended to its priority
+ * group.
+ */
+#define SCHEDULER_PRIORITY_IS_APPEND( priority ) \
+ ( ( ( priority ) & SCHEDULER_PRIORITY_APPEND_FLAG ) != 0 )
+
+/**
+ * @brief Initializes the scheduler to the policy chosen by the user.
+ *
+ * This routine initializes the scheduler to the policy chosen by the user
+ * through confdefs, or to the priority scheduler with ready chains by
+ * default.
+ */
+void _Scheduler_Handler_initialization( void );
+
+RTEMS_INLINE_ROUTINE Scheduler_Context *_Scheduler_Get_context(
+ const Scheduler_Control *scheduler
+)
+{
+ return scheduler->context;
+}
+
+RTEMS_INLINE_ROUTINE const Scheduler_Control *_Scheduler_Get_by_CPU(
+ const Per_CPU_Control *cpu
+)
+{
+#if defined(RTEMS_SMP)
+ return cpu->Scheduler.control;
+#else
+ (void) cpu;
+ return &_Scheduler_Table[ 0 ];
+#endif
+}
+
+/**
+ * @brief Acquires the scheduler instance inside a critical section (interrupts
+ * disabled).
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] lock_context The lock context to use for
+ * _Scheduler_Release_critical().
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Acquire_critical(
+ const Scheduler_Control *scheduler,
+ ISR_lock_Context *lock_context
+)
+{
+#if defined(RTEMS_SMP)
+ Scheduler_Context *context;
+
+ context = _Scheduler_Get_context( scheduler );
+ _ISR_lock_Acquire( &context->Lock, lock_context );
+#else
+ (void) scheduler;
+ (void) lock_context;
+#endif
+}
+
+/**
+ * @brief Releases the scheduler instance inside a critical section (interrupts
+ * disabled).
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] lock_context The lock context used for
+ * _Scheduler_Acquire_critical().
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Release_critical(
+ const Scheduler_Control *scheduler,
+ ISR_lock_Context *lock_context
+)
+{
+#if defined(RTEMS_SMP)
+ Scheduler_Context *context;
+
+ context = _Scheduler_Get_context( scheduler );
+ _ISR_lock_Release( &context->Lock, lock_context );
+#else
+ (void) scheduler;
+ (void) lock_context;
+#endif
+}
+
+#if defined(RTEMS_SMP)
+void _Scheduler_Request_ask_for_help( Thread_Control *the_thread );
+
+/**
+ * @brief Registers an ask for help request if necessary.
+ *
+ * The actual ask for help operation is carried out during
+ * _Thread_Do_dispatch() on a processor related to the thread. This yields a
+ * better separation of scheduler instances. A thread of one scheduler
+ * instance should not be forced to carry out too much work for threads on
+ * other scheduler instances.
+ *
+ * @param[in] the_thread The thread in need for help.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Ask_for_help( Thread_Control *the_thread )
+{
+ _Assert( _Thread_State_is_owner( the_thread ) );
+
+ if ( the_thread->Scheduler.helping_nodes > 0 ) {
+ _Scheduler_Request_ask_for_help( the_thread );
+ }
+}
+#endif
+
+/**
+ * The preferred method to add a new scheduler is to define the jump table
+ * entries and add a case to the _Scheduler_Initialize routine.
+ *
+ * Generic scheduling implementations that rely on the ready queue only can
+ * be found in the _Scheduler_queue_XXX functions.
+ */
+
+/*
+ * Passing the Scheduler_Control* to these functions allows for multiple
+ * scheduler's to exist simultaneously, which could be useful on an SMP
+ * system. Then remote Schedulers may be accessible. How to protect such
+ * accesses remains an open problem.
+ */
+
+/**
+ * @brief General scheduling decision.
+ *
+ * This kernel routine implements the scheduling decision logic for
+ * the scheduler. It does NOT dispatch.
+ *
+ * @param[in] the_thread The thread which state changed previously.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Schedule( Thread_Control *the_thread )
+{
+ const Scheduler_Control *scheduler;
+ ISR_lock_Context lock_context;
+
+ scheduler = _Thread_Scheduler_get_home( the_thread );
+ _Scheduler_Acquire_critical( scheduler, &lock_context );
+
+ ( *scheduler->Operations.schedule )( scheduler, the_thread );
+
+ _Scheduler_Release_critical( scheduler, &lock_context );
+}
+
+/**
+ * @brief Scheduler yield with a particular thread.
+ *
+ * This routine is invoked when a thread wishes to voluntarily transfer control
+ * of the processor to another thread.
+ *
+ * @param[in] the_thread The yielding thread.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Yield( Thread_Control *the_thread )
+{
+ const Scheduler_Control *scheduler;
+ ISR_lock_Context lock_context;
+
+ scheduler = _Thread_Scheduler_get_home( the_thread );
+ _Scheduler_Acquire_critical( scheduler, &lock_context );
+ ( *scheduler->Operations.yield )(
+ scheduler,
+ the_thread,
+ _Thread_Scheduler_get_home_node( the_thread )
+ );
+ _Scheduler_Release_critical( scheduler, &lock_context );
+}
+
+/**
+ * @brief Blocks a thread with respect to the scheduler.
+ *
+ * This routine removes @a the_thread from the scheduling decision for
+ * the scheduler. The primary task is to remove the thread from the
+ * ready queue. It performs any necessary schedulering operations
+ * including the selection of a new heir thread.
+ *
+ * @param[in] the_thread The thread.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Block( Thread_Control *the_thread )
+{
+#if defined(RTEMS_SMP)
+ Chain_Node *node;
+ const Chain_Node *tail;
+ Scheduler_Node *scheduler_node;
+ const Scheduler_Control *scheduler;
+ ISR_lock_Context lock_context;
+
+ node = _Chain_First( &the_thread->Scheduler.Scheduler_nodes );
+ tail = _Chain_Immutable_tail( &the_thread->Scheduler.Scheduler_nodes );
+
+ scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node );
+ scheduler = _Scheduler_Node_get_scheduler( scheduler_node );
+
+ _Scheduler_Acquire_critical( scheduler, &lock_context );
+ ( *scheduler->Operations.block )(
+ scheduler,
+ the_thread,
+ scheduler_node
+ );
+ _Scheduler_Release_critical( scheduler, &lock_context );
+
+ node = _Chain_Next( node );
+
+ while ( node != tail ) {
+ scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node );
+ scheduler = _Scheduler_Node_get_scheduler( scheduler_node );
+
+ _Scheduler_Acquire_critical( scheduler, &lock_context );
+ ( *scheduler->Operations.withdraw_node )(
+ scheduler,
+ the_thread,
+ scheduler_node,
+ THREAD_SCHEDULER_BLOCKED
+ );
+ _Scheduler_Release_critical( scheduler, &lock_context );
+
+ node = _Chain_Next( node );
+ }
+#else
+ const Scheduler_Control *scheduler;
+
+ scheduler = _Thread_Scheduler_get_home( the_thread );
+ ( *scheduler->Operations.block )(
+ scheduler,
+ the_thread,
+ _Thread_Scheduler_get_home_node( the_thread )
+ );
+#endif
+}
+
+/**
+ * @brief Unblocks a thread with respect to the scheduler.
+ *
+ * This operation must fetch the latest thread priority value for this
+ * scheduler instance and update its internal state if necessary.
+ *
+ * @param[in] the_thread The thread.
+ *
+ * @see _Scheduler_Node_get_priority().
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Unblock( Thread_Control *the_thread )
+{
+ const Scheduler_Control *scheduler;
+ ISR_lock_Context lock_context;
+
+ scheduler = _Thread_Scheduler_get_home( the_thread );
+ _Scheduler_Acquire_critical( scheduler, &lock_context );
+ ( *scheduler->Operations.unblock )(
+ scheduler,
+ the_thread,
+ _Thread_Scheduler_get_home_node( the_thread )
+ );
+ _Scheduler_Release_critical( scheduler, &lock_context );
+}
+
+/**
+ * @brief Propagates a priority change of a thread to the scheduler.
+ *
+ * On uni-processor configurations, this operation must evaluate the thread
+ * state. In case the thread is not ready, then the priority update should be
+ * deferred to the next scheduler unblock operation.
+ *
+ * The operation must update the heir and thread dispatch necessary variables
+ * in case the set of scheduled threads changes.
+ *
+ * @param[in] the_thread The thread changing its priority.
+ *
+ * @see _Scheduler_Node_get_priority().
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Update_priority( Thread_Control *the_thread )
+{
+#if defined(RTEMS_SMP)
+ Chain_Node *node;
+ const Chain_Node *tail;
+
+ _Thread_Scheduler_process_requests( the_thread );
+
+ node = _Chain_First( &the_thread->Scheduler.Scheduler_nodes );
+ tail = _Chain_Immutable_tail( &the_thread->Scheduler.Scheduler_nodes );
+
+ do {
+ Scheduler_Node *scheduler_node;
+ const Scheduler_Control *scheduler;
+ ISR_lock_Context lock_context;
+
+ scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node );
+ scheduler = _Scheduler_Node_get_scheduler( scheduler_node );
+
+ _Scheduler_Acquire_critical( scheduler, &lock_context );
+ ( *scheduler->Operations.update_priority )(
+ scheduler,
+ the_thread,
+ scheduler_node
+ );
+ _Scheduler_Release_critical( scheduler, &lock_context );
+
+ node = _Chain_Next( node );
+ } while ( node != tail );
+#else
+ const Scheduler_Control *scheduler;
+
+ scheduler = _Thread_Scheduler_get_home( the_thread );
+ ( *scheduler->Operations.update_priority )(
+ scheduler,
+ the_thread,
+ _Thread_Scheduler_get_home_node( the_thread )
+ );
+#endif
+}
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief Changes the sticky level of the home scheduler node and propagates a
+ * priority change of a thread to the scheduler.
+ *
+ * @param[in] the_thread The thread changing its priority or sticky level.
+ *
+ * @see _Scheduler_Update_priority().
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Priority_and_sticky_update(
+ Thread_Control *the_thread,
+ int sticky_level_change
+)
+{
+ Chain_Node *node;
+ const Chain_Node *tail;
+ Scheduler_Node *scheduler_node;
+ const Scheduler_Control *scheduler;
+ ISR_lock_Context lock_context;
+
+ _Thread_Scheduler_process_requests( the_thread );
+
+ node = _Chain_First( &the_thread->Scheduler.Scheduler_nodes );
+ scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node );
+ scheduler = _Scheduler_Node_get_scheduler( scheduler_node );
+
+ _Scheduler_Acquire_critical( scheduler, &lock_context );
+
+ scheduler_node->sticky_level += sticky_level_change;
+ _Assert( scheduler_node->sticky_level >= 0 );
+
+ ( *scheduler->Operations.update_priority )(
+ scheduler,
+ the_thread,
+ scheduler_node
+ );
+
+ _Scheduler_Release_critical( scheduler, &lock_context );
+
+ tail = _Chain_Immutable_tail( &the_thread->Scheduler.Scheduler_nodes );
+ node = _Chain_Next( node );
+
+ while ( node != tail ) {
+ scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node );
+ scheduler = _Scheduler_Node_get_scheduler( scheduler_node );
+
+ _Scheduler_Acquire_critical( scheduler, &lock_context );
+ ( *scheduler->Operations.update_priority )(
+ scheduler,
+ the_thread,
+ scheduler_node
+ );
+ _Scheduler_Release_critical( scheduler, &lock_context );
+
+ node = _Chain_Next( node );
+ }
+}
+#endif
+
+/**
+ * @brief Maps a thread priority from the user domain to the scheduler domain.
+ *
+ * Let M be the maximum scheduler priority. The mapping must be bijective in
+ * the closed interval [0, M], e.g. _Scheduler_Unmap_priority( scheduler,
+ * _Scheduler_Map_priority( scheduler, p ) ) == p for all p in [0, M]. For
+ * other values the mapping is undefined.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] priority The user domain thread priority.
+ *
+ * @return The corresponding thread priority of the scheduler domain is returned.
+ */
+RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Map_priority(
+ const Scheduler_Control *scheduler,
+ Priority_Control priority
+)
+{
+ return ( *scheduler->Operations.map_priority )( scheduler, priority );
+}
+
+/**
+ * @brief Unmaps a thread priority from the scheduler domain to the user domain.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] priority The scheduler domain thread priority.
+ *
+ * @return The corresponding thread priority of the user domain is returned.
+ */
+RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Unmap_priority(
+ const Scheduler_Control *scheduler,
+ Priority_Control priority
+)
+{
+ return ( *scheduler->Operations.unmap_priority )( scheduler, priority );
+}
+
+/**
+ * @brief Initializes a scheduler node.
+ *
+ * The scheduler node contains arbitrary data on function entry. The caller
+ * must ensure that _Scheduler_Node_destroy() will be called after a
+ * _Scheduler_Node_initialize() before the memory of the scheduler node is
+ * destroyed.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] node The scheduler node to initialize.
+ * @param[in] the_thread The thread of the scheduler node to initialize.
+ * @param[in] priority The thread priority.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Node_initialize(
+ const Scheduler_Control *scheduler,
+ Scheduler_Node *node,
+ Thread_Control *the_thread,
+ Priority_Control priority
+)
+{
+ ( *scheduler->Operations.node_initialize )(
+ scheduler,
+ node,
+ the_thread,
+ priority
+ );
+}
+
+/**
+ * @brief Destroys a scheduler node.
+ *
+ * The caller must ensure that _Scheduler_Node_destroy() will be called only
+ * after a corresponding _Scheduler_Node_initialize().
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] node The scheduler node to destroy.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Node_destroy(
+ const Scheduler_Control *scheduler,
+ Scheduler_Node *node
+)
+{
+ ( *scheduler->Operations.node_destroy )( scheduler, node );
+}
+
+/**
+ * @brief Releases a job of a thread with respect to the scheduler.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] priority_node The priority node of the job.
+ * @param[in] deadline The deadline in watchdog ticks since boot.
+ * @param[in] queue_context The thread queue context to provide the set of
+ * threads for _Thread_Priority_update().
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Release_job(
+ Thread_Control *the_thread,
+ Priority_Node *priority_node,
+ uint64_t deadline,
+ Thread_queue_Context *queue_context
+)
+{
+ const Scheduler_Control *scheduler = _Thread_Scheduler_get_home( the_thread );
+
+ _Thread_queue_Context_clear_priority_updates( queue_context );
+ ( *scheduler->Operations.release_job )(
+ scheduler,
+ the_thread,
+ priority_node,
+ deadline,
+ queue_context
+ );
+}
+
+/**
+ * @brief Cancels a job of a thread with respect to the scheduler.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] priority_node The priority node of the job.
+ * @param[in] queue_context The thread queue context to provide the set of
+ * threads for _Thread_Priority_update().
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Cancel_job(
+ Thread_Control *the_thread,
+ Priority_Node *priority_node,
+ Thread_queue_Context *queue_context
+)
+{
+ const Scheduler_Control *scheduler = _Thread_Scheduler_get_home( the_thread );
+
+ _Thread_queue_Context_clear_priority_updates( queue_context );
+ ( *scheduler->Operations.cancel_job )(
+ scheduler,
+ the_thread,
+ priority_node,
+ queue_context
+ );
+}
+
+/**
+ * @brief Scheduler method invoked at each clock tick.
+ *
+ * This method is invoked at each clock tick to allow the scheduler
+ * implementation to perform any activities required. For the
+ * scheduler which support standard RTEMS features, this includes
+ * time-slicing management.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Tick( const Per_CPU_Control *cpu )
+{
+ const Scheduler_Control *scheduler = _Scheduler_Get_by_CPU( cpu );
+ Thread_Control *executing = cpu->executing;
+
+ if ( scheduler != NULL && executing != NULL ) {
+ ( *scheduler->Operations.tick )( scheduler, executing );
+ }
+}
+
+/**
+ * @brief Starts the idle thread for a particular processor.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in,out] the_thread The idle thread for the processor.
+ * @param[in,out] cpu The processor for the idle thread.
+ *
+ * @see _Thread_Create_idle().
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Start_idle(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Per_CPU_Control *cpu
+)
+{
+ ( *scheduler->Operations.start_idle )( scheduler, the_thread, cpu );
+}
+
+RTEMS_INLINE_ROUTINE bool _Scheduler_Has_processor_ownership(
+ const Scheduler_Control *scheduler,
+ uint32_t cpu_index
+)
+{
+#if defined(RTEMS_SMP)
+ const Per_CPU_Control *cpu;
+ const Scheduler_Control *scheduler_of_cpu;
+
+ cpu = _Per_CPU_Get_by_index( cpu_index );
+ scheduler_of_cpu = _Scheduler_Get_by_CPU( cpu );
+
+ return scheduler_of_cpu == scheduler;
+#else
+ (void) scheduler;
+ (void) cpu_index;
+
+ return true;
+#endif
+}
+
+RTEMS_INLINE_ROUTINE const Processor_mask *_Scheduler_Get_processors(
+ const Scheduler_Control *scheduler
+)
+{
+#if defined(RTEMS_SMP)
+ return &_Scheduler_Get_context( scheduler )->Processors;
+#else
+ return &_Processor_mask_The_one_and_only;
+#endif
+}
+
+bool _Scheduler_Get_affinity(
+ Thread_Control *the_thread,
+ size_t cpusetsize,
+ cpu_set_t *cpuset
+);
+
+RTEMS_INLINE_ROUTINE bool _Scheduler_default_Set_affinity_body(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node,
+ const Processor_mask *affinity
+)
+{
+ (void) scheduler;
+ (void) the_thread;
+ (void) node;
+ return _Processor_mask_Is_subset( affinity, _SMP_Get_online_processors() );
+}
+
+bool _Scheduler_Set_affinity(
+ Thread_Control *the_thread,
+ size_t cpusetsize,
+ const cpu_set_t *cpuset
+);
+
+RTEMS_INLINE_ROUTINE void _Scheduler_Generic_block(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node,
+ void ( *extract )(
+ const Scheduler_Control *,
+ Thread_Control *,
+ Scheduler_Node *
+ ),
+ void ( *schedule )(
+ const Scheduler_Control *,
+ Thread_Control *,
+ bool
+ )
+)
+{
+ ( *extract )( scheduler, the_thread, node );
+
+ /* TODO: flash critical section? */
+
+ if ( _Thread_Is_executing( the_thread ) || _Thread_Is_heir( the_thread ) ) {
+ ( *schedule )( scheduler, the_thread, true );
+ }
+}
+
+RTEMS_INLINE_ROUTINE uint32_t _Scheduler_Get_processor_count(
+ const Scheduler_Control *scheduler
+)
+{
+#if defined(RTEMS_SMP)
+ const Scheduler_Context *context = _Scheduler_Get_context( scheduler );
+
+ return _Processor_mask_Count( &context->Processors );
+#else
+ (void) scheduler;
+
+ return 1;
+#endif
+}
+
+RTEMS_INLINE_ROUTINE Objects_Id _Scheduler_Build_id( uint32_t scheduler_index )
+{
+ return _Objects_Build_id(
+ OBJECTS_FAKE_OBJECTS_API,
+ OBJECTS_FAKE_OBJECTS_SCHEDULERS,
+ _Objects_Local_node,
+ (uint16_t) ( scheduler_index + 1 )
+ );
+}
+
+RTEMS_INLINE_ROUTINE uint32_t _Scheduler_Get_index_by_id( Objects_Id id )
+{
+ uint32_t minimum_id = _Scheduler_Build_id( 0 );
+
+ return id - minimum_id;
+}
+
+RTEMS_INLINE_ROUTINE const Scheduler_Control *_Scheduler_Get_by_id(
+ Objects_Id id
+)
+{
+ uint32_t index;
+
+ index = _Scheduler_Get_index_by_id( id );
+
+ if ( index >= _Scheduler_Count ) {
+ return NULL;
+ }
+
+ return &_Scheduler_Table[ index ];
+}
+
+RTEMS_INLINE_ROUTINE uint32_t _Scheduler_Get_index(
+ const Scheduler_Control *scheduler
+)
+{
+ return (uint32_t) (scheduler - &_Scheduler_Table[ 0 ]);
+}
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief Gets an idle thread from the scheduler instance.
+ *
+ * @param[in] context The scheduler instance context.
+ *
+ * @retval idle An idle thread for use. This function must always return an
+ * idle thread. If none is available, then this is a fatal error.
+ */
+typedef Thread_Control *( *Scheduler_Get_idle_thread )(
+ Scheduler_Context *context
+);
+
+/**
+ * @brief Releases an idle thread to the scheduler instance for reuse.
+ *
+ * @param[in] context The scheduler instance context.
+ * @param[in] idle The idle thread to release
+ */
+typedef void ( *Scheduler_Release_idle_thread )(
+ Scheduler_Context *context,
+ Thread_Control *idle
+);
+
+RTEMS_INLINE_ROUTINE void _Scheduler_Thread_change_state(
+ Thread_Control *the_thread,
+ Thread_Scheduler_state new_state
+)
+{
+ _Assert(
+ _ISR_lock_Is_owner( &the_thread->Scheduler.Lock )
+ || the_thread->Scheduler.state == THREAD_SCHEDULER_BLOCKED
+ || !_System_state_Is_up( _System_state_Get() )
+ );
+
+ the_thread->Scheduler.state = new_state;
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_Set_idle_thread(
+ Scheduler_Node *node,
+ Thread_Control *idle
+)
+{
+ _Assert( _Scheduler_Node_get_idle( node ) == NULL );
+ _Assert(
+ _Scheduler_Node_get_owner( node ) == _Scheduler_Node_get_user( node )
+ );
+
+ _Scheduler_Node_set_user( node, idle );
+ node->idle = idle;
+}
+
+/**
+ * @brief Use an idle thread for this scheduler node.
+ *
+ * A thread those home scheduler node has a sticky level greater than zero may
+ * use an idle thread in the home scheduler instance in case it executes
+ * currently in another scheduler instance or in case it is in a blocking
+ * state.
+ *
+ * @param[in] context The scheduler instance context.
+ * @param[in] node The node which wants to use the idle thread.
+ * @param[in] cpu The processor for the idle thread.
+ * @param[in] get_idle_thread Function to get an idle thread.
+ */
+RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Use_idle_thread(
+ Scheduler_Context *context,
+ Scheduler_Node *node,
+ Per_CPU_Control *cpu,
+ Scheduler_Get_idle_thread get_idle_thread
+)
+{
+ Thread_Control *idle = ( *get_idle_thread )( context );
+
+ _Scheduler_Set_idle_thread( node, idle );
+ _Thread_Set_CPU( idle, cpu );
+ return idle;
+}
+
+typedef enum {
+ SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE,
+ SCHEDULER_TRY_TO_SCHEDULE_DO_IDLE_EXCHANGE,
+ SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK
+} Scheduler_Try_to_schedule_action;
+
+/**
+ * @brief Try to schedule this scheduler node.
+ *
+ * @param[in] context The scheduler instance context.
+ * @param[in] node The node which wants to get scheduled.
+ * @param[in] idle A potential idle thread used by a potential victim node.
+ * @param[in] get_idle_thread Function to get an idle thread.
+ *
+ * @retval true This node can be scheduled.
+ * @retval false Otherwise.
+ */
+RTEMS_INLINE_ROUTINE Scheduler_Try_to_schedule_action
+_Scheduler_Try_to_schedule_node(
+ Scheduler_Context *context,
+ Scheduler_Node *node,
+ Thread_Control *idle,
+ Scheduler_Get_idle_thread get_idle_thread
+)
+{
+ ISR_lock_Context lock_context;
+ Scheduler_Try_to_schedule_action action;
+ Thread_Control *owner;
+
+ action = SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE;
+ owner = _Scheduler_Node_get_owner( node );
+ _Assert( _Scheduler_Node_get_user( node ) == owner );
+ _Assert( _Scheduler_Node_get_idle( node ) == NULL );
+
+ _Thread_Scheduler_acquire_critical( owner, &lock_context );
+
+ if ( owner->Scheduler.state == THREAD_SCHEDULER_READY ) {
+ _Thread_Scheduler_cancel_need_for_help( owner, _Thread_Get_CPU( owner ) );
+ _Scheduler_Thread_change_state( owner, THREAD_SCHEDULER_SCHEDULED );
+ } else if (
+ owner->Scheduler.state == THREAD_SCHEDULER_SCHEDULED
+ && node->sticky_level <= 1
+ ) {
+ action = SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK;
+ } else if ( node->sticky_level == 0 ) {
+ action = SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK;
+ } else if ( idle != NULL ) {
+ action = SCHEDULER_TRY_TO_SCHEDULE_DO_IDLE_EXCHANGE;
+ } else {
+ _Scheduler_Use_idle_thread(
+ context,
+ node,
+ _Thread_Get_CPU( owner ),
+ get_idle_thread
+ );
+ }
+
+ _Thread_Scheduler_release_critical( owner, &lock_context );
+ return action;
+}
+
+/**
+ * @brief Release an idle thread using this scheduler node.
+ *
+ * @param[in] context The scheduler instance context.
+ * @param[in] node The node which may have an idle thread as user.
+ * @param[in] release_idle_thread Function to release an idle thread.
+ *
+ * @retval idle The idle thread which used this node.
+ * @retval NULL This node had no idle thread as an user.
+ */
+RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Release_idle_thread(
+ Scheduler_Context *context,
+ Scheduler_Node *node,
+ Scheduler_Release_idle_thread release_idle_thread
+)
+{
+ Thread_Control *idle = _Scheduler_Node_get_idle( node );
+
+ if ( idle != NULL ) {
+ Thread_Control *owner = _Scheduler_Node_get_owner( node );
+
+ node->idle = NULL;
+ _Scheduler_Node_set_user( node, owner );
+ ( *release_idle_thread )( context, idle );
+ }
+
+ return idle;
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_Exchange_idle_thread(
+ Scheduler_Node *needs_idle,
+ Scheduler_Node *uses_idle,
+ Thread_Control *idle
+)
+{
+ uses_idle->idle = NULL;
+ _Scheduler_Node_set_user(
+ uses_idle,
+ _Scheduler_Node_get_owner( uses_idle )
+ );
+ _Scheduler_Set_idle_thread( needs_idle, idle );
+}
+
+/**
+ * @brief Block this scheduler node.
+ *
+ * @param[in] context The scheduler instance context.
+ * @param[in] thread The thread which wants to get blocked referencing this
+ * node. This is not necessarily the user of this node in case the node
+ * participates in the scheduler helping protocol.
+ * @param[in] node The node which wants to get blocked.
+ * @param[in] is_scheduled This node is scheduled.
+ * @param[in] get_idle_thread Function to get an idle thread.
+ *
+ * @retval thread_cpu The processor of the thread. Indicates to continue with
+ * the blocking operation.
+ * @retval NULL Otherwise.
+ */
+RTEMS_INLINE_ROUTINE Per_CPU_Control *_Scheduler_Block_node(
+ Scheduler_Context *context,
+ Thread_Control *thread,
+ Scheduler_Node *node,
+ bool is_scheduled,
+ Scheduler_Get_idle_thread get_idle_thread
+)
+{
+ int sticky_level;
+ ISR_lock_Context lock_context;
+ Per_CPU_Control *thread_cpu;
+
+ sticky_level = node->sticky_level;
+ --sticky_level;
+ node->sticky_level = sticky_level;
+ _Assert( sticky_level >= 0 );
+
+ _Thread_Scheduler_acquire_critical( thread, &lock_context );
+ thread_cpu = _Thread_Get_CPU( thread );
+ _Thread_Scheduler_cancel_need_for_help( thread, thread_cpu );
+ _Scheduler_Thread_change_state( thread, THREAD_SCHEDULER_BLOCKED );
+ _Thread_Scheduler_release_critical( thread, &lock_context );
+
+ if ( sticky_level > 0 ) {
+ if ( is_scheduled && _Scheduler_Node_get_idle( node ) == NULL ) {
+ Thread_Control *idle;
+
+ idle = _Scheduler_Use_idle_thread(
+ context,
+ node,
+ thread_cpu,
+ get_idle_thread
+ );
+ _Thread_Dispatch_update_heir( _Per_CPU_Get(), thread_cpu, idle );
+ }
+
+ return NULL;
+ }
+
+ _Assert( thread == _Scheduler_Node_get_user( node ) );
+ return thread_cpu;
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_Discard_idle_thread(
+ Scheduler_Context *context,
+ Thread_Control *the_thread,
+ Scheduler_Node *node,
+ Scheduler_Release_idle_thread release_idle_thread
+)
+{
+ Thread_Control *idle;
+ Thread_Control *owner;
+ Per_CPU_Control *cpu;
+
+ idle = _Scheduler_Node_get_idle( node );
+ owner = _Scheduler_Node_get_owner( node );
+
+ node->idle = NULL;
+ _Assert( _Scheduler_Node_get_user( node ) == idle );
+ _Scheduler_Node_set_user( node, owner );
+ ( *release_idle_thread )( context, idle );
+
+ cpu = _Thread_Get_CPU( idle );
+ _Thread_Set_CPU( the_thread, cpu );
+ _Thread_Dispatch_update_heir( _Per_CPU_Get(), cpu, the_thread );
+}
+
+/**
+ * @brief Unblock this scheduler node.
+ *
+ * @param[in] context The scheduler instance context.
+ * @param[in] the_thread The thread which wants to get unblocked.
+ * @param[in] node The node which wants to get unblocked.
+ * @param[in] is_scheduled This node is scheduled.
+ * @param[in] release_idle_thread Function to release an idle thread.
+ *
+ * @retval true Continue with the unblocking operation.
+ * @retval false Otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Scheduler_Unblock_node(
+ Scheduler_Context *context,
+ Thread_Control *the_thread,
+ Scheduler_Node *node,
+ bool is_scheduled,
+ Scheduler_Release_idle_thread release_idle_thread
+)
+{
+ bool unblock;
+
+ ++node->sticky_level;
+ _Assert( node->sticky_level > 0 );
+
+ if ( is_scheduled ) {
+ _Scheduler_Discard_idle_thread(
+ context,
+ the_thread,
+ node,
+ release_idle_thread
+ );
+ _Scheduler_Thread_change_state( the_thread, THREAD_SCHEDULER_SCHEDULED );
+ unblock = false;
+ } else {
+ _Scheduler_Thread_change_state( the_thread, THREAD_SCHEDULER_READY );
+ unblock = true;
+ }
+
+ return unblock;
+}
+#endif
+
+RTEMS_INLINE_ROUTINE void _Scheduler_Update_heir(
+ Thread_Control *new_heir,
+ bool force_dispatch
+)
+{
+ Thread_Control *heir = _Thread_Heir;
+
+ if ( heir != new_heir && ( heir->is_preemptible || force_dispatch ) ) {
+#if defined(RTEMS_SMP)
+ /*
+ * We need this state only for _Thread_Get_CPU_time_used(). Cannot use
+ * _Scheduler_Thread_change_state() since THREAD_SCHEDULER_BLOCKED to
+ * THREAD_SCHEDULER_BLOCKED state changes are illegal for the real SMP
+ * schedulers.
+ */
+ heir->Scheduler.state = THREAD_SCHEDULER_BLOCKED;
+ new_heir->Scheduler.state = THREAD_SCHEDULER_SCHEDULED;
+#endif
+ _Thread_Update_CPU_time_used( heir, _Thread_Get_CPU( heir ) );
+ _Thread_Heir = new_heir;
+ _Thread_Dispatch_necessary = true;
+ }
+}
+
+RTEMS_INLINE_ROUTINE Status_Control _Scheduler_Set(
+ const Scheduler_Control *new_scheduler,
+ Thread_Control *the_thread,
+ Priority_Control priority
+)
+{
+ Scheduler_Node *new_scheduler_node;
+ Scheduler_Node *old_scheduler_node;
+#if defined(RTEMS_SMP)
+ ISR_lock_Context lock_context;
+ const Scheduler_Control *old_scheduler;
+
+#endif
+
+ if ( the_thread->Wait.queue != NULL ) {
+ return STATUS_RESOURCE_IN_USE;
+ }
+
+ old_scheduler_node = _Thread_Scheduler_get_home_node( the_thread );
+ _Priority_Plain_extract(
+ &old_scheduler_node->Wait.Priority,
+ &the_thread->Real_priority
+ );
+
+ if ( !_Priority_Is_empty( &old_scheduler_node->Wait.Priority ) ) {
+ _Priority_Plain_insert(
+ &old_scheduler_node->Wait.Priority,
+ &the_thread->Real_priority,
+ the_thread->Real_priority.priority
+ );
+ return STATUS_RESOURCE_IN_USE;
+ }
+
+#if defined(RTEMS_SMP)
+ if ( !_Chain_Has_only_one_node( &the_thread->Scheduler.Wait_nodes ) ) {
+ _Priority_Plain_insert(
+ &old_scheduler_node->Wait.Priority,
+ &the_thread->Real_priority,
+ the_thread->Real_priority.priority
+ );
+ return STATUS_RESOURCE_IN_USE;
+ }
+
+ old_scheduler = _Thread_Scheduler_get_home( the_thread );
+ new_scheduler_node = _Thread_Scheduler_get_node_by_index(
+ the_thread,
+ _Scheduler_Get_index( new_scheduler )
+ );
+
+ _Scheduler_Acquire_critical( new_scheduler, &lock_context );
+
+ if (
+ _Scheduler_Get_processor_count( new_scheduler ) == 0
+ || !( *new_scheduler->Operations.set_affinity )(
+ new_scheduler,
+ the_thread,
+ new_scheduler_node,
+ &the_thread->Scheduler.Affinity
+ )
+ ) {
+ _Scheduler_Release_critical( new_scheduler, &lock_context );
+ _Priority_Plain_insert(
+ &old_scheduler_node->Wait.Priority,
+ &the_thread->Real_priority,
+ the_thread->Real_priority.priority
+ );
+ return STATUS_UNSATISFIED;
+ }
+
+ the_thread->Scheduler.home = new_scheduler;
+
+ _Scheduler_Release_critical( new_scheduler, &lock_context );
+
+ _Thread_Scheduler_process_requests( the_thread );
+#else
+ new_scheduler_node = old_scheduler_node;
+#endif
+
+ the_thread->Start.initial_priority = priority;
+ _Priority_Node_set_priority( &the_thread->Real_priority, priority );
+ _Priority_Initialize_one(
+ &new_scheduler_node->Wait.Priority,
+ &the_thread->Real_priority
+ );
+
+#if defined(RTEMS_SMP)
+ if ( old_scheduler != new_scheduler ) {
+ States_Control current_state;
+
+ current_state = the_thread->current_state;
+
+ if ( _States_Is_ready( current_state ) ) {
+ _Scheduler_Block( the_thread );
+ }
+
+ _Assert( old_scheduler_node->sticky_level == 0 );
+ _Assert( new_scheduler_node->sticky_level == 0 );
+
+ _Chain_Extract_unprotected( &old_scheduler_node->Thread.Wait_node );
+ _Assert( _Chain_Is_empty( &the_thread->Scheduler.Wait_nodes ) );
+ _Chain_Initialize_one(
+ &the_thread->Scheduler.Wait_nodes,
+ &new_scheduler_node->Thread.Wait_node
+ );
+ _Chain_Extract_unprotected(
+ &old_scheduler_node->Thread.Scheduler_node.Chain
+ );
+ _Assert( _Chain_Is_empty( &the_thread->Scheduler.Scheduler_nodes ) );
+ _Chain_Initialize_one(
+ &the_thread->Scheduler.Scheduler_nodes,
+ &new_scheduler_node->Thread.Scheduler_node.Chain
+ );
+
+ _Scheduler_Node_set_priority( new_scheduler_node, priority, false );
+
+ if ( _States_Is_ready( current_state ) ) {
+ _Scheduler_Unblock( the_thread );
+ }
+
+ return STATUS_SUCCESSFUL;
+ }
+#endif
+
+ _Scheduler_Node_set_priority( new_scheduler_node, priority, false );
+ _Scheduler_Update_priority( the_thread );
+ return STATUS_SUCCESSFUL;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/schedulernode.h b/cpukit/include/rtems/score/schedulernode.h
new file mode 100644
index 0000000000..d62e983853
--- /dev/null
+++ b/cpukit/include/rtems/score/schedulernode.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_SCHEDULERNODE_H
+#define _RTEMS_SCORE_SCHEDULERNODE_H
+
+#include <rtems/score/basedefs.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/smplockseq.h>
+
+struct _Thread_Control;
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief The scheduler node requests.
+ */
+typedef enum {
+ /**
+ * @brief The scheduler node is not on the list of pending requests.
+ */
+ SCHEDULER_NODE_REQUEST_NOT_PENDING,
+
+ /**
+ * @brief There is a pending scheduler node request to add this scheduler
+ * node to the Thread_Control::Scheduler::Scheduler_nodes chain.
+ */
+ SCHEDULER_NODE_REQUEST_ADD,
+
+ /**
+ * @brief There is a pending scheduler node request to remove this scheduler
+ * node from the Thread_Control::Scheduler::Scheduler_nodes chain.
+ */
+ SCHEDULER_NODE_REQUEST_REMOVE,
+
+ /**
+ * @brief The scheduler node is on the list of pending requests, but nothing
+ * should change.
+ */
+ SCHEDULER_NODE_REQUEST_NOTHING,
+
+} Scheduler_Node_request;
+#endif
+
+typedef struct Scheduler_Node Scheduler_Node;
+
+/**
+ * @brief Scheduler node for per-thread data.
+ */
+struct Scheduler_Node {
+#if defined(RTEMS_SMP)
+ /**
+ * @brief Chain node for usage in various scheduler data structures.
+ *
+ * Strictly, this is the wrong place for this field since the data structures
+ * to manage scheduler nodes belong to the particular scheduler
+ * implementation. Currently, all SMP scheduler implementations use chains
+ * or red-black trees. The node is here to simplify things, just like the
+ * object node in the thread control block.
+ */
+ union {
+ Chain_Node Chain;
+ RBTree_Node RBTree;
+ } Node;
+
+ /**
+ * @brief The sticky level determines if this scheduler node should use an
+ * idle thread in case this node is scheduled and the owner thread is
+ * blocked.
+ */
+ int sticky_level;
+
+ /**
+ * @brief The thread using this node.
+ *
+ * This is either the owner or an idle thread.
+ */
+ struct _Thread_Control *user;
+
+ /**
+ * @brief The idle thread claimed by this node in case the sticky level is
+ * greater than zero and the thread is block or is scheduled on another
+ * scheduler instance.
+ *
+ * This is necessary to ensure the priority ceiling protocols work across
+ * scheduler boundaries.
+ */
+ struct _Thread_Control *idle;
+#endif
+
+ /**
+ * @brief The thread owning this node.
+ */
+ struct _Thread_Control *owner;
+
+#if defined(RTEMS_SMP)
+ /**
+ * @brief Block to register and manage this scheduler node in the thread
+ * control block of the owner of this scheduler node.
+ */
+ struct {
+ /**
+ * @brief Node to add this scheduler node to
+ * Thread_Control::Scheduler::Wait_nodes.
+ */
+ Chain_Node Wait_node;
+
+ /**
+ * @brief Node to add this scheduler node to
+ * Thread_Control::Scheduler::Scheduler_nodes or a temporary remove list.
+ */
+ union {
+ /**
+ * @brief The node for Thread_Control::Scheduler::Scheduler_nodes.
+ */
+ Chain_Node Chain;
+
+ /**
+ * @brief The next pointer for a temporary remove list.
+ *
+ * @see _Thread_Scheduler_process_requests().
+ */
+ Scheduler_Node *next;
+ } Scheduler_node;
+
+ /**
+ * @brief Link to the next scheduler node in the
+ * Thread_Control::Scheduler::requests list.
+ */
+ Scheduler_Node *next_request;
+
+ /**
+ * @brief The current scheduler node request.
+ */
+ Scheduler_Node_request request;
+ } Thread;
+#endif
+
+ /**
+ * @brief Thread wait support block.
+ */
+ struct {
+ Priority_Aggregation Priority;
+ } Wait;
+
+ /**
+ * @brief The thread priority information used by the scheduler.
+ *
+ * The thread priority is manifest in two independent areas. One area is the
+ * user visible thread priority along with a potential thread queue. The
+ * other is the scheduler. During a thread priority change, the user visible
+ * thread priority and the thread queue are first updated and the thread
+ * priority value here is changed. Once this is done the scheduler is
+ * notified via the update priority operation, so that it can update its
+ * internal state and honour a new thread priority value.
+ */
+ struct {
+ /**
+ * @brief The thread priority value of this scheduler node.
+ *
+ * The producer of this value is _Thread_Change_priority(). The consumer
+ * is the scheduler via the unblock and update priority operations.
+ *
+ * This priority control consists of two parts. One part is the plain
+ * priority value (most-significant 63 bits). The other part is the
+ * least-significant bit which indicates if the thread should be appended
+ * (bit set) or prepended (bit cleared) to its priority group, see
+ * SCHEDULER_PRIORITY_APPEND().
+ */
+ Priority_Control value;
+
+#if defined(RTEMS_SMP)
+ /**
+ * @brief Sequence lock to synchronize priority value updates.
+ */
+ SMP_sequence_lock_Control Lock;
+#endif
+ } Priority;
+};
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief The size of a scheduler node.
+ *
+ * This value is provided via <rtems/confdefs.h>.
+ */
+extern const size_t _Scheduler_Node_size;
+#endif
+
+#if defined(RTEMS_SMP)
+#define SCHEDULER_NODE_OF_THREAD_WAIT_NODE( node ) \
+ RTEMS_CONTAINER_OF( node, Scheduler_Node, Thread.Wait_node )
+
+#define SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node ) \
+ RTEMS_CONTAINER_OF( node, Scheduler_Node, Thread.Scheduler_node.Chain )
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_SCHEDULERNODE_H */
diff --git a/cpukit/include/rtems/score/schedulernodeimpl.h b/cpukit/include/rtems/score/schedulernodeimpl.h
new file mode 100644
index 0000000000..8997b3f218
--- /dev/null
+++ b/cpukit/include/rtems/score/schedulernodeimpl.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2014, 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_SCHEDULERNODEIMPL_H
+#define _RTEMS_SCORE_SCHEDULERNODEIMPL_H
+
+#include <rtems/score/schedulernode.h>
+#include <rtems/score/priorityimpl.h>
+
+struct _Scheduler_Control;
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define SCHEDULER_NODE_OF_WAIT_PRIORITY_NODE( node ) \
+ RTEMS_CONTAINER_OF( node, Scheduler_Node, Wait.Priority.Node.Node.Chain )
+
+#define SCHEDULER_NODE_OF_WAIT_PRIORITY( node ) \
+ RTEMS_CONTAINER_OF( node, Scheduler_Node, Wait.Priority )
+
+/**
+ * @brief Priority append indicator for the priority control used for the
+ * scheduler node priority.
+ */
+#define SCHEDULER_PRIORITY_APPEND_FLAG 1
+
+RTEMS_INLINE_ROUTINE void _Scheduler_Node_do_initialize(
+ const struct _Scheduler_Control *scheduler,
+ Scheduler_Node *node,
+ Thread_Control *the_thread,
+ Priority_Control priority
+)
+{
+ node->owner = the_thread;
+
+ node->Priority.value = priority;
+
+#if defined(RTEMS_SMP)
+ _Chain_Initialize_node( &node->Thread.Wait_node );
+ node->Wait.Priority.scheduler = scheduler;
+ node->user = the_thread;
+ node->idle = NULL;
+ _SMP_sequence_lock_Initialize( &node->Priority.Lock );
+#else
+ (void) scheduler;
+ (void) the_thread;
+#endif
+}
+
+RTEMS_INLINE_ROUTINE const Scheduler_Control *_Scheduler_Node_get_scheduler(
+ const Scheduler_Node *node
+)
+{
+ return _Priority_Get_scheduler( &node->Wait.Priority );
+}
+
+RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_owner(
+ const Scheduler_Node *node
+)
+{
+ return node->owner;
+}
+
+RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Node_get_priority(
+ Scheduler_Node *node
+)
+{
+ Priority_Control priority;
+
+#if defined(RTEMS_SMP)
+ unsigned int seq;
+
+ do {
+ seq = _SMP_sequence_lock_Read_begin( &node->Priority.Lock );
+#endif
+
+ priority = node->Priority.value;
+
+#if defined(RTEMS_SMP)
+ } while ( _SMP_sequence_lock_Read_retry( &node->Priority.Lock, seq ) );
+#endif
+
+ return priority;
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_Node_set_priority(
+ Scheduler_Node *node,
+ Priority_Control new_priority,
+ bool prepend_it
+)
+{
+#if defined(RTEMS_SMP)
+ unsigned int seq;
+
+ seq = _SMP_sequence_lock_Write_begin( &node->Priority.Lock );
+#endif
+
+ new_priority |= ( prepend_it ? 0 : SCHEDULER_PRIORITY_APPEND_FLAG );
+ node->Priority.value = new_priority;
+
+#if defined(RTEMS_SMP)
+ _SMP_sequence_lock_Write_end( &node->Priority.Lock, seq );
+#endif
+}
+
+#if defined(RTEMS_SMP)
+RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_user(
+ const Scheduler_Node *node
+)
+{
+ return node->user;
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_Node_set_user(
+ Scheduler_Node *node,
+ Thread_Control *user
+)
+{
+ node->user = user;
+}
+
+RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_idle(
+ const Scheduler_Node *node
+)
+{
+ return node->idle;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_SCHEDULERNODEIMPL_H */
diff --git a/cpukit/include/rtems/score/schedulerpriority.h b/cpukit/include/rtems/score/schedulerpriority.h
new file mode 100644
index 0000000000..f5ae66102d
--- /dev/null
+++ b/cpukit/include/rtems/score/schedulerpriority.h
@@ -0,0 +1,163 @@
+/**
+ * @file rtems/score/schedulerpriority.h
+ *
+ * @brief Thread Manipulation with the Priority-Based Scheduler
+ *
+ * This include file contains all the constants and structures associated
+ * with the manipulation of threads for the priority-based scheduler.
+ */
+
+/*
+ * Copryight (c) 2010 Gedare Bloom.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * 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_SCHEDULERPRIORITY_H
+#define _RTEMS_SCORE_SCHEDULERPRIORITY_H
+
+#include <rtems/score/chain.h>
+#include <rtems/score/prioritybitmap.h>
+#include <rtems/score/scheduler.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreSchedulerDPS Deterministic Priority Scheduler
+ *
+ * @ingroup ScoreScheduler
+ */
+/**@{*/
+
+/**
+ * Entry points for the Deterministic Priority Based Scheduler.
+ */
+#define SCHEDULER_PRIORITY_ENTRY_POINTS \
+ { \
+ _Scheduler_priority_Initialize, /* initialize entry point */ \
+ _Scheduler_priority_Schedule, /* schedule entry point */ \
+ _Scheduler_priority_Yield, /* yield entry point */ \
+ _Scheduler_priority_Block, /* block entry point */ \
+ _Scheduler_priority_Unblock, /* unblock entry point */ \
+ _Scheduler_priority_Update_priority, /* update priority entry point */ \
+ _Scheduler_default_Map_priority, /* map priority entry point */ \
+ _Scheduler_default_Unmap_priority, /* unmap priority entry point */ \
+ SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
+ _Scheduler_priority_Node_initialize, /* node initialize entry point */ \
+ _Scheduler_default_Node_destroy, /* node destroy entry point */ \
+ _Scheduler_default_Release_job, /* new period of task */ \
+ _Scheduler_default_Cancel_job, /* cancel period of task */ \
+ _Scheduler_default_Tick, /* tick entry point */ \
+ _Scheduler_default_Start_idle /* start idle entry point */ \
+ SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY \
+ }
+
+typedef struct {
+ /**
+ * @brief Basic scheduler context.
+ */
+ Scheduler_Context Base;
+
+ /**
+ * @brief Bit map to indicate non-empty ready queues.
+ */
+ Priority_bit_map_Control Bit_map;
+
+ /**
+ * @brief One ready queue per priority level.
+ */
+ Chain_Control Ready[ 0 ];
+} Scheduler_priority_Context;
+
+/**
+ * @brief Data for ready queue operations.
+ */
+typedef struct {
+ /**
+ * @brief The thread priority currently used by the scheduler.
+ */
+ unsigned int current_priority;
+
+ /** This field points to the Ready FIFO for this thread's priority. */
+ Chain_Control *ready_chain;
+
+ /** This field contains precalculated priority map indices. */
+ Priority_bit_map_Information Priority_map;
+} Scheduler_priority_Ready_queue;
+
+/**
+ * @brief Scheduler node specialization for Deterministic Priority schedulers.
+ */
+typedef struct {
+ /**
+ * @brief Basic scheduler node.
+ */
+ Scheduler_Node Base;
+
+ /**
+ * @brief The associated ready queue of this node.
+ */
+ Scheduler_priority_Ready_queue Ready_queue;
+} Scheduler_priority_Node;
+
+/**
+ * @brief Initializes the priority scheduler.
+ * This routine initializes the priority scheduler.
+ */
+void _Scheduler_priority_Initialize( const Scheduler_Control *scheduler );
+
+void _Scheduler_priority_Block(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+/**
+ * @brief Sets the heir thread to be the next ready thread.
+ *
+ * This kernel routine sets the heir thread to be the next ready thread
+ * by invoking the_scheduler->ready_queue->operations->first().
+ */
+void _Scheduler_priority_Schedule(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+);
+
+void _Scheduler_priority_Unblock(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_priority_Update_priority(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *base_node
+);
+
+void _Scheduler_priority_Node_initialize(
+ const Scheduler_Control *scheduler,
+ Scheduler_Node *node,
+ Thread_Control *the_thread,
+ Priority_Control priority
+);
+
+void _Scheduler_priority_Yield(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/schedulerpriorityaffinitysmp.h b/cpukit/include/rtems/score/schedulerpriorityaffinitysmp.h
new file mode 100644
index 0000000000..d988d5752a
--- /dev/null
+++ b/cpukit/include/rtems/score/schedulerpriorityaffinitysmp.h
@@ -0,0 +1,181 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSchedulerPriorityAffinitySMP
+ *
+ * @brief Deterministic Priority Affinity SMP Scheduler API
+ */
+
+/*
+ * COPYRIGHT (c) 2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_SCHEDULERPRIORITYAFFINITYSMP_H
+#define _RTEMS_SCORE_SCHEDULERPRIORITYAFFINITYSMP_H
+
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/schedulersmp.h>
+#include <rtems/score/schedulerprioritysmp.h>
+
+#include <sys/cpuset.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ScoreSchedulerPriorityAffinitySMP Deterministic Priority Affinity SMP Scheduler
+ *
+ * @ingroup ScoreSchedulerPrioritySMP
+ *
+ * This is an extension of the Deterministic Priority SMP Scheduler. which
+ * is an implementation of the global fixed priority scheduler (G-FP).
+ * It adds thread to core affinity support.
+ *
+ * @note This is the first iteration of this scheduler. It currently tracks
+ * the requested affinity to exercise the Scheduler Framework but it
+ * does not honor that affinity in assigning threads to cores. This
+ * will be added in a subsequent revision.
+ * @{
+ */
+
+/**
+ * @brief Entry points for the Deterministic Priority Affinity SMP Scheduler.
+ */
+#define SCHEDULER_PRIORITY_AFFINITY_SMP_ENTRY_POINTS \
+ { \
+ _Scheduler_priority_SMP_Initialize, \
+ _Scheduler_default_Schedule, \
+ _Scheduler_priority_SMP_Yield, \
+ _Scheduler_priority_affinity_SMP_Block, \
+ _Scheduler_priority_affinity_SMP_Unblock, \
+ _Scheduler_priority_affinity_SMP_Update_priority, \
+ _Scheduler_default_Map_priority, \
+ _Scheduler_default_Unmap_priority, \
+ _Scheduler_priority_affinity_SMP_Ask_for_help, \
+ _Scheduler_priority_affinity_SMP_Reconsider_help_request, \
+ _Scheduler_priority_affinity_SMP_Withdraw_node, \
+ _Scheduler_priority_affinity_SMP_Add_processor, \
+ _Scheduler_priority_affinity_SMP_Remove_processor, \
+ _Scheduler_priority_affinity_SMP_Node_initialize, \
+ _Scheduler_default_Node_destroy, \
+ _Scheduler_default_Release_job, \
+ _Scheduler_default_Cancel_job, \
+ _Scheduler_default_Tick, \
+ _Scheduler_SMP_Start_idle, \
+ _Scheduler_priority_affinity_SMP_Set_affinity \
+ }
+
+/**
+ * @brief Initializes per thread scheduler information
+ *
+ * This routine allocates @a thread->scheduler.
+ *
+ * @param[in] scheduler points to the scheduler specific information.
+ * @param[in] node is the node the scheduler is allocating
+ * management memory for.
+ * @param[in] the_thread the thread of the node.
+ * @param[in] priority is the thread priority.
+ */
+void _Scheduler_priority_affinity_SMP_Node_initialize(
+ const Scheduler_Control *scheduler,
+ Scheduler_Node *node,
+ Thread_Control *the_thread,
+ Priority_Control priority
+);
+
+void _Scheduler_priority_affinity_SMP_Block(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_priority_affinity_SMP_Unblock(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_priority_affinity_SMP_Update_priority(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+bool _Scheduler_priority_affinity_SMP_Ask_for_help(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_priority_affinity_SMP_Reconsider_help_request(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_priority_affinity_SMP_Withdraw_node(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node,
+ Thread_Scheduler_state next_state
+);
+
+void _Scheduler_priority_affinity_SMP_Add_processor(
+ const Scheduler_Control *scheduler,
+ Thread_Control *idle
+);
+
+Thread_Control *_Scheduler_priority_affinity_SMP_Remove_processor(
+ const Scheduler_Control *scheduler,
+ struct Per_CPU_Control *cpu
+);
+
+/**
+ * @brief Set affinity for the priority affinity SMP scheduler.
+ *
+ * @param[in] scheduler The scheduler of the thread.
+ * @param[in] thread The associated thread.
+ * @param[in] affinity The new affinity set.
+ *
+ * @retval true if successful
+ * @retval false if unsuccessful
+ */
+bool _Scheduler_priority_affinity_SMP_Set_affinity(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node,
+ const Processor_mask *affinity
+);
+
+/**
+ * @brief Scheduler node specialization for Deterministic Priority Affinity SMP
+ * schedulers.
+ *
+ * This is a per thread structure.
+ */
+typedef struct {
+ /**
+ * @brief SMP priority scheduler node.
+ */
+ Scheduler_priority_SMP_Node Base;
+
+ /**
+ * @brief The thread processor affinity set.
+ */
+ Processor_mask Affinity;
+} Scheduler_priority_affinity_SMP_Node;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_SCHEDULERPRIORITYAFFINITYSMP_H */
diff --git a/cpukit/include/rtems/score/schedulerpriorityimpl.h b/cpukit/include/rtems/score/schedulerpriorityimpl.h
new file mode 100644
index 0000000000..354065fac4
--- /dev/null
+++ b/cpukit/include/rtems/score/schedulerpriorityimpl.h
@@ -0,0 +1,241 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines Associated with the Manipulation of the
+ * Priority-Based Scheduling Structures
+ *
+ * This inline file contains all of the inlined routines associated with
+ * the manipulation of the priority-based scheduling structures.
+ */
+
+/*
+ * Copyright (C) 2010 Gedare Bloom.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * 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_SCHEDULERPRIORITYIMPL_H
+#define _RTEMS_SCORE_SCHEDULERPRIORITYIMPL_H
+
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/chainimpl.h>
+#include <rtems/score/prioritybitmapimpl.h>
+#include <rtems/score/schedulerimpl.h>
+#include <rtems/score/thread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreSchedulerDPS
+ */
+/**@{**/
+
+RTEMS_INLINE_ROUTINE Scheduler_priority_Context *
+ _Scheduler_priority_Get_context( const Scheduler_Control *scheduler )
+{
+ return (Scheduler_priority_Context *) _Scheduler_Get_context( scheduler );
+}
+
+RTEMS_INLINE_ROUTINE Scheduler_priority_Node *_Scheduler_priority_Thread_get_node(
+ Thread_Control *the_thread
+)
+{
+ return (Scheduler_priority_Node *) _Thread_Scheduler_get_home_node( the_thread );
+}
+
+RTEMS_INLINE_ROUTINE Scheduler_priority_Node *_Scheduler_priority_Node_downcast(
+ Scheduler_Node *node
+)
+{
+ return (Scheduler_priority_Node *) node;
+}
+
+/**
+ * @brief Ready queue initialization.
+ *
+ * This routine initializes @a ready_queues for priority-based scheduling.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_initialize(
+ Chain_Control *ready_queues,
+ Priority_Control maximum_priority
+)
+{
+ size_t index;
+
+ for ( index = 0 ; index <= (size_t) maximum_priority ; ++index ) {
+ _Chain_Initialize_empty( &ready_queues[ index ] );
+ }
+}
+
+/**
+ * @brief Enqueues a node on the specified ready queue.
+ *
+ * The node is placed as the last element of its priority group.
+ *
+ * @param[in] node The node to enqueue.
+ * @param[in] ready_queue The ready queue.
+ * @param[in] bit_map The priority bit map of the scheduler instance.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue(
+ Chain_Node *node,
+ Scheduler_priority_Ready_queue *ready_queue,
+ Priority_bit_map_Control *bit_map
+)
+{
+ Chain_Control *ready_chain = ready_queue->ready_chain;
+
+ _Chain_Append_unprotected( ready_chain, node );
+ _Priority_bit_map_Add( bit_map, &ready_queue->Priority_map );
+}
+
+/**
+ * @brief Enqueues a node on the specified ready queue as first.
+ *
+ * The node is placed as the first element of its priority group.
+ *
+ * @param[in] node The node to enqueue as first.
+ * @param[in] ready_queue The ready queue.
+ * @param[in] bit_map The priority bit map of the scheduler instance.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue_first(
+ Chain_Node *node,
+ Scheduler_priority_Ready_queue *ready_queue,
+ Priority_bit_map_Control *bit_map
+)
+{
+ Chain_Control *ready_chain = ready_queue->ready_chain;
+
+ _Chain_Prepend_unprotected( ready_chain, node );
+ _Priority_bit_map_Add( bit_map, &ready_queue->Priority_map );
+}
+
+/**
+ * @brief Extracts a node from the specified ready queue.
+ *
+ * @param[in] node The node to extract.
+ * @param[in] ready_queue The ready queue.
+ * @param[in] bit_map The priority bit map of the scheduler instance.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_extract(
+ Chain_Node *node,
+ Scheduler_priority_Ready_queue *ready_queue,
+ Priority_bit_map_Control *bit_map
+)
+{
+ Chain_Control *ready_chain = ready_queue->ready_chain;
+
+ if ( _Chain_Has_only_one_node( ready_chain ) ) {
+ _Chain_Initialize_empty( ready_chain );
+ _Chain_Initialize_node( node );
+ _Priority_bit_map_Remove( bit_map, &ready_queue->Priority_map );
+ } else {
+ _Chain_Extract_unprotected( node );
+ }
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_priority_Extract_body(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+)
+{
+ Scheduler_priority_Context *context;
+ Scheduler_priority_Node *the_node;
+
+ context = _Scheduler_priority_Get_context( scheduler );
+ the_node = _Scheduler_priority_Node_downcast( node );
+
+ _Scheduler_priority_Ready_queue_extract(
+ &the_thread->Object.Node,
+ &the_node->Ready_queue,
+ &context->Bit_map
+ );
+}
+
+/**
+ * @brief Return a pointer to the first node.
+ *
+ * This routines returns a pointer to the first node on @a ready_queues.
+ *
+ * @param[in] bit_map The priority bit map of the scheduler instance.
+ * @param[in] ready_queues The ready queues of the scheduler instance.
+ *
+ * @return This method returns the first node.
+ */
+RTEMS_INLINE_ROUTINE Chain_Node *_Scheduler_priority_Ready_queue_first(
+ Priority_bit_map_Control *bit_map,
+ Chain_Control *ready_queues
+)
+{
+ Priority_Control index = _Priority_bit_map_Get_highest( bit_map );
+ Chain_Node *first = _Chain_First( &ready_queues[ index ] );
+
+ _Assert( first != _Chain_Tail( &ready_queues[ index ] ) );
+
+ return first;
+}
+
+/**
+ * @brief Scheduling decision logic.
+ *
+ * This kernel routine implements scheduling decision logic
+ * for priority-based scheduling.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ bool force_dispatch
+)
+{
+ Scheduler_priority_Context *context =
+ _Scheduler_priority_Get_context( scheduler );
+ Thread_Control *heir = (Thread_Control *)
+ _Scheduler_priority_Ready_queue_first(
+ &context->Bit_map,
+ &context->Ready[ 0 ]
+ );
+
+ ( void ) the_thread;
+
+ _Scheduler_Update_heir( heir, force_dispatch );
+}
+
+/**
+ * @brief Updates the specified ready queue data according to the new priority
+ * value.
+ *
+ * @param[in] ready_queue The ready queue.
+ * @param[in] new_priority The new priority.
+ * @param[in] bit_map The priority bit map of the scheduler instance.
+ * @param[in] ready_queues The ready queues of the scheduler instance.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_update(
+ Scheduler_priority_Ready_queue *ready_queue,
+ unsigned int new_priority,
+ Priority_bit_map_Control *bit_map,
+ Chain_Control *ready_queues
+)
+{
+ ready_queue->current_priority = new_priority;
+ ready_queue->ready_chain = &ready_queues[ new_priority ];
+
+ _Priority_bit_map_Initialize_information(
+ bit_map,
+ &ready_queue->Priority_map,
+ new_priority
+ );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/schedulerprioritysmp.h b/cpukit/include/rtems/score/schedulerprioritysmp.h
new file mode 100644
index 0000000000..6671da5b7a
--- /dev/null
+++ b/cpukit/include/rtems/score/schedulerprioritysmp.h
@@ -0,0 +1,171 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSchedulerPrioritySMP
+ *
+ * @brief Deterministic Priority SMP Scheduler API
+ */
+
+/*
+ * Copyright (c) 2013, 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_SCHEDULERPRIORITYSMP_H
+#define _RTEMS_SCORE_SCHEDULERPRIORITYSMP_H
+
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/schedulersmp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ScoreSchedulerPrioritySMP Deterministic Priority SMP Scheduler
+ *
+ * @ingroup ScoreSchedulerSMP
+ *
+ * This is an implementation of the global fixed priority scheduler (G-FP). It
+ * uses one ready chain per priority to ensure constant time insert operations.
+ * The scheduled chain uses linear insert operations and has at most processor
+ * count entries. Since the processor and priority count are constants all
+ * scheduler operations complete in a bounded execution time.
+ *
+ * The thread preempt mode will be ignored.
+ *
+ * @{
+ */
+
+/**
+ * @brief Scheduler context specialization for Deterministic Priority SMP
+ * schedulers.
+ */
+typedef struct {
+ Scheduler_SMP_Context Base;
+ Priority_bit_map_Control Bit_map;
+ Chain_Control Ready[ RTEMS_ZERO_LENGTH_ARRAY ];
+} Scheduler_priority_SMP_Context;
+
+/**
+ * @brief Scheduler node specialization for Deterministic Priority SMP
+ * schedulers.
+ */
+typedef struct {
+ /**
+ * @brief SMP scheduler node.
+ */
+ Scheduler_SMP_Node Base;
+
+ /**
+ * @brief The associated ready queue of this node.
+ */
+ Scheduler_priority_Ready_queue Ready_queue;
+} Scheduler_priority_SMP_Node;
+
+/**
+ * @brief Entry points for the Priority SMP Scheduler.
+ */
+#define SCHEDULER_PRIORITY_SMP_ENTRY_POINTS \
+ { \
+ _Scheduler_priority_SMP_Initialize, \
+ _Scheduler_default_Schedule, \
+ _Scheduler_priority_SMP_Yield, \
+ _Scheduler_priority_SMP_Block, \
+ _Scheduler_priority_SMP_Unblock, \
+ _Scheduler_priority_SMP_Update_priority, \
+ _Scheduler_default_Map_priority, \
+ _Scheduler_default_Unmap_priority, \
+ _Scheduler_priority_SMP_Ask_for_help, \
+ _Scheduler_priority_SMP_Reconsider_help_request, \
+ _Scheduler_priority_SMP_Withdraw_node, \
+ _Scheduler_priority_SMP_Add_processor, \
+ _Scheduler_priority_SMP_Remove_processor, \
+ _Scheduler_priority_SMP_Node_initialize, \
+ _Scheduler_default_Node_destroy, \
+ _Scheduler_default_Release_job, \
+ _Scheduler_default_Cancel_job, \
+ _Scheduler_default_Tick, \
+ _Scheduler_SMP_Start_idle \
+ SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY \
+ }
+
+void _Scheduler_priority_SMP_Initialize( const Scheduler_Control *scheduler );
+
+void _Scheduler_priority_SMP_Node_initialize(
+ const Scheduler_Control *scheduler,
+ Scheduler_Node *node,
+ Thread_Control *the_thread,
+ Priority_Control priority
+);
+
+void _Scheduler_priority_SMP_Block(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_priority_SMP_Unblock(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_priority_SMP_Update_priority(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+bool _Scheduler_priority_SMP_Ask_for_help(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_priority_SMP_Reconsider_help_request(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_priority_SMP_Withdraw_node(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node,
+ Thread_Scheduler_state next_state
+);
+
+void _Scheduler_priority_SMP_Add_processor(
+ const Scheduler_Control *scheduler,
+ Thread_Control *idle
+);
+
+Thread_Control *_Scheduler_priority_SMP_Remove_processor(
+ const Scheduler_Control *scheduler,
+ struct Per_CPU_Control *cpu
+);
+
+void _Scheduler_priority_SMP_Yield(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_SCHEDULERPRIORITYSMP_H */
diff --git a/cpukit/include/rtems/score/schedulerprioritysmpimpl.h b/cpukit/include/rtems/score/schedulerprioritysmpimpl.h
new file mode 100644
index 0000000000..17d6e552f3
--- /dev/null
+++ b/cpukit/include/rtems/score/schedulerprioritysmpimpl.h
@@ -0,0 +1,184 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSchedulerPrioritySMP
+ *
+ * @brief Deterministic Priority SMP Scheduler API
+ */
+
+/*
+ * Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_SCHEDULERPRIORITYSMPIMPL_H
+#define _RTEMS_SCORE_SCHEDULERPRIORITYSMPIMPL_H
+
+#include <rtems/score/schedulerprioritysmp.h>
+#include <rtems/score/schedulerpriorityimpl.h>
+#include <rtems/score/schedulersimpleimpl.h>
+#include <rtems/score/schedulersmpimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @ingroup ScoreSchedulerPrioritySMP
+ * @{
+ */
+
+static inline Scheduler_priority_SMP_Context *_Scheduler_priority_SMP_Get_self(
+ Scheduler_Context *context
+)
+{
+ return (Scheduler_priority_SMP_Context *) context;
+}
+
+static inline Scheduler_priority_SMP_Node *_Scheduler_priority_SMP_Thread_get_node(
+ Thread_Control *thread
+)
+{
+ return (Scheduler_priority_SMP_Node *) _Thread_Scheduler_get_home_node( thread );
+}
+
+static inline Scheduler_priority_SMP_Node *
+_Scheduler_priority_SMP_Node_downcast( Scheduler_Node *node )
+{
+ return (Scheduler_priority_SMP_Node *) node;
+}
+
+static inline bool _Scheduler_priority_SMP_Has_ready( Scheduler_Context *context )
+{
+ Scheduler_priority_SMP_Context *self =
+ _Scheduler_priority_SMP_Get_self( context );
+
+ return !_Priority_bit_map_Is_empty( &self->Bit_map );
+}
+
+static inline void _Scheduler_priority_SMP_Move_from_scheduled_to_ready(
+ Scheduler_Context *context,
+ Scheduler_Node *scheduled_to_ready
+)
+{
+ Scheduler_priority_SMP_Context *self =
+ _Scheduler_priority_SMP_Get_self( context );
+ Scheduler_priority_SMP_Node *node =
+ _Scheduler_priority_SMP_Node_downcast( scheduled_to_ready );
+
+ _Chain_Extract_unprotected( &node->Base.Base.Node.Chain );
+ _Scheduler_priority_Ready_queue_enqueue_first(
+ &node->Base.Base.Node.Chain,
+ &node->Ready_queue,
+ &self->Bit_map
+ );
+}
+
+static inline void _Scheduler_priority_SMP_Move_from_ready_to_scheduled(
+ Scheduler_Context *context,
+ Scheduler_Node *ready_to_scheduled
+)
+{
+ Scheduler_priority_SMP_Context *self;
+ Scheduler_priority_SMP_Node *node;
+ Priority_Control insert_priority;
+
+ self = _Scheduler_priority_SMP_Get_self( context );
+ node = _Scheduler_priority_SMP_Node_downcast( ready_to_scheduled );
+
+ _Scheduler_priority_Ready_queue_extract(
+ &node->Base.Base.Node.Chain,
+ &node->Ready_queue,
+ &self->Bit_map
+ );
+ insert_priority = _Scheduler_SMP_Node_priority( &node->Base.Base );
+ insert_priority = SCHEDULER_PRIORITY_APPEND( insert_priority );
+ _Chain_Insert_ordered_unprotected(
+ &self->Base.Scheduled,
+ &node->Base.Base.Node.Chain,
+ &insert_priority,
+ _Scheduler_SMP_Priority_less_equal
+ );
+}
+
+static inline void _Scheduler_priority_SMP_Insert_ready(
+ Scheduler_Context *context,
+ Scheduler_Node *node_base,
+ Priority_Control insert_priority
+)
+{
+ Scheduler_priority_SMP_Context *self;
+ Scheduler_priority_SMP_Node *node;
+
+ self = _Scheduler_priority_SMP_Get_self( context );
+ node = _Scheduler_priority_SMP_Node_downcast( node_base );
+
+ if ( SCHEDULER_PRIORITY_IS_APPEND( insert_priority ) ) {
+ _Scheduler_priority_Ready_queue_enqueue(
+ &node->Base.Base.Node.Chain,
+ &node->Ready_queue,
+ &self->Bit_map
+ );
+ } else {
+ _Scheduler_priority_Ready_queue_enqueue_first(
+ &node->Base.Base.Node.Chain,
+ &node->Ready_queue,
+ &self->Bit_map
+ );
+ }
+}
+
+static inline void _Scheduler_priority_SMP_Extract_from_ready(
+ Scheduler_Context *context,
+ Scheduler_Node *thread
+)
+{
+ Scheduler_priority_SMP_Context *self =
+ _Scheduler_priority_SMP_Get_self( context );
+ Scheduler_priority_SMP_Node *node =
+ _Scheduler_priority_SMP_Node_downcast( thread );
+
+ _Scheduler_priority_Ready_queue_extract(
+ &node->Base.Base.Node.Chain,
+ &node->Ready_queue,
+ &self->Bit_map
+ );
+}
+
+static inline void _Scheduler_priority_SMP_Do_update(
+ Scheduler_Context *context,
+ Scheduler_Node *node_to_update,
+ Priority_Control new_priority
+)
+{
+ Scheduler_priority_SMP_Context *self;
+ Scheduler_priority_SMP_Node *node;
+
+ self = _Scheduler_priority_SMP_Get_self( context );
+ node = _Scheduler_priority_SMP_Node_downcast( node_to_update );
+
+ _Scheduler_SMP_Node_update_priority( &node->Base, new_priority );
+ _Scheduler_priority_Ready_queue_update(
+ &node->Ready_queue,
+ SCHEDULER_PRIORITY_UNMAP( new_priority ),
+ &self->Bit_map,
+ &self->Ready[ 0 ]
+ );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_SCHEDULERPRIORITYSMPIMPL_H */
diff --git a/cpukit/include/rtems/score/schedulersimple.h b/cpukit/include/rtems/score/schedulersimple.h
new file mode 100644
index 0000000000..0d410d5676
--- /dev/null
+++ b/cpukit/include/rtems/score/schedulersimple.h
@@ -0,0 +1,126 @@
+/**
+ * @file rtems/score/schedulersimple.h
+ *
+ * @brief Manipulation of Threads Simple-Priority-Based Ready Queue
+ *
+ * This include file contains all the constants and structures associated
+ * with the manipulation of threads on a simple-priority-based ready queue.
+ */
+
+/*
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * 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_SCHEDULERSIMPLE_H
+#define _RTEMS_SCORE_SCHEDULERSIMPLE_H
+
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreSchedulerSimple Simple Priority Scheduler
+ *
+ * @ingroup ScoreScheduler
+ */
+/**@{*/
+
+#define SCHEDULER_SIMPLE_MAXIMUM_PRIORITY 255
+
+/**
+ * Entry points for Scheduler Simple
+ */
+#define SCHEDULER_SIMPLE_ENTRY_POINTS \
+ { \
+ _Scheduler_simple_Initialize, /* initialize entry point */ \
+ _Scheduler_simple_Schedule, /* schedule entry point */ \
+ _Scheduler_simple_Yield, /* yield entry point */ \
+ _Scheduler_simple_Block, /* block entry point */ \
+ _Scheduler_simple_Unblock, /* unblock entry point */ \
+ _Scheduler_simple_Update_priority, /* update priority entry point */ \
+ _Scheduler_default_Map_priority, /* map priority entry point */ \
+ _Scheduler_default_Unmap_priority, /* unmap priority entry point */ \
+ SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
+ _Scheduler_default_Node_initialize, /* node initialize entry point */ \
+ _Scheduler_default_Node_destroy, /* node destroy entry point */ \
+ _Scheduler_default_Release_job, /* new period of task */ \
+ _Scheduler_default_Cancel_job, /* cancel period of task */ \
+ _Scheduler_default_Tick, /* tick entry point */ \
+ _Scheduler_default_Start_idle /* start idle entry point */ \
+ SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY \
+ }
+
+/**
+ * @brief Simple scheduler context.
+ */
+typedef struct {
+ /**
+ * @brief Basic scheduler context.
+ */
+ Scheduler_Context Base;
+
+ /**
+ * @brief One ready queue for all ready threads.
+ */
+ Chain_Control Ready;
+} Scheduler_simple_Context;
+
+/**
+ * @brief Initialize simple scheduler.
+ *
+ * This routine initializes the simple scheduler.
+ */
+void _Scheduler_simple_Initialize( const Scheduler_Control *scheduler );
+
+/**
+ * This routine sets the heir thread to be the next ready thread
+ * on the ready queue by getting the first node in the scheduler
+ * information.
+ *
+ * @param[in] scheduler The scheduler instance.
+ * @param[in] the_thread causing the scheduling operation.
+ */
+void _Scheduler_simple_Schedule(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+);
+
+void _Scheduler_simple_Yield(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_simple_Block(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_simple_Unblock(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_simple_Update_priority(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/schedulersimpleimpl.h b/cpukit/include/rtems/score/schedulersimpleimpl.h
new file mode 100644
index 0000000000..3891839281
--- /dev/null
+++ b/cpukit/include/rtems/score/schedulersimpleimpl.h
@@ -0,0 +1,103 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines Associated with the Manipulation of the
+ * Priority-Based Scheduling Structures
+ *
+ * This inline file contains all of the inlined routines associated with
+ * the manipulation of the priority-based scheduling structures.
+ */
+
+/*
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * 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_SCHEDULERSIMPLEIMPL_H
+#define _RTEMS_SCORE_SCHEDULERSIMPLEIMPL_H
+
+#include <rtems/score/schedulersimple.h>
+#include <rtems/score/chainimpl.h>
+#include <rtems/score/schedulerimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreSchedulerSimple
+ */
+/**@{**/
+
+RTEMS_INLINE_ROUTINE Scheduler_simple_Context *
+ _Scheduler_simple_Get_context( const Scheduler_Control *scheduler )
+{
+ return (Scheduler_simple_Context *) _Scheduler_Get_context( scheduler );
+}
+
+RTEMS_INLINE_ROUTINE bool _Scheduler_simple_Priority_less_equal(
+ const void *to_insert,
+ const Chain_Node *next
+)
+{
+ const unsigned int *priority_to_insert;
+ const Thread_Control *thread_next;
+
+ priority_to_insert = (const unsigned int *) to_insert;
+ thread_next = (const Thread_Control *) next;
+
+ return *priority_to_insert <= _Thread_Get_priority( thread_next );
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_simple_Insert(
+ Chain_Control *chain,
+ Thread_Control *to_insert,
+ unsigned int insert_priority
+)
+{
+ _Chain_Insert_ordered_unprotected(
+ chain,
+ &to_insert->Object.Node,
+ &insert_priority,
+ _Scheduler_simple_Priority_less_equal
+ );
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_simple_Extract(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+)
+{
+ (void) scheduler;
+ (void) node;
+
+ _Chain_Extract_unprotected( &the_thread->Object.Node );
+}
+
+RTEMS_INLINE_ROUTINE void _Scheduler_simple_Schedule_body(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ bool force_dispatch
+)
+{
+ Scheduler_simple_Context *context =
+ _Scheduler_simple_Get_context( scheduler );
+ Thread_Control *heir = (Thread_Control *) _Chain_First( &context->Ready );
+
+ ( void ) the_thread;
+
+ _Scheduler_Update_heir( heir, force_dispatch );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/schedulersimplesmp.h b/cpukit/include/rtems/score/schedulersimplesmp.h
new file mode 100644
index 0000000000..bc75b205d5
--- /dev/null
+++ b/cpukit/include/rtems/score/schedulersimplesmp.h
@@ -0,0 +1,155 @@
+/**
+ * @file
+ *
+ * @brief Simple SMP Scheduler API
+ *
+ * @ingroup ScoreSchedulerSMPSimple
+ */
+
+/*
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * Copyright (c) 2013, 2016 embedded brains GmbH.
+ *
+ * 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_SCHEDULERSIMPLE_SMP_H
+#define _RTEMS_SCORE_SCHEDULERSIMPLE_SMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/schedulersmp.h>
+
+/**
+ * @defgroup ScoreSchedulerSMPSimple Simple Priority SMP Scheduler
+ *
+ * @ingroup ScoreSchedulerSMP
+ *
+ * The Simple Priority SMP Scheduler allocates a processor for the processor
+ * count highest priority ready threads. The thread priority and position in
+ * the ready chain are the only information to determine the scheduling
+ * decision. Threads with an allocated processor are in the scheduled chain.
+ * After initialization the scheduled chain has exactly processor count nodes.
+ * Each processor has exactly one allocated thread after initialization. All
+ * enqueue and extract operations may exchange threads with the scheduled
+ * chain. One thread will be added and another will be removed. The scheduled
+ * and ready chain is ordered according to the thread priority order. The
+ * chain insert operations are O(count of ready threads), thus this scheduler
+ * is unsuitable for most real-time applications.
+ *
+ * The thread preempt mode will be ignored.
+ *
+ * @{
+ */
+
+typedef struct {
+ Scheduler_SMP_Context Base;
+ Chain_Control Ready;
+} Scheduler_simple_SMP_Context;
+
+#define SCHEDULER_SIMPLE_SMP_MAXIMUM_PRIORITY 255
+
+/**
+ * @brief Entry points for the Simple SMP Scheduler.
+ */
+#define SCHEDULER_SIMPLE_SMP_ENTRY_POINTS \
+ { \
+ _Scheduler_simple_SMP_Initialize, \
+ _Scheduler_default_Schedule, \
+ _Scheduler_simple_SMP_Yield, \
+ _Scheduler_simple_SMP_Block, \
+ _Scheduler_simple_SMP_Unblock, \
+ _Scheduler_simple_SMP_Update_priority, \
+ _Scheduler_default_Map_priority, \
+ _Scheduler_default_Unmap_priority, \
+ _Scheduler_simple_SMP_Ask_for_help, \
+ _Scheduler_simple_SMP_Reconsider_help_request, \
+ _Scheduler_simple_SMP_Withdraw_node, \
+ _Scheduler_simple_SMP_Add_processor, \
+ _Scheduler_simple_SMP_Remove_processor, \
+ _Scheduler_simple_SMP_Node_initialize, \
+ _Scheduler_default_Node_destroy, \
+ _Scheduler_default_Release_job, \
+ _Scheduler_default_Cancel_job, \
+ _Scheduler_default_Tick, \
+ _Scheduler_SMP_Start_idle \
+ SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY \
+ }
+
+void _Scheduler_simple_SMP_Initialize( const Scheduler_Control *scheduler );
+
+void _Scheduler_simple_SMP_Node_initialize(
+ const Scheduler_Control *scheduler,
+ Scheduler_Node *node,
+ Thread_Control *the_thread,
+ Priority_Control priority
+);
+
+void _Scheduler_simple_SMP_Block(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_simple_SMP_Unblock(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_simple_SMP_Update_priority(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+bool _Scheduler_simple_SMP_Ask_for_help(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_simple_SMP_Reconsider_help_request(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_simple_SMP_Withdraw_node(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node,
+ Thread_Scheduler_state next_state
+);
+
+void _Scheduler_simple_SMP_Add_processor(
+ const Scheduler_Control *scheduler,
+ Thread_Control *idle
+);
+
+Thread_Control *_Scheduler_simple_SMP_Remove_processor(
+ const Scheduler_Control *scheduler,
+ struct Per_CPU_Control *cpu
+);
+
+void _Scheduler_simple_SMP_Yield(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/schedulersmp.h b/cpukit/include/rtems/score/schedulersmp.h
new file mode 100644
index 0000000000..0bd899a6a6
--- /dev/null
+++ b/cpukit/include/rtems/score/schedulersmp.h
@@ -0,0 +1,127 @@
+/**
+ * @file
+ *
+ * @brief SMP Scheduler API
+ *
+ * @ingroup ScoreSchedulerSMP
+ */
+
+/*
+ * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_SCHEDULERSMP_H
+#define _RTEMS_SCORE_SCHEDULERSMP_H
+
+#include <rtems/score/chain.h>
+#include <rtems/score/scheduler.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ScoreSchedulerSMP SMP Scheduler
+ *
+ * @ingroup ScoreScheduler
+ *
+ * @{
+ */
+
+/**
+ * @brief Scheduler context specialization for SMP schedulers.
+ */
+typedef struct {
+ /**
+ * @brief Basic scheduler context.
+ */
+ Scheduler_Context Base;
+
+ /**
+ * @brief The chain of scheduled nodes.
+ */
+ Chain_Control Scheduled;
+
+ /**
+ * @brief Chain of the available idle threads.
+ *
+ * Idle threads are used for the scheduler helping protocol. It is crucial
+ * that the idle threads preserve their relative order. This is the case for
+ * this priority based scheduler.
+ */
+ Chain_Control Idle_threads;
+} Scheduler_SMP_Context;
+
+/**
+ * @brief SMP scheduler node states.
+ */
+typedef enum {
+ /**
+ * @brief This scheduler node is blocked.
+ *
+ * A scheduler node is blocked if the corresponding thread is not ready.
+ */
+ SCHEDULER_SMP_NODE_BLOCKED,
+
+ /**
+ * @brief The scheduler node is scheduled.
+ *
+ * A scheduler node is scheduled if the corresponding thread is ready and the
+ * scheduler allocated a processor for it. A scheduled node is assigned to
+ * exactly one processor. The count of scheduled nodes in this scheduler
+ * instance equals the processor count owned by the scheduler instance.
+ */
+ SCHEDULER_SMP_NODE_SCHEDULED,
+
+ /**
+ * @brief This scheduler node is ready.
+ *
+ * A scheduler node is ready if the corresponding thread is ready and the
+ * scheduler did not allocate a processor for it.
+ */
+ SCHEDULER_SMP_NODE_READY
+} Scheduler_SMP_Node_state;
+
+/**
+ * @brief Scheduler node specialization for SMP schedulers.
+ */
+typedef struct {
+ /**
+ * @brief Basic scheduler node.
+ */
+ Scheduler_Node Base;
+
+ /**
+ * @brief The state of this node.
+ */
+ Scheduler_SMP_Node_state state;
+
+ /**
+ * @brief The current priority of thread owning this node.
+ */
+ Priority_Control priority;
+} Scheduler_SMP_Node;
+
+void _Scheduler_SMP_Start_idle(
+ const Scheduler_Control *scheduler,
+ Thread_Control *idle,
+ struct Per_CPU_Control *cpu
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_SCHEDULERSMP_H */
diff --git a/cpukit/include/rtems/score/schedulersmpimpl.h b/cpukit/include/rtems/score/schedulersmpimpl.h
new file mode 100644
index 0000000000..e152eb0878
--- /dev/null
+++ b/cpukit/include/rtems/score/schedulersmpimpl.h
@@ -0,0 +1,1482 @@
+/**
+ * @file
+ *
+ * @brief SMP Scheduler Implementation
+ *
+ * @ingroup ScoreSchedulerSMP
+ */
+
+/*
+ * Copyright (c) 2013, 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_SCHEDULERSMPIMPL_H
+#define _RTEMS_SCORE_SCHEDULERSMPIMPL_H
+
+#include <rtems/score/schedulersmp.h>
+#include <rtems/score/assert.h>
+#include <rtems/score/chainimpl.h>
+#include <rtems/score/schedulersimpleimpl.h>
+#include <rtems/bspIo.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @addtogroup ScoreSchedulerSMP
+ *
+ * The scheduler nodes can be in four states
+ * - @ref SCHEDULER_SMP_NODE_BLOCKED,
+ * - @ref SCHEDULER_SMP_NODE_SCHEDULED, and
+ * - @ref SCHEDULER_SMP_NODE_READY.
+ *
+ * State transitions are triggered via basic operations
+ * - _Scheduler_SMP_Enqueue(),
+ * - _Scheduler_SMP_Enqueue_scheduled(), and
+ * - _Scheduler_SMP_Block().
+ *
+ * @dot
+ * digraph {
+ * node [style="filled"];
+ *
+ * bs [label="BLOCKED"];
+ * ss [label="SCHEDULED", fillcolor="green"];
+ * rs [label="READY", fillcolor="red"];
+ *
+ * edge [label="enqueue"];
+ * edge [fontcolor="darkgreen", color="darkgreen"];
+ *
+ * bs -> ss;
+ *
+ * edge [fontcolor="red", color="red"];
+ *
+ * bs -> rs;
+ *
+ * edge [label="enqueue other"];
+ *
+ * ss -> rs;
+ *
+ * edge [label="block"];
+ * edge [fontcolor="black", color="black"];
+ *
+ * ss -> bs;
+ * rs -> bs;
+ *
+ * edge [label="block other"];
+ * edge [fontcolor="darkgreen", color="darkgreen"];
+ *
+ * rs -> ss;
+ * }
+ * @enddot
+ *
+ * During system initialization each processor of the scheduler instance starts
+ * with an idle thread assigned to it. Lets have a look at an example with two
+ * idle threads I and J with priority 5. We also have blocked threads A, B and
+ * C with priorities 1, 2 and 3 respectively. The scheduler nodes are ordered
+ * with respect to the thread priority from left to right in the below
+ * diagrams. The highest priority node (lowest priority number) is the
+ * leftmost node. Since the processor assignment is independent of the thread
+ * priority the processor indices may move from one state to the other.
+ *
+ * @dot
+ * digraph {
+ * node [style="filled"];
+ * edge [dir="none"];
+ * subgraph {
+ * rank = same;
+ *
+ * i [label="I (5)", fillcolor="green"];
+ * j [label="J (5)", fillcolor="green"];
+ * a [label="A (1)"];
+ * b [label="B (2)"];
+ * c [label="C (3)"];
+ * i -> j;
+ * }
+ *
+ * subgraph {
+ * rank = same;
+ *
+ * p0 [label="PROCESSOR 0", shape="box"];
+ * p1 [label="PROCESSOR 1", shape="box"];
+ * }
+ *
+ * i -> p0;
+ * j -> p1;
+ * }
+ * @enddot
+ *
+ * Lets start A. For this an enqueue operation is performed.
+ *
+ * @dot
+ * digraph {
+ * node [style="filled"];
+ * edge [dir="none"];
+ *
+ * subgraph {
+ * rank = same;
+ *
+ * i [label="I (5)", fillcolor="green"];
+ * j [label="J (5)", fillcolor="red"];
+ * a [label="A (1)", fillcolor="green"];
+ * b [label="B (2)"];
+ * c [label="C (3)"];
+ * a -> i;
+ * }
+ *
+ * subgraph {
+ * rank = same;
+ *
+ * p0 [label="PROCESSOR 0", shape="box"];
+ * p1 [label="PROCESSOR 1", shape="box"];
+ * }
+ *
+ * i -> p0;
+ * a -> p1;
+ * }
+ * @enddot
+ *
+ * Lets start C.
+ *
+ * @dot
+ * digraph {
+ * node [style="filled"];
+ * edge [dir="none"];
+ *
+ * subgraph {
+ * rank = same;
+ *
+ * a [label="A (1)", fillcolor="green"];
+ * c [label="C (3)", fillcolor="green"];
+ * i [label="I (5)", fillcolor="red"];
+ * j [label="J (5)", fillcolor="red"];
+ * b [label="B (2)"];
+ * a -> c;
+ * i -> j;
+ * }
+ *
+ * subgraph {
+ * rank = same;
+ *
+ * p0 [label="PROCESSOR 0", shape="box"];
+ * p1 [label="PROCESSOR 1", shape="box"];
+ * }
+ *
+ * c -> p0;
+ * a -> p1;
+ * }
+ * @enddot
+ *
+ * Lets start B.
+ *
+ * @dot
+ * digraph {
+ * node [style="filled"];
+ * edge [dir="none"];
+ *
+ * subgraph {
+ * rank = same;
+ *
+ * a [label="A (1)", fillcolor="green"];
+ * b [label="B (2)", fillcolor="green"];
+ * c [label="C (3)", fillcolor="red"];
+ * i [label="I (5)", fillcolor="red"];
+ * j [label="J (5)", fillcolor="red"];
+ * a -> b;
+ * c -> i -> j;
+ * }
+ *
+ * subgraph {
+ * rank = same;
+ *
+ * p0 [label="PROCESSOR 0", shape="box"];
+ * p1 [label="PROCESSOR 1", shape="box"];
+ * }
+ *
+ * b -> p0;
+ * a -> p1;
+ * }
+ * @enddot
+ *
+ * Lets change the priority of thread A to 4.
+ *
+ * @dot
+ * digraph {
+ * node [style="filled"];
+ * edge [dir="none"];
+ *
+ * subgraph {
+ * rank = same;
+ *
+ * b [label="B (2)", fillcolor="green"];
+ * c [label="C (3)", fillcolor="green"];
+ * a [label="A (4)", fillcolor="red"];
+ * i [label="I (5)", fillcolor="red"];
+ * j [label="J (5)", fillcolor="red"];
+ * b -> c;
+ * a -> i -> j;
+ * }
+ *
+ * subgraph {
+ * rank = same;
+ *
+ * p0 [label="PROCESSOR 0", shape="box"];
+ * p1 [label="PROCESSOR 1", shape="box"];
+ * }
+ *
+ * b -> p0;
+ * c -> p1;
+ * }
+ * @enddot
+ *
+ * Now perform a blocking operation with thread B. Please note that thread A
+ * migrated now from processor 0 to processor 1 and thread C still executes on
+ * processor 1.
+ *
+ * @dot
+ * digraph {
+ * node [style="filled"];
+ * edge [dir="none"];
+ *
+ * subgraph {
+ * rank = same;
+ *
+ * c [label="C (3)", fillcolor="green"];
+ * a [label="A (4)", fillcolor="green"];
+ * i [label="I (5)", fillcolor="red"];
+ * j [label="J (5)", fillcolor="red"];
+ * b [label="B (2)"];
+ * c -> a;
+ * i -> j;
+ * }
+ *
+ * subgraph {
+ * rank = same;
+ *
+ * p0 [label="PROCESSOR 0", shape="box"];
+ * p1 [label="PROCESSOR 1", shape="box"];
+ * }
+ *
+ * a -> p0;
+ * c -> p1;
+ * }
+ * @enddot
+ *
+ * @{
+ */
+
+typedef bool ( *Scheduler_SMP_Has_ready )(
+ Scheduler_Context *context
+);
+
+typedef Scheduler_Node *( *Scheduler_SMP_Get_highest_ready )(
+ Scheduler_Context *context,
+ Scheduler_Node *node
+);
+
+typedef Scheduler_Node *( *Scheduler_SMP_Get_lowest_scheduled )(
+ Scheduler_Context *context,
+ Scheduler_Node *filter
+);
+
+typedef void ( *Scheduler_SMP_Extract )(
+ Scheduler_Context *context,
+ Scheduler_Node *node_to_extract
+);
+
+typedef void ( *Scheduler_SMP_Insert )(
+ Scheduler_Context *context,
+ Scheduler_Node *node_to_insert,
+ Priority_Control insert_priority
+);
+
+typedef void ( *Scheduler_SMP_Move )(
+ Scheduler_Context *context,
+ Scheduler_Node *node_to_move
+);
+
+typedef bool ( *Scheduler_SMP_Ask_for_help )(
+ Scheduler_Context *context,
+ Thread_Control *thread,
+ Scheduler_Node *node
+);
+
+typedef void ( *Scheduler_SMP_Update )(
+ Scheduler_Context *context,
+ Scheduler_Node *node_to_update,
+ Priority_Control new_priority
+);
+
+typedef void ( *Scheduler_SMP_Set_affinity )(
+ Scheduler_Context *context,
+ Scheduler_Node *node,
+ void *arg
+);
+
+typedef bool ( *Scheduler_SMP_Enqueue )(
+ Scheduler_Context *context,
+ Scheduler_Node *node_to_enqueue,
+ Priority_Control priority
+);
+
+typedef void ( *Scheduler_SMP_Allocate_processor )(
+ Scheduler_Context *context,
+ Scheduler_Node *scheduled,
+ Scheduler_Node *victim,
+ Per_CPU_Control *victim_cpu
+);
+
+typedef void ( *Scheduler_SMP_Register_idle )(
+ Scheduler_Context *context,
+ Scheduler_Node *idle,
+ Per_CPU_Control *cpu
+);
+
+static inline void _Scheduler_SMP_Do_nothing_register_idle(
+ Scheduler_Context *context,
+ Scheduler_Node *idle,
+ Per_CPU_Control *cpu
+)
+{
+ (void) context;
+ (void) idle;
+ (void) cpu;
+}
+
+static inline bool _Scheduler_SMP_Priority_less_equal(
+ const void *to_insert,
+ const Chain_Node *next
+)
+{
+ const Priority_Control *priority_to_insert;
+ const Scheduler_SMP_Node *node_next;
+
+ priority_to_insert = (const Priority_Control *) to_insert;
+ node_next = (const Scheduler_SMP_Node *) next;
+
+ return *priority_to_insert <= node_next->priority;
+}
+
+static inline Scheduler_SMP_Context *_Scheduler_SMP_Get_self(
+ Scheduler_Context *context
+)
+{
+ return (Scheduler_SMP_Context *) context;
+}
+
+static inline void _Scheduler_SMP_Initialize(
+ Scheduler_SMP_Context *self
+)
+{
+ _Chain_Initialize_empty( &self->Scheduled );
+ _Chain_Initialize_empty( &self->Idle_threads );
+}
+
+static inline Scheduler_SMP_Node *_Scheduler_SMP_Thread_get_node(
+ Thread_Control *thread
+)
+{
+ return (Scheduler_SMP_Node *) _Thread_Scheduler_get_home_node( thread );
+}
+
+static inline Scheduler_SMP_Node *_Scheduler_SMP_Thread_get_own_node(
+ Thread_Control *thread
+)
+{
+ return (Scheduler_SMP_Node *) _Thread_Scheduler_get_home_node( thread );
+}
+
+static inline Scheduler_SMP_Node *_Scheduler_SMP_Node_downcast(
+ Scheduler_Node *node
+)
+{
+ return (Scheduler_SMP_Node *) node;
+}
+
+static inline Scheduler_SMP_Node_state _Scheduler_SMP_Node_state(
+ const Scheduler_Node *node
+)
+{
+ return ( (const Scheduler_SMP_Node *) node )->state;
+}
+
+static inline Priority_Control _Scheduler_SMP_Node_priority(
+ const Scheduler_Node *node
+)
+{
+ return ( (const Scheduler_SMP_Node *) node )->priority;
+}
+
+static inline void _Scheduler_SMP_Node_initialize(
+ const Scheduler_Control *scheduler,
+ Scheduler_SMP_Node *node,
+ Thread_Control *thread,
+ Priority_Control priority
+)
+{
+ _Scheduler_Node_do_initialize( scheduler, &node->Base, thread, priority );
+ node->state = SCHEDULER_SMP_NODE_BLOCKED;
+ node->priority = priority;
+}
+
+static inline void _Scheduler_SMP_Node_update_priority(
+ Scheduler_SMP_Node *node,
+ Priority_Control new_priority
+)
+{
+ node->priority = new_priority;
+}
+
+static inline void _Scheduler_SMP_Node_change_state(
+ Scheduler_Node *node,
+ Scheduler_SMP_Node_state new_state
+)
+{
+ Scheduler_SMP_Node *the_node;
+
+ the_node = _Scheduler_SMP_Node_downcast( node );
+ the_node->state = new_state;
+}
+
+static inline bool _Scheduler_SMP_Is_processor_owned_by_us(
+ const Scheduler_Context *context,
+ const Per_CPU_Control *cpu
+)
+{
+ return cpu->Scheduler.context == context;
+}
+
+static inline Thread_Control *_Scheduler_SMP_Get_idle_thread(
+ Scheduler_Context *context
+)
+{
+ Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context );
+ Thread_Control *idle = (Thread_Control *)
+ _Chain_Get_first_unprotected( &self->Idle_threads );
+
+ _Assert( &idle->Object.Node != _Chain_Tail( &self->Idle_threads ) );
+
+ return idle;
+}
+
+static inline void _Scheduler_SMP_Release_idle_thread(
+ Scheduler_Context *context,
+ Thread_Control *idle
+)
+{
+ Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context );
+
+ _Chain_Prepend_unprotected( &self->Idle_threads, &idle->Object.Node );
+}
+
+static inline void _Scheduler_SMP_Exctract_idle_thread(
+ Thread_Control *idle
+)
+{
+ _Chain_Extract_unprotected( &idle->Object.Node );
+}
+
+static inline void _Scheduler_SMP_Allocate_processor_lazy(
+ Scheduler_Context *context,
+ Scheduler_Node *scheduled,
+ Scheduler_Node *victim,
+ Per_CPU_Control *victim_cpu
+)
+{
+ Thread_Control *scheduled_thread = _Scheduler_Node_get_user( scheduled );
+ Thread_Control *victim_thread = _Scheduler_Node_get_user( victim );
+ Per_CPU_Control *scheduled_cpu = _Thread_Get_CPU( scheduled_thread );
+ Per_CPU_Control *cpu_self = _Per_CPU_Get();
+ Thread_Control *heir;
+
+ _Assert( _ISR_Get_level() != 0 );
+
+ if ( _Thread_Is_executing_on_a_processor( scheduled_thread ) ) {
+ if ( _Scheduler_SMP_Is_processor_owned_by_us( context, scheduled_cpu ) ) {
+ heir = scheduled_cpu->heir;
+ _Thread_Dispatch_update_heir(
+ cpu_self,
+ scheduled_cpu,
+ scheduled_thread
+ );
+ } else {
+ /* We have to force a migration to our processor set */
+ heir = scheduled_thread;
+ }
+ } else {
+ heir = scheduled_thread;
+ }
+
+ if ( heir != victim_thread ) {
+ _Thread_Set_CPU( heir, victim_cpu );
+ _Thread_Dispatch_update_heir( cpu_self, victim_cpu, heir );
+ }
+}
+
+/*
+ * This method is slightly different from
+ * _Scheduler_SMP_Allocate_processor_lazy() in that it does what it is asked to
+ * do. _Scheduler_SMP_Allocate_processor_lazy() attempts to prevent migrations
+ * but does not take into account affinity.
+ */
+static inline void _Scheduler_SMP_Allocate_processor_exact(
+ Scheduler_Context *context,
+ Scheduler_Node *scheduled,
+ Scheduler_Node *victim,
+ Per_CPU_Control *victim_cpu
+)
+{
+ Thread_Control *scheduled_thread = _Scheduler_Node_get_user( scheduled );
+ Per_CPU_Control *cpu_self = _Per_CPU_Get();
+
+ (void) context;
+ (void) victim;
+
+ _Thread_Set_CPU( scheduled_thread, victim_cpu );
+ _Thread_Dispatch_update_heir( cpu_self, victim_cpu, scheduled_thread );
+}
+
+static inline void _Scheduler_SMP_Allocate_processor(
+ Scheduler_Context *context,
+ Scheduler_Node *scheduled,
+ Scheduler_Node *victim,
+ Per_CPU_Control *victim_cpu,
+ Scheduler_SMP_Allocate_processor allocate_processor
+)
+{
+ _Scheduler_SMP_Node_change_state( scheduled, SCHEDULER_SMP_NODE_SCHEDULED );
+ ( *allocate_processor )( context, scheduled, victim, victim_cpu );
+}
+
+static inline Thread_Control *_Scheduler_SMP_Preempt(
+ Scheduler_Context *context,
+ Scheduler_Node *scheduled,
+ Scheduler_Node *victim,
+ Scheduler_SMP_Allocate_processor allocate_processor
+)
+{
+ Thread_Control *victim_thread;
+ ISR_lock_Context lock_context;
+ Per_CPU_Control *victim_cpu;
+
+ victim_thread = _Scheduler_Node_get_user( victim );
+ _Scheduler_SMP_Node_change_state( victim, SCHEDULER_SMP_NODE_READY );
+
+ _Thread_Scheduler_acquire_critical( victim_thread, &lock_context );
+
+ victim_cpu = _Thread_Get_CPU( victim_thread );
+
+ if ( victim_thread->Scheduler.state == THREAD_SCHEDULER_SCHEDULED ) {
+ _Scheduler_Thread_change_state( victim_thread, THREAD_SCHEDULER_READY );
+
+ if ( victim_thread->Scheduler.helping_nodes > 0 ) {
+ _Per_CPU_Acquire( victim_cpu );
+ _Chain_Append_unprotected(
+ &victim_cpu->Threads_in_need_for_help,
+ &victim_thread->Scheduler.Help_node
+ );
+ _Per_CPU_Release( victim_cpu );
+ }
+ }
+
+ _Thread_Scheduler_release_critical( victim_thread, &lock_context );
+
+ _Scheduler_SMP_Allocate_processor(
+ context,
+ scheduled,
+ victim,
+ victim_cpu,
+ allocate_processor
+ );
+
+ return victim_thread;
+}
+
+static inline Scheduler_Node *_Scheduler_SMP_Get_lowest_scheduled(
+ Scheduler_Context *context,
+ Scheduler_Node *filter
+)
+{
+ Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context );
+ Chain_Control *scheduled = &self->Scheduled;
+ Scheduler_Node *lowest_scheduled =
+ (Scheduler_Node *) _Chain_Last( scheduled );
+
+ (void) filter;
+
+ _Assert( &lowest_scheduled->Node.Chain != _Chain_Tail( scheduled ) );
+ _Assert(
+ _Chain_Next( &lowest_scheduled->Node.Chain ) == _Chain_Tail( scheduled )
+ );
+
+ return lowest_scheduled;
+}
+
+static inline void _Scheduler_SMP_Enqueue_to_scheduled(
+ Scheduler_Context *context,
+ Scheduler_Node *node,
+ Priority_Control priority,
+ Scheduler_Node *lowest_scheduled,
+ Scheduler_SMP_Insert insert_scheduled,
+ Scheduler_SMP_Move move_from_scheduled_to_ready,
+ Scheduler_SMP_Allocate_processor allocate_processor
+)
+{
+ Scheduler_Try_to_schedule_action action;
+
+ action = _Scheduler_Try_to_schedule_node(
+ context,
+ node,
+ _Scheduler_Node_get_idle( lowest_scheduled ),
+ _Scheduler_SMP_Get_idle_thread
+ );
+
+ if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE ) {
+ _Scheduler_SMP_Preempt(
+ context,
+ node,
+ lowest_scheduled,
+ allocate_processor
+ );
+
+ ( *insert_scheduled )( context, node, priority );
+ ( *move_from_scheduled_to_ready )( context, lowest_scheduled );
+
+ _Scheduler_Release_idle_thread(
+ context,
+ lowest_scheduled,
+ _Scheduler_SMP_Release_idle_thread
+ );
+ } else if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_IDLE_EXCHANGE ) {
+ _Scheduler_SMP_Node_change_state(
+ lowest_scheduled,
+ SCHEDULER_SMP_NODE_READY
+ );
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_SCHEDULED );
+
+ ( *insert_scheduled )( context, node, priority );
+ ( *move_from_scheduled_to_ready )( context, lowest_scheduled );
+
+ _Scheduler_Exchange_idle_thread(
+ node,
+ lowest_scheduled,
+ _Scheduler_Node_get_idle( lowest_scheduled )
+ );
+ } else {
+ _Assert( action == SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK );
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_BLOCKED );
+ }
+}
+
+/**
+ * @brief Enqueues a node according to the specified order function.
+ *
+ * The node must not be in the scheduled state.
+ *
+ * @param[in] context The scheduler instance context.
+ * @param[in] node The node to enqueue.
+ * @param[in] priority The node insert priority.
+ * @param[in] order The order function.
+ * @param[in] insert_ready Function to insert a node into the set of ready
+ * nodes.
+ * @param[in] insert_scheduled Function to insert a node into the set of
+ * scheduled nodes.
+ * @param[in] move_from_scheduled_to_ready Function to move a node from the set
+ * of scheduled nodes to the set of ready nodes.
+ * @param[in] get_lowest_scheduled Function to select the node from the
+ * scheduled nodes to replace. It may not be possible to find one, in this
+ * case a pointer must be returned so that the order functions returns false
+ * if this pointer is passed as the second argument to the order function.
+ * @param[in] allocate_processor Function to allocate a processor to a node
+ * based on the rules of the scheduler.
+ */
+static inline bool _Scheduler_SMP_Enqueue(
+ Scheduler_Context *context,
+ Scheduler_Node *node,
+ Priority_Control insert_priority,
+ Chain_Node_order order,
+ Scheduler_SMP_Insert insert_ready,
+ Scheduler_SMP_Insert insert_scheduled,
+ Scheduler_SMP_Move move_from_scheduled_to_ready,
+ Scheduler_SMP_Get_lowest_scheduled get_lowest_scheduled,
+ Scheduler_SMP_Allocate_processor allocate_processor
+)
+{
+ bool needs_help;
+ Scheduler_Node *lowest_scheduled;
+
+ lowest_scheduled = ( *get_lowest_scheduled )( context, node );
+
+ if ( ( *order )( &insert_priority, &lowest_scheduled->Node.Chain ) ) {
+ _Scheduler_SMP_Enqueue_to_scheduled(
+ context,
+ node,
+ insert_priority,
+ lowest_scheduled,
+ insert_scheduled,
+ move_from_scheduled_to_ready,
+ allocate_processor
+ );
+ needs_help = false;
+ } else {
+ ( *insert_ready )( context, node, insert_priority );
+ needs_help = true;
+ }
+
+ return needs_help;
+}
+
+/**
+ * @brief Enqueues a scheduled node according to the specified order
+ * function.
+ *
+ * @param[in] context The scheduler instance context.
+ * @param[in] node The node to enqueue.
+ * @param[in] order The order function.
+ * @param[in] extract_from_ready Function to extract a node from the set of
+ * ready nodes.
+ * @param[in] get_highest_ready Function to get the highest ready node.
+ * @param[in] insert_ready Function to insert a node into the set of ready
+ * nodes.
+ * @param[in] insert_scheduled Function to insert a node into the set of
+ * scheduled nodes.
+ * @param[in] move_from_ready_to_scheduled Function to move a node from the set
+ * of ready nodes to the set of scheduled nodes.
+ * @param[in] allocate_processor Function to allocate a processor to a node
+ * based on the rules of the scheduler.
+ */
+static inline bool _Scheduler_SMP_Enqueue_scheduled(
+ Scheduler_Context *context,
+ Scheduler_Node *const node,
+ Priority_Control insert_priority,
+ Chain_Node_order order,
+ Scheduler_SMP_Extract extract_from_ready,
+ Scheduler_SMP_Get_highest_ready get_highest_ready,
+ Scheduler_SMP_Insert insert_ready,
+ Scheduler_SMP_Insert insert_scheduled,
+ Scheduler_SMP_Move move_from_ready_to_scheduled,
+ Scheduler_SMP_Allocate_processor allocate_processor
+)
+{
+ while ( true ) {
+ Scheduler_Node *highest_ready;
+ Scheduler_Try_to_schedule_action action;
+
+ highest_ready = ( *get_highest_ready )( context, node );
+
+ /*
+ * The node has been extracted from the scheduled chain. We have to place
+ * it now on the scheduled or ready set.
+ */
+ if (
+ node->sticky_level > 0
+ && ( *order )( &insert_priority, &highest_ready->Node.Chain )
+ ) {
+ ( *insert_scheduled )( context, node, insert_priority );
+
+ if ( _Scheduler_Node_get_idle( node ) != NULL ) {
+ Thread_Control *owner;
+ ISR_lock_Context lock_context;
+
+ owner = _Scheduler_Node_get_owner( node );
+ _Thread_Scheduler_acquire_critical( owner, &lock_context );
+
+ if ( owner->Scheduler.state == THREAD_SCHEDULER_READY ) {
+ _Thread_Scheduler_cancel_need_for_help(
+ owner,
+ _Thread_Get_CPU( owner )
+ );
+ _Scheduler_Discard_idle_thread(
+ context,
+ owner,
+ node,
+ _Scheduler_SMP_Release_idle_thread
+ );
+ _Scheduler_Thread_change_state( owner, THREAD_SCHEDULER_SCHEDULED );
+ }
+
+ _Thread_Scheduler_release_critical( owner, &lock_context );
+ }
+
+ return false;
+ }
+
+ action = _Scheduler_Try_to_schedule_node(
+ context,
+ highest_ready,
+ _Scheduler_Node_get_idle( node ),
+ _Scheduler_SMP_Get_idle_thread
+ );
+
+ if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE ) {
+ Thread_Control *idle;
+
+ _Scheduler_SMP_Preempt(
+ context,
+ highest_ready,
+ node,
+ allocate_processor
+ );
+
+ ( *insert_ready )( context, node, insert_priority );
+ ( *move_from_ready_to_scheduled )( context, highest_ready );
+
+ idle = _Scheduler_Release_idle_thread(
+ context,
+ node,
+ _Scheduler_SMP_Release_idle_thread
+ );
+ return ( idle == NULL );
+ } else if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_IDLE_EXCHANGE ) {
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
+ _Scheduler_SMP_Node_change_state(
+ highest_ready,
+ SCHEDULER_SMP_NODE_SCHEDULED
+ );
+
+ ( *insert_ready )( context, node, insert_priority );
+ ( *move_from_ready_to_scheduled )( context, highest_ready );
+
+ _Scheduler_Exchange_idle_thread(
+ highest_ready,
+ node,
+ _Scheduler_Node_get_idle( node )
+ );
+ return false;
+ } else {
+ _Assert( action == SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK );
+
+ _Scheduler_SMP_Node_change_state(
+ highest_ready,
+ SCHEDULER_SMP_NODE_BLOCKED
+ );
+
+ ( *extract_from_ready )( context, highest_ready );
+ }
+ }
+}
+
+static inline void _Scheduler_SMP_Extract_from_scheduled(
+ Scheduler_Node *node
+)
+{
+ _Chain_Extract_unprotected( &node->Node.Chain );
+}
+
+static inline void _Scheduler_SMP_Schedule_highest_ready(
+ Scheduler_Context *context,
+ Scheduler_Node *victim,
+ Per_CPU_Control *victim_cpu,
+ Scheduler_SMP_Extract extract_from_ready,
+ Scheduler_SMP_Get_highest_ready get_highest_ready,
+ Scheduler_SMP_Move move_from_ready_to_scheduled,
+ Scheduler_SMP_Allocate_processor allocate_processor
+)
+{
+ Scheduler_Try_to_schedule_action action;
+
+ do {
+ Scheduler_Node *highest_ready = ( *get_highest_ready )( context, victim );
+
+ action = _Scheduler_Try_to_schedule_node(
+ context,
+ highest_ready,
+ NULL,
+ _Scheduler_SMP_Get_idle_thread
+ );
+
+ if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE ) {
+ _Scheduler_SMP_Allocate_processor(
+ context,
+ highest_ready,
+ victim,
+ victim_cpu,
+ allocate_processor
+ );
+
+ ( *move_from_ready_to_scheduled )( context, highest_ready );
+ } else {
+ _Assert( action == SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK );
+
+ _Scheduler_SMP_Node_change_state(
+ highest_ready,
+ SCHEDULER_SMP_NODE_BLOCKED
+ );
+
+ ( *extract_from_ready )( context, highest_ready );
+ }
+ } while ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK );
+}
+
+static inline void _Scheduler_SMP_Preempt_and_schedule_highest_ready(
+ Scheduler_Context *context,
+ Scheduler_Node *victim,
+ Per_CPU_Control *victim_cpu,
+ Scheduler_SMP_Extract extract_from_ready,
+ Scheduler_SMP_Get_highest_ready get_highest_ready,
+ Scheduler_SMP_Move move_from_ready_to_scheduled,
+ Scheduler_SMP_Allocate_processor allocate_processor
+)
+{
+ Scheduler_Try_to_schedule_action action;
+
+ do {
+ Scheduler_Node *highest_ready = ( *get_highest_ready )( context, victim );
+
+ action = _Scheduler_Try_to_schedule_node(
+ context,
+ highest_ready,
+ NULL,
+ _Scheduler_SMP_Get_idle_thread
+ );
+
+ if ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_SCHEDULE ) {
+ _Scheduler_SMP_Preempt(
+ context,
+ highest_ready,
+ victim,
+ allocate_processor
+ );
+
+ ( *move_from_ready_to_scheduled )( context, highest_ready );
+ } else {
+ _Assert( action == SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK );
+
+ _Scheduler_SMP_Node_change_state(
+ highest_ready,
+ SCHEDULER_SMP_NODE_BLOCKED
+ );
+
+ ( *extract_from_ready )( context, highest_ready );
+ }
+ } while ( action == SCHEDULER_TRY_TO_SCHEDULE_DO_BLOCK );
+}
+
+/**
+ * @brief Blocks a thread.
+ *
+ * @param[in] context The scheduler instance context.
+ * @param[in] thread The thread of the scheduling operation.
+ * @param[in] node The scheduler node of the thread to block.
+ * @param[in] extract_from_ready Function to extract a node from the set of
+ * ready nodes.
+ * @param[in] get_highest_ready Function to get the highest ready node.
+ * @param[in] move_from_ready_to_scheduled Function to move a node from the set
+ * of ready nodes to the set of scheduled nodes.
+ */
+static inline void _Scheduler_SMP_Block(
+ Scheduler_Context *context,
+ Thread_Control *thread,
+ Scheduler_Node *node,
+ Scheduler_SMP_Extract extract_from_ready,
+ Scheduler_SMP_Get_highest_ready get_highest_ready,
+ Scheduler_SMP_Move move_from_ready_to_scheduled,
+ Scheduler_SMP_Allocate_processor allocate_processor
+)
+{
+ Scheduler_SMP_Node_state node_state;
+ Per_CPU_Control *thread_cpu;
+
+ node_state = _Scheduler_SMP_Node_state( node );
+
+ thread_cpu = _Scheduler_Block_node(
+ context,
+ thread,
+ node,
+ node_state == SCHEDULER_SMP_NODE_SCHEDULED,
+ _Scheduler_SMP_Get_idle_thread
+ );
+
+ if ( thread_cpu != NULL ) {
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_BLOCKED );
+
+ if ( node_state == SCHEDULER_SMP_NODE_SCHEDULED ) {
+ _Scheduler_SMP_Extract_from_scheduled( node );
+ _Scheduler_SMP_Schedule_highest_ready(
+ context,
+ node,
+ thread_cpu,
+ extract_from_ready,
+ get_highest_ready,
+ move_from_ready_to_scheduled,
+ allocate_processor
+ );
+ } else if ( node_state == SCHEDULER_SMP_NODE_READY ) {
+ ( *extract_from_ready )( context, node );
+ }
+ }
+}
+
+static inline void _Scheduler_SMP_Unblock(
+ Scheduler_Context *context,
+ Thread_Control *thread,
+ Scheduler_Node *node,
+ Scheduler_SMP_Update update,
+ Scheduler_SMP_Enqueue enqueue
+)
+{
+ Scheduler_SMP_Node_state node_state;
+ bool unblock;
+
+ node_state = _Scheduler_SMP_Node_state( node );
+ unblock = _Scheduler_Unblock_node(
+ context,
+ thread,
+ node,
+ node_state == SCHEDULER_SMP_NODE_SCHEDULED,
+ _Scheduler_SMP_Release_idle_thread
+ );
+
+ if ( unblock ) {
+ Priority_Control priority;
+ bool needs_help;
+
+ priority = _Scheduler_Node_get_priority( node );
+ priority = SCHEDULER_PRIORITY_PURIFY( priority );
+
+ if ( priority != _Scheduler_SMP_Node_priority( node ) ) {
+ ( *update )( context, node, priority );
+ }
+
+ if ( node_state == SCHEDULER_SMP_NODE_BLOCKED ) {
+ Priority_Control insert_priority;
+
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
+ insert_priority = SCHEDULER_PRIORITY_APPEND( priority );
+ needs_help = ( *enqueue )( context, node, insert_priority );
+ } else {
+ _Assert( node_state == SCHEDULER_SMP_NODE_READY );
+ _Assert( node->sticky_level > 0 );
+ _Assert( node->idle == NULL );
+ needs_help = true;
+ }
+
+ if ( needs_help ) {
+ _Scheduler_Ask_for_help( thread );
+ }
+ }
+}
+
+static inline void _Scheduler_SMP_Update_priority(
+ Scheduler_Context *context,
+ Thread_Control *thread,
+ Scheduler_Node *node,
+ Scheduler_SMP_Extract extract_from_ready,
+ Scheduler_SMP_Update update,
+ Scheduler_SMP_Enqueue enqueue,
+ Scheduler_SMP_Enqueue enqueue_scheduled,
+ Scheduler_SMP_Ask_for_help ask_for_help
+)
+{
+ Priority_Control priority;
+ Priority_Control insert_priority;
+ Scheduler_SMP_Node_state node_state;
+
+ insert_priority = _Scheduler_Node_get_priority( node );
+ priority = SCHEDULER_PRIORITY_PURIFY( insert_priority );
+
+ if ( priority == _Scheduler_SMP_Node_priority( node ) ) {
+ if ( _Thread_Is_ready( thread ) ) {
+ ( *ask_for_help )( context, thread, node );
+ }
+
+ return;
+ }
+
+ node_state = _Scheduler_SMP_Node_state( node );
+
+ if ( node_state == SCHEDULER_SMP_NODE_SCHEDULED ) {
+ _Scheduler_SMP_Extract_from_scheduled( node );
+ ( *update )( context, node, priority );
+ ( *enqueue_scheduled )( context, node, insert_priority );
+ } else if ( node_state == SCHEDULER_SMP_NODE_READY ) {
+ ( *extract_from_ready )( context, node );
+ ( *update )( context, node, priority );
+ ( *enqueue )( context, node, insert_priority );
+ } else {
+ ( *update )( context, node, priority );
+
+ if ( _Thread_Is_ready( thread ) ) {
+ ( *ask_for_help )( context, thread, node );
+ }
+ }
+}
+
+static inline void _Scheduler_SMP_Yield(
+ Scheduler_Context *context,
+ Thread_Control *thread,
+ Scheduler_Node *node,
+ Scheduler_SMP_Extract extract_from_ready,
+ Scheduler_SMP_Enqueue enqueue,
+ Scheduler_SMP_Enqueue enqueue_scheduled
+)
+{
+ bool needs_help;
+ Scheduler_SMP_Node_state node_state;
+ Priority_Control insert_priority;
+
+ node_state = _Scheduler_SMP_Node_state( node );
+ insert_priority = _Scheduler_SMP_Node_priority( node );
+ insert_priority = SCHEDULER_PRIORITY_APPEND( insert_priority );
+
+ if ( node_state == SCHEDULER_SMP_NODE_SCHEDULED ) {
+ _Scheduler_SMP_Extract_from_scheduled( node );
+ ( *enqueue_scheduled )( context, node, insert_priority );
+ needs_help = false;
+ } else if ( node_state == SCHEDULER_SMP_NODE_READY ) {
+ ( *extract_from_ready )( context, node );
+
+ needs_help = ( *enqueue )( context, node, insert_priority );
+ } else {
+ needs_help = true;
+ }
+
+ if ( needs_help ) {
+ _Scheduler_Ask_for_help( thread );
+ }
+}
+
+static inline void _Scheduler_SMP_Insert_scheduled(
+ Scheduler_Context *context,
+ Scheduler_Node *node_to_insert,
+ Priority_Control priority_to_insert
+)
+{
+ Scheduler_SMP_Context *self;
+
+ self = _Scheduler_SMP_Get_self( context );
+
+ _Chain_Insert_ordered_unprotected(
+ &self->Scheduled,
+ &node_to_insert->Node.Chain,
+ &priority_to_insert,
+ _Scheduler_SMP_Priority_less_equal
+ );
+}
+
+static inline bool _Scheduler_SMP_Ask_for_help(
+ Scheduler_Context *context,
+ Thread_Control *thread,
+ Scheduler_Node *node,
+ Chain_Node_order order,
+ Scheduler_SMP_Insert insert_ready,
+ Scheduler_SMP_Insert insert_scheduled,
+ Scheduler_SMP_Move move_from_scheduled_to_ready,
+ Scheduler_SMP_Get_lowest_scheduled get_lowest_scheduled,
+ Scheduler_SMP_Allocate_processor allocate_processor
+)
+{
+ Scheduler_Node *lowest_scheduled;
+ ISR_lock_Context lock_context;
+ bool success;
+
+ lowest_scheduled = ( *get_lowest_scheduled )( context, node );
+
+ _Thread_Scheduler_acquire_critical( thread, &lock_context );
+
+ if ( thread->Scheduler.state == THREAD_SCHEDULER_READY ) {
+ Scheduler_SMP_Node_state node_state;
+
+ node_state = _Scheduler_SMP_Node_state( node );
+
+ if ( node_state == SCHEDULER_SMP_NODE_BLOCKED ) {
+ Priority_Control insert_priority;
+
+ insert_priority = _Scheduler_SMP_Node_priority( node );
+
+ if ( ( *order )( &insert_priority, &lowest_scheduled->Node.Chain ) ) {
+ _Thread_Scheduler_cancel_need_for_help(
+ thread,
+ _Thread_Get_CPU( thread )
+ );
+ _Scheduler_Thread_change_state( thread, THREAD_SCHEDULER_SCHEDULED );
+ _Thread_Scheduler_release_critical( thread, &lock_context );
+
+ _Scheduler_SMP_Preempt(
+ context,
+ node,
+ lowest_scheduled,
+ allocate_processor
+ );
+
+ ( *insert_scheduled )( context, node, insert_priority );
+ ( *move_from_scheduled_to_ready )( context, lowest_scheduled );
+
+ _Scheduler_Release_idle_thread(
+ context,
+ lowest_scheduled,
+ _Scheduler_SMP_Release_idle_thread
+ );
+ success = true;
+ } else {
+ _Thread_Scheduler_release_critical( thread, &lock_context );
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
+ ( *insert_ready )( context, node, insert_priority );
+ success = false;
+ }
+ } else if ( node_state == SCHEDULER_SMP_NODE_SCHEDULED ) {
+ _Thread_Scheduler_cancel_need_for_help(
+ thread,
+ _Thread_Get_CPU( thread )
+ );
+ _Scheduler_Discard_idle_thread(
+ context,
+ thread,
+ node,
+ _Scheduler_SMP_Release_idle_thread
+ );
+ _Scheduler_Thread_change_state( thread, THREAD_SCHEDULER_SCHEDULED );
+ _Thread_Scheduler_release_critical( thread, &lock_context );
+ success = true;
+ } else {
+ _Thread_Scheduler_release_critical( thread, &lock_context );
+ success = false;
+ }
+ } else {
+ _Thread_Scheduler_release_critical( thread, &lock_context );
+ success = false;
+ }
+
+ return success;
+}
+
+static inline void _Scheduler_SMP_Reconsider_help_request(
+ Scheduler_Context *context,
+ Thread_Control *thread,
+ Scheduler_Node *node,
+ Scheduler_SMP_Extract extract_from_ready
+)
+{
+ ISR_lock_Context lock_context;
+
+ _Thread_Scheduler_acquire_critical( thread, &lock_context );
+
+ if (
+ thread->Scheduler.state == THREAD_SCHEDULER_SCHEDULED
+ && _Scheduler_SMP_Node_state( node ) == SCHEDULER_SMP_NODE_READY
+ && node->sticky_level == 1
+ ) {
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_BLOCKED );
+ ( *extract_from_ready )( context, node );
+ }
+
+ _Thread_Scheduler_release_critical( thread, &lock_context );
+}
+
+static inline void _Scheduler_SMP_Withdraw_node(
+ Scheduler_Context *context,
+ Thread_Control *thread,
+ Scheduler_Node *node,
+ Thread_Scheduler_state next_state,
+ Scheduler_SMP_Extract extract_from_ready,
+ Scheduler_SMP_Get_highest_ready get_highest_ready,
+ Scheduler_SMP_Move move_from_ready_to_scheduled,
+ Scheduler_SMP_Allocate_processor allocate_processor
+)
+{
+ ISR_lock_Context lock_context;
+ Scheduler_SMP_Node_state node_state;
+
+ _Thread_Scheduler_acquire_critical( thread, &lock_context );
+
+ node_state = _Scheduler_SMP_Node_state( node );
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_BLOCKED );
+
+ if ( node_state == SCHEDULER_SMP_NODE_SCHEDULED ) {
+ Per_CPU_Control *thread_cpu;
+
+ thread_cpu = _Thread_Get_CPU( thread );
+ _Scheduler_Thread_change_state( thread, next_state );
+ _Thread_Scheduler_release_critical( thread, &lock_context );
+
+ _Scheduler_SMP_Extract_from_scheduled( node );
+ _Scheduler_SMP_Schedule_highest_ready(
+ context,
+ node,
+ thread_cpu,
+ extract_from_ready,
+ get_highest_ready,
+ move_from_ready_to_scheduled,
+ allocate_processor
+ );
+ } else if ( node_state == SCHEDULER_SMP_NODE_READY ) {
+ _Thread_Scheduler_release_critical( thread, &lock_context );
+ ( *extract_from_ready )( context, node );
+ } else {
+ _Assert( node_state == SCHEDULER_SMP_NODE_BLOCKED );
+ _Thread_Scheduler_release_critical( thread, &lock_context );
+ }
+}
+
+static inline void _Scheduler_SMP_Do_start_idle(
+ Scheduler_Context *context,
+ Thread_Control *idle,
+ Per_CPU_Control *cpu,
+ Scheduler_SMP_Register_idle register_idle
+)
+{
+ Scheduler_SMP_Context *self;
+ Scheduler_SMP_Node *node;
+
+ self = _Scheduler_SMP_Get_self( context );
+ node = _Scheduler_SMP_Thread_get_node( idle );
+
+ _Scheduler_Thread_change_state( idle, THREAD_SCHEDULER_SCHEDULED );
+ node->state = SCHEDULER_SMP_NODE_SCHEDULED;
+
+ _Thread_Set_CPU( idle, cpu );
+ ( *register_idle )( context, &node->Base, cpu );
+ _Chain_Append_unprotected( &self->Scheduled, &node->Base.Node.Chain );
+ _Scheduler_SMP_Release_idle_thread( &self->Base, idle );
+}
+
+static inline void _Scheduler_SMP_Add_processor(
+ Scheduler_Context *context,
+ Thread_Control *idle,
+ Scheduler_SMP_Has_ready has_ready,
+ Scheduler_SMP_Enqueue enqueue_scheduled,
+ Scheduler_SMP_Register_idle register_idle
+)
+{
+ Scheduler_SMP_Context *self;
+ Scheduler_Node *node;
+
+ self = _Scheduler_SMP_Get_self( context );
+ idle->Scheduler.state = THREAD_SCHEDULER_SCHEDULED;
+ _Scheduler_SMP_Release_idle_thread( &self->Base, idle );
+ node = _Thread_Scheduler_get_home_node( idle );
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_SCHEDULED );
+ ( *register_idle )( context, node, _Thread_Get_CPU( idle ) );
+
+ if ( ( *has_ready )( &self->Base ) ) {
+ Priority_Control insert_priority;
+
+ insert_priority = _Scheduler_SMP_Node_priority( node );
+ insert_priority = SCHEDULER_PRIORITY_APPEND( insert_priority );
+ ( *enqueue_scheduled )( &self->Base, node, insert_priority );
+ } else {
+ _Chain_Append_unprotected( &self->Scheduled, &node->Node.Chain );
+ }
+}
+
+static inline Thread_Control *_Scheduler_SMP_Remove_processor(
+ Scheduler_Context *context,
+ Per_CPU_Control *cpu,
+ Scheduler_SMP_Extract extract_from_ready,
+ Scheduler_SMP_Enqueue enqueue
+)
+{
+ Scheduler_SMP_Context *self;
+ Chain_Node *chain_node;
+ Scheduler_Node *victim_node;
+ Thread_Control *victim_user;
+ Thread_Control *victim_owner;
+ Thread_Control *idle;
+
+ self = _Scheduler_SMP_Get_self( context );
+ chain_node = _Chain_First( &self->Scheduled );
+
+ do {
+ _Assert( chain_node != _Chain_Immutable_tail( &self->Scheduled ) );
+ victim_node = (Scheduler_Node *) chain_node;
+ victim_user = _Scheduler_Node_get_user( victim_node );
+ chain_node = _Chain_Next( chain_node );
+ } while ( _Thread_Get_CPU( victim_user ) != cpu );
+
+ _Scheduler_SMP_Extract_from_scheduled( victim_node );
+ victim_owner = _Scheduler_Node_get_owner( victim_node );
+
+ if ( !victim_owner->is_idle ) {
+ Scheduler_Node *idle_node;
+
+ _Scheduler_Release_idle_thread(
+ &self->Base,
+ victim_node,
+ _Scheduler_SMP_Release_idle_thread
+ );
+ idle = _Scheduler_SMP_Get_idle_thread( &self->Base );
+ idle_node = _Thread_Scheduler_get_home_node( idle );
+ ( *extract_from_ready )( &self->Base, idle_node );
+ _Scheduler_SMP_Preempt(
+ &self->Base,
+ idle_node,
+ victim_node,
+ _Scheduler_SMP_Allocate_processor_exact
+ );
+
+ if ( !_Chain_Is_empty( &self->Scheduled ) ) {
+ Priority_Control insert_priority;
+
+ insert_priority = _Scheduler_SMP_Node_priority( victim_node );
+ insert_priority = SCHEDULER_PRIORITY_APPEND( insert_priority );
+ ( *enqueue )( context, victim_node, insert_priority );
+ }
+ } else {
+ _Assert( victim_owner == victim_user );
+ _Assert( _Scheduler_Node_get_idle( victim_node ) == NULL );
+ idle = victim_owner;
+ _Scheduler_SMP_Exctract_idle_thread( idle );
+ }
+
+ return idle;
+}
+
+static inline void _Scheduler_SMP_Set_affinity(
+ Scheduler_Context *context,
+ Thread_Control *thread,
+ Scheduler_Node *node,
+ void *arg,
+ Scheduler_SMP_Set_affinity set_affinity,
+ Scheduler_SMP_Extract extract_from_ready,
+ Scheduler_SMP_Get_highest_ready get_highest_ready,
+ Scheduler_SMP_Move move_from_ready_to_scheduled,
+ Scheduler_SMP_Enqueue enqueue,
+ Scheduler_SMP_Allocate_processor allocate_processor
+)
+{
+ Scheduler_SMP_Node_state node_state;
+ Priority_Control insert_priority;
+
+ node_state = _Scheduler_SMP_Node_state( node );
+ insert_priority = _Scheduler_SMP_Node_priority( node );
+ insert_priority = SCHEDULER_PRIORITY_APPEND( insert_priority );
+
+ if ( node_state == SCHEDULER_SMP_NODE_SCHEDULED ) {
+ _Scheduler_SMP_Extract_from_scheduled( node );
+ _Scheduler_SMP_Preempt_and_schedule_highest_ready(
+ context,
+ node,
+ _Thread_Get_CPU( thread ),
+ extract_from_ready,
+ get_highest_ready,
+ move_from_ready_to_scheduled,
+ allocate_processor
+ );
+ ( *set_affinity )( context, node, arg );
+ ( *enqueue )( context, node, insert_priority );
+ } else if ( node_state == SCHEDULER_SMP_NODE_READY ) {
+ ( *extract_from_ready )( context, node );
+ ( *set_affinity )( context, node, arg );
+ ( *enqueue )( context, node, insert_priority );
+ } else {
+ ( *set_affinity )( context, node, arg );
+ }
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_SCHEDULERSMPIMPL_H */
diff --git a/cpukit/include/rtems/score/schedulerstrongapa.h b/cpukit/include/rtems/score/schedulerstrongapa.h
new file mode 100644
index 0000000000..d961f20c68
--- /dev/null
+++ b/cpukit/include/rtems/score/schedulerstrongapa.h
@@ -0,0 +1,171 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSchedulerStrongAPA
+ *
+ * @brief Strong APA Scheduler API
+ */
+
+/*
+ * Copyright (c) 2013, 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_SCHEDULERSTRONGAPA_H
+#define _RTEMS_SCORE_SCHEDULERSTRONGAPA_H
+
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/schedulersmp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ScoreSchedulerStrongAPA Strong APA Scheduler
+ *
+ * @ingroup ScoreSchedulerSMP
+ *
+ * This is an implementation of the global fixed priority scheduler (G-FP). It
+ * uses one ready chain per priority to ensure constant time insert operations.
+ * The scheduled chain uses linear insert operations and has at most processor
+ * count entries. Since the processor and priority count are constants all
+ * scheduler operations complete in a bounded execution time.
+ *
+ * The the_thread preempt mode will be ignored.
+ *
+ * @{
+ */
+
+/**
+ * @brief Scheduler context specialization for Strong APA
+ * schedulers.
+ */
+typedef struct {
+ Scheduler_SMP_Context Base;
+ Priority_bit_map_Control Bit_map;
+ Chain_Control Ready[ RTEMS_ZERO_LENGTH_ARRAY ];
+} Scheduler_strong_APA_Context;
+
+/**
+ * @brief Scheduler node specialization for Strong APA
+ * schedulers.
+ */
+typedef struct {
+ /**
+ * @brief SMP scheduler node.
+ */
+ Scheduler_SMP_Node Base;
+
+ /**
+ * @brief The associated ready queue of this node.
+ */
+ Scheduler_priority_Ready_queue Ready_queue;
+} Scheduler_strong_APA_Node;
+
+/**
+ * @brief Entry points for the Strong APA Scheduler.
+ */
+#define SCHEDULER_STRONG_APA_ENTRY_POINTS \
+ { \
+ _Scheduler_strong_APA_Initialize, \
+ _Scheduler_default_Schedule, \
+ _Scheduler_strong_APA_Yield, \
+ _Scheduler_strong_APA_Block, \
+ _Scheduler_strong_APA_Unblock, \
+ _Scheduler_strong_APA_Update_priority, \
+ _Scheduler_default_Map_priority, \
+ _Scheduler_default_Unmap_priority, \
+ _Scheduler_strong_APA_Ask_for_help, \
+ _Scheduler_strong_APA_Reconsider_help_request, \
+ _Scheduler_strong_APA_Withdraw_node, \
+ _Scheduler_strong_APA_Add_processor, \
+ _Scheduler_strong_APA_Remove_processor, \
+ _Scheduler_strong_APA_Node_initialize, \
+ _Scheduler_default_Node_destroy, \
+ _Scheduler_default_Release_job, \
+ _Scheduler_default_Cancel_job, \
+ _Scheduler_default_Tick, \
+ _Scheduler_SMP_Start_idle \
+ SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY \
+ }
+
+void _Scheduler_strong_APA_Initialize( const Scheduler_Control *scheduler );
+
+void _Scheduler_strong_APA_Node_initialize(
+ const Scheduler_Control *scheduler,
+ Scheduler_Node *node,
+ Thread_Control *the_thread,
+ Priority_Control priority
+);
+
+void _Scheduler_strong_APA_Block(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_strong_APA_Unblock(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_strong_APA_Update_priority(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+bool _Scheduler_strong_APA_Ask_for_help(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_strong_APA_Reconsider_help_request(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+void _Scheduler_strong_APA_Withdraw_node(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node,
+ Thread_Scheduler_state next_state
+);
+
+void _Scheduler_strong_APA_Add_processor(
+ const Scheduler_Control *scheduler,
+ Thread_Control *idle
+);
+
+Thread_Control *_Scheduler_strong_APA_Remove_processor(
+ const Scheduler_Control *scheduler,
+ struct Per_CPU_Control *cpu
+);
+
+void _Scheduler_strong_APA_Yield(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Scheduler_Node *node
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_SCHEDULERSTRONGAPA_H */
diff --git a/cpukit/include/rtems/score/semaphoreimpl.h b/cpukit/include/rtems/score/semaphoreimpl.h
new file mode 100644
index 0000000000..a7857db93e
--- /dev/null
+++ b/cpukit/include/rtems/score/semaphoreimpl.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2015, 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_SEMAPHOREIMPL_H
+#define _RTEMS_SCORE_SEMAPHOREIMPL_H
+
+#include <sys/lock.h>
+
+#include <rtems/score/percpu.h>
+#include <rtems/score/threadqimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct {
+ Thread_queue_Syslock_queue Queue;
+ unsigned int count;
+} Sem_Control;
+
+#define SEMAPHORE_TQ_OPERATIONS &_Thread_queue_Operations_priority
+
+static inline Sem_Control *_Sem_Get( struct _Semaphore_Control *_sem )
+{
+ return (Sem_Control *) _sem;
+}
+
+static inline Thread_Control *_Sem_Queue_acquire_critical(
+ Sem_Control *sem,
+ Thread_queue_Context *queue_context
+)
+{
+ Thread_Control *executing;
+
+ executing = _Thread_Executing;
+ _Thread_queue_Queue_acquire_critical(
+ &sem->Queue.Queue,
+ &executing->Potpourri_stats,
+ &queue_context->Lock_context.Lock_context
+ );
+
+ return executing;
+}
+
+static inline void _Sem_Queue_release(
+ Sem_Control *sem,
+ ISR_Level level,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Queue_release_critical(
+ &sem->Queue.Queue,
+ &queue_context->Lock_context.Lock_context
+ );
+ _ISR_Local_enable( level );
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_SEMAPHOREIMPL_H */
diff --git a/cpukit/include/rtems/score/smp.h b/cpukit/include/rtems/score/smp.h
new file mode 100644
index 0000000000..469025e5dc
--- /dev/null
+++ b/cpukit/include/rtems/score/smp.h
@@ -0,0 +1,64 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSMP
+ *
+ * @brief SuperCore SMP Support API
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_SMP_H
+#define _RTEMS_SCORE_SMP_H
+
+#include <rtems/score/cpu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreSMP SMP Support
+ *
+ * @ingroup Score
+ *
+ * This defines the interface of the SuperCore SMP support.
+ *
+ * @{
+ */
+
+#if defined( RTEMS_SMP )
+ extern uint32_t _SMP_Processor_count;
+
+ static inline uint32_t _SMP_Get_processor_count( void )
+ {
+ return _SMP_Processor_count;
+ }
+#else
+ #define _SMP_Get_processor_count() UINT32_C(1)
+#endif
+
+#if defined( RTEMS_SMP )
+ static inline uint32_t _SMP_Get_current_processor( void )
+ {
+ return _CPU_SMP_Get_current_processor();
+ }
+#else
+ #define _SMP_Get_current_processor() UINT32_C(0)
+#endif
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/smpbarrier.h b/cpukit/include/rtems/score/smpbarrier.h
new file mode 100644
index 0000000000..fddf7bb1cd
--- /dev/null
+++ b/cpukit/include/rtems/score/smpbarrier.h
@@ -0,0 +1,125 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSMPBarrier
+ *
+ * @brief SMP Barrier API
+ */
+
+/*
+ * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_SMPBARRIER_H
+#define _RTEMS_SCORE_SMPBARRIER_H
+
+#include <rtems/score/cpuopts.h>
+#include <rtems/score/atomic.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ScoreSMPBarrier SMP Barriers
+ *
+ * @ingroup Score
+ *
+ * @brief The SMP barrier provides barrier synchronization for SMP systems at
+ * the lowest level.
+ *
+ * The SMP barrier is implemented as a sense barrier, see also Herlihy and
+ * Shavit, "The Art of Multiprocessor Programming", 17.3 Sense-Reversing
+ * Barrier.
+ *
+ * @{
+ */
+
+/**
+ * @brief SMP barrier control.
+ */
+typedef struct {
+ Atomic_Uint value;
+ Atomic_Uint sense;
+} SMP_barrier_Control;
+
+/**
+ * @brief SMP barrier per-thread state.
+ *
+ * Each user of the barrier must provide this per-thread state.
+ */
+typedef struct {
+ unsigned int sense;
+} SMP_barrier_State;
+
+/**
+ * @brief SMP barrier control initializer for static initialization.
+ */
+#define SMP_BARRIER_CONTROL_INITIALIZER \
+ { ATOMIC_INITIALIZER_UINT( 0U ), ATOMIC_INITIALIZER_UINT( 0U ) }
+
+/**
+ * @brief SMP barrier per-thread state initializer for static initialization.
+ */
+#define SMP_BARRIER_STATE_INITIALIZER { 0U }
+
+/**
+ * @brief Initializes a SMP barrier control.
+ *
+ * Concurrent initialization leads to unpredictable results.
+ *
+ * @param[out] control The SMP barrier control.
+ */
+static inline void _SMP_barrier_Control_initialize(
+ SMP_barrier_Control *control
+)
+{
+ _Atomic_Init_uint( &control->value, 0U );
+ _Atomic_Init_uint( &control->sense, 0U );
+}
+
+/**
+ * @brief Initializes a SMP barrier per-thread state.
+ *
+ * @param[out] state The SMP barrier control.
+ */
+static inline void _SMP_barrier_State_initialize(
+ SMP_barrier_State *state
+)
+{
+ state->sense = 0U;
+}
+
+/**
+ * @brief Waits on the SMP barrier until count threads rendezvoused.
+ *
+ * @param[in, out] control The SMP barrier control.
+ * @param[in, out] state The SMP barrier per-thread state.
+ * @param[in] count The thread count bound to rendezvous.
+ *
+ * @retval true This processor performed the barrier release.
+ * @retval false Otherwise.
+ */
+bool _SMP_barrier_Wait(
+ SMP_barrier_Control *control,
+ SMP_barrier_State *state,
+ unsigned int count
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_SMPBARRIER_H */
diff --git a/cpukit/include/rtems/score/smpimpl.h b/cpukit/include/rtems/score/smpimpl.h
new file mode 100644
index 0000000000..48e6a12498
--- /dev/null
+++ b/cpukit/include/rtems/score/smpimpl.h
@@ -0,0 +1,354 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSMPImpl
+ *
+ * @brief SuperCore SMP Implementation
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_SMPIMPL_H
+#define _RTEMS_SCORE_SMPIMPL_H
+
+#include <rtems/score/smp.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/processormask.h>
+#include <rtems/fatal.h>
+#include <rtems/rtems/cache.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreSMP SMP Support
+ *
+ * @ingroup Score
+ *
+ * This defines the interface of the SuperCore SMP support.
+ *
+ * @{
+ */
+
+/**
+ * @brief SMP message to request a processor shutdown.
+ *
+ * @see _SMP_Send_message().
+ */
+#define SMP_MESSAGE_SHUTDOWN 0x1UL
+
+/**
+ * @brief SMP message to request a test handler invocation.
+ *
+ * @see _SMP_Send_message().
+ */
+#define SMP_MESSAGE_TEST 0x2UL
+
+/**
+ * @brief SMP message to request a multicast action.
+ *
+ * @see _SMP_Send_message().
+ */
+#define SMP_MESSAGE_MULTICAST_ACTION 0x4UL
+
+/**
+ * @brief SMP message to request a clock tick.
+ *
+ * This message is provided for systems without a proper interrupt affinity
+ * support and may be used by the clock driver.
+ *
+ * @see _SMP_Send_message().
+ */
+#define SMP_MESSAGE_CLOCK_TICK 0x8UL
+
+/**
+ * @brief SMP fatal codes.
+ */
+typedef enum {
+ SMP_FATAL_BOOT_PROCESSOR_NOT_ASSIGNED_TO_SCHEDULER,
+ SMP_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT,
+ SMP_FATAL_MULTITASKING_START_ON_INVALID_PROCESSOR,
+ SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR,
+ SMP_FATAL_SHUTDOWN,
+ SMP_FATAL_SHUTDOWN_RESPONSE,
+ SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED
+} SMP_Fatal_code;
+
+static inline void _SMP_Fatal( SMP_Fatal_code code )
+{
+ _Terminate( RTEMS_FATAL_SOURCE_SMP, code );
+}
+
+/**
+ * @brief Initialize SMP Handler
+ *
+ * This method initialize the SMP Handler.
+ */
+#if defined( RTEMS_SMP )
+ void _SMP_Handler_initialize( void );
+#else
+ #define _SMP_Handler_initialize() \
+ do { } while ( 0 )
+#endif
+
+#if defined( RTEMS_SMP )
+
+/**
+ * @brief Set of online processors.
+ *
+ * A processor is online if was started during system initialization. In this
+ * case its corresponding bit in the mask is set.
+ *
+ * @see _SMP_Handler_initialize().
+ */
+extern Processor_mask _SMP_Online_processors;
+
+/**
+ * @brief Performs high-level initialization of a secondary processor and runs
+ * the application threads.
+ *
+ * The low-level initialization code must call this function to hand over the
+ * control of this processor to RTEMS. Interrupts must be disabled. It must
+ * be possible to send inter-processor interrupts to this processor. Since
+ * interrupts are disabled the inter-processor interrupt delivery is postponed
+ * until interrupts are enabled the first time. Interrupts are enabled during
+ * the execution begin of threads in case they have interrupt level zero (this
+ * is the default).
+ *
+ * The pre-requisites for the call to this function are
+ * - disabled interrupts,
+ * - delivery of inter-processor interrupts is possible,
+ * - a valid stack pointer and enough stack space,
+ * - a valid code memory, and
+ * - a valid BSS section.
+ *
+ * This function must not be called by the main processor. The main processor
+ * uses _Thread_Start_multitasking() instead.
+ *
+ * This function does not return to the caller.
+ */
+void _SMP_Start_multitasking_on_secondary_processor( void )
+ RTEMS_NO_RETURN;
+
+typedef void ( *SMP_Test_message_handler )( Per_CPU_Control *cpu_self );
+
+extern SMP_Test_message_handler _SMP_Test_message_handler;
+
+/**
+ * @brief Sets the handler for test messages.
+ *
+ * This handler can be used to test the inter-processor interrupt
+ * implementation.
+ */
+static inline void _SMP_Set_test_message_handler(
+ SMP_Test_message_handler handler
+)
+{
+ _SMP_Test_message_handler = handler;
+}
+
+/**
+ * @brief Processes all pending multicast actions.
+ */
+void _SMP_Multicast_actions_process( void );
+
+/**
+ * @brief Interrupt handler for inter-processor interrupts.
+ *
+ * @return The received message.
+ */
+static inline long unsigned _SMP_Inter_processor_interrupt_handler( void )
+{
+ Per_CPU_Control *cpu_self;
+ unsigned long message;
+
+ cpu_self = _Per_CPU_Get();
+
+ /*
+ * In the common case the inter-processor interrupt is issued to carry out a
+ * thread dispatch.
+ */
+ cpu_self->dispatch_necessary = true;
+
+ message = _Atomic_Exchange_ulong(
+ &cpu_self->message,
+ 0,
+ ATOMIC_ORDER_ACQUIRE
+ );
+
+ if ( message != 0 ) {
+ if ( ( message & SMP_MESSAGE_SHUTDOWN ) != 0 ) {
+ _SMP_Fatal( SMP_FATAL_SHUTDOWN_RESPONSE );
+ /* does not continue past here */
+ }
+
+ if ( ( message & SMP_MESSAGE_TEST ) != 0 ) {
+ ( *_SMP_Test_message_handler )( cpu_self );
+ }
+
+ if ( ( message & SMP_MESSAGE_MULTICAST_ACTION ) != 0 ) {
+ _SMP_Multicast_actions_process();
+ }
+ }
+
+ return message;
+}
+
+/**
+ * @brief Returns true, if the processor with the specified index should be
+ * started.
+ *
+ * @param[in] cpu_index The processor index.
+ *
+ * @retval true The processor should be started.
+ * @retval false Otherwise.
+ */
+bool _SMP_Should_start_processor( uint32_t cpu_index );
+
+/**
+ * @brief Sends an SMP message to a processor.
+ *
+ * The target processor may be the sending processor.
+ *
+ * @param[in] cpu_index The target processor of the message.
+ * @param[in] message The message.
+ */
+void _SMP_Send_message( uint32_t cpu_index, unsigned long message );
+
+/**
+ * @brief Sends an SMP message to all other online processors.
+ *
+ * @param[in] message The message.
+ */
+void _SMP_Send_message_broadcast(
+ unsigned long message
+);
+
+/**
+ * @brief Sends an SMP message to a set of processors.
+ *
+ * The sending processor may be part of the set.
+ *
+ * @param[in] targets The set of processors to send the message.
+ * @param[in] message The message.
+ */
+void _SMP_Send_message_multicast(
+ const Processor_mask *targets,
+ unsigned long message
+);
+
+typedef void ( *SMP_Action_handler )( void *arg );
+
+/**
+ * @brief Initiates an SMP multicast action to a set of processors.
+ *
+ * The current processor may be part of the set.
+ *
+ * @param[in] setsize The size of the set of target processors of the message.
+ * @param[in] cpus The set of target processors of the message.
+ * @param[in] handler The multicast action handler.
+ * @param[in] arg The multicast action argument.
+ */
+void _SMP_Multicast_action(
+ const size_t setsize,
+ const cpu_set_t *cpus,
+ SMP_Action_handler handler,
+ void *arg
+);
+
+/**
+ * @brief Executes a handler with argument on the specified processor on behalf
+ * of the boot processor.
+ *
+ * The calling processor must be the boot processor. In case the specified
+ * processor is not online or not in the
+ * PER_CPU_STATE_READY_TO_START_MULTITASKING state, then no action is
+ * performed.
+ *
+ * @param cpu The processor to execute the action.
+ * @param handler The handler of the action.
+ * @param arg The argument of the action.
+ *
+ * @retval true The handler executed on the specified processor.
+ * @retval false Otherwise.
+ *
+ * @see _SMP_Before_multitasking_action_broadcast().
+ */
+bool _SMP_Before_multitasking_action(
+ Per_CPU_Control *cpu,
+ SMP_Action_handler handler,
+ void *arg
+);
+
+/**
+ * @brief Executes a handler with argument on all online processors except the
+ * boot processor on behalf of the boot processor.
+ *
+ * The calling processor must be the boot processor.
+ *
+ * @param handler The handler of the action.
+ * @param arg The argument of the action.
+ *
+ * @retval true The handler executed on all online processors except the boot
+ * processor.
+ * @retval false Otherwise.
+ *
+ * @see _SMP_Before_multitasking_action().
+ */
+bool _SMP_Before_multitasking_action_broadcast(
+ SMP_Action_handler handler,
+ void *arg
+);
+
+#endif /* defined( RTEMS_SMP ) */
+
+/**
+ * @brief Requests a multitasking start on all configured and available
+ * processors.
+ */
+#if defined( RTEMS_SMP )
+ void _SMP_Request_start_multitasking( void );
+#else
+ #define _SMP_Request_start_multitasking() \
+ do { } while ( 0 )
+#endif
+
+/**
+ * @brief Requests a shutdown of all processors.
+ *
+ * This function is a part of the system termination procedure.
+ *
+ * @see _Terminate().
+ */
+#if defined( RTEMS_SMP )
+ void _SMP_Request_shutdown( void );
+#else
+ #define _SMP_Request_shutdown() \
+ do { } while ( 0 )
+#endif
+
+RTEMS_INLINE_ROUTINE const Processor_mask *_SMP_Get_online_processors( void )
+{
+#if defined(RTEMS_SMP)
+ return &_SMP_Online_processors;
+#else
+ return &_Processor_mask_The_one_and_only;
+#endif
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/smplock.h b/cpukit/include/rtems/score/smplock.h
new file mode 100644
index 0000000000..a156edfd92
--- /dev/null
+++ b/cpukit/include/rtems/score/smplock.h
@@ -0,0 +1,327 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSMPLock
+ *
+ * @brief SMP Lock API
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Copyright (c) 2013, 2016 embedded brains GmbH
+ *
+ * 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_SMPLOCK_H
+#define _RTEMS_SCORE_SMPLOCK_H
+
+#include <rtems/score/cpuopts.h>
+
+#if defined(RTEMS_SMP)
+
+#include <rtems/score/smplockstats.h>
+#include <rtems/score/smplockticket.h>
+#include <rtems/score/isrlevel.h>
+
+#if defined(RTEMS_DEBUG)
+#include <rtems/score/assert.h>
+#include <rtems/score/smp.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ScoreSMPLock SMP Locks
+ *
+ * @ingroup Score
+ *
+ * @brief The SMP lock provides mutual exclusion for SMP systems at the lowest
+ * level.
+ *
+ * The SMP lock is implemented as a ticket lock. This provides fairness in
+ * case of concurrent lock attempts.
+ *
+ * This SMP lock API uses a local context for acquire and release pairs. Such
+ * a context may be used to implement for example the Mellor-Crummey and Scott
+ * (MCS) locks in the future.
+ *
+ * @{
+ */
+
+#if defined(RTEMS_DEBUG) || defined(RTEMS_PROFILING)
+#define RTEMS_SMP_LOCK_DO_NOT_INLINE
+#endif
+
+/**
+ * @brief SMP lock control.
+ */
+typedef struct {
+ SMP_ticket_lock_Control Ticket_lock;
+#if defined(RTEMS_DEBUG)
+ /**
+ * @brief The index of the owning processor of this lock.
+ *
+ * The processor index is used instead of the executing thread, so that this
+ * works in interrupt and system initialization context. It is assumed that
+ * thread dispatching is disabled in SMP lock critical sections.
+ *
+ * In case the lock is free, then the value of this field is
+ * SMP_LOCK_NO_OWNER.
+ *
+ * @see _SMP_lock_Is_owner().
+ */
+ uint32_t owner;
+#endif
+#if defined(RTEMS_PROFILING)
+ SMP_lock_Stats Stats;
+#endif
+} SMP_lock_Control;
+
+/**
+ * @brief Local SMP lock context for acquire and release pairs.
+ */
+typedef struct {
+ ISR_Level isr_level;
+#if defined(RTEMS_DEBUG)
+ SMP_lock_Control *lock_used_for_acquire;
+#endif
+#if defined(RTEMS_PROFILING)
+ SMP_lock_Stats_context Stats_context;
+#endif
+} SMP_lock_Context;
+
+#if defined(RTEMS_DEBUG)
+#define SMP_LOCK_NO_OWNER 0
+#endif
+
+/**
+ * @brief SMP lock control initializer for static initialization.
+ */
+#if defined(RTEMS_DEBUG) && defined(RTEMS_PROFILING)
+ #define SMP_LOCK_INITIALIZER( name ) \
+ { \
+ SMP_TICKET_LOCK_INITIALIZER, \
+ SMP_LOCK_NO_OWNER, \
+ SMP_LOCK_STATS_INITIALIZER( name ) \
+ }
+#elif defined(RTEMS_DEBUG)
+ #define SMP_LOCK_INITIALIZER( name ) \
+ { SMP_TICKET_LOCK_INITIALIZER, SMP_LOCK_NO_OWNER }
+#elif defined(RTEMS_PROFILING)
+ #define SMP_LOCK_INITIALIZER( name ) \
+ { SMP_TICKET_LOCK_INITIALIZER, SMP_LOCK_STATS_INITIALIZER( name ) }
+#else
+ #define SMP_LOCK_INITIALIZER( name ) { SMP_TICKET_LOCK_INITIALIZER }
+#endif
+
+static inline void _SMP_lock_Initialize_inline(
+ SMP_lock_Control *lock,
+ const char *name
+)
+{
+ _SMP_ticket_lock_Initialize( &lock->Ticket_lock );
+#if defined(RTEMS_DEBUG)
+ lock->owner = SMP_LOCK_NO_OWNER;
+#endif
+#if defined(RTEMS_PROFILING)
+ _SMP_lock_Stats_initialize( &lock->Stats, name );
+#else
+ (void) name;
+#endif
+}
+
+/**
+ * @brief Initializes an SMP lock.
+ *
+ * Concurrent initialization leads to unpredictable results.
+ *
+ * @param[in] lock The SMP lock control.
+ * @param[in] name The name for the SMP lock statistics. This name must be
+ * persistent throughout the life time of this statistics block.
+ */
+#if defined(RTEMS_SMP_LOCK_DO_NOT_INLINE)
+void _SMP_lock_Initialize(
+ SMP_lock_Control *lock,
+ const char * name
+);
+#else
+#define _SMP_lock_Initialize( lock, name ) \
+ _SMP_lock_Initialize_inline( lock, name )
+#endif
+
+static inline void _SMP_lock_Destroy_inline( SMP_lock_Control *lock )
+{
+ _SMP_ticket_lock_Destroy( &lock->Ticket_lock );
+ _SMP_lock_Stats_destroy( &lock->Stats );
+}
+
+/**
+ * @brief Destroys an SMP lock.
+ *
+ * Concurrent destruction leads to unpredictable results.
+ *
+ * @param[in] lock The SMP lock control.
+ */
+#if defined(RTEMS_SMP_LOCK_DO_NOT_INLINE)
+void _SMP_lock_Destroy( SMP_lock_Control *lock );
+#else
+#define _SMP_lock_Destroy( lock ) \
+ _SMP_lock_Destroy_inline( lock )
+#endif
+
+#if defined(RTEMS_DEBUG)
+static inline uint32_t _SMP_lock_Who_am_I( void )
+{
+ /*
+ * The CPU index starts with zero. Increment it by one, to allow global SMP
+ * locks to reside in the BSS section.
+ */
+ return _SMP_Get_current_processor() + 1;
+}
+#endif
+
+static inline void _SMP_lock_Acquire_inline(
+ SMP_lock_Control *lock,
+ SMP_lock_Context *context
+)
+{
+#if defined(RTEMS_DEBUG)
+ context->lock_used_for_acquire = lock;
+#else
+ (void) context;
+#endif
+ _SMP_ticket_lock_Acquire(
+ &lock->Ticket_lock,
+ &lock->Stats,
+ &context->Stats_context
+ );
+#if defined(RTEMS_DEBUG)
+ lock->owner = _SMP_lock_Who_am_I();
+#endif
+}
+
+/**
+ * @brief Acquires an SMP lock.
+ *
+ * This function will not disable interrupts. The caller must ensure that the
+ * current thread of execution is not interrupted indefinite once it obtained
+ * the SMP lock.
+ *
+ * @param[in] lock The SMP lock control.
+ * @param[in] context The local SMP lock context for an acquire and release
+ * pair.
+ */
+void _SMP_lock_Acquire(
+ SMP_lock_Control *lock,
+ SMP_lock_Context *context
+);
+
+static inline void _SMP_lock_Release_inline(
+ SMP_lock_Control *lock,
+ SMP_lock_Context *context
+)
+{
+#if defined(RTEMS_DEBUG)
+ _Assert( context->lock_used_for_acquire == lock );
+ context->lock_used_for_acquire = NULL;
+ _Assert( lock->owner == _SMP_lock_Who_am_I() );
+ lock->owner = SMP_LOCK_NO_OWNER;
+#else
+ (void) context;
+#endif
+ _SMP_ticket_lock_Release(
+ &lock->Ticket_lock,
+ &context->Stats_context
+ );
+}
+
+/**
+ * @brief Releases an SMP lock.
+ *
+ * @param[in] lock The SMP lock control.
+ * @param[in] context The local SMP lock context for an acquire and release
+ * pair.
+ */
+#if defined(RTEMS_SMP_LOCK_DO_NOT_INLINE)
+void _SMP_lock_Release(
+ SMP_lock_Control *lock,
+ SMP_lock_Context *context
+);
+#else
+#define _SMP_lock_Release( lock, context ) \
+ _SMP_lock_Release_inline( lock, context )
+#endif
+
+static inline void _SMP_lock_ISR_disable_and_acquire_inline(
+ SMP_lock_Control *lock,
+ SMP_lock_Context *context
+)
+{
+ _ISR_Local_disable( context->isr_level );
+ _SMP_lock_Acquire_inline( lock, context );
+}
+
+/**
+ * @brief Disables interrupts and acquires the SMP lock.
+ *
+ * @param[in] lock The SMP lock control.
+ * @param[in] context The local SMP lock context for an acquire and release
+ * pair.
+ */
+void _SMP_lock_ISR_disable_and_acquire(
+ SMP_lock_Control *lock,
+ SMP_lock_Context *context
+);
+
+static inline void _SMP_lock_Release_and_ISR_enable_inline(
+ SMP_lock_Control *lock,
+ SMP_lock_Context *context
+)
+{
+ _SMP_lock_Release_inline( lock, context );
+ _ISR_Local_enable( context->isr_level );
+}
+
+/**
+ * @brief Releases the SMP lock and enables interrupts.
+ *
+ * @param[in] lock The SMP lock control.
+ * @param[in] context The local SMP lock context for an acquire and release
+ * pair.
+ */
+#if defined(RTEMS_SMP_LOCK_DO_NOT_INLINE)
+void _SMP_lock_Release_and_ISR_enable(
+ SMP_lock_Control *lock,
+ SMP_lock_Context *context
+);
+#else
+#define _SMP_lock_Release_and_ISR_enable( lock, context ) \
+ _SMP_lock_Release_and_ISR_enable_inline( lock, context )
+#endif
+
+#if defined(RTEMS_DEBUG)
+/**
+ * @brief Returns true, if the SMP lock is owned by the current processor,
+ * otherwise false.
+ *
+ * @param[in] lock The SMP lock control.
+ */
+bool _SMP_lock_Is_owner( const SMP_lock_Control *lock );
+#endif
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* RTEMS_SMP */
+
+#endif /* _RTEMS_SCORE_SMPLOCK_H */
diff --git a/cpukit/include/rtems/score/smplockmcs.h b/cpukit/include/rtems/score/smplockmcs.h
new file mode 100644
index 0000000000..5a1ad23dc9
--- /dev/null
+++ b/cpukit/include/rtems/score/smplockmcs.h
@@ -0,0 +1,262 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSMPLock
+ *
+ * @brief SMP Lock API
+ */
+
+/*
+ * Copyright (c) 2016 embedded brains GmbH
+ *
+ * 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_SMPLOCKMCS_H
+#define _RTEMS_SCORE_SMPLOCKMCS_H
+
+#include <rtems/score/cpuopts.h>
+
+#if defined(RTEMS_SMP)
+
+#include <rtems/score/atomic.h>
+#include <rtems/score/smplockstats.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @addtogroup ScoreSMPLock
+ *
+ * @{
+ */
+
+/**
+ * @brief SMP Mellor-Crummey and Scott (MCS) lock context.
+ */
+typedef struct SMP_MCS_lock_Context {
+ /**
+ * @brief The next context on the queue if it exists.
+ */
+ union {
+ /**
+ * @brief The next context as an atomic unsigned integer pointer value.
+ */
+ Atomic_Uintptr atomic;
+
+ /**
+ * @brief The next context as a normal pointer.
+ *
+ * Only provided for debugging purposes.
+ */
+ struct SMP_MCS_lock_Context *normal;
+ } next;
+
+ /**
+ * @brief Indicates if the lock is owned or free in case a previous context
+ * exits on the queue.
+ *
+ * This field is initialized to a non-zero value. The previous lock owner
+ * (which is the owner of the previous context) will set it to zero during
+ * its lock release.
+ */
+ Atomic_Uint locked;
+
+#if defined(RTEMS_PROFILING)
+ SMP_lock_Stats_context Stats_context;
+
+ unsigned int queue_length;
+#endif
+} SMP_MCS_lock_Context;
+
+/**
+ * @brief SMP Mellor-Crummey and Scott (MCS) lock control.
+ */
+typedef struct {
+ /**
+ * @brief The queue tail context.
+ *
+ * The lock is free, in case this field is zero, otherwise it is locked by
+ * the owner of the queue head.
+ */
+ union {
+ /**
+ * @brief The queue tail context as an atomic unsigned integer pointer
+ * value.
+ */
+ Atomic_Uintptr atomic;
+
+ /**
+ * @brief The queue tail context as a normal pointer.
+ *
+ * Only provided for debugging purposes.
+ */
+ struct SMP_MCS_lock_Context *normal;
+ } queue;
+} SMP_MCS_lock_Control;
+
+/**
+ * @brief SMP MCS lock control initializer for static initialization.
+ */
+#define SMP_MCS_LOCK_INITIALIZER { { ATOMIC_INITIALIZER_UINTPTR( 0 ) } }
+
+/**
+ * @brief Initializes an SMP MCS lock.
+ *
+ * Concurrent initialization leads to unpredictable results.
+ *
+ * @param lock The SMP MCS lock control.
+ */
+static inline void _SMP_MCS_lock_Initialize( SMP_MCS_lock_Control *lock )
+{
+ _Atomic_Init_uintptr( &lock->queue.atomic, 0 );
+}
+
+/**
+ * @brief Destroys an SMP MCS lock.
+ *
+ * Concurrent destruction leads to unpredictable results.
+ *
+ * @param lock The SMP MCS lock control.
+ */
+static inline void _SMP_MCS_lock_Destroy( SMP_MCS_lock_Control *lock )
+{
+ (void) lock;
+}
+
+static inline void _SMP_MCS_lock_Do_acquire(
+ SMP_MCS_lock_Control *lock,
+ SMP_MCS_lock_Context *context
+#if defined(RTEMS_PROFILING)
+ ,
+ SMP_lock_Stats *stats
+#endif
+)
+{
+ SMP_MCS_lock_Context *previous;
+#if defined(RTEMS_PROFILING)
+ SMP_lock_Stats_acquire_context acquire_context;
+
+ _SMP_lock_Stats_acquire_begin( &acquire_context );
+ context->queue_length = 0;
+#endif
+
+ _Atomic_Store_uintptr( &context->next.atomic, 0, ATOMIC_ORDER_RELAXED );
+ _Atomic_Store_uint( &context->locked, 1, ATOMIC_ORDER_RELAXED );
+
+ previous = (SMP_MCS_lock_Context *) _Atomic_Exchange_uintptr(
+ &lock->queue.atomic,
+ (uintptr_t) context,
+ ATOMIC_ORDER_ACQ_REL
+ );
+
+ if ( previous != NULL ) {
+ unsigned int locked;
+
+ _Atomic_Store_uintptr(
+ &previous->next.atomic,
+ (uintptr_t) context,
+ ATOMIC_ORDER_RELAXED
+ );
+
+ do {
+ locked = _Atomic_Load_uint( &context->locked, ATOMIC_ORDER_ACQUIRE );
+ } while ( locked != 0 );
+ }
+
+#if defined(RTEMS_PROFILING)
+ _SMP_lock_Stats_acquire_end(
+ &acquire_context,
+ stats,
+ &context->Stats_context,
+ context->queue_length
+ );
+#endif
+}
+
+/**
+ * @brief Acquires an SMP MCS lock.
+ *
+ * This function will not disable interrupts. The caller must ensure that the
+ * current thread of execution is not interrupted indefinite once it obtained
+ * the SMP MCS lock.
+ *
+ * @param lock The SMP MCS lock control.
+ * @param context The SMP MCS lock context.
+ * @param stats The SMP lock statistics.
+ */
+#if defined(RTEMS_PROFILING)
+ #define _SMP_MCS_lock_Acquire( lock, context, stats ) \
+ _SMP_MCS_lock_Do_acquire( lock, context, stats )
+#else
+ #define _SMP_MCS_lock_Acquire( lock, context, stats ) \
+ _SMP_MCS_lock_Do_acquire( lock, context )
+#endif
+
+/**
+ * @brief Releases an SMP MCS lock.
+ *
+ * @param lock The SMP MCS lock control.
+ * @param context The SMP MCS lock context.
+ */
+static inline void _SMP_MCS_lock_Release(
+ SMP_MCS_lock_Control *lock,
+ SMP_MCS_lock_Context *context
+)
+{
+ SMP_MCS_lock_Context *next;
+
+ next = (SMP_MCS_lock_Context *) _Atomic_Load_uintptr(
+ &context->next.atomic,
+ ATOMIC_ORDER_RELAXED
+ );
+
+ if ( next == NULL ) {
+ uintptr_t expected;
+ bool success;
+
+ expected = (uintptr_t) context;
+ success = _Atomic_Compare_exchange_uintptr(
+ &lock->queue.atomic,
+ &expected,
+ 0,
+ ATOMIC_ORDER_RELEASE,
+ ATOMIC_ORDER_RELAXED
+ );
+
+ if ( success ) {
+#if defined(RTEMS_PROFILING)
+ _SMP_lock_Stats_release_update( &context->Stats_context );
+#endif
+ /* Nobody waits. So, we are done */
+ return;
+ }
+
+ do {
+ next = (SMP_MCS_lock_Context *) _Atomic_Load_uintptr(
+ &context->next.atomic,
+ ATOMIC_ORDER_RELAXED
+ );
+ } while ( next == NULL );
+ }
+
+#if defined(RTEMS_PROFILING)
+ next->queue_length = context->queue_length + 1;
+ _SMP_lock_Stats_release_update( &context->Stats_context );
+#endif
+
+ _Atomic_Store_uint( &next->locked, 0, ATOMIC_ORDER_RELEASE );
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* RTEMS_SMP */
+
+#endif /* _RTEMS_SCORE_SMPLOCKMCS_H */
diff --git a/cpukit/include/rtems/score/smplockseq.h b/cpukit/include/rtems/score/smplockseq.h
new file mode 100644
index 0000000000..5daaee9c6e
--- /dev/null
+++ b/cpukit/include/rtems/score/smplockseq.h
@@ -0,0 +1,176 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSMPLock
+ *
+ * @brief SMP Lock API
+ */
+
+/*
+ * Copyright (c) 2016 embedded brains GmbH
+ *
+ * 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_SMPLOCKSEQ_H
+#define _RTEMS_SCORE_SMPLOCKSEQ_H
+
+#include <rtems/score/cpuopts.h>
+
+#if defined(RTEMS_SMP)
+
+#include <rtems/score/assert.h>
+#include <rtems/score/atomic.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @addtogroup ScoreSMPLock
+ *
+ * @{
+ */
+
+/**
+ * @brief SMP sequence lock control.
+ *
+ * The sequence lock offers a consistent data set for readers in the presence
+ * of at most one concurrent writer. Due to the read-modify-write operation in
+ * _SMP_sequence_lock_Read_retry() the data corresponding to the last written
+ * sequence number is observed. To allow multiple writers an additional SMP
+ * lock is necessary to serialize writes.
+ *
+ * See also Hans-J. Boehm, HP Laboratories,
+ * "Can Seqlocks Get Along With Programming Language Memory Models?",
+ * http://www.hpl.hp.com/techreports/2012/HPL-2012-68.pdf
+ */
+typedef struct {
+ /**
+ * @brief The sequence number.
+ *
+ * An odd value indicates that a write is in progress.
+ */
+ Atomic_Uint sequence;
+} SMP_sequence_lock_Control;
+
+/**
+ * @brief SMP sequence lock control initializer for static initialization.
+ */
+#define SMP_SEQUENCE_LOCK_INITIALIZER { ATOMIC_INITIALIZER_UINT( 0 ) }
+
+/**
+ * @brief Initializes an SMP sequence lock.
+ *
+ * Concurrent initialization leads to unpredictable results.
+ *
+ * @param lock The SMP sequence lock control.
+ */
+static inline void _SMP_sequence_lock_Initialize( SMP_sequence_lock_Control *lock )
+{
+ _Atomic_Init_uint( &lock->sequence, 0 );
+}
+
+/**
+ * @brief Destroys an SMP sequence lock.
+ *
+ * Concurrent destruction leads to unpredictable results.
+ *
+ * @param lock The SMP sequence lock control.
+ */
+static inline void _SMP_sequence_lock_Destroy( SMP_sequence_lock_Control *lock )
+{
+ (void) lock;
+}
+
+/**
+ * @brief Begins an SMP sequence lock write operation.
+ *
+ * This function will not disable interrupts. The caller must ensure that the
+ * current thread of execution is not interrupted indefinite since this would
+ * starve readers.
+ *
+ * @param lock The SMP sequence lock control.
+ *
+ * @return The current sequence number.
+ */
+static inline unsigned int _SMP_sequence_lock_Write_begin(
+ SMP_sequence_lock_Control *lock
+)
+{
+ unsigned int seq;
+
+ seq = _Atomic_Load_uint( &lock->sequence, ATOMIC_ORDER_RELAXED );
+ _Assert( seq % 2 == 0 );
+
+ _Atomic_Store_uint( &lock->sequence, seq + 1, ATOMIC_ORDER_RELAXED );
+
+ /* There is no atomic store with acquire/release semantics */
+ _Atomic_Fence( ATOMIC_ORDER_ACQ_REL );
+
+ return seq;
+}
+
+/**
+ * @brief Ends an SMP sequence lock write operation.
+ *
+ * @param lock The SMP sequence lock control.
+ * @param seq The sequence number returned by _SMP_sequence_lock_Write_begin().
+ */
+static inline void _SMP_sequence_lock_Write_end(
+ SMP_sequence_lock_Control *lock,
+ unsigned int seq
+)
+{
+ _Atomic_Store_uint( &lock->sequence, seq + 2, ATOMIC_ORDER_RELEASE );
+}
+
+/**
+ * @brief Begins an SMP sequence lock read operation.
+ *
+ * This function will not disable interrupts.
+ *
+ * @param lock The SMP sequence lock control.
+ *
+ * @return The current sequence number.
+ */
+static inline unsigned int _SMP_sequence_lock_Read_begin(
+ const SMP_sequence_lock_Control *lock
+)
+{
+ return _Atomic_Load_uint( &lock->sequence, ATOMIC_ORDER_ACQUIRE );
+}
+
+/**
+ * @brief Ends an SMP sequence lock read operation and indicates if a retry is
+ * necessary.
+ *
+ * @param lock The SMP sequence lock control.
+ * @param seq The sequence number returned by _SMP_sequence_lock_Read_begin().
+ *
+ * @retval true The read operation must be retried with a call to
+ * _SMP_sequence_lock_Read_begin().
+ * @retval false Otherwise.
+ */
+static inline bool _SMP_sequence_lock_Read_retry(
+ SMP_sequence_lock_Control *lock,
+ unsigned int seq
+)
+{
+ unsigned int seq2;
+
+ seq2 = _Atomic_Fetch_add_uint( &lock->sequence, 0, ATOMIC_ORDER_RELEASE );
+ return seq != seq2 || seq % 2 != 0;
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* RTEMS_SMP */
+
+#endif /* _RTEMS_SCORE_SMPLOCKSEQ_H */
diff --git a/cpukit/include/rtems/score/smplockstats.h b/cpukit/include/rtems/score/smplockstats.h
new file mode 100644
index 0000000000..dd8e06c81d
--- /dev/null
+++ b/cpukit/include/rtems/score/smplockstats.h
@@ -0,0 +1,277 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSMPLock
+ *
+ * @brief SMP Lock API
+ */
+
+/*
+ * Copyright (c) 2013, 2016 embedded brains GmbH
+ *
+ * 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_SMPLOCKSTATS_H
+#define _RTEMS_SCORE_SMPLOCKSTATS_H
+
+#include <rtems/score/cpuopts.h>
+
+#if defined(RTEMS_SMP)
+
+#include <rtems/score/chainimpl.h>
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @addtogroup ScoreSMPLock
+ *
+ * @{
+ */
+
+#if defined(RTEMS_PROFILING)
+
+/**
+ * @brief Count of lock contention counters for lock statistics.
+ */
+#define SMP_LOCK_STATS_CONTENTION_COUNTS 4
+
+/**
+ * @brief SMP lock statistics.
+ *
+ * The lock acquire attempt instant is the point in time right after the
+ * interrupt disable action in the lock acquire sequence.
+ *
+ * The lock acquire instant is the point in time right after the lock
+ * acquisition. This is the begin of the critical section code execution.
+ *
+ * The lock release instant is the point in time right before the interrupt
+ * enable action in the lock release sequence.
+ *
+ * The lock section time is the time elapsed between the lock acquire instant
+ * and the lock release instant.
+ *
+ * The lock acquire time is the time elapsed between the lock acquire attempt
+ * instant and the lock acquire instant.
+ */
+typedef struct {
+ /**
+ * @brief Node for SMP lock statistics chain.
+ */
+ Chain_Node Node;
+
+ /**
+ * @brief The maximum lock acquire time in CPU counter ticks.
+ */
+ CPU_Counter_ticks max_acquire_time;
+
+ /**
+ * @brief The maximum lock section time in CPU counter ticks.
+ */
+ CPU_Counter_ticks max_section_time;
+
+ /**
+ * @brief The count of lock uses.
+ *
+ * This value may overflow.
+ */
+ uint64_t usage_count;
+
+ /**
+ * @brief Total lock acquire time in nanoseconds.
+ *
+ * The average lock acquire time is the total acquire time divided by the
+ * lock usage count. The ration of the total section and total acquire times
+ * gives a measure for the lock contention.
+ *
+ * This value may overflow.
+ */
+ uint64_t total_acquire_time;
+
+ /**
+ * @brief The counts of lock acquire operations by contention.
+ *
+ * The contention count for index N corresponds to a lock acquire attempt
+ * with an initial queue length of N. The last index corresponds to all
+ * lock acquire attempts with an initial queue length greater than or equal
+ * to SMP_LOCK_STATS_CONTENTION_COUNTS minus one.
+ *
+ * The values may overflow.
+ */
+ uint64_t contention_counts[SMP_LOCK_STATS_CONTENTION_COUNTS];
+
+ /**
+ * @brief Total lock section time in CPU counter ticks.
+ *
+ * The average lock section time is the total section time divided by the
+ * lock usage count.
+ *
+ * This value may overflow.
+ */
+ uint64_t total_section_time;
+
+ /**
+ * @brief The lock name.
+ */
+ const char *name;
+} SMP_lock_Stats;
+
+/**
+ * @brief Local context for SMP lock statistics.
+ */
+typedef struct {
+ /**
+ * @brief The last lock acquire instant in CPU counter ticks.
+ *
+ * This value is used to measure the lock section time.
+ */
+ CPU_Counter_ticks acquire_instant;
+
+ /**
+ * @brief The lock stats used for the last lock acquire.
+ */
+ SMP_lock_Stats *stats;
+} SMP_lock_Stats_context;
+
+/**
+ * @brief SMP lock statistics initializer for static initialization.
+ */
+#define SMP_LOCK_STATS_INITIALIZER( name ) \
+ { { NULL, NULL }, 0, 0, 0, 0, { 0, 0, 0, 0 }, 0, name }
+
+/**
+ * @brief Initializes an SMP lock statistics block.
+ *
+ * @param[in, out] stats The SMP lock statistics block.
+ * @param[in] name The name for the SMP lock statistics. This name must be
+ * persistent throughout the life time of this statistics block.
+ */
+static inline void _SMP_lock_Stats_initialize(
+ SMP_lock_Stats *stats,
+ const char *name
+)
+{
+ SMP_lock_Stats init = SMP_LOCK_STATS_INITIALIZER( name );
+
+ *stats = init;
+}
+
+/**
+ * @brief Destroys an SMP lock statistics block.
+ *
+ * @param[in] stats The SMP lock statistics block.
+ */
+void _SMP_lock_Stats_destroy( SMP_lock_Stats *stats );
+
+void _SMP_lock_Stats_register( SMP_lock_Stats *stats );
+
+typedef struct {
+ CPU_Counter_ticks first;
+} SMP_lock_Stats_acquire_context;
+
+static inline void _SMP_lock_Stats_acquire_begin(
+ SMP_lock_Stats_acquire_context *acquire_context
+)
+{
+ acquire_context->first = _CPU_Counter_read();
+}
+
+static inline void _SMP_lock_Stats_acquire_end(
+ const SMP_lock_Stats_acquire_context *acquire_context,
+ SMP_lock_Stats *stats,
+ SMP_lock_Stats_context *stats_context,
+ unsigned int queue_length
+)
+{
+ CPU_Counter_ticks second;
+ CPU_Counter_ticks delta;
+
+ second = _CPU_Counter_read();
+ stats_context->acquire_instant = second;
+ delta = _CPU_Counter_difference( second, acquire_context->first );
+
+ ++stats->usage_count;
+
+ stats->total_acquire_time += delta;
+
+ if ( stats->max_acquire_time < delta ) {
+ stats->max_acquire_time = delta;
+ }
+
+ if ( queue_length >= SMP_LOCK_STATS_CONTENTION_COUNTS ) {
+ queue_length = SMP_LOCK_STATS_CONTENTION_COUNTS - 1;
+ }
+ ++stats->contention_counts[ queue_length ];
+
+ stats_context->stats = stats;
+}
+
+/**
+ * @brief Updates an SMP lock statistics block during a lock release.
+ *
+ * @param[in] stats_context The SMP lock statistics context.
+ */
+static inline void _SMP_lock_Stats_release_update(
+ const SMP_lock_Stats_context *stats_context
+)
+{
+ SMP_lock_Stats *stats = stats_context->stats;
+ CPU_Counter_ticks first = stats_context->acquire_instant;
+ CPU_Counter_ticks second = _CPU_Counter_read();
+ CPU_Counter_ticks delta = _CPU_Counter_difference( second, first );
+
+ stats->total_section_time += delta;
+
+ if ( stats->max_section_time < delta ) {
+ stats->max_section_time = delta;
+
+ if ( _Chain_Is_node_off_chain( &stats->Node ) ) {
+ _SMP_lock_Stats_register( stats );
+ }
+ }
+}
+
+typedef struct {
+ Chain_Node Node;
+ SMP_lock_Stats *current;
+} SMP_lock_Stats_iteration_context;
+
+void _SMP_lock_Stats_iteration_start(
+ SMP_lock_Stats_iteration_context *iteration_context
+);
+
+
+bool _SMP_lock_Stats_iteration_next(
+ SMP_lock_Stats_iteration_context *iteration_context,
+ SMP_lock_Stats *snapshot,
+ char *name,
+ size_t name_size
+);
+
+void _SMP_lock_Stats_iteration_stop(
+ SMP_lock_Stats_iteration_context *iteration_context
+);
+
+#else /* RTEMS_PROFILING */
+
+#define _SMP_lock_Stats_initialize( stats, name ) do { } while ( 0 )
+
+#define _SMP_lock_Stats_destroy( stats ) do { } while ( 0 )
+
+#endif /* !RTEMS_PROFILING */
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* RTEMS_SMP */
+
+#endif /* _RTEMS_SCORE_SMPLOCKSTATS_H */
diff --git a/cpukit/include/rtems/score/smplockticket.h b/cpukit/include/rtems/score/smplockticket.h
new file mode 100644
index 0000000000..e04c4056a5
--- /dev/null
+++ b/cpukit/include/rtems/score/smplockticket.h
@@ -0,0 +1,187 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSMPLock
+ *
+ * @brief SMP Lock API
+ */
+
+/*
+ * Copyright (c) 2013, 2016 embedded brains GmbH
+ *
+ * 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_SMPLOCKTICKET_H
+#define _RTEMS_SCORE_SMPLOCKTICKET_H
+
+#include <rtems/score/cpuopts.h>
+
+#if defined(RTEMS_SMP)
+
+#include <rtems/score/atomic.h>
+#include <rtems/score/smplockstats.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @addtogroup ScoreSMPLock
+ *
+ * @{
+ */
+
+/**
+ * @brief SMP ticket lock control.
+ */
+typedef struct {
+ Atomic_Uint next_ticket;
+ Atomic_Uint now_serving;
+} SMP_ticket_lock_Control;
+
+/**
+ * @brief SMP ticket lock control initializer for static initialization.
+ */
+#define SMP_TICKET_LOCK_INITIALIZER \
+ { \
+ ATOMIC_INITIALIZER_UINT( 0U ), \
+ ATOMIC_INITIALIZER_UINT( 0U ) \
+ }
+
+/**
+ * @brief Initializes an SMP ticket lock.
+ *
+ * Concurrent initialization leads to unpredictable results.
+ *
+ * @param[in] lock The SMP ticket lock control.
+ */
+static inline void _SMP_ticket_lock_Initialize(
+ SMP_ticket_lock_Control *lock
+)
+{
+ _Atomic_Init_uint( &lock->next_ticket, 0U );
+ _Atomic_Init_uint( &lock->now_serving, 0U );
+}
+
+/**
+ * @brief Destroys an SMP ticket lock.
+ *
+ * Concurrent destruction leads to unpredictable results.
+ *
+ * @param[in] lock The SMP ticket lock control.
+ */
+static inline void _SMP_ticket_lock_Destroy( SMP_ticket_lock_Control *lock )
+{
+ (void) lock;
+}
+
+static inline void _SMP_ticket_lock_Do_acquire(
+ SMP_ticket_lock_Control *lock
+#if defined(RTEMS_PROFILING)
+ ,
+ SMP_lock_Stats *stats,
+ SMP_lock_Stats_context *stats_context
+#endif
+)
+{
+ unsigned int my_ticket;
+ unsigned int now_serving;
+#if defined(RTEMS_PROFILING)
+ unsigned int initial_queue_length;
+ SMP_lock_Stats_acquire_context acquire_context;
+
+ _SMP_lock_Stats_acquire_begin( &acquire_context );
+#endif
+
+ my_ticket =
+ _Atomic_Fetch_add_uint( &lock->next_ticket, 1U, ATOMIC_ORDER_RELAXED );
+
+#if defined(RTEMS_PROFILING)
+ now_serving =
+ _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_ACQUIRE );
+ initial_queue_length = my_ticket - now_serving;
+
+ if ( initial_queue_length > 0 ) {
+#endif
+
+ do {
+ now_serving =
+ _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_ACQUIRE );
+ } while ( now_serving != my_ticket );
+
+#if defined(RTEMS_PROFILING)
+ }
+
+ _SMP_lock_Stats_acquire_end(
+ &acquire_context,
+ stats,
+ stats_context,
+ initial_queue_length
+ );
+#endif
+}
+
+/**
+ * @brief Acquires an SMP ticket lock.
+ *
+ * This function will not disable interrupts. The caller must ensure that the
+ * current thread of execution is not interrupted indefinite once it obtained
+ * the SMP ticket lock.
+ *
+ * @param[in] lock The SMP ticket lock control.
+ * @param[in] stats The SMP lock statistics.
+ * @param[out] stats_context The SMP lock statistics context.
+ */
+#if defined(RTEMS_PROFILING)
+ #define _SMP_ticket_lock_Acquire( lock, stats, stats_context ) \
+ _SMP_ticket_lock_Do_acquire( lock, stats, stats_context )
+#else
+ #define _SMP_ticket_lock_Acquire( lock, stats, stats_context ) \
+ _SMP_ticket_lock_Do_acquire( lock )
+#endif
+
+static inline void _SMP_ticket_lock_Do_release(
+ SMP_ticket_lock_Control *lock
+#if defined(RTEMS_PROFILING)
+ ,
+ const SMP_lock_Stats_context *stats_context
+#endif
+)
+{
+ unsigned int current_ticket =
+ _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_RELAXED );
+ unsigned int next_ticket = current_ticket + 1U;
+
+#if defined(RTEMS_PROFILING)
+ _SMP_lock_Stats_release_update( stats_context );
+#endif
+
+ _Atomic_Store_uint( &lock->now_serving, next_ticket, ATOMIC_ORDER_RELEASE );
+}
+
+/**
+ * @brief Releases an SMP ticket lock.
+ *
+ * @param[in] lock The SMP ticket lock control.
+ * @param[in] stats_context The SMP lock statistics context.
+ */
+#if defined(RTEMS_PROFILING)
+ #define _SMP_ticket_lock_Release( lock, stats_context ) \
+ _SMP_ticket_lock_Do_release( lock, stats_context )
+#else
+ #define _SMP_ticket_lock_Release( lock, stats_context ) \
+ _SMP_ticket_lock_Do_release( lock )
+#endif
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* RTEMS_SMP */
+
+#endif /* _RTEMS_SCORE_SMPLOCKTICKET_H */
diff --git a/cpukit/include/rtems/score/stack.h b/cpukit/include/rtems/score/stack.h
new file mode 100644
index 0000000000..9622495092
--- /dev/null
+++ b/cpukit/include/rtems/score/stack.h
@@ -0,0 +1,69 @@
+/**
+ * @file rtems/score/stack.h
+ *
+ * @brief Information About the Thread Stack Handler
+ *
+ * This include file contains all information about the thread
+ * Stack Handler. This Handler provides mechanisms which can be used to
+ * initialize and utilize stacks.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_STACK_H
+#define _RTEMS_SCORE_STACK_H
+
+#include <rtems/score/basedefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreStack Stack Handler
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality which is used in the management
+ * of thread stacks.
+ */
+/**@{*/
+
+/**
+ * The following constant defines the minimum stack size which every
+ * thread must exceed.
+ */
+#define STACK_MINIMUM_SIZE CPU_STACK_MINIMUM_SIZE
+
+/**
+ * The following defines the control block used to manage each stack.
+ */
+typedef struct {
+ /** This is the stack size. */
+ size_t size;
+ /** This is the low memory address of stack. */
+ void *area;
+} Stack_Control;
+
+/**
+ * This variable contains the the minimum stack size;
+ *
+ * @note It is instantiated and set by User Configuration via confdefs.h.
+ */
+extern uint32_t rtems_minimum_stack_size;
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/stackimpl.h b/cpukit/include/rtems/score/stackimpl.h
new file mode 100644
index 0000000000..4c622345ff
--- /dev/null
+++ b/cpukit/include/rtems/score/stackimpl.h
@@ -0,0 +1,99 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines from the Stack Handler
+ *
+ * This file contains the static inline implementation of the inlined
+ * routines from the Stack Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_STACKIMPL_H
+#define _RTEMS_SCORE_STACKIMPL_H
+
+#include <rtems/score/stack.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreStack
+ */
+/**@{**/
+
+/**
+ * This routine initializes the_stack record to indicate that
+ * size bytes of memory starting at starting_address have been
+ * reserved for a stack.
+ */
+RTEMS_INLINE_ROUTINE void _Stack_Initialize (
+ Stack_Control *the_stack,
+ void *starting_address,
+ size_t size
+)
+{
+ the_stack->area = starting_address;
+ the_stack->size = size;
+}
+
+/**
+ * This function returns the minimum stack size configured
+ * for this application.
+ *
+ * @return This method returns the minimum stack size;
+ */
+RTEMS_INLINE_ROUTINE uint32_t _Stack_Minimum (void)
+{
+ return rtems_minimum_stack_size;
+}
+
+/**
+ * This function returns true if size bytes is enough memory for
+ * a valid stack area on this processor, and false otherwise.
+ *
+ * @param[in] size is the stack size to check
+ *
+ * @return This method returns true if the stack is large enough.
+ */
+RTEMS_INLINE_ROUTINE bool _Stack_Is_enough (
+ size_t size
+)
+{
+ return ( size >= _Stack_Minimum() );
+}
+
+/**
+ * This function returns the appropriate stack size given the requested
+ * size. If the requested size is below the minimum, then the minimum
+ * configured stack size is returned.
+ *
+ * @param[in] size is the stack size to check
+ *
+ * @return This method returns the appropriate stack size.
+ */
+RTEMS_INLINE_ROUTINE size_t _Stack_Ensure_minimum (
+ size_t size
+)
+{
+ if ( size >= _Stack_Minimum() )
+ return size;
+ return _Stack_Minimum();
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/states.h b/cpukit/include/rtems/score/states.h
new file mode 100644
index 0000000000..ba59af6907
--- /dev/null
+++ b/cpukit/include/rtems/score/states.h
@@ -0,0 +1,50 @@
+/**
+ * @file rtems/score/states.h
+ *
+ * @brief Thread Execution State Information
+ *
+ * This include file defines thread execution state information.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_STATES_H
+#define _RTEMS_SCORE_STATES_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreStates SuperCore Thread States
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality which relates to the management of
+ * the state bitmap associated with each thread.
+ */
+/**@{*/
+
+/**
+ * The following type defines the control block used to manage a
+ * thread's state.
+ */
+typedef uint32_t States_Control;
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/statesimpl.h b/cpukit/include/rtems/score/statesimpl.h
new file mode 100644
index 0000000000..db462fbb9a
--- /dev/null
+++ b/cpukit/include/rtems/score/statesimpl.h
@@ -0,0 +1,283 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines Associated with Thread State Information
+ *
+ * This file contains the static inline implementation of the inlined
+ * routines associated with thread state information.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2012.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_STATESIMPL_H
+#define _RTEMS_SCORE_STATESIMPL_H
+
+#include <rtems/score/states.h>
+#include <rtems/score/basedefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreStates
+ */
+/**@{**/
+
+/*
+ * The following constants define the individual states which may be
+ * be used to compose and manipulate a thread's state. More frequently used
+ * states should use lower value bits to ease the use of immediate values on
+ * RISC architectures.
+ */
+
+/** This macro corresponds to a task being ready. */
+#define STATES_READY 0x00000000
+
+/** This macro corresponds to a task waiting for a mutex. */
+#define STATES_WAITING_FOR_MUTEX 0x00000001
+
+/** This macro corresponds to a task waiting for a semaphore. */
+#define STATES_WAITING_FOR_SEMAPHORE 0x00000002
+
+/** This macro corresponds to a task waiting for an event. */
+#define STATES_WAITING_FOR_EVENT 0x00000004
+
+/** This macro corresponds to a task waiting for a system event. */
+#define STATES_WAITING_FOR_SYSTEM_EVENT 0x00000008
+
+/** This macro corresponds to a task waiting for a message. */
+#define STATES_WAITING_FOR_MESSAGE 0x00000010
+
+/** This macro corresponds to a task waiting for a condition variable. */
+#define STATES_WAITING_FOR_CONDITION_VARIABLE 0x00000020
+
+/** This macro corresponds to a task waiting for a futex. */
+#define STATES_WAITING_FOR_FUTEX 0x00000040
+
+/** This macro corresponds to a task waiting for BSD wakeup. */
+#define STATES_WAITING_FOR_BSD_WAKEUP 0x00000080
+
+/**
+ * @brief This macro corresponds to a task which is waiting for a relative or
+ * absolute timeout.
+ */
+#define STATES_WAITING_FOR_TIME 0x00000100
+
+/** This macro corresponds to a task waiting for a period. */
+#define STATES_WAITING_FOR_PERIOD 0x00000200
+
+/** This macro corresponds to a task waiting for a signal. */
+#define STATES_WAITING_FOR_SIGNAL 0x00000400
+
+/** This macro corresponds to a task waiting for a barrier. */
+#define STATES_WAITING_FOR_BARRIER 0x00000800
+
+/** This macro corresponds to a task waiting for a RWLock. */
+#define STATES_WAITING_FOR_RWLOCK 0x00001000
+
+/** This macro corresponds to a task waiting for a join while exiting. */
+#define STATES_WAITING_FOR_JOIN_AT_EXIT 0x00002000
+
+/** This macro corresponds to a task waiting for a join. */
+#define STATES_WAITING_FOR_JOIN 0x00004000
+
+/** This macro corresponds to a task being suspended. */
+#define STATES_SUSPENDED 0x00008000
+
+/** This macro corresponds to a task waiting for a fixed size segment. */
+#define STATES_WAITING_FOR_SEGMENT 0x00010000
+
+/** This macro corresponds to a task those life is changing. */
+#define STATES_LIFE_IS_CHANGING 0x00020000
+
+/** This macro corresponds to a task being held by the debugger. */
+#define STATES_DEBUGGER 0x08000000
+
+/** This macro corresponds to a task which is in an interruptible
+ * blocking state.
+ */
+#define STATES_INTERRUPTIBLE_BY_SIGNAL 0x10000000
+
+/** This macro corresponds to a task waiting for a reply to an MPCI request. */
+#define STATES_WAITING_FOR_RPC_REPLY 0x20000000
+
+/** This macro corresponds to a task being a zombie. */
+#define STATES_ZOMBIE 0x40000000
+
+/** This macro corresponds to a task being created but not yet started. */
+#define STATES_DORMANT 0x80000000
+
+/** This macro corresponds to a task waiting for a local object operation. */
+#define STATES_LOCALLY_BLOCKED ( STATES_WAITING_FOR_SEGMENT | \
+ STATES_WAITING_FOR_MESSAGE | \
+ STATES_WAITING_FOR_SEMAPHORE | \
+ STATES_WAITING_FOR_MUTEX | \
+ STATES_WAITING_FOR_CONDITION_VARIABLE | \
+ STATES_WAITING_FOR_JOIN | \
+ STATES_WAITING_FOR_SIGNAL | \
+ STATES_WAITING_FOR_BARRIER | \
+ STATES_WAITING_FOR_BSD_WAKEUP | \
+ STATES_WAITING_FOR_FUTEX | \
+ STATES_WAITING_FOR_RWLOCK )
+
+/** This macro corresponds to a task waiting which is blocked. */
+#define STATES_BLOCKED ( STATES_LOCALLY_BLOCKED | \
+ STATES_WAITING_FOR_TIME | \
+ STATES_WAITING_FOR_PERIOD | \
+ STATES_WAITING_FOR_EVENT | \
+ STATES_WAITING_FOR_RPC_REPLY | \
+ STATES_WAITING_FOR_SYSTEM_EVENT | \
+ STATES_INTERRUPTIBLE_BY_SIGNAL )
+
+/** All state bits set to one (provided for _Thread_Start()) */
+#define STATES_ALL_SET 0xffffffff
+
+/**
+ * This function sets the given states_to_set into the current_state
+ * passed in. The result is returned to the user in current_state.
+ *
+ * @param[in] states_to_set is the state bits to set
+ * @param[in] current_state is the state set to add them to
+ *
+ * @return This method returns the updated states value.
+ */
+RTEMS_INLINE_ROUTINE States_Control _States_Set (
+ States_Control states_to_set,
+ States_Control current_state
+)
+{
+ return (current_state | states_to_set);
+}
+
+/**
+ * This function clears the given states_to_clear into the current_state
+ * passed in. The result is returned to the user in current_state.
+ *
+ * @param[in] states_to_clear is the state bits to clean
+ * @param[in] current_state is the state set to remove them from
+ *
+ * @return This method returns the updated states value.
+ */
+RTEMS_INLINE_ROUTINE States_Control _States_Clear (
+ States_Control states_to_clear,
+ States_Control current_state
+)
+{
+ return (current_state & ~states_to_clear);
+}
+
+/**
+ * This function returns true if the_states indicates that the
+ * state is READY, and false otherwise.
+ *
+ * @param[in] the_states is the task state set to test
+ *
+ * @return This method returns true if the desired state condition is set.
+ */
+RTEMS_INLINE_ROUTINE bool _States_Is_ready (
+ States_Control the_states
+)
+{
+ return (the_states == STATES_READY);
+}
+
+/**
+ * This function returns true if the DORMANT state is set in
+ * the_states, and false otherwise.
+ *
+ * @param[in] the_states is the task state set to test
+ *
+ * @return This method returns true if the desired state condition is set.
+ */
+RTEMS_INLINE_ROUTINE bool _States_Is_dormant (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_DORMANT);
+}
+
+/**
+ * This function returns true if the SUSPENDED state is set in
+ * the_states, and false otherwise.
+ *
+ * @param[in] the_states is the task state set to test
+ *
+ * @return This method returns true if the desired state condition is set.
+ */
+RTEMS_INLINE_ROUTINE bool _States_Is_suspended (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_SUSPENDED);
+}
+
+/**
+ * This function returns true if the WAITING_FOR_TIME state is set in
+ * the_states, and false otherwise.
+ *
+ * @param[in] the_states is the task state set to test
+ *
+ * @return This method returns true if the desired state condition is set.
+ */
+RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_rpc_reply (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_WAITING_FOR_RPC_REPLY);
+}
+
+RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_join_at_exit(
+ States_Control the_states
+)
+{
+ return ( the_states & STATES_WAITING_FOR_JOIN_AT_EXIT ) != 0;
+}
+
+/**
+ * This function returns true if the task's state is set in
+ * way that allows it to be interrupted by a signal.
+ *
+ * @param[in] the_states is the task state set to test
+ *
+ * @return This method returns true if the desired state condition is set.
+ */
+RTEMS_INLINE_ROUTINE bool _States_Is_interruptible_by_signal (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_INTERRUPTIBLE_BY_SIGNAL);
+
+}
+/**
+ * This function returns true if one of the states which indicates
+ * that a task is blocked waiting for a local resource is set in
+ * the_states, and false otherwise.
+ *
+ * @param[in] the_states is the task state set to test
+ *
+ * @return This method returns true if the desired state condition is set.
+ */
+
+RTEMS_INLINE_ROUTINE bool _States_Is_locally_blocked (
+ States_Control the_states
+)
+{
+ return (the_states & STATES_LOCALLY_BLOCKED);
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/status.h b/cpukit/include/rtems/score/status.h
new file mode 100644
index 0000000000..5b154bb207
--- /dev/null
+++ b/cpukit/include/rtems/score/status.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_STATUS_H
+#define _RTEMS_SCORE_STATUS_H
+
+#include <rtems/score/basedefs.h>
+
+#include <errno.h>
+#include <pthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @brief Status code parts for the Classic API.
+ *
+ * Must be in synchronization with rtems_status_code.
+ */
+typedef enum {
+ STATUS_CLASSIC_INCORRECT_STATE = 14,
+ STATUS_CLASSIC_INTERNAL_ERROR = 13,
+ STATUS_CLASSIC_INVALID_NUMBER = 10,
+ STATUS_CLASSIC_INVALID_PRIORITY = 19,
+ STATUS_CLASSIC_INVALID_SIZE = 8,
+ STATUS_CLASSIC_NO_MEMORY = 26,
+ STATUS_CLASSIC_NOT_DEFINED = 11,
+ STATUS_CLASSIC_NOT_OWNER_OF_RESOURCE = 23,
+ STATUS_CLASSIC_OBJECT_WAS_DELETED = 7,
+ STATUS_CLASSIC_RESOURCE_IN_USE = 12,
+ STATUS_CLASSIC_SUCCESSFUL = 0,
+ STATUS_CLASSIC_TIMEOUT = 6,
+ STATUS_CLASSIC_TOO_MANY = 5,
+ STATUS_CLASSIC_UNSATISFIED = 13
+} Status_Classic;
+
+/**
+ * @brief Macro to build a status code from Classic and POSIX API parts.
+ */
+#define STATUS_BUILD( classic_status, posix_status ) \
+ ( ( ( (unsigned int) ( posix_status ) ) << 8 ) | ( classic_status ) )
+
+/**
+ * @brief Macro to get the Classic API status code.
+ */
+#define STATUS_GET_CLASSIC( status ) \
+ ( ( status ) & 0xff )
+
+/**
+ * @brief Macro to get the POSIX API status code.
+ *
+ * Performs an arithmetic shift to reconstruct a negative POSIX status.
+ */
+#define STATUS_GET_POSIX( status ) \
+ ( ( ( (int) ( status ) ) | 0xff ) >> 8 )
+
+/**
+ * @brief Status codes.
+ */
+typedef enum {
+ STATUS_BARRIER_AUTOMATICALLY_RELEASED =
+ STATUS_BUILD( STATUS_CLASSIC_SUCCESSFUL, PTHREAD_BARRIER_SERIAL_THREAD ),
+ STATUS_DEADLOCK =
+ STATUS_BUILD( STATUS_CLASSIC_INCORRECT_STATE, EDEADLK ),
+ STATUS_FLUSHED =
+ STATUS_BUILD( STATUS_CLASSIC_UNSATISFIED, EAGAIN ),
+ STATUS_INCORRECT_STATE =
+ STATUS_BUILD( STATUS_CLASSIC_INCORRECT_STATE, EINVAL ),
+ STATUS_INTERRUPTED =
+ STATUS_BUILD( STATUS_CLASSIC_INTERNAL_ERROR, EINTR ),
+ STATUS_INVALID_NUMBER =
+ STATUS_BUILD( STATUS_CLASSIC_INVALID_NUMBER, EINVAL ),
+ STATUS_INVALID_PRIORITY =
+ STATUS_BUILD( STATUS_CLASSIC_INVALID_PRIORITY, EINVAL ),
+ STATUS_MAXIMUM_COUNT_EXCEEDED =
+ STATUS_BUILD( STATUS_CLASSIC_INTERNAL_ERROR, EOVERFLOW ),
+ STATUS_MESSAGE_INVALID_SIZE =
+ STATUS_BUILD( STATUS_CLASSIC_INVALID_SIZE, EMSGSIZE ),
+ STATUS_MESSAGE_QUEUE_WAIT_IN_ISR =
+ STATUS_BUILD( STATUS_CLASSIC_INTERNAL_ERROR, ENOMEM ),
+ STATUS_MESSAGE_QUEUE_WAS_DELETED =
+ STATUS_BUILD( STATUS_CLASSIC_OBJECT_WAS_DELETED, EBADF ),
+ STATUS_MINUS_ONE =
+ -1,
+ STATUS_MUTEX_CEILING_VIOLATED =
+ STATUS_BUILD( STATUS_CLASSIC_INVALID_PRIORITY, EINVAL ),
+ STATUS_NESTING_NOT_ALLOWED =
+ STATUS_BUILD( STATUS_CLASSIC_UNSATISFIED, EDEADLK ),
+ STATUS_NO_MEMORY =
+ STATUS_BUILD( STATUS_CLASSIC_NO_MEMORY, EINVAL ),
+ STATUS_NOT_DEFINED =
+ STATUS_BUILD( STATUS_CLASSIC_NOT_DEFINED, EINVAL ),
+ STATUS_NOT_OWNER =
+ STATUS_BUILD( STATUS_CLASSIC_NOT_OWNER_OF_RESOURCE, EPERM ),
+ STATUS_OBJECT_WAS_DELETED =
+ STATUS_BUILD( STATUS_CLASSIC_OBJECT_WAS_DELETED, EINVAL ),
+ STATUS_RESOURCE_IN_USE =
+ STATUS_BUILD( STATUS_CLASSIC_RESOURCE_IN_USE, EBUSY ),
+ STATUS_RESULT_TOO_LARGE =
+ STATUS_BUILD( STATUS_CLASSIC_UNSATISFIED, ERANGE ),
+ STATUS_SUCCESSFUL =
+ STATUS_BUILD( STATUS_CLASSIC_SUCCESSFUL, 0 ),
+ STATUS_TIMEOUT =
+ STATUS_BUILD( STATUS_CLASSIC_TIMEOUT, ETIMEDOUT ),
+ STATUS_TOO_MANY =
+ STATUS_BUILD( STATUS_CLASSIC_TOO_MANY, EAGAIN ),
+ STATUS_UNAVAILABLE =
+ STATUS_BUILD( STATUS_CLASSIC_UNSATISFIED, EBUSY ),
+ STATUS_UNSATISFIED =
+ STATUS_BUILD( STATUS_CLASSIC_UNSATISFIED, EAGAIN )
+} Status_Control;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_STATUS_H */
diff --git a/cpukit/include/rtems/score/sysstate.h b/cpukit/include/rtems/score/sysstate.h
new file mode 100644
index 0000000000..0e01927d9a
--- /dev/null
+++ b/cpukit/include/rtems/score/sysstate.h
@@ -0,0 +1,119 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSysState
+ *
+ * @brief System State Handler API
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_SYSSTATE_H
+#define _RTEMS_SCORE_SYSSTATE_H
+
+#include <rtems/score/basedefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreSysState System State Handler
+ *
+ * @ingroup Score
+ *
+ * @brief Management of the internal system state of RTEMS.
+ */
+/**@{**/
+
+/**
+ * @brief System states.
+ */
+typedef enum {
+ /**
+ * @brief The system is before the end of the first phase of initialization.
+ */
+ SYSTEM_STATE_BEFORE_INITIALIZATION,
+
+ /**
+ * @brief The system is between end of the first phase of initialization but
+ * before multitasking is started.
+ */
+ SYSTEM_STATE_BEFORE_MULTITASKING,
+
+ /**
+ * @brief The system is up and operating normally.
+ */
+ SYSTEM_STATE_UP,
+
+ /**
+ * @brief The system reached its terminal state.
+ */
+ SYSTEM_STATE_TERMINATED
+} System_state_Codes;
+
+#define SYSTEM_STATE_CODES_FIRST SYSTEM_STATE_BEFORE_INITIALIZATION
+
+#define SYSTEM_STATE_CODES_LAST SYSTEM_STATE_TERMINATED
+
+#if defined(RTEMS_MULTIPROCESSING)
+extern bool _System_state_Is_multiprocessing;
+#endif
+
+extern System_state_Codes _System_state_Current;
+
+RTEMS_INLINE_ROUTINE void _System_state_Set (
+ System_state_Codes state
+)
+{
+ _System_state_Current = state;
+}
+
+RTEMS_INLINE_ROUTINE System_state_Codes _System_state_Get ( void )
+{
+ return _System_state_Current;
+}
+
+RTEMS_INLINE_ROUTINE bool _System_state_Is_before_initialization (
+ System_state_Codes state
+)
+{
+ return (state == SYSTEM_STATE_BEFORE_INITIALIZATION);
+}
+
+RTEMS_INLINE_ROUTINE bool _System_state_Is_before_multitasking (
+ System_state_Codes state
+)
+{
+ return (state == SYSTEM_STATE_BEFORE_MULTITASKING);
+}
+
+RTEMS_INLINE_ROUTINE bool _System_state_Is_up (
+ System_state_Codes state
+)
+{
+ return (state == SYSTEM_STATE_UP);
+}
+
+RTEMS_INLINE_ROUTINE bool _System_state_Is_terminated (
+ System_state_Codes state
+)
+{
+ return (state == SYSTEM_STATE_TERMINATED);
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/thread.h b/cpukit/include/rtems/score/thread.h
new file mode 100644
index 0000000000..7e0e2722dd
--- /dev/null
+++ b/cpukit/include/rtems/score/thread.h
@@ -0,0 +1,935 @@
+/**
+ * @file rtems/score/thread.h
+ *
+ * @brief Constants and Structures Related with the Thread Control Block
+ *
+ * This include file contains all constants and structures associated
+ * with the thread control block.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Copyright (c) 2014, 2016 embedded brains GmbH.
+ *
+ * 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_THREAD_H
+#define _RTEMS_SCORE_THREAD_H
+
+#include <rtems/score/atomic.h>
+#include <rtems/score/context.h>
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/mppkt.h>
+#endif
+#include <rtems/score/isrlock.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/schedulernode.h>
+#include <rtems/score/stack.h>
+#include <rtems/score/states.h>
+#include <rtems/score/threadq.h>
+#include <rtems/score/timestamp.h>
+#include <rtems/score/watchdog.h>
+
+#if defined(RTEMS_SMP)
+#include <rtems/score/processormask.h>
+#endif
+
+struct _pthread_cleanup_context;
+
+struct Per_CPU_Control;
+
+struct _Scheduler_Control;
+
+struct User_extensions_Iterator;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreThread Thread Handler
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality related to the management of
+ * threads. This includes the creation, deletion, and scheduling of threads.
+ *
+ * The following variables are maintained as part of the per cpu data
+ * structure.
+ *
+ * + Idle thread pointer
+ * + Executing thread pointer
+ * + Heir thread pointer
+ */
+/**@{*/
+
+#if defined(RTEMS_POSIX_API)
+ #define RTEMS_SCORE_THREAD_ENABLE_EXHAUST_TIMESLICE
+#endif
+
+/*
+ * With the addition of the Constant Block Scheduler (CBS),
+ * this feature is needed even when POSIX is disabled.
+ */
+#define RTEMS_SCORE_THREAD_ENABLE_SCHEDULER_CALLOUT
+
+#if defined(RTEMS_POSIX_API)
+ #define RTEMS_SCORE_THREAD_ENABLE_USER_PROVIDED_STACK_VIA_API
+#endif
+
+#if defined(RTEMS_DEBUG)
+#define RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT
+#endif
+
+/*
+ * Only provided for backward compatiblity to not break application
+ * configurations.
+ */
+typedef void *Thread RTEMS_DEPRECATED;
+
+/**
+ * @brief Type of the numeric argument of a thread entry function with at
+ * least one numeric argument.
+ *
+ * This numeric argument type designates an unsigned integer type with the
+ * property that any valid pointer to void can be converted to this type and
+ * then converted back to a pointer to void. The result will compare equal to
+ * the original pointer.
+ */
+typedef CPU_Uint32ptr Thread_Entry_numeric_type;
+
+/**
+ * @brief Data for idle thread entry.
+ */
+typedef struct {
+ void *( *entry )( uintptr_t argument );
+} Thread_Entry_idle;
+
+/**
+ * @brief Data for thread entry with one numeric argument and no return value.
+ */
+typedef struct {
+ void ( *entry )( Thread_Entry_numeric_type argument );
+ Thread_Entry_numeric_type argument;
+} Thread_Entry_numeric;
+
+/**
+ * @brief Data for thread entry with one pointer argument and a pointer return
+ * value.
+ */
+typedef struct {
+ void *( *entry )( void *argument );
+ void *argument;
+} Thread_Entry_pointer;
+
+/**
+ * @brief Thread entry information.
+ */
+typedef struct {
+ /**
+ * @brief Thread entry adaptor.
+ *
+ * Calls the corresponding thread entry with the right parameters.
+ *
+ * @param executing The executing thread.
+ */
+ void ( *adaptor )( Thread_Control *executing );
+
+ /**
+ * @brief Thread entry data used by the adaptor to call the thread entry
+ * function with the right parameters.
+ */
+ union {
+ Thread_Entry_idle Idle;
+ Thread_Entry_numeric Numeric;
+ Thread_Entry_pointer Pointer;
+ } Kinds;
+} Thread_Entry_information;
+
+/**
+ * The following lists the algorithms used to manage the thread cpu budget.
+ *
+ * Reset Timeslice: At each context switch, reset the time quantum.
+ * Exhaust Timeslice: Only reset the quantum once it is consumed.
+ * Callout: Execute routine when budget is consumed.
+ */
+typedef enum {
+ THREAD_CPU_BUDGET_ALGORITHM_NONE,
+ THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE,
+ #if defined(RTEMS_SCORE_THREAD_ENABLE_EXHAUST_TIMESLICE)
+ THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE,
+ #endif
+ #if defined(RTEMS_SCORE_THREAD_ENABLE_SCHEDULER_CALLOUT)
+ THREAD_CPU_BUDGET_ALGORITHM_CALLOUT
+ #endif
+} Thread_CPU_budget_algorithms;
+
+/** This defines thes the entry point for the thread specific timeslice
+ * budget management algorithm.
+ */
+typedef void (*Thread_CPU_budget_algorithm_callout )( Thread_Control * );
+
+/**
+ * The following structure contains the information which defines
+ * the starting state of a thread.
+ */
+typedef struct {
+ /** This field contains the thread entry information. */
+ Thread_Entry_information Entry;
+ /*-------------- initial execution modes ----------------- */
+ /** This field indicates whether the thread was preemptible when
+ * it started.
+ */
+ bool is_preemptible;
+ /** This field indicates the CPU budget algorith. */
+ Thread_CPU_budget_algorithms budget_algorithm;
+ /** This field is the routine to invoke when the CPU allotment is
+ * consumed.
+ */
+ Thread_CPU_budget_algorithm_callout budget_callout;
+ /** This field is the initial ISR disable level of this thread. */
+ uint32_t isr_level;
+ /** This field is the initial priority. */
+ Priority_Control initial_priority;
+ #if defined(RTEMS_SCORE_THREAD_ENABLE_USER_PROVIDED_STACK_VIA_API)
+ /** This field indicates whether the SuperCore allocated the stack. */
+ bool core_allocated_stack;
+ #endif
+ /** This field is the stack information. */
+ Stack_Control Initial_stack;
+ #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+ /** This field is the initial FP context area address. */
+ Context_Control_fp *fp_context;
+ #endif
+ /** This field is the initial stack area address. */
+ void *stack;
+ /** The thread-local storage (TLS) area */
+ void *tls_area;
+} Thread_Start_information;
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief The thread state with respect to the scheduler.
+ */
+typedef enum {
+ /**
+ * @brief This thread is blocked with respect to the scheduler.
+ *
+ * This thread uses no scheduler nodes.
+ */
+ THREAD_SCHEDULER_BLOCKED,
+
+ /**
+ * @brief This thread is scheduled with respect to the scheduler.
+ *
+ * This thread executes using one of its scheduler nodes. This could be its
+ * own scheduler node or in case it owns resources taking part in the
+ * scheduler helping protocol a scheduler node of another thread.
+ */
+ THREAD_SCHEDULER_SCHEDULED,
+
+ /**
+ * @brief This thread is ready with respect to the scheduler.
+ *
+ * None of the scheduler nodes of this thread is scheduled.
+ */
+ THREAD_SCHEDULER_READY
+} Thread_Scheduler_state;
+#endif
+
+/**
+ * @brief Thread scheduler control.
+ */
+typedef struct {
+#if defined(RTEMS_SMP)
+ /**
+ * @brief Lock to protect the scheduler node change requests.
+ */
+ ISR_lock_Control Lock;
+
+ /**
+ * @brief The current scheduler state of this thread.
+ */
+ Thread_Scheduler_state state;
+
+ /**
+ * @brief The home scheduler control of this thread.
+ */
+ const struct _Scheduler_Control *home;
+
+ /**
+ * @brief The processor assigned by the current scheduler.
+ */
+ struct Per_CPU_Control *cpu;
+
+ /**
+ * @brief Scheduler nodes immediately available to the thread by its home
+ * scheduler instance and due to thread queue ownerships.
+ *
+ * This chain is protected by the thread wait lock.
+ *
+ * This chain is never empty. The first scheduler node on the chain is the
+ * scheduler node of the home scheduler instance.
+ */
+ Chain_Control Wait_nodes;
+
+ /**
+ * @brief Scheduler nodes immediately available to the schedulers for this
+ * thread.
+ *
+ * This chain is protected by the thread state lock.
+ *
+ * This chain is never empty. The first scheduler node on the chain is the
+ * scheduler node of the home scheduler instance.
+ */
+ Chain_Control Scheduler_nodes;
+
+ /**
+ * @brief Node for the Per_CPU_Control::Threads_in_need_for_help chain.
+ *
+ * This chain is protected by the Per_CPU_Control::Lock lock of the assigned
+ * processor.
+ */
+ Chain_Node Help_node;
+
+ /**
+ * @brief Count of nodes scheduler nodes minus one.
+ *
+ * This chain is protected by the thread state lock.
+ */
+ size_t helping_nodes;
+
+ /**
+ * @brief List of pending scheduler node requests.
+ *
+ * This list is protected by the thread scheduler lock.
+ */
+ Scheduler_Node *requests;
+
+ /**
+ * @brief The thread processor affinity set.
+ */
+ Processor_mask Affinity;
+#endif
+
+ /**
+ * @brief The scheduler nodes of this thread.
+ *
+ * Each thread has a scheduler node for each scheduler instance.
+ */
+ Scheduler_Node *nodes;
+} Thread_Scheduler_control;
+
+/**
+ * @brief Union type to hold a pointer to an immutable or a mutable object.
+ *
+ * The main purpose is to enable passing of pointers to read-only send buffers
+ * in the message passing subsystem. This approach is somewhat fragile since
+ * it prevents the compiler to check if the operations on objects are valid
+ * with respect to the constant qualifier. An alternative would be to add a
+ * third pointer argument for immutable objects, but this would increase the
+ * structure size.
+ */
+typedef union {
+ void *mutable_object;
+ const void *immutable_object;
+} Thread_Wait_information_Object_argument_type;
+
+/**
+ * @brief This type is able to contain several flags used to control the wait
+ * class and state of a thread.
+ *
+ * The mutually exclusive wait class flags are
+ * - @ref THREAD_WAIT_CLASS_EVENT,
+ * - @ref THREAD_WAIT_CLASS_SYSTEM_EVENT, and
+ * - @ref THREAD_WAIT_CLASS_OBJECT.
+ *
+ * The mutually exclusive wait state flags are
+ * - @ref THREAD_WAIT_STATE_INTEND_TO_BLOCK,
+ * - @ref THREAD_WAIT_STATE_BLOCKED, and
+ * - @ref THREAD_WAIT_STATE_READY_AGAIN.
+ */
+typedef unsigned int Thread_Wait_flags;
+
+/**
+ * @brief Information required to manage a thread while it is blocked.
+ *
+ * This contains the information required to manage a thread while it is
+ * blocked and to return information to it.
+ */
+typedef struct {
+#if defined(RTEMS_MULTIPROCESSING)
+ /*
+ * @brief This field is the identifier of the remote object this thread is
+ * waiting upon.
+ */
+ Objects_Id remote_id;
+#endif
+ /** This field is used to return an integer while when blocked. */
+ uint32_t count;
+ /** This field is for a pointer to a user return argument. */
+ void *return_argument;
+ /** This field is for a pointer to a second user return argument. */
+ Thread_Wait_information_Object_argument_type
+ return_argument_second;
+ /** This field contains any options in effect on this blocking operation. */
+ uint32_t option;
+ /** This field will contain the return status from a blocking operation.
+ *
+ * @note The following assumes that all API return codes can be
+ * treated as an uint32_t.
+ */
+ uint32_t return_code;
+
+ /**
+ * @brief This field contains several flags used to control the wait class
+ * and state of a thread in case fine-grained locking is used.
+ */
+#if defined(RTEMS_SMP)
+ Atomic_Uint flags;
+#else
+ Thread_Wait_flags flags;
+#endif
+
+#if defined(RTEMS_SMP)
+ /**
+ * @brief Thread wait lock control block.
+ *
+ * Parts of the thread wait information are protected by the thread wait
+ * default lock and additionally a thread queue lock in case the thread
+ * is enqueued on a thread queue.
+ *
+ * The thread wait lock mechanism protects the following thread variables
+ * - POSIX_API_Control::Attributes,
+ * - Scheduler_Node::Wait,
+ * - Thread_Control::Wait::Lock::Pending_requests,
+ * - Thread_Control::Wait::queue, and
+ * - Thread_Control::Wait::operations.
+ *
+ * @see _Thread_Wait_acquire(), _Thread_Wait_release(), _Thread_Wait_claim(),
+ * _Thread_Wait_restore_default() and _Thread_Wait_tranquilize().
+ */
+ struct {
+ /**
+ * @brief Thread wait default lock.
+ */
+ ISR_lock_Control Default;
+
+ /**
+ * @brief The pending thread wait lock acquire or tranquilize requests in
+ * case the thread is enqueued on a thread queue.
+ */
+ Chain_Control Pending_requests;
+
+ /**
+ * @brief Tranquilizer gate used by _Thread_Wait_tranquilize().
+ *
+ * This gate is closed by _Thread_Wait_claim(). In case there are no
+ * pending requests during a _Thread_Wait_restore_default(), then this gate
+ * is opened immediately, otherwise it is placed on the pending request
+ * chain and opened by _Thread_Wait_remove_request_locked() as the last
+ * gate on the chain to signal overall request completion.
+ */
+ Thread_queue_Gate Tranquilizer;
+ } Lock;
+
+ /**
+ * @brief Thread queue link provided for use by the thread wait lock owner to
+ * build a thread queue path.
+ */
+ Thread_queue_Link Link;
+#endif
+
+ /**
+ * @brief The current thread queue.
+ *
+ * If this field is NULL the thread is not enqueued on a thread queue. This
+ * field is protected by the thread wait default lock.
+ *
+ * @see _Thread_Wait_claim().
+ */
+ Thread_queue_Queue *queue;
+
+ /**
+ * @brief The current thread queue operations.
+ *
+ * This field is protected by the thread lock wait default lock.
+ *
+ * @see _Thread_Wait_claim().
+ */
+ const Thread_queue_Operations *operations;
+
+ Thread_queue_Heads *spare_heads;
+} Thread_Wait_information;
+
+/**
+ * @brief Information required to manage a thread timer.
+ */
+typedef struct {
+ ISR_LOCK_MEMBER( Lock )
+ Watchdog_Header *header;
+ Watchdog_Control Watchdog;
+} Thread_Timer_information;
+
+/**
+ * The following defines the control block used to manage
+ * each thread proxy.
+ *
+ * @note It is critical that proxies and threads have identical
+ * memory images for the shared part.
+ */
+typedef struct {
+ /** This field is the object management structure for each proxy. */
+ Objects_Control Object;
+
+ /**
+ * @see Thread_Control::Join_queue
+ */
+ Thread_queue_Control Join_queue;
+
+ /** This field is the current execution state of this proxy. */
+ States_Control current_state;
+
+ /**
+ * @brief The base priority of this thread in its home scheduler instance.
+ */
+ Priority_Node Real_priority;
+
+#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
+ /** This field is the number of mutexes currently held by this proxy. */
+ uint32_t resource_count;
+#endif
+
+ /**
+ * @brief Scheduler related control.
+ */
+ Thread_Scheduler_control Scheduler;
+
+ /** This field is the blocking information for this proxy. */
+ Thread_Wait_information Wait;
+ /** This field is the Watchdog used to manage proxy delays and timeouts. */
+ Thread_Timer_information Timer;
+#if defined(RTEMS_MULTIPROCESSING)
+ /** This field is the received response packet in an MP system. */
+ MP_packet_Prefix *receive_packet;
+ /****************** end of common block ********************/
+
+ /**
+ * @brief Thread queue callout for _Thread_queue_Enqueue().
+ */
+ Thread_queue_MP_callout thread_queue_callout;
+
+ /**
+ * @brief This field is used to manage the set of active proxies in the system.
+ */
+ RBTree_Node Active;
+
+ /**
+ * @brief The scheduler node providing the thread wait nodes used to enqueue
+ * this thread proxy on a thread queue.
+ */
+ Scheduler_Node Scheduler_node;
+
+ /**
+ * @brief Provide thread queue heads for this thread proxy.
+ *
+ * The actual size of the thread queue heads depends on the application
+ * configuration. Since thread proxies are never destroyed we can use the
+ * same storage place for the thread queue heads.
+ */
+ Thread_queue_Heads Thread_queue_heads[ RTEMS_ZERO_LENGTH_ARRAY ];
+#endif
+} Thread_Proxy_control;
+
+/**
+ * The following record defines the control block used
+ * to manage each thread.
+ *
+ * @note It is critical that proxies and threads have identical
+ * memory images for the shared part.
+ */
+typedef enum {
+ /** This value is for the Classic RTEMS API. */
+ THREAD_API_RTEMS,
+ /** This value is for the POSIX API. */
+ THREAD_API_POSIX
+} Thread_APIs;
+
+/** This macro defines the first API which has threads. */
+#define THREAD_API_FIRST THREAD_API_RTEMS
+
+/** This macro defines the last API which has threads. */
+#define THREAD_API_LAST THREAD_API_POSIX
+
+typedef struct Thread_Action Thread_Action;
+
+/**
+ * @brief Thread action handler.
+ *
+ * The thread action handler will be called with interrupts disabled and a
+ * corresponding lock acquired, e.g. _Thread_State_acquire(). The handler must
+ * release the corresponding lock, e.g. _Thread_State_release(). So, the
+ * corresponding lock may be used to protect private data used by the
+ * particular action.
+ *
+ * Since the action is passed to the handler additional data may be accessed
+ * via RTEMS_CONTAINER_OF().
+ *
+ * @param[in] the_thread The thread performing the action.
+ * @param[in] action The thread action.
+ * @param[in] lock_context The lock context to use for the lock release.
+ */
+typedef void ( *Thread_Action_handler )(
+ Thread_Control *the_thread,
+ Thread_Action *action,
+ ISR_lock_Context *lock_context
+);
+
+/**
+ * @brief Thread action.
+ *
+ * Thread actions can be chained together to trigger a set of actions on
+ * particular events like for example a thread post-switch. Use
+ * _Thread_Action_initialize() to initialize this structure.
+ *
+ * Thread actions are the building block for efficient implementation of
+ * - Classic signals delivery,
+ * - POSIX signals delivery, and
+ * - thread life-cycle changes.
+ *
+ * @see _Thread_Add_post_switch_action() and _Thread_Run_post_switch_actions().
+ */
+struct Thread_Action {
+ Chain_Node Node;
+ Thread_Action_handler handler;
+};
+
+/**
+ * @brief Per-thread information for POSIX Keys.
+ */
+typedef struct {
+ /**
+ * @brief Key value pairs registered for this thread.
+ */
+ RBTree_Control Key_value_pairs;
+
+ /**
+ * @brief Lock to protect the tree operations.
+ */
+ ISR_LOCK_MEMBER( Lock )
+} Thread_Keys_information;
+
+/**
+ * @brief Control block to manage thread actions.
+ *
+ * Use _Thread_Action_control_initialize() to initialize this structure.
+ */
+typedef struct {
+ Chain_Control Chain;
+} Thread_Action_control;
+
+/**
+ * @brief Thread life states.
+ *
+ * The thread life states are orthogonal to the thread states used for
+ * synchronization primitives and blocking operations. They reflect the state
+ * changes triggered with thread restart and delete requests.
+ *
+ * The individual state values must be a power of two to allow use of bit
+ * operations to manipulate and evaluate the thread life state.
+ */
+typedef enum {
+ THREAD_LIFE_PROTECTED = 0x1,
+ THREAD_LIFE_RESTARTING = 0x2,
+ THREAD_LIFE_TERMINATING = 0x4,
+ THREAD_LIFE_CHANGE_DEFERRED = 0x8,
+ THREAD_LIFE_DETACHED = 0x10
+} Thread_Life_state;
+
+/**
+ * @brief Thread life control.
+ */
+typedef struct {
+ /**
+ * @brief Thread life action used to react upon thread restart and delete
+ * requests.
+ */
+ Thread_Action Action;
+
+ /**
+ * @brief The current thread life state.
+ */
+ Thread_Life_state state;
+
+ /**
+ * @brief The count of pending life change requests.
+ */
+ uint32_t pending_life_change_requests;
+
+#if defined(RTEMS_POSIX_API)
+ /**
+ * @brief The thread exit value.
+ *
+ * It is,
+ * - the value passed to pthread_exit(), or
+ * - PTHREAD_CANCELED in case it is cancelled via pthread_cancel(), or
+ * - NULL.
+ */
+ void *exit_value;
+#endif
+} Thread_Life_control;
+
+typedef struct {
+ uint32_t flags;
+ void * control;
+}Thread_Capture_control;
+
+/**
+ * This structure defines the Thread Control Block (TCB).
+ *
+ * Uses a leading underscore in the structure name to allow forward
+ * declarations in standard header files provided by Newlib and GCC.
+ *
+ * In case the second member changes (currently Join_queue), then the memset()
+ * in _Thread_Initialize() must be adjusted.
+ */
+struct _Thread_Control {
+ /** This field is the object management structure for each thread. */
+ Objects_Control Object;
+
+ /**
+ * @brief Thread queue for thread join operations and multi-purpose lock.
+ *
+ * The lock of this thread queue is used for various purposes. It protects
+ * the following fields
+ *
+ * - RTEMS_API_Control::Signal,
+ * - Thread_Control::budget_algorithm,
+ * - Thread_Control::budget_callout,
+ * - Thread_Control::cpu_time_budget,
+ * - Thread_Control::current_state,
+ * - Thread_Control::Post_switch_actions,
+ * - Thread_Control::Scheduler::control, and
+ * - Thread_Control::Scheduler::own_control.
+ *
+ * @see _Thread_State_acquire().
+ */
+ Thread_queue_Control Join_queue;
+
+ /** This field is the current execution state of this thread. */
+ States_Control current_state;
+
+ /**
+ * @brief The base priority of this thread in its home scheduler instance.
+ */
+ Priority_Node Real_priority;
+
+#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
+ /** This field is the number of mutexes currently held by this thread. */
+ uint32_t resource_count;
+#endif
+
+ /**
+ * @brief Scheduler related control.
+ */
+ Thread_Scheduler_control Scheduler;
+
+ /** This field is the blocking information for this thread. */
+ Thread_Wait_information Wait;
+ /** This field is the Watchdog used to manage thread delays and timeouts. */
+ Thread_Timer_information Timer;
+#if defined(RTEMS_MULTIPROCESSING)
+ /** This field is the received response packet in an MP system. */
+ MP_packet_Prefix *receive_packet;
+#endif
+ /*================= end of common block =================*/
+
+#if defined(RTEMS_SMP) && defined(RTEMS_PROFILING)
+ /**
+ * @brief Potpourri lock statistics.
+ *
+ * These SMP lock statistics are used for all lock objects that lack a
+ * storage space for the statistics. Examples are lock objects used in
+ * external libraries which are independent of the actual RTEMS build
+ * configuration.
+ */
+ SMP_lock_Stats Potpourri_stats;
+#endif
+
+ /** This field is true if the thread is an idle thread. */
+ bool is_idle;
+#if defined(RTEMS_MULTIPROCESSING)
+ /** This field is true if the thread is offered globally */
+ bool is_global;
+#endif
+ /** This field is true if the thread is preemptible. */
+ bool is_preemptible;
+ /** This field is true if the thread uses the floating point unit. */
+ bool is_fp;
+
+ /**
+ * @brief True, if the thread was created with an inherited scheduler
+ * (PTHREAD_INHERIT_SCHED), and false otherwise.
+ */
+ bool was_created_with_inherited_scheduler;
+
+ /** This field is the length of the time quantum that this thread is
+ * allowed to consume. The algorithm used to manage limits on CPU usage
+ * is specified by budget_algorithm.
+ */
+ uint32_t cpu_time_budget;
+ /** This field is the algorithm used to manage this thread's time
+ * quantum. The algorithm may be specified as none which case,
+ * no limit is in place.
+ */
+ Thread_CPU_budget_algorithms budget_algorithm;
+ /** This field is the method invoked with the budgeted time is consumed. */
+ Thread_CPU_budget_algorithm_callout budget_callout;
+ /** This field is the amount of CPU time consumed by this thread
+ * since it was created.
+ */
+ Timestamp_Control cpu_time_used;
+
+ /** This field contains information about the starting state of
+ * this thread.
+ */
+ Thread_Start_information Start;
+
+ Thread_Action_control Post_switch_actions;
+
+ /** This field contains the context of this thread. */
+ Context_Control Registers;
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+ /** This field points to the floating point context for this thread.
+ * If NULL, the thread is integer only.
+ */
+ Context_Control_fp *fp_context;
+#endif
+ /** This field points to the newlib reentrancy structure for this thread. */
+ struct _reent *libc_reent;
+ /** This array contains the API extension area pointers. */
+ void *API_Extensions[ THREAD_API_LAST + 1 ];
+
+ /**
+ * @brief The POSIX Keys information.
+ */
+ Thread_Keys_information Keys;
+
+ /**
+ * @brief Thread life-cycle control.
+ *
+ * Control state changes triggered by thread restart and delete requests.
+ */
+ Thread_Life_control Life;
+
+ Thread_Capture_control Capture;
+
+ /**
+ * @brief LIFO list of POSIX cleanup contexts.
+ */
+ struct _pthread_cleanup_context *last_cleanup_context;
+
+ /**
+ * @brief LIFO list of user extensions iterators.
+ */
+ struct User_extensions_Iterator *last_user_extensions_iterator;
+
+ /**
+ * @brief Variable length array of user extension pointers.
+ *
+ * The length is defined by the application via <rtems/confdefs.h>.
+ */
+ void *extensions[ RTEMS_ZERO_LENGTH_ARRAY ];
+};
+
+#if (CPU_PROVIDES_IDLE_THREAD_BODY == FALSE)
+/**
+ * This routine is the body of the system idle thread.
+ *
+ * NOTE: This routine is actually instantiated by confdefs.h when needed.
+ */
+void *_Thread_Idle_body(
+ uintptr_t ignored
+);
+#endif
+
+typedef void (*rtems_per_thread_routine)( Thread_Control * );
+
+/* Use rtems_task_iterate() instead */
+void rtems_iterate_over_all_threads(
+ rtems_per_thread_routine routine
+) RTEMS_DEPRECATED;
+
+/**
+ * @brief Thread control add-on.
+ */
+typedef struct {
+ /**
+ * @brief Offset of the pointer field in Thread_Control referencing an
+ * application configuration dependent memory area in the thread control
+ * block.
+ */
+ size_t destination_offset;
+
+ /**
+ * @brief Offset relative to the thread control block begin to an application
+ * configuration dependent memory area.
+ */
+ size_t source_offset;
+} Thread_Control_add_on;
+
+/**
+ * @brief Thread control add-ons.
+ *
+ * The thread control block contains fields that point to application
+ * configuration dependent memory areas, like the scheduler information, the
+ * API control blocks, the user extension context table, and the Newlib
+ * re-entrancy support. Account for these areas in the configuration and
+ * avoid extra workspace allocations for these areas.
+ *
+ * This array is provided via <rtems/confdefs.h>.
+ *
+ * @see _Thread_Control_add_on_count and _Thread_Control_size.
+ */
+extern const Thread_Control_add_on _Thread_Control_add_ons[];
+
+/**
+ * @brief Thread control add-on count.
+ *
+ * Count of entries in _Thread_Control_add_ons.
+ *
+ * This value is provided via <rtems/confdefs.h>.
+ */
+extern const size_t _Thread_Control_add_on_count;
+
+/**
+ * @brief Size of the thread control block of a particular application.
+ *
+ * This value is provided via <rtems/confdefs.h>.
+ *
+ * @see _Thread_Control_add_ons.
+ */
+extern const size_t _Thread_Control_size;
+
+/**
+ * @brief Maximum size of a thread name in characters (including the
+ * terminating '\0' character).
+ *
+ * This value is provided via <rtems/confdefs.h>.
+ */
+extern const size_t _Thread_Maximum_name_size;
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/threaddispatch.h b/cpukit/include/rtems/score/threaddispatch.h
new file mode 100644
index 0000000000..63eb4c6fb4
--- /dev/null
+++ b/cpukit/include/rtems/score/threaddispatch.h
@@ -0,0 +1,281 @@
+/**
+ * @brief Constants and Structures Related with Thread Dispatch
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_THREADDISPATCH_H
+#define _RTEMS_SCORE_THREADDISPATCH_H
+
+#include <rtems/score/percpu.h>
+#include <rtems/score/isrlock.h>
+#include <rtems/score/profiling.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @addtogroup ScoreThread
+ *
+ * @{
+ */
+
+#if defined(RTEMS_SMP) || ( CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE )
+/**
+ * @brief Enables a robust thread dispatch.
+ *
+ * On each change of the thread dispatch disable level from one to zero the
+ * interrupt status is checked. In case interrupts are disabled and SMP is
+ * enabled or the CPU port needs it, then the system terminates with the fatal
+ * internal error INTERNAL_ERROR_BAD_THREAD_DISPATCH_ENVIRONMENT.
+ */
+#define RTEMS_SCORE_ROBUST_THREAD_DISPATCH
+#endif
+
+/**
+ * @brief Indicates if the executing thread is inside a thread dispatch
+ * critical section.
+ *
+ * @retval true Thread dispatching is enabled.
+ * @retval false The executing thread is inside a thread dispatch critical
+ * section and dispatching is not allowed.
+ */
+RTEMS_INLINE_ROUTINE bool _Thread_Dispatch_is_enabled(void)
+{
+ bool enabled;
+
+#if defined(RTEMS_SMP)
+ ISR_Level level;
+
+ _ISR_Local_disable( level );
+#endif
+
+ enabled = _Thread_Dispatch_disable_level == 0;
+
+#if defined(RTEMS_SMP)
+ _ISR_Local_enable( level );
+#endif
+
+ return enabled;
+}
+
+/**
+ * @brief Gets thread dispatch disable level.
+ *
+ * @return The value of the thread dispatch level.
+ */
+RTEMS_INLINE_ROUTINE uint32_t _Thread_Dispatch_get_disable_level(void)
+{
+ return _Thread_Dispatch_disable_level;
+}
+
+/**
+ * @brief Thread dispatch initialization.
+ *
+ * This routine initializes the thread dispatching subsystem.
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Dispatch_initialization( void )
+{
+ _Thread_Dispatch_disable_level = 1;
+}
+
+/**
+ * @brief Performs a thread dispatch if necessary.
+ *
+ * This routine is responsible for transferring control of the processor from
+ * the executing thread to the heir thread. Once the heir is running an
+ * attempt is made to run the pending post-switch thread actions.
+ *
+ * As part of this process, it is responsible for the following actions
+ * - update timing information of the executing thread,
+ * - save the context of the executing thread,
+ * - invokation of the thread switch user extensions,
+ * - restore the context of the heir thread, and
+ * - run of pending post-switch thread actions of the resulting executing
+ * thread.
+ *
+ * On entry the thread dispatch level must be equal to zero.
+ */
+void _Thread_Dispatch( void );
+
+/**
+ * @brief Directly do a thread dispatch.
+ *
+ * Must be called with a thread dispatch disable level of one, otherwise the
+ * INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL will occur. This function
+ * is useful for operations which synchronously block, e.g. self restart, self
+ * deletion, yield, sleep.
+ *
+ * @param[in] cpu_self The current processor.
+ *
+ * @see _Thread_Dispatch().
+ */
+void _Thread_Dispatch_direct( Per_CPU_Control *cpu_self );
+
+/**
+ * @brief Performs a thread dispatch on the current processor.
+ *
+ * On entry the thread dispatch disable level must be equal to one and
+ * interrupts must be disabled.
+ *
+ * This function assumes that a thread dispatch is necessary.
+ *
+ * @param[in] cpu_self The current processor.
+ * @param[in] level The previous interrupt level.
+ *
+ * @see _Thread_Dispatch().
+ */
+void _Thread_Do_dispatch( Per_CPU_Control *cpu_self, ISR_Level level );
+
+/**
+ * @brief Disables thread dispatching inside a critical section (interrupts
+ * disabled) with the current processor.
+ *
+ * @param[in] cpu_self The current processor.
+ * @param[in] lock_context The lock context of the corresponding
+ * _ISR_lock_ISR_disable() that started the critical section.
+ *
+ * @return The current processor.
+ */
+RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_Dispatch_disable_with_CPU(
+ Per_CPU_Control *cpu_self,
+ const ISR_lock_Context *lock_context
+)
+{
+ uint32_t disable_level;
+
+ disable_level = cpu_self->thread_dispatch_disable_level;
+ _Profiling_Thread_dispatch_disable_critical(
+ cpu_self,
+ disable_level,
+ lock_context
+ );
+ cpu_self->thread_dispatch_disable_level = disable_level + 1;
+
+ return cpu_self;
+}
+
+/**
+ * @brief Disables thread dispatching inside a critical section (interrupts
+ * disabled).
+ *
+ * @param[in] lock_context The lock context of the corresponding
+ * _ISR_lock_ISR_disable() that started the critical section.
+ *
+ * @return The current processor.
+ */
+RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_Dispatch_disable_critical(
+ const ISR_lock_Context *lock_context
+)
+{
+ return _Thread_Dispatch_disable_with_CPU( _Per_CPU_Get(), lock_context );
+}
+
+/**
+ * @brief Disables thread dispatching.
+ *
+ * @return The current processor.
+ */
+RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_Dispatch_disable( void )
+{
+ Per_CPU_Control *cpu_self;
+ ISR_lock_Context lock_context;
+
+#if defined( RTEMS_SMP ) || defined( RTEMS_PROFILING )
+ _ISR_lock_ISR_disable( &lock_context );
+#endif
+
+ cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
+
+#if defined( RTEMS_SMP ) || defined( RTEMS_PROFILING )
+ _ISR_lock_ISR_enable( &lock_context );
+#endif
+
+ return cpu_self;
+}
+
+/**
+ * @brief Enables thread dispatching.
+ *
+ * May perfrom a thread dispatch if necessary as a side-effect.
+ *
+ * @param[in] cpu_self The current processor.
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Dispatch_enable( Per_CPU_Control *cpu_self )
+{
+ uint32_t disable_level = cpu_self->thread_dispatch_disable_level;
+
+ if ( disable_level == 1 ) {
+ ISR_Level level;
+
+ _ISR_Local_disable( level );
+
+ if (
+ cpu_self->dispatch_necessary
+#if defined(RTEMS_SCORE_ROBUST_THREAD_DISPATCH)
+ || !_ISR_Is_enabled( level )
+#endif
+ ) {
+ _Thread_Do_dispatch( cpu_self, level );
+ } else {
+ cpu_self->thread_dispatch_disable_level = 0;
+ _Profiling_Thread_dispatch_enable( cpu_self, 0 );
+ }
+
+ _ISR_Local_enable( level );
+ } else {
+ _Assert( disable_level > 0 );
+ cpu_self->thread_dispatch_disable_level = disable_level - 1;
+ }
+}
+
+/**
+ * @brief Unnests thread dispatching.
+ *
+ * @param[in] cpu_self The current processor.
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Dispatch_unnest( Per_CPU_Control *cpu_self )
+{
+ _Assert( cpu_self->thread_dispatch_disable_level > 0 );
+ --cpu_self->thread_dispatch_disable_level;
+}
+
+/**
+ * @brief Requests a thread dispatch on the target processor.
+ *
+ * @param[in] cpu_self The current processor.
+ * @param[in] cpu_target The target processor to request a thread dispatch.
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Dispatch_request(
+ Per_CPU_Control *cpu_self,
+ Per_CPU_Control *cpu_target
+)
+{
+#if defined( RTEMS_SMP )
+ if ( cpu_self == cpu_target ) {
+ cpu_self->dispatch_necessary = true;
+ } else {
+ _Atomic_Fetch_or_ulong( &cpu_target->message, 0, ATOMIC_ORDER_RELEASE );
+ _CPU_SMP_Send_interrupt( _Per_CPU_Get_index( cpu_target ) );
+ }
+#else
+ cpu_self->dispatch_necessary = true;
+ (void) cpu_target;
+#endif
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_THREADDISPATCH_H */
diff --git a/cpukit/include/rtems/score/threadimpl.h b/cpukit/include/rtems/score/threadimpl.h
new file mode 100644
index 0000000000..b6722fae19
--- /dev/null
+++ b/cpukit/include/rtems/score/threadimpl.h
@@ -0,0 +1,1969 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines from the Thread Handler
+ *
+ * This file contains the macro implementation of the inlined
+ * routines from the Thread handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Copyright (c) 2014, 2017 embedded brains GmbH.
+ *
+ * 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_THREADIMPL_H
+#define _RTEMS_SCORE_THREADIMPL_H
+
+#include <rtems/score/thread.h>
+#include <rtems/score/assert.h>
+#include <rtems/score/chainimpl.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/objectimpl.h>
+#include <rtems/score/schedulernodeimpl.h>
+#include <rtems/score/statesimpl.h>
+#include <rtems/score/status.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/threadqimpl.h>
+#include <rtems/score/todimpl.h>
+#include <rtems/score/freechain.h>
+#include <rtems/score/watchdogimpl.h>
+#include <rtems/config.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreThread
+ */
+/**@{**/
+
+/**
+ * The following structure contains the information necessary to manage
+ * a thread which it is waiting for a resource.
+ */
+#define THREAD_STATUS_PROXY_BLOCKING 0x1111111
+
+/**
+ * Self for the GNU Ada Run-Time
+ */
+extern void *rtems_ada_self;
+
+typedef struct {
+ Objects_Information Objects;
+
+ Freechain_Control Free_thread_queue_heads;
+} Thread_Information;
+
+/**
+ * The following defines the information control block used to
+ * manage this class of objects.
+ */
+extern Thread_Information _Thread_Internal_information;
+
+/**
+ * @brief Object identifier of the global constructor thread.
+ *
+ * This variable is set by _RTEMS_tasks_Initialize_user_tasks_body() or
+ * _POSIX_Threads_Initialize_user_threads_body().
+ *
+ * It is consumed by _Thread_Handler().
+ */
+extern Objects_Id _Thread_Global_constructor;
+
+/**
+ * The following points to the thread whose floating point
+ * context is currently loaded.
+ */
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+extern Thread_Control *_Thread_Allocated_fp;
+#endif
+
+#if defined(RTEMS_SMP)
+#define THREAD_OF_SCHEDULER_HELP_NODE( node ) \
+ RTEMS_CONTAINER_OF( node, Thread_Control, Scheduler.Help_node )
+#endif
+
+typedef bool ( *Thread_Visitor )( Thread_Control *the_thread, void *arg );
+
+void _Thread_Iterate(
+ Thread_Visitor visitor,
+ void *arg
+);
+
+void _Thread_Initialize_information(
+ Thread_Information *information,
+ Objects_APIs the_api,
+ uint16_t the_class,
+ uint32_t maximum,
+ bool is_string,
+ uint32_t maximum_name_length
+);
+
+/**
+ * @brief Initialize thread handler.
+ *
+ * This routine performs the initialization necessary for this handler.
+ */
+void _Thread_Handler_initialization(void);
+
+/**
+ * @brief Create idle thread.
+ *
+ * This routine creates the idle thread.
+ *
+ * @warning No thread should be created before this one.
+ */
+void _Thread_Create_idle(void);
+
+/**
+ * @brief Start thread multitasking.
+ *
+ * This routine initiates multitasking. It is invoked only as
+ * part of initialization and its invocation is the last act of
+ * the non-multitasking part of the system initialization.
+ */
+void _Thread_Start_multitasking( void ) RTEMS_NO_RETURN;
+
+/**
+ * @brief Allocate the requested stack space for the thread.
+ *
+ * Allocate the requested stack space for the thread.
+ * Set the Start.stack field to the address of the stack.
+ *
+ * @param[in] the_thread is the thread where the stack space is requested
+ * @param[in] stack_size is the stack space is requested
+ *
+ * @retval actual size allocated after any adjustment
+ * @retval zero if the allocation failed
+ */
+size_t _Thread_Stack_Allocate(
+ Thread_Control *the_thread,
+ size_t stack_size
+);
+
+/**
+ * @brief Deallocate thread stack.
+ *
+ * Deallocate the Thread's stack.
+ */
+void _Thread_Stack_Free(
+ Thread_Control *the_thread
+);
+
+/**
+ * @brief Initialize thread.
+ *
+ * This routine initializes the specified the thread. It allocates
+ * all memory associated with this thread. It completes by adding
+ * the thread to the local object table so operations on this
+ * thread id are allowed.
+ *
+ * @note If stack_area is NULL, it is allocated from the workspace.
+ *
+ * @note If the stack is allocated from the workspace, then it is
+ * guaranteed to be of at least minimum size.
+ */
+bool _Thread_Initialize(
+ Thread_Information *information,
+ Thread_Control *the_thread,
+ const struct _Scheduler_Control *scheduler,
+ void *stack_area,
+ size_t stack_size,
+ bool is_fp,
+ Priority_Control priority,
+ bool is_preemptible,
+ Thread_CPU_budget_algorithms budget_algorithm,
+ Thread_CPU_budget_algorithm_callout budget_callout,
+ uint32_t isr_level,
+ Objects_Name name
+);
+
+/**
+ * @brief Initializes thread and executes it.
+ *
+ * This routine initializes the executable information for a thread
+ * and makes it ready to execute. After this routine executes, the
+ * thread competes with all other threads for CPU time.
+ *
+ * @param the_thread The thread to be started.
+ * @param entry The thread entry information.
+ */
+bool _Thread_Start(
+ Thread_Control *the_thread,
+ const Thread_Entry_information *entry,
+ ISR_lock_Context *lock_context
+);
+
+void _Thread_Restart_self(
+ Thread_Control *executing,
+ const Thread_Entry_information *entry,
+ ISR_lock_Context *lock_context
+) RTEMS_NO_RETURN;
+
+bool _Thread_Restart_other(
+ Thread_Control *the_thread,
+ const Thread_Entry_information *entry,
+ ISR_lock_Context *lock_context
+);
+
+void _Thread_Yield( Thread_Control *executing );
+
+Thread_Life_state _Thread_Change_life(
+ Thread_Life_state clear,
+ Thread_Life_state set,
+ Thread_Life_state ignore
+);
+
+Thread_Life_state _Thread_Set_life_protection( Thread_Life_state state );
+
+/**
+ * @brief Kills all zombie threads in the system.
+ *
+ * Threads change into the zombie state as the last step in the thread
+ * termination sequence right before a context switch to the heir thread is
+ * initiated. Since the thread stack is still in use during this phase we have
+ * to postpone the thread stack reclamation until this point. On SMP
+ * configurations we may have to busy wait for context switch completion here.
+ */
+void _Thread_Kill_zombies( void );
+
+void _Thread_Exit(
+ Thread_Control *executing,
+ Thread_Life_state set,
+ void *exit_value
+);
+
+void _Thread_Join(
+ Thread_Control *the_thread,
+ States_Control waiting_for_join,
+ Thread_Control *executing,
+ Thread_queue_Context *queue_context
+);
+
+void _Thread_Cancel(
+ Thread_Control *the_thread,
+ Thread_Control *executing,
+ void *exit_value
+);
+
+typedef struct {
+ Thread_queue_Context Base;
+ Thread_Control *cancel;
+} Thread_Close_context;
+
+/**
+ * @brief Closes the thread.
+ *
+ * Closes the thread object and starts the thread termination sequence. In
+ * case the executing thread is not terminated, then this function waits until
+ * the terminating thread reached the zombie state.
+ */
+void _Thread_Close(
+ Thread_Control *the_thread,
+ Thread_Control *executing,
+ Thread_Close_context *context
+);
+
+RTEMS_INLINE_ROUTINE bool _Thread_Is_ready( const Thread_Control *the_thread )
+{
+ return _States_Is_ready( the_thread->current_state );
+}
+
+States_Control _Thread_Clear_state_locked(
+ Thread_Control *the_thread,
+ States_Control state
+);
+
+/**
+ * @brief Clears the specified thread state.
+ *
+ * In case the previous state is a non-ready state and the next state is the
+ * ready state, then the thread is unblocked by the scheduler.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] state The state to clear. It must not be zero.
+ *
+ * @return The previous state.
+ */
+States_Control _Thread_Clear_state(
+ Thread_Control *the_thread,
+ States_Control state
+);
+
+States_Control _Thread_Set_state_locked(
+ Thread_Control *the_thread,
+ States_Control state
+);
+
+/**
+ * @brief Sets the specified thread state.
+ *
+ * In case the previous state is the ready state, then the thread is blocked by
+ * the scheduler.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] state The state to set. It must not be zero.
+ *
+ * @return The previous state.
+ */
+States_Control _Thread_Set_state(
+ Thread_Control *the_thread,
+ States_Control state
+);
+
+/**
+ * @brief Initializes enviroment for a thread.
+ *
+ * This routine initializes the context of @a the_thread to its
+ * appropriate starting state.
+ *
+ * @param[in] the_thread is the pointer to the thread control block.
+ */
+void _Thread_Load_environment(
+ Thread_Control *the_thread
+);
+
+void _Thread_Entry_adaptor_idle( Thread_Control *executing );
+
+void _Thread_Entry_adaptor_numeric( Thread_Control *executing );
+
+void _Thread_Entry_adaptor_pointer( Thread_Control *executing );
+
+/**
+ * @brief Wrapper function for all threads.
+ *
+ * This routine is the wrapper function for all threads. It is
+ * the starting point for all threads. The user provided thread
+ * entry point is invoked by this routine. Operations
+ * which must be performed immediately before and after the user's
+ * thread executes are found here.
+ *
+ * @note On entry, it is assumed all interrupts are blocked and that this
+ * routine needs to set the initial isr level. This may or may not
+ * actually be needed by the context switch routine and as a result
+ * interrupts may already be at there proper level. Either way,
+ * setting the initial isr level properly here is safe.
+ */
+void _Thread_Handler( void );
+
+RTEMS_INLINE_ROUTINE void _Thread_State_acquire_critical(
+ Thread_Control *the_thread,
+ ISR_lock_Context *lock_context
+)
+{
+ _Thread_queue_Do_acquire_critical( &the_thread->Join_queue, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_State_acquire(
+ Thread_Control *the_thread,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_ISR_disable( lock_context );
+ _Thread_State_acquire_critical( the_thread, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE Thread_Control *_Thread_State_acquire_for_executing(
+ ISR_lock_Context *lock_context
+)
+{
+ Thread_Control *executing;
+
+ _ISR_lock_ISR_disable( lock_context );
+ executing = _Thread_Executing;
+ _Thread_State_acquire_critical( executing, lock_context );
+
+ return executing;
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_State_release_critical(
+ Thread_Control *the_thread,
+ ISR_lock_Context *lock_context
+)
+{
+ _Thread_queue_Do_release_critical( &the_thread->Join_queue, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_State_release(
+ Thread_Control *the_thread,
+ ISR_lock_Context *lock_context
+)
+{
+ _Thread_State_release_critical( the_thread, lock_context );
+ _ISR_lock_ISR_enable( lock_context );
+}
+
+#if defined(RTEMS_DEBUG)
+RTEMS_INLINE_ROUTINE bool _Thread_State_is_owner(
+ const Thread_Control *the_thread
+)
+{
+ return _Thread_queue_Is_lock_owner( &the_thread->Join_queue );
+}
+#endif
+
+/**
+ * @brief Performs the priority actions specified by the thread queue context
+ * along the thread queue path.
+ *
+ * The caller must be the owner of the thread wait lock.
+ *
+ * @param start_of_path The start thread of the thread queue path.
+ * @param queue_context The thread queue context specifying the thread queue
+ * path and initial thread priority actions.
+ *
+ * @see _Thread_queue_Path_acquire_critical().
+ */
+void _Thread_Priority_perform_actions(
+ Thread_Control *start_of_path,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Adds the specified thread priority node to the corresponding thread
+ * priority aggregation.
+ *
+ * The caller must be the owner of the thread wait lock.
+ *
+ * @param the_thread The thread.
+ * @param priority_node The thread priority node to add.
+ * @param queue_context The thread queue context to return an updated set of
+ * threads for _Thread_Priority_update(). The thread queue context must be
+ * initialized via _Thread_queue_Context_clear_priority_updates() before a
+ * call of this function.
+ *
+ * @see _Thread_Wait_acquire().
+ */
+void _Thread_Priority_add(
+ Thread_Control *the_thread,
+ Priority_Node *priority_node,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Removes the specified thread priority node from the corresponding
+ * thread priority aggregation.
+ *
+ * The caller must be the owner of the thread wait lock.
+ *
+ * @param the_thread The thread.
+ * @param priority_node The thread priority node to remove.
+ * @param queue_context The thread queue context to return an updated set of
+ * threads for _Thread_Priority_update(). The thread queue context must be
+ * initialized via _Thread_queue_Context_clear_priority_updates() before a
+ * call of this function.
+ *
+ * @see _Thread_Wait_acquire().
+ */
+void _Thread_Priority_remove(
+ Thread_Control *the_thread,
+ Priority_Node *priority_node,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Propagates a thread priority value change in the specified thread
+ * priority node to the corresponding thread priority aggregation.
+ *
+ * The caller must be the owner of the thread wait lock.
+ *
+ * @param the_thread The thread.
+ * @param priority_node The thread priority node to change.
+ * @param prepend_it In case this is true, then the thread is prepended to
+ * its priority group in its home scheduler instance, otherwise it is
+ * appended.
+ * @param queue_context The thread queue context to return an updated set of
+ * threads for _Thread_Priority_update(). The thread queue context must be
+ * initialized via _Thread_queue_Context_clear_priority_updates() before a
+ * call of this function.
+ *
+ * @see _Thread_Wait_acquire().
+ */
+void _Thread_Priority_changed(
+ Thread_Control *the_thread,
+ Priority_Node *priority_node,
+ bool prepend_it,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Changes the thread priority value of the specified thread priority
+ * node in the corresponding thread priority aggregation.
+ *
+ * The caller must be the owner of the thread wait lock.
+ *
+ * @param the_thread The thread.
+ * @param priority_node The thread priority node to change.
+ * @param new_priority The new thread priority value of the thread priority
+ * node to change.
+ * @param prepend_it In case this is true, then the thread is prepended to
+ * its priority group in its home scheduler instance, otherwise it is
+ * appended.
+ * @param queue_context The thread queue context to return an updated set of
+ * threads for _Thread_Priority_update(). The thread queue context must be
+ * initialized via _Thread_queue_Context_clear_priority_updates() before a
+ * call of this function.
+ *
+ * @see _Thread_Wait_acquire().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Priority_change(
+ Thread_Control *the_thread,
+ Priority_Node *priority_node,
+ Priority_Control new_priority,
+ bool prepend_it,
+ Thread_queue_Context *queue_context
+)
+{
+ _Priority_Node_set_priority( priority_node, new_priority );
+ _Thread_Priority_changed(
+ the_thread,
+ priority_node,
+ prepend_it,
+ queue_context
+ );
+}
+
+/**
+ * @brief Replaces the victim priority node with the replacement priority node
+ * in the corresponding thread priority aggregation.
+ *
+ * The caller must be the owner of the thread wait lock.
+ *
+ * @param the_thread The thread.
+ * @param victim_node The victim thread priority node.
+ * @param replacement_node The replacement thread priority node.
+ *
+ * @see _Thread_Wait_acquire().
+ */
+void _Thread_Priority_replace(
+ Thread_Control *the_thread,
+ Priority_Node *victim_node,
+ Priority_Node *replacement_node
+);
+
+/**
+ * @brief Adds a priority node to the corresponding thread priority
+ * aggregation.
+ *
+ * The caller must be the owner of the thread wait lock.
+ *
+ * @param the_thread The thread.
+ * @param priority_node The thread priority node to add.
+ * @param queue_context The thread queue context to return an updated set of
+ * threads for _Thread_Priority_update(). The thread queue context must be
+ * initialized via _Thread_queue_Context_clear_priority_updates() before a
+ * call of this function.
+ *
+ * @see _Thread_Priority_add(), _Thread_Priority_change(),
+ * _Thread_Priority_changed() and _Thread_Priority_remove().
+ */
+void _Thread_Priority_update( Thread_queue_Context *queue_context );
+
+#if defined(RTEMS_SMP)
+void _Thread_Priority_and_sticky_update(
+ Thread_Control *the_thread,
+ int sticky_level_change
+);
+#endif
+
+/**
+ * @brief Returns true if the left thread priority is less than the right
+ * thread priority in the intuitive sense of priority and false otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Thread_Priority_less_than(
+ Priority_Control left,
+ Priority_Control right
+)
+{
+ return left > right;
+}
+
+/**
+ * @brief Returns the highest priority of the left and right thread priorities
+ * in the intuitive sense of priority.
+ */
+RTEMS_INLINE_ROUTINE Priority_Control _Thread_Priority_highest(
+ Priority_Control left,
+ Priority_Control right
+)
+{
+ return _Thread_Priority_less_than( left, right ) ? right : left;
+}
+
+RTEMS_INLINE_ROUTINE Objects_Information *_Thread_Get_objects_information(
+ Objects_Id id
+)
+{
+ uint32_t the_api;
+
+ the_api = _Objects_Get_API( id );
+
+ if ( !_Objects_Is_api_valid( the_api ) ) {
+ return NULL;
+ }
+
+ /*
+ * Threads are always first class :)
+ *
+ * There is no need to validate the object class of the object identifier,
+ * since this will be done by the object get methods.
+ */
+ return _Objects_Information_table[ the_api ][ 1 ];
+}
+
+/**
+ * @brief Gets a thread by its identifier.
+ *
+ * @see _Objects_Get().
+ */
+Thread_Control *_Thread_Get(
+ Objects_Id id,
+ ISR_lock_Context *lock_context
+);
+
+RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_Get_CPU(
+ const Thread_Control *thread
+)
+{
+#if defined(RTEMS_SMP)
+ return thread->Scheduler.cpu;
+#else
+ (void) thread;
+
+ return _Per_CPU_Get();
+#endif
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Set_CPU(
+ Thread_Control *thread,
+ Per_CPU_Control *cpu
+)
+{
+#if defined(RTEMS_SMP)
+ thread->Scheduler.cpu = cpu;
+#else
+ (void) thread;
+ (void) cpu;
+#endif
+}
+
+/**
+ * This function returns true if the_thread is the currently executing
+ * thread, and false otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE bool _Thread_Is_executing (
+ const Thread_Control *the_thread
+)
+{
+ return ( the_thread == _Thread_Executing );
+}
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief Returns @a true in case the thread executes currently on some
+ * processor in the system, otherwise @a false.
+ *
+ * Do not confuse this with _Thread_Is_executing() which checks only the
+ * current processor.
+ */
+RTEMS_INLINE_ROUTINE bool _Thread_Is_executing_on_a_processor(
+ const Thread_Control *the_thread
+)
+{
+ return _CPU_Context_Get_is_executing( &the_thread->Registers );
+}
+#endif
+
+/**
+ * This function returns true if the_thread is the heir
+ * thread, and false otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE bool _Thread_Is_heir (
+ const Thread_Control *the_thread
+)
+{
+ return ( the_thread == _Thread_Heir );
+}
+
+/**
+ * This routine clears any blocking state for the_thread. It performs
+ * any necessary scheduling operations including the selection of
+ * a new heir thread.
+ */
+
+RTEMS_INLINE_ROUTINE void _Thread_Unblock (
+ Thread_Control *the_thread
+)
+{
+ _Thread_Clear_state( the_thread, STATES_BLOCKED );
+}
+
+/**
+ * This function returns true if the floating point context of
+ * the_thread is currently loaded in the floating point unit, and
+ * false otherwise.
+ */
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+RTEMS_INLINE_ROUTINE bool _Thread_Is_allocated_fp (
+ const Thread_Control *the_thread
+)
+{
+ return ( the_thread == _Thread_Allocated_fp );
+}
+#endif
+
+/*
+ * If the CPU has hardware floating point, then we must address saving
+ * and restoring it as part of the context switch.
+ *
+ * The second conditional compilation section selects the algorithm used
+ * to context switch between floating point tasks. The deferred algorithm
+ * can be significantly better in a system with few floating point tasks
+ * because it reduces the total number of save and restore FP context
+ * operations. However, this algorithm can not be used on all CPUs due
+ * to unpredictable use of FP registers by some compilers for integer
+ * operations.
+ */
+
+RTEMS_INLINE_ROUTINE void _Thread_Save_fp( Thread_Control *executing )
+{
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+#if ( CPU_USE_DEFERRED_FP_SWITCH != TRUE )
+ if ( executing->fp_context != NULL )
+ _Context_Save_fp( &executing->fp_context );
+#endif
+#endif
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Restore_fp( Thread_Control *executing )
+{
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
+ if ( (executing->fp_context != NULL) &&
+ !_Thread_Is_allocated_fp( executing ) ) {
+ if ( _Thread_Allocated_fp != NULL )
+ _Context_Save_fp( &_Thread_Allocated_fp->fp_context );
+ _Context_Restore_fp( &executing->fp_context );
+ _Thread_Allocated_fp = executing;
+ }
+#else
+ if ( executing->fp_context != NULL )
+ _Context_Restore_fp( &executing->fp_context );
+#endif
+#endif
+}
+
+/**
+ * This routine is invoked when the currently loaded floating
+ * point context is now longer associated with an active thread.
+ */
+
+#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
+RTEMS_INLINE_ROUTINE void _Thread_Deallocate_fp( void )
+{
+ _Thread_Allocated_fp = NULL;
+}
+#endif
+
+/**
+ * This function returns true if dispatching is disabled, and false
+ * otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE bool _Thread_Is_context_switch_necessary( void )
+{
+ return ( _Thread_Dispatch_necessary );
+}
+
+/**
+ * This function returns true if the_thread is NULL and false otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE bool _Thread_Is_null (
+ const Thread_Control *the_thread
+)
+{
+ return ( the_thread == NULL );
+}
+
+/**
+ * @brief Is proxy blocking.
+ *
+ * status which indicates that a proxy is blocking, and false otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Thread_Is_proxy_blocking (
+ uint32_t code
+)
+{
+ return (code == THREAD_STATUS_PROXY_BLOCKING);
+}
+
+RTEMS_INLINE_ROUTINE uint32_t _Thread_Get_maximum_internal_threads(void)
+{
+ /* Idle threads */
+ uint32_t maximum_internal_threads =
+ rtems_configuration_get_maximum_processors();
+
+ /* MPCI thread */
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( _System_state_Is_multiprocessing ) {
+ ++maximum_internal_threads;
+ }
+#endif
+
+ return maximum_internal_threads;
+}
+
+RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Internal_allocate( void )
+{
+ return (Thread_Control *)
+ _Objects_Allocate_unprotected( &_Thread_Internal_information.Objects );
+}
+
+/**
+ * @brief Gets the heir of the processor and makes it executing.
+ *
+ * Must be called with interrupts disabled. The thread dispatch necessary
+ * indicator is cleared as a side-effect.
+ *
+ * @return The heir thread.
+ *
+ * @see _Thread_Dispatch(), _Thread_Start_multitasking() and
+ * _Thread_Dispatch_update_heir().
+ */
+RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Get_heir_and_make_it_executing(
+ Per_CPU_Control *cpu_self
+)
+{
+ Thread_Control *heir;
+
+ heir = cpu_self->heir;
+ cpu_self->dispatch_necessary = false;
+ cpu_self->executing = heir;
+
+ return heir;
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Update_CPU_time_used(
+ Thread_Control *the_thread,
+ Per_CPU_Control *cpu
+)
+{
+ Timestamp_Control last;
+ Timestamp_Control ran;
+
+ last = cpu->cpu_usage_timestamp;
+ _TOD_Get_uptime( &cpu->cpu_usage_timestamp );
+ _Timestamp_Subtract( &last, &cpu->cpu_usage_timestamp, &ran );
+ _Timestamp_Add_to( &the_thread->cpu_time_used, &ran );
+}
+
+#if defined( RTEMS_SMP )
+RTEMS_INLINE_ROUTINE void _Thread_Dispatch_update_heir(
+ Per_CPU_Control *cpu_self,
+ Per_CPU_Control *cpu_for_heir,
+ Thread_Control *heir
+)
+{
+ _Thread_Update_CPU_time_used( cpu_for_heir->heir, cpu_for_heir );
+
+ cpu_for_heir->heir = heir;
+
+ _Thread_Dispatch_request( cpu_self, cpu_for_heir );
+}
+#endif
+
+void _Thread_Get_CPU_time_used(
+ Thread_Control *the_thread,
+ Timestamp_Control *cpu_time_used
+);
+
+RTEMS_INLINE_ROUTINE void _Thread_Action_control_initialize(
+ Thread_Action_control *action_control
+)
+{
+ _Chain_Initialize_empty( &action_control->Chain );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Action_initialize(
+ Thread_Action *action
+)
+{
+ _Chain_Set_off_chain( &action->Node );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Add_post_switch_action(
+ Thread_Control *the_thread,
+ Thread_Action *action,
+ Thread_Action_handler handler
+)
+{
+ Per_CPU_Control *cpu_of_thread;
+
+ _Assert( _Thread_State_is_owner( the_thread ) );
+
+ cpu_of_thread = _Thread_Get_CPU( the_thread );
+
+ action->handler = handler;
+
+ _Thread_Dispatch_request( _Per_CPU_Get(), cpu_of_thread );
+
+ _Chain_Append_if_is_off_chain_unprotected(
+ &the_thread->Post_switch_actions.Chain,
+ &action->Node
+ );
+}
+
+RTEMS_INLINE_ROUTINE bool _Thread_Is_life_restarting(
+ Thread_Life_state life_state
+)
+{
+ return ( life_state & THREAD_LIFE_RESTARTING ) != 0;
+}
+
+RTEMS_INLINE_ROUTINE bool _Thread_Is_life_terminating(
+ Thread_Life_state life_state
+)
+{
+ return ( life_state & THREAD_LIFE_TERMINATING ) != 0;
+}
+
+RTEMS_INLINE_ROUTINE bool _Thread_Is_life_change_allowed(
+ Thread_Life_state life_state
+)
+{
+ return ( life_state
+ & ( THREAD_LIFE_PROTECTED | THREAD_LIFE_CHANGE_DEFERRED ) ) == 0;
+}
+
+RTEMS_INLINE_ROUTINE bool _Thread_Is_life_changing(
+ Thread_Life_state life_state
+)
+{
+ return ( life_state
+ & ( THREAD_LIFE_RESTARTING | THREAD_LIFE_TERMINATING ) ) != 0;
+}
+
+RTEMS_INLINE_ROUTINE bool _Thread_Is_joinable(
+ const Thread_Control *the_thread
+)
+{
+ _Assert( _Thread_State_is_owner( the_thread ) );
+ return ( the_thread->Life.state & THREAD_LIFE_DETACHED ) == 0;
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Resource_count_increment(
+ Thread_Control *the_thread
+)
+{
+#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
+ ++the_thread->resource_count;
+#else
+ (void) the_thread;
+#endif
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Resource_count_decrement(
+ Thread_Control *the_thread
+)
+{
+#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
+ --the_thread->resource_count;
+#else
+ (void) the_thread;
+#endif
+}
+
+#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
+/**
+ * @brief Returns true if the thread owns resources, and false otherwise.
+ *
+ * Resources are accounted with the Thread_Control::resource_count resource
+ * counter. This counter is used by mutex objects for example.
+ *
+ * @param[in] the_thread The thread.
+ */
+RTEMS_INLINE_ROUTINE bool _Thread_Owns_resources(
+ const Thread_Control *the_thread
+)
+{
+ return the_thread->resource_count != 0;
+}
+#endif
+
+#if defined(RTEMS_SMP)
+RTEMS_INLINE_ROUTINE void _Thread_Scheduler_cancel_need_for_help(
+ Thread_Control *the_thread,
+ Per_CPU_Control *cpu
+)
+{
+ _Per_CPU_Acquire( cpu );
+
+ if ( !_Chain_Is_node_off_chain( &the_thread->Scheduler.Help_node ) ) {
+ _Chain_Extract_unprotected( &the_thread->Scheduler.Help_node );
+ _Chain_Set_off_chain( &the_thread->Scheduler.Help_node );
+ }
+
+ _Per_CPU_Release( cpu );
+}
+#endif
+
+RTEMS_INLINE_ROUTINE const Scheduler_Control *_Thread_Scheduler_get_home(
+ const Thread_Control *the_thread
+)
+{
+#if defined(RTEMS_SMP)
+ return the_thread->Scheduler.home;
+#else
+ (void) the_thread;
+ return &_Scheduler_Table[ 0 ];
+#endif
+}
+
+RTEMS_INLINE_ROUTINE Scheduler_Node *_Thread_Scheduler_get_home_node(
+ const Thread_Control *the_thread
+)
+{
+#if defined(RTEMS_SMP)
+ _Assert( !_Chain_Is_empty( &the_thread->Scheduler.Wait_nodes ) );
+ return SCHEDULER_NODE_OF_THREAD_WAIT_NODE(
+ _Chain_First( &the_thread->Scheduler.Wait_nodes )
+ );
+#else
+ return the_thread->Scheduler.nodes;
+#endif
+}
+
+RTEMS_INLINE_ROUTINE Scheduler_Node *_Thread_Scheduler_get_node_by_index(
+ const Thread_Control *the_thread,
+ size_t scheduler_index
+)
+{
+#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
+}
+
+#if defined(RTEMS_SMP)
+RTEMS_INLINE_ROUTINE void _Thread_Scheduler_acquire_critical(
+ Thread_Control *the_thread,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Acquire( &the_thread->Scheduler.Lock, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Scheduler_release_critical(
+ Thread_Control *the_thread,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Release( &the_thread->Scheduler.Lock, lock_context );
+}
+
+#if defined(RTEMS_SMP)
+void _Thread_Scheduler_process_requests( Thread_Control *the_thread );
+#endif
+
+RTEMS_INLINE_ROUTINE void _Thread_Scheduler_add_request(
+ Thread_Control *the_thread,
+ Scheduler_Node *scheduler_node,
+ Scheduler_Node_request request
+)
+{
+ ISR_lock_Context lock_context;
+ Scheduler_Node_request current_request;
+
+ _Thread_Scheduler_acquire_critical( the_thread, &lock_context );
+
+ current_request = scheduler_node->Thread.request;
+
+ if ( current_request == SCHEDULER_NODE_REQUEST_NOT_PENDING ) {
+ _Assert(
+ request == SCHEDULER_NODE_REQUEST_ADD
+ || request == SCHEDULER_NODE_REQUEST_REMOVE
+ );
+ _Assert( scheduler_node->Thread.next_request == NULL );
+ scheduler_node->Thread.next_request = the_thread->Scheduler.requests;
+ the_thread->Scheduler.requests = scheduler_node;
+ } else if ( current_request != SCHEDULER_NODE_REQUEST_NOTHING ) {
+ _Assert(
+ ( current_request == SCHEDULER_NODE_REQUEST_ADD
+ && request == SCHEDULER_NODE_REQUEST_REMOVE )
+ || ( current_request == SCHEDULER_NODE_REQUEST_REMOVE
+ && request == SCHEDULER_NODE_REQUEST_ADD )
+ );
+ request = SCHEDULER_NODE_REQUEST_NOTHING;
+ }
+
+ scheduler_node->Thread.request = request;
+
+ _Thread_Scheduler_release_critical( the_thread, &lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Scheduler_add_wait_node(
+ Thread_Control *the_thread,
+ Scheduler_Node *scheduler_node
+)
+{
+ _Chain_Append_unprotected(
+ &the_thread->Scheduler.Wait_nodes,
+ &scheduler_node->Thread.Wait_node
+ );
+ _Thread_Scheduler_add_request(
+ the_thread,
+ scheduler_node,
+ SCHEDULER_NODE_REQUEST_ADD
+ );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Scheduler_remove_wait_node(
+ Thread_Control *the_thread,
+ Scheduler_Node *scheduler_node
+)
+{
+ _Chain_Extract_unprotected( &scheduler_node->Thread.Wait_node );
+ _Thread_Scheduler_add_request(
+ the_thread,
+ scheduler_node,
+ SCHEDULER_NODE_REQUEST_REMOVE
+ );
+}
+#endif
+
+/**
+ * @brief Returns the priority of the thread.
+ *
+ * Returns the user API and thread wait information relevant thread priority.
+ * This includes temporary thread priority adjustments due to locking
+ * protocols, a job release or the POSIX sporadic server for example.
+ *
+ * @return The priority of the thread.
+ */
+RTEMS_INLINE_ROUTINE Priority_Control _Thread_Get_priority(
+ const Thread_Control *the_thread
+)
+{
+ Scheduler_Node *scheduler_node;
+
+ scheduler_node = _Thread_Scheduler_get_home_node( the_thread );
+ return _Priority_Get_priority( &scheduler_node->Wait.Priority );
+}
+
+/**
+ * @brief Acquires the thread wait default lock inside a critical section
+ * (interrupts disabled).
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] lock_context The lock context used for the corresponding lock
+ * release.
+ *
+ * @see _Thread_Wait_release_default_critical().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire_default_critical(
+ Thread_Control *the_thread,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Acquire( &the_thread->Wait.Lock.Default, lock_context );
+}
+
+/**
+ * @brief Acquires the thread wait default lock and returns the executing
+ * thread.
+ *
+ * @param[in] lock_context The lock context used for the corresponding lock
+ * release.
+ *
+ * @return The executing thread.
+ *
+ * @see _Thread_Wait_release_default().
+ */
+RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Wait_acquire_default_for_executing(
+ ISR_lock_Context *lock_context
+)
+{
+ Thread_Control *executing;
+
+ _ISR_lock_ISR_disable( lock_context );
+ executing = _Thread_Executing;
+ _Thread_Wait_acquire_default_critical( executing, lock_context );
+
+ return executing;
+}
+
+/**
+ * @brief Acquires the thread wait default lock and disables interrupts.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] lock_context The lock context used for the corresponding lock
+ * release.
+ *
+ * @see _Thread_Wait_release_default().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire_default(
+ Thread_Control *the_thread,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_ISR_disable( lock_context );
+ _Thread_Wait_acquire_default_critical( the_thread, lock_context );
+}
+
+/**
+ * @brief Releases the thread wait default lock inside a critical section
+ * (interrupts disabled).
+ *
+ * The previous interrupt status is not restored.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] lock_context The lock context used for the corresponding lock
+ * acquire.
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_release_default_critical(
+ Thread_Control *the_thread,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Release( &the_thread->Wait.Lock.Default, lock_context );
+}
+
+/**
+ * @brief Releases the thread wait default lock and restores the previous
+ * interrupt status.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] lock_context The lock context used for the corresponding lock
+ * acquire.
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_release_default(
+ Thread_Control *the_thread,
+ ISR_lock_Context *lock_context
+)
+{
+ _Thread_Wait_release_default_critical( the_thread, lock_context );
+ _ISR_lock_ISR_enable( lock_context );
+}
+
+#if defined(RTEMS_SMP)
+#define THREAD_QUEUE_CONTEXT_OF_REQUEST( node ) \
+ RTEMS_CONTAINER_OF( node, Thread_queue_Context, Lock_context.Wait.Gate.Node )
+
+RTEMS_INLINE_ROUTINE void _Thread_Wait_remove_request_locked(
+ Thread_Control *the_thread,
+ Thread_queue_Lock_context *queue_lock_context
+)
+{
+ Chain_Node *first;
+
+ _Chain_Extract_unprotected( &queue_lock_context->Wait.Gate.Node );
+ first = _Chain_First( &the_thread->Wait.Lock.Pending_requests );
+
+ if ( first != _Chain_Tail( &the_thread->Wait.Lock.Pending_requests ) ) {
+ _Thread_queue_Gate_open( (Thread_queue_Gate *) first );
+ }
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire_queue_critical(
+ Thread_queue_Queue *queue,
+ Thread_queue_Lock_context *queue_lock_context
+)
+{
+ _Thread_queue_Queue_acquire_critical(
+ queue,
+ &_Thread_Executing->Potpourri_stats,
+ &queue_lock_context->Lock_context
+ );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Wait_release_queue_critical(
+ Thread_queue_Queue *queue,
+ Thread_queue_Lock_context *queue_lock_context
+)
+{
+ _Thread_queue_Queue_release_critical(
+ queue,
+ &queue_lock_context->Lock_context
+ );
+}
+#endif
+
+/**
+ * @brief Acquires the thread wait lock inside a critical section (interrupts
+ * disabled).
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] queue_context The thread queue context for the corresponding
+ * _Thread_Wait_release_critical().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire_critical(
+ Thread_Control *the_thread,
+ Thread_queue_Context *queue_context
+)
+{
+#if defined(RTEMS_SMP)
+ Thread_queue_Queue *queue;
+
+ _Thread_Wait_acquire_default_critical(
+ the_thread,
+ &queue_context->Lock_context.Lock_context
+ );
+
+ queue = the_thread->Wait.queue;
+ queue_context->Lock_context.Wait.queue = queue;
+
+ if ( queue != NULL ) {
+ _Thread_queue_Gate_add(
+ &the_thread->Wait.Lock.Pending_requests,
+ &queue_context->Lock_context.Wait.Gate
+ );
+ _Thread_Wait_release_default_critical(
+ the_thread,
+ &queue_context->Lock_context.Lock_context
+ );
+ _Thread_Wait_acquire_queue_critical( queue, &queue_context->Lock_context );
+
+ if ( queue_context->Lock_context.Wait.queue == NULL ) {
+ _Thread_Wait_release_queue_critical(
+ queue,
+ &queue_context->Lock_context
+ );
+ _Thread_Wait_acquire_default_critical(
+ the_thread,
+ &queue_context->Lock_context.Lock_context
+ );
+ _Thread_Wait_remove_request_locked(
+ the_thread,
+ &queue_context->Lock_context
+ );
+ _Assert( the_thread->Wait.queue == NULL );
+ }
+ }
+#else
+ (void) the_thread;
+ (void) queue_context;
+#endif
+}
+
+/**
+ * @brief Acquires the thread wait default lock and disables interrupts.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] queue_context The thread queue context for the corresponding
+ * _Thread_Wait_release().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire(
+ Thread_Control *the_thread,
+ Thread_queue_Context *queue_context
+)
+{
+ _ISR_lock_ISR_disable( &queue_context->Lock_context.Lock_context );
+ _Thread_Wait_acquire_critical( the_thread, queue_context );
+}
+
+/**
+ * @brief Releases the thread wait lock inside a critical section (interrupts
+ * disabled).
+ *
+ * The previous interrupt status is not restored.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] queue_context The thread queue context used for corresponding
+ * _Thread_Wait_acquire_critical().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_release_critical(
+ Thread_Control *the_thread,
+ Thread_queue_Context *queue_context
+)
+{
+#if defined(RTEMS_SMP)
+ Thread_queue_Queue *queue;
+
+ queue = queue_context->Lock_context.Wait.queue;
+
+ if ( queue != NULL ) {
+ _Thread_Wait_release_queue_critical(
+ queue, &queue_context->Lock_context
+ );
+ _Thread_Wait_acquire_default_critical(
+ the_thread,
+ &queue_context->Lock_context.Lock_context
+ );
+ _Thread_Wait_remove_request_locked(
+ the_thread,
+ &queue_context->Lock_context
+ );
+ }
+
+ _Thread_Wait_release_default_critical(
+ the_thread,
+ &queue_context->Lock_context.Lock_context
+ );
+#else
+ (void) the_thread;
+ (void) queue_context;
+#endif
+}
+
+/**
+ * @brief Releases the thread wait lock and restores the previous interrupt
+ * status.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] queue_context The thread queue context used for corresponding
+ * _Thread_Wait_acquire().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_release(
+ Thread_Control *the_thread,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_Wait_release_critical( the_thread, queue_context );
+ _ISR_lock_ISR_enable( &queue_context->Lock_context.Lock_context );
+}
+
+/**
+ * @brief Claims the thread wait queue.
+ *
+ * The caller must not be the owner of the default thread wait lock. The
+ * caller must be the owner of the corresponding thread queue lock. The
+ * registration of the corresponding thread queue operations is deferred and
+ * done after the deadlock detection. This is crucial to support timeouts on
+ * SMP configurations.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] queue The new thread queue.
+ *
+ * @see _Thread_Wait_claim_finalize() and _Thread_Wait_restore_default().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_claim(
+ Thread_Control *the_thread,
+ Thread_queue_Queue *queue
+)
+{
+ ISR_lock_Context lock_context;
+
+ _Thread_Wait_acquire_default_critical( the_thread, &lock_context );
+
+ _Assert( the_thread->Wait.queue == NULL );
+
+#if defined(RTEMS_SMP)
+ _Chain_Initialize_empty( &the_thread->Wait.Lock.Pending_requests );
+ _Chain_Initialize_node( &the_thread->Wait.Lock.Tranquilizer.Node );
+ _Thread_queue_Gate_close( &the_thread->Wait.Lock.Tranquilizer );
+#endif
+
+ the_thread->Wait.queue = queue;
+
+ _Thread_Wait_release_default_critical( the_thread, &lock_context );
+}
+
+/**
+ * @brief Finalizes the thread wait queue claim via registration of the
+ * corresponding thread queue operations.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] operations The corresponding thread queue operations.
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_claim_finalize(
+ Thread_Control *the_thread,
+ const Thread_queue_Operations *operations
+)
+{
+ the_thread->Wait.operations = operations;
+}
+
+/**
+ * @brief Removes a thread wait lock request.
+ *
+ * On SMP configurations, removes a thread wait lock request.
+ *
+ * On other configurations, this function does nothing.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] queue_lock_context The thread queue lock context used for
+ * corresponding _Thread_Wait_acquire().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_remove_request(
+ Thread_Control *the_thread,
+ Thread_queue_Lock_context *queue_lock_context
+)
+{
+#if defined(RTEMS_SMP)
+ ISR_lock_Context lock_context;
+
+ _Thread_Wait_acquire_default( the_thread, &lock_context );
+ _Thread_Wait_remove_request_locked( the_thread, queue_lock_context );
+ _Thread_Wait_release_default( the_thread, &lock_context );
+#else
+ (void) the_thread;
+ (void) queue_lock_context;
+#endif
+}
+
+/**
+ * @brief Restores the default thread wait queue and operations.
+ *
+ * The caller must be the owner of the current thread wait queue lock.
+ *
+ * On SMP configurations, the pending requests are updated to use the stale
+ * thread queue operations.
+ *
+ * @param[in] the_thread The thread.
+ *
+ * @see _Thread_Wait_claim().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_restore_default(
+ Thread_Control *the_thread
+)
+{
+#if defined(RTEMS_SMP)
+ ISR_lock_Context lock_context;
+ Chain_Node *node;
+ const Chain_Node *tail;
+
+ _Thread_Wait_acquire_default_critical( the_thread, &lock_context );
+
+ node = _Chain_First( &the_thread->Wait.Lock.Pending_requests );
+ tail = _Chain_Immutable_tail( &the_thread->Wait.Lock.Pending_requests );
+
+ if ( node != tail ) {
+ do {
+ Thread_queue_Context *queue_context;
+
+ queue_context = THREAD_QUEUE_CONTEXT_OF_REQUEST( node );
+ queue_context->Lock_context.Wait.queue = NULL;
+
+ node = _Chain_Next( node );
+ } while ( node != tail );
+
+ _Thread_queue_Gate_add(
+ &the_thread->Wait.Lock.Pending_requests,
+ &the_thread->Wait.Lock.Tranquilizer
+ );
+ } else {
+ _Thread_queue_Gate_open( &the_thread->Wait.Lock.Tranquilizer );
+ }
+#endif
+
+ the_thread->Wait.queue = NULL;
+ the_thread->Wait.operations = &_Thread_queue_Operations_default;
+
+#if defined(RTEMS_SMP)
+ _Thread_Wait_release_default_critical( the_thread, &lock_context );
+#endif
+}
+
+/**
+ * @brief Tranquilizes the thread after a wait on a thread queue.
+ *
+ * After the violent blocking procedure this function makes the thread calm and
+ * peaceful again so that it can carry out its normal work.
+ *
+ * On SMP configurations, ensures that all pending thread wait lock requests
+ * completed before the thread is able to begin a new thread wait procedure.
+ *
+ * On other configurations, this function does nothing.
+ *
+ * It must be called after a _Thread_Wait_claim() exactly once
+ * - after the corresponding thread queue lock was released, and
+ * - the default wait state is restored or some other processor is about to do
+ * this.
+ *
+ * @param[in] the_thread The thread.
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_tranquilize(
+ Thread_Control *the_thread
+)
+{
+#if defined(RTEMS_SMP)
+ _Thread_queue_Gate_wait( &the_thread->Wait.Lock.Tranquilizer );
+#else
+ (void) the_thread;
+#endif
+}
+
+/**
+ * @brief Cancels a thread wait on a thread queue.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] queue_context The thread queue context used for corresponding
+ * _Thread_Wait_acquire().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Wait_cancel(
+ Thread_Control *the_thread,
+ Thread_queue_Context *queue_context
+)
+{
+ Thread_queue_Queue *queue;
+
+ queue = the_thread->Wait.queue;
+
+#if defined(RTEMS_SMP)
+ if ( queue != NULL ) {
+ _Assert( queue_context->Lock_context.Wait.queue == queue );
+#endif
+
+ ( *the_thread->Wait.operations->extract )(
+ queue,
+ the_thread,
+ queue_context
+ );
+ _Thread_Wait_restore_default( the_thread );
+
+#if defined(RTEMS_SMP)
+ _Assert( queue_context->Lock_context.Wait.queue == NULL );
+ queue_context->Lock_context.Wait.queue = queue;
+ }
+#endif
+}
+
+/**
+ * @brief The initial thread wait flags value set by _Thread_Initialize().
+ */
+#define THREAD_WAIT_FLAGS_INITIAL 0x0U
+
+/**
+ * @brief Mask to get the thread wait state flags.
+ */
+#define THREAD_WAIT_STATE_MASK 0xffU
+
+/**
+ * @brief Indicates that the thread begins with the blocking operation.
+ *
+ * A blocking operation consists of an optional watchdog initialization and the
+ * setting of the appropriate thread blocking state with the corresponding
+ * scheduler block operation.
+ */
+#define THREAD_WAIT_STATE_INTEND_TO_BLOCK 0x1U
+
+/**
+ * @brief Indicates that the thread completed the blocking operation.
+ */
+#define THREAD_WAIT_STATE_BLOCKED 0x2U
+
+/**
+ * @brief Indicates that a condition to end the thread wait occurred.
+ *
+ * This could be a timeout, a signal, an event or a resource availability.
+ */
+#define THREAD_WAIT_STATE_READY_AGAIN 0x4U
+
+/**
+ * @brief Mask to get the thread wait class flags.
+ */
+#define THREAD_WAIT_CLASS_MASK 0xff00U
+
+/**
+ * @brief Indicates that the thread waits for an event.
+ */
+#define THREAD_WAIT_CLASS_EVENT 0x100U
+
+/**
+ * @brief Indicates that the thread waits for a system event.
+ */
+#define THREAD_WAIT_CLASS_SYSTEM_EVENT 0x200U
+
+/**
+ * @brief Indicates that the thread waits for an object.
+ */
+#define THREAD_WAIT_CLASS_OBJECT 0x400U
+
+/**
+ * @brief Indicates that the thread waits for a period.
+ */
+#define THREAD_WAIT_CLASS_PERIOD 0x800U
+
+RTEMS_INLINE_ROUTINE void _Thread_Wait_flags_set(
+ Thread_Control *the_thread,
+ Thread_Wait_flags flags
+)
+{
+#if defined(RTEMS_SMP)
+ _Atomic_Store_uint( &the_thread->Wait.flags, flags, ATOMIC_ORDER_RELAXED );
+#else
+ the_thread->Wait.flags = flags;
+#endif
+}
+
+RTEMS_INLINE_ROUTINE Thread_Wait_flags _Thread_Wait_flags_get(
+ const Thread_Control *the_thread
+)
+{
+#if defined(RTEMS_SMP)
+ return _Atomic_Load_uint( &the_thread->Wait.flags, ATOMIC_ORDER_RELAXED );
+#else
+ return the_thread->Wait.flags;
+#endif
+}
+
+RTEMS_INLINE_ROUTINE Thread_Wait_flags _Thread_Wait_flags_get_acquire(
+ const Thread_Control *the_thread
+)
+{
+#if defined(RTEMS_SMP)
+ return _Atomic_Load_uint( &the_thread->Wait.flags, ATOMIC_ORDER_ACQUIRE );
+#else
+ return the_thread->Wait.flags;
+#endif
+}
+
+/**
+ * @brief Tries to change the thread wait flags with release semantics in case
+ * of success.
+ *
+ * Must be called inside a critical section (interrupts disabled).
+ *
+ * In case the wait flags are equal to the expected wait flags, then the wait
+ * flags are set to the desired wait flags.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] expected_flags The expected wait flags.
+ * @param[in] desired_flags The desired wait flags.
+ *
+ * @retval true The wait flags were equal to the expected wait flags.
+ * @retval false Otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Thread_Wait_flags_try_change_release(
+ Thread_Control *the_thread,
+ Thread_Wait_flags expected_flags,
+ Thread_Wait_flags desired_flags
+)
+{
+ _Assert( _ISR_Get_level() != 0 );
+
+#if defined(RTEMS_SMP)
+ return _Atomic_Compare_exchange_uint(
+ &the_thread->Wait.flags,
+ &expected_flags,
+ desired_flags,
+ ATOMIC_ORDER_RELEASE,
+ ATOMIC_ORDER_RELAXED
+ );
+#else
+ bool success = ( the_thread->Wait.flags == expected_flags );
+
+ if ( success ) {
+ the_thread->Wait.flags = desired_flags;
+ }
+
+ return success;
+#endif
+}
+
+/**
+ * @brief Tries to change the thread wait flags with acquire semantics.
+ *
+ * In case the wait flags are equal to the expected wait flags, then the wait
+ * flags are set to the desired wait flags.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] expected_flags The expected wait flags.
+ * @param[in] desired_flags The desired wait flags.
+ *
+ * @retval true The wait flags were equal to the expected wait flags.
+ * @retval false Otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _Thread_Wait_flags_try_change_acquire(
+ Thread_Control *the_thread,
+ Thread_Wait_flags expected_flags,
+ Thread_Wait_flags desired_flags
+)
+{
+ bool success;
+#if defined(RTEMS_SMP)
+ return _Atomic_Compare_exchange_uint(
+ &the_thread->Wait.flags,
+ &expected_flags,
+ desired_flags,
+ ATOMIC_ORDER_ACQUIRE,
+ ATOMIC_ORDER_ACQUIRE
+ );
+#else
+ ISR_Level level;
+
+ _ISR_Local_disable( level );
+
+ success = _Thread_Wait_flags_try_change_release(
+ the_thread,
+ expected_flags,
+ desired_flags
+ );
+
+ _ISR_Local_enable( level );
+#endif
+
+ return success;
+}
+
+/**
+ * @brief Returns the object identifier of the object containing the current
+ * thread wait queue.
+ *
+ * This function may be used for debug and system information purposes. The
+ * caller must be the owner of the thread lock.
+ *
+ * @retval 0 The thread waits on no thread queue currently, the thread wait
+ * queue is not contained in an object, or the current thread state provides
+ * insufficient information, e.g. the thread is in the middle of a blocking
+ * operation.
+ * @retval other The object identifier of the object containing the thread wait
+ * queue.
+ */
+Objects_Id _Thread_Wait_get_id( const Thread_Control *the_thread );
+
+RTEMS_INLINE_ROUTINE Status_Control _Thread_Wait_get_status(
+ const Thread_Control *the_thread
+)
+{
+ return (Status_Control) the_thread->Wait.return_code;
+}
+
+/**
+ * @brief Cancels a blocking operation so that the thread can continue its
+ * execution.
+ *
+ * In case this function actually cancelled the blocking operation, then the
+ * thread wait return code is set to the specified status.
+ *
+ * A specialization of this function is _Thread_Timeout().
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] status The thread wait status.
+ */
+void _Thread_Continue( Thread_Control *the_thread, Status_Control status );
+
+/**
+ * @brief General purpose thread wait timeout.
+ *
+ * @param[in] the_watchdog The thread timer watchdog.
+ */
+void _Thread_Timeout( Watchdog_Control *the_watchdog );
+
+RTEMS_INLINE_ROUTINE void _Thread_Timer_initialize(
+ Thread_Timer_information *timer,
+ Per_CPU_Control *cpu
+)
+{
+ _ISR_lock_Initialize( &timer->Lock, "Thread Timer" );
+ timer->header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ];
+ _Watchdog_Preinitialize( &timer->Watchdog, cpu );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Add_timeout_ticks(
+ Thread_Control *the_thread,
+ Per_CPU_Control *cpu,
+ Watchdog_Interval ticks
+)
+{
+ ISR_lock_Context lock_context;
+
+ _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
+
+ the_thread->Timer.header =
+ &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ];
+ the_thread->Timer.Watchdog.routine = _Thread_Timeout;
+ _Watchdog_Per_CPU_insert_ticks( &the_thread->Timer.Watchdog, cpu, ticks );
+
+ _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Timer_insert_realtime(
+ Thread_Control *the_thread,
+ Per_CPU_Control *cpu,
+ Watchdog_Service_routine_entry routine,
+ uint64_t expire
+)
+{
+ ISR_lock_Context lock_context;
+
+ _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
+
+ the_thread->Timer.header =
+ &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ];
+ the_thread->Timer.Watchdog.routine = routine;
+ _Watchdog_Per_CPU_insert_realtime( &the_thread->Timer.Watchdog, cpu, expire );
+
+ _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Timer_remove( Thread_Control *the_thread )
+{
+ ISR_lock_Context lock_context;
+
+ _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
+
+ _Watchdog_Per_CPU_remove(
+ &the_thread->Timer.Watchdog,
+#if defined(RTEMS_SMP)
+ the_thread->Timer.Watchdog.cpu,
+#else
+ _Per_CPU_Get(),
+#endif
+ the_thread->Timer.header
+ );
+
+ _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_Remove_timer_and_unblock(
+ Thread_Control *the_thread,
+ Thread_queue_Queue *queue
+)
+{
+ _Thread_Wait_tranquilize( the_thread );
+ _Thread_Timer_remove( the_thread );
+
+#if defined(RTEMS_MULTIPROCESSING)
+ if ( _Objects_Is_local_id( the_thread->Object.id ) ) {
+ _Thread_Unblock( the_thread );
+ } else {
+ _Thread_queue_Unblock_proxy( queue, the_thread );
+ }
+#else
+ (void) queue;
+ _Thread_Unblock( the_thread );
+#endif
+}
+
+Status_Control _Thread_Set_name(
+ Thread_Control *the_thread,
+ const char *name
+);
+
+size_t _Thread_Get_name(
+ const Thread_Control *the_thread,
+ char *buffer,
+ size_t buffer_size
+);
+
+/** @}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(RTEMS_MULTIPROCESSING)
+#include <rtems/score/threadmp.h>
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/threadmp.h b/cpukit/include/rtems/score/threadmp.h
new file mode 100644
index 0000000000..9cde35b649
--- /dev/null
+++ b/cpukit/include/rtems/score/threadmp.h
@@ -0,0 +1,113 @@
+/**
+ * @file rtems/score/threadmp.h
+ *
+ * @brief Multiprocessing Portion of the Thread Package
+ *
+ * This include file contains the specification for all routines
+ * and data specific to the multiprocessing portion of the thread package.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_THREADMP_H
+#define _RTEMS_SCORE_THREADMP_H
+
+#ifndef _RTEMS_SCORE_THREADIMPL_H
+# error "Never use <rtems/score/threadmp.h> directly; include <rtems/score/threadimpl.h> instead."
+#endif
+
+#include <rtems/score/mpciimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreThreadMP Thread Handler Multiprocessing Support
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality which is related to managing
+ * threads in a multiprocessor system configuration. This handler must
+ * manage proxies which represent remote threads blocking on local
+ * operations.
+ */
+/**@{*/
+
+/**
+ * @brief Initialize MP thread handler.
+ *
+ * This routine initializes the multiprocessing portion of the Thread Handler.
+ */
+void _Thread_MP_Handler_initialization (
+ uint32_t maximum_proxies
+);
+
+/**
+ * @brief Allocate a MP proxy control block from
+ * the inactive chain of free proxy control blocks.
+ *
+ * This allocates a proxy control block from
+ * the inactive chain of free proxy control blocks.
+ *
+ * @note This function returns a thread control pointer
+ * because proxies are substitutes for remote threads.
+ */
+Thread_Control *_Thread_MP_Allocate_proxy (
+ States_Control the_state
+);
+
+/**
+ * @brief Removes the MP proxy control block for the specified
+ * id from the active chain of proxy control blocks.
+ *
+ * This function removes the proxy control block for the specified
+ * id from the active red-black tree of proxy control blocks.
+ */
+Thread_Control *_Thread_MP_Find_proxy (
+ Objects_Id the_id
+);
+
+/**
+ * This function returns true if the thread in question is the
+ * multiprocessing receive thread.
+ *
+ * @note This is a macro to avoid needing a prototype for
+ * _MPCI_Receive_server_tcb until it is used.
+ */
+#define _Thread_MP_Is_receive(_the_thread) \
+ ((_the_thread) == _MPCI_Receive_server_tcb)
+
+/**
+ * This routine frees a proxy control block to the
+ * inactive chain of free proxy control blocks.
+ */
+void _Thread_MP_Free_proxy( Thread_Control *the_thread );
+
+RTEMS_INLINE_ROUTINE bool _Thread_MP_Is_remote( Objects_Id id )
+{
+ Objects_Information *information;
+
+ information = _Thread_Get_objects_information( id );
+ if ( information == NULL ) {
+ return false;
+ }
+
+ return _Objects_MP_Is_remote( id, information );
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/threadq.h b/cpukit/include/rtems/score/threadq.h
new file mode 100644
index 0000000000..3e618bf5af
--- /dev/null
+++ b/cpukit/include/rtems/score/threadq.h
@@ -0,0 +1,595 @@
+/**
+ * @file
+ *
+ * @brief Constants and Structures Needed to Declare a Thread Queue
+ *
+ * This include file contains all the constants and structures
+ * needed to declare a thread queue.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_THREADQ_H
+#define _RTEMS_SCORE_THREADQ_H
+
+#include <rtems/score/chain.h>
+#include <rtems/score/isrlock.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/rbtree.h>
+#include <rtems/score/states.h>
+#include <rtems/score/watchdog.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Scheduler_Node;
+
+/**
+ * @defgroup ScoreThreadQueue Thread Queue Handler
+ *
+ * @ingroup Score
+ *
+ * This handler provides the capability to have threads block in
+ * ordered sets. The sets may be ordered using the FIFO or priority
+ * discipline.
+ */
+/**@{*/
+
+typedef struct _Thread_Control Thread_Control;
+
+typedef struct Thread_queue_Context Thread_queue_Context;
+
+typedef struct Thread_queue_Queue Thread_queue_Queue;
+
+typedef struct Thread_queue_Operations Thread_queue_Operations;
+
+/**
+ * @brief Thread queue enqueue callout.
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] the_thread The thread to enqueue.
+ * @param[in] cpu_self The current processor.
+ * @param[in] queue_context The thread queue context of the lock acquire.
+ *
+ * @see _Thread_queue_Context_set_enqueue_callout().
+ */
+typedef void ( *Thread_queue_Enqueue_callout )(
+ Thread_queue_Queue *queue,
+ Thread_Control *the_thread,
+ struct Per_CPU_Control *cpu_self,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Thread queue deadlock callout.
+ *
+ * @param the_thread The thread that detected the deadlock.
+ *
+ * @see _Thread_queue_Context_set_deadlock_callout().
+ */
+typedef void ( *Thread_queue_Deadlock_callout )(
+ Thread_Control *the_thread
+);
+
+#if defined(RTEMS_MULTIPROCESSING)
+/**
+ * @brief Multiprocessing (MP) support callout for thread queue operations.
+ *
+ * @param the_proxy The thread proxy of the thread queue operation. A thread
+ * control is actually a thread proxy if and only if
+ * _Objects_Is_local_id( the_proxy->Object.id ) is false.
+ * @param mp_id Object identifier of the object containing the thread queue.
+ *
+ * @see _Thread_queue_Context_set_MP_callout().
+ */
+typedef void ( *Thread_queue_MP_callout )(
+ Thread_Control *the_proxy,
+ Objects_Id mp_id
+);
+#endif
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief The thread queue gate is an SMP synchronization means.
+ *
+ * The gates are added to a list of requests. A busy wait is performed to make
+ * sure that preceding requests are carried out. Each predecessor notifies its
+ * successor about on request completion.
+ *
+ * @see _Thread_queue_Gate_add(), _Thread_queue_Gate_wait(), and
+ * _Thread_queue_Gate_open().
+ */
+typedef struct {
+ Chain_Node Node;
+
+ Atomic_Uint go_ahead;
+} Thread_queue_Gate;
+#endif
+
+typedef struct {
+ /**
+ * @brief The lock context for the thread queue acquire and release
+ * operations.
+ */
+ ISR_lock_Context Lock_context;
+
+#if defined(RTEMS_SMP)
+ /**
+ * @brief Data to support thread queue enqueue operations.
+ */
+ struct {
+ /**
+ * @brief Gate to synchronize thread wait lock requests.
+ *
+ * @see _Thread_Wait_acquire_critical() and _Thread_Wait_tranquilize().
+ */
+ Thread_queue_Gate Gate;
+
+ /**
+ * @brief The thread queue in case the thread is blocked on a thread queue.
+ */
+ Thread_queue_Queue *queue;
+ } Wait;
+#endif
+} Thread_queue_Lock_context;
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief A thread queue link from one thread to another specified by the
+ * thread queue owner and thread wait queue relationships.
+ */
+typedef struct {
+ /**
+ * @brief Node to register this link in the global thread queue links lookup
+ * tree.
+ */
+ RBTree_Node Registry_node;
+
+ /**
+ * @brief The source thread queue determined by the thread queue owner.
+ */
+ Thread_queue_Queue *source;
+
+ /**
+ * @brief The target thread queue determined by the thread wait queue of the
+ * source owner.
+ */
+ Thread_queue_Queue *target;
+
+ /**
+ * @brief Node to add this link to a thread queue path.
+ */
+ Chain_Node Path_node;
+
+ /**
+ * @brief The owner of this thread queue link.
+ */
+ Thread_Control *owner;
+
+ /**
+ * @brief The queue lock context used to acquire the thread wait lock of the
+ * owner.
+ */
+ Thread_queue_Lock_context Lock_context;
+} Thread_queue_Link;
+#endif
+
+/**
+ * @brief Thread queue context for the thread queue methods.
+ *
+ * @see _Thread_queue_Context_initialize().
+ */
+struct Thread_queue_Context {
+ /**
+ * @brief The lock context for the thread queue acquire and release
+ * operations.
+ */
+ Thread_queue_Lock_context Lock_context;
+
+ /**
+ * @brief The thread state for _Thread_queue_Enqueue().
+ */
+ States_Control thread_state;
+
+ /**
+ * @brief The enqueue callout for _Thread_queue_Enqueue().
+ *
+ * The callout is invoked after the release of the thread queue lock with
+ * thread dispatching disabled. Afterwards the thread is blocked. This
+ * callout must be used to install the thread watchdog for timeout handling.
+ *
+ * @see _Thread_queue_Enqueue_do_nothing_extra().
+ * _Thread_queue_Add_timeout_ticks(), and
+ * _Thread_queue_Add_timeout_realtime_timespec().
+ */
+ Thread_queue_Enqueue_callout enqueue_callout;
+
+ /**
+ * @brief Interval to wait.
+ *
+ * May be used by the enqueue callout to register a timeout handler.
+ */
+ union {
+ /**
+ * @brief The timeout in ticks.
+ */
+ Watchdog_Interval ticks;
+
+ /**
+ * @brief The timeout argument, e.g. pointer to struct timespec.
+ */
+ const void *arg;
+ } Timeout;
+
+#if defined(RTEMS_SMP)
+ /**
+ * @brief Representation of a thread queue path from a start thread queue to
+ * the terminal thread queue.
+ *
+ * The start thread queue is determined by the object on which a thread intends
+ * to block. The terminal thread queue is the thread queue reachable via
+ * thread queue links whose owner is not blocked on a thread queue. The thread
+ * queue links are determined by the thread queue owner and thread wait queue
+ * relationships.
+ */
+ struct {
+ /**
+ * @brief The chain of thread queue links defining the thread queue path.
+ */
+ Chain_Control Links;
+
+ /**
+ * @brief The start of a thread queue path.
+ */
+ Thread_queue_Link Start;
+
+ /**
+ * @brief In case of a deadlock, a link for the first thread on the path
+ * that tries to enqueue on a thread queue.
+ */
+ Thread_queue_Link Deadlock;
+ } Path;
+#endif
+
+ /**
+ * @brief Block to manage thread priority changes due to a thread queue
+ * operation.
+ */
+ struct {
+ /**
+ * @brief A priority action list.
+ */
+ Priority_Actions Actions;
+
+ /**
+ * @brief Count of threads to update the priority via
+ * _Thread_Priority_update().
+ */
+ size_t update_count;
+
+ /**
+ * @brief Threads to update the priority via _Thread_Priority_update().
+ *
+ * Currently, a maximum of two threads need an update in one rush, for
+ * example the thread of the thread queue operation and the owner of the
+ * thread queue.
+ */
+ Thread_Control *update[ 2 ];
+ } Priority;
+
+ /**
+ * @brief Invoked in case of a detected deadlock.
+ *
+ * Must be initialized for _Thread_queue_Enqueue() in case the
+ * thread queue may have an owner, e.g. for mutex objects.
+ *
+ * @see _Thread_queue_Context_set_deadlock_callout().
+ */
+ Thread_queue_Deadlock_callout deadlock_callout;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ /**
+ * @brief Callout to unblock the thread in case it is actually a thread
+ * proxy.
+ *
+ * This field is only used on multiprocessing configurations. Used by
+ * thread queue extract and unblock methods for objects with multiprocessing
+ * (MP) support.
+ *
+ * @see _Thread_queue_Context_set_MP_callout().
+ */
+ Thread_queue_MP_callout mp_callout;
+#endif
+};
+
+/**
+ * @brief Thread priority queue.
+ */
+typedef struct {
+#if defined(RTEMS_SMP)
+ /**
+ * @brief Node to enqueue this queue in the FIFO chain of the corresponding
+ * heads structure.
+ *
+ * @see Thread_queue_Heads::Heads::Fifo.
+ */
+ Chain_Node Node;
+#endif
+
+ /**
+ * @brief The actual thread priority queue.
+ */
+ Priority_Aggregation Queue;
+
+ /**
+ * @brief This priority queue is added to a scheduler node of the owner in
+ * case of priority inheritance.
+ */
+ struct Scheduler_Node *scheduler_node;
+} Thread_queue_Priority_queue;
+
+/**
+ * @brief Thread queue heads.
+ *
+ * Each thread is equipped with spare thread queue heads in case it is not
+ * enqueued on a thread queue. The first thread enqueued on a thread queue
+ * will give its spare thread queue heads to that thread queue. The threads
+ * arriving at the queue will add their thread queue heads to the free chain of
+ * the queue heads provided by the first thread enqueued. Once a thread is
+ * dequeued it use the free chain to get new spare thread queue heads.
+ *
+ * Uses a leading underscore in the structure name to allow forward
+ * declarations in standard header files provided by Newlib and GCC.
+ */
+typedef struct _Thread_queue_Heads {
+ /** This union contains the data structures used to manage the blocked
+ * set of tasks which varies based upon the discipline.
+ */
+ union {
+ /**
+ * @brief This is the FIFO discipline list.
+ *
+ * On SMP configurations this FIFO is used to enqueue the per scheduler
+ * instance priority queues of this structure. This ensures FIFO fairness
+ * among the highest priority thread of each scheduler instance.
+ */
+ Chain_Control Fifo;
+
+#if !defined(RTEMS_SMP)
+ /**
+ * @brief This is the set of threads for priority discipline waiting.
+ */
+ Thread_queue_Priority_queue Priority;
+#endif
+ } Heads;
+
+ /**
+ * @brief A chain with free thread queue heads providing the spare thread
+ * queue heads for a thread once it is dequeued.
+ */
+ Chain_Control Free_chain;
+
+ /**
+ * @brief A chain node to add these thread queue heads to the free chain of
+ * the thread queue heads dedicated to the thread queue of an object.
+ */
+ Chain_Node Free_node;
+
+#if defined(RTEMS_SMP)
+ /**
+ * @brief One priority queue per scheduler instance.
+ */
+ Thread_queue_Priority_queue Priority[ RTEMS_ZERO_LENGTH_ARRAY ];
+#endif
+} Thread_queue_Heads;
+
+#if defined(RTEMS_SMP)
+ #define THREAD_QUEUE_HEADS_SIZE( scheduler_count ) \
+ ( sizeof( Thread_queue_Heads ) \
+ + ( scheduler_count ) * sizeof( Thread_queue_Priority_queue ) )
+#else
+ #define THREAD_QUEUE_HEADS_SIZE( scheduler_count ) \
+ sizeof( Thread_queue_Heads )
+#endif
+
+struct Thread_queue_Queue {
+ /**
+ * @brief Lock to protect this thread queue.
+ *
+ * It may be used to protect additional state of the object embedding this
+ * thread queue.
+ *
+ * Must be the first component of this structure to be able to re-use
+ * implementation parts for structures defined by Newlib <sys/lock.h>.
+ *
+ * @see _Thread_queue_Acquire(), _Thread_queue_Acquire_critical() and
+ * _Thread_queue_Release().
+ */
+#if defined(RTEMS_SMP)
+ SMP_ticket_lock_Control Lock;
+#endif
+
+ /**
+ * @brief The thread queue heads.
+ *
+ * This pointer is NULL, if and only if no threads are enqueued. The first
+ * thread to enqueue will give its spare thread queue heads to this thread
+ * queue.
+ */
+ Thread_queue_Heads *heads;
+
+ /**
+ * @brief The thread queue owner.
+ */
+ Thread_Control *owner;
+
+ /**
+ * @brief The thread queue name.
+ */
+ const char *name;
+};
+
+/**
+ * @brief Thread queue action operation.
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] the_thread The thread.
+ * @param[in] queue_context The thread queue context providing the thread queue
+ * action set to perform. Returns the thread queue action set to perform on
+ * the thread queue owner or the empty set in case there is nothing to do.
+ */
+typedef void ( *Thread_queue_Priority_actions_operation )(
+ Thread_queue_Queue *queue,
+ Priority_Actions *priority_actions
+);
+
+/**
+ * @brief Thread queue enqueue operation.
+ *
+ * A potential thread to update the priority due to priority inheritance is
+ * returned via the thread queue context. This thread is handed over to
+ * _Thread_Priority_update().
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] the_thread The thread to enqueue on the queue.
+ */
+typedef void ( *Thread_queue_Enqueue_operation )(
+ Thread_queue_Queue *queue,
+ Thread_Control *the_thread,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Thread queue extract operation.
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] the_thread The thread to extract from the thread queue.
+ */
+typedef void ( *Thread_queue_Extract_operation )(
+ Thread_queue_Queue *queue,
+ Thread_Control *the_thread,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Thread queue surrender operation.
+ *
+ * This operation must dequeue and return the first thread on the queue.
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] heads The thread queue heads. It must not be NULL.
+ * @param[in] previous_owner The previous owner of the thread queue.
+ *
+ * @return The previous first thread on the queue.
+ */
+typedef Thread_Control *( *Thread_queue_Surrender_operation )(
+ Thread_queue_Queue *queue,
+ Thread_queue_Heads *heads,
+ Thread_Control *previous_owner,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Thread queue first operation.
+ *
+ * @param[in] heads The thread queue heads.
+ *
+ * @retval NULL No thread is present on the thread queue.
+ * @retval first The first thread of the thread queue according to the insert
+ * order. This thread remains on the thread queue.
+ */
+typedef Thread_Control *( *Thread_queue_First_operation )(
+ Thread_queue_Heads *heads
+);
+
+/**
+ * @brief Thread queue operations.
+ *
+ * @see _Thread_wait_Set_operations().
+ */
+struct Thread_queue_Operations {
+ /**
+ * @brief Thread queue priority actions operation.
+ */
+ Thread_queue_Priority_actions_operation priority_actions;
+
+ /**
+ * @brief Thread queue enqueue operation.
+ *
+ * Called by object routines to enqueue the thread.
+ */
+ Thread_queue_Enqueue_operation enqueue;
+
+ /**
+ * @brief Thread queue extract operation.
+ *
+ * Called by object routines to extract a thread from a thread queue.
+ */
+ Thread_queue_Extract_operation extract;
+
+ /**
+ * @brief Thread queue surrender operation.
+ */
+ Thread_queue_Surrender_operation surrender;
+
+ /**
+ * @brief Thread queue first operation.
+ */
+ Thread_queue_First_operation first;
+};
+
+/**
+ * This is the structure used to manage sets of tasks which are blocked
+ * waiting to acquire a resource.
+ */
+typedef struct {
+#if defined(RTEMS_SMP)
+#if defined(RTEMS_DEBUG)
+ /**
+ * @brief The index of the owning processor of the thread queue lock.
+ *
+ * The thread queue lock may be acquired via the thread lock also. This path
+ * is not covered by this field. In case the lock is not owned directly via
+ * _Thread_queue_Acquire(), then the value of this field is
+ * SMP_LOCK_NO_OWNER.
+ *
+ * Must be before the queue component of this structure to be able to re-use
+ * implementation parts for structures defined by Newlib <sys/lock.h>.
+ */
+ uint32_t owner;
+#endif
+
+#if defined(RTEMS_PROFILING)
+ /**
+ * @brief SMP lock statistics in case SMP and profiling are enabled.
+ *
+ * Must be before the queue component of this structure to be able to re-use
+ * implementation parts for structures defined by Newlib <sys/lock.h>.
+ */
+ SMP_lock_Stats Lock_stats;
+#endif
+#endif
+
+ /**
+ * @brief The actual thread queue.
+ */
+ Thread_queue_Queue Queue;
+} Thread_queue_Control;
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/threadqimpl.h b/cpukit/include/rtems/score/threadqimpl.h
new file mode 100644
index 0000000000..ecbd8fd42f
--- /dev/null
+++ b/cpukit/include/rtems/score/threadqimpl.h
@@ -0,0 +1,1265 @@
+/**
+ * @file rtems/score/threadq.h
+ *
+ * Constants and Structures Associated with the Manipulation of Objects
+ *
+ * This include file contains all the constants and structures associated
+ * with the manipulation of objects.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_THREADQIMPL_H
+#define _RTEMS_SCORE_THREADQIMPL_H
+
+#include <rtems/score/threadq.h>
+#include <rtems/score/chainimpl.h>
+#include <rtems/score/priorityimpl.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/smp.h>
+#include <rtems/score/status.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/threaddispatch.h>
+
+#if defined(RTEMS_DEBUG)
+#include <string.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreThreadQueue
+ */
+/**@{*/
+
+#define THREAD_QUEUE_LINK_OF_PATH_NODE( node ) \
+ RTEMS_CONTAINER_OF( node, Thread_queue_Link, Path_node );
+
+/**
+ * @brief Thread queue with a layout compatible to struct _Thread_queue_Queue
+ * defined in Newlib <sys/lock.h>.
+ */
+typedef struct {
+#if !defined(RTEMS_SMP)
+ /*
+ * The struct _Thread_queue_Queue definition is independent of the RTEMS
+ * build configuration. Thus, the storage space for the SMP lock is always
+ * present. In SMP configurations, the SMP lock is contained in the
+ * Thread_queue_Queue.
+ */
+ unsigned int reserved[2];
+#endif
+
+ Thread_queue_Queue Queue;
+} Thread_queue_Syslock_queue;
+
+void _Thread_queue_Enqueue_do_nothing_extra(
+ Thread_queue_Queue *queue,
+ Thread_Control *the_thread,
+ Per_CPU_Control *cpu_self,
+ Thread_queue_Context *queue_context
+);
+
+void _Thread_queue_Add_timeout_ticks(
+ Thread_queue_Queue *queue,
+ Thread_Control *the_thread,
+ Per_CPU_Control *cpu_self,
+ Thread_queue_Context *queue_context
+);
+
+void _Thread_queue_Add_timeout_monotonic_timespec(
+ Thread_queue_Queue *queue,
+ Thread_Control *the_thread,
+ Per_CPU_Control *cpu_self,
+ Thread_queue_Context *queue_context
+);
+
+void _Thread_queue_Add_timeout_realtime_timespec(
+ Thread_queue_Queue *queue,
+ Thread_Control *the_thread,
+ Per_CPU_Control *cpu_self,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Sets the thread wait return code to STATUS_DEADLOCK.
+ */
+void _Thread_queue_Deadlock_status( Thread_Control *the_thread );
+
+/**
+ * @brief Results in an INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK fatal error.
+ */
+void _Thread_queue_Deadlock_fatal( Thread_Control *the_thread );
+
+/**
+ * @brief Initializes a thread queue context.
+ *
+ * @param queue_context The thread queue context to initialize.
+ */
+RTEMS_INLINE_ROUTINE void _Thread_queue_Context_initialize(
+ Thread_queue_Context *queue_context
+)
+{
+#if defined(RTEMS_DEBUG)
+ memset( queue_context, 0x7f, sizeof( *queue_context ) );
+#if defined(RTEMS_SMP)
+ _Chain_Initialize_node( &queue_context->Lock_context.Wait.Gate.Node );
+#endif
+ queue_context->enqueue_callout = NULL;
+ queue_context->deadlock_callout = NULL;
+#else
+ (void) queue_context;
+#endif
+}
+
+/**
+ * @brief Sets the thread state for the thread to enqueue in the thread queue
+ * context.
+ *
+ * @param queue_context The thread queue context.
+ * @param state The thread state.
+ *
+ * @see _Thread_queue_Enqueue().
+ */
+RTEMS_INLINE_ROUTINE void
+_Thread_queue_Context_set_thread_state(
+ Thread_queue_Context *queue_context,
+ States_Control thread_state
+)
+{
+ queue_context->thread_state = thread_state;
+}
+
+/**
+ * @brief Sets the timeout ticks in the thread queue context.
+ *
+ * @param queue_context The thread queue context.
+ * @param ticks The timeout in ticks.
+ *
+ * @see _Thread_queue_Enqueue().
+ */
+RTEMS_INLINE_ROUTINE void
+_Thread_queue_Context_set_timeout_ticks(
+ Thread_queue_Context *queue_context,
+ Watchdog_Interval ticks
+)
+{
+ queue_context->Timeout.ticks = ticks;
+}
+
+/**
+ * @brief Sets the timeout argument in the thread queue context.
+ *
+ * @param queue_context The thread queue context.
+ * @param arg The timeout argument.
+ *
+ * @see _Thread_queue_Enqueue().
+ */
+RTEMS_INLINE_ROUTINE void
+_Thread_queue_Context_set_timeout_argument(
+ Thread_queue_Context *queue_context,
+ const void *arg
+)
+{
+ queue_context->Timeout.arg = arg;
+}
+
+/**
+ * @brief Sets the enqueue callout in the thread queue context.
+ *
+ * @param queue_context The thread queue context.
+ * @param enqueue_callout The enqueue callout.
+ *
+ * @see _Thread_queue_Enqueue().
+ */
+RTEMS_INLINE_ROUTINE void
+_Thread_queue_Context_set_enqueue_callout(
+ Thread_queue_Context *queue_context,
+ Thread_queue_Enqueue_callout enqueue_callout
+)
+{
+ queue_context->enqueue_callout = enqueue_callout;
+}
+
+/**
+ * @brief Sets the do nothing enqueue callout in the thread queue context.
+ *
+ * @param queue_context The thread queue context.
+ *
+ * @see _Thread_queue_Enqueue().
+ */
+RTEMS_INLINE_ROUTINE void
+_Thread_queue_Context_set_enqueue_do_nothing_extra(
+ Thread_queue_Context *queue_context
+)
+{
+ queue_context->enqueue_callout = _Thread_queue_Enqueue_do_nothing_extra;
+}
+
+/**
+ * @brief Sets the enqueue callout to add a relative monotonic timeout in
+ * ticks.
+ *
+ * @param queue_context The thread queue context.
+ * @param ticks The timeout in ticks.
+ *
+ * @see _Thread_queue_Enqueue().
+ */
+RTEMS_INLINE_ROUTINE void
+_Thread_queue_Context_set_enqueue_timeout_ticks(
+ Thread_queue_Context *queue_context,
+ Watchdog_Interval ticks
+)
+{
+ queue_context->Timeout.ticks = ticks;
+ queue_context->enqueue_callout = _Thread_queue_Add_timeout_ticks;
+}
+
+/**
+ * @brief Sets the enqueue callout to add an absolute monotonic timeout in
+ * timespec format.
+ *
+ * @param queue_context The thread queue context.
+ * @param abstime The absolute monotonic timeout.
+ *
+ * @see _Thread_queue_Enqueue().
+ */
+RTEMS_INLINE_ROUTINE void
+_Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
+ Thread_queue_Context *queue_context,
+ const struct timespec *abstime
+)
+{
+ queue_context->Timeout.arg = abstime;
+ queue_context->enqueue_callout =
+ _Thread_queue_Add_timeout_monotonic_timespec;
+}
+
+/**
+ * @brief Sets the enqueue callout to add an absolute realtime timeout in
+ * timespec format.
+ *
+ * @param queue_context The thread queue context.
+ * @param abstime The absolute realtime timeout.
+ *
+ * @see _Thread_queue_Enqueue().
+ */
+RTEMS_INLINE_ROUTINE void
+_Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
+ Thread_queue_Context *queue_context,
+ const struct timespec *abstime
+)
+{
+ queue_context->Timeout.arg = abstime;
+ queue_context->enqueue_callout = _Thread_queue_Add_timeout_realtime_timespec;
+}
+
+/**
+ * @brief Sets the deadlock callout in the thread queue
+ * context.
+ *
+ * A deadlock callout must be provided for _Thread_queue_Enqueue()
+ * operations that operate on thread queues which may have an owner, e.g. mutex
+ * objects. Available deadlock callouts are _Thread_queue_Deadlock_status()
+ * and _Thread_queue_Deadlock_fatal().
+ *
+ * @param queue_context The thread queue context.
+ * @param deadlock_callout The deadlock callout.
+ *
+ * @see _Thread_queue_Enqueue().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_queue_Context_set_deadlock_callout(
+ Thread_queue_Context *queue_context,
+ Thread_queue_Deadlock_callout deadlock_callout
+)
+{
+ queue_context->deadlock_callout = deadlock_callout;
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Context_clear_priority_updates(
+ Thread_queue_Context *queue_context
+)
+{
+ queue_context->Priority.update_count = 0;
+}
+
+RTEMS_INLINE_ROUTINE size_t _Thread_queue_Context_save_priority_updates(
+ Thread_queue_Context *queue_context
+)
+{
+ return queue_context->Priority.update_count;
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Context_restore_priority_updates(
+ Thread_queue_Context *queue_context,
+ size_t update_count
+)
+{
+ queue_context->Priority.update_count = update_count;
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Context_add_priority_update(
+ Thread_queue_Context *queue_context,
+ Thread_Control *the_thread
+)
+{
+ size_t n;
+
+ n = queue_context->Priority.update_count;
+ _Assert( n < RTEMS_ARRAY_SIZE( queue_context->Priority.update ) );
+
+ queue_context->Priority.update_count = n + 1;
+ queue_context->Priority.update[ n ] = the_thread;
+}
+
+#define _Thread_queue_Context_ISR_disable( queue_context, level ) \
+ do { \
+ _ISR_Local_disable( level ); \
+ _ISR_lock_ISR_disable_profile( \
+ &( queue_context )->Lock_context.Lock_context \
+ ) \
+ } while ( 0 )
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Context_set_ISR_level(
+ Thread_queue_Context *queue_context,
+ ISR_Level level
+)
+{
+ _ISR_lock_Context_set_level(
+ &queue_context->Lock_context.Lock_context,
+ level
+ );
+}
+
+RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_queue_Dispatch_disable(
+ Thread_queue_Context *queue_context
+)
+{
+ return _Thread_Dispatch_disable_critical(
+ &queue_context->Lock_context.Lock_context
+ );
+}
+
+/**
+ * @brief Sets the MP callout in the thread queue context.
+ *
+ * @param queue_context The thread queue context.
+ * @param mp_callout Callout to unblock the thread in case it is actually a
+ * thread proxy. This parameter is only used on multiprocessing
+ * configurations. Used by thread queue extract and unblock methods for
+ * objects with multiprocessing (MP) support.
+ */
+#if defined(RTEMS_MULTIPROCESSING)
+RTEMS_INLINE_ROUTINE void _Thread_queue_Context_set_MP_callout(
+ Thread_queue_Context *queue_context,
+ Thread_queue_MP_callout mp_callout
+)
+{
+ queue_context->mp_callout = mp_callout;
+}
+#else
+#define _Thread_queue_Context_set_MP_callout( queue_context, mp_callout ) \
+ do { \
+ (void) queue_context; \
+ } while ( 0 )
+#endif
+
+#if defined(RTEMS_SMP)
+RTEMS_INLINE_ROUTINE void _Thread_queue_Gate_close(
+ Thread_queue_Gate *gate
+)
+{
+ _Atomic_Store_uint( &gate->go_ahead, 0, ATOMIC_ORDER_RELAXED );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Gate_add(
+ Chain_Control *chain,
+ Thread_queue_Gate *gate
+)
+{
+ _Chain_Append_unprotected( chain, &gate->Node );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Gate_open(
+ Thread_queue_Gate *gate
+)
+{
+ _Atomic_Store_uint( &gate->go_ahead, 1, ATOMIC_ORDER_RELAXED );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Gate_wait(
+ Thread_queue_Gate *gate
+)
+{
+ while ( _Atomic_Load_uint( &gate->go_ahead, ATOMIC_ORDER_RELAXED ) == 0 ) {
+ /* Wait */
+ }
+}
+#endif
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Heads_initialize(
+ Thread_queue_Heads *heads
+)
+{
+#if defined(RTEMS_SMP)
+ size_t i;
+
+ for ( i = 0; i < _Scheduler_Count; ++i ) {
+ _Chain_Initialize_node( &heads->Priority[ i ].Node );
+ _Priority_Initialize_empty( &heads->Priority[ i ].Queue );
+ heads->Priority[ i ].Queue.scheduler = &_Scheduler_Table[ i ];
+ }
+#endif
+
+ _Chain_Initialize_empty( &heads->Free_chain );
+ _Chain_Initialize_node( &heads->Free_node );
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_initialize(
+ Thread_queue_Queue *queue,
+ const char *name
+)
+{
+#if defined(RTEMS_SMP)
+ _SMP_ticket_lock_Initialize( &queue->Lock );
+#endif
+ queue->heads = NULL;
+ queue->owner = NULL;
+ queue->name = name;
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_do_acquire_critical(
+ Thread_queue_Queue *queue,
+#if defined(RTEMS_SMP) && defined(RTEMS_PROFILING)
+ SMP_lock_Stats *lock_stats,
+#endif
+ ISR_lock_Context *lock_context
+)
+{
+#if defined(RTEMS_SMP)
+ _SMP_ticket_lock_Acquire(
+ &queue->Lock,
+ lock_stats,
+ &lock_context->Lock_context.Stats_context
+ );
+#else
+ (void) queue;
+ (void) lock_context;
+#endif
+}
+
+#if defined(RTEMS_SMP) && defined( RTEMS_PROFILING )
+ #define \
+ _Thread_queue_Queue_acquire_critical( queue, lock_stats, lock_context ) \
+ _Thread_queue_Queue_do_acquire_critical( queue, lock_stats, lock_context )
+#else
+ #define \
+ _Thread_queue_Queue_acquire_critical( queue, lock_stats, lock_context ) \
+ _Thread_queue_Queue_do_acquire_critical( queue, lock_context )
+#endif
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_release_critical(
+ Thread_queue_Queue *queue,
+ ISR_lock_Context *lock_context
+)
+{
+#if defined(RTEMS_SMP)
+ _SMP_ticket_lock_Release(
+ &queue->Lock,
+ &lock_context->Lock_context.Stats_context
+ );
+#else
+ (void) queue;
+ (void) lock_context;
+#endif
+}
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_release(
+ Thread_queue_Queue *queue,
+ ISR_lock_Context *lock_context
+)
+{
+ _Thread_queue_Queue_release_critical( queue, lock_context );
+ _ISR_lock_ISR_enable( lock_context );
+}
+
+/**
+ * @brief Copies the thread queue name to the specified buffer.
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] buffer The buffer for the thread queue name copy.
+ * @param[in] buffer_size The buffer size in characters.
+ * @param[in] id The object identifier in case the thread queue is embedded in
+ * an object with identifier, otherwise it is set to 0.
+ *
+ * @retval The length of the thread queue name. May be greater than or equal
+ * to the buffer size if truncation occurred.
+ */
+size_t _Thread_queue_Queue_get_name_and_id(
+ const Thread_queue_Queue *queue,
+ char *buffer,
+ size_t buffer_size,
+ Objects_Id *id
+);
+
+#if defined(RTEMS_SMP)
+void _Thread_queue_Do_acquire_critical(
+ Thread_queue_Control *the_thread_queue,
+ ISR_lock_Context *lock_context
+);
+#else
+RTEMS_INLINE_ROUTINE void _Thread_queue_Do_acquire_critical(
+ Thread_queue_Control *the_thread_queue,
+ ISR_lock_Context *lock_context
+)
+{
+ (void) the_thread_queue;
+ (void) lock_context;
+}
+#endif
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire_critical(
+ Thread_queue_Control *the_thread_queue,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Do_acquire_critical(
+ the_thread_queue,
+ &queue_context->Lock_context.Lock_context
+ );
+}
+
+#if defined(RTEMS_SMP)
+void _Thread_queue_Acquire(
+ Thread_queue_Control *the_thread_queue,
+ Thread_queue_Context *queue_context
+);
+#else
+RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire(
+ Thread_queue_Control *the_thread_queue,
+ Thread_queue_Context *queue_context
+)
+{
+ (void) the_thread_queue;
+ _ISR_lock_ISR_disable( &queue_context->Lock_context.Lock_context );
+}
+#endif
+
+#if defined(RTEMS_DEBUG)
+RTEMS_INLINE_ROUTINE bool _Thread_queue_Is_lock_owner(
+ const Thread_queue_Control *the_thread_queue
+)
+{
+#if defined(RTEMS_SMP)
+ return the_thread_queue->owner == _SMP_lock_Who_am_I();
+#else
+ return _ISR_Get_level() != 0;
+#endif
+}
+#endif
+
+#if defined(RTEMS_SMP)
+void _Thread_queue_Do_release_critical(
+ Thread_queue_Control *the_thread_queue,
+ ISR_lock_Context *lock_context
+);
+#else
+RTEMS_INLINE_ROUTINE void _Thread_queue_Do_release_critical(
+ Thread_queue_Control *the_thread_queue,
+ ISR_lock_Context *lock_context
+)
+{
+ (void) the_thread_queue;
+ (void) lock_context;
+ _Assert( _Thread_queue_Is_lock_owner( the_thread_queue ) );
+}
+#endif
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Release_critical(
+ Thread_queue_Control *the_thread_queue,
+ Thread_queue_Context *queue_context
+)
+{
+ _Thread_queue_Do_release_critical(
+ the_thread_queue,
+ &queue_context->Lock_context.Lock_context
+ );
+}
+
+#if defined(RTEMS_SMP)
+void _Thread_queue_Release(
+ Thread_queue_Control *the_thread_queue,
+ Thread_queue_Context *queue_context
+);
+#else
+RTEMS_INLINE_ROUTINE void _Thread_queue_Release(
+ Thread_queue_Control *the_thread_queue,
+ Thread_queue_Context *queue_context
+)
+{
+ (void) the_thread_queue;
+ _Assert( _Thread_queue_Is_lock_owner( the_thread_queue ) );
+ _ISR_lock_ISR_enable( &queue_context->Lock_context.Lock_context );
+}
+#endif
+
+Thread_Control *_Thread_queue_Do_dequeue(
+ Thread_queue_Control *the_thread_queue,
+ const Thread_queue_Operations *operations
+#if defined(RTEMS_MULTIPROCESSING)
+ ,
+ Thread_queue_MP_callout mp_callout
+#endif
+);
+
+/**
+ * @brief Gets a pointer to a thread waiting on the_thread_queue.
+ *
+ * This function returns a pointer to a thread waiting on
+ * the_thread_queue. The selection of this thread is based on
+ * the discipline of the_thread_queue. If no threads are waiting
+ * on the_thread_queue, then NULL is returned.
+ *
+ * - INTERRUPT LATENCY:
+ * + single case
+ */
+#if defined(RTEMS_MULTIPROCESSING)
+ #define _Thread_queue_Dequeue( \
+ the_thread_queue, \
+ operations, \
+ mp_callout \
+ ) \
+ _Thread_queue_Do_dequeue( \
+ the_thread_queue, \
+ operations, \
+ mp_callout \
+ )
+#else
+ #define _Thread_queue_Dequeue( \
+ the_thread_queue, \
+ operations, \
+ mp_callout \
+ ) \
+ _Thread_queue_Do_dequeue( \
+ the_thread_queue, \
+ operations \
+ )
+#endif
+
+/**
+ * @brief Blocks the thread and places it on the thread queue.
+ *
+ * This enqueues the thread on the thread queue, blocks the thread, and
+ * optionally starts the thread timer in case the timeout discipline is not
+ * WATCHDOG_NO_TIMEOUT. Timeout discipline and value are in the queue_context.
+ *
+ * The caller must be the owner of the thread queue lock. This function will
+ * release the thread queue lock and register it as the new thread lock.
+ * Thread dispatching is disabled before the thread queue lock is released.
+ * Thread dispatching is enabled once the sequence to block the thread is
+ * complete. The operation to enqueue the thread on the queue is protected by
+ * the thread queue lock. This makes it possible to use the thread queue lock
+ * to protect the state of objects embedding the thread queue and directly
+ * enter _Thread_queue_Enqueue() in case the thread must block.
+ *
+ * The thread queue context must be set up with the following functions,
+ * otherwise the behaviour is unpredictable
+ *
+ * - _Thread_queue_Context_set_thread_state(),
+ *
+ * - _Thread_queue_Context_set_enqueue_callout() or
+ * _Thread_queue_Context_set_enqueue_do_nothing_extra() or
+ * _Thread_queue_Context_set_enqueue_timeout_ticks() or
+ * _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec() or
+ * _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(),
+ *
+ * - _Thread_queue_Context_set_deadlock_callout().
+ *
+ * @code
+ * #include <rtems/score/threadqimpl.h>
+ * #include <rtems/score/statesimpl.h>
+ *
+ * #define MUTEX_TQ_OPERATIONS &_Thread_queue_Operations_priority
+ *
+ * typedef struct {
+ * Thread_queue_Control Queue;
+ * } Mutex;
+ *
+ * void _Mutex_Obtain( Mutex *mutex )
+ * {
+ * Thread_queue_Context queue_context;
+ * Thread_Control *executing;
+ *
+ * _Thread_queue_Context_initialize( &queue_context );
+ * _Thread_queue_Acquire( &mutex->Queue, queue_context );
+ *
+ * executing = _Thread_Executing;
+ *
+ * if ( mutex->Queue.owner == NULL ) {
+ * mutex->Queue.owner = executing;
+ * _Thread_queue_Release( &mutex->Queue, queue_context );
+ * } else {
+ * _Thread_queue_Context_set_thread_state(
+ * &queue_context,
+ * STATES_WAITING_FOR_MUTEX
+ * );
+ * _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
+ * _Thread_queue_Context_set_deadlock_callout(
+ * queue_context,
+ * _Thread_queue_Deadlock_fatal
+ * );
+ * _Thread_queue_Enqueue(
+ * &mutex->Queue.Queue,
+ * MUTEX_TQ_OPERATIONS,
+ * executing,
+ * &queue_context
+ * );
+ * }
+ * }
+ * @endcode
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] operations The thread queue operations.
+ * @param[in] the_thread The thread to enqueue.
+ * @param[in] queue_context The thread queue context of the lock acquire.
+ */
+void _Thread_queue_Enqueue(
+ Thread_queue_Queue *queue,
+ const Thread_queue_Operations *operations,
+ Thread_Control *the_thread,
+ Thread_queue_Context *queue_context
+);
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief Enqueues the thread on the thread queue and busy waits for dequeue.
+ *
+ * Optionally starts the thread timer in case the timeout discipline is not
+ * WATCHDOG_NO_TIMEOUT. Timeout discipline and value are in the queue_context.
+ *
+ * The caller must be the owner of the thread queue lock. This function will
+ * release the thread queue lock and register it as the new thread lock.
+ *
+ * The thread priorities of the owner and the are updated with respect to the
+ * scheduler. The sticky level of the thread is incremented. A thread
+ * dispatch is performed if necessary.
+ *
+ * Afterwards, the thread busy waits on the thread wait flags until a timeout
+ * occurs or the thread queue is surrendered to this thread. So, it sticks to
+ * the processor instead of blocking with respect to the scheduler.
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] operations The thread queue operations.
+ * @param[in] the_thread The thread to enqueue.
+ * @param[in] queue_context The thread queue context of the lock acquire.
+ */
+Status_Control _Thread_queue_Enqueue_sticky(
+ Thread_queue_Queue *queue,
+ const Thread_queue_Operations *operations,
+ Thread_Control *the_thread,
+ Thread_queue_Context *queue_context
+);
+#endif
+
+/**
+ * @brief Extracts the thread from the thread queue, restores the default wait
+ * operations and restores the default thread lock.
+ *
+ * The caller must be the owner of the thread queue lock. The thread queue
+ * lock is not released.
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] operations The thread queue operations.
+ * @param[in] the_thread The thread to extract.
+ * @param[in] queue_context The thread queue context.
+ *
+ * @return Returns the unblock indicator for _Thread_queue_Unblock_critical().
+ * True indicates, that this thread must be unblocked by the scheduler later in
+ * _Thread_queue_Unblock_critical(), and false otherwise. In case false is
+ * returned, then the thread queue enqueue procedure was interrupted. Thus it
+ * will unblock itself and the thread wait information is no longer accessible,
+ * since this thread may already block on another resource in an SMP
+ * configuration.
+ */
+bool _Thread_queue_Extract_locked(
+ Thread_queue_Queue *queue,
+ const Thread_queue_Operations *operations,
+ Thread_Control *the_thread,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Unblocks the thread which was on the thread queue before.
+ *
+ * The caller must be the owner of the thread queue lock. This function will
+ * release the thread queue lock. Thread dispatching is disabled before the
+ * thread queue lock is released and an unblock is necessary. Thread
+ * dispatching is enabled once the sequence to unblock the thread is complete.
+ *
+ * @param[in] unblock The unblock indicator returned by
+ * _Thread_queue_Extract_locked().
+ * @param[in] queue The actual thread queue.
+ * @param[in] the_thread The thread to extract.
+ * @param[in] lock_context The lock context of the lock acquire.
+ */
+void _Thread_queue_Unblock_critical(
+ bool unblock,
+ Thread_queue_Queue *queue,
+ Thread_Control *the_thread,
+ ISR_lock_Context *lock_context
+);
+
+/**
+ * @brief Extracts the thread from the thread queue and unblocks it.
+ *
+ * The caller must be the owner of the thread queue lock. This function will
+ * release the thread queue lock and restore the default thread lock. Thread
+ * dispatching is disabled before the thread queue lock is released and an
+ * unblock is necessary. Thread dispatching is enabled once the sequence to
+ * unblock the thread is complete. This makes it possible to use the thread
+ * queue lock to protect the state of objects embedding the thread queue and
+ * directly enter _Thread_queue_Extract_critical() to finalize an operation in
+ * case a waiting thread exists.
+ *
+ * @code
+ * #include <rtems/score/threadqimpl.h>
+ *
+ * typedef struct {
+ * Thread_queue_Control Queue;
+ * Thread_Control *owner;
+ * } Mutex;
+ *
+ * void _Mutex_Release( Mutex *mutex )
+ * {
+ * Thread_queue_Context queue_context;
+ * Thread_Control *first;
+ *
+ * _Thread_queue_Context_initialize( &queue_context, NULL );
+ * _Thread_queue_Acquire( &mutex->Queue, queue_context );
+ *
+ * first = _Thread_queue_First_locked( &mutex->Queue );
+ * mutex->owner = first;
+ *
+ * if ( first != NULL ) {
+ * _Thread_queue_Extract_critical(
+ * &mutex->Queue.Queue,
+ * mutex->Queue.operations,
+ * first,
+ * &queue_context
+ * );
+ * }
+ * @endcode
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] operations The thread queue operations.
+ * @param[in] the_thread The thread to extract.
+ * @param[in] queue_context The thread queue context of the lock acquire.
+ */
+void _Thread_queue_Extract_critical(
+ Thread_queue_Queue *queue,
+ const Thread_queue_Operations *operations,
+ Thread_Control *the_thread,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Extracts thread from thread queue.
+ *
+ * This routine removes @a the_thread its thread queue
+ * and cancels any timeouts associated with this blocking.
+ *
+ * @param[in] the_thread is the pointer to a thread control block that
+ * is to be removed
+ */
+void _Thread_queue_Extract( Thread_Control *the_thread );
+
+/**
+ * @brief Extracts the_thread from the_thread_queue.
+ *
+ * This routine extracts the_thread from the_thread_queue
+ * and ensures that if there is a proxy for this task on
+ * another node, it is also dealt with.
+ */
+void _Thread_queue_Extract_with_proxy(
+ Thread_Control *the_thread
+);
+
+/**
+ * @brief Surrenders the thread queue previously owned by the thread to the
+ * first enqueued thread.
+ *
+ * The owner of the thread queue must be set to NULL by the caller.
+ *
+ * This function releases the thread queue lock. In addition it performs a
+ * thread dispatch if necessary.
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] heads The thread queue heads. It must not be NULL.
+ * @param[in] previous_owner The previous owner thread surrendering the thread
+ * queue.
+ * @param[in] queue_context The thread queue context of the lock acquire.
+ * @param[in] operations The thread queue operations.
+ */
+void _Thread_queue_Surrender(
+ Thread_queue_Queue *queue,
+ Thread_queue_Heads *heads,
+ Thread_Control *previous_owner,
+ Thread_queue_Context *queue_context,
+ const Thread_queue_Operations *operations
+);
+
+#if defined(RTEMS_SMP)
+/**
+ * @brief Surrenders the thread queue previously owned by the thread to the
+ * first enqueued thread.
+ *
+ * The owner of the thread queue must be set to NULL by the caller.
+ *
+ * The caller must be the owner of the thread queue lock. This function will
+ * release the thread queue.
+ *
+ * The thread priorities of the previous owner and the new owner are updated. The
+ * sticky level of the previous owner is decremented. A thread dispatch is
+ * performed if necessary.
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] heads The thread queue heads. It must not be NULL.
+ * @param[in] previous_owner The previous owner thread surrendering the thread
+ * queue.
+ * @param[in] queue_context The thread queue context of the lock acquire.
+ * @param[in] operations The thread queue operations.
+ */
+void _Thread_queue_Surrender_sticky(
+ Thread_queue_Queue *queue,
+ Thread_queue_Heads *heads,
+ Thread_Control *previous_owner,
+ Thread_queue_Context *queue_context,
+ const Thread_queue_Operations *operations
+);
+#endif
+
+RTEMS_INLINE_ROUTINE bool _Thread_queue_Is_empty(
+ const Thread_queue_Queue *queue
+)
+{
+ return queue->heads == NULL;
+}
+
+/**
+ * @brief Returns the first thread on the thread queue if it exists, otherwise
+ * @c NULL.
+ *
+ * The caller must be the owner of the thread queue lock. The thread queue
+ * lock is not released.
+ *
+ * @param[in] the_thread_queue The thread queue.
+ * @param[in] operations The thread queue operations.
+ *
+ * @retval NULL No thread is present on the thread queue.
+ * @retval first The first thread on the thread queue according to the enqueue
+ * order.
+ */
+RTEMS_INLINE_ROUTINE Thread_Control *_Thread_queue_First_locked(
+ Thread_queue_Control *the_thread_queue,
+ const Thread_queue_Operations *operations
+)
+{
+ Thread_queue_Heads *heads = the_thread_queue->Queue.heads;
+
+ if ( heads != NULL ) {
+ return ( *operations->first )( heads );
+ } else {
+ return NULL;
+ }
+}
+
+/**
+ * @brief Returns the first thread on the thread queue if it exists, otherwise
+ * @c NULL.
+ *
+ * @param[in] the_thread_queue The thread queue.
+ *
+ * @retval NULL No thread is present on the thread queue.
+ * @retval first The first thread on the thread queue according to the enqueue
+ * order.
+ */
+Thread_Control *_Thread_queue_First(
+ Thread_queue_Control *the_thread_queue,
+ const Thread_queue_Operations *operations
+);
+
+/**
+ * @brief Thread queue flush filter function.
+ *
+ * Called under protection of the thread queue lock by
+ * _Thread_queue_Flush_critical() to optionally alter the thread wait
+ * information and control the iteration.
+ *
+ * @param the_thread The thread to extract. This is the first parameter to
+ * optimize for architectures that use the same register for the first
+ * parameter and the return value.
+ * @param queue The actual thread queue.
+ * @param queue_context The thread queue context of the lock acquire. May be
+ * used to pass additional data to the filter function via an overlay
+ * structure. The filter function should not release or acquire the thread
+ * queue lock.
+ *
+ * @retval the_thread Extract this thread.
+ * @retval NULL Do not extract this thread and stop the thread queue flush
+ * operation. Threads that are already extracted will complete the flush
+ * operation.
+ */
+typedef Thread_Control *( *Thread_queue_Flush_filter )(
+ Thread_Control *the_thread,
+ Thread_queue_Queue *queue,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Default thread queue flush filter function.
+ *
+ * @param the_thread The thread to extract.
+ * @param queue Unused.
+ * @param queue_context Unused.
+ *
+ * @retval the_thread Extract this thread.
+ */
+Thread_Control *_Thread_queue_Flush_default_filter(
+ Thread_Control *the_thread,
+ Thread_queue_Queue *queue,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Status unavailable thread queue flush filter function.
+ *
+ * Sets the thread wait return code of the thread to STATUS_UNAVAILABLE.
+ *
+ * @param the_thread The thread to extract.
+ * @param queue Unused.
+ * @param queue_context Unused.
+ *
+ * @retval the_thread Extract this thread.
+ */
+Thread_Control *_Thread_queue_Flush_status_unavailable(
+ Thread_Control *the_thread,
+ Thread_queue_Queue *queue,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Status object was deleted thread queue flush filter function.
+ *
+ * Sets the thread wait return code of the thread to STATUS_OBJECT_WAS_DELETED
+ *
+ * @param the_thread The thread to extract.
+ * @param queue Unused.
+ * @param queue_context Unused.
+ *
+ * @retval the_thread Extract this thread.
+ */
+Thread_Control *_Thread_queue_Flush_status_object_was_deleted(
+ Thread_Control *the_thread,
+ Thread_queue_Queue *queue,
+ Thread_queue_Context *queue_context
+);
+
+/**
+ * @brief Unblocks all threads enqueued on the thread queue.
+ *
+ * This function iteratively extracts the first enqueued thread of the thread
+ * queue until the thread queue is empty or the filter function indicates a
+ * stop. The thread timers of the extracted threads are cancelled. The
+ * extracted threads are unblocked.
+ *
+ * @param queue The actual thread queue.
+ * @param operations The thread queue operations.
+ * @param filter The filter functions is called for each thread to extract from
+ * the thread queue. It may be used to alter the thread under protection of
+ * the thread queue lock, for example to set the thread wait return code.
+ * The return value of the filter function controls if the thread queue flush
+ * operation should stop or continue.
+ * @param queue_context The thread queue context of the lock acquire. May be
+ * used to pass additional data to the filter function via an overlay
+ * structure. The filter function should not release or acquire the thread
+ * queue lock.
+ *
+ * @return The count of extracted threads.
+ */
+size_t _Thread_queue_Flush_critical(
+ Thread_queue_Queue *queue,
+ const Thread_queue_Operations *operations,
+ Thread_queue_Flush_filter filter,
+ Thread_queue_Context *queue_context
+);
+
+void _Thread_queue_Initialize(
+ Thread_queue_Control *the_thread_queue,
+ const char *name
+);
+
+#if defined(RTEMS_SMP) && defined(RTEMS_DEBUG) && defined(RTEMS_PROFILING)
+ #define THREAD_QUEUE_INITIALIZER( _name ) \
+ { \
+ .Lock_stats = SMP_LOCK_STATS_INITIALIZER( _name ), \
+ .owner = SMP_LOCK_NO_OWNER, \
+ .Queue = { \
+ .Lock = SMP_TICKET_LOCK_INITIALIZER, \
+ .heads = NULL, \
+ .owner = NULL, \
+ .name = _name \
+ } \
+ }
+#elif defined(RTEMS_SMP) && defined(RTEMS_DEBUG)
+ #define THREAD_QUEUE_INITIALIZER( _name ) \
+ { \
+ .owner = SMP_LOCK_NO_OWNER, \
+ .Queue = { \
+ .Lock = SMP_TICKET_LOCK_INITIALIZER, \
+ .heads = NULL, \
+ .owner = NULL, \
+ .name = _name \
+ } \
+ }
+#elif defined(RTEMS_SMP) && defined(RTEMS_PROFILING)
+ #define THREAD_QUEUE_INITIALIZER( _name ) \
+ { \
+ .Lock_stats = SMP_LOCK_STATS_INITIALIZER( _name ), \
+ .Queue = { \
+ .Lock = SMP_TICKET_LOCK_INITIALIZER, \
+ .heads = NULL, \
+ .owner = NULL, \
+ .name = _name \
+ } \
+ }
+#elif defined(RTEMS_SMP)
+ #define THREAD_QUEUE_INITIALIZER( _name ) \
+ { \
+ .Queue = { \
+ .Lock = SMP_TICKET_LOCK_INITIALIZER, \
+ .heads = NULL, \
+ .owner = NULL, \
+ .name = _name \
+ } \
+ }
+#else
+ #define THREAD_QUEUE_INITIALIZER( _name ) \
+ { \
+ .Queue = { \
+ .heads = NULL, \
+ .owner = NULL, \
+ .name = _name \
+ } \
+ }
+#endif
+
+RTEMS_INLINE_ROUTINE void _Thread_queue_Destroy(
+ Thread_queue_Control *the_thread_queue
+)
+{
+#if defined(RTEMS_SMP)
+ _SMP_ticket_lock_Destroy( &the_thread_queue->Queue.Lock );
+ _SMP_lock_Stats_destroy( &the_thread_queue->Lock_stats );
+#endif
+}
+
+#if defined(RTEMS_MULTIPROCESSING)
+void _Thread_queue_MP_callout_do_nothing(
+ Thread_Control *the_proxy,
+ Objects_Id mp_id
+);
+
+void _Thread_queue_Unblock_proxy(
+ Thread_queue_Queue *queue,
+ Thread_Control *the_thread
+);
+#endif
+
+#if defined(RTEMS_SMP)
+bool _Thread_queue_Path_acquire_critical(
+ Thread_queue_Queue *queue,
+ Thread_Control *the_thread,
+ Thread_queue_Context *queue_context
+);
+
+void _Thread_queue_Path_release_critical(
+ Thread_queue_Context *queue_context
+);
+#endif
+
+/**
+ * @brief Helper structure to ensure that all objects containing a thread queue
+ * have the right layout.
+ *
+ * @see _Thread_Wait_get_id() and THREAD_QUEUE_OBJECT_ASSERT().
+ */
+typedef struct {
+ Objects_Control Object;
+ Thread_queue_Control Wait_queue;
+} Thread_queue_Object;
+
+#define THREAD_QUEUE_OBJECT_ASSERT( object_type, wait_queue_member ) \
+ RTEMS_STATIC_ASSERT( \
+ offsetof( object_type, wait_queue_member ) \
+ == offsetof( Thread_queue_Object, Wait_queue ) \
+ && RTEMS_HAVE_MEMBER_SAME_TYPE( \
+ object_type, \
+ wait_queue_member, \
+ Thread_queue_Object, \
+ Wait_queue \
+ ), \
+ object_type \
+ )
+
+#define THREAD_QUEUE_QUEUE_TO_OBJECT( queue ) \
+ RTEMS_CONTAINER_OF( \
+ queue, \
+ Thread_queue_Object, \
+ Wait_queue.Queue \
+ )
+
+extern const Thread_queue_Operations _Thread_queue_Operations_default;
+
+extern const Thread_queue_Operations _Thread_queue_Operations_FIFO;
+
+extern const Thread_queue_Operations _Thread_queue_Operations_priority;
+
+extern const Thread_queue_Operations _Thread_queue_Operations_priority_inherit;
+
+/**
+ * @brief The special thread queue name to indicated that the thread queue is
+ * embedded in an object with identifier.
+ *
+ * @see _Thread_queue_Object_initialize().
+ */
+extern const char _Thread_queue_Object_name[];
+
+/**
+ * @brief Initializes a thread queue embedded in an object with identifier.
+ *
+ * The object must have the layout specified by Thread_queue_Object. It should
+ * be ensured with the THREAD_QUEUE_OBJECT_ASSERT() static assertion.
+ *
+ * @param[in] the_thread_queue The thread queue.
+ */
+void _Thread_queue_Object_initialize(
+ Thread_queue_Control *the_thread_queue
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/timecounter.h b/cpukit/include/rtems/score/timecounter.h
new file mode 100644
index 0000000000..79444de482
--- /dev/null
+++ b/cpukit/include/rtems/score/timecounter.h
@@ -0,0 +1,244 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreTimecounter
+ *
+ * @brief Timecounter API
+ */
+
+/*
+ * Copyright (c) 2015 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_TIMECOUNTER_H
+#define _RTEMS_SCORE_TIMECOUNTER_H
+
+#include <sys/time.h>
+#include <sys/timetc.h>
+#include <machine/_timecounter.h>
+
+#include <rtems/score/isrlock.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ScoreTimecounter Timecounter Handler
+ *
+ * @ingroup Score
+ *
+ * @{
+ */
+
+/**
+ * @brief Returns the wall clock time in the bintime format.
+ *
+ * @param[out] bt Returns the wall clock time.
+ */
+void _Timecounter_Bintime( struct bintime *bt );
+
+/**
+ * @brief Returns the wall clock time in the timespec format.
+ *
+ * @param[out] ts Returns the wall clock time.
+ */
+void _Timecounter_Nanotime( struct timespec *ts );
+
+/**
+ * @brief Returns the wall clock time in the timeval format.
+ *
+ * @param[out] tv Returns the wall clock time.
+ */
+void _Timecounter_Microtime( struct timeval *tv );
+
+/**
+ * @brief Returns the uptime in the bintime format.
+ *
+ * @param[out] bt Returns the uptime.
+ */
+void _Timecounter_Binuptime( struct bintime *bt );
+
+/**
+ * @brief Returns the uptime in the sbintime_t format.
+ *
+ * @return Returns the uptime.
+ */
+sbintime_t _Timecounter_Sbinuptime( void );
+
+/**
+ * @brief Returns the uptime in the timespec format.
+ *
+ * @param[out] ts Returns the uptime.
+ */
+void _Timecounter_Nanouptime( struct timespec *ts );
+
+/**
+ * @brief Returns the uptime in the timeval format.
+ *
+ * @param[out] tv Returns the uptime.
+ */
+void _Timecounter_Microuptime( struct timeval *tv );
+
+/**
+ * @brief Returns the wall clock time in the bintime format.
+ *
+ * This function obtains the time with a lower overhead and lower accuracy
+ * compared to the _Timecounter_Bintime() variant.
+ *
+ * @param[out] ts Returns the wall clock time.
+ */
+void _Timecounter_Getbintime( struct bintime *bt );
+
+/**
+ * @brief Returns the wall clock time in the timespec format.
+ *
+ * This function obtains the time with a lower overhead and lower accuracy
+ * compared to the _Timecounter_Nanotime() variant.
+ *
+ * @param[out] ts Returns the wall clock time.
+ *
+ * @see _Timecounter_Getbintime().
+ */
+void _Timecounter_Getnanotime( struct timespec *ts );
+
+/**
+ * @brief Returns the wall clock time in the timeval format.
+ *
+ * This function obtains the time with a lower overhead and lower accuracy
+ * compared to the _Timecounter_Microtime() variant.
+ *
+ * @param[out] tv Returns the wall clock time.
+ *
+ * @see _Timecounter_Getbintime().
+ */
+void _Timecounter_Getmicrotime( struct timeval *tv );
+
+/**
+ * @brief Returns the uptime in the bintime format.
+ *
+ * This function obtains the time with a lower overhead and lower accuracy
+ * compared to the _Timecounter_Binuptime() variant.
+ *
+ * @param[out] ts Returns the uptime.
+ */
+void _Timecounter_Getbinuptime( struct bintime *bt );
+
+/**
+ * @brief Returns the uptime in the timespec format.
+ *
+ * This function obtains the time with a lower overhead and lower accuracy
+ * compared to the _Timecounter_Nanouptime() variant.
+ *
+ * @param[out] ts Returns the uptime.
+ */
+void _Timecounter_Getnanouptime( struct timespec *ts );
+
+/**
+ * @brief Returns the uptime in the timeval format.
+ *
+ * This function obtains the time with a lower overhead and lower accuracy
+ * compared to the _Timecounter_Microuptime() variant.
+ *
+ * @param[out] tv Returns the uptime.
+ */
+void _Timecounter_Getmicrouptime( struct timeval *tv );
+
+/**
+ * @brief Returns the boot time in the timeval format.
+ *
+ * @param[out] tv Returns the boot time.
+ */
+void _Timecounter_Getboottime( struct timeval *tv );
+
+/**
+ * @brief Returns the boot time in the bintime format.
+ *
+ * @param[out] tv Returns the boot time.
+ */
+void _Timecounter_Getboottimebin( struct bintime *bt );
+
+/**
+ * @brief Installs the timecounter.
+ *
+ * The timecounter structure must contain valid values in the fields
+ * tc_get_timecount, tc_counter_mask, tc_frequency and tc_quality. All other
+ * fields must be zero initialized.
+ *
+ * @param[in] tc The timecounter.
+ */
+void _Timecounter_Install( struct timecounter *tc );
+
+/**
+ * @brief Performs a timecounter tick.
+ */
+void _Timecounter_Tick( void );
+
+/**
+ * @brief Lock to protect the timecounter mechanic.
+ */
+ISR_LOCK_DECLARE( extern, _Timecounter_Lock )
+
+/**
+ * @brief Acquires the timecounter lock.
+ *
+ * @param[in] lock_context The lock context.
+ *
+ * See _Timecounter_Tick_simple().
+ */
+#define _Timecounter_Acquire( lock_context ) \
+ _ISR_lock_ISR_disable_and_acquire( &_Timecounter_Lock, lock_context )
+
+/**
+ * @brief Performs a simple timecounter tick.
+ *
+ * This is a special purpose tick function for simple timecounter to support
+ * legacy clock drivers.
+ *
+ * @param[in] delta The time in timecounter ticks elapsed since the last call
+ * to _Timecounter_Tick_simple().
+ * @param[in] offset The current value of the timecounter.
+ * @param[in] lock_context The lock context of the corresponding
+ * _Timecounter_Acquire().
+ */
+void _Timecounter_Tick_simple(
+ uint32_t delta,
+ uint32_t offset,
+ ISR_lock_Context *lock_context
+);
+
+/**
+ * @brief The wall clock time in seconds.
+ */
+extern volatile time_t _Timecounter_Time_second;
+
+/**
+ * @brief The uptime in seconds.
+ *
+ * For compatibility with the FreeBSD network stack the initial value is one
+ * second.
+ */
+extern volatile int32_t _Timecounter_Time_uptime;
+
+/**
+ * @brief The current timecounter.
+ */
+extern struct timecounter *_Timecounter;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_TIMECOUNTER_H */
diff --git a/cpukit/include/rtems/score/timecounterimpl.h b/cpukit/include/rtems/score/timecounterimpl.h
new file mode 100644
index 0000000000..a48ac70683
--- /dev/null
+++ b/cpukit/include/rtems/score/timecounterimpl.h
@@ -0,0 +1,50 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreTimecounter
+ *
+ * @brief Timecounter Implementation
+ */
+
+/*
+ * Copyright (c) 2015 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_TIMECOUNTERIMPL_H
+#define _RTEMS_SCORE_TIMECOUNTERIMPL_H
+
+#include <rtems/score/timecounter.h>
+#include <sys/timetc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @addtogroup ScoreTimecounter
+ *
+ * @{
+ */
+
+void _Timecounter_Set_clock(
+ const struct bintime *bt,
+ ISR_lock_Context *lock_context
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_TIMECOUNTERIMPL_H */
diff --git a/cpukit/include/rtems/score/timespec.h b/cpukit/include/rtems/score/timespec.h
new file mode 100644
index 0000000000..72a000177f
--- /dev/null
+++ b/cpukit/include/rtems/score/timespec.h
@@ -0,0 +1,272 @@
+/**
+ * @file rtems/score/timespec.h
+ *
+ * This include file contains helpers for manipulating timespecs.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_TIMESPEC_H
+#define _RTEMS_SCORE_TIMESPEC_H
+
+/**
+ * @defgroup Timespec Helpers
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality related to manipulating
+ * POSIX struct timespecs.
+ */
+/**@{*/
+
+#include <stdbool.h> /* bool */
+#include <stdint.h> /* uint32_t */
+#include <time.h> /* struct timespec */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Set timespec to seconds nanosecond.
+ *
+ * This method sets the timespec to the specified seconds and nanoseconds
+ * value.
+ *
+ * @param[in] _time points to the timespec instance to validate.
+ * @param[in] _seconds is the seconds portion of the timespec
+ * @param[in] _nanoseconds is the nanoseconds portion of the timespec
+ */
+#define _Timespec_Set( _time, _seconds, _nanoseconds ) \
+ do { \
+ (_time)->tv_sec = (_seconds); \
+ (_time)->tv_nsec = (_nanoseconds); \
+ } while (0)
+
+/**
+ * @brief Sets the Timespec to Zero
+ *
+ * This method sets the timespec to zero.
+ * value.
+ *
+ * @param[in] _time points to the timespec instance to zero.
+ */
+#define _Timespec_Set_to_zero( _time ) \
+ do { \
+ (_time)->tv_sec = 0; \
+ (_time)->tv_nsec = 0; \
+ } while (0)
+
+/**
+ * @brief Get seconds portion of timespec.
+ *
+ * This method returns the seconds portion of the specified timespec
+ *
+ * @param[in] _time points to the timespec
+ *
+ * @retval The seconds portion of @a _time.
+ */
+#define _Timespec_Get_seconds( _time ) \
+ ((_time)->tv_sec)
+
+/**
+ * @brief Get nanoseconds portion of timespec.
+ *
+ * This method returns the nanoseconds portion of the specified timespec
+ *
+ * @param[in] _time points to the timespec
+ *
+ * @retval The nanoseconds portion of @a _time.
+ */
+#define _Timespec_Get_nanoseconds( _time ) \
+ ((_time)->tv_nsec)
+
+/**
+ * @brief Get the timestamp as nanoseconds.
+ *
+ * This method returns the timestamp as nanoseconds.
+ *
+ * @param[in] time points to the timestamp.
+ *
+ * @retval The time in nanoseconds.
+ */
+uint64_t _Timespec_Get_as_nanoseconds(
+ const struct timespec *time
+);
+
+/**
+ * @brief Check if timespec is valid.
+ *
+ * This method determines the validity of a timespec.
+ *
+ * @param[in] time is the timespec instance to validate.
+ *
+ * @retval This method returns true if @a time is valid and
+ * false otherwise.
+ */
+bool _Timespec_Is_valid(
+ const struct timespec *time
+);
+
+/**
+ * @brief The Timespec "less than" operator.
+ *
+ * This method is the less than operator for timespecs.
+ *
+ * @param[in] lhs is the left hand side timespec
+ * @param[in] rhs is the right hand side timespec
+ *
+ * @retval This method returns true if @a lhs is less than the @a rhs and
+ * false otherwise.
+ */
+bool _Timespec_Less_than(
+ const struct timespec *lhs,
+ const struct timespec *rhs
+);
+
+/**
+ * @brief The Timespec "greater than" operator.
+ *
+ * This method is the greater than operator for timespecs.
+ *
+ * @param[in] _lhs is the left hand side timespec
+ * @param[in] _rhs is the right hand side timespec
+ *
+ * @retval This method returns true if @a lhs is greater than the @a rhs and
+ * false otherwise.
+ */
+#define _Timespec_Greater_than( _lhs, _rhs ) \
+ _Timespec_Less_than( _rhs, _lhs )
+
+/**
+ * @brief The Timespec "equal to" operator.
+ *
+ * This method is the is equal to than operator for timespecs.
+ *
+ * @param[in] lhs is the left hand side timespec
+ * @param[in] rhs is the right hand side timespec
+ *
+ * @retval This method returns true if @a lhs is equal to @a rhs and
+ * false otherwise.
+ */
+#define _Timespec_Equal_to( lhs, rhs ) \
+ ( ((lhs)->tv_sec == (rhs)->tv_sec) && \
+ ((lhs)->tv_nsec == (rhs)->tv_nsec) \
+ )
+
+/**
+ * @brief Add two timespecs.
+ *
+ * This routine adds two timespecs. The second argument is added
+ * to the first.
+ *
+ * @param[in] time is the base time to be added to
+ * @param[in] add is the timespec to add to the first argument
+ *
+ * @retval This method returns the number of seconds @a time increased by.
+ */
+uint32_t _Timespec_Add_to(
+ struct timespec *time,
+ const struct timespec *add
+);
+
+/**
+ * @brief Convert timespec to number of ticks.
+ *
+ * This routine convert the @a time timespec to the corresponding number
+ * of clock ticks.
+ *
+ * @param[in] time is the time to be converted
+ *
+ * @retval This method returns the number of ticks computed.
+ */
+uint32_t _Timespec_To_ticks(
+ const struct timespec *time
+);
+
+/**
+ * @brief Convert ticks to timespec.
+ *
+ * This routine converts the @a ticks value to the corresponding
+ * timespec format @a time.
+ *
+ * @param[in] time is the timespec format time result
+ * @param[in] ticks is the number of ticks to convert
+ */
+void _Timespec_From_ticks(
+ uint32_t ticks,
+ struct timespec *time
+);
+
+/**
+ * @brief Subtract two timespec.
+ *
+ * This routine subtracts two timespecs. @a result is set to
+ * @a end - @a start.
+ *
+ * @param[in] start is the starting time
+ * @param[in] end is the ending time
+ * @param[in] result is the difference between starting and ending time.
+ *
+ * @retval This method fills in @a result.
+ */
+void _Timespec_Subtract(
+ const struct timespec *start,
+ const struct timespec *end,
+ struct timespec *result
+);
+
+/**
+ * @brief Divide timespec by an integer.
+ *
+ * This routine divides a timespec by an integer value. The expected
+ * use is to assist in benchmark calculations where you typically
+ * divide a duration by a number of iterations.
+ *
+ * @param[in] time is the total
+ * @param[in] iterations is the number of iterations
+ * @param[in] result is the average time.
+ *
+ * @retval This method fills in @a result.
+ */
+void _Timespec_Divide_by_integer(
+ const struct timespec *time,
+ uint32_t iterations,
+ struct timespec *result
+);
+
+/**
+ * @brief Divide a timespec by anonther timespec.
+ *
+ * This routine divides a timespec by another timespec. The
+ * intended use is for calculating percentages to three decimal points.
+ *
+ * @param[in] lhs is the left hand number
+ * @param[in] rhs is the right hand number
+ * @param[in] ival_percentage is the integer portion of the average
+ * @param[in] fval_percentage is the thousandths of percentage
+ *
+ * @retval This method fills in @a result.
+ */
+void _Timespec_Divide(
+ const struct timespec *lhs,
+ const struct timespec *rhs,
+ uint32_t *ival_percentage,
+ uint32_t *fval_percentage
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/timestamp.h b/cpukit/include/rtems/score/timestamp.h
new file mode 100644
index 0000000000..6fc17ced9c
--- /dev/null
+++ b/cpukit/include/rtems/score/timestamp.h
@@ -0,0 +1,323 @@
+/**
+ * @file rtems/score/timestamp.h
+ *
+ * @brief Helpers for Manipulating Timestamps
+ *
+ * This include file contains helpers for manipulating timestamps.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_TIMESTAMP_H
+#define _RTEMS_SCORE_TIMESTAMP_H
+
+/**
+ * @defgroup SuperCoreTimeStamp Score Timestamp
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality related to manipulating
+ * SuperCore Timestamps. SuperCore Timestamps may be used to
+ * represent time of day, uptime, or intervals.
+ *
+ * The key attribute of the SuperCore Timestamp handler is that it
+ * is a completely opaque handler. There can be multiple implementations
+ * of the required functionality and with a recompile, RTEMS can use
+ * any implementation. It is intended to be a simple wrapper.
+ *
+ * This handler can be implemented as either struct timespec or
+ * unsigned64 bit numbers. The use of a wrapper class allows the
+ * the implementation of timestamps to change on a per architecture
+ * basis. This is an important option as the performance of this
+ * handler is critical.
+ */
+/**@{*/
+
+#include <sys/time.h>
+
+#include <rtems/score/basedefs.h>
+#include <rtems/score/timespec.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Define the Timestamp control type.
+ */
+typedef sbintime_t Timestamp_Control;
+
+/**
+ * @brief Set timestamp to specified seconds and nanoseconds.
+ *
+ * This method sets the timestamp to the specified @a _seconds and @a _nanoseconds
+ * value.
+ *
+ * @param[in] _time points to the timestamp instance to validate.
+ * @param[in] _seconds is the seconds portion of the timestamp
+ * @param[in] _nanoseconds is the nanoseconds portion of the timestamp
+ */
+RTEMS_INLINE_ROUTINE void _Timestamp_Set(
+ Timestamp_Control *_time,
+ time_t _seconds,
+ long _nanoseconds
+)
+{
+ struct timespec _ts;
+
+ _ts.tv_sec = _seconds;
+ _ts.tv_nsec = _nanoseconds;
+
+ *_time = tstosbt(_ts);
+}
+
+/**
+ * @brief Sets the timestamp to zero.
+ *
+ * This method sets the timestamp to zero.
+ * value.
+ *
+ * @param[in] _time points to the timestamp instance to zero.
+ */
+
+RTEMS_INLINE_ROUTINE void _Timestamp_Set_to_zero(
+ Timestamp_Control *_time
+)
+{
+ *_time = 0;
+}
+
+/**
+ * @brief Less than operator for timestamps.
+ *
+ * This method is the less than operator for timestamps.
+ *
+ * @param[in] _lhs points to the left hand side timestamp
+ * @param[in] _rhs points to the right hand side timestamp
+ *
+ * @retval This method returns true if @a _lhs is less than the @a _rhs and
+ * false otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE bool _Timestamp_Less_than(
+ const Timestamp_Control *_lhs,
+ const Timestamp_Control *_rhs
+)
+{
+ return *_lhs < *_rhs;
+}
+
+/**
+ * @brief Greater than operator for timestamps.
+ *
+ * This method is the greater than operator for timestamps.
+ *
+ * @param[in] _lhs points to the left hand side timestamp
+ * @param[in] _rhs points to the right hand side timestamp
+ *
+ * @retval This method returns true if @a _lhs is greater than the @a _rhs and
+ * false otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE bool _Timestamp_Greater_than(
+ const Timestamp_Control *_lhs,
+ const Timestamp_Control *_rhs
+)
+{
+ return *_lhs > *_rhs;
+}
+
+/**
+ * @brief Equal to than operator for timestamps.
+ *
+ * This method is the is equal to than operator for timestamps.
+ *
+ * @param[in] _lhs points to the left hand side timestamp
+ * @param[in] _rhs points to the right hand side timestamp
+ *
+ * @retval This method returns true if @a _lhs is equal to @a _rhs and
+ * false otherwise.
+ */
+
+RTEMS_INLINE_ROUTINE bool _Timestamp_Equal_to(
+ const Timestamp_Control *_lhs,
+ const Timestamp_Control *_rhs
+)
+{
+ return *_lhs == *_rhs;
+}
+
+/**
+ * @brief Adds two timestamps.
+ *
+ * This routine adds two timestamps. The second argument is added
+ * to the first.
+ *
+ * @param[in] _time points to the base time to be added to
+ * @param[in] _add points to the timestamp to add to the first argument
+ */
+RTEMS_INLINE_ROUTINE void _Timestamp_Add_to(
+ Timestamp_Control *_time,
+ const Timestamp_Control *_add
+)
+{
+ *_time += *_add;
+}
+
+/**
+ * @brief Subtracts two timestamps.
+ *
+ * This routine subtracts two timestamps. @a result is set to
+ * @a end - @a start.
+ *
+ * @param[in] _start points to the starting time
+ * @param[in] _end points to the ending time
+ * @param[in] _result points to the difference between
+ * starting and ending time.
+ *
+ * @retval This method fills in @a _result.
+ */
+RTEMS_INLINE_ROUTINE void _Timestamp_Subtract(
+ const Timestamp_Control *_start,
+ const Timestamp_Control *_end,
+ Timestamp_Control *_result
+)
+{
+ *_result = *_end - *_start;
+}
+
+/**
+ * @brief Divides a timestamp by another timestamp.
+ *
+ * This routine divides a timestamp by another timestamp. The
+ * intended use is for calculating percentages to three decimal points.
+ *
+ * @param[in] _lhs points to the left hand number
+ * @param[in] _rhs points to the right hand number
+ * @param[in] _ival_percentage points to the integer portion of the average
+ * @param[in] _fval_percentage points to the thousandths of percentage
+ *
+ * @retval This method fills in @a result.
+ */
+RTEMS_INLINE_ROUTINE void _Timestamp_Divide(
+ const Timestamp_Control *_lhs,
+ const Timestamp_Control *_rhs,
+ uint32_t *_ival_percentage,
+ uint32_t *_fval_percentage
+)
+{
+ struct timespec _ts_left;
+ struct timespec _ts_right;
+
+ _ts_left = sbttots( *_lhs );
+ _ts_right = sbttots( *_rhs );
+
+ _Timespec_Divide(
+ &_ts_left,
+ &_ts_right,
+ _ival_percentage,
+ _fval_percentage
+ );
+}
+
+/**
+ * @brief Get seconds portion of timestamp.
+ *
+ * This method returns the seconds portion of the specified timestamp
+ *
+ * @param[in] _time points to the timestamp
+ *
+ * @retval The seconds portion of @a _time.
+ */
+RTEMS_INLINE_ROUTINE time_t _Timestamp_Get_seconds(
+ const Timestamp_Control *_time
+)
+{
+ return (*_time >> 32);
+}
+
+/**
+ * @brief Get nanoseconds portion of timestamp.
+ *
+ * This method returns the nanoseconds portion of the specified timestamp
+ *
+ * @param[in] _time points to the timestamp
+ *
+ * @retval The nanoseconds portion of @a _time.
+ */
+RTEMS_INLINE_ROUTINE uint32_t _Timestamp_Get_nanoseconds(
+ const Timestamp_Control *_time
+)
+{
+ struct timespec _ts;
+
+ _ts = sbttots( *_time );
+
+ return (uint32_t) _ts.tv_nsec;
+}
+
+/**
+ * @brief Get the timestamp as nanoseconds.
+ *
+ * This method returns the timestamp as nanoseconds.
+ *
+ * @param[in] _time points to the timestamp
+ *
+ * @retval The time in nanoseconds.
+ */
+RTEMS_INLINE_ROUTINE uint64_t _Timestamp_Get_as_nanoseconds(
+ const Timestamp_Control *_time
+)
+{
+ struct timespec _ts;
+
+ _ts = sbttots( *_time );
+
+ return _Timespec_Get_as_nanoseconds( &_ts );
+}
+
+/**
+ * @brief Convert timestamp to struct timespec.
+ *
+ * This method returns the seconds portion of the specified @a _timestamp.
+ *
+ * @param[in] _timestamp points to the timestamp
+ * @param[in] _timespec points to the timespec
+ */
+RTEMS_INLINE_ROUTINE void _Timestamp_To_timespec(
+ const Timestamp_Control *_timestamp,
+ struct timespec *_timespec
+)
+{
+ *_timespec = sbttots( *_timestamp );
+}
+
+/**
+ * @brief Convert timestamp to struct timeval.
+ *
+ * @param[in] _timestamp points to the timestamp
+ * @param[in] _timeval points to the timeval
+ */
+RTEMS_INLINE_ROUTINE void _Timestamp_To_timeval(
+ const Timestamp_Control *_timestamp,
+ struct timeval *_timeval
+)
+{
+ *_timeval = sbttotv( *_timestamp );
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/tls.h b/cpukit/include/rtems/score/tls.h
new file mode 100644
index 0000000000..644e54e6f7
--- /dev/null
+++ b/cpukit/include/rtems/score/tls.h
@@ -0,0 +1,217 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreTLS
+ *
+ * @brief Thread-Local Storage (TLS)
+ */
+
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_TLS_H
+#define _RTEMS_SCORE_TLS_H
+
+#include <rtems/score/cpu.h>
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup ScoreTLS Thread-Local Storage (TLS)
+ *
+ * @ingroup Score
+ *
+ * @brief Thread-local storage (TLS) support.
+ *
+ * Variants I and II are according to Ulrich Drepper, "ELF Handling For
+ * Thread-Local Storage".
+ *
+ * @{
+ */
+
+extern char _TLS_Data_begin[];
+
+extern char _TLS_Data_end[];
+
+extern char _TLS_Data_size[];
+
+extern char _TLS_BSS_begin[];
+
+extern char _TLS_BSS_end[];
+
+extern char _TLS_BSS_size[];
+
+extern char _TLS_Size[];
+
+extern char _TLS_Alignment[];
+
+typedef struct {
+ /*
+ * FIXME: Not sure if the generation number type is correct for all
+ * architectures.
+ */
+ uint32_t generation_number;
+
+ void *tls_blocks[1];
+} TLS_Dynamic_thread_vector;
+
+typedef struct TLS_Thread_control_block {
+#ifdef __i386__
+ struct TLS_Thread_control_block *tcb;
+#else
+ TLS_Dynamic_thread_vector *dtv;
+ uintptr_t reserved;
+#endif
+} TLS_Thread_control_block;
+
+typedef struct {
+ uintptr_t module;
+ uintptr_t offset;
+} TLS_Index;
+
+static inline uintptr_t _TLS_Get_size( void )
+{
+ /*
+ * Do not use _TLS_Size here since this will lead GCC to assume that this
+ * symbol is not 0 and the tests for 0 will be optimized away.
+ */
+ return (uintptr_t) _TLS_BSS_end - (uintptr_t) _TLS_Data_begin;
+}
+
+static inline uintptr_t _TLS_Heap_align_up( uintptr_t val )
+{
+ uintptr_t msk = CPU_HEAP_ALIGNMENT - 1;
+
+ return (val + msk) & ~msk;
+}
+
+static inline uintptr_t _TLS_Get_thread_control_block_area_size(
+ uintptr_t alignment
+)
+{
+ return alignment <= sizeof(TLS_Thread_control_block) ?
+ sizeof(TLS_Thread_control_block) : alignment;
+}
+
+static inline uintptr_t _TLS_Get_allocation_size(
+ uintptr_t size,
+ uintptr_t alignment
+)
+{
+ uintptr_t allocation_size = 0;
+
+ allocation_size += _TLS_Heap_align_up( size );
+ allocation_size += _TLS_Get_thread_control_block_area_size( alignment );
+
+#ifndef __i386__
+ allocation_size += sizeof(TLS_Dynamic_thread_vector);
+#endif
+
+ return allocation_size;
+}
+
+static inline void *_TLS_Copy_and_clear( void *tls_area )
+{
+ tls_area = memcpy(
+ tls_area,
+ _TLS_Data_begin,
+ (size_t) ((uintptr_t)_TLS_Data_size)
+ );
+
+
+ memset(
+ (char *) tls_area + (size_t)((intptr_t) _TLS_BSS_begin) -
+ (size_t)((intptr_t) _TLS_Data_begin),
+ 0,
+ ((size_t) (intptr_t)_TLS_BSS_size)
+ );
+
+ return tls_area;
+}
+
+static inline void *_TLS_Initialize(
+ void *tls_block,
+ TLS_Thread_control_block *tcb,
+ TLS_Dynamic_thread_vector *dtv
+)
+{
+#ifdef __i386__
+ (void) dtv;
+ tcb->tcb = tcb;
+#else
+ tcb->dtv = dtv;
+ dtv->generation_number = 1;
+ dtv->tls_blocks[0] = tls_block;
+#endif
+
+ return _TLS_Copy_and_clear( tls_block );
+}
+
+/* Use Variant I, TLS offsets emitted by linker takes the TCB into account */
+static inline void *_TLS_TCB_at_area_begin_initialize( void *tls_area )
+{
+ void *tls_block = (char *) tls_area
+ + _TLS_Get_thread_control_block_area_size( (uintptr_t) _TLS_Alignment );
+ TLS_Thread_control_block *tcb = tls_area;
+ uintptr_t aligned_size = _TLS_Heap_align_up( (uintptr_t) _TLS_Size );
+ TLS_Dynamic_thread_vector *dtv = (TLS_Dynamic_thread_vector *)
+ ((char *) tls_block + aligned_size);
+
+ return _TLS_Initialize( tls_block, tcb, dtv );
+}
+
+/* Use Variant I, TLS offsets emitted by linker neglects the TCB */
+static inline void *_TLS_TCB_before_TLS_block_initialize( void *tls_area )
+{
+ void *tls_block = (char *) tls_area
+ + _TLS_Get_thread_control_block_area_size( (uintptr_t) _TLS_Alignment );
+ TLS_Thread_control_block *tcb = (TLS_Thread_control_block *)
+ ((char *) tls_block - sizeof(*tcb));
+ uintptr_t aligned_size = _TLS_Heap_align_up( (uintptr_t) _TLS_Size );
+ TLS_Dynamic_thread_vector *dtv = (TLS_Dynamic_thread_vector *)
+ ((char *) tls_block + aligned_size);
+
+ return _TLS_Initialize( tls_block, tcb, dtv );
+}
+
+/* Use Variant II */
+static inline void *_TLS_TCB_after_TLS_block_initialize( void *tls_area )
+{
+ uintptr_t size = (uintptr_t) _TLS_Size;
+ uintptr_t tls_align = (uintptr_t) _TLS_Alignment;
+ uintptr_t tls_mask = tls_align - 1;
+ uintptr_t heap_align = _TLS_Heap_align_up( tls_align );
+ uintptr_t heap_mask = heap_align - 1;
+ TLS_Thread_control_block *tcb = (TLS_Thread_control_block *)
+ ((char *) tls_area + ((size + heap_mask) & ~heap_mask));
+ void *tls_block = (char *) tcb - ((size + tls_mask) & ~tls_mask);
+ TLS_Dynamic_thread_vector *dtv = (TLS_Dynamic_thread_vector *)
+ ((char *) tcb + sizeof(*tcb));
+
+ _TLS_Initialize( tls_block, tcb, dtv );
+
+ return tcb;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_TLS_H */
diff --git a/cpukit/include/rtems/score/tod.h b/cpukit/include/rtems/score/tod.h
new file mode 100644
index 0000000000..c0ab5e795d
--- /dev/null
+++ b/cpukit/include/rtems/score/tod.h
@@ -0,0 +1,32 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreTOD
+ *
+ * @brief Time of Day Handler API
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_TOD_H
+#define _RTEMS_SCORE_TOD_H
+
+#include <rtems/score/basedefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/todimpl.h b/cpukit/include/rtems/score/todimpl.h
new file mode 100644
index 0000000000..b00ab6cca2
--- /dev/null
+++ b/cpukit/include/rtems/score/todimpl.h
@@ -0,0 +1,304 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreTOD
+ *
+ * @brief Time of Day Handler API
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_TODIMPL_H
+#define _RTEMS_SCORE_TODIMPL_H
+
+#include <rtems/score/tod.h>
+#include <rtems/score/timestamp.h>
+#include <rtems/score/timecounterimpl.h>
+#include <rtems/score/watchdog.h>
+
+#include <sys/time.h>
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreTOD Time of Day Handler
+ *
+ * @ingroup Score
+ *
+ * The following constants are related to the time of day and are
+ * independent of RTEMS.
+ */
+/**@{*/
+
+/**
+ * This constant represents the number of seconds in a minute.
+ */
+#define TOD_SECONDS_PER_MINUTE (uint32_t)60
+
+/**
+ * This constant represents the number of minutes per hour.
+ */
+#define TOD_MINUTES_PER_HOUR (uint32_t)60
+
+/**
+ * This constant represents the number of months in a year.
+ */
+#define TOD_MONTHS_PER_YEAR (uint32_t)12
+
+/**
+ * This constant represents the number of days in a non-leap year.
+ */
+#define TOD_DAYS_PER_YEAR (uint32_t)365
+
+/**
+ * This constant represents the number of hours per day.
+ */
+#define TOD_HOURS_PER_DAY (uint32_t)24
+
+/**
+ * This constant represents the number of seconds in a day which does
+ * not include a leap second.
+ */
+#define TOD_SECONDS_PER_DAY (uint32_t) (TOD_SECONDS_PER_MINUTE * \
+ TOD_MINUTES_PER_HOUR * \
+ TOD_HOURS_PER_DAY)
+
+/**
+ * This constant represents the number of seconds in a non-leap year.
+ */
+#define TOD_SECONDS_PER_NON_LEAP_YEAR (365 * TOD_SECONDS_PER_DAY)
+
+/**
+ * This constant represents the number of millisecond in a second.
+ */
+#define TOD_MILLISECONDS_PER_SECOND (uint32_t)1000
+
+/**
+ * This constant represents the number of microseconds in a second.
+ */
+#define TOD_MICROSECONDS_PER_SECOND (uint32_t)1000000
+
+/**
+ * This constant represents the number of nanoseconds in a second.
+ */
+#define TOD_NANOSECONDS_PER_SECOND (uint32_t)1000000000
+
+/**
+ * This constant represents the number of nanoseconds in a mircosecond.
+ */
+#define TOD_NANOSECONDS_PER_MICROSECOND (uint32_t)1000
+
+/**@}*/
+
+/**
+ * Seconds from January 1, 1970 to January 1, 1988. Used to account for
+ * differences between POSIX API and RTEMS core. The timespec format time
+ * is kept in POSIX compliant form.
+ */
+#define TOD_SECONDS_1970_THROUGH_1988 \
+ (((1987 - 1970 + 1) * TOD_SECONDS_PER_NON_LEAP_YEAR) + \
+ (4 * TOD_SECONDS_PER_DAY))
+
+/**
+ * @brief Earliest year to which an time of day can be initialized.
+ *
+ * The following constant define the earliest year to which an
+ * time of day can be initialized. This is considered the
+ * epoch.
+ */
+#define TOD_BASE_YEAR 1988
+
+/**
+ * @defgroup ScoreTOD Time Of Day (TOD) Handler
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality used to manage time of day.
+ */
+/**@{*/
+
+/**
+ * @brief TOD control.
+ */
+typedef struct {
+ /**
+ * @brief Indicates if the time of day is set.
+ *
+ * This is true if the application has set the current
+ * time of day, and false otherwise.
+ */
+ bool is_set;
+} TOD_Control;
+
+extern TOD_Control _TOD;
+
+void _TOD_Lock( void );
+
+void _TOD_Unlock( void );
+
+#if defined(RTEMS_DEBUG)
+bool _TOD_Is_owner( void );
+#endif
+
+static inline void _TOD_Acquire( ISR_lock_Context *lock_context )
+{
+ _Timecounter_Acquire( lock_context );
+}
+
+/**
+ * @brief Sets the time of day.
+ *
+ * The caller must be the owner of the TOD lock.
+ *
+ * @param tod The new time of day in timespec format representing
+ * the time since UNIX Epoch.
+ * @param lock_context The ISR lock context used for the corresponding
+ * _TOD_Acquire(). The caller must be the owner of the TOD lock. This
+ * function will release the TOD lock.
+ */
+void _TOD_Set(
+ const struct timespec *tod,
+ ISR_lock_Context *lock_context
+);
+
+/**
+ * @brief Gets the current time in the timespec format.
+ *
+ * @param[out] time is the value gathered by the request
+ */
+static inline void _TOD_Get(
+ struct timespec *tod
+)
+{
+ _Timecounter_Nanotime( tod );
+}
+
+/**
+ * @brief Gets the system uptime with potential accuracy to the nanosecond.
+ *
+ * This routine returns the system uptime with potential accuracy
+ * to the nanosecond.
+ *
+ * The initial uptime value is undefined.
+ *
+ * @param[in] time is a pointer to the uptime to be returned
+ */
+static inline void _TOD_Get_uptime(
+ Timestamp_Control *time
+)
+{
+ *time = _Timecounter_Sbinuptime();
+}
+
+/**
+ * @brief Gets the system uptime with potential accuracy to the nanosecond.
+ * to the nanosecond.
+ *
+ * The initial uptime value is zero.
+ *
+ * @param[in] time is a pointer to the uptime to be returned
+ */
+static inline void _TOD_Get_zero_based_uptime(
+ Timestamp_Control *time
+)
+{
+ *time = _Timecounter_Sbinuptime() - SBT_1S;
+}
+
+/**
+ * @brief Gets the system uptime with potential accuracy to the nanosecond.
+ *
+ * The initial uptime value is zero.
+ *
+ * @param[in] time is a pointer to the uptime to be returned
+ */
+static inline void _TOD_Get_zero_based_uptime_as_timespec(
+ struct timespec *time
+)
+{
+ _Timecounter_Nanouptime( time );
+ --time->tv_sec;
+}
+
+/**
+ * @brief Number of seconds Since RTEMS epoch.
+ *
+ * The following contains the number of seconds from 00:00:00
+ * January 1, TOD_BASE_YEAR until the current time of day.
+ */
+static inline uint32_t _TOD_Seconds_since_epoch( void )
+{
+ return (uint32_t) _Timecounter_Time_second;
+}
+
+/**
+ * @brief Gets number of ticks in a second.
+ *
+ * This method returns the number of ticks in a second.
+ *
+ * @note If the clock tick value does not multiply evenly into a second
+ * then this number of ticks will be slightly shorter than a second.
+ */
+uint32_t TOD_TICKS_PER_SECOND_method(void);
+
+/**
+ * @brief Gets number of ticks in a second.
+ *
+ * This method exists to hide the fact that TOD_TICKS_PER_SECOND can not
+ * be implemented as a macro in a .h file due to visibility issues.
+ * The Configuration Table is not available to SuperCore .h files but
+ * is available to their .c files.
+ */
+#define TOD_TICKS_PER_SECOND TOD_TICKS_PER_SECOND_method()
+
+/**
+ * This routine returns a timeval based upon the internal timespec format TOD.
+ */
+
+RTEMS_INLINE_ROUTINE void _TOD_Get_timeval(
+ struct timeval *time
+)
+{
+ _Timecounter_Microtime( time );
+}
+
+/**
+ * @brief Adjust the Time of Time
+ *
+ * This method is used to adjust the current time of day by the
+ * specified amount.
+ *
+ * @param[in] delta is the amount to adjust
+ */
+void _TOD_Adjust(
+ const struct timespec *delta
+);
+
+/**
+ * @brief Check if the TOD is Set
+ *
+ * @return TRUE is the time is set. FALSE otherwise.
+ */
+RTEMS_INLINE_ROUTINE bool _TOD_Is_set( void )
+{
+ return _TOD.is_set;
+}
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/userext.h b/cpukit/include/rtems/score/userext.h
new file mode 100644
index 0000000000..5af5824808
--- /dev/null
+++ b/cpukit/include/rtems/score/userext.h
@@ -0,0 +1,273 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreUserExt
+ *
+ * @brief User Extension Handler API
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_USEREXT_H
+#define _RTEMS_SCORE_USEREXT_H
+
+#include <rtems/score/interr.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/thread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void User_extensions_routine RTEMS_DEPRECATED;
+
+/**
+ * @defgroup ScoreUserExt User Extension Handler
+ *
+ * @ingroup Score
+ *
+ * @brief The User Extension Handler provides invocation of application
+ * dependent routines at critical points in the life of each thread and the
+ * system as a whole.
+ */
+/**@{**/
+
+/**
+ * @brief Task create extension.
+ *
+ * It corresponds to _Thread_Initialize() (used by the rtems_task_create()
+ * directive and pthread_create()).
+ *
+ * It is invoked after the new thread has been completely initialized, but
+ * before it is placed on a ready chain.
+ *
+ * Thread dispatching may be disabled. This depends on the context of the
+ * _Thread_Initialize() call. Thread dispatch is disabled during the creation
+ * of the idle thread and the initialization threads. It can be considered as
+ * an invalid API usage, if the application calls _Thread_Initialize() with
+ * disabled thread dispatching. Disabled thread dispatching is different from
+ * disabled preemption.
+ *
+ * It can be assumed that the executing thread locked the allocator mutex.
+ * The only exception is the creation of the idle thread. In this case the
+ * allocator mutex is not locked. Since the allocator mutex allows nesting the
+ * normal memory allocation routines can be used.
+ *
+ * @param[in] executing The executing thread.
+ * @param[in] created The created thread.
+ *
+ * @retval true Successful operation.
+ * @retval false A thread create user extension will frequently attempt to
+ * allocate resources. If this allocation fails, then the extension should
+ * return @a false and the entire thread create operation will fail.
+ */
+typedef bool ( *User_extensions_thread_create_extension )(
+ Thread_Control *executing,
+ Thread_Control *created
+);
+
+/**
+ * @brief Task delete extension.
+ *
+ * It corresponds to _Thread_Close() (used by the rtems_task_delete()
+ * directive, pthread_exit() and pthread_cancel()).
+ *
+ * It is invoked before all resources of the thread are deleted. The executing
+ * and deleted arguments are never equal.
+ *
+ * Thread dispatching is enabled. The executing thread locked the allocator
+ * mutex.
+ *
+ * @param[in] executing The executing thread.
+ * @param[in] deleted The deleted thread.
+ */
+typedef void( *User_extensions_thread_delete_extension )(
+ Thread_Control *executing,
+ Thread_Control *deleted
+);
+
+/**
+ * @brief Task start extension.
+ *
+ * It corresponds to _Thread_Start() (used by the rtems_task_start()
+ * directive).
+ *
+ * It is invoked after the environment of the thread has been loaded and the
+ * thread has been made ready.
+ *
+ * Thread dispatching is disabled. The executing thread is not the holder of
+ * the allocator mutex.
+ *
+ * @param[in] executing The executing thread.
+ * @param[in] started The started thread.
+ */
+typedef void( *User_extensions_thread_start_extension )(
+ Thread_Control *executing,
+ Thread_Control *started
+);
+
+/**
+ * @brief Task restart extension.
+ *
+ * It corresponds to _Thread_Restart() (used by the rtems_task_restart()
+ * directive).
+ *
+ * It is invoked in the context of the restarted thread right before the
+ * execution context is reloaded. The executing and restarted arguments are
+ * always equal. The thread stack reflects the previous execution context.
+ *
+ * Thread dispatching is enabled. The thread is not the holder of the
+ * allocator mutex. The thread life is protected. Thread restart and delete
+ * requests issued by restart extensions lead to recursion.
+ *
+ * @param[in] executing The executing thread.
+ * @param[in] restarted The executing thread. Yes, the executing thread.
+ */
+typedef void( *User_extensions_thread_restart_extension )(
+ Thread_Control *executing,
+ Thread_Control *restarted
+);
+
+/**
+ * @brief Task switch extension.
+ *
+ * It corresponds to _Thread_Dispatch().
+ *
+ * It is invoked before the context switch from the executing to the heir
+ * thread.
+ *
+ * Thread dispatching is disabled. The state of the allocator mutex is
+ * arbitrary. Interrupts are disabled and the per-CPU lock is acquired on SMP
+ * configurations.
+ *
+ * The context switches initiated through _Thread_Start_multitasking() are not
+ * covered by this extension.
+ *
+ * @param[in] executing The executing thread.
+ * @param[in] heir The heir thread.
+ */
+typedef void( *User_extensions_thread_switch_extension )(
+ Thread_Control *executing,
+ Thread_Control *heir
+);
+
+/**
+ * @brief Task begin extension.
+ *
+ * It corresponds to _Thread_Handler().
+ *
+ * Thread dispatching is disabled. The executing thread is not the holder of
+ * the allocator mutex.
+ *
+ * @param[in] executing The executing thread.
+ */
+typedef void( *User_extensions_thread_begin_extension )(
+ Thread_Control *executing
+);
+
+/**
+ * @brief Task exitted extension.
+ *
+ * It corresponds to _Thread_Handler() after a return of the entry function.
+ *
+ * Thread dispatching is disabled. The state of the allocator mutex is
+ * arbitrary.
+ *
+ * @param[in] executing The executing thread.
+ */
+typedef void( *User_extensions_thread_exitted_extension )(
+ Thread_Control *executing
+);
+
+/**
+ * @brief Fatal error extension.
+ *
+ * It corresponds to _Terminate() (used by the rtems_fatal() directive).
+ *
+ * This extension should not call any RTEMS directives.
+ *
+ * @param[in] source The fatal source indicating the subsystem the fatal
+ * condition originated in.
+ * @param[in] always_set_to_false This parameter is always set to false and
+ * provided only for backward compatibility reasons.
+ * @param[in] code The fatal error code. This value must be interpreted with
+ * respect to the source.
+ */
+typedef void( *User_extensions_fatal_extension )(
+ Internal_errors_Source source,
+ bool always_set_to_false,
+ Internal_errors_t code
+);
+
+/**
+ * @brief Task termination extension.
+ *
+ * This extension is invoked by _Thread_Life_action_handler() in case a
+ * termination request is recognized.
+ *
+ * It is invoked in the context of the terminated thread right before the
+ * thread dispatch to the heir thread. The POSIX cleanup and key destructors
+ * execute in this context.
+ *
+ * Thread dispatching is enabled. The thread is not the holder of the
+ * allocator mutex. The thread life is protected. Thread restart and delete
+ * requests issued by terminate extensions lead to recursion.
+ *
+ * @param[in] terminated The terminated thread.
+ */
+typedef void( *User_extensions_thread_terminate_extension )(
+ Thread_Control *terminated
+);
+
+/**
+ * @brief User extension table.
+ */
+typedef struct {
+ User_extensions_thread_create_extension thread_create;
+ User_extensions_thread_start_extension thread_start;
+ User_extensions_thread_restart_extension thread_restart;
+ User_extensions_thread_delete_extension thread_delete;
+ User_extensions_thread_switch_extension thread_switch;
+ User_extensions_thread_begin_extension thread_begin;
+ User_extensions_thread_exitted_extension thread_exitted;
+ User_extensions_fatal_extension fatal;
+ User_extensions_thread_terminate_extension thread_terminate;
+} User_extensions_Table;
+
+/**
+ * @brief Manages the switch callouts.
+ *
+ * They are managed separately from other extensions for performance reasons.
+ */
+typedef struct {
+ Chain_Node Node;
+ User_extensions_thread_switch_extension thread_switch;
+} User_extensions_Switch_control;
+
+/**
+ * @brief Manages each user extension set.
+ *
+ * The switch control is part of the extensions control even if not used due to
+ * the extension not having a switch handler.
+ */
+typedef struct {
+ Chain_Node Node;
+ User_extensions_Switch_control Switch;
+ User_extensions_Table Callouts;
+} User_extensions_Control;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/userextimpl.h b/cpukit/include/rtems/score/userextimpl.h
new file mode 100644
index 0000000000..5ad2c63765
--- /dev/null
+++ b/cpukit/include/rtems/score/userextimpl.h
@@ -0,0 +1,369 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreUserExt
+ *
+ * @brief User Extension Handler API
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_USEREXTIMPL_H
+#define _RTEMS_SCORE_USEREXTIMPL_H
+
+#include <rtems/score/userext.h>
+#include <rtems/score/isrlock.h>
+#include <rtems/score/chainimpl.h>
+#include <rtems/score/percpu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreUserExt User Extension Handler
+ *
+ * @ingroup Score
+ *
+ * @addtogroup ScoreUserExt
+ */
+/**@{**/
+
+/**
+ * @brief Chain iterator for dynamic user extensions.
+ *
+ * Since user extensions may delete or restart the executing thread, we must
+ * clean up registered iterators.
+ *
+ * @see _User_extensions_Iterate(), _User_extensions_Destroy_iterators() and
+ * Thread_Control::last_user_extensions_iterator.
+ */
+typedef struct User_extensions_Iterator {
+ Chain_Iterator Iterator;
+ struct User_extensions_Iterator *previous;
+} User_extensions_Iterator;
+
+typedef struct {
+ /**
+ * @brief Active dynamically added user extensions.
+ */
+ Chain_Control Active;
+
+ /**
+ * @brief Chain iterator registration.
+ */
+ Chain_Iterator_registry Iterators;
+
+ /**
+ * @brief Lock to protect User_extensions_List::Active and
+ * User_extensions_List::Iterators.
+ */
+ ISR_LOCK_MEMBER( Lock )
+} User_extensions_List;
+
+/**
+ * @brief List of active extensions.
+ */
+extern User_extensions_List _User_extensions_List;
+
+/**
+ * @brief List of active task switch extensions.
+ */
+extern Chain_Control _User_extensions_Switches_list;
+
+/**
+ * @name Extension Maintainance
+ */
+/**@{**/
+
+void _User_extensions_Handler_initialization( void );
+
+void _User_extensions_Add_set(
+ User_extensions_Control *extension
+);
+
+RTEMS_INLINE_ROUTINE void _User_extensions_Add_API_set(
+ User_extensions_Control *extension
+)
+{
+ _User_extensions_Add_set( extension );
+}
+
+RTEMS_INLINE_ROUTINE void _User_extensions_Add_set_with_table(
+ User_extensions_Control *extension,
+ const User_extensions_Table *extension_table
+)
+{
+ extension->Callouts = *extension_table;
+
+ _User_extensions_Add_set( extension );
+}
+
+void _User_extensions_Remove_set(
+ User_extensions_Control *extension
+);
+
+/**
+ * @brief User extension visitor.
+ *
+ * @param[in, out] executing The currently executing thread.
+ * @param[in, out] arg The argument passed to _User_extensions_Iterate().
+ * @param[in] callouts The current callouts.
+ */
+typedef void (*User_extensions_Visitor)(
+ Thread_Control *executing,
+ void *arg,
+ const User_extensions_Table *callouts
+);
+
+typedef struct {
+ Thread_Control *created;
+ bool ok;
+} User_extensions_Thread_create_context;
+
+void _User_extensions_Thread_create_visitor(
+ Thread_Control *executing,
+ void *arg,
+ const User_extensions_Table *callouts
+);
+
+void _User_extensions_Thread_delete_visitor(
+ Thread_Control *executing,
+ void *arg,
+ const User_extensions_Table *callouts
+);
+
+void _User_extensions_Thread_start_visitor(
+ Thread_Control *executing,
+ void *arg,
+ const User_extensions_Table *callouts
+);
+
+void _User_extensions_Thread_restart_visitor(
+ Thread_Control *executing,
+ void *arg,
+ const User_extensions_Table *callouts
+);
+
+void _User_extensions_Thread_begin_visitor(
+ Thread_Control *executing,
+ void *arg,
+ const User_extensions_Table *callouts
+);
+
+void _User_extensions_Thread_exitted_visitor(
+ Thread_Control *executing,
+ void *arg,
+ const User_extensions_Table *callouts
+);
+
+typedef struct {
+ Internal_errors_Source source;
+ Internal_errors_t error;
+} User_extensions_Fatal_context;
+
+void _User_extensions_Fatal_visitor(
+ Thread_Control *executing,
+ void *arg,
+ const User_extensions_Table *callouts
+);
+
+void _User_extensions_Thread_terminate_visitor(
+ Thread_Control *executing,
+ void *arg,
+ const User_extensions_Table *callouts
+);
+
+/**
+ * @brief Iterates through all user extensions and calls the visitor for each.
+ *
+ * @param[in, out] arg The argument passed to the visitor.
+ * @param[in] visitor The visitor for each extension.
+ * @param[in] direction The iteration direction for dynamic extensions.
+ */
+void _User_extensions_Iterate(
+ void *arg,
+ User_extensions_Visitor visitor,
+ Chain_Iterator_direction direction
+);
+
+/** @} */
+
+/**
+ * @name Extension Callout Dispatcher
+ */
+/**@{**/
+
+static inline bool _User_extensions_Thread_create( Thread_Control *created )
+{
+ User_extensions_Thread_create_context ctx = { created, true };
+
+ _User_extensions_Iterate(
+ &ctx,
+ _User_extensions_Thread_create_visitor,
+ CHAIN_ITERATOR_FORWARD
+ );
+
+ return ctx.ok;
+}
+
+static inline void _User_extensions_Thread_delete( Thread_Control *deleted )
+{
+ _User_extensions_Iterate(
+ deleted,
+ _User_extensions_Thread_delete_visitor,
+ CHAIN_ITERATOR_BACKWARD
+ );
+}
+
+static inline void _User_extensions_Thread_start( Thread_Control *started )
+{
+ _User_extensions_Iterate(
+ started,
+ _User_extensions_Thread_start_visitor,
+ CHAIN_ITERATOR_FORWARD
+ );
+}
+
+static inline void _User_extensions_Thread_restart( Thread_Control *restarted )
+{
+ _User_extensions_Iterate(
+ restarted,
+ _User_extensions_Thread_restart_visitor,
+ CHAIN_ITERATOR_FORWARD
+ );
+}
+
+static inline void _User_extensions_Thread_begin( Thread_Control *executing )
+{
+ _User_extensions_Iterate(
+ executing,
+ _User_extensions_Thread_begin_visitor,
+ CHAIN_ITERATOR_FORWARD
+ );
+}
+
+static inline void _User_extensions_Thread_switch(
+ Thread_Control *executing,
+ Thread_Control *heir
+)
+{
+ const Chain_Control *chain = &_User_extensions_Switches_list;
+ const Chain_Node *tail = _Chain_Immutable_tail( chain );
+ const Chain_Node *node = _Chain_Immutable_first( chain );
+
+ if ( node != tail ) {
+ Per_CPU_Control *cpu_self;
+#if defined(RTEMS_SMP)
+ ISR_Level level;
+#endif
+
+ cpu_self = _Per_CPU_Get();
+
+#if defined(RTEMS_SMP)
+ _ISR_Local_disable( level );
+#endif
+ _Per_CPU_Acquire( cpu_self );
+
+ while ( node != tail ) {
+ const User_extensions_Switch_control *extension =
+ (const User_extensions_Switch_control *) node;
+
+ (*extension->thread_switch)( executing, heir );
+
+ node = _Chain_Immutable_next( node );
+ }
+
+ _Per_CPU_Release( cpu_self );
+#if defined(RTEMS_SMP)
+ _ISR_Local_enable( level );
+#endif
+ }
+}
+
+static inline void _User_extensions_Thread_exitted( Thread_Control *executing )
+{
+ _User_extensions_Iterate(
+ executing,
+ _User_extensions_Thread_exitted_visitor,
+ CHAIN_ITERATOR_FORWARD
+ );
+}
+
+static inline void _User_extensions_Fatal(
+ Internal_errors_Source source,
+ Internal_errors_t error
+)
+{
+ User_extensions_Fatal_context ctx = { source, error };
+
+ _User_extensions_Iterate(
+ &ctx,
+ _User_extensions_Fatal_visitor,
+ CHAIN_ITERATOR_FORWARD
+ );
+}
+
+static inline void _User_extensions_Thread_terminate(
+ Thread_Control *executing
+)
+{
+ _User_extensions_Iterate(
+ executing,
+ _User_extensions_Thread_terminate_visitor,
+ CHAIN_ITERATOR_BACKWARD
+ );
+}
+
+static inline void _User_extensions_Acquire( ISR_lock_Context *lock_context )
+{
+ _ISR_lock_ISR_disable_and_acquire(
+ &_User_extensions_List.Lock,
+ lock_context
+ );
+}
+
+static inline void _User_extensions_Release( ISR_lock_Context *lock_context )
+{
+ _ISR_lock_Release_and_ISR_enable(
+ &_User_extensions_List.Lock,
+ lock_context
+ );
+}
+
+static inline void _User_extensions_Destroy_iterators(
+ Thread_Control *the_thread
+)
+{
+ ISR_lock_Context lock_context;
+ User_extensions_Iterator *iter;
+
+ _User_extensions_Acquire( &lock_context );
+
+ iter = the_thread->last_user_extensions_iterator;
+
+ while ( iter != NULL ) {
+ _Chain_Iterator_destroy( &iter->Iterator );
+ iter = iter->previous;
+ }
+
+ _User_extensions_Release( &lock_context );
+}
+
+/** @} */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/watchdog.h b/cpukit/include/rtems/score/watchdog.h
new file mode 100644
index 0000000000..dbb092bbef
--- /dev/null
+++ b/cpukit/include/rtems/score/watchdog.h
@@ -0,0 +1,166 @@
+/**
+ * @file rtems/score/watchdog.h
+ *
+ * @brief Constants and Structures Associated with Watchdog Timers
+ *
+ * This include file contains all the constants and structures associated
+ * with watchdog timers. This Handler provides mechanisms which can be
+ * used to initialize and manipulate watchdog timers.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_WATCHDOG_H
+#define _RTEMS_SCORE_WATCHDOG_H
+
+#include <rtems/score/basedefs.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/rbtree.h>
+
+struct Per_CPU_Control;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreWatchdog Watchdog Handler
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality related to the scheduling of
+ * watchdog functions to be called at specific times in the future.
+ *
+ * @note This handler does not have anything to do with hardware watchdog
+ * timers.
+ */
+/**@{*/
+
+typedef struct Watchdog_Control Watchdog_Control;
+
+/**
+ * @brief Type is used to specify the length of intervals.
+ *
+ * This type is used to specify the length of intervals.
+ */
+typedef uint32_t Watchdog_Interval;
+
+/**
+ * @brief Special watchdog ticks value to indicate an infinite wait.
+ */
+#define WATCHDOG_NO_TIMEOUT 0
+
+/**
+ * @brief Return type from a Watchdog Service Routine.
+ *
+ * This type defines the return type from a Watchdog Service Routine.
+ */
+typedef void Watchdog_Service_routine;
+
+/**
+ * @brief Pointer to a watchdog service routine.
+ *
+ * This type define a pointer to a watchdog service routine.
+ */
+typedef Watchdog_Service_routine
+ ( *Watchdog_Service_routine_entry )( Watchdog_Control * );
+
+/**
+ * @brief The watchdog header to manage scheduled watchdogs.
+ */
+typedef struct {
+ /**
+ * @brief Red-black tree of scheduled watchdogs sorted by expiration time.
+ */
+ RBTree_Control Watchdogs;
+
+ /**
+ * @brief The scheduled watchdog with the earliest expiration time or NULL in
+ * case no watchdog is scheduled.
+ */
+ RBTree_Node *first;
+} Watchdog_Header;
+
+/**
+ * @brief The control block used to manage each watchdog timer.
+ *
+ * The following record defines the control block used
+ * to manage each watchdog timer.
+ */
+struct Watchdog_Control {
+ /**
+ * @brief Nodes for the watchdog.
+ */
+ union {
+ /**
+ * @brief this field is a red-black tree node structure and allows this to
+ * be placed on a red-black tree used to manage the scheduled watchdogs.
+ */
+ RBTree_Node RBTree;
+
+ /**
+ * @brief this field is a chain node structure and allows this to be placed
+ * on a chain used to manage pending watchdogs by the timer server.
+ */
+ Chain_Node Chain;
+ } Node;
+
+#if defined(RTEMS_SMP)
+ /** @brief This field references the processor of this watchdog control. */
+ struct Per_CPU_Control *cpu;
+#endif
+
+ /** @brief This field is the function to invoke. */
+ Watchdog_Service_routine_entry routine;
+
+ /** @brief This field is the expiration time point. */
+ uint64_t expire;
+};
+
+/**
+ * @brief The watchdog ticks counter.
+ *
+ * With a 1ms watchdog tick, this counter overflows after 50 days since boot.
+ */
+extern volatile Watchdog_Interval _Watchdog_Ticks_since_boot;
+
+/**
+ * @brief The watchdog nanoseconds per tick.
+ *
+ * This constant is defined by the application configuration via
+ * <rtems/confdefs.h>.
+ */
+extern const uint32_t _Watchdog_Nanoseconds_per_tick;
+
+/**
+ * @brief The watchdog ticks per second.
+ *
+ * This constant is defined by the application configuration via
+ * <rtems/confdefs.h>.
+ */
+extern const uint32_t _Watchdog_Ticks_per_second;
+
+/**
+ * @brief The maximum number of seconds representable in the monotonic watchdog
+ * format.
+ *
+ * This constant is defined by the application configuration via
+ * <rtems/confdefs.h>.
+ */
+extern const uint64_t _Watchdog_Monotonic_max_seconds;
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/watchdogimpl.h b/cpukit/include/rtems/score/watchdogimpl.h
new file mode 100644
index 0000000000..f219a70768
--- /dev/null
+++ b/cpukit/include/rtems/score/watchdogimpl.h
@@ -0,0 +1,574 @@
+/**
+ * @file
+ *
+ * @brief Inlined Routines in the Watchdog Handler
+ *
+ * This file contains the static inline implementation of all inlined
+ * routines in the Watchdog Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2004.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_WATCHDOGIMPL_H
+#define _RTEMS_SCORE_WATCHDOGIMPL_H
+
+#include <rtems/score/watchdog.h>
+#include <rtems/score/assert.h>
+#include <rtems/score/isrlock.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/rbtreeimpl.h>
+
+#include <sys/types.h>
+#include <sys/timespec.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreWatchdog
+ * @{
+ */
+
+/**
+ * @brief Watchdog states.
+ */
+typedef enum {
+ /**
+ * @brief The watchdog is scheduled and a black node in the red-black tree.
+ */
+ WATCHDOG_SCHEDULED_BLACK,
+
+ /**
+ * @brief The watchdog is scheduled and a red node in the red-black tree.
+ */
+ WATCHDOG_SCHEDULED_RED,
+
+ /**
+ * @brief The watchdog is inactive.
+ */
+ WATCHDOG_INACTIVE,
+
+ /**
+ * @brief The watchdog is on a chain of pending watchdogs.
+ *
+ * This state is used by the timer server for example.
+ */
+ WATCHDOG_PENDING
+} Watchdog_State;
+
+/**
+ * @brief Watchdog initializer for static initialization.
+ *
+ * The processor of this watchdog is set to processor with index zero.
+ *
+ * @see _Watchdog_Preinitialize().
+ */
+#if defined(RTEMS_SMP)
+ #define WATCHDOG_INITIALIZER( routine ) \
+ { \
+ { { { NULL, NULL, NULL, WATCHDOG_INACTIVE } } }, \
+ &_Per_CPU_Information[ 0 ].per_cpu, \
+ ( routine ), \
+ 0 \
+ }
+#else
+ #define WATCHDOG_INITIALIZER( routine ) \
+ { \
+ { { { NULL, NULL, NULL, WATCHDOG_INACTIVE } } }, \
+ ( routine ), \
+ 0 \
+ }
+#endif
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Header_initialize(
+ Watchdog_Header *header
+)
+{
+ _RBTree_Initialize_empty( &header->Watchdogs );
+ header->first = NULL;
+}
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Header_destroy(
+ Watchdog_Header *header
+)
+{
+ /* Do nothing */
+ (void) header;
+}
+
+/**
+ * @brief Performs a watchdog tick.
+ *
+ * @param cpu The processor for this watchdog tick.
+ */
+void _Watchdog_Tick( struct Per_CPU_Control *cpu );
+
+RTEMS_INLINE_ROUTINE Watchdog_State _Watchdog_Get_state(
+ const Watchdog_Control *the_watchdog
+)
+{
+ return RB_COLOR( &the_watchdog->Node.RBTree, Node );
+}
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Set_state(
+ Watchdog_Control *the_watchdog,
+ Watchdog_State state
+)
+{
+ RB_COLOR( &the_watchdog->Node.RBTree, Node ) = state;
+}
+
+RTEMS_INLINE_ROUTINE Per_CPU_Control *_Watchdog_Get_CPU(
+ const Watchdog_Control *the_watchdog
+)
+{
+#if defined(RTEMS_SMP)
+ return the_watchdog->cpu;
+#else
+ return _Per_CPU_Get_by_index( 0 );
+#endif
+}
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Set_CPU(
+ Watchdog_Control *the_watchdog,
+ Per_CPU_Control *cpu
+)
+{
+#if defined(RTEMS_SMP)
+ the_watchdog->cpu = cpu;
+#else
+ (void) cpu;
+#endif
+}
+
+/**
+ * @brief Pre-initializes a watchdog.
+ *
+ * This routine must be called before a watchdog is used in any way. The
+ * exception are statically initialized watchdogs via WATCHDOG_INITIALIZER().
+ *
+ * @param[in] the_watchdog The uninitialized watchdog.
+ */
+RTEMS_INLINE_ROUTINE void _Watchdog_Preinitialize(
+ Watchdog_Control *the_watchdog,
+ Per_CPU_Control *cpu
+)
+{
+ _Watchdog_Set_CPU( the_watchdog, cpu );
+ _Watchdog_Set_state( the_watchdog, WATCHDOG_INACTIVE );
+
+#if defined(RTEMS_DEBUG)
+ the_watchdog->routine = NULL;
+ the_watchdog->expire = 0;
+#endif
+}
+
+/**
+ * @brief Initializes a watchdog with a new service routine.
+ *
+ * The watchdog must be inactive.
+ */
+RTEMS_INLINE_ROUTINE void _Watchdog_Initialize(
+ Watchdog_Control *the_watchdog,
+ Watchdog_Service_routine_entry routine
+)
+{
+ _Assert( _Watchdog_Get_state( the_watchdog ) == WATCHDOG_INACTIVE );
+ the_watchdog->routine = routine;
+}
+
+void _Watchdog_Do_tickle(
+ Watchdog_Header *header,
+ uint64_t now,
+#if defined(RTEMS_SMP)
+ ISR_lock_Control *lock,
+#endif
+ ISR_lock_Context *lock_context
+);
+
+#if defined(RTEMS_SMP)
+ #define _Watchdog_Tickle( header, now, lock, lock_context ) \
+ _Watchdog_Do_tickle( header, now, lock, lock_context )
+#else
+ #define _Watchdog_Tickle( header, now, lock, lock_context ) \
+ _Watchdog_Do_tickle( header, now, lock_context )
+#endif
+
+/**
+ * @brief Inserts a watchdog into the set of scheduled watchdogs according to
+ * the specified expiration time.
+ *
+ * The watchdog must be inactive.
+ */
+void _Watchdog_Insert(
+ Watchdog_Header *header,
+ Watchdog_Control *the_watchdog,
+ uint64_t expire
+);
+
+/**
+ * @brief In case the watchdog is scheduled, then it is removed from the set of
+ * scheduled watchdogs.
+ *
+ * The watchdog must be initialized before this call.
+ */
+void _Watchdog_Remove(
+ Watchdog_Header *header,
+ Watchdog_Control *the_watchdog
+);
+
+/**
+ * @brief In case the watchdog is scheduled, then it is removed from the set of
+ * scheduled watchdogs.
+ *
+ * The watchdog must be initialized before this call.
+ *
+ * @retval 0 The now time is greater than or equal to the expiration time of
+ * the watchdog.
+ * @retval other The difference of the now and expiration time.
+ */
+RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Cancel(
+ Watchdog_Header *header,
+ Watchdog_Control *the_watchdog,
+ uint64_t now
+)
+{
+ uint64_t expire;
+ uint64_t remaining;
+
+ expire = the_watchdog->expire;
+
+ if ( now < expire ) {
+ remaining = expire - now;
+ } else {
+ remaining = 0;
+ }
+
+ _Watchdog_Remove( header, the_watchdog );
+
+ return remaining;
+}
+
+RTEMS_INLINE_ROUTINE bool _Watchdog_Is_scheduled(
+ const Watchdog_Control *the_watchdog
+)
+{
+ return _Watchdog_Get_state( the_watchdog ) < WATCHDOG_INACTIVE;
+}
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Next_first(
+ Watchdog_Header *header,
+ Watchdog_Control *the_watchdog
+)
+{
+ RBTree_Node *node = _RBTree_Right( &the_watchdog->Node.RBTree );
+
+ if ( node != NULL ) {
+ RBTree_Node *left;
+
+ while ( ( left = _RBTree_Left( node ) ) != NULL ) {
+ node = left;
+ }
+
+ header->first = node;
+ } else {
+ header->first = _RBTree_Parent( &the_watchdog->Node.RBTree );
+ }
+}
+
+/**
+ * @brief The maximum watchdog ticks value for the far future.
+ */
+#define WATCHDOG_MAXIMUM_TICKS UINT64_MAX
+
+#define WATCHDOG_NANOSECONDS_PER_SECOND 1000000000
+
+/**
+ * @brief The bits necessary to store 1000000000
+ * (= WATCHDOG_NANOSECONDS_PER_SECOND) nanoseconds.
+ *
+ * The expiration time is an unsigned 64-bit integer. To store absolute
+ * timeouts we use 30 bits (2**30 == 1073741824) for the nanoseconds and 34
+ * bits for the seconds since UNIX Epoch. This leads to a year 2514 problem.
+ */
+#define WATCHDOG_BITS_FOR_1E9_NANOSECONDS 30
+
+/**
+ * @brief The maximum number of seconds representable in the realtime watchdog
+ * format.
+ *
+ * We have 2**34 bits for the seconds part.
+ */
+#define WATCHDOG_REALTIME_MAX_SECONDS 0x3ffffffff
+
+RTEMS_INLINE_ROUTINE bool _Watchdog_Is_valid_timespec(
+ const struct timespec *ts
+)
+{
+ return ts != NULL
+ && (unsigned long) ts->tv_nsec < WATCHDOG_NANOSECONDS_PER_SECOND;
+}
+
+RTEMS_INLINE_ROUTINE bool _Watchdog_Is_valid_interval_timespec(
+ const struct timespec *ts
+)
+{
+ return _Watchdog_Is_valid_timespec( ts ) && ts->tv_sec >= 0;
+}
+
+RTEMS_INLINE_ROUTINE const struct timespec * _Watchdog_Future_timespec(
+ struct timespec *now,
+ const struct timespec *delta
+)
+{
+ uint64_t sec;
+
+ if ( !_Watchdog_Is_valid_interval_timespec( delta ) ) {
+ return NULL;
+ }
+
+ sec = (uint64_t) now->tv_sec;
+ sec += (uint64_t) delta->tv_sec;
+ now->tv_nsec += delta->tv_nsec;
+
+ /* We have 2 * (2**63 - 1) + 1 == UINT64_MAX */
+ if ( now->tv_nsec >= WATCHDOG_NANOSECONDS_PER_SECOND ) {
+ now->tv_nsec -= WATCHDOG_NANOSECONDS_PER_SECOND;
+ ++sec;
+ }
+
+ if ( sec <= INT64_MAX ) {
+ now->tv_sec = sec;
+ } else {
+ now->tv_sec = INT64_MAX;
+ }
+
+ return now;
+}
+
+RTEMS_INLINE_ROUTINE bool _Watchdog_Is_far_future_monotonic_timespec(
+ const struct timespec *ts
+)
+{
+ return ts->tv_sec >= _Watchdog_Monotonic_max_seconds;
+}
+
+RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Monotonic_from_timespec(
+ const struct timespec *ts
+)
+{
+ uint64_t ticks;
+
+ _Assert( _Watchdog_Is_valid_timespec( ts ) );
+ _Assert( ts->tv_sec >= 0 );
+ _Assert( !_Watchdog_Is_far_future_monotonic_timespec( ts ) );
+
+ ticks = (uint64_t) ts->tv_sec * _Watchdog_Ticks_per_second;
+ ticks += (unsigned long) ts->tv_nsec / _Watchdog_Nanoseconds_per_tick;
+
+ return ticks;
+}
+
+RTEMS_INLINE_ROUTINE bool _Watchdog_Is_far_future_realtime_timespec(
+ const struct timespec *ts
+)
+{
+ return ts->tv_sec > WATCHDOG_REALTIME_MAX_SECONDS;
+}
+
+RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Realtime_from_seconds(
+ uint32_t seconds
+)
+{
+ uint64_t ticks = seconds;
+
+ ticks <<= WATCHDOG_BITS_FOR_1E9_NANOSECONDS;
+
+ return ticks;
+}
+
+RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Realtime_from_timespec(
+ const struct timespec *ts
+)
+{
+ uint64_t ticks;
+
+ _Assert( _Watchdog_Is_valid_timespec( ts ) );
+ _Assert( ts->tv_sec >= 0 );
+ _Assert( !_Watchdog_Is_far_future_realtime_timespec( ts ) );
+
+ ticks = (uint64_t) ts->tv_sec;
+ ticks <<= WATCHDOG_BITS_FOR_1E9_NANOSECONDS;
+ ticks |= (uint32_t) ts->tv_nsec;
+
+ return ticks;
+}
+
+RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Realtime_from_sbintime(
+ sbintime_t sbt
+)
+{
+ uint64_t ticks = ( sbt >> 32 ) << WATCHDOG_BITS_FOR_1E9_NANOSECONDS;
+
+ ticks |= ( (uint64_t) 1000000000 * (uint32_t) sbt ) >> 32;
+
+ return ticks;
+}
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_acquire_critical(
+ Per_CPU_Control *cpu,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Acquire( &cpu->Watchdog.Lock, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_release_critical(
+ Per_CPU_Control *cpu,
+ ISR_lock_Context *lock_context
+)
+{
+ _ISR_lock_Release( &cpu->Watchdog.Lock, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Per_CPU_insert_ticks(
+ Watchdog_Control *the_watchdog,
+ Per_CPU_Control *cpu,
+ Watchdog_Interval ticks
+)
+{
+ ISR_lock_Context lock_context;
+ Watchdog_Header *header;
+ uint64_t expire;
+
+ header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ];
+
+ _Watchdog_Set_CPU( the_watchdog, cpu );
+
+ _Watchdog_Per_CPU_acquire_critical( cpu, &lock_context );
+ expire = ticks + cpu->Watchdog.ticks;
+ _Watchdog_Insert(header, the_watchdog, expire);
+ _Watchdog_Per_CPU_release_critical( cpu, &lock_context );
+ return expire;
+}
+
+RTEMS_INLINE_ROUTINE bool _Watchdog_Per_CPU_lazy_insert_monotonic(
+ Watchdog_Control *the_watchdog,
+ Per_CPU_Control *cpu,
+ uint64_t expire
+)
+{
+ ISR_lock_Context lock_context;
+ Watchdog_Header *header;
+ bool insert;
+
+ header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ];
+
+ _Watchdog_Set_CPU( the_watchdog, cpu );
+
+ _Watchdog_Per_CPU_acquire_critical( cpu, &lock_context );
+ insert = ( expire > cpu->Watchdog.ticks );
+
+ if ( insert ) {
+ _Watchdog_Insert(header, the_watchdog, expire);
+ }
+
+ _Watchdog_Per_CPU_release_critical( cpu, &lock_context );
+ return insert;
+}
+
+RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Per_CPU_insert_realtime(
+ Watchdog_Control *the_watchdog,
+ Per_CPU_Control *cpu,
+ uint64_t expire
+)
+{
+ ISR_lock_Context lock_context;
+ Watchdog_Header *header;
+
+ header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ];
+
+ _Watchdog_Set_CPU( the_watchdog, cpu );
+
+ _Watchdog_Per_CPU_acquire_critical( cpu, &lock_context );
+ _Watchdog_Insert(header, the_watchdog, expire);
+ _Watchdog_Per_CPU_release_critical( cpu, &lock_context );
+ return expire;
+}
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove(
+ Watchdog_Control *the_watchdog,
+ Per_CPU_Control *cpu,
+ Watchdog_Header *header
+)
+{
+ ISR_lock_Context lock_context;
+
+ _Watchdog_Per_CPU_acquire_critical( cpu, &lock_context );
+ _Watchdog_Remove(
+ header,
+ the_watchdog
+ );
+ _Watchdog_Per_CPU_release_critical( cpu, &lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove_monotonic(
+ Watchdog_Control *the_watchdog
+)
+{
+ Per_CPU_Control *cpu;
+
+ cpu = _Watchdog_Get_CPU( the_watchdog );
+ _Watchdog_Per_CPU_remove(
+ the_watchdog,
+ cpu,
+ &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ]
+ );
+}
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove_realtime(
+ Watchdog_Control *the_watchdog
+)
+{
+ Per_CPU_Control *cpu;
+
+ cpu = _Watchdog_Get_CPU( the_watchdog );
+ _Watchdog_Per_CPU_remove(
+ the_watchdog,
+ cpu,
+ &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ]
+ );
+}
+
+RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_tickle_realtime(
+ Per_CPU_Control *cpu,
+ uint64_t now
+)
+{
+ ISR_lock_Context lock_context;
+
+ _ISR_lock_ISR_disable_and_acquire( &cpu->Watchdog.Lock, &lock_context );
+ _Watchdog_Tickle(
+ &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ],
+ now,
+ &cpu->Watchdog.Lock,
+ &lock_context
+ );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/score/wkspace.h b/cpukit/include/rtems/score/wkspace.h
new file mode 100644
index 0000000000..3676ff28c4
--- /dev/null
+++ b/cpukit/include/rtems/score/wkspace.h
@@ -0,0 +1,138 @@
+/**
+ * @file rtems/score/wkspace.h
+ *
+ * @brief Information Related to the RAM Workspace
+ *
+ * This include file contains information related to the
+ * RAM Workspace. This Handler provides mechanisms which can be used to
+ * define, initialize and manipulate the workspace.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_WKSPACE_H
+#define _RTEMS_SCORE_WKSPACE_H
+
+#include <rtems/score/heap.h>
+#include <rtems/score/interr.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ScoreWorkspace Workspace Handler
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality related to the management of
+ * the RTEMS Executive Workspace.
+ */
+/**@{*/
+
+/**
+ * @brief Executive workspace control.
+ *
+ * This is the heap control structure used to manage the RTEMS Executive
+ * Workspace.
+ */
+extern Heap_Control _Workspace_Area;
+
+/**
+ * @brief Initilize workspace handler.
+ *
+ * This routine performs the initialization necessary for this handler.
+ */
+void _Workspace_Handler_initialization(
+ Heap_Area *areas,
+ size_t area_count,
+ Heap_Initialization_or_extend_handler extend
+);
+
+/**
+ * @brief Allocate memory from workspace.
+ *
+ * This routine returns the address of a block of memory of size
+ * bytes. If a block of the appropriate size cannot be allocated
+ * from the workspace, then NULL is returned.
+ *
+ * @param size is the requested size
+ *
+ * @retval a pointer to the requested memory or NULL.
+ */
+void *_Workspace_Allocate(
+ size_t size
+);
+
+/**
+ * @brief Allocate aligned memory from workspace.
+ *
+ * @param[in] size The size of the requested memory.
+ * @param[in] alignment The alignment of the requested memory.
+ *
+ * @retval NULL Not enough resources.
+ * @retval other The memory area begin.
+ */
+void *_Workspace_Allocate_aligned( size_t size, size_t alignment );
+
+/**
+ * @brief Free memory to the workspace.
+ *
+ * This function frees the specified block of memory. If the block
+ * belongs to the Workspace and can be successfully freed, then
+ * true is returned. Otherwise false is returned.
+ *
+ * @param block is the memory to free
+ *
+ * @note If @a block is equal to NULL, then the request is ignored.
+ * This allows the caller to not worry about whether or not
+ * a pointer is NULL.
+ */
+
+void _Workspace_Free(
+ void *block
+);
+
+/**
+ * @brief Workspace allocate or fail with fatal error.
+ *
+ * This routine returns the address of a block of memory of @a size
+ * bytes. If a block of the appropriate size cannot be allocated
+ * from the workspace, then the internal error handler is invoked.
+ *
+ * @param[in] size is the desired number of bytes to allocate
+ * @retval If successful, the starting address of the allocated memory
+ */
+void *_Workspace_Allocate_or_fatal_error(
+ size_t size
+);
+
+/**
+ * @brief Duplicates string with memory from the workspace.
+ *
+ * @param[in] string is the pointer to a zero terminated string.
+ * @param[in] len is the length of the string (equal to strlen(string)).
+ *
+ * @retval NULL Not enough memory.
+ * @retval other Duplicated string.
+ */
+char *_Workspace_String_duplicate(
+ const char *string,
+ size_t len
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/serdbg.h b/cpukit/include/rtems/serdbg.h
new file mode 100644
index 0000000000..fe106bce44
--- /dev/null
+++ b/cpukit/include/rtems/serdbg.h
@@ -0,0 +1,151 @@
+/*===============================================================*\
+| Project: RTEMS remote gdb over serial line |
++-----------------------------------------------------------------+
+| File: serdbg.h |
++-----------------------------------------------------------------+
+| Copyright (c) 2002 IMD |
+| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
+| <Thomas.Doerfler@imd-systems.de> |
+| all rights reserved |
++-----------------------------------------------------------------+
+| this file declares intialization functions to add |
+| a gdb remote debug stub to an RTEMS system |
+| |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 04.04.02 creation doe |
+\*===============================================================*/
+#ifndef _SERDBG_H
+#define _SERDBG_H
+
+#include <rtems.h>
+#include <termios.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ uint32_t baudrate; /* debug baud rate, e.g. 57600 */
+ void (*callout)(void); /* callout pointer during polling */
+ int (*open_io)(const char *dev_name, uint32_t baudrate); /* I/O open fnc */
+ const char *devname; /* debug device, e.g. "/dev/tty01" */
+ bool skip_init_bkpt; /* if TRUE, do not stop when initializing */
+} serdbg_conf_t;
+
+/*
+ * must be defined in init module...
+ */
+extern serdbg_conf_t serdbg_conf;
+
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+void putDebugChar
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| send character to remote debugger |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ char c /* char to send */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| <none> |
+\*=========================================================================*/
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int getDebugChar
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| get character from remote debugger |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ void /* <none> */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| <none> |
+\*=========================================================================*/
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+void serdbg_exceptionHandler
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| hook directly to an exception vector |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ int vecnum, /* vector index to hook at */
+ void *vector /* address of handler function */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| <none> |
+\*=========================================================================*/
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int serdbg_init
+(
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| initialize remote gdb session over serial line |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+ void
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| rtems_status_code |
+\*=========================================================================*/
+
+/*
+ * stuff from serdbgio.c
+ */
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int serdbg_open
+
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| try to open given serial debug port |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+(
+ const char *dev_name, /* name of device to open */
+ uint32_t baudrate /* baud rate to use */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0 on success, -1 and errno otherwise |
+\*=========================================================================*/
+
+
+extern int serdbg_init_dbg(void);
+
+/*
+ * Assumed to be provided by the BSP
+ */
+extern void set_debug_traps(void);
+extern void breakpoint(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SERDBG_H */
diff --git a/cpukit/include/rtems/serdbgcnf.h b/cpukit/include/rtems/serdbgcnf.h
new file mode 100644
index 0000000000..9d4087ae69
--- /dev/null
+++ b/cpukit/include/rtems/serdbgcnf.h
@@ -0,0 +1,91 @@
+/**
+ * @file
+ *
+ * @brief Adds a GDB remote Debug Stub to an RTEMS System
+ */
+
+/*===============================================================*\
+| Project: RTEMS configure remote gdb over serial line |
++-----------------------------------------------------------------+
+| File: serdbgcnf.h |
++-----------------------------------------------------------------+
+| Copyright (c) 2002 IMD |
+| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
+| <Thomas.Doerfler@imd-systems.de> |
+| all rights reserved |
++-----------------------------------------------------------------+
+| this file declares intialization functions to add |
+| a gdb remote debug stub to an RTEMS system |
+| |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 13.05.02 creation doe |
+\*===============================================================*/
+#ifndef _SERDBGCNF_H
+#define _SERDBGCNF_H
+
+#include <rtems/serdbg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef CONFIGURE_INIT
+
+/*
+ * fallback for baud rate to use
+ */
+#ifndef CONFIGURE_SERDBG_BAUDRATE
+#define CONFIGURE_SERDBG_BAUDRATE 9600
+#endif
+
+/*
+ * fallback for device name to use
+ */
+#ifndef CONFIGURE_SERDBG_DEVNAME
+#define CONFIGURE_SERDBG_DEVNAME "/dev/tty01"
+#endif
+
+/*
+ * fill in serdbg_conf structure
+ */
+serdbg_conf_t serdbg_conf = {
+ CONFIGURE_SERDBG_BAUDRATE,
+
+#ifdef CONFIGURE_SERDBG_CALLOUT
+ CONFIGURE_SERDBG_CALLOUT,
+#else
+ NULL,
+#endif
+
+#ifdef CONFIGURE_SERDBG_USE_POLLED_TERMIOS
+ serdbg_open,
+#else
+ NULL,
+#endif
+
+ CONFIGURE_SERDBG_DEVNAME,
+
+#ifdef CONFIGURE_SERDBG_SKIP_INIT_BKPT
+ true,
+#else
+ false,
+#endif
+};
+
+int serdbg_init(void) {
+#ifdef CONFIGURE_USE_SERDBG
+ return serdbg_init_dbg();
+#else
+ return 0;
+#endif
+}
+
+#endif /* CONFIGURE_INIT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SERDBGCNF_H */
diff --git a/cpukit/include/rtems/serial_mouse.h b/cpukit/include/rtems/serial_mouse.h
new file mode 100644
index 0000000000..174fcfb909
--- /dev/null
+++ b/cpukit/include/rtems/serial_mouse.h
@@ -0,0 +1,169 @@
+/**
+ * @file
+ *
+ * @brief Serial Mouse Driver
+ *
+ * This file describes the Serial Mouse Driver for all boards.
+ * This driver assumes that the BSP or application will provide
+ * an implementation of the method bsp_get_serial_mouse_device()
+ * which tells the driver what serial port device to open() and
+ * what type of mouse is connected.
+ *
+ * This driver relies on the Mouse Parser Engine.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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 __SERIAL_MOUSE_h__
+#define __SERIAL_MOUSE_h__
+
+#include <rtems/io.h>
+
+/* functions */
+
+/**
+ * @defgroup libmisc_serialmouse Serial Mouse Driver
+ * @ingroup libmisc_mouse
+ */
+/**@{*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Standard device file path for a PS2 mouse device.
+ */
+#define SERIAL_MOUSE_DEVICE_PS2 "/dev/psaux"
+
+/**
+ * This macro defines the serial mouse device driver entry points.
+ */
+#define SERIAL_MOUSE_DRIVER_TABLE_ENTRY \
+ { serial_mouse_initialize, serial_mouse_open, serial_mouse_close, \
+ serial_mouse_read, serial_mouse_write, serial_mouse_control }
+
+/**
+ * @brief The initialization of the serial mouse driver.
+ *
+ * This method initializes the serial mouse driver.
+ *
+ * @param[in] major is the mouse device major number
+ * @param[in] minor is the mouse device minor number
+ * @param[in] arg points to device driver arguments
+ */
+rtems_device_driver serial_mouse_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+);
+
+/**
+ * @brief Open device driver entry point for the serial mouse driver.
+ *
+ * This method implements the Open device driver entry
+ * point for the serial mouse driver.
+ *
+ * @param[in] major is the mouse device major number
+ * @param[in] minor is the mouse device minor number
+ * @param[in] arg points to device driver arguments
+ */
+rtems_device_driver serial_mouse_open(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+);
+
+/**
+ * @brief Close device driver entry point for the serial mouse driver.
+ *
+ * This method implements the Close device driver entry
+ * point for the serial mouse driver.
+ *
+ * @param[in] major is the mouse device major number
+ * @param[in] minor is the mouse device minor number
+ * @param[in] arg points to device driver arguments
+ */
+rtems_device_driver serial_mouse_close(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+);
+
+/**
+ * @brief Read device driver entry point for the serial mouse driver.
+ *
+ * This method implements the Read device driver entry
+ * point for the serial mouse driver.
+ *
+ * @param[in] major is the mouse device major number
+ * @param[in] minor is the mouse device minor number
+ * @param[in] arg points to device driver arguments
+ */
+rtems_device_driver serial_mouse_read(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+);
+
+/**
+ * @brief Write device driver entry point for the serial mouse driver.
+ *
+ * This method implements the Write device driver entry
+ * point for the serial mouse driver.
+ *
+ * @param[in] major is the mouse device major number
+ * @param[in] minor is the mouse device minor number
+ * @param[in] arg points to device driver arguments
+ */
+rtems_device_driver serial_mouse_write(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+);
+
+/**
+ * @brief IO Control device driver entry point for the serial mouse driver.
+ *
+ * This method implements the IO Control device driver entry
+ * point for the serial mouse driver.
+ *
+ * @param[in] major is the mouse device major number
+ * @param[in] minor is the mouse device minor number
+ * @param[in] arg points to device driver arguments
+ */
+rtems_device_driver serial_mouse_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+);
+
+/**
+ * @brief Obtain serial mouse configuration information.
+ *
+ * This method is implemented by the BSP or application and
+ * tells the driver what device to open() and what type of
+ * mouse is connected.
+ *
+ * @param[in] name will point to a string with the device name
+ * of the serial port with the mouse connected.
+ * @param[in] type will point to a string with the type of mouse connected.
+ *
+ * @retval This method returns true on success and false on error.
+ */
+bool bsp_get_serial_mouse_device(
+ const char **name,
+ const char **type
+);
+
+#ifdef __cplusplus
+}
+#endif
+/**@}*/
+#endif /* __tty_drv__ */
diff --git a/cpukit/include/rtems/seterr.h b/cpukit/include/rtems/seterr.h
new file mode 100644
index 0000000000..22fddc824e
--- /dev/null
+++ b/cpukit/include/rtems/seterr.h
@@ -0,0 +1,53 @@
+/**
+ * @file rtems/seterr.h
+ *
+ * @brief Data which Ease the Burden of Consistently Setting Errno
+ *
+ * This file contains macros and definitions which ease the burden
+ * of consistently setting errno and returning -1.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2006.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_SETERR_H
+#define _RTEMS_SETERR_H
+
+/**
+ * @defgroup ScoreSetErr Set Errno
+ *
+ * @ingroup Score
+ *
+ */
+/**@{*/
+
+#include <errno.h>
+
+/**
+ * This is a helper macro which will set the variable errno and return
+ * the specified value to the caller.
+ *
+ * @param[in] _error is the error code
+ * @param[in] _value is the value to return
+ */
+#define rtems_set_errno_and_return_value( _error, _value ) \
+ do { errno = ( _error ); return ( _value ); } while ( 0 )
+
+/**
+ * This is a helper macro which will set the variable errno and return
+ * -1 to the caller. This pattern is common to many POSIX methods.
+ *
+ * @param[in] _error is the error code
+ */
+#define rtems_set_errno_and_return_minus_one( _error ) \
+ rtems_set_errno_and_return_value( _error, -1 )
+
+/**@}*/
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/shell.h b/cpukit/include/rtems/shell.h
new file mode 100644
index 0000000000..98ddf0a958
--- /dev/null
+++ b/cpukit/include/rtems/shell.h
@@ -0,0 +1,385 @@
+/**
+ * @file rtems/shell.h
+ *
+ * @brief Instantatiate a New Terminal Shell
+ */
+
+/*
+ * Author:
+ *
+ * WORK: fernando.ruiz@ctv.es
+ * HOME: correo@fernando-ruiz.com
+ *
+ * Thanks at:
+ * Chris Johns
+ */
+
+#ifndef __RTEMS_SHELL_H__
+#define __RTEMS_SHELL_H__
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <rtems.h>
+#include <stdio.h>
+#include <termios.h>
+#include <rtems/fs.h>
+#include <rtems/libio.h>
+#include <rtems/chain.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Some key labels to define special keys.
+ */
+
+#define RTEMS_SHELL_KEYS_EXTENDED (0x8000)
+#define RTEMS_SHELL_KEYS_NORMAL_MASK (0x00ff)
+#define RTEMS_SHELL_KEYS_INS (0)
+#define RTEMS_SHELL_KEYS_DEL (1)
+#define RTEMS_SHELL_KEYS_UARROW (2)
+#define RTEMS_SHELL_KEYS_DARROW (3)
+#define RTEMS_SHELL_KEYS_LARROW (4)
+#define RTEMS_SHELL_KEYS_RARROW (5)
+#define RTEMS_SHELL_KEYS_HOME (6)
+#define RTEMS_SHELL_KEYS_END (7)
+#define RTEMS_SHELL_KEYS_F1 (8)
+#define RTEMS_SHELL_KEYS_F2 (9)
+#define RTEMS_SHELL_KEYS_F3 (10)
+#define RTEMS_SHELL_KEYS_F4 (11)
+#define RTEMS_SHELL_KEYS_F5 (12)
+#define RTEMS_SHELL_KEYS_F6 (13)
+#define RTEMS_SHELL_KEYS_F7 (14)
+#define RTEMS_SHELL_KEYS_F8 (15)
+#define RTEMS_SHELL_KEYS_F9 (16)
+#define RTEMS_SHELL_KEYS_F10 (17)
+
+typedef bool (*rtems_shell_login_check_t)(
+ const char * /* user */,
+ const char * /* passphrase */
+);
+
+extern bool rtems_shell_login_prompt(
+ FILE *in,
+ FILE *out,
+ const char *device,
+ rtems_shell_login_check_t check
+);
+
+extern bool rtems_shell_login_check(
+ const char *user,
+ const char *passphrase
+);
+
+typedef int (*rtems_shell_command_t)(int argc, char **argv);
+
+struct rtems_shell_cmd_tt;
+typedef struct rtems_shell_cmd_tt rtems_shell_cmd_t;
+
+struct rtems_shell_cmd_tt {
+ const char *name;
+ const char *usage;
+ const char *topic;
+ rtems_shell_command_t command;
+ rtems_shell_cmd_t *alias;
+ rtems_shell_cmd_t *next;
+ mode_t mode;
+ uid_t uid;
+ gid_t gid;
+};
+
+typedef struct {
+ const char *name;
+ const char *alias;
+} rtems_shell_alias_t;
+
+struct rtems_shell_topic_tt;
+typedef struct rtems_shell_topic_tt rtems_shell_topic_t;
+
+struct rtems_shell_topic_tt {
+ const char *topic;
+ rtems_shell_topic_t *next;
+};
+
+/*
+ * The return value has RTEMS_SHELL_KEYS_EXTENDED set if the key
+ * is extended, ie a special key.
+ */
+extern unsigned int rtems_shell_getchar(FILE *in);
+
+extern rtems_shell_cmd_t * rtems_shell_lookup_cmd(const char *cmd);
+
+extern rtems_shell_cmd_t *rtems_shell_add_cmd_struct(
+ rtems_shell_cmd_t *shell_cmd
+);
+
+rtems_shell_cmd_t * rtems_shell_add_cmd(
+ const char *cmd,
+ const char *topic,
+ const char *usage,
+ rtems_shell_command_t command
+);
+
+extern rtems_shell_cmd_t * rtems_shell_alias_cmd(
+ const char *cmd,
+ const char *alias
+);
+
+extern int rtems_shell_make_args(
+ char *commandLine,
+ int *argc_p,
+ char **argv_p,
+ int max_args
+);
+
+extern rtems_shell_topic_t * rtems_shell_lookup_topic(
+ const char *topic
+);
+
+extern bool rtems_shell_can_see_cmd(
+ const rtems_shell_cmd_t *shell_cmd
+);
+
+extern int rtems_shell_execute_cmd(
+ const char *cmd, int argc, char *argv[]
+);
+
+/*
+ * Call to set up the shell environment if you need to execute commands before
+ * running a shell.
+ */
+extern void rtems_shell_init_environment(
+ void
+);
+
+extern int rtems_shell_cat_file(
+ FILE *out,
+ const char *name
+);
+
+extern void rtems_shell_write_file(
+ const char *name,
+ const char *content
+);
+
+extern int rtems_shell_script_file(
+ int argc,
+ char **argv
+);
+
+/**
+ * Initialise the shell creating tasks to login and run the shell
+ * sessions.
+ *
+ * @param task_name Name of the shell task.
+ * @param task_stacksize The size of the stack. If 0 the default size is used.
+ * @param task_priority The priority the shell runs at.
+ * @param forever Repeat logins.
+ * @param wait Caller should block until shell exits.
+ * @param login_check User login check function, NULL disables login checks.
+ *
+ */
+extern rtems_status_code rtems_shell_init(
+ const char *task_name,
+ size_t task_stacksize,
+ rtems_task_priority task_priority,
+ const char *devname,
+ bool forever,
+ bool wait,
+ rtems_shell_login_check_t login_check
+);
+
+/**
+ * Run a shell script creating a shell tasks to execute the command under.
+ *
+ * @param task_name Name of the shell task.
+ * @param task_stacksize The size of the stack. If 0 the default size is used.
+ * @param task_priority The priority the shell runs at.
+ * @param input The file of commands. Can be 'stdin' to use stdin.
+ * @param output The output file to write commands to. Can be 'stdout',
+ * 'stderr' or '/dev/null'.
+ * @param output_append Append the output to the file or truncate the file.
+ * Create if it does not exist.
+ * @param wait Wait for the script to finish.
+ */
+extern rtems_status_code rtems_shell_script(
+ const char *task_name,
+ size_t task_stacksize, /* 0 default*/
+ rtems_task_priority task_priority,
+ const char *input,
+ const char *output,
+ bool output_append,
+ bool wait,
+ bool echo
+);
+
+/**
+ * Private environment associated with each shell instance.
+ */
+typedef struct {
+ /** 'S','E','N','V': Shell Environment */
+ rtems_name magic;
+ const char *devname;
+ const char *taskname;
+ bool exit_shell; /* logout */
+ bool forever; /* repeat login */
+ int errorlevel;
+ bool echo;
+ char cwd[256];
+ const char *input;
+ const char *output;
+ bool output_append;
+ rtems_id wake_on_end;
+ rtems_shell_login_check_t login_check;
+
+ /**
+ * @brief The real and effective UID of the shell task in case no login check
+ * is present.
+ */
+ uid_t uid;
+
+ /**
+ * @brief The real and effective GID of the shell task in case no login check
+ * is present.
+ */
+ gid_t gid;
+} rtems_shell_env_t;
+
+bool rtems_shell_main_loop(
+ rtems_shell_env_t *rtems_shell_env
+);
+
+extern const rtems_shell_env_t rtems_global_shell_env;
+
+rtems_shell_env_t *rtems_shell_get_current_env(void);
+void rtems_shell_dup_current_env(rtems_shell_env_t *);
+
+/*
+ * The types of file systems we can mount. We have them broken out
+ * out like this so they can be configured by shellconfig.h. The
+ * mount command needs special treatment due to some file systems
+ * being dependent on the network stack and some not. If we had
+ * all possible file systems being included it would force the
+ * networking stack into the applcation and this may not be
+ * required.
+ */
+struct rtems_shell_filesystems_tt;
+typedef struct rtems_shell_filesystems_tt rtems_shell_filesystems_t;
+
+typedef int (*rtems_shell_filesystems_mounter_t)(
+ const char* driver,
+ const char* path,
+ rtems_shell_filesystems_t* fs,
+ rtems_filesystem_options_t options
+);
+
+struct rtems_shell_filesystems_tt {
+ rtems_chain_node link;
+ const char *name;
+ int driver_needed;
+ const rtems_filesystem_operations_table *fs_ops;
+ rtems_shell_filesystems_mounter_t mounter;
+};
+
+/**
+ * This method dynamically builds the command line prompt string
+ * and places it in @a prompt.
+ *
+ * @param[in] shell_env is the shell execution environment
+ * @param[in] prompt is a pointer to a string buffer area
+ * @param[in] size is length of the prompt buffer area
+ *
+ * @return This method fills in the memory pointed to by @a prompt.
+ *
+ * @note An application specific implementation can be provided
+ * by the user.
+ */
+extern void rtems_shell_get_prompt(
+ rtems_shell_env_t *shell_env,
+ char *prompt,
+ size_t size
+);
+
+/**
+ * Helper for the mount command.
+ *
+ * @param[in] driver The path to the driver.
+ * @param[in] path The path to mount on.
+ * @param[in] fs The file system definition.
+ * @param[in] options Special file system options.
+ */
+extern int rtems_shell_libc_mounter(
+ const char* driver,
+ const char* path,
+ rtems_shell_filesystems_t* fs,
+ rtems_filesystem_options_t options
+);
+
+/**
+ * Add a new file system mount configuration to the mount command.
+ *
+ * @param[in] fs The file system mount data.
+ */
+extern void rtems_shell_mount_add_fsys(rtems_shell_filesystems_t* fs);
+
+/**
+ * Delete file system mount configuration from the mount command.
+ *
+ * @param[in] fs The file system mount data to remove.
+ */
+extern void rtems_shell_mount_del_fsys(rtems_shell_filesystems_t* fs);
+
+typedef void (*rtems_shell_wait_for_input_notification)(
+ int fd,
+ int seconds_remaining,
+ void *arg
+);
+
+/**
+ * @brief Waits for input.
+ *
+ * @retval RTEMS_SUCCESSFUL Input detected.
+ * @retval RTEMS_TIMEOUT Timeout expired.
+ * @retval RTEMS_UNSATISFIED Cannot change or restore termios attributes.
+ */
+extern rtems_status_code rtems_shell_wait_for_input(
+ int fd,
+ int timeout_in_seconds,
+ rtems_shell_wait_for_input_notification notification,
+ void *notification_arg
+);
+
+/**
+ * @brief Waits for explicit input.
+ *
+ * @param desired_input An explicit unsigned character to wait for or -1 to
+ * accept any input.
+ *
+ * @retval RTEMS_SUCCESSFUL Input detected.
+ * @retval RTEMS_TIMEOUT Timeout expired.
+ * @retval RTEMS_UNSATISFIED Cannot change or restore termios attributes.
+ */
+extern rtems_status_code rtems_shell_wait_for_explicit_input(
+ int fd,
+ int timeout_in_seconds,
+ rtems_shell_wait_for_input_notification notification,
+ void *notification_arg,
+ int desired_input
+);
+
+extern int rtems_shell_main_monitor(int argc, char **argv);
+
+/*
+ * Provide these commands for application use, as their implementation
+ * is tedious.
+ */
+int rtems_shell_main_mv(int argc, char *argv[]);
+int rtems_shell_main_cp(int argc, char *argv[]);
+int rtems_shell_main_rm(int argc, char *argv[]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/shellconfig.h b/cpukit/include/rtems/shellconfig.h
new file mode 100644
index 0000000000..9f68b313fb
--- /dev/null
+++ b/cpukit/include/rtems/shellconfig.h
@@ -0,0 +1,554 @@
+/**
+ * @file rtems/shellconfig.h
+ *
+ * RTEMS Shell Command Set Configuration
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2012.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_SHELL_CONFIG_h
+#define _RTEMS_SHELL_CONFIG_h
+
+#include <rtems/shell.h>
+
+/*
+ * Externs for all command definition structures
+ */
+extern rtems_shell_cmd_t rtems_shell_HELP_Command;
+extern rtems_shell_cmd_t rtems_shell_ALIAS_Command;
+extern rtems_shell_cmd_t rtems_shell_TIME_Command;
+extern rtems_shell_cmd_t rtems_shell_CMDLS_Command;
+extern rtems_shell_cmd_t rtems_shell_CMDCHOWN_Command;
+extern rtems_shell_cmd_t rtems_shell_CMDCHMOD_Command;
+extern rtems_shell_cmd_t rtems_shell_LOGOFF_Command;
+extern rtems_shell_cmd_t rtems_shell_SETENV_Command;
+extern rtems_shell_cmd_t rtems_shell_GETENV_Command;
+extern rtems_shell_cmd_t rtems_shell_UNSETENV_Command;
+
+extern rtems_shell_cmd_t rtems_shell_MDUMP_Command;
+extern rtems_shell_cmd_t rtems_shell_WDUMP_Command;
+extern rtems_shell_cmd_t rtems_shell_LDUMP_Command;
+extern rtems_shell_cmd_t rtems_shell_MEDIT_Command;
+extern rtems_shell_cmd_t rtems_shell_MFILL_Command;
+extern rtems_shell_cmd_t rtems_shell_MMOVE_Command;
+
+extern rtems_shell_cmd_t rtems_shell_JOEL_Command;
+extern rtems_shell_cmd_t rtems_shell_DATE_Command;
+extern rtems_shell_cmd_t rtems_shell_ECHO_Command;
+extern rtems_shell_cmd_t rtems_shell_EDIT_Command;
+extern rtems_shell_cmd_t rtems_shell_SLEEP_Command;
+extern rtems_shell_cmd_t rtems_shell_ID_Command;
+extern rtems_shell_cmd_t rtems_shell_TTY_Command;
+extern rtems_shell_cmd_t rtems_shell_WHOAMI_Command;
+
+extern rtems_shell_cmd_t rtems_shell_CP_Command;
+extern rtems_shell_cmd_t rtems_shell_PWD_Command;
+extern rtems_shell_cmd_t rtems_shell_LS_Command;
+extern rtems_shell_cmd_t rtems_shell_CHDIR_Command;
+extern rtems_shell_cmd_t rtems_shell_MKDIR_Command;
+extern rtems_shell_cmd_t rtems_shell_RMDIR_Command;
+extern rtems_shell_cmd_t rtems_shell_CHROOT_Command;
+extern rtems_shell_cmd_t rtems_shell_CHMOD_Command;
+extern rtems_shell_cmd_t rtems_shell_CAT_Command;
+extern rtems_shell_cmd_t rtems_shell_MKRFS_Command;
+extern rtems_shell_cmd_t rtems_shell_MSDOSFMT_Command;
+extern rtems_shell_cmd_t rtems_shell_MSDOSFMT_Alias;
+extern rtems_shell_cmd_t rtems_shell_MV_Command;
+extern rtems_shell_cmd_t rtems_shell_RM_Command;
+extern rtems_shell_cmd_t rtems_shell_LN_Command;
+extern rtems_shell_cmd_t rtems_shell_MKNOD_Command;
+extern rtems_shell_cmd_t rtems_shell_UMASK_Command;
+extern rtems_shell_cmd_t rtems_shell_LSOF_Command;
+extern rtems_shell_cmd_t rtems_shell_MOUNT_Command;
+extern rtems_shell_cmd_t rtems_shell_UNMOUNT_Command;
+extern rtems_shell_cmd_t rtems_shell_BLKSYNC_Command;
+extern rtems_shell_cmd_t rtems_shell_BLKSTATS_Command;
+extern rtems_shell_cmd_t rtems_shell_FDISK_Command;
+extern rtems_shell_cmd_t rtems_shell_DD_Command;
+extern rtems_shell_cmd_t rtems_shell_HEXDUMP_Command;
+extern rtems_shell_cmd_t rtems_shell_DEBUGRFS_Command;
+extern rtems_shell_cmd_t rtems_shell_DF_Command;
+extern rtems_shell_cmd_t rtems_shell_MD5_Command;
+
+extern rtems_shell_cmd_t rtems_shell_RTC_Command;
+
+extern rtems_shell_cmd_t rtems_shell_SHUTDOWN_Command;
+extern rtems_shell_cmd_t rtems_shell_CPUINFO_Command;
+extern rtems_shell_cmd_t rtems_shell_CPUUSE_Command;
+extern rtems_shell_cmd_t rtems_shell_TOP_Command;
+extern rtems_shell_cmd_t rtems_shell_STACKUSE_Command;
+extern rtems_shell_cmd_t rtems_shell_PERIODUSE_Command;
+extern rtems_shell_cmd_t rtems_shell_PROFREPORT_Command;
+extern rtems_shell_cmd_t rtems_shell_WKSPACE_INFO_Command;
+extern rtems_shell_cmd_t rtems_shell_MALLOC_INFO_Command;
+extern rtems_shell_cmd_t rtems_shell_RTRACE_Command;
+#if RTEMS_NETWORKING
+ extern rtems_shell_cmd_t rtems_shell_IFCONFIG_Command;
+ extern rtems_shell_cmd_t rtems_shell_ROUTE_Command;
+ extern rtems_shell_cmd_t rtems_shell_NETSTATS_Command;
+ extern rtems_shell_cmd_t rtems_shell_PING_Command;
+#endif
+
+/*
+ * Extern for System commands
+ */
+extern rtems_shell_cmd_t rtems_shell_DRVMGR_Command;
+extern rtems_shell_cmd_t rtems_shell_PCI_Command;
+
+extern rtems_shell_cmd_t * const rtems_shell_Initial_commands[];
+
+/*
+ * Extern for alias commands
+ */
+extern rtems_shell_alias_t rtems_shell_DIR_Alias;
+extern rtems_shell_alias_t rtems_shell_CD_Alias;
+extern rtems_shell_alias_t rtems_shell_EXIT_Alias;
+
+extern rtems_shell_alias_t * const rtems_shell_Initial_aliases[];
+
+/*
+ * If we are configured to alias a command, then make sure the underlying
+ * command is configured.
+ */
+
+#if !defined(CONFIGURE_SHELL_COMMANDS_ALL)
+ #if defined(CONFIGURE_SHELL_COMMANDS_DIR) && \
+ !defined(CONFIGURE_SHELL_COMMANDS_LS)
+ #define CONFIGURE_SHELL_COMMAND_LS
+ #endif
+
+ #if defined(CONFIGURE_SHELL_COMMANDS_CD) && \
+ !defined(CONFIGURE_SHELL_COMMANDS_CHDIR)
+ #define CONFIGURE_SHELL_COMMAND_CHDIR
+ #endif
+
+ #if defined(CONFIGURE_SHELL_COMMANDS_EXIT) && \
+ !defined(CONFIGURE_SHELL_COMMANDS_LOGOFF)
+ #define CONFIGURE_SHELL_COMMAND_LOGOFF
+ #endif
+#endif
+
+#if defined(CONFIGURE_SHELL_COMMANDS_INIT)
+ rtems_shell_alias_t * const rtems_shell_Initial_aliases[] = {
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_DIR)) || \
+ defined(CONFIGURE_SHELL_COMMAND_DIR)
+ &rtems_shell_DIR_Alias,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_CD)) || \
+ defined(CONFIGURE_SHELL_COMMAND_CD)
+ &rtems_shell_CD_Alias,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_EXIT)) || \
+ defined(CONFIGURE_SHELL_COMMAND_EXIT)
+ &rtems_shell_EXIT_Alias,
+ #endif
+
+ /*
+ * User defined shell aliases
+ */
+ #if defined(CONFIGURE_SHELL_USER_ALIASES)
+ CONFIGURE_SHELL_USER_ALIASES,
+ #endif
+ NULL
+ };
+
+ rtems_shell_cmd_t * const rtems_shell_Initial_commands[] = {
+ /*
+ * General comamnds that should be present
+ */
+ &rtems_shell_HELP_Command,
+ &rtems_shell_ALIAS_Command,
+ &rtems_shell_TIME_Command,
+
+ /*
+ * Common commands that can be optional
+ */
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_CMDLS)) || \
+ defined(CONFIGURE_SHELL_COMMAND_CMDLS)
+ &rtems_shell_CMDLS_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_CMDCHOWN)) || \
+ defined(CONFIGURE_SHELL_COMMAND_CMDCHOWN)
+ &rtems_shell_CMDCHOWN_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_CMDCHMOD)) || \
+ defined(CONFIGURE_SHELL_COMMAND_CMDCHMOD)
+ &rtems_shell_CMDCHMOD_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_JOEL)) || \
+ defined(CONFIGURE_SHELL_COMMAND_JOEL)
+ &rtems_shell_JOEL_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_DATE)) || \
+ defined(CONFIGURE_SHELL_COMMAND_DATE)
+ &rtems_shell_DATE_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_ECHO)) || \
+ defined(CONFIGURE_SHELL_COMMAND_ECHO)
+ &rtems_shell_ECHO_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_EDIT)) || \
+ defined(CONFIGURE_SHELL_COMMAND_EDIT)
+ &rtems_shell_EDIT_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_SLEEP)) || \
+ defined(CONFIGURE_SHELL_COMMAND_SLEEP)
+ &rtems_shell_SLEEP_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_ID)) || \
+ defined(CONFIGURE_SHELL_COMMAND_ID)
+ &rtems_shell_ID_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_TTY)) || \
+ defined(CONFIGURE_SHELL_COMMAND_TTY)
+ &rtems_shell_TTY_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_WHOAMI)) || \
+ defined(CONFIGURE_SHELL_COMMAND_WHOAMI)
+ &rtems_shell_WHOAMI_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_LOGOFF)) || \
+ defined(CONFIGURE_SHELL_COMMAND_LOGOFF)
+ &rtems_shell_LOGOFF_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_SETENV)) || \
+ defined(CONFIGURE_SHELL_COMMAND_SETENV)
+ &rtems_shell_SETENV_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_GETENV)) || \
+ defined(CONFIGURE_SHELL_COMMAND_GETENV)
+ &rtems_shell_GETENV_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_CRLENV)) || \
+ defined(CONFIGURE_SHELL_COMMAND_UNSETENV)
+ &rtems_shell_UNSETENV_Command,
+ #endif
+
+ /*
+ * Memory printing/modification family commands
+ */
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_MDUMP)) || \
+ defined(CONFIGURE_SHELL_COMMAND_MDUMP)
+ &rtems_shell_MDUMP_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_WDUMP)) || \
+ defined(CONFIGURE_SHELL_COMMAND_WDUMP)
+ &rtems_shell_WDUMP_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_LDUMP)) || \
+ defined(CONFIGURE_SHELL_COMMAND_LDUMP)
+ &rtems_shell_LDUMP_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_MEDIT)) || \
+ defined(CONFIGURE_SHELL_COMMAND_MEDIT)
+ &rtems_shell_MEDIT_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_MFILL)) || \
+ defined(CONFIGURE_SHELL_COMMAND_MFILL)
+ &rtems_shell_MFILL_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_MMOVE)) || \
+ defined(CONFIGURE_SHELL_COMMAND_MMOVE)
+ &rtems_shell_MMOVE_Command,
+ #endif
+
+ /*
+ * File and directory commands
+ */
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_CP)) || \
+ defined(CONFIGURE_SHELL_COMMAND_CP)
+ &rtems_shell_CP_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_PWD)) || \
+ defined(CONFIGURE_SHELL_COMMAND_PWD)
+ &rtems_shell_PWD_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_LS)) || \
+ defined(CONFIGURE_SHELL_COMMAND_LS)
+ &rtems_shell_LS_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_CHDIR)) || \
+ defined(CONFIGURE_SHELL_COMMAND_CHDIR)
+ &rtems_shell_CHDIR_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_MKDIR)) || \
+ defined(CONFIGURE_SHELL_COMMAND_MKDIR)
+ &rtems_shell_MKDIR_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_RMDIR)) || \
+ defined(CONFIGURE_SHELL_COMMAND_RMDIR)
+ &rtems_shell_RMDIR_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_CHROOT)) || \
+ defined(CONFIGURE_SHELL_COMMAND_CHROOT)
+ &rtems_shell_CHROOT_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_CHMOD)) || \
+ defined(CONFIGURE_SHELL_COMMAND_CHMOD)
+ &rtems_shell_CHMOD_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_CAT)) || \
+ defined(CONFIGURE_SHELL_COMMAND_CAT)
+ &rtems_shell_CAT_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_MKRFS)) || \
+ defined(CONFIGURE_SHELL_COMMAND_MKRFS)
+ &rtems_shell_MKRFS_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_MSDOSFMT)) || \
+ defined(CONFIGURE_SHELL_COMMAND_MSDOSFMT)
+ &rtems_shell_MSDOSFMT_Command,
+ &rtems_shell_MSDOSFMT_Alias,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_MV)) || \
+ defined(CONFIGURE_SHELL_COMMAND_MV)
+ &rtems_shell_MV_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_RM)) || \
+ defined(CONFIGURE_SHELL_COMMAND_RM)
+ &rtems_shell_RM_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_LN)) || \
+ defined(CONFIGURE_SHELL_COMMAND_LN)
+ &rtems_shell_LN_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_MKNOD)) || \
+ defined(CONFIGURE_SHELL_COMMAND_MKNOD)
+ &rtems_shell_MKNOD_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_UMASK)) || \
+ defined(CONFIGURE_SHELL_COMMAND_UMASK)
+ &rtems_shell_UMASK_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_LSOF)) || \
+ defined(CONFIGURE_SHELL_COMMAND_LSOF)
+ &rtems_shell_LSOF_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_MOUNT)) || \
+ defined(CONFIGURE_SHELL_COMMAND_MOUNT)
+ &rtems_shell_MOUNT_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_UNMOUNT)) || \
+ defined(CONFIGURE_SHELL_COMMAND_UNMOUNT)
+ &rtems_shell_UNMOUNT_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_BLKSYNC)) || \
+ defined(CONFIGURE_SHELL_COMMAND_BLKSYNC)
+ &rtems_shell_BLKSYNC_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_BLKSTATS)) || \
+ defined(CONFIGURE_SHELL_COMMAND_BLKSTATS)
+ &rtems_shell_BLKSTATS_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_FDISK)) || \
+ defined(CONFIGURE_SHELL_COMMAND_FDISK)
+ &rtems_shell_FDISK_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_DD)) || \
+ defined(CONFIGURE_SHELL_COMMAND_DD)
+ &rtems_shell_DD_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_HEXDUMP)) || \
+ defined(CONFIGURE_SHELL_COMMAND_HEXDUMP)
+ &rtems_shell_HEXDUMP_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_DEBUGRFS)) || \
+ defined(CONFIGURE_SHELL_COMMAND_DEBUGRFS)
+ &rtems_shell_DEBUGRFS_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_DF)) || \
+ defined(CONFIGURE_SHELL_COMMAND_DF)
+ &rtems_shell_DF_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_MD5)) || \
+ defined(CONFIGURE_SHELL_COMMAND_MD5)
+ &rtems_shell_MD5_Command,
+ #endif
+
+ /*
+ * RTEMS Related commands
+ */
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_SHUTDOWN)) || \
+ defined(CONFIGURE_SHELL_COMMAND_SHUTDOWN)
+ &rtems_shell_SHUTDOWN_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_CPUINFO)) || \
+ defined(CONFIGURE_SHELL_COMMAND_CPUINFO)
+ &rtems_shell_CPUINFO_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_CPUUSE)) || \
+ defined(CONFIGURE_SHELL_COMMAND_CPUUSE)
+ &rtems_shell_CPUUSE_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_TOP)) || \
+ defined(CONFIGURE_SHELL_COMMAND_TOP)
+ &rtems_shell_TOP_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_STACKUSE)) || \
+ defined(CONFIGURE_SHELL_COMMAND_STACKUSE)
+ &rtems_shell_STACKUSE_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_PERIODUSE)) || \
+ defined(CONFIGURE_SHELL_COMMAND_PERIODUSE)
+ &rtems_shell_PERIODUSE_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_PROFREPORT)) || \
+ defined(CONFIGURE_SHELL_COMMAND_PROFREPORT)
+ &rtems_shell_PROFREPORT_Command,
+ #endif
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_WKSPACE_INFO)) || \
+ defined(CONFIGURE_SHELL_COMMAND_WKSPACE_INFO)
+ &rtems_shell_WKSPACE_INFO_Command,
+ #endif
+
+ /*
+ * Malloc family commands
+ */
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_MALLOC_INFO)) || \
+ defined(CONFIGURE_SHELL_COMMAND_MALLOC_INFO)
+ &rtems_shell_MALLOC_INFO_Command,
+ #endif
+
+ /*
+ * Tracing family commands
+ */
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_RTRACE)) || \
+ defined(CONFIGURE_SHELL_COMMAND_RTRACE)
+ &rtems_shell_RTRACE_Command,
+ #endif
+
+ /*
+ * Network related commands
+ */
+ #if RTEMS_NETWORKING
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL_NETWORKING) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_IFCONFIG)) || \
+ defined(CONFIGURE_SHELL_COMMAND_IFCONFIG)
+ &rtems_shell_IFCONFIG_Command,
+ #endif
+
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL_NETWORKING) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_ROUTE)) || \
+ defined(CONFIGURE_SHELL_COMMAND_ROUTE)
+ &rtems_shell_ROUTE_Command,
+ #endif
+
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL_NETWORKING) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_NETSTATS)) || \
+ defined(CONFIGURE_SHELL_COMMAND_NETSTATS)
+ &rtems_shell_NETSTATS_Command,
+ #endif
+
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL_NETWORKING) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_PING)) || \
+ defined(CONFIGURE_SHELL_COMMAND_PING)
+ &rtems_shell_PING_Command,
+ #endif
+ #endif
+
+ /* Miscanellous shell commands */
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) \
+ && !defined(CONFIGURE_SHELL_NO_COMMAND_RTC)) \
+ || defined(CONFIGURE_SHELL_COMMAND_RTC)
+ &rtems_shell_RTC_Command,
+ #endif
+
+ /*
+ * System related commands
+ */
+ #if defined(RTEMS_DRVMGR_STARTUP) || defined(CONFIGURE_SHELL_COMMAND_DRVMGR)
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_DRVMGR)) || \
+ defined(CONFIGURE_SHELL_COMMAND_DRVMGR)
+ &rtems_shell_DRVMGR_Command,
+ #endif
+ #endif
+
+ #if defined(RTEMS_PCI_CONFIG_LIB)
+ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
+ !defined(CONFIGURE_SHELL_NO_COMMAND_PCI)) || \
+ defined(CONFIGURE_SHELL_COMMAND_PCI)
+ &rtems_shell_PCI_Command,
+ #endif
+ #endif
+
+ /*
+ * User defined shell commands
+ */
+ #if defined(CONFIGURE_SHELL_USER_COMMANDS)
+ CONFIGURE_SHELL_USER_COMMANDS,
+ #endif
+ NULL
+ };
+
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/sparse-disk.h b/cpukit/include/rtems/sparse-disk.h
new file mode 100644
index 0000000000..e558e08925
--- /dev/null
+++ b/cpukit/include/rtems/sparse-disk.h
@@ -0,0 +1,137 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_sparse_disk
+ *
+ * @brief Sparse disk block device API.
+ */
+
+/*
+ * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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 SPARSE_DISK_H
+#define SPARSE_DISK_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <rtems.h>
+#include <rtems/diskdevs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup rtems_sparse_disk Sparse Disk Device
+ *
+ * @ingroup rtems_blkdev
+ *
+ */
+/**@{**/
+
+typedef struct {
+ rtems_blkdev_bnum block;
+ void *data;
+} rtems_sparse_disk_key;
+
+typedef struct rtems_sparse_disk rtems_sparse_disk;
+
+typedef void (*rtems_sparse_disk_delete_handler)(rtems_sparse_disk *sparse_disk);
+
+struct rtems_sparse_disk {
+ rtems_id mutex;
+ rtems_blkdev_bnum blocks_with_buffer;
+ size_t used_count;
+ uint32_t media_block_size;
+ rtems_sparse_disk_delete_handler delete_handler;
+ uint8_t fill_pattern;
+ rtems_sparse_disk_key *key_table;
+};
+
+/**
+ * @brief Creates and registers a sparse disk.
+ *
+ * @param[in] device_file_name The device file name path.
+ * @param[in] media_block_size The media block size in bytes.
+ * @param[in] blocks_with_buffer Blocks of the device with a buffer. Other
+ * blocks can store only fill pattern value bytes.
+ * @param[in] block_count The media block count of the device. It is the sum
+ * of blocks with buffer and blocks that contain only fill pattern value bytes.
+ * @param[in] fill_pattern The fill pattern specifies the byte value of blocks
+ * without a buffer. It is also the initial value for blocks with a buffer.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_NUMBER Media block size or media block count is not
+ * positive. The blocks with buffer count is greater than the media block count.
+ * @retval RTEMS_NO_MEMORY Not enough memory.
+ * @retval RTEMS_TOO_MANY Cannot create semaphore.
+ * @retval RTEMS_UNSATISFIED Cannot create generic device node.
+ *
+ * @see rtems_sparse_disk_register().
+ */
+rtems_status_code rtems_sparse_disk_create_and_register(
+ const char *device_file_name,
+ uint32_t media_block_size,
+ rtems_blkdev_bnum blocks_with_buffer,
+ rtems_blkdev_bnum media_block_count,
+ uint8_t fill_pattern
+);
+
+/**
+ * @brief Frees a sparse disk.
+ *
+ * Calls free() on the sparse disk pointer.
+ */
+void rtems_sparse_disk_free( rtems_sparse_disk *sparse_disk );
+
+/**
+ * @brief Initializes and registers a sparse disk.
+ *
+ * This will create one semaphore for mutual exclusion.
+ *
+ * @param[in] device_file_name The device file name path.
+ * @param[in, out] sparse_disk The sparse disk.
+ * @param[in] media_block_size The media block size in bytes.
+ * @param[in] blocks_with_buffer Blocks of the device with a buffer. Other
+ * blocks can store only fill pattern value bytes.
+ * @param[in] block_count The media block count of the device. It is the sum
+ * of blocks with buffer and blocks that contain only fill pattern value bytes.
+ * @param[in] fill_pattern The fill pattern specifies the byte value of blocks
+ * without a buffer. It is also the initial value for blocks with a buffer.
+ * @param[in] sparse_disk_delete The sparse disk delete handler.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_NUMBER Media block size or media block count is not
+ * positive. The blocks with buffer count is greater than the media block count.
+ * @retval RTEMS_INVALID_ADDRESS Invalid sparse disk address.
+ * @retval RTEMS_TOO_MANY Cannot create semaphore.
+ * @retval RTEMS_UNSATISFIED Cannot create generic device node.
+ */
+rtems_status_code rtems_sparse_disk_register(
+ const char *device_file_name,
+ rtems_sparse_disk *sparse_disk,
+ uint32_t media_block_size,
+ rtems_blkdev_bnum blocks_with_buffer,
+ rtems_blkdev_bnum media_block_count,
+ uint8_t fill_pattern,
+ rtems_sparse_disk_delete_handler sparse_disk_delete
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SPARSE_DISK_H */
diff --git a/cpukit/include/rtems/spurious.h b/cpukit/include/rtems/spurious.h
new file mode 100644
index 0000000000..049f3bf3a0
--- /dev/null
+++ b/cpukit/include/rtems/spurious.h
@@ -0,0 +1,42 @@
+/**
+ * @file rtems/spurious.h
+ *
+ * This file describes the Spurious Interrupt Driver for all boards.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_SPURIOUS_H
+#define _RTEMS_SPURIOUS_H
+
+#include <rtems/rtems/types.h> /* rtems_id */
+#include <rtems/io.h> /* rtems_device_driver */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SPURIOUS_DRIVER_TABLE_ENTRY \
+ { Spurious_Initialize, NULL, NULL, NULL, NULL, NULL }
+
+rtems_device_driver Spurious_Initialize(
+ rtems_device_major_number,
+ rtems_device_minor_number,
+ void *,
+ rtems_id,
+ uint32_t *
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/stackchk.h b/cpukit/include/rtems/stackchk.h
new file mode 100644
index 0000000000..16fc4f9b9d
--- /dev/null
+++ b/cpukit/include/rtems/stackchk.h
@@ -0,0 +1,139 @@
+/**
+ * @file rtems/stackchk.h
+ *
+ * @defgroup libmisc_stackchk Stack Checker Mechanism
+ *
+ * @ingroup libmisc
+ * @brief Stack Checker Information
+ *
+ * This include file contains information necessary to utilize
+ * and install the stack checker mechanism.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2009.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_STACKCHK_H
+#define _RTEMS_STACKCHK_H
+
+#include <stdbool.h> /* bool */
+
+#include <rtems/score/thread.h> /* Thread_Control */
+#include <rtems/print.h>
+
+/**
+ * @defgroup libmisc_stackchk Stack Checker Mechanism
+ *
+ * @ingroup libmisc
+ */
+/**@{*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Checks if current task is blown its stack.
+ *
+ * This method is used to determine if the current stack pointer
+ * of the currently executing task is within bounds.
+ *
+ * @retval This method returns true if the currently executing task
+ * has blown its stack.
+ *
+ */
+bool rtems_stack_checker_is_blown( void );
+
+/**
+ * @brief Print the stack usage report using printk.
+ *
+ * This method prints a stack usage report for the curently executing
+ * task.
+ *
+ * @note It uses printk to print the report.
+ */
+void rtems_stack_checker_report_usage( void );
+
+/**
+ * @brief Print the stack usage report using caller's routine.
+ *
+ * This method prints a stack usage report for the curently executing
+ * task.
+ *
+ * @param[in] context is the context to pass to the print handler
+ * @param[in] print is the print handler
+ *
+ * @note It uses the caller's routine to print the report.
+ */
+void rtems_stack_checker_report_usage_with_plugin(
+ const rtems_printer *printer
+);
+
+/*************************************************************
+ *************************************************************
+ ** Prototyped only so the user extension can be installed **
+ *************************************************************
+ *************************************************************/
+
+/**
+ * @brief Stack Checker Task Create Extension
+ *
+ * This method is the task create extension for the stack checker.
+ *
+ * @param[in] running points to the currently executing task
+ * @param[in] the_thread points to the newly created task
+ *
+ * @note If this this the first task created, the stack checker
+ * will automatically intialize itself.
+ */
+bool rtems_stack_checker_create_extension(
+ Thread_Control *running,
+ Thread_Control *the_thread
+);
+
+/**
+ * @brief Stack Checker Task Context Switch Extension
+ *
+ * This method is the task context switch extension for the stack checker.
+ *
+ * @param[in] running points to the currently executing task which
+ * is being context switched out
+ * @param[in] running points to the heir task which we are switching to
+ *
+ * @note This is called from the internal method _Thread_Dispatch.
+ */
+void rtems_stack_checker_switch_extension(
+ Thread_Control *running,
+ Thread_Control *heir
+);
+
+/**
+ * @brief Stack Checker Extension Set Definition
+ *
+ * This macro defines the user extension handler set for the stack
+ * checker. This macro is normally only used by confdefs.h.
+ */
+#define RTEMS_STACK_CHECKER_EXTENSION \
+{ \
+ rtems_stack_checker_create_extension, /* rtems_task_create */ \
+ 0, /* rtems_task_start */ \
+ 0, /* rtems_task_restart */ \
+ 0, /* rtems_task_delete */ \
+ rtems_stack_checker_switch_extension, /* task_switch */ \
+ 0, /* task_begin */ \
+ 0, /* task_exitted */ \
+ 0 /* rtems_stack_checker_fatal_extension */, /* fatal */ \
+ 0, /* terminate */ \
+}
+
+#ifdef __cplusplus
+}
+#endif
+/**@}*/
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/stdio-redirect.h b/cpukit/include/rtems/stdio-redirect.h
new file mode 100644
index 0000000000..6f1d4cdd98
--- /dev/null
+++ b/cpukit/include/rtems/stdio-redirect.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2014 Chris Johns (chrisj@rtems.org)
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution.
+ *
+ * This software with is provided ``as is'' and with NO WARRANTY.
+ */
+
+/*
+ * @brief Redirect an stdio file decriptor.
+ *
+ * The is a helper module of code design to redirect an stdio file
+ * descriptor. You can optionally have the data buffered and/or you can provide
+ * a handler function that is called when data arrives.
+ *
+ * The module uses standard POSIX calls to implement the redirection and if the
+ * threading was POSIX based the code would be portable. Currently the code
+ * uses RTEMS threads.
+ *
+ * Redirecting stderr and stdout is useful in embedded system because you can
+ * transport the output off your device or create a web interface that can
+ * display the output. This can be a very powerful diagnostic and support tool.
+ *
+ * The implementation does:
+ *
+ * 1. Duplicate the file descriptor (fd) to redirect using the dup call. The
+ * duplicated desciptor is used to echo the output out the existing path.
+ *
+ * 2. Create a pipe using the pipe call.
+ *
+ * 3. Duplicate the pipe's writer file descriptor to user's file
+ * descriptor. This results in any writes to the user's fd being written to
+ * the pipe.
+ *
+ * 4. Create a reader task that blocks on the pipe. It optionally calls a
+ * handler and if configured buffers the data.
+ */
+
+#if !defined(RTEMS_STDIO_REDIRECT_H)
+#define RTEMS_STDIO_REDIRECT_H
+
+#include <stdbool.h>
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * Handler called whenever redirected data arrives.
+ *
+ * @param buffer The data.
+ * @param length The amount of data in the buffer.
+ */
+typedef void (*rtems_stdio_redirect_handler)(const char* buffer,
+ ssize_t length);
+
+/*
+ * Redirector data.
+ */
+typedef struct
+{
+ volatile uint32_t state; /**< The state. */
+ rtems_id reader; /**< The reader thread. */
+ rtems_id lock; /**< Lock for this struct. */
+ int fd; /**< The file descriptor to redirect. */
+ int fd_dup; /**< Duplicated fd to write to. */
+ int pipe[2]; /**< The pipe to the reader thread. */
+ char* input; /**< The input buffer the reader uses. */
+ ssize_t input_size; /**< The input buffer size. */
+ char* buffer; /**< Captured redirected data. */
+ ssize_t buffer_size; /**< Capture buffer size. */
+ ssize_t in; /**< Buffer in index. */
+ bool full; /**< The buffer is full. */
+ bool echo; /**< Echo the data out the existing path. */
+ rtems_stdio_redirect_handler handler; /**< Redirected data handler. */
+} rtems_stdio_redirect;
+
+/*
+ * Open a redirector returning the handle to it.
+ *
+ * @param fd The file descriptor to redirect.
+ * @param priority The priority of the reader thread.
+ */
+rtems_stdio_redirect* rtems_stdio_redirect_open(int fd,
+ rtems_task_priority priority,
+ size_t stack_size,
+ ssize_t input_size,
+ ssize_t buffer_size,
+ bool echo,
+ rtems_stdio_redirect_handler handler);
+
+/*
+ * Close the redirector.
+ */
+void rtems_stdio_redirect_close(rtems_stdio_redirect* sr);
+
+/*
+ * Get data from the capture buffer. Data read is removed from the buffer.
+ *
+ * @param sr The stdio redirection handle.
+ * @param buffer The buffer data is written into.
+ * @param length The size of the buffer.
+ * @return ssize_t The amount of data written and -1 or an error.
+ */
+ssize_t rtems_stdio_redirect_read(rtems_stdio_redirect* sr,
+ char* buffer,
+ ssize_t length);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/stringto.h b/cpukit/include/rtems/stringto.h
new file mode 100644
index 0000000000..878814da54
--- /dev/null
+++ b/cpukit/include/rtems/stringto.h
@@ -0,0 +1,262 @@
+/**
+ * @file rtems/stringto.h
+ *
+ * @defgroup libmisc_conv_help Conversion Helpers
+ *
+ * @ingroup libmisc
+ * @brief Convert String to Pointer (with validation)
+ *
+ * This file defines the interface to a set of string conversion helpers.
+ */
+
+/*
+ * COPYRIGHT (c) 2009-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_STRINGTO_H
+#define _RTEMS_STRINGTO_H
+/**
+ * @defgroup libmisc_conv_help Conversion Helpers
+ *
+ * @ingroup libmisc
+ */
+/**@{*/
+
+#include <rtems.h>
+
+/**
+ * @brief Convert String to Pointer (with validation).
+ *
+ * This method converts a string to a pointer (void *) with
+ * basic numeric validation.
+ *
+ * @param[in] s is the string to convert
+ * @param[in] n points to the variable to place the converted output in
+ * @param[in] endptr is used to keep track of the position in the string
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL on successful conversion
+ * and *n is filled in. Otherwise, the status indicates the
+ * source of the error.
+ */
+rtems_status_code rtems_string_to_pointer(
+ const char *s,
+ void **n,
+ char **endptr
+);
+
+/**
+ * @brief Convert String to Unsigned Character (with validation).
+ *
+ * This method converts a string to an unsigned character with
+ * range validation.
+ *
+ * @param[in] s is the string to convert
+ * @param[in] n points to the variable to place the converted output in
+ * @param[in] endptr is used to keep track of the position in the string
+ * @param[in] base is the expected base of the number
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL on successful conversion
+ * and *n is filled in. Otherwise, the status indicates the
+ * source of the error.
+ */
+rtems_status_code rtems_string_to_unsigned_char(
+ const char *s,
+ unsigned char *n,
+ char **endptr,
+ int base
+);
+
+/**
+ * @brief Convert String to Int (with validation).
+ *
+ * This method converts a string to an int with range validation.
+ *
+ * @param[in] s is the string to convert
+ * @param[in] n points to the variable to place the converted output in
+ * @param[in] endptr is used to keep track of the position in the string
+ * @param[in] base is the expected base of the number
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL on successful conversion
+ * and *n is filled in. Otherwise, the status indicates the
+ * source of the error.
+ */
+rtems_status_code rtems_string_to_int(
+ const char *s,
+ int *n,
+ char **endptr,
+ int base
+);
+
+/**
+ * @brief Convert String to Unsigned Int (with validation).
+ *
+ * This method converts a string to an unsigned int with range validation.
+ *
+ * @param[in] s is the string to convert
+ * @param[in] n points to the variable to place the converted output in
+ * @param[in] endptr is used to keep track of the position in the string
+ * @param[in] base is the expected base of the number
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL on successful conversion
+ * and *n is filled in. Otherwise, the status indicates the
+ * source of the error.
+ */
+rtems_status_code rtems_string_to_unsigned_int(
+ const char *s,
+ unsigned int *n,
+ char **endptr,
+ int base
+);
+
+/**
+ * @brief Convert String to Long (with validation).
+ *
+ * This method converts a string to a long with
+ * range validation.
+ *
+ * @param[in] s is the string to convert
+ * @param[in] n points to the variable to place the converted output in
+ * @param[in] endptr is used to keep track of the position in the string
+ * @param[in] base is the expected base of the number
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL on successful conversion
+ * and *n is filled in. Otherwise, the status indicates the
+ * source of the error.
+ */
+rtems_status_code rtems_string_to_long(
+ const char *s,
+ long *n,
+ char **endptr,
+ int base
+);
+
+/**
+ * @brief Convert String to Unsigned Long (with validation).
+ *
+ * This method converts a string to an unsigned long with
+ * range validation.
+ *
+ * @param[in] s is the string to convert
+ * @param[in] n points to the variable to place the converted output in
+ * @param[in] endptr is used to keep track of the position in the string
+ * @param[in] base is the expected base of the number
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL on successful conversion
+ * and *n is filled in. Otherwise, the status indicates the
+ * source of the error.
+ */
+rtems_status_code rtems_string_to_unsigned_long(
+ const char *s,
+ unsigned long *n,
+ char **endptr,
+ int base
+);
+
+/**
+ * @brief Convert String to Long Long (with validation).
+ *
+ * This method converts a string to a long long with
+ * range validation.
+ *
+ * @param[in] s is the string to convert
+ * @param[in] n points to the variable to place the converted output in
+ * @param[in] endptr is used to keep track of the position in the string
+ * @param[in] base is the expected base of the number
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL on successful conversion
+ * and *n is filled in. Otherwise, the status indicates the
+ * source of the error.
+ */
+rtems_status_code rtems_string_to_long_long(
+ const char *s,
+ long long *n,
+ char **endptr,
+ int base
+);
+
+/**
+ * @brief Convert String to Unsigned Long Long (with validation).
+ *
+ * This method converts a string to an unsigned character with
+ * range validation.
+ *
+ * @param[in] s is the string to convert
+ * @param[in] n points to the variable to place the converted output in
+ * @param[in] endptr is used to keep track of the position in the string
+ * @param[in] base is the expected base of the number
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL on successful conversion
+ * and *n is filled in. Otherwise, the status indicates the
+ * source of the error.
+ */
+rtems_status_code rtems_string_to_unsigned_long_long(
+ const char *s,
+ unsigned long long *n,
+ char **endptr,
+ int base
+);
+
+/**
+ * @brief Convert String to Float (with validation).
+ *
+ * This method converts a string to a float with range validation.
+ *
+ * @param[in] s is the string to convert
+ * @param[in] n points to the variable to place the converted output in
+ * @param[in] endptr is used to keep track of the position in the string
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL on successful conversion
+ * and *n is filled in. Otherwise, the status indicates the
+ * source of the error.
+ */
+rtems_status_code rtems_string_to_float(
+ const char *s,
+ float *n,
+ char **endptr
+);
+
+/**
+ * @brief Convert String to Double (with validation).
+ *
+ * This method converts a string to a double with range validation.
+ *
+ * @param[in] s is the string to convert
+ * @param[in] n points to the variable to place the converted output in
+ * @param[in] endptr is used to keep track of the position in the string
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL on successful conversion
+ * and *n is filled in. Otherwise, the status indicates the
+ * source of the error.
+ */
+rtems_status_code rtems_string_to_double(
+ const char *s,
+ double *n,
+ char **endptr
+);
+
+/**
+ * @brief Convert String to long double (with validation).
+ *
+ * This method converts a string to a long double with range validation.
+ *
+ * @param[in] s is the string to convert
+ * @param[in] n points to the variable to place the converted output in
+ * @param[in] endptr is used to keep track of the position in the string
+ *
+ * @retval This method returns RTEMS_SUCCESSFUL on successful conversion
+ * and *n is filled in. Otherwise, the status indicates the
+ * source of the error.
+ */
+rtems_status_code rtems_string_to_long_double(
+ const char *s,
+ long double *n,
+ char **endptr
+);
+
+#endif
+/**@}*/
diff --git a/cpukit/include/rtems/sysinit.h b/cpukit/include/rtems/sysinit.h
new file mode 100644
index 0000000000..535fb98e2c
--- /dev/null
+++ b/cpukit/include/rtems/sysinit.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2015 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_SYSINIT_H
+#define _RTEMS_SYSINIT_H
+
+#include <rtems/linkersets.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * 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
+ * order values to form a proper integer literal.
+ */
+#define RTEMS_SYSINIT_BSP_WORK_AREAS 000100
+#define RTEMS_SYSINIT_BSP_START 000200
+#define RTEMS_SYSINIT_INITIAL_EXTENSIONS 000300
+#define RTEMS_SYSINIT_MP_EARLY 000301
+#define RTEMS_SYSINIT_DATA_STRUCTURES 000302
+#define RTEMS_SYSINIT_MP 00030e
+#define RTEMS_SYSINIT_USER_EXTENSIONS 000320
+#define RTEMS_SYSINIT_CLASSIC_TASKS 000340
+#define RTEMS_SYSINIT_CLASSIC_TIMER 000341
+#define RTEMS_SYSINIT_CLASSIC_SIGNAL 000342
+#define RTEMS_SYSINIT_CLASSIC_EVENT 000343
+#define RTEMS_SYSINIT_CLASSIC_MESSAGE_QUEUE 000344
+#define RTEMS_SYSINIT_CLASSIC_SEMAPHORE 000345
+#define RTEMS_SYSINIT_CLASSIC_PARTITION 000346
+#define RTEMS_SYSINIT_CLASSIC_REGION 000347
+#define RTEMS_SYSINIT_CLASSIC_DUAL_PORTED_MEMORY 000348
+#define RTEMS_SYSINIT_CLASSIC_RATE_MONOTONIC 000349
+#define RTEMS_SYSINIT_CLASSIC_BARRIER 00034a
+#define RTEMS_SYSINIT_POSIX_SIGNALS 000360
+#define RTEMS_SYSINIT_POSIX_THREADS 000361
+#define RTEMS_SYSINIT_POSIX_MESSAGE_QUEUE 000364
+#define RTEMS_SYSINIT_POSIX_SEMAPHORE 000365
+#define RTEMS_SYSINIT_POSIX_TIMER 000366
+#define RTEMS_SYSINIT_POSIX_SHM 000369
+#define RTEMS_SYSINIT_POSIX_KEYS 00036a
+#define RTEMS_SYSINIT_POSIX_CLEANUP 00036b
+#define RTEMS_SYSINIT_IDLE_THREADS 000380
+#define RTEMS_SYSINIT_LIBIO 000400
+#define RTEMS_SYSINIT_ROOT_FILESYSTEM 000401
+#define RTEMS_SYSINIT_DRVMGR 000500
+#define RTEMS_SYSINIT_MP_SERVER 000501
+#define RTEMS_SYSINIT_BSP_PRE_DRIVERS 000600
+#define RTEMS_SYSINIT_DRVMGR_LEVEL_1 000700
+#define RTEMS_SYSINIT_DEVICE_DRIVERS 000701
+#define RTEMS_SYSINIT_DRVMGR_LEVEL_2 000702
+#define RTEMS_SYSINIT_DRVMGR_LEVEL_3 000703
+#define RTEMS_SYSINIT_DRVMGR_LEVEL_4 000704
+#define RTEMS_SYSINIT_MP_FINALIZE 000705
+#define RTEMS_SYSINIT_CLASSIC_USER_TASKS 000706
+#define RTEMS_SYSINIT_POSIX_USER_THREADS 000707
+#define RTEMS_SYSINIT_STD_FILE_DESCRIPTORS 000800
+#define RTEMS_SYSINIT_LAST ffffff
+
+/*
+ * The value of each order define must consist of exactly two hexadecimal
+ * digits without a 0x-prefix. A 0x-prefix is concatenated with the module and
+ * order values to form a proper integer literal.
+ */
+#define RTEMS_SYSINIT_ORDER_FIRST 00
+#define RTEMS_SYSINIT_ORDER_SECOND 01
+#define RTEMS_SYSINIT_ORDER_THIRD 02
+#define RTEMS_SYSINIT_ORDER_FOURTH 03
+#define RTEMS_SYSINIT_ORDER_FIFTH 04
+#define RTEMS_SYSINIT_ORDER_SIXTH 05
+#define RTEMS_SYSINIT_ORDER_SEVENTH 06
+#define RTEMS_SYSINIT_ORDER_EIGHTH 07
+#define RTEMS_SYSINIT_ORDER_NINETH 08
+#define RTEMS_SYSINIT_ORDER_TENTH 09
+#define RTEMS_SYSINIT_ORDER_MIDDLE 80
+#define RTEMS_SYSINIT_ORDER_LAST ff
+
+typedef void ( *rtems_sysinit_handler )( void );
+
+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 */
+#define RTEMS_SYSINIT_ITEM( handler, module, order ) \
+ _RTEMS_SYSINIT_ITEM( handler, module, order )
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SYSINIT_H */
diff --git a/cpukit/include/rtems/system.h b/cpukit/include/rtems/system.h
new file mode 100644
index 0000000000..26156c64f7
--- /dev/null
+++ b/cpukit/include/rtems/system.h
@@ -0,0 +1,66 @@
+/**
+ * @file
+ *
+ * @brief Information Included in Every Function in the Executive
+ *
+ * This include file contains information that is included in every
+ * function in the executive. This must be the first include file
+ * included in all internal RTEMS files.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2007.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_SYSTEM_H
+#define _RTEMS_SYSTEM_H
+
+#include <rtems/score/cpu.h>
+
+/**
+ * @defgroup ScoreSystem System Information
+ *
+ * @ingroup Score
+ */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ASM
+
+#ifdef RTEMS_POSIX_API
+/** The following is used by the POSIX implementation to catch bad paths. */
+int POSIX_NOT_IMPLEMENTED( void );
+#endif
+
+/**
+ * The following is the extern for the RTEMS version string.
+ *
+ * @note The contents of this string are CPU specific.
+ */
+extern const char _RTEMS_version[];
+
+/**
+ * The following is the extern for the RTEMS copyright string.
+ */
+extern const char _Copyright_Notice[];
+
+/** This macro defines the maximum length of a Classic API name. */
+#define RTEMS_MAXIMUM_NAME_LENGTH sizeof(rtems_name)
+
+#endif /* ASM */
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/telnetd.h b/cpukit/include/rtems/telnetd.h
new file mode 100644
index 0000000000..a5c8a187e3
--- /dev/null
+++ b/cpukit/include/rtems/telnetd.h
@@ -0,0 +1,110 @@
+/*
+ * Original Author: Fernando RUIZ CASAS (fernando.ruiz@ctv.es)
+ * May 2001
+ * Reworked by Till Straumann and .h overhauled by Joel Sherrill.
+ *
+ * Copyright (c) 2009 embedded brains GmbH and others.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * D-82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_TELNETD_H
+#define _RTEMS_TELNETD_H
+
+#include <rtems.h>
+#include <rtems/shell.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool rtems_telnetd_login_check(
+ const char *user,
+ const char *passphrase
+);
+
+/**
+ * @brief Telnet command type.
+ */
+typedef void (*rtems_telnetd_command)(
+ char * /* device name */,
+ void * /* arg */
+);
+
+/**
+ * @brief Telnet configuration structure.
+ */
+typedef struct {
+ /**
+ * @brief Function invoked for each Telnet connection.
+ *
+ * The first parameter contains the device name. The second parameter
+ * contains the argument pointer of this configuration table.
+ */
+ rtems_telnetd_command command;
+
+ /**
+ * @brief Argument for command function.
+ */
+ void *arg;
+
+ /**
+ * @brief Task priority.
+ *
+ * If this parameter is equal to zero, then the priority of network task is
+ * used or 100 if this priority is less than two.
+ */
+ rtems_task_priority priority;
+
+ /**
+ * @brief Task stack size.
+ */
+ size_t stack_size;
+
+ /**
+ * @brief Login check function.
+ *
+ * Method used for login checks. Use @c NULL to disable a login check.
+ */
+ rtems_shell_login_check_t login_check;
+
+ /**
+ * @brief Keep standard IO of the caller.
+ *
+ * Telnet takes over the standard input, output and error associated with
+ * task, if this parameter is set to @c true. In this case, it will @b not
+ * listen on any sockets. When this parameter is @c false, Telnet will
+ * create other tasks for the shell which listen on sockets.
+ */
+ bool keep_stdio;
+} rtems_telnetd_config_table;
+
+/**
+ * @brief Telnet configuration.
+ *
+ * The application must provide this configuration table. It is used by
+ * rtems_telnetd_initialize() to configure the Telnet subsystem. Do not modify
+ * the entries after the intialization since it is used internally.
+ */
+extern rtems_telnetd_config_table rtems_telnetd_config;
+
+/**
+ * @brief Initializes the Telnet subsystem.
+ *
+ * Uses the application provided @ref rtems_telnetd_config configuration table.
+ */
+rtems_status_code rtems_telnetd_initialize(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/termios_printk.h b/cpukit/include/rtems/termios_printk.h
new file mode 100644
index 0000000000..dcb183533a
--- /dev/null
+++ b/cpukit/include/rtems/termios_printk.h
@@ -0,0 +1,101 @@
+/*===============================================================*\
+| Project: RTEMS remote gdb over serial line |
++-----------------------------------------------------------------+
+| File: termios_printk.h |
++-----------------------------------------------------------------+
+| Copyright (c) 2002 IMD |
+| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
+| <Thomas.Doerfler@imd-systems.de> |
+| all rights reserved |
++-----------------------------------------------------------------+
+| this file declares intialization functions to add |
+| printk polled output via termios polled drivers |
+| |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 13.04.02 creation doe |
+\*===============================================================*/
+#ifndef _TERMIOS_PRINTK_H
+#define _TERMIOS_PRINTK_H
+
+#include <rtems.h>
+#include <termios.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ uint32_t baudrate; /* debug baud rate, e.g. 57600 */
+ void (*callout)(void); /* callout pointer during polling */
+ const char *devname; /* debug device, e.g. "/dev/tty01" */
+} termios_printk_conf_t;
+
+/*
+ * must be defined in init module...
+ */
+extern termios_printk_conf_t termios_printk_conf;
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+void termios_printk_outputchar
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| send one character to serial port |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+(
+ char c /* character to print */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| <none> |
+\*=========================================================================*/
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int termios_printk_inputchar
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| wait for one character from serial port |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+(
+ void /* none */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| received character |
+\*=========================================================================*/
+
+
+/*=========================================================================*\
+| Function: |
+\*-------------------------------------------------------------------------*/
+int termios_printk_open
+
+/*-------------------------------------------------------------------------*\
+| Purpose: |
+| try to open given serial debug port |
++---------------------------------------------------------------------------+
+| Input Parameters: |
+\*-------------------------------------------------------------------------*/
+(
+ const char *dev_name, /* name of device to open */
+ uint32_t baudrate /* baud rate to use */
+ );
+/*-------------------------------------------------------------------------*\
+| Return Value: |
+| 0 on success, -1 and errno otherwise |
+\*=========================================================================*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TERMIOS_PRINTK_H */
diff --git a/cpukit/include/rtems/termios_printk_cnf.h b/cpukit/include/rtems/termios_printk_cnf.h
new file mode 100644
index 0000000000..03c3090c38
--- /dev/null
+++ b/cpukit/include/rtems/termios_printk_cnf.h
@@ -0,0 +1,81 @@
+/**
+ * @file
+ *
+ * @brief Adds printk Support via Polled termios
+ */
+
+/*===============================================================*\
+| Project: RTEMS configure remote gdb over serial line |
++-----------------------------------------------------------------+
+| File: termios_printk_cnf.h |
++-----------------------------------------------------------------+
+| Copyright (c) 2002 IMD |
+| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
+| <Thomas.Doerfler@imd-systems.de> |
+| all rights reserved |
++-----------------------------------------------------------------+
+| this file declares intialization functions to add |
+| printk support via polled termios |
+| |
++-----------------------------------------------------------------+
+| date history ID |
+| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
+| 13.05.02 creation doe |
+\*===============================================================*/
+#ifndef _TERMIOS_PRINTK_CNF_H
+#define _TERMIOS_PRINTK_CNF_H
+
+#include <rtems/termios_printk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef CONFIGURE_INIT
+
+/*
+ * fallback for baud rate to use
+ */
+#ifndef CONFIGURE_TERMIOS_PRINTK_BAUDRATE
+#define CONFIGURE_TERMIOS_PRINTK_BAUDRATE 9600
+#endif
+
+/*
+ * fallback for device name to use
+ */
+#ifndef CONFIGURE_TERMIOS_PRINTK_DEVNAME
+#define CONFIGURE_TERMIOS_PRINTK_DEVNAME "/dev/console"
+#endif
+
+#ifdef CONFIGURE_USE_TERMIOS_PRINTK
+/*
+ * fill in termios_printk_conf structure
+ */
+termios_printk_conf_t termios_printk_conf = {
+ CONFIGURE_TERMIOS_PRINTK_BAUDRATE,
+
+#ifdef CONFIGURE_TERMIOS_PRINTK_CALLOUT
+ CONFIGURE_TERMIOS_PRINTK_CALLOUT,
+#else
+ NULL,
+#endif
+ CONFIGURE_TERMIOS_PRINTK_DEVNAME,
+};
+#endif
+
+int termios_printk_init(void) {
+#ifdef CONFIGURE_USE_TERMIOS_PRINTK
+ return termios_printk_open(termios_printk_conf.devname,
+ termios_printk_conf.baudrate);
+#else
+ return 0;
+#endif
+}
+
+#endif /* CONFIGURE_INIT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TERMIOS_PRINTK_CNF_H */
diff --git a/cpukit/include/rtems/termiostypes.h b/cpukit/include/rtems/termiostypes.h
new file mode 100644
index 0000000000..b3cac66e92
--- /dev/null
+++ b/cpukit/include/rtems/termiostypes.h
@@ -0,0 +1,602 @@
+/**
+ * @file rtems/termiostypes.h
+ *
+ * RTEMS termios device support internal data structures
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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 __TERMIOSTYPES_H
+#define __TERMIOSTYPES_H
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/assoc.h>
+#include <rtems/chain.h>
+#include <sys/ioccom.h>
+#include <stdint.h>
+#include <termios.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup TermiostypesSupport RTEMS Termios Device Support
+ *
+ * @ingroup libcsupport
+ *
+ * @brief RTEMS Termios Device Support Internal Data Structures
+ */
+
+/*
+ * Wakeup callback data structure
+ */
+struct ttywakeup {
+ void (*sw_pfn)(struct termios *tty, void *arg);
+ void *sw_arg;
+};
+
+/*
+ * Variables associated with the character buffer
+ */
+struct rtems_termios_rawbuf {
+ char *theBuf;
+ volatile unsigned int Head;
+ volatile unsigned int Tail;
+ volatile unsigned int Size;
+ rtems_id 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_id 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.
+ */
+RTEMS_INLINE_ROUTINE 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.
+ *
+ * @see rtems_termios_device_install().
+ */
+typedef struct rtems_termios_device_node {
+ rtems_chain_node node;
+ rtems_device_major_number major;
+ rtems_device_minor_number minor;
+ const rtems_termios_device_handler *handler;
+ const rtems_termios_device_flow *flow;
+ rtems_termios_device_context *context;
+ struct rtems_termios_tty *tty;
+} rtems_termios_device_node;
+
+/*
+ * Variables associated with each termios instance.
+ * One structure for each hardware I/O device.
+ */
+typedef struct rtems_termios_tty {
+ /*
+ * Linked-list of active TERMIOS devices
+ */
+ struct rtems_termios_tty *forw;
+ struct rtems_termios_tty *back;
+
+ /*
+ * How many times has this device been opened
+ */
+ int refcount;
+
+ /*
+ * This device
+ */
+ rtems_device_major_number major;
+ rtems_device_minor_number minor;
+
+ /*
+ * Mutual-exclusion semaphores
+ */
+ rtems_id isem;
+ rtems_id osem;
+
+ /*
+ * The canonical (cooked) character buffer
+ */
+ char *cbuf;
+ int ccount;
+ int cindex;
+
+ /*
+ * Keep track of cursor (printhead) position
+ */
+ int column;
+ int read_start_column;
+
+ /*
+ * The ioctl settings
+ */
+ struct termios termios;
+ rtems_interval vtimeTicks;
+
+ /*
+ * Raw input character buffer
+ */
+ struct rtems_termios_rawbuf rawInBuf;
+ uint32_t rawInBufSemaphoreOptions;
+ rtems_interval rawInBufSemaphoreTimeout;
+ rtems_interval rawInBufSemaphoreFirstTimeout;
+ unsigned int rawInBufDropped; /* Statistics */
+
+ /*
+ * Raw output character buffer
+ */
+ struct rtems_termios_rawbuf rawOutBuf;
+ int t_dqlen; /* count of characters dequeued from device */
+ enum {rob_idle, rob_busy, rob_wait } rawOutBufState;
+
+ /*
+ * Callbacks to device-specific routines
+ */
+ rtems_termios_callbacks device;
+
+ /**
+ * @brief Context for legacy devices using the callbacks.
+ */
+ rtems_termios_device_context legacy_device_context;
+
+ /**
+ * @brief The device handler.
+ */
+ rtems_termios_device_handler handler;
+
+ /**
+ * @brief The device flow control handler.
+ */
+ rtems_termios_device_flow flow;
+
+ volatile unsigned int flow_ctrl;
+ unsigned int lowwater,highwater;
+
+ /*
+ * I/O task IDs (for task-driven drivers)
+ */
+ rtems_id rxTaskId;
+ rtems_id txTaskId;
+
+ /*
+ * line discipline related stuff
+ */
+ int t_line; /* id of line discipline */
+ void *t_sc; /* hook for discipline-specific data structure */
+
+ /*
+ * Wakeup callback variables
+ */
+ struct ttywakeup tty_snd;
+ struct ttywakeup tty_rcv;
+ bool tty_rcvwakeup;
+
+ /**
+ * @brief Corresponding device node.
+ */
+ rtems_termios_device_node *device_node;
+
+ /**
+ * @brief Context for device driver.
+ */
+ rtems_termios_device_context *device_context;
+} rtems_termios_tty;
+
+/**
+ * @brief Installs a Termios device.
+ *
+ * The installed Termios device may be removed via unlink().
+ *
+ * @param[in] device_file The device file path.
+ * @param[in] handler The device handler. It must be persistent throughout the
+ * installed time of the device.
+ * @param[in] flow The device flow control handler. The device flow control
+ * handler are optional and may be @c NULL. If present must be persistent
+ * throughout the installed time of the device.
+ * @param[in] context The device context. It must be persistent throughout the
+ * installed time of the device.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_NO_MEMORY Not enough memory to create a device node.
+ * @retval RTEMS_UNSATISFIED Creation of the device file failed.
+ * @retval RTEMS_INCORRECT_STATE Termios is not initialized.
+ *
+ * @see rtems_termios_get_device_context().
+ */
+rtems_status_code rtems_termios_device_install(
+ const char *device_file,
+ const rtems_termios_device_handler *handler,
+ const rtems_termios_device_flow *flow,
+ rtems_termios_device_context *context
+);
+
+/**
+ * @brief Returns the device context of an installed Termios device.
+ *
+ * @param[in] tty The Termios control.
+ */
+RTEMS_INLINE_ROUTINE void *rtems_termios_get_device_context(
+ const rtems_termios_tty *tty
+)
+{
+ return tty->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.
+ */
+RTEMS_INLINE_ROUTINE 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.
+ */
+RTEMS_INLINE_ROUTINE 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
+ * value is chosen which minimizes the difference to the value specified.
+ *
+ * @param[in] term The Termios attributes.
+ * @param[in] baud The current baud setting of the device.
+ */
+void rtems_termios_set_best_baud(
+ struct termios *term,
+ uint32_t baud
+);
+
+struct rtems_termios_linesw {
+ int (*l_open) (struct rtems_termios_tty *tp);
+ int (*l_close)(struct rtems_termios_tty *tp);
+ int (*l_read )(struct rtems_termios_tty *tp,rtems_libio_rw_args_t *args);
+ int (*l_write)(struct rtems_termios_tty *tp,rtems_libio_rw_args_t *args);
+ int (*l_rint )(int c,struct rtems_termios_tty *tp);
+ int (*l_start)(struct rtems_termios_tty *tp);
+ int (*l_ioctl)(struct rtems_termios_tty *tp,rtems_libio_ioctl_args_t *args);
+ int (*l_modem)(struct rtems_termios_tty *tp,int flags);
+};
+
+/*
+ * FIXME: this should move to termios.h!
+ */
+void rtems_termios_rxirq_occured(struct rtems_termios_tty *tty);
+
+/*
+ * FIXME: this should move to termios.h!
+ * put a string to output ring buffer
+ */
+void rtems_termios_puts (
+ const void *buf,
+ size_t len,
+ struct rtems_termios_tty *tty
+);
+
+/*
+ * global hooks for line disciplines
+ */
+extern struct rtems_termios_linesw rtems_termios_linesw[];
+extern int rtems_termios_nlinesw;
+
+#define TTYDISC 0 /* termios tty line discipline */
+#define TABLDISC 3 /* tablet discipline */
+#define SLIPDISC 4 /* serial IP discipline */
+#define PPPDISC 5 /* PPP discipline */
+#define MAXLDISC 8
+
+/* baudrate xxx integer type */
+typedef uint32_t rtems_termios_baud_t;
+
+/**
+ * @brief RTEMS Termios Baud Table
+ */
+extern const rtems_assoc_t rtems_termios_baud_table [];
+
+/**
+ * @brief Converts the Integral Baud value @a baud to the Termios Control Flag
+ * Representation
+ *
+ * @retval B0 Invalid baud value or a baud value of 0.
+ * @retval other Baud constant according to @a baud.
+ */
+speed_t rtems_termios_number_to_baud(rtems_termios_baud_t baud);
+
+/**
+ * @brief Converts the baud flags to an integral baud value.
+ *
+ * @retval 0 Invalid baud value or a baud value of @c B0.
+ * @retval other Integral baud value.
+ */
+rtems_termios_baud_t rtems_termios_baud_to_number(speed_t baud);
+
+/**
+ * @brief Convert Bxxx Constant to Index
+ */
+int rtems_termios_baud_to_index(rtems_termios_baud_t termios_baud);
+
+/**
+ * @brief Sets the initial @a baud in the Termios context @a tty.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 Invalid baud value.
+ */
+int rtems_termios_set_initial_baud(
+ struct rtems_termios_tty *tty,
+ rtems_termios_baud_t baud
+);
+
+/**
+ * @brief Termios kqueue() filter filesystem node handler
+ *
+ * Real implementation is provided by libbsd.
+ */
+int rtems_termios_kqfilter(
+ rtems_libio_t *iop,
+ struct knote *kn
+);
+
+/**
+ * @brief Termios mmap() filter filesystem node handler
+ *
+ * Real implementation is provided by libbsd.
+ */
+int rtems_termios_mmap(
+ rtems_libio_t *iop,
+ void **addr,
+ size_t len,
+ int prot,
+ off_t off
+);
+
+/**
+ * @brief Termios poll() filesystem node handler.
+ *
+ * Real implementation is provided by libbsd.
+ */
+int rtems_termios_poll(
+ rtems_libio_t *iop,
+ int events
+);
+
+#define RTEMS_IO_SNDWAKEUP _IOW('t', 11, struct ttywakeup ) /* send tty wakeup */
+#define RTEMS_IO_RCVWAKEUP _IOW('t', 12, struct ttywakeup ) /* recv tty wakeup */
+
+#define OLCUC 0x00000100 /* map lower case to upper case on output */
+#define IUCLC 0x00004000 /* map upper case to lower case on input */
+
+#define RTEMS_TERMIOS_NUMBER_BAUD_RATES 25
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TERMIOSTYPES_H */
diff --git a/cpukit/include/rtems/test.h b/cpukit/include/rtems/test.h
new file mode 100644
index 0000000000..3dbdb9e32e
--- /dev/null
+++ b/cpukit/include/rtems/test.h
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2014, 2017 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_TEST_H
+#define _RTEMS_TEST_H
+
+#include <rtems.h>
+#include <rtems/printer.h>
+#include <rtems/score/atomic.h>
+#include <rtems/score/smpbarrier.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup RTEMSTest Test Support
+ *
+ * @brief Test support functions.
+ *
+ * @{
+ */
+
+/**
+ * @brief Each test must define a test name string.
+ */
+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(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code
+);
+
+/**
+ * @brief Initial extension for tests.
+ */
+#define RTEMS_TEST_INITIAL_EXTENSION \
+ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, rtems_test_fatal_extension }
+
+/**
+ * @brief Test states.
+ */
+typedef enum
+{
+ RTEMS_TEST_STATE_PASS,
+ RTEMS_TEST_STATE_FAIL,
+ RTEMS_TEST_STATE_USER_INPUT,
+ RTEMS_TEST_STATE_INDETERMINATE,
+ RTEMS_TEST_STATE_BENCHMARK
+} RTEMS_TEST_STATE;
+
+#if (TEST_STATE_EXPECTED_FAIL && TEST_STATE_USER_INPUT) || \
+ (TEST_STATE_EXPECTED_FAIL && TEST_STATE_INDETERMINATE) || \
+ (TEST_STATE_EXPECTED_FAIL && TEST_STATE_BENCHMARK) || \
+ (TEST_STATE_USER_INPUT && TEST_STATE_INDETERMINATE) || \
+ (TEST_STATE_USER_INPUT && TEST_STATE_BENCHMARK) || \
+ (TEST_STATE_INDETERMINATE && TEST_STATE_BENCHMARK)
+ #error Test states must be unique
+#endif
+
+#if TEST_STATE_EXPECTED_FAIL
+ #define TEST_STATE RTEMS_TEST_STATE_FAIL
+#elif TEST_STATE_USER_INPUT
+ #define TEST_STATE RTEMS_TEST_STATE_USER_INPUT
+#elif TEST_STATE_INDETERMINATE
+ #define TEST_STATE RTEMS_TEST_STATE_INDETERMINATE
+#elif TEST_STATE_BENCHMARK
+ #define TEST_STATE RTEMS_TEST_STATE_BENCHMARK
+#else
+ #define TEST_STATE RTEMS_TEST_STATE_PASS
+#endif
+
+/**
+ * @brief Prints a begin of test message using printf().
+ *
+ * @returns As specified by printf().
+ */
+int rtems_test_begin(const char* name, const RTEMS_TEST_STATE state);
+
+/**
+ * @brief Prints an end of test message using printf().
+ *
+ * @returns As specified by printf().
+ */
+int rtems_test_end(const char* name);
+
+/**
+ * @brief Exit the test without calling exit() since it closes stdin, etc and
+ * pulls in stdio code
+ */
+void rtems_test_exit(int status) RTEMS_NO_RETURN;
+
+/**
+ * @brief Prints via the RTEMS printer.
+ *
+ * @returns 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;
+
+/**
+ * @brief Internal context for parallel job execution.
+ */
+typedef struct {
+ Atomic_Ulong stop;
+ SMP_barrier_Control barrier;
+ size_t worker_count;
+ rtems_id worker_ids[RTEMS_TEST_PARALLEL_PROCESSOR_MAX];
+ rtems_id stop_worker_timer_id;
+ const struct rtems_test_parallel_job *jobs;
+ size_t job_count;
+} rtems_test_parallel_context;
+
+/**
+ * @brief Worker task setup handler.
+ *
+ * Called during rtems_test_parallel() to optionally setup a worker task before
+ * it is started.
+ *
+ * @param[in] ctx The parallel context.
+ * @param[in] worker_index The worker index.
+ * @param[in] worker_id The worker task identifier.
+ */
+typedef void (*rtems_test_parallel_worker_setup)(
+ rtems_test_parallel_context *ctx,
+ size_t worker_index,
+ rtems_id worker_id
+);
+
+/**
+ * @brief Basic parallel job description.
+ */
+struct rtems_test_parallel_job {
+ /**
+ * @brief Job initialization handler.
+ *
+ * This handler executes only in the context of the master worker before the
+ * job body handler.
+ *
+ * @param[in] ctx The parallel context.
+ * @param[in] arg The user specified argument.
+ * @param[in] active_workers Count of active workers. Depends on the cascade
+ * option.
+ *
+ * @return The desired job body execution time in clock ticks. See
+ * rtems_test_parallel_stop_job().
+ */
+ rtems_interval (*init)(
+ rtems_test_parallel_context *ctx,
+ void *arg,
+ size_t active_workers
+ );
+
+ /**
+ * @brief Job body handler.
+ *
+ * @param[in] ctx The parallel context.
+ * @param[in] arg The user specified argument.
+ * @param[in] active_workers Count of active workers. Depends on the cascade
+ * option.
+ * @param[in] worker_index The worker index. It ranges from 0 to the
+ * processor count minus one.
+ */
+ void (*body)(
+ rtems_test_parallel_context *ctx,
+ void *arg,
+ size_t active_workers,
+ size_t worker_index
+ );
+
+ /**
+ * @brief Job finalization handler.
+ *
+ * This handler executes only in the context of the master worker after the
+ * job body handler.
+ *
+ * @param[in] ctx The parallel context.
+ * @param[in] arg The user specified argument.
+ * @param[in] active_workers Count of active workers. Depends on the cascade
+ * option.
+ */
+ void (*fini)(
+ rtems_test_parallel_context *ctx,
+ void *arg,
+ size_t active_workers
+ );
+
+ /**
+ * @brief Job specific argument.
+ */
+ void *arg;
+
+ /**
+ * @brief Job cascading flag.
+ *
+ * This flag indicates whether the job should be executed in a cascaded
+ * manner (the job is executed on one processor first, two processors
+ * afterwards and incremented step by step until all processors are used).
+ */
+ bool cascade;
+};
+
+/**
+ * @brief Indicates if a job body should stop its work loop.
+ *
+ * @param[in] ctx The parallel context.
+ *
+ * @retval true The job body should stop its work loop and return to the caller.
+ * @retval false Otherwise.
+ */
+static inline bool rtems_test_parallel_stop_job(
+ const rtems_test_parallel_context *ctx
+)
+{
+ return _Atomic_Load_ulong(&ctx->stop, ATOMIC_ORDER_RELAXED) != 0;
+}
+
+/**
+ * @brief Indicates if a worker is the master worker.
+ *
+ * The master worker is the thread that called rtems_test_parallel().
+ *
+ * @param[in] worker_index The worker index.
+ *
+ * @retval true This is the master worker.
+ * @retval false Otherwise.
+ */
+static inline bool rtems_test_parallel_is_master_worker(size_t worker_index)
+{
+ return worker_index == 0;
+}
+
+/**
+ * @brief Returns the task identifier for a worker.
+ *
+ * @param[in] ctx The parallel context.
+ * @param[in] worker_index The worker index.
+ *
+ * @return The task identifier of the worker.
+ */
+static inline rtems_id rtems_test_parallel_get_task_id(
+ const rtems_test_parallel_context *ctx,
+ size_t worker_index
+)
+{
+ return ctx->worker_ids[worker_index];
+}
+
+/**
+ * @brief Runs a bunch of jobs in parallel on all processors of the system.
+ *
+ * The worker tasks inherit the priority of the executing task.
+ *
+ * There are SMP barriers before and after the job body.
+ *
+ * @param[in] ctx The parallel context.
+ * @param[in] worker_setup Optional handler to setup a worker task before it is
+ * started.
+ * @param[in] jobs The table of jobs.
+ * @param[in] job_count The count of jobs in the job table.
+ */
+void rtems_test_parallel(
+ rtems_test_parallel_context *ctx,
+ rtems_test_parallel_worker_setup worker_setup,
+ const rtems_test_parallel_job *jobs,
+ size_t job_count
+);
+
+/**
+ * @brief Performs a busy loop with the specified iteration count.
+ *
+ * This function is optimized to not perform memory accesses and should have a
+ * small jitter.
+ *
+ * @param[in] count The iteration count.
+ */
+void rtems_test_busy(uint_fast32_t count);
+
+/**
+ * @brief Returns a count value for rtems_test_busy() which yields roughly a
+ * duration of one clock tick.
+ */
+uint_fast32_t rtems_test_get_one_tick_busy_count(void);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_TEST_H */
diff --git a/cpukit/include/rtems/timecounter.h b/cpukit/include/rtems/timecounter.h
new file mode 100644
index 0000000000..8d1bd78618
--- /dev/null
+++ b/cpukit/include/rtems/timecounter.h
@@ -0,0 +1,335 @@
+/**
+ * @file
+ *
+ * @ingroup SAPITimecounter
+ *
+ * @brief Timecounter API
+ */
+
+/*
+ * Copyright (c) 2015 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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_TIMECOUNTER_H
+#define _RTEMS_TIMECOUNTER_H
+
+#include <rtems/score/timecounter.h>
+#include <rtems/score/basedefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @defgroup SAPITimecounter Timecounter Support
+ *
+ * @{
+ */
+
+/**
+ * @brief Timecounter quality for the clock drivers.
+ *
+ * Timecounter with higher quality value are used in favour of those with lower
+ * quality value.
+ */
+#define RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER 100
+
+/**
+ * @copydoc _Timecounter_Install()
+ *
+ * Below is an exemplary code snippet that shows the adjustable parameters and
+ * the following call of the install routine.
+ *
+ * @code
+ * struct timecounter tc;
+ *
+ * uint32_t get_timecount( struct timecounter *tc )
+ * {
+ * return some_free_running_counter;
+ * }
+ *
+ * void install( void )
+ * {
+ * tc.tc_get_timecount = get_timecount;
+ * tc.tc_counter_mask = 0xffffffff;
+ * tc.tc_frequency = 123456;
+ * tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ * rtems_timecounter_install( &tc );
+ * }
+ * @endcode
+ */
+RTEMS_INLINE_ROUTINE void rtems_timecounter_install(
+ struct timecounter *tc
+)
+{
+ _Timecounter_Install( tc );
+}
+
+/**
+ * @copydoc _Timecounter_Tick()
+ */
+RTEMS_INLINE_ROUTINE void rtems_timecounter_tick(void)
+{
+ _Timecounter_Tick();
+}
+
+/**
+ * @brief Simple timecounter to support legacy clock drivers.
+ */
+typedef struct {
+ struct timecounter tc;
+ uint64_t scaler;
+ uint32_t real_interval;
+ uint32_t binary_interval;
+} rtems_timecounter_simple;
+
+/**
+ * @brief At tick handling done under protection of the timecounter lock.
+ */
+typedef void rtems_timecounter_simple_at_tick(
+ rtems_timecounter_simple *tc
+);
+
+/**
+ * @brief Returns the current value of a simple timecounter.
+ */
+typedef uint32_t rtems_timecounter_simple_get(
+ rtems_timecounter_simple *tc
+);
+
+/**
+ * @brief Returns true if the interrupt of a simple timecounter is pending, and
+ * false otherwise.
+ */
+typedef bool rtems_timecounter_simple_is_pending(
+ rtems_timecounter_simple *tc
+);
+
+/**
+ * @brief Initializes and installs a simple timecounter.
+ *
+ * A simple timecounter can be used if the hardware provides no free running
+ * counter. A periodic hardware counter must be provided. The counter period
+ * must be synchronous to the clock tick. The counter ticks per clock tick is
+ * scaled up to the next power of two.
+ *
+ * @param[in] tc Zero initialized simple timecounter.
+ * @param[in] counter_frequency_in_hz The hardware counter frequency in Hz.
+ * @param[in] counter_ticks_per_clock_tick The hardware counter ticks per clock
+ * tick.
+ * @param[in] get_timecount The method to get the current time count.
+ *
+ * @code
+ * #include <rtems/timecounter.h>
+ *
+ * static rtems_timecounter_simple some_tc;
+ *
+ * static uint32_t some_tc_get( rtems_timecounter_simple *tc )
+ * {
+ * return some.value;
+ * }
+ *
+ * static bool some_tc_is_pending( rtems_timecounter_simple *tc )
+ * {
+ * return some.is_pending;
+ * }
+ *
+ * static uint32_t some_tc_get_timecount( struct timecounter *tc )
+ * {
+ * return rtems_timecounter_simple_downcounter_get(
+ * tc,
+ * some_tc_get,
+ * some_tc_is_pending
+ * );
+ * }
+ *
+ * static void some_tc_tick( void )
+ * {
+ * rtems_timecounter_simple_downcounter_tick( &some_tc, some_tc_get );
+ * }
+ *
+ * void some_tc_init( void )
+ * {
+ * uint64_t us_per_tick;
+ * uint32_t counter_frequency_in_hz;
+ * uint32_t counter_ticks_per_clock_tick;
+ *
+ * us_per_tick = rtems_configuration_get_microseconds_per_tick();
+ * counter_frequency_in_hz = some_tc_get_frequency();
+ * counter_ticks_per_clock_tick =
+ * (uint32_t) ( counter_frequency_in_hz * us_per_tick ) / 1000000;
+ *
+ * some_tc_init_hardware( counter_ticks_per_clock_tick );
+ * some_tc_init_clock_tick_interrupt( some_tc_tick );
+ *
+ * rtems_timecounter_simple_install(
+ * &some_tc,
+ * counter_frequency_in_hz,
+ * counter_ticks_per_clock_tick,
+ * some_tc_get_timecount
+ * );
+ * }
+ * @endcode
+ *
+ * @see rtems_timecounter_simple_downcounter_get(),
+ * rtems_timecounter_simple_downcounter_tick(),
+ * rtems_timecounter_simple_upcounter_get() and
+ * rtems_timecounter_simple_upcounter_tick().
+ */
+void rtems_timecounter_simple_install(
+ rtems_timecounter_simple *tc,
+ uint32_t counter_frequency_in_hz,
+ uint32_t counter_ticks_per_clock_tick,
+ timecounter_get_t *get_timecount
+);
+
+/**
+ * @brief Maps a simple timecounter value into its binary frequency domain.
+ *
+ * @param[in] tc The simple timecounter.
+ * @param[in] value The value of the simple timecounter.
+ *
+ * @return The scaled value.
+ */
+RTEMS_INLINE_ROUTINE uint32_t rtems_timecounter_simple_scale(
+ const rtems_timecounter_simple *tc,
+ uint32_t value
+)
+{
+ return (uint32_t) ( ( value * tc->scaler ) >> 32 );
+}
+
+/**
+ * @brief Performs a simple timecounter tick for downcounters.
+ *
+ * @param[in] tc The simple timecounter.
+ * @param[in] get The method to get the value of the simple timecounter.
+ * @param[in] at_tick The method to perform work under timecounter lock
+ * protection at this tick, e.g. clear a pending flag.
+ */
+RTEMS_INLINE_ROUTINE void rtems_timecounter_simple_downcounter_tick(
+ rtems_timecounter_simple *tc,
+ rtems_timecounter_simple_get get,
+ rtems_timecounter_simple_at_tick at_tick
+)
+{
+ ISR_lock_Context lock_context;
+ uint32_t current;
+
+ _Timecounter_Acquire( &lock_context );
+
+ ( *at_tick )( tc );
+
+ current = rtems_timecounter_simple_scale(
+ tc,
+ tc->real_interval - ( *get )( tc )
+ );
+
+ _Timecounter_Tick_simple( tc->binary_interval, current, &lock_context );
+}
+
+/**
+ * @brief Performs a simple timecounter tick for upcounters.
+ *
+ * @param[in] tc The simple timecounter.
+ * @param[in] get The method to get the value of the simple timecounter.
+ * @param[in] at_tick The method to perform work under timecounter lock
+ * protection at this tick, e.g. clear a pending flag.
+ */
+RTEMS_INLINE_ROUTINE void rtems_timecounter_simple_upcounter_tick(
+ rtems_timecounter_simple *tc,
+ rtems_timecounter_simple_get get,
+ rtems_timecounter_simple_at_tick at_tick
+)
+{
+ ISR_lock_Context lock_context;
+ uint32_t current;
+
+ _Timecounter_Acquire( &lock_context );
+
+ ( *at_tick )( tc );
+
+ current = rtems_timecounter_simple_scale( tc, ( *get )( tc ) );
+
+ _Timecounter_Tick_simple( tc->binary_interval, current, &lock_context );
+}
+
+/**
+ * @brief Gets the simple timecounter value mapped to its binary frequency
+ * domain for downcounters.
+ *
+ * @param[in] tc The simple timecounter.
+ * @param[in] get The method to get the value of the simple timecounter.
+ * @param[in] is_pending The method which indicates if the interrupt of the
+ * simple timecounter is pending.
+ */
+RTEMS_INLINE_ROUTINE uint32_t rtems_timecounter_simple_downcounter_get(
+ struct timecounter *tc_base,
+ rtems_timecounter_simple_get get,
+ rtems_timecounter_simple_is_pending is_pending
+)
+{
+ rtems_timecounter_simple *tc;
+ uint32_t counter;
+ uint32_t interval;
+
+ tc = (rtems_timecounter_simple *) tc_base;
+ counter = ( *get )( tc );
+ interval = tc->real_interval;
+
+ if ( ( *is_pending )( tc ) ) {
+ counter = ( *get )( tc );
+ interval *= 2;
+ }
+
+ return rtems_timecounter_simple_scale( tc, interval - counter );
+}
+
+/**
+ * @brief Gets the simple timecounter value mapped to its binary frequency
+ * domain for upcounters.
+ *
+ * @param[in] tc The simple timecounter.
+ * @param[in] get The method to get the value of the simple timecounter.
+ * @param[in] is_pending The method which indicates if the interrupt of the
+ * simple timecounter is pending.
+ */
+RTEMS_INLINE_ROUTINE uint32_t rtems_timecounter_simple_upcounter_get(
+ struct timecounter *tc_base,
+ rtems_timecounter_simple_get get,
+ rtems_timecounter_simple_is_pending is_pending
+)
+{
+ rtems_timecounter_simple *tc;
+ uint32_t counter;
+ uint32_t interval;
+
+ tc = (rtems_timecounter_simple *) tc_base;
+ counter = ( *get )( tc );
+ interval = 0;
+
+ if ( ( *is_pending )( tc ) ) {
+ counter = ( *get )( tc );
+ interval = tc->real_interval;
+ }
+
+ return rtems_timecounter_simple_scale( tc, interval + counter );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_TIMECOUNTER_H */
diff --git a/cpukit/include/rtems/timespec.h b/cpukit/include/rtems/timespec.h
new file mode 100644
index 0000000000..e82d271492
--- /dev/null
+++ b/cpukit/include/rtems/timespec.h
@@ -0,0 +1,305 @@
+/**
+ * @file
+ *
+ * @brief Timespec API
+ *
+ * This include file contains API for manipulating timespecs.
+ */
+
+/*
+ * Copyright (c) 2012.
+ * Krzysztof Miesowicz <krzysztof.miesowicz@gmail.com>
+ *
+ * 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_TIMESPEC_H
+#define _RTEMS_TIMESPEC_H
+
+#include <rtems/score/timespec.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup TimespecAPI Timespec
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * @brief Timespec API
+ *
+ * @{
+ *
+ */
+
+/**
+ * @brief Is timespec valid
+ *
+ * This method determines the validity of a timespec.
+ *
+ * @param[in] time is the timespec instance to validate.
+ *
+ * @retval true The timespec is valid.
+ * @retval false The timespec is not valid.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_timespec_is_valid(
+ const struct timespec *time
+)
+{
+ return _Timespec_Is_valid(time);
+}
+
+/**
+ * @brief Timespec less than operator.
+ *
+ * This method is the less than operator for timespecs.
+ *
+ * @param[in] lhs is the left hand side timespec
+ * @param[in] rhs is the right hand side timespec
+ *
+ * @retval true @a lhs is less than @a rhs.
+ * @retval false @a lhs is not less than @a rhs.
+ *
+ */
+RTEMS_INLINE_ROUTINE bool rtems_timespec_less_than(
+ const struct timespec *lhs,
+ const struct timespec *rhs
+)
+{
+ return _Timespec_Less_than(lhs,rhs);
+}
+
+/**
+ * @brief Add to a timespec.
+ *
+ * This routine adds two timespecs. The second argument is added
+ * to the first.
+ *
+ * @param[in] time is the base time to be added to
+ * @param[in] add is the timespec to add to the first argument
+ *
+ * @return This method returns the number of seconds @a time increased by.
+ */
+RTEMS_INLINE_ROUTINE uint32_t rtems_timespec_add_to(
+ struct timespec *time,
+ const struct timespec *add
+)
+{
+ return _Timespec_Add_to(time,add);
+}
+
+/**
+ * @brief Convert timespec to number of ticks.
+ *
+ * This routine convert the @a time timespec to the corresponding number
+ * of clock ticks.
+ *
+ * @param[in] time is the time to be converted
+ *
+ * @return This method returns the number of ticks computed.
+ */
+RTEMS_INLINE_ROUTINE uint32_t rtems_timespec_to_ticks(
+ const struct timespec *time
+)
+{
+ return _Timespec_To_ticks(time);
+}
+
+/**
+ * @brief Convert ticks to timespec.
+ *
+ * This routine converts the @a ticks value to the corresponding
+ * timespec format @a time.
+ *
+ * @param[in] time is the timespec format time result
+ * @param[in] ticks is the number of ticks to convert
+ */
+
+RTEMS_INLINE_ROUTINE void rtems_timespec_from_ticks(
+ uint32_t ticks,
+ struct timespec *time
+)
+{
+ _Timespec_From_ticks(ticks,time);
+}
+
+/**
+ * @brief Subtract two timespec.
+ *
+ * This routine subtracts two timespecs. @a result is set to
+ * @a end - @a start.
+ *
+ * @param[in] start is the starting time
+ * @param[in] end is the ending time
+ * @param[in] result is the difference between starting and ending time.
+ *
+ * @return This method fills in @a result.
+ */
+RTEMS_INLINE_ROUTINE void rtems_timespec_subtract(
+ const struct timespec *start,
+ const struct timespec *end,
+ struct timespec *result
+)
+{
+ _Timespec_Subtract(start,end,result);
+}
+
+/**
+ * @brief Divide timespec by integer.
+ *
+ * This routine divides a timespec by an integer value. The expected
+ * use is to assist in benchmark calculations where you typically
+ * divide a duration by a number of iterations.
+ *
+ * @param[in] time is the total
+ * @param[in] iterations is the number of iterations
+ * @param[in] result is the average time.
+ *
+ * @return This method fills in @a result.
+ */
+RTEMS_INLINE_ROUTINE void rtems_timespec_divide_by_integer(
+ const struct timespec *time,
+ uint32_t iterations,
+ struct timespec *result
+)
+{
+ _Timespec_Divide_by_integer(time,iterations,result);
+}
+
+/**
+ * @brief Divide timespec.
+ *
+ * This routine divides a timespec by another timespec. The
+ * intended use is for calculating percentages to three decimal points.
+ *
+ * @param[in] lhs is the left hand number
+ * @param[in] rhs is the right hand number
+ * @param[in] ival_percentage is the integer portion of the average
+ * @param[in] fval_percentage is the thousandths of percentage
+ *
+ * @return This method fills in @a result.
+ */
+RTEMS_INLINE_ROUTINE void rtems_timespec_divide(
+ const struct timespec *lhs,
+ const struct timespec *rhs,
+ uint32_t *ival_percentage,
+ uint32_t *fval_percentage
+)
+{
+ _Timespec_Divide(lhs,rhs,ival_percentage,fval_percentage);
+}
+
+/**
+ * @brief Set timespec to seconds nanosecond.
+ *
+ * This method sets the timespec to the specified seconds and nanoseconds
+ * value.
+ *
+ * @param[in] _time points to the timespec instance to validate.
+ * @param[in] _seconds is the seconds portion of the timespec
+ * @param[in] _nanoseconds is the nanoseconds portion of the timespec
+ */
+RTEMS_INLINE_ROUTINE void rtems_timespec_set(
+ struct timespec *_time,
+ time_t _seconds,
+ uint32_t _nanoseconds
+)
+{
+ _Timespec_Set( _time, _seconds, _nanoseconds );
+}
+
+/**
+ * @brief Zero timespec.
+ *
+ * This method sets the timespec to zero.
+ * value.
+ *
+ * @param[in] _time points to the timespec instance to zero.
+ */
+RTEMS_INLINE_ROUTINE void rtems_timespec_zero(
+ struct timespec *_time
+)
+{
+ _Timespec_Set_to_zero( _time );
+}
+
+/**
+ * @brief Get seconds portion of timespec.
+ *
+ * This method returns the seconds portion of the specified timespec
+ *
+ * @param[in] _time points to the timespec
+ *
+ * @return The seconds portion of @a _time.
+ */
+RTEMS_INLINE_ROUTINE time_t rtems_timespec_get_seconds(
+ struct timespec *_time
+)
+{
+ return _Timespec_Get_seconds( _time );
+}
+
+/**
+ * @brief Get nanoseconds portion of timespec.
+ *
+ * This method returns the nanoseconds portion of the specified timespec
+ *
+ * @param[in] _time points to the timespec
+ *
+ * @return The nanoseconds portion of @a _time.
+ */
+RTEMS_INLINE_ROUTINE uint32_t rtems_timespec_get_nanoseconds(
+ struct timespec *_time
+)
+{
+ return _Timespec_Get_nanoseconds( _time );
+}
+
+/**
+ * @brief Timespec greater than operator.
+ *
+ * This method is the greater than operator for timespecs.
+ *
+ * @param[in] _lhs is the left hand side timespec
+ * @param[in] _rhs is the right hand side timespec
+ *
+ * @retval true @a _lhs is greater than @a _rhs.
+ * @retval false @a _lhs is not greater than @a _rhs.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_timespec_greater_than(
+ const struct timespec *_lhs,
+ const struct timespec *_rhs
+)
+{
+ return _Timespec_Greater_than( _lhs, _rhs );
+}
+/**
+ * @brief Timespec equal to Operator
+ *
+ * This method is the is equal to than operator for timespecs.
+ *
+ * @param[in] lhs is the left hand side timespec
+ * @param[in] rhs is the right hand side timespec
+ *
+ * @retval true @a lhs is equal to @a rhs.
+ * @retval false @a lhs is not equal to @a rhs.
+ */
+RTEMS_INLINE_ROUTINE bool rtems_timespec_equal_to(
+ const struct timespec *lhs,
+ const struct timespec *rhs
+)
+{
+ return _Timespec_Equal_to( lhs, rhs);
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/tod.h b/cpukit/include/rtems/tod.h
new file mode 100644
index 0000000000..971e8548e8
--- /dev/null
+++ b/cpukit/include/rtems/tod.h
@@ -0,0 +1,70 @@
+/**
+ * @file
+ *
+ * @ingroup shared_tod
+ *
+ * @brief Real Time Clock Time of Day API Definition
+ */
+
+/*
+ *
+ * Based on MVME162 TOD by:
+ * COPYRIGHT (C) 1997
+ * by Katsutoshi Shibuya - BU Denken Co.,Ltd. - Sapporo - JAPAN
+ * ALL RIGHTS RESERVED
+ *
+ * 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 TOD_H
+#define TOD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup shared_tod RTC
+ *
+ * @ingroup bsp_shared
+ *
+ * @brief Set the RTC
+ */
+int setRealTime(
+ const rtems_time_of_day *tod
+);
+
+/*
+ * Get the time from the RTC.
+ */
+
+void getRealTime(
+ rtems_time_of_day *tod
+);
+
+/*
+ * Read real time from RTC and set it to RTEMS' clock manager
+ */
+
+void setRealTimeToRTEMS(void);
+
+/*
+ * Read time from RTEMS' clock manager and set it to RTC
+ */
+
+void setRealTimeFromRTEMS(void);
+
+/*
+ * Return the difference between RTC and RTEMS' clock manager time in minutes.
+ * If the difference is greater than 1 day, this returns 9999.
+ */
+
+int checkRealTime(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/include/rtems/trace/rtems-trace-buffer-vars.h b/cpukit/include/rtems/trace/rtems-trace-buffer-vars.h
new file mode 100644
index 0000000000..8f0ff08587
--- /dev/null
+++ b/cpukit/include/rtems/trace/rtems-trace-buffer-vars.h
@@ -0,0 +1,148 @@
+/**
+ * @file
+ *
+ * @ingroup Shell
+ *
+ * @brief Access to the RTEMS Trace Buffer Generator (TBG).
+ */
+/*
+ * Copyright (c) 2015 Chris Johns <chrisj@rtems.org>
+ *
+ * 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.
+ */
+
+#if !defined (_RTEMS_TRACE_BUFFER_VARS_H_)
+#define _RTEMS_TRACE_BUFFER_VARS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * These functions are provided as a separated interface to the Trace Buffer
+ * Generatror (TBG) data are not really designed for any real-time performance
+ * type interface.
+ *
+ * Separating the data from the codes stops the compiler incorrectly loop
+ * optimising.
+ */
+
+typedef struct
+{
+ uint32_t size;
+ const char* const type;
+} __rtld_trace_sig_arg;
+
+ typedef struct {
+ uint32_t argc;
+ const __rtld_trace_sig_arg* args;
+} __rtld_trace_sig;
+
+typedef __rtld_trace_sig_arg rtems_trace_sig_arg;
+typedef __rtld_trace_sig rtems_trace_sig;
+
+/**
+ * Returns the number of trace functions.
+ */
+uint32_t rtems_trace_names_size (void);
+
+/**
+ * Return the name given an index. No range checking.
+ */
+const char* rtems_trace_names (const uint32_t index);
+
+/**
+ * Returns the number of words in the enables array.
+ */
+uint32_t rtems_trace_enables_size (void);
+
+/**
+ * Return the enable 32bit bitmap indexed into the enables array. No range
+ * checking.
+ */
+uint32_t rtems_trace_enables (const uint32_t index);
+
+/**
+ * Returns the number of words in the triggers array.
+ */
+uint32_t rtems_trace_triggers_size (void);
+
+/**
+ * Return the trigger 32bit bitmap indexed into the triggers array. No range
+ * checking.
+ */
+uint32_t rtems_trace_triggers (const uint32_t index);
+
+/**
+ * Return the trace function signature.
+ */
+const rtems_trace_sig* rtems_trace_signatures (const uint32_t index);
+
+/**
+ * Return true is the enable bit is set for the trace function index.
+ */
+bool rtems_trace_enable_set(const uint32_t index);
+
+/**
+ * Return true is the trigger bit is set for the trace function index.
+ */
+bool rtems_trace_trigger_set(const uint32_t index);
+
+/**
+ * The application has been linked with Trace Buffering generated code.
+ */
+bool rtems_trace_buffering_present (void);
+
+/**
+ * Return the trace buffering mode flags.
+ */
+uint32_t rtems_trace_buffering_mode (void);
+
+/**
+ * Return the size of the trace buffering buffer in words.
+ */
+uint32_t rtems_trace_buffering_buffer_size (void);
+
+/**
+ * Return the base of the trace buffering buffer.
+ */
+uint32_t* rtems_trace_buffering_buffer (void);
+
+/**
+ * Return the buffer level. This is only stable if tracing has finished.
+ */
+uint32_t rtems_trace_buffering_buffer_in (void);
+
+/**
+ * The tracing has finished.
+ */
+bool rtems_trace_buffering_finished (void);
+
+/**
+ * Trace has been triggered and enable trace functions are being recorded.
+ */
+bool rtems_trace_buffering_triggered (void);
+
+/**
+ * Start tracing by clearing the triggered flag, setting to 0 and clearing the
+ * finished flag.
+ */
+void rtems_trace_buffering_start (void);
+
+/**
+ * Stop tracing by setting the finished flag.
+ */
+void rtems_trace_buffering_stop (void);
+
+/**
+ * Resume tracing by setting the finished flag.
+ */
+void rtems_trace_buffering_resume (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/cpukit/include/rtems/untar.h b/cpukit/include/rtems/untar.h
new file mode 100644
index 0000000000..bc0a97c103
--- /dev/null
+++ b/cpukit/include/rtems/untar.h
@@ -0,0 +1,260 @@
+/**
+ * @file
+ *
+ * @brief Untar an Image
+ *
+ * This file defines the interface to methods which can untar an image.
+ */
+
+/*
+ * Written by: Jake Janovetz <janovetz@tempest.ece.uiuc.edu>
+ *
+ * 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_UNTAR_H
+#define _RTEMS_UNTAR_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <tar.h>
+#include <zlib.h>
+#include <xz.h>
+
+#include <rtems/print.h>
+
+/**
+ * @defgroup libmisc_untar_img Untar Image
+ *
+ * @ingroup libmisc
+ */
+/**@{*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UNTAR_SUCCESSFUL 0
+#define UNTAR_FAIL 1
+#define UNTAR_INVALID_CHECKSUM 2
+#define UNTAR_INVALID_HEADER 3
+
+#define UNTAR_GZ_INFLATE_FAILED 4
+#define UNTAR_GZ_INFLATE_END_FAILED 5
+
+int Untar_FromMemory(void *tar_buf, size_t size);
+int Untar_FromMemory_Print(void *tar_buf, size_t size, const rtems_printer* printer);
+int Untar_FromFile(const char *tar_name);
+int Untar_FromFile_Print(const char *tar_name, const rtems_printer* printer);
+
+typedef struct {
+ /**
+ * @brief Current context state.
+ */
+ enum {
+ UNTAR_CHUNK_HEADER,
+ UNTAR_CHUNK_SKIP,
+ UNTAR_CHUNK_WRITE,
+ UNTAR_CHUNK_ERROR
+ } state;
+
+ /**
+ * @brief Header buffer.
+ */
+ char header[512];
+
+ /**
+ * @brief Name buffer.
+ */
+ char fname[100];
+
+ /**
+ * @brief Number of bytes of overall length are already processed.
+ */
+ size_t done_bytes;
+
+ /**
+ * @brief Mode of the file.
+ */
+ unsigned long mode;
+
+ /**
+ * @brief Overall amount of bytes to be processed.
+ */
+ unsigned long todo_bytes;
+
+ /**
+ * @brief Overall amount of blocks to be processed.
+ */
+ unsigned long todo_blocks;
+
+ /**
+ * @brief File descriptor of output file.
+ */
+ int out_fd;
+} Untar_ChunkContext;
+
+typedef struct {
+ /**
+ * @brief Instance of Chunk Context needed for tar decompression.
+ */
+ Untar_ChunkContext base;
+
+ /**
+ * @brief Current zlib context.
+ */
+ z_stream strm;
+
+ /**
+ * @brief Buffer that contains the inflated data.
+ */
+ void *inflateBuffer;
+
+ /**
+ * @brief Size of buffer that contains the inflated data.
+ */
+ size_t inflateBufferSize;
+
+} Untar_GzChunkContext;
+
+typedef struct {
+ /**
+ * @brief Instance of Chunk Context needed for tar decompression.
+ */
+ Untar_ChunkContext base;
+
+ /**
+ * @brief Xz context.
+ */
+ struct xz_dec* strm;
+
+ /**
+ * @brief Xz buffer.
+ */
+ struct xz_buf buf;
+
+ /**
+ * @brief Buffer that contains the inflated data.
+ */
+ void *inflateBuffer;
+
+ /**
+ * @brief Size of buffer that contains the inflated data.
+ */
+ size_t inflateBufferSize;
+
+} Untar_XzChunkContext;
+
+/**
+ * @brief Initializes the Untar_ChunkContext files out of a part of a block of
+ * memory.
+ *
+ * @param Untar_ChunkContext *context [in] Pointer to a context structure.
+ */
+void Untar_ChunkContext_Init(Untar_ChunkContext *context);
+
+/*
+ * @brief Rips links, directories and files out of a part of a block of memory.
+ *
+ * @param Untar_ChunkContext *context [in] Pointer to a context structure.
+ * @param void *chunk [in] Pointer to a chunk of a TAR buffer.
+ * @param size_t chunk_size [in] Length of the chunk of a TAR buffer.
+ *
+ * @retval UNTAR_SUCCESSFUL (0) on successful completion.
+ * @retval UNTAR_FAIL for a faulty step within the process.
+ * @retval UNTAR_INVALID_CHECKSUM for an invalid header checksum.
+ * @retval UNTAR_INVALID_HEADER for an invalid header.
+ */
+
+int Untar_FromChunk_Print(
+ Untar_ChunkContext *context,
+ void *chunk,
+ size_t chunk_size,
+ const rtems_printer* printer
+);
+
+/**
+ * @brief Initializes the Untar_ChunkGzContext.
+ *
+ * @param Untar_ChunkGzContext *context [in] Pointer to a context structure.
+ * @param void *inflateBuffer [in] Pointer to a context structure.
+ * @param size_t inflateBufferSize [in] Size of inflateBuffer.
+ */
+int Untar_GzChunkContext_Init(
+ Untar_GzChunkContext *ctx,
+ void *inflateBuffer,
+ size_t inflateBufferSize
+);
+
+/*
+ * @brief Untars a GZ compressed POSIX TAR file.
+ *
+ * This is a subroutine used to rip links, directories, and
+ * files out of a tar.gz/tgz file.
+ *
+ * @param Untar_ChunkContext *context [in] Pointer to a context structure.
+ * @param ssize buflen [in] Size of valid bytes in input buffer.
+ * @param z_stream *strm [in] Pointer to the current zlib context.
+ */
+int Untar_FromGzChunk_Print(
+ Untar_GzChunkContext *ctx,
+ void *chunk,
+ size_t chunk_size,
+ const rtems_printer* printer
+);
+
+/**
+ * @brief Initializes the Untar_ChunkXzContext.
+ *
+ * @param Untar_ChunkXzContext *context [in] Pointer to a context structure.
+ * @param enum xz_mode mode [in] Dictionary mode.
+ * @param uint32_t dict_max [in] Maximum size of dictionary.
+ * @param void *inflateBuffer [in] Pointer to a context structure.
+ * @param size_t inflateBufferSize [in] Size of inflateBuffer.
+ */
+int Untar_XzChunkContext_Init(
+ Untar_XzChunkContext *ctx,
+ enum xz_mode mode,
+ uint32_t dict_max,
+ void *inflateBuffer,
+ size_t inflateBufferSize
+);
+
+/*
+ * @brief Untars a XZ compressed POSIX TAR file.
+ *
+ * This is a subroutine used to rip links, directories, and
+ * files out of a tar.gz/tgz file.
+ *
+ * @param Untar_ChunkContext *context [in] Pointer to a context structure.
+ * @param ssize buflen [in] Size of valid bytes in input buffer.
+ * @param z_stream *strm [in] Pointer to the current zlib context.
+ */
+int Untar_FromXzChunk_Print(
+ Untar_XzChunkContext *ctx,
+ const void *chunk,
+ size_t chunk_size,
+ const rtems_printer* printer
+);
+
+/**************************************************************************
+ * This converts octal ASCII number representations into an
+ * unsigned long. Only support 32-bit numbers for now.
+ *************************************************************************/
+extern unsigned long
+_rtems_octal2ulong(const char *octascii, size_t len);
+
+/************************************************************************
+ * Compute the TAR checksum and check with the value in
+ * the archive. The checksum is computed over the entire
+ * header, but the checksum field is substituted with blanks.
+ ************************************************************************/
+extern int
+_rtems_tar_header_checksum(const char *bufr);
+
+#ifdef __cplusplus
+}
+#endif
+/**@}*/
+#endif /* _RTEMS_UNTAR_H */
diff --git a/cpukit/include/rtems/version.h b/cpukit/include/rtems/version.h
new file mode 100644
index 0000000000..b806cb8c2f
--- /dev/null
+++ b/cpukit/include/rtems/version.h
@@ -0,0 +1,77 @@
+/**
+ * @file
+ *
+ * @brief Version API.
+ */
+
+/*
+ * Copyright (C) 2017.
+ * Chris Johns <chrisj@rtems.org>
+ *
+ * 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_VERSION_H
+#define _RTEMS_VERSION_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicVersion Version
+ *
+ * @ingroup ClassicVersion
+ *
+ * @brief The Version API provides functions to return the version or parts of
+ * the version of RTEMS you are using.
+ */
+/**@{**/
+
+/**
+ * @brief Returns the version string.
+ *
+ * @retval text The version as a string.
+ */
+const char *rtems_version( void );
+
+/**
+ * @brief Returns the version's major number.
+ *
+ * @retval int The version's major number.
+ */
+int rtems_version_major( void );
+
+/**
+ * @brief Returns the version's minor number.
+ *
+ * @retval int The version's minor number.
+ */
+int rtems_version_minor( void );
+
+/**
+ * @brief Returns the version's revision number.
+ *
+ * @retval int The version's revision number.
+ */
+int rtems_version_revision( void );
+
+/**
+ * @brief Returns the version control key for the current version of code that
+ * has been built. The key is specific to the version control system being used
+ * and allows the built version to be identified.
+ *
+ * @retval int The version's version control key.
+ */
+const char *rtems_version_control_key( void );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/cpukit/include/rtems/vmeintr.h b/cpukit/include/rtems/vmeintr.h
new file mode 100644
index 0000000000..74bda9bf08
--- /dev/null
+++ b/cpukit/include/rtems/vmeintr.h
@@ -0,0 +1,59 @@
+/**
+ * @file
+ *
+ * @brief VMEbus Interface Library
+ *
+ * This file is the specification for the VMEbus interface library
+ * which should be provided by all BSPs for VMEbus Single Board
+ * Computers but currently only a few do so.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-1999.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * 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_VMEINTR_H
+#define _RTEMS_VMEINTR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This defines the mask which is used to determine which
+ * interrupt levels are affected by a call to this package.
+ * The LSB corresponds to VME interrupt 0 and the MSB
+ * to VME interrupt 7.
+ *
+ */
+
+typedef uint8_t VME_interrupt_Mask;
+
+/*
+ * VME_interrupt_Disable
+ *
+ */
+
+void VME_interrupt_Disable (
+ VME_interrupt_Mask mask /* IN */
+);
+
+/*
+ * VME_interrupt_Disable
+ *
+ */
+
+void VME_interrupt_Enable (
+ VME_interrupt_Mask mask /* IN */
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of include file */