summaryrefslogtreecommitdiffstats
path: root/cpukit/include/rtems
diff options
context:
space:
mode:
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 */