From ac7d5ef06a6d6e8d84abbd1f0b82162725f98326 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 11 May 1995 17:39:37 +0000 Subject: Initial revision --- cpukit/libcsupport/include/clockdrv.h | 58 ++ cpukit/libcsupport/include/console.h | 40 ++ cpukit/libcsupport/include/iosupp.h | 44 ++ cpukit/libcsupport/include/rtems/libcsupport.h | 47 ++ cpukit/libcsupport/include/spurious.h | 38 ++ cpukit/libcsupport/include/timerdrv.h | 40 ++ cpukit/libcsupport/include/vmeintr.h | 58 ++ cpukit/libcsupport/src/README | 37 ++ cpukit/libcsupport/src/__brk.c | 40 ++ cpukit/libcsupport/src/__gettod.c | 84 +++ cpukit/libcsupport/src/__times.c | 65 ++ cpukit/libcsupport/src/malloc.c | 280 +++++++++ cpukit/libcsupport/src/newlibc.c | 292 +++++++++ cpukit/libcsupport/src/no_libc.c | 45 ++ cpukit/libcsupport/src/unixlibc.c | 7 + cpukit/libmisc/README | 16 + cpukit/libmisc/monitor/README | 7 + cpukit/libmisc/monitor/mon-monitor.c | 307 +++++++++ cpukit/libmisc/monitor/mon-symbols.c | 327 ++++++++++ cpukit/libmisc/monitor/monitor.h | 38 ++ cpukit/libmisc/monitor/symbols.h | 80 +++ cpukit/libmisc/stackchk/README | 41 ++ cpukit/libmisc/stackchk/check.c | 439 +++++++++++++ cpukit/libmisc/stackchk/internal.h | 94 +++ cpukit/libmisc/stackchk/stackchk.h | 41 ++ cpukit/rtems/include/rtems.h | 79 +++ cpukit/rtems/include/rtems/rtems/asr.h | 177 ++++++ cpukit/rtems/include/rtems/rtems/attr.h | 188 ++++++ cpukit/rtems/include/rtems/rtems/clock.h | 102 +++ cpukit/rtems/include/rtems/rtems/dpmem.h | 210 +++++++ cpukit/rtems/include/rtems/rtems/event.h | 158 +++++ cpukit/rtems/include/rtems/rtems/eventmp.h | 147 +++++ cpukit/rtems/include/rtems/rtems/eventset.h | 142 +++++ cpukit/rtems/include/rtems/rtems/intr.h | 125 ++++ cpukit/rtems/include/rtems/rtems/message.h | 461 ++++++++++++++ cpukit/rtems/include/rtems/rtems/modes.h | 183 ++++++ cpukit/rtems/include/rtems/rtems/mp.h | 67 ++ cpukit/rtems/include/rtems/rtems/msgmp.h | 175 ++++++ cpukit/rtems/include/rtems/rtems/options.h | 79 +++ cpukit/rtems/include/rtems/rtems/part.h | 290 +++++++++ cpukit/rtems/include/rtems/rtems/partmp.h | 160 +++++ cpukit/rtems/include/rtems/rtems/ratemon.h | 285 +++++++++ cpukit/rtems/include/rtems/rtems/region.h | 311 +++++++++ cpukit/rtems/include/rtems/rtems/regionmp.h | 165 +++++ cpukit/rtems/include/rtems/rtems/sem.h | 238 +++++++ cpukit/rtems/include/rtems/rtems/semmp.h | 163 +++++ cpukit/rtems/include/rtems/rtems/signal.h | 72 +++ cpukit/rtems/include/rtems/rtems/signalmp.h | 147 +++++ cpukit/rtems/include/rtems/rtems/status.h | 109 ++++ cpukit/rtems/include/rtems/rtems/taskmp.h | 167 +++++ cpukit/rtems/include/rtems/rtems/tasks.h | 315 ++++++++++ cpukit/rtems/include/rtems/rtems/timer.h | 292 +++++++++ cpukit/rtems/inline/rtems/rtems/asr.inl | 105 ++++ cpukit/rtems/inline/rtems/rtems/attr.inl | 125 ++++ cpukit/rtems/inline/rtems/rtems/dpmem.inl | 75 +++ cpukit/rtems/inline/rtems/rtems/event.inl | 30 + cpukit/rtems/inline/rtems/rtems/eventset.inl | 71 +++ cpukit/rtems/inline/rtems/rtems/message.inl | 160 +++++ cpukit/rtems/inline/rtems/rtems/modes.inl | 136 ++++ cpukit/rtems/inline/rtems/rtems/options.inl | 47 ++ cpukit/rtems/inline/rtems/rtems/part.inl | 157 +++++ cpukit/rtems/inline/rtems/rtems/ratemon.inl | 113 ++++ cpukit/rtems/inline/rtems/rtems/region.inl | 101 +++ cpukit/rtems/inline/rtems/rtems/sem.inl | 73 +++ cpukit/rtems/inline/rtems/rtems/status.inl | 60 ++ cpukit/rtems/inline/rtems/rtems/tasks.inl | 90 +++ cpukit/rtems/inline/rtems/rtems/timer.inl | 112 ++++ cpukit/rtems/macros/rtems/rtems/asr.inl | 89 +++ cpukit/rtems/macros/rtems/rtems/attr.inl | 91 +++ cpukit/rtems/macros/rtems/rtems/dpmem.inl | 59 ++ cpukit/rtems/macros/rtems/rtems/event.inl | 28 + cpukit/rtems/macros/rtems/rtems/eventset.inl | 53 ++ cpukit/rtems/macros/rtems/rtems/message.inl | 118 ++++ cpukit/rtems/macros/rtems/rtems/modes.inl | 101 +++ cpukit/rtems/macros/rtems/rtems/options.inl | 39 ++ cpukit/rtems/macros/rtems/rtems/part.inl | 117 ++++ cpukit/rtems/macros/rtems/rtems/ratemon.inl | 85 +++ cpukit/rtems/macros/rtems/rtems/region.inl | 75 +++ cpukit/rtems/macros/rtems/rtems/sem.inl | 58 ++ cpukit/rtems/macros/rtems/rtems/status.inl | 47 ++ cpukit/rtems/macros/rtems/rtems/tasks.inl | 82 +++ cpukit/rtems/macros/rtems/rtems/timer.inl | 85 +++ cpukit/rtems/src/dpmem.c | 268 ++++++++ cpukit/rtems/src/event.c | 294 +++++++++ cpukit/rtems/src/eventmp.c | 188 ++++++ cpukit/rtems/src/intr.c | 85 +++ cpukit/rtems/src/mp.c | 128 ++++ cpukit/rtems/src/msg.c | 708 +++++++++++++++++++++ cpukit/rtems/src/msgmp.c | 397 ++++++++++++ cpukit/rtems/src/part.c | 322 ++++++++++ cpukit/rtems/src/partmp.c | 300 +++++++++ cpukit/rtems/src/ratemon.c | 401 ++++++++++++ cpukit/rtems/src/region.c | 456 ++++++++++++++ cpukit/rtems/src/regionmp.c | 308 +++++++++ cpukit/rtems/src/rtclock.c | 153 +++++ cpukit/rtems/src/rtemstimer.c | 343 ++++++++++ cpukit/rtems/src/sem.c | 483 ++++++++++++++ cpukit/rtems/src/semmp.c | 306 +++++++++ cpukit/rtems/src/signal.c | 110 ++++ cpukit/rtems/src/signalmp.c | 187 ++++++ cpukit/rtems/src/taskmp.c | 338 ++++++++++ cpukit/rtems/src/tasks.c | 816 ++++++++++++++++++++++++ cpukit/sapi/include/rtems/config.h | 321 ++++++++++ cpukit/sapi/include/rtems/extension.h | 169 +++++ cpukit/sapi/include/rtems/fatal.h | 49 ++ cpukit/sapi/include/rtems/init.h | 101 +++ cpukit/sapi/include/rtems/io.h | 204 ++++++ cpukit/sapi/include/rtems/mptables.h | 29 + cpukit/sapi/inline/rtems/extension.inl | 73 +++ cpukit/sapi/macros/rtems/extension.inl | 58 ++ cpukit/sapi/src/debug.c | 62 ++ cpukit/sapi/src/exinit.c | 245 ++++++++ cpukit/sapi/src/extension.c | 156 +++++ cpukit/sapi/src/fatal.c | 54 ++ cpukit/sapi/src/io.c | 316 ++++++++++ cpukit/score/cpu/hppa1.1/cpu.c | 313 +++++++++ cpukit/score/cpu/i386/asm.h | 131 ++++ cpukit/score/cpu/i386/cpu.c | 121 ++++ cpukit/score/cpu/i386/rtems/asm.h | 131 ++++ cpukit/score/cpu/i960/asm.h | 107 ++++ cpukit/score/cpu/i960/cpu.c | 124 ++++ cpukit/score/cpu/m68k/asm.h | 127 ++++ cpukit/score/cpu/m68k/cpu.c | 97 +++ cpukit/score/cpu/m68k/rtems/asm.h | 127 ++++ cpukit/score/cpu/no_cpu/asm.h | 98 +++ cpukit/score/cpu/no_cpu/cpu.c | 132 ++++ cpukit/score/cpu/no_cpu/cpu_asm.c | 152 +++++ cpukit/score/cpu/no_cpu/rtems/asm.h | 98 +++ cpukit/score/cpu/unix/cpu.c | 529 ++++++++++++++++ cpukit/score/include/rtems/debug.h | 98 +++ cpukit/score/include/rtems/score/address.h | 122 ++++ cpukit/score/include/rtems/score/bitfield.h | 49 ++ cpukit/score/include/rtems/score/chain.h | 432 +++++++++++++ cpukit/score/include/rtems/score/context.h | 133 ++++ cpukit/score/include/rtems/score/copyrt.h | 42 ++ cpukit/score/include/rtems/score/heap.h | 396 ++++++++++++ cpukit/score/include/rtems/score/isr.h | 239 +++++++ cpukit/score/include/rtems/score/mpci.h | 171 +++++ cpukit/score/include/rtems/score/mppkt.h | 123 ++++ cpukit/score/include/rtems/score/object.h | 380 +++++++++++ cpukit/score/include/rtems/score/objectmp.h | 165 +++++ cpukit/score/include/rtems/score/priority.h | 195 ++++++ cpukit/score/include/rtems/score/stack.h | 95 +++ cpukit/score/include/rtems/score/states.h | 337 ++++++++++ cpukit/score/include/rtems/score/sysstate.h | 143 +++++ cpukit/score/include/rtems/score/thread.h | 721 +++++++++++++++++++++ cpukit/score/include/rtems/score/threadmp.h | 134 ++++ cpukit/score/include/rtems/score/threadq.h | 264 ++++++++ cpukit/score/include/rtems/score/tod.h | 300 +++++++++ cpukit/score/include/rtems/score/tqdata.h | 90 +++ cpukit/score/include/rtems/score/userext.h | 213 +++++++ cpukit/score/include/rtems/score/watchdog.h | 471 ++++++++++++++ cpukit/score/include/rtems/score/wkspace.h | 99 +++ cpukit/score/include/rtems/system.h | 132 ++++ cpukit/score/inline/rtems/score/address.inl | 109 ++++ cpukit/score/inline/rtems/score/chain.inl | 292 +++++++++ cpukit/score/inline/rtems/score/heap.inl | 203 ++++++ cpukit/score/inline/rtems/score/isr.inl | 70 +++ cpukit/score/inline/rtems/score/mppkt.inl | 49 ++ cpukit/score/inline/rtems/score/object.inl | 198 ++++++ cpukit/score/inline/rtems/score/objectmp.inl | 62 ++ cpukit/score/inline/rtems/score/priority.inl | 168 +++++ cpukit/score/inline/rtems/score/stack.inl | 63 ++ cpukit/score/inline/rtems/score/states.inl | 285 +++++++++ cpukit/score/inline/rtems/score/sysstate.inl | 103 +++ cpukit/score/inline/rtems/score/thread.inl | 252 ++++++++ cpukit/score/inline/rtems/score/threadmp.inl | 53 ++ cpukit/score/inline/rtems/score/tod.inl | 72 +++ cpukit/score/inline/rtems/score/tqdata.inl | 47 ++ cpukit/score/inline/rtems/score/userext.inl | 268 ++++++++ cpukit/score/inline/rtems/score/watchdog.inl | 296 +++++++++ cpukit/score/inline/rtems/score/wkspace.inl | 104 +++ cpukit/score/macros/README | 18 + cpukit/score/macros/rtems/score/README | 18 + cpukit/score/macros/rtems/score/address.inl | 79 +++ cpukit/score/macros/rtems/score/chain.inl | 200 ++++++ cpukit/score/macros/rtems/score/heap.inl | 136 ++++ cpukit/score/macros/rtems/score/isr.inl | 60 ++ cpukit/score/macros/rtems/score/mppkt.inl | 41 ++ cpukit/score/macros/rtems/score/object.inl | 146 +++++ cpukit/score/macros/rtems/score/objectmp.inl | 50 ++ cpukit/score/macros/rtems/score/priority.inl | 144 +++++ cpukit/score/macros/rtems/score/stack.inl | 50 ++ cpukit/score/macros/rtems/score/states.inl | 201 ++++++ cpukit/score/macros/rtems/score/sysstate.inl | 77 +++ cpukit/score/macros/rtems/score/thread.inl | 193 ++++++ cpukit/score/macros/rtems/score/threadmp.inl | 50 ++ cpukit/score/macros/rtems/score/tod.inl | 59 ++ cpukit/score/macros/rtems/score/tqdata.inl | 39 ++ cpukit/score/macros/rtems/score/userext.inl | 184 ++++++ cpukit/score/macros/rtems/score/watchdog.inl | 202 ++++++ cpukit/score/macros/rtems/score/wkspace.inl | 101 +++ cpukit/score/src/chain.c | 202 ++++++ cpukit/score/src/coretod.c | 236 +++++++ cpukit/score/src/heap.c | 478 ++++++++++++++ cpukit/score/src/mpci.c | 237 +++++++ cpukit/score/src/object.c | 228 +++++++ cpukit/score/src/objectmp.c | 250 ++++++++ cpukit/score/src/thread.c | 805 ++++++++++++++++++++++++ cpukit/score/src/threadmp.c | 229 +++++++ cpukit/score/src/threadq.c | 837 +++++++++++++++++++++++++ cpukit/score/src/watchdog.c | 225 +++++++ cpukit/score/src/wkspace.c | 47 ++ 203 files changed, 34929 insertions(+) create mode 100644 cpukit/libcsupport/include/clockdrv.h create mode 100644 cpukit/libcsupport/include/console.h create mode 100644 cpukit/libcsupport/include/iosupp.h create mode 100644 cpukit/libcsupport/include/rtems/libcsupport.h create mode 100644 cpukit/libcsupport/include/spurious.h create mode 100644 cpukit/libcsupport/include/timerdrv.h create mode 100644 cpukit/libcsupport/include/vmeintr.h create mode 100644 cpukit/libcsupport/src/README create mode 100644 cpukit/libcsupport/src/__brk.c create mode 100644 cpukit/libcsupport/src/__gettod.c create mode 100644 cpukit/libcsupport/src/__times.c create mode 100644 cpukit/libcsupport/src/malloc.c create mode 100644 cpukit/libcsupport/src/newlibc.c create mode 100644 cpukit/libcsupport/src/no_libc.c create mode 100644 cpukit/libcsupport/src/unixlibc.c create mode 100644 cpukit/libmisc/README create mode 100644 cpukit/libmisc/monitor/README create mode 100644 cpukit/libmisc/monitor/mon-monitor.c create mode 100644 cpukit/libmisc/monitor/mon-symbols.c create mode 100644 cpukit/libmisc/monitor/monitor.h create mode 100644 cpukit/libmisc/monitor/symbols.h create mode 100644 cpukit/libmisc/stackchk/README create mode 100644 cpukit/libmisc/stackchk/check.c create mode 100644 cpukit/libmisc/stackchk/internal.h create mode 100644 cpukit/libmisc/stackchk/stackchk.h create mode 100644 cpukit/rtems/include/rtems.h create mode 100644 cpukit/rtems/include/rtems/rtems/asr.h create mode 100644 cpukit/rtems/include/rtems/rtems/attr.h create mode 100644 cpukit/rtems/include/rtems/rtems/clock.h create mode 100644 cpukit/rtems/include/rtems/rtems/dpmem.h create mode 100644 cpukit/rtems/include/rtems/rtems/event.h create mode 100644 cpukit/rtems/include/rtems/rtems/eventmp.h create mode 100644 cpukit/rtems/include/rtems/rtems/eventset.h create mode 100644 cpukit/rtems/include/rtems/rtems/intr.h create mode 100644 cpukit/rtems/include/rtems/rtems/message.h create mode 100644 cpukit/rtems/include/rtems/rtems/modes.h create mode 100644 cpukit/rtems/include/rtems/rtems/mp.h create mode 100644 cpukit/rtems/include/rtems/rtems/msgmp.h create mode 100644 cpukit/rtems/include/rtems/rtems/options.h create mode 100644 cpukit/rtems/include/rtems/rtems/part.h create mode 100644 cpukit/rtems/include/rtems/rtems/partmp.h create mode 100644 cpukit/rtems/include/rtems/rtems/ratemon.h create mode 100644 cpukit/rtems/include/rtems/rtems/region.h create mode 100644 cpukit/rtems/include/rtems/rtems/regionmp.h create mode 100644 cpukit/rtems/include/rtems/rtems/sem.h create mode 100644 cpukit/rtems/include/rtems/rtems/semmp.h create mode 100644 cpukit/rtems/include/rtems/rtems/signal.h create mode 100644 cpukit/rtems/include/rtems/rtems/signalmp.h create mode 100644 cpukit/rtems/include/rtems/rtems/status.h create mode 100644 cpukit/rtems/include/rtems/rtems/taskmp.h create mode 100644 cpukit/rtems/include/rtems/rtems/tasks.h create mode 100644 cpukit/rtems/include/rtems/rtems/timer.h create mode 100644 cpukit/rtems/inline/rtems/rtems/asr.inl create mode 100644 cpukit/rtems/inline/rtems/rtems/attr.inl create mode 100644 cpukit/rtems/inline/rtems/rtems/dpmem.inl create mode 100644 cpukit/rtems/inline/rtems/rtems/event.inl create mode 100644 cpukit/rtems/inline/rtems/rtems/eventset.inl create mode 100644 cpukit/rtems/inline/rtems/rtems/message.inl create mode 100644 cpukit/rtems/inline/rtems/rtems/modes.inl create mode 100644 cpukit/rtems/inline/rtems/rtems/options.inl create mode 100644 cpukit/rtems/inline/rtems/rtems/part.inl create mode 100644 cpukit/rtems/inline/rtems/rtems/ratemon.inl create mode 100644 cpukit/rtems/inline/rtems/rtems/region.inl create mode 100644 cpukit/rtems/inline/rtems/rtems/sem.inl create mode 100644 cpukit/rtems/inline/rtems/rtems/status.inl create mode 100644 cpukit/rtems/inline/rtems/rtems/tasks.inl create mode 100644 cpukit/rtems/inline/rtems/rtems/timer.inl create mode 100644 cpukit/rtems/macros/rtems/rtems/asr.inl create mode 100644 cpukit/rtems/macros/rtems/rtems/attr.inl create mode 100644 cpukit/rtems/macros/rtems/rtems/dpmem.inl create mode 100644 cpukit/rtems/macros/rtems/rtems/event.inl create mode 100644 cpukit/rtems/macros/rtems/rtems/eventset.inl create mode 100644 cpukit/rtems/macros/rtems/rtems/message.inl create mode 100644 cpukit/rtems/macros/rtems/rtems/modes.inl create mode 100644 cpukit/rtems/macros/rtems/rtems/options.inl create mode 100644 cpukit/rtems/macros/rtems/rtems/part.inl create mode 100644 cpukit/rtems/macros/rtems/rtems/ratemon.inl create mode 100644 cpukit/rtems/macros/rtems/rtems/region.inl create mode 100644 cpukit/rtems/macros/rtems/rtems/sem.inl create mode 100644 cpukit/rtems/macros/rtems/rtems/status.inl create mode 100644 cpukit/rtems/macros/rtems/rtems/tasks.inl create mode 100644 cpukit/rtems/macros/rtems/rtems/timer.inl create mode 100644 cpukit/rtems/src/dpmem.c create mode 100644 cpukit/rtems/src/event.c create mode 100644 cpukit/rtems/src/eventmp.c create mode 100644 cpukit/rtems/src/intr.c create mode 100644 cpukit/rtems/src/mp.c create mode 100644 cpukit/rtems/src/msg.c create mode 100644 cpukit/rtems/src/msgmp.c create mode 100644 cpukit/rtems/src/part.c create mode 100644 cpukit/rtems/src/partmp.c create mode 100644 cpukit/rtems/src/ratemon.c create mode 100644 cpukit/rtems/src/region.c create mode 100644 cpukit/rtems/src/regionmp.c create mode 100644 cpukit/rtems/src/rtclock.c create mode 100644 cpukit/rtems/src/rtemstimer.c create mode 100644 cpukit/rtems/src/sem.c create mode 100644 cpukit/rtems/src/semmp.c create mode 100644 cpukit/rtems/src/signal.c create mode 100644 cpukit/rtems/src/signalmp.c create mode 100644 cpukit/rtems/src/taskmp.c create mode 100644 cpukit/rtems/src/tasks.c create mode 100644 cpukit/sapi/include/rtems/config.h create mode 100644 cpukit/sapi/include/rtems/extension.h create mode 100644 cpukit/sapi/include/rtems/fatal.h create mode 100644 cpukit/sapi/include/rtems/init.h create mode 100644 cpukit/sapi/include/rtems/io.h create mode 100644 cpukit/sapi/include/rtems/mptables.h create mode 100644 cpukit/sapi/inline/rtems/extension.inl create mode 100644 cpukit/sapi/macros/rtems/extension.inl create mode 100644 cpukit/sapi/src/debug.c create mode 100644 cpukit/sapi/src/exinit.c create mode 100644 cpukit/sapi/src/extension.c create mode 100644 cpukit/sapi/src/fatal.c create mode 100644 cpukit/sapi/src/io.c create mode 100644 cpukit/score/cpu/hppa1.1/cpu.c create mode 100644 cpukit/score/cpu/i386/asm.h create mode 100644 cpukit/score/cpu/i386/cpu.c create mode 100644 cpukit/score/cpu/i386/rtems/asm.h create mode 100644 cpukit/score/cpu/i960/asm.h create mode 100644 cpukit/score/cpu/i960/cpu.c create mode 100644 cpukit/score/cpu/m68k/asm.h create mode 100644 cpukit/score/cpu/m68k/cpu.c create mode 100644 cpukit/score/cpu/m68k/rtems/asm.h create mode 100644 cpukit/score/cpu/no_cpu/asm.h create mode 100644 cpukit/score/cpu/no_cpu/cpu.c create mode 100644 cpukit/score/cpu/no_cpu/cpu_asm.c create mode 100644 cpukit/score/cpu/no_cpu/rtems/asm.h create mode 100644 cpukit/score/cpu/unix/cpu.c create mode 100644 cpukit/score/include/rtems/debug.h create mode 100644 cpukit/score/include/rtems/score/address.h create mode 100644 cpukit/score/include/rtems/score/bitfield.h create mode 100644 cpukit/score/include/rtems/score/chain.h create mode 100644 cpukit/score/include/rtems/score/context.h create mode 100644 cpukit/score/include/rtems/score/copyrt.h create mode 100644 cpukit/score/include/rtems/score/heap.h create mode 100644 cpukit/score/include/rtems/score/isr.h create mode 100644 cpukit/score/include/rtems/score/mpci.h create mode 100644 cpukit/score/include/rtems/score/mppkt.h create mode 100644 cpukit/score/include/rtems/score/object.h create mode 100644 cpukit/score/include/rtems/score/objectmp.h create mode 100644 cpukit/score/include/rtems/score/priority.h create mode 100644 cpukit/score/include/rtems/score/stack.h create mode 100644 cpukit/score/include/rtems/score/states.h create mode 100644 cpukit/score/include/rtems/score/sysstate.h create mode 100644 cpukit/score/include/rtems/score/thread.h create mode 100644 cpukit/score/include/rtems/score/threadmp.h create mode 100644 cpukit/score/include/rtems/score/threadq.h create mode 100644 cpukit/score/include/rtems/score/tod.h create mode 100644 cpukit/score/include/rtems/score/tqdata.h create mode 100644 cpukit/score/include/rtems/score/userext.h create mode 100644 cpukit/score/include/rtems/score/watchdog.h create mode 100644 cpukit/score/include/rtems/score/wkspace.h create mode 100644 cpukit/score/include/rtems/system.h create mode 100644 cpukit/score/inline/rtems/score/address.inl create mode 100644 cpukit/score/inline/rtems/score/chain.inl create mode 100644 cpukit/score/inline/rtems/score/heap.inl create mode 100644 cpukit/score/inline/rtems/score/isr.inl create mode 100644 cpukit/score/inline/rtems/score/mppkt.inl create mode 100644 cpukit/score/inline/rtems/score/object.inl create mode 100644 cpukit/score/inline/rtems/score/objectmp.inl create mode 100644 cpukit/score/inline/rtems/score/priority.inl create mode 100644 cpukit/score/inline/rtems/score/stack.inl create mode 100644 cpukit/score/inline/rtems/score/states.inl create mode 100644 cpukit/score/inline/rtems/score/sysstate.inl create mode 100644 cpukit/score/inline/rtems/score/thread.inl create mode 100644 cpukit/score/inline/rtems/score/threadmp.inl create mode 100644 cpukit/score/inline/rtems/score/tod.inl create mode 100644 cpukit/score/inline/rtems/score/tqdata.inl create mode 100644 cpukit/score/inline/rtems/score/userext.inl create mode 100644 cpukit/score/inline/rtems/score/watchdog.inl create mode 100644 cpukit/score/inline/rtems/score/wkspace.inl create mode 100644 cpukit/score/macros/README create mode 100644 cpukit/score/macros/rtems/score/README create mode 100644 cpukit/score/macros/rtems/score/address.inl create mode 100644 cpukit/score/macros/rtems/score/chain.inl create mode 100644 cpukit/score/macros/rtems/score/heap.inl create mode 100644 cpukit/score/macros/rtems/score/isr.inl create mode 100644 cpukit/score/macros/rtems/score/mppkt.inl create mode 100644 cpukit/score/macros/rtems/score/object.inl create mode 100644 cpukit/score/macros/rtems/score/objectmp.inl create mode 100644 cpukit/score/macros/rtems/score/priority.inl create mode 100644 cpukit/score/macros/rtems/score/stack.inl create mode 100644 cpukit/score/macros/rtems/score/states.inl create mode 100644 cpukit/score/macros/rtems/score/sysstate.inl create mode 100644 cpukit/score/macros/rtems/score/thread.inl create mode 100644 cpukit/score/macros/rtems/score/threadmp.inl create mode 100644 cpukit/score/macros/rtems/score/tod.inl create mode 100644 cpukit/score/macros/rtems/score/tqdata.inl create mode 100644 cpukit/score/macros/rtems/score/userext.inl create mode 100644 cpukit/score/macros/rtems/score/watchdog.inl create mode 100644 cpukit/score/macros/rtems/score/wkspace.inl create mode 100644 cpukit/score/src/chain.c create mode 100644 cpukit/score/src/coretod.c create mode 100644 cpukit/score/src/heap.c create mode 100644 cpukit/score/src/mpci.c create mode 100644 cpukit/score/src/object.c create mode 100644 cpukit/score/src/objectmp.c create mode 100644 cpukit/score/src/thread.c create mode 100644 cpukit/score/src/threadmp.c create mode 100644 cpukit/score/src/threadq.c create mode 100644 cpukit/score/src/watchdog.c create mode 100644 cpukit/score/src/wkspace.c (limited to 'cpukit') diff --git a/cpukit/libcsupport/include/clockdrv.h b/cpukit/libcsupport/include/clockdrv.h new file mode 100644 index 0000000000..aad9bd6d3b --- /dev/null +++ b/cpukit/libcsupport/include/clockdrv.h @@ -0,0 +1,58 @@ +/* clock.h + * + * This file describes the Clock Driver for all boards. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __CLOCK_DRIVER_h +#define __CLOCK_DRIVER_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* variables */ + +extern volatile rtems_unsigned32 Clock_driver_ticks; + +/* functions */ + +rtems_task Exit_task(); +void exit_task_init(); + +void Install_clock( rtems_isr_entry ); +void ReInstall_clock( rtems_isr_entry ); +void Clock_exit(); + +rtems_isr Clock_isr( + rtems_vector_number +); + +/* driver entries */ + +#define CLOCK_DRIVER_TABLE_ENTRY \ + { Clock_initialize, NULL, NULL, NULL, NULL, NULL } + +rtems_device_driver Clock_initialize( + rtems_device_major_number, + rtems_device_minor_number, + void *, + rtems_id, + rtems_unsigned32 * +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/console.h b/cpukit/libcsupport/include/console.h new file mode 100644 index 0000000000..d102c6a1b1 --- /dev/null +++ b/cpukit/libcsupport/include/console.h @@ -0,0 +1,40 @@ +/* console.h + * + * This file describes the Console Device Driver for all boards. + * This driver provides support for the standard C Library. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef _CONSOLE_DRIVER_h +#define _CONSOLE_DRIVER_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define CONSOLE_DRIVER_TABLE_ENTRY \ + { console_initialize, NULL, NULL, NULL, NULL, NULL } + +rtems_device_driver console_initialize( + rtems_device_major_number, + rtems_device_minor_number, + void *, + rtems_id, + rtems_unsigned32 * +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/iosupp.h b/cpukit/libcsupport/include/iosupp.h new file mode 100644 index 0000000000..5f4a83b8ca --- /dev/null +++ b/cpukit/libcsupport/include/iosupp.h @@ -0,0 +1,44 @@ +/* iosupp.h + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __IOSUPP_h +#define __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/libcsupport/include/rtems/libcsupport.h b/cpukit/libcsupport/include/rtems/libcsupport.h new file mode 100644 index 0000000000..2b199707f8 --- /dev/null +++ b/cpukit/libcsupport/include/rtems/libcsupport.h @@ -0,0 +1,47 @@ +/* libcsupport.h + * + * This include file contains the information regarding the + * RTEMS specific support for the standard C library. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __LIBC_SUPPORT_h +#define __LIBC_SUPPORT_h + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void RTEMS_Malloc_Initialize( + void *start, + size_t length, + size_t sbrk_amount +); + +extern void libc_init(int reentrant); + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/spurious.h b/cpukit/libcsupport/include/spurious.h new file mode 100644 index 0000000000..428e826164 --- /dev/null +++ b/cpukit/libcsupport/include/spurious.h @@ -0,0 +1,38 @@ +/* spurious.h + * + * This file describes the Spurious Interrupt Driver for all boards. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993. + * On-Line Applications Research Corporation (OAR). + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __SPURIOUS_h +#define __SPURIOUS_h + +#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, + rtems_unsigned32 * +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/timerdrv.h b/cpukit/libcsupport/include/timerdrv.h new file mode 100644 index 0000000000..d091b62410 --- /dev/null +++ b/cpukit/libcsupport/include/timerdrv.h @@ -0,0 +1,40 @@ +/* timerdrv.h + * + * This file describes the Timer Driver for all boards. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __TIMER_DRIVER_h +#define __TIMER_DRIVER_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* functions */ + +void Timer_initialize( void ); + +rtems_unsigned32 Read_timer( void ); + +rtems_status_code Empty_function( void ); + +void Set_find_average_overhead( + rtems_boolean find_flag +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libcsupport/include/vmeintr.h b/cpukit/libcsupport/include/vmeintr.h new file mode 100644 index 0000000000..6148114ce8 --- /dev/null +++ b/cpukit/libcsupport/include/vmeintr.h @@ -0,0 +1,58 @@ +/* + * vmeintr.h + * + * 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, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __VME_INTERRUPT_h +#define __VME_INTERRUPT_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 rtems_unsigned8 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 */ diff --git a/cpukit/libcsupport/src/README b/cpukit/libcsupport/src/README new file mode 100644 index 0000000000..ee7a90501e --- /dev/null +++ b/cpukit/libcsupport/src/README @@ -0,0 +1,37 @@ +-- +-- $Id$ +-- + +Overview of newlib support (newlib is from CYGNUS) + Each task can have its own libc state including: + open stdio files + strtok + multi precision arithmetic state + etc. + + This is implemented by a reentrancy data structure for each task. + + When a task is "started" (in RTEMS sense) the reentrancy structure + is allocated. Its address is stored in notepad[NOTEPAD_LAST]. + + When task is switched to, the value of global variable _impure_ptr + is changed to the value of the new tasks reentrancy structure. + + When a task is deleted + atexit() processing (for that task) happens + task's stdio buffers are flushed + + When exit(3) is called + calling task's atexit processing done + global libc state atexit processing done + (this will include any atexit routines installed by drivers) + executive is shutdown + causes a context switch back to bsp land + + +NOTE: + libc extension are installed by bsp_libc_init() + iff we are using clock interrupts. + This hack is necessary to allow the tmtests to avoid + timing the extensions. + diff --git a/cpukit/libcsupport/src/__brk.c b/cpukit/libcsupport/src/__brk.c new file mode 100644 index 0000000000..6fb15342fe --- /dev/null +++ b/cpukit/libcsupport/src/__brk.c @@ -0,0 +1,40 @@ +/* + * RTEMS "Broken" __brk/__sbrk Implementation + * + * NOTE: sbrk is BSP provided. + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +#include +#include +#include +#ifdef RTEMS_NEWLIB +#include +#endif +#include + +/* we use RTEMS for memory management. We don't need sbrk */ + +void * __sbrk(int incr) +{ + errno = EINVAL; + return (void *)0; +} + +int __brk( const void *endds ) +{ + errno = EINVAL; + return -1; +} diff --git a/cpukit/libcsupport/src/__gettod.c b/cpukit/libcsupport/src/__gettod.c new file mode 100644 index 0000000000..a1ab9776c8 --- /dev/null +++ b/cpukit/libcsupport/src/__gettod.c @@ -0,0 +1,84 @@ +#if !defined(RTEMS_UNIX) +/* + * RTEMS gettimeofday Implementation + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +#ifdef RTEMS_NEWLIB +#include +#endif +#include +#include +#include +#include + +/* + * NOTE: The solaris gettimeofday does not have a second parameter. + */ + +int gettimeofday( + struct timeval *tp, + struct timezone *tzp +) +{ + rtems_status_code status; + rtems_clock_time_value time; + + if ( !tp || !tzp ) { + errno = EFAULT; + return -1; + } + + /* "POSIX" does not seem to allow for not having a TOD */ + status = rtems_clock_get( RTEMS_CLOCK_GET_TIME_VALUE, &time ); + if ( status != RTEMS_SUCCESSFUL ) { + assert( 0 ); + return -1; + } + + tp->tv_sec = time.seconds; + tp->tv_usec = time.microseconds; + +#if 0 + tzp->minuteswest = timezone / 60; /* from seconds to minutes */ + tzp->dsttime = daylight; +#endif + + /* + * newlib does not have timezone and daylight savings time + * yet. When it does this needs to be fixed. + */ + + tzp->tz_minuteswest = 0; /* at UTC */ + tzp->tz_dsttime = 0; /* no daylight savings */ + return 0; +} + +/* + * "Reentrant" versions of the above routines implemented above. + */ + +#if 0 +int _gettimeofday_r( + struct _reent *ignored_reentrancy_stuff, + struct timeval *tp, + struct timezone *tzp +) +{ + return gettimeofday( tp, tzp ); +} +#endif + +#endif diff --git a/cpukit/libcsupport/src/__times.c b/cpukit/libcsupport/src/__times.c new file mode 100644 index 0000000000..12fd9241fe --- /dev/null +++ b/cpukit/libcsupport/src/__times.c @@ -0,0 +1,65 @@ +/* + * RTEMS _times Implementation + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +#include +#include +#include +#include +#include + +clock_t _times( + struct tms *ptms +) +{ + rtems_status_code status; + rtems_interval ticks_since_boot; + + if ( !ptms ) { + errno = EFAULT; + return -1; + } + + /* "POSIX" does not seem to allow for not having a TOD */ + status = rtems_clock_get( + RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, + &ticks_since_boot + ); + if ( status != RTEMS_SUCCESSFUL ) { + assert( 0 ); + return -1; + } + + /* + * RTEMS has no notion of system versus user time and does + * not (as of 3.2.0) keep track of CPU usage on a per task basis. + */ + + ptms->tms_utime = ticks_since_boot; + ptms->tms_stime = 0; + ptms->tms_cutime = 0; + ptms->tms_cstime = 0; + + return 0; +} + +clock_t times( + struct tms *ptms +) +{ + return _times( ptms ); +} + diff --git a/cpukit/libcsupport/src/malloc.c b/cpukit/libcsupport/src/malloc.c new file mode 100644 index 0000000000..7d0ba04143 --- /dev/null +++ b/cpukit/libcsupport/src/malloc.c @@ -0,0 +1,280 @@ +/* + * RTEMS Malloc Family Implementation + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#ifdef RTEMS_LIBC +#include +#endif +#include "libcsupport.h" +#ifdef RTEMS_NEWLIB +#include +#endif + +#include +#include +#include +#include +#include +#include + +/* + * XXX: Do we really need to duplicate these? It appears that they + * only cause typing problems. + */ + +#if 0 +void *malloc(size_t); +void *calloc(size_t, size_t); +void *realloc(void *, size_t); +void free(void *); +void *sbrk(size_t); +#endif + +rtems_id RTEMS_Malloc_Heap; +size_t RTEMS_Malloc_Sbrk_amount; + +void RTEMS_Malloc_Initialize( + void *start, + size_t length, + size_t sbrk_amount +) +{ + rtems_status_code status; + void *starting_address; + rtems_unsigned32 u32_address; + + /* + * If the starting address is 0 then we are to attempt to + * get length worth of memory using sbrk. Make sure we + * align the address that we get back. + */ + + starting_address = start; + + if (!starting_address) { + u32_address = (unsigned int)sbrk(length); + + if (u32_address == -1) { + rtems_fatal_error_occurred( RTEMS_NO_MEMORY ); + /* DOES NOT RETURN!!! */ + } + + if (u32_address & (CPU_ALIGNMENT-1)) { + u32_address = (u32_address + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + /* XXX: if we do any alignment .. then length should be shortened */ + } + + starting_address = (void *)u32_address; + } + + /* + * Unfortunately we cannot use assert if this fails because if this + * has failed we do not have a heap and if we do not have a heap + * STDIO cannot work because there will be no buffers. + */ + + status = rtems_region_create( + rtems_build_name( 'H', 'E', 'A', 'P' ), + starting_address, + length, + 8, /* XXX : use CPU dependent RTEMS constant */ + RTEMS_DEFAULT_ATTRIBUTES, + &RTEMS_Malloc_Heap + ); + if ( status != RTEMS_SUCCESSFUL ) + rtems_fatal_error_occurred( status ); +} + +void *malloc( + size_t size +) +{ + void *return_this; + void *starting_address; + rtems_unsigned32 the_size; + rtems_unsigned32 sbrk_amount; + rtems_status_code status; + + if ( !size ) + return (void *) 0; + + /* + * Try to give a segment in the current region if there is not + * enough space then try to grow the region using rtems_region_extend(). + * If this fails then return a NULL pointer. + */ + + status = rtems_region_get_segment( + RTEMS_Malloc_Heap, + size, + RTEMS_NO_WAIT, + RTEMS_NO_TIMEOUT, + &return_this + ); + + if ( status != RTEMS_SUCCESSFUL ) { + /* + * Round to the "requested sbrk amount" so hopefully we won't have + * to grow again for a while. This effectively does sbrk() calls + * in "page" amounts. + */ + + sbrk_amount = RTEMS_Malloc_Sbrk_amount; + + if ( sbrk_amount == 0 ) + return (void *) 0; + + the_size = ((size + sbrk_amount) / sbrk_amount * sbrk_amount); + + if (((rtems_unsigned32)starting_address = sbrk(the_size)) == -1) + return (void *) 0; + + /* + fprintf(stderr, "Extended the C heap starting at 0x%x for %d bytes\n", + (unsigned32)starting_address, the_size); + */ + + status = rtems_region_extend( + RTEMS_Malloc_Heap, + starting_address, + the_size + ); + if ( status != RTEMS_SUCCESSFUL ) { + sbrk(-the_size); + return(FALSE); + errno = ENOMEM; + return (void *) 0; + } + status = rtems_region_get_segment( + RTEMS_Malloc_Heap, + size, + RTEMS_NO_WAIT, + RTEMS_NO_TIMEOUT, + &return_this + ); + if ( status != RTEMS_SUCCESSFUL ) { + errno = ENOMEM; + return (void *) 0; + } + } + + return return_this; +} + +void *calloc( + size_t nelem, + size_t elsize +) +{ + register char *cptr; + int length; + + length = nelem * elsize; + cptr = malloc( length ); + if ( cptr ) + memset( cptr, '\0', length ); + + return cptr; +} + +void *realloc( + void *ptr, + size_t size +) +{ + rtems_unsigned32 old_size; + rtems_status_code status; + char *new_area; + + if ( !ptr ) + return malloc( size ); + + if ( !size ) { + free( ptr ); + return (void *) 0; + } + + status = rtems_region_get_segment_size( RTEMS_Malloc_Heap, ptr, &old_size ); + if ( status != RTEMS_SUCCESSFUL ) { + errno = EINVAL; + return (void *) 0; + } + + new_area = malloc( size ); + if ( !new_area ) { + free( ptr ); + return (void *) 0; + } + + memcpy( new_area, ptr, (size < old_size) ? size : old_size ); + free( ptr ); + + return new_area; + +} + +void free( + void *ptr +) +{ + rtems_status_code status; + + if ( !ptr ) + return; + + status = rtems_region_return_segment( RTEMS_Malloc_Heap, ptr ); + if ( status != RTEMS_SUCCESSFUL ) { + errno = EINVAL; + assert( 0 ); + } +} + +/* + * "Reentrant" versions of the above routines implemented above. + */ + +#ifdef RTEMS_NEWLIB +void *malloc_r( + struct _reent *ignored, + size_t size +) +{ + return malloc( size ); +} + +void *calloc_r( + size_t nelem, + size_t elsize +) +{ + return calloc( nelem, elsize ); +} + +void *realloc_r( + void *ptr, + size_t size +) +{ + return realloc_r( ptr, size ); +} + +void free_r( + void *ptr +) +{ + free( ptr ); +} +#endif + diff --git a/cpukit/libcsupport/src/newlibc.c b/cpukit/libcsupport/src/newlibc.c new file mode 100644 index 0000000000..3c5e58b67c --- /dev/null +++ b/cpukit/libcsupport/src/newlibc.c @@ -0,0 +1,292 @@ +/* + * @(#)newlibc.c 1.8 - 95/04/25 + * + */ + +#if defined(RTEMS_NEWLIB) + +/* + * File: $RCSfile$ + * Project: PixelFlow + * Created: 94/12/7 + * Revision: $Revision$ + * Last Mod: $Date$ + * + * COPYRIGHT (c) 1994 by Division Incorporated + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Division Incorporated not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * Division Incorporated makes no representations about the + * suitability of this software for any purpose. + * + * Description: + * Implementation of hooks for the CYGNUS newlib libc + * These hooks set things up so that: + * '_REENT' is switched at task switch time. + * + * + * TODO: + * + * NOTE: + * + * $Id$ + * + */ + +#include +#include +#include /* for free() */ +#include /* for memset() */ + +#include /* for extern of _REENT (aka _impure_ptr) */ + +#include "internal.h" + +#define LIBC_NOTEPAD RTEMS_NOTEPAD_LAST + + +int libc_reentrant; /* do we think we are reentrant? */ +struct _reent libc_global_reent = _REENT_INIT(libc_global_reent);; + +/* + * CYGNUS newlib routine that does atexit() processing and flushes + * stdio streams + * undocumented + */ + +extern void _wrapup_reent(struct _reent *); +extern void _reclaim_reent(struct _reent *); + +void +libc_wrapup(void) +{ + _wrapup_reent(0); + if (_REENT != &libc_global_reent) + { + _wrapup_reent(&libc_global_reent); +#if 0 + /* don't reclaim this one, just in case we do printfs */ + /* on our way out to ROM */ + _reclaim_reent(&libc_global_reent); +#endif + _REENT = &libc_global_reent; + } +} + + +rtems_extension +libc_create_hook(rtems_tcb *current_task, + rtems_tcb *creating_task) +{ + MY_task_set_note(creating_task, LIBC_NOTEPAD, 0); +} + +/* + * Called for all user TASKS (system tasks are SYSI and IDLE) + */ + +rtems_extension +libc_start_hook(rtems_tcb *current_task, + rtems_tcb *starting_task) +{ + struct _reent *ptr; + + /* NOTE: our malloc is reentrant without a reent ptr since + * it is based on region manager + */ + + ptr = (struct _reent *) malloc(sizeof(struct _reent)); + + /* GCC extension: structure constants */ + *ptr = (struct _reent) _REENT_INIT((*ptr)); + + MY_task_set_note(starting_task, LIBC_NOTEPAD, (rtems_unsigned32) ptr); +} + +rtems_extension +libc_switch_hook(rtems_tcb *current_task, + rtems_tcb *heir_task) +{ + rtems_unsigned32 impure_value; + + /* XXX We can't use rtems_task_set_note() here since SYSI task has a + * tid of 0, which is treated specially (optimized, actually) + * by rtems_task_set_note + */ + + impure_value = (rtems_unsigned32) _REENT; + MY_task_set_note(current_task, LIBC_NOTEPAD, impure_value); + + _REENT = (struct _reent *) MY_task_get_note(heir_task, LIBC_NOTEPAD); + +} + +/* + * Function: libc_delete_hook + * Created: 94/12/10 + * + * Description: + * Called when a task is deleted. + * Must restore the new lib reentrancy state for the new current + * task. + * + * Parameters: + * + * + * Returns: + * + * + * Side Effects: + * + * Notes: + * + * + * Deficiencies/ToDo: + * + * + */ +rtems_extension +libc_delete_hook(rtems_tcb *current_task, + rtems_tcb *deleted_task) +{ + struct _reent *ptr; + + /* + * The reentrancy structure was allocated by newlib using malloc() + */ + + if (current_task == deleted_task) + { + ptr = _REENT; + } + else + { + ptr = (struct _reent *) MY_task_get_note(deleted_task, LIBC_NOTEPAD); + } + + if (ptr) + { + _wrapup_reent(ptr); + _reclaim_reent(ptr); + } + + MY_task_set_note(deleted_task, LIBC_NOTEPAD, 0); + + /* + * Require the switch back to another task to install its own + */ + + if (current_task == deleted_task) + { + _REENT = 0; + } +} + +/* + * Function: libc_init + * Created: 94/12/10 + * + * Description: + * Init libc for CYGNUS newlib + * Set up _REENT to use our global libc_global_reent. + * (newlib provides a global of its own, but we prefer our + * own name for it) + * + * If reentrancy is desired (which it should be), then + * we install the task extension hooks to maintain the + * newlib reentrancy global variable _REENT on task + * create, delete, switch, exit, etc. + * + * Parameters: + * reentrant non-zero if reentrant library desired. + * + * Returns: + * + * Side Effects: + * installs libc extensions if reentrant. + * + * Notes: + * + * + * Deficiencies/ToDo: + * + */ + +void +libc_init(int reentrant) +{ + rtems_extensions_table libc_extension; + rtems_id extension_id; + rtems_status_code rc; + + _REENT = &libc_global_reent; + + if (reentrant) + { + memset(&libc_extension, 0, sizeof(libc_extension)); + + libc_extension.rtems_task_create = libc_create_hook; + libc_extension.rtems_task_start = libc_start_hook; + libc_extension.task_switch = libc_switch_hook; + libc_extension.rtems_task_delete = libc_delete_hook; + + rc = rtems_extension_create(rtems_build_name('L', 'I', 'B', 'C'), + &libc_extension, &extension_id); + if (rc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(rc); + + libc_reentrant = reentrant; + } +} + + +void +exit(int status) +{ + libc_wrapup(); + rtems_shutdown_executive(status); +} + + +/* + * Function: _exit + * Created: 94/12/10 + * + * Description: + * Called from exit() after it does atexit() processing and stdio fflush's + * + * called from bottom of exit() to really delete the task. + * If we are using reentrant libc, then let the delete extension + * do all the work, otherwise if a shutdown is in progress, + * then just do it. + * + * Parameters: + * exit status + * + * Returns: + * does not return + * + * Side Effects: + * + * Notes: + * + * + * Deficiencies/ToDo: + * + * + */ + +#ifndef RTEMS_UNIX +void _exit(int status) +{ + rtems_shutdown_executive(status); +} +#endif + +#endif diff --git a/cpukit/libcsupport/src/no_libc.c b/cpukit/libcsupport/src/no_libc.c new file mode 100644 index 0000000000..43a91eb30e --- /dev/null +++ b/cpukit/libcsupport/src/no_libc.c @@ -0,0 +1,45 @@ +#if !defined(RTEMS_LIBC) && !defined(RTEMS_NEWLIB) && !defined(RTEMS_UNIX) + +/* no_libc.h + * + * This file contains stubs for the reentrancy hooks when + * an unknown C library is used. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + + +#include + +#include "libcsupport.h" +#include "internal.h" + +#include /* for free() */ + +void +libc_init(int reentrant) +{ +} + +void libc_suspend_main(void) +{ +} + + +void libc_global_exit(rtems_unsigned32 code) +{ +} + +void _exit(int status) +{ +} + +#endif diff --git a/cpukit/libcsupport/src/unixlibc.c b/cpukit/libcsupport/src/unixlibc.c new file mode 100644 index 0000000000..74b4eea360 --- /dev/null +++ b/cpukit/libcsupport/src/unixlibc.c @@ -0,0 +1,7 @@ +#if defined(RTEMS_UNIXLIB) + +void libc_init(int reentrant) +{ +} + +#endif diff --git a/cpukit/libmisc/README b/cpukit/libmisc/README new file mode 100644 index 0000000000..6825898121 --- /dev/null +++ b/cpukit/libmisc/README @@ -0,0 +1,16 @@ +# +# $Id$ +# + +This directory contains for the "miscellaneous" library. Currently +the only item in this library is a user extension set which checks +for a task "blowing" it's stack. + +The following ideas have been mentioned for items which could go +in this library, but this list is not all inclusive: + + + Workspace Consistency Checker + + Task Execution Time Monitor + +The intent of this library is to provide a home for useful utility routines +which are dependent upon RTEMS. diff --git a/cpukit/libmisc/monitor/README b/cpukit/libmisc/monitor/README new file mode 100644 index 0000000000..cae39d593c --- /dev/null +++ b/cpukit/libmisc/monitor/README @@ -0,0 +1,7 @@ +# +# $Id$ +# + +This is a snapshot of a work in process. It is the beginnings of a +debug monitor task and trap handler which is tasking aware. + diff --git a/cpukit/libmisc/monitor/mon-monitor.c b/cpukit/libmisc/monitor/mon-monitor.c new file mode 100644 index 0000000000..aa466143f9 --- /dev/null +++ b/cpukit/libmisc/monitor/mon-monitor.c @@ -0,0 +1,307 @@ +/* + * @(#)monitor.c 1.6 - 95/04/24 + * + */ + +/* + * mon-task.c + * + * Description: + * RTEMS monitor task + * + * + * + * TODO: + * add pause command (monitor sleeps for 'n' ticks, then wakes up) + * + */ + +#include +/* #include */ + +#include "symbols.h" +#include "monitor.h" + +#include +#include +#include +#include + +#define STREQ(a,b) (strcmp(a,b) == 0) + +/* set by trap handler */ +extern rtems_tcb *debugger_interrupted_task; +extern rtems_context *debugger_interrupted_task_context; +extern rtems_unsigned32 debugger_trap; + +/* our task id needs to be public so any debugger can resume us */ +rtems_unsigned32 rtems_monitor_task_id; + + +rtems_symbol_table_t *rtems_monitor_symbols; + + +#ifndef MONITOR_PROMPT +#define MONITOR_PROMPT "rtems> " +#endif + +#define MONITOR_WAKEUP_EVENT RTEMS_EVENT_0 + +/* + * Function: rtems_monitor_init + * + * Description: + * Create the RTEMS monitor task + * + * Parameters: + * 'monitor_suspend' arg is passed as initial arg to monitor task + * If TRUE, monitor will suspend itself as it starts up. Otherwise + * it will begin its command loop. + * + * Returns: + * + * + * Side Effects: + * + * + * Notes: + * + * + * Deficiencies/ToDo: + * + * + */ + +/* + * make_argv(cp): token-count + * Break up the command line in 'cp' into global argv[] and argc (return + * value). + */ + +int +rtems_monitor_make_argv( + char *cp, + int *argc_p, + char **argv) +{ + int argc = 0; + + while ((cp = strtok(cp, " \t\n\r"))) + { + argv[argc++] = cp; + cp = (char *) NULL; + } + argv[argc] = (char *) NULL; /* end of argv */ + + return *argc_p = argc; +} + +void +rtems_monitor_init(rtems_boolean monitor_suspend) +{ + rtems_status_code status; + + status = rtems_task_create(rtems_build_name('R', 'M', 'O', 'N'), + 1, 0/*stack*/, RTEMS_NO_PREEMPT | RTEMS_INTERRUPT_LEVEL(0), RTEMS_DEFAULT_ATTRIBUTES, &rtems_monitor_task_id); + if (status != RTEMS_SUCCESSFUL) + { + printf("could not create monitor task\n"); + goto done; + } + + rtems_monitor_symbols_loadup(); + + status = rtems_task_start(rtems_monitor_task_id, rtems_monitor_task, monitor_suspend); + if (status != RTEMS_SUCCESSFUL) + { + printf("could not start monitor!\n"); + goto done; + } + +done: +} + +rtems_status_code +rtems_monitor_suspend(rtems_interval timeout) +{ + rtems_event_set event_set; + rtems_status_code status; + + status = rtems_event_receive(MONITOR_WAKEUP_EVENT, RTEMS_DEFAULT_OPTIONS, timeout, &event_set); + return status; +} + +void +rtems_monitor_wakeup(void) +{ + rtems_status_code status; + + status = rtems_event_send(rtems_monitor_task_id, MONITOR_WAKEUP_EVENT); +} + + +/* + * Read and break up a monitor command + * + * We have to loop on the gets call, since it will return NULL under UNIX + * RTEMS when we get a signal (eg: SIGALRM). + */ + +int +rtems_monitor_read_command(char *command, + int *argc, + char **argv) +{ + printf("%s", MONITOR_PROMPT); fflush(stdout); + while (gets(command) == (char *) 0) + ; + return rtems_monitor_make_argv(command, argc, argv); +} + +void +rtems_monitor_task(rtems_task_argument monitor_suspend) +{ + rtems_tcb *debugee = 0; + char command[513]; + rtems_context *rp; + rtems_context_fp *fp; + char *cp; + int argc; + char *argv[64]; + + if ((rtems_boolean) monitor_suspend) + (void) rtems_monitor_suspend(RTEMS_NO_TIMEOUT); + + for (;;) + { + extern rtems_tcb * _Thread_Executing; + debugee = _Thread_Executing; + rp = &debugee->Registers; + fp = (rtems_context_fp *) debugee->fp_context; /* possibly 0 */ + + if (0 == rtems_monitor_read_command(command, &argc, argv)) + continue; + + if (STREQ(argv[0], "quit")) + rtems_monitor_suspend(RTEMS_NO_TIMEOUT); + else if (STREQ(argv[0], "pause")) + rtems_monitor_suspend(1); + +#ifdef CPU_INVOKE_DEBUGGER + else if (STREQ(argv[0], "debug")) + { + CPU_INVOKE_DEBUGGER; + } +#endif + else if (STREQ(argv[0], "symbol")) + { + char *symbol; + char *value; + + if (argc != 3) + { + printf("usage: symbol symname symvalue\n"); + continue; + } + + symbol = argv[1]; + value = argv[2]; + if (symbol && value) + { + rtems_symbol_t *sp; + sp = rtems_symbol_create(rtems_monitor_symbols, + symbol, + (rtems_unsigned32) strtoul(value, 0, 16)); + if (sp) + printf("symbol defined is at %p\n", sp); + else + printf("could not define symbol\n"); + } + else + printf("parsing error\n"); + } + else + { + printf("Unrecognized command: '%s'\n", argv[0]); + } + } +} + +/* + * Function: rtems_monitor_symbols_loadup + * + * Description: + * Create and load the monitor's symbol table. + * We are reading the output format of 'gnm' which looks like this: + * + * 400a7068 ? _Rate_monotonic_Information + * 400a708c ? _Thread_Dispatch_disable_level + * 400a7090 ? _Configuration_Table + * + * + * We ignore the type field. + * + * Parameters: + * + * + * Returns: + * + * + * Side Effects: + * Creates and fills in 'rtems_monitor_symbols' table + * + * Notes: + * + * + * Deficiencies/ToDo: + * Someday this should know BFD + * Maybe we could get objcopy to just copy the symbol areas + * and copy that down. + * + */ + +void +rtems_monitor_symbols_loadup(void) +{ + FILE *fp; + char buffer[128]; + + rtems_monitor_symbols = rtems_symbol_table_create(10); + if (rtems_monitor_symbols == 0) + return; + + fp = fdopen(8, "r"); + if (fp == 0) + return; + + while (fgets(buffer, sizeof(buffer) - 1, fp)) + { + char *symbol; + char *value; + char *ignored_type; + + value = strtok(buffer, " \t\n"); + ignored_type = strtok(0, " \t\n"); + symbol = strtok(0, " \t\n"); + + if (symbol && ignored_type && value) + { + rtems_symbol_t *sp; + sp = rtems_symbol_create(rtems_monitor_symbols, + symbol, + (rtems_unsigned32) strtoul(value, 0, 16)); + if (sp == 0) + { + printf("could not define symbol\n"); + goto done; + } + } + else + { + printf("parsing error\n"); + goto done; + } + } + +done: +} diff --git a/cpukit/libmisc/monitor/mon-symbols.c b/cpukit/libmisc/monitor/mon-symbols.c new file mode 100644 index 0000000000..58d35befa1 --- /dev/null +++ b/cpukit/libmisc/monitor/mon-symbols.c @@ -0,0 +1,327 @@ +/* + * @(#)symbols.c 1.3 - 95/04/24 + * + */ + +/* #define qsort _quicksort */ + +/* + * File: symbols.c + * + * Description: + * Symbol table manager for the RTEMS monitor. + * These routines may be used by other system resources also. + * + * + * TODO: + */ + +#include +#include +#include +#include + +#include "symbols.h" + +extern rtems_symbol_table_t *rtems_monitor_symbols; + +#ifdef RTEMS_DEBUG +#define CHK_ADR_PTR(p) \ +do { \ + if (((p) < rtems_monitor_symbols->addresses) || \ + ((p) >= (rtems_monitor_symbols->addresses + rtems_monitor_symbols->next))) \ + { \ + printf("bad address pointer %p\n", (p)); \ + rtems_fatal_error_occurred(RTEMS_INVALID_ADDRESS); \ + } \ +} while (0) + +#define CHK_NAME_PTR(p) \ +do { \ + if (((p) < rtems_monitor_symbols->symbols) || \ + ((p) >= (rtems_monitor_symbols->symbols + rtems_monitor_symbols->next))) \ + { \ + printf("bad symbol pointer %p\n", (p)); \ + rtems_fatal_error_occurred(RTEMS_INVALID_ADDRESS); \ + } \ +} while (0) +#else +#define CHK_ADR_PTR(p) +#define CHK_NAME_PTR(p) +#endif + +rtems_symbol_table_t * +rtems_symbol_table_create() +{ + rtems_symbol_table_t *table; + + table = (rtems_symbol_table_t *) malloc(sizeof(rtems_symbol_table_t)); + memset((void *) table, 0, sizeof(*table)); + + table->growth_factor = 30; /* 30 percent */ + + return table; +} + +void +rtems_symbol_table_destroy(rtems_symbol_table_t *table) +{ + rtems_symbol_string_block_t *p, *pnext; + + if (table) + { + if (table->addresses) + (void) free(table->addresses); + table->addresses = 0; + + if (table->symbols) + (void) free(table->symbols); + table->symbols = 0; + + p = table->string_buffer_head; + while (p) + { + pnext = p->next; + free(p); + p = pnext; + } + table->string_buffer_head = 0; + table->string_buffer_current = 0; + + free(table); + } +} + +rtems_symbol_t * +rtems_symbol_create( + rtems_symbol_table_t *table, + char *name, + rtems_unsigned32 value + ) +{ + int symbol_length; + size_t newsize; + rtems_symbol_t *sp; + + symbol_length = strlen(name) + 1; /* include '\000' in length */ + + /* need to grow the table? */ + if (table->next >= table->size) + { + if (table->size == 0) + newsize = 100; + else + newsize = table->size + (table->size / (100 / table->growth_factor)); + + table->addresses = (rtems_symbol_t *) realloc((void *) table->addresses, newsize * sizeof(rtems_symbol_t)); + if (table->addresses == 0) /* blew it; lost orig */ + goto failed; + + table->symbols = (rtems_symbol_t *) realloc((void *) table->symbols, newsize * sizeof(rtems_symbol_t)); + if (table->symbols == 0) /* blew it; lost orig */ + goto failed; + + table->size = newsize; + } + + sp = &table->addresses[table->next]; + sp->value = value; + + /* Have to add it to string pool */ + /* need to grow pool? */ + + if ((table->string_buffer_head == 0) || + (table->strings_next + symbol_length) >= SYMBOL_STRING_BLOCK_SIZE) + { + rtems_symbol_string_block_t *p; + + p = (rtems_symbol_string_block_t *) malloc(sizeof(rtems_symbol_string_block_t)); + if (p == 0) + goto failed; + p->next = 0; + if (table->string_buffer_head == 0) + table->string_buffer_head = p; + else + table->string_buffer_current->next = p; + table->string_buffer_current = p; + + table->strings_next = 0; + } + + sp->name = table->string_buffer_current->buffer + table->strings_next; + (void) strcpy(sp->name, name); + + table->strings_next += symbol_length; + + table->symbols[table->next] = *sp; + + table->sorted = 0; + table->next++; + + return sp; + +/* XXX Not sure what to do here. We've possibly destroyed the initial + symbol table due to realloc failure */ +failed: + return 0; +} + +/* + * Qsort entry point for compare by address + */ + +int +rtems_symbol_compare(const void *e1, + const void *e2) +{ + rtems_symbol_t *s1, *s2; + s1 = (rtems_symbol_t *) e1; + s2 = (rtems_symbol_t *) e2; + + CHK_ADR_PTR(s1); + CHK_ADR_PTR(s2); + + if (s1->value < s2->value) + return -1; + if (s1->value > s2->value) + return 1; + return 0; +} + +/* + * Qsort entry point for compare by string name (case independent) + */ + +int +rtems_symbol_string_compare(const void *e1, + const void *e2) +{ + rtems_symbol_t *s1, *s2; + s1 = (rtems_symbol_t *) e1; + s2 = (rtems_symbol_t *) e2; + + CHK_NAME_PTR(s1); + CHK_NAME_PTR(s2); + + return strcasecmp(s1->name, s2->name); +} + + +/* + * Sort the symbol table using qsort + */ + +void +rtems_symbol_sort(rtems_symbol_table_t *table) +{ +#ifdef simhppa + printf("Sorting symbols ... "); /* so slow we need a msg */ + fflush(stdout); +#endif + + qsort((void *) table->addresses, (size_t) table->next, + sizeof(rtems_symbol_t), rtems_symbol_compare); + + qsort((void *) table->symbols, (size_t) table->next, + sizeof(rtems_symbol_t), rtems_symbol_string_compare); + +#ifdef simhppa + /* so slow we need a msg */ + printf("done\n"); +#endif + + table->sorted = 1; +} + +/* + * Search the symbol table by address + * This code based on CYGNUS newlib bsearch, but changed + * to allow for finding closest symbol <= key + */ + +rtems_symbol_t * +rtems_symbol_value_lookup( + rtems_symbol_table_t *table, + rtems_unsigned32 value + ) +{ + rtems_symbol_t *sp; + rtems_symbol_t *base; + rtems_symbol_t *best = 0; + rtems_unsigned32 distance; + rtems_unsigned32 best_distance = ~0; + rtems_unsigned32 elements; + + if ((table == 0) || (table->size == 0)) + return 0; + + if (table->sorted == 0) + rtems_symbol_sort(table); + + base = table->addresses; + elements = table->next; + + while (elements) + { + sp = base + (elements / 2); + if (value < sp->value) + elements /= 2; + else if (value > sp->value) + { + distance = value - sp->value; + if (distance < best_distance) + { + best_distance = distance; + best = sp; + } + base = sp + 1; + elements = (elements / 2) - (elements % 2 ? 0 : 1); + } + else + return sp; + } + + if (value == base->value) + return base; + + return best; +} + +/* + * Search the symbol table by string name (case independent) + */ + +rtems_symbol_t * +rtems_symbol_name_lookup( + rtems_symbol_table_t *table, + char *name + ) +{ + rtems_symbol_t *sp = 0; + rtems_symbol_t key; + + if ((table == 0) || (name == 0)) + goto done; + + if (table->sorted == 0) + { + rtems_symbol_sort(table); + } + + /* + * dummy up one for bsearch() + */ + + key.name = name; + key.value = 0; + + sp = (rtems_symbol_t *) bsearch((const void *) &key, + (const void *) table->symbols, + (size_t) table->next, + sizeof(rtems_symbol_t), + rtems_symbol_string_compare); + +done: + return sp; +} + diff --git a/cpukit/libmisc/monitor/monitor.h b/cpukit/libmisc/monitor/monitor.h new file mode 100644 index 0000000000..195aa73695 --- /dev/null +++ b/cpukit/libmisc/monitor/monitor.h @@ -0,0 +1,38 @@ +/* + * @(#)monitor.h 1.2 - 95/04/24 + * + */ + +/* + * File: monitor.h + * + * Description: + * The RTEMS monitor task include file. + * + * + * + * TODO: + * + */ + +#ifndef __MONITOR_H +#define __MONITOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +void rtems_monitor_init(rtems_boolean monitor_suspend); +void rtems_monitor_wakeup(void); +void rtems_monitor_task(rtems_task_argument monitor_suspend); +void rtems_monitor_symbols_loadup(void); + +extern rtems_unsigned32 rtems_monitor_task_id; + +extern rtems_symbol_table_t *rtems_monitor_symbols; + +#ifdef __cplusplus +} +#endif + +#endif /* ! __MONITOR_H */ diff --git a/cpukit/libmisc/monitor/symbols.h b/cpukit/libmisc/monitor/symbols.h new file mode 100644 index 0000000000..680ac6d2cf --- /dev/null +++ b/cpukit/libmisc/monitor/symbols.h @@ -0,0 +1,80 @@ +/* + * File: symbols.h + * + * Description: + * Entry points for symbol table routines. + * + * + * + * TODO: + * + */ + +#ifndef _INCLUDE_SYMBOLS_H +#define _INCLUDE_SYMBOLS_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + rtems_unsigned32 value; + char *name; +} rtems_symbol_t; + +#define SYMBOL_STRING_BLOCK_SIZE 4080 +typedef struct rtems_symbol_string_block_s { + struct rtems_symbol_string_block_s *next; + char buffer[SYMBOL_STRING_BLOCK_SIZE]; +} rtems_symbol_string_block_t; + +typedef struct { + + rtems_unsigned32 sorted; /* are symbols sorted right now? */ + + rtems_unsigned32 growth_factor; /* % to grow by when needed */ + + rtems_unsigned32 next; /* next symbol slot to use when adding */ + rtems_unsigned32 size; /* max # of symbols */ + + /* + * Symbol list -- sorted by address (when we do a lookup) + */ + + rtems_symbol_t *addresses; /* symbol array by address */ + + /* + * String list -- sorted by name (when we do a lookup) + * This is a duplicate of the info in table->addresses, but it's + * pretty small, so I don't worry about it. + */ + + rtems_symbol_t *symbols; /* symbol array */ + + /* + * String pool, unsorted, a list of blocks of string data + */ + + rtems_symbol_string_block_t *string_buffer_head; + rtems_symbol_string_block_t *string_buffer_current; + rtems_unsigned32 strings_next; /* next byte to use in this block */ + +} rtems_symbol_table_t; + +void rtems_symbol_table_destroy(rtems_symbol_table_t *table); +rtems_symbol_table_t *rtems_symbol_table_create(); +rtems_symbol_t *rtems_symbol_create(rtems_symbol_table_t *, + char *, rtems_unsigned32); +rtems_symbol_t *rtems_symbol_value_lookup(rtems_symbol_table_t *, + rtems_unsigned32); +rtems_symbol_t *rtems_symbol_name_lookup(rtems_symbol_table_t *, + char *); + +#define rtems_symbol_name(sp) ((sp)->name) +#define rtems_symbol_value(sp) ((sp)->value) + +#ifdef __cplusplus +} +#endif + +#endif /* ! _INCLUDE_SYMBOLS_H */ diff --git a/cpukit/libmisc/stackchk/README b/cpukit/libmisc/stackchk/README new file mode 100644 index 0000000000..20e76f07bc --- /dev/null +++ b/cpukit/libmisc/stackchk/README @@ -0,0 +1,41 @@ +# +# $Id$ +# + +This directory contains a stack bounds checker. It provides two +primary features: + + + check for stack overflow at each context switch + + provides an educated guess at each task's stack usage + +The stack overflow check at context switch works by looking for +a 16 byte pattern at the logical end of the stack to be corrupted. +The "guesser" assumes that the entire stack was prefilled with a known +pattern and assumes that the pattern is still in place if the memory +has not been used as a stack. + +Both of these can be fooled by pushing large holes onto the stack +and not writing to them... or (much more unlikely) writing the +magic patterns into memory. + +This code has not been extensively tested. It is provided as a tool +for RTEMS users to catch the most common mistake in multitasking +systems ... too little stack space. Suggestions and comments are appreciated. + +NOTES: + +1. Stack usage information is questionable on CPUs which push + large holes on stack. + +2. The stack checker has a tendency to generate a fault when + trying to print the helpful diagnostic message. If it comes + out, congratulations. If not, then the variable Stack_check_Blown_task + contains a pointer to the TCB of the offending task. This + is usually enough to go on. + +FUTURE: + +1. Determine how/if gcc will generate stack probe calls and support that. + +2. Get accurate stack usage numbers on i960.. it pushes very large + holes on the stack. diff --git a/cpukit/libmisc/stackchk/check.c b/cpukit/libmisc/stackchk/check.c new file mode 100644 index 0000000000..8b923f5c02 --- /dev/null +++ b/cpukit/libmisc/stackchk/check.c @@ -0,0 +1,439 @@ +/* + * Stack Overflow Check User Extension Set + * + * NOTE: This extension set automatically determines at + * initialization time whether the stack for this + * CPU grows up or down and installs the correct + * extension routines for that direction. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + * + */ + +#include +#include +#include +#include +#include +#include +#ifdef XXX_RTEMS_H_FIXED +#include +#else +#include +extern rtems_configuration_table BSP_Configuration; +#endif + +#include +#include +#include +#include + +#include "stackchk.h" +#include "internal.h" + +/* + * This variable contains the name of the task which "blew" the stack. + * It is NULL if the system is all right. + */ + +Thread_Control *Stack_check_Blown_task; + +/* + * The extension table for the stack checker. + */ + +rtems_extensions_table Stack_check_Extension_table = { + Stack_check_Create_extension, /* rtems_task_create */ + 0, /* rtems_task_start */ + 0, /* rtems_task_restart */ + 0, /* rtems_task_delete */ + Stack_check_Switch_extension, /* task_switch */ + Stack_check_Begin_extension, /* task_begin */ + 0, /* task_exitted */ + Stack_check_Fatal_extension, /* fatal */ +}; + +/* + * The "magic pattern" used to mark the end of the stack. + */ + +Stack_check_Control Stack_check_Pattern; + +/* + * Where the pattern goes in the stack area is dependent upon + * whether the stack grow to the high or low area of the memory. + * + */ + +#if ( CPU_STACK_GROWS_UP == TRUE ) + +#define Stack_check_Get_pattern_area( _the_stack ) \ + ((Stack_check_Control *) \ + ((_the_stack)->area + (_the_stack)->size - sizeof( Stack_check_Control ) )) + +#define Stack_check_Calculate_used( _low, _size, _high_water ) \ + ((_high_water) - (_low)) + +#define Stack_check_usable_stack_start(_the_stack) \ + ((_the_stack)->area) + +#else + +#define Stack_check_Get_pattern_area( _the_stack ) \ + ((Stack_check_Control *) ((_the_stack)->area + HEAP_OVERHEAD)) + +#define Stack_check_Calculate_used( _low, _size, _high_water) \ + ( ((_low) + (_size)) - (_high_water) ) + +#define Stack_check_usable_stack_start(_the_stack) \ + ((_the_stack)->area + sizeof(Stack_check_Control)) + +#endif + +#define Stack_check_usable_stack_size(_the_stack) \ + ((_the_stack)->size - sizeof(Stack_check_Control)) + + +/* + * Do we have an interrupt stack? + * XXX it would sure be nice if the interrupt stack were also + * stored in a "stack" structure! + */ + + +Stack_Control stack_check_interrupt_stack; + +/* + * Fill an entire stack area with BYTE_PATTERN. + * This will be used by a Fatal extension to check for + * amount of actual stack used + */ + +void +stack_check_dope_stack(Stack_Control *stack) +{ + memset(stack->area, BYTE_PATTERN, stack->size); +} + + +/*PAGE + * + * Stack_check_Initialize + */ + +unsigned32 stack_check_initialized = 0; + +void Stack_check_Initialize( void ) +{ + rtems_status_code status; + Objects_Id id_ignored; + unsigned32 *p; + + if (stack_check_initialized) + return; + + /* + * Dope the pattern and fill areas + */ + + for ( p = Stack_check_Pattern.pattern; + p < &Stack_check_Pattern.pattern[PATTERN_SIZE_WORDS]; + p += 4 + ) + { + p[0] = 0xFEEDF00D; /* FEED FOOD to BAD DOG */ + p[1] = 0x0BAD0D06; + p[2] = 0xDEADF00D; /* DEAD FOOD GOOD DOG */ + p[3] = 0x600D0D06; + }; + + status = rtems_extension_create( + rtems_build_name( 'S', 'T', 'C', 'K' ), + &Stack_check_Extension_table, + &id_ignored + ); + assert ( status == RTEMS_SUCCESSFUL ); + + Stack_check_Blown_task = 0; + + /* + * If installed by a task, that task will not get setup properly + * since it missed out on the create hook. This will cause a + * failure on first switch out of that task. + * So pretend here that we actually ran create and begin extensions. + */ + + if (_Thread_Executing) + { + Stack_check_Create_extension(_Thread_Executing, _Thread_Executing); + } + + /* + * If appropriate, setup the interrupt stack for high water testing + * also. + */ + if (_CPU_Interrupt_stack_low && _CPU_Interrupt_stack_high) + { + stack_check_interrupt_stack.area = _CPU_Interrupt_stack_low; + stack_check_interrupt_stack.size = _CPU_Interrupt_stack_high - + _CPU_Interrupt_stack_low; + + stack_check_dope_stack(&stack_check_interrupt_stack); + } + + stack_check_initialized = 1; +} + +/*PAGE + * + * Stack_check_Create_extension + */ + +void Stack_check_Create_extension( + Thread_Control *running, + Thread_Control *the_thread +) +{ + if (the_thread && (the_thread != _Thread_Executing)) + stack_check_dope_stack(&the_thread->Start.Initial_stack); +} + +/*PAGE + * + * Stack_check_Begin_extension + */ + +void Stack_check_Begin_extension( + Thread_Control *the_thread +) +{ + Stack_check_Control *the_pattern; + + if ( the_thread->Object.id == 0 ) /* skip system tasks */ + return; + + the_pattern = Stack_check_Get_pattern_area(&the_thread->Start.Initial_stack); + + *the_pattern = Stack_check_Pattern; +} + +/*PAGE + * + * Stack_check_report_blown_task + * Report a blown stack. Needs to be a separate routine + * so that interrupt handlers can use this too. + * + * Caller must have set the Stack_check_Blown_task. + * + * NOTE: The system is in a questionable state... we may not get + * the following message out. + */ + +void Stack_check_report_blown_task(void) +{ + Stack_Control *stack; + Thread_Control *running; + + running = Stack_check_Blown_task; + stack = &running->Start.Initial_stack; + + fprintf( + stderr, + "BLOWN STACK!!! Offending task(%p): id=0x%08x; name=0x%08x", + running, + running->Object.id, + running->name); + fflush(stderr); + + if (BSP_Configuration.User_multiprocessing_table) + fprintf( + stderr, + "; node=%d\n", + BSP_Configuration.User_multiprocessing_table->node + ); + else + fprintf(stderr, "\n"); + fflush(stderr); + + fprintf( + stderr, + " stack covers range 0x%08x - 0x%08x (%d bytes)\n", + (unsigned32) stack->area, + (unsigned32) stack->area + stack->size - 1, + (unsigned32) stack->size); + fflush(stderr); + + fprintf( + stderr, + " Damaged pattern begins at 0x%08x and is %d bytes long\n", + (unsigned32) Stack_check_Get_pattern_area(stack), PATTERN_SIZE_BYTES); + fflush(stderr); + + rtems_fatal_error_occurred( (unsigned32) "STACK BLOWN" ); +} + +/*PAGE + * + * Stack_check_Switch_extension + */ + +void Stack_check_Switch_extension( + Thread_Control *running, + Thread_Control *heir +) +{ + if ( running->Object.id == 0 ) /* skip system tasks */ + return; + + if (0 != memcmp( (void *) Stack_check_Get_pattern_area( &running->Start.Initial_stack)->pattern, + (void *) Stack_check_Pattern.pattern, + PATTERN_SIZE_BYTES)) + { + Stack_check_Blown_task = running; + Stack_check_report_blown_task(); + } +} + +void *Stack_check_find_high_water_mark( + const void *s, + size_t n +) +{ + const unsigned32 *base, *ebase; + unsigned32 length; + + base = s; + length = n/4; + +#if ( CPU_STACK_GROWS_UP == TRUE ) + /* + * start at higher memory and find first word that does not + * match pattern + */ + + base += length - 1; + for (ebase = s; base > ebase; base--) + if (*base != U32_PATTERN) + return (void *) base; +#else + /* + * start at lower memory and find first word that does not + * match pattern + */ + + for (ebase = base + length; base < ebase; base++) + if (*base != U32_PATTERN) + return (void *) base; +#endif + + return (void *)0; +} + +/*PAGE + * + * Stack_check_Dump_threads_usage + * Try to print out how much stack was actually used by the task. + * + */ + +void Stack_check_Dump_threads_usage( + Thread_Control *the_thread +) +{ + unsigned32 size, used; + void *low; + void *high_water_mark; + Stack_Control *stack; + + if ( !the_thread ) + return; + + /* + * XXX HACK to get to interrupt stack + */ + + if (the_thread == (Thread_Control *) -1) + { + if (stack_check_interrupt_stack.area) + { + stack = &stack_check_interrupt_stack; + the_thread = 0; + } + else + return; + } + else + stack = &the_thread->Start.Initial_stack; + + low = Stack_check_usable_stack_start(stack); + size = Stack_check_usable_stack_size(stack); + + high_water_mark = Stack_check_find_high_water_mark(low, size); + + if ( high_water_mark ) + used = Stack_check_Calculate_used( low, size, high_water_mark ); + else + used = 0; + + printf( "0x%08x 0x%08x 0x%08x 0x%08x %8d %8d\n", + the_thread ? the_thread->Object.id : ~0, + the_thread ? the_thread->name : + rtems_build_name('I', 'N', 'T', 'R'), + (unsigned32) stack->area, + (unsigned32) stack->area + (unsigned32) stack->size - 1, + size, + used + ); +} + +/*PAGE + * + * Stack_check_Fatal_extension + */ + +void Stack_check_Fatal_extension( unsigned32 status ) +{ + if (status == 0) + Stack_check_Dump_usage(); +} + + +/*PAGE + * + * Stack_check_Dump_usage + */ + +void Stack_check_Dump_usage( void ) +{ + unsigned32 i; + Thread_Control *the_thread; + unsigned32 hit_running = 0; + + if (stack_check_initialized == 0) + return; + + printf( + " ID NAME LOW HIGH AVAILABLE USED\n" + ); + for ( i=1 ; i<_Thread_Information.maximum ; i++ ) { + the_thread = (Thread_Control *)_Thread_Information.local_table[ i ]; + Stack_check_Dump_threads_usage( the_thread ); + if ( the_thread == _Thread_Executing ) + hit_running = 1; + } + + if ( !hit_running ) + Stack_check_Dump_threads_usage( _Thread_Executing ); + + /* dump interrupt stack info if any */ + Stack_check_Dump_threads_usage((Thread_Control *) -1); +} + diff --git a/cpukit/libmisc/stackchk/internal.h b/cpukit/libmisc/stackchk/internal.h new file mode 100644 index 0000000000..19c9f5e267 --- /dev/null +++ b/cpukit/libmisc/stackchk/internal.h @@ -0,0 +1,94 @@ +/* internal.h + * + * This include file contains internal information + * for the RTEMS stack checker. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INTERNAL_STACK_CHECK_h +#define __INTERNAL_STACK_CHECK_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This structure is used to fill in and compare the "end of stack" + * marker pattern. + * pattern area must be a multiple of 4 words. + */ + +#ifdef CPU_STACK_CHECK_SIZE +#define PATTERN_SIZE_WORDS (((CPU_STACK_CHECK_SIZE / 4) + 3) & ~0x3) +#else +#define PATTERN_SIZE_WORDS 4 +#endif + +#define PATTERN_SIZE_BYTES (PATTERN_SIZE_WORDS * 4) + +typedef struct { + unsigned32 pattern[ PATTERN_SIZE_WORDS ]; +} Stack_check_Control; + +/* + * The pattern used to fill the entire stack. + */ + +#define BYTE_PATTERN 0xA5 +#define U32_PATTERN 0xA5A5A5A5 + +/* + * Stack_check_Create_extension + */ + +void Stack_check_Create_extension( + Thread_Control *running, + Thread_Control *the_thread +); + +/* + * Stack_check_Begin_extension + */ + +void Stack_check_Begin_extension( + Thread_Control *the_thread +); + +/* + * Stack_check_Switch_extension + */ + +void Stack_check_Switch_extension( + Thread_Control *running, + Thread_Control *heir +); + +/* + * Stack_check_Fatal_extension + */ + +void Stack_check_Fatal_extension( + unsigned32 +); + +/* + * Stack_check_Dump_usage + */ + +void Stack_check_Dump_usage( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/libmisc/stackchk/stackchk.h b/cpukit/libmisc/stackchk/stackchk.h new file mode 100644 index 0000000000..f3281c63fe --- /dev/null +++ b/cpukit/libmisc/stackchk/stackchk.h @@ -0,0 +1,41 @@ +/* stackchk.h + * + * This include file contains information necessary to utilize + * and install the stack checker mechanism. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __STACK_CHECK_h +#define __STACK_CHECK_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Stack_check_Initialize + */ + +void Stack_check_Initialize( void ); + +/* + * Stack_check_Dump_usage + */ + +void Stack_check_Dump_usage( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems.h b/cpukit/rtems/include/rtems.h new file mode 100644 index 0000000000..d0ab705f57 --- /dev/null +++ b/cpukit/rtems/include/rtems.h @@ -0,0 +1,79 @@ +/* rtems.h + * + * This include file contains information about RTEMS executive that + * is required by the application and is CPU independent. It includes + * two (2) CPU dependent files to tailor its data structures for a + * particular processor. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_RTEMS_GENERIC_h +#define __RTEMS_RTEMS_GENERIC_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * RTEMS basic type definitions + */ + +typedef unsigned8 rtems_unsigned8; /* unsigned 8-bit value */ +typedef unsigned16 rtems_unsigned16; /* unsigned 16-bit value */ +typedef unsigned32 rtems_unsigned32; /* unsigned 32-bit value */ +typedef unsigned64 rtems_unsigned64; /* unsigned 64-bit value */ + +typedef signed8 rtems_signed8; /* signed 8-bit value */ +typedef signed16 rtems_signed16; /* signed 16-bit value */ +typedef signed32 rtems_signed32; /* signed 32-bit value */ +typedef signed64 rtems_signed64; /* signed 64-bit value */ + +typedef single_precision rtems_single; /* single precision float */ +typedef double_precision rtems_double; /* double precision float */ + +typedef boolean rtems_boolean; + +typedef Objects_Name rtems_name; +typedef Objects_Id rtems_id; + +typedef Context_Control rtems_context; +typedef Context_Control_fp rtems_context_fp; +typedef CPU_Interrupt_frame rtems_interrupt_frame; + +#define RTEMS_HAS_HARDWARE_FP CPU_HARDWARE_FP + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/asr.h b/cpukit/rtems/include/rtems/rtems/asr.h new file mode 100644 index 0000000000..44d03f2802 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/asr.h @@ -0,0 +1,177 @@ +/* asr.h + * + * 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, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_ASR_h +#define __RTEMS_ASR_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * + * The following type defines the control block used to manage + * each signal set. + */ + +typedef unsigned32 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 { + rtems_asr_entry handler; /* address of RTEMS_ASR */ + rtems_mode mode_set; /* RTEMS_ASR mode */ + rtems_signal_set signals_posted; /* signal set */ + rtems_signal_set signals_pending; /* pending signal set */ + unsigned32 nest_level; /* nest level of RTEMS_ASR */ +} ASR_Information; + +/* + * The following constants define the individual signals which may + * be used to compose a signal set. + */ + +#define RTEMS_SIGNAL_0 0x00000001 +#define RTEMS_SIGNAL_1 0x00000002 +#define RTEMS_SIGNAL_2 0x00000004 +#define RTEMS_SIGNAL_3 0x00000008 +#define RTEMS_SIGNAL_4 0x00000010 +#define RTEMS_SIGNAL_5 0x00000020 +#define RTEMS_SIGNAL_6 0x00000040 +#define RTEMS_SIGNAL_7 0x00000080 +#define RTEMS_SIGNAL_8 0x00000100 +#define RTEMS_SIGNAL_9 0x00000200 +#define RTEMS_SIGNAL_10 0x00000400 +#define RTEMS_SIGNAL_11 0x00000800 +#define RTEMS_SIGNAL_12 0x00001000 +#define RTEMS_SIGNAL_13 0x00002000 +#define RTEMS_SIGNAL_14 0x00004000 +#define RTEMS_SIGNAL_15 0x00008000 +#define RTEMS_SIGNAL_16 0x00010000 +#define RTEMS_SIGNAL_17 0x00020000 +#define RTEMS_SIGNAL_18 0x00040000 +#define RTEMS_SIGNAL_19 0x00080000 +#define RTEMS_SIGNAL_20 0x00100000 +#define RTEMS_SIGNAL_21 0x00200000 +#define RTEMS_SIGNAL_22 0x00400000 +#define RTEMS_SIGNAL_23 0x00800000 +#define RTEMS_SIGNAL_24 0x01000000 +#define RTEMS_SIGNAL_25 0x02000000 +#define RTEMS_SIGNAL_26 0x04000000 +#define RTEMS_SIGNAL_27 0x08000000 +#define RTEMS_SIGNAL_28 0x10000000 +#define RTEMS_SIGNAL_29 0x20000000 +#define RTEMS_SIGNAL_30 0x40000000 +#define RTEMS_SIGNAL_31 0x80000000 + +/* + * _ASR_Initialize + * + * DESCRIPTION: + * + * This routine initializes the given RTEMS_ASR information record. + */ + +STATIC INLINE void _ASR_Initialize ( + ASR_Information *information +); + +/* + * _ASR_Swap_signals + * + * DESCRIPTION: + * + * This routine atomically swaps the pending and posted signal + * sets. This is done when the thread alters its mode in such a + * way that the RTEMS_ASR disable/enable flag changes. + */ + +STATIC INLINE void _ASR_Swap_signals ( + ASR_Information *information +); + +/* + * _ASR_Is_null_handler + * + * DESCRIPTION: + * + * This function returns TRUE if the given asr_handler is NULL and + * FALSE otherwise. + */ + +STATIC INLINE boolean _ASR_Is_null_handler ( + rtems_asr_entry asr_handler +); + +/* + * _ASR_Are_signals_pending + * + * DESCRIPTION: + * + * This function returns TRUE if there are signals pending in the + * given RTEMS_ASR information record and FALSE otherwise. + */ + +STATIC INLINE boolean _ASR_Are_signals_pending ( + ASR_Information *information +); + +/* + * _ASR_Post_signals + * + * DESCRIPTION: + * + * This routine posts the given signals into the signal_set + * passed in. The result is returned to the user in signal_set. + * + * NOTE: This must be implemented as a macro. + */ + +STATIC INLINE void _ASR_Post_signals( + rtems_signal_set signals, + rtems_signal_set *signal_set +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/attr.h b/cpukit/rtems/include/rtems/rtems/attr.h new file mode 100644 index 0000000000..1c59c98dcd --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/attr.h @@ -0,0 +1,188 @@ +/* attr.h + * + * This include file contains all information about the Object Attributes + * Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_ATTRIBUTES_h +#define __RTEMS_ATTRIBUTES_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* types */ + +typedef unsigned32 rtems_attribute; + +/* constants */ + +#define RTEMS_DEFAULT_ATTRIBUTES 0x00000000 + +#define RTEMS_NO_FLOATING_POINT 0x00000000 /* don't use FP HW */ +#define RTEMS_FLOATING_POINT 0x00000001 /* utilize coprocessor */ + +#define RTEMS_LOCAL 0x00000000 /* local resource */ +#define RTEMS_GLOBAL 0x00000002 /* global resource */ + +#define RTEMS_FIFO 0x00000000 /* process RTEMS_FIFO */ +#define RTEMS_PRIORITY 0x00000004 /* process by priority */ + +#define RTEMS_NO_LIMIT 0x00000000 /* unlimited Q entries */ +#define RTEMS_LIMIT 0x00000008 /* limit Q entries */ + +#define RTEMS_COUNTING_SEMAPHORE 0x00000000 +#define RTEMS_BINARY_SEMAPHORE 0x00000010 + +#define RTEMS_NO_INHERIT_PRIORITY 0x00000000 +#define RTEMS_INHERIT_PRIORITY 0x00000020 + +#if ( CPU_HARDWARE_FP == TRUE ) +#define ATTRIBUTES_NOT_SUPPORTED 0 +#else +#define ATTRIBUTES_NOT_SUPPORTED RTEMS_FLOATING_POINT +#endif + +#if ( CPU_ALL_TASKS_ARE_FP == TRUE ) +#define ATTRIBUTES_REQUIRED RTEMS_FLOATING_POINT +#else +#define ATTRIBUTES_REQUIRED 0 +#endif + +/* + * _Attributes_Handler_initialization + * + * DESCRIPTION: + * + * This routine performs initialization for this handler. + * + * NOTE: There is no initialization required in C. Conditional compilation + * takes care of this in C. + */ + +#define _Attributes_Handler_initialization() + +/* + * _Attributes_Set + * + * DESCRIPTION: + * + * This function sets the requested new_attributes in the attribute_set + * passed in. The result is returned to the user. + */ + +STATIC INLINE rtems_attribute _Attributes_Set ( + rtems_attribute new_attributes, + rtems_attribute attribute_set +); + +/* + * _Attributes_Clear + * + * DESCRIPTION: + * + * This function clears the requested new_attributes in the attribute_set + * passed in. The result is returned to the user. + */ + +STATIC INLINE rtems_attribute _Attributes_Clear ( + rtems_attribute attribute_set, + rtems_attribute mask +); + +/* + * _Attributes_Is_floating_point + * + * DESCRIPTION: + * + * This function returns TRUE if the floating point attribute is + * enabled in the attribute_set and FALSE otherwise. + */ + +STATIC INLINE boolean _Attributes_Is_floating_point( + rtems_attribute attribute_set +); + +/* + * _Attributes_Is_global + * + * DESCRIPTION: + * + * This function returns TRUE if the global object attribute is + * enabled in the attribute_set and FALSE otherwise. + */ + +STATIC INLINE boolean _Attributes_Is_global( + rtems_attribute attribute_set +); + +/* + * _Attributes_Is_priority + * + * DESCRIPTION: + * + * This function returns TRUE if the priority attribute is + * enabled in the attribute_set and FALSE otherwise. + */ + +STATIC INLINE boolean _Attributes_Is_priority( + rtems_attribute attribute_set +); + +/* + * _Attributes_Is_limit + * + * DESCRIPTION: + * + * This function returns TRUE if the limited attribute is + * enabled in the attribute_set and FALSE otherwise. + */ + +STATIC INLINE boolean _Attributes_Is_limit( + rtems_attribute attribute_set +); + +/* + * _Attributes_Is_binary_semaphore + * + * DESCRIPTION: + * + * This function returns TRUE if the binary semaphore attribute is + * enabled in the attribute_set and FALSE otherwise. + */ + +STATIC INLINE boolean _Attributes_Is_binary_semaphore( + rtems_attribute attribute_set +); + +/* + * _Attributes_Is_inherit_priority + * + * DESCRIPTION: + * + * This function returns TRUE if the priority inheritance attribute + * is enabled in the attribute_set and FALSE otherwise. + */ + +STATIC INLINE boolean _Attributes_Is_inherit_priority( + rtems_attribute attribute_set +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/clock.h b/cpukit/rtems/include/rtems/rtems/clock.h new file mode 100644 index 0000000000..e849ab4f40 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/clock.h @@ -0,0 +1,102 @@ +/* clock.h + * + * 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 + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_CLOCK_h +#define __RTEMS_CLOCK_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * List of things which can be returned by the rtems_clock_get directive. + */ + +typedef enum { + RTEMS_CLOCK_GET_TOD, + RTEMS_CLOCK_GET_SECONDS_SINCE_EPOCH, + RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, + RTEMS_CLOCK_GET_TICKS_PER_SECOND, + RTEMS_CLOCK_GET_TIME_VALUE +} rtems_clock_get_options; + +/* + * Standard flavor style to return TOD in for a rtems_clock_get option. + */ + +typedef struct { + unsigned32 seconds; + unsigned32 microseconds; +} rtems_clock_time_value; + +/* + * rtems_clock_get + * + * DESCRIPTION: + * + * This routine implements the rtems_clock_get directive. It returns + * one of the following: + * + current time of day + * + seconds since epoch + * + ticks since boot + * + ticks per second + */ + +rtems_status_code rtems_clock_get( + rtems_clock_get_options option, + void *time_buffer +); + +/* + * rtems_clock_set + * + * DESCRIPTION: + * + * This routine implements the rtems_clock_set directive. It sets + * the current time of day to that in the time_buffer record. + */ + +rtems_status_code rtems_clock_set( + rtems_time_of_day *time_buffer +); + +/* + * rtems_clock_tick + * + * DESCRIPTION: + * + * This routine implements the rtems_clock_tick directive. It is invoked + * to inform RTEMS of the occurrence of a clock tick. + */ + +rtems_status_code rtems_clock_tick( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/dpmem.h b/cpukit/rtems/include/rtems/rtems/dpmem.h new file mode 100644 index 0000000000..669eb394d8 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/dpmem.h @@ -0,0 +1,210 @@ +/* dpmem.h + * + * 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, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_DUAL_PORTED_MEMORY_h +#define __RTEMS_DUAL_PORTED_MEMORY_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * 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 { + Objects_Control Object; + void *internal_base; /* base internal address */ + void *external_base; /* base external address */ + unsigned32 length; /* length of dual-ported area */ +} Dual_ported_memory_Control; + +/* + * The following define the internal Dual Ported Memory information. + */ + +EXTERN Objects_Information _Dual_ported_memory_Information; + +/* + * _Dual_ported_memory_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _Dual_ported_memory_Manager_initialization( + unsigned32 maximum_ports +); + +/* + * rtems_port_create + * + * DESCRIPTION: + * + * This routine implements the rtems_port_create directive. The port + * will have the name 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. + */ + +rtems_status_code rtems_port_create( + Objects_Name name, + void *internal_start, + void *external_start, + unsigned32 length, + Objects_Id *id +); + +/* + * rtems_port_ident + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_port_ident( + Objects_Name name, + Objects_Id *id +); + +/* + * rtems_port_delete + * + * DESCRIPTION: + * + * This routine implements the rtems_port_delete directive. It deletes + * the port associated with ID. + */ + +rtems_status_code rtems_port_delete( + Objects_Id id +); + +/* + * rtems_port_external_to_internal + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_port_external_to_internal( + Objects_Id id, + void *external, + void **internal +); + +/* + * rtems_port_internal_to_external + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_port_internal_to_external( + Objects_Id id, + void *internal, + void **external +); + +/* + * _Dual_ported_memory_Allocate + * + * DESCRIPTION: + * + * This routine allocates a port control block from the inactive chain + * of free port control blocks. + */ + +STATIC INLINE Dual_ported_memory_Control + *_Dual_ported_memory_Allocate ( void ); + +/* + * _Dual_ported_memory_Free + * + * DESCRIPTION: + * + * This routine frees a port control block to the inactive chain + * of free port control blocks. + */ + +STATIC INLINE void _Dual_ported_memory_Free ( + Dual_ported_memory_Control *the_port +); + +/* + * _Dual_ported_memory_Get + * + * DESCRIPTION: + * + * This function maps port IDs to port control blocks. If ID + * corresponds to a local port, then it returns the_port control + * pointer which maps to ID and location is set to OBJECTS_LOCAL. + * Global ports are not supported, thus if ID does not map to a + * local port, location is set to OBJECTS_ERROR and the_port is + * undefined. + */ + +STATIC INLINE Dual_ported_memory_Control *_Dual_ported_memory_Get ( + Objects_Id id, + Objects_Locations *location +); + +/* + * _Dual_ported_memory_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_port is NULL and FALSE otherwise. + */ + +STATIC INLINE boolean _Dual_ported_memory_Is_null( + Dual_ported_memory_Control *the_port +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/event.h b/cpukit/rtems/include/rtems/rtems/event.h new file mode 100644 index 0000000000..aeb71b2abd --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/event.h @@ -0,0 +1,158 @@ +/* event.h + * + * 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, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_EVENT_h +#define __RTEMS_EVENT_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +/* + * This constant is passed as the event_in to the + * rtems_event_receive directive to determine which events are pending. + */ + +#define EVENT_CURRENT 0 + +/* + * _Event_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +STATIC INLINE void _Event_Manager_initialization( void ); + +/* + * rtems_event_send + * + * DESCRIPTION: + * + * This routine implements the rtems_event_send directive. It sends + * event_in to the task specified by ID. If the task is blocked + * waiting to receive events and the posting of event_in satisfies + * the task's event condition, then it is unblocked. + */ + +rtems_status_code rtems_event_send ( + Objects_Id id, + rtems_event_set event_in +); + +/* + * rtems_event_receive + * + * DESCRIPTION: + * + * This routine implements the rtems_event_receive directive. This + * directive is invoked when the calling task wishes to receive + * the event_in event condition. One of the fields in the option_set + * parameter determines whether the receive request is satisfied if + * any or all of the events are pending. If the event condition + * is not satisfied immediately, then the task may block with an + * optional timeout of TICKS clock ticks or return immediately. + * This determination is based on another field in the option_set + * parameter. This directive returns the events received in the + * event_out parameter. + */ + +rtems_status_code rtems_event_receive ( + rtems_event_set event_in, + rtems_option option_set, + rtems_interval ticks, + rtems_event_set *event_out +); + +/* + * _Event_Seize + * + * DESCRIPTION: + * + * This routine determines if the event condition event_in is + * satisfied. If so or if the no_wait option is enabled in option_set, + * then the procedure returns immediately. If neither of these + * conditions is true, then the calling task is blocked with an + * optional timeout of ticks clock ticks. + */ + +void _Event_Seize ( + rtems_event_set event_in, + rtems_option option_set, + rtems_interval ticks +); + +/* + * _Event_Surrender + * + * DESCRIPTION: + * + * This routine determines if the event condition of the_thread + * has been satisfied. If so, it unblocks the_thread. + */ + +void _Event_Surrender ( + Thread_Control *the_thread +); + +/* + * _Event_Timeout + * + * DESCRIPTION: + * + * This routine is invoked when a task's event receive request + * has not been satisfied after the specified timeout interval. + * The task represented by ID will be unblocked and its status + * code will be set in it's control block to indicate that a timeout + * has occurred. + */ + +void _Event_Timeout ( + Objects_Id id, + void *ignored +); + +/* + * The following defines the synchronization flag used by the + * Event Manager to insure that signals sent to the currently + * executing thread are received properly. + */ + +EXTERN boolean _Event_Sync; /* event manager sync flag */ + +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/eventmp.h b/cpukit/rtems/include/rtems/rtems/eventmp.h new file mode 100644 index 0000000000..9df2ef1e22 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/eventmp.h @@ -0,0 +1,147 @@ +/* eventmp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Event Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_EVENT_MP_h +#define __RTEMS_EVENT_MP_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +/* + * The following enumerated type defines the list of + * remote event operations. + */ + +typedef enum { + EVENT_MP_SEND_REQUEST = 0, + EVENT_MP_SEND_RESPONSE = 1, +} Event_MP_Remote_operations; + +/* + * The following data structure defines the packet used to perform + * remote event operations. + */ + +typedef struct { + rtems_packet_prefix Prefix; + Event_MP_Remote_operations operation; + rtems_event_set event_in; +} Event_MP_Packet; + +/* + * _Event_MP_Send_process_packet + * + * DESCRIPTION: + * + * 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. + */ + +/* + * _Event_MP_Send_request_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ + +rtems_status_code _Event_MP_Send_request_packet ( + Event_MP_Remote_operations operation, + Objects_Id event_id, + rtems_event_set event_in +); + +/* + * _Event_MP_Send_response_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ + +void _Event_MP_Send_response_packet ( + Event_MP_Remote_operations operation, + Thread_Control *the_thread +); + +/* + * + * _Event_MP_Process_packet + * + * DESCRIPTION: + * + * 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 +); + +/* + * _Event_MP_Send_object_was_deleted + * + * DESCRIPTION: + * + * 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. + */ + +/* + * _Event_MP_Send_extract_proxy + * + * DESCRIPTION: + * + * 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. + */ + +/* + * _Event_MP_Get_packet + * + * DESCRIPTION: + * + * This function is used to obtain a event mp packet. + */ + +Event_MP_Packet *_Event_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of file */ diff --git a/cpukit/rtems/include/rtems/rtems/eventset.h b/cpukit/rtems/include/rtems/rtems/eventset.h new file mode 100644 index 0000000000..a25dabe58b --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/eventset.h @@ -0,0 +1,142 @@ +/* eventset.h + * + * This include file contains the information pertaining to the + * Event Sets Handler. This handler provides methods for the manipulation + * of event sets which will be sent and received by tasks. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_EVENT_SET_h +#define __RTEMS_EVENT_SET_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following defines the type used to control event sets. + */ + +typedef unsigned32 rtems_event_set; + +/* + * The following constants define the individual events which may + * be used to compose an event set. + */ + +#define RTEMS_PENDING_EVENTS 0 /* receive pending events */ +#define RTEMS_ALL_EVENTS 0xFFFFFFFF + +#define RTEMS_EVENT_0 0x00000001 +#define RTEMS_EVENT_1 0x00000002 +#define RTEMS_EVENT_2 0x00000004 +#define RTEMS_EVENT_3 0x00000008 +#define RTEMS_EVENT_4 0x00000010 +#define RTEMS_EVENT_5 0x00000020 +#define RTEMS_EVENT_6 0x00000040 +#define RTEMS_EVENT_7 0x00000080 +#define RTEMS_EVENT_8 0x00000100 +#define RTEMS_EVENT_9 0x00000200 +#define RTEMS_EVENT_10 0x00000400 +#define RTEMS_EVENT_11 0x00000800 +#define RTEMS_EVENT_12 0x00001000 +#define RTEMS_EVENT_13 0x00002000 +#define RTEMS_EVENT_14 0x00004000 +#define RTEMS_EVENT_15 0x00008000 +#define RTEMS_EVENT_16 0x00010000 +#define RTEMS_EVENT_17 0x00020000 +#define RTEMS_EVENT_18 0x00040000 +#define RTEMS_EVENT_19 0x00080000 +#define RTEMS_EVENT_20 0x00100000 +#define RTEMS_EVENT_21 0x00200000 +#define RTEMS_EVENT_22 0x00400000 +#define RTEMS_EVENT_23 0x00800000 +#define RTEMS_EVENT_24 0x01000000 +#define RTEMS_EVENT_25 0x02000000 +#define RTEMS_EVENT_26 0x04000000 +#define RTEMS_EVENT_27 0x08000000 +#define RTEMS_EVENT_28 0x10000000 +#define RTEMS_EVENT_29 0x20000000 +#define RTEMS_EVENT_30 0x40000000 +#define RTEMS_EVENT_31 0x80000000 + + +/* + * The following constant is the value of an event set which + * has no events pending. + */ + +#define EVENT_SETS_NONE_PENDING 0 + +/* + * _Event_sets_Is_empty + * + * DESCRIPTION: + * + * This function returns TRUE if on events are posted in the event_set, + * and FALSE otherwise. + */ + +STATIC INLINE boolean _Event_sets_Is_empty( + rtems_event_set the_event_set +); + +/* + * _Event_sets_Post + * + * DESCRIPTION: + * + * This routine posts the given new_events into the event_set + * passed in. The result is returned to the user in event_set. + */ + +STATIC INLINE void _Event_sets_Post( + rtems_event_set the_new_events, + rtems_event_set *the_event_set +); + +/* + * _Event_sets_Get + * + * DESCRIPTION: + * + * This function returns the events in event_condition which are + * set in event_set. + */ + +STATIC INLINE rtems_event_set _Event_sets_Get( + rtems_event_set the_event_set, + rtems_event_set the_event_condition +); + +/* + * _Event_sets_Clear + * + * DESCRIPTION: + * + * This function removes the events in mask from the event_set + * passed in. The result is returned to the user in event_set. + */ + +STATIC INLINE rtems_event_set _Event_sets_Clear( + rtems_event_set the_event_set, + rtems_event_set the_mask +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/intr.h b/cpukit/rtems/include/rtems/rtems/intr.h new file mode 100644 index 0000000000..3669af1ccc --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/intr.h @@ -0,0 +1,125 @@ +/* intr.h + * + * This include file contains all the constants and structures associated + * with the Interrupt Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_INTERRUPT_h +#define __RTEMS_INTERRUPT_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * Interrupt level type + */ + +typedef ISR_Level rtems_interrupt_level; + +/* + * _Interrupt_Manager_initialization + * + * DESCRIPTION: + * + * This routine initializes the interrupt manager. + * + */ + +void _Interrupt_Manager_initialization( void ); + +/* + * rtems_interrupt_catch + * + * DESCRIPTION: + * + * This routine implements the rtems_interrupt_catch directive. This + * directive installs new_isr_handler as the RTEMS interrupt service + * routine for vector. The previous RTEMS interrupt service + * routine is returned in old_isr_handler. + */ + +rtems_status_code rtems_interrupt_catch( + rtems_isr_entry new_isr_handler, + rtems_vector_number vector, + rtems_isr_entry *old_isr_handler +); + +/* + * rtems_interrupt_disable + * + * DESCRIPTION: + * + * This routine disables all maskable interrupts and returns the + * previous level in _isr_cookie. + */ + +#define rtems_interrupt_disable( _isr_cookie ) \ + _ISR_Disable(_isr_cookie) + +/* + * rtems_interrupt_enable + * + * DESCRIPTION: + * + * This routine enables maskable interrupts to the level indicated + * _isr_cookie. + */ + +#define rtems_interrupt_enable( _isr_cookie ) \ + _ISR_Enable(_isr_cookie) + +/* + * rtems_interrupt_flash + * + * DESCRIPTION: + * + * This routine temporarily enables maskable interrupts to the + * level in _isr_cookie before redisabling them. + */ + +#define rtems_interrupt_flash( _isr_cookie ) \ + _ISR_Flash(_isr_cookie) + +/* + * rtems_interrupt_cause + * + * DESCRIPTION: + * + * This routine generates an interrupt. + * + * NOTE: No implementation. + */ + +#define rtems_interrupt_cause( _interrupt_to_cause ) + +/* + * rtems_interrupt_cause + * + * DESCRIPTION: + * + * This routine clears the specified interrupt. + * + * NOTE: No implementation. + */ + +#define rtems_interrupt_clear( _interrupt_to_clear ) + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/message.h b/cpukit/rtems/include/rtems/rtems/message.h new file mode 100644 index 0000000000..aefcea3c36 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/message.h @@ -0,0 +1,461 @@ +/* message.h + * + * 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, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_MESSAGE_QUEUE_h +#define __RTEMS_MESSAGE_QUEUE_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* + * The following defines the data types needed to manipulate + * the contents of message buffers. + */ + +typedef struct { + unsigned32 field1; + unsigned32 field2; + unsigned32 field3; + unsigned32 field4; +} Message_queue_Buffer; + +/* + * The following records define the organization of a message + * buffer. + */ + +typedef struct { + Chain_Node Node; + Message_queue_Buffer Contents; +} Message_queue_Buffer_control; + +/* + * The following records define the control block used to manage + * each message queue. + */ + +typedef struct { + Objects_Control Object; + Thread_queue_Control Wait_queue; + rtems_attribute attribute_set; + unsigned32 maximum_pending_messages; + unsigned32 number_of_pending_messages; + Chain_Control Pending_messages; +} Message_queue_Control; + +/* + * The following defines the information control block used to + * manage this class of objects. + */ + +EXTERN Objects_Information _Message_queue_Information; + +/* + * The following defines the data structures used to + * manage the pool of inactive message buffers. + */ + +EXTERN Chain_Control _Message_queue_Inactive_messages; + +/* + * 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 { + MESSAGE_QUEUE_SEND_REQUEST = 0, + MESSAGE_QUEUE_URGENT_REQUEST = 1 +} Message_queue_Submit_types; + +/* + * _Message_queue_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _Message_queue_Manager_initialization( + unsigned32 maximum_message_queues, + unsigned32 maximum_messages +); + +/* + * rtems_message_queue_create + * + * DESCRIPTION: + * + * This routine implements the rtems_message_queue_create directive. The + * message queue will have the name name. If the attribute_set indicates + * that the message queue is to be limited in the number of messages + * that can be outstanding, then count indicates the maximum number of + * messages that will be held. It returns the id of the created + * message queue in ID. + */ + +rtems_status_code rtems_message_queue_create( + Objects_Name name, + unsigned32 count, + rtems_attribute attribute_set, + Objects_Id *id +); + +/* + * rtems_message_queue_ident + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_message_queue_ident( + Objects_Name name, + unsigned32 node, + Objects_Id *id +); + +/* + * rtems_message_queue_delete + * + * DESCRIPTION: + * + * This routine implements the rtems_message_queue_delete directive. The + * message queue indicated by ID is deleted. + */ + +rtems_status_code rtems_message_queue_delete( + Objects_Id id +); + +/* + * rtems_message_queue_send + * + * DESCRIPTION: + * + * 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( + Objects_Id id, + void *buffer +); + +/* + * rtems_message_queue_urgent + * + * DESCRIPTION: + * + * 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_urgent( + Objects_Id id, + void *buffer +); + +/* + * rtems_message_queue_broadcast + * + * DESCRIPTION: + * + * 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_broadcast( + Objects_Id id, + void *buffer, + unsigned32 *count +); + +/* + * rtems_message_queue_receive + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_message_queue_receive( + Objects_Id id, + void *buffer, + unsigned32 option_set, + rtems_interval timeout +); + +/* + * rtems_message_queue_flush + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_message_queue_flush( + Objects_Id id, + unsigned32 *count +); + +/* + * _Message_queue_Copy_buffer + * + * DESCRIPTION: + * + * This routine copies the contents of the source message buffer + * to the destination message buffer. + */ + +STATIC INLINE void _Message_queue_Copy_buffer ( + Message_queue_Buffer *source, + Message_queue_Buffer *destination +); + +/* + * _Message_queue_Seize + * + * DESCRIPTION: + * + * This routine attempts to receive a message from the_message_queue. + * If a message is available or if the RTEMS_NO_WAIT option is enabled in + * option_set, then the routine returns. Otherwise, the calling task + * is blocked until a message is available. If a message is returned + * to the task, then buffer will contain its contents. + */ + +boolean _Message_queue_Seize( + Message_queue_Control *the_message_queue, + unsigned32 option_set, + Message_queue_Buffer *buffer +); + +/* + * _Message_queue_Flush_support + * + * DESCRIPTION: + * + * This routine flushes all outstanding messages and returns + * them to the inactive message chain. + */ + +unsigned32 _Message_queue_Flush_support( + Message_queue_Control *the_message_queue +); + +/* + * _Message_queue_Submit + * + * DESCRIPTION: + * + * This routine provides the common foundation for the + * rtems_message_queue_send and rtems_message_queue_urgent directives. + */ + +rtems_status_code _Message_queue_Submit( + Objects_Id id, + Message_queue_Buffer *buffer, + Message_queue_Submit_types submit_type +); + +/* + * _Message_queue_Allocate_message_buffer + * + * DESCRIPTION: + * + * This function allocates a message buffer from the inactive + * message buffer chain. + */ + +STATIC INLINE Message_queue_Buffer_control * + _Message_queue_Allocate_message_buffer ( void ); + +/* + * _Message_queue_Free_message_buffer + * + * DESCRIPTION: + * + * This routine frees a message buffer to the inactive + * message buffer chain. + */ + +STATIC INLINE void _Message_queue_Free_message_buffer ( + Message_queue_Buffer_control *the_message +); + +/* + * _Message_queue_Get_pending_message + * + * DESCRIPTION: + * + * This function removes the first message from the_message_queue + * and returns a pointer to it. + */ + +STATIC INLINE + Message_queue_Buffer_control *_Message_queue_Get_pending_message ( + Message_queue_Control *the_message_queue +); + +/* + * _Message_queue_Append + * + * DESCRIPTION: + * + * This routine places the_message at the rear of the outstanding + * messages on the_message_queue. + */ + +STATIC INLINE void _Message_queue_Append ( + Message_queue_Control *the_message_queue, + Message_queue_Buffer_control *the_message +); + +/* + * _Message_queue_Prepend + * + * DESCRIPTION: + * + * This routine places the_message at the rear of the outstanding + * messages on the_message_queue. + */ + +STATIC INLINE void _Message_queue_Prepend ( + Message_queue_Control *the_message_queue, + Message_queue_Buffer_control *the_message +); + +/* + * _Message_queue_Is_null + * + * DESCRIPTION: + * + * This function places the_message at the rear of the outstanding + * messages on the_message_queue. + */ + +STATIC INLINE boolean _Message_queue_Is_null ( + Message_queue_Control *the_message_queue +); + +/* + * _Message_queue_Allocate + * + * DESCRIPTION: + * + * This function allocates a message queue control block from + * the inactive chain of free message queue control blocks. + */ + +STATIC INLINE Message_queue_Control *_Message_queue_Allocate ( void ); + +/* + * _Message_queue_Free + * + * DESCRIPTION: + * + * This routine allocates a message queue control block from + * the inactive chain of free message queue control blocks. + */ + +STATIC INLINE void _Message_queue_Free ( + Message_queue_Control *the_message_queue +); + +/* + * _Message_queue_Get + * + * DESCRIPTION: + * + * This function maps message queue IDs to message queue control + * blocks. If ID corresponds to a local message queue, then it + * returns the_message_queue control pointer which maps to ID + * and location is set to OBJECTS_LOCAL. If the message queue ID is + * global and resides on a remote node, then location is set + * to OBJECTS_REMOTE, and the_message_queue is undefined. + * Otherwise, location is set to OBJECTS_ERROR and + * the_message_queue is undefined. + */ + +STATIC INLINE Message_queue_Control *_Message_queue_Get ( + Objects_Id id, + Objects_Locations *location +); + +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/modes.h b/cpukit/rtems/include/rtems/rtems/modes.h new file mode 100644 index 0000000000..9e714591ab --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/modes.h @@ -0,0 +1,183 @@ +/* modes.h + * + * This include file contains all constants and structures associated + * with the RTEMS thread and RTEMS_ASR modes. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_MODES_h +#define __RTEMS_MODES_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * The following type defines the control block used to manage + * each a mode set. + */ + +typedef unsigned32 rtems_mode; + +/* + * 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 + +#define RTEMS_DEFAULT_MODES 0x00000000 +#define RTEMS_CURRENT_MODE 0 + +#define RTEMS_PREEMPT_MASK 0x00000100 /* preemption bit */ +#define RTEMS_TIMESLICE_MASK 0x00000200 /* timeslice bit */ +#define RTEMS_ASR_MASK 0x00000400 /* RTEMS_ASR enable bit */ +#define RTEMS_INTERRUPT_MASK CPU_MODES_INTERRUPT_MASK + +#define RTEMS_PREEMPT 0x00000000 /* enable preemption */ +#define RTEMS_NO_PREEMPT 0x00000100 /* disable preemption */ + +#define RTEMS_NO_TIMESLICE 0x00000000 /* disable timeslicing */ +#define RTEMS_TIMESLICE 0x00000200 /* enable timeslicing */ + +#define RTEMS_ASR 0x00000000 /* enable RTEMS_ASR */ +#define RTEMS_NO_ASR 0x00000400 /* disable RTEMS_ASR */ + +/* + * The number of bits for interrupt levels is CPU dependent. + * RTEMS supports 0 to 256 levels in bits 0-7 of the mode. + */ + +/* + * RTEMS_INTERRUPT_LEVEL + * + * DESCRIPTION: + * + * 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. + */ + +STATIC INLINE unsigned32 RTEMS_INTERRUPT_LEVEL ( + rtems_mode mode_set +); + +/* + * _Modes_Mask_changed + * + * DESCRIPTION: + * + * This function returns TRUE if any of the mode flags in mask + * are set in mode_set, and FALSE otherwise. + */ + +STATIC INLINE boolean _Modes_Mask_changed ( + rtems_mode mode_set, + rtems_mode masks +); + +/* + * _Modes_Is_asr_disabled + * + * DESCRIPTION: + * + * This function returns TRUE if mode_set indicates that Asynchronous + * Signal Processing is disabled, and FALSE otherwise. + */ + +STATIC INLINE boolean _Modes_Is_asr_disabled ( + rtems_mode mode_set +); + +/* + * _Modes_Is_preempt + * + * DESCRIPTION: + * + * This function returns TRUE if mode_set indicates that preemption + * is enabled, and FALSE otherwise. + */ + +STATIC INLINE boolean _Modes_Is_preempt ( + rtems_mode mode_set +); + +/* + * _Modes_Is_timeslice + * + * DESCRIPTION: + * + * This function returns TRUE if mode_set indicates that timeslicing + * is enabled, and FALSE otherwise. + */ + +STATIC INLINE boolean _Modes_Is_timeslice ( + rtems_mode mode_set +); + +/* + * _Modes_Get_interrupt_level + * + * DESCRIPTION: + * + * This function returns the interrupt level portion of the mode_set. + */ + +STATIC INLINE ISR_Level _Modes_Get_interrupt_level ( + rtems_mode mode_set +); + +/* + * _Modes_Set_interrupt_level + * + * DESCRIPTION: + * + * This routine sets the current interrupt level to that specified + * in the mode_set. + */ + +STATIC INLINE void _Modes_Set_interrupt_level ( + rtems_mode mode_set +); + +/* + * _Modes_Change + * + * DESCRIPTION: + * + * 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. + */ + +STATIC INLINE void _Modes_Change ( + rtems_mode old_mode_set, + rtems_mode new_mode_set, + rtems_mode mask, + rtems_mode *out_mode_set, + rtems_mode *changed +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/mp.h b/cpukit/rtems/include/rtems/rtems/mp.h new file mode 100644 index 0000000000..96147d3b44 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/mp.h @@ -0,0 +1,67 @@ +/* mp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_MP_h +#define __RTEMS_MP_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * + * _Multiprocessing_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _Multiprocessing_Manager_initialization ( void ); + +/* + * + * rtems_multiprocessing_announce + * + * DESCRIPTION: + * + * 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 ); + +/* + * + * _Multiprocessing_Receive_server + * + * DESCRIPTION: + * + * This routine is a server thread which processes remote requests + * from other nodes. + */ + +Thread _Multiprocessing_Receive_server ( + Thread_Argument ignored +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/msgmp.h b/cpukit/rtems/include/rtems/rtems/msgmp.h new file mode 100644 index 0000000000..486bf00002 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/msgmp.h @@ -0,0 +1,175 @@ +/* msgmp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Message Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_MESSAGE_QUEUE_MP_h +#define __RTEMS_MESSAGE_QUEUE_MP_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include + +/* + * 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_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; + Objects_Name name; + rtems_option option_set; + Objects_Id proxy_id; + unsigned32 count; + unsigned32 pad0; + unsigned32 pad1; + unsigned32 pad2; + Message_queue_Buffer Buffer; +} Message_queue_MP_Packet; + +/* + * _Message_queue_MP_Send_process_packet + * + * DESCRIPTION: + * + * 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, + Objects_Name name, + Objects_Id proxy_id +); + +/* + * _Message_queue_MP_Send_request_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ + +rtems_status_code _Message_queue_MP_Send_request_packet ( + Message_queue_MP_Remote_operations operation, + Objects_Id message_queue_id, + Message_queue_Buffer *buffer, + rtems_option option_set, + rtems_interval timeout +); + +/* + * _Message_queue_MP_Send_response_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ + +void _Message_queue_MP_Send_response_packet ( + Message_queue_MP_Remote_operations operation, + Objects_Id message_queue_id, + Thread_Control *the_thread +); + +/* + * + * _Message_queue_MP_Process_packet + * + * DESCRIPTION: + * + * 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 +); + +/* + * _Message_queue_MP_Send_object_was_deleted + * + * DESCRIPTION: + * + * 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 +); + +/* + * _Message_queue_MP_Send_extract_proxy + * + * DESCRIPTION: + * + * 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 +); + +/* + * _Message_queue_MP_Get_packet + * + * DESCRIPTION: + * + * This function is used to obtain a message queue mp packet. + */ + +Message_queue_MP_Packet *_Message_queue_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of file */ diff --git a/cpukit/rtems/include/rtems/rtems/options.h b/cpukit/rtems/include/rtems/rtems/options.h new file mode 100644 index 0000000000..b318aad8c9 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/options.h @@ -0,0 +1,79 @@ +/* options.h + * + * This include file contains information which defines the + * options available on many directives. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_OPTIONS_h +#define __RTEMS_OPTIONS_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following type defines the control block used to manage + * option sets. + */ + +typedef unsigned32 rtems_option; + +/* + * The following constants define the individual options which may + * be used to compose an option set. + */ + +#define RTEMS_DEFAULT_OPTIONS 0x00000000 + +#define RTEMS_WAIT 0x00000000 /* wait on resource */ +#define RTEMS_NO_WAIT 0x00000001 /* do not wait on resource */ + +#define RTEMS_EVENT_ALL 0x00000000 /* wait for all events */ +#define RTEMS_EVENT_ANY 0x00000002 /* wait on any event */ + +/* + * _Options_Is_no_wait + * + * DESCRIPTION: + * + * This function returns TRUE if the RTEMS_NO_WAIT option is enabled in + * option_set, and FALSE otherwise. + * + */ + +STATIC INLINE boolean _Options_Is_no_wait ( + rtems_option option_set +); + +/* + * _Options_Is_any + * + * DESCRIPTION: + * + * This function returns TRUE if the RTEMS_EVENT_ANY option is enabled in + * OPTION_SET, and FALSE otherwise. + * + */ + +STATIC INLINE boolean _Options_Is_any ( + rtems_option option_set +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/part.h b/cpukit/rtems/include/rtems/rtems/part.h new file mode 100644 index 0000000000..e639029dc8 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/part.h @@ -0,0 +1,290 @@ +/* partition.h + * + * 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, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_PARTITION_h +#define __RTEMS_PARTITION_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* + * The following defines the control block used to manage each partition. + */ + +typedef struct { + Objects_Control Object; + void *starting_address; /* physical address */ + unsigned32 length; /* in bytes */ + unsigned32 buffer_size; /* in bytes */ + rtems_attribute attribute_set; /* attributes */ + unsigned32 number_of_used_blocks; /* or allocated buffers */ + Chain_Control Memory; /* buffer chain */ +} Partition_Control; + +/* + * The following defines the information control block used to + * manage this class of objects. + */ + +EXTERN Objects_Information _Partition_Information; + +/* + * _Partition_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _Partition_Manager_initialization( + unsigned32 maximum_partitions +); + +/* + * rtems_partition_create + * + * DESCRIPTION: + * + * 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( + Objects_Name name, + void *starting_address, + unsigned32 length, + unsigned32 buffer_size, + rtems_attribute attribute_set, + Objects_Id *id +); + +/* + * rtems_partition_ident + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_partition_ident( + Objects_Name name, + unsigned32 node, + Objects_Id *id +); + +/* + * rtems_partition_delete + * + * DESCRIPTION: + * + * This routine implements the rtems_partition_delete directive. The + * partition indicated by ID is deleted. + */ + +rtems_status_code rtems_partition_delete( + Objects_Id id +); + +/* + * rtems_partition_get_buffer + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_partition_get_buffer( + Objects_Id id, + void **buffer +); + +/* + * rtems_partition_return_buffer + * + * DESCRIPTION: + * + * 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( + Objects_Id id, + void *buffer +); + +/* + * _Partition_Allocate_buffer + * + * DESCRIPTION: + * + * This function attempts to allocate a buffer from the_partition. + * If successful, it returns the address of the allocated buffer. + * Otherwise, it returns NULL. + */ + +STATIC INLINE void *_Partition_Allocate_buffer ( + Partition_Control *the_partition +); + +/* + * _Partition_Free_buffer + * + * DESCRIPTION: + * + * This routine frees the_buffer to the_partition. + */ + +STATIC INLINE void _Partition_Free_buffer ( + Partition_Control *the_partition, + Chain_Node *the_buffer +); + +/* + * _Partition_Is_buffer_on_boundary + * + * DESCRIPTION: + * + * This function returns TRUE if the_buffer is on a valid buffer + * boundary for the_partition, and FALSE otherwise. + */ + +STATIC INLINE boolean _Partition_Is_buffer_on_boundary ( + void *the_buffer, + Partition_Control *the_partition +); + +/* + * _Partition_Is_buffer_valid + * + * DESCRIPTION: + * + * This function returns TRUE if the_buffer is a valid buffer from + * the_partition, otherwise FALSE is returned. + */ + +STATIC INLINE boolean _Partition_Is_buffer_valid ( + Chain_Node *the_buffer, + Partition_Control *the_partition +); + +/* + * _Partition_Is_buffer_size_aligned + * + * DESCRIPTION: + * + * 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. + */ + +STATIC INLINE boolean _Partition_Is_buffer_size_aligned ( + unsigned32 buffer_size +); + +/* + * _Partition_Allocate + * + * DESCRIPTION: + * + * This function allocates a partition control block from + * the inactive chain of free partition control blocks. + */ + +STATIC INLINE Partition_Control *_Partition_Allocate ( void ); + +/* + * _Partition_Free + * + * DESCRIPTION: + * + * This routine frees a partition control block to the + * inactive chain of free partition control blocks. + */ + +STATIC INLINE void _Partition_Free ( + Partition_Control *the_partition +); + +/* + * _Partition_Get + * + * DESCRIPTION: + * + * This function maps partition IDs to partition control blocks. + * If ID corresponds to a local partition, then it returns + * the_partition control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. If the partition ID is global and + * resides on a remote node, then location is set to OBJECTS_REMOTE, + * and the_partition is undefined. Otherwise, location is set + * to OBJECTS_ERROR and the_partition is undefined. + */ + +STATIC INLINE Partition_Control *_Partition_Get ( + Objects_Id id, + Objects_Locations *location +); + +/* + * _Partition_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_partition is NULL + * and FALSE otherwise. + */ + +STATIC INLINE boolean _Partition_Is_null ( + Partition_Control *the_partition +); + +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/partmp.h b/cpukit/rtems/include/rtems/rtems/partmp.h new file mode 100644 index 0000000000..deacaf7bd1 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/partmp.h @@ -0,0 +1,160 @@ +/* partmp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Partition Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_PARTITION_MP_h +#define __RTEMS_PARTITION_MP_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +/* + * 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; + Objects_Name name; + void *buffer; + Objects_Id proxy_id; +} Partition_MP_Packet; + +/* + * _Partition_MP_Send_process_packet + * + * DESCRIPTION: + * + * 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, + Objects_Name name, + Objects_Id proxy_id +); + +/* + * _Partition_MP_Send_request_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ + +rtems_status_code _Partition_MP_Send_request_packet ( + Partition_MP_Remote_operations operation, + Objects_Id partition_id, + void *buffer +); + +/* + * _Partition_MP_Send_response_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ + +void _Partition_MP_Send_response_packet ( + Partition_MP_Remote_operations operation, + Objects_Id partition_id, + Thread_Control *the_thread +); + +/* + * + * _Partition_MP_Process_packet + * + * DESCRIPTION: + * + * 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 +); + +/* + * _Partition_MP_Send_object_was_deleted + * + * DESCRIPTION: + * + * 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. + */ + +/* + * _Partition_MP_Send_extract_proxy + * + * DESCRIPTION: + * + * 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 +); + +/* + * _Partition_MP_Get_packet + * + * DESCRIPTION: + * + * This function is used to obtain a partition mp packet. + */ + +Partition_MP_Packet *_Partition_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of file */ diff --git a/cpukit/rtems/include/rtems/rtems/ratemon.h b/cpukit/rtems/include/rtems/rtems/ratemon.h new file mode 100644 index 0000000000..86acfb9a38 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/ratemon.h @@ -0,0 +1,285 @@ +/* ratemon.h + * + * This include file contains all the constants, structures, and + * prototypes associated with the Rate Monotonic Manager. This manager + * provides facilities to implement tasks 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 + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_RATE_MONOTONIC_h +#define __RTEMS_RATE_MONOTONIC_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* + * The following enumerated type defines the states in which a + * period may be. + */ + +typedef enum { + RATE_MONOTONIC_INACTIVE, /* off chain, never initialized */ + RATE_MONOTONIC_ACTIVE, /* on chain, running continuously */ + RATE_MONOTONIC_EXPIRED /* off chain, will be reset by next rm_period */ +} 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 RTEMS_NO_TIMEOUT + +/* + * The following structure defines the control block used to manage + * each period. + */ + +typedef struct { + Objects_Control Object; + Watchdog_Control Timer; + Rate_Monotonic_Period_states state; + Thread_Control *owner; +} Rate_monotonic_Control; + +EXTERN Objects_Information _Rate_monotonic_Information; + +/* + * _Rate_monotonic_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _Rate_monotonic_Manager_initialization( + unsigned32 maximum_periods +); + +/* + * rtems_rate_monotonic_create + * + * DESCRIPTION: + * + * 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( + Objects_Name name, + Objects_Id *id +); + +/* + * rtems_rate_monotonic_ident + * + * DESCRIPTION: + * + * This routine implements the rtems_rate_monotonic_ident directive. + * This directive 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. + */ + +rtems_status_code rtems_rate_monotonic_ident( + Objects_Name name, + Objects_Id *id +); + +/* + * rtems_rate_monotonic_cancel + * + * DESCRIPTION: + * + * This routine implements the rtems_rate_monotonic_cancel directive. This + * directive stops the period associated with ID from continuing to + * run. + */ + +rtems_status_code rtems_rate_monotonic_cancel( + Objects_Id id +); + +/* + * rtems_rate_monotonic_delete + * + * DESCRIPTION: + * + * This routine implements the rtems_rate_monotonic_delete directive. The + * period indicated by ID is deleted. + */ + +rtems_status_code rtems_rate_monotonic_delete( + Objects_Id id +); + +/* + * rtems_rate_monotonic_period + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_rate_monotonic_period( + Objects_Id id, + rtems_interval length +); + +/* + * _Rate_monotonic_Allocate + * + * DESCRIPTION: + * + * This function allocates a period control block from + * the inactive chain of free period control blocks. + */ + +STATIC INLINE Rate_monotonic_Control *_Rate_monotonic_Allocate( void ); + +/* + * _Rate_monotonic_Free + * + * DESCRIPTION: + * + * This routine allocates a period control block from + * the inactive chain of free period control blocks. + */ + +STATIC INLINE void _Rate_monotonic_Free ( + Rate_monotonic_Control *the_period +); + +/* + * _Rate_monotonic_Get + * + * DESCRIPTION: + * + * This function maps period IDs to period control blocks. + * If ID corresponds to a local period, then it returns + * the_period control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. Otherwise, location is set + * to OBJECTS_ERROR and the_period is undefined. + */ + +STATIC INLINE Rate_monotonic_Control *_Rate_monotonic_Get ( + Objects_Id id, + Objects_Locations *location +); + +/* + * _Rate_monotonic_Set_state + * + * DESCRIPTION: + * + * This function blocks the calling task so that it is waiting for + * a period to expire. It returns TRUE if the task was successfully + * blocked, and FALSE otherwise. + */ + +boolean _Rate_monotonic_Set_state( + Rate_monotonic_Control *the_period +); + +/* + * _Rate_monotonic_Timeout + * + * DESCRIPTION: + * + * This routine is invoked when the period represented + * by ID expires. If the task which owns this period is blocked + * waiting for the period to expire, then it is readied and the + * period is restarted. If the owning task is not waiting for the + * period to expire, then the period is placed in the EXPIRED + * state and not restarted. + */ + +void _Rate_monotonic_Timeout ( + Objects_Id id, + void *ignored +); + +/* + * _Rate_monotonic_Is_active + * + * DESCRIPTION: + * + * This function returns TRUE if the_period is in the ACTIVE state, + * and FALSE otherwise. + */ + +STATIC INLINE boolean _Rate_monotonic_Is_active ( + Rate_monotonic_Control *the_period +); + +/* + * _Rate_monotonic_Is_inactive + * + * DESCRIPTION: + * + * This function returns TRUE if the_period is in the ACTIVE state, + * and FALSE otherwise. + */ + +STATIC INLINE boolean _Rate_monotonic_Is_inactive ( + Rate_monotonic_Control *the_period +); + +/* + * _Rate_monotonic_Is_expired + * + * DESCRIPTION: + * + * This function returns TRUE if the_period is in the EXPIRED state, + * and FALSE otherwise. + */ + +STATIC INLINE boolean _Rate_monotonic_Is_expired ( + Rate_monotonic_Control *the_period +); + +/* + * _Rate_monotonic_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_period is NULL and FALSE otherwise. + */ + +STATIC INLINE boolean _Rate_monotonic_Is_null ( + Rate_monotonic_Control *the_period +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/region.h b/cpukit/rtems/include/rtems/rtems/region.h new file mode 100644 index 0000000000..c31e193c33 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/region.h @@ -0,0 +1,311 @@ +/* region.h + * + * 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, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_REGION_h +#define __RTEMS_REGION_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +/* + * The following records define the control block used to manage + * each region. + */ + +typedef struct { + Objects_Control Object; + Thread_queue_Control Wait_queue; /* waiting threads */ + void *starting_address; /* physical start addr */ + unsigned32 length; /* physical length(bytes) */ + unsigned32 page_size; /* in bytes */ + unsigned32 maximum_segment_size; /* in bytes */ + rtems_attribute attribute_set; + unsigned32 number_of_used_blocks; /* blocks allocated */ + Heap_Control Memory; +} Region_Control; + +/* + * The following defines the information control block used to + * manage this class of objects. + */ + +EXTERN Objects_Information _Region_Information; + +/* + * _Region_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _Region_Manager_initialization( + unsigned32 maximum_regions +); + +/* + * rtems_region_create + * + * DESCRIPTION: + * + * 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( + Objects_Name name, + void *starting_address, + unsigned32 length, + unsigned32 page_size, + rtems_attribute attribute_set, + Objects_Id *id +); + +/* + * rtems_region_extend + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_region_extend( + Objects_Id id, + void *starting_address, + unsigned32 length +); + +/* + * rtems_region_ident + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_region_ident( + Objects_Name name, + Objects_Id *id +); + +/* + * rtems_region_delete + * + * DESCRIPTION: + * + * This routine implements the rtems_region_delete directive. The + * region indicated by ID is deleted. + */ + +rtems_status_code rtems_region_delete( + Objects_Id id +); + +/* + * rtems_region_get_segment + * + * DESCRIPTION: + * + * This routine implements the rtems_region_get_segment directive. It + * attempts to allocate a segment from the region associated with ID. + * If a segment of the requested size can be allocated, its address + * is returned in segment. If no segment is available, then the task + * may return immediately or block waiting for a segment with an optional + * timeout of timeout clock ticks. Whether the task blocks or returns + * immediately is based on the no_wait option in the option_set. + */ + +rtems_status_code rtems_region_get_segment( + Objects_Id id, + unsigned32 size, + rtems_option option_set, + rtems_interval timeout, + void **segment +); + +/* + * rtems_region_get_segment_size + * + * DESCRIPTION: + * + * This routine implements the rtems_region_get_segment_size directive. It + * returns the size in bytes of the specified user memory area. + */ + +rtems_status_code rtems_region_get_segment_size( + Objects_Id id, + void *segment, + unsigned32 *size +); + +/* + * rtems_region_return_segment + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_region_return_segment( + Objects_Id id, + void *segment +); + +/* + * _Region_Allocate + * + * DESCRIPTION: + * + * This function allocates a region control block from + * the inactive chain of free region control blocks. + */ + +STATIC INLINE Region_Control *_Region_Allocate( void ); + +/* + * _Region_Free + * + * DESCRIPTION: + * + * This routine frees a region control block to the + * inactive chain of free region control blocks. + */ + +STATIC INLINE void _Region_Free ( + Region_Control *the_region +); + +/* + * _Region_Get + * + * DESCRIPTION: + * + * This function maps region IDs to region control blocks. + * If ID corresponds to a local region, then it returns + * the_region control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. Otherwise, location is set + * to OBJECTS_ERROR and the_region is undefined. + */ + +STATIC INLINE Region_Control *_Region_Get ( + Objects_Id id, + Objects_Locations *location +); + +/* + * _Region_Allocate_segment + * + * DESCRIPTION: + * + * This function attempts to allocate a segment from the_region. + * If successful, it returns the address of the allocated segment. + * Otherwise, it returns NULL. + */ + +STATIC INLINE void *_Region_Allocate_segment ( + Region_Control *the_region, + unsigned32 size +); + +/* + * _Region_Free_segment + * + * DESCRIPTION: + * + * This function frees the_segment to the_region. + */ + +STATIC INLINE boolean _Region_Free_segment ( + Region_Control *the_region, + void *the_segment +); + +/* + * _Region_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_region is NULL and FALSE otherwise. + */ + +STATIC INLINE boolean _Region_Is_null ( + Region_Control *the_region +); + +#include +#include + +/* + * _Region_Debug_Walk + * + * DESCRIPTION: + * + * This routine is invoked to verify the integrity of a heap associated + * with the_region. + */ + +#ifdef RTEMS_DEBUG + +#define _Region_Debug_Walk( _the_region, _source ) \ + do { \ + if ( _Debug_Is_enabled( RTEMS_DEBUG_REGION ) ) \ + _Heap_Walk( &(_the_region)->Memory, _source, FALSE ); \ + } while ( 0 ) + +#else + +#define _Region_Debug_Walk( _the_region, _source ) + +#endif + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/regionmp.h b/cpukit/rtems/include/rtems/rtems/regionmp.h new file mode 100644 index 0000000000..2810656078 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/regionmp.h @@ -0,0 +1,165 @@ +/* regionmp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Region Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_REGION_MP_h +#define __RTEMS_REGION_MP_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +/* + * The following enumerated type defines the list of + * remote region operations. + */ + +typedef enum { + REGION_MP_ANNOUNCE_CREATE = 0, + REGION_MP_ANNOUNCE_DELETE = 1, + REGION_MP_EXTRACT_PROXY = 2, + REGION_MP_GET_SEGMENT_REQUEST = 3, + REGION_MP_GET_SEGMENT_RESPONSE = 4, + REGION_MP_RETURN_SEGMENT_REQUEST = 5, + REGION_MP_RETURN_SEGMENT_RESPONSE = 6, +} Region_MP_Remote_operations; + +/* + * The following data structure defines the packet used to perform + * remote region operations. + */ + +typedef struct { + rtems_packet_prefix Prefix; + Region_MP_Remote_operations operation; + Objects_Name name; + rtems_option option_set; + unsigned32 size; + Objects_Id proxy_id; + void *segment; +} Region_MP_Packet; + +/* + * _Region_MP_Send_process_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * process operation can be performed on another node. + */ + +void _Region_MP_Send_process_packet ( + Region_MP_Remote_operations operation, + Objects_Id region_id, + Objects_Name name, + Objects_Id proxy_id +); + +/* + * _Region_MP_Send_request_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ + +rtems_status_code _Region_MP_Send_request_packet ( + Region_MP_Remote_operations operation, + Objects_Id region_id, + void *segment, + unsigned32 size, + rtems_option option_set, + rtems_interval timeout +); + +/* + * _Region_MP_Send_response_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ + +void _Region_MP_Send_response_packet ( + Region_MP_Remote_operations operation, + Objects_Id region_id, + Thread_Control *the_thread +); + +/* + * + * _Region_MP_Process_packet + * + * DESCRIPTION: + * + * This routine performs the actions specific to this package for + * the request from another node. + */ + +void _Region_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +); + +/* + * _Region_MP_Send_object_was_deleted + * + * DESCRIPTION: + * + * 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 Region since a region + * cannot be deleted when segments are in use. + */ + +/* + * _Region_MP_Send_extract_proxy + * + * DESCRIPTION: + * + * 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 _Region_MP_Send_extract_proxy ( + Thread_Control *the_thread +); + +/* + * _Region_MP_Get_packet + * + * DESCRIPTION: + * + * This function is used to obtain a region mp packet. + */ + +Region_MP_Packet *_Region_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of file */ diff --git a/cpukit/rtems/include/rtems/rtems/sem.h b/cpukit/rtems/include/rtems/rtems/sem.h new file mode 100644 index 0000000000..66f5ab82b8 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/sem.h @@ -0,0 +1,238 @@ +/* semaphore.h + * + * 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 + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_SEMAPHORE_h +#define __RTEMS_SEMAPHORE_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* + * The following defines the control block used to manage each semaphore. + */ + +typedef struct { + Objects_Control Object; + Thread_queue_Control Wait_queue; + rtems_attribute attribute_set; + unsigned32 count; + unsigned32 nest_count; + Thread_Control *holder; + Objects_Id holder_id; +} Semaphore_Control; + +/* + * The following defines the information control block used to manage + * this class of objects. + */ + +EXTERN Objects_Information _Semaphore_Information; + +/* + * _Semaphore_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _Semaphore_Manager_initialization( + unsigned32 maximum_semaphores +); + +/* + * rtems_semaphore_create + * + * DESCRIPTION: + * + * 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( + Objects_Name name, + unsigned32 count, + rtems_attribute attribute_set, + Objects_Id *id +); + +/* + * rtems_semaphore_ident + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_semaphore_ident( + Objects_Name name, + unsigned32 node, + Objects_Id *id +); + +/* + * rtems_semaphore_delete + * + * DESCRIPTION: + * + * This routine implements the rtems_semaphore_delete directive. The + * semaphore indicated by ID is deleted. + */ + +rtems_status_code rtems_semaphore_delete( + Objects_Id id +); + +/* + * rtems_semaphore_obtain + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_semaphore_obtain( + Objects_Id id, + unsigned32 option_set, + rtems_interval timeout +); + +/* + * rtems_semaphore_release + * + * DESCRIPTION: + * + * 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( + Objects_Id id +); + +/* + * _Semaphore_Seize + * + * DESCRIPTION: + * + * This routine attempts to receive a unit from the_semaphore. + * If a unit is available or if the RTEMS_NO_WAIT option is enabled in + * option_set, then the routine returns. Otherwise, the calling task + * is blocked until a unit becomes available. + */ + +boolean _Semaphore_Seize( + Semaphore_Control *the_semaphore, + unsigned32 option_set +); + +/* + * _Semaphore_Allocate + * + * DESCRIPTION: + * + * This function allocates a semaphore control block from + * the inactive chain of free semaphore control blocks. + */ + +STATIC INLINE Semaphore_Control *_Semaphore_Allocate( void ); + +/* + * _Semaphore_Free + * + * DESCRIPTION: + * + * This routine frees a semaphore control block to the + * inactive chain of free semaphore control blocks. + */ + +STATIC INLINE void _Semaphore_Free ( + Semaphore_Control *the_semaphore +); + +/* + * _Semaphore_Get + * + * DESCRIPTION: + * + * This function maps semaphore IDs to semaphore control blocks. + * If ID corresponds to a local semaphore, then it returns + * the_semaphore control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. if the semaphore ID is global and + * resides on a remote node, then location is set to OBJECTS_REMOTE, + * and the_semaphore is undefined. Otherwise, location is set + * to OBJECTS_ERROR and the_semaphore is undefined. + */ + +STATIC INLINE Semaphore_Control *_Semaphore_Get ( + Objects_Id id, + Objects_Locations *location +); + +/* + * _Semaphore_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_semaphore is NULL and FALSE otherwise. + */ + +STATIC INLINE boolean _Semaphore_Is_null ( + Semaphore_Control *the_semaphore +); + +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/semmp.h b/cpukit/rtems/include/rtems/rtems/semmp.h new file mode 100644 index 0000000000..2d0554c8cc --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/semmp.h @@ -0,0 +1,163 @@ +/* semmp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Semaphore Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_SEMAPHORE_MP_h +#define __RTEMS_SEMAPHORE_MP_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include + +/* + * 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; + Objects_Name name; + rtems_option option_set; + Objects_Id proxy_id; +} Semaphore_MP_Packet; + +/* + * _Semaphore_MP_Send_process_packet + * + * DESCRIPTION: + * + * 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, + Objects_Name name, + Objects_Id proxy_id +); + +/* + * _Semaphore_MP_Send_request_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ + +rtems_status_code _Semaphore_MP_Send_request_packet ( + Semaphore_MP_Remote_operations operation, + Objects_Id semaphore_id, + rtems_option option_set, + rtems_interval timeout +); + +/* + * _Semaphore_MP_Send_response_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ + +void _Semaphore_MP_Send_response_packet ( + Semaphore_MP_Remote_operations operation, + Objects_Id semaphore_id, + Thread_Control *the_thread +); + +/* + * + * _Semaphore_MP_Process_packet + * + * DESCRIPTION: + * + * 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 +); + +/* + * _Semaphore_MP_Send_object_was_deleted + * + * DESCRIPTION: + * + * 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 +); + +/* + * _Semaphore_MP_Send_extract_proxy + * + * DESCRIPTION: + * + * 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 +); + +/* + * _Semaphore_MP_Get_packet + * + * DESCRIPTION: + * + * This function is used to obtain a semaphore mp packet. + */ + +Semaphore_MP_Packet *_Semaphore_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of file */ diff --git a/cpukit/rtems/include/rtems/rtems/signal.h b/cpukit/rtems/include/rtems/rtems/signal.h new file mode 100644 index 0000000000..2466a8f931 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/signal.h @@ -0,0 +1,72 @@ +/* signal.h + * + * This include file contains all the constants and structures associated + * with the Signal Manager. This manager provides capabilities required + * for asynchronous communication between tasks via signal sets. + * + * Directives provided are: + * + * + establish an asynchronous signal routine + * + send a signal set to a task + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_SIGNAL_h +#define __RTEMS_SIGNAL_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +/* + * rtems_signal_catch + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_signal_catch( + rtems_asr_entry asr_handler, + rtems_mode mode_set +); + +/* + * rtems_signal_send + * + * DESCRIPTION: + * + * This routine implements the rtems_signal_send directive. This directive + * sends the signal_set to the task specified by ID. + */ + +rtems_status_code rtems_signal_send( + Objects_Id id, + rtems_signal_set signal_set +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/signalmp.h b/cpukit/rtems/include/rtems/rtems/signalmp.h new file mode 100644 index 0000000000..36a2d81594 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/signalmp.h @@ -0,0 +1,147 @@ +/* signalmp.h + * + * This include file contains all the constants and structures associated + * with the Multiprocessing Support in the Signal Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_SIGNAL_MP_h +#define __RTEMS_SIGNAL_MP_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +/* + * The following enumerated type defines the list of + * remote signal operations. + */ + +typedef enum { + SIGNAL_MP_SEND_REQUEST = 0, + SIGNAL_MP_SEND_RESPONSE = 1, +} Signal_MP_Remote_operations; + +/* + * The following data structure defines the packet used to perform + * remote signal operations. + */ + +typedef struct { + rtems_packet_prefix Prefix; + Signal_MP_Remote_operations operation; + rtems_signal_set signal_in; +} Signal_MP_Packet; + +/* + * _Signal_MP_Send_process_packet + * + * DESCRIPTION: + * + * 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. + */ + +/* + * _Signal_MP_Send_request_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ + +rtems_status_code _Signal_MP_Send_request_packet ( + Signal_MP_Remote_operations operation, + Objects_Id task_id, + rtems_signal_set signal_in +); + +/* + * _Signal_MP_Send_response_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ + +void _Signal_MP_Send_response_packet ( + Signal_MP_Remote_operations operation, + Thread_Control *the_thread +); + +/* + * + * _Signal_MP_Process_packet + * + * DESCRIPTION: + * + * 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 +); + +/* + * _Signal_MP_Send_object_was_deleted + * + * DESCRIPTION: + * + * 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. + */ + +/* + * _Signal_MP_Send_extract_proxy + * + * DESCRIPTION: + * + * 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. + */ + +/* + * _Signal_MP_Get_packet + * + * DESCRIPTION: + * + * This function is used to obtain a signal mp packet. + */ + +Signal_MP_Packet *_Signal_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of file */ diff --git a/cpukit/rtems/include/rtems/rtems/status.h b/cpukit/rtems/include/rtems/rtems/status.h new file mode 100644 index 0000000000..42b8754780 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/status.h @@ -0,0 +1,109 @@ +/* status.h + * + * This include file contains the status codes returned from the + * executive directives. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_STATUS_h +#define __RTEMS_STATUS_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* types */ + +/* enumerated constants */ + +typedef enum { + RTEMS_SUCCESSFUL = 0, /* successful completion */ + RTEMS_TASK_EXITTED = 1, /* returned from a thread */ + RTEMS_MP_NOT_CONFIGURED = 2, /* multiprocessing not configured */ + RTEMS_INVALID_NAME = 3, /* invalid object name */ + RTEMS_INVALID_ID = 4, /* invalid object id */ + RTEMS_TOO_MANY = 5, /* too many */ + RTEMS_TIMEOUT = 6, /* timed out waiting */ + RTEMS_OBJECT_WAS_DELETED = 7, /* object deleted while waiting */ + RTEMS_INVALID_SIZE = 8, /* specified size was invalid */ + RTEMS_INVALID_ADDRESS = 9, /* address specified is invalid */ + RTEMS_INVALID_NUMBER = 10, /* number was invalid */ + RTEMS_NOT_DEFINED = 11, /* item has not been initialized */ + RTEMS_RESOURCE_IN_USE = 12, /* resources still outstanding */ + RTEMS_UNSATISFIED = 13, /* request not satisfied */ + RTEMS_INCORRECT_STATE = 14, /* thread is in wrong state */ + RTEMS_ALREADY_SUSPENDED = 15, /* thread already in state */ + RTEMS_ILLEGAL_ON_SELF = 16, /* illegal on calling thread */ + RTEMS_ILLEGAL_ON_REMOTE_OBJECT = 17, /* illegal for remote object */ + RTEMS_CALLED_FROM_ISR = 18, /* called from wrong environment */ + RTEMS_INVALID_PRIORITY = 19, /* invalid thread priority */ + RTEMS_INVALID_CLOCK = 20, /* invalid date/time */ + RTEMS_INVALID_NODE = 21, /* invalid node id */ + RTEMS_NOT_CONFIGURED = 22, /* directive not configured */ + RTEMS_NOT_OWNER_OF_RESOURCE = 23, /* not owner of resource */ + RTEMS_NOT_IMPLEMENTED = 24, /* directive not implemented */ + RTEMS_INTERNAL_ERROR = 25, /* RTEMS inconsistency detected */ + RTEMS_PROXY_BLOCKING = 26, /* internal multiprocessing only */ + RTEMS_NO_MEMORY = 27 /* could not get enough memory */ +} rtems_status_code; + +#define RTEMS_STATUS_CODES_FIRST RTEMS_SUCCESSFUL +#define RTEMS_STATUS_CODES_LAST RTEMS_NO_MEMORY + +/* + * rtems_is_status_successful + * + * DESCRIPTION: + * + * This function returns TRUE if the status code is equal to RTEMS_SUCCESSFUL, + * and FALSE otherwise. + */ + +STATIC INLINE boolean rtems_is_status_successful ( + rtems_status_code code +); + +/* + * rtems_are_statuses_equal + * + * DESCRIPTION: + * + * This function returns TRUE if the status code1 is equal to code2, + * and FALSE otherwise. + */ + +STATIC INLINE boolean rtems_are_statuses_equal ( + rtems_status_code code1, + rtems_status_code code2 +); + +/* + * _Status_Is_proxy_blocking + * + * DESCRIPTION: + * + * This function returns TRUE if the status code is equal to the + * status which indicates that a proxy is blocking, and FALSE otherwise. + */ + +STATIC INLINE boolean _Status_Is_proxy_blocking ( + rtems_status_code code +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/taskmp.h b/cpukit/rtems/include/rtems/rtems/taskmp.h new file mode 100644 index 0000000000..57ab50c630 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/taskmp.h @@ -0,0 +1,167 @@ +/* taskmp.h + * + * This include file contains all the constants and structures associated + * with the multiprocessing support in the task manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_RTEMS_TASKS_MP_h +#define __RTEMS_RTEMS_TASKS_MP_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include + +/* + * 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_GET_NOTE_REQUEST = 8, + RTEMS_TASKS_MP_GET_NOTE_RESPONSE = 9, + RTEMS_TASKS_MP_SET_NOTE_REQUEST = 10, + RTEMS_TASKS_MP_SET_NOTE_RESPONSE = 11, +} RTEMS_tasks_MP_Remote_operations; + +/* + * The following data structure defines the packet used to perform + * remote task operations. + */ + +typedef struct { + rtems_packet_prefix Prefix; + RTEMS_tasks_MP_Remote_operations operation; + Objects_Name name; + rtems_task_priority the_priority; + unsigned32 notepad; + unsigned32 note; +} RTEMS_tasks_MP_Packet; + +/* + * _RTEMS_tasks_MP_Send_process_packet + * + * DESCRIPTION: + * + * 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, + Objects_Name name +); + +/* + * _RTEMS_tasks_MP_Send_request_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive operation can be initiated on another node. + */ + +rtems_status_code _RTEMS_tasks_MP_Send_request_packet ( + RTEMS_tasks_MP_Remote_operations operation, + Objects_Id task_id, + rtems_task_priority the_priority, + unsigned32 notepad, + unsigned32 note +); + +/* + * _RTEMS_tasks_MP_Send_response_packet + * + * DESCRIPTION: + * + * This routine performs a remote procedure call so that a + * directive can be performed on another node. + */ + +void _RTEMS_tasks_MP_Send_response_packet ( + RTEMS_tasks_MP_Remote_operations operation, + Thread_Control *the_thread +); + +/* + * + * _RTEMS_tasks_MP_Process_packet + * + * DESCRIPTION: + * + * 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 +); + +/* + * _RTEMS_tasks_MP_Send_object_was_deleted + * + * DESCRIPTION: + * + * 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 + * + * DESCRIPTION: + * + * 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. + * + */ + +/* + * _RTEMS_tasks_MP_Get_packet + * + * DESCRIPTION: + * + * This function is used to obtain a task mp packet. + */ + +RTEMS_tasks_MP_Packet *_RTEMS_tasks_MP_Get_packet ( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of file */ diff --git a/cpukit/rtems/include/rtems/rtems/tasks.h b/cpukit/rtems/include/rtems/rtems/tasks.h new file mode 100644 index 0000000000..d92913548e --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/tasks.h @@ -0,0 +1,315 @@ +/* tasks.h + * + * 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 + * + get a task notepad entry + * + set a task notepad entry + * + wake up after interval + * + wake up when specified + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_RTEMS_TASKS_h +#define __RTEMS_RTEMS_TASKS_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * 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 RTEMS_NO_TIMEOUT + +/* + * rtems_task_create + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_task_create( + Objects_Name name, + rtems_task_priority initial_priority, + unsigned32 stack_size, + rtems_mode initial_modes, + rtems_attribute attribute_set, + Objects_Id *id +); + +/* + * rtems_task_ident + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_task_ident( + Objects_Name name, + unsigned32 node, + Objects_Id *id +); + +/* + * rtems_task_delete + * + * DESCRIPTION: + * + * This routine implements the rtems_task_delete directive. The + * task indicated by ID is deleted. + */ + +rtems_status_code rtems_task_delete( + Objects_Id id +); + +/* + * rtems_task_get_note + * + * DESCRIPTION: + * + * This routine implements the rtems_task_get_note directive. The + * value of the indicated notepad for the task associated with ID + * is returned in note. + */ + +rtems_status_code rtems_task_get_note( + Objects_Id id, + unsigned32 notepad, + unsigned32 *note +); + +/* + * rtems_task_set_note + * + * DESCRIPTION: + * + * This routine implements the rtems_task_set_note directive. The + * value of the indicated notepad for the task associated with ID + * is returned in note. + */ + +rtems_status_code rtems_task_set_note( + Objects_Id id, + unsigned32 notepad, + unsigned32 note +); + +/* + * rtems_task_mode + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_task_mode( + rtems_mode mode_set, + rtems_mode mask, + rtems_mode *previous_mode_set +); + +/* + * rtems_task_restart + * + * DESCRIPTION: + * + * This routine implements the rtems_task_restart directive. The + * task associated with ID is restarted at its initial entry + * point with the new argument. + */ + +rtems_status_code rtems_task_restart( + Objects_Id id, + unsigned32 arg +); + +/* + * rtems_task_suspend + * + * DESCRIPTION: + * + * This routine implements the rtems_task_suspend directive. The + * SUSPENDED state is set for task associated with ID. + */ + +rtems_status_code rtems_task_suspend( + Objects_Id id +); + +/* + * rtems_task_resume + * + * DESCRIPTION: + * + * This routine implements the rtems_task_resume Directive. The + * SUSPENDED state is cleared for task associated with ID. + */ + +rtems_status_code rtems_task_resume( + Objects_Id id +); + +/* + * rtems_task_set_priority + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_task_set_priority( + Objects_Id id, + rtems_task_priority new_priority, + rtems_task_priority *old_priority +); + +/* + * rtems_task_start + * + * DESCRIPTION: + * + * 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( + Objects_Id id, + rtems_task_entry entry_point, + unsigned32 argument +); + +/* + * rtems_task_wake_when + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_task_wake_when( + rtems_time_of_day *time_buffer +); + +/* + * rtems_task_wake_after + * + * DESCRIPTION: + * + * This routine implements the rtems_task_wake_after directive. The + * calling task is blocked until the indicated number of clock + * ticks have occurred. + */ + +rtems_status_code rtems_task_wake_after( + rtems_interval ticks +); + +/* + * _RTEMS_tasks_Allocate + * + * DESCRIPTION: + * + * This function allocates a task control block from + * the inactive chain of free task control blocks. + */ + +STATIC INLINE Thread_Control *_RTEMS_tasks_Allocate( void ); + +/* + * _RTEMS_tasks_Free + * + * DESCRIPTION: + * + * This routine frees a task control block to the + * inactive chain of free task control blocks. + + */ + +STATIC INLINE void _RTEMS_tasks_Free ( + Thread_Control *the_task +); + +/* + * _RTEMS_tasks_Cancel_wait + * + * DESCRIPTION: + * + * This routine unblocks the_thread and cancels any timers + * which the_thread has active. + */ + +STATIC INLINE void _RTEMS_tasks_Cancel_wait( + Thread_Control *the_thread +); + +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/include/rtems/rtems/timer.h b/cpukit/rtems/include/rtems/rtems/timer.h new file mode 100644 index 0000000000..f6ccb5f4a1 --- /dev/null +++ b/cpukit/rtems/include/rtems/rtems/timer.h @@ -0,0 +1,292 @@ +/* timer.h + * + * 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 a timer to fire after a number of ticks have passed + * + set a timer to fire when a specified date and time has been reached + * + reset a timer + * + cancel a time + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_TIMER_h +#define __RTEMS_TIMER_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* + * The following enumerated type details the classes to which a timer + * may belong. + */ + +typedef enum { + TIMER_INTERVAL, + TIMER_TIME_OF_DAY, + TIMER_DORMANT +} Timer_Classes; + +/* + * The following defines the type of a Timer Service Routine. + */ + +typedef rtems_timer_service_routine_entry Timer_Service; + +/* + * The following defines the information control block used to manage + * this class of objects. + */ + +EXTERN Objects_Information _Timer_Information; + +/* + * The following records define the control block used to manage + * each timer. + */ + +typedef struct { + Objects_Control Object; + Watchdog_Control Ticker; + Timer_Classes the_class; +} Timer_Control; + +/* + * _Timer_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _Timer_Manager_initialization( + unsigned32 maximum_timers +); + +/* + * rtems_timer_create + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_timer_create( + Objects_Name name, + Objects_Id *id +); + +/* + * rtems_timer_ident + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_timer_ident( + Objects_Name name, + Objects_Id *id +); + +/* + * rtems_timer_cancel + * + * DESCRIPTION: + * + * 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( + Objects_Id id +); + +/* + * rtems_timer_delete + * + * DESCRIPTION: + * + * This routine implements the rtems_timer_delete directive. The + * timer indicated by ID is deleted. + */ + +rtems_status_code rtems_timer_delete( + Objects_Id id +); + +/* + * rtems_timer_fire_after + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_timer_fire_after( + Objects_Id id, + rtems_interval ticks, + Timer_Service routine, + void *user_data +); + +/* + * rtems_timer_fire_when + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code rtems_timer_fire_when( + Objects_Id id, + rtems_time_of_day *wall_time, + Timer_Service routine, + void *user_data +); + +/* + * rtems_timer_reset + * + * DESCRIPTION: + * + * 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( + Objects_Id id +); + +/* + * _Timer_Allocate + * + * DESCRIPTION: + * + * This function allocates a timer control block from + * the inactive chain of free timer control blocks. + */ + +STATIC INLINE Timer_Control *_Timer_Allocate( void ); + +/* + * _Timer_Free + * + * DESCRIPTION: + * + * This routine frees a timer control block to the + * inactive chain of free timer control blocks. + */ + +STATIC INLINE void _Timer_Free ( + Timer_Control *the_timer +); + +/* + * _Timer_Get + * + * DESCRIPTION: + * + * 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. + */ + +STATIC INLINE Timer_Control *_Timer_Get ( + Objects_Id id, + Objects_Locations *location +); + +/* + * _Timer_Is_interval_class + * + * DESCRIPTION: + * + * This function returns TRUE if the class is that of an INTERVAL + * timer, and FALSE otherwise. + */ + +STATIC INLINE boolean _Timer_Is_interval_class ( + Timer_Classes the_class +); + +/* + * _Timer_Is_time_of_day_class + * + * DESCRIPTION: + * + * This function returns TRUE if the class is that of an INTERVAL + * timer, and FALSE otherwise. + */ + +STATIC INLINE boolean _Timer_Is_timer_of_day_class ( + Timer_Classes the_class +); + +/* + * _Timer_Is_dormant_class + * + * DESCRIPTION: + * + * This function returns TRUE if the class is that of a DORMANT + * timer, and FALSE otherwise. + */ + +STATIC INLINE boolean _Timer_Is_dormant_class ( + Timer_Classes the_class +); + +/* + * _Timer_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_timer is NULL and FALSE otherwise. + */ + +STATIC INLINE boolean _Timer_Is_null ( + Timer_Control *the_timer +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/asr.inl b/cpukit/rtems/inline/rtems/rtems/asr.inl new file mode 100644 index 0000000000..a2da1ae311 --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/asr.inl @@ -0,0 +1,105 @@ +/* inline/asr.inl + * + * This include file contains the implemenation of all routines + * associated with the asynchronous signal handler which are inlined. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INLINE_ASR_inl +#define __INLINE_ASR_inl + +#include + +/*PAGE + * + * _ASR_Initialize + * + */ + +STATIC INLINE void _ASR_Initialize ( + ASR_Information *information +) +{ + information->handler = NULL; + information->mode_set = RTEMS_DEFAULT_MODES; + information->signals_posted = 0; + information->signals_pending = 0; + information->nest_level = 0; +} + +/*PAGE + * + * _ASR_Swap_signals + * + */ + +STATIC INLINE void _ASR_Swap_signals ( + ASR_Information *information +) +{ + rtems_signal_set _signals; + ISR_Level _level; + + _ISR_Disable( _level ); + _signals = information->signals_pending; + information->signals_pending = information->signals_posted; + information->signals_posted = _signals; + _ISR_Enable( _level ); +} + +/*PAGE + * + * _ASR_Is_null_handler + * + */ + +STATIC INLINE boolean _ASR_Is_null_handler ( + rtems_asr_entry asr_handler +) +{ + return asr_handler == NULL; +} + +/*PAGE + * + * _ASR_Are_signals_pending + * + */ + +STATIC INLINE boolean _ASR_Are_signals_pending ( + ASR_Information *information +) +{ + return information->signals_posted != 0; +} + +/*PAGE + * + * _ASR_Post_signals + * + */ + +STATIC INLINE void _ASR_Post_signals( + rtems_signal_set signals, + rtems_signal_set *signal_set +) +{ + ISR_Level _level; + + _ISR_Disable( _level ); + *signal_set |= signals; + _ISR_Enable( _level ); +} + + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/attr.inl b/cpukit/rtems/inline/rtems/rtems/attr.inl new file mode 100644 index 0000000000..c657a08211 --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/attr.inl @@ -0,0 +1,125 @@ +/* inline/attr.inl + * + * This include file contains all of the inlined routines associated + * with attributes. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INLINE_ATTRIBUTES_inl +#define __INLINE_ATTRIBUTES_inl + +/*PAGE + * + * _Attributes_Set + */ + +STATIC INLINE rtems_attribute _Attributes_Set ( + rtems_attribute new_attributes, + rtems_attribute attribute_set +) +{ + return attribute_set | new_attributes; +} + +/*PAGE + * + * _Attributes_Clear + */ + +STATIC INLINE rtems_attribute _Attributes_Clear ( + rtems_attribute attribute_set, + rtems_attribute mask +) +{ + return attribute_set & ~mask; +} + +/*PAGE + * + * _Attributes_Is_floating_point + * + */ + +STATIC INLINE boolean _Attributes_Is_floating_point( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_FLOATING_POINT ); +} + +/*PAGE + * + * _Attributes_Is_global + * + */ + +STATIC INLINE boolean _Attributes_Is_global( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_GLOBAL ); +} + +/*PAGE + * + * _Attributes_Is_priority + * + */ + +STATIC INLINE boolean _Attributes_Is_priority( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_PRIORITY ); +} + +/*PAGE + * + * _Attributes_Is_limit + * + */ + +STATIC INLINE boolean _Attributes_Is_limit( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_LIMIT ); +} + +/*PAGE + * + * _Attributes_Is_binary_semaphore + * + */ + +STATIC INLINE boolean _Attributes_Is_binary_semaphore( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_BINARY_SEMAPHORE ); +} + +/*PAGE + * + * _Attributes_Is_inherit_priority + * + */ + +STATIC INLINE boolean _Attributes_Is_inherit_priority( + rtems_attribute attribute_set +) +{ + return ( attribute_set & RTEMS_INHERIT_PRIORITY ); +} + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/dpmem.inl b/cpukit/rtems/inline/rtems/rtems/dpmem.inl new file mode 100644 index 0000000000..829ec5ab07 --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/dpmem.inl @@ -0,0 +1,75 @@ +/* inline/dpmem.inl + * + * This include file contains the inline routine used in conjunction + * with the Dual Ported Memory Manager + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INLINE_DPMEM_inl +#define __INLINE_DPMEM_inl + + +/*PAGE + * + * _Dual_ported_memory_Allocate + * + */ + +STATIC INLINE Dual_ported_memory_Control + *_Dual_ported_memory_Allocate ( void ) +{ + return (Dual_ported_memory_Control *) + _Objects_Allocate( &_Dual_ported_memory_Information ); +} + +/*PAGE + * + * _Dual_ported_memory_Free + * + */ + +STATIC INLINE void _Dual_ported_memory_Free ( + Dual_ported_memory_Control *the_port +) +{ + _Objects_Free( &_Dual_ported_memory_Information, &the_port->Object ); +} + +/*PAGE + * + * _Dual_ported_memory_Get + * + */ + +STATIC INLINE Dual_ported_memory_Control *_Dual_ported_memory_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (Dual_ported_memory_Control *) + _Objects_Get( &_Dual_ported_memory_Information, id, location ); +} + +/*PAGE + * + * _Dual_ported_memory_Is_null + */ + +STATIC INLINE boolean _Dual_ported_memory_Is_null( + Dual_ported_memory_Control *the_port +) +{ + return ( the_port == NULL ); +} + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/event.inl b/cpukit/rtems/inline/rtems/rtems/event.inl new file mode 100644 index 0000000000..2f2f480001 --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/event.inl @@ -0,0 +1,30 @@ +/* inline/event.inl + * + * This include file contains the static inline implementation of + * macros for the Event Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MACROS_EVENT_inl +#define __MACROS_EVENT_inl + +/* + * Event_Manager_initialization + */ + +STATIC INLINE void _Event_Manager_initialization( void ) +{ + _Event_Sync = FALSE; +} + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/eventset.inl b/cpukit/rtems/inline/rtems/rtems/eventset.inl new file mode 100644 index 0000000000..b38c61de1a --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/eventset.inl @@ -0,0 +1,71 @@ +/* inline/eventset.inl + * + * This include file contains the information pertaining to event sets. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INLINE_EVENT_SET_inl +#define __INLINE_EVENT_SET_inl + +/*PAGE + * + * _Event_sets_Is_empty + */ + +STATIC INLINE boolean _Event_sets_Is_empty( + rtems_event_set the_event_set +) +{ + return ( the_event_set == 0 ); +} + +/*PAGE + * + * _Event_sets_Post + */ + +STATIC INLINE void _Event_sets_Post( + rtems_event_set the_new_events, + rtems_event_set *the_event_set +) +{ + *the_event_set |= the_new_events; +} + +/*PAGE + * + * _Event_sets_Get + */ + +STATIC INLINE 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 ); +} + +/*PAGE + * + * _Event_sets_Clear + */ + +STATIC INLINE rtems_event_set _Event_sets_Clear( + rtems_event_set the_event_set, + rtems_event_set the_mask +) +{ + return ( the_event_set & ~(the_mask) ); +} + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/message.inl b/cpukit/rtems/inline/rtems/rtems/message.inl new file mode 100644 index 0000000000..ee8d5f6cb1 --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/message.inl @@ -0,0 +1,160 @@ +/* message.inl + * + * This include file contains the static inline implementation of all + * inlined routines in the Message Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MESSAGE_QUEUE_inl +#define __MESSAGE_QUEUE_inl + +/*PAGE + * + * _Message_queue_Copy_buffer + * + */ + +STATIC INLINE void _Message_queue_Copy_buffer ( + Message_queue_Buffer *source, + Message_queue_Buffer *destination +) +{ + *destination = *source; +} + +/*PAGE + * + * _Message_queue_Allocate_message_buffer + * + */ + +STATIC INLINE Message_queue_Buffer_control * + _Message_queue_Allocate_message_buffer ( void ) +{ + return (Message_queue_Buffer_control *) + _Chain_Get( &_Message_queue_Inactive_messages ); +} + +/*PAGE + * + * _Message_queue_Free_message_buffer + * + */ + +STATIC INLINE void _Message_queue_Free_message_buffer ( + Message_queue_Buffer_control *the_message +) +{ + _Chain_Append( &_Message_queue_Inactive_messages, &the_message->Node ); +} + +/*PAGE + * + * _Message_queue_Get_pending_message + * + */ + +STATIC INLINE + Message_queue_Buffer_control *_Message_queue_Get_pending_message ( + Message_queue_Control *the_message_queue +) +{ + return (Message_queue_Buffer_control *) + _Chain_Get_unprotected( &the_message_queue->Pending_messages ); +} + +/*PAGE + * + * _Message_queue_Append + * + */ + +STATIC INLINE void _Message_queue_Append ( + Message_queue_Control *the_message_queue, + Message_queue_Buffer_control *the_message +) +{ + _Chain_Append( &the_message_queue->Pending_messages, &the_message->Node ); +} + +/*PAGE + * + * _Message_queue_Prepend + * + */ + +STATIC INLINE void _Message_queue_Prepend ( + Message_queue_Control *the_message_queue, + Message_queue_Buffer_control *the_message +) +{ + _Chain_Prepend( + &the_message_queue->Pending_messages, + &the_message->Node + ); +} + +/*PAGE + * + * _Message_queue_Is_null + * + */ + +STATIC INLINE boolean _Message_queue_Is_null ( + Message_queue_Control *the_message_queue +) +{ + return ( the_message_queue == NULL ); +} + +/*PAGE + * + * _Message_queue_Allocate + * + */ + +STATIC INLINE Message_queue_Control *_Message_queue_Allocate ( void ) +{ + return (Message_queue_Control *) + _Objects_Allocate( &_Message_queue_Information ); +} + +/*PAGE + * + * _Message_queue_Free + * + */ + +STATIC INLINE void _Message_queue_Free ( + Message_queue_Control *the_message_queue +) +{ + _Objects_Free( &_Message_queue_Information, &the_message_queue->Object ); +} + +/*PAGE + * + * _Message_queue_Get + * + */ + +STATIC INLINE Message_queue_Control *_Message_queue_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (Message_queue_Control *) + _Objects_Get( &_Message_queue_Information, id, location ); +} + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/modes.inl b/cpukit/rtems/inline/rtems/rtems/modes.inl new file mode 100644 index 0000000000..6331a18a3a --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/modes.inl @@ -0,0 +1,136 @@ +/* modes.inl + * + * This include file contains the static inline implementation of the + * inlined routines in the Mode Handler + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MODES_inl +#define __MODES_inl + +/*PAGE + * + * RTEMS_INTERRUPT_LEVEL + */ + +STATIC INLINE unsigned32 RTEMS_INTERRUPT_LEVEL ( + rtems_mode mode_set +) +{ + return mode_set & RTEMS_INTERRUPT_MASK; +} + +/*PAGE + * + * _Modes_Mask_changed + * + */ + +STATIC INLINE boolean _Modes_Mask_changed ( + rtems_mode mode_set, + rtems_mode masks +) +{ + return ( mode_set & masks ); +} + +/*PAGE + * + * _Modes_Is_asr_disabled + * + */ + +STATIC INLINE boolean _Modes_Is_asr_disabled ( + rtems_mode mode_set +) +{ + return ( mode_set & RTEMS_ASR_MASK ); +} + +/*PAGE + * + * _Modes_Is_preempt + * + */ + +STATIC INLINE boolean _Modes_Is_preempt ( + rtems_mode mode_set +) +{ + return ( ( mode_set & RTEMS_PREEMPT_MASK ) == RTEMS_PREEMPT ); +} + +/*PAGE + * + * _Modes_Is_timeslice + * + */ + +STATIC INLINE boolean _Modes_Is_timeslice ( + rtems_mode mode_set +) +{ + return ((mode_set & (RTEMS_TIMESLICE_MASK|RTEMS_PREEMPT_MASK)) == + (RTEMS_TIMESLICE|RTEMS_PREEMPT) ); +} + +/*PAGE + * + * _Modes_Get_interrupt_level + * + */ + +STATIC INLINE ISR_Level _Modes_Get_interrupt_level ( + rtems_mode mode_set +) +{ + return ( mode_set & RTEMS_INTERRUPT_MASK ); +} + +/*PAGE + * + * _Modes_Set_interrupt_level + * + */ + +STATIC INLINE void _Modes_Set_interrupt_level ( + rtems_mode mode_set +) +{ + _ISR_Set_level( _Modes_Get_interrupt_level( mode_set ) ); +} + +/*PAGE + * + * _Modes_Change + * + */ + +STATIC INLINE void _Modes_Change ( + rtems_mode old_mode_set, + rtems_mode new_mode_set, + rtems_mode mask, + rtems_mode *out_mode_set, + rtems_mode *changed +) +{ + rtems_mode _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; +} + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/options.inl b/cpukit/rtems/inline/rtems/rtems/options.inl new file mode 100644 index 0000000000..b3c7312010 --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/options.inl @@ -0,0 +1,47 @@ +/* options.inl + * + * This file contains the static inline implementation of the inlined + * routines from the Options Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __OPTIONS_inl +#define __OPTIONS_inl + +/*PAGE + * + * _Options_Is_no_wait + * + */ + +STATIC INLINE boolean _Options_Is_no_wait ( + rtems_option option_set +) +{ + return (option_set & RTEMS_NO_WAIT); +} + +/*PAGE + * + * _Options_Is_any + * + */ + +STATIC INLINE boolean _Options_Is_any ( + rtems_option option_set +) +{ + return (option_set & RTEMS_EVENT_ANY); +} + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/part.inl b/cpukit/rtems/inline/rtems/rtems/part.inl new file mode 100644 index 0000000000..78f86dcefc --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/part.inl @@ -0,0 +1,157 @@ +/* part.inl + * + * This file contains the macro implementation of all inlined routines + * in the Partition Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __PARTITION_inl +#define __PARTITION_inl + +/*PAGE + * + * _Partition_Allocate_buffer + * + */ + +STATIC INLINE void *_Partition_Allocate_buffer ( + Partition_Control *the_partition +) +{ + return _Chain_Get( &the_partition->Memory ); +} + +/*PAGE + * + * _Partition_Free_buffer + * + */ + +STATIC INLINE void _Partition_Free_buffer ( + Partition_Control *the_partition, + Chain_Node *the_buffer +) +{ + _Chain_Append( &the_partition->Memory, the_buffer ); +} + +/*PAGE + * + * _Partition_Is_buffer_on_boundary + * + */ + +STATIC INLINE boolean _Partition_Is_buffer_on_boundary ( + void *the_buffer, + Partition_Control *the_partition +) +{ + unsigned32 offset; + + offset = (unsigned32) _Addresses_Subtract( + the_buffer, + the_partition->starting_address + ); + + return ((offset % the_partition->buffer_size) == 0); +} + +/*PAGE + * + * _Partition_Is_buffer_valid + * + */ + +STATIC INLINE boolean _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 ) + ); +} + +/*PAGE + * + * _Partition_Is_buffer_size_aligned + * + */ + +STATIC INLINE boolean _Partition_Is_buffer_size_aligned ( + unsigned32 buffer_size +) +{ + return ((buffer_size % CPU_PARTITION_ALIGNMENT) == 0); +} + +/*PAGE + * + * _Partition_Allocate + * + */ + +STATIC INLINE Partition_Control *_Partition_Allocate ( void ) +{ + return (Partition_Control *) _Objects_Allocate( &_Partition_Information ); +} + +/*PAGE + * + * _Partition_Free + * + */ + +STATIC INLINE void _Partition_Free ( + Partition_Control *the_partition +) +{ + _Objects_Free( &_Partition_Information, &the_partition->Object ); +} + +/*PAGE + * + * _Partition_Get + * + */ + +STATIC INLINE Partition_Control *_Partition_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (Partition_Control *) + _Objects_Get( &_Partition_Information, id, location ); +} + +/*PAGE + * + * _Partition_Is_null + * + */ + +STATIC INLINE boolean _Partition_Is_null ( + Partition_Control *the_partition +) +{ + return ( the_partition == NULL ); +} + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/ratemon.inl b/cpukit/rtems/inline/rtems/rtems/ratemon.inl new file mode 100644 index 0000000000..b748f919b3 --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/ratemon.inl @@ -0,0 +1,113 @@ +/* ratemon.inl + * + * This file contains the static inline implementation of the inlined + * routines in the Rate Monotonic Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RATE_MONOTONIC_inl +#define __RATE_MONOTONIC_inl + +/*PAGE + * + * _Rate_monotonic_Allocate + * + */ + +STATIC INLINE Rate_monotonic_Control *_Rate_monotonic_Allocate( void ) +{ + return (Rate_monotonic_Control *) + _Objects_Allocate( &_Rate_monotonic_Information ); +} + +/*PAGE + * + * _Rate_monotonic_Free + * + */ + +STATIC INLINE void _Rate_monotonic_Free ( + Rate_monotonic_Control *the_period +) +{ + _Objects_Free( &_Rate_monotonic_Information, &the_period->Object ); +} + +/*PAGE + * + * _Rate_monotonic_Get + * + */ + +STATIC INLINE Rate_monotonic_Control *_Rate_monotonic_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (Rate_monotonic_Control *) + _Objects_Get( &_Rate_monotonic_Information, id, location ); +} + +/*PAGE + * + * _Rate_monotonic_Is_active + * + */ + +STATIC INLINE boolean _Rate_monotonic_Is_active ( + Rate_monotonic_Control *the_period +) +{ + return (the_period->state == RATE_MONOTONIC_ACTIVE); +} + +/*PAGE + * + * _Rate_monotonic_Is_inactive + * + */ + +STATIC INLINE boolean _Rate_monotonic_Is_inactive ( + Rate_monotonic_Control *the_period +) +{ + return (the_period->state == RATE_MONOTONIC_INACTIVE); +} + +/*PAGE + * + * _Rate_monotonic_Is_expired + * + */ + +STATIC INLINE boolean _Rate_monotonic_Is_expired ( + Rate_monotonic_Control *the_period +) +{ + return (the_period->state == RATE_MONOTONIC_EXPIRED); +} + +/*PAGE + * + * _Rate_monotonic_Is_null + * + */ + +STATIC INLINE boolean _Rate_monotonic_Is_null ( + Rate_monotonic_Control *the_period +) +{ + return (the_period == NULL); +} + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/region.inl b/cpukit/rtems/inline/rtems/rtems/region.inl new file mode 100644 index 0000000000..5a0e4da1bf --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/region.inl @@ -0,0 +1,101 @@ +/* region.inl + * + * This file contains the macro implementation of the inlined + * routines from the Region Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __REGION_inl +#define __REGION_inl + +/*PAGE + * + * _Region_Allocate + * + */ + +STATIC INLINE Region_Control *_Region_Allocate( void ) +{ + return (Region_Control *) _Objects_Allocate( &_Region_Information ); +} + +/*PAGE + * + * _Region_Free + * + */ + +STATIC INLINE void _Region_Free ( + Region_Control *the_region +) +{ + _Objects_Free( &_Region_Information, &the_region->Object ); +} + +/*PAGE + * + * _Region_Get + * + */ + +STATIC INLINE Region_Control *_Region_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (Region_Control *) + _Objects_Get( &_Region_Information, id, location ); +} + +/*PAGE + * + * _Region_Allocate_segment + * + */ + +STATIC INLINE void *_Region_Allocate_segment ( + Region_Control *the_region, + unsigned32 size +) +{ + return _Heap_Allocate( &the_region->Memory, size ); +} + +/*PAGE + * + * _Region_Free_segment + * + */ + +STATIC INLINE boolean _Region_Free_segment ( + Region_Control *the_region, + void *the_segment +) +{ + return _Heap_Free( &the_region->Memory, the_segment ); +} + +/*PAGE + * + * _Region_Is_null + * + */ + +STATIC INLINE boolean _Region_Is_null ( + Region_Control *the_region +) +{ + return ( the_region == NULL ); +} + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/sem.inl b/cpukit/rtems/inline/rtems/rtems/sem.inl new file mode 100644 index 0000000000..518684a97a --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/sem.inl @@ -0,0 +1,73 @@ +/* sem.inl + * + * This file contains the static inlin implementation of the inlined + * routines from the Semaphore Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __SEMAPHORE_inl +#define __SEMAPHORE_inl + +/*PAGE + * + * _Semaphore_Allocate + * + */ + +STATIC INLINE Semaphore_Control *_Semaphore_Allocate( void ) +{ + return (Semaphore_Control *) _Objects_Allocate( &_Semaphore_Information ); +} + +/*PAGE + * + * _Semaphore_Free + * + */ + +STATIC INLINE void _Semaphore_Free ( + Semaphore_Control *the_semaphore +) +{ + _Objects_Free( &_Semaphore_Information, &the_semaphore->Object ); +} + +/*PAGE + * + * _Semaphore_Get + * + */ + +STATIC INLINE Semaphore_Control *_Semaphore_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (Semaphore_Control *) + _Objects_Get( &_Semaphore_Information, id, location ); +} + +/*PAGE + * + * _Semaphore_Is_null + * + */ + +STATIC INLINE boolean _Semaphore_Is_null ( + Semaphore_Control *the_semaphore +) +{ + return ( the_semaphore == NULL ); +} + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/status.inl b/cpukit/rtems/inline/rtems/rtems/status.inl new file mode 100644 index 0000000000..bd158e535b --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/status.inl @@ -0,0 +1,60 @@ +/* inline/status.inl + * + * This include file contains the implementations of the inlined + * routines for the status package. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INLINE_STATUS_inl +#define __INLINE_STATUS_inl + +/*PAGE + * + * rtems_is_status_successful + * + */ + +STATIC INLINE boolean rtems_is_status_successful( + rtems_status_code code +) +{ + return (code == RTEMS_SUCCESSFUL); +} + +/*PAGE + * + * rtems_are_statuses_equal + * + */ + +STATIC INLINE boolean rtems_are_statuses_equal( + rtems_status_code code1, + rtems_status_code code2 +) +{ + return (code1 == code2); +} + +/* + * _Status_Is_proxy_blocking + * + */ + +STATIC INLINE boolean _Status_Is_proxy_blocking ( + rtems_status_code code +) +{ + return (code == RTEMS_PROXY_BLOCKING); +} + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/tasks.inl b/cpukit/rtems/inline/rtems/rtems/tasks.inl new file mode 100644 index 0000000000..d5df18831a --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/tasks.inl @@ -0,0 +1,90 @@ +/* tasks.inl + * + * This file contains the static inline implementation of all inlined + * routines in the with RTEMS Tasks Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_TASKS_inl +#define __RTEMS_TASKS_inl + +/*PAGE + * + * _RTEMS_tasks_Allocate + * + */ + +STATIC INLINE Thread_Control *_RTEMS_tasks_Allocate( void ) +{ + return (Thread_Control *) _Objects_Allocate( &_Thread_Information ); +} + +/*PAGE + * + * _RTEMS_tasks_Free + * + */ + +STATIC INLINE void _RTEMS_tasks_Free ( + Thread_Control *the_task +) +{ + _Objects_Free( &_Thread_Information, &the_task->Object ); +} + +/*PAGE + * + * _RTEMS_tasks_Cancel_wait + * + */ + +STATIC INLINE void _RTEMS_tasks_Cancel_wait( + Thread_Control *the_thread +) +{ + States_Control state; + States_Control remote_state; + + state = the_thread->current_state; + + if ( _States_Is_waiting_on_thread_queue( state ) ) { + if ( _States_Is_waiting_for_rpc_reply( state ) && + _States_Is_locally_blocked( state ) ) { + remote_state = _States_Clear( + STATES_WAITING_FOR_RPC_REPLY | STATES_TRANSIENT, + state + ); + + switch ( remote_state ) { + + case STATES_WAITING_FOR_BUFFER: + _Partition_MP_Send_extract_proxy( the_thread ); + break; + case STATES_WAITING_FOR_SEGMENT: + _Region_MP_Send_extract_proxy( the_thread ); + break; + case STATES_WAITING_FOR_SEMAPHORE: + _Semaphore_MP_Send_extract_proxy( the_thread ); + break; + case STATES_WAITING_FOR_MESSAGE: + _Message_queue_MP_Send_extract_proxy( the_thread ); + break; + } + } + _Thread_queue_Extract( the_thread->Wait.queue, the_thread ); + } + else if ( _Watchdog_Is_active( &the_thread->Timer ) ) + (void) _Watchdog_Remove( &the_thread->Timer ); +} + +#endif +/* end of include file */ diff --git a/cpukit/rtems/inline/rtems/rtems/timer.inl b/cpukit/rtems/inline/rtems/rtems/timer.inl new file mode 100644 index 0000000000..7af3b9fa3d --- /dev/null +++ b/cpukit/rtems/inline/rtems/rtems/timer.inl @@ -0,0 +1,112 @@ +/* timer.inl + * + * This file contains the static inline implementation of the inlined routines + * from the Timer Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __TIMER_inl +#define __TIMER_inl + +/*PAGE + * + * _Timer_Allocate + * + */ + +STATIC INLINE Timer_Control *_Timer_Allocate( void ) +{ + return (Timer_Control *) _Objects_Allocate( &_Timer_Information ); +} + +/*PAGE + * + * _Timer_Free + * + */ + +STATIC INLINE void _Timer_Free ( + Timer_Control *the_timer +) +{ + _Objects_Free( &_Timer_Information, &the_timer->Object ); +} + +/*PAGE + * + * _Timer_Get + * + */ + +STATIC INLINE Timer_Control *_Timer_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (Timer_Control *) + _Objects_Get( &_Timer_Information, id, location ); +} + +/*PAGE + * + * _Timer_Is_interval_class + * + */ + +STATIC INLINE boolean _Timer_Is_interval_class ( + Timer_Classes the_class +) +{ + return ( the_class == TIMER_INTERVAL ); +} + +/*PAGE + * + * _Timer_Is_time_of_day_class + * + */ + +STATIC INLINE boolean _Timer_Is_timer_of_day_class ( + Timer_Classes the_class +) +{ + return ( the_class == TIMER_TIME_OF_DAY ); +} + +/*PAGE + * + * _Timer_Is_dormant_class + * + */ + +STATIC INLINE boolean _Timer_Is_dormant_class ( + Timer_Classes the_class +) +{ + return ( the_class == TIMER_DORMANT ); +} + +/*PAGE + * + * _Timer_Is_null + * + */ + +STATIC INLINE boolean _Timer_Is_null ( + Timer_Control *the_timer +) +{ + return ( the_timer == NULL ); +} + +#endif +/* end of include file */ diff --git a/cpukit/rtems/macros/rtems/rtems/asr.inl b/cpukit/rtems/macros/rtems/rtems/asr.inl new file mode 100644 index 0000000000..421755879b --- /dev/null +++ b/cpukit/rtems/macros/rtems/rtems/asr.inl @@ -0,0 +1,89 @@ +/* macros/asr.h + * + * This include file contains the implemenation of all routines + * associated with the asynchronous signal handler which are inlined. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INLINE_ASR_h +#define __INLINE_ASR_h + +#include + +/*PAGE + * + * _ASR_Initialize + * + */ + +#define _ASR_Initialize( _information ) \ +{ \ + (_information)->handler = NULL; \ + (_information)->mode_set = RTEMS_DEFAULT_MODES; \ + (_information)->signals_posted = 0; \ + (_information)->signals_pending = 0; \ + (_information)->nest_level = 0; \ +} + +/*PAGE + * + * _ASR_Swap_signals + * + */ + +#define _ASR_Swap_signals( _information ) \ +{ \ + rtems_signal_set _signals; \ + ISR_Level _level; \ + \ + _ISR_Disable( _level ); \ + _signals = (_information)->signals_pending; \ + (_information)->signals_pending = (_information)->signals_posted; \ + (_information)->signals_posted = _signals; \ + _ISR_Enable( _level ); \ +} + +/*PAGE + * + * _ASR_Is_null_handler + * + */ + +#define _ASR_Is_null_handler( _asr_handler ) \ + ( (_asr_handler) == NULL ) + +/*PAGE + * + * _ASR_Are_signals_pending + * + */ + +#define _ASR_Are_signals_pending( _information ) \ + ( (_information)->signals_posted != 0 ) + +/*PAGE + * + * _ASR_Post_signals + * + */ + +#define _ASR_Post_signals( _signals, _signal_set ) \ + do { \ + ISR_Level _level; \ + \ + _ISR_Disable( _level ); \ + *(_signal_set) |= (_signals); \ + _ISR_Enable( _level ); \ + } while ( 0 ) + +#endif +/* end of include file */ diff --git a/cpukit/rtems/macros/rtems/rtems/attr.inl b/cpukit/rtems/macros/rtems/rtems/attr.inl new file mode 100644 index 0000000000..602622ca35 --- /dev/null +++ b/cpukit/rtems/macros/rtems/rtems/attr.inl @@ -0,0 +1,91 @@ +/* macros/attr.h + * + * This include file contains all of the inlined routines associated + * with attributes. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MACROS_ATTRIBUTES_h +#define __MACROS_ATTRIBUTES_h + +/*PAGE + * + * _Attributes_Set + */ + +#define _Attributes_Set( _new_attributes, _attribute_set ) \ + ( (_attribute_set) | (_new_attributes) ) + +/*PAGE + * + * _Attributes_Clear + */ + +#define _Attributes_Clear( _attribute_set, _mask ) \ + ( (_attribute_set) & ~(_mask) ) + +/*PAGE + * + * _Attributes_Is_floating_point + * + */ + +#define _Attributes_Is_floating_point( _attribute_set ) \ + ( (_attribute_set) & RTEMS_FLOATING_POINT ) + +/*PAGE + * + * _Attributes_Is_global + * + */ + +#define _Attributes_Is_global( _attribute_set ) \ + ( (_attribute_set) & RTEMS_GLOBAL ) + +/*PAGE + * + * _Attributes_Is_priority + * + */ + +#define _Attributes_Is_priority( _attribute_set ) \ + ( (_attribute_set) & RTEMS_PRIORITY ) + +/*PAGE + * + * _Attributes_Is_limit + * + */ + +#define _Attributes_Is_limit( _attribute_set ) \ + ( (_attribute_set) & RTEMS_LIMIT ) + +/*PAGE + * + * _Attributes_Is_binary_semaphore + * + */ + +#define _Attributes_Is_binary_semaphore( _attribute_set ) \ + ( (_attribute_set) & RTEMS_BINARY_SEMAPHORE ) + +/*PAGE + * + * _Attributes_Is_inherit_priority + * + */ + +#define _Attributes_Is_inherit_priority( _attribute_set ) \ + ( (_attribute_set) & RTEMS_INHERIT_PRIORITY ) + +#endif +/* end of include file */ diff --git a/cpukit/rtems/macros/rtems/rtems/dpmem.inl b/cpukit/rtems/macros/rtems/rtems/dpmem.inl new file mode 100644 index 0000000000..3e1d7bce95 --- /dev/null +++ b/cpukit/rtems/macros/rtems/rtems/dpmem.inl @@ -0,0 +1,59 @@ +/* macros/dpmem.h + * + * This include file contains the inline routine used in conjunction + * with the Dual Ported Memory Manager + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MACROS_DPMEM_h +#define __MACROS_DPMEM_h + +/*PAGE + * + * _Dual_ported_memory_Allocate + * + */ + +#define _Dual_ported_memory_Allocate() \ + (Dual_ported_memory_Control *) \ + _Objects_Allocate( &_Dual_ported_memory_Information ) + +/*PAGE + * + * _Dual_ported_memory_Free + * + */ + +#define _Dual_ported_memory_Free( _the_port ) \ + _Objects_Free( &_Dual_ported_memory_Information, &(_the_port)->Object ) + +/*PAGE + * + * _Dual_ported_memory_Get + * + */ + +#define _Dual_ported_memory_Get( _id, _location ) \ + (Dual_ported_memory_Control *) \ + _Objects_Get( &_Dual_ported_memory_Information, (_id), (_location) ) + + +/*PAGE + * + * _Dual_ported_memory_Is_null + */ + +#define _Dual_ported_memory_Is_null( _the_port ) \ + ( (_the_port) == NULL ) + +#endif +/* end of include file */ diff --git a/cpukit/rtems/macros/rtems/rtems/event.inl b/cpukit/rtems/macros/rtems/rtems/event.inl new file mode 100644 index 0000000000..1d4cb78237 --- /dev/null +++ b/cpukit/rtems/macros/rtems/rtems/event.inl @@ -0,0 +1,28 @@ +/* macros/event.h + * + * This include file contains the implementation of macros for + * the Event Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MACROS_EVENT_h +#define __MACROS_EVENT_h + +/* + * Event_Manager_initialization + */ + +#define _Event_Manager_initialization() \ + _Event_Sync = FALSE + +#endif +/* end of include file */ diff --git a/cpukit/rtems/macros/rtems/rtems/eventset.inl b/cpukit/rtems/macros/rtems/rtems/eventset.inl new file mode 100644 index 0000000000..1803d18637 --- /dev/null +++ b/cpukit/rtems/macros/rtems/rtems/eventset.inl @@ -0,0 +1,53 @@ +/* eventset.inl + * + * This include file contains the macro implementation of inlined + * routines in the event set object. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __EVENT_SET_inl +#define __EVENT_SET_inl + +/*PAGE + * + * _Event_sets_Is_empty + */ + +#define _Event_sets_Is_empty( _the_event_set ) \ + ((_the_event_set) == 0 ) + +/*PAGE + * + * _Event_sets_Is_empty + */ + +#define _Event_sets_Post( _the_new_events, _the_event_set ) \ + *(_the_event_set) |= (_the_new_events) + +/*PAGE + * + * _Event_sets_Is_empty + */ + +#define _Event_sets_Get( _the_event_set, _the_event_condition ) \ + ((_the_event_set) & (_the_event_condition)) + +/*PAGE + * + * _Event_sets_Clear + */ + +#define _Event_sets_Clear( _the_event_set, _the_mask ) \ + ((_the_event_set) & ~(_the_mask)) + +#endif +/* end of include file */ diff --git a/cpukit/rtems/macros/rtems/rtems/message.inl b/cpukit/rtems/macros/rtems/rtems/message.inl new file mode 100644 index 0000000000..5415708ac5 --- /dev/null +++ b/cpukit/rtems/macros/rtems/rtems/message.inl @@ -0,0 +1,118 @@ +/* message.inl + * + * This include file contains the macro implementation of all + * inlined routines in the Message Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MESSAGE_QUEUE_inl +#define __MESSAGE_QUEUE_inl + +/*PAGE + * + * _Message_queue_Copy_buffer + */ + +#define _Message_queue_Copy_buffer( _source, _destination ) \ + *(Message_queue_Buffer *)(_destination) = \ + *(Message_queue_Buffer *)(_source) + +/*PAGE + * + * _Message_queue_Allocate_message_buffer + * + */ + +#define _Message_queue_Allocate_message_buffer() \ + (Message_queue_Buffer_control *) \ + _Chain_Get( &_Message_queue_Inactive_messages ) + +/*PAGE + * + * _Message_queue_Free_message_buffer + * + */ + +#define _Message_queue_Free_message_buffer( _the_message ) \ + _Chain_Append( &_Message_queue_Inactive_messages, &(_the_message)->Node ) + +/*PAGE + * + * _Message_queue_Get_pending_message + * + */ + +#define _Message_queue_Get_pending_message( _the_message_queue ) \ + (Message_queue_Buffer_control *) \ + _Chain_Get_unprotected( &(_the_message_queue)->Pending_messages ) + +/*PAGE + * + * _Message_queue_Append + * + */ + +#define _Message_queue_Append( _the_message_queue, _the_message ) \ + _Chain_Append( &(_the_message_queue)->Pending_messages, \ + &(_the_message)->Node ) + +/*PAGE + * + * _Message_queue_Prepend + * + */ + +#define _Message_queue_Prepend( _the_message_queue, _the_message ) \ + _Chain_Prepend( &(_the_message_queue)->Pending_messages, \ + &(_the_message)->Node ) + +/*PAGE + * + * _Message_queue_Is_null + * + */ + +#define _Message_queue_Is_null( _the_message_queue ) \ + ( (_the_message_queue) == NULL ) + +/*PAGE + * + * _Message_queue_Allocate + * + */ + +#define _Message_queue_Allocate() \ + (Message_queue_Control *) \ + _Objects_Allocate( &_Message_queue_Information ) + +/*PAGE + * + * _Message_queue_Free + * + */ + +#define _Message_queue_Free( _the_message_queue ) \ + _Objects_Free( &_Message_queue_Information, \ + &(_the_message_queue)->Object ) + +/*PAGE + * + * _Message_queue_Get + * + */ + +#define _Message_queue_Get( _id, _location ) \ + (Message_queue_Control *) \ + _Objects_Get( &_Message_queue_Information, (_id), (_location) ) + +#endif +/* end of include file */ diff --git a/cpukit/rtems/macros/rtems/rtems/modes.inl b/cpukit/rtems/macros/rtems/rtems/modes.inl new file mode 100644 index 0000000000..f8ac061dce --- /dev/null +++ b/cpukit/rtems/macros/rtems/rtems/modes.inl @@ -0,0 +1,101 @@ +/* modes.inl + * + * This include file contains the macro implementation of the + * inlined routines in the Mode Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MODES_inl +#define __MODES_inl + +/*PAGE + * + * RTEMS_INTERRUPT_LEVEL + */ + +#define RTEMS_INTERRUPT_LEVEL( _mode_set ) \ + ( (_mode_set) & RTEMS_INTERRUPT_MASK ) + +/*PAGE + * + * _Modes_Mask_changed + * + */ + +#define _Modes_Mask_changed( _mode_set, _masks ) \ + ( (_mode_set) & (_masks) ) + +/*PAGE + * + * _Modes_Is_asr_disabled + * + */ + +#define _Modes_Is_asr_disabled( _mode_set ) \ + ( (_mode_set) & RTEMS_ASR_MASK ) + +/*PAGE + * + * _Modes_Is_preempt + * + */ + +#define _Modes_Is_preempt( _mode_set ) \ + ( ( (_mode_set) & RTEMS_PREEMPT_MASK ) == RTEMS_PREEMPT ) + +/*PAGE + * + * _Modes_Is_timeslice + * + */ + +#define _Modes_Is_timeslice( _mode_set ) \ + (((_mode_set) & (RTEMS_TIMESLICE_MASK|RTEMS_PREEMPT_MASK)) == \ + (RTEMS_TIMESLICE|RTEMS_PREEMPT) ) + +/*PAGE + * + * _Modes_Get_interrupt_level + * + */ + +#define _Modes_Get_interrupt_level( _mode_set ) \ + ( (_mode_set) & RTEMS_INTERRUPT_MASK ) + +/*PAGE + * + * _Modes_Set_interrupt_level + * + */ + +#define _Modes_Set_interrupt_level( _mode_set ) \ + _ISR_Set_level( _Modes_Get_interrupt_level( (_mode_set) ) ) + +/*PAGE + * + * _Modes_Change + * + */ + +#define _Modes_Change( _old_mode_set, _new_mode_set, \ + _mask, _out_mode_set, _changed ) \ + { rtems_mode _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; \ + } + +#endif +/* end of include file */ diff --git a/cpukit/rtems/macros/rtems/rtems/options.inl b/cpukit/rtems/macros/rtems/rtems/options.inl new file mode 100644 index 0000000000..7c14e4fe4f --- /dev/null +++ b/cpukit/rtems/macros/rtems/rtems/options.inl @@ -0,0 +1,39 @@ +/* options.inl + * + * This file contains the macro implementation of the inlined + * routines from the Options Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __OPTIONS_inl +#define __OPTIONS_inl + +/*PAGE + * + * _Options_Is_no_wait + * + */ + +#define _Options_Is_no_wait( _option_set ) \ + ( (_option_set) & RTEMS_NO_WAIT ) + +/*PAGE + * + * _Options_Is_any + * + */ + +#define _Options_Is_any( _option_set ) \ + ( (_option_set) & RTEMS_EVENT_ANY ) + +#endif +/* end of include file */ diff --git a/cpukit/rtems/macros/rtems/rtems/part.inl b/cpukit/rtems/macros/rtems/rtems/part.inl new file mode 100644 index 0000000000..55c188b210 --- /dev/null +++ b/cpukit/rtems/macros/rtems/rtems/part.inl @@ -0,0 +1,117 @@ +/* part.inl + * + * This file contains the macro implementation of all inlined routines + * in the Partition Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __PARTITION_inl +#define __PARTITION_inl + +/*PAGE + * + * _Partition_Allocate_buffer + * + */ + +#define _Partition_Allocate_buffer( _the_partition ) \ + _Chain_Get( &(_the_partition)->Memory ) + +/*PAGE + * + * _Partition_Free_buffer + * + */ + +#define _Partition_Free_buffer( _the_partition, _the_buffer ) \ + _Chain_Append( &(_the_partition)->Memory, (_the_buffer) ) + +/*PAGE + * + * _Partition_Is_buffer_on_boundary + * + */ + +#define _Partition_Is_buffer_on_boundary( _the_buffer, _the_partition ) \ + ((((unsigned32) _Addresses_Subtract( \ + (_the_buffer), \ + (_the_partition)->starting_address ) \ + ) % \ + (_the_partition)->buffer_size) == 0) + +/*PAGE + * + * _Partition_Is_buffer_valid + * + */ + +#define _Partition_Is_buffer_valid( _the_buffer, _the_partition ) \ + ( \ + _Addresses_Is_in_range( \ + (_the_buffer), \ + (_the_partition)->starting_address, \ + _Addresses_Add_offset( \ + (_the_partition)->starting_address, \ + (_the_partition)->length \ + ) \ + ) && \ + _Partition_Is_buffer_on_boundary( (_the_buffer), (_the_partition) ) \ + ) + +/*PAGE + * + * _Partition_Is_buffer_size_aligned + * + */ + +#define _Partition_Is_buffer_size_aligned( _buffer_size ) \ + ((_buffer_size) % CPU_PARTITION_ALIGNMENT == 0) + +/*PAGE + * + * _Partition_Allocate + * + */ + +#define _Partition_Allocate() \ + (Partition_Control *) _Objects_Allocate( &_Partition_Information ) + +/*PAGE + * + * _Partition_Free + * + */ + +#define _Partition_Free( _the_partition ) \ + _Objects_Free( &_Partition_Information, &(_the_partition)->Object ) + +/*PAGE + * + * _Partition_Get + * + */ + +#define _Partition_Get( _id, _location ) \ + (Partition_Control *) \ + _Objects_Get( &_Partition_Information, (_id), (_location) ) + +/*PAGE + * + * _Partition_Is_null + * + */ + +#define _Partition_Is_null( _the_partition ) \ + ( (_the_partition) == NULL ) + +#endif +/* end of include file */ diff --git a/cpukit/rtems/macros/rtems/rtems/ratemon.inl b/cpukit/rtems/macros/rtems/rtems/ratemon.inl new file mode 100644 index 0000000000..ebb182e6f1 --- /dev/null +++ b/cpukit/rtems/macros/rtems/rtems/ratemon.inl @@ -0,0 +1,85 @@ +/* ratemon.inl + * + * This file contains the macro implementation of the inlined + * routines in the Rate Monotonic Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RATE_MONOTONIC_inl +#define __RATE_MONOTONIC_inl + +/*PAGE + * + * _Rate_monotonic_Allocate + * + */ + +#define _Rate_monotonic_Allocate() \ + (Rate_monotonic_Control *) \ + _Objects_Allocate( &_Rate_monotonic_Information ) + +/*PAGE + * + * _Rate_monotonic_Free + * + */ + +#define _Rate_monotonic_Free( _the_period ) \ + _Objects_Free( &_Rate_monotonic_Information, &(_the_period)->Object ) + +/*PAGE + * + * _Rate_monotonic_Get + * + */ + +#define _Rate_monotonic_Get( _id, _location ) \ + (Rate_monotonic_Control *) \ + _Objects_Get( &_Rate_monotonic_Information, (_id), (_location) ) + +/*PAGE + * + * _Rate_monotonic_Is_active + * + */ + +#define _Rate_monotonic_Is_active( _the_period ) \ + ((_the_period)->state == RATE_MONOTONIC_ACTIVE) + +/*PAGE + * + * _Rate_monotonic_Is_inactive + * + */ + +#define _Rate_monotonic_Is_inactive( _the_period ) \ + ((_the_period)->state == RATE_MONOTONIC_INACTIVE) + +/*PAGE + * + * _Rate_monotonic_Is_expired + * + */ + +#define _Rate_monotonic_Is_expired( _the_period ) \ + ((_the_period)->state == RATE_MONOTONIC_EXPIRED) + +/*PAGE + * + * _Rate_monotonic_Is_null + * + */ + +#define _Rate_monotonic_Is_null( _the_period ) ( (_the_period) == NULL ) + +#endif +/* end of include file */ diff --git a/cpukit/rtems/macros/rtems/rtems/region.inl b/cpukit/rtems/macros/rtems/rtems/region.inl new file mode 100644 index 0000000000..667d77e307 --- /dev/null +++ b/cpukit/rtems/macros/rtems/rtems/region.inl @@ -0,0 +1,75 @@ +/* region.inl + * + * This file contains the macro implementation of the inlined + * routines from the Region Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __REGION_inl +#define __REGION_inl + +/*PAGE + * + * _Region_Allocate + * + */ + +#define _Region_Allocate() \ + (Region_Control *) _Objects_Allocate( &_Region_Information ) + +/*PAGE + * + * _Region_Free + * + */ + +#define _Region_Free( _the_region ) \ + _Objects_Free( &_Region_Information, &(_the_region)->Object ) + +/*PAGE + * + * _Region_Get + * + */ + +#define _Region_Get( _id, _location ) \ + (Region_Control *) \ + _Objects_Get( &_Region_Information, (_id), (_location) ) + +/*PAGE + * + * _Region_Allocate_segment + * + */ + +#define _Region_Allocate_segment( _the_region, _size ) \ + _Heap_Allocate( &(_the_region)->Memory, (_size) ) + +/*PAGE + * + * _Region_Free_segment + * + */ + +#define _Region_Free_segment( _the_region, _the_segment ) \ + _Heap_Free( &(_the_region)->Memory, (_the_segment) ) + +/*PAGE + * + * _Region_Is_null + * + */ + +#define _Region_Is_null( _the_region ) ( (_the_region) == NULL ) + +#endif +/* end of include file */ diff --git a/cpukit/rtems/macros/rtems/rtems/sem.inl b/cpukit/rtems/macros/rtems/rtems/sem.inl new file mode 100644 index 0000000000..7e94069009 --- /dev/null +++ b/cpukit/rtems/macros/rtems/rtems/sem.inl @@ -0,0 +1,58 @@ +/* sem.inl + * + * This file contains the macro implementation of the inlined + * routines from the Semaphore Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __SEMAPHORE_inl +#define __SEMAPHORE_inl + +/*PAGE + * + * _Semaphore_Allocate + * + */ + +#define _Semaphore_Allocate() \ + (Semaphore_Control *) _Objects_Allocate( &_Semaphore_Information ) + +/*PAGE + * + * _Semaphore_Free + * + */ + +#define _Semaphore_Free( _the_semaphore ) \ + _Objects_Free( &_Semaphore_Information, &(_the_semaphore)->Object ) + +/*PAGE + * + * _Semaphore_Get + * + */ + +#define _Semaphore_Get( _id, _location ) \ + (Semaphore_Control *) \ + _Objects_Get( &_Semaphore_Information, (_id), (_location) ) + +/*PAGE + * + * _Semaphore_Is_null + * + */ + +#define _Semaphore_Is_null( _the_semaphore ) \ + ( (_the_semaphore) == NULL ) + +#endif +/* end of include file */ diff --git a/cpukit/rtems/macros/rtems/rtems/status.inl b/cpukit/rtems/macros/rtems/rtems/status.inl new file mode 100644 index 0000000000..c4f8a523df --- /dev/null +++ b/cpukit/rtems/macros/rtems/rtems/status.inl @@ -0,0 +1,47 @@ +/* macros/status.h + * + * This include file contains the implementations of the inlined + * routines for the status package. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MACROS_STATUS_h +#define __MACROS_STATUS_h + +/*PAGE + * + * rtems_is_status_successful + * + */ + +#define rtems_is_status_successful( _code ) \ + ( (_code) == RTEMS_SUCCESSFUL ) + +/*PAGE + * + * rtems_are_statuses_equal + * + */ + +#define rtems_are_statuses_equal( _code1, _code2 ) \ + ((_code1) == (_code2)) + +/* + * _Status_Is_proxy_blocking + * + */ + +#define _Status_Is_proxy_blocking( _code ) \ + ( (_code) == RTEMS_PROXY_BLOCKING ) + +#endif +/* end of include file */ diff --git a/cpukit/rtems/macros/rtems/rtems/tasks.inl b/cpukit/rtems/macros/rtems/rtems/tasks.inl new file mode 100644 index 0000000000..7b40cbf7fd --- /dev/null +++ b/cpukit/rtems/macros/rtems/rtems/tasks.inl @@ -0,0 +1,82 @@ +/* tasks.inl + * + * This file contains the macro implementation of all inlined + * routines in the with RTEMS Tasks Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_TASKS_inl +#define __RTEMS_TASKS_inl + +/*PAGE + * + * _RTEMS_tasks_Allocate + * + */ + +#define _RTEMS_tasks_Allocate() \ + (Thread_Control *) _Objects_Allocate( &_Thread_Information ) + +/*PAGE + * + * _RTEMS_tasks_Free + * + */ + +#define _RTEMS_tasks_Free( _the_task ) \ + _Objects_Free( &_Thread_Information, &(_the_task)->Object ) + +/*PAGE + * + * _RTEMS_tasks_Cancel_wait + * + */ + +#define _RTEMS_tasks_Cancel_wait( _the_thread ) \ + { \ + States_Control _state; \ + States_Control _remote_state; \ + \ + _state = (_the_thread)->current_state; \ + \ + if ( _States_Is_waiting_on_thread_queue( _state ) ) { \ + if ( _States_Is_waiting_for_rpc_reply( _state ) && \ + _States_Is_locally_blocked( _state ) ) { \ + _remote_state = _States_Clear( \ + STATES_WAITING_FOR_RPC_REPLY + STATES_TRANSIENT, \ + _state \ + ); \ + \ + switch ( _remote_state ) { \ + \ + case STATES_WAITING_FOR_BUFFER: \ + _Partition_MP_Send_extract_proxy( (_the_thread) ); \ + break; \ + case STATES_WAITING_FOR_SEGMENT: \ + _Region_MP_Send_extract_proxy( (_the_thread) ); \ + break; \ + case STATES_WAITING_FOR_SEMAPHORE: \ + _Semaphore_MP_Send_extract_proxy( (_the_thread) ); \ + break; \ + case STATES_WAITING_FOR_MESSAGE: \ + _Message_queue_MP_Send_extract_proxy( (_the_thread) ); \ + break; \ + } \ + } \ + _Thread_queue_Extract( (_the_thread)->Wait.queue, (_the_thread) ); \ + } \ + else if ( _Watchdog_Is_active( &(_the_thread)->Timer ) ) \ + (void) _Watchdog_Remove( &(_the_thread)->Timer ); \ + } + +#endif +/* end of include file */ diff --git a/cpukit/rtems/macros/rtems/rtems/timer.inl b/cpukit/rtems/macros/rtems/rtems/timer.inl new file mode 100644 index 0000000000..9026bed570 --- /dev/null +++ b/cpukit/rtems/macros/rtems/rtems/timer.inl @@ -0,0 +1,85 @@ +/* timer.inl + * + * This file contains the macro implementation of the inlined routines + * from the Timer Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __TIMER_inl +#define __TIMER_inl + +/*PAGE + * + * _Timer_Allocate + * + */ + +#define _Timer_Allocate() \ + (Timer_Control *) _Objects_Allocate( &_Timer_Information ) + +/*PAGE + * + * _Timer_Free + * + */ + +#define _Timer_Free( _the_timer ) \ + _Objects_Free( &_Timer_Information, &(_the_timer)->Object ) + +/*PAGE + * + * _Timer_Get + * + */ + +#define _Timer_Get( _id, _location ) \ + (Timer_Control *) \ + _Objects_Get( &_Timer_Information, (_id), (_location) ) + +/*PAGE + * + * _Timer_Is_interval_class + * + */ + +#define _Timer_Is_interval_class( _the_class ) \ + ( (_the_class) == TIMER_INTERVAL ) + +/*PAGE + * + * _Timer_Is_time_of_day_class + * + */ + +#define _Timer_Is_time_of_day_class( _the_class ) \ + ( (_the_class) == TIMER_TIME_OF_DAY ) + +/*PAGE + * + * _Timer_Is_dormant_class + * + */ + +#define _Timer_Is_dormant_class( _the_class ) \ + ( (_the_class) == TIMER_DORMANT ) + +/*PAGE + * + * _Timer_Is_null + * + */ + +#define _Timer_Is_null( _the_timer ) \ + ( (_the_timer) == NULL ) + +#endif +/* end of include file */ diff --git a/cpukit/rtems/src/dpmem.c b/cpukit/rtems/src/dpmem.c new file mode 100644 index 0000000000..0aacecec5b --- /dev/null +++ b/cpukit/rtems/src/dpmem.c @@ -0,0 +1,268 @@ +/* + * Dual Port Memory Manager + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include + +/*PAGE + * + * _Dual_ported_memory_Manager_initialization + * + * This routine initializes all dual-ported memory manager related + * data structures. + * + * Input parameters: + * maximum_ports - number of ports to initialize + * + * Output parameters: NONE + */ + +void _Dual_ported_memory_Manager_initialization( + unsigned32 maximum_ports +) +{ + _Objects_Initialize_information( + &_Dual_ported_memory_Information, + FALSE, + maximum_ports, + sizeof( Dual_ported_memory_Control ) + ); +} + +/*PAGE + * + * rtems_port_create + * + * This directive creates a port into a dual-ported memory area. + * + * Input parameters: + * name - user defined port name + * internal_start - internal start address of port + * external_start - external start address of port + * length - physical length in bytes + * id - address of port id to set + * + * Output parameters: + * id - port id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_port_create( + Objects_Name name, + void *internal_start, + void *external_start, + unsigned32 length, + Objects_Id *id +) +{ + register Dual_ported_memory_Control *the_port; + + if ( !_Objects_Is_name_valid( name) ) + return ( RTEMS_INVALID_NAME ); + + if ( !_Addresses_Is_aligned( internal_start ) || + !_Addresses_Is_aligned( external_start ) ) + return( RTEMS_INVALID_ADDRESS ); + + _Thread_Disable_dispatch(); /* to prevent deletion */ + + the_port = _Dual_ported_memory_Allocate(); + + if ( !the_port ) { + _Thread_Enable_dispatch(); + return( RTEMS_TOO_MANY ); + } + + the_port->internal_base = internal_start; + the_port->external_base = external_start; + the_port->length = length - 1; + + _Objects_Open( &_Dual_ported_memory_Information, + &the_port->Object, name ); + *id = the_port->Object.id; + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); +} + +/*PAGE + * + * rtems_port_ident + * + * This directive returns the system ID associated with + * the port name. + * + * Input parameters: + * name - user defined port name + * id - pointer to port id + * + * Output parameters: + * *id - port id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_port_ident( + Objects_Name name, + Objects_Id *id +) +{ + return( + _Objects_Name_to_id( + &_Dual_ported_memory_Information, + name, + RTEMS_SEARCH_ALL_NODES, + id + ) + ); +} + +/*PAGE + * + * rtems_port_delete + * + * This directive allows a thread to delete a dual-ported memory area + * specified by the dual-ported memory identifier. + * + * Input parameters: + * id - dual-ported memory area id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_port_delete( + Objects_Id id +) +{ + register Dual_ported_memory_Control *the_port; + Objects_Locations location; + + the_port = _Dual_ported_memory_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: /* this error cannot be returned */ + return( RTEMS_INTERNAL_ERROR ); + case OBJECTS_LOCAL: + _Objects_Close( &_Dual_ported_memory_Information, &the_port->Object ); + _Dual_ported_memory_Free( the_port ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_port_internal_to_external + * + * This directive converts an internal dual-ported memory address to an + * external dual-ported memory address. If the given internal address + * is an invalid dual-ported address, then the external address is set + * to the given internal address. + * + * Input parameters: + * id - id of dual-ported memory object + * internal - internal address to set + * external - pointer to external address + * + * Output parameters: + * external - external address + * RTEMS_SUCCESSFUL - always succeeds + */ + +rtems_status_code rtems_port_internal_to_external( + Objects_Id id, + void *internal, + void **external +) +{ + register Dual_ported_memory_Control *the_port; + Objects_Locations location; + unsigned32 ending; + + the_port = _Dual_ported_memory_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: /* this error cannot be returned */ + return( RTEMS_INTERNAL_ERROR ); + case OBJECTS_LOCAL: + ending = _Addresses_Subtract( internal, the_port->internal_base ); + if ( ending > the_port->length ) + *external = internal; + else + *external = _Addresses_Add_offset( the_port->external_base, + ending ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_port_external_to_internal + * + * This directive converts an external dual-ported memory address to an + * internal dual-ported memory address. If the given external address + * is an invalid dual-ported address, then the internal address is set + * to the given external address. + * + * Input parameters: + * id - id of dp memory object + * external - external address + * internal - pointer of internal address to set + * + * Output parameters: + * internal - internal address + * RTEMS_SUCCESSFUL - always succeeds + */ + +rtems_status_code rtems_port_external_to_internal( + Objects_Id id, + void *external, + void **internal +) +{ + register Dual_ported_memory_Control *the_port; + Objects_Locations location; + unsigned32 ending; + + the_port = _Dual_ported_memory_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: /* this error cannot be returned */ + return( RTEMS_INTERNAL_ERROR ); + case OBJECTS_LOCAL: + ending = _Addresses_Subtract( external, the_port->external_base ); + if ( ending > the_port->length ) + *internal = external; + else + *internal = _Addresses_Add_offset( the_port->internal_base, + ending ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/event.c b/cpukit/rtems/src/event.c new file mode 100644 index 0000000000..6a25ae81c3 --- /dev/null +++ b/cpukit/rtems/src/event.c @@ -0,0 +1,294 @@ +/* + * Event Manager + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_event_send + * + * This directive allows a thread send an event set to another thread. + * + * Input parameters: + * id - thread id + * event - event set + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_event_send( + Objects_Id id, + rtems_event_set event_in +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + return( + _Event_MP_Send_request_packet( + EVENT_MP_SEND_REQUEST, + id, + event_in + ) + ); + case OBJECTS_LOCAL: + _Event_sets_Post( event_in, &the_thread->pending_events ); + _Event_Surrender( the_thread ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_event_receive + * + * This directive allows a thread to receive a set of events. + * + * Input parameters: + * event_in - input event condition + * option_set - options + * ticks - number of ticks to wait (0 means wait forever) + * event_out - pointer to output event set + * + * Output parameters: + * event out - event set + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_event_receive( + rtems_event_set event_in, + rtems_option option_set, + rtems_interval ticks, + rtems_event_set *event_out +) +{ + if ( _Event_sets_Is_empty( event_in ) ) { + *event_out = _Thread_Executing->pending_events; + return( RTEMS_SUCCESSFUL ); + } + + _Thread_Disable_dispatch(); + _Event_Seize( event_in, option_set, ticks ); + _Thread_Enable_dispatch(); + *event_out = _Thread_Executing->events_out; + return( _Thread_Executing->Wait.return_code ); +} + +/*PAGE + * + * _Event_Seize + * + * This routine attempts to satisfy the requested event condition + * for the running thread. + * + * Input parameters: + * event_in - the event condition to satisfy + * option_set - acquire event options + * ticks - interval to wait + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * available + * wait + * check sync + */ + +void _Event_Seize( + rtems_event_set event_in, + rtems_option option_set, + rtems_interval ticks +) +{ + Thread_Control *executing; + rtems_event_set seized_events; + rtems_event_set pending_events; + ISR_Level level; + + executing = _Thread_Executing; + executing->Wait.return_code = RTEMS_SUCCESSFUL; + + _ISR_Disable( level ); + pending_events = executing->pending_events; + seized_events = _Event_sets_Get( pending_events, event_in ); + + if ( !_Event_sets_Is_empty( seized_events ) && + (seized_events == event_in || _Options_Is_any( option_set )) ) { + executing->pending_events = + _Event_sets_Clear( pending_events, seized_events ); + _ISR_Enable( level ); + executing->events_out = seized_events; + return; + } + + if ( _Options_Is_no_wait( option_set ) ) { + _ISR_Enable( level ); + executing->Wait.return_code = RTEMS_UNSATISFIED; + executing->events_out = seized_events; + return; + } + + _Event_Sync = TRUE; + executing->Wait.option_set = option_set; + executing->Wait.Extra.event_condition = event_in; + + _ISR_Enable( level ); + _Thread_Set_state( executing, STATES_WAITING_FOR_EVENT ); + + if ( ticks ) { + _Watchdog_Initialize( + &executing->Timer, + _Event_Timeout, + executing->Object.id, + NULL + ); + _Watchdog_Insert_ticks( + &executing->Timer, + ticks, + WATCHDOG_NO_ACTIVATE + ); + } + + _ISR_Disable( level ); + if ( _Event_Sync == TRUE ) { + _Event_Sync = FALSE; + if ( ticks ) + _Watchdog_Activate( &executing->Timer ); + _ISR_Enable( level ); + return; + } + _ISR_Enable( level ); + (void) _Watchdog_Remove( &executing->Timer ); + _Thread_Unblock( executing ); + return; +} + +/*PAGE + * + * _Event_Surrender + * + * This routines remove a thread from the specified threadq. + * + * Input parameters: + * the_thread - pointer to thread to be dequeued + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * before flash + * after flash + * check sync + */ + +void _Event_Surrender( + Thread_Control *the_thread +) +{ + ISR_Level level; + rtems_event_set pending_events; + rtems_event_set event_condition; + rtems_event_set seized_events; + + _ISR_Disable( level ); + pending_events = the_thread->pending_events; + event_condition = the_thread->Wait.Extra.event_condition; + + seized_events = _Event_sets_Get( pending_events, event_condition ); + + if ( !_Event_sets_Is_empty( seized_events ) ) { + if ( _States_Is_waiting_for_event( the_thread->current_state ) ) { + if ( seized_events == event_condition || + _Options_Is_any( the_thread->Wait.option_set ) ) { + the_thread->pending_events = + _Event_sets_Clear( pending_events, seized_events ); + (rtems_event_set *)the_thread->events_out = seized_events; + + _ISR_Flash( level ); + + if ( !_Watchdog_Is_active( &the_thread->Timer ) ) { + _ISR_Enable( level ); + _Thread_Unblock( the_thread ); + } + else { + _Watchdog_Deactivate( &the_thread->Timer ); + _ISR_Enable( level ); + (void) _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + } + return; + } + } + else if ( _Thread_Is_executing( the_thread ) && _Event_Sync == TRUE ) { + if ( seized_events == event_condition || + _Options_Is_any( the_thread->Wait.option_set ) ) { + the_thread->pending_events = + _Event_sets_Clear( pending_events,seized_events ); + (rtems_event_set *)the_thread->events_out = seized_events; + _Event_Sync = FALSE; + } + } + } + _ISR_Enable( level ); +} + +/*PAGE + * + * _Event_Timeout + * + * This routine processes a thread which timeouts while waiting to + * receive an event_set. It is called by the watchdog handler. + * + * Input parameters: + * id - thread id + * + * Output parameters: NONE + */ + +void _Event_Timeout( + Objects_Id id, + void *ignored +) +{ + Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + case OBJECTS_REMOTE: /* impossible */ + break; + case OBJECTS_LOCAL: + the_thread->Wait.return_code = RTEMS_TIMEOUT; + _Thread_Unblock( the_thread ); + _Thread_Unnest_dispatch(); + break; + } +} diff --git a/cpukit/rtems/src/eventmp.c b/cpukit/rtems/src/eventmp.c new file mode 100644 index 0000000000..4bc5925c2a --- /dev/null +++ b/cpukit/rtems/src/eventmp.c @@ -0,0 +1,188 @@ +/* + * Multiprocessing Support for the Event Manager + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Event_MP_Send_process_packet + * + * This subprogram is not needed since there are no process + * packets to be sent by this manager. + * + */ + +/*PAGE + * + * _Event_MP_Send_request_packet + * + */ + +rtems_status_code _Event_MP_Send_request_packet ( + Event_MP_Remote_operations operation, + Objects_Id event_id, + rtems_event_set event_in +) +{ + Event_MP_Packet *the_packet; + + switch ( operation ) { + + case EVENT_MP_SEND_REQUEST: + + the_packet = _Event_MP_Get_packet(); + the_packet->Prefix.the_class = RTEMS_MP_PACKET_EVENT; + the_packet->Prefix.length = sizeof ( Event_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Event_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = event_id; + the_packet->event_in = event_in; + + return + _MPCI_Send_request_packet( + rtems_get_node( event_id ), + &the_packet->Prefix, + STATES_READY + ); + + break; + + case EVENT_MP_SEND_RESPONSE: + break; + + } + /* + * The following line is included to satisfy compilers which + * produce warnings when a function does not end with a return. + */ + return RTEMS_SUCCESSFUL; +} + +/*PAGE + * + * _Event_MP_Send_response_packet + * + */ + +void _Event_MP_Send_response_packet ( + Event_MP_Remote_operations operation, + Thread_Control *the_thread +) +{ + Event_MP_Packet *the_packet; + + switch ( operation ) { + + case EVENT_MP_SEND_RESPONSE: + + the_packet = ( Event_MP_Packet *) the_thread->receive_packet; + +/* + * The packet being returned already contains the class, length, and + * to_convert fields, therefore they are not set in this routine. + */ + the_packet->operation = operation; + the_packet->Prefix.id = the_packet->Prefix.source_tid; + + _MPCI_Send_response_packet( + rtems_get_node( the_packet->Prefix.source_tid ), + &the_packet->Prefix + ); + break; + + case EVENT_MP_SEND_REQUEST: + break; + + } +} + +/*PAGE + * + * + * _Event_MP_Process_packet + * + */ + +void _Event_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +) +{ + Event_MP_Packet *the_packet; + Thread_Control *the_thread; + + the_packet = (Event_MP_Packet *) the_packet_prefix; + + switch ( the_packet->operation ) { + + case EVENT_MP_SEND_REQUEST: + + the_packet->Prefix.return_code = rtems_event_send( + the_packet->Prefix.id, + the_packet->event_in + ); + + _Event_MP_Send_response_packet( + EVENT_MP_SEND_RESPONSE, + _Thread_Executing + ); + break; + + case EVENT_MP_SEND_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + _MPCI_Return_packet( the_packet_prefix ); + + break; + + } +} + +/*PAGE + * + * _Event_MP_Send_object_was_deleted + * + * This subprogram is not needed since there are no objects + * deleted by this manager. + * + */ + +/*PAGE + * + * _Event_MP_Send_extract_proxy + * + * This subprogram is not needed since there are no objects + * deleted by this manager. + * + */ + +/*PAGE + * + * _Event_MP_Get_packet + * + */ + +Event_MP_Packet *_Event_MP_Get_packet ( void ) +{ + return ( (Event_MP_Packet *) _MPCI_Get_packet() ); +} + +/* end of file */ diff --git a/cpukit/rtems/src/intr.c b/cpukit/rtems/src/intr.c new file mode 100644 index 0000000000..25f5176967 --- /dev/null +++ b/cpukit/rtems/src/intr.c @@ -0,0 +1,85 @@ +/* + * Interrupt Manager + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include + +/* _Interrupt_Manager_initialization + * + * This routine initializes the interrupt manager. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _Interrupt_Manager_initialization( void ) +{ +#if ( CPU_ALLOCATE_INTERRUPT_STACK == TRUE ) + + if ( _CPU_Table.interrupt_stack_size < RTEMS_MINIMUM_STACK_SIZE ) + rtems_fatal_error_occurred( RTEMS_INVALID_SIZE ); + + _CPU_Interrupt_stack_low = + _Workspace_Allocate_or_fatal_error( _CPU_Table.interrupt_stack_size ); + + _CPU_Interrupt_stack_high = _Addresses_Add_offset( + _CPU_Interrupt_stack_low, + _CPU_Table.interrupt_stack_size + ); + +#endif + +#if ( CPU_HAS_HARDWARE_INTERRUPT_STACK == TRUE ) + _CPU_Install_interrupt_stack(); +#endif + +} + +/* rtems_interrupt_catch + * + * This directive allows a thread to specify what action to take when + * catching signals. + * + * Input parameters: + * new_isr_handler - address of interrupt service routine (isr) + * vector - interrupt vector number + * old_isr_handler - address at which to store previous ISR address + * + * Output parameters: + * RTEMS_SUCCESSFUL - always succeeds + * *old_isr_handler - 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 +) +{ + if ( !_ISR_Is_vector_number_valid( vector ) ) + return( RTEMS_INVALID_NUMBER ); + + if ( !_ISR_Is_valid_user_handler( new_isr_handler ) ) + return( RTEMS_INVALID_ADDRESS ); + + _ISR_Install_vector( + vector, (proc_ptr)new_isr_handler, (proc_ptr *)old_isr_handler ); + + return( RTEMS_SUCCESSFUL ); +} diff --git a/cpukit/rtems/src/mp.c b/cpukit/rtems/src/mp.c new file mode 100644 index 0000000000..f9522b2296 --- /dev/null +++ b/cpukit/rtems/src/mp.c @@ -0,0 +1,128 @@ +/* + * Multiprocessing Manager + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Multiprocessing_Manager_initialization + * + */ + +void _Multiprocessing_Manager_initialization ( void ) +{ + if ( _Configuration_MP_table->node < 1 || + _Configuration_MP_table->node > _Configuration_MP_table->maximum_nodes ) + rtems_fatal_error_occurred( RTEMS_INVALID_NODE ); + + _Internal_threads_Set_MP_receive_server( _Multiprocessing_Receive_server ); +} + +/*PAGE + * + * rtems_multiprocessing_announce + * + */ + +void rtems_multiprocessing_announce ( void ) +{ + _Thread_MP_Ready(); +} + +/*PAGE + * + * _Multiprocessing_Receive_server + * + */ + +Thread _Multiprocessing_Receive_server ( + Thread_Argument ignored +) +{ + + rtems_packet_prefix *the_packet; + + _Thread_Dispatch_disable_level = 1; + + for ( ; ; ) { + + _Internal_threads_System_initialization_thread->Notepads[ 0 ] = 1; + + the_packet = _MPCI_Receive_packet(); + + if ( ! the_packet ) { + _Thread_MP_Block(); + _Thread_Dispatch_disable_level = 1; + } + else { + + _Thread_Executing->receive_packet = the_packet; + + switch ( the_packet->the_class ) { + + case RTEMS_MP_PACKET_INTERNAL_THREADS: + _Internal_threads_MP_Process_packet( the_packet ); + break; + + case RTEMS_MP_PACKET_TASKS: + _RTEMS_tasks_MP_Process_packet( the_packet ); + break; + + case RTEMS_MP_PACKET_MESSAGE_QUEUE: + _Message_queue_MP_Process_packet( the_packet ); + break; + + case RTEMS_MP_PACKET_SEMAPHORE: + _Semaphore_MP_Process_packet( the_packet ); + break; + + case RTEMS_MP_PACKET_PARTITION: + _Partition_MP_Process_packet( the_packet ); + break; + + case RTEMS_MP_PACKET_REGION: + /* Global regions are unsupported at this time */ + break; + + case RTEMS_MP_PACKET_EVENT: + _Event_MP_Process_packet( the_packet ); + break; + + case RTEMS_MP_PACKET_SIGNAL: + _Signal_MP_Process_packet( the_packet ); + break; + } + } + } +} + +/* end of file */ diff --git a/cpukit/rtems/src/msg.c b/cpukit/rtems/src/msg.c new file mode 100644 index 0000000000..7cfe683ce5 --- /dev/null +++ b/cpukit/rtems/src/msg.c @@ -0,0 +1,708 @@ +/* + * Message Queue Manager + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Message_queue_Manager_initialization + * + * This routine initializes all message queue manager related + * data structures. + * + * Input parameters: + * maximum_message_queues - number of message queues to initialize + * maximum_message - number of messages per queue + * + * Output parameters: NONE + */ + +void _Message_queue_Manager_initialization( + unsigned32 maximum_message_queues, + unsigned32 maximum_messages +) +{ + + _Objects_Initialize_information( + &_Message_queue_Information, + TRUE, + maximum_message_queues, + sizeof( Message_queue_Control ) + ); + + if ( maximum_messages == 0 ) { + + _Chain_Initialize_empty( &_Message_queue_Inactive_messages ); + + } else { + + + _Chain_Initialize( + &_Message_queue_Inactive_messages, + _Workspace_Allocate_or_fatal_error( + maximum_messages * sizeof( Message_queue_Buffer_control ) + ), + maximum_messages, + sizeof( Message_queue_Buffer_control ) + ); + + } +} + +/*PAGE + * + * rtems_message_queue_create + * + * This directive creates a message queue by allocating and initializing + * a message queue data structure. + * + * Input parameters: + * name - user defined queue name + * count - maximum message and reserved buffer count + * attribute_set - process method + * id - pointer to queue + * + * Output parameters: + * id - queue id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_message_queue_create( + Objects_Name name, + unsigned32 count, + rtems_attribute attribute_set, + Objects_Id *id +) +{ + register Message_queue_Control *the_message_queue; + + if ( !_Objects_Is_name_valid( name ) ) + return ( RTEMS_INVALID_NAME ); + + if ( _Attributes_Is_global( attribute_set ) && + !_Configuration_Is_multiprocessing() ) + return( RTEMS_MP_NOT_CONFIGURED ); + + _Thread_Disable_dispatch(); /* protects object pointer */ + + the_message_queue = _Message_queue_Allocate(); + + if ( !the_message_queue ) { + _Thread_Enable_dispatch(); + return( RTEMS_TOO_MANY ); + } + + if ( _Attributes_Is_global( attribute_set ) && + !( _Objects_MP_Open( &_Message_queue_Information, name, + the_message_queue->Object.id, FALSE ) ) ) { + _Message_queue_Free( the_message_queue ); + _Thread_Enable_dispatch(); + return( RTEMS_TOO_MANY ); + } + + if ( _Attributes_Is_limit( attribute_set ) ) + the_message_queue->maximum_pending_messages = count; + else + the_message_queue->maximum_pending_messages = 0xffffffff; + + the_message_queue->attribute_set = attribute_set; + the_message_queue->number_of_pending_messages = 0; + + _Chain_Initialize_empty( &the_message_queue->Pending_messages ); + + _Thread_queue_Initialize( &the_message_queue->Wait_queue, attribute_set, + STATES_WAITING_FOR_MESSAGE ); + + _Objects_Open( &_Message_queue_Information, + &the_message_queue->Object, name ); + + *id = the_message_queue->Object.id; + + if ( _Attributes_Is_global( attribute_set ) ) + _Message_queue_MP_Send_process_packet( + MESSAGE_QUEUE_MP_ANNOUNCE_CREATE, + the_message_queue->Object.id, + name, + 0 + ); + + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); +} + +/*PAGE + * + * rtems_message_queue_ident + * + * This directive returns the system ID associated with + * the message queue name. + * + * Input parameters: + * name - user defined message queue name + * node - node(s) to be searched + * id - pointer to message queue id + * + * Output parameters: + * *id - message queue id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_message_queue_ident( + Objects_Name name, + unsigned32 node, + Objects_Id *id +) +{ + return( _Objects_Name_to_id( &_Message_queue_Information, name, + node, id ) ); +} + +/*PAGE + * + * rtems_message_queue_delete + * + * This directive allows a thread to delete the message queue specified + * by the given queue identifier. + * + * Input parameters: + * id - queue id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_message_queue_delete( + Objects_Id id +) +{ + register Message_queue_Control *the_message_queue; + Objects_Locations location; + + the_message_queue = _Message_queue_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + _Thread_Dispatch(); + return( RTEMS_ILLEGAL_ON_REMOTE_OBJECT ); + case OBJECTS_LOCAL: + _Objects_Close( &_Message_queue_Information, + &the_message_queue->Object ); + + if ( the_message_queue->number_of_pending_messages != 0 ) + (void) _Message_queue_Flush_support( the_message_queue ); + else + _Thread_queue_Flush( + &the_message_queue->Wait_queue, + _Message_queue_MP_Send_object_was_deleted + ); + + _Message_queue_Free( the_message_queue ); + + if ( _Attributes_Is_global( the_message_queue->attribute_set ) ) { + _Objects_MP_Close( + &_Message_queue_Information, + the_message_queue->Object.id + ); + + _Message_queue_MP_Send_process_packet( + MESSAGE_QUEUE_MP_ANNOUNCE_DELETE, + the_message_queue->Object.id, + 0, /* Not used */ + MPCI_DEFAULT_TIMEOUT + ); + } + + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_message_queue_send + * + * This routine implements the directives q_send. It sends a + * message to the specified message queue. + * + * Input parameters: + * id - pointer to message queue + * buffer - pointer to message buffer + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_message_queue_send( + Objects_Id id, + void *buffer +) +{ + return( _Message_queue_Submit( + id, + (Message_queue_Buffer *) buffer, + MESSAGE_QUEUE_SEND_REQUEST + ) + ); +} + +/*PAGE + * + * rtems_message_queue_urgent + * + * This routine implements the directives q_urgent. It urgents a + * message to the specified message queue. + * + * Input parameters: + * id - pointer to message queue + * buffer - pointer to message buffer + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_message_queue_urgent( + Objects_Id id, + void *buffer +) +{ + return( _Message_queue_Submit( + id, + (Message_queue_Buffer *) buffer, + MESSAGE_QUEUE_URGENT_REQUEST + ) + ); +} + +/*PAGE + * + * rtems_message_queue_broadcast + * + * This directive sends a message for every thread waiting on the queue + * designated by id. + * + * Input parameters: + * id - pointer to message queue + * buffer - pointer to message buffer + * count - pointer to area to store number of threads made ready + * + * Output parameters: + * count - number of threads made ready + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_message_queue_broadcast( + Objects_Id id, + void *buffer, + unsigned32 *count +) +{ + register Message_queue_Control *the_message_queue; + Objects_Locations location; + Thread_Control *the_thread; + unsigned32 number_broadcasted; + + the_message_queue = _Message_queue_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + _Thread_Executing->Wait.return_argument = count; + + return + _Message_queue_MP_Send_request_packet( + MESSAGE_QUEUE_MP_BROADCAST_REQUEST, + id, + (Message_queue_Buffer *) buffer, + 0, /* Not used */ + MPCI_DEFAULT_TIMEOUT + ); + + case OBJECTS_LOCAL: + number_broadcasted = 0; + while ( (the_thread = + _Thread_queue_Dequeue(&the_message_queue->Wait_queue)) ) { + number_broadcasted += 1; + _Message_queue_Copy_buffer( + (Message_queue_Buffer *) buffer, + the_thread->Wait.return_argument + ); + + if ( !_Objects_Is_local_id( the_thread->Object.id ) ) { + the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL; + + _Message_queue_MP_Send_response_packet( + MESSAGE_QUEUE_MP_RECEIVE_RESPONSE, + id, + the_thread + ); + } + } + _Thread_Enable_dispatch(); + *count = number_broadcasted; + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_message_queue_receive + * + * This directive dequeues a message from the designated message queue + * and copies it into the requesting thread's buffer. + * + * Input parameters: + * id - queue id + * buffer - pointer to message buffer + * option_set - options on receive + * timeout - number of ticks to wait + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_message_queue_receive( + Objects_Id id, + void *buffer, + unsigned32 option_set, + rtems_interval timeout +) +{ + register Message_queue_Control *the_message_queue; + Objects_Locations location; + + the_message_queue = _Message_queue_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + _Thread_Executing->Wait.return_argument = buffer; + return + _Message_queue_MP_Send_request_packet( + MESSAGE_QUEUE_MP_RECEIVE_REQUEST, + id, + buffer, + option_set, + timeout + ); + + case OBJECTS_LOCAL: + if ( !_Message_queue_Seize( the_message_queue, option_set, buffer ) ) + _Thread_queue_Enqueue( &the_message_queue->Wait_queue, timeout ); + _Thread_Enable_dispatch(); + return( _Thread_Executing->Wait.return_code ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_message_queue_flush + * + * This directive removes all pending messages from a queue and returns + * the number of messages removed. If no messages were present then + * a count of zero is returned. + * + * Input parameters: + * id - queue id + * count - return area for count + * + * Output parameters: + * count - number of messages removed ( 0 = empty queue ) + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_message_queue_flush( + Objects_Id id, + unsigned32 *count +) +{ + register Message_queue_Control *the_message_queue; + Objects_Locations location; + + the_message_queue = _Message_queue_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + _Thread_Executing->Wait.return_argument = count; + + return + _Message_queue_MP_Send_request_packet( + MESSAGE_QUEUE_MP_FLUSH_REQUEST, + id, + 0, /* Not used */ + 0, /* Not used */ + MPCI_DEFAULT_TIMEOUT + ); + + case OBJECTS_LOCAL: + if ( the_message_queue->number_of_pending_messages != 0 ) + *count = _Message_queue_Flush_support( the_message_queue ); + else + *count = 0; + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * _Message_queue_Seize + * + * 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. + * + * Input parameters: + * the_message_queue - pointer to message queue + * option_set - options on receive + * the_buffer - pointer to message buffer to be filled + * + * Output parameters: + * TRUE - if message received or RTEMS_NO_WAIT and no message + * FALSE - if thread is to block + * + * NOTE: Dependent on BUFFER_LENGTH + * + * INTERRUPT LATENCY: + * available + * wait + */ + +boolean _Message_queue_Seize( + Message_queue_Control *the_message_queue, + rtems_option option_set, + Message_queue_Buffer *buffer +) +{ + ISR_Level level; + Message_queue_Buffer_control *the_message; + Thread_Control *executing; + + executing = _Thread_Executing; + executing->Wait.return_code = RTEMS_SUCCESSFUL; + _ISR_Disable( level ); + if ( the_message_queue->number_of_pending_messages != 0 ) { + the_message_queue->number_of_pending_messages -= 1; + + the_message = _Message_queue_Get_pending_message( the_message_queue ); + _ISR_Enable( level ); + _Message_queue_Copy_buffer( &the_message->Contents, buffer ); + _Message_queue_Free_message_buffer( the_message ); + return( TRUE ); + } + + if ( _Options_Is_no_wait( option_set ) ) { + _ISR_Enable( level ); + executing->Wait.return_code = RTEMS_UNSATISFIED; + return( TRUE ); + } + + the_message_queue->Wait_queue.sync = TRUE; + executing->Wait.queue = &the_message_queue->Wait_queue; + executing->Wait.id = the_message_queue->Object.id; + executing->Wait.option_set = option_set; + executing->Wait.return_argument = (unsigned32 *)buffer; + _ISR_Enable( level ); + return( FALSE ); +} + +/*PAGE + * + * _Message_queue_Flush_support + * + * This message manager routine removes all messages from a message queue + * and returns them to the inactive message pool. + * + * Input parameters: + * the_message_queue - pointer to message queue + * + * Output parameters: + * returns - number of messages placed on inactive chain + * + * INTERRUPT LATENCY: + * only case + */ + +unsigned32 _Message_queue_Flush_support( + Message_queue_Control *the_message_queue +) +{ + ISR_Level level; + Chain_Node *inactive_first; + Chain_Node *message_queue_first; + Chain_Node *message_queue_last; + unsigned32 count; + + _ISR_Disable( level ); + inactive_first = _Message_queue_Inactive_messages.first; + message_queue_first = the_message_queue->Pending_messages.first; + message_queue_last = the_message_queue->Pending_messages.last; + + _Message_queue_Inactive_messages.first = message_queue_first; + message_queue_last->next = inactive_first; + inactive_first->previous = message_queue_last; + message_queue_first->previous = + _Chain_Head( &_Message_queue_Inactive_messages ); + + _Chain_Initialize_empty( &the_message_queue->Pending_messages ); + + count = the_message_queue->number_of_pending_messages; + the_message_queue->number_of_pending_messages = 0; + _ISR_Enable( level ); + return( count ); +} + +/*PAGE + * + * _Message_queue_Submit + * + * This routine implements the directives q_send and q_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. + * + * Input parameters: + * id - pointer to message queue + * the_buffer - pointer to message buffer + * submit_type - send or urgent message + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code _Message_queue_Submit( + Objects_Id id, + Message_queue_Buffer *buffer, + Message_queue_Submit_types submit_type +) +{ + register Message_queue_Control *the_message_queue; + Objects_Locations location; + Thread_Control *the_thread; + Message_queue_Buffer_control *the_message; + + the_message_queue = _Message_queue_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + switch ( submit_type ) { + case MESSAGE_QUEUE_SEND_REQUEST: + return + _Message_queue_MP_Send_request_packet( + MESSAGE_QUEUE_MP_SEND_REQUEST, + id, + buffer, + 0, /* Not used */ + MPCI_DEFAULT_TIMEOUT + ); + + case MESSAGE_QUEUE_URGENT_REQUEST: + return + _Message_queue_MP_Send_request_packet( + MESSAGE_QUEUE_MP_URGENT_REQUEST, + id, + buffer, + 0, /* Not used */ + MPCI_DEFAULT_TIMEOUT + ); + } + case OBJECTS_LOCAL: + the_thread = _Thread_queue_Dequeue( &the_message_queue->Wait_queue ); + + if ( the_thread ) { + + _Message_queue_Copy_buffer( + buffer, + the_thread->Wait.return_argument + ); + + if ( !_Objects_Is_local_id( the_thread->Object.id ) ) { + the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL; + + _Message_queue_MP_Send_response_packet( + MESSAGE_QUEUE_MP_RECEIVE_RESPONSE, + id, + the_thread + ); + + } + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + if ( the_message_queue->number_of_pending_messages == + the_message_queue->maximum_pending_messages ) { + _Thread_Enable_dispatch(); + return( RTEMS_TOO_MANY ); + } + + the_message = _Message_queue_Allocate_message_buffer(); + + if ( !the_message ) { + _Thread_Enable_dispatch(); + return( RTEMS_UNSATISFIED ); + } + + _Message_queue_Copy_buffer( buffer, &the_message->Contents ); + + the_message_queue->number_of_pending_messages += 1; + + switch ( submit_type ) { + case MESSAGE_QUEUE_SEND_REQUEST: + _Message_queue_Append( the_message_queue, the_message ); + break; + case MESSAGE_QUEUE_URGENT_REQUEST: + _Message_queue_Prepend( the_message_queue, the_message ); + break; + } + + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/msgmp.c b/cpukit/rtems/src/msgmp.c new file mode 100644 index 0000000000..d3a1a02f33 --- /dev/null +++ b/cpukit/rtems/src/msgmp.c @@ -0,0 +1,397 @@ +/* + * Multiprocessing Support for the Message Queue Manager + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Message_queue_MP_Send_process_packet + * + */ + +void _Message_queue_MP_Send_process_packet ( + Message_queue_MP_Remote_operations operation, + Objects_Id message_queue_id, + Objects_Name name, + Objects_Id proxy_id +) +{ + Message_queue_MP_Packet *the_packet; + unsigned32 node; + + switch ( operation ) { + + case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE: + case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE: + case MESSAGE_QUEUE_MP_EXTRACT_PROXY: + + the_packet = _Message_queue_MP_Get_packet(); + the_packet->Prefix.the_class = RTEMS_MP_PACKET_MESSAGE_QUEUE; + the_packet->Prefix.length = sizeof ( Message_queue_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Message_queue_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = message_queue_id; + the_packet->name = name; + the_packet->proxy_id = proxy_id; + + if ( operation == MESSAGE_QUEUE_MP_EXTRACT_PROXY ) + node = rtems_get_node( message_queue_id ); + else + node = MPCI_ALL_NODES; + + _MPCI_Send_process_packet( node, &the_packet->Prefix ); + break; + + case MESSAGE_QUEUE_MP_RECEIVE_REQUEST: + case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE: + case MESSAGE_QUEUE_MP_SEND_REQUEST: + case MESSAGE_QUEUE_MP_SEND_RESPONSE: + case MESSAGE_QUEUE_MP_URGENT_REQUEST: + case MESSAGE_QUEUE_MP_URGENT_RESPONSE: + case MESSAGE_QUEUE_MP_BROADCAST_REQUEST: + case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE: + case MESSAGE_QUEUE_MP_FLUSH_REQUEST: + case MESSAGE_QUEUE_MP_FLUSH_RESPONSE: + break; + + } +} + +/*PAGE + * + * _Message_queue_MP_Send_request_packet + * + */ + +rtems_status_code _Message_queue_MP_Send_request_packet ( + Message_queue_MP_Remote_operations operation, + Objects_Id message_queue_id, + Message_queue_Buffer *buffer, + rtems_option option_set, + rtems_interval timeout +) +{ + Message_queue_MP_Packet *the_packet; + + switch ( operation ) { + + case MESSAGE_QUEUE_MP_RECEIVE_REQUEST: + case MESSAGE_QUEUE_MP_SEND_REQUEST: + case MESSAGE_QUEUE_MP_URGENT_REQUEST: + case MESSAGE_QUEUE_MP_BROADCAST_REQUEST: + case MESSAGE_QUEUE_MP_FLUSH_REQUEST: + + the_packet = _Message_queue_MP_Get_packet(); + the_packet->Prefix.the_class = RTEMS_MP_PACKET_MESSAGE_QUEUE; + the_packet->Prefix.length = sizeof ( Message_queue_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Message_queue_MP_Packet ) - + sizeof ( Message_queue_Buffer ); + if ( ! _Options_Is_no_wait(option_set)) + the_packet->Prefix.timeout = timeout; + + the_packet->operation = operation; + the_packet->Prefix.id = message_queue_id; + the_packet->option_set = option_set; + + if ( buffer ) + _Message_queue_Copy_buffer( buffer, &the_packet->Buffer ); + + return + _MPCI_Send_request_packet( + rtems_get_node( message_queue_id ), + &the_packet->Prefix, + STATES_WAITING_FOR_MESSAGE + ); + break; + + case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE: + case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE: + case MESSAGE_QUEUE_MP_EXTRACT_PROXY: + case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE: + case MESSAGE_QUEUE_MP_SEND_RESPONSE: + case MESSAGE_QUEUE_MP_URGENT_RESPONSE: + case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE: + case MESSAGE_QUEUE_MP_FLUSH_RESPONSE: + break; + + } + /* + * The following line is included to satisfy compilers which + * produce warnings when a function does not end with a return. + */ + return RTEMS_SUCCESSFUL; +} + +/*PAGE + * + * _Message_queue_MP_Send_response_packet + * + */ + +void _Message_queue_MP_Send_response_packet ( + Message_queue_MP_Remote_operations operation, + Objects_Id message_queue_id, + Thread_Control *the_thread +) +{ + Message_queue_MP_Packet *the_packet; + + switch ( operation ) { + + case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE: + case MESSAGE_QUEUE_MP_SEND_RESPONSE: + case MESSAGE_QUEUE_MP_URGENT_RESPONSE: + case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE: + case MESSAGE_QUEUE_MP_FLUSH_RESPONSE: + + the_packet = ( Message_queue_MP_Packet *) the_thread->receive_packet; + +/* + * The packet being returned already contains the class, length, and + * to_convert fields, therefore they are not set in this routine. + */ + the_packet->operation = operation; + the_packet->Prefix.id = the_packet->Prefix.source_tid; + + _MPCI_Send_response_packet( + rtems_get_node( the_packet->Prefix.source_tid ), + &the_packet->Prefix + ); + break; + + case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE: + case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE: + case MESSAGE_QUEUE_MP_EXTRACT_PROXY: + case MESSAGE_QUEUE_MP_RECEIVE_REQUEST: + case MESSAGE_QUEUE_MP_SEND_REQUEST: + case MESSAGE_QUEUE_MP_URGENT_REQUEST: + case MESSAGE_QUEUE_MP_BROADCAST_REQUEST: + case MESSAGE_QUEUE_MP_FLUSH_REQUEST: + break; + + } +} + +/*PAGE + * + * + * _Message_queue_MP_Process_packet + * + */ + +void _Message_queue_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +) +{ + Message_queue_MP_Packet *the_packet; + Thread_Control *the_thread; + boolean ignored; + + the_packet = (Message_queue_MP_Packet *) the_packet_prefix; + + switch ( the_packet->operation ) { + + case MESSAGE_QUEUE_MP_ANNOUNCE_CREATE: + + ignored = _Objects_MP_Open( + &_Message_queue_Information, + the_packet->name, + the_packet->Prefix.id, + TRUE + ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case MESSAGE_QUEUE_MP_ANNOUNCE_DELETE: + + _Objects_MP_Close( &_Message_queue_Information, the_packet->Prefix.id ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case MESSAGE_QUEUE_MP_EXTRACT_PROXY: + + the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id ); + + if ( ! _Thread_Is_null( the_thread ) ) + _Thread_queue_Extract( the_thread->Wait.queue, the_thread ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case MESSAGE_QUEUE_MP_RECEIVE_REQUEST: + + the_packet->Prefix.return_code = rtems_message_queue_receive( + the_packet->Prefix.id, + &the_packet->Buffer, + the_packet->option_set, + the_packet->Prefix.timeout + ); + + if ( ! _Status_Is_proxy_blocking( the_packet->Prefix.return_code ) ) + _Message_queue_MP_Send_response_packet( + MESSAGE_QUEUE_MP_RECEIVE_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case MESSAGE_QUEUE_MP_RECEIVE_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + _Message_queue_Copy_buffer( + &the_packet->Buffer, + (Message_queue_Buffer *) the_thread->Wait.return_argument + ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case MESSAGE_QUEUE_MP_SEND_REQUEST: + + the_packet->Prefix.return_code = rtems_message_queue_send( + the_packet->Prefix.id, + &the_packet->Buffer + ); + + _Message_queue_MP_Send_response_packet( + MESSAGE_QUEUE_MP_SEND_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case MESSAGE_QUEUE_MP_SEND_RESPONSE: + case MESSAGE_QUEUE_MP_URGENT_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case MESSAGE_QUEUE_MP_URGENT_REQUEST: + + the_packet->Prefix.return_code = rtems_message_queue_urgent( + the_packet->Prefix.id, + &the_packet->Buffer + ); + + _Message_queue_MP_Send_response_packet( + MESSAGE_QUEUE_MP_URGENT_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case MESSAGE_QUEUE_MP_BROADCAST_REQUEST: + + the_packet->Prefix.return_code = rtems_message_queue_broadcast( + the_packet->Prefix.id, + &the_packet->Buffer, + &the_packet->count + ); + + _Message_queue_MP_Send_response_packet( + MESSAGE_QUEUE_MP_BROADCAST_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case MESSAGE_QUEUE_MP_BROADCAST_RESPONSE: + case MESSAGE_QUEUE_MP_FLUSH_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + *(unsigned32 *)the_thread->Wait.return_argument = the_packet->count; + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case MESSAGE_QUEUE_MP_FLUSH_REQUEST: + + the_packet->Prefix.return_code = rtems_message_queue_flush( + the_packet->Prefix.id, + &the_packet->count + ); + + _Message_queue_MP_Send_response_packet( + MESSAGE_QUEUE_MP_FLUSH_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + } +} + +/*PAGE + * + * _Message_queue_MP_Send_object_was_deleted + * + */ + +void _Message_queue_MP_Send_object_was_deleted ( + Thread_Control *the_proxy +) +{ + the_proxy->receive_packet->return_code = RTEMS_OBJECT_WAS_DELETED; + + _Message_queue_MP_Send_response_packet( + MESSAGE_QUEUE_MP_RECEIVE_RESPONSE, + the_proxy->Wait.id, + the_proxy + ); +} + +/*PAGE + * + * _Message_queue_MP_Send_extract_proxy + * + */ + +void _Message_queue_MP_Send_extract_proxy ( + Thread_Control *the_thread +) +{ + _Message_queue_MP_Send_process_packet( + MESSAGE_QUEUE_MP_EXTRACT_PROXY, + the_thread->Wait.id, + (Objects_Name) 0, + the_thread->Object.id + ); +} + +/*PAGE + * + * _Message_queue_MP_Get_packet + * + */ + +Message_queue_MP_Packet *_Message_queue_MP_Get_packet ( void ) +{ + return ( (Message_queue_MP_Packet *) _MPCI_Get_packet() ); +} + +/* end of file */ diff --git a/cpukit/rtems/src/part.c b/cpukit/rtems/src/part.c new file mode 100644 index 0000000000..1fa2e0e716 --- /dev/null +++ b/cpukit/rtems/src/part.c @@ -0,0 +1,322 @@ +/* + * Partition Manager + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Partition_Manager_initialization + * + * This routine initializes all partition manager related + * data structures. + * + * Input parameters: + * maximum_partitions - number of partitions to initialize + * + * Output parameters: NONE + */ + +void _Partition_Manager_initialization( + unsigned32 maximum_partitions +) +{ + _Objects_Initialize_information( + &_Partition_Information, + TRUE, + maximum_partitions, + sizeof( Partition_Control ) + ); + +} + +/*PAGE + * + * rtems_partition_create + * + * This directive creates a partiton of fixed sized buffers from the + * given contiguous memory area. + * + * Input parameters: + * name - user defined partition name + * starting_address - physical start address of partition + * length - physical length in bytes + * buffer_size - size of buffers in bytes + * attribute_set - partition attributes + * id - pointer to partition id + * + * Output parameters: + * id - partition id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_partition_create( + Objects_Name name, + void *starting_address, + unsigned32 length, + unsigned32 buffer_size, + rtems_attribute attribute_set, + Objects_Id *id +) +{ + register Partition_Control *the_partition; + + if ( !_Objects_Is_name_valid( name ) ) + return ( RTEMS_INVALID_NAME ); + + if ( length == 0 || buffer_size == 0 || length < buffer_size || + !_Partition_Is_buffer_size_aligned( buffer_size ) ) + return ( RTEMS_INVALID_SIZE ); + + if ( !_Addresses_Is_aligned( starting_address ) ) + return( RTEMS_INVALID_ADDRESS ); + + if ( _Attributes_Is_global( attribute_set ) && + !_Configuration_Is_multiprocessing() ) + return( RTEMS_MP_NOT_CONFIGURED ); + + _Thread_Disable_dispatch(); /* prevents deletion */ + + the_partition = _Partition_Allocate(); + + if ( !the_partition ) { + _Thread_Enable_dispatch(); + return( RTEMS_TOO_MANY ); + } + + if ( _Attributes_Is_global( attribute_set ) && + !( _Objects_MP_Open( &_Partition_Information, name, + the_partition->Object.id, FALSE ) ) ) { + _Partition_Free( the_partition ); + _Thread_Enable_dispatch(); + return( RTEMS_TOO_MANY ); + } + 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 ); + + _Objects_Open( &_Partition_Information, &the_partition->Object, name ); + + *id = the_partition->Object.id; + if ( _Attributes_Is_global( attribute_set ) ) + _Partition_MP_Send_process_packet( + PARTITION_MP_ANNOUNCE_CREATE, + the_partition->Object.id, + name, + 0 /* Not used */ + ); + + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); +} + +/*PAGE + * + * rtems_partition_ident + * + * This directive returns the system ID associated with + * the partition name. + * + * Input parameters: + * name - user defined partition name + * node - node(s) to be searched + * id - pointer to partition id + * + * Output parameters: + * *id - partition id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_partition_ident( + Objects_Name name, + unsigned32 node, + Objects_Id *id +) +{ + return( _Objects_Name_to_id( &_Partition_Information, name, node, id ) ); +} + +/*PAGE + * + * rtems_partition_delete + * + * This directive allows a thread to delete a partition specified by + * the partition identifier, provided that none of its buffers are + * still allocated. + * + * Input parameters: + * id - partition id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_partition_delete( + Objects_Id id +) +{ + register Partition_Control *the_partition; + Objects_Locations location; + + the_partition = _Partition_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + _Thread_Dispatch(); + return( RTEMS_ILLEGAL_ON_REMOTE_OBJECT ); + case OBJECTS_LOCAL: + if ( the_partition->number_of_used_blocks == 0 ) { + _Objects_Close( &_Partition_Information, &the_partition->Object ); + _Partition_Free( the_partition ); + if ( _Attributes_Is_global( the_partition->attribute_set ) ) { + + _Objects_MP_Close( + &_Partition_Information, + the_partition->Object.id + ); + + _Partition_MP_Send_process_packet( + PARTITION_MP_ANNOUNCE_DELETE, + the_partition->Object.id, + 0, /* Not used */ + 0 /* Not used */ + ); + } + + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + _Thread_Enable_dispatch(); + return( RTEMS_RESOURCE_IN_USE ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_partition_get_buffer + * + * This directive will obtain a buffer from a buffer partition. + * + * Input parameters: + * id - partition id + * buffer - pointer to buffer address + * + * Output parameters: + * buffer - pointer to buffer address filled in + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_partition_get_buffer( + Objects_Id id, + void **buffer +) +{ + register Partition_Control *the_partition; + Objects_Locations location; + void *the_buffer; + + the_partition = _Partition_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + _Thread_Executing->Wait.return_argument = buffer; + return( + _Partition_MP_Send_request_packet( + PARTITION_MP_GET_BUFFER_REQUEST, + id, + 0 /* Not used */ + ) + ); + case OBJECTS_LOCAL: + the_buffer = _Partition_Allocate_buffer( the_partition ); + if ( the_buffer ) { + the_partition->number_of_used_blocks += 1; + _Thread_Enable_dispatch(); + *buffer = the_buffer; + return( RTEMS_SUCCESSFUL ); + } + _Thread_Enable_dispatch(); + return( RTEMS_UNSATISFIED ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_partition_return_buffer + * + * This directive will return the given buffer to the specified + * buffer partition. + * + * Input parameters: + * id - partition id + * buffer - pointer to buffer address + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_partition_return_buffer( + Objects_Id id, + void *buffer +) +{ + register Partition_Control *the_partition; + Objects_Locations location; + + the_partition = _Partition_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + return( + _Partition_MP_Send_request_packet( + PARTITION_MP_RETURN_BUFFER_REQUEST, + id, + buffer + ) + ); + case OBJECTS_LOCAL: + if ( _Partition_Is_buffer_valid( buffer, the_partition ) ) { + _Partition_Free_buffer( the_partition, buffer ); + the_partition->number_of_used_blocks -= 1; + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + _Thread_Enable_dispatch(); + return( RTEMS_INVALID_ADDRESS ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/partmp.c b/cpukit/rtems/src/partmp.c new file mode 100644 index 0000000000..9cc1723106 --- /dev/null +++ b/cpukit/rtems/src/partmp.c @@ -0,0 +1,300 @@ +/* + * Multiprocessing Support for the Partition Manager + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Partition_MP_Send_process_packet + * + */ + +void _Partition_MP_Send_process_packet ( + Partition_MP_Remote_operations operation, + Objects_Id partition_id, + Objects_Name name, + Objects_Id proxy_id +) +{ + Partition_MP_Packet *the_packet; + unsigned32 node; + + switch ( operation ) { + + case PARTITION_MP_ANNOUNCE_CREATE: + case PARTITION_MP_ANNOUNCE_DELETE: + case PARTITION_MP_EXTRACT_PROXY: + + the_packet = _Partition_MP_Get_packet(); + the_packet->Prefix.the_class = RTEMS_MP_PACKET_PARTITION; + the_packet->Prefix.length = sizeof ( Partition_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Partition_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = partition_id; + the_packet->name = name; + the_packet->proxy_id = proxy_id; + + if ( operation == PARTITION_MP_EXTRACT_PROXY ) + node = rtems_get_node( partition_id ); + else + node = MPCI_ALL_NODES; + + _MPCI_Send_process_packet( node, &the_packet->Prefix ); + break; + + case PARTITION_MP_GET_BUFFER_REQUEST: + case PARTITION_MP_GET_BUFFER_RESPONSE: + case PARTITION_MP_RETURN_BUFFER_REQUEST: + case PARTITION_MP_RETURN_BUFFER_RESPONSE: + break; + } +} + +/*PAGE + * + * _Partition_MP_Send_request_packet + * + */ + +rtems_status_code _Partition_MP_Send_request_packet ( + Partition_MP_Remote_operations operation, + Objects_Id partition_id, + void *buffer +) +{ + Partition_MP_Packet *the_packet; + + switch ( operation ) { + + case PARTITION_MP_GET_BUFFER_REQUEST: + case PARTITION_MP_RETURN_BUFFER_REQUEST: + + the_packet = _Partition_MP_Get_packet(); + the_packet->Prefix.the_class = RTEMS_MP_PACKET_PARTITION; + the_packet->Prefix.length = sizeof ( Partition_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Partition_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = partition_id; + the_packet->buffer = buffer; + + return + _MPCI_Send_request_packet( + rtems_get_node( partition_id ), + &the_packet->Prefix, + STATES_READY /* Not used */ + ); + + break; + + case PARTITION_MP_ANNOUNCE_CREATE: + case PARTITION_MP_ANNOUNCE_DELETE: + case PARTITION_MP_EXTRACT_PROXY: + case PARTITION_MP_GET_BUFFER_RESPONSE: + case PARTITION_MP_RETURN_BUFFER_RESPONSE: + break; + + } + /* + * The following line is included to satisfy compilers which + * produce warnings when a function does not end with a return. + */ + return RTEMS_SUCCESSFUL; +} + +/*PAGE + * + * _Partition_MP_Send_response_packet + * + */ + +void _Partition_MP_Send_response_packet ( + Partition_MP_Remote_operations operation, + Objects_Id partition_id, + Thread_Control *the_thread +) +{ + Partition_MP_Packet *the_packet; + + switch ( operation ) { + + case PARTITION_MP_GET_BUFFER_RESPONSE: + case PARTITION_MP_RETURN_BUFFER_RESPONSE: + + the_packet = ( Partition_MP_Packet *) the_thread->receive_packet; + +/* + * The packet being returned already contains the class, length, and + * to_convert fields, therefore they are not set in this routine. + */ + the_packet->operation = operation; + the_packet->Prefix.id = the_packet->Prefix.source_tid; + + _MPCI_Send_response_packet( + rtems_get_node( the_packet->Prefix.source_tid ), + &the_packet->Prefix + ); + break; + + case PARTITION_MP_ANNOUNCE_CREATE: + case PARTITION_MP_ANNOUNCE_DELETE: + case PARTITION_MP_EXTRACT_PROXY: + case PARTITION_MP_GET_BUFFER_REQUEST: + case PARTITION_MP_RETURN_BUFFER_REQUEST: + break; + + } +} + +/*PAGE + * + * + * _Partition_MP_Process_packet + * + */ + +void _Partition_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +) +{ + Partition_MP_Packet *the_packet; + Thread_Control *the_thread; + boolean ignored; + + the_packet = (Partition_MP_Packet *) the_packet_prefix; + + switch ( the_packet->operation ) { + + case PARTITION_MP_ANNOUNCE_CREATE: + + ignored = _Objects_MP_Open( + &_Partition_Information, + the_packet->name, + the_packet->Prefix.id, + TRUE + ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case PARTITION_MP_ANNOUNCE_DELETE: + + _Objects_MP_Close( &_Partition_Information, the_packet->Prefix.id ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case PARTITION_MP_EXTRACT_PROXY: + + the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id ); + + if ( ! _Thread_Is_null( the_thread ) ) + _Thread_queue_Extract( the_thread->Wait.queue, the_thread ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case PARTITION_MP_GET_BUFFER_REQUEST: + + the_packet->Prefix.return_code = rtems_partition_get_buffer( + the_packet->Prefix.id, + &the_packet->buffer + ); + + _Partition_MP_Send_response_packet( + PARTITION_MP_GET_BUFFER_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case PARTITION_MP_GET_BUFFER_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + *(void **)the_thread->Wait.return_argument = the_packet->buffer; + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case PARTITION_MP_RETURN_BUFFER_REQUEST: + + the_packet->Prefix.return_code = rtems_partition_return_buffer( + the_packet->Prefix.id, + the_packet->buffer + ); + + _Partition_MP_Send_response_packet( + PARTITION_MP_RETURN_BUFFER_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case PARTITION_MP_RETURN_BUFFER_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + } +} + +/*PAGE + * + * _Partition_MP_Send_object_was_deleted + * + * This routine is not needed by the Partition since a partition + * cannot be deleted when buffers are in use. + * + */ + +/*PAGE + * + * _Partition_MP_Send_extract_proxy + * + */ + +void _Partition_MP_Send_extract_proxy ( + Thread_Control *the_thread +) +{ + _Partition_MP_Send_process_packet( + PARTITION_MP_EXTRACT_PROXY, + the_thread->Wait.id, + (Objects_Name) 0, + the_thread->Object.id + ); + +} + +/*PAGE + * + * _Partition_MP_Get_packet + * + */ + +Partition_MP_Packet *_Partition_MP_Get_packet ( void ) +{ + return ( (Partition_MP_Packet *) _MPCI_Get_packet() ); +} + +/* end of file */ diff --git a/cpukit/rtems/src/ratemon.c b/cpukit/rtems/src/ratemon.c new file mode 100644 index 0000000000..3c0733a3ab --- /dev/null +++ b/cpukit/rtems/src/ratemon.c @@ -0,0 +1,401 @@ +/* + * Rate Monotonic Manager + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include + +/*PAGE + * + * _Rate_monotonic_Manager_initialization + * + * This routine initializes all Rate Monotonic Manager related + * data structures. + * + * Input parameters: + * maximum_periods - number of periods timers to initialize + * + * Output parameters: NONE + * + * NOTE: The Rate Monotonic Manager is built on top of the Watchdog + * Handler. + */ + +void _Rate_monotonic_Manager_initialization( + unsigned32 maximum_periods +) +{ + _Objects_Initialize_information( + &_Rate_monotonic_Information, + FALSE, + maximum_periods, + sizeof( Rate_monotonic_Control ) + ); +} + +/*PAGE + * + * rtems_rate_monotonic_create + * + * This directive creates a rate monotonic timer and performs + * some initialization. + * + * Input parameters: + * name - name of period + * id - pointer to rate monotonic id + * + * Output parameters: + * id - rate monotonic id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_rate_monotonic_create( + Objects_Name name, + Objects_Id *id +) +{ + Rate_monotonic_Control *the_period; + + if ( !_Objects_Is_name_valid( name ) ) + return( RTEMS_INVALID_NAME ); + + _Thread_Disable_dispatch(); /* to prevent deletion */ + + the_period = _Rate_monotonic_Allocate(); + + if ( !the_period ) { + _Thread_Enable_dispatch(); + return( RTEMS_TOO_MANY ); + } + + the_period->owner = _Thread_Executing; + the_period->state = RATE_MONOTONIC_INACTIVE; + + _Objects_Open( &_Rate_monotonic_Information, &the_period->Object, name ); + + *id = the_period->Object.id; + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); +} + +/*PAGE + * + * rtems_rate_monotonic_ident + * + * This directive returns the system ID associated with + * the rate monotonic period name. + * + * Input parameters: + * name - user defined period name + * id - pointer to period id + * + * Output parameters: + * *id - region id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_rate_monotonic_ident( + Objects_Name name, + Objects_Id *id +) +{ + return _Objects_Name_to_id( + &_Rate_monotonic_Information, + name, + RTEMS_SEARCH_LOCAL_NODE, + id + ); +} + +/*PAGE + * + * rtems_rate_monotonic_cancel + * + * This directive allows a thread to cancel a rate monotonic timer. + * + * Input parameters: + * id - rate monotonic id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful and caller is not the owning thread + * error code - if unsuccessful + */ + +rtems_status_code rtems_rate_monotonic_cancel( + Objects_Id id +) +{ + Rate_monotonic_Control *the_period; + Objects_Locations location; + + the_period = _Rate_monotonic_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: /* should never return this */ + return( RTEMS_INTERNAL_ERROR ); + case OBJECTS_LOCAL: + if ( !_Thread_Is_executing( the_period->owner ) ) { + _Thread_Enable_dispatch(); + return( RTEMS_NOT_OWNER_OF_RESOURCE ); + } + (void) _Watchdog_Remove( &the_period->Timer ); + the_period->state = RATE_MONOTONIC_INACTIVE; + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_rate_monotonic_delete + * + * This directive allows a thread to delete a rate monotonic timer. + * + * Input parameters: + * id - rate monotonic id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_rate_monotonic_delete( + Objects_Id id +) +{ + Rate_monotonic_Control *the_period; + Objects_Locations location; + + the_period = _Rate_monotonic_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: /* should never return this */ + return( RTEMS_INTERNAL_ERROR ); + case OBJECTS_LOCAL: + _Objects_Close( &_Rate_monotonic_Information, &the_period->Object ); + (void) _Watchdog_Remove( &the_period->Timer ); + the_period->state = RATE_MONOTONIC_INACTIVE; + _Rate_monotonic_Free( the_period ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_rate_monotonic_period + * + * This directive allows a thread to manipulate a rate monotonic timer. + * + * Input parameters: + * id - rate monotonic id + * length - length of period (in ticks) + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_rate_monotonic_period( + Objects_Id id, + rtems_interval length +) +{ + Rate_monotonic_Control *the_period; + Objects_Locations location; + rtems_status_code return_value; + + the_period = _Rate_monotonic_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: /* should never return this */ + return( RTEMS_INTERNAL_ERROR ); + case OBJECTS_LOCAL: + if ( !_Thread_Is_executing( the_period->owner ) ) { + _Thread_Enable_dispatch(); + return( RTEMS_NOT_OWNER_OF_RESOURCE ); + } + + if ( length == RTEMS_PERIOD_STATUS ) { + switch ( the_period->state ) { + case RATE_MONOTONIC_INACTIVE: + return_value = RTEMS_NOT_DEFINED; + break; + case RATE_MONOTONIC_ACTIVE: + return_value = RTEMS_SUCCESSFUL; + break; + case RATE_MONOTONIC_EXPIRED: + return_value = RTEMS_TIMEOUT; + break; + default: /* unreached -- only to remove warnings */ + return_value = RTEMS_INTERNAL_ERROR; + break; + } + _Thread_Enable_dispatch(); + return( return_value ); + } + + switch ( the_period->state ) { + case RATE_MONOTONIC_INACTIVE: + the_period->state = RATE_MONOTONIC_ACTIVE; + _Watchdog_Initialize( + &the_period->Timer, + _Rate_monotonic_Timeout, + id, + NULL + ); + _Watchdog_Insert_ticks( + &the_period->Timer, length, WATCHDOG_ACTIVATE_NOW ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + + case RATE_MONOTONIC_ACTIVE: +/* following is and could be a critical section problem */ + _Thread_Executing->Wait.id = the_period->Object.id; + if ( _Rate_monotonic_Set_state( the_period ) ) { + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + /* has expired -- fall into next case */ + case RATE_MONOTONIC_EXPIRED: + the_period->state = RATE_MONOTONIC_ACTIVE; + _Watchdog_Insert_ticks( + &the_period->Timer, length, WATCHDOG_ACTIVATE_NOW ); + _Thread_Enable_dispatch(); + return( RTEMS_TIMEOUT ); + } + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * _Rate_monotonic_Set_state + * + * This kernel routine sets the STATES_WAITING_FOR_PERIOD state in + * the running thread's tcb if the specified period has not expired. + * The ready chain is adjusted if necessary. + * + * Input parameters: + * the_period - pointer to period control block + * + * Output parameters: + * TRUE - if blocked successfully for period + * FALSE - if period has expired + * + * INTERRUPT LATENCY: + * delete node + * priority map + * select heir + */ + +boolean _Rate_monotonic_Set_state( +Rate_monotonic_Control *the_period +) +{ + Thread_Control *executing; + Chain_Control *ready; + ISR_Level level; + States_Control old_state; + + executing = _Thread_Executing; + ready = executing->ready; + _ISR_Disable( level ); + + old_state = executing->current_state; + + if ( _Rate_monotonic_Is_expired( the_period ) ) { + _ISR_Enable( level ); + return( FALSE ); + } + + executing->current_state = + _States_Set( STATES_WAITING_FOR_PERIOD, old_state ); + + if ( _States_Is_ready( old_state ) ) { + if ( _Chain_Has_only_one_node( ready ) ) { + _Chain_Initialize_empty( ready ); + _Priority_Remove_from_bit_map( &executing->Priority_map ); + _ISR_Flash( level ); + } else { + _Chain_Extract_unprotected( &executing->Object.Node ); + _ISR_Flash( level ); + } + + if ( _Thread_Is_heir( executing ) ) + _Thread_Calculate_heir(); + + _Context_Switch_necessary = TRUE; + } + + _ISR_Enable( level ); + return( TRUE ); +} + +/*PAGE + * + * _Rate_monotonic_Timeout + * + * This routine processes a period ending. If the owning thread + * is waiting for the period, that thread is unblocked and the + * period reinitiated. Otherwise, the period is expired. + * This routine is called by the watchdog handler. + * + * Input parameters: + * id - period id + * + * Output parameters: NONE + */ + +void _Rate_monotonic_Timeout( + Objects_Id id, + void *ignored +) +{ + Rate_monotonic_Control *the_period; + Objects_Locations location; + Thread_Control *the_thread; + + the_period = _Rate_monotonic_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + case OBJECTS_REMOTE: /* impossible */ + break; + case OBJECTS_LOCAL: + the_thread = the_period->owner; + if ( _States_Is_waiting_for_period( the_thread->current_state ) && + the_thread->Wait.id == the_period->Object.id ) { + _Thread_Unblock( the_thread ); + _Watchdog_Reset( &the_period->Timer ); + } + else + the_period->state = RATE_MONOTONIC_EXPIRED; + _Thread_Unnest_dispatch(); + break; + } +} + diff --git a/cpukit/rtems/src/region.c b/cpukit/rtems/src/region.c new file mode 100644 index 0000000000..c62214eaf6 --- /dev/null +++ b/cpukit/rtems/src/region.c @@ -0,0 +1,456 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Region_Manager_initialization + * + * This routine initializes all region manager related data structures. + * + * Input parameters: + * maximum_regions - number of regions to initialize + * + * Output parameters: NONE + */ + +void _Region_Manager_initialization( + unsigned32 maximum_regions +) +{ + _Objects_Initialize_information( + &_Region_Information, + FALSE, + maximum_regions, + sizeof( Region_Control ) + ); +} + +/*PAGE + * + * rtems_region_create + * + * This directive creates a region of physical contiguous memory area + * from which variable sized segments can be allocated. + * + * Input parameters: + * name - user defined region name + * starting_address - physical start address of region + * length - physical length in bytes + * page_size - page size in bytes + * attribute_set - region attributes + * id - address of region id to set + * + * Output parameters: + * id - region id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_create( + Objects_Name name, + void *starting_address, + unsigned32 length, + unsigned32 page_size, + rtems_attribute attribute_set, + Objects_Id *id +) +{ + Region_Control *the_region; + + if ( !_Objects_Is_name_valid( name ) ) + return ( RTEMS_INVALID_NAME ); + + if ( !_Addresses_Is_aligned( starting_address ) ) + return( RTEMS_INVALID_ADDRESS ); + + _Thread_Disable_dispatch(); /* to prevent deletion */ + + the_region = _Region_Allocate(); + + if ( !the_region ) { + _Thread_Enable_dispatch(); + return( RTEMS_TOO_MANY ); + } + + the_region->maximum_segment_size = + _Heap_Initialize(&the_region->Memory, starting_address, length, page_size); + + if ( !the_region->maximum_segment_size ) { + _Region_Free( the_region ); + _Thread_Enable_dispatch(); + return( RTEMS_INVALID_SIZE ); + } + + the_region->starting_address = starting_address; + the_region->length = length; + the_region->page_size = page_size; + the_region->attribute_set = attribute_set; + the_region->number_of_used_blocks = 0; + + _Thread_queue_Initialize( + &the_region->Wait_queue, attribute_set, STATES_WAITING_FOR_SEGMENT ); + + _Objects_Open( &_Region_Information, &the_region->Object, name ); + + *id = the_region->Object.id; + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); +} + +/*PAGE + * + * rtems_region_ident + * + * This directive returns the system ID associated with + * the region name. + * + * Input parameters: + * name - user defined region name + * id - pointer to region id + * + * Output parameters: + * *id - region id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_ident( + Objects_Name name, + Objects_Id *id +) +{ + return _Objects_Name_to_id( + &_Region_Information, + name, + RTEMS_SEARCH_LOCAL_NODE, + id + ); +} + +/*PAGE + * + * rtems_region_delete + * + * This directive allows a thread to delete a region specified by + * the region identifier, provided that none of its segments are + * still allocated. + * + * Input parameters: + * id - region id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_delete( + Objects_Id id +) +{ + register Region_Control *the_region; + Objects_Locations location; + + the_region = _Region_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: /* this error cannot be returned */ + return( RTEMS_INTERNAL_ERROR ); + case OBJECTS_LOCAL: + _Region_Debug_Walk( the_region, 5 ); + if ( the_region->number_of_used_blocks == 0 ) { + _Objects_Close( &_Region_Information, &the_region->Object ); + _Region_Free( the_region ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + _Thread_Enable_dispatch(); + return( RTEMS_RESOURCE_IN_USE ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_region_extend + * + * This directive attempts to grow a region of physical contiguous memory area + * from which variable sized segments can be allocated. + * + * Input parameters: + * id - id of region to grow + * start - starting address of memory area for extension + * length - physical length in bytes to grow the region + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_extend( + Objects_Id id, + void *starting_address, + unsigned32 length +) +{ + Region_Control *the_region; + Objects_Locations location; + unsigned32 amount_extended; + Heap_Extend_status heap_status; + rtems_status_code status; + + status = RTEMS_SUCCESSFUL; + + the_region = _Region_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: /* this error cannot be returned */ + return( RTEMS_INTERNAL_ERROR ); + case OBJECTS_LOCAL: + + heap_status = _Heap_Extend( + &the_region->Memory, + starting_address, + length, + &amount_extended + ); + + switch ( heap_status ) { + case HEAP_EXTEND_SUCCESSFUL: + the_region->length += amount_extended; + the_region->maximum_segment_size += amount_extended; + break; + case HEAP_EXTEND_ERROR: + status = RTEMS_INVALID_ADDRESS; + break; + case HEAP_EXTEND_NOT_IMPLEMENTED: + status = RTEMS_NOT_IMPLEMENTED; + break; + } + _Thread_Enable_dispatch(); + return( status ); + } + + return( RTEMS_INTERNAL_ERROR ); +} + +/*PAGE + * + * rtems_region_get_segment + * + * This directive will obtain a segment from the given region. + * + * Input parameters: + * id - region id + * size - segment size in bytes + * option_set - wait option + * timeout - number of ticks to wait (0 means wait forever) + * segment - pointer to segment address + * + * Output parameters: + * segment - pointer to segment address filled in + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_get_segment( + Objects_Id id, + unsigned32 size, + rtems_option option_set, + rtems_interval timeout, + void **segment +) +{ + register Region_Control *the_region; + Objects_Locations location; + Thread_Control *executing; + void *the_segment; + + if ( size == 0 ) + return( RTEMS_INVALID_SIZE ); + + executing = _Thread_Executing; + the_region = _Region_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: /* this error cannot be returned */ + return( RTEMS_INTERNAL_ERROR ); + case OBJECTS_LOCAL: + if ( size > the_region->maximum_segment_size ) { + _Thread_Enable_dispatch(); + return( RTEMS_INVALID_SIZE ); + } + + _Region_Debug_Walk( the_region, 1 ); + + the_segment = _Region_Allocate_segment( the_region, size ); + + _Region_Debug_Walk( the_region, 2 ); + + if ( the_segment ) { + the_region->number_of_used_blocks += 1; + _Thread_Enable_dispatch(); + *segment = the_segment; + return( RTEMS_SUCCESSFUL ); + } + + if ( _Options_Is_no_wait( option_set ) ) { + _Thread_Enable_dispatch(); + return( RTEMS_UNSATISFIED ); + } + + executing->Wait.queue = &the_region->Wait_queue; + executing->Wait.id = id; + executing->Wait.Extra.segment_size = size; + executing->Wait.return_argument = (unsigned32 *) segment; + + the_region->Wait_queue.sync = TRUE; + + _Thread_queue_Enqueue( &the_region->Wait_queue, timeout ); + + _Thread_Enable_dispatch(); + return( executing->Wait.return_code ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} +/*PAGE + * + * rtems_region_get_segment_size + * + * This directive will return the size of the segment indicated + * + * Input parameters: + * id - region id + * segment - segment address + * size - pointer to segment size in bytes + * + * Output parameters: + * size - segment size in bytes filled in + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_get_segment_size( + Objects_Id id, + void *segment, + unsigned32 *size +) +{ + register Region_Control *the_region; + Objects_Locations location; + Thread_Control *executing; + + executing = _Thread_Executing; + the_region = _Region_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: /* this error cannot be returned */ + return( RTEMS_INTERNAL_ERROR ); + case OBJECTS_LOCAL: + + if ( _Heap_Size_of_user_area( &the_region->Memory, segment, size ) ) { + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + _Thread_Enable_dispatch(); + return( RTEMS_INVALID_ADDRESS ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_region_return_segment + * + * This directive will return a segment to its region. + * + * Input parameters: + * id - region id + * segment - pointer to segment address + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_return_segment( + Objects_Id id, + void *segment +) +{ + register Region_Control *the_region; + Thread_Control *the_thread; + Objects_Locations location; + void **the_segment; + int status; + + the_region = _Region_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: /* this error cannot be returned */ + return( RTEMS_INTERNAL_ERROR ); + case OBJECTS_LOCAL: + + _Region_Debug_Walk( the_region, 3 ); + + status = _Region_Free_segment( the_region, segment ); + + _Region_Debug_Walk( the_region, 4 ); + + if ( !status ) { + _Thread_Enable_dispatch(); + return( RTEMS_INVALID_ADDRESS ); + } + + the_region->number_of_used_blocks -= 1; + for ( ; ; ) { + the_thread = _Thread_queue_First( &the_region->Wait_queue ); + + if ( the_thread == NULL ) + break; + + the_segment = _Region_Allocate_segment( + the_region, the_thread->Wait.Extra.segment_size ); + + if ( the_segment == NULL ) + break; + + *(void **)the_thread->Wait.return_argument = the_segment; + the_region->number_of_used_blocks += 1; + _Thread_queue_Extract( &the_region->Wait_queue, the_thread ); + the_thread->Wait.return_code = RTEMS_SUCCESSFUL; + } + + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/regionmp.c b/cpukit/rtems/src/regionmp.c new file mode 100644 index 0000000000..558ae1639a --- /dev/null +++ b/cpukit/rtems/src/regionmp.c @@ -0,0 +1,308 @@ +/* + * Multiprocessing Support for the Region Manager + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Region_MP_Send_process_packet + * + */ + +void _Region_MP_Send_process_packet ( + Region_MP_Remote_operations operation, + Objects_Id region_id, + Objects_Name name, + Objects_Id proxy_id +) +{ + Region_MP_Packet *the_packet; + unsigned32 node; + + switch ( operation ) { + + case REGION_MP_ANNOUNCE_CREATE: + case REGION_MP_ANNOUNCE_DELETE: + case REGION_MP_EXTRACT_PROXY: + + the_packet = _Region_MP_Get_packet(); + the_packet->Prefix.the_class = RTEMS_MP_PACKET_REGION; + the_packet->Prefix.length = sizeof ( Region_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Region_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = region_id; + the_packet->name = name; + the_packet->proxy_id = proxy_id; + + if ( operation == REGION_MP_EXTRACT_PROXY ) + node = rtems_get_node( region_id ); + else + node = MPCI_ALL_NODES; + + _MPCI_Send_process_packet( node, &the_packet->Prefix ); + break; + + case REGION_MP_GET_SEGMENT_REQUEST: + case REGION_MP_GET_SEGMENT_RESPONSE: + case REGION_MP_RETURN_SEGMENT_REQUEST: + case REGION_MP_RETURN_SEGMENT_RESPONSE: + break; + } +} + +/*PAGE + * + * _Region_MP_Send_request_packet + * + */ + +rtems_status_code _Region_MP_Send_request_packet ( + Region_MP_Remote_operations operation, + Objects_Id region_id, + void *segment, + unsigned32 size, + rtems_option option_set, + rtems_interval timeout +) +{ + Region_MP_Packet *the_packet; + + switch ( operation ) { + + case REGION_MP_GET_SEGMENT_REQUEST: + case REGION_MP_RETURN_SEGMENT_REQUEST: + + the_packet = _Region_MP_Get_packet(); + the_packet->Prefix.the_class = RTEMS_MP_PACKET_REGION; + the_packet->Prefix.length = sizeof ( Region_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Region_MP_Packet ); + if ( ! _Options_Is_no_wait(option_set)) + the_packet->Prefix.timeout = timeout; + + the_packet->operation = operation; + the_packet->Prefix.id = region_id; + the_packet->segment = segment; + the_packet->size = size; + the_packet->option_set = option_set; + + return _MPCI_Send_request_packet( + rtems_get_node( region_id ), + &the_packet->Prefix, + STATES_READY /* Not used */ + ); + break; + + case REGION_MP_ANNOUNCE_CREATE: + case REGION_MP_ANNOUNCE_DELETE: + case REGION_MP_EXTRACT_PROXY: + case REGION_MP_GET_SEGMENT_RESPONSE: + case REGION_MP_RETURN_SEGMENT_RESPONSE: + break; + + } + /* + * The following line is included to satisfy compilers which + * produce warnings when a function does not end with a return. + */ + return RTEMS_INTERNAL_ERROR; +} + +/*PAGE + * + * _Region_MP_Send_response_packet + * + */ + +void _Region_MP_Send_response_packet ( + Region_MP_Remote_operations operation, + Objects_Id region_id, + Thread_Control *the_thread +) +{ + Region_MP_Packet *the_packet; + + switch ( operation ) { + + case REGION_MP_GET_SEGMENT_RESPONSE: + case REGION_MP_RETURN_SEGMENT_RESPONSE: + + the_packet = ( Region_MP_Packet *) the_thread->receive_packet; + +/* + * The packet being returned already contains the class, length, and + * to_convert fields, therefore they are not set in this routine. + */ + the_packet->operation = operation; + the_packet->Prefix.id = the_packet->Prefix.source_tid; + + _MPCI_Send_response_packet( + rtems_get_node( the_packet->Prefix.source_tid ), + &the_packet->Prefix + ); + break; + + case REGION_MP_ANNOUNCE_CREATE: + case REGION_MP_ANNOUNCE_DELETE: + case REGION_MP_EXTRACT_PROXY: + case REGION_MP_GET_SEGMENT_REQUEST: + case REGION_MP_RETURN_SEGMENT_REQUEST: + break; + + } +} + +/*PAGE + * + * + * _Region_MP_Process_packet + * + */ + +void _Region_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +) +{ + Region_MP_Packet *the_packet; + Thread_Control *the_thread; + boolean ignored; + + the_packet = (Region_MP_Packet *) the_packet_prefix; + + switch ( the_packet->operation ) { + + case REGION_MP_ANNOUNCE_CREATE: + + ignored = _Objects_MP_Open( + &_Region_Information, + the_packet->name, + the_packet->Prefix.id, + TRUE + ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case REGION_MP_ANNOUNCE_DELETE: + + _Objects_MP_Close( &_Region_Information, the_packet->Prefix.id ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case REGION_MP_EXTRACT_PROXY: + + the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id ); + + if ( ! _Thread_Is_null( the_thread ) ) + _Thread_queue_Extract( the_thread->Wait.queue, the_thread ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case REGION_MP_GET_SEGMENT_REQUEST: + + the_packet->Prefix.return_code = rtems_region_get_segment( + the_packet->Prefix.id, + the_packet->size, + the_packet->option_set, + the_packet->Prefix.timeout, + &the_packet->segment + ); + + _Region_MP_Send_response_packet( + REGION_MP_GET_SEGMENT_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case REGION_MP_GET_SEGMENT_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + *(void **)the_thread->Wait.return_argument = the_packet->segment; + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case REGION_MP_RETURN_SEGMENT_REQUEST: + + the_packet->Prefix.return_code = rtems_region_return_segment( + the_packet->Prefix.id, + the_packet->segment + ); + + _Region_MP_Send_response_packet( + REGION_MP_RETURN_SEGMENT_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case REGION_MP_RETURN_SEGMENT_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + } +} + +/*PAGE + * + * _Region_MP_Send_object_was_deleted + * + * This routine is not needed by the Region since a region + * cannot be deleted when segments are in use. + * + */ + +/*PAGE + * + * _Region_MP_Send_extract_proxy + * + */ + +void _Region_MP_Send_extract_proxy ( + Thread_Control *the_thread +) +{ + _Region_MP_Send_process_packet( + REGION_MP_EXTRACT_PROXY, + the_thread->Wait.id, + (Objects_Name) 0, + the_thread->Object.id + ); +} + +/*PAGE + * + * _Region_MP_Get_packet + * + */ + +Region_MP_Packet *_Region_MP_Get_packet ( void ) +{ + return ( (Region_MP_Packet *) _MPCI_Get_packet() ); +} + +/* end of file */ diff --git a/cpukit/rtems/src/rtclock.c b/cpukit/rtems/src/rtclock.c new file mode 100644 index 0000000000..f82baa6337 --- /dev/null +++ b/cpukit/rtems/src/rtclock.c @@ -0,0 +1,153 @@ +/* + * Clock Manager + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_clock_get + * + * This directive returns the current date and time. If the time has + * not been set by a tm_set then an error is returned. + * + * Input parameters: + * option - which value to return + * time_buffer - pointer to output buffer (a time and date structure + * or an interval) + * + * Output parameters: + * time_buffer - output filled in + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_clock_get( + rtems_clock_get_options option, + void *time_buffer +) +{ + ISR_Level level; + rtems_interval tmp; + + switch ( option ) { + case RTEMS_CLOCK_GET_TOD: + if ( !_TOD_Is_set() ) + return( RTEMS_NOT_DEFINED ); + + *(rtems_time_of_day *)time_buffer = _TOD_Current; + return( RTEMS_SUCCESSFUL ); + + case RTEMS_CLOCK_GET_SECONDS_SINCE_EPOCH: + if ( !_TOD_Is_set() ) + return( RTEMS_NOT_DEFINED ); + + *(rtems_interval *)time_buffer = _TOD_Seconds_since_epoch; + return( RTEMS_SUCCESSFUL ); + + case RTEMS_CLOCK_GET_TICKS_SINCE_BOOT: + *(rtems_interval *)time_buffer = _TOD_Ticks_since_boot; + return( RTEMS_SUCCESSFUL ); + + case RTEMS_CLOCK_GET_TICKS_PER_SECOND: + *(rtems_interval *)time_buffer = _TOD_Ticks_per_second; + return( RTEMS_SUCCESSFUL ); + + case RTEMS_CLOCK_GET_TIME_VALUE: + if ( !_TOD_Is_set() ) + return( RTEMS_NOT_DEFINED ); + + _ISR_Disable( level ); + ((rtems_clock_time_value *)time_buffer)->seconds = + _TOD_Seconds_since_epoch; + tmp = _TOD_Current.ticks; + _ISR_Enable( level ); + + tmp *= _Configuration_Table->microseconds_per_tick; + ((rtems_clock_time_value *)time_buffer)->microseconds = tmp; + + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_SUCCESSFUL ); /* should never get here */ + +} + +/*PAGE + * + * rtems_clock_set + * + * This directive sets the date and time for this node. + * + * Input parameters: + * time_buffer - pointer to the time and date structure + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_clock_set( + rtems_time_of_day *time_buffer +) +{ + rtems_status_code local_result; + rtems_interval seconds; + + local_result = _TOD_Validate( time_buffer ); + if ( rtems_is_status_successful( local_result ) ) { + seconds = _TOD_To_seconds( time_buffer ); + _Thread_Disable_dispatch(); + _TOD_Set( time_buffer, seconds ); + _Thread_Enable_dispatch(); + + } + return( local_result ); +} + +/*PAGE + * + * rtems_clock_tick + * + * This directive notifies the executve that a tick has occurred. + * When the tick occurs the time manager updates and maintains + * the calendar time, timeslicing, and any timeout delays. + * + * Input parameters: NONE + * + * Output parameters: + * RTEMS_SUCCESSFUL - always succeeds + * + * NOTE: This routine only works for leap-years through 2099. + */ + +rtems_status_code rtems_clock_tick( void ) +{ + _TOD_Tickle_ticks(); + + _Watchdog_Tickle_ticks(); + + _Thread_Tickle_timeslice(); + + if ( _Thread_Is_context_switch_necessary() && + _Thread_Is_dispatching_enabled() ) + _Thread_Dispatch(); + + return( RTEMS_SUCCESSFUL ); +} diff --git a/cpukit/rtems/src/rtemstimer.c b/cpukit/rtems/src/rtemstimer.c new file mode 100644 index 0000000000..076091bee4 --- /dev/null +++ b/cpukit/rtems/src/rtemstimer.c @@ -0,0 +1,343 @@ +/* + * Timer Manager + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Timer_Manager_initialization + * + * This routine initializes all timer manager related data structures. + * + * Input parameters: + * maximum_timers - number of timers to initialize + * + * Output parameters: NONE + */ + +void _Timer_Manager_initialization( + unsigned32 maximum_timers +) +{ + _Objects_Initialize_information( + &_Timer_Information, + FALSE, + maximum_timers, + sizeof( Timer_Control ) + ); +} + +/*PAGE + * + * rtems_timer_create + * + * This directive creates a timer and performs some initialization. + * + * Input parameters: + * name - timer name + * id - pointer to timer id + * + * Output parameters: + * id - timer id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_timer_create( + Objects_Name name, + Objects_Id *id +) +{ + Timer_Control *the_timer; + + if ( !_Objects_Is_name_valid( name ) ) + return ( RTEMS_INVALID_NAME ); + + _Thread_Disable_dispatch(); /* to prevent deletion */ + + the_timer = _Timer_Allocate(); + + if ( !the_timer ) { + _Thread_Enable_dispatch(); + return( RTEMS_TOO_MANY ); + } + + the_timer->the_class = TIMER_DORMANT; + + _Objects_Open( &_Timer_Information, &the_timer->Object, name ); + + *id = the_timer->Object.id; + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); +} + +/*PAGE + * + * rtems_timer_ident + * + * This directive returns the system ID associated with + * the timer name. + * + * Input parameters: + * name - user defined message queue name + * id - pointer to timer id + * + * Output parameters: + * *id - message queue id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_timer_ident( + Objects_Name name, + Objects_Id *id +) +{ + return _Objects_Name_to_id( + &_Timer_Information, + name, + RTEMS_SEARCH_LOCAL_NODE, + id + ); +} + +/*PAGE + * + * rtems_timer_cancel + * + * This directive allows a thread to cancel a timer. + * + * Input parameters: + * id - timer id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_timer_cancel( + Objects_Id id +) +{ + Timer_Control *the_timer; + Objects_Locations location; + + the_timer = _Timer_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: /* should never return this */ + return( RTEMS_INTERNAL_ERROR ); + case OBJECTS_LOCAL: + if ( !_Timer_Is_dormant_class( the_timer->the_class ) ) { + (void) _Watchdog_Remove( &the_timer->Ticker ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + _Thread_Enable_dispatch(); + return( RTEMS_INCORRECT_STATE ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_timer_delete + * + * This directive allows a thread to delete a timer. + * + * Input parameters: + * id - timer id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_timer_delete( + Objects_Id id +) +{ + Timer_Control *the_timer; + Objects_Locations location; + + the_timer = _Timer_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: /* should never return this */ + return( RTEMS_INTERNAL_ERROR ); + case OBJECTS_LOCAL: + _Objects_Close( &_Timer_Information, &the_timer->Object ); + (void) _Watchdog_Remove( &the_timer->Ticker ); + _Timer_Free( the_timer ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_timer_fire_after + * + * This directive allows a thread to start a timer. + * + * Input parameters: + * id - timer id + * ticks - interval until routine is fired + * routine - routine to schedule + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_timer_fire_after( + Objects_Id id, + rtems_interval ticks, + Timer_Service routine, + void *user_data +) +{ + Timer_Control *the_timer; + Objects_Locations location; + + if ( ticks == 0 ) + return( RTEMS_INVALID_NUMBER ); + + the_timer = _Timer_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: /* should never return this */ + return( RTEMS_INTERNAL_ERROR ); + case OBJECTS_LOCAL: + (void) _Watchdog_Remove( &the_timer->Ticker ); + the_timer->the_class = TIMER_INTERVAL; + _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); + _Watchdog_Insert_ticks( &the_timer->Ticker, + ticks, WATCHDOG_ACTIVATE_NOW ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_timer_fire_when + * + * This directive allows a thread to start a timer. + * + * Input parameters: + * id - timer id + * wall_time - time of day to fire timer + * routine - routine to schedule + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_timer_fire_when( + Objects_Id id, + rtems_time_of_day *wall_time, + Timer_Service routine, + void *user_data +) +{ + Timer_Control *the_timer; + Objects_Locations location; + rtems_status_code validate_status; + rtems_interval seconds; + + if ( !_TOD_Is_set() ) + return( RTEMS_NOT_DEFINED ); + + validate_status = _TOD_Validate( wall_time ); + if ( !rtems_is_status_successful( validate_status ) ) + return( validate_status ); + + seconds = _TOD_To_seconds( wall_time ); + if ( seconds <= _TOD_Seconds_since_epoch ) + return( RTEMS_INVALID_CLOCK ); + + the_timer = _Timer_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: /* should never return this */ + return( RTEMS_INTERNAL_ERROR ); + case OBJECTS_LOCAL: + (void) _Watchdog_Remove( &the_timer->Ticker ); + the_timer->the_class = TIMER_TIME_OF_DAY; + _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); + _Watchdog_Insert_seconds( &the_timer->Ticker, + seconds - _TOD_Seconds_since_epoch, WATCHDOG_ACTIVATE_NOW ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_timer_reset + * + * This directive allows a thread to reset a timer. + * + * Input parameters: + * id - timer id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_timer_reset( + Objects_Id id +) +{ + Timer_Control *the_timer; + Objects_Locations location; + + the_timer = _Timer_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: /* should never return this */ + return( RTEMS_INTERNAL_ERROR ); + case OBJECTS_LOCAL: + if ( _Timer_Is_interval_class( the_timer->the_class ) ) { + _Watchdog_Reset( &the_timer->Ticker ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + _Thread_Enable_dispatch(); + return( RTEMS_NOT_DEFINED ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/sem.c b/cpukit/rtems/src/sem.c new file mode 100644 index 0000000000..19410c62f1 --- /dev/null +++ b/cpukit/rtems/src/sem.c @@ -0,0 +1,483 @@ +/* + * Semaphore Manager + * + * DESCRIPTION: + * + * This package is the implementation of 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 + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Semaphore_Manager_initialization + * + * This routine initializes all semaphore manager related data structures. + * + * Input parameters: + * maximum_semaphores - maximum configured semaphores + * + * Output parameters: NONE + */ + +void _Semaphore_Manager_initialization( + unsigned32 maximum_semaphores +) +{ + _Objects_Initialize_information( + &_Semaphore_Information, + TRUE, + maximum_semaphores, + sizeof( Semaphore_Control ) + ); +} + +/*PAGE + * + * rtems_semaphore_create + * + * This directive creates a semaphore and sets the initial value based + * on the given count. A semaphore id is returned. + * + * Input parameters: + * name - user defined semaphore name + * count - initial count of semaphore + * attribute_set - semaphore attributes + * id - pointer to semaphore id + * + * Output parameters: + * id - semaphore id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_semaphore_create( + Objects_Name name, + unsigned32 count, + rtems_attribute attribute_set, + Objects_Id *id +) +{ + register Semaphore_Control *the_semaphore; + + if ( !_Objects_Is_name_valid( name ) ) + return ( RTEMS_INVALID_NAME ); + + if ( _Attributes_Is_global( attribute_set ) ) { + + if ( !_Configuration_Is_multiprocessing() ) + return( RTEMS_MP_NOT_CONFIGURED ); + + if ( _Attributes_Is_inherit_priority( attribute_set ) ) + return( RTEMS_NOT_DEFINED ); + + } else if ( _Attributes_Is_inherit_priority( attribute_set ) ) { + + if ( ! ( _Attributes_Is_binary_semaphore( attribute_set ) && + _Attributes_Is_priority( attribute_set ) ) ) + return( RTEMS_NOT_DEFINED ); + + } + + if ( _Attributes_Is_binary_semaphore( attribute_set ) && ( count > 1 ) ) + return( RTEMS_INVALID_NUMBER ); + + _Thread_Disable_dispatch(); /* prevents deletion */ + + the_semaphore = _Semaphore_Allocate(); + + if ( !the_semaphore ) { + _Thread_Enable_dispatch(); + return( RTEMS_TOO_MANY ); + } + + if ( _Attributes_Is_global( attribute_set ) && + !( _Objects_MP_Open( &_Semaphore_Information, name, + the_semaphore->Object.id, FALSE ) ) ) { + _Semaphore_Free( the_semaphore ); + _Thread_Enable_dispatch(); + return( RTEMS_TOO_MANY ); + } + + the_semaphore->attribute_set = attribute_set; + the_semaphore->count = count; + + if ( _Attributes_Is_binary_semaphore( attribute_set ) && count == 0 ) { + the_semaphore->nest_count = 1; + the_semaphore->holder = _Thread_Executing; + the_semaphore->holder_id = _Thread_Executing->Object.id; + _Thread_Executing->resource_count++; + } else { + the_semaphore->nest_count = 0; + the_semaphore->holder = NULL; + the_semaphore->holder_id = 0; + } + + _Thread_queue_Initialize( &the_semaphore->Wait_queue, + attribute_set, STATES_WAITING_FOR_SEMAPHORE ); + + _Objects_Open( &_Semaphore_Information, &the_semaphore->Object, name ); + + *id = the_semaphore->Object.id; + + if ( _Attributes_Is_global( attribute_set ) ) + _Semaphore_MP_Send_process_packet( + SEMAPHORE_MP_ANNOUNCE_CREATE, + the_semaphore->Object.id, + name, + 0 /* Not used */ + ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); +} + +/*PAGE + * + * rtems_semaphore_ident + * + * This directive returns the system ID associated with + * the semaphore name. + * + * Input parameters: + * name - user defined semaphore name + * node - node(s) to be searched + * id - pointer to semaphore id + * + * Output parameters: + * *id - semaphore id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_semaphore_ident( + Objects_Name name, + unsigned32 node, + Objects_Id *id +) +{ + return( _Objects_Name_to_id( &_Semaphore_Information, name, node, id ) ); +} + +/*PAGE + * + * rtems_semaphore_delete + * + * This directive allows a thread to delete a semaphore specified by + * the semaphore id. The semaphore is freed back to the inactive + * semaphore chain. + * + * Input parameters: + * id - semaphore id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_semaphore_delete( + Objects_Id id +) +{ + register Semaphore_Control *the_semaphore; + Objects_Locations location; + + the_semaphore = _Semaphore_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + _Thread_Dispatch(); + return( RTEMS_ILLEGAL_ON_REMOTE_OBJECT ); + case OBJECTS_LOCAL: + if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set) && + ( the_semaphore->count == 0 ) ) { + _Thread_Enable_dispatch(); + return( RTEMS_RESOURCE_IN_USE ); + } + + _Objects_Close( &_Semaphore_Information, &the_semaphore->Object ); + + _Thread_queue_Flush( + &the_semaphore->Wait_queue, + _Semaphore_MP_Send_object_was_deleted + ); + + _Semaphore_Free( the_semaphore ); + + if ( _Attributes_Is_global( the_semaphore->attribute_set ) ) { + + _Objects_MP_Close( &_Semaphore_Information, the_semaphore->Object.id ); + + _Semaphore_MP_Send_process_packet( + SEMAPHORE_MP_ANNOUNCE_DELETE, + the_semaphore->Object.id, + 0, /* Not used */ + 0 /* Not used */ + ); + } + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_semaphore_obtain + * + * This directive allows a thread to acquire a semaphore. + * + * Input parameters: + * id - semaphore id + * option_set - wait option + * timeout - number of ticks to wait (0 means wait forever) + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_semaphore_obtain( + Objects_Id id, + unsigned32 option_set, + rtems_interval timeout +) +{ + register Semaphore_Control *the_semaphore; + Objects_Locations location; + + the_semaphore = _Semaphore_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + return _Semaphore_MP_Send_request_packet( + SEMAPHORE_MP_OBTAIN_REQUEST, + id, + option_set, + timeout + ); + case OBJECTS_LOCAL: + if ( !_Semaphore_Seize( the_semaphore, option_set ) ) { + if ( _Attributes_Is_inherit_priority( the_semaphore->attribute_set ) && + the_semaphore->holder->current_priority > + _Thread_Executing->current_priority ) { + _Thread_Change_priority( + the_semaphore->holder, _Thread_Executing->current_priority ); + } + _Thread_queue_Enqueue( &the_semaphore->Wait_queue, timeout ); + } + _Thread_Enable_dispatch(); + return( _Thread_Executing->Wait.return_code ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_semaphore_release + * + * This directive allows a thread to release a semaphore. + * + * Input parameters: + * id - semaphore id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_semaphore_release( + Objects_Id id +) +{ + register Semaphore_Control *the_semaphore; + Objects_Locations location; + Thread_Control *the_thread; + + the_semaphore = _Semaphore_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + return( + _Semaphore_MP_Send_request_packet( + SEMAPHORE_MP_RELEASE_REQUEST, + id, + 0, /* Not used */ + MPCI_DEFAULT_TIMEOUT + ) + ); + case OBJECTS_LOCAL: + if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set)) { + + if ( !_Objects_Are_ids_equal( + _Thread_Executing->Object.id, the_semaphore->holder_id ) ) { + _Thread_Enable_dispatch(); + return( RTEMS_NOT_OWNER_OF_RESOURCE ); + } + + the_semaphore->nest_count--; + + if ( the_semaphore->nest_count != 0 ) { + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + _Thread_Executing->resource_count--; + the_semaphore->holder = NULL; + the_semaphore->holder_id = 0; + + /* + * Whether or not someone is waiting for the semaphore, an + * inherited priority must be lowered if this is the last + * semaphore (i.e. resource) this task has. + */ + + if ( _Attributes_Is_inherit_priority(the_semaphore->attribute_set) && + _Thread_Executing->resource_count == 0 && + _Thread_Executing->real_priority != + _Thread_Executing->current_priority ) { + _Thread_Change_priority( + _Thread_Executing, _Thread_Executing->real_priority ); + } + + } + + if ( (the_thread = _Thread_queue_Dequeue(&the_semaphore->Wait_queue)) ) { + + if ( !_Objects_Is_local_id( the_thread->Object.id ) ) { + the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL; + + if ( _Attributes_Is_binary_semaphore(the_semaphore->attribute_set) ) { + the_semaphore->holder = NULL; + the_semaphore->holder_id = the_thread->Object.id; + the_semaphore->nest_count = 1; + } + + _Semaphore_MP_Send_response_packet( + SEMAPHORE_MP_OBTAIN_RESPONSE, + id, + the_thread + ); + } else { + + if ( _Attributes_Is_binary_semaphore(the_semaphore->attribute_set) ) { + the_semaphore->holder = the_thread; + the_semaphore->holder_id = the_thread->Object.id; + the_thread->resource_count++; + the_semaphore->nest_count = 1; + } + + /* + * No special action for priority inheritance because the_thread + * is guaranteed to be the highest priority thread waiting for + * the semaphore. + */ + } + } else + the_semaphore->count += 1; + + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * _Semaphore_Seize + * + * This routine attempts to allocate a semaphore to the calling thread. + * + * Input parameters: + * the_semaphore - pointer to semaphore control block + * option_set - acquire semaphore options + * + * Output parameters: + * TRUE - if semaphore allocated + * FALSE - if semaphore NOT allocated + * + * INTERRUPT LATENCY: + * available + * wait + */ + +boolean _Semaphore_Seize( + Semaphore_Control *the_semaphore, + rtems_option option_set +) +{ + Thread_Control *executing; + ISR_Level level; + + executing = _Thread_Executing; + executing->Wait.return_code = RTEMS_SUCCESSFUL; + _ISR_Disable( level ); + if ( the_semaphore->count != 0 ) { + the_semaphore->count -= 1; + if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set ) ) { + the_semaphore->holder = executing; + the_semaphore->holder_id = executing->Object.id; + the_semaphore->nest_count = 1; + executing->resource_count++; + } + _ISR_Enable( level ); + return( TRUE ); + } + + if ( _Options_Is_no_wait( option_set ) ) { + _ISR_Enable( level ); + executing->Wait.return_code = RTEMS_UNSATISFIED; + return( TRUE ); + } + + if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set ) ) { + if ( _Objects_Are_ids_equal( + _Thread_Executing->Object.id, the_semaphore->holder_id ) ) { + the_semaphore->nest_count++; + _ISR_Enable( level ); + return( TRUE ); + } + } + + the_semaphore->Wait_queue.sync = TRUE; + executing->Wait.queue = &the_semaphore->Wait_queue; + executing->Wait.id = the_semaphore->Object.id; + executing->Wait.option_set = option_set; + _ISR_Enable( level ); + return( FALSE ); +} diff --git a/cpukit/rtems/src/semmp.c b/cpukit/rtems/src/semmp.c new file mode 100644 index 0000000000..d131d48150 --- /dev/null +++ b/cpukit/rtems/src/semmp.c @@ -0,0 +1,306 @@ +/* + * Multiprocessing Support for the Semaphore Manager + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Semaphore_MP_Send_process_packet + * + */ + +void _Semaphore_MP_Send_process_packet ( + Semaphore_MP_Remote_operations operation, + Objects_Id semaphore_id, + Objects_Name name, + Objects_Id proxy_id +) +{ + Semaphore_MP_Packet *the_packet; + unsigned32 node; + + switch ( operation ) { + + case SEMAPHORE_MP_ANNOUNCE_CREATE: + case SEMAPHORE_MP_ANNOUNCE_DELETE: + case SEMAPHORE_MP_EXTRACT_PROXY: + + the_packet = _Semaphore_MP_Get_packet(); + the_packet->Prefix.the_class = RTEMS_MP_PACKET_SEMAPHORE; + the_packet->Prefix.length = sizeof ( Semaphore_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Semaphore_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = semaphore_id; + the_packet->name = name; + the_packet->proxy_id = proxy_id; + + if ( operation == SEMAPHORE_MP_EXTRACT_PROXY ) + node = rtems_get_node( semaphore_id ); + else + node = MPCI_ALL_NODES; + + _MPCI_Send_process_packet( node, &the_packet->Prefix ); + break; + + case SEMAPHORE_MP_OBTAIN_REQUEST: + case SEMAPHORE_MP_OBTAIN_RESPONSE: + case SEMAPHORE_MP_RELEASE_REQUEST: + case SEMAPHORE_MP_RELEASE_RESPONSE: + break; + } +} + +/*PAGE + * + * _Semaphore_MP_Send_request_packet + * + */ + +rtems_status_code _Semaphore_MP_Send_request_packet ( + Semaphore_MP_Remote_operations operation, + Objects_Id semaphore_id, + rtems_option option_set, + rtems_interval timeout +) +{ + Semaphore_MP_Packet *the_packet; + + switch ( operation ) { + + case SEMAPHORE_MP_OBTAIN_REQUEST: + case SEMAPHORE_MP_RELEASE_REQUEST: + + the_packet = _Semaphore_MP_Get_packet(); + the_packet->Prefix.the_class = RTEMS_MP_PACKET_SEMAPHORE; + the_packet->Prefix.length = sizeof ( Semaphore_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Semaphore_MP_Packet ); + if ( ! _Options_Is_no_wait(option_set)) + the_packet->Prefix.timeout = timeout; + + the_packet->operation = operation; + the_packet->Prefix.id = semaphore_id; + the_packet->option_set = option_set; + + return _MPCI_Send_request_packet( + rtems_get_node( semaphore_id ), + &the_packet->Prefix, + STATES_WAITING_FOR_SEMAPHORE + ); + break; + + case SEMAPHORE_MP_ANNOUNCE_CREATE: + case SEMAPHORE_MP_ANNOUNCE_DELETE: + case SEMAPHORE_MP_EXTRACT_PROXY: + case SEMAPHORE_MP_OBTAIN_RESPONSE: + case SEMAPHORE_MP_RELEASE_RESPONSE: + break; + + } + /* + * The following line is included to satisfy compilers which + * produce warnings when a function does not end with a return. + */ + return RTEMS_SUCCESSFUL; +} + +/*PAGE + * + * _Semaphore_MP_Send_response_packet + * + */ + +void _Semaphore_MP_Send_response_packet ( + Semaphore_MP_Remote_operations operation, + Objects_Id semaphore_id, + Thread_Control *the_thread +) +{ + Semaphore_MP_Packet *the_packet; + + switch ( operation ) { + + case SEMAPHORE_MP_OBTAIN_RESPONSE: + case SEMAPHORE_MP_RELEASE_RESPONSE: + + the_packet = ( Semaphore_MP_Packet *) the_thread->receive_packet; + +/* + * The packet being returned already contains the class, length, and + * to_convert fields, therefore they are not set in this routine. + */ + the_packet->operation = operation; + the_packet->Prefix.id = the_packet->Prefix.source_tid; + + _MPCI_Send_response_packet( + rtems_get_node( the_packet->Prefix.source_tid ), + &the_packet->Prefix + ); + break; + + case SEMAPHORE_MP_ANNOUNCE_CREATE: + case SEMAPHORE_MP_ANNOUNCE_DELETE: + case SEMAPHORE_MP_EXTRACT_PROXY: + case SEMAPHORE_MP_OBTAIN_REQUEST: + case SEMAPHORE_MP_RELEASE_REQUEST: + break; + + } +} + +/*PAGE + * + * + * _Semaphore_MP_Process_packet + * + */ + +void _Semaphore_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +) +{ + Semaphore_MP_Packet *the_packet; + Thread_Control *the_thread; + boolean ignored; + + the_packet = (Semaphore_MP_Packet *) the_packet_prefix; + + switch ( the_packet->operation ) { + + case SEMAPHORE_MP_ANNOUNCE_CREATE: + + ignored = _Objects_MP_Open( + &_Semaphore_Information, + the_packet->name, + the_packet->Prefix.id, + TRUE + ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case SEMAPHORE_MP_ANNOUNCE_DELETE: + + _Objects_MP_Close( &_Semaphore_Information, the_packet->Prefix.id ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case SEMAPHORE_MP_EXTRACT_PROXY: + + the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id ); + + if ( ! _Thread_Is_null( the_thread ) ) + _Thread_queue_Extract( the_thread->Wait.queue, the_thread ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case SEMAPHORE_MP_OBTAIN_REQUEST: + + the_packet->Prefix.return_code = rtems_semaphore_obtain( + the_packet->Prefix.id, + the_packet->option_set, + the_packet->Prefix.timeout + ); + + if ( ! _Status_Is_proxy_blocking( the_packet->Prefix.return_code ) ) + _Semaphore_MP_Send_response_packet( + SEMAPHORE_MP_OBTAIN_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + + case SEMAPHORE_MP_OBTAIN_RESPONSE: + case SEMAPHORE_MP_RELEASE_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case SEMAPHORE_MP_RELEASE_REQUEST: + + the_packet->Prefix.return_code = rtems_semaphore_release( + the_packet->Prefix.id + ); + + _Semaphore_MP_Send_response_packet( + SEMAPHORE_MP_RELEASE_RESPONSE, + the_packet->Prefix.id, + _Thread_Executing + ); + break; + } +} + +/*PAGE + * + * _Semaphore_MP_Send_object_was_deleted + * + */ + +void _Semaphore_MP_Send_object_was_deleted ( + Thread_Control *the_proxy +) +{ + the_proxy->receive_packet->return_code = RTEMS_OBJECT_WAS_DELETED; + + _Semaphore_MP_Send_response_packet( + SEMAPHORE_MP_OBTAIN_RESPONSE, + the_proxy->Wait.id, + the_proxy + ); + +} + +/*PAGE + * + * _Semaphore_MP_Send_extract_proxy + * + */ + +void _Semaphore_MP_Send_extract_proxy ( + Thread_Control *the_thread +) +{ + _Semaphore_MP_Send_process_packet( + SEMAPHORE_MP_EXTRACT_PROXY, + the_thread->Wait.id, + (Objects_Name) 0, + the_thread->Object.id + ); + +} + +/*PAGE + * + * _Semaphore_MP_Get_packet + * + */ + +Semaphore_MP_Packet *_Semaphore_MP_Get_packet ( void ) +{ + return ( (Semaphore_MP_Packet *) _MPCI_Get_packet() ); +} + +/* end of file */ diff --git a/cpukit/rtems/src/signal.c b/cpukit/rtems/src/signal.c new file mode 100644 index 0000000000..411df5d86c --- /dev/null +++ b/cpukit/rtems/src/signal.c @@ -0,0 +1,110 @@ +/* + * Signal Manager + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_signal_catch + * + * This directive allows a thread to specify what action to take when + * catching signals. + * + * Input parameters: + * handler - address of asynchronous signal routine (asr) + * ( NULL indicates asr is invalid ) + * mode_set - mode value for asr + * + * Output parameters: + * RTEMS_SUCCESSFUL - always succeeds + */ + +rtems_status_code rtems_signal_catch( + rtems_asr_entry handler, + rtems_mode mode_set +) +{ + Thread_Control *executing; + + executing = _Thread_Executing; + _Thread_Disable_dispatch(); /* cannot reschedule while */ + /* the thread is inconsistent */ + + if ( ! _ASR_Is_null_handler( handler ) ) { + executing->Signal.mode_set = mode_set; + executing->Signal.handler = handler; + } + else + _ASR_Initialize( &executing->Signal ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); +} + +/*PAGE + * + * rtems_signal_send + * + * This directive allows a thread to send signals to a thread. + * + * Input parameters: + * id - thread id + * signal_set - signal set + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_signal_send( + Objects_Id id, + rtems_signal_set signal_set +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + return _Signal_MP_Send_request_packet( + SIGNAL_MP_SEND_REQUEST, + id, + signal_set + ); + case OBJECTS_LOCAL: + if ( ! _ASR_Is_null_handler( the_thread->Signal.handler ) ) { + if ( _Modes_Is_asr_disabled( the_thread->current_modes ) ) + _ASR_Post_signals( signal_set, &the_thread->Signal.signals_pending ); + else { + _ASR_Post_signals( signal_set, &the_thread->Signal.signals_posted ); + if ( _ISR_Is_in_progress() && _Thread_Is_executing( the_thread ) ) + _ISR_Signals_to_thread_executing = TRUE; + } + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + _Thread_Enable_dispatch(); + return( RTEMS_NOT_DEFINED ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/signalmp.c b/cpukit/rtems/src/signalmp.c new file mode 100644 index 0000000000..4ac8123766 --- /dev/null +++ b/cpukit/rtems/src/signalmp.c @@ -0,0 +1,187 @@ +/* + * Multiprocessing Support for the Signal Manager + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Signal_MP_Send_process_packet + * + * This subprogram is not needed since there are no process + * packets to be sent by this manager. + * + */ + +/*PAGE + * + * _Signal_MP_Send_request_packet + * + */ + +rtems_status_code _Signal_MP_Send_request_packet ( + Signal_MP_Remote_operations operation, + Objects_Id task_id, + rtems_signal_set signal_in +) +{ + Signal_MP_Packet *the_packet; + + switch ( operation ) { + + case SIGNAL_MP_SEND_REQUEST: + + the_packet = _Signal_MP_Get_packet(); + the_packet->Prefix.the_class = RTEMS_MP_PACKET_SIGNAL; + the_packet->Prefix.length = sizeof ( Signal_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( Signal_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = task_id; + the_packet->signal_in = signal_in; + + return _MPCI_Send_request_packet( + rtems_get_node( task_id ), + &the_packet->Prefix, + STATES_READY /* Not used */ + ); + break; + + case SIGNAL_MP_SEND_RESPONSE: + break; + + } + /* + * The following line is included to satisfy compilers which + * produce warnings when a function does not end with a return. + */ + return RTEMS_INTERNAL_ERROR; +} + +/*PAGE + * + * _Signal_MP_Send_response_packet + * + */ + +void _Signal_MP_Send_response_packet ( + Signal_MP_Remote_operations operation, + Thread_Control *the_thread +) +{ + Signal_MP_Packet *the_packet; + + switch ( operation ) { + + case SIGNAL_MP_SEND_RESPONSE: + + the_packet = ( Signal_MP_Packet *) the_thread->receive_packet; + +/* + * The packet being returned already contains the class, length, and + * to_convert fields, therefore they are not set in this routine. + */ + the_packet->operation = operation; + the_packet->Prefix.id = the_packet->Prefix.source_tid; + + _MPCI_Send_response_packet( + rtems_get_node( the_packet->Prefix.source_tid ), + &the_packet->Prefix + ); + break; + + case SIGNAL_MP_SEND_REQUEST: + break; + + } +} + +/*PAGE + * + * + * _Signal_MP_Process_packet + * + */ + +void _Signal_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +) +{ + Signal_MP_Packet *the_packet; + Thread_Control *the_thread; + + the_packet = (Signal_MP_Packet *) the_packet_prefix; + + switch ( the_packet->operation ) { + + case SIGNAL_MP_SEND_REQUEST: + + the_packet->Prefix.return_code = rtems_signal_send( + the_packet->Prefix.id, + the_packet->signal_in + ); + + _Signal_MP_Send_response_packet( + SIGNAL_MP_SEND_RESPONSE, + _Thread_Executing + ); + break; + + case SIGNAL_MP_SEND_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + } +} + +/*PAGE + * + * _Signal_MP_Send_object_was_deleted + * + * This subprogram is not needed since there are no objects + * deleted by this manager. + * + */ + +/*PAGE + * + * _Signal_MP_Send_extract_proxy + * + * This subprogram is not needed since there are no objects + * deleted by this manager. + * + */ + +/*PAGE + * + * _Signal_MP_Get_packet + * + */ + +Signal_MP_Packet *_Signal_MP_Get_packet ( void ) +{ + return ( (Signal_MP_Packet *) _MPCI_Get_packet() ); +} + +/* end of file */ diff --git a/cpukit/rtems/src/taskmp.c b/cpukit/rtems/src/taskmp.c new file mode 100644 index 0000000000..b938c60c53 --- /dev/null +++ b/cpukit/rtems/src/taskmp.c @@ -0,0 +1,338 @@ +/* + * Multiprocessing Support for the RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _RTEMS_tasks_MP_Send_process_packet + * + */ + +void _RTEMS_tasks_MP_Send_process_packet ( + RTEMS_tasks_MP_Remote_operations operation, + Objects_Id task_id, + Objects_Name name +) +{ + RTEMS_tasks_MP_Packet *the_packet; + + switch ( operation ) { + + case RTEMS_TASKS_MP_ANNOUNCE_CREATE: + case RTEMS_TASKS_MP_ANNOUNCE_DELETE: + + the_packet = _RTEMS_tasks_MP_Get_packet(); + the_packet->Prefix.the_class = RTEMS_MP_PACKET_TASKS; + the_packet->Prefix.length = sizeof ( RTEMS_tasks_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( RTEMS_tasks_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = task_id; + the_packet->name = name; + + _MPCI_Send_process_packet( MPCI_ALL_NODES, &the_packet->Prefix ); + break; + + case RTEMS_TASKS_MP_SUSPEND_REQUEST: + case RTEMS_TASKS_MP_SUSPEND_RESPONSE: + case RTEMS_TASKS_MP_RESUME_REQUEST: + case RTEMS_TASKS_MP_RESUME_RESPONSE: + case RTEMS_TASKS_MP_SET_PRIORITY_REQUEST: + case RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE: + case RTEMS_TASKS_MP_GET_NOTE_REQUEST: + case RTEMS_TASKS_MP_GET_NOTE_RESPONSE: + case RTEMS_TASKS_MP_SET_NOTE_REQUEST: + case RTEMS_TASKS_MP_SET_NOTE_RESPONSE: + break; + } +} + +/*PAGE + * + * _RTEMS_tasks_MP_Send_request_packet + * + */ + +rtems_status_code _RTEMS_tasks_MP_Send_request_packet ( + RTEMS_tasks_MP_Remote_operations operation, + Objects_Id task_id, + rtems_task_priority new_priority, + unsigned32 notepad, + unsigned32 note +) +{ + RTEMS_tasks_MP_Packet *the_packet; + + switch ( operation ) { + + case RTEMS_TASKS_MP_SUSPEND_REQUEST: + case RTEMS_TASKS_MP_RESUME_REQUEST: + case RTEMS_TASKS_MP_SET_PRIORITY_REQUEST: + case RTEMS_TASKS_MP_GET_NOTE_REQUEST: + case RTEMS_TASKS_MP_SET_NOTE_REQUEST: + + the_packet = _RTEMS_tasks_MP_Get_packet(); + the_packet->Prefix.the_class = RTEMS_MP_PACKET_TASKS; + the_packet->Prefix.length = sizeof ( RTEMS_tasks_MP_Packet ); + the_packet->Prefix.to_convert = sizeof ( RTEMS_tasks_MP_Packet ); + the_packet->operation = operation; + the_packet->Prefix.id = task_id; + the_packet->the_priority = new_priority; + the_packet->notepad = notepad; + the_packet->note = note; + + return _MPCI_Send_request_packet( + rtems_get_node( task_id ), + &the_packet->Prefix, + STATES_READY /* Not used */ + ); + break; + + case RTEMS_TASKS_MP_ANNOUNCE_CREATE: + case RTEMS_TASKS_MP_ANNOUNCE_DELETE: + case RTEMS_TASKS_MP_SUSPEND_RESPONSE: + case RTEMS_TASKS_MP_RESUME_RESPONSE: + case RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE: + case RTEMS_TASKS_MP_GET_NOTE_RESPONSE: + case RTEMS_TASKS_MP_SET_NOTE_RESPONSE: + break; + + } + /* + * The following line is included to satisfy compilers which + * produce warnings when a function does not end with a return. + */ + return RTEMS_SUCCESSFUL; +} + +/*PAGE + * + * _RTEMS_tasks_MP_Send_response_packet + * + */ + +void _RTEMS_tasks_MP_Send_response_packet ( + RTEMS_tasks_MP_Remote_operations operation, + Thread_Control *the_thread +) +{ + RTEMS_tasks_MP_Packet *the_packet; + + switch ( operation ) { + + case RTEMS_TASKS_MP_SUSPEND_RESPONSE: + case RTEMS_TASKS_MP_RESUME_RESPONSE: + case RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE: + case RTEMS_TASKS_MP_GET_NOTE_RESPONSE: + case RTEMS_TASKS_MP_SET_NOTE_RESPONSE: + + the_packet = (RTEMS_tasks_MP_Packet *) the_thread->receive_packet; + +/* + * The packet being returned already contains the class, length, and + * to_convert fields, therefore they are not set in this routine. + */ + the_packet->operation = operation; + the_packet->Prefix.id = the_packet->Prefix.source_tid; + + _MPCI_Send_response_packet( + rtems_get_node( the_packet->Prefix.source_tid ), + &the_packet->Prefix + ); + break; + + case RTEMS_TASKS_MP_ANNOUNCE_CREATE: + case RTEMS_TASKS_MP_ANNOUNCE_DELETE: + case RTEMS_TASKS_MP_SUSPEND_REQUEST: + case RTEMS_TASKS_MP_RESUME_REQUEST: + case RTEMS_TASKS_MP_SET_PRIORITY_REQUEST: + case RTEMS_TASKS_MP_GET_NOTE_REQUEST: + case RTEMS_TASKS_MP_SET_NOTE_REQUEST: + break; + + } +} + +/*PAGE + * + * + * _RTEMS_tasks_MP_Process_packet + * + */ + +void _RTEMS_tasks_MP_Process_packet ( + rtems_packet_prefix *the_packet_prefix +) +{ + RTEMS_tasks_MP_Packet *the_packet; + Thread_Control *the_thread; + boolean ignored; + + the_packet = (RTEMS_tasks_MP_Packet *) the_packet_prefix; + + switch ( the_packet->operation ) { + + case RTEMS_TASKS_MP_ANNOUNCE_CREATE: + + ignored = _Objects_MP_Open( + &_Thread_Information, + the_packet->name, + the_packet->Prefix.id, + TRUE + ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case RTEMS_TASKS_MP_ANNOUNCE_DELETE: + + _Objects_MP_Close( &_Thread_Information, the_packet->Prefix.id ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case RTEMS_TASKS_MP_SUSPEND_REQUEST: + + the_packet->Prefix.return_code = rtems_task_suspend( + the_packet->Prefix.id + ); + + _RTEMS_tasks_MP_Send_response_packet( + RTEMS_TASKS_MP_SUSPEND_RESPONSE, + _Thread_Executing + ); + break; + + case RTEMS_TASKS_MP_SUSPEND_RESPONSE: + case RTEMS_TASKS_MP_RESUME_RESPONSE: + case RTEMS_TASKS_MP_SET_NOTE_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case RTEMS_TASKS_MP_RESUME_REQUEST: + + the_packet->Prefix.return_code = rtems_task_resume( + the_packet->Prefix.id + ); + + _RTEMS_tasks_MP_Send_response_packet( + RTEMS_TASKS_MP_RESUME_RESPONSE, + _Thread_Executing + ); + break; + + case RTEMS_TASKS_MP_SET_PRIORITY_REQUEST: + + the_packet->Prefix.return_code = rtems_task_set_priority( + the_packet->Prefix.id, + the_packet->the_priority, + &the_packet->the_priority + ); + + _RTEMS_tasks_MP_Send_response_packet( + RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE, + _Thread_Executing + ); + break; + + case RTEMS_TASKS_MP_SET_PRIORITY_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + *(rtems_task_priority *)the_thread->Wait.return_argument = + the_packet->the_priority; + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case RTEMS_TASKS_MP_GET_NOTE_REQUEST: + + the_packet->Prefix.return_code = rtems_task_get_note( + the_packet->Prefix.id, + the_packet->notepad, + &the_packet->note + ); + + _RTEMS_tasks_MP_Send_response_packet( + RTEMS_TASKS_MP_GET_NOTE_RESPONSE, + _Thread_Executing + ); + break; + + case RTEMS_TASKS_MP_GET_NOTE_RESPONSE: + + the_thread = _MPCI_Process_response( the_packet_prefix ); + + *(unsigned32 *)the_thread->Wait.return_argument = the_packet->note; + + _MPCI_Return_packet( the_packet_prefix ); + break; + + case RTEMS_TASKS_MP_SET_NOTE_REQUEST: + + the_packet->Prefix.return_code = rtems_task_set_note( + the_packet->Prefix.id, + the_packet->notepad, + the_packet->note + ); + + _RTEMS_tasks_MP_Send_response_packet( + RTEMS_TASKS_MP_SET_NOTE_RESPONSE, + _Thread_Executing + ); + break; + } +} + +/*PAGE + * + * _RTEMS_tasks_MP_Send_object_was_deleted + * + * This routine is not neededby the Tasks since a task + * cannot be globally deleted. + * + */ + +/*PAGE + * + * _RTEMS_tasks_MP_Send_extract_proxy + * + * This routine is not neededby the Tasks since a task + * cannot be globally deleted. + * + */ + +/*PAGE + * + * _RTEMS_tasks_MP_Get_packet + * + */ + +RTEMS_tasks_MP_Packet *_RTEMS_tasks_MP_Get_packet ( void ) +{ + return ( (RTEMS_tasks_MP_Packet *) _MPCI_Get_packet() ); +} + +/* end of file */ diff --git a/cpukit/rtems/src/tasks.c b/cpukit/rtems/src/tasks.c new file mode 100644 index 0000000000..edba524d94 --- /dev/null +++ b/cpukit/rtems/src/tasks.c @@ -0,0 +1,816 @@ +/* + * RTEMS Task Manager + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_task_create + * + * This directive creates a thread by allocating and initializing a + * thread control block and a stack. The newly created thread is + * placed in the dormant state. + * + * Input parameters: + * name - user defined thread name + * initial_priority - thread priority + * stack_size - stack size in bytes + * initial_modes - initial thread mode + * attribute_set - thread attributes + * id - pointer to thread id + * + * Output parameters: + * id - thread id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_create( + Objects_Name name, + rtems_task_priority initial_priority, + unsigned32 stack_size, + rtems_mode initial_modes, + rtems_attribute attribute_set, + Objects_Id *id +) +{ + register Thread_Control *the_thread; + unsigned32 actual_stack_size; + unsigned32 memory_needed; + void *memory; + rtems_attribute the_attribute_set; + + if ( !_Objects_Is_name_valid( name ) ) + return ( RTEMS_INVALID_NAME ); + +#if 0 + if ( !_Stack_Is_enough( stack_size ) ) + return( RTEMS_INVALID_SIZE ); +#endif + + if ( !_Stack_Is_enough( stack_size ) ) + actual_stack_size = RTEMS_MINIMUM_STACK_SIZE; + else + actual_stack_size = stack_size; + + if ( !_Priority_Is_valid( initial_priority ) ) + return( RTEMS_INVALID_PRIORITY ); + + /* + * Fix the attribute set to match the attributes which + * this processor (1) requires and (2) is able to support. + * First add in the required flags for attribute_set + * Typically this might include FP if the platform + * or application required all tasks to be fp aware. + * Then turn off the requested bits which are not supported. + */ + + the_attribute_set = _Attributes_Set( attribute_set, ATTRIBUTES_REQUIRED ); + the_attribute_set = + _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED ); + + if ( _Attributes_Is_global( the_attribute_set ) && + !_Configuration_Is_multiprocessing() ) + return( RTEMS_MP_NOT_CONFIGURED ); + + _Thread_Disable_dispatch(); /* to prevent deletion */ + + the_thread = _RTEMS_tasks_Allocate(); + + if ( !the_thread ) { + _Thread_Enable_dispatch(); + return( RTEMS_TOO_MANY ); + } + + actual_stack_size = _Stack_Adjust_size( actual_stack_size ); + memory_needed = actual_stack_size; + + if ( _Attributes_Is_floating_point( the_attribute_set ) ) + memory_needed += CONTEXT_FP_SIZE; + + memory = _Workspace_Allocate( memory_needed ); + + if ( !memory ) { + _RTEMS_tasks_Free( the_thread ); + _Thread_Enable_dispatch(); + return( RTEMS_UNSATISFIED ); + } + + /* + * Stack is put in the lower address regions of the allocated memory. + * The optional floating point context area goes into the higher part + * of the allocated memory. + */ + + _Stack_Initialize( + &the_thread->Start.Initial_stack, memory, actual_stack_size ); + + if ( _Attributes_Is_floating_point( the_attribute_set ) ) + the_thread->fp_context = _Context_Fp_start( memory, actual_stack_size ); + else + the_thread->fp_context = NULL; + + the_thread->Start.fp_context = the_thread->fp_context; + + if ( _Attributes_Is_global( the_attribute_set ) && + !( _Objects_MP_Open( &_Thread_Information, name, + the_thread->Object.id, FALSE ) ) ) { + _RTEMS_tasks_Free( the_thread ); + (void) _Workspace_Free( memory ); + _Thread_Enable_dispatch(); + return( RTEMS_TOO_MANY ); + } + + the_thread->name = name; + the_thread->attribute_set = the_attribute_set; + the_thread->current_state = STATES_DORMANT; + the_thread->current_modes = initial_modes; + the_thread->pending_events = EVENT_SETS_NONE_PENDING; + the_thread->resource_count = 0; + the_thread->real_priority = initial_priority; + the_thread->Start.initial_priority = initial_priority; + the_thread->Start.initial_modes = initial_modes; + + _Thread_Set_priority( the_thread, initial_priority ); + + _ASR_Initialize( &the_thread->Signal ); + + _Objects_Open( &_Thread_Information, &the_thread->Object, name ); + + *id = the_thread->Object.id; + + _User_extensions_Task_create( the_thread ); + + if ( _Attributes_Is_global( the_attribute_set ) ) + _RTEMS_tasks_MP_Send_process_packet( + RTEMS_TASKS_MP_ANNOUNCE_CREATE, + the_thread->Object.id, + name + ); + + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); +} + +/*PAGE + * + * rtems_task_ident + * + * This directive returns the system ID associated with + * the thread name. + * + * Input parameters: + * name - user defined thread name + * node - node(s) to be searched + * id - pointer to thread id + * + * Output parameters: + * *id - thread id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_ident( + Objects_Name name, + unsigned32 node, + Objects_Id *id +) +{ + if ( name != OBJECTS_ID_OF_SELF ) + return( _Objects_Name_to_id( &_Thread_Information, name, node, id ) ); + + *id = _Thread_Executing->Object.id; + return( RTEMS_SUCCESSFUL ); +} + +/*PAGE + * + * rtems_task_start + * + * This directive readies the thread identified by the "id" + * based on its current priorty, to await execution. A thread + * can be started only from the dormant state. + * + * Input parameters: + * id - thread id + * entry_point - start execution address of thread + * argument - thread argument + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_start( + Objects_Id id, + rtems_task_entry entry_point, + unsigned32 argument +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + if ( entry_point == NULL ) + return( RTEMS_INVALID_ADDRESS ); + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + _Thread_Dispatch(); + return( RTEMS_ILLEGAL_ON_REMOTE_OBJECT ); + case OBJECTS_LOCAL: + if ( _States_Is_dormant( the_thread->current_state ) ) { + + the_thread->Start.entry_point = entry_point; + the_thread->Start.initial_argument = argument; + + _Thread_Load_environment( the_thread ); + + _Thread_Ready( the_thread ); + + _User_extensions_Task_start( the_thread ); + + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + _Thread_Enable_dispatch(); + return( RTEMS_INCORRECT_STATE ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_task_restart + * + * This directive readies the specified thread. It restores + * the thread environment to the original values established + * at thread creation and start time. A thread can be restarted + * from any state except the dormant state. + * + * Input parameters: + * id - thread id + * argument - thread argument + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_restart( + Objects_Id id, + unsigned32 argument +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + _Thread_Dispatch(); + return( RTEMS_ILLEGAL_ON_REMOTE_OBJECT ); + case OBJECTS_LOCAL: + if ( !_States_Is_dormant( the_thread->current_state ) ) { + + _Thread_Set_transient( the_thread ); + _ASR_Initialize( &the_thread->Signal ); + the_thread->pending_events = EVENT_SETS_NONE_PENDING; + the_thread->resource_count = 0; + the_thread->current_modes = the_thread->Start.initial_modes; + the_thread->Start.initial_argument = argument; + + _RTEMS_tasks_Cancel_wait( the_thread ); + + if ( the_thread->current_priority != + the_thread->Start.initial_priority ) { + the_thread->real_priority = the_thread->Start.initial_priority; + _Thread_Set_priority( the_thread, + the_thread->Start.initial_priority ); + } + + _Thread_Load_environment( the_thread ); + + _Thread_Ready( the_thread ); + + _User_extensions_Task_restart( the_thread ); + + if ( _Thread_Is_executing ( the_thread ) ) + _Thread_Restart_self(); + + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + _Thread_Enable_dispatch(); + return( RTEMS_INCORRECT_STATE ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_task_delete + * + * This directive allows a thread to delete itself or the thread + * identified in the id field. The executive halts execution + * of the thread and frees the thread control block. + * + * Input parameters: + * id - thread id + * + * Output parameters: + * nothing - if id is the requesting thread (always succeeds) + * RTEMS_SUCCESSFUL - if successful and id is + * not the requesting thread + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_delete( + Objects_Id id +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + _Thread_Dispatch(); + return( RTEMS_ILLEGAL_ON_REMOTE_OBJECT ); + case OBJECTS_LOCAL: + _Objects_Close( &_Thread_Information, &the_thread->Object ); + + _Thread_Set_state( the_thread, STATES_TRANSIENT ); + + _User_extensions_Task_delete( the_thread ); + +#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE ) + if ( _Thread_Is_allocated_fp( the_thread ) ) + _Thread_Deallocate_fp(); +#endif + the_thread->fp_context = NULL; + + _RTEMS_tasks_Cancel_wait( the_thread ); + + (void) _Workspace_Free( the_thread->Start.Initial_stack.area ); + + _RTEMS_tasks_Free( the_thread ); + + if ( _Attributes_Is_global( the_thread->attribute_set ) ) { + + _Objects_MP_Close( &_Thread_Information, the_thread->Object.id ); + + _RTEMS_tasks_MP_Send_process_packet( + RTEMS_TASKS_MP_ANNOUNCE_DELETE, + the_thread->Object.id, + 0 /* Not used */ + ); + } + + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_task_suspend + * + * This directive will place the specified thread in the "suspended" + * state. Note that the suspended state can be in addition to + * other waiting states. + * + * Input parameters: + * id - thread id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_suspend( + Objects_Id id +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + return( + _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_SUSPEND_REQUEST, + id, + 0, /* Not used */ + 0, /* Not used */ + 0 /* Not used */ + ) + ); + case OBJECTS_LOCAL: + if ( !_States_Is_suspended( the_thread->current_state ) ) { + _Thread_Set_state( the_thread, STATES_SUSPENDED ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + _Thread_Enable_dispatch(); + return( RTEMS_ALREADY_SUSPENDED ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_task_resume + * + * This directive will remove the specified thread + * from the suspended state. + * + * Input parameters: + * id - thread id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_resume( + Objects_Id id +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + return( + _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_RESUME_REQUEST, + id, + 0, /* Not used */ + 0, /* Not used */ + 0 /* Not used */ + ) + ); + case OBJECTS_LOCAL: + if ( _States_Is_suspended( the_thread->current_state ) ) { + _Thread_Resume( the_thread ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + _Thread_Enable_dispatch(); + return( RTEMS_INCORRECT_STATE ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_task_set_priority + * + * This directive changes the priority of the specified thread. + * The specified thread can be any thread in the system including + * the requesting thread. + * + * Input parameters: + * id - thread id (0 indicates requesting thread) + * new_priority - thread priority (0 indicates current priority) + * old_priority - pointer to previous priority + * + * Output parameters: + * old_priority - previous priority + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_set_priority( + Objects_Id id, + rtems_task_priority new_priority, + rtems_task_priority *old_priority +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + if ( new_priority != RTEMS_CURRENT_PRIORITY && + !_Priority_Is_valid( new_priority ) ) + return( RTEMS_INVALID_PRIORITY ); + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + _Thread_Executing->Wait.return_argument = old_priority; + return( + _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_SET_PRIORITY_REQUEST, + id, + new_priority, + 0, /* Not used */ + 0 /* Not used */ + ) + ); + case OBJECTS_LOCAL: + *old_priority = the_thread->current_priority; + if ( new_priority != RTEMS_CURRENT_PRIORITY ) { + the_thread->real_priority = new_priority; + if ( the_thread->resource_count == 0 || + the_thread->current_priority > new_priority ) + _Thread_Change_priority( the_thread, new_priority ); + } + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_task_mode + * + * This directive enables and disables several modes of + * execution for the requesting thread. + * + * Input parameters: + * mode_set - new mode + * mask - mask + * previous_mode_set - address of previous mode set + * + * Output: + * *previous_mode_set - previous mode set + * always returns RTEMS_SUCCESSFUL + */ + +rtems_status_code rtems_task_mode( + rtems_mode mode_set, + rtems_mode mask, + rtems_mode *previous_mode_set +) +{ + if ( _Thread_Change_mode( mode_set, mask, previous_mode_set ) ) + _Thread_Dispatch(); + return( RTEMS_SUCCESSFUL ); +} + +/*PAGE + * + * rtems_task_get_note + * + * This directive obtains the note from the specified notepad + * of the specified thread. + * + * Input parameters: + * id - thread id + * notepad - notepad number + * note - pointer to note + * + * Output parameters: + * note - filled in if successful + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_get_note( + Objects_Id id, + unsigned32 notepad, + unsigned32 *note +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + /* + * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would + * be checking an unsigned number for being negative. + */ + + if ( notepad > RTEMS_NOTEPAD_LAST ) + return( RTEMS_INVALID_NUMBER ); + + /* + * Optimize the most likely case to avoid the Thread_Dispatch. + */ + + if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) || + _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) { + *note = _Thread_Executing->Notepads[ notepad ]; + return( RTEMS_SUCCESSFUL ); + } + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + _Thread_Executing->Wait.return_argument = note; + + return _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_GET_NOTE_REQUEST, + id, + 0, /* Not used */ + notepad, + 0 /* Not used */ + ); + case OBJECTS_LOCAL: + *note= the_thread->Notepads[ notepad ]; + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_task_set_note + * + * This directive sets the specified notepad contents to the given + * note. + * + * Input parameters: + * id - thread id + * notepad - notepad number + * note - note value + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_set_note( + Objects_Id id, + unsigned32 notepad, + unsigned32 note +) +{ + register Thread_Control *the_thread; + Objects_Locations location; + + /* + * NOTE: There is no check for < RTEMS_NOTEPAD_FIRST because that would + * be checking an unsigned number for being negative. + */ + + if ( notepad > RTEMS_NOTEPAD_LAST ) + return( RTEMS_INVALID_NUMBER ); + + /* + * Optimize the most likely case to avoid the Thread_Dispatch. + */ + + if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) || + _Objects_Are_ids_equal( id, _Thread_Executing->Object.id ) ) { + _Thread_Executing->Notepads[ notepad ] = note; + return( RTEMS_SUCCESSFUL ); + } + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + return( RTEMS_INVALID_ID ); + case OBJECTS_REMOTE: + return _RTEMS_tasks_MP_Send_request_packet( + RTEMS_TASKS_MP_SET_NOTE_REQUEST, + id, + 0, /* Not used */ + notepad, + note + ); + + case OBJECTS_LOCAL: + the_thread->Notepads[ notepad ] = note; + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} + +/*PAGE + * + * rtems_task_wake_after + * + * This directive suspends the requesting thread for the given amount + * of ticks. + * + * Input parameters: + * ticks - number of ticks to wait + * + * Output parameters: + * RTEMS_SUCCESSFUL - always successful + */ + +rtems_status_code rtems_task_wake_after( + rtems_interval ticks +) +{ + if ( ticks == 0 ) { + _Thread_Yield_processor(); + _Thread_Dispatch(); + } else { + _Thread_Disable_dispatch(); + _Thread_Set_state( _Thread_Executing, STATES_DELAYING ); + _Watchdog_Initialize( + &_Thread_Executing->Timer, + _Thread_Delay_ended, + _Thread_Executing->Object.id, + NULL + ); + _Watchdog_Insert_ticks( &_Thread_Executing->Timer, + ticks, WATCHDOG_ACTIVATE_NOW ); + _Thread_Enable_dispatch(); + } + return( RTEMS_SUCCESSFUL ); +} + +/*PAGE + * + * rtems_task_wake_when + * + * This directive blocks the requesting thread until the given date and + * time is reached. + * + * Input parameters: + * time_buffer - pointer to the time and date structure + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_task_wake_when( +rtems_time_of_day *time_buffer +) +{ + rtems_interval seconds; + rtems_status_code local_result; + + if ( !_TOD_Is_set() ) + return( RTEMS_NOT_DEFINED ); + + time_buffer->ticks = 0; + + local_result = _TOD_Validate( time_buffer ); + + if ( !rtems_is_status_successful( local_result ) ) + return( local_result ); + + seconds = _TOD_To_seconds( time_buffer ); + + if ( seconds <= _TOD_Seconds_since_epoch ) + return( RTEMS_INVALID_CLOCK ); + + _Thread_Disable_dispatch(); + _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_TIME ); + _Watchdog_Initialize( + &_Thread_Executing->Timer, + _Thread_Delay_ended, + _Thread_Executing->Object.id, + NULL + ); + _Watchdog_Insert_seconds( &_Thread_Executing->Timer, + seconds - _TOD_Seconds_since_epoch, WATCHDOG_ACTIVATE_NOW ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); +} diff --git a/cpukit/sapi/include/rtems/config.h b/cpukit/sapi/include/rtems/config.h new file mode 100644 index 0000000000..b5080b6133 --- /dev/null +++ b/cpukit/sapi/include/rtems/config.h @@ -0,0 +1,321 @@ +/* config.h + * + * This include file contains the table of user defined configuration + * parameters. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_CONFIGURATION_h +#define __RTEMS_CONFIGURATION_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + * 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 { + Objects_Name name; /* task name */ + unsigned32 stack_size; /* task stack size */ + rtems_task_priority initial_priority; /* task priority */ + rtems_attribute attribute_set; /* task attributes */ + rtems_task_entry entry_point; /* task entry point */ + rtems_mode mode_set; /* task initial mode */ + unsigned32 argument; /* task argument */ +} rtems_initialization_tasks_table; + +/* + * + * The following defines the types for: + * + * + major and minor numbers + * + the return type of a device driver entry + * + a pointer to a device driver entry + * + an entry in the the Device Driver Address Table. Each entry in this + * table corresponds to an application provided device driver and + * defines the entry points for that device driver. + */ + +typedef unsigned32 rtems_device_major_number; +typedef unsigned32 rtems_device_minor_number; + +typedef void rtems_device_driver; + +typedef rtems_device_driver ( *rtems_device_driver_entry )( + rtems_device_major_number, + rtems_device_minor_number, + void *, + Objects_Id, + unsigned32 * + ); + +typedef struct { + rtems_device_driver_entry initialization; /* initialization procedure */ + rtems_device_driver_entry open; /* open request procedure */ + rtems_device_driver_entry close; /* close request procedure */ + rtems_device_driver_entry read; /* read request procedure */ + rtems_device_driver_entry write; /* write request procedure */ + rtems_device_driver_entry control; /* special functions procedure */ +} rtems_driver_address_table; + +/* + * The following records defines the User Extension Table. + * This table defines the application dependent routines which + * are invoked at critical points in the life of each task and + * the system as a whole. + */ + +typedef void rtems_extension; + +typedef rtems_extension ( *rtems_task_create_extension )( + rtems_tcb *, + rtems_tcb * + ); + +typedef rtems_extension ( *rtems_task_delete_extension )( + rtems_tcb *, + rtems_tcb * + ); + +typedef rtems_extension ( *rtems_task_start_extension )( + rtems_tcb *, + rtems_tcb * + ); + +typedef rtems_extension ( *rtems_task_restart_extension )( + rtems_tcb *, + rtems_tcb * + ); + +typedef rtems_extension ( *rtems_task_switch_extension )( + rtems_tcb *, + rtems_tcb * + ); + +typedef rtems_extension ( *rtems_task_begin_extension )( + rtems_tcb * + ); + +typedef rtems_extension ( *rtems_task_exitted_extension )( + rtems_tcb * + ); + +typedef rtems_extension ( *rtems_fatal_extension )( + unsigned32 + ); + +typedef struct { + rtems_task_create_extension rtems_task_create; + rtems_task_start_extension rtems_task_start; + rtems_task_restart_extension rtems_task_restart; + rtems_task_delete_extension rtems_task_delete; + rtems_task_switch_extension task_switch; + rtems_task_begin_extension task_begin; + rtems_task_exitted_extension task_exitted; + rtems_fatal_extension fatal; +} rtems_extensions_table; + +/* + * The following records define the Multiprocessor Communications + * Interface (MPCI) Table. This table defines the user-provided + * MPCI which is a required part of a multiprocessor RTEMS system. + * + * For non-blocking local operations that become remote operations, + * we need a timeout. This is a per-driver timeout: default_timeout + */ + +/* XXX FORWARD REFERENCES */ + +typedef struct Configuration_Table rtems_configuration_table; +typedef struct Configuration_Table_MP rtems_multiprocessing_table; + +typedef void rtems_mpci_entry; + +typedef rtems_mpci_entry ( *rtems_mpci_initialization_entry )( + rtems_configuration_table *, + rtems_cpu_table *, + rtems_multiprocessing_table * + ); + +typedef rtems_mpci_entry ( *rtems_mpci_get_packet_entry )( + rtems_packet_prefix ** + ); + +typedef rtems_mpci_entry ( *rtems_mpci_return_packet_entry )( + rtems_packet_prefix * + ); + +typedef rtems_mpci_entry ( *rtems_mpci_send_entry )( + unsigned32, + rtems_packet_prefix * + ); + +typedef rtems_mpci_entry ( *rtems_mpci_receive_entry )( + rtems_packet_prefix ** + ); + +typedef struct { + unsigned32 default_timeout; /* in ticks */ + rtems_mpci_initialization_entry initialization; + rtems_mpci_get_packet_entry get_packet; + rtems_mpci_return_packet_entry return_packet; + rtems_mpci_send_entry send_packet; + rtems_mpci_receive_entry receive_packet; +} rtems_mpci_table; + +/* + * 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. + */ + +struct Configuration_Table_MP { + unsigned32 node; /* local node number */ + unsigned32 maximum_nodes; /* maximum # nodes in system */ + unsigned32 maximum_global_objects; /* maximum # global objects */ + unsigned32 maximum_proxies; /* maximum # proxies */ + rtems_mpci_table *User_mpci_table; + /* pointer to MPCI table */ +}; + +/* + * 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 + * + required number of each object type + * + microseconds per clock tick + * + clock ticks per task timeslice + */ + +struct Configuration_Table { + void *work_space_start; + unsigned32 work_space_size; + unsigned32 maximum_tasks; + unsigned32 maximum_timers; + unsigned32 maximum_semaphores; + unsigned32 maximum_message_queues; + unsigned32 maximum_messages; + unsigned32 maximum_partitions; + unsigned32 maximum_regions; + unsigned32 maximum_ports; + unsigned32 maximum_periods; + unsigned32 maximum_extensions; + unsigned32 microseconds_per_tick; + unsigned32 ticks_per_timeslice; + unsigned32 number_of_initialization_tasks; + rtems_initialization_tasks_table *User_initialization_tasks_table; + unsigned32 number_of_device_drivers; + rtems_driver_address_table *Device_driver_table; + rtems_extensions_table *User_extension_table; + rtems_multiprocessing_table *User_multiprocessing_table; +}; + +/* + * The following defines the default Multiprocessing Configuration + * Table. This table is used in a single processor system. + */ + +extern const rtems_multiprocessing_table + _Configuration_Default_multiprocessing_table; + +/* + * The following define the internal pointers to the user's + * configuration information. + */ + +EXTERN rtems_configuration_table *_Configuration_Table; +EXTERN rtems_multiprocessing_table *_Configuration_MP_table; +EXTERN rtems_mpci_table *_Configuration_MPCI_table; + +/* + * + * _Configuration_Handler_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this handler. + */ + +STATIC INLINE void _Configuration_Handler_initialization( + rtems_configuration_table *configuration_table, + rtems_multiprocessing_table *multiprocessing_table, + rtems_mpci_table *users_mpci_table +); + +/* + * _Configuration_Is_multiprocessing + * + * DESCRIPTION: + * + * This function determines if a multiprocessing application has been + * configured, if so, TRUE is returned, otherwise FALSE is returned. + */ + +STATIC INLINE boolean _Configuration_Is_multiprocessing( void ); + +/* + * _Configuration_Is_null_driver_address_table_pointer + * + * DESCRIPTION: + * + * This function returns TRUE if the_table is NULL and FALSE otherwise. + */ + +STATIC INLINE boolean _Configuration_Is_null_driver_address_table_pointer( + rtems_driver_address_table *the_table +); + +/* + * _Configuration_Is_null_extension_table_pointer + * + * DESCRIPTION: + * + * This function returns TRUE if the_table is NULL and FALSE otherwise. + */ + +STATIC INLINE boolean _Configuration_Is_null_extension_table_pointer( + rtems_extensions_table *the_table +); + +/* + * _Configuration_Is_null_initialization_tasks_table_pointer + * + * DESCRIPTION: + * + * This function returns TRUE if the_table is NULL and FALSE otherwise. + */ + +STATIC INLINE boolean + _Configuration_Is_null_initialization_tasks_table_pointer( + rtems_initialization_tasks_table *the_table +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/sapi/include/rtems/extension.h b/cpukit/sapi/include/rtems/extension.h new file mode 100644 index 0000000000..1e20fe6470 --- /dev/null +++ b/cpukit/sapi/include/rtems/extension.h @@ -0,0 +1,169 @@ +/* extension.h + * + * This include file contains all the constants, structures, and + * prototypes associated with the User Extension Manager. This manager + * provides a mechanism for manipulating sets of user-defined extensions. + * + * Directives provided are: + * + * + create user extension set + * + get ID of user extension set + * + delete user extension set + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_EXTENSION_MANAGER_h +#define __RTEMS_EXTENSION_MANAGER_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + * The following defines the information control block used to manage + * this class of objects. + */ + +EXTERN Objects_Information _Extension_Information; + +/* + * The following records define the control block used to manage + * each extension. + */ + +typedef struct { + Objects_Control Object; + User_extensions_Control Extension; +} Extension_Control; + +/* + * _Extension_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _Extension_Manager_initialization( + unsigned32 maximum_extensions +); + +/* + * rtems_extension_create + * + * DESCRIPTION: + * + * This routine implements the rtems_extension_create directive. The + * extension will have the name name. The entry points of the + * routines which constitute this extension set are in EXTENSION_TABLE. + * It returns the id of the created extension in ID. + */ + +rtems_status_code rtems_extension_create( + Objects_Name name, + rtems_extensions_table *extension_table, + Objects_Id *id +); + +/* + * rtems_extension_ident + * + * DESCRIPTION: + * + * This routine implements the rtems_extension_ident directive. + * This directive returns the extension ID associated with name. + * If more than one extension is named name, then the extension + * to which the ID belongs is arbitrary. + */ + +rtems_status_code rtems_extension_ident( + Objects_Name name, + Objects_Id *id +); + +/* + * rtems_extension_delete + * + * DESCRIPTION: + * + * This routine implements the rtems_extension_delete directive. The + * extension indicated by ID is deleted. + */ + +rtems_status_code rtems_extension_delete( + Objects_Id id +); + +/* + * _Extension_Allocate + * + * DESCRIPTION: + * + * This function allocates a extension control block from + * the inactive chain of free extension control blocks. + */ + +STATIC INLINE Extension_Control *_Extension_Allocate( void ); + +/* + * _Extension_Free + * + * DESCRIPTION: + * + * This routine frees a extension control block to the + * inactive chain of free extension control blocks. + */ + +STATIC INLINE void _Extension_Free ( + Extension_Control *the_extension +); + +/* + * _Extension_Get + * + * DESCRIPTION: + * + * This function maps extension IDs to extension control blocks. + * If ID corresponds to a local extension, then it returns + * the extension 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. + */ + +STATIC INLINE Extension_Control *_Extension_Get ( + Objects_Id id, + Objects_Locations *location +); + +/* + * _Extension_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_extension is NULL and FALSE otherwise. + */ + +STATIC INLINE boolean _Extension_Is_null( + Extension_Control *the_extension +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/sapi/include/rtems/fatal.h b/cpukit/sapi/include/rtems/fatal.h new file mode 100644 index 0000000000..f61b4183f3 --- /dev/null +++ b/cpukit/sapi/include/rtems/fatal.h @@ -0,0 +1,49 @@ +/* fatal.h + * + * This include file contains constants and prototypes related + * to the Fatal Error Manager. This manager processes all fatal or + * irrecoverable errors. + * + * This manager provides directives to: + * + * + announce a fatal error has occurred + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_FATAL_h +#define __RTEMS_FATAL_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * rtems_fatal_error_occurred + * + * DESCRIPTION: + * + * This is the routine which implements the rtems_fatal_error_occurred + * directive. It is invoked when the application or RTEMS + * determines that a fatal error has occurred. + */ + +void volatile rtems_fatal_error_occurred( + unsigned32 the_error +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/sapi/include/rtems/init.h b/cpukit/sapi/include/rtems/init.h new file mode 100644 index 0000000000..a5ed1688b7 --- /dev/null +++ b/cpukit/sapi/include/rtems/init.h @@ -0,0 +1,101 @@ +/* init.h + * + * 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, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_INIT_h +#define __RTEMS_INIT_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + * rtems_initialize_executive + * + * DESCRIPTION: + * + * This routine implements the rtems_initialize_executive directive. This + * directive is invoked at system startup to initialize the RTEMS + * multitasking environment. + */ + +void rtems_initialize_executive( + rtems_configuration_table *configuration_table, + rtems_cpu_table *cpu_table +); + +/* + * rtems_initialize_executive_early + * + * DESCRIPTION: + * + * This routine implements the early portion of rtems_initialize_executive + * directive up to the pretasking hook. This directive is invoked at system + * startup to initialize the RTEMS multitasking environment. + */ + +rtems_interrupt_level rtems_initialize_executive_early( + rtems_configuration_table *configuration_table, + rtems_cpu_table *cpu_table +); + +/* + * rtems_initialize_executive_late + * + * DESCRIPTION: + * + * This routine implements the early portion of rtems_initialize_executive + * directive up to the pretasking hook. This directive is invoked at system + * startup to initialize the RTEMS multitasking environment. + */ + +void rtems_initialize_executive_late( + rtems_interrupt_level bsp_level +); + +/* + * rtems_shutdown_executive + * + * DESCRIPTION: + * + * This routine implements the rtems_shutdown_executive directive. The + * invocation of this directive results in the RTEMS environment being + * shutdown and multitasking halted. From the application's perspective, + * invocation of this directive results in the rtems_initialize_executive + * directive exitting to the startup code which invoked it. + */ + +void rtems_shutdown_executive( + unsigned32 result +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/sapi/include/rtems/io.h b/cpukit/sapi/include/rtems/io.h new file mode 100644 index 0000000000..6824377170 --- /dev/null +++ b/cpukit/sapi/include/rtems/io.h @@ -0,0 +1,204 @@ +/* io.h + * + * This include file contains all the constants and structures associated + * with the Input/Output Manager. This manager provides a well defined + * mechanism for accessing device drivers and a structured methodology for + * organizing device drivers. + * + * Directives provided are: + * + * + initialize a device driver + * + open a device driver + * + close a device driver + * + read from a device driver + * + write to a device driver + * + special device services + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_IO_h +#define __RTEMS_IO_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * The following type defines the set of IO operations which are + * recognized by _IO_Handler and can be supported by a RTEMS + * device driver. + */ + +typedef enum { + IO_INITIALIZE_OPERATION = 0, + IO_OPEN_OPERATION = 1, + IO_CLOSE_OPERATION = 2, + IO_READ_OPERATION = 3, + IO_WRITE_OPERATION = 4, + IO_CONTROL_OPERATION = 5 +} IO_operations; + +/* + * The following declare the data required to manage the Device Driver + * Address Table. + */ + +EXTERN unsigned32 _IO_Number_of_drivers; +EXTERN rtems_driver_address_table *_IO_Driver_address_table; + +/* + * _IO_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +STATIC INLINE void _IO_Manager_initialization( + rtems_driver_address_table *driver_table, + unsigned32 number_of_drivers +); + +/* + * rtems_io_initialize + * + * DESCRIPTION: + * + * This routine implements the rtems_io_initialize directive. It is invoked + * to initialize a device driver or an individual device. + */ + +rtems_status_code rtems_io_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument, + unsigned32 *return_value +); + +/* + * rtems_io_open + * + * DESCRIPTION: + * + * This routine implements the rtems_io_open directive. It is invoked + * to open a device. + */ + +rtems_status_code rtems_io_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument, + unsigned32 *return_value +); + +/* + * rtems_io_close + * + * DESCRIPTION: + * + * This routine implements the rtems_io_close directive. It is invoked + * to close a device. + */ + +rtems_status_code rtems_io_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument, + unsigned32 *return_value +); + +/* + * rtems_io_read + * + * DESCRIPTION: + * + * This routine implements the rtems_io_read directive. It is invoked + * to read from a device. + */ + +rtems_status_code rtems_io_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument, + unsigned32 *return_value +); + +/* + * rtems_io_write + * + * DESCRIPTION: + * + * This routine implements the rtems_io_write directive. It is invoked + * to write to a device. + */ + +rtems_status_code rtems_io_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument, + unsigned32 *return_value +); + +/* + * rtems_io_control + * + * DESCRIPTION: + * + * This routine implements the rtems_io_control directive. It is invoked + * to perform a device specific operation on a device. + */ + +rtems_status_code rtems_io_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument, + unsigned32 *return_value +); + +/* + * _IO_Initialize_all_drivers + * + * DESCRIPTION: + * + * This routine initializes all of the device drivers configured + * in the Device Driver Address Table. + */ + +void _IO_Initialize_all_drivers( void ); + +/* + * _IO_Handler_routine + * + * DESCRIPTION: + * + * This routine provides the common foundation for all of the IO + * Manager's directives. + */ + +rtems_status_code _IO_Handler_routine( + IO_operations operation, + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument, + unsigned32 *return_value +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/sapi/include/rtems/mptables.h b/cpukit/sapi/include/rtems/mptables.h new file mode 100644 index 0000000000..b8e4c6de43 --- /dev/null +++ b/cpukit/sapi/include/rtems/mptables.h @@ -0,0 +1,29 @@ +/* mptables.h + * + * This include file contains the executive's pre-initialized tables + * used in a multiprocessor configuration. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#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/sapi/inline/rtems/extension.inl b/cpukit/sapi/inline/rtems/extension.inl new file mode 100644 index 0000000000..27941923b0 --- /dev/null +++ b/cpukit/sapi/inline/rtems/extension.inl @@ -0,0 +1,73 @@ +/* extension.inl + * + * This file contains the static inline implementation of the inlined routines + * from the Extension Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __EXTENSION_MANAGER_inl +#define __EXTENSION_MANAGER_inl + +/*PAGE + * + * _Extension_Allocate + * + */ + +STATIC INLINE Extension_Control *_Extension_Allocate( void ) +{ + return (Extension_Control *) _Objects_Allocate( &_Extension_Information ); +} + +/*PAGE + * + * _Extension_Free + * + */ + +STATIC INLINE void _Extension_Free ( + Extension_Control *the_extension +) +{ + _Objects_Free( &_Extension_Information, &the_extension->Object ); +} + +/*PAGE + * + * _Extension_Get + * + */ + +STATIC INLINE Extension_Control *_Extension_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (Extension_Control *) + _Objects_Get( &_Extension_Information, id, location ); +} + +/*PAGE + * + * _Extension_Is_null + * + */ + +STATIC INLINE boolean _Extension_Is_null ( + Extension_Control *the_extension +) +{ + return ( the_extension == NULL ); +} + +#endif +/* end of include file */ diff --git a/cpukit/sapi/macros/rtems/extension.inl b/cpukit/sapi/macros/rtems/extension.inl new file mode 100644 index 0000000000..96fb9d1b3e --- /dev/null +++ b/cpukit/sapi/macros/rtems/extension.inl @@ -0,0 +1,58 @@ +/* extension.inl + * + * This file contains the macro implementation of the inlined routines + * from the Extension Manager. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __EXTENSION_inl +#define __EXTENSION_inl + +/*PAGE + * + * _Extension_Allocate + * + */ + +#define _Extension_Allocate() \ + (Extension_Control *) _Objects_Allocate( &_Extension_Information ) + +/*PAGE + * + * _Extension_Free + * + */ + +#define _Extension_Free( _the_extension ) \ + _Objects_Free( &_Extension_Information, &(_the_extension)->Object ) + +/*PAGE + * + * _Extension_Get + * + */ + +#define _Extension_Get( _id, _location ) \ + (Extension_Control *) \ + _Objects_Get( &_Extension_Information, (_id), (_location) ) + +/*PAGE + * + * _Extension_Is_null + * + */ + +#define _Extension_Is_null( _the_extension ) \ + ( (_the_extension) == NULL ) + +#endif +/* end of include file */ diff --git a/cpukit/sapi/src/debug.c b/cpukit/sapi/src/debug.c new file mode 100644 index 0000000000..5c42fa92f6 --- /dev/null +++ b/cpukit/sapi/src/debug.c @@ -0,0 +1,62 @@ +/* + * Debug Manager + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include + +/*PAGE + * + * _Debug_Manager_initialization + */ + +void _Debug_Manager_initialization( void ) +{ + rtems_debug_disable( RTEMS_DEBUG_ALL_MASK ); +} + +/*PAGE + * + * rtems_debug_enable + */ + +void rtems_debug_enable ( + rtems_debug_control to_be_enabled +) +{ + _Debug_Level |= to_be_enabled; +} + +/*PAGE + * + * rtems_debug_disable + */ + +void rtems_debug_disable ( + rtems_debug_control to_be_disabled +) +{ + _Debug_Level &= ~to_be_disabled; +} + +/*PAGE + * + * _Debug_Is_enabled + */ + +boolean _Debug_Is_enabled( + rtems_debug_control level +) +{ + return (_Debug_Level & level); +} diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c new file mode 100644 index 0000000000..cc45a11c94 --- /dev/null +++ b/cpukit/sapi/src/exinit.c @@ -0,0 +1,245 @@ +/* + * Initialization Manager + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +/* + * INIT is defined so all of the data will be included in this + * file. + */ + +#define INIT + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/*PAGE + * + * rtems_initialize_executive + * + * This directive initializes all the kernels data structures + * to the states necessary for the kernel to begin execution. All + * include files that contain global variable definitions should be + * included in this file. The system threads and initialization threads + * are created and started by this routine. This routine then + * initiates multithreading. + * + * Input parameters: + * configuration_table - pointer to the user's configuration table + * cpu_table - pointer to the user's CPU configuration table + * + * Output parameters: NONE + */ + +struct months { + unsigned32 months[2][13]; +}; + +void rtems_initialize_executive( + rtems_configuration_table *configuration_table, + rtems_cpu_table *cpu_table +) +{ + rtems_interrupt_level bsp_level; + + bsp_level = rtems_initialize_executive_early(configuration_table, cpu_table); + rtems_initialize_executive_late( bsp_level ); +} + +rtems_interrupt_level rtems_initialize_executive_early( + rtems_configuration_table *configuration_table, + rtems_cpu_table *cpu_table +) +{ + rtems_interrupt_level bsp_level; + rtems_multiprocessing_table *multiprocessing_table; + + /* + * Dispatching and interrupts are disabled until the end of the + * initialization sequence. This prevents an inadvertent context + * switch before the executive is initialized. + */ + + _ISR_Disable( bsp_level ); + + _System_state_Set( SYSTEM_STATE_BEFORE_INITIALIZATION ); + + _CPU_Initialize( cpu_table, _Thread_Dispatch ); + + multiprocessing_table = configuration_table->User_multiprocessing_table; + if ( multiprocessing_table == NULL ) + multiprocessing_table = + (void *) &_Configuration_Default_multiprocessing_table; + + _Configuration_Handler_initialization( + configuration_table, + multiprocessing_table, + multiprocessing_table->User_mpci_table + ); + + _Attributes_Handler_initialization(); + + _Thread_Dispatch_initialization(); + + _User_extensions_Handler_initialization( + configuration_table->User_extension_table + ); + + _Workspace_Handler_initialization( + (void *)configuration_table->work_space_start, + configuration_table->work_space_size + ); + + _ISR_Handler_initialization(); + + _Objects_Handler_initialization( + multiprocessing_table->node, + multiprocessing_table->maximum_global_objects + ); + + _Priority_Handler_initialization(); + + _Watchdog_Handler_initialization(); + + _TOD_Handler_initialization( configuration_table->microseconds_per_tick ); + + _Thread_Handler_initialization( + configuration_table->maximum_tasks, + configuration_table->ticks_per_timeslice, + multiprocessing_table->maximum_proxies + ); + + _MPCI_Handler_initialization(); + +/* MANAGERS */ + + _Interrupt_Manager_initialization(); + + _Multiprocessing_Manager_initialization(); + + _Timer_Manager_initialization( configuration_table->maximum_timers ); + + _Extension_Manager_initialization( configuration_table->maximum_extensions ); + + _IO_Manager_initialization( + configuration_table->Device_driver_table, + configuration_table->number_of_device_drivers + ); + + _Event_Manager_initialization(); + + _Message_queue_Manager_initialization( + configuration_table->maximum_message_queues, + configuration_table->maximum_messages + ); + + _Semaphore_Manager_initialization( + configuration_table->maximum_semaphores + ); + + _Partition_Manager_initialization( + configuration_table->maximum_partitions + ); + + _Region_Manager_initialization( configuration_table->maximum_regions ); + + _Dual_ported_memory_Manager_initialization( + configuration_table->maximum_ports + ); + + _Rate_monotonic_Manager_initialization( + configuration_table->maximum_periods + ); + + _Internal_threads_Initialization(); + + if ( cpu_table->pretasking_hook ) + (*cpu_table->pretasking_hook)(); + + _System_state_Set( SYSTEM_STATE_BEFORE_MULTITASKING ); + + return bsp_level; +} + +void rtems_initialize_executive_late( + rtems_interrupt_level bsp_level +) +{ + + _System_state_Set( SYSTEM_STATE_BEGIN_MULTITASKING ); + + _Thread_Start_multitasking( + _Internal_threads_System_initialization_thread, + _Internal_threads_Idle_thread + ); + + /* + * Restore the interrupt level to what the BSP had. Technically, + * this is unnecessary since the BSP should have all interrupts + * disabled when rtems_initialize_executive is invoked. But this keeps + * the ISR Disable/Enable calls paired. + */ + + _ISR_Enable( bsp_level ); +} + +/*PAGE + * + * rtems_shutdown_executive + * + * This kernel routine shutdowns the executive. It halts multitasking + * and returns control to the application execution "thread" which + * initialially invoked the rtems_initialize_executive directive. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void rtems_shutdown_executive( + unsigned32 result +) +{ + _Thread_Stop_multitasking(); +} diff --git a/cpukit/sapi/src/extension.c b/cpukit/sapi/src/extension.c new file mode 100644 index 0000000000..10c974ef8e --- /dev/null +++ b/cpukit/sapi/src/extension.c @@ -0,0 +1,156 @@ +/* + * Extension Manager + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include + +/*PAGE + * + * _Extension_Manager_initialization + * + * This routine initializes all extension manager related data structures. + * + * Input parameters: + * maximum_extensions - number of extensions to initialize + * + * Output parameters: NONE + */ + +void _Extension_Manager_initialization( + unsigned32 maximum_extensions +) +{ + _Objects_Initialize_information( + &_Extension_Information, + FALSE, + maximum_extensions, + sizeof( Extension_Control ) + ); +} + +/*PAGE + * + * rtems_extension_create + * + * This directive creates a extension and performs some initialization. + * + * Input parameters: + * name - extension name + * extension_table - pointer to extension set information + * id - pointer to extension id + * + * Output parameters: + * id - extension id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_extension_create( + Objects_Name name, + rtems_extensions_table *extension_table, + Objects_Id *id +) +{ + Extension_Control *the_extension; + + if ( !_Objects_Is_name_valid( name ) ) + return ( RTEMS_INVALID_NAME ); + + _Thread_Disable_dispatch(); /* to prevent deletion */ + + the_extension = _Extension_Allocate(); + + if ( !the_extension ) { + _Thread_Enable_dispatch(); + return( RTEMS_TOO_MANY ); + } + + _User_extensions_Add_set( &the_extension->Extension, extension_table ); + + _Objects_Open( &_Extension_Information, &the_extension->Object, name ); + + *id = the_extension->Object.id; + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); +} + +/*PAGE + * + * rtems_extension_ident + * + * This directive returns the system ID associated with + * the extension name. + * + * Input parameters: + * name - user defined message queue name + * id - pointer to extension id + * + * Output parameters: + * *id - message queue id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_extension_ident( + Objects_Name name, + Objects_Id *id +) +{ + return _Objects_Name_to_id( + &_Extension_Information, + name, + RTEMS_SEARCH_LOCAL_NODE, + id + ); +} + +/*PAGE + * + * rtems_extension_delete + * + * This directive allows a thread to delete a extension. + * + * Input parameters: + * id - extension id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_extension_delete( + Objects_Id id +) +{ + Extension_Control *the_extension; + Objects_Locations location; + + the_extension = _Extension_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + case OBJECTS_REMOTE: /* should never return this */ + return( RTEMS_INVALID_ID ); + case OBJECTS_LOCAL: + _User_extensions_Remove_set( &the_extension->Extension ); + _Objects_Close( &_Extension_Information, &the_extension->Object ); + _Extension_Free( the_extension ); + _Thread_Enable_dispatch(); + return( RTEMS_SUCCESSFUL ); + } + + return( RTEMS_INTERNAL_ERROR ); /* unreached - only to remove warnings */ +} diff --git a/cpukit/sapi/src/fatal.c b/cpukit/sapi/src/fatal.c new file mode 100644 index 0000000000..2ecc73ff3f --- /dev/null +++ b/cpukit/sapi/src/fatal.c @@ -0,0 +1,54 @@ +/* + * Fatal Error Manager + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_fatal_error_occurred + * + * This directive will invoke the fatal error handler supplied by the user + * followed by the the default one provided by the executive. The default + * error handler assumes no hardware is present to help inform the user + * of the problem. Halt stores the error code in a known register, + * disables interrupts, and halts the CPU. If the CPU does not have a + * halt instruction, it will loop to itself. + * + * Input parameters: + * the_error - fatal error status code + * + * Output parameters: + * the_error - on stack + * status register - on stack + * + * NOTE: The the_error is not necessarily a directive status code. + */ + +void volatile rtems_fatal_error_occurred( + unsigned32 the_error +) +{ + + _User_extensions_Fatal( the_error ); + + _System_state_Set( SYSTEM_STATE_FAILED ); + + _CPU_Fatal_halt( the_error ); + +/* will not return from this routine */ +} diff --git a/cpukit/sapi/src/io.c b/cpukit/sapi/src/io.c new file mode 100644 index 0000000000..cf78bb9f71 --- /dev/null +++ b/cpukit/sapi/src/io.c @@ -0,0 +1,316 @@ +/* + * Input/Output Manager + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include + +/*PAGE + * + * _IO_Initialize_all_drivers + * + * This routine initializes all device drivers + * + * Input Paramters: NONE + * + * Output Parameters: NONE + */ + +void _IO_Initialize_all_drivers( void ) +{ + rtems_device_major_number major; + unsigned32 ignored; + + for ( major=0 ; major < _IO_Number_of_drivers ; major ++ ) + (void) rtems_io_initialize( major, 0, _Configuration_Table, &ignored ); +} + +/*PAGE + * + * rtems_io_initialize + * + * This routine is the initialization directive of the IO manager. + * + * Input Paramters: + * major - device driver number + * minor - device number + * argument - pointer to argument(s) + * return_value - pointer to driver's return value + * + * Output Parameters: + * returns - return code + * *return_value - driver's return code + */ + +rtems_status_code rtems_io_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument, + unsigned32 *return_value +) +{ + return _IO_Handler_routine( + IO_INITIALIZE_OPERATION, + major, + minor, + argument, + return_value + ); +} + +/*PAGE + * + * rtems_io_open + * + * This routine is the open directive of the IO manager. + * + * Input Paramters: + * major - device driver number + * minor - device number + * argument - pointer to argument(s) + * return_value - pointer to driver's return value + * + * Output Parameters: + * returns - return code + * *return_value - driver's return code + */ + +rtems_status_code rtems_io_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument, + unsigned32 *return_value +) +{ + return _IO_Handler_routine( + IO_OPEN_OPERATION, + major, + minor, + argument, + return_value + ); +} + +/*PAGE + * + * rtems_io_close + * + * This routine is the close directive of the IO manager. + * + * Input Paramters: + * major - device driver number + * minor - device number + * argument - pointer to argument(s) + * return_value - pointer to driver's return value + * + * Output Parameters: + * returns - return code + * *return_value - driver's return code + */ + +rtems_status_code rtems_io_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument, + unsigned32 *return_value +) +{ + return _IO_Handler_routine( + IO_CLOSE_OPERATION, + major, + minor, + argument, + return_value + ); +} + +/*PAGE + * + * rtems_io_read + * + * This routine is the read directive of the IO manager. + * + * Input Paramters: + * major - device driver number + * minor - device number + * argument - pointer to argument(s) + * return_value - pointer to driver's return value + * + * Output Parameters: + * returns - return code + * *return_value - driver's return code + */ + +rtems_status_code rtems_io_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument, + unsigned32 *return_value +) +{ + return _IO_Handler_routine( + IO_READ_OPERATION, + major, + minor, + argument, + return_value + ); +} + +/*PAGE + * + * rtems_io_write + * + * This routine is the write directive of the IO manager. + * + * Input Paramters: + * major - device driver number + * minor - device number + * argument - pointer to argument(s) + * return_value - pointer to driver's return value + * + * Output Parameters: + * returns - return code + * *return_value - driver's return code + */ + +rtems_status_code rtems_io_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument, + unsigned32 *return_value +) +{ + return _IO_Handler_routine( + IO_WRITE_OPERATION, + major, + minor, + argument, + return_value + ); +} + +/*PAGE + * + * rtems_io_control + * + * This routine is the control directive of the IO manager. + * + * Input Paramters: + * major - device driver number + * minor - device number + * argument - pointer to argument(s) + * return_value - pointer to driver's return value + * + * Output Parameters: + * returns - return code + * *return_value - driver's return code + */ + +rtems_status_code rtems_io_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument, + unsigned32 *return_value +) +{ + return _IO_Handler_routine( + IO_CONTROL_OPERATION, + major, + minor, + argument, + return_value + ); +} + +/*PAGE + * + * _IO_Handler_routine + * + * This routine implements all IO manager directives. + * + * Input Paramters: + * operation - I/O operation to be performed + * major - device driver number + * minor - device number + * argument - pointer to argument(s) + * return_value - pointer to driver's return value + * + * Output Parameters: + * returns - return code + * *return_value - driver's return code + */ + +rtems_status_code _IO_Handler_routine( + IO_operations operation, + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument, + unsigned32 *return_value +) +{ + rtems_device_driver_entry io_callout; + + /* + * NOTE: There is no range checking as in Ada because: + * + arrays in Ada are not always zero based. + * + with zero based arrays, a comparison of an unsigned + * number being less than zero would be necessary to + * check it as a range. This would cause a warning for + * checking an unsigned number for being negative. + */ + + if ( major >= _IO_Number_of_drivers ) + return ( RTEMS_INVALID_NUMBER ); + + switch ( operation ) { + case IO_INITIALIZE_OPERATION: + io_callout = _IO_Driver_address_table[ major ].initialization; + break; + case IO_OPEN_OPERATION: + io_callout = _IO_Driver_address_table[ major ].open; + break; + case IO_CLOSE_OPERATION: + io_callout = _IO_Driver_address_table[ major ].close; + break; + case IO_READ_OPERATION: + io_callout = _IO_Driver_address_table[ major ].read; + break; + case IO_WRITE_OPERATION: + io_callout = _IO_Driver_address_table[ major ].write; + break; + case IO_CONTROL_OPERATION: + io_callout = _IO_Driver_address_table[ major ].control; + break; + default: /* unreached -- only to remove warnings */ + io_callout = NULL; + break; + } + + if ( io_callout != NULL ) + (*io_callout)( + major, + minor, + argument, + _Thread_Executing->Object.id, + return_value + ); + else + *return_value = 0; + + return( RTEMS_SUCCESSFUL ); +} diff --git a/cpukit/score/cpu/hppa1.1/cpu.c b/cpukit/score/cpu/hppa1.1/cpu.c new file mode 100644 index 0000000000..b69a172b4e --- /dev/null +++ b/cpukit/score/cpu/hppa1.1/cpu.c @@ -0,0 +1,313 @@ +/* + * HP PA-RISC Dependent Source + * + * COPYRIGHT (c) 1994 by Division Incorporated + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Division Incorporated not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * Division Incorporated makes no representations about the + * suitability of this software for any purpose. + * + * $Id$ + */ + +#include +#include +#include +#include +#include + +rtems_status_code hppa_external_interrupt_initialize(void); +void hppa_external_interrupt_enable(unsigned32); +void hppa_external_interrupt_disable(unsigned32); +void hppa_external_interrupt(unsigned32, CPU_Interrupt_frame *); + +/* + * Our interrupt handlers take a 2nd argument: + * a pointer to a CPU_Interrupt_frame + * So we use our own prototype instead of rtems_isr_entry + */ + +typedef rtems_isr ( *hppa_rtems_isr_entry )( + rtems_vector_number, + CPU_Interrupt_frame * + ); + + +/* + * who are we? cpu number + * Not used by executive proper, just kept (or not) as a convenience + * for libcpu and libbsp stuff that wants it. + * + * Defaults to 0. If the BSP doesn't like it, it can change it. + */ + +int cpu_number; /* from 0; cpu number in a multi cpu system */ + + +/* _CPU_Initialize + * + * This routine performs processor dependent initialization. + * + * INPUT PARAMETERS: + * cpu_table - CPU table to initialize + * thread_dispatch - address of disptaching routine + * + */ + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) /* ignored on this CPU */ +) +{ + register unsigned8 *fp_context; + unsigned32 iva; + unsigned32 iva_table; + int i; + + extern void IVA_Table(void); + + if ( cpu_table == NULL ) + rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED ); + + /* + * XXX; need to setup fpsr smarter perhaps + */ + + fp_context = (unsigned8*) &_CPU_Null_fp_context; + for (i=0 ; i= HPPA_INTERRUPT_EXTERNAL_BASE) + { + unsigned32 external_vector; + + external_vector = vector - HPPA_INTERRUPT_EXTERNAL_BASE; + if (new_handler) + hppa_external_interrupt_enable(external_vector); + else + /* XXX this can never happen due to _ISR_Is_valid_user_handler */ + hppa_external_interrupt_disable(external_vector); + } +} + + +/* + * Support for external and spurious interrupts on HPPA + * + * TODO: + * delete interrupt.c etc. + * Count interrupts + * make sure interrupts disabled properly + * should handler check again for more interrupts before exit? + * How to enable interrupts from an interrupt handler? + * Make sure there is an entry for everything in ISR_Vector_Table + */ + +#define DISMISS(mask) set_eirr(mask) +#define DISABLE(mask) set_eiem(get_eiem() & ~(mask)) +#define ENABLE(mask) set_eiem(get_eiem() | (mask)) +#define VECTOR_TO_MASK(v) (1 << (31 - (v))) + +/* + * Init the external interrupt scheme + * called by bsp_start() + */ + +rtems_status_code +hppa_external_interrupt_initialize(void) +{ + rtems_isr_entry ignore; + + /* mark them all unused */ + + DISABLE(~0); + DISMISS(~0); + + /* install the external interrupt handler */ + rtems_interrupt_catch((rtems_isr_entry) hppa_external_interrupt, + HPPA_INTERRUPT_EXTERNAL_INTERRUPT, &ignore) ; + + return RTEMS_SUCCESSFUL; +} + +/* + * Enable a specific external interrupt + */ + +void +hppa_external_interrupt_enable(unsigned32 v) +{ + unsigned32 isrlevel; + + _CPU_ISR_Disable(isrlevel); + ENABLE(VECTOR_TO_MASK(v)); + _CPU_ISR_Enable(isrlevel); +} + +/* + * Does not clear or otherwise affect any pending requests + */ + +void +hppa_external_interrupt_disable(unsigned32 v) +{ + unsigned32 isrlevel; + + _CPU_ISR_Disable(isrlevel); + DISABLE(VECTOR_TO_MASK(v)); + _CPU_ISR_Enable(isrlevel); +} + +void +hppa_external_interrupt_spurious_handler(unsigned32 vector, + CPU_Interrupt_frame *iframe) +{ +/* XXX should not be printing :) + printf("spurious external interrupt: %d at pc 0x%x; disabling\n", + vector, iframe->Interrupt.pcoqfront); +*/ + DISMISS(VECTOR_TO_MASK(vector)); + DISABLE(VECTOR_TO_MASK(vector)); +} + +void +hppa_external_interrupt_report_spurious(unsigned32 spurious, + CPU_Interrupt_frame *iframe) +{ + int v; + for (v=0; v < HPPA_EXTERNAL_INTERRUPTS; v++) + if (VECTOR_TO_MASK(v) & spurious) + hppa_external_interrupt_spurious_handler(v, iframe); + DISMISS(spurious); +} + + +/* + * External interrupt handler. + * This is installed as cpu interrupt handler for + * HPPA_INTERRUPT_EXTERNAL_INTERRUPT. It vectors out to + * specific external interrupt handlers. + */ + +void +hppa_external_interrupt(unsigned32 vector, + CPU_Interrupt_frame *iframe) +{ + unsigned32 mask; + unsigned32 *vp, *max_vp; + unsigned32 external_vector; + unsigned32 global_vector; + hppa_rtems_isr_entry handler; + + max_vp = &_CPU_Table.external_interrupt[_CPU_Table.external_interrupts]; + while ( (mask = (get_eirr() & get_eiem())) ) + { + for (vp = _CPU_Table.external_interrupt; (vp < max_vp) && mask; vp++) + { + unsigned32 m; + + external_vector = *vp; + global_vector = external_vector + HPPA_INTERRUPT_EXTERNAL_BASE; + m = VECTOR_TO_MASK(external_vector); + handler = (hppa_rtems_isr_entry) _ISR_Vector_table[global_vector]; + if ((m & mask) && handler) + { + DISMISS(m); + mask &= ~m; + (*handler)(global_vector, iframe); + } + } + + if (mask != 0) { + if ( _CPU_Table.spurious_handler ) + (*((hppa_rtems_isr_entry) _CPU_Table.spurious_handler))( + mask, + iframe + ); + else + hppa_external_interrupt_report_spurious(mask, iframe); + } + } +} + +/* + * Halt the system. + * Called by the _CPU_Fatal_halt macro + * + * XXX + * Later on, this will allow us to return to the prom. + * For now, we just ignore 'type_of_halt' + */ + +void +hppa_cpu_halt(unsigned32 type_of_halt, + unsigned32 the_error) +{ + unsigned32 isrlevel; + + _CPU_ISR_Disable(isrlevel); + + asm volatile( "copy %0,%%r1" : : "r" (the_error) ); + HPPA_ASM_BREAK(1, 0); +} diff --git a/cpukit/score/cpu/i386/asm.h b/cpukit/score/cpu/i386/asm.h new file mode 100644 index 0000000000..f123defcd9 --- /dev/null +++ b/cpukit/score/cpu/i386/asm.h @@ -0,0 +1,131 @@ +/* asm.h + * + * This include file attempts to address the problems + * caused by incompatible flavors of assemblers and + * toolsets. It primarily addresses variations in the + * use of leading underscores on symbols and the requirement + * that register names be preceded by a %. + * + * + * NOTE: The spacing in the use of these macros + * is critical to them working as advertised. + * + * COPYRIGHT: + * + * This file is based on similar code found in newlib available + * from ftp.cygnus.com. The file which was used had no copyright + * notice. This file is freely distributable as long as the source + * of the file is noted. This file is: + * + * COPYRIGHT (c) 1994. + * On-Line Applications Research Corporation (OAR). + * + * $Id$ + */ + +#ifndef __i386_ASM_h +#define __i386_ASM_h + +/* + * Indicate we are in an assembly file and get the basic CPU definitions. + */ + +#define ASM +#include + +/* + * Recent versions of GNU cpp define variables which indicate the + * need for underscores and percents. If not using GNU cpp or + * the version does not support this, then you will obviously + * have to define these as appropriate. + */ + +#ifndef __USER_LABEL_PREFIX__ +#define __USER_LABEL_PREFIX__ _ +#endif + +/* + * Looks like there is a bug in gcc 2.6.2 where this is not + * defined correctly when configured as i386-coff and + * i386-aout. + */ + +#undef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ % + +/* +#ifndef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ +#endif +*/ + +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ + +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +/* Use the right prefix for registers. */ + +#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) + +#define eax REG (eax) +#define ebx REG (ebx) +#define ecx REG (ecx) +#define edx REG (edx) +#define esi REG (esi) +#define edi REG (edi) +#define esp REG (esp) +#define ebp REG (ebp) + +#define ax REG (ax) +#define bx REG (bx) +#define cx REG (cx) +#define dx REG (dx) +#define si REG (si) +#define di REG (di) +#define sp REG (sp) +#define bp REG (bp) + +#define ah REG (ah) +#define al REG (al) + +#define cs REG (cs) +#define ds REG (ds) +#define es REG (es) +#define fs REG (fs) +#define gs REG (gs) +#define ss REG (ss) + +/* + * Define macros to handle section beginning and ends. + */ + + +#define BEGIN_CODE_DCL .text +#define END_CODE_DCL +#define BEGIN_DATA_DCL .data +#define END_DATA_DCL +#define BEGIN_CODE .text +#define END_CODE +#define BEGIN_DATA +#define END_DATA +#define BEGIN_BSS +#define END_BSS +#define END + +/* + * Following must be tailor for a particular flavor of the C compiler. + * They may need to put underscores in front of the symbols. + */ + +#define PUBLIC(sym) .globl SYM (sym) +#define EXTERN(sym) .globl SYM (sym) + +#endif +/* end of include file */ + + diff --git a/cpukit/score/cpu/i386/cpu.c b/cpukit/score/cpu/i386/cpu.c new file mode 100644 index 0000000000..05a836f7e3 --- /dev/null +++ b/cpukit/score/cpu/i386/cpu.c @@ -0,0 +1,121 @@ +/* + * Intel i386 Dependent Source + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include + +/* _CPU_Initialize + * + * This routine performs processor dependent initialization. + * + * INPUT PARAMETERS: + * cpu_table - CPU table to initialize + * thread_dispatch - address of disptaching routine + */ + + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) /* ignored on this CPU */ +) +{ + register unsigned16 fp_status asm ("ax"); + register unsigned8 *fp_context; + + if ( cpu_table == NULL ) + rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED ); + + _CPU_Table = *cpu_table; + + /* + * The following code saves a NULL i387 context which is given + * to each task at start and restart time. The following code + * is based upon that provided in the i386 Programmer's + * Manual and should work on any coprocessor greater than + * the i80287. + * + * NOTE: The NO RTEMS_WAIT form of the coprocessor instructions + * MUST be used in case there is not a coprocessor + * to wait for. + */ + + fp_status = 0xa5a5; + asm volatile( "fninit" ); + asm volatile( "fnstsw %0" : "=a" (fp_status) : "0" (fp_status) ); + + if ( fp_status == 0 ) { + + fp_context = _CPU_Null_fp_context; + + asm volatile( "fsave (%0)" : "=r" (fp_context) + : "0" (fp_context) + ); + } +} + +/* _CPU_ISR_install_vector + * + * This kernel routine installs the RTEMS handler for the + * specified vector. + * + * Input parameters: + * vector - interrupt vector number + * old_handler - former ISR for this vector number + * new_handler - replacement ISR for this vector number + * + * Output parameters: NONE + * + */ + +void _ISR_Handler_0(), _ISR_Handler_1(); + +#define PER_ISR_ENTRY \ + (((unsigned32) _ISR_Handler_1 - (unsigned32) _ISR_Handler_0)) + +#define _Interrupt_Handler_entry( _vector ) \ + (((unsigned32)_ISR_Handler_0) + ((_vector) * PER_ISR_ENTRY)) + +void _CPU_ISR_install_vector( + unsigned32 vector, + proc_ptr new_handler, + proc_ptr *old_handler +) +{ + i386_IDT_slot idt; + unsigned32 unique_handler; + + /* calculate the unique entry point for this vector */ + unique_handler = _Interrupt_Handler_entry( vector ); + + /* build the IDT entry */ + idt.offset_0_15 = ((unsigned32) unique_handler) & 0xffff; + idt.segment_selector = i386_get_cs(); + idt.reserved = 0x00; + idt.p_dpl = 0x8e; /* present, ISR */ + idt.offset_16_31 = ((unsigned32) unique_handler) >> 16; + + /* install the IDT entry */ + i386_Install_idt( + (unsigned32) &idt, + _CPU_Table.interrupt_table_segment, + (unsigned32) _CPU_Table.interrupt_table_offset + (8 * vector) + ); + + /* "portable" part */ + *old_handler = _ISR_Vector_table[ vector ]; + _ISR_Vector_table[ vector ] = new_handler; +} diff --git a/cpukit/score/cpu/i386/rtems/asm.h b/cpukit/score/cpu/i386/rtems/asm.h new file mode 100644 index 0000000000..f123defcd9 --- /dev/null +++ b/cpukit/score/cpu/i386/rtems/asm.h @@ -0,0 +1,131 @@ +/* asm.h + * + * This include file attempts to address the problems + * caused by incompatible flavors of assemblers and + * toolsets. It primarily addresses variations in the + * use of leading underscores on symbols and the requirement + * that register names be preceded by a %. + * + * + * NOTE: The spacing in the use of these macros + * is critical to them working as advertised. + * + * COPYRIGHT: + * + * This file is based on similar code found in newlib available + * from ftp.cygnus.com. The file which was used had no copyright + * notice. This file is freely distributable as long as the source + * of the file is noted. This file is: + * + * COPYRIGHT (c) 1994. + * On-Line Applications Research Corporation (OAR). + * + * $Id$ + */ + +#ifndef __i386_ASM_h +#define __i386_ASM_h + +/* + * Indicate we are in an assembly file and get the basic CPU definitions. + */ + +#define ASM +#include + +/* + * Recent versions of GNU cpp define variables which indicate the + * need for underscores and percents. If not using GNU cpp or + * the version does not support this, then you will obviously + * have to define these as appropriate. + */ + +#ifndef __USER_LABEL_PREFIX__ +#define __USER_LABEL_PREFIX__ _ +#endif + +/* + * Looks like there is a bug in gcc 2.6.2 where this is not + * defined correctly when configured as i386-coff and + * i386-aout. + */ + +#undef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ % + +/* +#ifndef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ +#endif +*/ + +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ + +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +/* Use the right prefix for registers. */ + +#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) + +#define eax REG (eax) +#define ebx REG (ebx) +#define ecx REG (ecx) +#define edx REG (edx) +#define esi REG (esi) +#define edi REG (edi) +#define esp REG (esp) +#define ebp REG (ebp) + +#define ax REG (ax) +#define bx REG (bx) +#define cx REG (cx) +#define dx REG (dx) +#define si REG (si) +#define di REG (di) +#define sp REG (sp) +#define bp REG (bp) + +#define ah REG (ah) +#define al REG (al) + +#define cs REG (cs) +#define ds REG (ds) +#define es REG (es) +#define fs REG (fs) +#define gs REG (gs) +#define ss REG (ss) + +/* + * Define macros to handle section beginning and ends. + */ + + +#define BEGIN_CODE_DCL .text +#define END_CODE_DCL +#define BEGIN_DATA_DCL .data +#define END_DATA_DCL +#define BEGIN_CODE .text +#define END_CODE +#define BEGIN_DATA +#define END_DATA +#define BEGIN_BSS +#define END_BSS +#define END + +/* + * Following must be tailor for a particular flavor of the C compiler. + * They may need to put underscores in front of the symbols. + */ + +#define PUBLIC(sym) .globl SYM (sym) +#define EXTERN(sym) .globl SYM (sym) + +#endif +/* end of include file */ + + diff --git a/cpukit/score/cpu/i960/asm.h b/cpukit/score/cpu/i960/asm.h new file mode 100644 index 0000000000..1c40601473 --- /dev/null +++ b/cpukit/score/cpu/i960/asm.h @@ -0,0 +1,107 @@ +/* asm.h + * + * This include file attempts to address the problems + * caused by incompatible flavors of assemblers and + * toolsets. It primarily addresses variations in the + * use of leading underscores on symbols and the requirement + * that register names be preceded by a %. + * + * + * NOTE: The spacing in the use of these macros + * is critical to them working as advertised. + * + * COPYRIGHT: + * + * This file is based on similar code found in newlib available + * from ftp.cygnus.com. The file which was used had no copyright + * notice. This file is freely distributable as long as the source + * of the file is noted. This file is: + * + * COPYRIGHT (c) 1994. + * On-Line Applications Research Corporation (OAR). + * + * $Id$ + */ + +#ifndef __i960_ASM_h +#define __i960_ASM_h + +/* + * Indicate we are in an assembly file and get the basic CPU definitions. + */ + +#define ASM +#include + +/* + * Recent versions of GNU cpp define variables which indicate the + * need for underscores and percents. If not using GNU cpp or + * the version does not support this, then you will obviously + * have to define these as appropriate. + */ + +#ifndef __USER_LABEL_PREFIX__ +#define __USER_LABEL_PREFIX__ _ +#endif + +#ifndef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ +#endif + +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ + +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +/* Use the right prefix for registers. */ + +#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) + +#define g0 REG (g0) +#define g1 REG (g1) +#define g2 REG (g2) +#define g3 REG (g3) +#define g4 REG (g4) +#define g5 REG (g5) +#define g6 REG (g6) +#define g7 REG (g7) +#define g8 REG (g8) +#define g9 REG (g9) +#define g10 REG (g10) +#define g11 REG (g11) +#define g12 REG (g12) +#define g13 REG (g13) +#define g14 REG (g14) +#define g15 REG (g15) + +/* + * Define macros to handle section beginning and ends. + */ + + +#define BEGIN_CODE_DCL .text +#define END_CODE_DCL +#define BEGIN_DATA_DCL .data +#define END_DATA_DCL +#define BEGIN_CODE .text +#define END_CODE +#define BEGIN_DATA +#define END_DATA +#define BEGIN_BSS +#define END_BSS +#define END + +/* + * Following must be tailor for a particular flavor of the C compiler. + * They may need to put underscores in front of the symbols. + */ + +#define PUBLIC(sym) .globl SYM (sym) +#define EXTERN(sym) .globl SYM (sym) + +#endif +/* end of include file */ diff --git a/cpukit/score/cpu/i960/cpu.c b/cpukit/score/cpu/i960/cpu.c new file mode 100644 index 0000000000..68ecb0525c --- /dev/null +++ b/cpukit/score/cpu/i960/cpu.c @@ -0,0 +1,124 @@ +/* + * Intel i960CA Dependent Source + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#if defined(__i960CA__) || defined(__i960_CA__) || defined(__i960CA) +#else +#warning "*** ENTIRE FILE IMPLEMENTED & TESTED FOR CA ONLY ***" +#warning "*** THIS FILE WILL NOT COMPILE ON ANOTHER FAMILY MEMBER ***" +#endif + +#include +#include +#include + +/* _CPU_Initialize + * + * This routine performs processor dependent initialization. + * + * INPUT PARAMETERS: + * cpu_table - CPU table to initialize + * thread_dispatch - address of disptaching routine + * + * OUTPUT PARAMETERS: NONE + */ + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) /* ignored on this CPU */ +) +{ + + if ( cpu_table == NULL ) + rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED ); + + _CPU_Table = *cpu_table; + +} + +/* _CPU__ISR_Install_vector + * + * Install the RTEMS vector wrapper in the CPU's interrupt table. + * + * Input parameters: + * vector - interrupt vector number + * old_handler - former ISR for this vector number + * new_handler - replacement ISR for this vector number + * + * Output parameters: NONE + * + */ + +#define _Is_vector_caching_enabled( _prcb ) \ + ((_prcb)->control_tbl->icon & 0x2000) + +void _CPU_ISR_install_vector( + unsigned32 vector, + proc_ptr new_handler, + proc_ptr *old_handler +) +{ + i960ca_PRCB *prcb = _CPU_Table.Prcb; + proc_ptr *cached_intr_tbl = NULL; + +/* The i80960CA does not support vectors 0-7. The first 9 entries + * in the Interrupt Table are used to manage pending interrupts. + * Thus vector 8, the first valid vector number, is actually in + * slot 9 in the table. + */ + + *old_handler = _ISR_Vector_table[ vector ]; + + _ISR_Vector_table[ vector ] = new_handler; + + prcb->intr_tbl[ vector + 1 ] = _ISR_Handler; + if ( _Is_vector_caching_enabled( prcb ) ) + if ( (vector & 0xf) == 0x2 ) /* cacheable? */ + cached_intr_tbl[ vector >> 4 ] = _ISR_Handler; +} + +/*PAGE + * + * _CPU_Install_interrupt_stack + */ + +#define soft_reset( prcb ) \ + { register i960ca_PRCB *_prcb = (prcb); \ + register unsigned32 *_next=0; \ + register unsigned32 _cmd = 0x30000; \ + asm volatile( "lda next,%1; \ + sysctl %0,%1,%2; \ + next: mov g0,g0" \ + : "=d" (_cmd), "=d" (_next), "=d" (_prcb) \ + : "0" (_cmd), "1" (_next), "2" (_prcb) ); \ + } + +void _CPU_Install_interrupt_stack( void ) +{ + i960ca_PRCB *prcb = _CPU_Table.Prcb; + unsigned32 level; + + /* + * Set the Interrupt Stack in the PRCB and force a reload of it. + * Interrupts are disabled for safety. + */ + + _CPU_ISR_Disable( level ); + + prcb->intr_stack = _CPU_Interrupt_stack_low; + + soft_reset( prcb ); + + _CPU_ISR_Enable( level ); +} diff --git a/cpukit/score/cpu/m68k/asm.h b/cpukit/score/cpu/m68k/asm.h new file mode 100644 index 0000000000..068c58058c --- /dev/null +++ b/cpukit/score/cpu/m68k/asm.h @@ -0,0 +1,127 @@ +/* asm.h + * + * This include file attempts to address the problems + * caused by incompatible flavors of assemblers and + * toolsets. It primarily addresses variations in the + * use of leading underscores on symbols and the requirement + * that register names be preceded by a %. + * + * + * NOTE: The spacing in the use of these macros + * is critical to them working as advertised. + * + * COPYRIGHT: + * + * This file is based on similar code found in newlib available + * from ftp.cygnus.com. The file which was used had no copyright + * notice. This file is freely distributable as long as the source + * of the file is noted. This file is: + * + * COPYRIGHT (c) 1994. + * On-Line Applications Research Corporation (OAR). + * + * $Id$ + */ + +#ifndef __M68k_ASM_h +#define __M68k_ASM_h + +/* + * Indicate we are in an assembly file and get the basic CPU definitions. + */ + +#define ASM +#include + +/* + * Recent versions of GNU cpp define variables which indicate the + * need for underscores and percents. If not using GNU cpp or + * the version does not support this, then you will obviously + * have to define these as appropriate. + */ + +#ifndef __USER_LABEL_PREFIX__ +#define __USER_LABEL_PREFIX__ _ +#endif + +#ifndef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ +#endif + +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ + +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +/* Use the right prefix for registers. */ + +#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) + +#define d0 REG (d0) +#define d1 REG (d1) +#define d2 REG (d2) +#define d3 REG (d3) +#define d4 REG (d4) +#define d5 REG (d5) +#define d6 REG (d6) +#define d7 REG (d7) +#define a0 REG (a0) +#define a1 REG (a1) +#define a2 REG (a2) +#define a3 REG (a3) +#define a4 REG (a4) +#define a5 REG (a5) +#define a6 REG (a6) +#define a7 REG (a7) + +#define msp REG (msp) +#define usp REG (usp) +#define isp REG (isp) +#define sr REG (sr) + +#define fp0 REG (fp0) +#define fp1 REG (fp1) +#define fp2 REG (fp2) +#define fp3 REG (fp3) +#define fp4 REG (fp4) +#define fp5 REG (fp5) +#define fp6 REG (fp6) +#define fp7 REG (fp7) + +#define fpc REG (fpc) +#define fpi REG (fpi) +#define fps REG (fps) + +/* + * Define macros to handle section beginning and ends. + */ + + +#define BEGIN_CODE_DCL .text +#define END_CODE_DCL +#define BEGIN_DATA_DCL .data +#define END_DATA_DCL +#define BEGIN_CODE .text +#define END_CODE +#define BEGIN_DATA +#define END_DATA +#define BEGIN_BSS +#define END_BSS +#define END + +/* + * Following must be tailor for a particular flavor of the C compiler. + * They may need to put underscores in front of the symbols. + */ + +#define PUBLIC(sym) .globl SYM (sym) +#define EXTERN(sym) .globl SYM (sym) + +#endif +/* end of include file */ + + diff --git a/cpukit/score/cpu/m68k/cpu.c b/cpukit/score/cpu/m68k/cpu.c new file mode 100644 index 0000000000..45484da1f4 --- /dev/null +++ b/cpukit/score/cpu/m68k/cpu.c @@ -0,0 +1,97 @@ +/* + * Motorola MC68020 Dependent Source + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +/* _CPU_Initialize + * + * This routine performs processor dependent initialization. + * + * INPUT PARAMETERS: + * cpu_table - CPU table to initialize + * thread_dispatch - entry pointer to thread dispatcher + * + * OUTPUT PARAMETERS: NONE + */ + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) /* ignored on this CPU */ +) +{ + + if ( cpu_table == NULL ) + rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED ); + + _CPU_Table = *cpu_table; + +} + +/* _CPU_ISR_install_vector + * + * This kernel routine installs the RTEMS handler for the + * specified vector. + * + * Input parameters: + * vector - interrupt vector number + * new_handler - replacement ISR for this vector number + * old_handler - former ISR for this vector number + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +void _CPU_ISR_install_vector( + unsigned32 vector, + proc_ptr new_handler, + proc_ptr *old_handler +) +{ + proc_ptr *interrupt_table = NULL; + + m68k_get_vbr( interrupt_table ); + + *old_handler = _ISR_Vector_table[ vector ]; + + _ISR_Vector_table[ vector ] = new_handler; + interrupt_table[ vector ] = _ISR_Handler; +} + + +/*PAGE + * + * _CPU_Install_interrupt_stack + */ + +void _CPU_Install_interrupt_stack( void ) +{ +#if ( M68K_HAS_SEPARATE_STACKS == 1 ) + void *isp = _CPU_Interrupt_stack_high; + + asm volatile ( "movec %0,%%isp" : "=r" (isp) : "0" (isp) ); +#else +#warning "FIX ME... HOW DO I INSTALL THE INTERRUPT STACK!!!" +#endif +} + diff --git a/cpukit/score/cpu/m68k/rtems/asm.h b/cpukit/score/cpu/m68k/rtems/asm.h new file mode 100644 index 0000000000..068c58058c --- /dev/null +++ b/cpukit/score/cpu/m68k/rtems/asm.h @@ -0,0 +1,127 @@ +/* asm.h + * + * This include file attempts to address the problems + * caused by incompatible flavors of assemblers and + * toolsets. It primarily addresses variations in the + * use of leading underscores on symbols and the requirement + * that register names be preceded by a %. + * + * + * NOTE: The spacing in the use of these macros + * is critical to them working as advertised. + * + * COPYRIGHT: + * + * This file is based on similar code found in newlib available + * from ftp.cygnus.com. The file which was used had no copyright + * notice. This file is freely distributable as long as the source + * of the file is noted. This file is: + * + * COPYRIGHT (c) 1994. + * On-Line Applications Research Corporation (OAR). + * + * $Id$ + */ + +#ifndef __M68k_ASM_h +#define __M68k_ASM_h + +/* + * Indicate we are in an assembly file and get the basic CPU definitions. + */ + +#define ASM +#include + +/* + * Recent versions of GNU cpp define variables which indicate the + * need for underscores and percents. If not using GNU cpp or + * the version does not support this, then you will obviously + * have to define these as appropriate. + */ + +#ifndef __USER_LABEL_PREFIX__ +#define __USER_LABEL_PREFIX__ _ +#endif + +#ifndef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ +#endif + +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ + +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +/* Use the right prefix for registers. */ + +#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) + +#define d0 REG (d0) +#define d1 REG (d1) +#define d2 REG (d2) +#define d3 REG (d3) +#define d4 REG (d4) +#define d5 REG (d5) +#define d6 REG (d6) +#define d7 REG (d7) +#define a0 REG (a0) +#define a1 REG (a1) +#define a2 REG (a2) +#define a3 REG (a3) +#define a4 REG (a4) +#define a5 REG (a5) +#define a6 REG (a6) +#define a7 REG (a7) + +#define msp REG (msp) +#define usp REG (usp) +#define isp REG (isp) +#define sr REG (sr) + +#define fp0 REG (fp0) +#define fp1 REG (fp1) +#define fp2 REG (fp2) +#define fp3 REG (fp3) +#define fp4 REG (fp4) +#define fp5 REG (fp5) +#define fp6 REG (fp6) +#define fp7 REG (fp7) + +#define fpc REG (fpc) +#define fpi REG (fpi) +#define fps REG (fps) + +/* + * Define macros to handle section beginning and ends. + */ + + +#define BEGIN_CODE_DCL .text +#define END_CODE_DCL +#define BEGIN_DATA_DCL .data +#define END_DATA_DCL +#define BEGIN_CODE .text +#define END_CODE +#define BEGIN_DATA +#define END_DATA +#define BEGIN_BSS +#define END_BSS +#define END + +/* + * Following must be tailor for a particular flavor of the C compiler. + * They may need to put underscores in front of the symbols. + */ + +#define PUBLIC(sym) .globl SYM (sym) +#define EXTERN(sym) .globl SYM (sym) + +#endif +/* end of include file */ + + diff --git a/cpukit/score/cpu/no_cpu/asm.h b/cpukit/score/cpu/no_cpu/asm.h new file mode 100644 index 0000000000..69b1f0f825 --- /dev/null +++ b/cpukit/score/cpu/no_cpu/asm.h @@ -0,0 +1,98 @@ +/* asm.h + * + * This include file attempts to address the problems + * caused by incompatible flavors of assemblers and + * toolsets. It primarily addresses variations in the + * use of leading underscores on symbols and the requirement + * that register names be preceded by a %. + * + * + * NOTE: The spacing in the use of these macros + * is critical to them working as advertised. + * + * COPYRIGHT: + * + * This file is based on similar code found in newlib available + * from ftp.cygnus.com. The file which was used had no copyright + * notice. This file is freely distributable as long as the source + * of the file is noted. This file is: + * + * COPYRIGHT (c) 1994. + * On-Line Applications Research Corporation (OAR). + * + * $Id$ + */ + +#ifndef __NO_CPU_ASM_h +#define __NO_CPU_ASM_h + +/* + * Indicate we are in an assembly file and get the basic CPU definitions. + */ + +#define ASM +#include + +/* + * Recent versions of GNU cpp define variables which indicate the + * need for underscores and percents. If not using GNU cpp or + * the version does not support this, then you will obviously + * have to define these as appropriate. + */ + +#ifndef __USER_LABEL_PREFIX__ +#define __USER_LABEL_PREFIX__ _ +#endif + +#ifndef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ +#endif + +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ + +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +/* Use the right prefix for registers. */ + +#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) + +/* + * define macros for all of the registers on this CPU + * + * EXAMPLE: #define d0 REG (d0) + */ + +/* + * Define macros to handle section beginning and ends. + */ + + +#define BEGIN_CODE_DCL .text +#define END_CODE_DCL +#define BEGIN_DATA_DCL .data +#define END_DATA_DCL +#define BEGIN_CODE .text +#define END_CODE +#define BEGIN_DATA +#define END_DATA +#define BEGIN_BSS +#define END_BSS +#define END + +/* + * Following must be tailor for a particular flavor of the C compiler. + * They may need to put underscores in front of the symbols. + */ + +#define PUBLIC(sym) .globl SYM (sym) +#define EXTERN(sym) .globl SYM (sym) + +#endif +/* end of include file */ + + diff --git a/cpukit/score/cpu/no_cpu/cpu.c b/cpukit/score/cpu/no_cpu/cpu.c new file mode 100644 index 0000000000..f09d935c2d --- /dev/null +++ b/cpukit/score/cpu/no_cpu/cpu.c @@ -0,0 +1,132 @@ +/* + * XXX CPU Dependent Source + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include + +/* _CPU_Initialize + * + * This routine performs processor dependent initialization. + * + * INPUT PARAMETERS: + * cpu_table - CPU table to initialize + * thread_dispatch - address of disptaching routine + */ + + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) /* ignored on this CPU */ +) +{ + if ( cpu_table == NULL ) + rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED ); + + /* + * The thread_dispatch argument is the address of the entry point + * for the routine called at the end of an ISR once it has been + * decided a context switch is necessary. On some compilation + * systems it is difficult to call a high-level language routine + * from assembly. This allows us to trick these systems. + * + * If you encounter this problem save the entry point in a CPU + * dependent variable. + */ + + _CPU_Thread_dispatch_pointer = thread_dispatch; + + /* + * XXX; If there is not an easy way to initialize the FP context + * during Context_Initialize, then it is usually easier to + * save an "uninitialized" FP context here and copy it to + * the task's during Context_Initialize. + */ + + /* XXX: FP context initialization support */ + + _CPU_Table = *cpu_table; +} + +/* _CPU_ISR_install_vector + * + * This kernel routine installs the RTEMS handler for the + * specified vector. + * + * Input parameters: + * vector - interrupt vector number + * old_handler - former ISR for this vector number + * new_handler - replacement ISR for this vector number + * + * Output parameters: NONE + * + */ + + +void _CPU_ISR_install_vector( + unsigned32 vector, + proc_ptr new_handler, + proc_ptr *old_handler +) +{ + *old_handler = _ISR_Vector_table[ vector ]; + + /* + * If the interrupt vector table is a table of pointer to isr entry + * points, then we need to install the appropriate RTEMS interrupt + * handler for this vector number. + */ + + /* + * We put the actual user ISR address in '_ISR_vector_table'. This will + * be used by the _ISR_Handler so the user gets control. + */ + + _ISR_Vector_table[ vector ] = new_handler; +} + +/*PAGE + * + * _CPU_Install_interrupt_stack + */ + +void _CPU_Install_interrupt_stack( void ) +{ +} + +/*PAGE + * + * _CPU_Internal_threads_Idle_thread_body + * + * NOTES: + * + * 1. This is the same as the regular CPU independent algorithm. + * + * 2. If you implement this using a "halt", "idle", or "shutdown" + * instruction, then don't forget to put it in an infinite loop. + * + * 3. Be warned. Some processors with onboard DMA have been known + * to stop the DMA if the CPU were put in IDLE mode. This might + * also be a problem with other on-chip peripherals. So use this + * hook with caution. + */ + +void _CPU_Internal_threads_Idle_thread_body( void ) +{ + + for( ; ; ) + /* insert your "halt" instruction here */ ; +} diff --git a/cpukit/score/cpu/no_cpu/cpu_asm.c b/cpukit/score/cpu/no_cpu/cpu_asm.c new file mode 100644 index 0000000000..26246a93c2 --- /dev/null +++ b/cpukit/score/cpu/no_cpu/cpu_asm.c @@ -0,0 +1,152 @@ +/* cpu_asm.c ===> cpu_asm.S or cpu_asm.s + * + * This file contains the basic algorithms for all assembly code used + * in an specific CPU port of RTEMS. These algorithms must be implemented + * in assembly language + * + * NOTE: This is supposed to be a .S or .s file NOT a C file. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +/* + * This is supposed to be an assembly file. This means that system.h + * and cpu.h should not be included in a "real" cpu_asm file. An + * implementation in assembly should include "cpu_asm.h> + */ + +#include +#include +/* #include "cpu_asm.h> */ + +/* + * _CPU_Context_save_fp_context + * + * This routine is responsible for saving the FP context + * at *fp_context_ptr. If the point to load the FP context + * from is changed then the pointer is modified by this routine. + * + * Sometimes a macro implementation of this is in cpu.h which dereferences + * the ** and a similarly named routine in this file is passed something + * like a (Context_Control_fp *). The general rule on making this decision + * is to avoid writing assembly language. + */ + +void _CPU_Context_save_fp( + void **fp_context_ptr +) +{ +} + +/* + * _CPU_Context_restore_fp_context + * + * This routine is responsible for restoring the FP context + * at *fp_context_ptr. If the point to load the FP context + * from is changed then the pointer is modified by this routine. + * + * Sometimes a macro implementation of this is in cpu.h which dereferences + * the ** and a similarly named routine in this file is passed something + * like a (Context_Control_fp *). The general rule on making this decision + * is to avoid writing assembly language. + */ + +void _CPU_Context_restore_fp( + void **fp_context_ptr +) +{ +} + +/* _CPU_Context_switch + * + * This routine performs a normal non-FP context switch. + */ + +void _CPU_Context_switch( + Context_Control *run, + Context_Control *heir +) +{ +} + +/* + * _CPU_Context_restore + * + * This routine is generallu used only to restart self in an + * efficient manner. It may simply be a label in _CPU_Context_switch. + * + * NOTE: May be unnecessary to reload some registers. + */ + +void _CPU_Context_restore( + Context_Control *new_context +) +{ +} + +/* void __ISR_Handler() + * + * This routine provides the RTEMS interrupt management. + * + */ + +void _ISR_Handler() +{ + /* + * This discussion ignores a lot of the ugly details in a real + * implementation such as saving enough registers/state to be + * able to do something real. Keep in mind that the goal is + * to invoke a user's ISR handler which is written in C and + * uses a certain set of registers. + * + * Also note that the exact order is to a large extent flexible. + * Hardware will dictate a sequence for a certain subset of + * _ISR_Handler while requirements for setting + */ + + /* + * At entry to "common" _ISR_Handler, the vector number must be + * available. On some CPUs the hardware puts either the vector + * number or the offset into the vector table for this ISR in a + * known place. If the hardware does not give us this information, + * then the assembly portion of RTEMS for this port will contain + * a set of distinct interrupt entry points which somehow place + * the vector number in a known place (which is safe if another + * interrupt nests this one) and branches to _ISR_Handler. + * + * save some or all context on stack + * may need to save some special interrupt information for exit + * + * #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE ) + * if ( _ISR_Nest_level == 0 ) + * switch to software interrupt stack + * #endif + * + * _ISR_Nest_level++; + * + * _Thread_Dispatch_disable_level++; + * + * (*_ISR_Vector_table[ vector ])( vector ); + * + * if ( --__ISR_Nest_level == 0 ) { + * if ( _Context_Switch_necessary || _ISR_Signals_to_thread_executing ) + * call _Thread_Dispatch() or prepare to return to _ISR_Dispatch + * #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE ) + * restore stack + * #endif + * } + * + * prepare to get out of interrupt + * return from interrupt + * + */ +} + diff --git a/cpukit/score/cpu/no_cpu/rtems/asm.h b/cpukit/score/cpu/no_cpu/rtems/asm.h new file mode 100644 index 0000000000..69b1f0f825 --- /dev/null +++ b/cpukit/score/cpu/no_cpu/rtems/asm.h @@ -0,0 +1,98 @@ +/* asm.h + * + * This include file attempts to address the problems + * caused by incompatible flavors of assemblers and + * toolsets. It primarily addresses variations in the + * use of leading underscores on symbols and the requirement + * that register names be preceded by a %. + * + * + * NOTE: The spacing in the use of these macros + * is critical to them working as advertised. + * + * COPYRIGHT: + * + * This file is based on similar code found in newlib available + * from ftp.cygnus.com. The file which was used had no copyright + * notice. This file is freely distributable as long as the source + * of the file is noted. This file is: + * + * COPYRIGHT (c) 1994. + * On-Line Applications Research Corporation (OAR). + * + * $Id$ + */ + +#ifndef __NO_CPU_ASM_h +#define __NO_CPU_ASM_h + +/* + * Indicate we are in an assembly file and get the basic CPU definitions. + */ + +#define ASM +#include + +/* + * Recent versions of GNU cpp define variables which indicate the + * need for underscores and percents. If not using GNU cpp or + * the version does not support this, then you will obviously + * have to define these as appropriate. + */ + +#ifndef __USER_LABEL_PREFIX__ +#define __USER_LABEL_PREFIX__ _ +#endif + +#ifndef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ +#endif + +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ + +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +/* Use the right prefix for registers. */ + +#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) + +/* + * define macros for all of the registers on this CPU + * + * EXAMPLE: #define d0 REG (d0) + */ + +/* + * Define macros to handle section beginning and ends. + */ + + +#define BEGIN_CODE_DCL .text +#define END_CODE_DCL +#define BEGIN_DATA_DCL .data +#define END_DATA_DCL +#define BEGIN_CODE .text +#define END_CODE +#define BEGIN_DATA +#define END_DATA +#define BEGIN_BSS +#define END_BSS +#define END + +/* + * Following must be tailor for a particular flavor of the C compiler. + * They may need to put underscores in front of the symbols. + */ + +#define PUBLIC(sym) .globl SYM (sym) +#define EXTERN(sym) .globl SYM (sym) + +#endif +/* end of include file */ + + diff --git a/cpukit/score/cpu/unix/cpu.c b/cpukit/score/cpu/unix/cpu.c new file mode 100644 index 0000000000..ed94953d58 --- /dev/null +++ b/cpukit/score/cpu/unix/cpu.c @@ -0,0 +1,529 @@ +/* + * HP PA-RISC CPU Dependent Source + * + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Division Incorporated not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * Division Incorporated makes no representations about the + * suitability of this software for any purpose. + * + * $Id$ + */ + +#include +#include +#include +#include +/* + * In order to get the types and prototypes used in this file under + * Solaris 2.3, it is necessary to pull the following magic. + */ + +#if defined(solaris) +#warning "Ignore the undefining __STDC__ warning" +#undef __STDC__ +#define __STDC__ 0 +#undef _POSIX_C_SOURCE +#endif + +#include +#include +#include +#include +#include +#include + +extern void set_vector(proc_ptr, int, int); +extern void _Thread_Dispatch(void); + +extern unsigned32 _Thread_Dispatch_disable_level; +extern unsigned32 _SYSTEM_ID; +extern boolean _Context_Switch_necessary; + + +rtems_status_code signal_initialize(void); +void Stray_signal(int); +void signal_enable(unsigned32); +void signal_disable(unsigned32); +void interrupt_handler(); + +sigset_t UNIX_SIGNAL_MASK; +jmp_buf default_context; + +/* + * Which cpu are we? Used by libcpu and libbsp. + */ + +int cpu_number; + +/* _CPU_Initialize + * + * This routine performs processor dependent initialization. + * + * INPUT PARAMETERS: + * cpu_table - CPU table to initialize + * thread_dispatch - address of disptaching routine + */ + + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) /* ignored on this CPU */ +) +{ + unsigned32 i; + + if ( cpu_table == NULL ) + rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED ); + + /* + * The thread_dispatch argument is the address of the entry point + * for the routine called at the end of an ISR once it has been + * decided a context switch is necessary. On some compilation + * systems it is difficult to call a high-level language routine + * from assembly. This allows us to trick these systems. + * + * If you encounter this problem save the entry point in a CPU + * dependent variable. + */ + + _CPU_Thread_dispatch_pointer = thread_dispatch; + + /* + * XXX; If there is not an easy way to initialize the FP context + * during Context_Initialize, then it is usually easier to + * save an "uninitialized" FP context here and copy it to + * the task's during Context_Initialize. + */ + + /* XXX: FP context initialization support */ + + _CPU_Table = *cpu_table; + +#if defined(hppa1_1) && defined(RTEMS_UNIXLIB) + /* + * HACK - set the _SYSTEM_ID to 0x20c so that setjmp/longjmp + * will handle the full 32 floating point registers. + * + * NOTE: Is this a bug in HPUX9? + */ + + _SYSTEM_ID = 0x20c; +#endif + + /* + * get default values to use in _CPU_Context_Initialize() + */ + + setjmp(default_context); + + /* + * Block all the signals except SIGTRAP for the debugger + * and SIGABRT for fatal errors. + */ + + _CPU_ISR_Set_signal_level(1); + + sigfillset(&UNIX_SIGNAL_MASK); + sigdelset(&UNIX_SIGNAL_MASK, SIGTRAP); + sigdelset(&UNIX_SIGNAL_MASK, SIGABRT); + sigdelset(&UNIX_SIGNAL_MASK, SIGIOT); + sigdelset(&UNIX_SIGNAL_MASK, SIGCONT); + + sigprocmask(SIG_BLOCK, &UNIX_SIGNAL_MASK, 0); + + /* + * Set the handler for all signals to be signal_handler + * which will then vector out to the correct handler + * for whichever signal actually happened. Initially + * set the vectors to the stray signal handler. + */ + + for (i = 0; i < 32; i++) + (void)set_vector(Stray_signal, i, 1); + + signal_initialize(); +} + +/* _CPU_ISR_install_vector + * + * This kernel routine installs the RTEMS handler for the + * specified vector. + * + * Input parameters: + * vector - interrupt vector number + * old_handler - former ISR for this vector number + * new_handler - replacement ISR for this vector number + * + * Output parameters: NONE + * + */ + + +void _CPU_ISR_install_vector( + unsigned32 vector, + proc_ptr new_handler, + proc_ptr *old_handler +) +{ + *old_handler = _ISR_Vector_table[ vector ]; + + /* + * If the interrupt vector table is a table of pointer to isr entry + * points, then we need to install the appropriate RTEMS interrupt + * handler for this vector number. + */ + + /* + * We put the actual user ISR address in '_ISR_vector_table'. This will + * be used by the _ISR_Handler so the user gets control. + */ + + _ISR_Vector_table[ vector ] = new_handler; +} + +/*PAGE + * + * _CPU_Install_interrupt_stack + */ + +void _CPU_Install_interrupt_stack( void ) +{ +} + +/*PAGE + * + * _CPU_Internal_threads_Idle_thread_body + * + * NOTES: + * + * 1. This is the same as the regular CPU independent algorithm. + * + * 2. If you implement this using a "halt", "idle", or "shutdown" + * instruction, then don't forget to put it in an infinite loop. + * + * 3. Be warned. Some processors with onboard DMA have been known + * to stop the DMA if the CPU were put in IDLE mode. This might + * also be a problem with other on-chip peripherals. So use this + * hook with caution. + */ + +void _CPU_Internal_threads_Idle_thread_body( void ) +{ + while (1) + pause(); +} + +void _CPU_Context_Initialize( + Context_Control *_the_context, + unsigned32 *_stack_base, + unsigned32 _size, + unsigned32 _new_level, + proc_ptr *_entry_point +) +{ + unsigned32 *addr; + unsigned32 jmp_addr; + unsigned32 _stack; + unsigned32 _the_size; + + jmp_addr = (unsigned32) _entry_point; + + _stack = ((unsigned32)(_stack_base) + CPU_STACK_ALIGNMENT); + _stack &= ~(CPU_STACK_ALIGNMENT - 1); + + _the_size = _size & ~(CPU_STACK_ALIGNMENT - 1); + + /* + * Slam our jmp_buf template into the context we are creating + */ + + memcpy(_the_context, default_context, sizeof(jmp_buf)); + + addr = (unsigned32 *)_the_context; + +#if defined(hppa1_1) + *(addr + RP_OFF) = jmp_addr; + *(addr + SP_OFF) = (unsigned32)(_stack + CPU_FRAME_SIZE); + + /* + * See if we are using shared libraries by checking + * bit 30 in 24 off of newp. If bit 30 is set then + * we are using shared libraries and the jump address + * is at what 24 off of newp points to so shove that + * into 24 off of newp instead. + */ + + if (jmp_addr & 0x40000000) { + jmp_addr &= 0xfffffffc; + *(addr + RP_OFF) = (unsigned32)*(unsigned32 *)jmp_addr; + } +#elif defined(sparc) + + /* + * See /usr/include/sys/stack.h in Solaris 2.3 for a nice + * diagram of the stack. + */ + + asm ("ta 0x03"); /* flush registers */ + + *(addr + RP_OFF) = jmp_addr + ADDR_ADJ_OFFSET; + *(addr + SP_OFF) = (unsigned32)(_stack +_the_size - CPU_FRAME_SIZE); + *(addr + FP_OFF) = (unsigned32)(_stack +_the_size); +#else +#error "UNKNOWN CPU!!!" +#endif + + if (_new_level) + _CPU_ISR_Set_signal_level(1); + else + _CPU_ISR_Set_signal_level(0); + +} + +void _CPU_Context_restore( + Context_Control *next +) +{ + longjmp(next->regs, 0); +} + +void _CPU_Context_switch( + Context_Control *current, + Context_Control *next +) +{ + /* + * Save the current context + */ + + if (setjmp(current->regs) == 0) { + + /* + * Switch to the new context + */ + + longjmp(next->regs, 0); + } +} + +void _CPU_Save_float_context( + Context_Control_fp *fp_context +) +{ +} + +void _CPU_Restore_float_context( + Context_Control_fp *fp_context +) +{ +} + +void _CPU_ISR_Set_signal_level(unsigned32 level) +{ + if (level) + _CPU_Disable_signal(); + else + _CPU_Enable_signal(0); +} + + +unsigned32 _CPU_Disable_signal(void) +{ + sigset_t old_mask; + sigset_t empty_mask; + + sigemptyset(&empty_mask); + sigemptyset(&old_mask); + sigprocmask(SIG_BLOCK, &UNIX_SIGNAL_MASK, &old_mask); + + if (memcmp((char *)&empty_mask, (char *)&old_mask, sizeof(sigset_t)) != 0) + return 1; + + return 0; +} + + +void _CPU_Enable_signal(unsigned32 level) +{ + if (level == 0) + sigprocmask(SIG_UNBLOCK, &UNIX_SIGNAL_MASK, 0); +} + + +/* + * Support for external and spurious interrupts on HPPA + * + * TODO: + * delete interrupt.c etc. + * Count interrupts + * make sure interrupts disabled properly + * should handler check again for more interrupts before exit? + * How to enable interrupts from an interrupt handler? + * Make sure there is an entry for everything in ISR_Vector_Table + */ + +/* + * Init the external interrupt scheme + * called by bsp_start() + */ + +rtems_status_code +signal_initialize(void) +{ + struct sigaction act; + sigset_t mask; + + /* mark them all active except for TraceTrap and Abort */ + + sigfillset(&mask); + sigdelset(&mask, SIGTRAP); + sigdelset(&mask, SIGABRT); + sigdelset(&mask, SIGIOT); + sigdelset(&mask, SIGCONT); + sigprocmask(SIG_UNBLOCK, &mask, 0); + + act.sa_handler = interrupt_handler; + act.sa_mask = mask; +#if defined(solaris) + act.sa_flags = SA_RESTART; +#else + act.sa_flags = 0; +#endif + + sigaction(SIGHUP, &act, 0); + sigaction(SIGINT, &act, 0); + sigaction(SIGQUIT, &act, 0); + sigaction(SIGILL, &act, 0); + sigaction(SIGEMT, &act, 0); + sigaction(SIGFPE, &act, 0); + sigaction(SIGKILL, &act, 0); + sigaction(SIGBUS, &act, 0); + sigaction(SIGSEGV, &act, 0); + sigaction(SIGSYS, &act, 0); + sigaction(SIGPIPE, &act, 0); + sigaction(SIGALRM, &act, 0); + sigaction(SIGTERM, &act, 0); + sigaction(SIGUSR1, &act, 0); + sigaction(SIGUSR2, &act, 0); + sigaction(SIGCHLD, &act, 0); + sigaction(SIGCLD, &act, 0); + sigaction(SIGPWR, &act, 0); + sigaction(SIGVTALRM, &act, 0); + sigaction(SIGPROF, &act, 0); + sigaction(SIGIO, &act, 0); + sigaction(SIGWINCH, &act, 0); + sigaction(SIGSTOP, &act, 0); + sigaction(SIGTTIN, &act, 0); + sigaction(SIGTTOU, &act, 0); + sigaction(SIGURG, &act, 0); +/* + * XXX: Really should be on HPUX. + */ + +#if defined(hppa1_1) + sigaction(SIGLOST, &act, 0); +#endif + + return RTEMS_SUCCESSFUL; +} + + +/* + * External interrupt handler. + * This is installed as cpu interrupt handler. + * It vectors out to specific external interrupt handlers. + */ + +void +interrupt_handler(int vector) +{ + if (_ISR_Nest_level++ == 0) { + /* switch to interrupt stack */ + } + + _Thread_Dispatch_disable_level++; + + if (_ISR_Vector_table[vector]) { + _ISR_Vector_table[vector](vector); + } + else { + Stray_signal(vector); + } + + if (_ISR_Nest_level-- == 0) { + /* switch back to original stack */ + } + + _Thread_Dispatch_disable_level--; + + if (_Thread_Dispatch_disable_level == 0 && + (_Context_Switch_necessary || _ISR_Signals_to_thread_executing)) { + _CPU_Enable_signal(0); + _Thread_Dispatch(); + } +} + + +void +Stray_signal(int sig_num) +{ + char buffer[ 80 ]; + + /* + * We avoid using the stdio section of the library. + * The following is generally safe. + */ + + write( + 2, + buffer, + sprintf( buffer, "Stray signal %d\n", sig_num ) + ); + + /* + * If it was a "fatal" signal, then exit here + * If app code has installed a hander for one of these, then + * we won't call Stray_signal, so this is ok. + */ + + switch (sig_num) + { + case SIGINT: + case SIGHUP: + case SIGQUIT: + case SIGILL: + case SIGEMT: + case SIGKILL: + case SIGBUS: + case SIGSEGV: + case SIGTERM: + _CPU_Fatal_error(0x100 + sig_num); + } +} + + +void +_CPU_Fatal_error(unsigned32 error) +{ + setitimer(ITIMER_REAL, 0, 0); + + _exit(error); +} + +int +_CPU_ffs(unsigned32 value) +{ + int output; + + output = ffs(value); + output = output - 1; + + return(output); +} diff --git a/cpukit/score/include/rtems/debug.h b/cpukit/score/include/rtems/debug.h new file mode 100644 index 0000000000..afe6251bbe --- /dev/null +++ b/cpukit/score/include/rtems/debug.h @@ -0,0 +1,98 @@ +/* debug.h + * + * This include file contains the information pertaining to the debug + * support within RTEMS. It is currently cast in the form of a + * Manager since it is externally accessible. + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_DEBUG_h +#define __RTEMS_DEBUG_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following type is used to manage the debug mask. + */ + +typedef unsigned32 rtems_debug_control; + +/* + * These constants represent various classes of debugging. + */ + +#define RTEMS_DEBUG_ALL_MASK 0xffffffff +#define RTEMS_DEBUG_REGION 0x00000001 + +/* + * This variable contains the current debug level. + */ + +EXTERN rtems_debug_control _Debug_Level; + +/* + * _Debug_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _Debug_Manager_initialization( void ); + +/* + * rtems_debug_enable + * + * DESCRIPTION: + * + * This routine enables the specified types of debug checks. + */ + +void rtems_debug_enable ( + rtems_debug_control to_be_enabled +); + +/* + * rtems_debug_disable + * + * DESCRIPTION: + * + * This routine disables the specified types of debug checks. + */ + +void rtems_debug_disable ( + rtems_debug_control to_be_disabled +); + +/* + * + * _Debug_Is_enabled + * + * DESCRIPTION: + * + * This routine returns TRUE if the requested debug level is + * enabled, and FALSE otherwise. + */ + +boolean _Debug_Is_enabled( + rtems_debug_control level +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/address.h b/cpukit/score/include/rtems/score/address.h new file mode 100644 index 0000000000..0abd113f63 --- /dev/null +++ b/cpukit/score/include/rtems/score/address.h @@ -0,0 +1,122 @@ +/* address.h + * + * This include file contains the information required to manipulate + * physical addresses. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_ADDRESSES_h +#define __RTEMS_ADDRESSES_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * _Addresses_Add_offset + * + * DESCRIPTION: + * + * This function is used to add an offset to a base address. + * It returns the resulting address. This address is typically + * converted to an access type before being used further. + */ + +STATIC INLINE void *_Addresses_Add_offset ( + void *base, + unsigned32 offset +); + +/* + * _Addresses_Subtract_offset + * + * DESCRIPTION: + * + * This function is used to subtract an offset from a base + * address. It returns the resulting address. This address is + * typically converted to an access type before being used further. + */ + +STATIC INLINE void *_Addresses_Subtract_offset( + void *base, + unsigned32 offset +); + +/* + * _Addresses_Add + * + * DESCRIPTION: + * + * This function is used to add two addresses. It returns the + * resulting address. This address is typically converted to an + * access type before being used further. + */ + +STATIC INLINE void *_Addresses_Add ( + void *left, + void *right +); + +/* + * _Addresses_Subtract + * + * DESCRIPTION: + * + * This function is used to subtract two addresses. It returns the + * resulting offset. + */ + +STATIC INLINE unsigned32 _Addresses_Subtract ( + void *left, + void *right +); + +/* + * _Addresses_Is_aligned + * + * DESCRIPTION: + * + * 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. + */ + +STATIC INLINE boolean _Addresses_Is_aligned ( + void *address +); + +/* + * _Addresses_Is_in_range + * + * DESCRIPTION: + * + * 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. + */ + +STATIC INLINE boolean _Addresses_Is_in_range ( + void *address, + void *base, + void *limit +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/bitfield.h b/cpukit/score/include/rtems/score/bitfield.h new file mode 100644 index 0000000000..a74ea97735 --- /dev/null +++ b/cpukit/score/include/rtems/score/bitfield.h @@ -0,0 +1,49 @@ +/* bitfield.h + * + * This include file contains all bit field manipulation routines. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_BITFIELD_h +#define __RTEMS_BITFIELD_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * _Bitfield_Find_first_bit + * + * DESCRIPTION: + * + * This routine returns the bit_number of the first bit set + * in the specified value. The correspondence between bit_number + * and actual bit position is processor dependent. The search for + * the first bit set may run from most to least significant bit + * or vice-versa. + * + * NOTE: + * + * This routine is used when the executing thread is removed + * from the ready state and, as a result, its performance has a + * significant impact on the performance of the executive as a whole. + */ + +#define _Bitfield_Find_first_bit( _value, _bit_number ) \ + _CPU_Bitfield_Find_first_bit( _value, _bit_number ) + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/chain.h b/cpukit/score/include/rtems/score/chain.h new file mode 100644 index 0000000000..06cc47cc65 --- /dev/null +++ b/cpukit/score/include/rtems/score/chain.h @@ -0,0 +1,432 @@ +/* chain.h + * + * This include file contains all the constants and structures associated + * with the Doubly Linked Chain Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_CHAIN_h +#define __RTEMS_CHAIN_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * 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. + * + */ + +typedef struct Chain_Node_struct Chain_Node; + +struct Chain_Node_struct { + Chain_Node *next; + Chain_Node *previous; +}; + +/* + * 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 chain control structure is + * treated as two overlapping chain nodes. The permanent + * head of the chain overlays a node structure on the + * first and permanent_null fields. The permanent tail + * of the chain overlays a node structure on the + * permanent_null and last elements of the structure. + * + */ + +typedef struct { + Chain_Node *first; + Chain_Node *permanent_null; + Chain_Node *last; +} Chain_Control; + +/* + * _Chain_Initialize + * + * DESCRIPTION: + * + * This routine initializes the_chain structure to manage the + * contiguous array of number_nodes nodes which starts at + * starting_address. Each node is of node_size bytes. + * + */ + +void _Chain_Initialize( + Chain_Control *the_chain, + void *starting_address, + unsigned32 number_nodes, + unsigned32 node_size +); + +/* + * _Chain_Initialize_empty + * + * DESCRIPTION: + * + * This routine initializes the specified chain to contain zero nodes. + * + */ + +STATIC INLINE void _Chain_Initialize_empty( + Chain_Control *the_chain +); + +/* + * _Chain_Are_nodes_equal + * + * DESCRIPTION: + * + * This function returns TRUE if LEFT and RIGHT are equal, + * and FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Are_nodes_equal( + Chain_Node *left, + Chain_Node *right +); + +/* + * _Chain_Extract_unprotected + * + * DESCRIPTION: + * + * This routine extracts the_node from the chain on which it resides. + * It does NOT disable interrupts to insure the atomicity of the + * extract operation. + * + */ + +STATIC INLINE void _Chain_Extract_unprotected( + Chain_Node *the_node +); + +/* + * _Chain_Extract + * + * DESCRIPTION: + * + * This routine extracts the_node from the chain on which it resides. + * It disables interrupts to insure the atomicity of the + * extract operation. + * + */ + +void _Chain_Extract( + Chain_Node *the_node +); + +/* + * _Chain_Get_unprotected + * + * DESCRIPTION: + * + * 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. + * It does NOT disable interrupts to insure the atomicity of the + * get operation. + * + */ + +STATIC INLINE Chain_Node *_Chain_Get_unprotected( + Chain_Control *the_chain +); + +/* + * _Chain_Get + * + * DESCRIPTION: + * + * 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. + * It disables interrupts to insure the atomicity of the + * get operation. + * + */ + +Chain_Node *_Chain_Get( + Chain_Control *the_chain +); + +/* + * _Chain_Get_first_unprotected + * + * DESCRIPTION: + * + * This function removes the first node from the_chain and returns + * a pointer to that node. It does NOT disable interrupts to insure + * the atomicity of the get operation. + * + */ + +STATIC INLINE Chain_Node *_Chain_Get_first_unprotected( + Chain_Control *the_chain +); + +/* + * _Chain_Insert_unprotected + * + * DESCRIPTION: + * + * This routine inserts the_node on a chain immediately following + * after_node. It does NOT disable interrupts to insure the atomicity + * of the extract operation. + * + */ + +STATIC INLINE void _Chain_Insert_unprotected( + Chain_Node *after_node, + Chain_Node *the_node +); + +/* + * _Chain_Insert + * + * DESCRIPTION: + * + * This routine inserts the_node on a chain immediately following + * after_node. It disables interrupts to insure the atomicity + * of the extract operation. + * + */ + +void _Chain_Insert( + Chain_Node *after_node, + Chain_Node *the_node +); + +/* + * _Chain_Append_unprotected + * + * DESCRIPTION: + * + * This routine appends the_node onto the end of the_chain. + * It does NOT disable interrupts to insure the atomicity of the + * append operation. + * + */ + +STATIC INLINE void _Chain_Append_unprotected( + Chain_Control *the_chain, + Chain_Node *the_node +); + +/* + * _Chain_Append + * + * DESCRIPTION: + * + * This routine appends the_node onto the end of the_chain. + * It disables interrupts to insure the atomicity of the + * append operation. + * + */ + +void _Chain_Append( + Chain_Control *the_chain, + Chain_Node *the_node +); + +/* + * _Chain_Prepend_unprotected + * + * DESCRIPTION: + * + * This routine prepends the_node onto the front of the_chain. + * It does NOT disable interrupts to insure the atomicity of the + * prepend operation. + * + */ + +STATIC INLINE void _Chain_Prepend_unprotected( + Chain_Control *the_chain, + Chain_Node *the_node +); + +/* + * _Chain_Prepend + * + * DESCRIPTION: + * + * This routine prepends the_node onto the front of the_chain. + * It disables interrupts to insure the atomicity of the + * prepend operation. + * + */ + +STATIC INLINE void _Chain_Prepend( + Chain_Control *the_chain, + Chain_Node *the_node +); + +/* + * _Chain_Head + * + * DESCRIPTION: + * + * This function returns a pointer to the first node on the chain. + * + */ + +STATIC INLINE Chain_Node *_Chain_Head( + Chain_Control *the_chain +); + +/* + * _Chain_Tail + * + * DESCRIPTION: + * + * This function returns a pointer to the last node on the chain. + * + */ + +STATIC INLINE Chain_Node *_Chain_Tail( + Chain_Control *the_chain +); + +/* + * _Chain_Is_head + * + * DESCRIPTION: + * + * This function returns TRUE if the_node is the head of the_chain and + * FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Is_head( + Chain_Control *the_chain, + Chain_Node *the_node +); + +/* + * _Chain_Is_tail + * + * DESCRIPTION: + * + * This function returns TRUE if the_node is the tail of the_chain and + * FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Is_tail( + Chain_Control *the_chain, + Chain_Node *the_node +); + +/* + * _Chain_Is_first + * + * DESCRIPTION: + * + * This function returns TRUE if the_node is the first node on a chain and + * FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Is_first( + Chain_Node *the_node +); + +/* + * _Chain_Is_last + * + * DESCRIPTION: + * + * This function returns TRUE if the_node is the last node on a chain and + * FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Is_last( + Chain_Node *the_node +); + +/* + * _Chain_Is_empty + * + * DESCRIPTION: + * + * This function returns TRUE if there a no nodes on the_chain and + * FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Is_empty( + Chain_Control *the_chain +); + +/* + * _Chain_Has_only_one_node + * + * DESCRIPTION: + * + * This function returns TRUE if there is only one node on the_chain and + * FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Has_only_one_node( + Chain_Control *the_chain +); + +/* + * _Chain_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_chain is NULL and FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Is_null( + Chain_Control *the_chain +); + +/* + * _Chain_Is_null_node + * + * DESCRIPTION: + * + * This function returns TRUE if the_node is NULL and FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Is_null_node( + Chain_Node *the_node +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/context.h b/cpukit/score/include/rtems/score/context.h new file mode 100644 index 0000000000..9b8ee92b04 --- /dev/null +++ b/cpukit/score/include/rtems/score/context.h @@ -0,0 +1,133 @@ +/* context.h + * + * This include file contains all information about a context. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_CONTEXT_h +#define __RTEMS_CONTEXT_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * The following constant defines the number of bytes required + * to store a full floating point context. + */ + +#define CONTEXT_FP_SIZE CPU_CONTEXT_FP_SIZE + +/* + * The following variable is set to TRUE when a reschedule operation + * has determined that the processor should be taken away from the + * currently executing thread and given to the heir thread. + */ + +EXTERN boolean _Context_Switch_necessary; + +/* + * _Context_Initialize + * + * DESCRIPTION: + * + * This routine initializes THE_CONTEXT such that the stack + * pointer, interrupt level, and entry point are correct for the + * thread's initial state. + */ + +#define _Context_Initialize( _the_context, _stack, _size, _isr, _entry ) \ + _CPU_Context_Initialize( _the_context, _stack, _size, _isr, _entry ) + +/* + * _Context_Switch + * + * DESCRIPTION: + * + * This routine saves the current context into the EXECUTING + * context record and restores the context specified by HEIR. + */ + +#define _Context_Switch( _executing, _heir ) \ + _CPU_Context_switch( _executing, _heir ) + +/* + * _Context_Restart_self + * + * DESCRIPTION: + * + * This routine restarts the calling thread by restoring its initial + * stack pointer and returning to the thread's entry point. + */ + +#define _Context_Restart_self( _the_context ) \ + _CPU_Context_Restart_self( _the_context ) + +/* + * _Context_Fp_start + * + * DESCRIPTION: + * + * This function returns the starting address of the floating + * point context save area. It is assumed that the are reserved + * for the floating point save area is large enough. + */ + +#define _Context_Fp_start( _base, _offset ) \ + _CPU_Context_Fp_start( (_base), (_offset) ) + +/* + * _Context_Initialize_fp + * + * DESCRIPTION: + * + * This routine initializes the floating point context save + * area to contain an initial known state. + */ + +#define _Context_Initialize_fp( _fp_area ) \ + _CPU_Context_Initialize_fp( _fp_area ) + +/* + * _Context_Restore_fp + * + * DESCRIPTION: + * + * This routine restores the floating point context contained + * in the FP_CONTEXT area. It is assumed that the current + * floating point context has been saved by a previous invocation + * of SAVE_FP. + */ + +#define _Context_Restore_fp( _fp ) \ + _CPU_Context_restore_fp( _fp ) + +/* + * _Context_Save_fp + * + * DESCRIPTION: + * + * This routine saves the current floating point context + * in the FP_CONTEXT area. + */ + +#define _Context_Save_fp( _fp ) \ + _CPU_Context_save_fp( _fp ) + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/copyrt.h b/cpukit/score/include/rtems/score/copyrt.h new file mode 100644 index 0000000000..c711ba09b3 --- /dev/null +++ b/cpukit/score/include/rtems/score/copyrt.h @@ -0,0 +1,42 @@ +/* copyrt.h + * + * This include file contains the copyright notice for RTEMS + * which is included in every binary copy of the executive. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_COPYRIGHT_h +#define __RTEMS_COPYRIGHT_h + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef INIT + +const char _Copyright_Notice[] = +"COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.\n\ +On-Line Applications Research Corporation (OAR).\n\ +All rights assigned to U.S. Government, 1994.\n"; + +#else + +extern const char _Copyright_Notice[]; + +#endif + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/heap.h b/cpukit/score/include/rtems/score/heap.h new file mode 100644 index 0000000000..9eb348a760 --- /dev/null +++ b/cpukit/score/include/rtems/score/heap.h @@ -0,0 +1,396 @@ +/* heap.h + * + * This include file contains the information pertaining to the Heap + * Handler. 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 unallocated blocks is contained in the heap space. A heap header + * contains control information for the heap. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_HEAP_h +#define __RTEMS_HEAP_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Status codes for heap_extend + */ + +typedef enum { + HEAP_EXTEND_SUCCESSFUL, + HEAP_EXTEND_ERROR, + HEAP_EXTEND_NOT_IMPLEMENTED +} Heap_Extend_status; + +/* + * Constants used in the size/used field of each heap block to + * indicate when a block is free or in use. + */ + +#define HEAP_BLOCK_USED 1 /* indicates block is in use */ +#define HEAP_BLOCK_FREE 0 /* indicates block is free */ + +/* + * The size/used field value for the dummy front and back flags. + */ + +#define HEAP_DUMMY_FLAG (0 + HEAP_BLOCK_USED) + +/* + * The following constants reflect various requirements of the + * heap data structures which impact the management of a heap. + * + * NOTE: Because free block overhead is greater than used block + * overhead AND a portion of the allocated space is from + * the extra free block overhead, the absolute lower bound + * of the minimum fragment size is equal to the size of + * the free block overhead. + */ + +#define HEAP_OVERHEAD \ + (sizeof( unsigned32 ) * 2) /* size dummy first and last blocks */ +#define HEAP_BLOCK_USED_OVERHEAD \ + (sizeof( void * ) * 2) /* num bytes overhead in used block */ +#define HEAP_MINIMUM_SIZE \ + (HEAP_OVERHEAD + sizeof (Heap_Block)) + /* min number of bytes the user may */ + /* specify for the heap size */ + +/* + * The following defines the data structure used to manage + * individual blocks in a heap. When the block is allocated, the + * next and previous fields are not used by the Heap Handler + * and thus the address returned for the block starts at + * the address of the next field. + * + * NOTE: The next and previous pointers are only valid when the + * block is free. Caution must be exercised to insure that + * allocated blocks are large enough to contain them and + * that they are not accidentally overwritten when the + * block is actually allocated. + */ + +typedef struct Heap_Block_struct Heap_Block; + +struct Heap_Block_struct { + unsigned32 back_flag; /* size and status of prev block */ + unsigned32 front_flag; /* size and status of block */ + Heap_Block *next; /* pointer to next block */ + Heap_Block *previous; /* pointer to previous block */ +}; + +/* + * The following defines the control block used to manage each heap. + * + * NOTE: + * + * This structure is layed out such that it can be used a a dummy + * first and last block on the free block chain. The extra padding + * insures the dummy last block is the correct size. + * + * The first Heap_Block starts at first while the second starts at + * final. This is effectively the same trick as is used in the Chain + * Handler. + */ + +typedef struct { + Heap_Block *start; /* first valid block address in heap */ + Heap_Block *final; /* last valid block address in heap */ + + Heap_Block *first; /* pointer to first block in heap */ + Heap_Block *permanent_null; /* always NULL pointer */ + Heap_Block *last; /* pointer to last block in heap */ + unsigned32 page_size; /* allocation unit */ + unsigned32 reserved; +} Heap_Control; + +/* + * _Heap_Initialize + * + * DESCRIPTION: + * + * This routine initializes the_heap record to manage the + * contiguous heap of size bytes which starts at starting_address. + * Blocks of memory are allocated from the heap in multiples of + * page_size byte units. + */ + +unsigned32 _Heap_Initialize( + Heap_Control *the_heap, + void *starting_address, + unsigned32 size, + unsigned32 page_size +); + +/* + * _Heap_Extend + * + * DESCRIPTION: + * + * This routine grows the_heap memory area using the size bytes which + * begin at starting_address. + */ + +Heap_Extend_status _Heap_Extend( + Heap_Control *the_heap, + void *starting_address, + unsigned32 size, + unsigned32 *amount_extended +); + +/* + * _Heap_Allocate + * + * DESCRIPTION: + * + * DESCRIPTION: + * + * This function attempts to allocate a block of size bytes from + * the_heap. If insufficient memory is free in the_heap to allocate + * a block of the requested size, then NULL is returned. + */ + +void *_Heap_Allocate( + Heap_Control *the_heap, + unsigned32 size +); + +/* + * _Heap_Size_of_user_area + * + * DESCRIPTION: + * + * This kernel routine sets size to the size of the given heap block. + * It returns TRUE if the starting_address is in the heap, and FALSE + * otherwise. + */ + +boolean _Heap_Size_of_user_area( + Heap_Control *the_heap, + void *starting_address, + unsigned32 *size +); + +/* + * _Heap_Free + * + * DESCRIPTION: + * + * This routine returns the block of memory which begins + * at starting_address to the_heap. Any coalescing which is + * possible with the freeing of this routine is performed. + */ + +boolean _Heap_Free( + Heap_Control *the_heap, + void *start_address +); + +/* + * _Heap_Walk + * + * DESCRIPTION: + * + * This routine walks the heap to verify its integrity. + */ + +void _Heap_Walk( + Heap_Control *the_heap, + int source, + boolean do_dump +); + +/* + * _Heap_Head + * + * DESCRIPTION: + * + * This function returns the head of the specified heap. + */ + +STATIC INLINE Heap_Block *_Heap_Head ( + Heap_Control *the_heap +); + +/* + * _Heap_Tail + * + * DESCRIPTION: + * + * This function returns the tail of the specified heap. + */ + +STATIC INLINE Heap_Block *_Heap_Tail ( + Heap_Control *the_heap +); + +/* + * _Heap_Previous_block + * + * DESCRIPTION: + * + * This function returns the address of the block which physically + * precedes the_block in memory. + */ + +STATIC INLINE Heap_Block *_Heap_Previous_block ( + Heap_Block *the_block +); + +/* + * _Heap_Next_block + * + * DESCRIPTION: + * + * This function returns the address of the block which physically + * follows the_block in memory. + */ + +STATIC INLINE Heap_Block *_Heap_Next_block ( + Heap_Block *the_block +); + +/* + * _Heap_Block_at + * + * DESCRIPTION: + * + * This function calculates and returns a block's location (address) + * in the heap based upad a base address and an offset. + */ + +STATIC INLINE Heap_Block *_Heap_Block_at( + void *base, + unsigned32 offset +); + +/* + * _Heap_Is_previous_block_free + * + * DESCRIPTION: + * + * This function returns TRUE if the previous block of the_block + * is free, and FALSE otherwise. + */ + +STATIC INLINE boolean _Heap_Is_previous_block_free ( + Heap_Block *the_block +); + +/* + * _Heap_Is_block_free + * + * DESCRIPTION: + * + * This function returns TRUE if the block is free, and FALSE otherwise. + */ + +STATIC INLINE boolean _Heap_Is_block_free ( + Heap_Block *the_block +); + +/* + * _Heap_Is_block_used + * + * DESCRIPTION: + * + * This function returns TRUE if the block is currently allocated, + * and FALSE otherwise. + */ + +STATIC INLINE boolean _Heap_Is_block_used ( + Heap_Block *the_block +); + +/* + * _Heap_Block_size + * + * DESCRIPTION: + * + * This function returns the size of the_block in bytes. + */ + +STATIC INLINE unsigned32 _Heap_Block_size ( + Heap_Block *the_block +); + +/* + * _Heap_Start_of_user_area + * + * DESCRIPTION: + * + * This function returns the starting address of the portion of the block + * which the user may access. + */ + +STATIC INLINE void *_Heap_Start_of_user_area ( + Heap_Block *the_block +); + +/* + * _Heap_Is_block_in + * + * DESCRIPTION: + * + * This function returns TRUE if the_block is within the memory area + * managed by the_heap, and FALSE otherwise. + */ + +STATIC INLINE boolean _Heap_Is_block_in ( + Heap_Control *the_heap, + Heap_Block *the_block +); + + +/* + * _Heap_Is_page_size_valid + * + * DESCRIPTION: + * + * This function validates a specified heap page size. If the page size + * is 0 or if lies outside a page size alignment boundary it is invalid + * and FALSE is returned. Otherwise, the page size is valid and TRUE is + * returned. + */ + +STATIC INLINE boolean _Heap_Is_page_size_valid( + unsigned32 page_size +); + +/* + * _Heap_Build_flag + * + * DESCRIPTION: + * + * This function returns the block flag composed of size and in_use_flag. + * The flag returned is suitable for use as a back or front flag in a + * heap block. + */ + +STATIC INLINE unsigned32 _Heap_Build_flag ( + unsigned32 size, + unsigned32 in_use_flag +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/isr.h b/cpukit/score/include/rtems/score/isr.h new file mode 100644 index 0000000000..77c3f8663e --- /dev/null +++ b/cpukit/score/include/rtems/score/isr.h @@ -0,0 +1,239 @@ +/* isr.h + * + * 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, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_ISR_h +#define __RTEMS_ISR_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following type defines the control block used to manage + * the interrupt level portion of the status register. + */ + +typedef unsigned32 ISR_Level; + +/* + * The following type defines the control block used to manage + * the vectors. + */ + +typedef unsigned32 rtems_vector_number; + +/* + * Return type for ISR Handler + */ + +typedef void rtems_isr; + +/* + * Pointer to an ISR Handler + */ + +typedef rtems_isr ( *rtems_isr_entry )( + rtems_vector_number + ); +/* + * The following is TRUE if signals have been sent to the currently + * executing thread by an ISR handler. + */ + +EXTERN boolean _ISR_Signals_to_thread_executing; + +/* + * The following contains the interrupt service routine nest level. + * When this variable is zero, a thread is executing. + */ + +EXTERN unsigned32 _ISR_Nest_level; + +/* + * The following declares the RTEMS Vector Table. Application + * interrupt service routines are vectored by RTEMS via this table. + */ + +EXTERN rtems_isr_entry _ISR_Vector_table[CPU_INTERRUPT_NUMBER_OF_VECTORS]; + +/* + * _ISR_Handler_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this handler. + */ + +STATIC INLINE void _ISR_Handler_initialization ( void ); + +/* + * _ISR_Disable + * + * DESCRIPTION: + * + * This routine disables all interrupts so that a critical section + * of code can be executing without being interrupted. Upon return, + * the argument _level will contain the previous interrupt mask level. + */ + +#define _ISR_Disable( _level ) \ + _CPU_ISR_Disable( _level ) + +/* + * _ISR_Enable + * + * DESCRIPTION: + * + * This routine enables interrupts to the previous interrupt mask + * LEVEL. It is used at the end of a critical section of code to + * enable interrupts so they can be processed again. + */ + +#define _ISR_Enable( _level ) \ + _CPU_ISR_Enable( _level ) + +/* + * _ISR_Flash + * + * DESCRIPTION: + * + * This routine 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 insure that the critical section + * properly protects itself. + */ + +#define _ISR_Flash( _level ) \ + _CPU_ISR_Flash( _level ) + +/* + * _ISR_Is_in_progress + * + * DESCRIPTION: + * + * 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. The + * directives available to an interrupt service routine are restricted. + */ + +STATIC INLINE boolean _ISR_Is_in_progress( void ); + +/* + * _ISR_Install_vector + * + * DESCRIPTION: + * + * This routine installs new_handler as the interrupt service routine + * for the specified vector. The previous interrupt service routine is + * returned as old_handler. + */ + +#define _ISR_Install_vector( _vector, _new_handler, _old_handler ) \ + _CPU_ISR_install_vector( _vector, _new_handler, _old_handler ) + +/* + * _ISR_Set_level + * + * DESCRIPTION: + * + * This routine sets the current interrupt level to that specified + * by new_level. The new interrupt level is effective when the + * routine exits. + */ + +#define _ISR_Set_level( _new_level ) \ + _CPU_ISR_Set_level( _new_level ) + +/* + * _ISR_Is_vector_number_valid + * + * DESCRIPTION: + * + * This function returns TRUE if the vector is a valid vector number + * for this processor and FALSE otherwise. + */ + +STATIC INLINE boolean _ISR_Is_vector_number_valid ( + rtems_vector_number vector +); + +/* + * _ISR_Is_valid_user_handler + * + * DESCRIPTION: + * + * This function returns TRUE if handler is the entry point of a valid + * use interrupt service routine and FALSE otherwise. + */ + +STATIC INLINE boolean _ISR_Is_valid_user_handler ( + void *handler +); + +/* + * _ISR_Handler + * + * DESCRIPTION: + * + * This routine is the RTEMS 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 + * insure that the necessary thread scheduling operations are + * performed when the outermost interrupt service routine exits. + * + * NOTE: Implemented in assembly language. + */ + +void _ISR_Handler( void ); + +/* + * _ISR_Dispatch + * + * DESCRIPTION: + * + * This routine provides a wrapper so that the routine + * _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: Implemented in assembly language. + */ + +void _ISR_Dispatch( void ); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/mpci.h b/cpukit/score/include/rtems/score/mpci.h new file mode 100644 index 0000000000..ca06dd243b --- /dev/null +++ b/cpukit/score/include/rtems/score/mpci.h @@ -0,0 +1,171 @@ +/* mpci.h + * + * This include file contains all the constants and structures associated + * with the MPCI layer. It provides mechanisms to utilize packets. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_MPCI_h +#define __RTEMS_MPCI_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include + +/* + * The following defines the node number used when a broadcast is desired. + */ + +#define MPCI_ALL_NODES 0 + +/* + * 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 + +/* + * _MPCI_Handler_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this handler. + */ + +void _MPCI_Handler_initialization ( void ); + +/* + * _MPCI_Initialization + * + * DESCRIPTION: + * + * This routine initializes the MPCI driver by + * invoking the user provided MPCI initialization callout. + */ + +void _MPCI_Initialization ( void ); + +/* + * _MPCI_Get_packet + * + * DESCRIPTION: + * + * This function obtains a packet by invoking the user provided + * MPCI get packet callout. + */ + +rtems_packet_prefix *_MPCI_Get_packet ( void ); + +/* + * _MPCI_Return_packet + * + * DESCRIPTION: + * + * This routine returns a packet by invoking the user provided + * MPCI return packet callout. + */ + +void _MPCI_Return_packet ( + rtems_packet_prefix *the_packet +); + +/* + * _MPCI_Send_process_packet + * + * DESCRIPTION: + * + * This routine sends a process packet by invoking the user provided + * MPCI send callout. + */ + +void _MPCI_Send_process_packet ( + unsigned32 destination, + rtems_packet_prefix *the_packet +); + +/* + * _MPCI_Send_request_packet + * + * DESCRIPTION: + * + * This routine sends a request packet by invoking the user provided + * MPCI send callout. + */ + +rtems_status_code _MPCI_Send_request_packet ( + unsigned32 destination, + rtems_packet_prefix *the_packet, + States_Control extra_state +); + +/* + * _MPCI_Send_response_packet + * + * DESCRIPTION: + * + * This routine sends a response packet by invoking the user provided + * MPCI send callout. + */ + +void _MPCI_Send_response_packet ( + unsigned32 destination, + rtems_packet_prefix *the_packet +); + +/* + * _MPCI_Receive_packet + * + * DESCRIPTION: + * + * This routine receives a packet by invoking the user provided + * MPCI receive callout. + */ + +rtems_packet_prefix *_MPCI_Receive_packet ( void ); + +/* + * _MPCI_Process_response + * + * DESCRIPTION: + * + * This routine obtains a packet by invoking the user provided + * MPCI get packet callout. + */ + +Thread_Control *_MPCI_Process_response ( + rtems_packet_prefix *the_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; + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/mppkt.h b/cpukit/score/include/rtems/score/mppkt.h new file mode 100644 index 0000000000..e0cf6b1967 --- /dev/null +++ b/cpukit/score/include/rtems/score/mppkt.h @@ -0,0 +1,123 @@ +/* mppkt.h + * + * This package is the specification for the Packet Handler. + * This handler defines the basic RTEMS packet and provides + * mechanisms to utilize packets based on this prefix. + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_MP_PACKET_h +#define __RTEMS_MP_PACKET_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* + * The following enumerated type defines the packet classes + * supported by RTEMS. + * + * NOTE: In general, each class corresponds to a manager + * which supports global operations. Each manager + * defines the set of supported operations. + */ + +typedef enum { + RTEMS_MP_PACKET_INTERNAL_THREADS = 0, + RTEMS_MP_PACKET_TASKS = 1, + RTEMS_MP_PACKET_MESSAGE_QUEUE = 2, + RTEMS_MP_PACKET_SEMAPHORE = 3, + RTEMS_MP_PACKET_PARTITION = 4, + RTEMS_MP_PACKET_REGION = 5, + RTEMS_MP_PACKET_EVENT = 6, + RTEMS_MP_PACKET_SIGNAL = 7 +} rtems_mp_packet_classes; + +#define MP_PACKET_CLASSES_FIRST RTEMS_MP_PACKET_INTERNAL_THREADS +#define MP_PACKET_CLASSES_LAST RTEMS_MP_PACKET_SIGNAL + +/* + * The following record contains the prefix for every packet + * passed between RTEMS nodes. + * + * NOTE: This structure is padded to insure that anything + * following it is on a 16 byte boundary. This is + * the most stringent structure alignment rule + * the RTEMS project has encountered yet (i960CA). + */ + +typedef struct { + rtems_mp_packet_classes the_class; + Objects_Id id; + Objects_Id source_tid; + rtems_task_priority source_priority; + rtems_status_code return_code; + unsigned32 length; + unsigned32 to_convert; + rtems_interval timeout; +} rtems_packet_prefix; + +/* + * An MPCI must support packets of at least this size. + */ + +#define RTEMS_MINIMUM_PACKET_SIZE 64 + +/* + * The following constant defines the number of unsigned32's + * in a packet which must be converted to native format in a + * heterogeneous system. In packets longer than + * RTEMS_MINIMUN_HETERO_CONVERSION unsigned32's, some of the "extra" data + * may a user message buffer which is not automatically endian swapped. + */ + +#define RTEMS_MINIMUN_HETERO_CONVERSION ( sizeof( rtems_packet_prefix ) / 4 ) + +/* + * _Mp_packet_Is_valid_packet_class + * + * DESCRIPTION: + * + * This function returns TRUE if the the_packet_class is valid, + * and FALSE otherwise. + */ + +STATIC INLINE boolean _Mp_packet_Is_valid_packet_class ( + rtems_mp_packet_classes the_packet_class +); + +/* + * _Mp_packet_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the the_packet_class is null, + * and FALSE otherwise. + */ + +STATIC INLINE boolean _Mp_packet_Is_null ( + rtems_packet_prefix *the_packet +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/object.h b/cpukit/score/include/rtems/score/object.h new file mode 100644 index 0000000000..50eede9fd7 --- /dev/null +++ b/cpukit/score/include/rtems/score/object.h @@ -0,0 +1,380 @@ +/* object.h + * + * This include file contains all the constants and structures associated + * with the RTEMS Object Handler. This Handler provides mechanisms which + * can be used to initialize and manipulate all RTEMS objects. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_OBJECTS_h +#define __RTEMS_OBJECTS_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * The following type defines the control block used to manage + * object names. + */ + +typedef unsigned32 Objects_Name; + +/* + * The following type defines the control block used to manage + * object IDs. + */ + +typedef unsigned32 Objects_Id; + +/* + * This enumerated type lists the locations which may be returned + * by _Objects_Get. These codes indicate the success of locating + * an object with the specified ID. + */ + +typedef enum { + OBJECTS_LOCAL = 0, /* object is local */ + OBJECTS_REMOTE = 1, /* object is remote */ + OBJECTS_ERROR = 2 /* id was invalid */ +} Objects_Locations; + +/* + * The following defines the Object Control Block used to manage + * each object local to this node. + */ + +typedef struct { + Chain_Node Node; + Objects_Id id; +} Objects_Control; + +/* + * The following defines the structure for the information used to + * manage each class of objects. + */ + +typedef struct { + Objects_Id minimum_id; /* minimum valid id of this type */ + Objects_Id maximum_id; /* maximum valid id of this type */ + unsigned32 maximum; /* maximum number of objects */ + Objects_Control **local_table; /* table of local object pointers */ + Objects_Name *name_table; /* table of local object names */ + Chain_Control *global_table; /* pointer to global table */ + Chain_Control Inactive; /* chain of inactive ctl blocks */ +} Objects_Information; + +/* + * The following defines the data storage which contains the + * node number of the local node. + */ + +EXTERN unsigned32 _Objects_Local_node; + +/* + * The following defines the constant which may be used + * with _Objects_Get to manipulate the calling task. + * + */ + +#define OBJECTS_ID_OF_SELF 0 + +/* + * The following define the constants which may be used in name searches. + */ + +#define RTEMS_SEARCH_ALL_NODES 0 +#define RTEMS_SEARCH_OTHER_NODES 0x7FFFFFFE +#define RTEMS_SEARCH_LOCAL_NODE 0x7FFFFFFF +#define RTEMS_WHO_AM_I 0 + +/* + * _Objects_Handler_initialization + * + * DESCRIPTION: + * + * This function performs the initialization necessary for this handler. + * + */ + +void _Objects_Handler_initialization( + unsigned32 node, + unsigned32 maximum_global_objects +); + +/* + * _Objects_Initialize_information + * + * DESCRIPTION: + * + * 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. + * + */ + +void _Objects_Initialize_information ( + Objects_Information *information, + boolean supports_global, + unsigned32 maximum, + unsigned32 size +); + +/* + * _Objects_Name_to_id + * + * DESCRIPTION: + * + * 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. + * + */ + +rtems_status_code _Objects_Name_to_id( + Objects_Information *information, + Objects_Name name, + unsigned32 node, + Objects_Id *id +); + +/* + * _Objects_Get + * + * DESCRIPTION: + * + * 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. + * + */ + +Objects_Control *_Objects_Get ( + Objects_Information *information, + Objects_Id id, + Objects_Locations *location +); + +/* + * _Objects_Is_name_valid + * + * DESCRIPTION: + * + * This function returns TRUE if the name is valid, and FALSE otherwise. + */ + +STATIC INLINE boolean _Objects_Is_name_valid ( + Objects_Name name +); + +/* + * rtems_build_name + * + * DESCRIPTION: + * + * This function returns an object name composed of the four characters + * C1, C2, C3, and C4. + * + * NOTE: + * + * This must be implemented as a macro for use in Configuration Tables. + * + */ + +#define rtems_build_name( _C1, _C2, _C3, _C4 ) \ + ( (_C1) << 24 | (_C2) << 16 | (_C3) << 8 | (_C4) ) + +/* + * rtems_name_to_characters + * + * DESCRIPTION: + * + * This function breaks the object name into the four component + * characters C1, C2, C3, and C4. + * + */ + +STATIC INLINE void rtems_name_to_characters( + Objects_Name name, + char *c1, + char *c2, + char *c3, + char *c4 +); + +/* + * _Objects_Build_id + * + * DESCRIPTION: + * + * This function builds an object's id from the processor node and index + * values specified. + * + */ + +STATIC INLINE Objects_Id _Objects_Build_id( + unsigned32 node, + unsigned32 index +); + +/* + * rtems_get_node + * + * DESCRIPTION: + * + * This function returns the node portion of the ID. + * + */ + +STATIC INLINE unsigned32 rtems_get_node( + Objects_Id id +); + +/* + * rtems_get_index + * + * DESCRIPTION: + * + * This function returns the index portion of the ID. + * + */ + +STATIC INLINE unsigned32 rtems_get_index( + Objects_Id id +); + +/* + * _Objects_Is_local_node + * + * DESCRIPTION: + * + * This function returns TRUE if the node is of the local object, and + * FALSE otherwise. + * + */ + +STATIC INLINE boolean _Objects_Is_local_node( + unsigned32 node +); + +/* + * _Objects_Is_local_id + * + * DESCRIPTION: + * + * This function returns TRUE if the id is of a local object, and + * FALSE otherwise. + * + */ + +STATIC INLINE boolean _Objects_Is_local_id( + Objects_Id id +); + +/* + * _Objects_Are_ids_equal + * + * DESCRIPTION: + * + * This function returns TRUE if left and right are equal, + * and FALSE otherwise. + * + */ + +STATIC INLINE boolean _Objects_Are_ids_equal( + Objects_Id left, + Objects_Id right +); + +/* + * _Objects_Allocate + * + * DESCRIPTION: + * + * This function allocates a object control block from + * the inactive chain of free object control blocks. + * + */ + +STATIC INLINE Objects_Control *_Objects_Allocate( + Objects_Information *information +); + +/* + * _Objects_Free + * + * DESCRIPTION: + * + * This function frees a object control block to the + * inactive chain of free object control blocks. + * + */ + +STATIC INLINE void _Objects_Free( + Objects_Information *information, + Objects_Control *the_object +); + +/* + * _Objects_Open + * + * DESCRIPTION: + * + * This function places the_object control pointer and object name + * in the Local Pointer and Local Name Tables, respectively. + * + */ + +STATIC INLINE void _Objects_Open( + Objects_Information *information, + Objects_Control *the_object, + Objects_Name name +); + +/* + * _Objects_Close + * + * DESCRIPTION: + * + * This function removes the_object control pointer and object name + * in the Local Pointer and Local Name Tables. + * + */ + +STATIC INLINE void _Objects_Close( + Objects_Information *information, + Objects_Control *the_object +); + +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/objectmp.h b/cpukit/score/include/rtems/score/objectmp.h new file mode 100644 index 0000000000..0d29fda753 --- /dev/null +++ b/cpukit/score/include/rtems/score/objectmp.h @@ -0,0 +1,165 @@ +/* objectmp.h + * + * This include file contains all the constants and structures associated + * with the manipulation of Global RTEMS Objects. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_OBJECTS_MP_h +#define __RTEMS_OBJECTS_MP_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This defines the Global Object Control Block used to manage + * objects resident on other nodes. + */ + +typedef struct { + Objects_Control Object; + Objects_Name name; +} Objects_MP_Control; + +/* + * _Objects_MP_Handler_initialization + * + * DESCRIPTION: + * + * This routine intializes the inactive global object chain + * based on the maximum number of global objects configured. + */ + +void _Objects_MP_Handler_initialization ( + unsigned32 maximum_global_objects +); + +/* + * _Objects_MP_Allocate_global_object + * + * DESCRIPTION: + * + * This function allocates a Global Object control block. + */ + +STATIC INLINE Objects_MP_Control *_Objects_MP_Allocate_global_object ( + void +); + +/* + * _Objects_MP_Free_global_object + * + * DESCRIPTION: + * + * This routine deallocates a Global Object control block. + */ + +STATIC INLINE void _Objects_MP_Free_global_object ( + Objects_MP_Control *the_object +); + +/* + * _Objects_MP_Is_null_global_object + * + * DESCRIPTION: + * + * This function returns whether the global object is NULL or not. + */ + +STATIC INLINE boolean _Objects_MP_Is_null_global_object ( + Objects_MP_Control *the_object +); + +/* + * _Objects_MP_Open + * + * DESCRIPTION: + * + * 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. + */ + +boolean _Objects_MP_Open ( + Objects_Information *information, + Objects_Name the_name, + Objects_Id the_id, + boolean is_fatal_error +); + +/* + * _Objects_MP_Close + * + * DESCRIPTION: + * + * 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 +); + +/* + * _Objects_MP_Global_name_search + * + * DESCRIPTION: + * + * 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. + */ + +rtems_status_code _Objects_MP_Global_name_search ( + Objects_Information *information, + Objects_Name the_name, + unsigned32 nodes_to_search, + Objects_Id *the_id +); + +/* + * _Objects_MP_Is_remote + * + * DESCRIPTION: + * + * This function searches the Global Object Table managed + * by information for the object indicated by ID. If the object + * is found, then location is set to objects_remote, otherwise + * location is set to objects_error. In both cases, the_object + * is undefined. + */ + +void _Objects_MP_Is_remote ( + Objects_Information *information, + Objects_Id the_id, + Objects_Locations *location, + Objects_Control **the_object +); + +/* + * The following chain header is used to manage the set of + * inactive global object control blocks. + */ + +EXTERN Chain_Control _Objects_MP_Inactive_global_objects; + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/priority.h b/cpukit/score/include/rtems/score/priority.h new file mode 100644 index 0000000000..823611b080 --- /dev/null +++ b/cpukit/score/include/rtems/score/priority.h @@ -0,0 +1,195 @@ +/* priority.h + * + * This include file contains all thread priority manipulation routines. + * This Handler provides mechanisms which can be used to + * initialize and manipulate RTEMS priorities. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_PRIORITY_h +#define __RTEMS_PRIORITY_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following type defines the control block used to manage + * thread priorities. + * + * NOTE: Priority 0 is reserved for internal threads only. + */ + +typedef unsigned32 rtems_task_priority; + +#define RTEMS_MINIMUM_PRIORITY 1 /* highest thread priority */ +#define RTEMS_MAXIMUM_PRIORITY 255 /* lowest thread priority */ + +/* + * The following record defines the information associated with + * each thread to manage its interaction with the priority bit maps. + */ + +typedef struct { + Priority_Bit_map_control *minor; /* addr of minor bit map slot */ + Priority_Bit_map_control ready_major; /* priority bit map ready mask */ + Priority_Bit_map_control ready_minor; /* priority bit map ready mask */ + Priority_Bit_map_control block_major; /* priority bit map block mask */ + Priority_Bit_map_control block_minor; /* priority bit map block mask */ +} Priority_Information; + +/* + * The following data items are the priority bit map. + * Each of the sixteen bits used in the _Priority_Major_bit_map is + * associated with one of the sixteen entries in the _Priority_Bit_map. + * Each bit in the _Priority_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. + */ + +EXTERN volatile Priority_Bit_map_control _Priority_Major_bit_map; +EXTERN Priority_Bit_map_control _Priority_Bit_map[16] CPU_STRUCTURE_ALIGNMENT; + +/* + * The following constants are useful when manipulating priority. + */ + +#define RTEMS_CURRENT_PRIORITY 0 /* obtain current priority */ + +/* + * The definition of the Priority_Bit_map_control type is CPU dependent. + * + */ + +/* + * _Priority_Handler_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this handler. + */ + +STATIC INLINE void _Priority_Handler_initialization( void ); + +/* + * _Priority_Is_valid + * + * DESCRIPTION: + * + * This function returns TRUE if the_priority if valid for a + * user task, and FALSE otherwise. + */ + +STATIC INLINE boolean _Priority_Is_valid ( + rtems_task_priority the_priority +); + +/* + * _Priority_Major + * + * DESCRIPTION: + * + * This function returns the major portion of the_priority. + */ + +STATIC INLINE unsigned32 _Priority_Major ( + rtems_task_priority the_priority +); + +/* + * _Priority_Minor + * + * DESCRIPTION: + * + * This function returns the minor portion of the_priority. + */ + +STATIC INLINE unsigned32 _Priority_Minor ( + rtems_task_priority the_priority +); + +/* + * _Priority_Add_to_bit_map + * + * DESCRIPTION: + * + * This routine uses the_priority_map to update the priority + * bit maps to indicate that a thread has been readied. + */ + +STATIC INLINE void _Priority_Add_to_bit_map ( + Priority_Information *the_priority_map +); + +/* + * _Priority_Remove_from_bit_map + * + * DESCRIPTION: + * + * This routine uses the_priority_map to update the priority + * bit maps to indicate that a thread has been removed from the + * ready state. + */ + +STATIC INLINE void _Priority_Remove_from_bit_map ( + Priority_Information *the_priority_map +); + +/* + * _Priority_Get_highest + * + * DESCRIPTION: + * + * This function returns the priority of the highest priority + * ready thread. + */ + +STATIC INLINE rtems_task_priority _Priority_Get_highest( void ); + +/* + * _Priority_Initialize_information + * + * DESCRIPTION: + * + * This routine initializes the_priority_map so that it + * contains the information necessary to manage a thread + * at new_priority. + */ + +STATIC INLINE void _Priority_Initialize_information( + Priority_Information *the_priority_map, + rtems_task_priority new_priority +); + +/* + * _Priority_Is_group_empty + * + * DESCRIPTION: + * + * This function returns TRUE if the priority GROUP is empty, and + * FALSE otherwise. + */ + +STATIC INLINE boolean _Priority_Is_group_empty ( + rtems_task_priority the_priority +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/stack.h b/cpukit/score/include/rtems/score/stack.h new file mode 100644 index 0000000000..a0fce1ef04 --- /dev/null +++ b/cpukit/score/include/rtems/score/stack.h @@ -0,0 +1,95 @@ +/* stack.h + * + * 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, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_STACK_h +#define __RTEMS_STACK_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following constant defines the minimum stack size which every + * thread must exceed. + */ + +#define RTEMS_MINIMUM_STACK_SIZE CPU_STACK_MINIMUM_SIZE + +/* + * The following defines the control block used to manage each stack. + */ + +typedef struct { + unsigned32 size; /* stack size */ + void *area; /* low memory addr of stack */ +} Stack_Control; + +/* + * _Stack_Initialize + * + * DESCRIPTION: + * + * This routine initializes the_stack record to indicate that + * size bytes of memory starting at starting_address have been + * reserved for a stack. + */ + +STATIC INLINE void _Stack_Initialize ( + Stack_Control *the_stack, + void *starting_address, + unsigned32 size +); + +/* + * _Stack_Is_enough + * + * DESCRIPTION: + * + * This function returns TRUE if size bytes is enough memory for + * a valid stack area on this processor, and FALSE otherwise. + */ + +STATIC INLINE boolean _Stack_Is_enough ( + unsigned32 size +); + +/* + * _Stack_Adjust_size + * + * DESCRIPTION: + * + * This function increases the stack size to insure that the thread + * has the desired amount of stack space after the initial stack + * pointer is determined based on alignment restrictions. + * + * NOTE: + * + * The amount of adjustment for alignment is CPU dependent. + */ + +STATIC INLINE unsigned32 _Stack_Adjust_size ( + unsigned32 size +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/states.h b/cpukit/score/include/rtems/score/states.h new file mode 100644 index 0000000000..56f67ecc49 --- /dev/null +++ b/cpukit/score/include/rtems/score/states.h @@ -0,0 +1,337 @@ +/* states.h + * + * This include file contains all RTEMS state information. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_STATES_h +#define __RTEMS_STATES_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following type defines the control block used to manage a + * thread's state. + */ + +typedef unsigned32 States_Control; + +/* + * The following constants define the individual states which may be + * be used to compose and manipulate a thread's state. + */ + +#define STATES_ALL_SET 0xffff /* all states */ +#define STATES_READY 0x0000 /* ready to run */ +#define STATES_DORMANT 0x0001 /* created but not started */ +#define STATES_SUSPENDED 0x0002 /* waiting to be resumed */ +#define STATES_TRANSIENT 0x0004 /* thread in transition */ +#define STATES_DELAYING 0x0008 /* wait for timeout */ +#define STATES_WAITING_FOR_BUFFER 0x0010 /* wait for partition buffer */ +#define STATES_WAITING_FOR_SEGMENT 0x0020 /* wait for region segment */ +#define STATES_WAITING_FOR_MESSAGE 0x0040 /* wait for message */ +#define STATES_WAITING_FOR_EVENT 0x0080 /* wait for event */ +#define STATES_WAITING_FOR_SEMAPHORE 0x0100 /* wait for semaphore */ +#define STATES_WAITING_FOR_TIME 0x0200 /* wait for specific TOD */ +#define STATES_WAITING_FOR_RPC_REPLY 0x0400 /* wait for rpc reply */ +#define STATES_WAITING_FOR_PERIOD 0x0800 /* rate monotonic delay */ + +#define STATES_LOCALLY_BLOCKED ( STATES_WAITING_FOR_BUFFER | \ + STATES_WAITING_FOR_SEGMENT | \ + STATES_WAITING_FOR_MESSAGE | \ + STATES_WAITING_FOR_SEMAPHORE ) + +#define STATES_WAITING_ON_THREAD_QUEUE \ + ( STATES_LOCALLY_BLOCKED | \ + STATES_WAITING_FOR_RPC_REPLY ) + +#define STATES_BLOCKED ( STATES_DELAYING | \ + STATES_WAITING_FOR_TIME | \ + STATES_WAITING_FOR_PERIOD | \ + STATES_WAITING_FOR_EVENT | \ + STATES_WAITING_ON_THREAD_QUEUE ) + +/* + * _States_Set + * + * DESCRIPTION: + * + * This function sets the given states_to_set into the current_state + * passed in. The result is returned to the user in current_state. + */ + +STATIC INLINE States_Control _States_Set ( + States_Control states_to_set, + States_Control current_state +); + +/* + * _States_Clear + * + * DESCRIPTION: + * + * This function clears the given states_to_clear into the current_state + * passed in. The result is returned to the user in current_state. + */ + +STATIC INLINE States_Control _States_Clear ( + States_Control states_to_clear, + States_Control current_state +); + +/* + * _States_Is_ready + * + * DESCRIPTION: + * + * This function returns TRUE if the_states indicates that the + * state is READY, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_ready ( + States_Control the_states +); + +/* + * _States_Is_only_dormant + * + * DESCRIPTION: + * + * This function returns TRUE if the DORMANT state is the ONLY state + * set in the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_only_dormant ( + States_Control the_states +); + +/* + * _States_Is_dormant + * + * DESCRIPTION: + * + * This function returns TRUE if the DORMANT state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_dormant ( + States_Control the_states +); + +/* + * _States_Is_suspended + * + * DESCRIPTION: + * + * This function returns TRUE if the SUSPENDED state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_suspended ( + States_Control the_states +); + +/* + * _States_Is_Transient + * + * DESCRIPTION: + * + * This function returns TRUE if the TRANSIENT state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_transient ( + States_Control the_states +); + +/* + * _States_Is_delaying + * + * DESCRIPTION: + * + * This function returns TRUE if the DELAYING state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_delaying ( + States_Control the_states +); + +/* + * _States_Is_waiting_for_buffer + * + * DESCRIPTION: + * + * This function returns TRUE if the WAITING_FOR_BUFFER state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_waiting_for_buffer ( + States_Control the_states +); + +/* + * _States_Is_waiting_for_segment + * + * DESCRIPTION: + * + * This function returns TRUE if the WAITING_FOR_SEGMENT state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_waiting_for_segment ( + States_Control the_states +); + +/* + * _States_Is_waiting_for_message + * + * DESCRIPTION: + * + * This function returns TRUE if the WAITING_FOR_MESSAGE state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_waiting_for_message ( + States_Control the_states +); + +/* + * _States_Is_waiting_for_event + * + * DESCRIPTION: + * + * This function returns TRUE if the WAITING_FOR_EVENT state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_waiting_for_event ( + States_Control the_states +); + +/* + * _States_Is_waiting_for_semaphore + * + * DESCRIPTION: + * + * This function returns TRUE if the WAITING_FOR_SEMAPHORE state + * is set in the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_waiting_for_semaphore ( + States_Control the_states +); + +/* + * _States_Is_waiting_for_time + * + * DESCRIPTION: + * + * This function returns TRUE if the WAITING_FOR_TIME state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_waiting_for_time ( + States_Control the_states +); + +/* + * _States_Is_waiting_for_rpc_reply + * + * DESCRIPTION: + * + * This function returns TRUE if the WAITING_FOR_TIME state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_waiting_for_rpc_reply ( + States_Control the_states +); + +/* + * _States_Is_waiting_for_period + * + * DESCRIPTION: + * + * This function returns TRUE if the WAITING_FOR_PERIOD state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_waiting_for_period ( + States_Control the_states +); + +/* + * _States_Is_locally_blocked + * + * DESCRIPTION: + * + * 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. + */ + +STATIC INLINE boolean _States_Is_locally_blocked ( + States_Control the_states +); + +/* + * _States_Is_waiting_on_thread_queue + * + * DESCRIPTION: + * + * 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. + */ + +STATIC INLINE boolean _States_Is_waiting_on_thread_queue ( + States_Control the_states +); + +/* + * _States_Is_blocked + * + * DESCRIPTION: + * + * This function returns TRUE if one of the states which indicates + * that a task is blocked is set in the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_blocked ( + States_Control the_states +); + +/* + * _States_Are_set + * + * DESCRIPTION: + * + * This function returns TRUE if any of the states in the mask + * are set in the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Are_set ( + States_Control the_states, + States_Control mask +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/sysstate.h b/cpukit/score/include/rtems/score/sysstate.h new file mode 100644 index 0000000000..511a26cefc --- /dev/null +++ b/cpukit/score/include/rtems/score/sysstate.h @@ -0,0 +1,143 @@ +/* sysstates.h + * + * This include file contains information regarding the system state. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_SYSTEM_STATE_h +#define __RTEMS_SYSTEM_STATE_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* types */ + +/* enumerated constants */ + +/* + * The following type defines the possible system states. + */ + +typedef enum { + SYSTEM_STATE_BEFORE_INITIALIZATION, /* start -> end of 1st init part */ + SYSTEM_STATE_BEFORE_MULTITASKING, /* end of 1st -> beginning of 2nd */ + SYSTEM_STATE_BEGIN_MULTITASKING, /* beginning of 2nd -> end of SYSI */ + SYSTEM_STATE_UP, /* normal operation */ + SYSTEM_STATE_FAILED /* fatal error occurred */ +} System_state_Codes; + +#define SYSTEM_STATE_CODES_FIRST SYSTEM_STATE_BEFORE_INITIALIZATION +#define SYSTEM_STATE_CODES_LAST SYSTEM_STATE_FAILED + +/* + * The following variable contains the current system state. + */ + +EXTERN System_state_Codes _System_state_Current; + +/* + * _System_state_Set + * + * DESCRIPTION: + * + * This routine sets the current system state to that specified by + * the called. + */ + +STATIC INLINE void _System_state_Set ( + System_state_Codes state +); + +/* + * _System_state_Get + * + * DESCRIPTION: + * + * This function returns the current system state. + */ + +STATIC INLINE System_state_Codes _System_state_Get ( void ); + +/* + * _System_state_Is_before_initialization + * + * DESCRIPTION: + * + * This function returns TRUE if the state is equal to the + * "before initialization" state, and FALSE otherwise. + */ + +STATIC INLINE boolean _System_state_Is_before_initialization ( + System_state_Codes state +); + +/* + * _System_state_Is_before_multitasking + * + * DESCRIPTION: + * + * This function returns TRUE if the state is equal to the + * "before multitasking" state, and FALSE otherwise. + */ + +STATIC INLINE boolean _System_state_Is_before_multitasking ( + System_state_Codes state +); + +/* + * _System_state_Is_begin_multitasking + * + * DESCRIPTION: + * + * This function returns TRUE if the state is equal to the + * "begin multitasking" state, and FALSE otherwise. + */ + +STATIC INLINE boolean _System_state_Is_begin_multitasking ( + System_state_Codes state +); + +/* + * _System_state_Is_up + * + * DESCRIPTION: + * + * This function returns TRUE if the state is equal to the + * "up" state, and FALSE otherwise. + */ + +STATIC INLINE boolean _System_state_Is_up ( + System_state_Codes state +); + +/* + * _System_state_Is_failed + * + * DESCRIPTION: + * + * This function returns TRUE if the state is equal to the + * "failed" state, and FALSE otherwise. + */ + +STATIC INLINE boolean _System_state_Is_failed ( + System_state_Codes state +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h new file mode 100644 index 0000000000..de07a721ef --- /dev/null +++ b/cpukit/score/include/rtems/score/thread.h @@ -0,0 +1,721 @@ +/* thread.h + * + * This include file contains all constants and structures associated + * with the thread control block. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_THREAD_h +#define __RTEMS_THREAD_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Notepads constants (indices into notepad array) + */ + +#define RTEMS_NOTEPAD_FIRST 0 /* lowest numbered notepad */ +#define RTEMS_NOTEPAD_0 0 /* notepad location 0 */ +#define RTEMS_NOTEPAD_1 1 /* notepad location 1 */ +#define RTEMS_NOTEPAD_2 2 /* notepad location 2 */ +#define RTEMS_NOTEPAD_3 3 /* notepad location 3 */ +#define RTEMS_NOTEPAD_4 4 /* notepad location 4 */ +#define RTEMS_NOTEPAD_5 5 /* notepad location 5 */ +#define RTEMS_NOTEPAD_6 6 /* notepad location 6 */ +#define RTEMS_NOTEPAD_7 7 /* notepad location 7 */ +#define RTEMS_NOTEPAD_8 8 /* notepad location 8 */ +#define RTEMS_NOTEPAD_9 9 /* notepad location 9 */ +#define RTEMS_NOTEPAD_10 10 /* notepad location 10 */ +#define RTEMS_NOTEPAD_11 11 /* notepad location 11 */ +#define RTEMS_NOTEPAD_12 12 /* notepad location 12 */ +#define RTEMS_NOTEPAD_13 13 /* notepad location 13 */ +#define RTEMS_NOTEPAD_14 14 /* notepad location 14 */ +#define RTEMS_NOTEPAD_15 15 /* notepad location 15 */ +#define RTEMS_NOTEPAD_LAST RTEMS_NOTEPAD_15 /* highest numbered notepad */ + +/* + * The following defines the "return type" of an RTEMS thread. + * + * NOTE: Keep both types for internal threads. + */ + +typedef void rtems_task; +typedef void Thread; + +/* + * The following defines the argument to an RTEMS thread. + */ + +typedef unsigned32 rtems_task_argument; +typedef unsigned32 Thread_Argument; + +/* + * The following defines the type for the entry point of an RTEMS thread. + */ + +typedef rtems_task ( *rtems_task_entry )( + rtems_task_argument + ); + +typedef Thread ( *Thread_Entry )( + Thread_Argument + ); + +/* + * The following structure contains the information which defines + * the starting state of a thread. + */ + +typedef struct { + Thread_Entry entry_point; /* starting thread address */ + unsigned32 initial_argument; /* initial argument */ + rtems_mode initial_modes; /* initial mode */ + rtems_task_priority initial_priority; /* initial priority */ + void *fp_context; /* initial FP context area address */ + Stack_Control Initial_stack; /* stack information */ +} Thread_Start_information; + +/* + * The following structure contains the information necessary to manage + * a thread which it is waiting for a resource. + */ + +typedef struct { + Objects_Id id; /* waiting on this object */ + rtems_option option_set; /* wait mode */ + union { + unsigned32 segment_size; /* size of segment requested */ + rtems_event_set event_condition; + } Extra; + void *return_argument; /* address of user return param */ + rtems_status_code return_code; /* status for thread awakened */ + Chain_Control Block2n; /* 2 - n priority blocked chain */ + Thread_queue_Control *queue; /* pointer to thread queue */ +} Thread_Wait_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 { + Objects_Control Object; + Objects_Name name; + States_Control current_state; + rtems_task_priority current_priority; + rtems_task_priority real_priority; + unsigned32 resource_count; + Thread_Wait_information Wait; + Watchdog_Control Timer; + rtems_packet_prefix *receive_packet; + /****************** end of common block ********************/ + Chain_Node Active; +} 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 struct { + Objects_Control Object; + Objects_Name name; + States_Control current_state; + rtems_task_priority current_priority; + rtems_task_priority real_priority; + unsigned32 resource_count; + Thread_Wait_information Wait; + Watchdog_Control Timer; + rtems_packet_prefix *receive_packet; + /****************** end of common block ********************/ + Chain_Control *ready; + Priority_Information Priority_map; + rtems_event_set pending_events; + rtems_event_set events_out; + Thread_Start_information Start; + ASR_Information Signal; + rtems_mode current_modes; + rtems_attribute attribute_set; + Context_Control Registers; + void *fp_context; + unsigned32 Notepads[ 16 ]; + void *extension; +} Thread_Control; + +/* + * External API name for Thread_Control + */ + +typedef Thread_Control rtems_tcb; + +/* + * The following declares the dispatch critical section nesting + * counter which is used to prevent context switches at inopportune + * moments. + */ + +EXTERN unsigned32 _Thread_Dispatch_disable_level; + +/* + * The following data items are used to manage timeslicing. + */ + +EXTERN unsigned32 _Thread_Ticks_remaining_in_timeslice; +EXTERN unsigned32 _Thread_Ticks_per_timeslice; + +/* + * The following points to the array of FIFOs used to manage the + * set of ready threads. + */ + +EXTERN Chain_Control *_Thread_Ready_chain; + +/* + * The following points to the thread which is currently executing. + * This thread is implicitly manipulated by numerous directives. + */ + +EXTERN Thread_Control *_Thread_Executing; + +/* + * The following points to the highest priority ready thread + * in the system. Unless the current thread is RTEMS_NO_PREEMPT, + * then this thread will be context switched to when the next + * dispatch occurs. + */ + +EXTERN Thread_Control *_Thread_Heir; + +/* + * The following points to the thread whose floating point + * context is currently loaded. + */ + +EXTERN Thread_Control *_Thread_Allocated_fp; + +/* + * The following defines the information control block used to + * manage this class of objects. + */ + +EXTERN Objects_Information _Thread_Information; + +/* + * The following context area contains the context of the "thread" + * which invoked rtems_initialize_executive. This context is restored + * as the last action of the rtems_shutdown_executive directive. Thus + * control of the processor can be returned to the environment + * which initiated RTEMS. + */ + +EXTERN Context_Control _Thread_BSP_context; + +/* + * _Thread_Handler_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this handler. + */ + +void _Thread_Handler_initialization ( + unsigned32 maximum_tasks, + unsigned32 ticks_per_timeslice, + unsigned32 maximum_proxies +); + +/* + * _Thread_Start_multitasking + * + * DESCRIPTION: + * + * This routine initiates multitasking. It is invoked only as + * part of initialization and its invocation is the last act of + * the rtems_initialize_executive directive. + */ + +void _Thread_Start_multitasking ( + Thread_Control *system_thread, + Thread_Control *idle_thread +); + +/* + * _Thread_Stop_multitasking + * + * DESCRIPTION: + * + * This routine halts multitasking and returns control to + * the "thread" which initially invoked the rtems_initialize_executive + * directive. + */ + +STATIC INLINE void _Thread_Stop_multitasking( void ); + +/* + * _Thread_Dispatch_initialization + * + * DESCRIPTION: + * + * This routine initializes the thread dispatching subsystem. + */ + +STATIC INLINE void _Thread_Dispatch_initialization( void ); + +/* + * _Thread_Dispatch + * + * DESCRIPTION: + * + * This routine is responsible for transferring control of the + * processor from the executing thread to the heir thread. As part + * of this process, it is responsible for the following actions: + * + * + saving the context of the executing thread + * + restoring the context of the heir thread + * + dispatching any signals for the resulting executing thread + */ + +void _Thread_Dispatch( void ); + +/* + * _Thread_Ready + * + * DESCRIPTION: + * + * This routine removes any set states for the_thread. It performs + * any necessary scheduling operations including the selection of + * a new heir thread. + */ + +void _Thread_Ready( + Thread_Control *the_thread +); + +/* + * _Thread_Clear_state + * + * DESCRIPTION: + * + * This routine clears the indicated STATES for the_thread. It performs + * any necessary scheduling operations including the selection of + * a new heir thread. + */ + +void _Thread_Clear_state( + Thread_Control *the_thread, + States_Control state +); + +/* + * _Thread_Set_state + * + * DESCRIPTION: + * + * This routine sets the indicated states for the_thread. It performs + * any necessary scheduling operations including the selection of + * a new heir thread. + * + */ + +void _Thread_Set_state( + Thread_Control *the_thread, + States_Control state +); + +/* + * _Thread_Set_transient + * + * DESCRIPTION: + * + * This routine sets the TRANSIENT state for the_thread. It performs + * any necessary scheduling operations including the selection of + * a new heir thread. + */ + +void _Thread_Set_transient( + Thread_Control *the_thread +); + +/* + * _Thread_Reset_timeslice + * + * DESCRIPTION: + * + * This routine is invoked upon expiration of the currently + * executing thread's timeslice. If no other thread's are ready + * at the priority of the currently executing thread, then the + * executing thread's timeslice is reset. Otherwise, the + * currently executing thread is placed at the rear of the + * RTEMS_FIFO for this priority and a new heir is selected. + */ + +void _Thread_Reset_timeslice( void ); + +/* + * _Thread_Tickle_timeslice + * + * DESCRIPTION: + * + * This routine is invoked as part of processing each clock tick. + * It is responsible for determining if the current thread allows + * timeslicing and, if so, when its timeslice expires. + */ + +void _Thread_Tickle_timeslice( void ); + +/* + * _Thread_Yield_processor + * + * DESCRIPTION: + * + * This routine is invoked when a thread wishes to voluntarily + * transfer control of the processor to another thread of equal + * or greater priority. + */ + +void _Thread_Yield_processor( void ); + +/* + * _Thread_Is_executing + * + * DESCRIPTION: + * + * This function returns TRUE if the_thread is the currently executing + * thread, and FALSE otherwise. + */ + +STATIC INLINE boolean _Thread_Is_executing ( + Thread_Control *the_thread +); + +/* + * _Thread_Is_heir + * + * DESCRIPTION: + * + * This function returns TRUE if the_thread is the heir + * thread, and FALSE otherwise. + */ + +STATIC INLINE boolean _Thread_Is_executing ( + Thread_Control *the_thread +); + +/* + * _Thread_Is_executing_also_the_heir + * + * DESCRIPTION: + * + * This function returns TRUE if the currently executing thread + * is also the heir thread, and FALSE otherwise. + */ + +STATIC INLINE boolean _Thread_Is_executing_also_the_heir( void ); + +/* + * _Thread_Load_environment + * + * DESCRIPTION: + * + * This routine initializes the context of the_thread to its + * appropriate starting state. + */ + +void _Thread_Load_environment( + Thread_Control *the_thread +); + +/* + * _Thread_Handler + * + * DESCRIPTION: + * + * 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. + */ + +void _Thread_Handler( void ); + +/* + * _Thread_Delay_ended + * + * DESCRIPTION: + * + * This routine is invoked when a thread must be unblocked at the + * end of a delay such as the rtems_task_wake_after and rtems_task_wake_when + * directives. + */ + +void _Thread_Delay_ended( + Objects_Id id, + void *ignored +); + +/* + * _Thread_Change_priority + * + * DESCRIPTION: + * + * This routine changes the current priority of the_thread to + * new_priority. It performs any necessary scheduling operations + * including the selection of a new heir thread. + */ + +void _Thread_Change_priority ( + Thread_Control *the_thread, + rtems_task_priority new_priority +); + +/* + * _Thread_Set_priority + * + * DESCRIPTION: + * + * This routine updates the priority related fields in the_thread + * control block to indicate the current priority is now new_priority. + */ + +void _Thread_Set_priority( + Thread_Control *the_thread, + rtems_task_priority new_priority +); + +/* + * _Thread_Change_mode + * + * DESCRIPTION: + * + * This routine changes the current values of the modes + * indicated by mask of the calling thread are changed to that + * indicated in mode_set. The former mode of the thread is + * returned in mode_set. If the changes in the current mode + * indicate that a thread dispatch operation may be necessary, + * then need_dispatch is TRUE, otherwise it is FALSE. + */ + +boolean _Thread_Change_mode( + rtems_mode new_mode_set, + rtems_mode mask, + rtems_mode *old_mode_set +); + +/* + * _Thread_Resume + * + * DESCRIPTION: + * + * This routine clears the SUSPENDED state for the_thread. It performs + * any necessary scheduling operations including the selection of + * a new heir thread. + */ + +STATIC INLINE void _Thread_Resume ( + Thread_Control *the_thread +); + +/* + * _Thread_Unblock + * + * DESCRIPTION: + * + * This routine clears any blocking state for the_thread. It performs + * any necessary scheduling operations including the selection of + * a new heir thread. + */ + +STATIC INLINE void _Thread_Unblock ( + Thread_Control *the_thread +); + +/* + * _Thread_Restart_self + * + * DESCRIPTION: + * + * This routine resets the current context of the calling thread + * to that of its initial state. + */ + +STATIC INLINE void _Thread_Restart_self( void ); + +/* + * _Thread_Calculate_heir + * + * DESCRIPTION: + * + * This function returns a pointer to the highest priority + * ready thread. + */ + +STATIC INLINE void _Thread_Calculate_heir( void ); + +/* + * _Thread_Is_allocated_fp + * + * DESCRIPTION: + * + * This function returns TRUE if the floating point context of + * the_thread is currently loaded in the floating point unit, and + * FALSE otherwise. + */ + +STATIC INLINE boolean _Thread_Is_allocated_fp ( + Thread_Control *the_thread +); + +/* + * _Thread_Deallocate_fp + * + * DESCRIPTION: + * + * This routine is invoked when the currently loaded floating + * point context is now longer associated with an active thread. + */ + +STATIC INLINE void _Thread_Deallocate_fp( void ); + +/* + * _Thread_Disable_dispatch + * + * DESCRIPTION: + * + * This routine prevents dispatching. + */ + +STATIC INLINE void _Thread_Disable_dispatch( void ); + +/* + * _Thread_Enable_dispatch + * + * DESCRIPTION: + * + * This routine allows dispatching to occur again. If this is + * the outer most dispatching critical section, then a dispatching + * operation will be performed and, if necessary, control of the + * processor will be transferred to the heir thread. + */ + +#if ( CPU_INLINE_ENABLE_DISPATCH == TRUE ) + +STATIC INLINE void _Thread_Enable_dispatch(); + +#endif + +#if ( CPU_INLINE_ENABLE_DISPATCH == FALSE ) + +void _Thread_Enable_dispatch( void ); + +#endif + +/* + * _Thread_Unnest_dispatch + * + * DESCRIPTION: + * + * This routine allows dispatching to occur again. However, + * no dispatching operation is performed even if this is the outer + * most dispatching critical section. + */ + +STATIC INLINE void _Thread_Unnest_dispatch( void ); + +/* + * _Thread_Is_dispatching_enabled + * + * DESCRIPTION: + * + * This function returns TRUE if dispatching is disabled, and FALSE + * otherwise. + */ + +STATIC INLINE boolean _Thread_Is_dispatching_enabled( void ); + +/* + * _Thread_Is_context_switch_necessary + * + * DESCRIPTION: + * + * This function returns TRUE if dispatching is disabled, and FALSE + * otherwise. + */ + +STATIC INLINE boolean _Thread_Is_context_switch_necessary( void ); + +/* + * _Thread_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_thread is NULL and FALSE otherwise. + */ + +STATIC INLINE boolean _Thread_Is_null ( + Thread_Control *the_thread +); + +/* + * _Thread_Get + * + * DESCRIPTION: + * + * This function maps thread IDs to thread control + * blocks. If ID corresponds to a local thread, then it + * returns the_thread control pointer which maps to ID + * and location is set to OBJECTS_LOCAL. If the thread ID is + * global and resides on a remote node, then location is set + * to OBJECTS_REMOTE, and the_thread is undefined. + * Otherwise, location is set to OBJECTS_ERROR and + * the_thread is undefined. + */ + +STATIC INLINE Thread_Control *_Thread_Get ( + Objects_Id id, + Objects_Locations *location +); + +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/threadmp.h b/cpukit/score/include/rtems/score/threadmp.h new file mode 100644 index 0000000000..c6e8252030 --- /dev/null +++ b/cpukit/score/include/rtems/score/threadmp.h @@ -0,0 +1,134 @@ +/* threadmp.h + * + * This include file contains the specification for all routines + * and data specific to the multiprocessing portion of the thread package. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_THREAD_MP_h +#define __RTEMS_THREAD_MP_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * _Thread_MP_Handler_initialization + * + * DESCRIPTION: + * + * This package is the specification for the Thread Handler's + * multiprocessing specific support routines. + */ + +void _Thread_MP_Handler_initialization ( + unsigned32 maximum_proxies +); + +/* + * _Thread_MP_Is_receive + * + * DESCRIPTION: + * + * This function returns true if the thread in question is the + * multiprocessing receive thread. + */ + +STATIC INLINE boolean _Thread_MP_Is_receive ( + Thread_Control *the_thread +); + +/* + * _Thread_MP_Allocate_proxy + * + * DESCRIPTION: + * + * 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 +); + +/* + * _Thread_MP_Free_proxy + * + * DESCRIPTION: + * + * This routine frees a proxy control block to the + * inactive chain of free proxy control blocks. + */ + +STATIC INLINE void _Thread_MP_Free_proxy ( + Thread_Control *the_thread +); + +/* + * _Thread_MP_Find_proxy + * + * DESCRIPTION: + * + * This function removes the proxy control block for the specified + * id from the active chain of proxy control blocks. + */ + +Thread_Control *_Thread_MP_Find_proxy ( + Objects_Id the_id +); + +/* + * _Thread_MP_Block + * + * DESCRIPTION: + * + * This routine blocks the MP Receive server thread. + */ + +void _Thread_MP_Block( void ); + +/* + * _Thread_MP_Ready + * + * DESCRIPTION: + * + * This routine readies the MP Receive server thread. + */ + +void _Thread_MP_Ready( void ); + +/* + * 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 *_Thread_MP_Receive; + +/* + * The following chains are used to manage proxies. + */ + +EXTERN Chain_Control _Thread_MP_Active_proxies; +EXTERN Chain_Control _Thread_MP_Inactive_proxies; + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/threadq.h b/cpukit/score/include/rtems/score/threadq.h new file mode 100644 index 0000000000..291044ead1 --- /dev/null +++ b/cpukit/score/include/rtems/score/threadq.h @@ -0,0 +1,264 @@ +/* threadq.h + * + * This include file contains all the constants and structures associated + * with the manipulation of objects. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_THREAD_QUEUE_h +#define __RTEMS_THREAD_QUEUE_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include +#include + +/* + * The following type defines the callout used when a remote task + * is extracted from a local thread queue. + */ + +typedef void ( *Thread_queue_Flush_callout )( + Thread_Control * + ); + +/* + * _Thread_queue_Dequeue + * + * DESCRIPTION: + * + * 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. + */ + +Thread_Control *_Thread_queue_Dequeue( + Thread_queue_Control *the_thread_queue +); + +/* + * _Thread_queue_Enqueue + * + * DESCRIPTION: + * + * This routine enqueues the currently executing thread on + * the_thread_queue with an optional timeout. + */ + +void _Thread_queue_Enqueue( + Thread_queue_Control *the_thread_queue, + rtems_interval timeout +); + +/* + * _Thread_queue_Extract + * + * DESCRIPTION: + * + * This routine removes the_thread from the_thread_queue + * and cancels any timeouts associated with this blocking. + */ + +void _Thread_queue_Extract( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread +); + +/* + * _Thread_queue_First + * + * DESCRIPTION: + * + * This function returns a pointer to the "first" thread + * on the_thread_queue. The "first" thread is selected + * based on the discipline of the_thread_queue. + */ + +Thread_Control *_Thread_queue_First( + Thread_queue_Control *the_thread_queue +); + +/* + * _Thread_queue_Flush + * + * DESCRIPTION: + * + * This routine unblocks all threads blocked on the_thread_queue + * and cancels any associated timeouts. + */ + +void _Thread_queue_Flush( + Thread_queue_Control *the_thread_queue, + Thread_queue_Flush_callout remote_extract_callout +); + +/* + * _Thread_queue_Initialize + * + * DESCRIPTION: + * + * This routine initializes the_thread_queue based on the + * discipline indicated in attribute_set. The state set on + * threads which block on the_thread_queue is state. + */ + +void _Thread_queue_Initialize( + Thread_queue_Control *the_thread_queue, + rtems_attribute attribute_set, + States_Control state +); + +/* + * _Thread_queue_Dequeue_priority + * + * DESCRIPTION: + * + * This function returns a pointer to the highest priority + * thread waiting on the_thread_queue. If no threads are waiting + * on the_thread_queue, then NULL is returned. + */ + +Thread_Control *_Thread_queue_Dequeue_priority( + Thread_queue_Control *the_thread_queue +); + +/* + * _Thread_queue_Enqueue_priority + * + * DESCRIPTION: + * + * This routine enqueues the currently executing thread on + * the_thread_queue with an optional timeout using the + * priority discipline. + */ + +void _Thread_queue_Enqueue_priority( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread, + rtems_interval timeout +); + +/* + * _Thread_queue_Extract_priority + * + * DESCRIPTION: + * + * This routine removes the_thread from the_thread_queue + * and cancels any timeouts associated with this blocking. + */ + +void _Thread_queue_Extract_priority( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread +); + +/* + * _Thread_queue_First_priority + * + * DESCRIPTION: + * + * This function returns a pointer to the "first" thread + * on the_thread_queue. The "first" thread is the highest + * priority thread waiting on the_thread_queue. + */ + +Thread_Control *_Thread_queue_First_priority( + Thread_queue_Control *the_thread_queue +); + +/* + * _Thread_queue_Dequeue_FIFO + * + * DESCRIPTION: + * + * This function returns a pointer to the thread which has + * been waiting the longest on the_thread_queue. If no + * threads are waiting on the_thread_queue, then NULL is returned. + */ + +Thread_Control *_Thread_queue_Dequeue_fifo( + Thread_queue_Control *the_thread_queue +); + +/* + * _Thread_queue_Enqueue_FIFO + * + * DESCRIPTION: + * + * This routine enqueues the currently executing thread on + * the_thread_queue with an optional timeout using the + * RTEMS_FIFO discipline. + */ + +void _Thread_queue_Enqueue_fifo( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread, + rtems_interval timeout +); + +/* + * _Thread_queue_Extract_FIFO + * + * DESCRIPTION: + * + * This routine removes the_thread from the_thread_queue + * and cancels any timeouts associated with this blocking. + */ + +void _Thread_queue_Extract_fifo( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread +); + +/* + * _Thread_queue_First_FIFO + * + * DESCRIPTION: + * + * This function returns a pointer to the "first" thread + * on the_thread_queue. The first thread is the thread + * which has been waiting longest on the_thread_queue. + */ + +Thread_Control *_Thread_queue_First_fifo( + Thread_queue_Control *the_thread_queue +); + +/* + * _Thread_queue_timeout + * + * DESCRIPTION: + * + * This routine is invoked when a task's request has not + * been satisfied after the timeout interval specified to + * enqueue. The task represented by ID will be unblocked and + * its status code will be set in it's control block to indicate + * that a timeout has occurred. + */ + +void _Thread_queue_Timeout ( + Objects_Id id, + void *ignored +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/tod.h b/cpukit/score/include/rtems/score/tod.h new file mode 100644 index 0000000000..ae7e2b9747 --- /dev/null +++ b/cpukit/score/include/rtems/score/tod.h @@ -0,0 +1,300 @@ +/* tod.h + * + * This include file contains all the constants and structures associated + * with the Time of Day Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_TIME_OF_DAY_h +#define __RTEMS_TIME_OF_DAY_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + * The following constants are related to the time of day. + */ + +#define TOD_SECONDS_PER_MINUTE 60 +#define TOD_MINUTES_PER_HOUR 60 +#define TOD_MONTHS_PER_YEAR 12 +#define TOD_DAYS_PER_YEAR 365 +#define TOD_HOURS_PER_DAY 24 +#define TOD_SECONDS_PER_DAY (TOD_SECONDS_PER_MINUTE * \ + TOD_MINUTES_PER_HOUR * \ + TOD_HOURS_PER_DAY) + +#define TOD_MICROSECONDS_PER_SECOND 1000000 +#define TOD_MILLISECONDS_PER_SECOND 1000 + +/* + * The following constant define the earliest year to which an + * RTEMS time of day can be initialized. This is considered the + * epoch. + */ + +#define TOD_BASE_YEAR 1988 + +/* + * The following record defines the time of control block. This + * control block is used to maintain the current time of day. + */ + +typedef struct { /* RTEID style time/date */ + unsigned32 year; /* year, A.D. */ + unsigned32 month; /* month, 1 -> 12 */ + unsigned32 day; /* day, 1 -> 31 */ + unsigned32 hour; /* hour, 0 -> 23 */ + unsigned32 minute; /* minute, 0 -> 59 */ + unsigned32 second; /* second, 0 -> 59 */ + unsigned32 ticks; /* elapsed ticks between secs */ +} rtems_time_of_day; + +/* + * The following contains the current time of day. + */ + +EXTERN rtems_time_of_day _TOD_Current; + +/* + * The following contains the number of seconds from 00:00:00 + * January 1, TOD_BASE_YEAR until the current time of day. + */ + +EXTERN rtems_interval _TOD_Seconds_since_epoch; + +/* + * The following contains the number of ticks since the + * system was booted. + */ + +EXTERN rtems_interval _TOD_Ticks_since_boot; + +/* + * The following contains the number of microseconds per tick. + */ + +EXTERN unsigned32 _TOD_Microseconds_per_tick; + +/* + * The following contains the number of clock ticks per second. + * + * NOTE: + * + * If one second is NOT evenly divisible by the number of microseconds + * per clock tick, this value will contain only the integer portion + * of the division. This means that the interval between clock ticks + * can be a source of error in the current time of day. + */ + +EXTERN unsigned32 _TOD_Ticks_per_second; + +/* + * This is the control structure for the watchdog timer which + * fires to service the seconds chain. + */ + +EXTERN Watchdog_Control _TOD_Seconds_watchdog; + +#ifdef INIT + +/* + * The following array contains the number of days in all months. + * The first dimension should be 1 for leap years, and 0 otherwise. + * The second dimension should range from 1 to 12 for January to + * February, respectively. + */ + +const unsigned32 _TOD_Days_per_month[ 2 ][ 13 ] = { + { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +}; + +/* + * The following array contains the number of days in all months + * up to the month indicated by the index of the second dimension. + * The first dimension should be 1 for leap years, and 0 otherwise. + */ + +const unsigned16 _TOD_Days_to_date[2][13] = { + { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }, + { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 } +}; + +/* + * The following array contains the number of days in the years + * since the last leap year. The index should be 0 for leap + * years, and the number of years since the beginning of a leap + * year otherwise. + */ + +const unsigned16 _TOD_Days_since_last_leap_year[4] = { 0, 366, 761, 1126 }; + +#else + +extern const unsigned16 _TOD_Days_to_date[2][13]; /* Julian days */ +extern const unsigned16 _TOD_Days_since_last_leap_year[4]; +extern const unsigned32 _TOD_Days_per_month[2][13]; + +#endif + +/* + * _TOD_Handler_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this handler. + */ + +void _TOD_Handler_initialization( + unsigned32 microseconds_per_tick +); + +/* + * _TOD_Set + * + * DESCRIPTION: + * + * This routine sets the current time of day to THE_TOD and + * the equivalent SECONDS_SINCE_EPOCH. + */ + +void _TOD_Set( + rtems_time_of_day *the_tod, + rtems_interval seconds_since_epoch +); + +/* + * _TOD_Validate + * + * DESCRIPTION: + * + * This function returns STATUS.RTEMS_SUCCESSFUL if THE_TOD contains + * a valid time of day, and FALSE otherwise. + */ + +rtems_status_code _TOD_Validate( + rtems_time_of_day *the_tod +); + +/* + * _TOD_To_seconds + * + * DESCRIPTION: + * + * This function returns the number seconds between the epoch and THE_TOD. + */ + +rtems_interval _TOD_To_seconds( + rtems_time_of_day *the_tod +); + +/* + * _TOD_Is_set + * + * DESCRIPTION: + * + * This function returns TRUE if the application has set the current + * time of day, and FALSE otherwise. + */ + +STATIC INLINE boolean _TOD_Is_set( void ); + +/* + * _TOD_Tickle_ticks + * + * DESCRIPTION: + * + * This routine increments the ticks field of the current time of + * day at each clock tick. + */ + +STATIC INLINE void _TOD_Tickle_ticks( void ); + +/* + * _TOD_Deactivate + * + * DESCRIPTION: + * + * This routine deactivates updating of the current time of day. + */ + +STATIC INLINE void _TOD_Deactivate( void ); + +/* + * _TOD_Activate + * + * DESCRIPTION: + * + * This routine deactivates updating of the current time of day. + */ + +STATIC INLINE void _TOD_Activate( + rtems_interval ticks +); + +/* + * _TOD_Tickle + * + * DESCRIPTION: + * + * This routine is scheduled as a watchdog function and is invoked at + * each second boundary. It updates the current time of day to indicate + * that a second has passed and processes the seconds watchdog chain. + */ + +void _TOD_Tickle( + Objects_Id id, + void *ignored +); + +/* + * RTEMS_MILLISECONDS_TO_MICROSECONDS + * + * DESCRIPTION: + * + * This routine converts an interval expressed in milliseconds to microseconds. + * + * NOTE: + * + * This must be a macro so it can be used in "static" tables. + */ + +#define RTEMS_MILLISECONDS_TO_MICROSECONDS(_ms) ((_ms) * 1000) + +/* + * RTEMS_MILLISECONDS_TO_TICKS + * + * DESCRIPTION: + * + * This routine converts an interval expressed in milliseconds to ticks. + * + * NOTE: + * + * This must be a macro so it can be used in "static" tables. + */ + +#define RTEMS_MILLISECONDS_TO_TICKS(_ms) \ + (RTEMS_MILLISECONDS_TO_MICROSECONDS(_ms) / _TOD_Microseconds_per_tick) + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/tqdata.h b/cpukit/score/include/rtems/score/tqdata.h new file mode 100644 index 0000000000..8c43fa4c72 --- /dev/null +++ b/cpukit/score/include/rtems/score/tqdata.h @@ -0,0 +1,90 @@ +/* tqdata.h + * + * This include file contains all the constants and structures + * needed to declare a thread queue. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_THREAD_QUEUE_DATA_h +#define __RTEMS_THREAD_QUEUE_DATA_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* + * The following enumerated type details all of the disciplines + * supported by the Thread Queue Handler. + */ + +typedef enum { + THREAD_QUEUE_DATA_FIFO_DISCIPLINE, /* RTEMS_FIFO queue discipline */ + THREAD_QUEUE_DATA_PRIORITY_DISCIPLINE, /* RTEMS_PRIORITY queue discipline */ +} Thread_queue_Disciplines; + +/* + * The following record defines the control block used + * to manage each thread. + */ + +#define TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS 4 /* # of pri groups */ + +typedef struct { + union { + Chain_Control Fifo; /* FIFO discipline list */ + Chain_Control Priority[TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS]; + /* priority discipline list */ + } Queues; + boolean sync; /* alloc/dealloc critical section */ + Thread_queue_Disciplines discipline; /* queue discipline */ + States_Control state; /* state of threads on Thread_q */ +} Thread_queue_Control; + +/* + * _Thread_queue_Header_number + * + * DESCRIPTION: + * + * This function returns the index of the priority chain on which + * a thread of the_priority should be placed. + */ + +STATIC INLINE unsigned32 _Thread_queue_Header_number ( + rtems_task_priority the_priority +); + +/* + * _Thread_queue_Is_reverse_search + * + * DESCRIPTION: + * + * This function returns TRUE if the_priority indicates that the + * enqueue search should start at the front of this priority + * group chain, and FALSE if the search should start at the rear. + */ + +STATIC INLINE boolean _Thread_queue_Is_reverse_search ( + rtems_task_priority the_priority +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/userext.h b/cpukit/score/include/rtems/score/userext.h new file mode 100644 index 0000000000..37131959d9 --- /dev/null +++ b/cpukit/score/include/rtems/score/userext.h @@ -0,0 +1,213 @@ +/* userext.h + * + * This include file contains all information about user extensions. This + * Handler provides mechanisms which can be used to initialize and manipulate + * all RTEMS user extensions. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_USER_EXTENSIONS_h +#define __RTEMS_USER_EXTENSIONS_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + * The following is used to manage each user extension set. + */ + +typedef struct { + Chain_Node Node; + rtems_extensions_table Callouts; +} User_extensions_Control; + +/* + * The following contains the static extension set which may be + * configured by the application. + */ + +EXTERN User_extensions_Control _User_extensions_Initial; + +/* + * The following is used to manage the list of active extensions. + */ + +EXTERN Chain_Control _User_extensions_List; + + +/* + * _User_extensions_Handler_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this handler. + */ + +STATIC INLINE void _User_extensions_Handler_initialization ( + rtems_extensions_table *initial_extensions +); + +/* + * _User_extensions_Add_set + * + * DESCRIPTION: + * + * This routine is used to add a user extension set to the active list. + */ + +STATIC INLINE void _User_extensions_Add_set ( + User_extensions_Control *the_extension, + rtems_extensions_table *extension_table +); + +/* + * _User_extensions_Remove_set + * + * DESCRIPTION: + * + * This routine is used to remove a user extension set from the active list. + */ + +STATIC INLINE void _User_extensions_Remove_set ( + User_extensions_Control *the_extension +); + +/* + * _User_extensions_Task_create + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension for + * the rtems_task_create directive. + */ + +STATIC INLINE void _User_extensions_Task_create ( + Thread_Control *the_thread +); + +/* + * _User_extensions_Task_delete + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension for + * the rtems_task_delete directive. + */ + +STATIC INLINE void _User_extensions_Task_delete ( + Thread_Control *the_thread +); + +/* + * _User_extensions_Task_start + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension for + * the rtems_task_start directive. + */ + +STATIC INLINE void _User_extensions_Task_start ( + Thread_Control *the_thread +); + +/* + * _User_extensions_Task_restart + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension for + * the rtems_task_restart directive. + */ + +STATIC INLINE void _User_extensions_Task_restart ( + Thread_Control *the_thread +); + +/* + * _User_extensions_Task_switch + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension which + * is invoked when a context switch occurs. + */ + +STATIC INLINE void _User_extensions_Task_switch ( + Thread_Control *executing, + Thread_Control *heir +); + +/* + * _User_extensions_Task_begin + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension which + * is invoked when a task begins. + */ + +STATIC INLINE void _User_extensions_Task_begin ( + Thread_Control *executing +); + +/* + * _User_extensions_Task_exitted + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension which + * is invoked when a task exits. + */ + +STATIC INLINE void _User_extensions_Task_exitted ( + Thread_Control *executing +); + +/* + * _User_extensions_Task_exitted + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension which + * is invoked when a task exits. + */ + +STATIC INLINE void _User_extensions_Task_exitted ( + Thread_Control *executing +); + +/* + * _User_extensions_Fatal + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension for + * the rtems_fatal_error_occurred directive. + */ + +STATIC INLINE void _User_extensions_Fatal ( + unsigned32 the_error +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/watchdog.h b/cpukit/score/include/rtems/score/watchdog.h new file mode 100644 index 0000000000..5c897615f7 --- /dev/null +++ b/cpukit/score/include/rtems/score/watchdog.h @@ -0,0 +1,471 @@ +/* watchdog.h + * + * 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, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_WATCHDOG_h +#define __RTEMS_WATCHDOG_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * The following type defines the control block used to manage + * intervals. + */ + +typedef unsigned32 rtems_interval; + +/* + * The following types define a pointer to a watchdog/timer service routine. + */ + +typedef void rtems_timer_service_routine; + +typedef rtems_timer_service_routine ( *rtems_timer_service_routine_entry )( + Objects_Id, + void * + ); + +/* + * Constant for indefinite wait. (actually an illegal interval) + */ + +#define RTEMS_NO_TIMEOUT 0 + +/* + * The following enumerated type details the modes in which the + * Watchdog_Insert routine may operate. The watchdog may be + * activated automatically at insert time or later, explicitly + * by the caller. + */ + +typedef enum { + WATCHDOG_ACTIVATE_NOW, /* activate watchdog as part of insertion */ + WATCHDOG_NO_ACTIVATE /* watchdog will be explicitly activated */ +} Watchdog_Insert_modes; + +/* + * The following enumerated type lists the states in which a + * watchdog timer may be at any given time. + */ + +typedef enum { + WATCHDOG_INACTIVE, /* off all chains */ + WATCHDOG_ACTIVE, /* on chain, allowed to fire */ + WATCHDOG_REINSERT, /* on chain, reset without firing if expires */ + WATCHDOG_REMOVE_IT /* on chain, remove without firing if expires */ +} Watchdog_States; + +/* + * The following enumerated type details the manner in which + * a watchdog chain may be adjusted by the Watchdog_Adjust + * routine. The direction indicates a movement FORWARD + * or BACKWARD in time. + */ + +typedef enum { + WATCHDOG_FORWARD, /* adjust delta value forward */ + WATCHDOG_BACKWARD /* adjust delta value backward */ +} Watchdog_Adjust_directions; + +/* + * The following record defines the control block used + * to manage each watchdog timer. + */ + +typedef struct { + Chain_Node Node; + Watchdog_States state; + rtems_interval initial; + rtems_interval delta_interval; + rtems_timer_service_routine_entry routine; + Objects_Id id; + void *user_data; +} Watchdog_Control; + +/* + * The following type is used for synchronization purposes + * during an insert on a watchdog delta chain. + * + * NOTE: Watchdog_Pointer is only used to insure that + * Watchdog_Synchronization_pointer is a pointer + * which is volatile rather than a pointer to a + * volatile block of memory. + */ + +typedef Watchdog_Control *Watchdog_Pointer; +typedef volatile Watchdog_Pointer Watchdog_Synchronization_pointer; + +/* + * The following defines the watchdog chains which are managed + * on ticks and second boundaries. + */ + +EXTERN Chain_Control _Watchdog_Ticks_chain; +EXTERN Chain_Control _Watchdog_Seconds_chain; + +/* + * The following defines the synchronization variable used to + * allow interrupts to be enabled while inserting a watchdog + * on a watchdog chain. + */ + +EXTERN Watchdog_Synchronization_pointer _Watchdog_Sync; + +/* + * _Watchdog_Handler_initialization + * + * DESCRIPTION: + * + * This routine initializes the watchdog handler. The watchdog + * synchronization flag is initialized and the watchdog chains are + * initialized and emptied. + */ + +void _Watchdog_Handler_initialization( void ); + +/* + * + * _Watchdog_Initialize + * + * DESCRIPTION: + * + * This routine initializes the specified watchdog. The watchdog is + * made inactive, the watchdog id and handler routine are set to the + * specified values. + */ + +STATIC INLINE void _Watchdog_Initialize( + Watchdog_Control *the_watchdog, + rtems_timer_service_routine_entry routine, + Objects_Id id, + void *user_data +); + +/* + * _Watchdog_Remove + * + * DESCRIPTION: + * + * This routine removes THE_WATCHDOG from the watchdog chain on which + * it resides and returns the state THE_WATCHDOG timer was in. + */ + +Watchdog_States _Watchdog_Remove ( + Watchdog_Control *the_watchdog +); + +/* + * + * _Watchdog_Is_active + * + * DESCRIPTION: + * + * This routine returns TRUE if the watchdog timer is in the ACTIVE + * state, and FALSE otherwise. + */ + +STATIC INLINE boolean _Watchdog_Is_active( + Watchdog_Control *the_watchdog +); + +/* + * + * _Watchdog_Activate + * + * DESCRIPTION: + * + * This routine activates THE_WATCHDOG timer which is already + * on a watchdog chain. + */ + +STATIC INLINE void _Watchdog_Activate( + Watchdog_Control *the_watchdog +); + +/* + * + * _Watchdog_Deactivate + * + * DESCRIPTION: + * + * This routine deactivates THE_WATCHDOG timer which will remain + * on a watchdog chain. + */ + +STATIC INLINE void _Watchdog_Deactivate( + Watchdog_Control *the_watchdog +); + +/* + * + * _Watchdog_Tickle_ticks + * + * DESCRIPTION: + * + * This routine is invoked at each clock tick to update the ticks + * watchdog chain. + */ + +STATIC INLINE void _Watchdog_Tickle_ticks( void ); + +/* + * + * _Watchdog_Tickle_seconds + * + * DESCRIPTION: + * + * This routine is invoked at each clock tick to update the seconds + * watchdog chain. + */ + +STATIC INLINE void _Watchdog_Tickle_seconds( void ); + +/* + * + * _Watchdog_Insert_ticks + * + * DESCRIPTION: + * + * This routine inserts THE_WATCHDOG into the ticks watchdog chain + * for a time of UNITS ticks. The INSERT_MODE indicates whether + * THE_WATCHDOG is to be activated automatically or later, explicitly + * by the caller. + */ + +STATIC INLINE void _Watchdog_Insert_ticks( + Watchdog_Control *the_watchdog, + rtems_interval units, + Watchdog_Insert_modes insert_mode +); + +/* + * + * _Watchdog_Insert_seconds + * + * DESCRIPTION: + * + * This routine inserts THE_WATCHDOG into the seconds watchdog chain + * for a time of UNITS seconds. The INSERT_MODE indicates whether + * THE_WATCHDOG is to be activated automatically or later, explicitly + * by the caller. + */ + +STATIC INLINE void _Watchdog_Insert_seconds( + Watchdog_Control *the_watchdog, + rtems_interval units, + Watchdog_Insert_modes insert_mode +); + +/* + * + * _Watchdog_Adjust_seconds + * + * DESCRIPTION: + * + * This routine adjusts the seconds watchdog chain in the forward + * or backward DIRECTION for UNITS seconds. This is invoked when the + * current time of day is changed. + */ + +STATIC INLINE void _Watchdog_Adjust_seconds( + Watchdog_Adjust_directions direction, + rtems_interval units +); + +/* + * + * _Watchdog_Adjust_ticks + * + * DESCRIPTION: + * + * This routine adjusts the ticks watchdog chain in the forward + * or backward DIRECTION for UNITS ticks. + */ + +STATIC INLINE void _Watchdog_Adjust_ticks( + Watchdog_Adjust_directions direction, + rtems_interval units +); + +/* + * + * _Watchdog_Reset + * + * DESCRIPTION: + * + * This routine resets THE_WATCHDOG timer to its state at INSERT + * time. This routine is valid only on interval watchdog timers + * and is used to make an interval watchdog timer fire "every" so + * many ticks. + */ + +STATIC INLINE void _Watchdog_Reset( + Watchdog_Control *the_watchdog +); + +/* + * + * _Watchdog_Next + * + * DESCRIPTION: + * + * This routine returns a pointer to the watchdog timer following + * THE_WATCHDOG on the watchdog chain. + */ + +STATIC INLINE Watchdog_Control *_Watchdog_Next( + Watchdog_Control *the_watchdog +); + +/* + * + * _Watchdog_Previous + * + * DESCRIPTION: + * + * This routine returns a pointer to the watchdog timer preceding + * THE_WATCHDOG on the watchdog chain. + */ + +STATIC INLINE Watchdog_Control *_Watchdog_Previous( + Watchdog_Control *the_watchdog +); + +/* + * + * _Watchdog_First + * + * DESCRIPTION: + * + * This routine returns a pointer to the first watchdog timer + * on the watchdog chain HEADER. + */ + +STATIC INLINE Watchdog_Control *_Watchdog_First( + Chain_Control *header +); + +/* + * + * _Watchdog_Last + * + * DESCRIPTION: + * + * This routine returns a pointer to the last watchdog timer + * on the watchdog chain HEADER. + */ +STATIC INLINE Watchdog_Control *_Watchdog_Last( + Chain_Control *header +); + +/* + * + * _Watchdog_Get_sync + * + * DESCRIPTION: + * + * This routine returns the current synchronization timer. This + * routine is used so that interrupts can be enabled while a + * watchdog timer is being inserted into a watchdog chain. + */ + +STATIC INLINE Watchdog_Control *_Watchdog_Get_sync( void ); + +/* + * + * _Watchdog_Set_sync + * + * DESCRIPTION: + * + * This routine sets the current synchronization timer. This + * routine is used so that interrupts can be enabled while a + * watchdog timer is being inserted into a watchdog chain. + */ + +STATIC INLINE void _Watchdog_Set_sync( + Watchdog_Control *the_watchdog +); + +/* + * + * _Watchdog_Clear_sync + * + * DESCRIPTION: + * + * This routine will set the watchdog synchronization flag to a + * NULL address indicating synchronization is unnecessary. + */ + +STATIC INLINE void _Watchdog_Clear_sync( void ); + +/* + * _Watchdog_Adjust + * + * DESCRIPTION: + * + * This routine adjusts the HEADER watchdog chain in the forward + * or backward DIRECTION for UNITS ticks. + */ + +void _Watchdog_Adjust ( + Chain_Control *header, + Watchdog_Adjust_directions direction, + rtems_interval units +); + +/* + * _Watchdog_Insert + * + * DESCRIPTION: + * + * This routine inserts THE_WATCHDOG into the HEADER watchdog chain + * for a time of UNITS. The INSERT_MODE indicates whether + * THE_WATCHDOG is to be activated automatically or later, explicitly + * by the caller. + * + */ + +void _Watchdog_Insert ( + Chain_Control *header, + Watchdog_Control *the_watchdog, + Watchdog_Insert_modes insert_mode +); + +/* + * _Watchdog_Tickle + * + * DESCRIPTION: + * + * This routine is invoked at appropriate intervals to update + * the HEADER watchdog chain. + */ + +void _Watchdog_Tickle ( + Chain_Control *header +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/wkspace.h b/cpukit/score/include/rtems/score/wkspace.h new file mode 100644 index 0000000000..14bc090291 --- /dev/null +++ b/cpukit/score/include/rtems/score/wkspace.h @@ -0,0 +1,99 @@ +/* wkspace.h + * + * This include file contains information related to the RTEMS + * RAM Workspace. This Handler provides mechanisms which can be used to + * define, initialize and manipulate the RTEMS workspace. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_WORKSPACE_h +#define __RTEMS_WORKSPACE_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* + * The following is used to manage the RTEMS Workspace. + * + */ + +EXTERN Heap_Control _Workspace_Area; /* executive heap header */ + +/* + * _Workspace_Handler_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this handler. + */ + +STATIC INLINE void _Workspace_Handler_initialization( + void *starting_address, + unsigned32 size +); + +/* + * _Workspace_Allocate + * + * DESCRIPTION: + * + * 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. + */ + +STATIC INLINE void *_Workspace_Allocate( + unsigned32 size +); + +/* + * _Workspace_Allocate_or_fatal_error + * + * DESCRIPTION: + * + * 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 the rtems_fatal_error_occurred directive + * is invoked. + */ + +STATIC INLINE void *_Workspace_Allocate_or_fatal_error( + unsigned32 size +); + +/* + * _Workspace_Free + * + * DESCRIPTION: + * + * 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. + */ + +STATIC INLINE boolean _Workspace_Free( + void *block +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/system.h b/cpukit/score/include/rtems/system.h new file mode 100644 index 0000000000..3ff3772d11 --- /dev/null +++ b/cpukit/score/include/rtems/system.h @@ -0,0 +1,132 @@ +/* system.h + * + * 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, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_SYSTEM_h +#define __RTEMS_SYSTEM_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following define the CPU Family and Model within the family + * + * NOTE: The string "REPLACE_THIS_WITH_USE_INLINE_OR_MACROS" is replaced + * with either "USE_INLINES" or "USE_MACROS" based upon the + * whether this target configuration uses the inline or + * macro implementations of the inlined RTEMS routines. + */ + + +#define REPLACE_THIS_WITH_USE_INLINE_OR_MACROS + +/* + * The following insures that all data is declared in the space + * of the Initialization Manager. It is referenced as "external" + * in every other file. + */ + +#ifdef INIT +#undef EXTERN +#define EXTERN +#else +#undef EXTERN +#define EXTERN extern +#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 USE_INLINES +#define STATIC static +#define INLINE __inline__ +#else +/* +#error Only the GNU C compiler is currently supported!!! +*/ +#define STATIC +#define INLINE +#endif + +/* + * Include a base set of files. + */ + +/* + * XXX: Eventually proc_ptr needs to disappear!!! + */ + +typedef void * proc_ptr; + +#include /* processor specific information */ +#include /* RTEMS status codes */ + +/* + * Define NULL + */ + +#ifndef NULL +#define NULL 0 /* NULL value */ +#endif + +/* + * Boolean constants + */ + +#if !defined( TRUE ) || (TRUE != 1) +#undef TRUE +#define TRUE (1) +#endif + +#if !defined( FALSE ) || (FALSE != 0) +#undef FALSE +#define FALSE (0) +#endif + +#define stringify( _x ) # _x + +/* + * The following is the extern for the RTEMS version string. + * The contents of this string are CPU specific. + */ + +extern const char _RTEMS_version[]; /* RTEMS version string */ +extern const char _Copyright_Notice[]; /* RTEMS copyright string */ + +/* + * The jump table of entry points into RTEMS directives. + */ + +#define NUMBER_OF_ENTRY_POINTS 79 +extern const void * _Entry_points[ NUMBER_OF_ENTRY_POINTS + 1 ]; + +/* + * The following defines the CPU dependent information table. + */ + +EXTERN rtems_cpu_table _CPU_Table; /* CPU dependent info */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/address.inl b/cpukit/score/inline/rtems/score/address.inl new file mode 100644 index 0000000000..f9189e625e --- /dev/null +++ b/cpukit/score/inline/rtems/score/address.inl @@ -0,0 +1,109 @@ +/* inline/address.inl + * + * This include file contains the bodies of the routines + * about addresses which are inlined. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INLINE_ADDRESSES_inl +#define __INLINE_ADDRESSES_inl + +/*PAGE + * + * _Addresses_Add_offset + * + */ + +STATIC INLINE void *_Addresses_Add_offset ( + void *base, + unsigned32 offset +) +{ + return (base + offset); +} + +/*PAGE + * + * _Addresses_Subtract_offset + * + */ + +STATIC INLINE void *_Addresses_Subtract_offset ( + void *base, + unsigned32 offset +) +{ + return (base - offset); +} + +/*PAGE + * + * _Addresses_Add + * + * NOTE: The cast of an address to an unsigned32 makes this code + * dependent on an addresses being thirty two bits. + */ + +STATIC INLINE void *_Addresses_Add ( + void *left, + void *right +) +{ + return (left + (unsigned32)right); +} + +/*PAGE + * + * _Addresses_Subtract + * + * NOTE: The cast of an address to an unsigned32 makes this code + * dependent on an addresses being thirty two bits. + */ + +STATIC INLINE unsigned32 _Addresses_Subtract ( + void *left, + void *right +) +{ + return (left - right); +} + +/*PAGE + * + * _Addresses_Is_aligned + * + */ + +STATIC INLINE boolean _Addresses_Is_aligned ( + void *address +) +{ + return ( ( (unsigned32)address % CPU_ALIGNMENT ) == 0 ); +} + +/*PAGE + * + * _Addresses_Is_in_range + * + */ + +STATIC INLINE boolean _Addresses_Is_in_range ( + void *address, + void *base, + void *limit +) +{ + return ( address >= base && address <= limit ); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/chain.inl b/cpukit/score/inline/rtems/score/chain.inl new file mode 100644 index 0000000000..63706544e4 --- /dev/null +++ b/cpukit/score/inline/rtems/score/chain.inl @@ -0,0 +1,292 @@ +/* inline/chain.inl + * + * This include file contains the bodies of the routines which are + * associated with doubly linked chains and inlined. + * + * NOTE: The routines in this file are ordered from simple + * to complex. No other Chain Handler routine is referenced + * unless it has already been defined. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INLINE_CHAIN_inl +#define __INLINE_CHAIN_inl + +/*PAGE + * + * _Chain_Are_nodes_equal + */ + +STATIC INLINE boolean _Chain_Are_nodes_equal( + Chain_Node *left, + Chain_Node *right +) +{ + return left == right; +} + +/*PAGE + * + * _Chain_Is_null + */ + +STATIC INLINE boolean _Chain_Is_null( + Chain_Control *the_chain +) +{ + return ( the_chain == NULL ); +} + +/*PAGE + * + * _Chain_Is_null_node + */ + +STATIC INLINE boolean _Chain_Is_null_node( + Chain_Node *the_node +) +{ + return ( the_node == NULL ); +} + +/*PAGE + * + * _Chain_Head + */ + +STATIC INLINE Chain_Node *_Chain_Head( + Chain_Control *the_chain +) +{ + return (Chain_Node *) the_chain; +} + +/*PAGE + * + * _Chain_Tail + */ + +STATIC INLINE Chain_Node *_Chain_Tail( + Chain_Control *the_chain +) +{ + return (Chain_Node *) &the_chain->permanent_null; +} + +/*PAGE + * + * _Chain_Is_empty + */ + +STATIC INLINE boolean _Chain_Is_empty( + Chain_Control *the_chain +) +{ + return ( the_chain->first == _Chain_Tail( the_chain ) ); +} + +/*PAGE + * + * _Chain_Is_first + */ + +STATIC INLINE boolean _Chain_Is_first( + Chain_Node *the_node +) +{ + return ( the_node->previous == NULL ); +} + +/*PAGE + * + * _Chain_Is_last + */ + +STATIC INLINE boolean _Chain_Is_last( + Chain_Node *the_node +) +{ + return ( the_node->next == NULL ); +} + +/*PAGE + * + * _Chain_Has_only_one_node + */ + +STATIC INLINE boolean _Chain_Has_only_one_node( + Chain_Control *the_chain +) +{ + return ( the_chain->first == the_chain->last ); +} + +/*PAGE + * + * _Chain_Is_head + */ + +STATIC INLINE boolean _Chain_Is_head( + Chain_Control *the_chain, + Chain_Node *the_node +) +{ + return ( the_node == _Chain_Head( the_chain ) ); +} + +/*PAGE + * + * _Chain_Is_tail + */ + +STATIC INLINE boolean _Chain_Is_tail( + Chain_Control *the_chain, + Chain_Node *the_node +) +{ + return ( the_node == _Chain_Tail( the_chain ) ); +} + +/*PAGE + * + * Chain_Initialize_empty + */ + +STATIC INLINE void _Chain_Initialize_empty( + Chain_Control *the_chain +) +{ + the_chain->first = _Chain_Tail( the_chain ); + the_chain->permanent_null = NULL; + the_chain->last = _Chain_Head( the_chain ); +} + +/*PAGE + * + * _Chain_Extract_unprotected + */ + +STATIC INLINE 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; +} + +/*PAGE + * + * _Chain_Get_first_unprotected + */ + +STATIC INLINE Chain_Node *_Chain_Get_first_unprotected( + Chain_Control *the_chain +) +{ + Chain_Node *return_node; + Chain_Node *new_first; + + return_node = the_chain->first; + new_first = return_node->next; + the_chain->first = new_first; + new_first->previous = _Chain_Head( the_chain ); + + return return_node; +} + +/*PAGE + * + * Chain_Get_unprotected + */ + +STATIC INLINE 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; +} + +/*PAGE + * + * _Chain_Insert_unprotected + */ + +STATIC INLINE void _Chain_Insert_unprotected( + Chain_Node *after_node, + Chain_Node *the_node +) +{ + Chain_Node *before_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; +} + +/*PAGE + * + * _Chain_Append_unprotected + */ + +STATIC INLINE void _Chain_Append_unprotected( + Chain_Control *the_chain, + Chain_Node *the_node +) +{ + Chain_Node *old_last_node; + + the_node->next = _Chain_Tail( the_chain ); + old_last_node = the_chain->last; + the_chain->last = the_node; + old_last_node->next = the_node; + the_node->previous = old_last_node; +} + +/*PAGE + * + * _Chain_Prepend_unprotected + */ + +STATIC INLINE void _Chain_Prepend_unprotected( + Chain_Control *the_chain, + Chain_Node *the_node +) +{ + _Chain_Insert_unprotected( _Chain_Head( the_chain ), the_node ); + +} + +/*PAGE + * + * _Chain_Prepend + */ + +STATIC INLINE void _Chain_Prepend( + Chain_Control *the_chain, + Chain_Node *the_node +) +{ + _Chain_Insert( _Chain_Head( the_chain ), the_node ); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/heap.inl b/cpukit/score/inline/rtems/score/heap.inl new file mode 100644 index 0000000000..58be9b02af --- /dev/null +++ b/cpukit/score/inline/rtems/score/heap.inl @@ -0,0 +1,203 @@ +/* heap.inl + * + * This file contains the static inline implementation of the inlined + * routines from the heap handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __HEAP_inl +#define __HEAP_inl + +#include + +/*PAGE + * + * _Heap_Head + * + */ + +STATIC INLINE Heap_Block *_Heap_Head ( + Heap_Control *the_heap +) +{ + return (Heap_Block *)&the_heap->start; +} + +/*PAGE + * + * _Heap_Tail + * + */ + +STATIC INLINE Heap_Block *_Heap_Tail ( + Heap_Control *the_heap +) +{ + return (Heap_Block *)&the_heap->final; +} + +/*PAGE + * + * _Heap_Previous_block + * + */ + +STATIC INLINE Heap_Block *_Heap_Previous_block ( + Heap_Block *the_block +) +{ + return (Heap_Block *) _Addresses_Subtract_offset( + (void *)the_block, + the_block->back_flag & ~ HEAP_BLOCK_USED + ); +} + +/*PAGE + * + * _Heap_Next_block + * + * NOTE: Next_block assumes that the block is free. + */ + +STATIC INLINE Heap_Block *_Heap_Next_block ( + Heap_Block *the_block +) +{ + return (Heap_Block *) _Addresses_Add_offset( + (void *)the_block, + the_block->front_flag & ~ HEAP_BLOCK_USED + ); +} + +/*PAGE + * + * _Heap_Block_at + * + */ + +STATIC INLINE Heap_Block *_Heap_Block_at( + void *base, + unsigned32 offset +) +{ + return (Heap_Block *) _Addresses_Add_offset( (void *)base, offset ); +} + +/*PAGE + * + * _Heap_Is_previous_block_free + * + */ + +STATIC INLINE boolean _Heap_Is_previous_block_free ( + Heap_Block *the_block +) +{ + return !(the_block->back_flag & HEAP_BLOCK_USED); +} + +/*PAGE + * + * _Heap_Is_block_free + * + */ + +STATIC INLINE boolean _Heap_Is_block_free ( + Heap_Block *the_block +) +{ + return !(the_block->front_flag & HEAP_BLOCK_USED); +} + +/*PAGE + * + * _Heap_Is_block_used + * + */ + +STATIC INLINE boolean _Heap_Is_block_used ( + Heap_Block *the_block +) +{ + return (the_block->front_flag & HEAP_BLOCK_USED); +} + +/*PAGE + * + * _Heap_Block_size + * + */ + +STATIC INLINE unsigned32 _Heap_Block_size ( + Heap_Block *the_block +) +{ + return (the_block->front_flag & ~HEAP_BLOCK_USED); +} + +/*PAGE + * + * _Heap_Start_of_user_area + * + */ + +STATIC INLINE void *_Heap_Start_of_user_area ( + Heap_Block *the_block +) +{ + return (void *) &the_block->next; +} + +/*PAGE + * + * _Heap_Is_block_in + * + */ + +STATIC INLINE boolean _Heap_Is_block_in ( + Heap_Control *the_heap, + Heap_Block *the_block +) +{ + return _Addresses_Is_in_range( the_block, the_heap->start, the_heap->final ); +} + +/*PAGE + * + * _Heap_Is_page_size_valid + * + */ + +STATIC INLINE boolean _Heap_Is_page_size_valid( + unsigned32 page_size +) +{ + return ((page_size != 0) && + ((page_size % CPU_HEAP_ALIGNMENT) == 0)); +} + +/*PAGE + * + * _Heap_Build_flag + * + */ + +STATIC INLINE unsigned32 _Heap_Build_flag ( + unsigned32 size, + unsigned32 in_use_flag +) +{ + return size | in_use_flag; +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/isr.inl b/cpukit/score/inline/rtems/score/isr.inl new file mode 100644 index 0000000000..f44880c3b6 --- /dev/null +++ b/cpukit/score/inline/rtems/score/isr.inl @@ -0,0 +1,70 @@ +/* isr.inl + * + * This include file contains the static implementation of all + * inlined routines in the Interrupt Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __ISR_inl +#define __ISR_inl + +/*PAGE + * + * _ISR_Handler_initialization + * + */ + +STATIC INLINE void _ISR_Handler_initialization ( void ) +{ + _ISR_Signals_to_thread_executing = FALSE; + _ISR_Nest_level = 0; +} + +/*PAGE + * + * _ISR_Is_in_progress + * + */ + +STATIC INLINE boolean _ISR_Is_in_progress( void ) +{ + return (_ISR_Nest_level != 0); +} + +/*PAGE + * + * _ISR_Is_vector_number_valid + * + */ + +STATIC INLINE boolean _ISR_Is_vector_number_valid ( + unsigned32 vector +) +{ + return ( vector < CPU_INTERRUPT_NUMBER_OF_VECTORS ); +} + +/*PAGE + * + * _ISR_Is_valid_user_handler + * + */ + +STATIC INLINE boolean _ISR_Is_valid_user_handler ( + void *handler +) +{ + return ( handler != NULL); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/mppkt.inl b/cpukit/score/inline/rtems/score/mppkt.inl new file mode 100644 index 0000000000..22ec30a28c --- /dev/null +++ b/cpukit/score/inline/rtems/score/mppkt.inl @@ -0,0 +1,49 @@ +/* inline/mppkt.inl + * + * This package is the implementation of the Packet Handler + * routines which are inlined. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INLINE_MP_PACKET_inl +#define __INLINE_MP_PACKET_inl + +/*PAGE + * + * _Mp_packet_Is_valid_packet_class + * + * NOTE: Check for lower bounds (MP_PACKET_CLASSES_FIRST ) is unnecessary + * because this enum starts at lower bound of zero. + */ + +STATIC INLINE boolean _Mp_packet_Is_valid_packet_class ( + rtems_mp_packet_classes the_packet_class +) +{ + return ( the_packet_class <= MP_PACKET_CLASSES_LAST ); +} + +/*PAGE + * + * _Mp_packet_Is_null + * + */ + +STATIC INLINE boolean _Mp_packet_Is_null ( + rtems_packet_prefix *the_packet +) +{ + return the_packet == NULL; +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/object.inl b/cpukit/score/inline/rtems/score/object.inl new file mode 100644 index 0000000000..9c2110077c --- /dev/null +++ b/cpukit/score/inline/rtems/score/object.inl @@ -0,0 +1,198 @@ +/* object.inl + * + * This include file contains the static inline implementation of all + * of the inlined routines in the Object Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __OBJECTS_inl +#define __OBJECTS_inl + +/*PAGE + * + * _Objects_Is_name_valid + * + */ + +STATIC INLINE boolean _Objects_Is_name_valid ( + Objects_Name name +) +{ + return ( name != 0 ); +} + +/*PAGE + * + * rtems_name_to_characters + * + */ + +STATIC INLINE void rtems_name_to_characters( + Objects_Name name, + char *c1, + char *c2, + char *c3, + char *c4 +) +{ + *c1 = (name >> 24) & 0xff; + *c2 = (name >> 16) & 0xff; + *c3 = (name >> 8) & 0xff; + *c4 = name & 0xff; +} + +/*PAGE + * + * _Objects_Build_id + * + */ + +STATIC INLINE Objects_Id _Objects_Build_id( + unsigned32 node, + unsigned32 index +) +{ + return ( (node << 16) | index ); +} + +/*PAGE + * + * rtems_get_node + * + */ + +STATIC INLINE unsigned32 rtems_get_node( + Objects_Id id +) +{ + return (id >> 16); +} + +/*PAGE + * + * rtems_get_index + * + */ + +STATIC INLINE unsigned32 rtems_get_index( + Objects_Id id +) +{ + return (id &0xFFFF); +} + +/*PAGE + * + * _Objects_Is_local_node + * + */ + +STATIC INLINE boolean _Objects_Is_local_node( + unsigned32 node +) +{ + return ( node == _Objects_Local_node ); +} + +/*PAGE + * + * _Objects_Is_local_id + * + */ + +STATIC INLINE boolean _Objects_Is_local_id( + Objects_Id id +) +{ + return _Objects_Is_local_node( rtems_get_node(id) ); +} + +/*PAGE + * + * _Objects_Are_ids_equal + * + */ + +STATIC INLINE boolean _Objects_Are_ids_equal( + Objects_Id left, + Objects_Id right +) +{ + return ( left == right ); +} + +/*PAGE + * + * _Objects_Allocate + * + */ + +STATIC INLINE Objects_Control *_Objects_Allocate( + Objects_Information *information +) +{ + return (Objects_Control *) _Chain_Get( &information->Inactive ); +} + +/*PAGE + * + * _Objects_Free + * + */ + +STATIC INLINE void _Objects_Free( + Objects_Information *information, + Objects_Control *the_object +) +{ + _Chain_Append( &information->Inactive, &the_object->Node ); +} + +/*PAGE + * + * _Objects_Open + * + */ + +STATIC INLINE void _Objects_Open( + Objects_Information *information, + Objects_Control *the_object, + Objects_Name name +) +{ + unsigned32 index; + + index = rtems_get_index( the_object->id ); + information->local_table[ index ] = the_object; + information->name_table[ index ] = name; +} + +/*PAGE + * + * _Objects_Close + * + */ + +STATIC INLINE void _Objects_Close( + Objects_Information *information, + Objects_Control *the_object +) +{ + unsigned32 index; + + index = rtems_get_index( the_object->id ); + information->local_table[ index ] = NULL; + information->name_table[ index ] = 0; +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/objectmp.inl b/cpukit/score/inline/rtems/score/objectmp.inl new file mode 100644 index 0000000000..e09a3df528 --- /dev/null +++ b/cpukit/score/inline/rtems/score/objectmp.inl @@ -0,0 +1,62 @@ +/* inline/objectmp.inl + * + * This include file contains the bodies of all inlined routines + * which deal with global objects. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INLINE_MP_OBJECTS_inl +#define __INLINE_MP_OBJECTS_inl + +/*PAGE + * + * _Objects_MP_Allocate_global_object + * + */ + +STATIC INLINE Objects_MP_Control *_Objects_MP_Allocate_global_object ( + void +) +{ + return (Objects_MP_Control *) + _Chain_Get( &_Objects_MP_Inactive_global_objects ); +} + +/*PAGE + * _Objects_MP_Free_global_object + * + */ + +STATIC INLINE void _Objects_MP_Free_global_object ( + Objects_MP_Control *the_object +) +{ + _Chain_Append( + &_Objects_MP_Inactive_global_objects, + &the_object->Object.Node + ); +} + +/*PAGE + * _Objects_MP_Is_null_global_object + * + */ + +STATIC INLINE boolean _Objects_MP_Is_null_global_object ( + Objects_MP_Control *the_object +) +{ + return( the_object == NULL ); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/priority.inl b/cpukit/score/inline/rtems/score/priority.inl new file mode 100644 index 0000000000..9e7c159f65 --- /dev/null +++ b/cpukit/score/inline/rtems/score/priority.inl @@ -0,0 +1,168 @@ +/* priority.inl + * + * This file contains the static inline implementation of all inlined + * routines in the Priority Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __PRIORITY_inl +#define __PRIORITY_inl + +#include + +/*PAGE + * + * _Priority_Handler_initialization + * + */ + +STATIC INLINE void _Priority_Handler_initialization( void ) +{ + unsigned32 index; + + _Priority_Major_bit_map = 0; + for ( index=0 ; index <16 ; index++ ) + _Priority_Bit_map[ index ] = 0; +} + +/*PAGE + * + * _Priority_Is_valid + * + */ + +STATIC INLINE boolean _Priority_Is_valid ( + rtems_task_priority the_priority +) +{ + return ( ( the_priority >= RTEMS_MINIMUM_PRIORITY ) && + ( the_priority <= RTEMS_MAXIMUM_PRIORITY ) ); +} + +/*PAGE + * + * _Priority_Major + * + */ + +STATIC INLINE unsigned32 _Priority_Major ( + rtems_task_priority the_priority +) +{ + return ( the_priority / 16 ); +} + +/*PAGE + * + * _Priority_Minor + * + */ + +STATIC INLINE unsigned32 _Priority_Minor ( + rtems_task_priority the_priority +) +{ + return ( the_priority % 16 ); +} + +/*PAGE + * + * _Priority_Add_to_bit_map + * + */ + +STATIC INLINE void _Priority_Add_to_bit_map ( + Priority_Information *the_priority_map +) +{ + *the_priority_map->minor |= the_priority_map->ready_minor; + _Priority_Major_bit_map |= the_priority_map->ready_major; +} + +/*PAGE + * + * _Priority_Remove_from_bit_map + * + */ + +STATIC INLINE void _Priority_Remove_from_bit_map ( + Priority_Information *the_priority_map +) +{ + *the_priority_map->minor &= the_priority_map->block_minor; + if ( *the_priority_map->minor == 0 ) + _Priority_Major_bit_map &= the_priority_map->block_major; +} + +/*PAGE + * + * _Priority_Get_highest + * + */ + +STATIC INLINE rtems_task_priority _Priority_Get_highest( void ) +{ + Priority_Bit_map_control minor; + Priority_Bit_map_control major; + + _Bitfield_Find_first_bit( _Priority_Major_bit_map, major ); + _Bitfield_Find_first_bit( _Priority_Bit_map[major], minor ); + + return (_CPU_Priority_Bits_index( major ) << 4) + + _CPU_Priority_Bits_index( minor ); +} + +/*PAGE + * + * _Priority_Initialize_information + * + */ + +STATIC INLINE void _Priority_Initialize_information( + Priority_Information *the_priority_map, + rtems_task_priority new_priority +) +{ + Priority_Bit_map_control major; + Priority_Bit_map_control minor; + Priority_Bit_map_control mask; + + major = _Priority_Major( new_priority ); + minor = _Priority_Minor( new_priority ); + + the_priority_map->minor = + &_Priority_Bit_map[ _CPU_Priority_Bits_index(major) ]; + + mask = _CPU_Priority_Mask( major ); + the_priority_map->ready_major = mask; + the_priority_map->block_major = ~mask; + + mask = _CPU_Priority_Mask( minor ); + the_priority_map->ready_minor = mask; + the_priority_map->block_minor = ~mask; +} + +/*PAGE + * + * _Priority_Is_group_empty + * + */ + +STATIC INLINE boolean _Priority_Is_group_empty ( + rtems_task_priority the_priority +) +{ + return the_priority == 0; +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/stack.inl b/cpukit/score/inline/rtems/score/stack.inl new file mode 100644 index 0000000000..24a6d9d873 --- /dev/null +++ b/cpukit/score/inline/rtems/score/stack.inl @@ -0,0 +1,63 @@ +/* stack.inl + * + * This file contains the static inline implementation of the inlined + * routines from the Stack Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __STACK_inl +#define __STACK_inl + +/*PAGE + * + * _Stack_Initialize + * + */ + +STATIC INLINE void _Stack_Initialize ( + Stack_Control *the_stack, + void *starting_address, + unsigned32 size +) +{ + the_stack->area = starting_address; + the_stack->size = size; +} + +/*PAGE + * + * _Stack_Is_enough + * + */ + +STATIC INLINE boolean _Stack_Is_enough ( + unsigned32 size +) +{ + return ( size >= RTEMS_MINIMUM_STACK_SIZE ); +} + +/*PAGE + * + * _Stack_Adjust_size + * + */ + +STATIC INLINE unsigned32 _Stack_Adjust_size ( + unsigned32 size +) +{ + return size + CPU_STACK_ALIGNMENT; +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/states.inl b/cpukit/score/inline/rtems/score/states.inl new file mode 100644 index 0000000000..316f40e4eb --- /dev/null +++ b/cpukit/score/inline/rtems/score/states.inl @@ -0,0 +1,285 @@ +/* states.inl + * + * This file contains the macro implementation of the inlined + * routines associated with RTEMS state information. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __STATES_inl +#define __STATES_inl + +/*PAGE + * + * _States_Set + * + */ + +STATIC INLINE States_Control _States_Set ( + States_Control states_to_set, + States_Control current_state +) +{ + return (current_state | states_to_set); +} + +/*PAGE + * + * _States_Clear + * + */ + +STATIC INLINE States_Control _States_Clear ( + States_Control states_to_clear, + States_Control current_state +) +{ + return (current_state & ~states_to_clear); +} + +/*PAGE + * + * _States_Is_ready + * + */ + +STATIC INLINE boolean _States_Is_ready ( + States_Control the_states +) +{ + return (the_states == STATES_READY); +} + +/*PAGE + * + * _States_Is_only_dormant + * + */ + +STATIC INLINE boolean _States_Is_only_dormant ( + States_Control the_states +) +{ + return (the_states == STATES_DORMANT); +} + +/*PAGE + * + * _States_Is_dormant + * + */ + +STATIC INLINE boolean _States_Is_dormant ( + States_Control the_states +) +{ + return (the_states & STATES_DORMANT); +} + +/*PAGE + * + * _States_Is_suspended + * + */ + +STATIC INLINE boolean _States_Is_suspended ( + States_Control the_states +) +{ + return (the_states & STATES_SUSPENDED); +} + +/*PAGE + * + * _States_Is_Transient + * + */ + +STATIC INLINE boolean _States_Is_transient ( + States_Control the_states +) +{ + return (the_states & STATES_TRANSIENT); +} + +/*PAGE + * + * _States_Is_delaying + * + */ + +STATIC INLINE boolean _States_Is_delaying ( + States_Control the_states +) +{ + return (the_states & STATES_DELAYING); +} + +/*PAGE + * + * _States_Is_waiting_for_buffer + * + */ + +STATIC INLINE boolean _States_Is_waiting_for_buffer ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_BUFFER); +} + +/*PAGE + * + * _States_Is_waiting_for_segment + * + */ + +STATIC INLINE boolean _States_Is_waiting_for_segment ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_SEGMENT); +} + +/*PAGE + * + * _States_Is_waiting_for_message + * + */ + +STATIC INLINE boolean _States_Is_waiting_for_message ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_MESSAGE); +} + +/*PAGE + * + * _States_Is_waiting_for_event + * + */ + +STATIC INLINE boolean _States_Is_waiting_for_event ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_EVENT); +} + +/*PAGE + * + * _States_Is_waiting_for_semaphore + * + */ + +STATIC INLINE boolean _States_Is_waiting_for_semaphore ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_SEMAPHORE); +} + +/*PAGE + * + * _States_Is_waiting_for_time + * + */ + +STATIC INLINE boolean _States_Is_waiting_for_time ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_TIME); +} + +/*PAGE + * + * _States_Is_waiting_for_rpc_reply + * + */ + +STATIC INLINE boolean _States_Is_waiting_for_rpc_reply ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_RPC_REPLY); +} + +/*PAGE + * + * _States_Is_waiting_for_period + * + */ + +STATIC INLINE boolean _States_Is_waiting_for_period ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_PERIOD); +} + +/*PAGE + * + * _States_Is_locally_blocked + * + */ + +STATIC INLINE boolean _States_Is_locally_blocked ( + States_Control the_states +) +{ + return (the_states & STATES_LOCALLY_BLOCKED); +} + +/*PAGE + * + * _States_Is_waiting_on_thread_queue + * + */ + +STATIC INLINE boolean _States_Is_waiting_on_thread_queue ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_ON_THREAD_QUEUE); +} + +/*PAGE + * + * _States_Is_blocked + * + */ + +STATIC INLINE boolean _States_Is_blocked ( + States_Control the_states +) +{ + return (the_states & STATES_BLOCKED); +} + +/*PAGEPAGE + * + * + * _States_Are_set + * + */ + +STATIC INLINE boolean _States_Are_set ( + States_Control the_states, + States_Control mask +) +{ + return ( (the_states & mask) != STATES_READY); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/sysstate.inl b/cpukit/score/inline/rtems/score/sysstate.inl new file mode 100644 index 0000000000..14d838cb14 --- /dev/null +++ b/cpukit/score/inline/rtems/score/sysstate.inl @@ -0,0 +1,103 @@ +/* sysstates.inl + * + * This file contains the inline implementation of routines regarding the + * system state. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __SYSTEM_STATE_inl +#define __SYSTEM_STATE_inl + +/*PAGE + * + * _System_state_Set + */ + +STATIC INLINE void _System_state_Set ( + System_state_Codes state +) +{ + _System_state_Current = state; +} + +/*PAGE + * + * _System_state_Get + */ + +STATIC INLINE System_state_Codes _System_state_Get ( void ) +{ + return _System_state_Current; +} + +/*PAGE + * + * _System_state_Is_before_initialization + */ + +STATIC INLINE boolean _System_state_Is_before_initialization ( + System_state_Codes state +) +{ + return (state == SYSTEM_STATE_BEFORE_INITIALIZATION); +} + +/*PAGE + * + * _System_state_Is_before_multitasking + */ + +STATIC INLINE boolean _System_state_Is_before_multitasking ( + System_state_Codes state +) +{ + return (state == SYSTEM_STATE_BEFORE_MULTITASKING); +} + +/*PAGE + * + * _System_state_Is_begin_multitasking + */ + +STATIC INLINE boolean _System_state_Is_begin_multitasking ( + System_state_Codes state +) +{ + return (state == SYSTEM_STATE_BEGIN_MULTITASKING); +} + +/*PAGE + * + * _System_state_Is_up + */ + +STATIC INLINE boolean _System_state_Is_up ( + System_state_Codes state +) +{ + return (state == SYSTEM_STATE_UP); +} + +/*PAGE + * + * _System_state_Is_failed + */ + +STATIC INLINE boolean _System_state_Is_failed ( + System_state_Codes state +) +{ + return (state == SYSTEM_STATE_FAILED); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/thread.inl b/cpukit/score/inline/rtems/score/thread.inl new file mode 100644 index 0000000000..35b8eeccfe --- /dev/null +++ b/cpukit/score/inline/rtems/score/thread.inl @@ -0,0 +1,252 @@ +/* thread.inl + * + * This file contains the macro implementation of the inlined + * routines from the Thread handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __THREAD_inl +#define __THREAD_inl + +/*PAGE + * + * _Thread_Stop_multitasking + * + */ + +STATIC INLINE void _Thread_Stop_multitasking( void ) +{ + _Context_Switch( &_Thread_Executing->Registers, &_Thread_BSP_context ); +} + +/*PAGE + * + * _Thread_Is_executing + * + */ + +STATIC INLINE boolean _Thread_Is_executing ( + Thread_Control *the_thread +) +{ + return ( the_thread == _Thread_Executing ); +} + +/*PAGE + * + * _Thread_Is_heir + * + */ + +STATIC INLINE boolean _Thread_Is_heir ( + Thread_Control *the_thread +) +{ + return ( the_thread == _Thread_Heir ); +} + +/*PAGE + * + * _Thread_Is_executing_also_the_heir + * + */ + +STATIC INLINE boolean _Thread_Is_executing_also_the_heir( void ) +{ + return ( _Thread_Executing == _Thread_Heir ); +} + +/*PAGE + * + * _Thread_Resume + * + */ + +STATIC INLINE void _Thread_Resume ( + Thread_Control *the_thread +) +{ + _Thread_Clear_state( the_thread, STATES_SUSPENDED ); +} + +/*PAGE + * + * _Thread_Unblock + * + */ + +STATIC INLINE void _Thread_Unblock ( + Thread_Control *the_thread +) +{ + _Thread_Clear_state( the_thread, STATES_BLOCKED ); +} + +/*PAGE + * + * _Thread_Restart_self + * + */ + +STATIC INLINE void _Thread_Restart_self( void ) +{ + if ( _Thread_Executing->fp_context != NULL ) + _Context_Restore_fp( &_Thread_Executing->fp_context ); + + _CPU_Context_Restart_self( &_Thread_Executing->Registers ); +} + +/*PAGE + * + * _Thread_Calculate_heir + * + */ + +STATIC INLINE void _Thread_Calculate_heir( void ) +{ + _Thread_Heir = (Thread_Control *) + _Thread_Ready_chain[ _Priority_Get_highest() ].first; +} + +/*PAGE + * + * _Thread_Is_allocated_fp + * + */ + +STATIC INLINE boolean _Thread_Is_allocated_fp ( + Thread_Control *the_thread +) +{ + return ( the_thread == _Thread_Allocated_fp ); +} + +/*PAGE + * + * _Thread_Deallocate_fp + * + */ + +STATIC INLINE void _Thread_Deallocate_fp( void ) +{ + _Thread_Allocated_fp = NULL; +} + +/*PAGE + * + * _Thread_Disable_dispatch + * + */ + +STATIC INLINE void _Thread_Disable_dispatch( void ) +{ + _Thread_Dispatch_disable_level += 1; +} + +/*PAGE + * + * _Thread_Enable_dispatch + * + */ + +#if ( CPU_INLINE_ENABLE_DISPATCH == TRUE ) +STATIC INLINE void _Thread_Enable_dispatch() +{ + if ( (--_Thread_Dispatch_disable_level) == 0 ) + _Thread_Dispatch(); +} +#endif + +#if ( CPU_INLINE_ENABLE_DISPATCH == FALSE ) +void _Thread_Enable_dispatch( void ); +#endif + +/*PAGE + * + * _Thread_Unnest_dispatch + * + */ + +STATIC INLINE void _Thread_Unnest_dispatch( void ) +{ + _Thread_Dispatch_disable_level -= 1; +} + +/*PAGE + * + * _Thread_Is_dispatching_enabled + * + */ + +STATIC INLINE boolean _Thread_Is_dispatching_enabled( void ) +{ + return ( _Thread_Dispatch_disable_level == 0 ); +} + +/*PAGE + * + * _Thread_Is_context_switch_necessary + * + */ + +STATIC INLINE boolean _Thread_Is_context_switch_necessary( void ) +{ + return ( _Context_Switch_necessary ); +} + +/*PAGE + * + * _Thread_Dispatch_initialization + * + */ + +STATIC INLINE void _Thread_Dispatch_initialization( void ) +{ + _Thread_Dispatch_disable_level = 1; +} + +/*PAGE + * + * _Thread_Is_null + * + */ + +STATIC INLINE boolean _Thread_Is_null ( + Thread_Control *the_thread +) +{ + return ( the_thread == NULL ); +} + +/*PAGE + * + * _Thread_Get + * + */ + +STATIC INLINE Thread_Control *_Thread_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ) { + _Thread_Disable_dispatch(); + *location = OBJECTS_LOCAL; + return( _Thread_Executing ); + } + + return (Thread_Control *) + _Objects_Get( &_Thread_Information, id, location ); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/threadmp.inl b/cpukit/score/inline/rtems/score/threadmp.inl new file mode 100644 index 0000000000..f4beba59ed --- /dev/null +++ b/cpukit/score/inline/rtems/score/threadmp.inl @@ -0,0 +1,53 @@ +/* inline/threadmp.inl + * + * This include file contains the bodies of all inlined routines + * for the multiprocessing part of thread package. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INLINE_MP_THREAD_inl +#define __INLINE_MP_THREAD_inl + +/*PAGE + * + * _Thread_MP_Is_receive + * + */ + +STATIC INLINE boolean _Thread_MP_Is_receive ( + Thread_Control *the_thread +) +{ + return the_thread == _Thread_MP_Receive; +} + +/*PAGE + * + * _Thread_MP_Free_proxy + * + */ + +STATIC INLINE void _Thread_MP_Free_proxy ( + Thread_Control *the_thread +) +{ + Thread_Proxy_control *the_proxy; + + the_proxy = (Thread_Proxy_control *) the_thread; + + _Chain_Extract( &the_proxy->Active ); + + _Chain_Append( &_Thread_MP_Inactive_proxies, &the_thread->Object.Node ); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/tod.inl b/cpukit/score/inline/rtems/score/tod.inl new file mode 100644 index 0000000000..dadcdabcda --- /dev/null +++ b/cpukit/score/inline/rtems/score/tod.inl @@ -0,0 +1,72 @@ +/* tod.inl + * + * This file contains the static inline implementation of the inlined routines + * from the Time of Day Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __TIME_OF_DAY_inl +#define __TIME_OF_DAY_inl + +/*PAGE + * + * _TOD_Is_set + * + */ + +STATIC INLINE boolean _TOD_Is_set( void ) +{ + return _Watchdog_Is_active( &_TOD_Seconds_watchdog ); +} + +/*PAGE + * + * _TOD_Tickle_ticks + * + */ + +STATIC INLINE void _TOD_Tickle_ticks( void ) +{ + _TOD_Current.ticks += 1; + _TOD_Ticks_since_boot += 1; +} + +/*PAGE + * + * _TOD_Deactivate + * + */ + +STATIC INLINE void _TOD_Deactivate( void ) +{ + _Watchdog_Remove( &_TOD_Seconds_watchdog ); +} + +/*PAGE + * + * _TOD_Activate + * + */ + +STATIC INLINE void _TOD_Activate( + rtems_interval ticks +) +{ + _Watchdog_Insert_ticks( + &_TOD_Seconds_watchdog, + ticks, + WATCHDOG_ACTIVATE_NOW + ); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/tqdata.inl b/cpukit/score/inline/rtems/score/tqdata.inl new file mode 100644 index 0000000000..7ec1e9e186 --- /dev/null +++ b/cpukit/score/inline/rtems/score/tqdata.inl @@ -0,0 +1,47 @@ +/* tqdata.inl + * + * This file contains the static inline implementation of the inlined + * routines needed to support the Thread Queue Data. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __THREAD_QUEUE_DATA_inl +#define __THREAD_QUEUE_DATA_inl + +/*PAGE + * + * _Thread_queue_Header_number + * + */ + +STATIC INLINE unsigned32 _Thread_queue_Header_number ( + rtems_task_priority the_priority +) +{ + return ( the_priority >> 6 ); +} + +/*PAGE + * + * _Thread_queue_Is_reverse_search + * + */ + +STATIC INLINE boolean _Thread_queue_Is_reverse_search ( + rtems_task_priority the_priority +) +{ + return ( the_priority & 0x20 ); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/userext.inl b/cpukit/score/inline/rtems/score/userext.inl new file mode 100644 index 0000000000..1558da968a --- /dev/null +++ b/cpukit/score/inline/rtems/score/userext.inl @@ -0,0 +1,268 @@ +/* userext.inl + * + * This file contains the macro implementation of the inlined routines + * from the User Extension Handler + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __USER_EXTENSIONS_inl +#define __USER_EXTENSIONS_inl + +/*PAGE + * + * _User_extensions_Handler_initialization + * + */ + +STATIC INLINE void _User_extensions_Handler_initialization ( + rtems_extensions_table *initial_extensions +) +{ + _Chain_Initialize_empty( &_User_extensions_List ); + + if ( initial_extensions ) { + _User_extensions_Initial.Callouts = *initial_extensions; + _Chain_Append( &_User_extensions_List, &_User_extensions_Initial.Node ); + } +} + +/*PAGE + * + * _User_extensions_Add_set + */ + +STATIC INLINE void _User_extensions_Add_set ( + User_extensions_Control *the_extension, + rtems_extensions_table *extension_table +) +{ + the_extension->Callouts = *extension_table; + + _Chain_Append( &_User_extensions_List, &the_extension->Node ); +} + +/*PAGE + * + * _User_extensions_Remove_set + */ + +STATIC INLINE void _User_extensions_Remove_set ( + User_extensions_Control *the_extension +) +{ + _Chain_Extract( &the_extension->Node ); +} + +/*PAGE + * + * _User_extensions_Task_create + * + */ + +STATIC INLINE void _User_extensions_Task_create ( + Thread_Control *the_thread +) +{ + Chain_Node *the_node; + User_extensions_Control *the_extension; + + for ( the_node = _User_extensions_List.first ; + !_Chain_Is_tail( &_User_extensions_List, the_node ) ; + the_node = the_node->next ) { + + the_extension = (User_extensions_Control *) the_node; + + if ( the_extension->Callouts.rtems_task_create != NULL ) + (*the_extension->Callouts.rtems_task_create)( + _Thread_Executing, + the_thread + ); + } +} + +/*PAGE + * + * _User_extensions_Task_delete + */ + +STATIC INLINE void _User_extensions_Task_delete ( + Thread_Control *the_thread +) +{ + Chain_Node *the_node; + User_extensions_Control *the_extension; + + for ( the_node = _User_extensions_List.last ; + !_Chain_Is_head( &_User_extensions_List, the_node ) ; + the_node = the_node->previous ) { + + the_extension = (User_extensions_Control *) the_node; + + if ( the_extension->Callouts.rtems_task_delete != NULL ) + (*the_extension->Callouts.rtems_task_delete)( + _Thread_Executing, + the_thread + ); + } +} + +/*PAGE + * + * _User_extensions_Task_start + * + */ + +STATIC INLINE void _User_extensions_Task_start ( + Thread_Control *the_thread +) +{ + Chain_Node *the_node; + User_extensions_Control *the_extension; + + for ( the_node = _User_extensions_List.first ; + !_Chain_Is_tail( &_User_extensions_List, the_node ) ; + the_node = the_node->next ) { + + the_extension = (User_extensions_Control *) the_node; + + if ( the_extension->Callouts.rtems_task_start != NULL ) + (*the_extension->Callouts.rtems_task_start)( + _Thread_Executing, + the_thread + ); + } +} + +/*PAGE + * + * _User_extensions_Task_restart + * + */ + +STATIC INLINE void _User_extensions_Task_restart ( + Thread_Control *the_thread +) +{ + Chain_Node *the_node; + User_extensions_Control *the_extension; + + for ( the_node = _User_extensions_List.first ; + !_Chain_Is_tail( &_User_extensions_List, the_node ) ; + the_node = the_node->next ) { + + the_extension = (User_extensions_Control *) the_node; + + if ( the_extension->Callouts.rtems_task_restart != NULL ) + (*the_extension->Callouts.rtems_task_restart)( + _Thread_Executing, + the_thread + ); + } +} + +/*PAGE + * + * _User_extensions_Task_switch + * + */ + +STATIC INLINE void _User_extensions_Task_switch ( + Thread_Control *executing, + Thread_Control *heir +) +{ + Chain_Node *the_node; + User_extensions_Control *the_extension; + + for ( the_node = _User_extensions_List.first ; + !_Chain_Is_tail( &_User_extensions_List, the_node ) ; + the_node = the_node->next ) { + + the_extension = (User_extensions_Control *) the_node; + + if ( the_extension->Callouts.task_switch != NULL ) + (*the_extension->Callouts.task_switch)( executing, heir ); + } +} + +/*PAGE + * + * _User_extensions_Task_begin + * + */ + +STATIC INLINE void _User_extensions_Task_begin ( + Thread_Control *executing +) +{ + Chain_Node *the_node; + User_extensions_Control *the_extension; + + for ( the_node = _User_extensions_List.first ; + !_Chain_Is_tail( &_User_extensions_List, the_node ) ; + the_node = the_node->next ) { + + the_extension = (User_extensions_Control *) the_node; + + if ( the_extension->Callouts.task_begin != NULL ) + (*the_extension->Callouts.task_begin)( executing ); + } +} + +/*PAGE + * + * _User_extensions_Task_exitted + */ + +STATIC INLINE void _User_extensions_Task_exitted ( + Thread_Control *executing +) +{ + Chain_Node *the_node; + User_extensions_Control *the_extension; + + for ( the_node = _User_extensions_List.last ; + !_Chain_Is_head( &_User_extensions_List, the_node ) ; + the_node = the_node->previous ) { + + the_extension = (User_extensions_Control *) the_node; + + if ( the_extension->Callouts.task_exitted != NULL ) + (*the_extension->Callouts.task_exitted)( executing ); + } +} + +/*PAGE + * + * _User_extensions_Fatal + */ + +STATIC INLINE void _User_extensions_Fatal ( + unsigned32 the_error +) +{ + Chain_Node *the_node; + User_extensions_Control *the_extension; + + for ( the_node = _User_extensions_List.last ; + !_Chain_Is_head( &_User_extensions_List, the_node ) ; + the_node = the_node->previous ) { + + the_extension = (User_extensions_Control *) the_node; + + if ( the_extension->Callouts.fatal != NULL ) + (*the_extension->Callouts.fatal)( the_error ); + } +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/watchdog.inl b/cpukit/score/inline/rtems/score/watchdog.inl new file mode 100644 index 0000000000..d5d12cbeef --- /dev/null +++ b/cpukit/score/inline/rtems/score/watchdog.inl @@ -0,0 +1,296 @@ +/* watchdog.inl + * + * This file contains the static inline implementation of all inlined + * routines in the Watchdog Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __WATCHDOG_inl +#define __WATCHDOG_inl + +/*PAGE + * + * _Watchdog_Initialize + * + */ + +STATIC INLINE void _Watchdog_Initialize( + Watchdog_Control *the_watchdog, + rtems_timer_service_routine_entry routine, + Objects_Id id, + void *user_data +) +{ + the_watchdog->state = WATCHDOG_INACTIVE; + the_watchdog->routine = routine; + the_watchdog->id = id; + the_watchdog->user_data = user_data; +} + +/*PAGE + * + * _Watchdog_Is_active + * + */ + +STATIC INLINE boolean _Watchdog_Is_active( + Watchdog_Control *the_watchdog +) +{ + + return ( the_watchdog->state == WATCHDOG_ACTIVE ); + +} + +/*PAGE + * + * _Watchdog_Activate + * + */ + +STATIC INLINE void _Watchdog_Activate( + Watchdog_Control *the_watchdog +) +{ + + the_watchdog->state = WATCHDOG_ACTIVE; + +} + +/*PAGE + * + * _Watchdog_Deactivate + * + */ + +STATIC INLINE void _Watchdog_Deactivate( + Watchdog_Control *the_watchdog +) +{ + + the_watchdog->state = WATCHDOG_REMOVE_IT; + +} + +/*PAGE + * + * _Watchdog_Tickle_ticks + * + */ + +STATIC INLINE void _Watchdog_Tickle_ticks( void ) +{ + + _Watchdog_Tickle( &_Watchdog_Ticks_chain ); + +} + +/*PAGE + * + * _Watchdog_Tickle_seconds + * + */ + +STATIC INLINE void _Watchdog_Tickle_seconds( void ) +{ + + _Watchdog_Tickle( &_Watchdog_Seconds_chain ); + +} + +/*PAGE + * + * _Watchdog_Insert_ticks + * + */ + +STATIC INLINE void _Watchdog_Insert_ticks( + Watchdog_Control *the_watchdog, + rtems_interval units, + Watchdog_Insert_modes insert_mode +) +{ + + the_watchdog->initial = units; + + _Watchdog_Insert( &_Watchdog_Ticks_chain, the_watchdog, insert_mode ); + +} + +/*PAGE + * + * _Watchdog_Insert_seconds + * + */ + +STATIC INLINE void _Watchdog_Insert_seconds( + Watchdog_Control *the_watchdog, + rtems_interval units, + Watchdog_Insert_modes insert_mode +) +{ + + the_watchdog->initial = units; + + _Watchdog_Insert( &_Watchdog_Seconds_chain, the_watchdog, insert_mode ); + +} + +/*PAGE + * + * _Watchdog_Adjust_seconds + * + */ + +STATIC INLINE void _Watchdog_Adjust_seconds( + Watchdog_Adjust_directions direction, + rtems_interval units +) +{ + + _Watchdog_Adjust( &_Watchdog_Seconds_chain, direction, units ); + +} + +/*PAGE + * + * _Watchdog_Adjust_ticks + * + */ + +STATIC INLINE void _Watchdog_Adjust_ticks( + Watchdog_Adjust_directions direction, + rtems_interval units +) +{ + + _Watchdog_Adjust( &_Watchdog_Ticks_chain, direction, units ); + +} + +/*PAGE + * + * _Watchdog_Reset + * + */ + +STATIC INLINE void _Watchdog_Reset( + Watchdog_Control *the_watchdog +) +{ + + (void) _Watchdog_Remove( the_watchdog ); + + _Watchdog_Insert( + &_Watchdog_Ticks_chain, + the_watchdog, + WATCHDOG_ACTIVATE_NOW + ); + +} + +/*PAGE + * + * _Watchdog_Next + * + */ + +STATIC INLINE Watchdog_Control *_Watchdog_Next( + Watchdog_Control *the_watchdog +) +{ + + return ( (Watchdog_Control *) the_watchdog->Node.next ); + +} + +/*PAGE + * + * _Watchdog_Previous + * + */ + +STATIC INLINE Watchdog_Control *_Watchdog_Previous( + Watchdog_Control *the_watchdog +) +{ + + return ( (Watchdog_Control *) the_watchdog->Node.previous ); + +} + +/*PAGE + * + * _Watchdog_First + * + */ + +STATIC INLINE Watchdog_Control *_Watchdog_First( + Chain_Control *header +) +{ + + return ( (Watchdog_Control *) header->first ); + +} + +/*PAGE + * + * _Watchdog_Last + * + */ +STATIC INLINE Watchdog_Control *_Watchdog_Last( + Chain_Control *header +) +{ + + return ( (Watchdog_Control *) header->last ); + +} + +/*PAGE + * + * _Watchdog_Get_sync + * + */ + +STATIC INLINE Watchdog_Control *_Watchdog_Get_sync( void ) +{ + return (Watchdog_Control *) _Watchdog_Sync; +} + +/*PAGE + * + * _Watchdog_Set_sync + * + */ + +STATIC INLINE void _Watchdog_Set_sync( + Watchdog_Control *the_watchdog +) +{ + _Watchdog_Sync = (Watchdog_Synchronization_pointer) the_watchdog; +} + +/*PAGE + * + * _Watchdog_Clear_sync + * + */ + +STATIC INLINE void _Watchdog_Clear_sync( void ) +{ + _Watchdog_Sync = NULL; +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/wkspace.inl b/cpukit/score/inline/rtems/score/wkspace.inl new file mode 100644 index 0000000000..fee7623a6c --- /dev/null +++ b/cpukit/score/inline/rtems/score/wkspace.inl @@ -0,0 +1,104 @@ +/* wkspace.inl + * + * This include file contains the bodies of the routines which contains + * information related to the RTEMS RAM Workspace. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __WORKSPACE_inl +#define __WORKSPACE_inl + +/*PAGE + * + * _Workspace_Handler_initialization + * + */ + +STATIC INLINE void _Workspace_Handler_initialization( + void *starting_address, + unsigned32 size +) +{ + unsigned32 *zero_out_array; + unsigned32 index; + unsigned32 memory_available; + + if ( (starting_address == NULL) || + !_Addresses_Is_aligned( starting_address ) ) + rtems_fatal_error_occurred( RTEMS_INVALID_ADDRESS ); + + if ( _CPU_Table.do_zero_of_workspace ) { + for( zero_out_array = (unsigned32 *) starting_address, index = 0 ; + index < size / 4 ; + index++ ) + zero_out_array[ index ] = 0; + } + + memory_available = _Heap_Initialize( + &_Workspace_Area, + starting_address, + size, + CPU_HEAP_ALIGNMENT + ); + + if ( memory_available == 0 ) + rtems_fatal_error_occurred( RTEMS_UNSATISFIED ); +} + +/*PAGE + * + * _Workspace_Allocate + * + */ + +STATIC INLINE void *_Workspace_Allocate( + unsigned32 size +) +{ + return _Heap_Allocate( &_Workspace_Area, size ); +} + +/*PAGE + * + * _Workspace_Allocate_or_fatal_error + * + */ + +STATIC INLINE void *_Workspace_Allocate_or_fatal_error( + unsigned32 size +) +{ + void *memory; + + memory = _Workspace_Allocate( size ); + + if ( memory == NULL ) + rtems_fatal_error_occurred( RTEMS_UNSATISFIED ); + + return memory; +} + +/*PAGE + * + * _Workspace_Free + * + */ + +STATIC INLINE boolean _Workspace_Free( + void *block +) +{ + return _Heap_Free( &_Workspace_Area, block ); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/README b/cpukit/score/macros/README new file mode 100644 index 0000000000..b2f0c4d481 --- /dev/null +++ b/cpukit/score/macros/README @@ -0,0 +1,18 @@ +# +# $Id$ +# + +The files in this directory are not considered the "primary" source +of inlined routines for RTEMS. The "inline" directory contains +the implementations of the inlined basis which are regularly +tested. In general, an effort is made to keep the contents of +this directory up to date but testing is only performed irregularly +and even then it is usually with a single target processor and BSP. + +The primary purpose of the code in this directory is to insure +that RTEMS can be compiled using a C compiler which does not support +static inline routines. + +These were last successfully tested on 2/1/95 on a prerelease version +of 3.2.0. The testing was done only on the Force CPU386 i386 target board. +No testing was done on version of the code in the final release. diff --git a/cpukit/score/macros/rtems/score/README b/cpukit/score/macros/rtems/score/README new file mode 100644 index 0000000000..b2f0c4d481 --- /dev/null +++ b/cpukit/score/macros/rtems/score/README @@ -0,0 +1,18 @@ +# +# $Id$ +# + +The files in this directory are not considered the "primary" source +of inlined routines for RTEMS. The "inline" directory contains +the implementations of the inlined basis which are regularly +tested. In general, an effort is made to keep the contents of +this directory up to date but testing is only performed irregularly +and even then it is usually with a single target processor and BSP. + +The primary purpose of the code in this directory is to insure +that RTEMS can be compiled using a C compiler which does not support +static inline routines. + +These were last successfully tested on 2/1/95 on a prerelease version +of 3.2.0. The testing was done only on the Force CPU386 i386 target board. +No testing was done on version of the code in the final release. diff --git a/cpukit/score/macros/rtems/score/address.inl b/cpukit/score/macros/rtems/score/address.inl new file mode 100644 index 0000000000..f2672f2500 --- /dev/null +++ b/cpukit/score/macros/rtems/score/address.inl @@ -0,0 +1,79 @@ +/* macros/address.h + * + * This include file contains the bodies of the routines + * about addresses which are inlined. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MACROS_ADDRESSES_h +#define __MACROS_ADDRESSES_h + +/*PAGE + * + * _Addresses_Add_offset + * + */ + +#define _Addresses_Add_offset( _base, _offset ) \ + ((void *)(_base) + (_offset)) + +/*PAGE + * + * _Addresses_Subtract_offset + * + */ + +#define _Addresses_Subtract_offset( _base, _offset ) \ + ((void *)(_base) - (_offset)) + +/*PAGE + * + * _Addresses_Add + * + * NOTE: The cast of an address to an unsigned32 makes this code + * dependent on an addresses being thirty two bits. + */ + +#define _Addresses_Add( _left, _right ) \ + ((void *)(_left) + (unsigned32)(_right)) + +/*PAGE + * + * _Addresses_Subtract + * + * NOTE: The cast of an address to an unsigned32 makes this code + * dependent on an addresses being thirty two bits. + */ + +#define _Addresses_Subtract( _left, _right ) \ + ((void *)(_left) - (void *)(_right)) + +/*PAGE + * + * _Addresses_Is_aligned + * + */ + +#define _Addresses_Is_aligned( _address ) \ + ( ( (unsigned32)(_address) % 4 ) == 0 ) + +/*PAGE + * + * _Addresses_Is_in_range + * + */ + +#define _Addresses_Is_in_range( _address, _base, _limit ) \ + ( (_address) >= (_base) && (_address) <= (_limit) ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/chain.inl b/cpukit/score/macros/rtems/score/chain.inl new file mode 100644 index 0000000000..a53b3fc270 --- /dev/null +++ b/cpukit/score/macros/rtems/score/chain.inl @@ -0,0 +1,200 @@ +/* macros/chain.h + * + * This include file contains the bodies of the routines which are + * associated with doubly linked chains and inlined. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MACROS_CHAIN_h +#define __MACROS_CHAIN_h + +/*PAGE + * + * _Chain_Are_nodes_equal + */ + +#define _Chain_Are_nodes_equal( _left, _right ) \ + ( (_left) == (_right) ) + +/*PAGE + * + * _Chain_Is_null + */ + +#define _Chain_Is_null( _the_chain ) \ + ( (_the_chain) == NULL ) + +/*PAGE + * + * _Chain_Is_null_node + */ + +#define _Chain_Is_null_node( _the_node ) \ + ( (_the_node) == NULL ) + +/*PAGE + * + * _Chain_Head + */ + +#define _Chain_Head( _the_chain ) \ + ((Chain_Node *) (_the_chain)) + +/*PAGE + * + * _Chain_Tail + */ + +#define _Chain_Tail( _the_chain ) \ + ((Chain_Node *) &(_the_chain)->permanent_null) + +/*PAGE + * + * _Chain_Is_empty + */ + +#define _Chain_Is_empty( _the_chain ) \ + ( (_the_chain)->first == _Chain_Tail( (_the_chain) ) ) + +/*PAGE + * + * _Chain_Is_first + */ + +#define _Chain_Is_first( _the_node ) \ + ( (the_node)->previous == NULL ) + +/*PAGE + * + * _Chain_Is_last + */ + +#define _Chain_Is_last( _the_node ) \ + ( (_the_node)->next == NULL ) + +/*PAGE + * + * _Chain_Has_only_one_node + */ + +#define _Chain_Has_only_one_node( _the_chain ) \ + ( (_the_chain)->first == (_the_chain)->last ) + +/*PAGE + * + * _Chain_Is_head + */ + +#define _Chain_Is_head( _the_chain, _the_node ) \ + ( (_the_node) == _Chain_Head( (_the_chain) ) ) + +/*PAGE + * + * _Chain_Is_tail + */ + +#define _Chain_Is_tail( _the_chain, _the_node ) \ + ( (_the_node) == _Chain_Tail( (_the_chain) ) ) + +/*PAGE + * + * Chain_Initialize_empty + */ + +#define _Chain_Initialize_empty( _the_chain ) \ +{ \ + (_the_chain)->first = _Chain_Tail( (_the_chain) ); \ + (_the_chain)->permanent_null = NULL; \ + (_the_chain)->last = _Chain_Head( (_the_chain) ); \ +} + +/*PAGE + * + * _Chain_Extract_unprotected + */ + +#define _Chain_Extract_unprotected( _the_node ) \ +{ \ + Chain_Node *_next; \ + Chain_Node *_previous; \ + \ + _next = (_the_node)->next; \ + _previous = (_the_node)->previous; \ + _next->previous = _previous; \ + _previous->next = _next; \ +} + +/*PAGE + * + * _Chain_Get_unprotected + */ + +/*PAGE + * + * Chain_Get_unprotected + */ + +#define _Chain_Get_unprotected( _the_chain ) \ + (( !_Chain_Is_empty( (_the_chain) ) ) \ + ? _Chain_Get_unprotected( (_the_chain) ) \ + : NULL) + +/*PAGE + * + * _Chain_Insert_unprotected + */ + +#define _Chain_Insert_unprotected( _after_node, _the_node ) \ +{ \ + Chain_Node *_before_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); \ +} + +/*PAGE + * + * _Chain_Append_unprotected + */ + +#define _Chain_Append_unprotected( _the_chain, _the_node ) \ +{ \ + Chain_Node *_old_last_node; \ + \ + (_the_node)->next = _Chain_Tail( (_the_chain) ); \ + _old_last_node = (_the_chain)->last; \ + (_the_chain)->last = (_the_node); \ + _old_last_node->next = (_the_node); \ + (_the_node)->previous = _old_last_node; \ +} + +/*PAGE + * + * _Chain_Prepend_unprotected + */ + +#define _Chain_Prepend_unprotected( _the_chain, _the_node ) \ + _Chain_Insert_unprotected( _Chain_Head( (_the_chain) ), (_the_node) ) + +/*PAGE + * + * _Chain_Prepend + */ + +#define _Chain_Prepend( _the_chain, _the_node ) \ + _Chain_Insert( _Chain_Head( (_the_chain) ), (_the_node) ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/heap.inl b/cpukit/score/macros/rtems/score/heap.inl new file mode 100644 index 0000000000..6f06478207 --- /dev/null +++ b/cpukit/score/macros/rtems/score/heap.inl @@ -0,0 +1,136 @@ +/* heap.inl + * + * This file contains the macro implementation of the inlined + * routines from the heap handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __HEAP_inl +#define __HEAP_inl + +#include + +/*PAGE + * + * _Heap_Head + */ + +#define _Heap_Head( _the_heap ) \ + ((Heap_Block *)&(_the_heap)->start) + +/*PAGE + * + * _Heap_Tail + */ + +#define _Heap_Tail( _the_heap ) \ + ((Heap_Block *)&(_the_heap)->final) + +/*PAGE + * + * _Heap_Previous_block + */ + +#define _Heap_Previous_block( _the_block ) \ + ( (Heap_Block *) _Addresses_Subtract_offset( \ + (void *)(_the_block), \ + (_the_block)->back_flag & ~ HEAP_BLOCK_USED \ + ) + +/*PAGE + * + * _Heap_Next_block + */ + +#define _Heap_Next_block( _the_block ) \ + ( (Heap_Block *) _Addresses_Add_offset( \ + (void *)(_the_block), \ + (_the_block)->front_flag & ~ HEAP_BLOCK_USED \ + ) + +/*PAGE + * + * _Heap_Block_at + */ + +#define _Heap_Block_at( _base, _offset ) \ + ( (Heap_Block *) \ + _Addresses_Add_offset( (void *)(_base), (_offset) ) ) + +/*PAGE + * + * _Heap_Is_previous_block_free + */ + +#define _Heap_Is_previous_block_free( _the_block ) \ + ( !((_the_block)->back_flag & HEAP_BLOCK_USED) ) + +/*PAGE + * + * _Heap_Is_block_free + */ + +#define _Heap_Is_block_free( _the_block ) \ + ( !((_the_block)->front_flag & HEAP_BLOCK_USED) ) + +/*PAGE + * + * _Heap_Is_block_used + */ + +#define _Heap_Is_block_used( _the_block ) \ + ((_the_block)->front_flag & HEAP_BLOCK_USED) + +/*PAGE + * + * _Heap_Block_size + */ + +#define _Heap_Block_size( _the_block ) \ + ((_the_block)->front_flag & ~HEAP_BLOCK_USED) + +/*PAGE + * + * _Heap_Start_of_user_area + */ + +#define _Heap_Start_of_user_area( _the_block ) \ + ((void *) &(_the_block)->next) + +/*PAGE + * + * _Heap_Is_block_in + */ + +#define _Heap_Is_block_in( _the_heap, _the_block ) \ + ( ((_the_block) >= (_the_heap)->start) && \ + ((_the_block) <= (_the_heap)->final) ) + +/*PAGE + * + * _Heap_Is_page_size_valid + */ + +#define _Heap_Is_page_size_valid( _page_size ) \ + ( ((_page_size) != 0) && \ + (((_page_size) % CPU_HEAP_ALIGNMENT) == 0) ) + +/*PAGE + * + * _Heap_Build_flag + */ + +#define _Heap_Build_flag( _size, _in_use_flag ) \ + ( (_size) | (_in_use_flag)) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/isr.inl b/cpukit/score/macros/rtems/score/isr.inl new file mode 100644 index 0000000000..93f234c7ff --- /dev/null +++ b/cpukit/score/macros/rtems/score/isr.inl @@ -0,0 +1,60 @@ +/* isr.inl + * + * This include file contains the macro implementation of all + * inlined routines in the Interrupt Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __ISR_inl +#define __ISR_inl + +/*PAGE + * + * _ISR_Handler_initialization + * + */ + +#define _ISR_Handler_initialization() \ + { \ + _ISR_Signals_to_thread_executing = FALSE; \ + _ISR_Nest_level = 0; \ + } + +/*PAGE + * + * _ISR_Is_in_progress + * + */ + +#define _ISR_Is_in_progress() \ + (_ISR_Nest_level != 0) + +/*PAGE + * + * _ISR_Is_vector_number_valid + * + */ + +#define _ISR_Is_vector_number_valid( _vector ) \ + ( (_vector) < CPU_INTERRUPT_NUMBER_OF_VECTORS ) + +/*PAGE + * + * _ISR_Is_valid_user_handler + * + */ + +#define _ISR_Is_valid_user_handler( _handler ) \ + ((_handler) != NULL) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/mppkt.inl b/cpukit/score/macros/rtems/score/mppkt.inl new file mode 100644 index 0000000000..ff1d51034b --- /dev/null +++ b/cpukit/score/macros/rtems/score/mppkt.inl @@ -0,0 +1,41 @@ +/* macros/mppkt.h + * + * This package is the implementation of the Packet Handler + * routines which are inlined. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MACROS_MP_PACKET_h +#define __MACROS_MP_PACKET_h + +/*PAGE + * + * _Mp_packet_Is_valid_packet_class + * + * NOTE: Check for lower bounds (MP_PACKET_CLASSES_FIRST ) is unnecessary + * because this enum starts at lower bound of zero. + */ + +#define _Mp_packet_Is_valid_packet_class( _the_packet_class ) \ + ( (_the_packet_class) <= MP_PACKET_CLASSES_LAST ) + +/*PAGE + * + * _Mp_packet_Is_null + * + */ + +#define _Mp_packet_Is_null ( _the_packet ) \ + ( (_the_packet) == NULL ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/object.inl b/cpukit/score/macros/rtems/score/object.inl new file mode 100644 index 0000000000..f4fdc39d6e --- /dev/null +++ b/cpukit/score/macros/rtems/score/object.inl @@ -0,0 +1,146 @@ +/* object.inl + * + * This include file contains the macro implementation of all + * of the inlined routines in the Object Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __OBJECTS_inl +#define __OBJECTS_inl + +/*PAGE + * + * _Objects_Is_name_valid + * + */ + +#define _Objects_Is_name_valid( _name ) \ + ( (_name) != 0 ) + +/* + * rtems_name_to_characters + * + */ + +#define rtems_name_to_characters( _name, _c1, _c2, _c3, _c4 ) \ + { \ + (*(_c1) = ((_name) >> 24) & 0xff; \ + (*(_c2) = ((_name) >> 16) & 0xff; \ + (*(_c3) = ((_name) >> 8) & 0xff; \ + (*(_c4) = ((_name)) & 0xff; \ + } +); + +/*PAGE + * + * _Objects_Build_id + * + */ + +#define _Objects_Build_id( _node, _index ) \ + ( ((_node) << 16) | (_index) ) + +/*PAGE + * + * rtems_get_node + * + */ + +#define rtems_get_node( _id ) \ + ((_id) >> 16) + +/*PAGE + * + * rtems_get_index + * + */ + +#define rtems_get_index( _id ) \ + ((_id) & 0xFFFF) + +/*PAGE + * + * _Objects_Is_local_node + * + */ + +#define _Objects_Is_local_node( _node ) \ + ( (_node) == _Objects_Local_node ) + +/*PAGE + * + * _Objects_Is_local_id + * + */ + +#define _Objects_Is_local_id( _id ) \ + _Objects_Is_local_node( rtems_get_node(_id) ) + +/*PAGE + * + * _Objects_Are_ids_equal + * + */ + +#define _Objects_Are_ids_equal( _left, _right ) \ + ( (_left) == (_right) ) + +/*PAGE + * + * _Objects_Allocate + * + */ + +#define _Objects_Allocate( _information ) \ + (Objects_Control *) _Chain_Get( &(_information)->Inactive ) + +/*PAGE + * + * _Objects_Free + * + */ + +#define _Objects_Free( _information, _the_object ) \ + _Chain_Append( &(_information)->Inactive, &(_the_object)->Node ) + +/*PAGE + * + * _Objects_Open + * + */ + +#define _Objects_Open( _information, _the_object, _name ) \ + { \ + unsigned32 _index; \ + \ + _index = rtems_get_index( (_the_object)->id ); \ + (_information)->local_table[ _index ] = (_the_object); \ + (_information)->name_table[ _index ] = (_name); \ + } + +/*PAGE + * + * _Objects_Close + * + */ + +#define _Objects_Close( _information, _the_object ) \ + { \ + unsigned32 _index; \ + \ + _index = rtems_get_index( (_the_object)->id ); \ + (_information)->local_table[ _index ] = NULL; \ + (_information)->name_table[ _index ] = 0; \ + } + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/objectmp.inl b/cpukit/score/macros/rtems/score/objectmp.inl new file mode 100644 index 0000000000..2f1c5ac7fa --- /dev/null +++ b/cpukit/score/macros/rtems/score/objectmp.inl @@ -0,0 +1,50 @@ +/* macros/objectmp.inl + * + * This include file contains the bodies of all inlined routines + * which deal with global objects. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MACROS_MP_OBJECTS_inl +#define __MACROS_MP_OBJECTS_inl + +/*PAGE + * + * _Objects_MP_Allocate_global_object + * + */ + +#define _Objects_MP_Allocate_global_object() \ + (Objects_MP_Control *) \ + _Chain_Get( &_Objects_MP_Inactive_global_objects ) + +/*PAGE + * _Objects_MP_Free_global_object + * + */ + +#define _Objects_MP_Free_global_object( _the_object ) \ + _Chain_Append( \ + &_Objects_MP_Inactive_global_objects, \ + &(_the_object)->Object.Node \ + ) + +/*PAGE + * _Objects_MP_Is_null_global_object + * + */ + +#define _Objects_MP_Is_null_global_object( _the_object ) \ + ( (_the_object) == NULL ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/priority.inl b/cpukit/score/macros/rtems/score/priority.inl new file mode 100644 index 0000000000..7ad1fd909a --- /dev/null +++ b/cpukit/score/macros/rtems/score/priority.inl @@ -0,0 +1,144 @@ +/* priority.inl + * + * This file contains the macro implementation of all inlined routines + * in the Priority Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __PRIORITY_inl +#define __PRIORITY_inl + +#include + +/*PAGE + * + * _Priority_Handler_initialization + * + */ + +#define _Priority_Handler_initialization() \ + { \ + unsigned32 index; \ + \ + _Priority_Major_bit_map = 0; \ + for ( index=0 ; index <16 ; index++ ) \ + _Priority_Bit_map[ index ] = 0; \ + } + +/*PAGE + * + * _Priority_Is_valid + * + */ + +#define _Priority_Is_valid( _the_priority ) \ + ( ( (_the_priority) >= RTEMS_MINIMUM_PRIORITY ) && \ + ( (_the_priority) <= RTEMS_MAXIMUM_PRIORITY ) ) + +/*PAGE + * + * _Priority_Major + * + */ + +#define _Priority_Major( _the_priority ) ( (_the_priority) / 16 ) + +/*PAGE + * + * _Priority_Minor + * + */ + +#define _Priority_Minor( _the_priority ) ( (_the_priority) % 16 ) + +/*PAGE + * + * _Priority_Add_to_bit_map + * + */ + +#define _Priority_Add_to_bit_map( _the_priority_map ) \ + { \ + *(_the_priority_map)->minor |= (_the_priority_map)->ready_minor; \ + _Priority_Major_bit_map |= (_the_priority_map)->ready_major; \ + } + +/*PAGE + * + * _Priority_Remove_from_bit_map + * + */ + +#define _Priority_Remove_from_bit_map( _the_priority_map ) \ + { \ + *(_the_priority_map)->minor &= (_the_priority_map)->block_minor; \ + if ( *(_the_priority_map)->minor == 0 ) \ + _Priority_Major_bit_map &= (_the_priority_map)->block_major; \ + } + +/*PAGE + * + * _Priority_Get_highest + * + */ + +#define _Priority_Get_highest( _high_priority ) \ + { \ + Priority_Bit_map_control minor; \ + Priority_Bit_map_control major; \ + \ + _Bitfield_Find_first_bit( _Priority_Major_bit_map, major ); \ + _Bitfield_Find_first_bit( _Priority_Bit_map[major], minor ); \ + \ + (_high_priority) = (_CPU_Priority_Bits_index( major ) * 16) + \ + _CPU_Priority_Bits_index( minor ); \ + } + +/*PAGE + * + * _Priority_Initialize_information + * + */ + +#define _Priority_Initialize_information( \ + _the_priority_map, _new_priority ) \ + { \ + Priority_Bit_map_control _major; \ + Priority_Bit_map_control _minor; \ + Priority_Bit_map_control _mask; \ + \ + _major = _Priority_Major( (_new_priority) ); \ + _minor = _Priority_Minor( (_new_priority) ); \ + \ + (_the_priority_map)->minor = \ + &_Priority_Bit_map[ _CPU_Priority_Bits_index(_major) ]; \ + \ + _mask = _CPU_Priority_Mask( _major ); \ + (_the_priority_map)->ready_major = _mask; \ + (_the_priority_map)->block_major = ~_mask; \ + \ + _mask = _CPU_Priority_Mask( _minor ); \ + (_the_priority_map)->ready_minor = _mask; \ + (_the_priority_map)->block_minor = ~_mask; \ + } + +/*PAGE + * + * _Priority_Is_group_empty + * + */ + +#define _Priority_Is_group_empty ( _the_priority ) \ + ( (_the_priority) == 0 ) +} +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/stack.inl b/cpukit/score/macros/rtems/score/stack.inl new file mode 100644 index 0000000000..208503b45f --- /dev/null +++ b/cpukit/score/macros/rtems/score/stack.inl @@ -0,0 +1,50 @@ +/* stack.inl + * + * This file contains the macro implementation of the inlined + * routines from the Stack Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __STACK_inl +#define __STACK_inl + +/*PAGE + * + * _Stack_Initialize + * + */ + +#define _Stack_Initialize( _the_stack, _starting_address, _size ) \ + { \ + (_the_stack)->area = (_starting_address); \ + (_the_stack)->size = (_size); \ + } + +/*PAGE + * + * _Stack_Is_enough + * + */ + +#define _Stack_Is_enough( _size ) \ + ( (_size) >= RTEMS_MINIMUM_STACK_SIZE ) + +/*PAGE + * + * _Stack_Adjust_size + */ + +#define _Stack_Adjust_size( _size ) \ + ((_size) + CPU_STACK_ALIGNMENT) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/states.inl b/cpukit/score/macros/rtems/score/states.inl new file mode 100644 index 0000000000..f69c4ba042 --- /dev/null +++ b/cpukit/score/macros/rtems/score/states.inl @@ -0,0 +1,201 @@ +/* states.inl + * + * This file contains the macro implementation of the inlined + * routines associated with RTEMS state information. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __STATES_inl +#define __STATES_inl + +/*PAGE + * + * _States_Set + * + */ + +#define _States_Set( _states_to_set, _current_state ) \ + ((_current_state) | (_states_to_set)) + +/*PAGE + * + * _States_Clear + * + */ + +#define _States_Clear( _states_to_clear, _current_state ) \ + ((_current_state) & ~(_states_to_clear)) + +/*PAGE + * + * _States_Is_ready + * + */ + +#define _States_Is_ready( _the_states ) \ + ( (_the_states) == STATES_READY ) + +/*PAGE + * + * _States_Is_only_dormant + * + */ + +#define _States_Is_only_dormant( _the_states ) \ + ( (_the_states) == STATES_DORMANT ) + +/*PAGE + * + * _States_Is_dormant + * + */ + +#define _States_Is_dormant( _the_states ) \ + ( (_the_states) & STATES_DORMANT ) + +/*PAGE + * + * _States_Is_suspended + * + */ + +#define _States_Is_suspended( _the_states ) \ + ( (_the_states) & STATES_SUSPENDED ) + +/*PAGE + * + * _States_Is_Transient + * + */ + +#define _States_Is_transient( _the_states ) \ + ( (_the_states) & STATES_TRANSIENT ) + +/*PAGE + * + * _States_Is_delaying + * + */ + +#define _States_Is_delaying( _the_states ) \ + ( (_the_states) & STATES_DELAYING ) + +/*PAGE + * + * _States_Is_waiting_for_buffer + * + */ + +#define _States_Is_waiting_for_buffer( _the_states ) \ + ( (_the_states) & STATES_WAITING_FOR_BUFFER ) + +/*PAGE + * + * _States_Is_waiting_for_segment + * + */ + +#define _States_Is_waiting_for_segment( _the_states ) \ + ( (_the_states) & STATES_WAITING_FOR_SEGMENT ) + +/*PAGE + * + * _States_Is_waiting_for_message + * + */ + +#define _States_Is_waiting_for_message( _the_states ) \ + ( (_the_states) & STATES_WAITING_FOR_MESSAGE ) + +/*PAGE + * + * _States_Is_waiting_for_event + * + */ + +#define _States_Is_waiting_for_event( _the_states ) \ + ( (_the_states) & STATES_WAITING_FOR_EVENT ) + +/*PAGE + * + * _States_Is_waiting_for_semaphore + * + */ + +#define _States_Is_waiting_for_semaphore( _the_states ) \ + ( (_the_states) & STATES_WAITING_FOR_SEMAPHORE ) + +/*PAGE + * + * _States_Is_waiting_for_time + * + */ + +#define _States_Is_waiting_for_time( _the_states ) \ + ( (_the_states) & STATES_WAITING_FOR_TIME ) + +/*PAGE + * + * _States_Is_waiting_for_rpc_reply + * + */ + +#define _States_Is_waiting_for_rpc_reply( _the_states ) \ + ( (_the_states) & STATES_WAITING_FOR_RPC_REPLY ) + +/*PAGE + * + * _States_Is_waiting_for_period + * + */ + +#define _States_Is_waiting_for_period( _the_states ) \ + ( (_the_states) & STATES_WAITING_FOR_PERIOD ) + +/*PAGE + * + * _States_Is_locally_blocked + * + */ + +#define _States_Is_locally_blocked( _the_states ) \ + ( (_the_states) & STATES_LOCALLY_BLOCKED ) + +/*PAGE + * + * _States_Is_waiting_on_thread_queue + * + */ + +#define _States_Is_waiting_on_thread_queue( _the_states ) \ + ( (_the_states) & STATES_WAITING_ON_THREAD_QUEUE ) + +/*PAGE + * + * _States_Is_blocked + * + */ + +#define _States_Is_blocked( _the_states ) \ + ( (_the_states) & STATES_BLOCKED ) + +/*PAGE + * + * _States_Are_set + * + */ + +#define _States_Are_set( _the_states, _mask ) \ + ( ((_the_states) & (_mask)) != STATES_READY ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/sysstate.inl b/cpukit/score/macros/rtems/score/sysstate.inl new file mode 100644 index 0000000000..5cc9f9e9f9 --- /dev/null +++ b/cpukit/score/macros/rtems/score/sysstate.inl @@ -0,0 +1,77 @@ +/* sysstates.inl + * + * This file contains the macro implementation of routines regarding the + * system state. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __SYSTEM_STATE_inl +#define __SYSTEM_STATE_inl + +/*PAGE + * + * _System_state_Set + */ + +#define _System_state_Set( _state ) \ + _System_state_Current = (_state) + +/*PAGE + * + * _System_state_Get + */ + +#define _System_state_Get( void ) \ + (_System_state_Current) + +/*PAGE + * + * _System_state_Is_before_initialization + */ + +#define _System_state_Is_before_initialization( _state ) \ + ((_state) == SYSTEM_STATE_BEFORE_INITIALIZATION) + +/*PAGE + * + * _System_state_Is_before_multitasking + */ + +#define _System_state_Is_before_multitasking( _state ) \ + ((_state) == SYSTEM_STATE_BEFORE_MULTITASKING) + +/*PAGE + * + * _System_state_Is_begin_multitasking + */ + +#define _System_state_Is_begin_multitasking( _state ) \ + ((_state) == SYSTEM_STATE_BEGIN_MULTITASKING) + +/*PAGE + * + * _System_state_Is_up + */ + +#define _System_state_Is_up( _state ) \ + ((_state) == SYSTEM_STATE_UP) + +/*PAGE + * + * _System_state_Is_failed + */ + +#define _System_state_Is_failed( _state ) \ + ((_state) == SYSTEM_STATE_FAILED) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/thread.inl b/cpukit/score/macros/rtems/score/thread.inl new file mode 100644 index 0000000000..0e041de5ac --- /dev/null +++ b/cpukit/score/macros/rtems/score/thread.inl @@ -0,0 +1,193 @@ +/* thread.inl + * + * This file contains the macro implementation of the inlined + * routines from the Thread handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __THREAD_inl +#define __THREAD_inl + +/*PAGE + * + * _Thread_Stop_multitasking + * + */ + +#define _Thread_Stop_multitasking() \ + _Context_Switch( &_Thread_Executing->Registers, &_Thread_BSP_context ); + +/*PAGE + * + * _Thread_Is_executing + * + */ + +#define _Thread_Is_executing( _the_thread ) \ + ( (_the_thread) == _Thread_Executing ) + +/*PAGE + * + * _Thread_Is_heir + * + */ + +#define _Thread_Is_heir( _the_thread ) \ + ( (_the_thread) == _Thread_Heir ) + +/*PAGE + * + * _Thread_Is_executing_also_the_heir + * + */ + +#define _Thread_Is_executing_also_the_heir() \ + ( _Thread_Executing == _Thread_Heir ) + +/*PAGE + * + * _Thread_Resume + * + */ + +#define _Thread_Resume( _the_thread ) \ + _Thread_Clear_state( (_the_thread), STATES_SUSPENDED ) + +/*PAGE + * + * _Thread_Unblock + * + */ + +#define _Thread_Unblock( _the_thread ) \ + _Thread_Clear_state( (_the_thread), STATES_BLOCKED ); + +/*PAGE + * + * _Thread_Restart_self + * + */ + +#define _Thread_Restart_self() \ + { \ + if ( _Thread_Executing->fp_context != NULL ) \ + _Context_Restore_fp( &_Thread_Executing->fp_context ); \ + \ + _CPU_Context_Restart_self( &_Thread_Executing->Registers ); \ + } + +/*PAGE + * + * _Thread_Calculate_heir + * + */ + +#define _Thread_Calculate_heir() \ + { \ + rtems_task_priority highest; \ + \ + _Priority_Get_highest( highest ); \ + \ + _Thread_Heir = (Thread_Control *) _Thread_Ready_chain[ highest ].first; \ + } + +/*PAGE + * + * _Thread_Is_allocated_fp + * + */ + +#define _Thread_Is_allocated_fp( _the_thread ) \ + ( (_the_thread) == _Thread_Allocated_fp ) + +/*PAGE + * + * _Thread_Deallocate_fp + * + */ + +#define _Thread_Deallocate_fp() \ + _Thread_Allocated_fp = NULL + +/*PAGE + * + * _Thread_Disable_dispatch + * + */ + +#define _Thread_Disable_dispatch() \ + _Thread_Dispatch_disable_level += 1 + +/*PAGE + * + * _Thread_Enable_dispatch + * + */ + +#if ( CPU_INLINE_ENABLE_DISPATCH == TRUE ) +#define _Thread_Enable_dispatch() \ + { if ( (--_Thread_Dispatch_disable_level) == 0 ) \ + _Thread_Dispatch(); \ + } +#endif + +#if ( CPU_INLINE_ENABLE_DISPATCH == FALSE ) +void _Thread_Enable_dispatch( void ); +#endif + +/*PAGE + * + * _Thread_Unnest_dispatch + * + */ + +#define _Thread_Unnest_dispatch() \ + _Thread_Dispatch_disable_level -= 1 + +/*PAGE + * + * _Thread_Is_dispatching_enabled + * + */ + +#define _Thread_Is_dispatching_enabled() \ + ( _Thread_Dispatch_disable_level == 0 ) + +/*PAGE + * + * _Thread_Is_context_switch_necessary + * + */ + +#define _Thread_Is_context_switch_necessary() \ + ( _Context_Switch_necessary == TRUE ) + +/*PAGE + * + * _Thread_Dispatch_initialization + * + */ + +#define _Thread_Dispatch_initialization() \ + _Thread_Dispatch_disable_level = 1 + +/*PAGE + * + * _Thread_Is_null + * + */ + +#define _Thread_Is_null( _the_thread ) \ + ( (_the_thread) == NULL ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/threadmp.inl b/cpukit/score/macros/rtems/score/threadmp.inl new file mode 100644 index 0000000000..c601862f96 --- /dev/null +++ b/cpukit/score/macros/rtems/score/threadmp.inl @@ -0,0 +1,50 @@ +/* macros/threadmp.h + * + * This include file contains the bodies of all inlined routines + * for the multiprocessing part of thread package. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MACROS_MP_THREAD_h +#define __MACROS_MP_THREAD_h + +/*PAGE + * + * _Thread_MP_Is_receive + * + */ + +#define _Thread_MP_Is_receive( _the_thread ) \ + ( (_the_thread) == _Thread_MP_Receive) + +/*PAGE + * + * _Thread_MP_Free_proxy + * + */ + +#define _Thread_MP_Free_proxy( _the_thread ) \ +{ \ + Thread_Proxy_control *_the_proxy; \ + \ + _the_proxy = (Thread_Proxy_control *) (_the_thread); \ + \ + _Chain_Extract( &_the_proxy->Active ); \ + \ + _Chain_Append( \ + &_Thread_MP_Inactive_proxies, \ + &(_the_thread)->Object.Node \ + ); \ +} + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/tod.inl b/cpukit/score/macros/rtems/score/tod.inl new file mode 100644 index 0000000000..9360a588b1 --- /dev/null +++ b/cpukit/score/macros/rtems/score/tod.inl @@ -0,0 +1,59 @@ +/* tod.inl + * + * This file contains the macro implementation of the inlined routines + * from the Time of Day Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __TIME_OF_DAY_inl +#define __TIME_OF_DAY_inl + +/*PAGE + * + * _TOD_Is_set + * + */ + +#define _TOD_Is_set() \ + _Watchdog_Is_active( &_TOD_Seconds_watchdog ) + +/*PAGE + * + * _TOD_Tickle_ticks + * + */ + +#define _TOD_Tickle_ticks() \ + _TOD_Current.ticks++; \ + _TOD_Ticks_since_boot++ + +/*PAGE + * + * _TOD_Deactivate + * + */ + +#define _TOD_Deactivate() \ + _Watchdog_Remove( &_TOD_Seconds_watchdog ) + +/*PAGE + * + * _TOD_Activate + * + */ + +#define _TOD_Activate( ticks ) \ + _Watchdog_Insert_ticks( &_TOD_Seconds_watchdog, \ + (ticks), WATCHDOG_ACTIVATE_NOW ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/tqdata.inl b/cpukit/score/macros/rtems/score/tqdata.inl new file mode 100644 index 0000000000..5f657c1a94 --- /dev/null +++ b/cpukit/score/macros/rtems/score/tqdata.inl @@ -0,0 +1,39 @@ +/* tqdata.inl + * + * This file contains the macro implementation of the inlined + * routines needed to support the Thread Queue Data. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __THREAD_QUEUE_DATA_inl +#define __THREAD_QUEUE_DATA_inl + +/*PAGE + * + * _Thread_queue_Header_number + * + */ + +#define _Thread_queue_Header_number( _the_priority ) \ + ( (_the_priority) >> 6 ) + +/*PAGE + * + * _Thread_queue_Is_reverse_search + * + */ + +#define _Thread_queue_Is_reverse_search( _the_priority ) \ + ( (_the_priority) & 0x20 ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/userext.inl b/cpukit/score/macros/rtems/score/userext.inl new file mode 100644 index 0000000000..781f30ad40 --- /dev/null +++ b/cpukit/score/macros/rtems/score/userext.inl @@ -0,0 +1,184 @@ +/* userext.inl + * + * This file contains the macro implementation of the inlined routines + * from the User Extension Handler + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __USER_EXTENSIONS_inl +#define __USER_EXTENSIONS_inl + +/*PAGE + * + * _User_extensions_Handler_initialization + * + */ + +#define _User_extensions_Handler_initialization( _initial_extensions ) \ + { \ + _Chain_Initialize_empty( &_User_extensions_List ); \ + \ + if ( (_initial_extensions) ) { \ + _User_extensions_Initial.Callouts = *(_initial_extensions); \ + _Chain_Append( \ + &_User_extensions_List, &_User_extensions_Initial.Node ); \ + } \ + } + +/*PAGE + * + * _User_extensions_Add_set + */ + +#define _User_extensions_Add_set( _the_extension, _extension_table ) \ + { \ + (_the_extension)->Callouts = *(_extension_table); \ + \ + _Chain_Append( &_User_extensions_List, &(_the_extension)->Node ); \ + } + +/*PAGE + * + * _User_extensions_Remove_set + */ + +#define _User_extensions_Remove_set( _the_extension ) \ + _Chain_Extract( &(_the_extension)->Node ) + +/*PAGE + * + * _User_extensions_Run_list_forward + * + * NOTE: No parentheses around macro names here to avoid + * messing up the name and function call expansion. + */ + +#define _User_extensions_Run_list_forward( _name, _arguments ) \ + do { \ + Chain_Node *the_node; \ + User_extensions_Control *the_extension; \ + \ + for ( the_node = _User_extensions_List.first ; \ + !_Chain_Is_tail( &_User_extensions_List, the_node ) ; \ + the_node = the_node->next ) { \ + the_extension = (User_extensions_Control *) the_node; \ + \ + if ( the_extension->Callouts.## _name != NULL ) \ + (*the_extension->Callouts.## _name) _arguments; \ + \ + } \ + \ + } while ( 0 ) + +/*PAGE + * + * _User_extensions_Run_list_backward + * + * NOTE: No parentheses around macro names here to avoid + * messing up the name and function call expansion. + */ + +#define _User_extensions_Run_list_backward( _name, _arguments ) \ + do { \ + Chain_Node *the_node; \ + User_extensions_Control *the_extension; \ + \ + for ( the_node = _User_extensions_List.last ; \ + !_Chain_Is_head( &_User_extensions_List, the_node ) ; \ + the_node = the_node->previous ) { \ + the_extension = (User_extensions_Control *) the_node; \ + \ + if ( the_extension->Callouts.## _name != NULL ) \ + (*the_extension->Callouts.## _name) _arguments; \ + \ + } \ + \ + } while ( 0 ) + +/*PAGE + * + * _User_extensions_Task_create + * + */ + +#define _User_extensions_Task_create( _the_thread ) \ + _User_extensions_Run_list_forward(rtems_task_create, \ + (_Thread_Executing, _the_thread) ) + +/*PAGE + * + * _User_extensions_Task_delete + * + */ + +#define _User_extensions_Task_delete( _the_thread ) \ + _User_extensions_Run_list_backward(rtems_task_delete, \ + (_Thread_Executing, _the_thread) ) + +/*PAGE + * + * _User_extensions_Task_start + * + */ + +#define _User_extensions_Task_start( _the_thread ) \ + _User_extensions_Run_list_forward(rtems_task_start, \ + (_Thread_Executing, _the_thread) ) + +/*PAGE + * + * _User_extensions_Task_restart + * + */ + +#define _User_extensions_Task_restart( _the_thread ) \ + _User_extensions_Run_list_forward(rtems_task_restart,\ + (_Thread_Executing, _the_thread) ) + +/*PAGE + * + * _User_extensions_Task_switch + * + */ + +#define _User_extensions_Task_switch( _executing, _heir ) \ + _User_extensions_Run_list_forward(task_switch, (_executing, _heir) ) + +/*PAGE + * + * _User_extensions_Task_begin + * + */ + +#define _User_extensions_Task_begin( _executing ) \ + _User_extensions_Run_list_forward(task_begin, (_executing) ) + +/*PAGE + * + * _User_extensions_Task_exitted + * + */ + +#define _User_extensions_Task_exitted( _executing ) \ + _User_extensions_Run_list_backward(task_exitted, (_executing) ) + +/*PAGE + * + * _User_extensions_Fatal + * + */ + +#define _User_extensions_Fatal( _the_error ) \ + _User_extensions_Run_list_backward(fatal, (_the_error) ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/watchdog.inl b/cpukit/score/macros/rtems/score/watchdog.inl new file mode 100644 index 0000000000..1b150d8dab --- /dev/null +++ b/cpukit/score/macros/rtems/score/watchdog.inl @@ -0,0 +1,202 @@ +/* watchdog.inl + * + * This file contains the macro implementation of all inlined routines + * in the Watchdog Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __WATCHDOG_inl +#define __WATCHDOG_inl + +#include + +/*PAGE + * + * _Watchdog_Initialize + * + */ + +#define _Watchdog_Initialize( _the_watchdog, _routine, _id, _user_data ) \ + { \ + (_the_watchdog)->state = WATCHDOG_INACTIVE; \ + (_the_watchdog)->routine = (_routine); \ + (_the_watchdog)->id = (_id); \ + (_the_watchdog)->user_data = (_user_data); \ + } + +/*PAGE + * + * _Watchdog_Is_active + * + */ + +#define _Watchdog_Is_active( _the_watchdog ) \ + ( (_the_watchdog)->state == WATCHDOG_ACTIVE ) + +/*PAGE + * + * _Watchdog_Activate + * + */ + +#define _Watchdog_Activate( _the_watchdog ) \ + (_the_watchdog)->state = WATCHDOG_ACTIVE + +/*PAGE + * + * _Watchdog_Deactivate + * + */ + +#define _Watchdog_Deactivate( _the_watchdog ) \ + (_the_watchdog)->state = WATCHDOG_REMOVE_IT + +/*PAGE + * + * _Watchdog_Tickle_ticks + * + */ + +#define _Watchdog_Tickle_ticks() \ + _Watchdog_Tickle( &_Watchdog_Ticks_chain ) + +/*PAGE + * + * _Watchdog_Tickle_seconds + * + */ + +#define _Watchdog_Tickle_seconds() \ + _Watchdog_Tickle( &_Watchdog_Seconds_chain ) + +/*PAGE + * + * _Watchdog_Insert_ticks + * + */ + +#define _Watchdog_Insert_ticks( _the_watchdog, _units, _insert_mode ) \ + { \ + (_the_watchdog)->initial = (_units); \ + _Watchdog_Insert( &_Watchdog_Ticks_chain, \ + (_the_watchdog), (_insert_mode) ); \ + } + +/*PAGE + * + * _Watchdog_Insert_seconds + * + */ + +#define _Watchdog_Insert_seconds( _the_watchdog, _units, _insert_mode ) \ + { \ + (_the_watchdog)->initial = (_units); \ + _Watchdog_Insert( &_Watchdog_Seconds_chain, \ + (_the_watchdog), (_insert_mode) ); \ + } + +/*PAGE + * + * _Watchdog_Adjust_seconds + * + */ + +#define _Watchdog_Adjust_seconds( _direction, _units ) \ + _Watchdog_Adjust( &_Watchdog_Seconds_chain, (_direction), (_units) ) + +/*PAGE + * + * _Watchdog_Adjust_ticks + * + */ + +#define _Watchdog_Adjust_ticks( _direction, _units ) \ + _Watchdog_Adjust( &_Watchdog_Ticks_chain, (_direction), (_units) ) + +/*PAGE + * + * _Watchdog_Reset + * + */ + +#define _Watchdog_Reset( _the_watchdog ) \ + { \ + (void) _Watchdog_Remove( (_the_watchdog) ); \ + _Watchdog_Insert( &_Watchdog_Ticks_chain, \ + (_the_watchdog), WATCHDOG_ACTIVATE_NOW ); \ + } + +/*PAGE + * + * _Watchdog_Next + * + */ + +#define _Watchdog_Next( _watchdog ) \ + ((Watchdog_Control *) (_watchdog)->Node.next) + +/*PAGE + * + * _Watchdog_Previous + * + */ + +#define _Watchdog_Previous( _watchdog ) \ + ((Watchdog_Control *) (_watchdog)->Node.previous) + +/*PAGE + * + * _Watchdog_First + * + */ + +#define _Watchdog_First( _header ) \ + ((Watchdog_Control *) (_header)->first) + +/*PAGE + * + * _Watchdog_Last + * + */ + +#define _Watchdog_Last( _header ) \ + ((Watchdog_Control *) (_header)->last) + +/*PAGE + * + * _Watchdog_Get_sync + * + */ + +#define _Watchdog_Get_sync() \ + ((Watchdog_Control *) _Watchdog_Sync) + +/*PAGE + * + * _Watchdog_Set_sync + * + */ + +#define _Watchdog_Set_sync( _the_watchdog ) \ + _Watchdog_Sync = (Watchdog_Synchronization_pointer) (_the_watchdog) + +/*PAGE + * + * _Watchdog_Clear_sync + * + */ + +#define _Watchdog_Clear_sync() \ + _Watchdog_Sync = NULL; + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/wkspace.inl b/cpukit/score/macros/rtems/score/wkspace.inl new file mode 100644 index 0000000000..3c516bfb93 --- /dev/null +++ b/cpukit/score/macros/rtems/score/wkspace.inl @@ -0,0 +1,101 @@ +/* wkspace.inl + * + * This file contains the macro implementation of the inlined routines + * from the RTEMS RAM Workspace Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __WORKSPACE_inl +#define __WORKSPACE_inl + +#include +#include +#include + +/*PAGE + * + * _Workspace_Handler_initialization + * + */ + +#define _Workspace_Handler_initialization( _starting_address, _size ) \ +{ \ + unsigned32 *zero_out_array; \ + unsigned32 index; \ + unsigned32 memory_available; \ + \ + if ( ((_starting_address) == NULL) || \ + !_Addresses_Is_aligned( (_starting_address) ) ) \ + rtems_fatal_error_occurred( RTEMS_INVALID_ADDRESS ); \ + \ + if ( _CPU_Table.do_zero_of_workspace ) { \ + for( zero_out_array = (unsigned32 *) (_starting_address), index = 0 ; \ + index < (_size) / 4 ; \ + index++ ) \ + zero_out_array[ index ] = 0; \ + } \ + \ + memory_available = _Heap_Initialize( \ + &_Workspace_Area, \ + (_starting_address), \ + (_size), \ + CPU_ALIGNMENT \ + ); \ + \ + if ( memory_available == 0 ) \ + rtems_fatal_error_occurred( RTEMS_UNSATISFIED ); \ +} + +/*PAGE + * + * _Workspace_Allocate + * + */ + +#define _Workspace_Allocate( _size ) \ + _Heap_Allocate( &_Workspace_Area, (_size) ) + +/*PAGE + * + * _Workspace_Allocate_or_fatal_error + * + * NOTE: XXX FIX ME + * + * When not using static inlines, this should really be a function + * somewhere. + */ + +static inline void _Workspace_Allocate_or_fatal_error( + unsigned32 size +) +{ + void *memory; + + memory = _Workspace_Allocate( size ); + + if ( memory == NULL ) + rtems_fatal_error_occurred( RTEMS_UNSATISFIED ); + + return memory; +} + +/*PAGE + * + * _Workspace_Free + * + */ + +#define _Workspace_Free( _block ) \ + _Heap_Free( &_Workspace_Area, (_block) ) + +#endif +/* end of include file */ diff --git a/cpukit/score/src/chain.c b/cpukit/score/src/chain.c new file mode 100644 index 0000000000..88f6759b0b --- /dev/null +++ b/cpukit/score/src/chain.c @@ -0,0 +1,202 @@ +/* + * Chain Handler + * + * NOTE: + * + * The order of this file is to allow proper compilation due to the + * order of inlining required by the compiler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include + +/*PAGE + * + * _Chain_Initialize + * + * This kernel routine initializes a doubly linked chain. + * + * Input parameters: + * the_chain - pointer to chain header + * starting_address - starting address of first node + * number_nodes - number of nodes in chain + * node_size - size of node in bytes + * + * Output parameters: NONE + */ + +void _Chain_Initialize( + Chain_Control *the_chain, + void *starting_address, + unsigned32 number_nodes, + unsigned32 node_size +) +{ + unsigned32 count; + Chain_Node *current; + Chain_Node *next; + + count = number_nodes; + current = _Chain_Head( the_chain ); + the_chain->permanent_null = NULL; + next = (Chain_Node *)starting_address; + while ( count-- ) { + current->next = next; + next->previous = current; + current = next; + next = (Chain_Node *) + _Addresses_Add_offset( (void *) next, node_size ); + } + current->next = _Chain_Tail( the_chain ); + the_chain->last = current; +} + +/*PAGE + * + * _Chain_Get_first_unprotected + */ + +#ifndef USE_INLINES +Chain_Node *_Chain_Get_first_unprotected( + Chain_Control *the_chain +) +{ + Chain_Node *return_node; + Chain_Node *new_first; + + return_node = the_chain->first; + new_first = return_node->next; + the_chain->first = new_first; + new_first->previous = _Chain_Head( the_chain ); + + return return_node; +} +#endif /* USE_INLINES */ + +/*PAGE + * + * _Chain_Get + * + * This kernel routine returns a pointer to a node taken from the + * given chain. + * + * Input parameters: + * the_chain - pointer to chain header + * + * Output parameters: + * return_node - pointer to node in chain allocated + * CHAIN_END - if no nodes available + * + * INTERRUPT LATENCY: + * only case + */ + +Chain_Node *_Chain_Get( + Chain_Control *the_chain +) +{ + ISR_Level level; + Chain_Node *return_node; + + return_node = NULL; + _ISR_Disable( level ); + if ( !_Chain_Is_empty( the_chain ) ) + return_node = _Chain_Get_first_unprotected( the_chain ); + _ISR_Enable( level ); + return return_node; +} + +/*PAGE + * + * _Chain_Append + * + * This kernel routine puts a node on the end of the specified chain. + * + * Input parameters: + * the_chain - pointer to chain header + * node - address of node to put at rear of chain + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * only case + */ + +void _Chain_Append( + Chain_Control *the_chain, + Chain_Node *node +) +{ + ISR_Level level; + + _ISR_Disable( level ); + _Chain_Append_unprotected( the_chain, node ); + _ISR_Enable( level ); +} + +/*PAGE + * + * _Chain_Extract + * + * This kernel routine deletes the given node from a chain. + * + * Input parameters: + * node - pointer to node in chain to be deleted + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * only case + */ + +void _Chain_Extract( + Chain_Node *node +) +{ + ISR_Level level; + + _ISR_Disable( level ); + _Chain_Extract_unprotected( node ); + _ISR_Enable( level ); +} + +/*PAGE + * + * _Chain_Insert + * + * This kernel routine inserts a given node after a specified node + * a requested chain. + * + * Input parameters: + * after_node - pointer to node in chain to be inserted after + * node - pointer to node to be inserted + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * only case + */ + +void _Chain_Insert( + Chain_Node *after_node, + Chain_Node *node +) +{ + ISR_Level level; + + _ISR_Disable( level ); + _Chain_Insert_unprotected( after_node, node ); + _ISR_Enable( level ); +} diff --git a/cpukit/score/src/coretod.c b/cpukit/score/src/coretod.c new file mode 100644 index 0000000000..4689c637d7 --- /dev/null +++ b/cpukit/score/src/coretod.c @@ -0,0 +1,236 @@ +/* + * Time of Day (TOD) Handler + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include + +/*PAGE + * + * _TOD_Handler_initialization + * + * This routine initializes the time of day handler. + * + * Input parameters: + * microseconds_per_tick - microseconds between clock ticks + * + * Output parameters: NONE + */ + +void _TOD_Handler_initialization( + unsigned32 microseconds_per_tick +) +{ + _TOD_Microseconds_per_tick = microseconds_per_tick; + + _TOD_Ticks_since_boot = 0; + _TOD_Seconds_since_epoch = 0; + + _TOD_Current.year = TOD_BASE_YEAR; + _TOD_Current.month = 1; + _TOD_Current.day = 1; + _TOD_Current.hour = 0; + _TOD_Current.minute = 0; + _TOD_Current.second = 0; + _TOD_Current.ticks = 0; + + if ( microseconds_per_tick == 0 ) + _TOD_Ticks_per_second = 0; + else + _TOD_Ticks_per_second = + TOD_MICROSECONDS_PER_SECOND / microseconds_per_tick; + + _Watchdog_Initialize( &_TOD_Seconds_watchdog, _TOD_Tickle, 0, NULL ); +} + +/*PAGE + * + * _TOD_Set + * + * This rountine sets the current date and time with the specified + * new date and time structure. + * + * Input parameters: + * the_tod - pointer to the time and date structure + * seconds_since_epoch - seconds since system epoch + * + * Output parameters: NONE + */ + +void _TOD_Set( + rtems_time_of_day *the_tod, + rtems_interval seconds_since_epoch +) +{ + rtems_interval ticks_until_next_second; + + _Thread_Disable_dispatch(); + _TOD_Deactivate(); + + if ( seconds_since_epoch < _TOD_Seconds_since_epoch ) + _Watchdog_Adjust_seconds( WATCHDOG_BACKWARD, + _TOD_Seconds_since_epoch - seconds_since_epoch ); + else + _Watchdog_Adjust_seconds( WATCHDOG_FORWARD, + seconds_since_epoch - _TOD_Seconds_since_epoch ); + + ticks_until_next_second = _TOD_Ticks_per_second; + if ( ticks_until_next_second > _TOD_Current.ticks ) + ticks_until_next_second -= _TOD_Current.ticks; + + _TOD_Current = *the_tod; + _TOD_Seconds_since_epoch = seconds_since_epoch; + _TOD_Activate( ticks_until_next_second ); + + _Thread_Enable_dispatch(); +} + +/*PAGE + * + * _TOD_Validate + * + * This kernel routine checks the validity of a date and time structure. + * + * Input parameters: + * the_tod - pointer to a time and date structure + * + * Output parameters: + * RTEMS_SUCCESSFUL - if the date, time, and tick are valid + * RTEMS_INVALID_CLOCK - if the the_tod is invalid + * + * NOTE: This routine only works for leap-years through 2099. + */ + +rtems_status_code _TOD_Validate( + rtems_time_of_day *the_tod +) +{ + unsigned32 days_in_month; + + if ((the_tod->ticks >= _TOD_Ticks_per_second) || + (the_tod->second >= TOD_SECONDS_PER_MINUTE) || + (the_tod->minute >= TOD_MINUTES_PER_HOUR) || + (the_tod->hour >= TOD_HOURS_PER_DAY) || + (the_tod->month == 0) || + (the_tod->month > TOD_MONTHS_PER_YEAR) || + (the_tod->year < TOD_BASE_YEAR) || + (the_tod->day == 0) ) + return RTEMS_INVALID_CLOCK; + + if ( (the_tod->year % 4) == 0 ) + days_in_month = _TOD_Days_per_month[ 1 ][ the_tod->month ]; + else + days_in_month = _TOD_Days_per_month[ 0 ][ the_tod->month ]; + + if ( the_tod->day > days_in_month ) + return RTEMS_INVALID_CLOCK; + + return RTEMS_SUCCESSFUL; +} + +/*PAGE + * + * _TOD_To_seconds + * + * This routine returns the seconds from the epoch until the + * current date and time. + * + * Input parameters: + * the_tod - pointer to the time and date structure + * + * Output parameters: + * returns - seconds since epoch until the_tod + */ + +unsigned32 _TOD_To_seconds( + rtems_time_of_day *the_tod +) +{ + unsigned32 time; + unsigned32 year_mod_4; + + time = the_tod->day - 1; + year_mod_4 = the_tod->year & 3; + + if ( year_mod_4 == 0 ) + time += _TOD_Days_to_date[ 1 ][ the_tod->month ]; + else + time += _TOD_Days_to_date[ 0 ][ the_tod->month ]; + + time += ( (the_tod->year - TOD_BASE_YEAR) / 4 ) * + ( (TOD_DAYS_PER_YEAR * 4) + 1); + + time += _TOD_Days_since_last_leap_year[ year_mod_4 ]; + + time *= TOD_SECONDS_PER_DAY; + + time += ((the_tod->hour * TOD_MINUTES_PER_HOUR) + the_tod->minute) + * TOD_SECONDS_PER_MINUTE; + + time += the_tod->second; + + return( time ); +} + +/*PAGE + * + * _TOD_Tickle + * + * This routine updates the calendar time and tickles the + * per second watchdog timer chain. + * + * Input parameters: + * ignored - this parameter is ignored + * + * Output parameters: NONE + * + * NOTE: This routine only works for leap-years through 2099. + */ + +void _TOD_Tickle( + Objects_Id id, + void *ignored +) +{ + unsigned32 leap; + + _TOD_Current.ticks = 0; + ++_TOD_Seconds_since_epoch; + if ( ++_TOD_Current.second >= TOD_SECONDS_PER_MINUTE ) { + _TOD_Current.second = 0; + if ( ++_TOD_Current.minute >= TOD_MINUTES_PER_HOUR ) { + _TOD_Current.minute = 0; + if ( ++_TOD_Current.hour >= TOD_HOURS_PER_DAY ) { + _TOD_Current.hour = 0; + if ( _TOD_Current.year & 0x3 ) leap = 0; + else leap = 1; + if ( ++_TOD_Current.day > + _TOD_Days_per_month[ leap ][ _TOD_Current.month ]) { + _TOD_Current.day = 1; + if ( ++_TOD_Current.month > TOD_MONTHS_PER_YEAR ) { + _TOD_Current.month = 1; + _TOD_Current.year++; + } + } + } + } + } + + _Watchdog_Tickle_seconds(); + _Watchdog_Insert_ticks( &_TOD_Seconds_watchdog, _TOD_Ticks_per_second, + WATCHDOG_ACTIVATE_NOW ); +} diff --git a/cpukit/score/src/heap.c b/cpukit/score/src/heap.c new file mode 100644 index 0000000000..485012ddf7 --- /dev/null +++ b/cpukit/score/src/heap.c @@ -0,0 +1,478 @@ +/* + * Heap Handler + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + + +#include +#include +#include + +/*PAGE + * + * _Heap_Initialize + * + * This kernel routine initializes a heap. + * + * Input parameters: + * the_heap - pointer to heap header + * starting_address - starting address of heap + * size - size of heap + * page_size - allocatable unit of memory + * + * Output parameters: + * returns - maximum memory available if RTEMS_SUCCESSFUL + * 0 - otherwise + * + * This is what a heap looks like in memory immediately + * after initialization: + * + * +--------------------------------+ + * 0 | size = 0 | status = used | a.k.a. dummy back flag + * +--------------------------------+ + * 4 | size = size-8 | status = free | a.k.a. front flag + * +--------------------------------+ + * 8 | next = PERM HEAP_TAIL | + * +--------------------------------+ + * 12 | previous = PERM HEAP_HEAD | + * +--------------------------------+ + * | | + * | memory available | + * | for allocation | + * | | + * +--------------------------------+ + * size - 8 | size = size-8 | status = free | a.k.a. back flag + * +--------------------------------+ + * size - 4 | size = 0 | status = used | a.k.a. dummy front flag + * +--------------------------------+ + */ + +unsigned32 _Heap_Initialize( + Heap_Control *the_heap, + void *starting_address, + unsigned32 size, + unsigned32 page_size +) +{ + Heap_Block *the_block; + unsigned32 the_size; + + if ( !_Heap_Is_page_size_valid( page_size ) || + (size < HEAP_MINIMUM_SIZE) ) + return 0; + + the_heap->page_size = page_size; + the_size = size - HEAP_OVERHEAD; + + the_block = (Heap_Block *) starting_address; + the_block->back_flag = HEAP_DUMMY_FLAG; + the_block->front_flag = the_size; + the_block->next = _Heap_Tail( the_heap ); + the_block->previous = _Heap_Head( the_heap ); + + the_heap->start = the_block; + the_heap->first = the_block; + the_heap->permanent_null = NULL; + the_heap->last = the_block; + + the_block = _Heap_Next_block( the_block ); + the_block->back_flag = the_size; + the_block->front_flag = HEAP_DUMMY_FLAG; + the_heap->final = the_block; + + return ( the_size - HEAP_BLOCK_USED_OVERHEAD ); +} + +/*PAGE + * + * _Heap_Extend + * + * This routine grows the_heap memory area using the size bytes which + * begin at starting_address. + * + * Input parameters: + * the_heap - pointer to heap header. + * starting_address - pointer to the memory area. + * size - size in bytes of the memory block to allocate. + * + * Output parameters: + * *amount_extended - amount of memory added to the_heap + */ + +Heap_Extend_status _Heap_Extend( + Heap_Control *the_heap, + void *starting_address, + unsigned32 size, + unsigned32 *amount_extended +) +{ + Heap_Block *the_block; + Heap_Block *next_block; + Heap_Block *previous_block; + + /* + * There are five possibilities for the location of starting + * address: + * + * 1. non-contiguous lower address (NOT SUPPORTED) + * 2. contiguous lower address (NOT SUPPORTED) + * 3. in the heap (ERROR) + * 4. contiguous higher address (SUPPORTED) + * 5. non-contiguous higher address (NOT SUPPORTED) + * + * As noted, this code only supports (4). + */ + + if ( starting_address >= (void *) the_heap->start && /* case 3 */ + starting_address <= (void *) the_heap->final + ) + return HEAP_EXTEND_ERROR; + + if ( starting_address < (void *) the_heap->start ) { /* cases 1 and 2 */ + + return HEAP_EXTEND_NOT_IMPLEMENTED; /* cases 1 and 2 */ + + } else { /* cases 4 and 5 */ + + the_block = (Heap_Block *) (starting_address - HEAP_OVERHEAD); + if ( the_block != the_heap->final ) + return HEAP_EXTEND_NOT_IMPLEMENTED; /* case 5 */ + } + + /* + * Currently only case 4 should make it to this point. + */ + + *amount_extended = size - HEAP_BLOCK_USED_OVERHEAD; + + previous_block = the_heap->last; + + the_block = (Heap_Block *) starting_address; + the_block->front_flag = size; + the_block->next = previous_block->next; + the_block->previous = previous_block; + + previous_block->next = the_block; + the_heap->last = the_block; + + next_block = _Heap_Next_block( the_block ); + next_block->back_flag = size; + next_block->front_flag = HEAP_DUMMY_FLAG; + the_heap->final = next_block; + + return HEAP_EXTEND_SUCCESSFUL; +} + +/*PAGE + * + * _Heap_Allocate + * + * This kernel routine allocates the requested size of memory + * from the specified heap. + * + * Input parameters: + * the_heap - pointer to heap header. + * size - size in bytes of the memory block to allocate. + * + * Output parameters: + * returns - starting address of memory block allocated + */ + +void *_Heap_Allocate( + Heap_Control *the_heap, + unsigned32 size +) +{ + unsigned32 excess; + unsigned32 the_size; + Heap_Block *the_block; + Heap_Block *next_block; + Heap_Block *temporary_block; + + excess = size % the_heap->page_size; + the_size = size + HEAP_BLOCK_USED_OVERHEAD; + + if ( excess ) + the_size += the_heap->page_size - excess; + + if ( the_size < sizeof( Heap_Block ) ) + the_size = sizeof( Heap_Block ); + + for ( the_block = the_heap->first; + ; + the_block = the_block->next ) { + if ( the_block == _Heap_Tail( the_heap ) ) + return( NULL ); + if ( the_block->front_flag >= the_size ) + break; + } + + if ( (the_block->front_flag - the_size) > + (the_heap->page_size + HEAP_BLOCK_USED_OVERHEAD) ) { + the_block->front_flag -= the_size; + next_block = _Heap_Next_block( the_block ); + next_block->back_flag = the_block->front_flag; + + temporary_block = _Heap_Block_at( next_block, the_size ); + temporary_block->back_flag = + next_block->front_flag = _Heap_Build_flag( the_size, + HEAP_BLOCK_USED ); + return( _Heap_Start_of_user_area( next_block ) ); + } else { + next_block = _Heap_Next_block( the_block ); + next_block->back_flag = _Heap_Build_flag( the_block->front_flag, + HEAP_BLOCK_USED ); + the_block->front_flag = next_block->back_flag; + the_block->next->previous = the_block->previous; + the_block->previous->next = the_block->next; + return( _Heap_Start_of_user_area( the_block ) ); + } +} + +/*PAGE + * + * _Heap_Size_of_user_area + * + * This kernel routine returns the size of the memory area + * given heap block. + * + * Input parameters: + * the_heap - pointer to heap header + * starting_address - starting address of the memory block to free. + * size - pointer to size of area + * + * Output parameters: + * size - size of area filled in + * TRUE - if starting_address is valid heap address + * FALSE - if starting_address is invalid heap address + */ + +boolean _Heap_Size_of_user_area( + Heap_Control *the_heap, + void *starting_address, + unsigned32 *size +) +{ + Heap_Block *the_block; + Heap_Block *next_block; + unsigned32 the_size; + + the_block = _Heap_Block_at( starting_address, - (sizeof( void * ) * 2) ); + + if ( !_Heap_Is_block_in( the_heap, the_block ) || + _Heap_Is_block_free( the_block ) ) + return( FALSE ); + + the_size = _Heap_Block_size( the_block ); + next_block = _Heap_Block_at( the_block, the_size ); + + if ( !_Heap_Is_block_in( the_heap, next_block ) || + (the_block->front_flag != next_block->back_flag) ) + return( FALSE ); + + *size = the_size; + return( TRUE ); +} + +/*PAGE + * + * _Heap_Free + * + * This kernel routine returns the memory designated by the + * given heap and given starting address to the memory pool. + * + * Input parameters: + * the_heap - pointer to heap header + * starting_address - starting address of the memory block to free. + * + * Output parameters: + * TRUE - if starting_address is valid heap address + * FALSE - if starting_address is invalid heap address + */ + +boolean _Heap_Free( + Heap_Control *the_heap, + void *starting_address +) +{ + Heap_Block *the_block; + Heap_Block *next_block; + Heap_Block *new_next_block; + Heap_Block *previous_block; + Heap_Block *temporary_block; + unsigned32 the_size; + + the_block = _Heap_Block_at( starting_address, - (sizeof( void * ) * 2) ); + + if ( !_Heap_Is_block_in( the_heap, the_block ) || + _Heap_Is_block_free( the_block ) ) { + return( FALSE ); + } + + the_size = _Heap_Block_size( the_block ); + next_block = _Heap_Block_at( the_block, the_size ); + + if ( !_Heap_Is_block_in( the_heap, next_block ) || + (the_block->front_flag != next_block->back_flag) ) { + return( FALSE ); + } + + if ( _Heap_Is_previous_block_free( the_block ) ) { + previous_block = _Heap_Previous_block( the_block ); + + if ( !_Heap_Is_block_in( the_heap, previous_block ) ) { + return( FALSE ); + } + + if ( _Heap_Is_block_free( next_block ) ) { /* coalesce both */ + previous_block->front_flag += next_block->front_flag + the_size; + temporary_block = _Heap_Next_block( previous_block ); + temporary_block->back_flag = previous_block->front_flag; + next_block->next->previous = next_block->previous; + next_block->previous->next = next_block->next; + } + else { /* coalesce prev */ + previous_block->front_flag = + next_block->back_flag = previous_block->front_flag + the_size; + } + } + else if ( _Heap_Is_block_free( next_block ) ) { /* coalesce next */ + the_block->front_flag = the_size + next_block->front_flag; + new_next_block = _Heap_Next_block( the_block ); + new_next_block->back_flag = the_block->front_flag; + the_block->next = next_block->next; + the_block->previous = next_block->previous; + next_block->previous->next = the_block; + next_block->next->previous = the_block; + + if (the_heap->first == next_block) + the_heap->first = the_block; + } + else { /* no coalesce */ + next_block->back_flag = + the_block->front_flag = the_size; + the_block->previous = _Heap_Head( the_heap ); + the_block->next = the_heap->first; + the_heap->first = the_block; + the_block->next->previous = the_block; + } + + return( TRUE ); +} + +/*PAGE + * + * _Heap_Walk + * + * This kernel routine walks the heap and verifies its correctness. + * + * Input parameters: + * the_heap - pointer to heap header + * source - a numeric indicator of the invoker of this routine + * do_dump - when TRUE print the information + * + * Output parameters: NONE + */ + +#include +#include + +void _Heap_Walk( + Heap_Control *the_heap, + int source, + boolean do_dump +) +{ + Heap_Block *the_block; + Heap_Block *next_block; + int notdone = 1; + + /* + * We don't want to allow walking the heap until we have + * transferred control to the user task so we watch the + * system state. + */ + + if ( !_System_state_Is_up( _System_state_Get() ) ) + return; + + the_block = the_heap->start; + + if (do_dump == TRUE) { + printf("\nPASS: %d start @ 0x%p final 0x%p, first 0x%p last 0x%p\n", + source, the_heap->start, the_heap->final, + the_heap->first, the_heap->last + ); + } + + /* + * Handle the 1st block + */ + + if (the_block->back_flag != HEAP_DUMMY_FLAG) { + printf("PASS: %d Back flag of 1st block isn't HEAP_DUMMY_FLAG\n", source); + } + + while (notdone) { + if (do_dump == TRUE) { + printf("PASS: %d Block @ 0x%p Back %d, Front %d", + source, the_block, + the_block->back_flag, the_block->front_flag); + if ( _Heap_Is_block_free(the_block) ) { + printf( " Prev 0x%p, Next 0x%p\n", + the_block->previous, the_block->next); + } else { + printf("\n"); + } + } + + /* + * Handle the last block + */ + + if ( the_block->front_flag != HEAP_DUMMY_FLAG ) { + next_block = _Heap_Next_block(the_block); + if ( the_block->front_flag != next_block->back_flag ) { + printf("PASS: %d Front and back flags don't match\n", source); + printf(" Current Block: Back - %d, Front - %d", + the_block->back_flag, the_block->front_flag); + if (do_dump == TRUE) { + if (_Heap_Is_block_free(the_block)) { + printf(" Prev 0x%p, Next 0x%p\n", + the_block->previous, the_block->next); + } else { + printf("\n"); + } + } else { + printf("\n"); + } + printf(" Next Block: Back - %d, Front - %d", + next_block->back_flag, next_block->front_flag); + if (do_dump == TRUE) { + if (_Heap_Is_block_free(next_block)) { + printf(" Prev 0x%p, Next 0x%p\n", + the_block->previous, the_block->next); + } else { + printf("\n"); + } + } else { + printf("\n"); + } + } + } + + if (the_block->front_flag == HEAP_DUMMY_FLAG) + notdone = 0; + else + the_block = next_block; + } +} diff --git a/cpukit/score/src/mpci.c b/cpukit/score/src/mpci.c new file mode 100644 index 0000000000..e8d3803d76 --- /dev/null +++ b/cpukit/score/src/mpci.c @@ -0,0 +1,237 @@ +/* + * Multiprocessing Communications Interface (MPCI) Handler + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _MPCI_Handler_initialization + * + * This subprogram performs the initialization necessary for this handler. + */ + +void _MPCI_Handler_initialization ( void ) +{ + _Thread_queue_Initialize( + &_MPCI_Remote_blocked_threads, + RTEMS_FIFO, + STATES_WAITING_FOR_RPC_REPLY + ); +} + +/*PAGE + * + * _MPCI_Initialization + * + * This subprogram initializes the MPCI driver by + * invoking the user provided MPCI initialization callout. + */ + +void _MPCI_Initialization ( void ) +{ + (*_Configuration_MPCI_table->initialization)( + _Configuration_Table, + &_CPU_Table, + _Configuration_MP_table + ); +} + +/*PAGE + * + * _MPCI_Get_packet + * + * This subprogram obtains a packet by invoking the user provided + * MPCI get packet callout. + */ + +rtems_packet_prefix *_MPCI_Get_packet ( void ) +{ + rtems_packet_prefix *the_packet; + + (*_Configuration_MPCI_table->get_packet)( &the_packet ); + + if ( the_packet == NULL ) + rtems_fatal_error_occurred( RTEMS_UNSATISFIED ); + + /* + * Put in a default timeout that will be used for + * all packets that do not otherwise have a timeout. + */ + + the_packet->timeout = MPCI_DEFAULT_TIMEOUT; + + return the_packet; +} + +/*PAGE + * + * _MPCI_Return_packet + * + * This subprogram returns a packet by invoking the user provided + * MPCI return packet callout. + */ + +void _MPCI_Return_packet ( + rtems_packet_prefix *the_packet +) +{ + (*_Configuration_MPCI_table->return_packet)( the_packet ); +} + +/*PAGE + * + * _MPCI_Send_process_packet + * + * This subprogram sends a process packet by invoking the user provided + * MPCI send callout. + */ + +void _MPCI_Send_process_packet ( + unsigned32 destination, + rtems_packet_prefix *the_packet +) +{ + the_packet->source_tid = _Thread_Executing->Object.id; + the_packet->to_convert = + ( the_packet->to_convert - sizeof(rtems_packet_prefix) ) / + sizeof(unsigned32); + + (*_Configuration_MPCI_table->send_packet)( destination, the_packet ); +} + +/*PAGE + * + * _MPCI_Send_request_packet + * + * This subprogram sends a request packet by invoking the user provided + * MPCI send callout. + */ + +rtems_status_code _MPCI_Send_request_packet ( + unsigned32 destination, + rtems_packet_prefix *the_packet, + States_Control extra_state +) +{ + the_packet->source_tid = _Thread_Executing->Object.id; + the_packet->source_priority = _Thread_Executing->current_priority; + the_packet->to_convert = + ( the_packet->to_convert - sizeof(rtems_packet_prefix) ) / + sizeof(unsigned32); + + _Thread_Executing->Wait.id = the_packet->id; + + _Thread_Executing->Wait.queue = &_MPCI_Remote_blocked_threads; + + _Thread_Disable_dispatch(); + + (*_Configuration_MPCI_table->send_packet)( destination, the_packet ); + + _MPCI_Remote_blocked_threads.sync = TRUE; + + /* + * See if we need a default timeout + */ + + if (the_packet->timeout == MPCI_DEFAULT_TIMEOUT) + the_packet->timeout = _Configuration_MPCI_table->default_timeout; + + _Thread_queue_Enqueue( &_MPCI_Remote_blocked_threads, the_packet->timeout ); + + _Thread_Executing->current_state = + _States_Set( extra_state, _Thread_Executing->current_state ); + + _Thread_Enable_dispatch(); + + return _Thread_Executing->Wait.return_code; +} + +/*PAGE + * + * _MPCI_Send_response_packet + * + * This subprogram sends a response packet by invoking the user provided + * MPCI send callout. + */ + +void _MPCI_Send_response_packet ( + unsigned32 destination, + rtems_packet_prefix *the_packet +) +{ + the_packet->source_tid = _Thread_Executing->Object.id; + + (*_Configuration_MPCI_table->send_packet)( destination, the_packet ); +} + +/*PAGE + * + * _MPCI_Receive_packet + * + * This subprogram receives a packet by invoking the user provided + * MPCI receive callout. + */ + +rtems_packet_prefix *_MPCI_Receive_packet ( void ) +{ + rtems_packet_prefix *the_packet; + + (*_Configuration_MPCI_table->receive_packet)( &the_packet ); + + return the_packet; +} + +/*PAGE + * + * _MPCI_Process_response + * + * This subprogram obtains a packet by invoking the user provided + * MPCI get packet callout. + */ + +Thread_Control *_MPCI_Process_response ( + rtems_packet_prefix *the_packet +) +{ + Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( the_packet->id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + case OBJECTS_REMOTE: + the_thread = NULL; /* IMPOSSIBLE */ + break; + case OBJECTS_LOCAL: + _Thread_queue_Extract( &_MPCI_Remote_blocked_threads, the_thread ); + the_thread->Wait.return_code = the_packet->return_code; + _Thread_Unnest_dispatch(); + break; + } + + return the_thread; +} + +/* end of file */ diff --git a/cpukit/score/src/object.c b/cpukit/score/src/object.c new file mode 100644 index 0000000000..71c365fa1e --- /dev/null +++ b/cpukit/score/src/object.c @@ -0,0 +1,228 @@ +/* + * Object Handler + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Objects_Handler_initialization + * + * This routine initializes the object handler. + * + * Input parameters: + * node - local node + * maximum_global_objects - number of configured global objects + * + * Output parameters: NONE + */ + +void _Objects_Handler_initialization( + unsigned32 node, + unsigned32 maximum_global_objects +) +{ + _Objects_Local_node = node; + + _Objects_MP_Handler_initialization( maximum_global_objects ); +} + +/*PAGE + * + * _Objects_Initialize_information + * + * This routine initializes all object information related data structures. + * + * Input parameters: + * information - object class + * supports_global - TRUE if this is a global object class + * maximum - maximum objects of this class + * size - size of this object's control block + * + * Output parameters: NONE + */ + +void _Objects_Initialize_information( + Objects_Information *information, + boolean supports_global, + unsigned32 maximum, + unsigned32 size +) +{ + unsigned32 minimum_index; + unsigned32 index; + Objects_Control *the_object; + + information->maximum = maximum; + + if ( maximum == 0 ) minimum_index = 0; + else minimum_index = 1; + + information->minimum_id = + _Objects_Build_id( _Objects_Local_node, minimum_index ); + + information->maximum_id = + _Objects_Build_id( _Objects_Local_node, maximum ); + + information->local_table = _Workspace_Allocate_or_fatal_error( + (maximum + 1) * sizeof(Objects_Control *) + ); + + information->name_table = _Workspace_Allocate_or_fatal_error( + (maximum + 1) * sizeof(Objects_Name) + ); + + for ( index=0 ; index < maximum ; index++ ) { + information->local_table[ index ] = NULL; + information->name_table[ index ] = 0; + } + + if ( maximum == 0 ) { + _Chain_Initialize_empty( &information->Inactive ); + } else { + + + _Chain_Initialize( + &information->Inactive, + _Workspace_Allocate_or_fatal_error( maximum * size ), + maximum, + size + ); + + the_object = (Objects_Control *) information->Inactive.first; + for ( index=1; + index <= maximum ; + index++ ) { + the_object->id = _Objects_Build_id( _Objects_Local_node, index ); + the_object = (Objects_Control *) the_object->Node.next; + } + + } + + if ( supports_global == TRUE && _Configuration_Is_multiprocessing() ) { + + information->global_table = _Workspace_Allocate_or_fatal_error( + (_Configuration_MP_table->maximum_nodes + 1) * sizeof(Chain_Control) + ); + + for ( index=1; + index <= _Configuration_MP_table->maximum_nodes ; + index++ ) + _Chain_Initialize_empty( &information->global_table[ index ] ); + } + else + information->global_table = NULL; +} + +/*PAGE + * + * _Objects_Name_to_id + * + * These kernel routines search the object table(s) for the given + * object name and returns the associated object id. + * + * Input parameters: + * information - object information + * name - user defined object name + * node - node indentifier (0 indicates any node) + * id - address of return ID + * + * Output parameters: + * obj_id - object id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code _Objects_Name_to_id( + Objects_Information *information, + Objects_Name name, + unsigned32 node, + Objects_Id *id +) +{ + Objects_Name *names; + unsigned32 index; + + if ( name == 0 ) + return( RTEMS_INVALID_NAME ); + + if ( (information->maximum != 0) && + (node == RTEMS_SEARCH_ALL_NODES || + node == RTEMS_SEARCH_LOCAL_NODE || + _Objects_Is_local_node( node )) ) { + for ( names = information->name_table, index = 1; + index <= information->maximum; + index++ + ) + if ( name == names[ index ] ) { + *id = _Objects_Build_id( _Objects_Local_node, index ); + return( RTEMS_SUCCESSFUL ); + } + } + + if ( _Objects_Is_local_node( node ) || node == RTEMS_SEARCH_LOCAL_NODE ) + return( RTEMS_INVALID_NAME ); + + return ( _Objects_MP_Global_name_search( information, name, node, id ) ); +} + +/*PAGE + * + * _Objects_Get + * + * This routine sets the object pointer for the given + * object id based on the given object information structure. + * + * Input parameters: + * information - pointer to entry in table for this class + * id - object id to search for + * location - address of where to store the location + * + * Output parameters: + * returns - address of object if local + * location - one of the following: + * OBJECTS_ERROR - invalid object ID + * OBJECTS_REMOTE - remote object + * OBJECTS_LOCAL - local object + */ + +Objects_Control *_Objects_Get( + Objects_Information *information, + Objects_Id id, + Objects_Locations *location +) +{ + Objects_Control *the_object; + unsigned32 index; + + index = id - information->minimum_id; + if ( information->maximum >= index ) { + _Thread_Disable_dispatch(); + if ( (the_object = information->local_table[index+1]) != NULL ) { + *location = OBJECTS_LOCAL; + return( the_object ); + } + _Thread_Enable_dispatch(); + *location = OBJECTS_ERROR; + return( NULL ); + } + *location = OBJECTS_ERROR; + _Objects_MP_Is_remote( information, id, location, &the_object ); + return the_object; +} diff --git a/cpukit/score/src/objectmp.c b/cpukit/score/src/objectmp.c new file mode 100644 index 0000000000..d75a34b150 --- /dev/null +++ b/cpukit/score/src/objectmp.c @@ -0,0 +1,250 @@ +/* + * Multiprocessing Support for the Object Handler + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include + +/*PAGE + * + * _Objects_MP_Handler_initialization + * + */ + +void _Objects_MP_Handler_initialization ( + unsigned32 maximum_global_objects +) +{ + + if ( maximum_global_objects == 0 ) { + _Chain_Initialize_empty( &_Objects_MP_Inactive_global_objects ); + return; + } + + _Chain_Initialize( + &_Objects_MP_Inactive_global_objects, + _Workspace_Allocate_or_fatal_error( + maximum_global_objects * sizeof( Objects_MP_Control ) + ), + maximum_global_objects, + sizeof( Objects_MP_Control ) + ); + +} + +/*PAGE + * + * _Objects_MP_Open + * + */ + +boolean _Objects_MP_Open ( + Objects_Information *information, + Objects_Name the_name, + Objects_Id the_id, + boolean is_fatal_error +) +{ + Objects_MP_Control *the_global_object; + + the_global_object = _Objects_MP_Allocate_global_object(); + if ( _Objects_MP_Is_null_global_object( the_global_object ) ) { + + if ( is_fatal_error == FALSE ) + return FALSE; + + rtems_fatal_error_occurred( RTEMS_TOO_MANY ); + + } + + the_global_object->Object.id = the_id; + the_global_object->name = the_name; + + _Chain_Prepend( + &information->global_table[ rtems_get_node( the_id ) ], + &the_global_object->Object.Node + ); + + return TRUE; +} + +/*PAGE + * + * _Objects_MP_Close + * + */ + +void _Objects_MP_Close ( + Objects_Information *information, + Objects_Id the_id +) +{ + Chain_Control *the_chain; + Chain_Node *the_node; + Objects_MP_Control *the_object; + + the_chain = &information->global_table[ rtems_get_node( the_id ) ]; + + for ( the_node = the_chain->first ; + !_Chain_Is_tail( the_chain, the_node ) ; + the_node = the_node->next ) { + + the_object = (Objects_MP_Control *) the_node; + + if ( _Objects_Are_ids_equal( the_object->Object.id, the_id ) ) { + + _Chain_Extract( the_node ); + _Objects_MP_Free_global_object( the_object ); + + return; + + } + + } + + rtems_fatal_error_occurred( RTEMS_INVALID_ID ); + + +} + +/*PAGE + * + * _Objects_MP_Global_name_search + * + */ + +rtems_status_code _Objects_MP_Global_name_search ( + Objects_Information *information, + Objects_Name the_name, + unsigned32 nodes_to_search, + Objects_Id *the_id +) +{ + unsigned32 low_node; + unsigned32 high_node; + unsigned32 node_index; + Chain_Control *the_chain; + Chain_Node *the_node; + Objects_MP_Control *the_object; + + + if ( nodes_to_search > _Configuration_MP_table->maximum_nodes ) + return ( RTEMS_INVALID_NODE ); + + if ( information->global_table == NULL ) + return ( RTEMS_INVALID_NAME ); + + if ( nodes_to_search == RTEMS_SEARCH_ALL_NODES || + nodes_to_search == RTEMS_SEARCH_OTHER_NODES ) { + low_node = 1; + high_node = _Configuration_MP_table->maximum_nodes; + } else { + low_node = + high_node = nodes_to_search; + } + + _Thread_Disable_dispatch(); + + for ( node_index = low_node ; node_index <= high_node ; node_index++ ) { + + /* + * NOTE: The local node was search (if necessary) by + * _Objects_Name_to_id before this was invoked. + */ + + if ( !_Objects_Is_local_node( node_index ) ) { + the_chain = &information->global_table[ node_index ]; + + for ( the_node = the_chain->first ; + !_Chain_Is_tail( the_chain, the_node ) ; + the_node = the_node->next ) { + + the_object = (Objects_MP_Control *) the_node; + + if ( the_object->name == the_name ) { + *the_id = the_object->Object.id; + _Thread_Enable_dispatch(); + return ( RTEMS_SUCCESSFUL ); + } + } + } + } + + _Thread_Enable_dispatch(); + return ( RTEMS_INVALID_NAME ); +} + +/*PAGE + * + * _Objects_MP_Is_remote + * + */ + +void _Objects_MP_Is_remote ( + Objects_Information *information, + Objects_Id the_id, + Objects_Locations *location, + Objects_Control **the_object +) +{ + unsigned32 node; + Chain_Control *the_chain; + Chain_Node *the_node; + Objects_MP_Control *the_global_object; + + node = rtems_get_node( the_id ); + + /* + * NOTE: The local node was search (if necessary) by + * _Objects_Name_to_id before this was invoked. + * + * The NODE field of an object id cannot be 0 + * because 0 is an invalid node number. + */ + + if ( node == 0 || + _Objects_Is_local_node( node ) || + node > _Configuration_MP_table->maximum_nodes || + information->global_table == NULL ) { + + *location = OBJECTS_ERROR; + *the_object = NULL; + return; + } + + _Thread_Disable_dispatch(); + + the_chain = &information->global_table[ node ]; + + for ( the_node = the_chain->first ; + !_Chain_Is_tail( the_chain, the_node ) ; + the_node = the_node->next ) { + + the_global_object = (Objects_MP_Control *) the_node; + + if ( _Objects_Are_ids_equal( the_global_object->Object.id, the_id ) ) { + _Thread_Unnest_dispatch(); + *location = OBJECTS_REMOTE; + *the_object = (Objects_Control *) the_global_object; + return; + } + } + + _Thread_Enable_dispatch(); + *location = OBJECTS_ERROR; + *the_object = NULL; + +} diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c new file mode 100644 index 0000000000..2d9fc33e6b --- /dev/null +++ b/cpukit/score/src/thread.c @@ -0,0 +1,805 @@ +/* + * Thread Handler + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Thread_Handler_initialization + * + * This routine initializes all thread manager related data structures. + * + * Input parameters: + * maximum_tasks - number of tasks to initialize + * ticks_per_timeslice - clock ticks per quantum + * + * Output parameters: NONE + */ + +void _Thread_Handler_initialization( + unsigned32 maximum_tasks, + unsigned32 ticks_per_timeslice, + unsigned32 maximum_proxies +) +{ + unsigned32 index; + + _Context_Switch_necessary = FALSE; + _Thread_Executing = NULL; + _Thread_Heir = NULL; + _Thread_Allocated_fp = NULL; + + _Thread_Ticks_remaining_in_timeslice = ticks_per_timeslice; + _Thread_Ticks_per_timeslice = ticks_per_timeslice; + + _Objects_Initialize_information( + &_Thread_Information, + TRUE, + maximum_tasks, + sizeof( Thread_Control ) + ); + + _Thread_Ready_chain = _Workspace_Allocate_or_fatal_error( + (RTEMS_MAXIMUM_PRIORITY + 1) * sizeof(Chain_Control) + ); + + for ( index=0; index <= RTEMS_MAXIMUM_PRIORITY ; index++ ) + _Chain_Initialize_empty( &_Thread_Ready_chain[ index ] ); + + _Thread_MP_Handler_initialization( maximum_proxies ); +} + +/*PAGE + * + * _Thread_Start_multitasking + * + * This kernel routine readies the requested thread, the thread chain + * is adjusted. A new heir thread may be selected. + * + * Input parameters: + * system_thread - pointer to system initialization thread control block + * idle_thread - pointer to idle thread control block + * + * Output parameters: NONE + * + * NOTE: This routine uses the "blocking" heir selection mechanism. + * This insures the correct heir after a thread restart. + * + * INTERRUPT LATENCY: + * ready chain + * select heir + */ + +void _Thread_Start_multitasking( + Thread_Control *system_thread, + Thread_Control *idle_thread +) +{ + + _Thread_Executing = + _Thread_Heir = + _Thread_MP_Receive = system_thread; + + /* + * Scheduling will not work "correctly" until the above + * statements have been executed. + */ + + _Thread_Ready( system_thread ); + _Thread_Ready( idle_thread ); + + _Context_Switch_necessary = FALSE; + + _Context_Switch( &_Thread_BSP_context, &system_thread->Registers ); + +} + +/*PAGE + * + * _Thread_Dispatch + * + * This kernel routine determines if a dispatch is needed, and if so + * dispatches to the heir thread. Once the heir is running an attempt + * is made to dispatch any ASRs. + * + * ALTERNATE ENTRY POINTS: + * void _Thread_Enable_dispatch(); + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * dispatch thread + * no dispatch thread + */ + +#if ( CPU_INLINE_ENABLE_DISPATCH == FALSE ) +void _Thread_Enable_dispatch( void ) +{ + if ( --_Thread_Dispatch_disable_level ) + return; + _Thread_Dispatch(); +} +#endif + +void _Thread_Dispatch( void ) +{ + Thread_Control *executing; + Thread_Control *heir; + ISR_Level level; + rtems_signal_set signal_set; + rtems_mode previous_mode; + + executing = _Thread_Executing; + _ISR_Disable( level ); + while ( _Context_Switch_necessary == TRUE ) { + heir = _Thread_Heir; + _Thread_Dispatch_disable_level = 1; + _Context_Switch_necessary = FALSE; + _Thread_Executing = heir; + _ISR_Enable( level ); + + _User_extensions_Task_switch( executing, heir ); + + _Thread_Ticks_remaining_in_timeslice = _Thread_Ticks_per_timeslice; + + /* + * 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. + */ + +#if ( CPU_HARDWARE_FP == TRUE ) +#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE ) + if ( (heir->fp_context != NULL) && !_Thread_Is_allocated_fp( heir ) ) { + if ( _Thread_Allocated_fp != NULL ) + _Context_Save_fp( &_Thread_Allocated_fp->fp_context ); + _Context_Restore_fp( &heir->fp_context ); + _Thread_Allocated_fp = heir; + } +#else + if ( executing->fp_context != NULL ) + _Context_Save_fp( &executing->fp_context ); + + if ( heir->fp_context != NULL ) + _Context_Restore_fp( &heir->fp_context ); +#endif +#endif + + _Context_Switch( &executing->Registers, &heir->Registers ); + + executing = _Thread_Executing; + _ISR_Disable( level ); + } + + _Thread_Dispatch_disable_level = 0; + + if ( _ASR_Are_signals_pending( &executing->Signal ) ) { + signal_set = executing->Signal.signals_posted; + executing->Signal.signals_posted = 0; + _ISR_Enable( level ); + + executing->Signal.nest_level += 1; + if (_Thread_Change_mode( executing->Signal.mode_set, + RTEMS_ALL_MODE_MASKS, &previous_mode )) + _Thread_Dispatch(); + + (*executing->Signal.handler)( signal_set ); + + executing->Signal.nest_level -= 1; + if (_Thread_Change_mode( previous_mode, + RTEMS_ALL_MODE_MASKS, &previous_mode )) + _Thread_Dispatch(); + } + else + _ISR_Enable( level ); +} + +/*PAGE + * + * _Thread_Ready + * + * This kernel routine readies the requested thread, the thread chain + * is adjusted. A new heir thread may be selected. + * + * Input parameters: + * the_thread - pointer to thread control block + * + * Output parameters: NONE + * + * NOTE: This routine uses the "blocking" heir selection mechanism. + * This insures the correct heir after a thread restart. + * + * INTERRUPT LATENCY: + * ready chain + * select heir + */ + +void _Thread_Ready( + Thread_Control *the_thread +) +{ + ISR_Level level; + Thread_Control *heir; + + _ISR_Disable( level ); + + the_thread->current_state = STATES_READY; + + _Priority_Add_to_bit_map( &the_thread->Priority_map ); + + _Chain_Append_unprotected( the_thread->ready, &the_thread->Object.Node ); + + _ISR_Flash( level ); + + _Thread_Calculate_heir(); + + heir = _Thread_Heir; + + if ( !_Thread_Is_executing( heir ) && + _Modes_Is_preempt( _Thread_Executing->current_modes ) ) + _Context_Switch_necessary = TRUE; + + _ISR_Enable( level ); +} + +/*PAGE + * + * _Thread_Clear_state + * + * This kernel routine clears the appropriate states in the + * requested thread. The thread ready chain is adjusted if + * necessary and the Heir thread is set accordingly. + * + * Input parameters: + * the_thread - pointer to thread control block + * state - state set to clear + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * priority map + * select heir + */ + +void _Thread_Clear_state( + Thread_Control *the_thread, + States_Control state +) +{ + ISR_Level level; + + _ISR_Disable( level ); + the_thread->current_state = + _States_Clear( state, the_thread->current_state ); + + if ( _States_Is_ready( the_thread->current_state ) ) { + + _Priority_Add_to_bit_map( &the_thread->Priority_map ); + + _Chain_Append_unprotected( the_thread->ready, &the_thread->Object.Node ); + + _ISR_Flash( level ); + + if ( the_thread->current_priority < _Thread_Heir->current_priority ) { + _Thread_Heir = the_thread; + if ( _Modes_Is_preempt( _Thread_Executing->current_modes ) ) + _Context_Switch_necessary = TRUE; + } + } + _ISR_Enable( level ); +} + +/*PAGE + * + * _Thread_Set_state + * + * This kernel routine sets the requested state in the THREAD. The + * THREAD chain is adjusted if necessary. + * + * Input parameters: + * the_thread - pointer to thread control block + * state - state to be set + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * ready chain + * select map + */ + +void _Thread_Set_state( + Thread_Control *the_thread, + States_Control state +) +{ + ISR_Level level; + Chain_Control *ready; + + ready = the_thread->ready; + _ISR_Disable( level ); + if ( !_States_Is_ready( the_thread->current_state ) ) { + the_thread->current_state = + _States_Set( state, the_thread->current_state ); + _ISR_Enable( level ); + return; + } + + the_thread->current_state = state; + + if ( _Chain_Has_only_one_node( ready ) ) { + + _Chain_Initialize_empty( ready ); + _Priority_Remove_from_bit_map( &the_thread->Priority_map ); + + } else + _Chain_Extract_unprotected( &the_thread->Object.Node ); + + _ISR_Flash( level ); + + if ( _Thread_Is_heir( the_thread ) ) + _Thread_Calculate_heir(); + + if ( _Thread_Is_executing( the_thread ) ) + _Context_Switch_necessary = TRUE; + + _ISR_Enable( level ); +} + +/*PAGE + * + * _Thread_Set_transient + * + * This kernel routine places the requested thread in the transient state + * which will remove it from the ready queue, if necessary. No + * rescheduling is necessary because it is assumed that the transient + * state will be cleared before dispatching is enabled. + * + * Input parameters: + * the_thread - pointer to thread control block + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * only case + */ + +void _Thread_Set_transient( + Thread_Control *the_thread +) +{ + ISR_Level level; + unsigned32 old_state; + Chain_Control *ready; + + ready = the_thread->ready; + _ISR_Disable( level ); + + old_state = the_thread->current_state; + the_thread->current_state = _States_Set( STATES_TRANSIENT, old_state ); + + if ( _States_Is_ready( old_state ) ) { + if ( _Chain_Has_only_one_node( ready ) ) { + + _Chain_Initialize_empty( ready ); + _Priority_Remove_from_bit_map( &the_thread->Priority_map ); + + } else + _Chain_Extract_unprotected( &the_thread->Object.Node ); + } + + _ISR_Enable( level ); + +} + +/*PAGE + * + * _Thread_Reset_timeslice + * + * This routine will remove the running thread from the ready chain + * and place it immediately at the rear of this chain and then the + * timeslice counter is reset. The heir THREAD will be updated if + * the running is also the currently the heir. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * ready chain + * select heir + */ + +void _Thread_Reset_timeslice( void ) +{ + ISR_Level level; + Thread_Control *executing; + Chain_Control *ready; + + executing = _Thread_Executing; + ready = executing->ready; + _ISR_Disable( level ); + if ( _Chain_Has_only_one_node( ready ) ) { + _Thread_Ticks_remaining_in_timeslice = _Thread_Ticks_per_timeslice; + _ISR_Enable( level ); + return; + } + _Chain_Extract_unprotected( &executing->Object.Node ); + _Chain_Append_unprotected( ready, &executing->Object.Node ); + + _ISR_Flash( level ); + + if ( _Thread_Is_heir( executing ) ) + _Thread_Heir = (Thread_Control *) ready->first; + + _Context_Switch_necessary = TRUE; + + _ISR_Enable( level ); +} + +/*PAGE + * + * _Thread_Tickle_timeslice + * + * This scheduler routine determines if timeslicing is enabled + * for the currently executing thread and, if so, updates the + * timeslice count and checks for timeslice expiration. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _Thread_Tickle_timeslice( void ) +{ + if ( ( _Modes_Is_timeslice(_Thread_Executing->current_modes) ) && + ( _States_Is_ready( _Thread_Executing->current_state ) ) && + ( --_Thread_Ticks_remaining_in_timeslice == 0 ) ) { + _Thread_Reset_timeslice(); + } +} + +/*PAGE + * + * _Thread_Yield_processor + * + * This kernel routine will remove the running THREAD from the ready chain + * and place it immediatly at the rear of this chain. Reset timeslice + * and yield the processor functions both use this routine, therefore if + * reset is TRUE and this is the only thread on the chain then the + * timeslice counter is reset. The heir THREAD will be updated if the + * running is also the currently the heir. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * ready chain + * select heir + */ + +void _Thread_Yield_processor( void ) +{ + ISR_Level level; + Thread_Control *executing; + Chain_Control *ready; + + executing = _Thread_Executing; + ready = executing->ready; + _ISR_Disable( level ); + if ( !_Chain_Has_only_one_node( ready ) ) { + _Chain_Extract_unprotected( &executing->Object.Node ); + _Chain_Append_unprotected( ready, &executing->Object.Node ); + + _ISR_Flash( level ); + + if ( _Thread_Is_heir( executing ) ) + _Thread_Heir = (Thread_Control *) ready->first; + _Context_Switch_necessary = TRUE; + } + else if ( !_Thread_Is_heir( executing ) ) + _Context_Switch_necessary = TRUE; + + _ISR_Enable( level ); +} + +/*PAGE + * + * _Thread_Load_environment + * + * Load starting environment for another thread from its start area in the + * thread. Only called from t_restart and t_start. + * + * Input parameters: + * the_thread - thread control block pointer + * + * Output parameters: NONE + */ + +void _Thread_Load_environment( + Thread_Control *the_thread +) +{ + if ( the_thread->Start.fp_context ) { + the_thread->fp_context = the_thread->Start.fp_context; + _Context_Initialize_fp( &the_thread->fp_context ); + } + + _Context_Initialize( + &the_thread->Registers, + the_thread->Start.Initial_stack.area, + the_thread->Start.Initial_stack.size, + _Modes_Get_interrupt_level( the_thread->Start.initial_modes ), + _Thread_Handler + ); + +} + +/*PAGE + * + * _Thread_Handler + * + * This routine is the default thread exitted error handler. It is + * returned to when a thread exits. The configured fatal error handler + * is invoked to process the exit. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _Thread_Handler( void ) +{ + Thread_Control *executing; + + executing = _Thread_Executing; + + _Thread_Dispatch_disable_level = 0; + + /* + * Do the 'begin' here instead of after the context switch. + * This ensures 'switch' extensions can not be called before + * 'begin' extensions. + */ + + _User_extensions_Task_begin( executing ); + + if ( _Thread_Is_context_switch_necessary() ) + _Thread_Dispatch(); + + (*executing->Start.entry_point)( executing->Start.initial_argument ); + + _User_extensions_Task_exitted( executing ); + + rtems_fatal_error_occurred( RTEMS_TASK_EXITTED ); +} + +/*PAGE + * + * _Thread_Delay_ended + * + * This routine processes a thread whose delay period has ended. + * It is called by the watchdog handler. + * + * Input parameters: + * id - thread id + * + * Output parameters: NONE + */ + +void _Thread_Delay_ended( + Objects_Id id, + void *ignored +) +{ + Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + case OBJECTS_REMOTE: /* impossible */ + break; + case OBJECTS_LOCAL: + _Thread_Unblock( the_thread ); + _Thread_Unnest_dispatch(); + break; + } +} + +/*PAGE + * + * _Thread_Change_priority + * + * This kernel routine changes the priority of the thread. The + * thread chain is adjusted if necessary. + * + * Input parameters: + * the_thread - pointer to thread control block + * new_priority - ultimate priority + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * ready chain + * select heir + */ + +void _Thread_Change_priority( + Thread_Control *the_thread, + rtems_task_priority new_priority +) +{ + ISR_Level level; + + _Thread_Set_transient( the_thread ); + + if ( the_thread->current_priority != new_priority ) + _Thread_Set_priority( the_thread, new_priority ); + + _ISR_Disable( level ); + + the_thread->current_state = + _States_Clear( STATES_TRANSIENT, the_thread->current_state ); + + if ( ! _States_Is_ready( the_thread->current_state ) ) { + _ISR_Enable( level ); + return; + } + + _Priority_Add_to_bit_map( &the_thread->Priority_map ); + _Chain_Append_unprotected( the_thread->ready, &the_thread->Object.Node ); + + _ISR_Flash( level ); + + _Thread_Calculate_heir(); + + if ( !_Thread_Is_executing_also_the_heir() && + _Modes_Is_preempt(_Thread_Executing->current_modes) ) + _Context_Switch_necessary = TRUE; + + _ISR_Enable( level ); +} + +/*PAGE + * + * _Thread_Set_priority + * + * This directive enables and disables several modes of + * execution for the requesting thread. + * + * Input parameters: + * the_thread - pointer to thread priority + * new_priority - new priority + * + * Output: NONE + */ + +void _Thread_Set_priority( + Thread_Control *the_thread, + rtems_task_priority new_priority +) +{ + the_thread->current_priority = new_priority; + the_thread->ready = &_Thread_Ready_chain[ new_priority ]; + + _Priority_Initialize_information( &the_thread->Priority_map, new_priority ); +} + +/*PAGE + * + * _Thread_Change_mode + * + * This routine enables and disables several modes of + * execution for the requesting thread. + * + * Input parameters: + * mode - new mode + * mask - mask + * old_mode_set - address of previous mode + * + * Output: + * *old_mode_set - previous mode + * returns TRUE if scheduling necessary + * + * INTERRUPT LATENCY: + * only one case + */ + +boolean _Thread_Change_mode( + unsigned32 new_mode_set, + unsigned32 mask, + unsigned32 *old_mode_set +) +{ + rtems_mode changed; + rtems_mode threads_new_mode_set; + Thread_Control *executing; + boolean need_dispatch; + + executing = _Thread_Executing; + *old_mode_set = executing->current_modes; + + _Modes_Change( executing->current_modes, + new_mode_set, mask, &threads_new_mode_set, &changed ); + + _Modes_Set_interrupt_level( threads_new_mode_set ); + + if ( _Modes_Mask_changed( changed, RTEMS_ASR_MASK ) ) + _ASR_Swap_signals( &executing->Signal ); + + executing->current_modes = threads_new_mode_set; + need_dispatch = TRUE; + + if ( !_States_Is_ready( executing->current_state ) || + ( !_Thread_Is_heir( executing ) && + _Modes_Is_preempt(threads_new_mode_set) ) ) + + _Context_Switch_necessary = TRUE; + + else if ( !_ASR_Are_signals_pending( &executing->Signal ) ) + + need_dispatch = FALSE; + + return need_dispatch; +} + +/*PAGE + * + * _Thread_Get + * + * NOTE: If we are not using static inlines, this must be a real + * subroutine call. + */ + +#ifndef USE_INLINES + +STATIC INLINE Thread_Control *_Thread_Get ( + Objects_Id id, + unsigned32 *location +) +{ + if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ) { + _Thread_Disable_dispatch(); + *location = OBJECTS_LOCAL; + return( _Thread_Executing ); + } + + return (Thread_Control *) _Objects_Get( &_Thread_Information, id, location ); +} +#endif + diff --git a/cpukit/score/src/threadmp.c b/cpukit/score/src/threadmp.c new file mode 100644 index 0000000000..5d352e2d25 --- /dev/null +++ b/cpukit/score/src/threadmp.c @@ -0,0 +1,229 @@ +/* + * Multiprocessing Support for the Thread Handler + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include + +/*PAGE + * + * _Thread_MP_Handler_initialization + * + */ + +void _Thread_MP_Handler_initialization ( + unsigned32 maximum_proxies +) +{ + + _Chain_Initialize_empty( &_Thread_MP_Active_proxies ); + + if ( maximum_proxies == 0 ) { + _Chain_Initialize_empty( &_Thread_MP_Inactive_proxies ); + return; + } + + + _Chain_Initialize( + &_Thread_MP_Inactive_proxies, + _Workspace_Allocate_or_fatal_error( + maximum_proxies * sizeof( Thread_Proxy_control ) + ), + maximum_proxies, + sizeof( Thread_Proxy_control ) + ); + +} + +/*PAGE + * + * _Thread_MP_Allocate_proxy + * + */ + +Thread_Control *_Thread_MP_Allocate_proxy ( + States_Control the_state +) +{ + Thread_Control *the_thread; + Thread_Proxy_control *the_proxy; + + the_thread = (Thread_Control *)_Chain_Get( &_Thread_MP_Inactive_proxies ); + + if ( !_Thread_Is_null( the_thread ) ) { + + the_proxy = (Thread_Proxy_control *) the_thread; + + _Thread_Executing->Wait.return_code = RTEMS_PROXY_BLOCKING; + + the_proxy->receive_packet = _Thread_MP_Receive->receive_packet; + + the_proxy->Object.id = _Thread_MP_Receive->receive_packet->source_tid; + + the_proxy->current_priority = + _Thread_MP_Receive->receive_packet->source_priority; + + the_proxy->current_state = _States_Set( STATES_DORMANT, the_state ); + + the_proxy->Wait = _Thread_Executing->Wait; + + _Chain_Append( &_Thread_MP_Active_proxies, &the_proxy->Active ); + + return the_thread; + } + + rtems_fatal_error_occurred( RTEMS_TOO_MANY ); + + /* + * NOTE: The following return insures that the compiler will + * think that all paths return a value. + */ + + return NULL; +} + +/*PAGE + * + * _Thread_MP_Find_proxy + * + */ + +/* + * The following macro provides the offset of the Active element + * in the Thread_Proxy_control structure. This is the logical + * equivalent of the POSITION attribute in Ada. + */ + +#define _Thread_MP_Proxy_Active_offset \ + ((unsigned32)&(((Thread_Proxy_control *)0))->Active) + +Thread_Control *_Thread_MP_Find_proxy ( + Objects_Id the_id +) +{ + + Chain_Node *proxy_node; + Thread_Control *the_thread; + ISR_Level level; + +restart: + + _ISR_Disable( level ); + + for ( proxy_node = _Thread_MP_Active_proxies.first; + !_Chain_Is_tail( &_Thread_MP_Active_proxies, proxy_node ) ; + ) { + + the_thread = _Addresses_Subtract_offset( + proxy_node, + _Thread_MP_Proxy_Active_offset + ); + + if ( _Objects_Are_ids_equal( the_thread->Object.id, the_id ) ) { + _ISR_Enable( level ); + return the_thread; + } + + _ISR_Flash( level ); + + proxy_node = proxy_node->next; + + /* + * A proxy which is only dormant is not in a blocking state. + * Therefore, we are looking at proxy which has been moved from + * active to inactive chain (by an ISR) and need to restart + * the search. + */ + + if ( _States_Is_only_dormant( the_thread->current_state ) ) { + _ISR_Enable( level ); + goto restart; + } + } + + _ISR_Enable( level ); + return NULL; +} + +/*PAGE + * + * _Thread_MP_Block + * + */ + +void _Thread_MP_Block( void ) +{ + ISR_Level level; + + _ISR_Disable( level ); + + if ( _Thread_MP_Receive->Notepads[ 0 ] != 0 ) { + _Priority_Remove_from_bit_map( &_Thread_MP_Receive->Priority_map ); + + _Thread_MP_Receive->current_state = STATES_SUSPENDED; + + _ISR_Flash( level ); + + _Thread_Calculate_heir(); + + _Context_Switch_necessary = TRUE; + + _ISR_Enable( level ); + + _Thread_Dispatch_disable_level = 0; + + _Thread_Dispatch(); + + return; + + } + _ISR_Enable( level ); + +} + +/*PAGE + * + * _Thread_MP_Ready + * + */ + +void _Thread_MP_Ready( void ) +{ + ISR_Level level; + + _ISR_Disable( level ); + + if ( _States_Is_suspended( _Thread_MP_Receive->current_state ) ) { + _Priority_Add_to_bit_map( &_Thread_MP_Receive->Priority_map ); + + _Thread_MP_Receive->current_state = STATES_READY; + + _Thread_Heir = _Thread_MP_Receive; + + _Context_Switch_necessary = TRUE; + + _ISR_Enable( level ); + + if ( _Thread_Is_dispatching_enabled() ) + _Thread_Dispatch(); + + } else { + + _Thread_MP_Receive->Notepads[ 0 ] = 0; + _ISR_Enable( level ); + + } +} diff --git a/cpukit/score/src/threadq.c b/cpukit/score/src/threadq.c new file mode 100644 index 0000000000..60ffb5db38 --- /dev/null +++ b/cpukit/score/src/threadq.c @@ -0,0 +1,837 @@ +/* + * Thread Queue Handler + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Thread_queue_Initialize + * + * This routine initializes the specified threadq. + * + * Input parameters: + * the_thread_queue - pointer to a threadq header + * attribute_set - used to determine queueing discipline + * state - state of waiting threads + * + * Output parameters: NONE + */ + +void _Thread_queue_Initialize( + Thread_queue_Control *the_thread_queue, + rtems_attribute attribute_set, + States_Control state +) +{ + unsigned32 index; + + if ( _Attributes_Is_priority( attribute_set ) ) { + the_thread_queue->discipline = THREAD_QUEUE_DATA_PRIORITY_DISCIPLINE; + for( index=0 ; + index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ; + index++) + _Chain_Initialize_empty( &the_thread_queue->Queues.Priority[index] ); + } + else { + the_thread_queue->discipline = THREAD_QUEUE_DATA_FIFO_DISCIPLINE; + _Chain_Initialize_empty( &the_thread_queue->Queues.Fifo ); + } + + the_thread_queue->state = state; + +} + +/*PAGE + * + * _Thread_queue_Enqueue + * + * This routine blocks a thread, places it on a thread, and optionally + * starts a timeout timer. + * + * Input parameters: + * the_thread_queue - pointer to threadq + * timeout - interval to wait + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * only case + */ + +void _Thread_queue_Enqueue( + Thread_queue_Control *the_thread_queue, + rtems_interval timeout +) +{ + Thread_Control *the_thread; + + the_thread = _Thread_Executing; + + if ( _Thread_MP_Is_receive( the_thread ) ) + the_thread = _Thread_MP_Allocate_proxy( the_thread_queue->state ); + else + _Thread_Set_state( the_thread, the_thread_queue->state ); + + if ( timeout ) { + _Watchdog_Initialize( + &the_thread->Timer, + _Thread_queue_Timeout, + the_thread->Object.id, + NULL + ); + + _Watchdog_Insert_ticks( + &the_thread->Timer, + timeout, + WATCHDOG_NO_ACTIVATE + ); + } + + switch( the_thread_queue->discipline ) { + case THREAD_QUEUE_DATA_FIFO_DISCIPLINE: + _Thread_queue_Enqueue_fifo( the_thread_queue, the_thread, timeout ); + break; + case THREAD_QUEUE_DATA_PRIORITY_DISCIPLINE: + _Thread_queue_Enqueue_priority( + the_thread_queue, the_thread, timeout ); + break; + } +} + +/*PAGE + * + * _Thread_queue_Dequeue + * + * This routine removes a thread from the specified threadq. If the + * threadq discipline is RTEMS_FIFO, it unblocks a thread, and cancels its + * timeout timer. Priority discipline is processed elsewhere. + * + * Input parameters: + * the_thread_queue - pointer to threadq + * + * Output parameters: + * returns - thread dequeued or NULL + * + * INTERRUPT LATENCY: + * check sync + * RTEMS_FIFO + */ + +Thread_Control *_Thread_queue_Dequeue( + Thread_queue_Control *the_thread_queue +) +{ + Thread_Control *the_thread; + ISR_Level level; + + switch ( the_thread_queue->discipline ) { + case THREAD_QUEUE_DATA_FIFO_DISCIPLINE: + the_thread = _Thread_queue_Dequeue_fifo( the_thread_queue ); + break; + case THREAD_QUEUE_DATA_PRIORITY_DISCIPLINE: + the_thread = _Thread_queue_Dequeue_priority( the_thread_queue ); + break; + default: /* this is only to prevent warnings */ + the_thread = NULL; + break; + } + + if ( !_Thread_Is_null( the_thread ) ) + return( the_thread ); + + _ISR_Disable( level ); + if ( the_thread_queue->sync == FALSE ) { + _ISR_Enable( level ); + return( NULL ); + } + + the_thread_queue->sync = FALSE; + _ISR_Enable( level ); + return( _Thread_Executing ); +} + +/*PAGE + * + * _Thread_queue_Extract + * + * This routine removes a specific thread from the specified threadq, + * deletes any timeout, and unblocks the thread. + * + * Input parameters: + * the_thread_queue - pointer to a threadq header + * the_thread - pointer to a thread control block + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: NONE + */ + +void _Thread_queue_Extract( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread +) +{ + switch ( the_thread_queue->discipline ) { + case THREAD_QUEUE_DATA_FIFO_DISCIPLINE: + _Thread_queue_Extract_fifo( the_thread_queue, the_thread ); + break; + case THREAD_QUEUE_DATA_PRIORITY_DISCIPLINE: + _Thread_queue_Extract_priority( the_thread_queue, the_thread ); + break; + } +} + +/*PAGE + * + * _Thread_queue_Flush + * + * This kernel routine flushes the given thread queue. + * + * Input parameters: + * the_thread_queue - pointer to threadq to be flushed + * + * Output parameters: NONE + */ + +void _Thread_queue_Flush( + Thread_queue_Control *the_thread_queue, + Thread_queue_Flush_callout remote_extract_callout +) +{ + Thread_Control *the_thread; + + while ( (the_thread = _Thread_queue_Dequeue( the_thread_queue )) ) { + if ( _Objects_Is_local_id( the_thread->Object.id ) ) + the_thread->Wait.return_code = RTEMS_OBJECT_WAS_DELETED; + else + ( *remote_extract_callout )( the_thread ); + } +} + +/*PAGE + * + * _Thread_queue_First + * + * This routines returns a pointer to the first thread on the + * specified threadq. + * + * Input parameters: + * the_thread_queue - pointer to thread queue + * + * Output parameters: + * returns - first thread or NULL + */ + +Thread_Control *_Thread_queue_First( + Thread_queue_Control *the_thread_queue +) +{ + Thread_Control *the_thread; + + switch ( the_thread_queue->discipline ) { + case THREAD_QUEUE_DATA_FIFO_DISCIPLINE: + the_thread = _Thread_queue_First_fifo( the_thread_queue ); + break; + case THREAD_QUEUE_DATA_PRIORITY_DISCIPLINE: + the_thread = _Thread_queue_First_priority( the_thread_queue ); + break; + default: /* this is only to prevent warnings */ + the_thread = NULL; + break; + } + + return the_thread; +} + +/*PAGE + * + * _Thread_queue_Timeout + * + * This routine processes a thread which timeouts while waiting on + * a thread queue. It is called by the watchdog handler. + * + * Input parameters: + * id - thread id + * + * Output parameters: NONE + */ + +void _Thread_queue_Timeout( + Objects_Id id, + void *ignored +) +{ + Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + case OBJECTS_REMOTE: /* impossible */ + break; + case OBJECTS_LOCAL: + the_thread->Wait.return_code = RTEMS_TIMEOUT; + _Thread_queue_Extract( the_thread->Wait.queue, the_thread ); + _Thread_Unnest_dispatch(); + break; + } +} + +/*PAGE + * + * _Thread_queue_Enqueue_fifo + * + * This routine blocks a thread, places it on a thread, and optionally + * starts a timeout timer. + * + * Input parameters: + * the_thread_queue - pointer to threadq + * the_thread - pointer to the thread to block + * timeout - interval to wait + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * only case + */ + +void _Thread_queue_Enqueue_fifo ( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread, + rtems_interval timeout +) +{ + ISR_Level level; + + _ISR_Disable( level ); + if ( the_thread_queue->sync == TRUE ) { + the_thread_queue->sync = FALSE; + + _Chain_Append_unprotected( + &the_thread_queue->Queues.Fifo, + &the_thread->Object.Node + ); + + if ( timeout != RTEMS_NO_TIMEOUT ) + _Watchdog_Activate( &the_thread->Timer ); + + _ISR_Enable( level ); + return; + } + + if ( !_Watchdog_Is_active( &the_thread->Timer ) ) { + _ISR_Enable( level ); + _Thread_Unblock( the_thread ); + } else { + _Watchdog_Deactivate( &the_thread->Timer ); + _ISR_Enable( level ); + (void) _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + } + + if ( !_Objects_Is_local_id( the_thread->Object.id ) ) + _Thread_MP_Free_proxy( the_thread ); + +} + +/*PAGE + * + * _Thread_queue_Dequeue_fifo + * + * This routine removes a thread from the specified threadq. + * + * Input parameters: + * the_thread_queue - pointer to threadq + * + * Output parameters: + * returns - thread dequeued or NULL + * + * INTERRUPT LATENCY: + * check sync + * RTEMS_FIFO + */ + +Thread_Control *_Thread_queue_Dequeue_fifo( + Thread_queue_Control *the_thread_queue +) +{ + ISR_Level level; + Thread_Control *the_thread; + + _ISR_Disable( level ); + if ( !_Chain_Is_empty( &the_thread_queue->Queues.Fifo ) ) { + + the_thread = (Thread_Control *) + _Chain_Get_first_unprotected( &the_thread_queue->Queues.Fifo ); + + if ( !_Watchdog_Is_active( &the_thread->Timer ) ) { + _ISR_Enable( level ); + _Thread_Unblock( the_thread ); + } else { + _Watchdog_Deactivate( &the_thread->Timer ); + _ISR_Enable( level ); + (void) _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + } + + if ( !_Objects_Is_local_id( the_thread->Object.id ) ) + _Thread_MP_Free_proxy( the_thread ); + + return( the_thread ); + } + _ISR_Enable( level ); + return( NULL ); +} + +/*PAGE + * + * _Thread_queue_Extract_fifo + * + * This routine removes a specific thread from the specified threadq, + * deletes any timeout, and unblocks the thread. + * + * Input parameters: + * the_thread_queue - pointer to a threadq header + * the_thread - pointer to the thread to block + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * EXTRACT_FIFO + */ + +void _Thread_queue_Extract_fifo( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread +) +{ + ISR_Level level; + + _ISR_Disable( level ); + + if ( !_States_Is_waiting_on_thread_queue( the_thread->current_state ) ) { + _ISR_Enable( level ); + return; + } + + _Chain_Extract_unprotected( &the_thread->Object.Node ); + + if ( !_Watchdog_Is_active( &the_thread->Timer ) ) { + _ISR_Enable( level ); + _Thread_Unblock( the_thread ); + } else { + _Watchdog_Deactivate( &the_thread->Timer ); + _ISR_Enable( level ); + (void) _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + } + + if ( !_Objects_Is_local_id( the_thread->Object.id ) ) + _Thread_MP_Free_proxy( the_thread ); +} + +/*PAGE + * + * _Thread_queue_First_fifo + * + * This routines returns a pointer to the first thread on the + * specified threadq. + * + * Input parameters: + * the_thread_queue - pointer to threadq + * + * Output parameters: + * returns - first thread or NULL + */ + +Thread_Control *_Thread_queue_First_fifo( + Thread_queue_Control *the_thread_queue +) +{ + if ( !_Chain_Is_empty( &the_thread_queue->Queues.Fifo ) ) + return (Thread_Control *) the_thread_queue->Queues.Fifo.first; + + return NULL; +} + +/*PAGE + * + * _Thread_queue_Enqueue_priority + * + * This routine blocks a thread, places it on a thread, and optionally + * starts a timeout timer. + * + * Input parameters: + * the_thread_queue - pointer to threadq + * thread - thread to insert + * timeout - timeout interval in ticks + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * forward less than + * forward equal + */ + +void _Thread_queue_Enqueue_priority( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread, + rtems_interval timeout +) +{ + rtems_task_priority search_priority; + Thread_Control *search_thread; + ISR_Level level; + Chain_Control *header; + unsigned32 header_index; + Chain_Node *the_node; + Chain_Node *next_node; + Chain_Node *previous_node; + Chain_Node *search_node; + rtems_task_priority priority; + States_Control block_state; + + _Chain_Initialize_empty( &the_thread->Wait.Block2n ); + + priority = the_thread->current_priority; + header_index = _Thread_queue_Header_number( priority ); + header = &the_thread_queue->Queues.Priority[ header_index ]; + block_state = the_thread_queue->state; + + if ( _Thread_queue_Is_reverse_search( priority ) ) + goto restart_reverse_search; + +restart_forward_search: + search_priority = RTEMS_MINIMUM_PRIORITY - 1; + _ISR_Disable( level ); + search_thread = (Thread_Control *) header->first; + while ( !_Chain_Is_tail( header, (Chain_Node *)search_thread ) ) { + search_priority = search_thread->current_priority; + if ( priority <= search_priority ) + break; + +#if ( CPU_UNROLL_ENQUEUE_PRIORITY == TRUE ) + search_thread = (Thread_Control *) search_thread->Object.Node.next; + if ( _Chain_Is_tail( header, (Chain_Node *)search_thread ) ) + break; + search_priority = search_thread->current_priority; + if ( priority <= search_priority ) + break; +#endif + _ISR_Flash( level ); + if ( !_States_Are_set( search_thread->current_state, block_state) ) { + _ISR_Enable( level ); + goto restart_forward_search; + } + search_thread = + (Thread_Control *)search_thread->Object.Node.next; + } + if ( the_thread_queue->sync == FALSE ) + goto syncronize; + + the_thread_queue->sync = FALSE; + if ( timeout != RTEMS_NO_TIMEOUT ) + _Watchdog_Activate( &the_thread->Timer ); + + if ( priority == search_priority ) + goto equal_priority; + + search_node = (Chain_Node *) search_thread; + previous_node = search_node->previous; + the_node = (Chain_Node *) the_thread; + + the_node->next = search_node; + the_node->previous = previous_node; + previous_node->next = the_node; + search_node->previous = the_node; + _ISR_Enable( level ); + return; + +restart_reverse_search: + search_priority = RTEMS_MAXIMUM_PRIORITY + 1; + + _ISR_Disable( level ); + search_thread = (Thread_Control *) header->last; + while ( !_Chain_Is_head( header, (Chain_Node *)search_thread ) ) { + search_priority = search_thread->current_priority; + if ( priority >= search_priority ) + break; +#if ( CPU_UNROLL_ENQUEUE_PRIORITY == TRUE ) + search_thread = (Thread_Control *) search_thread->Object.Node.previous; + if ( _Chain_Is_head( header, (Chain_Node *)search_thread ) ) + break; + search_priority = search_thread->current_priority; + if ( priority >= search_priority ) + break; +#endif + _ISR_Flash( level ); + if ( !_States_Are_set( search_thread->current_state, block_state) ) { + _ISR_Enable( level ); + goto restart_reverse_search; + } + search_thread = (Thread_Control *) + search_thread->Object.Node.previous; + } + if ( !the_thread_queue->sync ) + goto syncronize; + + the_thread_queue->sync = FALSE; + if ( timeout != RTEMS_NO_TIMEOUT ) + _Watchdog_Activate( &the_thread->Timer ); + + if ( priority == search_priority ) + goto equal_priority; + + search_node = (Chain_Node *) search_thread; + next_node = search_node->next; + the_node = (Chain_Node *) the_thread; + + the_node->next = next_node; + the_node->previous = search_node; + search_node->next = the_node; + next_node->previous = the_node; + _ISR_Enable( level ); + return; + +equal_priority: /* add at end of priority group */ + search_node = _Chain_Tail( &search_thread->Wait.Block2n ); + previous_node = search_node->previous; + the_node = (Chain_Node *) the_thread; + + the_node->next = search_node; + the_node->previous = previous_node; + previous_node->next = the_node; + search_node->previous = the_node; + _ISR_Enable( level ); + return; + +syncronize: + if ( !_Watchdog_Is_active( &the_thread->Timer ) ) { + _ISR_Enable( level ); + _Thread_Unblock( the_thread ); + } else { + _Watchdog_Deactivate( &the_thread->Timer ); + _ISR_Enable( level ); + (void) _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + } + if ( !_Objects_Is_local_id( the_thread->Object.id ) ) + _Thread_MP_Free_proxy( the_thread ); +} + +/*PAGE + * + * _Thread_queue_Dequeue_priority + * + * This routine removes a thread from the specified RTEMS_PRIORITY based + * threadq, unblocks it, and cancels its timeout timer. + * + * Input parameters: + * the_thread_queue - pointer to thread queue + * + * Output parameters: + * returns - thread dequeued or NULL + * + * INTERRUPT LATENCY: + * only case + */ + +Thread_Control *_Thread_queue_Dequeue_priority( + Thread_queue_Control *the_thread_queue +) +{ + unsigned32 index; + ISR_Level level; + Thread_Control *the_thread; + Thread_Control *new_first_thread; + Chain_Node *new_first_node; + Chain_Node *new_second_node; + Chain_Node *last_node; + Chain_Node *next_node; + Chain_Node *previous_node; + + for( index=0 ; + index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ; + index++ ) { + _ISR_Disable( level ); + if ( !_Chain_Is_empty( &the_thread_queue->Queues.Priority[ index ] ) ) { + the_thread = (Thread_Control *) + the_thread_queue->Queues.Priority[ index ].first; + goto dequeue; + } + _ISR_Enable( level ); + } + return NULL; + +dequeue: + new_first_node = the_thread->Wait.Block2n.first; + new_first_thread = (Thread_Control *) new_first_node; + next_node = the_thread->Object.Node.next; + previous_node = the_thread->Object.Node.previous; + + if ( !_Chain_Is_empty( &the_thread->Wait.Block2n ) ) { + last_node = the_thread->Wait.Block2n.last; + new_second_node = new_first_node->next; + + previous_node->next = new_first_node; + next_node->previous = new_first_node; + new_first_node->next = next_node; + new_first_node->previous = previous_node; + + if ( !_Chain_Has_only_one_node( &the_thread->Wait.Block2n ) ) { + /* > two threads on 2-n */ + new_second_node->previous = + _Chain_Head( &new_first_thread->Wait.Block2n ); + + new_first_thread->Wait.Block2n.first = new_second_node; + new_first_thread->Wait.Block2n.last = last_node; + + last_node->next = _Chain_Tail( &new_first_thread->Wait.Block2n ); + } + } else { + previous_node->next = next_node; + next_node->previous = previous_node; + } + + if ( !_Watchdog_Is_active( &the_thread->Timer ) ) { + _ISR_Enable( level ); + _Thread_Unblock( the_thread ); + } else { + _Watchdog_Deactivate( &the_thread->Timer ); + _ISR_Enable( level ); + (void) _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + } + + if ( !_Objects_Is_local_id( the_thread->Object.id ) ) + _Thread_MP_Free_proxy( the_thread ); + return( the_thread ); +} + +/*PAGE + * + * _Thread_queue_Extract_priority + * + * This routine removes a specific thread from the specified threadq, + * deletes any timeout, and unblocks the thread. + * + * Input parameters: + * the_thread_queue - pointer to a threadq header + * the_thread - pointer to a thread control block + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * EXTRACT_PRIORITY + */ + +void _Thread_queue_Extract_priority( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread +) +{ + ISR_Level level; + Chain_Node *the_node; + Chain_Node *next_node; + Chain_Node *previous_node; + Thread_Control *new_first_thread; + Chain_Node *new_first_node; + Chain_Node *new_second_node; + Chain_Node *last_node; + + the_node = (Chain_Node *) the_thread; + _ISR_Disable( level ); + if ( _States_Is_waiting_on_thread_queue( the_thread->current_state ) ) { + next_node = the_node->next; + previous_node = the_node->previous; + + if ( !_Chain_Is_empty( &the_thread->Wait.Block2n ) ) { + new_first_node = the_thread->Wait.Block2n.first; + new_first_thread = (Thread_Control *) new_first_node; + last_node = the_thread->Wait.Block2n.last; + new_second_node = new_first_node->next; + + previous_node->next = new_first_node; + next_node->previous = new_first_node; + new_first_node->next = next_node; + new_first_node->previous = previous_node; + + if ( !_Chain_Has_only_one_node( &the_thread->Wait.Block2n ) ) { + /* > two threads on 2-n */ + new_second_node->previous = + _Chain_Head( &new_first_thread->Wait.Block2n ); + new_first_thread->Wait.Block2n.first = new_second_node; + + new_first_thread->Wait.Block2n.last = last_node; + last_node->next = _Chain_Tail( &new_first_thread->Wait.Block2n ); + } + } else { + previous_node->next = next_node; + next_node->previous = previous_node; + } + + if ( !_Watchdog_Is_active( &the_thread->Timer ) ) { + _ISR_Enable( level ); + _Thread_Unblock( the_thread ); + } else { + _Watchdog_Deactivate( &the_thread->Timer ); + _ISR_Enable( level ); + (void) _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + } + + if ( !_Objects_Is_local_id( the_thread->Object.id ) ) + _Thread_MP_Free_proxy( the_thread ); + } + else + _ISR_Enable( level ); +} + +/*PAGE + * + * _Thread_queue_First_priority + * + * This routines returns a pointer to the first thread on the + * specified threadq. + * + * Input parameters: + * the_thread_queue - pointer to thread queue + * + * Output parameters: + * returns - first thread or NULL + */ + +Thread_Control *_Thread_queue_First_priority ( + Thread_queue_Control *the_thread_queue +) +{ + unsigned32 index; + + for( index=0 ; + index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ; + index++ ) { + if ( !_Chain_Is_empty( &the_thread_queue->Queues.Priority[ index ] ) ) + return (Thread_Control *) + the_thread_queue->Queues.Priority[ index ].first; + } + return NULL; +} diff --git a/cpukit/score/src/watchdog.c b/cpukit/score/src/watchdog.c new file mode 100644 index 0000000000..7db26c0cd5 --- /dev/null +++ b/cpukit/score/src/watchdog.c @@ -0,0 +1,225 @@ +/* + * Watchdog Handler + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +/*PAGE + * + * _Watchdog_Handler_initialization + * + * This routine initializes the watchdog handler. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _Watchdog_Handler_initialization( void ) +{ + _Watchdog_Clear_sync(); + _Chain_Initialize_empty( &_Watchdog_Ticks_chain ); + _Chain_Initialize_empty( &_Watchdog_Seconds_chain ); +} + +/*PAGE + * + * _Watchdog_Remove + * + * The routine removes a watchdog from a delta chain and updates + * the delta counters of the remaining watchdogs. + */ + +Watchdog_States _Watchdog_Remove( + Watchdog_Control *the_watchdog +) +{ + ISR_Level level; + Watchdog_States previous_state; + Watchdog_Control *next_watchdog; + + _ISR_Disable( level ); + previous_state = the_watchdog->state; + switch ( previous_state ) { + case WATCHDOG_INACTIVE: + break; + case WATCHDOG_ACTIVE: + case WATCHDOG_REINSERT: + case WATCHDOG_REMOVE_IT: + + the_watchdog->state = WATCHDOG_INACTIVE; + next_watchdog = _Watchdog_Next( the_watchdog ); + + if ( _Watchdog_Next(next_watchdog) ) + next_watchdog->delta_interval += the_watchdog->delta_interval; + + if ( the_watchdog == _Watchdog_Sync ) + _Watchdog_Sync = _Watchdog_Previous( the_watchdog ); + + _Chain_Extract_unprotected( &the_watchdog->Node ); + break; + } + _ISR_Enable( level ); + return( previous_state ); +} + +/*PAGE + * + * _Watchdog_Adjust + * + * This routine adjusts the delta chain backward or forward in response + * to a time change. + * + * Input parameters: + * header - pointer to the delta chain to be adjusted + * direction - forward or backward adjustment to delta chain + * units - units to adjust + * + * Output parameters: + */ + +void _Watchdog_Adjust( + Chain_Control *header, + Watchdog_Adjust_directions direction, + rtems_interval units +) +{ + if ( !_Chain_Is_empty( header ) ) { + switch ( direction ) { + case WATCHDOG_BACKWARD: + _Watchdog_First( header )->delta_interval += units; + break; + case WATCHDOG_FORWARD: + while ( units ) { + if ( units < _Watchdog_First( header )->delta_interval ) { + _Watchdog_First( header )->delta_interval -= units; + break; + } else { + units -= _Watchdog_First( header )->delta_interval; + _Watchdog_First( header )->delta_interval = 1; + _Watchdog_Tickle( header ); + if ( _Chain_Is_empty( header ) ) + break; + } + } + break; + } + } +} + +/*PAGE + * + * _Watchdog_Insert + * + * This routine inserts a watchdog timer on to the appropriate delta + * chain while updating the delta interval counters. + */ + +void _Watchdog_Insert( + Chain_Control *header, + Watchdog_Control *the_watchdog, + Watchdog_Insert_modes insert_mode +) +{ + ISR_Level level; + Watchdog_Control *after; + + the_watchdog->state = WATCHDOG_REINSERT; + the_watchdog->delta_interval = the_watchdog->initial; + + _ISR_Disable( level ); + + for ( after = _Watchdog_First( header ) ; + ; + after = _Watchdog_Next( _Watchdog_Get_sync() ) ) { + + if ( the_watchdog->delta_interval == 0 || !_Watchdog_Next( after ) ) + break; + + if ( the_watchdog->delta_interval < after->delta_interval ) { + after->delta_interval -= the_watchdog->delta_interval; + break; + } + + the_watchdog->delta_interval -= after->delta_interval; + _Watchdog_Set_sync( after ); + + /* + * If you experience problems comment out the _ISR_Flash line. Under + * certain circumstances, this flash allows interrupts to execute + * which violate the design assumptions. The critical section + * mechanism used here must be redesigned to address this. + */ + + _ISR_Flash( level ); + } + + if ( insert_mode == WATCHDOG_ACTIVATE_NOW ) + _Watchdog_Activate( the_watchdog ); + + _Chain_Insert_unprotected( after->Node.previous, &the_watchdog->Node ); + + _Watchdog_Clear_sync(); + + _ISR_Enable( level ); +} + +/*PAGE + * + * _Watchdog_Tickle + * + * This routine decrements the delta counter in response to a tick. The + * delta chain is updated accordingly. + * + * Input parameters: + * header - pointer to the delta chain to be tickled + * + * Output parameters: NONE + */ + +void _Watchdog_Tickle( + Chain_Control *header +) +{ + Watchdog_Control *the_watchdog; + + if ( _Chain_Is_empty( header ) ) + return; + + the_watchdog = _Watchdog_First( header ); + the_watchdog->delta_interval--; + if ( the_watchdog->delta_interval != 0 ) + return; + + do { + switch( _Watchdog_Remove( the_watchdog ) ) { + case WATCHDOG_ACTIVE: + (*the_watchdog->routine)( + the_watchdog->id, + the_watchdog->user_data + ); + break; + case WATCHDOG_REINSERT: + _Watchdog_Insert( header, the_watchdog, WATCHDOG_ACTIVATE_NOW ); + break; + case WATCHDOG_INACTIVE: + case WATCHDOG_REMOVE_IT: + break; + } + the_watchdog = _Watchdog_First( header ); + } while ( !_Chain_Is_empty( header ) && + (the_watchdog->delta_interval == 0) ); +} diff --git a/cpukit/score/src/wkspace.c b/cpukit/score/src/wkspace.c new file mode 100644 index 0000000000..577b0f6c01 --- /dev/null +++ b/cpukit/score/src/wkspace.c @@ -0,0 +1,47 @@ +/* + * Workspace Handler + * + * NOTE: + * + * This file only exists to contain the one function which cannot + * be written as a macro when "static inlines" are not used. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +#ifndef USE_INLINES + +/*PAGE + * + * _Workspace_Allocate_or_fatal_error + * + */ + +void *_Workspace_Allocate_or_fatal_error( + unsigned32 size +) +{ + void *memory; + + memory = _Workspace_Allocate( size ); + + if ( memory == NULL ) + rtems_fatal_error_occurred( RTEMS_UNSATISFIED ); + + return memory; +} + +#endif /* USE_INLINES */ + -- cgit v1.2.3