From ac7d5ef06a6d6e8d84abbd1f0b82162725f98326 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 11 May 1995 17:39:37 +0000 Subject: Initial revision --- c/src/exec/score/cpu/hppa1.1/cpu.c | 313 ++++++++ c/src/exec/score/cpu/hppa1.1/cpu.h | 581 ++++++++++++++ c/src/exec/score/cpu/hppa1.1/cpu_asm.h | 73 ++ c/src/exec/score/cpu/hppa1.1/cpu_asm.s | 797 +++++++++++++++++++ c/src/exec/score/cpu/hppa1.1/hppa.h | 704 +++++++++++++++++ c/src/exec/score/cpu/hppa1.1/rtems.s | 53 ++ c/src/exec/score/cpu/i386/asm.h | 131 ++++ c/src/exec/score/cpu/i386/cpu.c | 121 +++ c/src/exec/score/cpu/i386/cpu.h | 367 +++++++++ c/src/exec/score/cpu/i386/cpu_asm.s | 654 ++++++++++++++++ c/src/exec/score/cpu/i386/i386.h | 493 ++++++++++++ c/src/exec/score/cpu/i386/rtems.s | 31 + c/src/exec/score/cpu/i960/asm.h | 107 +++ c/src/exec/score/cpu/i960/cpu.c | 124 +++ c/src/exec/score/cpu/i960/cpu.h | 424 +++++++++++ c/src/exec/score/cpu/i960/cpu_asm.s | 199 +++++ c/src/exec/score/cpu/i960/i960.h | 289 +++++++ c/src/exec/score/cpu/i960/rtems.s | 25 + c/src/exec/score/cpu/m68k/asm.h | 127 ++++ c/src/exec/score/cpu/m68k/cpu.c | 97 +++ c/src/exec/score/cpu/m68k/cpu.h | 412 ++++++++++ c/src/exec/score/cpu/m68k/cpu_asm.s | 202 +++++ c/src/exec/score/cpu/m68k/m68k.h | 282 +++++++ c/src/exec/score/cpu/m68k/rtems.s | 46 ++ c/src/exec/score/cpu/no_cpu/asm.h | 98 +++ c/src/exec/score/cpu/no_cpu/cpu.c | 132 ++++ c/src/exec/score/cpu/no_cpu/cpu.h | 818 ++++++++++++++++++++ c/src/exec/score/cpu/no_cpu/cpu_asm.c | 152 ++++ c/src/exec/score/cpu/no_cpu/cpu_asm.h | 70 ++ c/src/exec/score/cpu/no_cpu/no_cpu.h | 86 +++ c/src/exec/score/cpu/no_cpu/rtems.c | 45 ++ c/src/exec/score/cpu/unix/cpu.c | 529 +++++++++++++ c/src/exec/score/cpu/unix/cpu.h | 929 +++++++++++++++++++++++ c/src/exec/score/cpu/unix/unix.h | 90 +++ c/src/exec/score/headers/address.h | 122 +++ c/src/exec/score/headers/bitfield.h | 49 ++ c/src/exec/score/headers/chain.h | 432 +++++++++++ c/src/exec/score/headers/context.h | 133 ++++ c/src/exec/score/headers/copyrt.h | 42 + c/src/exec/score/headers/debug.h | 98 +++ c/src/exec/score/headers/heap.h | 396 ++++++++++ c/src/exec/score/headers/isr.h | 239 ++++++ c/src/exec/score/headers/mpci.h | 171 +++++ c/src/exec/score/headers/mppkt.h | 123 +++ c/src/exec/score/headers/object.h | 380 +++++++++ c/src/exec/score/headers/objectmp.h | 165 ++++ c/src/exec/score/headers/priority.h | 195 +++++ c/src/exec/score/headers/stack.h | 95 +++ c/src/exec/score/headers/states.h | 337 ++++++++ c/src/exec/score/headers/sysstate.h | 143 ++++ c/src/exec/score/headers/system.h | 132 ++++ c/src/exec/score/headers/thread.h | 721 ++++++++++++++++++ c/src/exec/score/headers/threadmp.h | 134 ++++ c/src/exec/score/headers/threadq.h | 264 +++++++ c/src/exec/score/headers/tod.h | 300 ++++++++ c/src/exec/score/headers/tqdata.h | 90 +++ c/src/exec/score/headers/userext.h | 213 ++++++ c/src/exec/score/headers/watchdog.h | 471 ++++++++++++ c/src/exec/score/headers/wkspace.h | 99 +++ c/src/exec/score/include/rtems/debug.h | 98 +++ c/src/exec/score/include/rtems/score/address.h | 122 +++ c/src/exec/score/include/rtems/score/bitfield.h | 49 ++ c/src/exec/score/include/rtems/score/chain.h | 432 +++++++++++ c/src/exec/score/include/rtems/score/context.h | 133 ++++ c/src/exec/score/include/rtems/score/copyrt.h | 42 + c/src/exec/score/include/rtems/score/heap.h | 396 ++++++++++ c/src/exec/score/include/rtems/score/isr.h | 239 ++++++ c/src/exec/score/include/rtems/score/mpci.h | 171 +++++ c/src/exec/score/include/rtems/score/mppkt.h | 123 +++ c/src/exec/score/include/rtems/score/object.h | 380 +++++++++ c/src/exec/score/include/rtems/score/objectmp.h | 165 ++++ c/src/exec/score/include/rtems/score/priority.h | 195 +++++ c/src/exec/score/include/rtems/score/stack.h | 95 +++ c/src/exec/score/include/rtems/score/states.h | 337 ++++++++ c/src/exec/score/include/rtems/score/sysstate.h | 143 ++++ c/src/exec/score/include/rtems/score/thread.h | 721 ++++++++++++++++++ c/src/exec/score/include/rtems/score/threadmp.h | 134 ++++ c/src/exec/score/include/rtems/score/threadq.h | 264 +++++++ c/src/exec/score/include/rtems/score/tod.h | 300 ++++++++ c/src/exec/score/include/rtems/score/tqdata.h | 90 +++ c/src/exec/score/include/rtems/score/userext.h | 213 ++++++ c/src/exec/score/include/rtems/score/watchdog.h | 471 ++++++++++++ c/src/exec/score/include/rtems/score/wkspace.h | 99 +++ c/src/exec/score/include/rtems/system.h | 132 ++++ c/src/exec/score/inline/address.inl | 109 +++ c/src/exec/score/inline/chain.inl | 292 +++++++ c/src/exec/score/inline/heap.inl | 203 +++++ c/src/exec/score/inline/isr.inl | 70 ++ c/src/exec/score/inline/mppkt.inl | 49 ++ c/src/exec/score/inline/object.inl | 198 +++++ c/src/exec/score/inline/objectmp.inl | 62 ++ c/src/exec/score/inline/priority.inl | 168 ++++ c/src/exec/score/inline/rtems/score/address.inl | 109 +++ c/src/exec/score/inline/rtems/score/chain.inl | 292 +++++++ c/src/exec/score/inline/rtems/score/heap.inl | 203 +++++ c/src/exec/score/inline/rtems/score/isr.inl | 70 ++ c/src/exec/score/inline/rtems/score/mppkt.inl | 49 ++ c/src/exec/score/inline/rtems/score/object.inl | 198 +++++ c/src/exec/score/inline/rtems/score/objectmp.inl | 62 ++ c/src/exec/score/inline/rtems/score/priority.inl | 168 ++++ c/src/exec/score/inline/rtems/score/stack.inl | 63 ++ c/src/exec/score/inline/rtems/score/states.inl | 285 +++++++ c/src/exec/score/inline/rtems/score/sysstate.inl | 103 +++ c/src/exec/score/inline/rtems/score/thread.inl | 252 ++++++ c/src/exec/score/inline/rtems/score/threadmp.inl | 53 ++ c/src/exec/score/inline/rtems/score/tod.inl | 72 ++ c/src/exec/score/inline/rtems/score/tqdata.inl | 47 ++ c/src/exec/score/inline/rtems/score/userext.inl | 268 +++++++ c/src/exec/score/inline/rtems/score/watchdog.inl | 296 ++++++++ c/src/exec/score/inline/rtems/score/wkspace.inl | 104 +++ c/src/exec/score/inline/stack.inl | 63 ++ c/src/exec/score/inline/states.inl | 285 +++++++ c/src/exec/score/inline/sysstate.inl | 103 +++ c/src/exec/score/inline/thread.inl | 252 ++++++ c/src/exec/score/inline/threadmp.inl | 53 ++ c/src/exec/score/inline/tod.inl | 72 ++ c/src/exec/score/inline/tqdata.inl | 47 ++ c/src/exec/score/inline/userext.inl | 268 +++++++ c/src/exec/score/inline/watchdog.inl | 296 ++++++++ c/src/exec/score/inline/wkspace.inl | 104 +++ c/src/exec/score/macros/README | 18 + c/src/exec/score/macros/address.inl | 79 ++ c/src/exec/score/macros/chain.inl | 200 +++++ c/src/exec/score/macros/heap.inl | 136 ++++ c/src/exec/score/macros/isr.inl | 60 ++ c/src/exec/score/macros/mppkt.inl | 41 + c/src/exec/score/macros/object.inl | 146 ++++ c/src/exec/score/macros/objectmp.inl | 50 ++ c/src/exec/score/macros/priority.inl | 144 ++++ c/src/exec/score/macros/rtems/score/README | 18 + c/src/exec/score/macros/rtems/score/address.inl | 79 ++ c/src/exec/score/macros/rtems/score/chain.inl | 200 +++++ c/src/exec/score/macros/rtems/score/heap.inl | 136 ++++ c/src/exec/score/macros/rtems/score/isr.inl | 60 ++ c/src/exec/score/macros/rtems/score/mppkt.inl | 41 + c/src/exec/score/macros/rtems/score/object.inl | 146 ++++ c/src/exec/score/macros/rtems/score/objectmp.inl | 50 ++ c/src/exec/score/macros/rtems/score/priority.inl | 144 ++++ c/src/exec/score/macros/rtems/score/stack.inl | 50 ++ c/src/exec/score/macros/rtems/score/states.inl | 201 +++++ c/src/exec/score/macros/rtems/score/sysstate.inl | 77 ++ c/src/exec/score/macros/rtems/score/thread.inl | 193 +++++ c/src/exec/score/macros/rtems/score/threadmp.inl | 50 ++ c/src/exec/score/macros/rtems/score/tod.inl | 59 ++ c/src/exec/score/macros/rtems/score/tqdata.inl | 39 + c/src/exec/score/macros/rtems/score/userext.inl | 184 +++++ c/src/exec/score/macros/rtems/score/watchdog.inl | 202 +++++ c/src/exec/score/macros/rtems/score/wkspace.inl | 101 +++ c/src/exec/score/macros/stack.inl | 50 ++ c/src/exec/score/macros/states.inl | 201 +++++ c/src/exec/score/macros/sysstate.inl | 77 ++ c/src/exec/score/macros/thread.inl | 193 +++++ c/src/exec/score/macros/threadmp.inl | 50 ++ c/src/exec/score/macros/tod.inl | 59 ++ c/src/exec/score/macros/tqdata.inl | 39 + c/src/exec/score/macros/userext.inl | 184 +++++ c/src/exec/score/macros/watchdog.inl | 202 +++++ c/src/exec/score/macros/wkspace.inl | 101 +++ c/src/exec/score/src/chain.c | 202 +++++ c/src/exec/score/src/coretod.c | 236 ++++++ c/src/exec/score/src/heap.c | 478 ++++++++++++ c/src/exec/score/src/mpci.c | 237 ++++++ c/src/exec/score/src/object.c | 228 ++++++ c/src/exec/score/src/objectmp.c | 250 ++++++ c/src/exec/score/src/thread.c | 805 ++++++++++++++++++++ c/src/exec/score/src/threadmp.c | 229 ++++++ c/src/exec/score/src/threadq.c | 837 ++++++++++++++++++++ c/src/exec/score/src/tod.c | 236 ++++++ c/src/exec/score/src/watchdog.c | 225 ++++++ c/src/exec/score/src/wkspace.c | 47 ++ c/src/exec/score/tools/hppa1.1/genoffsets.c | 191 +++++ 171 files changed, 34338 insertions(+) create mode 100644 c/src/exec/score/cpu/hppa1.1/cpu.c create mode 100644 c/src/exec/score/cpu/hppa1.1/cpu.h create mode 100644 c/src/exec/score/cpu/hppa1.1/cpu_asm.h create mode 100644 c/src/exec/score/cpu/hppa1.1/cpu_asm.s create mode 100644 c/src/exec/score/cpu/hppa1.1/hppa.h create mode 100644 c/src/exec/score/cpu/hppa1.1/rtems.s create mode 100644 c/src/exec/score/cpu/i386/asm.h create mode 100644 c/src/exec/score/cpu/i386/cpu.c create mode 100644 c/src/exec/score/cpu/i386/cpu.h create mode 100644 c/src/exec/score/cpu/i386/cpu_asm.s create mode 100644 c/src/exec/score/cpu/i386/i386.h create mode 100644 c/src/exec/score/cpu/i386/rtems.s create mode 100644 c/src/exec/score/cpu/i960/asm.h create mode 100644 c/src/exec/score/cpu/i960/cpu.c create mode 100644 c/src/exec/score/cpu/i960/cpu.h create mode 100644 c/src/exec/score/cpu/i960/cpu_asm.s create mode 100644 c/src/exec/score/cpu/i960/i960.h create mode 100644 c/src/exec/score/cpu/i960/rtems.s create mode 100644 c/src/exec/score/cpu/m68k/asm.h create mode 100644 c/src/exec/score/cpu/m68k/cpu.c create mode 100644 c/src/exec/score/cpu/m68k/cpu.h create mode 100644 c/src/exec/score/cpu/m68k/cpu_asm.s create mode 100644 c/src/exec/score/cpu/m68k/m68k.h create mode 100644 c/src/exec/score/cpu/m68k/rtems.s create mode 100644 c/src/exec/score/cpu/no_cpu/asm.h create mode 100644 c/src/exec/score/cpu/no_cpu/cpu.c create mode 100644 c/src/exec/score/cpu/no_cpu/cpu.h create mode 100644 c/src/exec/score/cpu/no_cpu/cpu_asm.c create mode 100644 c/src/exec/score/cpu/no_cpu/cpu_asm.h create mode 100644 c/src/exec/score/cpu/no_cpu/no_cpu.h create mode 100644 c/src/exec/score/cpu/no_cpu/rtems.c create mode 100644 c/src/exec/score/cpu/unix/cpu.c create mode 100644 c/src/exec/score/cpu/unix/cpu.h create mode 100644 c/src/exec/score/cpu/unix/unix.h create mode 100644 c/src/exec/score/headers/address.h create mode 100644 c/src/exec/score/headers/bitfield.h create mode 100644 c/src/exec/score/headers/chain.h create mode 100644 c/src/exec/score/headers/context.h create mode 100644 c/src/exec/score/headers/copyrt.h create mode 100644 c/src/exec/score/headers/debug.h create mode 100644 c/src/exec/score/headers/heap.h create mode 100644 c/src/exec/score/headers/isr.h create mode 100644 c/src/exec/score/headers/mpci.h create mode 100644 c/src/exec/score/headers/mppkt.h create mode 100644 c/src/exec/score/headers/object.h create mode 100644 c/src/exec/score/headers/objectmp.h create mode 100644 c/src/exec/score/headers/priority.h create mode 100644 c/src/exec/score/headers/stack.h create mode 100644 c/src/exec/score/headers/states.h create mode 100644 c/src/exec/score/headers/sysstate.h create mode 100644 c/src/exec/score/headers/system.h create mode 100644 c/src/exec/score/headers/thread.h create mode 100644 c/src/exec/score/headers/threadmp.h create mode 100644 c/src/exec/score/headers/threadq.h create mode 100644 c/src/exec/score/headers/tod.h create mode 100644 c/src/exec/score/headers/tqdata.h create mode 100644 c/src/exec/score/headers/userext.h create mode 100644 c/src/exec/score/headers/watchdog.h create mode 100644 c/src/exec/score/headers/wkspace.h create mode 100644 c/src/exec/score/include/rtems/debug.h create mode 100644 c/src/exec/score/include/rtems/score/address.h create mode 100644 c/src/exec/score/include/rtems/score/bitfield.h create mode 100644 c/src/exec/score/include/rtems/score/chain.h create mode 100644 c/src/exec/score/include/rtems/score/context.h create mode 100644 c/src/exec/score/include/rtems/score/copyrt.h create mode 100644 c/src/exec/score/include/rtems/score/heap.h create mode 100644 c/src/exec/score/include/rtems/score/isr.h create mode 100644 c/src/exec/score/include/rtems/score/mpci.h create mode 100644 c/src/exec/score/include/rtems/score/mppkt.h create mode 100644 c/src/exec/score/include/rtems/score/object.h create mode 100644 c/src/exec/score/include/rtems/score/objectmp.h create mode 100644 c/src/exec/score/include/rtems/score/priority.h create mode 100644 c/src/exec/score/include/rtems/score/stack.h create mode 100644 c/src/exec/score/include/rtems/score/states.h create mode 100644 c/src/exec/score/include/rtems/score/sysstate.h create mode 100644 c/src/exec/score/include/rtems/score/thread.h create mode 100644 c/src/exec/score/include/rtems/score/threadmp.h create mode 100644 c/src/exec/score/include/rtems/score/threadq.h create mode 100644 c/src/exec/score/include/rtems/score/tod.h create mode 100644 c/src/exec/score/include/rtems/score/tqdata.h create mode 100644 c/src/exec/score/include/rtems/score/userext.h create mode 100644 c/src/exec/score/include/rtems/score/watchdog.h create mode 100644 c/src/exec/score/include/rtems/score/wkspace.h create mode 100644 c/src/exec/score/include/rtems/system.h create mode 100644 c/src/exec/score/inline/address.inl create mode 100644 c/src/exec/score/inline/chain.inl create mode 100644 c/src/exec/score/inline/heap.inl create mode 100644 c/src/exec/score/inline/isr.inl create mode 100644 c/src/exec/score/inline/mppkt.inl create mode 100644 c/src/exec/score/inline/object.inl create mode 100644 c/src/exec/score/inline/objectmp.inl create mode 100644 c/src/exec/score/inline/priority.inl create mode 100644 c/src/exec/score/inline/rtems/score/address.inl create mode 100644 c/src/exec/score/inline/rtems/score/chain.inl create mode 100644 c/src/exec/score/inline/rtems/score/heap.inl create mode 100644 c/src/exec/score/inline/rtems/score/isr.inl create mode 100644 c/src/exec/score/inline/rtems/score/mppkt.inl create mode 100644 c/src/exec/score/inline/rtems/score/object.inl create mode 100644 c/src/exec/score/inline/rtems/score/objectmp.inl create mode 100644 c/src/exec/score/inline/rtems/score/priority.inl create mode 100644 c/src/exec/score/inline/rtems/score/stack.inl create mode 100644 c/src/exec/score/inline/rtems/score/states.inl create mode 100644 c/src/exec/score/inline/rtems/score/sysstate.inl create mode 100644 c/src/exec/score/inline/rtems/score/thread.inl create mode 100644 c/src/exec/score/inline/rtems/score/threadmp.inl create mode 100644 c/src/exec/score/inline/rtems/score/tod.inl create mode 100644 c/src/exec/score/inline/rtems/score/tqdata.inl create mode 100644 c/src/exec/score/inline/rtems/score/userext.inl create mode 100644 c/src/exec/score/inline/rtems/score/watchdog.inl create mode 100644 c/src/exec/score/inline/rtems/score/wkspace.inl create mode 100644 c/src/exec/score/inline/stack.inl create mode 100644 c/src/exec/score/inline/states.inl create mode 100644 c/src/exec/score/inline/sysstate.inl create mode 100644 c/src/exec/score/inline/thread.inl create mode 100644 c/src/exec/score/inline/threadmp.inl create mode 100644 c/src/exec/score/inline/tod.inl create mode 100644 c/src/exec/score/inline/tqdata.inl create mode 100644 c/src/exec/score/inline/userext.inl create mode 100644 c/src/exec/score/inline/watchdog.inl create mode 100644 c/src/exec/score/inline/wkspace.inl create mode 100644 c/src/exec/score/macros/README create mode 100644 c/src/exec/score/macros/address.inl create mode 100644 c/src/exec/score/macros/chain.inl create mode 100644 c/src/exec/score/macros/heap.inl create mode 100644 c/src/exec/score/macros/isr.inl create mode 100644 c/src/exec/score/macros/mppkt.inl create mode 100644 c/src/exec/score/macros/object.inl create mode 100644 c/src/exec/score/macros/objectmp.inl create mode 100644 c/src/exec/score/macros/priority.inl create mode 100644 c/src/exec/score/macros/rtems/score/README create mode 100644 c/src/exec/score/macros/rtems/score/address.inl create mode 100644 c/src/exec/score/macros/rtems/score/chain.inl create mode 100644 c/src/exec/score/macros/rtems/score/heap.inl create mode 100644 c/src/exec/score/macros/rtems/score/isr.inl create mode 100644 c/src/exec/score/macros/rtems/score/mppkt.inl create mode 100644 c/src/exec/score/macros/rtems/score/object.inl create mode 100644 c/src/exec/score/macros/rtems/score/objectmp.inl create mode 100644 c/src/exec/score/macros/rtems/score/priority.inl create mode 100644 c/src/exec/score/macros/rtems/score/stack.inl create mode 100644 c/src/exec/score/macros/rtems/score/states.inl create mode 100644 c/src/exec/score/macros/rtems/score/sysstate.inl create mode 100644 c/src/exec/score/macros/rtems/score/thread.inl create mode 100644 c/src/exec/score/macros/rtems/score/threadmp.inl create mode 100644 c/src/exec/score/macros/rtems/score/tod.inl create mode 100644 c/src/exec/score/macros/rtems/score/tqdata.inl create mode 100644 c/src/exec/score/macros/rtems/score/userext.inl create mode 100644 c/src/exec/score/macros/rtems/score/watchdog.inl create mode 100644 c/src/exec/score/macros/rtems/score/wkspace.inl create mode 100644 c/src/exec/score/macros/stack.inl create mode 100644 c/src/exec/score/macros/states.inl create mode 100644 c/src/exec/score/macros/sysstate.inl create mode 100644 c/src/exec/score/macros/thread.inl create mode 100644 c/src/exec/score/macros/threadmp.inl create mode 100644 c/src/exec/score/macros/tod.inl create mode 100644 c/src/exec/score/macros/tqdata.inl create mode 100644 c/src/exec/score/macros/userext.inl create mode 100644 c/src/exec/score/macros/watchdog.inl create mode 100644 c/src/exec/score/macros/wkspace.inl create mode 100644 c/src/exec/score/src/chain.c create mode 100644 c/src/exec/score/src/coretod.c create mode 100644 c/src/exec/score/src/heap.c create mode 100644 c/src/exec/score/src/mpci.c create mode 100644 c/src/exec/score/src/object.c create mode 100644 c/src/exec/score/src/objectmp.c create mode 100644 c/src/exec/score/src/thread.c create mode 100644 c/src/exec/score/src/threadmp.c create mode 100644 c/src/exec/score/src/threadq.c create mode 100644 c/src/exec/score/src/tod.c create mode 100644 c/src/exec/score/src/watchdog.c create mode 100644 c/src/exec/score/src/wkspace.c create mode 100644 c/src/exec/score/tools/hppa1.1/genoffsets.c (limited to 'c/src/exec/score') diff --git a/c/src/exec/score/cpu/hppa1.1/cpu.c b/c/src/exec/score/cpu/hppa1.1/cpu.c new file mode 100644 index 0000000000..b69a172b4e --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/cpu/hppa1.1/cpu.h b/c/src/exec/score/cpu/hppa1.1/cpu.h new file mode 100644 index 0000000000..3e8f31fcf0 --- /dev/null +++ b/c/src/exec/score/cpu/hppa1.1/cpu.h @@ -0,0 +1,581 @@ +/* cpu.h + * + * This include file contains information pertaining to the HP + * PA-RISC processor (Level 1.1). + * + * 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. + * + * + * Note: + * This file is included by both C and assembler code ( -DASM ) + * + * $Id$ + */ + +#ifndef __CPU_h +#define __CPU_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include /* pick up machine definitions */ + +/* conditional compilation parameters */ + +#define CPU_INLINE_ENABLE_DISPATCH FALSE +#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE + +/* + * RTEMS manages an interrupt stack in software for the HPPA. + */ + +#define CPU_HAS_SOFTWARE_INTERRUPT_STACK TRUE +#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE +#define CPU_ALLOCATE_INTERRUPT_STACK TRUE + +/* + * HPPA has hardware FP, it is assumed to exist by GCC so all tasks + * may implicitly use it (especially for integer multiplies). Because + * the FP context is technically part of the basic integer context + * on this CPU, we cannot use the deferred FP context switch algorithm. + */ + +#define CPU_HARDWARE_FP TRUE +#define CPU_ALL_TASKS_ARE_FP TRUE +#define CPU_IDLE_TASK_IS_FP FALSE +#define CPU_USE_DEFERRED_FP_SWITCH FALSE + +#define CPU_PROVIDES_IDLE_THREAD_BODY FALSE +#define CPU_STACK_GROWS_UP TRUE +#define CPU_STRUCTURE_ALIGNMENT __attribute__ ((__aligned__ (32))) + +/* constants */ + +#define CPU_MODES_INTERRUPT_LEVEL 0x00000001 /* interrupt level in mode */ +#define CPU_MODES_INTERRUPT_MASK 0x00000001 /* interrupt level in mode */ + +/* + * PSW contstants + */ + +#define CPU_PSW_BASE (HPPA_PSW_C | HPPA_PSW_Q | HPPA_PSW_P | HPPA_PSW_D) +#define CPU_PSW_INTERRUPTS_ON (CPU_PSW_BASE | HPPA_PSW_I) +#define CPU_PSW_INTERRUPTS_OFF (CPU_PSW_BASE) + +#define CPU_PSW_DEFAULT CPU_PSW_BASE + + +#ifndef ASM + +/* + * Contexts + * + * This means we have the following context items: + * 1. task level context stuff:: Context_Control + * 2. floating point task stuff:: Context_Control_fp + * + * The PA-RISC is very fast so the expense of saving an extra register + * or two is not of great concern at the present. So we are not making + * a distinction between what is saved during a task switch and what is + * saved at each interrupt. Plus saving the entire context should make + * it easier to make gdb aware of RTEMS tasks. + */ + +typedef struct { + unsigned32 flags; /* whatever */ + unsigned32 gr1; /* scratch -- caller saves */ + unsigned32 gr2; /* RP -- return pointer */ + unsigned32 gr3; /* scratch -- callee saves */ + unsigned32 gr4; /* scratch -- callee saves */ + unsigned32 gr5; /* scratch -- callee saves */ + unsigned32 gr6; /* scratch -- callee saves */ + unsigned32 gr7; /* scratch -- callee saves */ + unsigned32 gr8; /* scratch -- callee saves */ + unsigned32 gr9; /* scratch -- callee saves */ + unsigned32 gr10; /* scratch -- callee saves */ + unsigned32 gr11; /* scratch -- callee saves */ + unsigned32 gr12; /* scratch -- callee saves */ + unsigned32 gr13; /* scratch -- callee saves */ + unsigned32 gr14; /* scratch -- callee saves */ + unsigned32 gr15; /* scratch -- callee saves */ + unsigned32 gr16; /* scratch -- callee saves */ + unsigned32 gr17; /* scratch -- callee saves */ + unsigned32 gr18; /* scratch -- callee saves */ + unsigned32 gr19; /* scratch -- caller saves */ + unsigned32 gr20; /* scratch -- caller saves */ + unsigned32 gr21; /* scratch -- caller saves */ + unsigned32 gr22; /* scratch -- caller saves */ + unsigned32 gr23; /* argument 3 */ + unsigned32 gr24; /* argument 2 */ + unsigned32 gr25; /* argument 1 */ + unsigned32 gr26; /* argument 0 */ + unsigned32 gr27; /* DP -- global data pointer */ + unsigned32 gr28; /* return values -- caller saves */ + unsigned32 gr29; /* return values -- caller saves */ + unsigned32 sp; /* gr30 */ + unsigned32 gr31; + + /* Various control registers */ + + unsigned32 sar; /* cr11 */ + unsigned32 ipsw; /* cr22; full 32 bits of psw */ + unsigned32 iir; /* cr19; interrupt instruction register */ + unsigned32 ior; /* cr21; interrupt offset register */ + unsigned32 isr; /* cr20; interrupt space register (not used) */ + unsigned32 pcoqfront; /* cr18; front que offset */ + unsigned32 pcoqback; /* cr18; back que offset */ + unsigned32 pcsqfront; /* cr17; front que space (not used) */ + unsigned32 pcsqback; /* cr17; back que space (not used) */ + unsigned32 itimer; /* cr16; itimer value */ + +} Context_Control; + + +/* Must be double word aligned. + * This will be ok since our allocator returns 8 byte aligned chunks + */ + +typedef struct { + double fr0; /* status */ + double fr1; /* exception information */ + double fr2; /* exception information */ + double fr3; /* exception information */ + double fr4; /* argument */ + double fr5; /* argument */ + double fr6; /* argument */ + double fr7; /* argument */ + double fr8; /* scratch -- caller saves */ + double fr9; /* scratch -- caller saves */ + double fr10; /* scratch -- caller saves */ + double fr11; /* scratch -- caller saves */ + double fr12; /* callee saves -- (PA-RISC 1.1 CPUs) */ + double fr13; /* callee saves -- (PA-RISC 1.1 CPUs) */ + double fr14; /* callee saves -- (PA-RISC 1.1 CPUs) */ + double fr15; /* callee saves -- (PA-RISC 1.1 CPUs) */ + double fr16; /* callee saves -- (PA-RISC 1.1 CPUs) */ + double fr17; /* callee saves -- (PA-RISC 1.1 CPUs) */ + double fr18; /* callee saves -- (PA-RISC 1.1 CPUs) */ + double fr19; /* callee saves -- (PA-RISC 1.1 CPUs) */ + double fr20; /* callee saves -- (PA-RISC 1.1 CPUs) */ + double fr21; /* callee saves -- (PA-RISC 1.1 CPUs) */ + double fr22; /* caller saves -- (PA-RISC 1.1 CPUs) */ + double fr23; /* caller saves -- (PA-RISC 1.1 CPUs) */ + double fr24; /* caller saves -- (PA-RISC 1.1 CPUs) */ + double fr25; /* caller saves -- (PA-RISC 1.1 CPUs) */ + double fr26; /* caller saves -- (PA-RISC 1.1 CPUs) */ + double fr27; /* caller saves -- (PA-RISC 1.1 CPUs) */ + double fr28; /* caller saves -- (PA-RISC 1.1 CPUs) */ + double fr29; /* caller saves -- (PA-RISC 1.1 CPUs) */ + double fr30; /* caller saves -- (PA-RISC 1.1 CPUs) */ + double fr31; /* caller saves -- (PA-RISC 1.1 CPUs) */ +} Context_Control_fp; + +/* + * The following structure defines the set of information saved + * on the current stack by RTEMS upon receipt of each interrupt. + */ + +typedef struct { + Context_Control Integer; + Context_Control_fp Floating_Point; +} CPU_Interrupt_frame; + +/* + * The following table contains the information required to configure + * the HPPA specific parameters. + */ + +typedef struct { + void (*pretasking_hook)( void ); + void (*predriver_hook)( void ); + void (*postdriver_hook)( void ); + void (*idle_task)( void ); + + /* HPPA simulator is slow enough; don't waste time + * zeroing memory that is already zero + */ + boolean do_zero_of_workspace; + + unsigned32 interrupt_stack_size; + unsigned32 extra_system_initialization_stack; + + /* + * Control of external interrupts. + * We keep a table of external vector numbers (0 - 31) + * The table is sorted by priority, that is: the first entry + * in the table indicates the vector that is highest priorty. + * The handler function is stored in _ISR_Vector_Table[] and + * is set by rtems_interrupt_catch() + */ + + unsigned32 external_interrupts; /* # of external interrupts we use */ + unsigned32 external_interrupt[HPPA_EXTERNAL_INTERRUPTS]; + + void (*spurious_handler)( unsigned32 mask, CPU_Interrupt_frame *); + + unsigned32 itimer_clicks_per_microsecond; /* for use by Clock driver */ +} rtems_cpu_table; + +/* variables */ + +EXTERN Context_Control_fp _CPU_Null_fp_context; +EXTERN unsigned32 _CPU_Default_gr27; +EXTERN void *_CPU_Interrupt_stack_low; +EXTERN void *_CPU_Interrupt_stack_high; + +#endif /* ! ASM */ + +/* + * context size area for floating point + */ + +#ifndef ASM +#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp ) +#endif + +/* + * size of a frame on the stack + */ + +#define CPU_FRAME_SIZE (16 * 4) + +/* + * (Optional) # of bytes for libmisc/stackchk to check + * If not specifed, then it defaults to something reasonable + * for most architectures. + */ + +#define CPU_STACK_CHECK_SIZE (CPU_FRAME_SIZE * 2) + +/* + * extra stack required by system initialization thread + */ + +#define CPU_SYSTEM_INITIALIZATION_THREAD_EXTRA_STACK 0 + +/* + * HPPA has 32 interrupts, then 32 external interrupts + * Rtems (_ISR_Vector_Table) is aware of the first 64 + * A BSP may reserve more. + * + * External interrupts all come thru the same vector (4) + * The external handler is the only person aware of the other + * interrupts (genie, rhino, etc) + */ + +#define CPU_INTERRUPT_NUMBER_OF_VECTORS (HPPA_INTERRUPT_MAX) + +/* + * Don't be chintzy here; we don't want to debug these problems + * Some of the tests eat almost 4k. + * Plus, the HPPA always allocates chunks of 64 bytes for stack + * growth. + */ + +#define CPU_STACK_MINIMUM_SIZE (8 * 1024) + +/* + * HPPA double's must be on 8 byte boundary + */ + +#define CPU_ALIGNMENT 8 + +/* + * just follow the basic HPPA alignment for the heap and partition + */ + +#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT +#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT + +/* + * HPPA stack is best when 64 byte aligned. + */ + +#define CPU_STACK_ALIGNMENT 64 + +#ifndef ASM + +/* macros */ + +/* + * ISR handler macros + * + * These macros perform the following functions: + * + disable all maskable CPU interrupts + * + restore previous interrupt level (enable) + * + temporarily restore interrupts (flash) + * + set a particular level + */ + +/* Disable interrupts; returning previous level in _level */ +#define _CPU_ISR_Disable( _isr_cookie ) \ + do { \ + HPPA_ASM_RSM(HPPA_PSW_I, _isr_cookie); \ + } while(0) + +/* Enable interrupts to previous level from _CPU_ISR_Disable + * does not change 'level' */ +#define _CPU_ISR_Enable( _isr_cookie ) \ + { \ + HPPA_ASM_MTSM( _isr_cookie ); \ + } + +/* restore, then disable interrupts; does not change level */ +#define _CPU_ISR_Flash( _isr_cookie ) \ + { \ + register int _ignore; \ + _CPU_ISR_Enable( _isr_cookie ); \ + _CPU_ISR_Disable( _ignore ); \ + } + +/* + * Interrupt task levels + * + * Future scheme proposal + * level will be an index into a array. + * Each entry of array will be the interrupt bits + * enabled for that level. There will be 32 bits of external + * interrupts (to be placed in EIEM) and some (optional) bsp + * specific bits + * + * For pixel flow this *may* mean something like: + * level 0: all interrupts enabled (external + rhino) + * level 1: rhino disabled + * level 2: all io interrupts disabled (timer still enabled) + * level 7: *ALL* disabled (timer disabled) + */ + +/* set interrupts on or off; does not return new level */ +#define _CPU_ISR_Set_level( new_level ) \ + { \ + volatile int ignore; \ + if ( new_level ) HPPA_ASM_RSM(HPPA_PSW_I, ignore); \ + else HPPA_ASM_SSM(HPPA_PSW_I, ignore); \ + } + +/* end of ISR handler macros */ + +/* + * Context handler macros + * + * These macros perform the following functions: + * + initialize a context area + * + restart the current thread + * + calculate the initial pointer into a FP context area + * + initialize an FP context area + * + * HPPA port adds two macros which hide the "indirectness" of the + * pointer passed the save/restore FP context assembly routines. + */ + +#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \ + _new_level, _entry_point ) \ + do { \ + unsigned32 _stack; \ + \ + (_the_context)->flags = 0xfeedf00d; \ + (_the_context)->pcoqfront = (unsigned32)(_entry_point); \ + (_the_context)->pcoqback = (unsigned32)(_entry_point) + 4; \ + (_the_context)->pcsqfront = 0; \ + (_the_context)->pcsqback = 0; \ + if ( (_new_level) ) \ + (_the_context)->ipsw = CPU_PSW_INTERRUPTS_OFF; \ + else \ + (_the_context)->ipsw = CPU_PSW_INTERRUPTS_ON; \ + \ + _stack = ((unsigned32)(_stack_base) + (CPU_STACK_ALIGNMENT - 1)); \ + _stack &= ~(CPU_STACK_ALIGNMENT - 1); \ + if ((_stack - (unsigned32) (_stack_base)) < CPU_FRAME_SIZE) \ + _stack += CPU_FRAME_SIZE; \ + \ + (_the_context)->sp = (_stack); \ + (_the_context)->gr27 = _CPU_Default_gr27; \ + } while (0) + +#define _CPU_Context_Restart_self( _the_context ) \ + do { \ + _CPU_Context_restore( (_the_context) ); \ + } while (0) + +#define _CPU_Context_Fp_start( _base, _offset ) \ + ( (void *) (_base) + (_offset) ) + +#define _CPU_Context_Initialize_fp( _destination ) \ + do { \ + *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context;\ + } while(0) + +#define _CPU_Context_save_fp( _fp_context ) \ + _CPU_Save_float_context( *(Context_Control_fp **)(_fp_context) ) + +#define _CPU_Context_restore_fp( _fp_context ) \ + _CPU_Restore_float_context( *(Context_Control_fp **)(_fp_context) ) + +/* end of Context handler macros */ + +/* + * Fatal Error manager macros + * + * These macros perform the following functions: + * + disable interrupts and halt the CPU + */ + +void hppa_cpu_halt(unsigned32 type_of_halt, unsigned32 the_error); +#define _CPU_Fatal_halt( _error ) \ + hppa_cpu_halt(0, _error) + +/* end of Fatal Error manager macros */ + +/* + * Bitfield handler macros + * + * These macros perform the following functions: + * + scan for the highest numbered (MSB) set in a 16 bit bitfield + * + * NOTE: + * + * The HPPA does not have a scan instruction. This functionality + * is implemented in software. + */ + +int hppa_rtems_ffs(unsigned int value); +#define _CPU_Bitfield_Find_first_bit( _value, _output ) \ + _output = hppa_rtems_ffs(_value) + +/* end of Bitfield handler macros */ + +/* + * Priority handler macros + * + * These macros perform the following functions: + * + return a mask with the bit for this major/minor portion of + * of thread priority set. + * + translate the bit number returned by "Bitfield_find_first_bit" + * into an index into the thread ready chain bit maps + * + * Note: 255 is the lowest priority + */ + +#define _CPU_Priority_Mask( _bit_number ) \ + ( 1 << (_bit_number) ) + +#define _CPU_Priority_Bits_index( _priority ) \ + (_priority) + +/* end of Priority handler macros */ + +/* functions */ + +/* + * _CPU_Initialize + * + * This routine performs CPU dependent initialization. + */ + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) +); + +/* + * _CPU_ISR_install_vector + * + * This routine installs an interrupt vector. + */ + +void _CPU_ISR_install_vector( + unsigned32 vector, + proc_ptr new_handler, + proc_ptr *old_handler +); + +/* + * _CPU_Context_switch + * + * This routine switches from the run context to the heir context. + */ + +void _CPU_Context_switch( + Context_Control *run, + Context_Control *heir +); + +/* + * _CPU_Context_restore + * + * This routine is generally used only to restart self in an + * efficient manner and avoid stack conflicts. + */ + +void _CPU_Context_restore( + Context_Control *new_context +); + +/* + * _CPU_Save_float_context + * + * This routine saves the floating point context passed to it. + * + * NOTE: _CPU_Context_save_fp is implemented as a macro on the HPPA + * which dereferences the pointer before calling this. + */ + +void _CPU_Save_float_context( + Context_Control_fp *fp_context +); + +/* + * _CPU_Restore_float_context + * + * This routine restores the floating point context passed to it. + * + * NOTE: _CPU_Context_save_fp is implemented as a macro on the HPPA + * which dereferences the pointer before calling this. + */ + +void _CPU_Restore_float_context( + Context_Control_fp *fp_context +); + + +/* The following routine swaps the endian format of an unsigned int. + * It must be static so it can be referenced indirectly. + */ + +static inline unsigned int +CPU_swap_u32(unsigned32 value) +{ + unsigned32 swapped; + + HPPA_ASM_SWAPBYTES(value, swapped); + + return( swapped ); +} + +/* + * Unused; I think it should go away + */ + +#if 0 +#define enable_tracing() +#endif + +#endif /* ! ASM */ + +#ifdef __cplusplus +} +#endif + +#endif /* ! __CPU_h */ diff --git a/c/src/exec/score/cpu/hppa1.1/cpu_asm.h b/c/src/exec/score/cpu/hppa1.1/cpu_asm.h new file mode 100644 index 0000000000..8e480c2a5c --- /dev/null +++ b/c/src/exec/score/cpu/hppa1.1/cpu_asm.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 1990,1991 The University of Utah and + * the Center for Software Science (CSS). All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the Center + * for Software Science at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSS ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSS DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSS requests users of this software to return to css-dist@cs.utah.edu any + * improvements that they make and grant CSS redistribution rights. + * + * Utah $Hdr: asm.h 1.6 91/12/03$ + * + * RTEMS: $Id$ + */ + +/* + * Hardware Space Registers + */ +sr0 .reg %sr0 +sr1 .reg %sr1 +sr2 .reg %sr2 +sr3 .reg %sr3 +sr4 .reg %sr4 +sr5 .reg %sr5 +sr6 .reg %sr6 +sr7 .reg %sr7 + +/* + * Control register aliases + */ + +rctr .reg %cr0 +pidr1 .reg %cr8 +pidr2 .reg %cr9 +ccr .reg %cr10 +sar .reg %cr11 +pidr3 .reg %cr12 +pidr4 .reg %cr13 +iva .reg %cr14 +eiem .reg %cr15 +itmr .reg %cr16 +pcsq .reg %cr17 +pcoq .reg %cr18 +iir .reg %cr19 +isr .reg %cr20 +ior .reg %cr21 +ipsw .reg %cr22 +eirr .reg %cr23 + +/* + * Calling Convention + */ +rp .reg %r2 +arg3 .reg %r23 +arg2 .reg %r24 +arg1 .reg %r25 +arg0 .reg %r26 +dp .reg %r27 +ret0 .reg %r28 +ret1 .reg %r29 +sl .reg %r29 +sp .reg %r30 + + diff --git a/c/src/exec/score/cpu/hppa1.1/cpu_asm.s b/c/src/exec/score/cpu/hppa1.1/cpu_asm.s new file mode 100644 index 0000000000..43a5bb2499 --- /dev/null +++ b/c/src/exec/score/cpu/hppa1.1/cpu_asm.s @@ -0,0 +1,797 @@ +# @(#)cpu_asm.S 1.5 - 95/04/24 +# +# +# TODO: +# Context_switch needs to only save callee save registers +# I think this means can skip: r1, r2, r19-29, r31 +# Ref: p 3-2 of Procedure Calling Conventions Manual +# This should be #ifndef DEBUG so that debugger has +# accurate visibility into all registers +# +# This file contains the assembly code for the HPPA implementation +# of RTEMS. +# +# COPYRIGHT (c) 1994,95 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 + + .SPACE $PRIVATE$ + .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31 + .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82 + .SPACE $TEXT$ + .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44 + .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY + .SPACE $TEXT$ + .SUBSPA $CODE$ + +# +# Special register usage for context switch and interrupts +# Stay away from %cr28 which is used for TLB misses on 72000 +# + +isr_arg0 .reg %cr24 +isr_r9 .reg %cr25 + +# +# Interrupt stack frame looks like this +# +# offset item +# ----------------------------------------------------------------- +# INTEGER_CONTEXT_OFFSET Context_Control +# FP_CONTEXT_OFFSET Context_Control_fp +# +# It is padded out to a multiple of 64 +# + + +# PAGE^L +# void __Generic_ISR_Handler() +# +# This routine provides the RTEMS interrupt management. +# +# NOTE: +# Upon entry, the stack will contain a stack frame back to the +# interrupted task. If dispatching is enabled, this is the +# outer most interrupt, (and a context switch is necessary or +# the current task has signals), then set up the stack to +# transfer control to the interrupt dispatcher. +# +# +# We jump here from the interrupt vector. +# The hardware has done some stuff for us: +# PSW saved in IPSW +# PSW set to 0 +# PSW[E] set to default (0) +# PSW[M] set to 1 iff this is HPMC +# +# IIA queue is frozen (since PSW[Q] is now 0) +# privilege level promoted to 0 +# IIR, ISR, IOR potentially updated if PSW[Q] was 1 at trap +# registers GR 1,8,9,16,17,24,25 copied to shadow regs +# SHR 0 1 2 3 4 5 6 +# +# Our vector stub did the following +# placed vector number is in r1 +# +# stub +# r1 <- vector number +# save ipsw under rock +# ipsw = ipsw & ~1 -- disable ints +# save qregs under rock +# qra = _Generic_ISR_handler +# rfi +# +################################################ + +# Distinct Interrupt Entry Points +# +# The following macro and the 32 instantiations of the macro +# are necessary to determine which interrupt vector occurred. +# The following macro allows a unique entry point to be defined +# for each vector. +# +# r9 was loaded with the vector before branching here +# scratch registers available: gr1, gr8, gr9, gr16, gr17, gr24 +# +# NOTE: +# .align 32 doesn not seem to work in the continuation below +# so just have to count 8 instructions +# +# NOTE: +# this whole scheme needs to be rethought for TLB traps which +# have requirements about what tlb faults they can incur. +# ref: TLB Operation Requirements in 1.1 arch book + +#define THANDLER(vector) \ + mtctl %r9, isr_r9 ! \ + b _Generic_ISR_Handler! \ + ldi vector, %r9! \ + nop ! \ + nop ! \ + nop ! \ + nop ! \ + nop + + .align 4096 + .EXPORT IVA_Table,ENTRY,PRIV_LEV=0 +IVA_Table: + .PROC + .CALLINFO FRAME=0,NO_CALLS + .ENTRY + + THANDLER(0) /* unused */ + + THANDLER(HPPA_INTERRUPT_HIGH_PRIORITY_MACHINE_CHECK) + + THANDLER(HPPA_INTERRUPT_POWER_FAIL) + + THANDLER(HPPA_INTERRUPT_RECOVERY_COUNTER) + + THANDLER(HPPA_INTERRUPT_EXTERNAL_INTERRUPT) + + THANDLER(HPPA_INTERRUPT_LOW_PRIORITY_MACHINE_CHECK) + + THANDLER(HPPA_INTERRUPT_INSTRUCTION_TLB_MISS) + + THANDLER(HPPA_INTERRUPT_INSTRUCTION_MEMORY_PROTECTION) + + THANDLER(HPPA_INTERRUPT_ILLEGAL_INSTRUCTION) + + THANDLER(HPPA_INTERRUPT_BREAK_INSTRUCTION) + + THANDLER(HPPA_INTERRUPT_PRIVILEGED_OPERATION) + + THANDLER(HPPA_INTERRUPT_PRIVILEGED_REGISTER) + + THANDLER(HPPA_INTERRUPT_OVERFLOW) + + THANDLER(HPPA_INTERRUPT_CONDITIONAL) + + THANDLER(HPPA_INTERRUPT_ASSIST_EXCEPTION) + + THANDLER(HPPA_INTERRUPT_DATA_TLB_MISS) + + THANDLER(HPPA_INTERRUPT_NON_ACCESS_INSTRUCTION_TLB_MISS) + + THANDLER(HPPA_INTERRUPT_NON_ACCESS_DATA_TLB_MISS) + + THANDLER(HPPA_INTERRUPT_DATA_MEMORY_PROTECTION) + + THANDLER(HPPA_INTERRUPT_DATA_MEMORY_BREAK) + + THANDLER(HPPA_INTERRUPT_TLB_DIRTY_BIT) + + THANDLER(HPPA_INTERRUPT_PAGE_REFERENCE) + + THANDLER(HPPA_INTERRUPT_ASSIST_EMULATION) + + THANDLER(HPPA_INTERRUPT_HIGHER_PRIVILEGE_TRANSFER) + + THANDLER(HPPA_INTERRUPT_LOWER_PRIVILEGE_TRANSFER) + + THANDLER(HPPA_INTERRUPT_TAKEN_BRANCH) + + THANDLER(HPPA_INTERRUPT_DATA_MEMORY_ACCESS_RIGHTS) + + THANDLER(HPPA_INTERRUPT_DATA_MEMORY_PROTECTION_ID) + + THANDLER(HPPA_INTERRUPT_UNALIGNED_DATA_REFERENCE) + + THANDLER(HPPA_INTERRUPT_PERFORMANCE_MONITOR) + + THANDLER(HPPA_INTERRUPT_INSTRUCTION_DEBUG) + + THANDLER(HPPA_INTERRUPT_DATA_DEBUG) + + .EXIT + .PROCEND + + .EXPORT _Generic_ISR_Handler,ENTRY,PRIV_LEV=0 +_Generic_ISR_Handler: + .PROC + .CALLINFO FRAME=0,NO_CALLS + .ENTRY + +# Turn on the D bit in psw so we can start saving stuff on stack +# (interrupt context pieces that need to be saved before the RFI) + + ssm HPPA_PSW_D, %r0 + mtctl arg0, isr_arg0 + +# save interrupt state + mfctl ipsw, arg0 + stw arg0, IPSW_OFFSET(sp) + + mfctl iir, arg0 + stw arg0, IIR_OFFSET(sp) + + mfctl ior, arg0 + stw arg0, IOR_OFFSET(sp) + + mfctl pcoq, arg0 + stw arg0, PCOQFRONT_OFFSET(sp) + + mtctl %r0, pcoq + mfctl pcoq, arg0 + stw arg0, PCOQBACK_OFFSET(sp) + + mfctl %sar, arg0 + stw arg0, SAR_OFFSET(sp) + +# Prepare to re-enter virtual mode +# We need Q in case the interrupt handler enables interrupts +# + + ldil L%CPU_PSW_DEFAULT, arg0 + ldo R%CPU_PSW_DEFAULT(arg0), arg0 + mtctl arg0, ipsw + +# Now jump to "rest_of_isr_handler" with the rfi +# We are assuming the space queues are all correct already + + ldil L%rest_of_isr_handler, arg0 + ldo R%rest_of_isr_handler(arg0), arg0 + mtctl arg0, pcoq + ldo 4(arg0), arg0 + mtctl arg0, pcoq + + rfi + nop + +# At this point we are back in virtual mode and all our +# normal addressing is once again ok. + +rest_of_isr_handler: + +# +# Build an interrupt frame to hold the contexts we will need. +# We have already saved the interrupt items on the stack + +# At this point the following registers are damaged wrt the interrupt +# reg current value saved value +# ------------------------------------------------ +# arg0 scratch isr_arg0 (ctl) +# r9 vector number isr_r9 (ctl) +# +# Point to beginning of integer context and +# save the integer context + stw %r1,R1_OFFSET(sp) + stw %r2,R2_OFFSET(sp) + stw %r3,R3_OFFSET(sp) + stw %r4,R4_OFFSET(sp) + stw %r5,R5_OFFSET(sp) + stw %r6,R6_OFFSET(sp) + stw %r7,R7_OFFSET(sp) + stw %r8,R8_OFFSET(sp) + stw %r9,R9_OFFSET(sp) + stw %r10,R10_OFFSET(sp) + stw %r11,R11_OFFSET(sp) + stw %r12,R12_OFFSET(sp) + stw %r13,R13_OFFSET(sp) + stw %r14,R14_OFFSET(sp) + stw %r15,R15_OFFSET(sp) + stw %r16,R16_OFFSET(sp) + stw %r17,R17_OFFSET(sp) + stw %r18,R18_OFFSET(sp) + stw %r19,R19_OFFSET(sp) + stw %r20,R20_OFFSET(sp) + stw %r21,R21_OFFSET(sp) + stw %r22,R22_OFFSET(sp) + stw %r23,R23_OFFSET(sp) + stw %r24,R24_OFFSET(sp) + stw %r25,R25_OFFSET(sp) + stw %r26,R26_OFFSET(sp) + stw %r27,R27_OFFSET(sp) + stw %r28,R28_OFFSET(sp) + stw %r29,R29_OFFSET(sp) + stw %r30,R30_OFFSET(sp) + stw %r31,R31_OFFSET(sp) + +# Now most registers are available since they have been saved +# +# The following items are currently wrong in the integer context +# reg current value saved value +# ------------------------------------------------ +# arg0 scratch isr_arg0 (ctl) +# r9 vector number isr_r9 (ctl) +# +# Fix them + + mfctl isr_arg0,%r3 + stw %r3,ARG0_OFFSET(sp) + + mfctl isr_r9,%r3 + stw %r3,R9_OFFSET(sp) + +# +# At this point we are done with isr_arg0, and isr_r9 control registers +# + + +# Point to beginning of float context and +# save the floating point context -- doing whatever patches are necessary + .call ARGW0=GR + bl _CPU_Save_float_context,%r2 + ldo FP_CONTEXT_OFFSET(sp),arg0 + +# save the ptr to interrupt frame as an argument for the interrupt handler + copy sp, arg1 + +# Advance the frame to point beyond all interrupt contexts (integer & float) +# this also includes the pad to align to 64byte stack boundary + ldo CPU_INTERRUPT_FRAME_SIZE(sp), sp + +# r3 -- &_ISR_Nest_level +# r5 -- value _ISR_Nest_level +# r4 -- &_Thread_Dispatch_disable_level +# r6 -- value _Thread_Dispatch_disable_level +# r9 -- vector number + + .import _ISR_Nest_level,data + ldil L%_ISR_Nest_level,%r3 + ldo R%_ISR_Nest_level(%r3),%r3 + ldw 0(%r3),%r5 + + .import _Thread_Dispatch_disable_level,data + ldil L%_Thread_Dispatch_disable_level,%r4 + ldo R%_Thread_Dispatch_disable_level(%r4),%r4 + ldw 0(%r4),%r6 + +# increment interrupt nest level counter. If outermost interrupt +# switch the stack and squirrel away the previous sp. + addi 1,%r5,%r5 + stw %r5, 0(%r3) + +# compute and save new stack (with frame) +# just in case we are nested -- simpler this way + comibf,= 1,%r5,stack_done + ldo 128(sp),%r7 + +# +# Switch to interrupt stack allocated by the interrupt manager (intr.c) +# + .import _CPU_Interrupt_stack_low,data + ldil L%_CPU_Interrupt_stack_low,%r7 + ldw R%_CPU_Interrupt_stack_low(%r7),%r7 + ldo 128(%r7),%r7 + +stack_done: +# save our current stack pointer where the "old sp" is supposed to be + stw sp, -4(%r7) +# and switch stacks (or advance old stack in nested case) + copy %r7, sp + +# increment the dispatch disable level counter. + addi 1,%r6,%r6 + stw %r6, 0(%r4) + +# load address of user handler + .import _ISR_Vector_table,data + ldil L%_ISR_Vector_table,%r8 + ldo R%_ISR_Vector_table(%r8),%r8 + ldwx,s %r9(%r8),%r8 + +# invoke user interrupt handler +# Interrupts are currently disabled, as per RTEMS convention +# The handler has the option of re-enabling interrupts +# NOTE: can not use 'bl' since it uses "pc-relative" addressing +# and we are using a hard coded address from a table +# So... we fudge r2 ourselves (ala dynacall) +# + copy %r9, %r26 + .call ARGW0=GR, ARGW1=GR + blr %r0, rp + bv,n 0(%r8) + +post_user_interrupt_handler: + +# Back from user handler(s) +# Disable external interrupts (since the interrupt handler could +# have turned them on) and return to the interrupted task stack (assuming +# (_ISR_Nest_level == 0) + + rsm HPPA_PSW_I, %r0 + ldw -4(sp), sp + +# r3 -- &_ISR_Nest_level +# r5 -- value _ISR_Nest_level +# r4 -- &_Thread_Dispatch_disable_level +# r6 -- value _Thread_Dispatch_disable_level + + .import _ISR_Nest_level,data + ldil L%_ISR_Nest_level,%r3 + ldo R%_ISR_Nest_level(%r3),%r3 + ldw 0(%r3),%r5 + + .import _Thread_Dispatch_disable_level,data + ldil L%_Thread_Dispatch_disable_level,%r4 + ldo R%_Thread_Dispatch_disable_level(%r4),%r4 + ldw 0(%r4), %r6 + +# decrement isr nest level + addi -1, %r5, %r5 + stw %r5, 0(%r3) + +# decrement dispatch disable level counter and, if not 0, go on + addi -1,%r6,%r6 + comibf,= 0,%r6,isr_restore + stw %r6, 0(%r4) + +# check whether or not a context switch is necessary + .import _Context_Switch_necessary,data + ldil L%_Context_Switch_necessary,%r8 + ldw R%_Context_Switch_necessary(%r8),%r8 + comibf,=,n 0,%r8,ISR_dispatch + +# check whether or not a context switch is necessary because an ISR +# sent signals to the interrupted task + .import _ISR_Signals_to_thread_executing,data + ldil L%_ISR_Signals_to_thread_executing,%r8 + ldw R%_ISR_Signals_to_thread_executing(%r8),%r8 + comibt,=,n 0,%r8,isr_restore + +# OK, something happened while in ISR and we need to switch to a task +# other than the one which was interrupted or the +# ISR_Signals_to_thread_executing case +# We also turn on interrupts, since the interrupted task had them +# on (obviously :-) and Thread_Dispatch is happy to leave ints on. +# + +ISR_dispatch: + ssm HPPA_PSW_I, %r0 + + .import _Thread_Dispatch,code + .call + bl _Thread_Dispatch,%r2 + ldo 128(sp),sp + + ldo -128(sp),sp + + rsm HPPA_PSW_I, %r0 + +isr_restore: + +# Get a pointer to beginning of our stack frame + ldo -CPU_INTERRUPT_FRAME_SIZE(sp), %arg1 + +# restore float + .call ARGW0=GR + bl _CPU_Restore_float_context,%r2 + ldo FP_CONTEXT_OFFSET(%arg1), arg0 + + copy %arg1, %arg0 + +# ********** FALL THRU ********** + +# Jump here from bottom of Context_Switch +# Also called directly by _CPU_Context_Restart_self via _Thread_Restart_self +# restore interrupt state +# + + .EXPORT _CPU_Context_restore +_CPU_Context_restore: + +# Turn off Q & I so we can write pcoq + rsm HPPA_PSW_Q + HPPA_PSW_I, %r0 + + ldw IPSW_OFFSET(arg0), %r8 + mtctl %r8, ipsw + + ldw SAR_OFFSET(arg0), %r9 + mtctl %r9, sar + + ldw PCOQFRONT_OFFSET(arg0), %r10 + mtctl %r10, pcoq + + ldw PCOQBACK_OFFSET(arg0), %r11 + mtctl %r11, pcoq + +# +# restore integer state +# + ldw R1_OFFSET(arg0),%r1 + ldw R2_OFFSET(arg0),%r2 + ldw R3_OFFSET(arg0),%r3 + ldw R4_OFFSET(arg0),%r4 + ldw R5_OFFSET(arg0),%r5 + ldw R6_OFFSET(arg0),%r6 + ldw R7_OFFSET(arg0),%r7 + ldw R8_OFFSET(arg0),%r8 + ldw R9_OFFSET(arg0),%r9 + ldw R10_OFFSET(arg0),%r10 + ldw R11_OFFSET(arg0),%r11 + ldw R12_OFFSET(arg0),%r12 + ldw R13_OFFSET(arg0),%r13 + ldw R14_OFFSET(arg0),%r14 + ldw R15_OFFSET(arg0),%r15 + ldw R16_OFFSET(arg0),%r16 + ldw R17_OFFSET(arg0),%r17 + ldw R18_OFFSET(arg0),%r18 + ldw R19_OFFSET(arg0),%r19 + ldw R20_OFFSET(arg0),%r20 + ldw R21_OFFSET(arg0),%r21 + ldw R22_OFFSET(arg0),%r22 + ldw R23_OFFSET(arg0),%r23 + ldw R24_OFFSET(arg0),%r24 + ldw R25_OFFSET(arg0),%r25 +# skipping r26 (aka arg0) until we are done with it + ldw R27_OFFSET(arg0),%r27 + ldw R28_OFFSET(arg0),%r28 + ldw R29_OFFSET(arg0),%r29 + ldw R30_OFFSET(arg0),%r30 + ldw R31_OFFSET(arg0),%r31 + +# Must load r26 last since it is arg0 + ldw R26_OFFSET(arg0),%r26 + +isr_exit: + rfi + .EXIT + .PROCEND + +# +# This section is used to context switch floating point registers. +# Ref: 6-35 of Architecture 1.1 +# +# NOTE: since integer multiply uses the floating point unit, +# we have to save/restore fp on every trap. We cannot +# just try to keep track of fp usage. + + .align 32 + .EXPORT _CPU_Save_float_context,ENTRY,PRIV_LEV=0 +_CPU_Save_float_context: + .PROC + .CALLINFO FRAME=0,NO_CALLS + .ENTRY + fstds,ma %fr0,8(%arg0) + fstds,ma %fr1,8(%arg0) + fstds,ma %fr2,8(%arg0) + fstds,ma %fr3,8(%arg0) + fstds,ma %fr4,8(%arg0) + fstds,ma %fr5,8(%arg0) + fstds,ma %fr6,8(%arg0) + fstds,ma %fr7,8(%arg0) + fstds,ma %fr8,8(%arg0) + fstds,ma %fr9,8(%arg0) + fstds,ma %fr10,8(%arg0) + fstds,ma %fr11,8(%arg0) + fstds,ma %fr12,8(%arg0) + fstds,ma %fr13,8(%arg0) + fstds,ma %fr14,8(%arg0) + fstds,ma %fr15,8(%arg0) + fstds,ma %fr16,8(%arg0) + fstds,ma %fr17,8(%arg0) + fstds,ma %fr18,8(%arg0) + fstds,ma %fr19,8(%arg0) + fstds,ma %fr20,8(%arg0) + fstds,ma %fr21,8(%arg0) + fstds,ma %fr22,8(%arg0) + fstds,ma %fr23,8(%arg0) + fstds,ma %fr24,8(%arg0) + fstds,ma %fr25,8(%arg0) + fstds,ma %fr26,8(%arg0) + fstds,ma %fr27,8(%arg0) + fstds,ma %fr28,8(%arg0) + fstds,ma %fr29,8(%arg0) + fstds,ma %fr30,8(%arg0) + fstds %fr31,0(%arg0) + bv 0(%r2) + addi -(31*8), %arg0, %arg0 ; restore arg0 just for fun + .EXIT + .PROCEND + + .align 32 + .EXPORT _CPU_Restore_float_context,ENTRY,PRIV_LEV=0 +_CPU_Restore_float_context: + .PROC + .CALLINFO FRAME=0,NO_CALLS + .ENTRY + addi (31*8), %arg0, %arg0 ; point at last double + fldds 0(%arg0),%fr31 + fldds,mb -8(%arg0),%fr30 + fldds,mb -8(%arg0),%fr29 + fldds,mb -8(%arg0),%fr28 + fldds,mb -8(%arg0),%fr27 + fldds,mb -8(%arg0),%fr26 + fldds,mb -8(%arg0),%fr25 + fldds,mb -8(%arg0),%fr24 + fldds,mb -8(%arg0),%fr23 + fldds,mb -8(%arg0),%fr22 + fldds,mb -8(%arg0),%fr21 + fldds,mb -8(%arg0),%fr20 + fldds,mb -8(%arg0),%fr19 + fldds,mb -8(%arg0),%fr18 + fldds,mb -8(%arg0),%fr17 + fldds,mb -8(%arg0),%fr16 + fldds,mb -8(%arg0),%fr15 + fldds,mb -8(%arg0),%fr14 + fldds,mb -8(%arg0),%fr13 + fldds,mb -8(%arg0),%fr12 + fldds,mb -8(%arg0),%fr11 + fldds,mb -8(%arg0),%fr10 + fldds,mb -8(%arg0),%fr9 + fldds,mb -8(%arg0),%fr8 + fldds,mb -8(%arg0),%fr7 + fldds,mb -8(%arg0),%fr6 + fldds,mb -8(%arg0),%fr5 + fldds,mb -8(%arg0),%fr4 + fldds,mb -8(%arg0),%fr3 + fldds,mb -8(%arg0),%fr2 + fldds,mb -8(%arg0),%fr1 + bv 0(%r2) + fldds,mb -8(%arg0),%fr0 + .EXIT + .PROCEND + +# +# These 2 small routines are unused right now. +# Normally we just go thru _CPU_Save_float_context (and Restore) +# +# Here we just deref the ptr and jump up, letting _CPU_Save_float_context +# do the return for us. +# + .EXPORT _CPU_Context_save_fp,ENTRY,PRIV_LEV=0 +_CPU_Context_save_fp: + .PROC + .CALLINFO FRAME=0,NO_CALLS + .ENTRY + bl _CPU_Save_float_context, %r0 + ldw 0(%arg0), %arg0 + .EXIT + .PROCEND + + .EXPORT _CPU_Context_restore_fp,ENTRY,PRIV_LEV=0 +_CPU_Context_restore_fp: + .PROC + .CALLINFO FRAME=0,NO_CALLS + .ENTRY + bl _CPU_Restore_float_context, %r0 + ldw 0(%arg0), %arg0 + .EXIT + .PROCEND + + +# void _CPU_Context_switch( run_context, heir_context ) +# +# This routine performs a normal non-FP context switch. +# + + .align 32 + .EXPORT _CPU_Context_switch,ENTRY,PRIV_LEV=0,ARGW0=GR,ARGW1=GR +_CPU_Context_switch: + .PROC + .CALLINFO FRAME=64 + .ENTRY + +# Save the integer context + stw %r1,R1_OFFSET(arg0) + stw %r2,R2_OFFSET(arg0) + stw %r3,R3_OFFSET(arg0) + stw %r4,R4_OFFSET(arg0) + stw %r5,R5_OFFSET(arg0) + stw %r6,R6_OFFSET(arg0) + stw %r7,R7_OFFSET(arg0) + stw %r8,R8_OFFSET(arg0) + stw %r9,R9_OFFSET(arg0) + stw %r10,R10_OFFSET(arg0) + stw %r11,R11_OFFSET(arg0) + stw %r12,R12_OFFSET(arg0) + stw %r13,R13_OFFSET(arg0) + stw %r14,R14_OFFSET(arg0) + stw %r15,R15_OFFSET(arg0) + stw %r16,R16_OFFSET(arg0) + stw %r17,R17_OFFSET(arg0) + stw %r18,R18_OFFSET(arg0) + stw %r19,R19_OFFSET(arg0) + stw %r20,R20_OFFSET(arg0) + stw %r21,R21_OFFSET(arg0) + stw %r22,R22_OFFSET(arg0) + stw %r23,R23_OFFSET(arg0) + stw %r24,R24_OFFSET(arg0) + stw %r25,R25_OFFSET(arg0) + stw %r26,R26_OFFSET(arg0) + stw %r27,R27_OFFSET(arg0) + stw %r28,R28_OFFSET(arg0) + stw %r29,R29_OFFSET(arg0) + stw %r30,R30_OFFSET(arg0) + stw %r31,R31_OFFSET(arg0) + +# fill in interrupt context section + stw %r2, PCOQFRONT_OFFSET(%arg0) + ldo 4(%r2), %r2 + stw %r2, PCOQBACK_OFFSET(%arg0) + +# Generate a suitable IPSW by using the system default psw +# with the current low bits added in. + + ldil L%CPU_PSW_DEFAULT, %r2 + ldo R%CPU_PSW_DEFAULT(%r2), %r2 + ssm 0, %arg2 + dep %arg2, 31, 8, %r2 + stw %r2, IPSW_OFFSET(%arg0) + +# at this point, the running task context is completely saved +# Now jump to the bottom of the interrupt handler to load the +# heirs context + + b _CPU_Context_restore + copy %arg1, %arg0 + + .EXIT + .PROCEND + + +/* + * Find first bit + * NOTE: + * This is used (and written) only for the ready chain code and + * priority bit maps. + * Any other use constitutes fraud. + * Returns first bit from the least significant side. + * Eg: if input is 0x8001 + * output will indicate the '1' bit and return 0. + * This is counter to HPPA bit numbering which calls this + * bit 31. This way simplifies the macros _CPU_Priority_Mask + * and _CPU_Priority_Bits_index. + * + * NOTE: + * We just use 16 bit version + * does not handle zero case + * + * Based on the UTAH Mach libc version of ffs. + */ + + .align 32 + .EXPORT hppa_rtems_ffs,ENTRY,PRIV_LEV=0,ARGW0=GR +hppa_rtems_ffs: + .PROC + .CALLINFO FRAME=0,NO_CALLS + .ENTRY + +#ifdef RETURN_ERROR_ON_ZERO + comb,= %arg0,%r0,ffsdone ; If arg0 is 0 + ldi -1,%ret0 ; return -1 +#endif + +#if BITFIELD_SIZE == 32 + ldi 31,%ret0 ; Set return to high bit + extru,= %arg0,31,16,%r0 ; If low 16 bits are non-zero + addi,tr -16,%ret0,%ret0 ; subtract 16 from bitpos + shd %r0,%arg0,16,%arg0 ; else shift right 16 bits +#else + ldi 15,%ret0 ; Set return to high bit +#endif + extru,= %arg0,31,8,%r0 ; If low 8 bits are non-zero + addi,tr -8,%ret0,%ret0 ; subtract 8 from bitpos + shd %r0,%arg0,8,%arg0 ; else shift right 8 bits + extru,= %arg0,31,4,%r0 ; If low 4 bits are non-zero + addi,tr -4,%ret0,%ret0 ; subtract 4 from bitpos + shd %r0,%arg0,4,%arg0 ; else shift right 4 bits + extru,= %arg0,31,2,%r0 ; If low 2 bits are non-zero + addi,tr -2,%ret0,%ret0 ; subtract 2 from bitpos + shd %r0,%arg0,2,%arg0 ; else shift right 2 bits + extru,= %arg0,31,1,%r0 ; If low bit is non-zero + addi -1,%ret0,%ret0 ; subtract 1 from bitpos +ffsdone: + bv,n 0(%r2) + nop + .EXIT + .PROCEND diff --git a/c/src/exec/score/cpu/hppa1.1/hppa.h b/c/src/exec/score/cpu/hppa1.1/hppa.h new file mode 100644 index 0000000000..8829bb8c87 --- /dev/null +++ b/c/src/exec/score/cpu/hppa1.1/hppa.h @@ -0,0 +1,704 @@ +/* + * @(#)hppa.h 1.5 - 95/04/25 + * + * + * File: $RCSfile$ + * Project: PixelFlow + * Created: 94/10/4 + * RespEngr: tony bennett + * Revision: $Revision$ + * Last Mod: $Date$ + * + * Description: + * + * Definitions for HP PA Risc + * ref: PA RISC 1.1 Architecture and Instruction Set Reference Manual + * + * 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. + * + * + * Note: + * This file is included by both C and assembler code ( -DASM ) + * + * $Id$ + */ + +#ifndef _INCLUDE_HPPA_H +#define _INCLUDE_HPPA_H + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * The following define the CPU Family and Model within the family + * + * NOTE: The string "REPLACE_THIS_WITH_THE_CPU_MODEL" is replaced + * with the name of the appropriate macro for this target CPU. + */ + +#define hppa1_1 +#define REPLACE_THIS_WITH_THE_CPU_MODEL +#define REPLACE_THIS_WITH_THE_BSP + +/* + * This section contains the information required to build + * RTEMS for a particular member of the Hewlett Packard + * PA-RISC family. It does this by setting variables to + * indicate which implementation dependent features are + * present in a particular member of the family. + */ + +#if defined(hppa7100) + +#define RTEMS_MODEL_NAME "hppa 7100" + +#elif defined(hppa7200) + +#define RTEMS_MODEL_NAME "hppa 7200" + +#else + +#error "Unsupported CPU Model" + +#endif + +/* + * Define the name of the CPU family. + */ + +#define CPU_NAME "HP PA-RISC 1.1" + +#ifndef ASM +/* + * This section defines the basic types for this processor. + */ + +typedef unsigned char unsigned8; /* 8-bit unsigned integer */ +typedef unsigned short unsigned16; /* 16-bit unsigned integer */ +typedef unsigned int unsigned32; /* 32-bit unsigned integer */ +typedef unsigned long long unsigned64; /* 64-bit unsigned integer */ + +typedef unsigned16 Priority_Bit_map_control; + +typedef char signed8; /* 8-bit signed integer */ +typedef short signed16; /* 16-bit signed integer */ +typedef int signed32; /* 32-bit signed integer */ +typedef long long signed64; /* 64 bit signed integer */ + +typedef unsigned32 boolean; /* Boolean value */ + +typedef float single_precision; /* single precision float */ +typedef double double_precision; /* double precision float */ + +#endif /* !ASM */ + + +/* + * Processor Status Word (PSW) Masks + */ + +#define HPPA_PSW_Y 0x80000000 /* Data Debug Trap Disable */ +#define HPPA_PSW_Z 0x40000000 /* Instruction Debug Trap Disable */ +#define HPPA_PSW_r2 0x20000000 /* reserved */ +#define HPPA_PSW_r3 0x10000000 /* reserved */ +#define HPPA_PSW_r4 0x08000000 /* reserved */ +#define HPPA_PSW_E 0x04000000 /* Little Endian on Memory References */ +#define HPPA_PSW_S 0x02000000 /* Secure Interval Timer */ +#define HPPA_PSW_T 0x01000000 /* Taken Branch Trap Enable */ +#define HPPA_PSW_H 0x00800000 /* Higher-Privilege Transfer Trap Enable*/ +#define HPPA_PSW_L 0x00400000 /* Lower-Privilege Transfer Trap Enable */ +#define HPPA_PSW_N 0x00200000 /* PC Queue Front Instruction Nullified */ +#define HPPA_PSW_X 0x00100000 /* Data Memory Break Disable */ +#define HPPA_PSW_B 0x00080000 /* Taken Branch in Previous Cycle */ +#define HPPA_PSW_C 0x00040000 /* Code Address Translation Enable */ +#define HPPA_PSW_V 0x00020000 /* Divide Step Correction */ +#define HPPA_PSW_M 0x00010000 /* High-Priority Machine Check Disable */ +#define HPPA_PSW_CB 0x0000ff00 /* Carry/Borrow Bits */ +#define HPPA_PSW_r24 0x00000080 /* reserved */ +#define HPPA_PSW_G 0x00000040 /* Debug trap Enable */ +#define HPPA_PSW_F 0x00000020 /* Performance monitor interrupt unmask */ +#define HPPA_PSW_R 0x00000010 /* Recovery Counter Enable */ +#define HPPA_PSW_Q 0x00000008 /* Interruption State Collection Enable */ +#define HPPA_PSW_P 0x00000004 /* Protection ID Validation Enable */ +#define HPPA_PSW_D 0x00000002 /* Data Address Translation Enable */ +#define HPPA_PSW_I 0x00000001 /* External, Power Failure, */ + /* Low-Priority Machine Check */ + /* Interruption Enable */ + +/* + * HPPA traps and interrupts + * basic layout. Note numbers do not denote priority + * + * 0-31 basic traps and interrupts defined by HPPA architecture + * 32-63 32 external interrupts + * 64-... bsp defined + */ + +#define HPPA_INTERRUPT_NON_EXISTENT 0 +/* group 1 */ +#define HPPA_INTERRUPT_HIGH_PRIORITY_MACHINE_CHECK 1 +/* group 2 */ +#define HPPA_INTERRUPT_POWER_FAIL 2 +#define HPPA_INTERRUPT_RECOVERY_COUNTER 3 +#define HPPA_INTERRUPT_EXTERNAL_INTERRUPT 4 +#define HPPA_INTERRUPT_LOW_PRIORITY_MACHINE_CHECK 5 +#define HPPA_INTERRUPT_PERFORMANCE_MONITOR 29 +/* group 3 */ +#define HPPA_INTERRUPT_INSTRUCTION_TLB_MISS 6 +#define HPPA_INTERRUPT_INSTRUCTION_MEMORY_PROTECTION 7 +#define HPPA_INTERRUPT_INSTRUCTION_DEBUG 30 +#define HPPA_INTERRUPT_ILLEGAL_INSTRUCTION 8 +#define HPPA_INTERRUPT_BREAK_INSTRUCTION 9 +#define HPPA_INTERRUPT_PRIVILEGED_OPERATION 10 +#define HPPA_INTERRUPT_PRIVILEGED_REGISTER 11 +#define HPPA_INTERRUPT_OVERFLOW 12 +#define HPPA_INTERRUPT_CONDITIONAL 13 +#define HPPA_INTERRUPT_ASSIST_EXCEPTION 14 +#define HPPA_INTERRUPT_DATA_TLB_MISS 15 +#define HPPA_INTERRUPT_NON_ACCESS_INSTRUCTION_TLB_MISS 16 +#define HPPA_INTERRUPT_NON_ACCESS_DATA_TLB_MISS 17 +#define HPPA_INTERRUPT_DATA_MEMORY_ACCESS_RIGHTS 26 +#define HPPA_INTERRUPT_DATA_MEMORY_PROTECTION_ID 27 +#define HPPA_INTERRUPT_UNALIGNED_DATA_REFERENCE 28 +#define HPPA_INTERRUPT_DATA_MEMORY_PROTECTION 18 +#define HPPA_INTERRUPT_DATA_MEMORY_BREAK 19 +#define HPPA_INTERRUPT_TLB_DIRTY_BIT 20 +#define HPPA_INTERRUPT_PAGE_REFERENCE 21 +#define HPPA_INTERRUPT_DATA_DEBUG 31 +#define HPPA_INTERRUPT_ASSIST_EMULATION 22 +/* group 4 */ +#define HPPA_INTERRUPT_HIGHER_PRIVILEGE_TRANSFER 23 +#define HPPA_INTERRUPT_LOWER_PRIVILEGE_TRANSFER 24 +#define HPPA_INTERRUPT_TAKEN_BRANCH 25 + +#define HPPA_INTERRUPT_ON_CHIP_MAX 31 + +/* External Interrupts via interrupt 4 */ + +#define HPPA_INTERRUPT_EXTERNAL_BASE 32 + +#define HPPA_INTERRUPT_EXTERNAL_0 32 +#define HPPA_INTERRUPT_EXTERNAL_1 33 +#define HPPA_INTERRUPT_EXTERNAL_2 34 +#define HPPA_INTERRUPT_EXTERNAL_3 35 +#define HPPA_INTERRUPT_EXTERNAL_4 36 +#define HPPA_INTERRUPT_EXTERNAL_5 37 +#define HPPA_INTERRUPT_EXTERNAL_6 38 +#define HPPA_INTERRUPT_EXTERNAL_7 39 +#define HPPA_INTERRUPT_EXTERNAL_8 40 +#define HPPA_INTERRUPT_EXTERNAL_9 41 +#define HPPA_INTERRUPT_EXTERNAL_10 42 +#define HPPA_INTERRUPT_EXTERNAL_11 43 +#define HPPA_INTERRUPT_EXTERNAL_12 44 +#define HPPA_INTERRUPT_EXTERNAL_13 45 +#define HPPA_INTERRUPT_EXTERNAL_14 46 +#define HPPA_INTERRUPT_EXTERNAL_15 47 +#define HPPA_INTERRUPT_EXTERNAL_16 48 +#define HPPA_INTERRUPT_EXTERNAL_17 49 +#define HPPA_INTERRUPT_EXTERNAL_18 50 +#define HPPA_INTERRUPT_EXTERNAL_19 51 +#define HPPA_INTERRUPT_EXTERNAL_20 52 +#define HPPA_INTERRUPT_EXTERNAL_21 53 +#define HPPA_INTERRUPT_EXTERNAL_22 54 +#define HPPA_INTERRUPT_EXTERNAL_23 55 +#define HPPA_INTERRUPT_EXTERNAL_24 56 +#define HPPA_INTERRUPT_EXTERNAL_25 57 +#define HPPA_INTERRUPT_EXTERNAL_26 58 +#define HPPA_INTERRUPT_EXTERNAL_27 59 +#define HPPA_INTERRUPT_EXTERNAL_28 60 +#define HPPA_INTERRUPT_EXTERNAL_29 61 +#define HPPA_INTERRUPT_EXTERNAL_30 62 +#define HPPA_INTERRUPT_EXTERNAL_31 63 + +#define HPPA_INTERRUPT_EXTERNAL_INTERVAL_TIMER HPPA_INTERRUPT_EXTERNAL_0 +#define HPPA_EXTERNAL_INTERRUPTS 32 + +/* BSP defined interrupts begin here */ + +#define HPPA_INTERRUPT_MAX 64 + +/* + * Inline macros for misc. interesting opcodes + */ + +/* generate a global label */ +#define HPPA_ASM_LABEL(label) \ + asm(".export " label ", ! .label " label); + +/* Return From Interrupt RFI */ +#define HPPA_ASM_RFI() asm volatile ("rfi") + +/* Set System Mask SSM i,t */ +#define HPPA_ASM_SSM(i,gr) asm volatile ("ssm %1, %0" \ + : "=r" (gr) \ + : "i" (i)) +/* Reset System Mask RSM i,t */ +#define HPPA_ASM_RSM(i,gr) asm volatile ("rsm %1, %0" \ + : "=r" (gr) \ + : "i" (i)) +/* Move To System Mask MTSM r */ +#define HPPA_ASM_MTSM(gr) asm volatile ("mtsm %0" \ + : : "r" (gr)) + +/* Load Space Identifier LDSID (s,b),t */ +#define HPPA_ASM_LDSID(sr,grb,grt) asm volatile ("ldsid (%1,%2),%0" \ + : "=r" (grt) \ + : "i" (sr), \ + "r" (grb)) + +/* + * Gcc extended asm doesn't really allow for treatment of space registers + * as "registers", so we have to use "i" format. + * Unfortunately this means that the "=" constraint is not available. + */ + +/* Move To Space Register MTSP r,sr */ +#define HPPA_ASM_MTSP(gr,sr) asm volatile ("mtsp %1,%0" \ + : : "i" (sr), \ + "r" (gr)) + +/* Move From Space Register MFSP sr,t */ +#define HPPA_ASM_MFSP(sr,gr) asm volatile ("mfsp %1,%0" \ + : "=r" (gr) \ + : "i" (sr)) + +/* Move To Control register MTCTL r,t */ +#define HPPA_ASM_MTCTL(gr,cr) asm volatile ("mtctl %1,%0" \ + : : "i" (cr), \ + "r" (gr)) + +/* Move From Control register MFCTL r,t */ +#define HPPA_ASM_MFCTL(cr,gr) asm volatile ("mfctl %1,%0" \ + : "=r" (gr) \ + : "i" (cr)) + +/* Synchronize caches SYNC */ +#define HPPA_ASM_SYNC() asm volatile ("sync") + +/* Probe Read Access PROBER (s,b),r,t */ +#define HPPA_ASM_PROBER(sr,groff,gracc,grt) \ + asm volatile ("prober (%1,%2),%3,%0" \ + : "=r" (grt) \ + : "i" (sr), \ + "r" (groff), \ + "r" (gracc)) + +/* Probe Read Access Immediate PROBERI (s,b),i,t*/ +#define HPPA_ASM_PROBERI(sr,groff,iacc,grt) \ + asm volatile ("proberi (%1,%2),%3,%0" \ + : "=r" (grt) \ + : "i" (sr), \ + "r" (groff), \ + "i" (iacc)) + +/* Probe Write Access PROBEW (s,b),r,t */ +#define HPPA_ASM_PROBEW(sr,groff,gracc,grt) \ + asm volatile ("probew (%1,%2),%3,%0" \ + : "=r" (grt) \ + : "i" (sr), \ + "r" (groff), \ + "r" (gracc)) + +/* Probe Write Access Immediate PROBEWI (s,b),i,t */ +#define HPPA_ASM_PROBEWI(sr,groff,iacc,grt) \ + asm volatile ("probewi (%1,%2),%3,%0" \ + : "=r" (grt) \ + : "i" (sr), \ + "r" (groff), \ + "i" (iacc)) + +/* Load Physical Address LPA x(s,b),t */ +#define HPPA_ASM_LPA(sr,grb,grt) asm volatile ("lpa %%r0(%1,%2),%0" \ + : "=r" (grt) \ + : "i" (sr), \ + "r" (grb)) + +/* Load Coherence Index LCI x(s,b),t */ +/* AKA: Load Hash Address LHA x(s,b),t */ +#define HPPA_ASM_LCI(grx,sr,grb,grt) asm volatile ("lha %1(%2,%3),%0" \ + : "=r" (grt) \ + : "r" (grx),\ + "i" (sr), \ + "r" (grb)) +#define HPPA_ASM_LHA(grx,sr,grb,grt) HPPA_ASM_LCI(grx,sr,grb,grt) + +/* Purge Data Tlb PDTLB x(s,b) */ +#define HPPA_ASM_PDTLB(grx,sr,grb) asm volatile ("pdtlb %0(%1,%2)" \ + : : "r" (grx), \ + "i" (sr), \ + "r" (grb)) + +/* Purge Instruction Tlb PITLB x(s,b) */ +#define HPPA_ASM_PITLB(grx,sr,grb) asm volatile ("pitlb %0(%1,%2)" \ + : : "r" (grx), \ + "i" (sr), \ + "r" (grb)) + +/* Purge Data Tlb Entry PDTLBE x(s,b) */ +#define HPPA_ASM_PDTLBE(grx,sr,grb) asm volatile ("pdtlbe %0(%1,%2)" \ + : : "r" (grx), \ + "i" (sr), \ + "r" (grb)) + +/* Purge Instruction Tlb Entry PITLBE x(s,b) */ +#define HPPA_ASM_PITLBE(grx,sr,grb) asm volatile ("pitlbe %0(%1,%2)" \ + : : "r" (grx), \ + "i" (sr), \ + "r" (grb)) + + +/* Insert Data TLB Address IDTLBA r,(s,b) */ +#define HPPA_ASM_IDTLBA(gr,sr,grb) asm volatile ("idtlba %0,(%1,%2)" \ + : : "r" (gr), \ + "i" (sr), \ + "r" (grb)) + +/* Insert Instruction TLB Address IITLBA r,(s,b) */ +#define HPPA_ASM_IITLBA(gr,sr,grb) asm volatile ("iitlba %0,(%1,%2)" \ + : : "r" (gr), \ + "i" (sr), \ + "r" (grb)) + +/* Insert Data TLB Protection IDTLBP r,(s,b) */ +#define HPPA_ASM_IDTLBP(gr,sr,grb) asm volatile ("idtlbp %0,(%1,%2)" \ + : : "r" (gr), \ + "i" (sr), \ + "r" (grb)) + +/* Insert Instruction TLB Protection IITLBP r,(s,b) */ +#define HPPA_ASM_IITLBP(gr,sr,grb) asm volatile ("iitlbp %0,(%1,%2)" \ + : : "r" (gr), \ + "i" (sr), \ + "r" (grb)) + +/* Purge Data Cache PDC x(s,b) */ +#define HPPA_ASM_PDC(grx,sr,grb) asm volatile ("pdc %0(%1,%2)" \ + : : "r" (grx), \ + "i" (sr), \ + "r" (grb)) + +/* Flush Data Cache FDC x(s,b) */ +#define HPPA_ASM_FDC(grx,sr,grb) asm volatile ("fdc %0(%1,%2)" \ + : : "r" (grx), \ + "i" (sr), \ + "r" (grb)) + +/* Flush Instruction Cache FDC x(s,b) */ +#define HPPA_ASM_FIC(grx,sr,grb) asm volatile ("fic %0(%1,%2)" \ + : : "r" (grx), \ + "i" (sr), \ + "r" (grb)) + +/* Flush Data Cache Entry FDCE x(s,b) */ +#define HPPA_ASM_FDCE(grx,sr,grb) asm volatile ("fdce %0(%1,%2)" \ + : : "r" (grx), \ + "i" (sr), \ + "r" (grb)) + +/* Flush Instruction Cache Entry FICE x(s,b) */ +#define HPPA_ASM_FICE(grx,sr,grb) asm volatile ("fice %0(%1,%2)" \ + : : "r" (grx), \ + "i" (sr), \ + "r" (grb)) + +/* Break BREAK i5,i13 */ +#define HPPA_ASM_BREAK(i5,i13) asm volatile ("break %0,%1" \ + : : "i" (i5), \ + "i" (i13)) + +/* Load and Clear Word Short LDCWS d(s,b),t */ +#define HPPA_ASM_LDCWS(i,sr,grb,grt) asm volatile ("ldcws %1(%2,%3),%0" \ + : "=r" (grt) \ + : "i" (i), \ + "i" (sr), \ + "r" (grb)) + +/* Load and Clear Word Indexed LDCWX x(s,b),t */ +#define HPPA_ASM_LDCWX(grx,sr,grb,grt) asm volatile ("ldcwx %1(%2,%3),%0" \ + : "=r" (grt) \ + : "r" (grx), \ + "i" (sr), \ + "r" (grb)) + +/* Load Word Absolute Short LDWAS d(b),t */ +/* NOTE: "short" here means "short displacement" */ +#define HPPA_ASM_LDWAS(disp,grbase,gr) asm volatile("ldwas %1(%2),%0" \ + : "=r" (gr) \ + : "i" (disp), \ + "r" (grbase)) + +/* Store Word Absolute Short STWAS r,d(b) */ +/* NOTE: "short" here means "short displacement" */ +#define HPPA_ASM_STWAS(gr,disp,grbase) asm volatile("stwas %0,%1(%2)" \ + : : "r" (gr), \ + "i" (disp), \ + "r" (grbase)) + +/* + * Swap bytes + * REFERENCE: PA72000 TRM -- Appendix C + */ +#define HPPA_ASM_SWAPBYTES(value, swapped) asm volatile( \ + " shd %1,%1,16,%0 \n\ + dep %0,15,8,%0 \n\ + shd %1,%0,8,%0" \ + : "=r" (swapped) \ + : "r" (value) \ + ) + + +/* 72000 Diagnose instructions follow + * These macros assume gas knows about these instructions. + * gas2.2.u1 did not. + * I added them to my copy and installed it locally. + * + * There are *very* special requirements for these guys + * ref: TRM 6.1.3 Programming Constraints + * + * The macros below handle the following rules + * + * Except for WIT, WDT, WDD, WIDO, WIDE, all DIAGNOSE must be doubled. + * Must never be nullified (hence the leading nop) + * NOP must preced every RDD,RDT,WDD,WDT,RDTLB + * Instruction preceeding GR_SHDW must not set any of the GR's saved + * + * The macros do *NOT* deal with the following problems + * doubled DIAGNOSE instructions must not straddle a page boundary + * if code translation enabled. (since 2nd could trap on ITLB) + * If you care about DHIT and DPE bits of DR0, then + * No store instruction in the 2 insn window before RDD + */ + + +/* Move To CPU/DIAG register MTCPU r,t */ +#define HPPA_ASM_MTCPU(gr,dr) asm volatile (" nop \n" \ + " mtcpu %1,%0 \n" \ + " mtcpu %1,%0" \ + : : "i" (dr), \ + "r" (gr)) + +/* Move From CPU/DIAG register MFCPU r,t */ +#define HPPA_ASM_MFCPU(dr,gr) asm volatile (" nop \n" \ + " mfcpu %1,%0\n" \ + " mfcpu %1,%0" \ + : "=r" (gr) \ + : "i" (dr)) + +/* Transfer of Control Enable TOC_EN */ +#define HPPA_ASM_TOC_EN() asm volatile (" tocen \n" \ + " tocen") + +/* Transfer of Control Disable TOC_DIS */ +#define HPPA_ASM_TOC_DIS() asm volatile (" tocdis \n" \ + " tocdis") + +/* Shadow Registers to General Register SHDW_GR */ +#define HPPA_ASM_SHDW_GR() asm volatile (" shdwgr \n" \ + " shdwgr" \ + ::: "r1" "r8" "r9" "r16" \ + "r17" "r24" "r25") + +/* General Registers to Shadow Register GR_SHDW */ +#define HPPA_ASM_GR_SHDW() asm volatile (" nop \n" \ + " grshdw \n" \ + " grshdw") + +/* + * Definitions of special registers for use by the above macros. + */ + +/* Hardware Space Registers */ +#define SR0 0 +#define SR1 1 +#define SR2 2 +#define SR3 3 +#define SR4 4 +#define SR5 5 +#define SR6 6 +#define SR7 7 + +/* Hardware Control Registers */ +#define CR0 0 +#define RCTR 0 /* Recovery Counter Register */ + +#define CR8 8 /* Protection ID 1 */ +#define PIDR1 8 + +#define CR9 9 /* Protection ID 2 */ +#define PIDR2 9 + +#define CR10 10 +#define CCR 10 /* Coprocessor Confiquration Register */ + +#define CR11 11 +#define SAR 11 /* Shift Amount Register */ + +#define CR12 12 +#define PIDR3 12 /* Protection ID 3 */ + +#define CR13 13 +#define PIDR4 13 /* Protection ID 4 */ + +#define CR14 14 +#define IVA 14 /* Interrupt Vector Address */ + +#define CR15 15 +#define EIEM 15 /* External Interrupt Enable Mask */ + +#define CR16 16 +#define ITMR 16 /* Interval Timer */ + +#define CR17 17 +#define PCSQ 17 /* Program Counter Space queue */ + +#define CR18 18 +#define PCOQ 18 /* Program Counter Offset queue */ + +#define CR19 19 +#define IIR 19 /* Interruption Instruction Register */ + +#define CR20 20 +#define ISR 20 /* Interruption Space Register */ + +#define CR21 21 +#define IOR 21 /* Interruption Offset Register */ + +#define CR22 22 +#define IPSW 22 /* Interrpution Processor Status Word */ + +#define CR23 23 +#define EIRR 23 /* External Interrupt Request */ + +#define CR24 24 +#define PPDA 24 /* Physcial Page Directory Address */ +#define TR0 24 /* Temporary register 0 */ + +#define CR25 25 +#define HTA 25 /* Hash Table Address */ +#define TR1 25 /* Temporary register 1 */ + +#define CR26 26 +#define TR2 26 /* Temporary register 2 */ + +#define CR27 27 +#define TR3 27 /* Temporary register 3 */ + +#define CR28 28 +#define TR4 28 /* Temporary register 4 */ + +#define CR29 29 +#define TR5 29 /* Temporary register 5 */ + +#define CR30 30 +#define TR6 30 /* Temporary register 6 */ + +#define CR31 31 +#define CPUID 31 /* MP identifier */ + +/* + * Diagnose registers + */ + +#define DR0 0 +#define DR1 1 +#define DR8 8 +#define DR24 24 +#define DR25 25 + +/* + * Tear apart a break instruction to find its type. + */ +#define HPPA_BREAK5(x) ((x) & 0x1F) +#define HPPA_BREAK13(x) (((x) >> 13) & 0x1FFF) + +/* assemble a break instruction */ +#define HPPA_BREAK(i5,i13) (((i5) & 0x1F) | (((i13) & 0x1FFF) << 13)) + + +#ifndef ASM + +/* + * static inline utility functions to get at control registers + */ + +#define EMIT_GET_CONTROL(name, reg) \ +static __inline__ unsigned int \ +get_ ## name (void) \ +{ \ + unsigned int value; \ + HPPA_ASM_MFCTL(reg, value); \ + return value; \ +} + +#define EMIT_SET_CONTROL(name, reg) \ +static __inline__ unsigned int \ +set_ ## name (unsigned int new_value) \ +{ \ + HPPA_ASM_MTCTL(new_value, reg); \ +} + +#define EMIT_CONTROLS(name, reg) \ + EMIT_GET_CONTROL(name, reg) \ + EMIT_SET_CONTROL(name, reg) + +EMIT_CONTROLS(recovery, RCTR); /* CR0 */ +EMIT_CONTROLS(pid1, PIDR1); /* CR8 */ +EMIT_CONTROLS(pid2, PIDR2); /* CR9 */ +EMIT_CONTROLS(ccr, CCR); /* CR10; CCR and SCR share CR10 */ +EMIT_CONTROLS(scr, CCR); /* CR10; CCR and SCR share CR10 */ +EMIT_CONTROLS(sar, SAR); /* CR11 */ +EMIT_CONTROLS(pid3, PIDR3); /* CR12 */ +EMIT_CONTROLS(pid4, PIDR4); /* CR13 */ +EMIT_CONTROLS(iva, IVA); /* CR14 */ +EMIT_CONTROLS(eiem, EIEM); /* CR15 */ +EMIT_CONTROLS(itimer, ITMR); /* CR16 */ +EMIT_CONTROLS(pcsq, PCSQ); /* CR17 */ +EMIT_CONTROLS(pcoq, PCOQ); /* CR18 */ +EMIT_CONTROLS(iir, IIR); /* CR19 */ +EMIT_CONTROLS(isr, ISR); /* CR20 */ +EMIT_CONTROLS(ior, IOR); /* CR21 */ +EMIT_CONTROLS(ipsw, IPSW); /* CR22 */ +EMIT_CONTROLS(eirr, EIRR); /* CR23 */ +EMIT_CONTROLS(tr0, TR0); /* CR24 */ +EMIT_CONTROLS(tr1, TR1); /* CR25 */ +EMIT_CONTROLS(tr2, TR2); /* CR26 */ +EMIT_CONTROLS(tr3, TR3); /* CR27 */ +EMIT_CONTROLS(tr4, TR4); /* CR28 */ +EMIT_CONTROLS(tr5, TR5); /* CR29 */ +EMIT_CONTROLS(tr6, TR6); /* CR30 */ +EMIT_CONTROLS(tr7, CR31); /* CR31 */ + +/* + * If and How to invoke the debugger (a ROM debugger generally) + */ + +#ifdef SIMHPPA_ROM +/* invoke the pflow debugger */ +#define CPU_INVOKE_DEBUGGER \ + do { \ + extern void debugger_break(void); \ + debugger_break(); \ + } while (0) +#endif + + +#endif /* ASM */ + +#ifdef __cplusplus +} +#endif + +#endif /* ! _INCLUDE_HPPA_H */ + diff --git a/c/src/exec/score/cpu/hppa1.1/rtems.s b/c/src/exec/score/cpu/hppa1.1/rtems.s new file mode 100644 index 0000000000..dd215c9af0 --- /dev/null +++ b/c/src/exec/score/cpu/hppa1.1/rtems.s @@ -0,0 +1,53 @@ +/* rtems.S + * + * This file contains the single entry point code for + * the HPPA implementation of RTEMS. + * + * 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 + + .SPACE $PRIVATE$ + .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31 + .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82 + .SPACE $TEXT$ + .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44 + .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY + .SPACE $TEXT$ + .SUBSPA $CODE$ + + .align 32 + .EXPORT cpu_jump_to_directive,ENTRY,PRIV_LEV=0 +cpu_jump_to_directive + .PROC + .CALLINFO FRAME=0,NO_CALLS + .ENTRY + +# invoke user interrupt handler + +# XXX: look at register usage and code +# XXX: this is not necessarily right!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# r9 = directive number + + .import _Entry_points,data + ldil L%_Entry_points,%r8 + ldo R%_Entry_points(%r8),%r8 + ldwx,s %r9(%r8),%r8 + + .call ARGW0=GR + bv,n 0(%r8) + nop + + .EXIT + .PROCEND + diff --git a/c/src/exec/score/cpu/i386/asm.h b/c/src/exec/score/cpu/i386/asm.h new file mode 100644 index 0000000000..f123defcd9 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/cpu/i386/cpu.c b/c/src/exec/score/cpu/i386/cpu.c new file mode 100644 index 0000000000..05a836f7e3 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/cpu/i386/cpu.h b/c/src/exec/score/cpu/i386/cpu.h new file mode 100644 index 0000000000..a66cb37abc --- /dev/null +++ b/c/src/exec/score/cpu/i386/cpu.h @@ -0,0 +1,367 @@ +/* cpu.h + * + * This include file contains information pertaining to the Intel + * i386 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 __CPU_h +#define __CPU_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* conditional compilation parameters */ + +#define CPU_INLINE_ENABLE_DISPATCH TRUE +#define CPU_UNROLL_ENQUEUE_PRIORITY FALSE + +/* + * i386 has an RTEMS allocated and managed interrupt stack. + */ + +#define CPU_HAS_SOFTWARE_INTERRUPT_STACK TRUE +#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE +#define CPU_ALLOCATE_INTERRUPT_STACK TRUE + +/* + * Some family members have no FP, some have an FPU such as the i387 + * for the i386, others have it built in (i486DX, Pentium). + */ + +#if ( I386_HAS_FPU == 1 ) +#define CPU_HARDWARE_FP TRUE /* i387 for i386 */ +#else +#define CPU_HARDWARE_FP FALSE +#endif + +#define CPU_ALL_TASKS_ARE_FP FALSE +#define CPU_IDLE_TASK_IS_FP FALSE +#define CPU_USE_DEFERRED_FP_SWITCH TRUE + +#define CPU_PROVIDES_IDLE_THREAD_BODY FALSE +#define CPU_STACK_GROWS_UP FALSE +#define CPU_STRUCTURE_ALIGNMENT + +/* structures */ + +/* + * Basic integer context for the i386 family. + */ + +typedef struct { + unsigned32 eflags; /* extended flags register */ + void *esp; /* extended stack pointer register */ + void *ebp; /* extended base pointer register */ + unsigned32 ebx; /* extended bx register */ + unsigned32 esi; /* extended source index register */ + unsigned32 edi; /* extended destination index flags register */ +} Context_Control; + +/* + * FP context save area for the i387 numeric coprocessors. + */ + +typedef struct { + unsigned8 fp_save_area[108]; /* context size area for I80387 */ + /* 28 bytes for environment */ +} Context_Control_fp; + +/* + * The following structure defines the set of information saved + * on the current stack by RTEMS upon receipt of each interrupt. + */ + +typedef struct { + unsigned32 TBD; /* XXX Fix for this CPU */ +} CPU_Interrupt_frame; + +/* + * The following table contains the information required to configure + * the i386 specific parameters. + */ + +typedef struct { + void (*pretasking_hook)( void ); + void (*predriver_hook)( void ); + void (*postdriver_hook)( void ); + void (*idle_task)( void ); + boolean do_zero_of_workspace; + unsigned32 interrupt_stack_size; + unsigned32 extra_system_initialization_stack; + + unsigned32 interrupt_table_segment; + void *interrupt_table_offset; +} rtems_cpu_table; + +/* + * context size area for floating point + * + * NOTE: This is out of place on the i386 to avoid a forward reference. + */ + +#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp ) + +/* variables */ + +EXTERN unsigned8 _CPU_Null_fp_context[ CPU_CONTEXT_FP_SIZE ]; +EXTERN void *_CPU_Interrupt_stack_low; +EXTERN void *_CPU_Interrupt_stack_high; + +/* constants */ + +/* + * This defines the number of levels and the mask used to pick those + * bits out of a thread mode. + */ + +#define CPU_MODES_INTERRUPT_LEVEL 0x00000001 /* interrupt level in mode */ +#define CPU_MODES_INTERRUPT_MASK 0x00000001 /* interrupt level in mode */ + +/* + * extra stack required by system initialization thread + */ + +#define CPU_SYSTEM_INITIALIZATION_THREAD_EXTRA_STACK 1024 + +/* + * i386 family supports 256 distinct vectors. + */ + +#define CPU_INTERRUPT_NUMBER_OF_VECTORS 256 + +/* + * Minimum size of a thread's stack. + * + * NOTE: 256 bytes is probably too low in most cases. + */ + +#define CPU_STACK_MINIMUM_SIZE 256 + +/* + * i386 is pretty tolerant of alignment. Just put things on 4 byte boundaries. + */ + +#define CPU_ALIGNMENT 4 +#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT +#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT + +/* + * On i386 thread stacks require no further alignment after allocation + * from the Workspace. + */ + +#define CPU_STACK_ALIGNMENT 0 + +/* macros */ + +/* + * ISR handler macros + * + * These macros perform the following functions: + * + disable all maskable CPU interrupts + * + restore previous interrupt level (enable) + * + temporarily restore interrupts (flash) + * + set a particular level + */ + +#define _CPU_ISR_Disable( _level ) i386_disable_interrupts( _level ) + +#define _CPU_ISR_Enable( _level ) i386_enable_interrupts( _level ) + +#define _CPU_ISR_Flash( _level ) i386_flash_interrupts( _level ) + +#define _CPU_ISR_Set_level( _new_level ) \ + { \ + if ( _new_level ) asm volatile ( "cli" ); \ + else asm volatile ( "sti" ); \ + } + +/* end of ISR handler macros */ + +/* + * Context handler macros + * + * These macros perform the following functions: + * + initialize a context area + * + restart the current thread + * + calculate the initial pointer into a FP context area + * + initialize an FP context area + */ + +#define CPU_EFLAGS_INTERRUPTS_ON 0x00003202 +#define CPU_EFLAGS_INTERRUPTS_OFF 0x00003002 + +#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \ + _isr, _entry_point ) \ + do { \ + unsigned32 _stack; \ + \ + if ( (_isr) ) (_the_context)->eflags = CPU_EFLAGS_INTERRUPTS_OFF; \ + else (_the_context)->eflags = CPU_EFLAGS_INTERRUPTS_ON; \ + \ + _stack = ((unsigned32)(_stack_base)) + (_size) - 4; \ + \ + *((proc_ptr *)(_stack)) = (_entry_point); \ + (_the_context)->ebp = (void *) _stack; \ + (_the_context)->esp = (void *) _stack; \ + } while (0) + +#define _CPU_Context_Restart_self( _the_context ) \ + _CPU_Context_restore( (_the_context) ); + +#define _CPU_Context_Fp_start( _base, _offset ) \ + ( (void *) _Addresses_Add_offset( (_base), (_offset) ) ) + +#define _CPU_Context_Initialize_fp( _fp_area ) \ + { \ + unsigned32 *_source = (unsigned32 *) _CPU_Null_fp_context; \ + unsigned32 *_destination = (unsigned32 *) *(_fp_area); \ + unsigned32 _index; \ + \ + for ( _index=0 ; _index < CPU_CONTEXT_FP_SIZE/4 ; _index++ ) \ + *_destination++ = *_source++; \ + } + +/* end of Context handler macros */ + +/* + * Fatal Error manager macros + * + * These macros perform the following functions: + * + disable interrupts and halt the CPU + */ + +#define _CPU_Fatal_halt( _error ) \ + { \ + asm volatile ( "cli ; \ + movl %0,%%eax ; \ + hlt" \ + : "=r" ((_error)) : "0" ((_error)) \ + ); \ + } + +/* end of Fatal Error manager macros */ + +/* + * Bitfield handler macros + * + * These macros perform the following functions: + * + scan for the highest numbered (MSB) set in a 16 bit bitfield + */ + +#define _CPU_Bitfield_Find_first_bit( _value, _output ) \ + { \ + register unsigned16 __value_in_register = (_value); \ + \ + _output = 0; \ + \ + asm volatile ( "bsfw %0,%1 " \ + : "=r" (__value_in_register), "=r" (_output) \ + : "0" (__value_in_register), "1" (_output) \ + ); \ + } + +/* end of Bitfield handler macros */ + +/* + * Priority handler macros + * + * These macros perform the following functions: + * + return a mask with the bit for this major/minor portion of + * of thread priority set. + * + translate the bit number returned by "Bitfield_find_first_bit" + * into an index into the thread ready chain bit maps + */ + +#define _CPU_Priority_Mask( _bit_number ) \ + ( 1 << (_bit_number) ) + +#define _CPU_Priority_Bits_index( _priority ) \ + (_priority) + +/* functions */ + +/* + * _CPU_Initialize + * + * This routine performs CPU dependent initialization. + */ + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) +); + +/* + * _CPU_ISR_install_vector + * + * This routine installs an interrupt vector. + */ + +void _CPU_ISR_install_vector( + unsigned32 vector, + proc_ptr new_handler, + proc_ptr *old_handler +); + +/* + * _CPU_Context_switch + * + * This routine switches from the run context to the heir context. + */ + +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 and avoid stack conflicts. + */ + +void _CPU_Context_restore( + Context_Control *new_context +); + +/* + * _CPU_Context_save_fp + * + * This routine saves the floating point context passed to it. + */ + +void _CPU_Context_save_fp( + void **fp_context_ptr +); + +/* + * _CPU_Context_restore_fp + * + * This routine restores the floating point context passed to it. + */ + +void _CPU_Context_restore_fp( + void **fp_context_ptr +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/exec/score/cpu/i386/cpu_asm.s b/c/src/exec/score/cpu/i386/cpu_asm.s new file mode 100644 index 0000000000..121b4409d9 --- /dev/null +++ b/c/src/exec/score/cpu/i386/cpu_asm.s @@ -0,0 +1,654 @@ +/* cpu_asm.s + * + * This file contains all assembly code for the Intel i386 implementation + * of RTEMS. + * + * 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 + +/* + * Format of i386 Register structure + */ + +.set REG_EFLAGS, 0 +.set REG_ESP, REG_EFLAGS + 4 +.set REG_EBP, REG_ESP + 4 +.set REG_EBX, REG_EBP + 4 +.set REG_ESI, REG_EBX + 4 +.set REG_EDI, REG_ESI + 4 +.set SIZE_REGS, REG_EDI + 4 + + BEGIN_CODE + +/* + * void _CPU_Context_switch( run_context, heir_context ) + * + * This routine performs a normal non-FP context. + */ + + .align 2 + PUBLIC (_CPU_Context_switch) + +.set RUNCONTEXT_ARG, 4 # save context argument +.set HEIRCONTEXT_ARG, 8 # restore context argument + +SYM (_CPU_Context_switch): + movl RUNCONTEXT_ARG(esp),eax # eax = running threads context + pushf # push eflags + popl REG_EFLAGS(eax) # save eflags + movl esp,REG_ESP(eax) # save stack pointer + movl ebp,REG_EBP(eax) # save base pointer + movl ebx,REG_EBX(eax) # save ebx + movl esi,REG_ESI(eax) # save source register + movl edi,REG_EDI(eax) # save destination register + + movl HEIRCONTEXT_ARG(esp),eax # eax = heir threads context + +restore: + pushl REG_EFLAGS(eax) # push eflags + popf # restore eflags + movl REG_ESP(eax),esp # restore stack pointer + movl REG_EBP(eax),ebp # restore base pointer + movl REG_EBX(eax),ebx # restore ebx + movl REG_ESI(eax),esi # restore source register + movl REG_EDI(eax),edi # restore destination register + ret + +/* + * NOTE: May be unnecessary to reload some registers. + */ + +/* + * void _CPU_Context_restore( new_context ) + * + * This routine performs a normal non-FP context. + */ + + PUBLIC (_CPU_Context_restore) + +.set NEWCONTEXT_ARG, 4 # context to restore argument + +SYM (_CPU_Context_restore): + + movl NEWCONTEXT_ARG(esp),eax # eax = running threads context + jmp restore + +/*PAGE + * void _CPU_Context_save_fp_context( &fp_context_ptr ) + * void _CPU_Context_restore_fp_context( &fp_context_ptr ) + * + * This section is used to context switch an i80287, i80387, + * the built-in coprocessor or the i80486 or compatible. + */ + +.set FPCONTEXT_ARG, 4 # FP context argument + + .align 2 + PUBLIC (_CPU_Context_save_fp) +SYM (_CPU_Context_save_fp): + movl FPCONTEXT_ARG(esp),eax # eax = &ptr to FP context area + movl (eax),eax # eax = FP context area + fsave (eax) # save FP context + ret + + .align 2 + PUBLIC (_CPU_Context_restore_fp) +SYM (_CPU_Context_restore_fp): + movl FPCONTEXT_ARG(esp),eax # eax = &ptr to FP context area + movl (eax),eax # eax = FP context area + frstor (eax) # restore FP context + ret + +/*PAGE + * void _ISR_Handler() + * + * This routine provides the RTEMS interrupt management. + * + * NOTE: + * Upon entry, the stack will contain a stack frame back to the + * interrupted task. If dispatching is enabled, this is the + * outer most interrupt, and (a context switch is necessary or + * the current task has signals), then set up the stack to + * transfer control to the interrupt dispatcher. + */ + +.set SET_SEGMENT_REGISTERS_IN_INTERRUPT, 0 + +.set SAVED_REGS , 32 # space consumed by saved regs +.set EIP_OFFSET , SAVED_REGS # offset of tasks eip +.set CS_OFFSET , EIP_OFFSET+4 # offset of tasks code segment +.set EFLAGS_OFFSET , CS_OFFSET+4 # offset of tasks eflags + + .align 2 + PUBLIC (_ISR_Handler) + +SYM (_ISR_Handler): + /* + * Before this was point is reached the vectors unique + * entry point did the following: + * + * 1. saved all registers with a "pusha" + * 2. put the vector number in eax. + * + * BEGINNING OF ESTABLISH SEGMENTS + * + * WARNING: If an interrupt can occur when the segments are + * not correct, then this is where we should establish + * the segments. In addition to establishing the + * segments, it may be necessary to establish a stack + * in the current data area on the outermost interrupt. + * + * NOTE: If the previous values of the segment registers are + * pushed, do not forget to adjust SAVED_REGS. + * + * NOTE: Make sure the exit code which restores these + * when this type of code is needed. + */ + + /***** ESTABLISH SEGMENTS CODE GOES HERE ******/ + + /* + * END OF ESTABLISH SEGMENTS + */ + + /* + * Now switch stacks if necessary + */ + + movl esp, edx # edx = previous stack pointer + cmpl $0, SYM (_ISR_Nest_level) # is this the outermost interrupt? + jne nested # No, then continue + movl SYM (_CPU_Interrupt_stack_high), esp + + /* + * We want to insure that the old stack pointer is on the + * stack we will be on at the end of the ISR when we restore it. + * By saving it on every interrupt, all we have to do is pop it + * near the end of every interrupt. + */ + +nested: + pushl edx # save the previous stack pointer + incl SYM (_ISR_Nest_level) # one nest level deeper + incl SYM (_Thread_Dispatch_disable_level) # disable multitasking + + # EAX is preloaded with the vector number. + push eax # push vector number + mov SYM (_ISR_Vector_table) (,eax,4),eax + # eax = Users handler + call eax # invoke user ISR + pop eax # eax = vector number + + decl SYM (_ISR_Nest_level) # one less ISR nest level + # If interrupts are nested, + # then dispatching is disabled + + decl SYM (_Thread_Dispatch_disable_level) + # unnest multitasking + # Is dispatch disabled + jne exit # Yes, then exit + + cmpl $0, SYM (_Context_Switch_necessary) + # Is task switch necessary? + jne bframe # Yes, then build stack + + cmpl $0, SYM (_ISR_Signals_to_thread_executing) + # signals sent to Run_thread + # while in interrupt handler? + je exit # No, exit + +bframe: + cli # DISABLE INTERRUPTS!! + popl esp # restore the stack pointer + movl $0, SYM (_ISR_Signals_to_thread_executing) + # push the isf for Isr_dispatch + push EFLAGS_OFFSET(esp) # push tasks eflags + push cs # cs of Isr_dispatch + push $ SYM (_ISR_Dispatch) # entry point + iret + +exit: + cli # DISABLE INTERRUPTS!! + popl esp # restore the stack pointer + + /* + * BEGINNING OF DE-ESTABLISH SEGMENTS + * + * NOTE: Make sure there is code here if code is added to + * load the segment registers. + * + */ + + /******* DE-ESTABLISH SEGMENTS CODE GOES HERE ********/ + + /* + * END OF DE-ESTABLISH SEGMENTS + */ + + popa # restore general registers + iret + +/*PAGE + * Distinct Interrupt Entry Points + * + * The following macro and the 256 instantiations of the macro + * are necessary to determine which interrupt vector occurred. + * The following macro allows a unique entry point to be defined + * for each vector. + * + * NOTE: There are not spaces around the vector number argument + * to the DISTINCT_INTERRUPT_ENTRY macro because m4 will + * undesirably generate the symbol "_Isr_handler_ N" + * instead of "_Isr_handler_N" like we want. + */ + +#define DISTINCT_INTERRUPT_ENTRY(_vector) \ + .align 16 ; \ + PUBLIC (_ISR_Handler_ ## _vector ) ; \ +SYM (_ISR_Handler_ ## _vector ): \ + pusha ; \ + xor eax, eax ; \ + movb $ ## _vector, al ; \ + jmp SYM (_ISR_Handler) ; + +DISTINCT_INTERRUPT_ENTRY(0) +DISTINCT_INTERRUPT_ENTRY(1) +DISTINCT_INTERRUPT_ENTRY(2) +DISTINCT_INTERRUPT_ENTRY(3) +DISTINCT_INTERRUPT_ENTRY(4) +DISTINCT_INTERRUPT_ENTRY(5) +DISTINCT_INTERRUPT_ENTRY(6) +DISTINCT_INTERRUPT_ENTRY(7) +DISTINCT_INTERRUPT_ENTRY(8) +DISTINCT_INTERRUPT_ENTRY(9) +DISTINCT_INTERRUPT_ENTRY(10) +DISTINCT_INTERRUPT_ENTRY(11) +DISTINCT_INTERRUPT_ENTRY(12) +DISTINCT_INTERRUPT_ENTRY(13) +DISTINCT_INTERRUPT_ENTRY(14) +DISTINCT_INTERRUPT_ENTRY(15) +DISTINCT_INTERRUPT_ENTRY(16) +DISTINCT_INTERRUPT_ENTRY(17) +DISTINCT_INTERRUPT_ENTRY(18) +DISTINCT_INTERRUPT_ENTRY(19) +DISTINCT_INTERRUPT_ENTRY(20) +DISTINCT_INTERRUPT_ENTRY(21) +DISTINCT_INTERRUPT_ENTRY(22) +DISTINCT_INTERRUPT_ENTRY(23) +DISTINCT_INTERRUPT_ENTRY(24) +DISTINCT_INTERRUPT_ENTRY(25) +DISTINCT_INTERRUPT_ENTRY(26) +DISTINCT_INTERRUPT_ENTRY(27) +DISTINCT_INTERRUPT_ENTRY(28) +DISTINCT_INTERRUPT_ENTRY(29) +DISTINCT_INTERRUPT_ENTRY(30) +DISTINCT_INTERRUPT_ENTRY(31) +DISTINCT_INTERRUPT_ENTRY(32) +DISTINCT_INTERRUPT_ENTRY(33) +DISTINCT_INTERRUPT_ENTRY(34) +DISTINCT_INTERRUPT_ENTRY(35) +DISTINCT_INTERRUPT_ENTRY(36) +DISTINCT_INTERRUPT_ENTRY(37) +DISTINCT_INTERRUPT_ENTRY(38) +DISTINCT_INTERRUPT_ENTRY(39) +DISTINCT_INTERRUPT_ENTRY(40) +DISTINCT_INTERRUPT_ENTRY(41) +DISTINCT_INTERRUPT_ENTRY(42) +DISTINCT_INTERRUPT_ENTRY(43) +DISTINCT_INTERRUPT_ENTRY(44) +DISTINCT_INTERRUPT_ENTRY(45) +DISTINCT_INTERRUPT_ENTRY(46) +DISTINCT_INTERRUPT_ENTRY(47) +DISTINCT_INTERRUPT_ENTRY(48) +DISTINCT_INTERRUPT_ENTRY(49) +DISTINCT_INTERRUPT_ENTRY(50) +DISTINCT_INTERRUPT_ENTRY(51) +DISTINCT_INTERRUPT_ENTRY(52) +DISTINCT_INTERRUPT_ENTRY(53) +DISTINCT_INTERRUPT_ENTRY(54) +DISTINCT_INTERRUPT_ENTRY(55) +DISTINCT_INTERRUPT_ENTRY(56) +DISTINCT_INTERRUPT_ENTRY(57) +DISTINCT_INTERRUPT_ENTRY(58) +DISTINCT_INTERRUPT_ENTRY(59) +DISTINCT_INTERRUPT_ENTRY(60) +DISTINCT_INTERRUPT_ENTRY(61) +DISTINCT_INTERRUPT_ENTRY(62) +DISTINCT_INTERRUPT_ENTRY(63) +DISTINCT_INTERRUPT_ENTRY(64) +DISTINCT_INTERRUPT_ENTRY(65) +DISTINCT_INTERRUPT_ENTRY(66) +DISTINCT_INTERRUPT_ENTRY(67) +DISTINCT_INTERRUPT_ENTRY(68) +DISTINCT_INTERRUPT_ENTRY(69) +DISTINCT_INTERRUPT_ENTRY(70) +DISTINCT_INTERRUPT_ENTRY(71) +DISTINCT_INTERRUPT_ENTRY(72) +DISTINCT_INTERRUPT_ENTRY(73) +DISTINCT_INTERRUPT_ENTRY(74) +DISTINCT_INTERRUPT_ENTRY(75) +DISTINCT_INTERRUPT_ENTRY(76) +DISTINCT_INTERRUPT_ENTRY(77) +DISTINCT_INTERRUPT_ENTRY(78) +DISTINCT_INTERRUPT_ENTRY(79) +DISTINCT_INTERRUPT_ENTRY(80) +DISTINCT_INTERRUPT_ENTRY(81) +DISTINCT_INTERRUPT_ENTRY(82) +DISTINCT_INTERRUPT_ENTRY(83) +DISTINCT_INTERRUPT_ENTRY(84) +DISTINCT_INTERRUPT_ENTRY(85) +DISTINCT_INTERRUPT_ENTRY(86) +DISTINCT_INTERRUPT_ENTRY(87) +DISTINCT_INTERRUPT_ENTRY(88) +DISTINCT_INTERRUPT_ENTRY(89) +DISTINCT_INTERRUPT_ENTRY(90) +DISTINCT_INTERRUPT_ENTRY(91) +DISTINCT_INTERRUPT_ENTRY(92) +DISTINCT_INTERRUPT_ENTRY(93) +DISTINCT_INTERRUPT_ENTRY(94) +DISTINCT_INTERRUPT_ENTRY(95) +DISTINCT_INTERRUPT_ENTRY(96) +DISTINCT_INTERRUPT_ENTRY(97) +DISTINCT_INTERRUPT_ENTRY(98) +DISTINCT_INTERRUPT_ENTRY(99) +DISTINCT_INTERRUPT_ENTRY(100) +DISTINCT_INTERRUPT_ENTRY(101) +DISTINCT_INTERRUPT_ENTRY(102) +DISTINCT_INTERRUPT_ENTRY(103) +DISTINCT_INTERRUPT_ENTRY(104) +DISTINCT_INTERRUPT_ENTRY(105) +DISTINCT_INTERRUPT_ENTRY(106) +DISTINCT_INTERRUPT_ENTRY(107) +DISTINCT_INTERRUPT_ENTRY(108) +DISTINCT_INTERRUPT_ENTRY(109) +DISTINCT_INTERRUPT_ENTRY(110) +DISTINCT_INTERRUPT_ENTRY(111) +DISTINCT_INTERRUPT_ENTRY(112) +DISTINCT_INTERRUPT_ENTRY(113) +DISTINCT_INTERRUPT_ENTRY(114) +DISTINCT_INTERRUPT_ENTRY(115) +DISTINCT_INTERRUPT_ENTRY(116) +DISTINCT_INTERRUPT_ENTRY(117) +DISTINCT_INTERRUPT_ENTRY(118) +DISTINCT_INTERRUPT_ENTRY(119) +DISTINCT_INTERRUPT_ENTRY(120) +DISTINCT_INTERRUPT_ENTRY(121) +DISTINCT_INTERRUPT_ENTRY(122) +DISTINCT_INTERRUPT_ENTRY(123) +DISTINCT_INTERRUPT_ENTRY(124) +DISTINCT_INTERRUPT_ENTRY(125) +DISTINCT_INTERRUPT_ENTRY(126) +DISTINCT_INTERRUPT_ENTRY(127) +DISTINCT_INTERRUPT_ENTRY(128) +DISTINCT_INTERRUPT_ENTRY(129) +DISTINCT_INTERRUPT_ENTRY(130) +DISTINCT_INTERRUPT_ENTRY(131) +DISTINCT_INTERRUPT_ENTRY(132) +DISTINCT_INTERRUPT_ENTRY(133) +DISTINCT_INTERRUPT_ENTRY(134) +DISTINCT_INTERRUPT_ENTRY(135) +DISTINCT_INTERRUPT_ENTRY(136) +DISTINCT_INTERRUPT_ENTRY(137) +DISTINCT_INTERRUPT_ENTRY(138) +DISTINCT_INTERRUPT_ENTRY(139) +DISTINCT_INTERRUPT_ENTRY(140) +DISTINCT_INTERRUPT_ENTRY(141) +DISTINCT_INTERRUPT_ENTRY(142) +DISTINCT_INTERRUPT_ENTRY(143) +DISTINCT_INTERRUPT_ENTRY(144) +DISTINCT_INTERRUPT_ENTRY(145) +DISTINCT_INTERRUPT_ENTRY(146) +DISTINCT_INTERRUPT_ENTRY(147) +DISTINCT_INTERRUPT_ENTRY(148) +DISTINCT_INTERRUPT_ENTRY(149) +DISTINCT_INTERRUPT_ENTRY(150) +DISTINCT_INTERRUPT_ENTRY(151) +DISTINCT_INTERRUPT_ENTRY(152) +DISTINCT_INTERRUPT_ENTRY(153) +DISTINCT_INTERRUPT_ENTRY(154) +DISTINCT_INTERRUPT_ENTRY(155) +DISTINCT_INTERRUPT_ENTRY(156) +DISTINCT_INTERRUPT_ENTRY(157) +DISTINCT_INTERRUPT_ENTRY(158) +DISTINCT_INTERRUPT_ENTRY(159) +DISTINCT_INTERRUPT_ENTRY(160) +DISTINCT_INTERRUPT_ENTRY(161) +DISTINCT_INTERRUPT_ENTRY(162) +DISTINCT_INTERRUPT_ENTRY(163) +DISTINCT_INTERRUPT_ENTRY(164) +DISTINCT_INTERRUPT_ENTRY(165) +DISTINCT_INTERRUPT_ENTRY(166) +DISTINCT_INTERRUPT_ENTRY(167) +DISTINCT_INTERRUPT_ENTRY(168) +DISTINCT_INTERRUPT_ENTRY(169) +DISTINCT_INTERRUPT_ENTRY(170) +DISTINCT_INTERRUPT_ENTRY(171) +DISTINCT_INTERRUPT_ENTRY(172) +DISTINCT_INTERRUPT_ENTRY(173) +DISTINCT_INTERRUPT_ENTRY(174) +DISTINCT_INTERRUPT_ENTRY(175) +DISTINCT_INTERRUPT_ENTRY(176) +DISTINCT_INTERRUPT_ENTRY(177) +DISTINCT_INTERRUPT_ENTRY(178) +DISTINCT_INTERRUPT_ENTRY(179) +DISTINCT_INTERRUPT_ENTRY(180) +DISTINCT_INTERRUPT_ENTRY(181) +DISTINCT_INTERRUPT_ENTRY(182) +DISTINCT_INTERRUPT_ENTRY(183) +DISTINCT_INTERRUPT_ENTRY(184) +DISTINCT_INTERRUPT_ENTRY(185) +DISTINCT_INTERRUPT_ENTRY(186) +DISTINCT_INTERRUPT_ENTRY(187) +DISTINCT_INTERRUPT_ENTRY(188) +DISTINCT_INTERRUPT_ENTRY(189) +DISTINCT_INTERRUPT_ENTRY(190) +DISTINCT_INTERRUPT_ENTRY(191) +DISTINCT_INTERRUPT_ENTRY(192) +DISTINCT_INTERRUPT_ENTRY(193) +DISTINCT_INTERRUPT_ENTRY(194) +DISTINCT_INTERRUPT_ENTRY(195) +DISTINCT_INTERRUPT_ENTRY(196) +DISTINCT_INTERRUPT_ENTRY(197) +DISTINCT_INTERRUPT_ENTRY(198) +DISTINCT_INTERRUPT_ENTRY(199) +DISTINCT_INTERRUPT_ENTRY(200) +DISTINCT_INTERRUPT_ENTRY(201) +DISTINCT_INTERRUPT_ENTRY(202) +DISTINCT_INTERRUPT_ENTRY(203) +DISTINCT_INTERRUPT_ENTRY(204) +DISTINCT_INTERRUPT_ENTRY(205) +DISTINCT_INTERRUPT_ENTRY(206) +DISTINCT_INTERRUPT_ENTRY(207) +DISTINCT_INTERRUPT_ENTRY(208) +DISTINCT_INTERRUPT_ENTRY(209) +DISTINCT_INTERRUPT_ENTRY(210) +DISTINCT_INTERRUPT_ENTRY(211) +DISTINCT_INTERRUPT_ENTRY(212) +DISTINCT_INTERRUPT_ENTRY(213) +DISTINCT_INTERRUPT_ENTRY(214) +DISTINCT_INTERRUPT_ENTRY(215) +DISTINCT_INTERRUPT_ENTRY(216) +DISTINCT_INTERRUPT_ENTRY(217) +DISTINCT_INTERRUPT_ENTRY(218) +DISTINCT_INTERRUPT_ENTRY(219) +DISTINCT_INTERRUPT_ENTRY(220) +DISTINCT_INTERRUPT_ENTRY(221) +DISTINCT_INTERRUPT_ENTRY(222) +DISTINCT_INTERRUPT_ENTRY(223) +DISTINCT_INTERRUPT_ENTRY(224) +DISTINCT_INTERRUPT_ENTRY(225) +DISTINCT_INTERRUPT_ENTRY(226) +DISTINCT_INTERRUPT_ENTRY(227) +DISTINCT_INTERRUPT_ENTRY(228) +DISTINCT_INTERRUPT_ENTRY(229) +DISTINCT_INTERRUPT_ENTRY(230) +DISTINCT_INTERRUPT_ENTRY(231) +DISTINCT_INTERRUPT_ENTRY(232) +DISTINCT_INTERRUPT_ENTRY(233) +DISTINCT_INTERRUPT_ENTRY(234) +DISTINCT_INTERRUPT_ENTRY(235) +DISTINCT_INTERRUPT_ENTRY(236) +DISTINCT_INTERRUPT_ENTRY(237) +DISTINCT_INTERRUPT_ENTRY(238) +DISTINCT_INTERRUPT_ENTRY(239) +DISTINCT_INTERRUPT_ENTRY(240) +DISTINCT_INTERRUPT_ENTRY(241) +DISTINCT_INTERRUPT_ENTRY(242) +DISTINCT_INTERRUPT_ENTRY(243) +DISTINCT_INTERRUPT_ENTRY(244) +DISTINCT_INTERRUPT_ENTRY(245) +DISTINCT_INTERRUPT_ENTRY(246) +DISTINCT_INTERRUPT_ENTRY(247) +DISTINCT_INTERRUPT_ENTRY(248) +DISTINCT_INTERRUPT_ENTRY(249) +DISTINCT_INTERRUPT_ENTRY(250) +DISTINCT_INTERRUPT_ENTRY(251) +DISTINCT_INTERRUPT_ENTRY(252) +DISTINCT_INTERRUPT_ENTRY(253) +DISTINCT_INTERRUPT_ENTRY(254) +DISTINCT_INTERRUPT_ENTRY(255) + +/*PAGE + * void _ISR_Dispatch() + * + * Entry point from the outermost interrupt service routine exit. + * The current stack is the supervisor mode stack. + */ + + PUBLIC (_ISR_Dispatch) +SYM (_ISR_Dispatch): + + call SYM (_Thread_Dispatch) # invoke Dispatcher + + /* + * BEGINNING OF DE-ESTABLISH SEGMENTS + * + * NOTE: Make sure there is code here if code is added to + * load the segment registers. + * + */ + + /***** DE-ESTABLISH SEGMENTS CODE GOES HERE ****/ + + /* + * END OF DE-ESTABLISH SEGMENTS + */ + + popa # restore general registers + iret # return to interrupted thread + +/*PAGE + * + * void i386_Install_idt( + * unsigned32 source_offset, + * unsigned16 destination_segment, + * unsigned32 destination_offset + * ); + */ + + .align 2 + PUBLIC (i386_Install_idt) + +.set INSTALL_IDT_SAVED_REGS, 8 + +.set SOURCE_OFFSET_ARG, INSTALL_IDT_SAVED_REGS + 4 +.set DESTINATION_SEGMENT_ARG, INSTALL_IDT_SAVED_REGS + 8 +.set DESTINATION_OFFSET_ARG, INSTALL_IDT_SAVED_REGS + 12 + +SYM (i386_Install_idt): + push esi + push edi + + movl SOURCE_OFFSET_ARG(esp),esi + movl DESTINATION_OFFSET_ARG(esp),edi + + pushf # save flags + cli # DISABLE INTERRUPTS!!! + + movw DESTINATION_SEGMENT_ARG+4(esp),ax + push es # save es + movw ax,es + movsl # copy 1st half of IDT entry + movsl # copy 2nd half of IDT entry + pop es # restore es + + popf # ENABLE INTERRUPTS!!! + + pop edi + pop esi + ret + +/* + * void *i386_Logical_to_physical( + * rtems_unsigned16 segment, + * void *address + * ); + * + * Returns thirty-two bit physical address for segment:address. + */ + +.set SEGMENT_ARG, 4 +.set ADDRESS_ARG, 8 + + PUBLIC (i386_Logical_to_physical) + +SYM (i386_Logical_to_physical): + + xorl eax,eax # clear eax + movzwl SEGMENT_ARG(esp),ecx # ecx = segment value + movl $ SYM (_Global_descriptor_table),edx + # edx = address of our GDT + addl ecx,edx # edx = address of desired entry + movb 7(edx),ah # ah = base 31:24 + movb 4(edx),al # al = base 23:16 + shll $16,eax # move ax into correct bits + movw 2(edx),ax # ax = base 0:15 + movl ADDRESS_ARG(esp),ecx # ecx = address to convert + addl eax,ecx # ecx = physical address equivalent + movl ecx,eax # eax = ecx + ret + +/* + * void *i386_Physical_to_logical( + * rtems_unsigned16 segment, + * void *address + * ); + * + * Returns thirty-two bit physical address for segment:address. + */ + +/* + *.set SEGMENT_ARG, 4 + *.set ADDRESS_ARG, 8 -- use sets from above + */ + + PUBLIC (i386_Physical_to_logical) + +SYM (i386_Physical_to_logical): + xorl eax,eax # clear eax + movzwl SEGMENT_ARG(esp),ecx # ecx = segment value + movl $ SYM (_Global_descriptor_table),edx + # edx = address of our GDT + addl ecx,edx # edx = address of desired entry + movb 7(edx),ah # ah = base 31:24 + movb 4(edx),al # al = base 23:16 + shll $16,eax # move ax into correct bits + movw 2(edx),ax # ax = base 0:15 + movl ADDRESS_ARG(esp),ecx # ecx = address to convert + subl eax,ecx # ecx = logical address equivalent + movl ecx,eax # eax = ecx + ret + +END_CODE + +END diff --git a/c/src/exec/score/cpu/i386/i386.h b/c/src/exec/score/cpu/i386/i386.h new file mode 100644 index 0000000000..a8db759984 --- /dev/null +++ b/c/src/exec/score/cpu/i386/i386.h @@ -0,0 +1,493 @@ +/* i386.h + * + * This include file contains information pertaining to the Intel + * i386 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 __i386_h +#define __i386_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following define the CPU Family and Model within the family + * + * NOTE: The string "REPLACE_THIS_WITH_THE_CPU_MODEL" is replaced + * with the name of the appropriate macro for this target CPU. + */ + +#define i386 +#define REPLACE_THIS_WITH_THE_CPU_MODEL +#define REPLACE_THIS_WITH_THE_BSP + +/* + * This section contains the information required to build + * RTEMS for a particular member of the Intel i386 + * family when executing in protected mode. It does + * this by setting variables to indicate which implementation + * dependent features are present in a particular member + * of the family. + * + * Currently recognized: + * i386_fp (i386 DX or SX w/i387) + * i386_fp (i386 DX or SX w/o i387) + * i486dx + * i486sx + * pentium + * + * Floating point is the only feature which currently varies. Eventually + * the i486-plus level instruction for endian swapping should be added + * to this feature list. + */ + +#if defined(i386_fp) + +#define RTEMS_MODEL_NAME "i386 with i387" +#define I386_HAS_FPU 1 + +#elif defined(i386_nofp) + +#define RTEMS_MODEL_NAME "i386 w/o i387" +#define I386_HAS_FPU 1 + +#elif defined(i486dx) + +#define RTEMS_MODEL_NAME "i486dx" +#define I386_HAS_FPU 1 + +#elif defined(i486sx) + +#define RTEMS_MODEL_NAME "i486sx" +#define I386_HAS_FPU 0 + +#elif defined(pentium) + +#define RTEMS_MODEL_NAME "Pentium" +#define I386_HAS_FPU 1 + +#else + +#error "Unsupported CPU Model" + +#endif + +/* + * Define the name of the CPU family. + */ + +#define CPU_NAME "Intel i386" + +#ifndef ASM + +/* + * This section defines the basic types for this processor. + */ + +typedef unsigned char unsigned8; /* 8-bit unsigned integer */ +typedef unsigned short unsigned16; /* 16-bit unsigned integer */ +typedef unsigned int unsigned32; /* 32-bit unsigned integer */ +typedef unsigned long long unsigned64; /* 64-bit unsigned integer */ + +typedef unsigned16 Priority_Bit_map_control; + +typedef unsigned char signed8; /* 8-bit signed integer */ +typedef unsigned short signed16; /* 16-bit signed integer */ +typedef unsigned int signed32; /* 32-bit signed integer */ +typedef long long signed64; /* 64-bit signed integer */ + +typedef unsigned32 boolean; /* Boolean value */ + +typedef float single_precision; /* single precision float */ +typedef double double_precision; /* double precision float */ + +/* + * Structure which makes it easier to deal with LxDT and SxDT instructions. + */ + +typedef struct { + unsigned short limit; + unsigned short physical_address[ 2 ]; +} i386_DTR_load_save_format; + +/* See Chapter 5 - Memory Management in i386 manual */ + +typedef struct { + unsigned short limit_0_15; + unsigned short base_0_15; + unsigned char base_16_23; + unsigned char type_dt_dpl_p; + unsigned char limit_16_19_granularity; + unsigned char base_24_31; +} i386_GDT_slot; + +/* See Chapter 9 - Exceptions and Interrupts in i386 manual + * + * NOTE: This is the IDT entry for interrupt gates ONLY. + */ + +typedef struct { + unsigned short offset_0_15; + unsigned short segment_selector; + unsigned char reserved; + unsigned char p_dpl; + unsigned short offset_16_31; +} i386_IDT_slot; + +typedef void ( *i386_isr )( void ); + +#define i386_disable_interrupts( _level ) \ + { \ + _level = 0; /* avoids warnings */ \ + asm volatile ( "pushf ; \ + cli ; \ + pop %0" \ + : "=r" ((_level)) : "0" ((_level)) \ + ); \ + } + +#define i386_enable_interrupts( _level ) \ + { \ + asm volatile ( "push %0 ; \ + popf" \ + : "=r" ((_level)) : "0" ((_level)) \ + ); \ + } + +#define i386_flash_interrupts( _level ) \ + { \ + asm volatile ( "push %0 ; \ + popf ; \ + cli" \ + : "=r" ((_level)) : "0" ((_level)) \ + ); \ + } + +/* + * The following routine swaps the endian format of an unsigned int. + * It must be static so it can be referenced indirectly. + */ + +static inline unsigned int i386_swap_U32( + unsigned int value +) +{ + asm volatile( "rorw $8,%%ax;" + "rorl $16,%0;" + "rorw $8,%%ax" : "=a" (value) : "0" (value) ); + + return( value ); +} + +/* + * Segment Access Routines + * + * NOTE: Unfortunately, these are still static inlines even when the + * "macro" implementation of the generic code is used. + */ + +static inline unsigned short i386_get_cs() +{ + register unsigned short segment = 0; + + asm volatile ( "movw %%cs,%0" : "=r" (segment) : "0" (segment) ); + + return segment; +} + +static inline unsigned short i386_get_ds() +{ + register unsigned short segment = 0; + + asm volatile ( "movw %%ds,%0" : "=r" (segment) : "0" (segment) ); + + return segment; +} + +static inline unsigned short i386_get_es() +{ + register unsigned short segment = 0; + + asm volatile ( "movw %%es,%0" : "=r" (segment) : "0" (segment) ); + + return segment; +} + +static inline unsigned short i386_get_ss() +{ + register unsigned short segment = 0; + + asm volatile ( "movw %%ss,%0" : "=r" (segment) : "0" (segment) ); + + return segment; +} + +static inline unsigned short i386_get_fs() +{ + register unsigned short segment = 0; + + asm volatile ( "movw %%fs,%0" : "=r" (segment) : "0" (segment) ); + + return segment; +} + +static inline unsigned short i386_get_gs() +{ + register unsigned short segment = 0; + + asm volatile ( "movw %%gs,%0" : "=r" (segment) : "0" (segment) ); + + return segment; +} + +/* + * IO Port Access Routines + */ + +#define i386_outport_byte( _port, _value ) \ + { register unsigned short __port = _port; \ + register unsigned char __value = _value; \ + \ + asm volatile ( "outb %0,%1" : "=a" (__value), "=d" (__port) \ + : "0" (__value), "1" (__port) \ + ); \ + } + +#define i386_outport_word( _port, _value ) \ + { register unsigned short __port = _port; \ + register unsigned short __value = _value; \ + \ + asm volatile ( "outw %0,%1" : "=a" (__value), "=d" (__port) \ + : "0" (__value), "1" (__port) \ + ); \ + } + +#define i386_outport_long( _port, _value ) \ + { register unsigned short __port = _port; \ + register unsigned int __value = _value; \ + \ + asm volatile ( "outl %0,%1" : "=a" (__value), "=d" (__port) \ + : "0" (__value), "1" (__port) \ + ); \ + } + +#define i386_inport_byte( _port, _value ) \ + { register unsigned short __port = _port; \ + register unsigned char __value = 0; \ + \ + asm volatile ( "inb %1,%0" : "=a" (__value), "=d" (__port) \ + : "0" (__value), "1" (__port) \ + ); \ + _value = __value; \ + } + +#define i386_inport_word( _port, _value ) \ + { register unsigned short __port = _port; \ + register unsigned short __value = 0; \ + \ + asm volatile ( "inw %1,%0" : "=a" (__value), "=d" (__port) \ + : "0" (__value), "1" (__port) \ + ); \ + _value = __value; \ + } + +#define i386_inport_long( _port, _value ) \ + { register unsigned short __port = _port; \ + register unsigned int __value = 0; \ + \ + asm volatile ( "inl %1,%0" : "=a" (__value), "=d" (__port) \ + : "0" (__value), "1" (__port) \ + ); \ + _value = __value; \ + } + +/* + * Descriptor Table helper routines + */ + + +#define i386_get_GDTR( _gdtr_address ) \ + { \ + void *_gdtr = (_gdtr_address); \ + \ + asm volatile( "sgdt (%0)" : "=r" (_gdtr) : "0" (_gdtr) ); \ + } + +#define i386_get_GDT_slot( _gdtr_base, _segment, _slot_address ) \ + { \ + register unsigned int _gdt_slot = (_gdtr_base) + (_segment); \ + register volatile void *_slot = (_slot_address); \ + register unsigned int _temporary = 0; \ + \ + asm volatile( "movl %%gs:(%0),%1 ; \ + movl %1,(%2) ; \ + movl %%gs:4(%0),%1 ; \ + movl %1,4(%2)" \ + : "=r" (_gdt_slot), "=r" (_temporary), "=r" (_slot) \ + : "0" (_gdt_slot), "1" (_temporary), "2" (_slot) \ + ); \ + } + +#define i386_set_GDT_slot( _gdtr_base, _segment, _slot_address ) \ + { \ + register unsigned int _gdt_slot = (_gdtr_base) + (_segment); \ + register volatile void *_slot = (_slot_address); \ + register unsigned int _temporary = 0; \ + \ + asm volatile( "movl (%2),%1 ; \ + movl %1,%%gs:(%0) ; \ + movl 4(%2),%1 ; \ + movl %1,%%gs:4(%0) \ + " \ + : "=r" (_gdt_slot), "=r" (_temporary), "=r" (_slot) \ + : "0" (_gdt_slot), "1" (_temporary), "2" (_slot) \ + ); \ + } + +static inline void i386_set_segment( + unsigned short segment, + unsigned int base, + unsigned int limit +) +{ + i386_DTR_load_save_format gdtr; + volatile i386_GDT_slot Gdt_slot; + volatile i386_GDT_slot *gdt_slot = &Gdt_slot; + unsigned short tmp_segment = 0; + unsigned int limit_adjusted; + + /* load physical address of the GDT */ + + i386_get_GDTR( &gdtr ); + + gdt_slot->type_dt_dpl_p = 0x92; /* present, dpl=0, */ + /* application=1, */ + /* type=data read/write */ + gdt_slot->limit_16_19_granularity = 0x40; /* 32 bit segment */ + + limit_adjusted = limit; + if ( limit > 4095 ) { + gdt_slot->limit_16_19_granularity |= 0x80; /* set granularity bit */ + limit_adjusted /= 4096; + } + + gdt_slot->limit_16_19_granularity |= (limit_adjusted >> 16) & 0xff; + gdt_slot->limit_0_15 = limit_adjusted & 0xffff; + + gdt_slot->base_0_15 = base & 0xffff; + gdt_slot->base_16_23 = (base >> 16) & 0xff; + gdt_slot->base_24_31 = (base >> 24); + + i386_set_GDT_slot( + gdtr.physical_address[0] + (gdtr.physical_address[1] << 16), + segment, + gdt_slot + ); + + /* Now, reload all segment registers so the limit takes effect. */ + + asm volatile( "movw %%ds,%0 ; movw %0,%%ds + movw %%es,%0 ; movw %0,%%es + movw %%fs,%0 ; movw %0,%%fs + movw %%gs,%0 ; movw %0,%%gs + movw %%ss,%0 ; movw %0,%%ss" + : "=r" (tmp_segment) + : "0" (tmp_segment) + ); + +} + +/* routines */ + +/* + * i386_Logical_to_physical + * + * Converts logical address to physical address. + */ + +void *i386_Logical_to_physical( + unsigned short segment, + void *address +); + +/* + * i386_Physical_to_logical + * + * Converts physical address to logical address. + */ + +void *i386_Physical_to_logical( + unsigned short segment, + void *address +); + +/* + * i386_Install_idt + * + * This routine installs an IDT entry. + */ + +void i386_Install_idt( + unsigned int source_offset, + unsigned short destination_segment, + unsigned int destination_offset +); + +/* + * "Simpler" names for a lot of the things defined in this file + */ + +/* segment access routines */ + +#define get_cs() i386_get_cs() +#define get_ds() i386_get_ds() +#define get_es() i386_get_es() +#define get_ss() i386_get_ss() +#define get_fs() i386_get_fs() +#define get_gs() i386_get_gs() + +#define CPU_swap_u32( _value ) i386_swap_U32( _value ) + +/* i80x86 I/O instructions */ + +#define outport_byte( _port, _value ) i386_outport_byte( _port, _value ) +#define outport_word( _port, _value ) i386_outport_word( _port, _value ) +#define outport_long( _port, _value ) i386_outport_long( _port, _value ) +#define inport_byte( _port, _value ) i386_inport_byte( _port, _value ) +#define inport_word( _port, _value ) i386_inport_word( _port, _value ) +#define inport_long( _port, _value ) i386_inport_long( _port, _value ) + +/* complicated static inline functions */ + +#define get_GDTR( _gdtr_address ) \ + i386_get_GDTR( _gdtr_address ) + +#define get_GDT_slot( _gdtr_base, _segment, _slot_address ) \ + i386_get_GDT_slot( _gdtr_base, _segment, _slot_address ) + +#define set_GDT_slot( _gdtr_base, _segment, _slot_address ) \ + i386_set_GDT_slot( _gdtr_base, _segment, _slot_address ) + +#define set_segment( _segment, _base, _limit ) \ + i386_set_segment( _segment, _base, _limit ) + + +#ifdef __cplusplus +} +#endif + +#endif /* !ASM */ + +#endif +/* end of include file */ diff --git a/c/src/exec/score/cpu/i386/rtems.s b/c/src/exec/score/cpu/i386/rtems.s new file mode 100644 index 0000000000..df65600e15 --- /dev/null +++ b/c/src/exec/score/cpu/i386/rtems.s @@ -0,0 +1,31 @@ +/* rtems.s + * + * This file contains the single entry point code for + * the i386 implementation of RTEMS. + * + * 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 + + EXTERN (_Entry_points) + + BEGIN_CODE + + .align 2 + PUBLIC (RTEMS) + +SYM (RTEMS): + jmpl SYM (_Entry_points)(,eax,4) + + END_CODE + +END diff --git a/c/src/exec/score/cpu/i960/asm.h b/c/src/exec/score/cpu/i960/asm.h new file mode 100644 index 0000000000..1c40601473 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/cpu/i960/cpu.c b/c/src/exec/score/cpu/i960/cpu.c new file mode 100644 index 0000000000..68ecb0525c --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/cpu/i960/cpu.h b/c/src/exec/score/cpu/i960/cpu.h new file mode 100644 index 0000000000..71a3341702 --- /dev/null +++ b/c/src/exec/score/cpu/i960/cpu.h @@ -0,0 +1,424 @@ +/* cpu.h + * + * This include file contains information pertaining to the Intel + * i960 processor family. + * + * 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 __CPU_h +#define __CPU_h + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma align 4 /* for GNU C structure alignment */ + +#include + +#define CPU_INLINE_ENABLE_DISPATCH FALSE +#define CPU_UNROLL_ENQUEUE_PRIORITY FALSE + +/* + * Use the i960's hardware interrupt stack support and have the + * interrupt manager allocate the memory for it. + */ + +#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE +#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE +#define CPU_ALLOCATE_INTERRUPT_STACK TRUE + +/* + * Some family members have no FP (SA/KA/CA/CF), others have it built in + * (KB/MC/MX). There does not appear to be an external coprocessor + * for this family. + */ + +#if ( I960_HAS_FPU == 1 ) +#define CPU_HARDWARE_FP TRUE +#error "Floating point support for i960 family has been implemented!!!" +#else +#define CPU_HARDWARE_FP FALSE +#endif + +#define CPU_ALL_TASKS_ARE_FP FALSE +#define CPU_IDLE_TASK_IS_FP FALSE +#define CPU_USE_DEFERRED_FP_SWITCH TRUE + +#define CPU_PROVIDES_IDLE_THREAD_BODY FALSE +#define CPU_STACK_GROWS_UP TRUE +#define CPU_STRUCTURE_ALIGNMENT __attribute__ ((aligned (16))) + +/* structures */ + +/* + * Basic integer context for the i960 family. + */ + +typedef struct { + void *r0_pfp; /* (r0) Previous Frame Pointer */ + void *r1_sp; /* (r1) Stack Pointer */ + unsigned32 pc; /* (pc) Processor Control */ + void *g8; /* (g8) Global Register 8 */ + void *g9; /* (g9) Global Register 9 */ + void *g10; /* (g10) Global Register 10 */ + void *g11; /* (g11) Global Register 11 */ + void *g12; /* (g12) Global Register 12 */ + void *g13; /* (g13) Global Register 13 */ + unsigned32 g14; /* (g14) Global Register 14 */ + void *g15_fp; /* (g15) Frame Pointer */ +} Context_Control; + +/* + * FP context save area for the i960 Numeric Extension + */ + +typedef struct { + unsigned32 fp0_1; /* (fp0) first word */ + unsigned32 fp0_2; /* (fp0) second word */ + unsigned32 fp0_3; /* (fp0) third word */ + unsigned32 fp1_1; /* (fp1) first word */ + unsigned32 fp1_2; /* (fp1) second word */ + unsigned32 fp1_3; /* (fp1) third word */ + unsigned32 fp2_1; /* (fp2) first word */ + unsigned32 fp2_2; /* (fp2) second word */ + unsigned32 fp2_3; /* (fp2) third word */ + unsigned32 fp3_1; /* (fp3) first word */ + unsigned32 fp3_2; /* (fp3) second word */ + unsigned32 fp3_3; /* (fp3) third word */ +} Context_Control_fp; + +/* + * The following structure defines the set of information saved + * on the current stack by RTEMS upon receipt of each interrupt. + */ + +typedef struct { + unsigned32 TBD; /* XXX Fix for this CPU */ +} CPU_Interrupt_frame; + +/* + * Call frame for the i960 family. + */ + +typedef struct { + void *r0_pfp; /* (r0) Previous Frame Pointer */ + void *r1_sp; /* (r1) Stack Pointer */ + void *r2_rip; /* (r2) Return Instruction Pointer */ + void *r3; /* (r3) Local Register 3 */ + void *r4; /* (r4) Local Register 4 */ + void *r5; /* (r5) Local Register 5 */ + void *r6; /* (r6) Local Register 6 */ + void *r7; /* (r7) Local Register 7 */ + void *r8; /* (r8) Local Register 8 */ + void *r9; /* (r9) Local Register 9 */ + void *r10; /* (r10) Local Register 10 */ + void *r11; /* (r11) Local Register 11 */ + void *r12; /* (r12) Local Register 12 */ + void *r13; /* (r13) Local Register 13 */ + void *r14; /* (r14) Local Register 14 */ + void *r15; /* (r15) Local Register 15 */ + /* XXX Looks like sometimes there is FP stuff here (MC manual)? */ +} CPU_Call_frame; + +/* + * The following table contains the information required to configure + * the i960 specific parameters. + */ + +typedef struct { + void (*pretasking_hook)( void ); + void (*predriver_hook)( void ); + void (*postdriver_hook)( void ); + void (*idle_task)( void ); + boolean do_zero_of_workspace; + unsigned32 interrupt_stack_size; + unsigned32 extra_system_initialization_stack; +#if defined(__i960CA__) || defined(__i960_CA__) || defined(__i960CA) + i960ca_PRCB *Prcb; +#endif +} rtems_cpu_table; + +/* variables */ + +EXTERN void *_CPU_Interrupt_stack_low; +EXTERN void *_CPU_Interrupt_stack_high; + +/* constants */ + +/* + * This defines the number of levels and the mask used to pick those + * bits out of a thread mode. + */ + +#define CPU_MODES_INTERRUPT_LEVEL 0x0000001f /* interrupt level in mode */ +#define CPU_MODES_INTERRUPT_MASK 0x0000001f /* interrupt level in mode */ + +/* + * context size area for floating point + */ + +#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp ) + +/* + * extra stack required by system initialization thread + * + * NOTE: Make sure this stays positive ... + */ + +#define CPU_SYSTEM_INITIALIZATION_THREAD_EXTRA_STACK \ + (4096 - CPU_STACK_MINIMUM_SIZE) + +/* + * i960 family supports 256 distinct vectors. + */ + +#define CPU_INTERRUPT_NUMBER_OF_VECTORS 256 + +/* + * Minimum size of a thread's stack. + * + * NOTE: See CPU_SYSTEM_INITIALIZATION_THREAD_EXTRA_STACK + */ + +#define CPU_STACK_MINIMUM_SIZE 1024 + +/* + * i960 is pretty tolerant of alignment. Just put things on 4 byte boundaries. + */ + +#define CPU_ALIGNMENT 4 +#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT +#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT + +/* + * i960ca stack requires 16 byte alignment + * + * NOTE: This factor may need to be family member dependent. + */ + +#define CPU_STACK_ALIGNMENT 16 + +/* macros */ + +/* + * ISR handler macros + * + * These macros perform the following functions: + * + disable all maskable CPU interrupts + * + restore previous interrupt level (enable) + * + temporarily restore interrupts (flash) + * + set a particular level + */ + +#define _CPU_ISR_Disable( _level ) i960_disable_interrupts( _level ) +#define _CPU_ISR_Enable( _level ) i960_enable_interrupts( _level ) +#define _CPU_ISR_Flash( _level ) i960_flash_interrupts( _level ) + +#define _CPU_ISR_Set_level( newlevel ) \ + { \ + unsigned32 _mask, _level=(newlevel); \ + \ + __asm__ volatile ( "ldconst 0x1f0000,%0; \ + modpc 0,%0,%1" : "=d" (_mask), "=d" (_level) \ + : "0" (_mask), "1" (_level) \ + ); \ + } + +/* ISR handler section macros */ + +/* + * Context handler macros + * + * These macros perform the following functions: + * + initialize a context area + * + restart the current thread + * + calculate the initial pointer into a FP context area + * + initialize an FP context area + */ + +#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \ + _isr, _entry ) \ + { CPU_Call_frame *_texit_frame; \ + unsigned32 _mask; \ + unsigned32 _base_pc; \ + unsigned32 _stack_tmp; \ + void *_stack; \ + \ + _stack_tmp = (unsigned32)(_stack_base) + CPU_STACK_ALIGNMENT; \ + _stack_tmp &= ~(CPU_STACK_ALIGNMENT - 1); \ + _stack = (void *) _stack_tmp; \ + \ + __asm__ volatile ( "flushreg" : : ); /* flush register cache */ \ + \ + (_the_context)->r0_pfp = _stack; \ + (_the_context)->g15_fp = _stack + (1 * sizeof(CPU_Call_frame)); \ + (_the_context)->r1_sp = _stack + (2 * sizeof(CPU_Call_frame)); \ + __asm__ volatile ( "ldconst 0x1f0000,%0 ; " \ + "modpc 0,0,%1 ; " \ + "andnot %0,%1,%1 ; " \ + : "=d" (_mask), "=d" (_base_pc) : ); \ + (_the_context)->pc = _base_pc | ((_isr) << 16); \ + (_the_context)->g14 = 0; \ + \ + _texit_frame = (CPU_Call_frame *)_stack; \ + _texit_frame->r0_pfp = NULL; \ + _texit_frame->r1_sp = (_the_context)->g15_fp; \ + _texit_frame->r2_rip = (_entry); \ + } + +#define _CPU_Context_Restart_self( _the_context ) \ + _CPU_Context_restore( (_the_context) ); + +#define _CPU_Context_Fp_start( _base, _offset ) NULL + +#define _CPU_Context_Initialize_fp( _fp_area ) + +/* end of Context handler macros */ + +/* + * Fatal Error manager macros + * + * These macros perform the following functions: + * + disable interrupts and halt the CPU + */ + +#define _CPU_Fatal_halt( _errorcode ) \ + { unsigned32 _mask, _level; \ + unsigned32 _error = (_errorcode); \ + \ + __asm__ volatile ( "ldconst 0x1f0000,%0 ; \ + mov %0,%1 ; \ + modpc 0,%0,%1 ; \ + mov %2,g0 ; \ + self: b self " \ + : "=d" (_mask), "=d" (_level), "=d" (_error) : ); \ + } + +/* end of Fatal Error Manager macros */ + +/* + * Bitfield handler macros + * + * These macros perform the following functions: + * + scan for the highest numbered (MSB) set in a 16 bit bitfield + */ + +#define _CPU_Bitfield_Find_first_bit( _value, _output ) \ + { unsigned32 _search = (_value); \ + \ + __asm__ volatile ( "scanbit %0,%1 " \ + : "=d" (_search), "=d" (_output) \ + : "0" (_search), "1" (_output) ); \ + } + +/* end of Bitfield handler macros */ + +/* + * Priority handler macros + * + * These macros perform the following functions: + * + return a mask with the bit for this major/minor portion of + * of thread priority set. + * + translate the bit number returned by "Bitfield_find_first_bit" + * into an index into the thread ready chain bit maps + */ + +#define _CPU_Priority_Mask( _bit_number ) \ + ( 0x8000 >> (_bit_number) ) + +#define _CPU_Priority_Bits_index( _priority ) \ + ( 15 - (_priority) ) + +/* end of Priority handler macros */ + +/* functions */ + +/* + * _CPU_Initialize + * + * This routine performs CPU dependent initialization. + */ + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) +); + +/* + * _CPU_ISR_install_vector + * + * This routine installs an interrupt vector. + */ + +void _CPU_ISR_install_vector( + unsigned32 vector, + proc_ptr new_handler, + proc_ptr *old_handler +); + +/* + * _CPU_Install_interrupt_stack + * + * This routine installs the hardware interrupt stack pointer. + */ + +void _CPU_Install_interrupt_stack( void ); + +/* + * _CPU_Context_switch + * + * This routine switches from the run context to the heir context. + */ + +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 and avoid stack conflicts. + */ + +void _CPU_Context_restore( + Context_Control *new_context +); + +/* + * _CPU_Context_save_fp + * + * This routine saves the floating point context passed to it. + */ + +void _CPU_Context_save_fp( + void **fp_context_ptr +); + +/* + * _CPU_Context_restore_fp + * + * This routine restores the floating point context passed to it. + */ + +void _CPU_Context_restore_fp( + void **fp_context_ptr +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/exec/score/cpu/i960/cpu_asm.s b/c/src/exec/score/cpu/i960/cpu_asm.s new file mode 100644 index 0000000000..eb11e14760 --- /dev/null +++ b/c/src/exec/score/cpu/i960/cpu_asm.s @@ -0,0 +1,199 @@ +/* cpu_asm.s + * + * This file contains all assembly code for the i960CA implementation + * of RTEMS. + * + * 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$ + */ + + .text +/* + * Format of i960ca Register structure + */ + +.set REG_R0_PFP , 0 # (r0) Previous Frame Pointer +.set REG_R1_SP , REG_R0_PFP+4 # (r1) Stack Pointer +.set REG_PC , REG_R1_SP+4 # (pc) Processor Controls +.set REG_G8 , REG_PC+4 # (g8) Global Register 8 +.set REG_G9 , REG_G8+4 # (g9) Global Register 9 +.set REG_G10 , REG_G9+4 # (g10) Global Register 10 +.set REG_G11 , REG_G10+4 # (g11) Global Register 11 +.set REG_G12 , REG_G11+4 # (g12) Global Register 12 +.set REG_G13 , REG_G12+4 # (g13) Global Register 13 +.set REG_G14 , REG_G13+4 # (g14) Global Register 14 +.set REG_G15_FP , REG_G14+4 # (g15) Global Register 15 +.set SIZE_REGS , REG_G15_FP+4 # size of cpu_context_registers + # structure + +/* + * void _CPU_Context_switch( run_context, heir_context ) + * + * This routine performs a normal non-FP context. + */ + .align 4 + .globl __CPU_Context_switch + +__CPU_Context_switch: + modpc 0,0,g2 # get old intr level (PC) + st g2,REG_PC(g0) # save pc + stq g8,REG_G8(g0) # save g8-g11 + stq g12,REG_G12(g0) # save g12-g15 + stl pfp,REG_R0_PFP(g0) # save pfp, sp + +restore: flushreg # flush register cache + ldconst 0x001f0000,g2 # g2 = PC mask + ld REG_PC(g1),g3 # thread->Regs.pc = pc; + ldq REG_G12(g1),g12 # restore g12-g15 + ldl REG_R0_PFP(g1),pfp # restore pfp, sp + ldq REG_G8(g1),g8 # restore g8-g11 + modpc 0,g2,g3 # restore PC register + ret + +/* + * void _CPU_Context_restore( new_context ) + * + * This routine performs a normal non-FP context. + */ + + .globl __CPU_Context_restore +__CPU_Context_restore: + mov g0,g1 # g0 = _Thread_executing + b restore + +/*PAGE + * void _CPU_Context_save_fp_context( &fp_context_ptr ) + * void _CPU_Context_restore_fp_context( &fp_context_ptr ) + * + * There is currently no hardware floating point for the i960. + */ + + .globl __CPU_Context_save_fp + .globl __CPU_Context_restore_fp +__CPU_Context_save_fp: +__CPU_Context_restore_fp: +#if ( I960_HAS_FPU == 1 ) +#error "Floating point support for i960 family has been implemented!!!" +#endif + ret + +/*PAGE + * void __ISR_Handler() + * + * This routine provides the RTEMS interrupt management. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * NOTE: + * Upon entry, the supervisor stack will contain a stack frame + * back to the interrupted thread and the interrupt stack will contain + * an interrupt stack frame. If dispatching is enabled, this + * is the outer most interrupt, and (a context switch is necessary or + * the current thread has signals), then set up the supervisor stack to + * transfer control to the interrupt dispatcher. + */ + + .globl __ISR_Handler +__ISR_Handler: + #ldconst 1,r8 + #modpc 0,r8,r8 # enable tracing + + # r4 = &_Thread_Dispatch_disable_level + ld __Thread_Dispatch_disable_level,r4 + movl g0,r8 # save g0-g1 + + ld -16+8(fp),g0 # g0 = vector number + movl g2,r10 # save g2-g3 + + ld __ISR_Nest_level,r5 # r5 = &_Isr_nest_level + mov g14,r7 # save g14 + + lda 0,g14 # NOT Branch and Link + movl g4,r12 # save g4-g5 + + lda 1(r4),r4 # increment dispatch disable level + movl g6,r14 # save g6-g7 + + ld __ISR_Vector_table[g0*4],g1 # g1 = Users handler + addo 1,r5,r5 # increment ISR level + + st r4,__Thread_Dispatch_disable_level + # one ISR nest level deeper + subo 1,r4,r4 # decrement dispatch disable level + + st r5,__ISR_Nest_level # disable multitasking + subo 1,r5,r5 # decrement ISR nest level + + callx (g1) # invoke user ISR + + st r4,__Thread_Dispatch_disable_level + # unnest multitasking + st r5,__ISR_Nest_level # one less ISR nest level + cmpobne.f 0,r4,exit # If dispatch disabled, exit + ldl -16(fp),g0 # g0 = threads PC reg + # g1 = threads AC reg + ld __Context_Switch_necessary,r6 + # r6 = Is thread switch necessary? + bbs.f 13,g0,exit # not outer level, then exit + cmpobne.f 0,r6,bframe # Switch necessary? + + ld __ISR_Signals_to_thread_executing,g2 + # signals sent to Run_thread + # while in interrupt handler? + cmpobe.f 0,g2,exit # No, then exit + +bframe: mov 0,g2 + st g2,__ISR_Signals_to_thread_executing + + ldconst 0x1f0000,g2 # g2 = intr disable mask + mov g2,g3 # g3 = new intr level + modpc 0,g2,g3 # set new level + + andnot 7,pfp,r4 # r4 = pfp without ret type + flushreg # flush registers + # push _Isr_dispatch ret frame + # build ISF in r4-r6 + ldconst 64,g2 # g2 = size of stack frame + ld 4(r4),g3 # g3 = previous sp + addo g2,g3,r5 # r5 = _Isr_dispatch SP + lda __ISR_Dispatch,r6 # r6 = _Isr_dispatch entry + stt r4,(g3) # set _Isr_dispatch ret info + st g1,16(g3) # set r4 = AC for ISR disp + or 7,g3,pfp # pfp to _Isr_dispatch + +exit: mov r7,g14 # restore g14 + movq r8,g0 # restore g0-g3 + movq r12,g4 # restore g4-g7 + ret + + +/*PAGE + * + * void __ISR_Dispatch() + * + * Entry point from the outermost interrupt service routine exit. + * The current stack is the supervisor mode stack. + */ + +__ISR_Dispatch: + mov g14,r7 + mov 0,g14 + movq g0,r8 + movq g4,r12 + call __Thread_Dispatch + + ldconst -1,r5 # r5 = reload mask + modac r5,r4,r4 # restore threads AC register + mov r7,g14 + movq r8,g0 + movq r12,g4 + ret diff --git a/c/src/exec/score/cpu/i960/i960.h b/c/src/exec/score/cpu/i960/i960.h new file mode 100644 index 0000000000..fe7e68e95f --- /dev/null +++ b/c/src/exec/score/cpu/i960/i960.h @@ -0,0 +1,289 @@ +/* i960.h + * + * This include file contains information pertaining to the Intel + * i960 processor family. + * + * 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 __i960_h +#define __i960_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following define the CPU Family and Model within the family + * + * NOTE: The string "REPLACE_THIS_WITH_THE_CPU_MODEL" is replaced + * with the name of the appropriate macro for this target CPU. + */ + +#define i960 +#define REPLACE_THIS_WITH_THE_CPU_MODEL +#define REPLACE_THIS_WITH_THE_BSP + +/* + * This file contains the information required to build + * RTEMS for a particular member of the Intel i960 + * family. It does this by setting variables to indicate + * which implementation dependent features are present + * in a particular member of the family. + * + * NOTE: For now i960 is really the i960ca. eventually need + * to put in at least support for FPU. + */ + +#if defined(i960ca) + +#define RTEMS_MODEL_NAME "i960ca" +#define I960_HAS_FPU 0 + +#else + +#error "Unsupported CPU Model" + +#endif + +/* + * Define the name of the CPU family. + */ + +#define CPU_NAME "Intel i960" + +#ifndef ASM + +/* + * This section defines the basic types for this processor. + */ + +typedef unsigned char unsigned8; /* 8-bit unsigned integer */ +typedef unsigned short unsigned16; /* 16-bit unsigned integer */ +typedef unsigned int unsigned32; /* 32-bit unsigned integer */ +typedef unsigned long long unsigned64; /* 64-bit unsigned integer */ + +typedef unsigned32 Priority_Bit_map_control; + +typedef char signed8; /* 8-bit signed integer */ +typedef short signed16; /* 16-bit signed integer */ +typedef int signed32; /* 32-bit signed integer */ +typedef long long signed64; /* 64-bit signed integer */ + +typedef unsigned32 boolean; /* Boolean value */ + +typedef float single_precision; /* single precision float */ +typedef double double_precision; /* double precision float */ + +/* + * XXX should have an ifdef here and have stuff for the other + * XXX family members... + */ + +#if defined(__i960CA__) || defined(__i960_CA__) || defined(__i960CA) + +/* i960CA control structures */ + +/* Intel i960CA Control Table */ + +typedef struct { + /* Control Group 0 */ + unsigned int ipb0; /* IP breakpoint 0 */ + unsigned int ipb1; /* IP breakpoint 1 */ + unsigned int dab0; /* data address breakpoint 0 */ + unsigned int dab1; /* data address breakpoint 1 */ + /* Control Group 1 */ + unsigned int imap0; /* interrupt map 0 */ + unsigned int imap1; /* interrupt map 1 */ + unsigned int imap2; /* interrupt map 2 */ + unsigned int icon; /* interrupt control */ + /* Control Group 2 */ + unsigned int mcon0; /* memory region 0 configuration */ + unsigned int mcon1; /* memory region 1 configuration */ + unsigned int mcon2; /* memory region 2 configuration */ + unsigned int mcon3; /* memory region 3 configuration */ + /* Control Group 3 */ + unsigned int mcon4; /* memory region 4 configuration */ + unsigned int mcon5; /* memory region 5 configuration */ + unsigned int mcon6; /* memory region 6 configuration */ + unsigned int mcon7; /* memory region 7 configuration */ + /* Control Group 4 */ + unsigned int mcon8; /* memory region 8 configuration */ + unsigned int mcon9; /* memory region 9 configuration */ + unsigned int mcon10; /* memory region 10 configuration */ + unsigned int mcon11; /* memory region 11 configuration */ + /* Control Group 5 */ + unsigned int mcon12; /* memory region 12 configuration */ + unsigned int mcon13; /* memory region 13 configuration */ + unsigned int mcon14; /* memory region 14 configuration */ + unsigned int mcon15; /* memory region 15 configuration */ + /* Control Group 6 */ + unsigned int bpcon; /* breakpoint control */ + unsigned int tc; /* trace control */ + unsigned int bcon; /* bus configuration control */ + unsigned int reserved; /* reserved */ +} i960ca_control_table; + +/* Intel i960CA Processor Control Block */ + +typedef struct { + unsigned int *fault_tbl; /* fault table base address */ + i960ca_control_table + *control_tbl; /* control table base address */ + unsigned int initial_ac; /* AC register initial value */ + unsigned int fault_config; /* fault configuration word */ + void **intr_tbl; /* interrupt table base address */ + void *sys_proc_tbl; /* system procedure table + base address */ + unsigned int reserved; /* reserved */ + unsigned int *intr_stack; /* interrupt stack pointer */ + unsigned int ins_cache_cfg; /* instruction cache + configuration word */ + unsigned int reg_cache_cfg; /* register cache configuration word */ +} i960ca_PRCB; + +#endif + +typedef void ( *i960_isr )( void ); + +#define i960_disable_interrupts( oldlevel ) \ + { (oldlevel) = 0x1f0000; \ + asm volatile ( "modpc 0,%1,%1" \ + : "=d" ((oldlevel)) \ + : "0" ((oldlevel)) ); \ + } + +#define i960_enable_interrupts( oldlevel ) \ + { unsigned int _mask = 0x1f0000; \ + asm volatile ( "modpc 0,%0,%1" \ + : "=d" (_mask), "=d" ((oldlevel)) \ + : "0" (_mask), "1" ((oldlevel)) ); \ + } + +#define i960_flash_interrupts( oldlevel ) \ + { unsigned int _mask = 0x1f0000; \ + asm volatile ( "modpc 0,%0,%1 ; \ + mov %0,%1 ; \ + modpc 0,%0,%1" \ + : "=d" (_mask), "=d" ((oldlevel)) \ + : "0" (_mask), "1" ((oldlevel)) ); \ + } + +#define i960_atomic_modify( mask, addr, prev ) \ + { register unsigned int _mask = (mask); \ + register unsigned int *_addr = (unsigned int *)(addr); \ + asm volatile( "atmod %0,%1,%1" \ + : "=d" (_addr), "=d" (_mask) \ + : "0" (_addr), "1" (_mask) ); \ + (prev) = _mask; \ + } + + +#define atomic_modify( _mask, _address, _previous ) \ + i960_atomic_modify( _mask, _address, _previous ) + +#define i960_enable_tracing() \ + { register unsigned32 _pc = 0x1; \ + asm volatile( "modpc 0,%0,%0" : "=d" (_pc) : "0" (_pc) ); \ + } + +#define i960_unmask_intr( xint ) \ + { register unsigned32 _mask= (1<<(xint)); \ + asm volatile( "or sf1,%0,sf1" : "=d" (_mask) : "0" (_mask) ); \ + } + +#define i960_mask_intr( xint ) \ + { register unsigned32 _mask= (1<<(xint)); \ + asm volatile( "andnot %0,sf1,sf1" : "=d" (_mask) : "0" (_mask) ); \ + } + +#define i960_clear_intr( xint ) \ + { register unsigned32 _xint=(xint); \ + asm volatile( "loop_til_cleared: + clrbit %0,sf0,sf0 ; \ + bbs %0,sf0,loop_til_cleared" \ + : "=d" (_xint) : "0" (_xint) ); \ + } + +#define i960_reload_ctl_group( group ) \ + { register int _cmd = ((group)|0x400) ; \ + asm volatile( "sysctl %0,%0,%0" : "=d" (_cmd) : "0" (_cmd) ); \ + } + +#define i960_cause_intr( intr ) \ + { register int _intr = (intr); \ + asm volatile( "sysctl %0,%0,%0" : "=d" (_intr) : "0" (_intr) ); \ + } + +#define i960_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) ); \ + } + +static inline unsigned32 i960_pend_intrs() +{ register unsigned32 _intr=0; + asm volatile( "mov sf0,%0" : "=d" (_intr) : "0" (_intr) ); + return ( _intr ); +} + +static inline unsigned32 i960_mask_intrs() +{ register unsigned32 _intr=0; + asm volatile( "mov sf1,%0" : "=d" (_intr) : "0" (_intr) ); + return( _intr ); +} + +static inline unsigned32 i960_get_fp() +{ register unsigned32 _fp=0; + asm volatile( "mov fp,%0" : "=d" (_fp) : "0" (_fp) ); + return ( _fp ); +} + +/* + * The following routine swaps the endian format of an unsigned int. + * It must be static because it is referenced indirectly. + * + * This version is based on code presented in Vol. 4, No. 4 of + * Insight 960. It is certainly something you wouldn't think + * of on your own. + */ + +static inline unsigned int CPU_swap_u32( + unsigned int value +) +{ + register unsigned int to_swap = value; + register unsigned int temp = 0xFF00FF00; + register unsigned int swapped = 0; + + /* to_swap swapped */ + asm volatile ( "rotate 16,%0,%2 ;" /* 0x12345678 0x56781234 */ + "modify %1,%0,%2 ;" /* 0x12345678 0x12785634 */ + "rotate 8,%2,%2" /* 0x12345678 0x78563412 */ + : "=r" (to_swap), "=r" (temp), "=r" (swapped) + : "0" (to_swap), "1" (temp), "2" (swapped) + ); + return( swapped ); +} + +#ifdef __cplusplus +} +#endif + +#endif /* !ASM */ + +#endif +/* end of include file */ diff --git a/c/src/exec/score/cpu/i960/rtems.s b/c/src/exec/score/cpu/i960/rtems.s new file mode 100644 index 0000000000..8abf47a276 --- /dev/null +++ b/c/src/exec/score/cpu/i960/rtems.s @@ -0,0 +1,25 @@ +/* rtems.s + * + * This file contains the single entry point code for + * the i960 implementation of RTEMS. + * + * 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$ + */ + + .text + + .align 4 + .globl RTEMS + +RTEMS: + ld __Entry_points[g7*4],r4 + bx (r4) + diff --git a/c/src/exec/score/cpu/m68k/asm.h b/c/src/exec/score/cpu/m68k/asm.h new file mode 100644 index 0000000000..068c58058c --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/cpu/m68k/cpu.c b/c/src/exec/score/cpu/m68k/cpu.c new file mode 100644 index 0000000000..45484da1f4 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/cpu/m68k/cpu.h b/c/src/exec/score/cpu/m68k/cpu.h new file mode 100644 index 0000000000..a1dd27db57 --- /dev/null +++ b/c/src/exec/score/cpu/m68k/cpu.h @@ -0,0 +1,412 @@ +/* cpu.h + * + * This include file contains information pertaining to the Motorola + * m68xxx processor family. + * + * 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 __CPU_h +#define __CPU_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * If defined, this causes some of the macros to initialize their + * variables to zero before doing inline assembly. This gets rid + * of compile time warnings at the cost of a little execution time + * in some time critical routines. + */ + +#define NO_UNINITIALIZED_WARNINGS + +#include + +/* conditional compilation parameters */ + +#define CPU_INLINE_ENABLE_DISPATCH TRUE +#define CPU_UNROLL_ENQUEUE_PRIORITY FALSE + +/* + * Use the m68k's hardware interrupt stack support and have the + * interrupt manager allocate the memory for it. + */ + +#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE +#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE +#define CPU_ALLOCATE_INTERRUPT_STACK TRUE + +/* + * Some family members have no FP, some have an FPU such as the + * MC68881/MC68882 for the MC68020, others have it built in (MC68030, 040). + */ + +#if ( M68K_HAS_FPU == 1 ) +#define CPU_HARDWARE_FP TRUE +#else +#define CPU_HARDWARE_FP FALSE +#endif + +/* + * All tasks are not by default floating point tasks on this CPU. + * The IDLE task does not have a floating point context on this CPU. + * It is safe to use the deferred floating point context switch + * algorithm on this CPU. + */ + +#define CPU_ALL_TASKS_ARE_FP FALSE +#define CPU_IDLE_TASK_IS_FP FALSE +#define CPU_USE_DEFERRED_FP_SWITCH TRUE + +#define CPU_PROVIDES_IDLE_THREAD_BODY FALSE +#define CPU_STACK_GROWS_UP FALSE +#define CPU_STRUCTURE_ALIGNMENT + +/* structures */ + +/* + * Basic integer context for the m68k family. + */ + +typedef struct { + unsigned32 sr; /* (sr) status register */ + unsigned32 d2; /* (d2) data register 2 */ + unsigned32 d3; /* (d3) data register 3 */ + unsigned32 d4; /* (d4) data register 4 */ + unsigned32 d5; /* (d5) data register 5 */ + unsigned32 d6; /* (d6) data register 6 */ + unsigned32 d7; /* (d7) data register 7 */ + void *a2; /* (a2) address register 2 */ + void *a3; /* (a3) address register 3 */ + void *a4; /* (a4) address register 4 */ + void *a5; /* (a5) address register 5 */ + void *a6; /* (a6) address register 6 */ + void *a7_msp; /* (a7) master stack pointer */ +} Context_Control; + +/* + * FP context save area for the M68881/M68882 numeric coprocessors. + */ + +typedef struct { + unsigned8 fp_save_area[332]; /* 216 bytes for FSAVE/FRESTORE */ + /* 96 bytes for FMOVEM FP0-7 */ + /* 12 bytes for FMOVEM CREGS */ + /* 4 bytes for non-null flag */ +} Context_Control_fp; + +/* + * The following structure defines the set of information saved + * on the current stack by RTEMS upon receipt of each interrupt. + */ + +typedef struct { + unsigned32 TBD; /* XXX Fix for this CPU */ +} CPU_Interrupt_frame; + +/* + * The following table contains the information required to configure + * the m68k specific parameters. + */ + +typedef struct { + void (*pretasking_hook)( void ); + void (*predriver_hook)( void ); + void (*postdriver_hook)( void ); + void (*idle_task)( void ); + boolean do_zero_of_workspace; + unsigned32 interrupt_stack_size; + unsigned32 extra_system_initialization_stack; + m68k_isr *interrupt_vector_table; +} rtems_cpu_table; + +/* variables */ + +EXTERN void *_CPU_Interrupt_stack_low; +EXTERN void *_CPU_Interrupt_stack_high; + +/* constants */ + +/* + * This defines the number of levels and the mask used to pick those + * bits out of a thread mode. + */ + +#define CPU_MODES_INTERRUPT_LEVEL 0x00000007 /* interrupt level in mode */ +#define CPU_MODES_INTERRUPT_MASK 0x00000007 /* interrupt level in mode */ + +/* + * context size area for floating point + */ + +#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp ) + +/* + * extra stack required by system initialization thread + */ + +#define CPU_SYSTEM_INITIALIZATION_THREAD_EXTRA_STACK 1024 + +/* + * m68k family supports 256 distinct vectors. + */ + +#define CPU_INTERRUPT_NUMBER_OF_VECTORS 256 + +/* + * Minimum size of a thread's stack. + * + * NOTE: 256 bytes is probably too low in most cases. + */ + +#define CPU_STACK_MINIMUM_SIZE 256 + +/* + * m68k is pretty tolerant of alignment. Just put things on 4 byte boundaries. + */ + +#define CPU_ALIGNMENT 4 +#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT +#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT + +/* + * On m68k thread stacks require no further alignment after allocation + * from the Workspace. + */ + +#define CPU_STACK_ALIGNMENT 0 + +/* macros */ + +/* + * ISR handler macros + * + * These macros perform the following functions: + * + disable all maskable CPU interrupts + * + restore previous interrupt level (enable) + * + temporarily restore interrupts (flash) + * + set a particular level + */ + +#define _CPU_ISR_Disable( _level ) \ + m68k_disable_interrupts( _level ) + +#define _CPU_ISR_Enable( _level ) \ + m68k_enable_interrupts( _level ) + +#define _CPU_ISR_Flash( _level ) \ + m68k_flash_interrupts( _level ) + +#define _CPU_ISR_Set_level( _newlevel ) \ + m68k_set_interrupt_level( _newlevel ) + +/* end of ISR handler macros */ + +/* + * Context handler macros + * + * These macros perform the following functions: + * + initialize a context area + * + restart the current thread + * + calculate the initial pointer into a FP context area + * + initialize an FP context area + */ + +#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \ + _isr, _entry_point ) \ + do { \ + void *_stack; \ + \ + (_the_context)->sr = 0x3000 | ((_isr) << 8); \ + _stack = (void *)(_stack_base) + (_size) - 4; \ + (_the_context)->a7_msp = _stack; \ + *(void **)_stack = (_entry_point); \ + } while ( 0 ) + +#define _CPU_Context_Restart_self( _the_context ) \ + { asm volatile( "movew %0,%%sr ; " \ + "moval %1,%%a7 ; " \ + "rts" \ + : "=d" ((_the_context)->sr), "=d" ((_the_context)->a7_msp) \ + : "0" ((_the_context)->sr), "1" ((_the_context)->a7_msp) ); \ + } + +#define _CPU_Context_Fp_start( _base, _offset ) \ + ((void *) \ + _Addresses_Add_offset( \ + (_base), \ + (_offset) + CPU_CONTEXT_FP_SIZE - 4 \ + ) \ + ) + +#define _CPU_Context_Initialize_fp( _fp_area ) \ + { unsigned32 *_fp_context = (unsigned32 *)*(_fp_area); \ + \ + *(--(_fp_context)) = 0; \ + *(_fp_area) = (unsigned8 *)(_fp_context); \ + } + +/* end of Context handler macros */ + +/* + * Fatal Error manager macros + * + * These macros perform the following functions: + * + disable interrupts and halt the CPU + */ + +#define _CPU_Fatal_halt( _error ) \ + { asm volatile( "movl %0,%%d0; " \ + "orw #0x0700,%%sr; " \ + "stop #0x2700" : "=d" ((_error)) : "0" ((_error)) ); \ + } + +/* end of Fatal Error manager macros */ + +/* + * Bitfield handler macros + * + * These macros perform the following functions: + * + scan for the highest numbered (MSB) set in a 16 bit bitfield + * + * NOTE: + * + * It appears that on the M68020 bitfield are always 32 bits wide + * when in a register. This code forces the bitfield to be in + * memory (it really always is anyway). This allows us to + * have a real 16 bit wide bitfield which operates "correctly." + */ + +#if ( M68K_HAS_BFFFO == 1 ) +#ifdef NO_UNINITIALIZED_WARNINGS + +#define _CPU_Bitfield_Find_first_bit( _value, _output ) \ + { \ + register void *__base = (void *)&(_value); \ + \ + (_output) = 0; /* avoids warnings */ \ + asm volatile( "bfffo (%0),#0,#16,%1" \ + : "=a" (__base), "=d" ((_output)) \ + : "0" (__base), "1" ((_output)) ) ; \ + } +#else +#define _CPU_Bitfield_Find_first_bit( _value, _output ) \ + { \ + register void *__base = (void *)&(_value); \ + \ + asm volatile( "bfffo (%0),#0,#16,%1" \ + : "=a" (__base), "=d" ((_output)) \ + : "0" (__base), "1" ((_output)) ) ; \ + } +#endif + +#else + +#define _CPU_Bitfield_Find_first_bit( _value, _output ) \ + (_output) = 0 /* avoids warnings */ + +#warning "FIX ME... NEEDS A SOFTWARE BFFFO IMPLEMENTATION" +#warning "SEE no_cpu/cpu.h FOR POSSIBLE ALGORITHMS" + +#endif + +/* end of Bitfield handler macros */ + +/* + * Priority handler macros + * + * These macros perform the following functions: + * + return a mask with the bit for this major/minor portion of + * of thread priority set. + * + translate the bit number returned by "Bitfield_find_first_bit" + * into an index into the thread ready chain bit maps + */ + +#define _CPU_Priority_Mask( _bit_number ) \ + ( 0x8000 >> (_bit_number) ) + +#define _CPU_Priority_Bits_index( _priority ) \ + (_priority) + +/* end of Priority handler macros */ + +/* functions */ + +/* + * _CPU_Initialize + * + * This routine performs CPU dependent initialization. + */ + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) +); + +/* + * _CPU_ISR_install_vector + * + * This routine installs an interrupt vector. + */ + +void _CPU_ISR_install_vector( + unsigned32 vector, + proc_ptr new_handler, + proc_ptr *old_handler +); + +/* + * _CPU_Install_interrupt_stack + * + * This routine installs the hardware interrupt stack pointer. + */ + +void _CPU_Install_interrupt_stack( void ); + +/* + * _CPU_Context_switch + * + * This routine switches from the run context to the heir context. + */ + +void _CPU_Context_switch( + Context_Control *run, + Context_Control *heir +); + +/* + * _CPU_Context_save_fp + * + * This routine saves the floating point context passed to it. + */ + +void _CPU_Context_restore_fp( + void **fp_context_ptr +); + +/* + * _CPU_Context_restore_fp + * + * This routine restores the floating point context passed to it. + */ + +void _CPU_Context_save_fp( + void **fp_context_ptr +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/exec/score/cpu/m68k/cpu_asm.s b/c/src/exec/score/cpu/m68k/cpu_asm.s new file mode 100644 index 0000000000..d8615627a0 --- /dev/null +++ b/c/src/exec/score/cpu/m68k/cpu_asm.s @@ -0,0 +1,202 @@ +/* cpu_asm.s + * + * This file contains all assembly code for the MC68020 implementation + * of RTEMS. + * + * 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 + + .text + +/* void _CPU_Context_switch( run_context, heir_context ) + * + * This routine performs a normal non-FP context. + */ + + .align 4 + .global SYM (_CPU_Context_switch) + +.set RUNCONTEXT_ARG, 4 | save context argument +.set HEIRCONTEXT_ARG, 8 | restore context argument + +SYM (_CPU_Context_switch): + moval a7@(RUNCONTEXT_ARG),a0| a0 = running thread context + movw sr,d1 | d1 = status register + movml d1-d7/a2-a7,a0@ | save context + + moval a7@(HEIRCONTEXT_ARG),a0| a0 = heir thread context +restore: movml a0@,d1-d7/a2-a7 | restore context + movw d1,sr | restore status register + rts + +/*PAGE + * void __CPU_Context_save_fp_context( &fp_context_ptr ) + * void __CPU_Context_restore_fp_context( &fp_context_ptr ) + * + * These routines are used to context switch a MC68881 or MC68882. + * + * NOTE: Context save and restore code is based upon the code shown + * on page 6-38 of the MC68881/68882 Users Manual (rev 1). + * + * CPU_FP_CONTEXT_SIZE is higher than expected to account for the + * -1 pushed at end of this sequence. + */ + +.set FPCONTEXT_ARG, 4 | save FP context argument + + .align 4 + .global SYM (_CPU_Context_save_fp) +SYM (_CPU_Context_save_fp): +#if ( M68K_HAS_FPU == 1 ) + moval a7@(FPCONTEXT_ARG),a1 | a1 = &ptr to context area + moval a1@,a0 | a0 = Save context area + fsave a0@- | save 68881/68882 state frame + tstb a0@ | check for a null frame + beq nosv | Yes, skip save of user model + fmovem fp0-fp7,a0@- | save data registers (fp0-fp7) + fmovem fpc/fps/fpi,a0@- | and save control registers + movl #-1,a0@- | place not-null flag on stack +nosv: movl a0,a1@ | save pointer to saved context +#endif + rts + + .align 4 + .global SYM (_CPU_Context_restore_fp) +SYM (_CPU_Context_restore_fp): +#if ( M68K_HAS_FPU == 1 ) + moval a7@(FPCONTEXT_ARG),a1 | a1 = &ptr to context area + moval a1@,a0 | a0 = address of saved context + tstb a0@ | Null context frame? + beq norst | Yes, skip fp restore + addql #4,a0 | throwaway non-null flag + fmovem a0@+,fpc/fps/fpi | restore control registers + fmovem a0@+,fp0-fp7 | restore data regs (fp0-fp7) +norst: frestore a0@+ | restore the fp state frame + movl a0,a1@ | save pointer to saved context +#endif + rts + +/*PAGE + * void _ISR_Handler() + * + * This routine provides the RTEMS interrupt management. + * + * NOTE: + * Upon entry, the master stack will contain an interrupt stack frame + * back to the interrupted thread and the interrupt stack will contain + * a throwaway interrupt stack frame. If dispatching is enabled, this + * is the outer most interrupt, and (a context switch is necessary or + * the current thread has signals), then set up the master stack to + * transfer control to the interrupt dispatcher. + */ + +.set SR_OFFSET, 0 | Status register offset +.set PC_OFFSET, 2 | Program Counter offset +.set FVO_OFFSET, 6 | Format/vector offset + +.set SAVED, 16 | space for saved registers + + .align 4 + .global SYM (_ISR_Handler) + +SYM (_ISR_Handler): + moveml d0-d1/a0-a1,a7@- | save d0-d1,a0-a1 + addql #1,SYM (_ISR_Nest_level) | one nest level deeper + addql #1,SYM (_Thread_Dispatch_disable_level) + | disable multitasking + movew a7@(SAVED+FVO_OFFSET),d0 | d0 = F/VO + andl #0x0fff,d0 | d0 = vector offset in vbr + +#if ( M68K_HAS_PREINDEXING == 1 ) + movel @( SYM (_ISR_Vector_table),d0:w:1),a0| fetch the ISR +#else + movel # SYM (_ISR_Vector_table),a0 | a0 = base of RTEMS table + addal d0,a0 | a0 = address of vector + movel @(a0),a0 | a0 = address of user routine +#warning "UNTESTED CODE!!!" +#endif + + lsrl #2,d0 | d0 = vector number + movel d0,a7@- | push vector number + jbsr a0@ | invoke the user ISR + addql #4,a7 | remove vector number + + subql #1,SYM (_ISR_Nest_level) | one less nest level + subql #1,SYM (_Thread_Dispatch_disable_level) + | unnest multitasking + bne exit | If dispatch disabled, exit + + movew #0xf000,d0 | isolate format nibble + andw a7@(SAVED+FVO_OFFSET),d0 | get F/VO + cmpiw #0x1000,d0 | is it a throwaway isf? + bne exit | NOT outer level, so branch + + tstl SYM (_Context_Switch_necessary) + | Is thread switch necessary? + bne bframe | Yes, invoke dispatcher + + tstl SYM (_ISR_Signals_to_thread_executing) + | signals sent to Run_thread + | while in interrupt handler? + beq exit | No, then exit + + +bframe: clrl SYM (_ISR_Signals_to_thread_executing) + | If sent, will be processed +#if ( M68K_HAS_SEPARATE_STACKS == 1 ) + movec msp,a0 | a0 = master stack pointer + movew #0,a0@- | push format word + movel # SYM (_ISR_Dispatch),a0@- | push return addr + movew a0@(6+SR_OFFSET),a0@- | push thread sr + movec a0,msp | set master stack pointer +#else +#warning "FIX ME ... HOW DO I DISPATCH FROM AN INTERRUPT?" +/* probably will simply need to push the _ISR_Dispatch frame */ +#endif + +exit: moveml a7@+,d0-d1/a0-a1 | restore d0-d1,a0-a1 + rte | return to thread + | OR _Isr_dispatch + +/*PAGE + * void _ISR_Dispatch() + * + * Entry point from the outermost interrupt service routine exit. + * The current stack is the supervisor mode stack if this processor + * has separate stacks. + * + * 1. save all registers not preserved across C calls. + * 2. invoke the _Thread_Dispatch routine to switch tasks + * or a signal to the currently executing task. + * 3. restore all registers not preserved across C calls. + * 4. return from interrupt + */ + + .global SYM (_ISR_Dispatch) +SYM (_ISR_Dispatch): + movml d0-d1/a0-a1,a7@- + jsr SYM (_Thread_Dispatch) + movml a7@+,d0-d1/a0-a1 + rte + + + + + + + + + + + diff --git a/c/src/exec/score/cpu/m68k/m68k.h b/c/src/exec/score/cpu/m68k/m68k.h new file mode 100644 index 0000000000..3a62b7553b --- /dev/null +++ b/c/src/exec/score/cpu/m68k/m68k.h @@ -0,0 +1,282 @@ +/* m68k.h + * + * This include file contains information pertaining to the Motorola + * m68xxx processor family. + * + * 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 __M68k_h +#define __M68k_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following define the CPU Family and Model within the family + * + * NOTE: The string "REPLACE_THIS_WITH_THE_CPU_MODEL" is replaced + * with the name of the appropriate macro for this target CPU. + */ + +#define m68k +#define REPLACE_THIS_WITH_THE_CPU_MODEL +#define REPLACE_THIS_WITH_THE_BSP + +/* + * This section contains the information required to build + * RTEMS for a particular member of the Motorola MC68xxx + * family. It does this by setting variables to indicate + * which implementation dependent features are present in + * a particular member of the family. + * + * Currently recognized: + * m68000 (no FP) + * m68020 (implies FP) + * m68020_nofp (no FP) + * m68030 (implies FP) + * m68040 (implies FP) + * m68lc040 (no FP) + * m68ec040 (no FP) + * + * Primary difference (for RTEMS) between m68040, m680lc040, and + * m68ec040 is the presence or abscense of the FPU. + * + * Here is some information on the 040 variants (courtesy of Doug McBride, + * mcbride@rodin.colorado.edu): + * + * "The 68040 is a superset of the 68EC040 and the 68LC040. The + * 68EC040 and 68LC040 do not have FPU's. The 68LC040 and the + * 68EC040 have renamed the DLE pin as JS0 which must be tied to + * Gnd or Vcc. The 68EC040 has renamed the MDIS pin as JS1. The + * 68EC040 has access control units instead of memory management units. + * The 68EC040 should not have the PFLUSH or PTEST instructions executed + * (cause an indeterminate result). The 68EC040 and 68LC040 do not + * implement the DLE or multiplexed bus modes. The 68EC040 does not + * implement the output buffer impedance selection mode of operation." + */ + +#if defined(m68000) + +#define RTEMS_MODEL_NAME "m68000" +#define M68K_HAS_VBR 0 +#define M68K_HAS_SEPARATE_STACKS 0 +#define M68K_HAS_FPU 0 +#define M68K_HAS_BFFFO 0 +#define M68K_HAS_PREINDEXING 0 + +#elif defined(m68020) + +#define RTEMS_MODEL_NAME "m68020" +#define M68K_HAS_VBR 1 +#define M68K_HAS_SEPARATE_STACKS 1 +#define M68K_HAS_FPU 1 +#define M68K_HAS_BFFFO 1 +#define M68K_HAS_PREINDEXING 1 + +#elif defined(m68020_nofp) + +#define RTEMS_MODEL_NAME "m68020 w/o fp" +#define M68K_HAS_VBR 1 +#define M68K_HAS_SEPARATE_STACKS 1 +#define M68K_HAS_FPU 0 +#define M68K_HAS_BFFFO 1 +#define M68K_HAS_PREINDEXING 1 + +#elif defined(m68030) + +#define RTEMS_MODEL_NAME "m68030" +#define M68K_HAS_VBR 1 +#define M68K_HAS_SEPARATE_STACKS 1 +#define M68K_HAS_FPU 1 +#define M68K_HAS_BFFFO 1 +#define M68K_HAS_PREINDEXING 1 + +#elif defined(m68040) + +#define RTEMS_MODEL_NAME "m68040" +#define M68K_HAS_VBR 1 +#define M68K_HAS_SEPARATE_STACKS 1 +#define M68K_HAS_FPU 1 +#define M68K_HAS_BFFFO 1 +#define M68K_HAS_PREINDEXING 1 + +#elif defined(m68lc040) + +#define RTEMS_MODEL_NAME "m68lc040" +#define M68K_HAS_VBR 1 +#define M68K_HAS_SEPARATE_STACKS 1 +#define M68K_HAS_FPU 0 +#define M68K_HAS_BFFFO 1 +#define M68K_HAS_PREINDEXING 1 + +#elif defined(m68ec040) + +#define RTEMS_MODEL_NAME "m68ec040" +#define M68K_HAS_VBR 1 +#define M68K_HAS_SEPARATE_STACKS 1 +#define M68K_HAS_FPU 0 +#define M68K_HAS_BFFFO 1 +#define M68K_HAS_PREINDEXING 1 + +#else + +#error "Unsupported CPU Model" + +#endif + +/* + * If defined, this causes some of the macros to initialize their + * variables to zero before doing inline assembly. This gets rid + * of compile time warnings at the cost of a little execution time + * in some time critical routines. + */ + +#define NO_UNINITIALIZED_WARNINGS + +/* + * Define the name of the CPU family. + */ + +#define CPU_NAME "Motorola MC68xxx" + +#ifndef ASM + +/* + * This section defines the basic types for this processor. + */ + +typedef unsigned char unsigned8; /* unsigned 8-bit integer */ +typedef unsigned short unsigned16; /* unsigned 16-bit integer */ +typedef unsigned int unsigned32; /* unsigned 32-bit integer */ +typedef unsigned long long unsigned64; /* unsigned 64-bit integer */ + +typedef unsigned16 Priority_Bit_map_control; + +typedef char signed8; /* signed 8-bit integer */ +typedef short signed16; /* signed 16-bit integer */ +typedef int signed32; /* signed 32-bit integer */ +typedef long long signed64; /* signed 64-bit integer */ + +typedef unsigned32 boolean; /* Boolean value */ + +typedef float single_precision; /* single precision float */ +typedef double double_precision; /* double precision float */ + +/* + * + */ + +typedef void ( *m68k_isr )( void ); + +#ifdef NO_UNINITIALIZED_WARNINGS +#define m68k_disable_interrupts( _level ) \ + { \ + (_level) = 0; /* avoids warnings */ \ + asm volatile ( "movew %%sr,%0 ; \ + orw #0x0700,%%sr" \ + : "=d" ((_level)) : "0" ((_level)) \ + ); \ + } +#else +#define m68k_disable_interrupts( _level ) \ + { \ + asm volatile ( "movew %%sr,%0 ; \ + orw #0x0700,%%sr" \ + : "=d" ((_level)) : "0" ((_level)) \ + ); \ + } +#endif + +#define m68k_enable_interrupts( _level ) \ + { \ + asm volatile ( "movew %0,%%sr " \ + : "=d" ((_level)) : "0" ((_level)) \ + ); \ + } + +#define m68k_flash_interrupts( _level ) \ + { \ + asm volatile ( "movew %0,%%sr ; \ + orw #0x0700,%%sr" \ + : "=d" ((_level)) : "0" ((_level)) \ + ); \ + } + +#define m68k_set_interrupt_level( _newlevel ) \ + { \ + register unsigned32 _tmpsr = 0; \ + \ + asm volatile( "movw %%sr,%0" \ + : "=d" (_tmpsr) : "0" (_tmpsr) \ + ); \ + \ + _tmpsr = (_tmpsr & 0xf8ff) | ((_newlevel) << 8); \ + \ + asm volatile( "movw %0,%%sr" \ + : "=d" (_tmpsr) : "0" (_tmpsr) \ + ); \ + } + +#if ( M68K_HAS_VBR == 1 ) +#define m68k_get_vbr( vbr ) \ + { (vbr) = 0; \ + asm volatile ( "movec %%vbr,%0 " \ + : "=r" (vbr) : "0" (vbr) ); \ + } + +#define m68k_set_vbr( vbr ) \ + { register m68k_isr *_vbr= (m68k_isr *)(vbr); \ + asm volatile ( "movec %0,%%vbr " \ + : "=a" (_vbr) : "0" (_vbr) ); \ + } +#else +#define m68k_get_vbr( _vbr ) _vbr = 0 +#define m68k_set_vbr( _vbr ) +#endif + +/* + * The following routine swaps the endian format of an unsigned int. + * It must be static because it is referenced indirectly. + */ + +static inline unsigned int m68k_swap_u32( + unsigned int value +) +{ + unsigned int swapped = value; + + asm volatile( "rorw #8,%0" : "=d" (swapped) : "0" (swapped) ); + asm volatile( "swap %0" : "=d" (swapped) : "0" (swapped) ); + asm volatile( "rorw #8,%0" : "=d" (swapped) : "0" (swapped) ); + + return( swapped ); +} + +/* XXX this is only valid for some m68k family members and should be fixed */ + +#define m68k_enable_caching() \ + { register unsigned32 _ctl=0x01; \ + asm volatile ( "movec %0,%%cacr" \ + : "=d" (_ctl) : "0" (_ctl) ); \ + } + +#define CPU_swap_u32( value ) m68k_swap_u32( value ) + +#ifdef __cplusplus +} +#endif + +#endif /* !ASM */ + +#endif +/* end of include file */ diff --git a/c/src/exec/score/cpu/m68k/rtems.s b/c/src/exec/score/cpu/m68k/rtems.s new file mode 100644 index 0000000000..faae97e487 --- /dev/null +++ b/c/src/exec/score/cpu/m68k/rtems.s @@ -0,0 +1,46 @@ +/* rtems.s + * + * This file contains the single entry point code for + * the m68k implementation of RTEMS. + * + * 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 + +/* + * There seems to be no reason to have two versions of this. + * The following version should work across the entire family. + * The worst assumption is that gcc will put entry in a scratch + * register and not screw up the stack. + * + * NOTE: This is a 68020 version: + * + * jmpl @(%%d0:l:4)@(__Entry_points) + */ + + EXTERN (_Entry_points) + + BEGIN_CODE + + .align 4 + .global SYM (RTEMS) + +SYM (RTEMS): + moveal SYM (_Entry_points), a0 + lsll #2, d0 + addal d0, a0 + moveal @(a0),a0 + jmpl @(a0) + + END_CODE +END diff --git a/c/src/exec/score/cpu/no_cpu/asm.h b/c/src/exec/score/cpu/no_cpu/asm.h new file mode 100644 index 0000000000..69b1f0f825 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/cpu/no_cpu/cpu.c b/c/src/exec/score/cpu/no_cpu/cpu.c new file mode 100644 index 0000000000..f09d935c2d --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/cpu/no_cpu/cpu.h b/c/src/exec/score/cpu/no_cpu/cpu.h new file mode 100644 index 0000000000..cf38b64a4d --- /dev/null +++ b/c/src/exec/score/cpu/no_cpu/cpu.h @@ -0,0 +1,818 @@ +/* cpu.h + * + * This include file contains information pertaining to the XXX + * 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 __CPU_h +#define __CPU_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include /* pick up machine definitions */ + +/* conditional compilation parameters */ + +/* + * Should the calls to _Thread_Enable_dispatch be inlined? + * + * If TRUE, then they are inlined. + * If FALSE, then a subroutine call is made. + * + * Basically this is an example of the classic trade-off of size + * versus speed. Inlining the call (TRUE) typically increases the + * size of RTEMS while speeding up the enabling of dispatching. + * [NOTE: In general, the _Thread_Dispatch_disable_level will + * only be 0 or 1 unless you are in an interrupt handler and that + * interrupt handler invokes the executive.] When not inlined + * something calls _Thread_Enable_dispatch which in turns calls + * _Thread_Dispatch. If the enable dispatch is inlined, then + * one subroutine call is avoided entirely.] + */ + +#define CPU_INLINE_ENABLE_DISPATCH FALSE + +/* + * Should the body of the search loops in _Thread_queue_Enqueue_priority + * be unrolled one time? In unrolled each iteration of the loop examines + * two "nodes" on the chain being searched. Otherwise, only one node + * is examined per iteration. + * + * If TRUE, then the loops are unrolled. + * If FALSE, then the loops are not unrolled. + * + * The primary factor in making this decision is the cost of disabling + * and enabling interrupts (_ISR_Flash) versus the cost of rest of the + * body of the loop. On some CPUs, the flash is more expensive than + * one iteration of the loop body. In this case, it might be desirable + * to unroll the loop. It is important to note that on some CPUs, this + * code is the longest interrupt disable period in RTEMS. So it is + * necessary to strike a balance when setting this parameter. + */ + +#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE + +/* + * Does RTEMS manage a dedicated interrupt stack in software? + * + * If TRUE, then a stack is allocated in _Interrupt_Manager_initialization. + * If FALSE, nothing is done. + * + * If the CPU supports a dedicated interrupt stack in hardware, + * then it is generally the responsibility of the BSP to allocate it + * and set it up. + * + * If the CPU does not support a dedicated interrupt stack, then + * the porter has two options: (1) execute interrupts on the + * stack of the interrupted task, and (2) have RTEMS manage a dedicated + * interrupt stack. + * + * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE. + * + * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and + * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is + * possible that both are FALSE for a particular CPU. Although it + * is unclear what that would imply about the interrupt processing + * procedure on that CPU. + */ + +#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE + +/* + * Does this CPU have hardware support for a dedicated interrupt stack? + * + * If TRUE, then it must be installed during initialization. + * If FALSE, then no installation is performed. + * + * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE. + * + * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and + * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is + * possible that both are FALSE for a particular CPU. Although it + * is unclear what that would imply about the interrupt processing + * procedure on that CPU. + */ + +#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE + +/* + * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager? + * + * If TRUE, then the memory is allocated during initialization. + * If FALSE, then the memory is allocated during initialization. + * + * This should be TRUE is CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE + * or CPU_INSTALL_HARDWARE_INTERRUPT_STACK is TRUE. + */ + +#define CPU_ALLOCATE_INTERRUPT_STACK TRUE + +/* + * Does the CPU have hardware floating point? + * + * If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported. + * If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored. + * + * If there is a FP coprocessor such as the i387 or mc68881, then + * the answer is TRUE. + * + * The macro name "NO_CPU_HAS_FPU" should be made CPU specific. + * It indicates whether or not this CPU model has FP support. For + * example, it would be possible to have an i386_nofp CPU model + * which set this to false to indicate that you have an i386 without + * an i387 and wish to leave floating point support out of RTEMS. + */ + +#if ( NO_CPU_HAS_FPU == 1 ) +#define CPU_HARDWARE_FP TRUE +#else +#define CPU_HARDWARE_FP FALSE +#endif + +/* + * Are all tasks RTEMS_FLOATING_POINT tasks implicitly? + * + * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed. + * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed. + * + * So far, the only CPU in which this option has been used is the + * HP PA-RISC. The HP C compiler and gcc both implicitly use the + * floating point registers to perform integer multiplies. If + * a function which you would not think utilize the FP unit DOES, + * then one can not easily predict which tasks will use the FP hardware. + * In this case, this option should be TRUE. + * + * If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well. + */ + +#define CPU_ALL_TASKS_ARE_FP TRUE + +/* + * Should the IDLE task have a floating point context? + * + * If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task + * and it has a floating point context which is switched in and out. + * If FALSE, then the IDLE task does not have a floating point context. + * + * Setting this to TRUE negatively impacts the time required to preempt + * the IDLE task from an interrupt because the floating point context + * must be saved as part of the preemption. + */ + +#define CPU_IDLE_TASK_IS_FP FALSE + +/* + * Should the saving of the floating point registers be deferred + * until a context switch is made to another different floating point + * task? + * + * If TRUE, then the floating point context will not be stored until + * necessary. It will remain in the floating point registers and not + * disturned until another floating point task is switched to. + * + * If FALSE, then the floating point context is saved when a floating + * point task is switched out and restored when the next floating point + * task is restored. The state of the floating point registers between + * those two operations is not specified. + * + * If the floating point context does NOT have to be saved as part of + * interrupt dispatching, then it should be safe to set this to TRUE. + * + * Setting this flag to TRUE results in using a different algorithm + * for deciding when to save and restore the floating point context. + * The deferred FP switch algorithm minimizes the number of times + * the FP context is saved and restored. The FP context is not saved + * until a context switch is made to another, different FP task. + * Thus in a system with only one FP task, the FP context will never + * be saved or restored. + */ + +#define CPU_USE_DEFERRED_FP_SWITCH TRUE + +/* + * Does this port provide a CPU dependent IDLE task implementation? + * + * If TRUE, then the routine _CPU_Internal_threads_Idle_thread_body + * must be provided and is the default IDLE thread body instead of + * _Internal_threads_Idle_thread_body. + * + * If FALSE, then use the generic IDLE thread body if the BSP does + * not provide one. + * + * This is intended to allow for supporting processors which have + * a low power or idle mode. When the IDLE thread is executed, then + * the CPU can be powered down. + * + * The order of precedence for selecting the IDLE thread body is: + * + * 1. BSP provided + * 2. CPU dependent (if provided) + * 3. generic (if no BSP and no CPU dependent) + */ + +#define CPU_PROVIDES_IDLE_THREAD_BODY TRUE + +/* + * Does the stack grow up (toward higher addresses) or down + * (toward lower addresses)? + * + * If TRUE, then the grows upward. + * If FALSE, then the grows toward smaller addresses. + */ + +#define CPU_STACK_GROWS_UP TRUE + +/* + * The following is the variable attribute used to force alignment + * of critical RTEMS structures. On some processors it may make + * sense to have these aligned on tighter boundaries than + * the minimum requirements of the compiler in order to have as + * much of the critical data area as possible in a cache line. + * + * The placement of this macro in the declaration of the variables + * is based on the syntactically requirements of the GNU C + * "__attribute__" extension. For example with GNU C, use + * the following to force a structures to a 32 byte boundary. + * + * __attribute__ ((aligned (32))) + * + * NOTE: Currently only the Priority Bit Map table uses this feature. + * To benefit from using this, the data must be heavily + * used so it will stay in the cache and used frequently enough + * in the executive to justify turning this on. + */ + +#define CPU_STRUCTURE_ALIGNMENT + +/* + * The following defines the number of bits actually used in the + * interrupt field of the task mode. How those bits map to the + * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level(). + */ + +#define CPU_MODES_INTERRUPT_MASK 0x00000001 + +/* + * Processor defined structures + * + * Examples structures include the descriptor tables from the i386 + * and the processor control structure on the i960ca. + */ + +/* may need to put some structures here. */ + +/* + * Contexts + * + * Generally there are 2 types of context to save. + * 1. Interrupt registers to save + * 2. Task level registers to save + * + * This means we have the following 3 context items: + * 1. task level context stuff:: Context_Control + * 2. floating point task stuff:: Context_Control_fp + * 3. special interrupt level context :: Context_Control_interrupt + * + * On some processors, it is cost-effective to save only the callee + * preserved registers during a task context switch. This means + * that the ISR code needs to save those registers which do not + * persist across function calls. It is not mandatory to make this + * distinctions between the caller/callee saves registers for the + * purpose of minimizing context saved during task switch and on interrupts. + * If the cost of saving extra registers is minimal, simplicity is the + * choice. Save the same context on interrupt entry as for tasks in + * this case. + * + * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then + * care should be used in designing the context area. + * + * On some CPUs with hardware floating point support, the Context_Control_fp + * structure will not be used or it simply consist of an array of a + * fixed number of bytes. This is done when the floating point context + * is dumped by a "FP save context" type instruction and the format + * is not really defined by the CPU. In this case, there is no need + * to figure out the exact format -- only the size. Of course, although + * this is enough information for RTEMS, it is probably not enough for + * a debugger such as gdb. But that is another problem. + */ + +typedef struct { + unsigned32 some_integer_register; + unsigned32 some_system_register; +} Context_Control; + +typedef struct { + double some_float_register; +} Context_Control_fp; + +typedef struct { + unsigned32 special_interrupt_register; +} CPU_Interrupt_frame; + + +/* + * The following table contains the information required to configure + * the XXX processor specific parameters. + * + * NOTE: The interrupt_stack_size field is required if + * CPU_ALLOCATE_INTERRUPT_STACK is defined as TRUE. + * + * The pretasking_hook, predriver_hook, and postdriver_hook, + * and the do_zero_of_workspace fields are required on ALL CPUs. + */ + +typedef struct { + void (*pretasking_hook)( void ); + void (*predriver_hook)( void ); + void (*postdriver_hook)( void ); + void (*idle_task)( void ); + boolean do_zero_of_workspace; + unsigned32 interrupt_stack_size; + unsigned32 extra_system_initialization_stack; + unsigned32 some_other_cpu_dependent_info; +} rtems_cpu_table; + +/* + * This variable is optional. It is used on CPUs on which it is difficult + * to generate an "uninitialized" FP context. It is filled in by + * _CPU_Initialize and copied into the task's FP context area during + * _CPU_Context_Initialize. + */ + +EXTERN Context_Control_fp _CPU_Null_fp_context; + +/* + * On some CPUs, RTEMS supports a software managed interrupt stack. + * This stack is allocated by the Interrupt Manager and the switch + * is performed in _ISR_Handler. These variables contain pointers + * to the lowest and highest addresses in the chunk of memory allocated + * for the interrupt stack. Since it is unknown whether the stack + * grows up or down (in general), this give the CPU dependent + * code the option of picking the version it wants to use. + * + * NOTE: These two variables are required if the macro + * CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE. + */ + +EXTERN void *_CPU_Interrupt_stack_low; +EXTERN void *_CPU_Interrupt_stack_high; + +/* + * With some compilation systems, it is difficult if not impossible to + * call a high-level language routine from assembly language. This + * is especially true of commercial Ada compilers and name mangling + * C++ ones. This variable can be optionally defined by the CPU porter + * and contains the address of the routine _Thread_Dispatch. This + * can make it easier to invoke that routine at the end of the interrupt + * sequence (if a dispatch is necessary). + */ + +EXTERN void (*_CPU_Thread_dispatch_pointer)(); + +/* + * Nothing prevents the porter from declaring more CPU specific variables. + */ + +/* XXX: if needed, put more variables here */ + +/* + * The size of the floating point context area. On some CPUs this + * will not be a "sizeof" because the format of the floating point + * area is not defined -- only the size is. This is usually on + * CPUs with a "floating point save context" instruction. + */ + +#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp ) + +/* + * Amount of extra stack (above minimum stack size) required by + * system initialization thread. Remember that in a multiprocessor + * system the system intialization thread becomes the MP server thread. + */ + +#define CPU_SYSTEM_INITIALIZATION_THREAD_EXTRA_STACK 0 + +/* + * This defines the number of entries in the ISR_Vector_table managed + * by RTEMS. + */ + +#define CPU_INTERRUPT_NUMBER_OF_VECTORS 32 + +/* + * Should be large enough to run all RTEMS tests. This insures + * that a "reasonable" small application should not have any problems. + */ + +#define CPU_STACK_MINIMUM_SIZE (1024*4) + +/* + * CPU's worst alignment requirement for data types on a byte boundary. This + * alignment does not take into account the requirements for the stack. + */ + +#define CPU_ALIGNMENT 8 + +/* + * This number corresponds to the byte alignment requirement for the + * heap handler. This alignment requirement may be stricter than that + * for the data types alignment specified by CPU_ALIGNMENT. It is + * common for the heap to follow the same alignment requirement as + * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap, + * then this should be set to CPU_ALIGNMENT. + * + * NOTE: This does not have to be a power of 2. It does have to + * be greater or equal to than CPU_ALIGNMENT. + */ + +#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT + +/* + * This number corresponds to the byte alignment requirement for memory + * buffers allocated by the partition manager. This alignment requirement + * may be stricter than that for the data types alignment specified by + * CPU_ALIGNMENT. It is common for the partition to follow the same + * alignment requirement as CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict + * enough for the partition, then this should be set to CPU_ALIGNMENT. + * + * NOTE: This does not have to be a power of 2. It does have to + * be greater or equal to than CPU_ALIGNMENT. + */ + +#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT + +/* + * This number corresponds to the byte alignment requirement for the + * stack. This alignment requirement may be stricter than that for the + * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT + * is strict enough for the stack, then this should be set to 0. + * + * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT. + */ + +#define CPU_STACK_ALIGNMENT 0 + +/* ISR handler macros */ + +/* + * Disable all interrupts for an RTEMS critical section. The previous + * level is returned in _level. + */ + +#define _CPU_ISR_Disable( _isr_cookie ) \ + { \ + (_isr_cookie) = 0; /* do something to prevent warnings */ \ + } + +/* + * Enable interrupts to the previous level (returned by _CPU_ISR_Disable). + * This indicates the end of an RTEMS critical section. The parameter + * _level is not modified. + */ + +#define _CPU_ISR_Enable( _isr_cookie ) \ + { \ + } + +/* + * This temporarily restores the interrupt to _level before immediately + * disabling them again. This is used to divide long RTEMS critical + * sections into two or more parts. The parameter _level is not + * modified. + */ + +#define _CPU_ISR_Flash( _isr_cookie ) \ + { \ + } + +/* + * Map interrupt level in task mode onto the hardware that the CPU + * actually provides. Currently, interrupt levels which do not + * map onto the CPU in a generic fashion are undefined. Someday, + * it would be nice if these were "mapped" by the application + * via a callout. For example, m68k has 8 levels 0 - 7, levels + * 8 - 255 would be available for bsp/application specific meaning. + * This could be used to manage a programmable interrupt controller + * via the rtems_task_mode directive. + */ + +#define _CPU_ISR_Set_level( new_level ) \ + { \ + } + +/* end of ISR handler macros */ + +/* Context handler macros */ + +/* + * Initialize the context to a state suitable for starting a + * task after a context restore operation. Generally, this + * involves: + * + * - setting a starting address + * - preparing the stack + * - preparing the stack and frame pointers + * - setting the proper interrupt level in the context + * - initializing the floating point context + * + * This routine generally does not set any unnecessary register + * in the context. The state of the "general data" registers is + * undefined at task start time. + */ + +#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \ + _isr, _entry_point ) \ + { \ + } + +/* + * This routine is responsible for somehow restarting the currently + * executing task. If you are lucky, then all that is necessary + * is restoring the context. Otherwise, there will need to be + * a special assembly routine which does something special in this + * case. Context_Restore should work most of the time. It will + * not work if restarting self conflicts with the stack frame + * assumptions of restoring a context. + */ + +#define _CPU_Context_Restart_self( _the_context ) \ + _CPU_Context_restore( (_the_context) ); + +/* + * The purpose of this macro is to allow the initial pointer into + * a floating point context area (used to save the floating point + * context) to be at an arbitrary place in the floating point + * context area. + * + * This is necessary because some FP units are designed to have + * their context saved as a stack which grows into lower addresses. + * Other FP units can be saved by simply moving registers into offsets + * from the base of the context area. Finally some FP units provide + * a "dump context" instruction which could fill in from high to low + * or low to high based on the whim of the CPU designers. + */ + +#define _CPU_Context_Fp_start( _base, _offset ) \ + ( (void *) (_base) + (_offset) ) + +/* + * This routine initializes the FP context area passed to it to. + * There are a few standard ways in which to initialize the + * floating point context. The code included for this macro assumes + * that this is a CPU in which a "initial" FP context was saved into + * _CPU_Null_fp_context and it simply copies it to the destination + * context passed to it. + * + * Other models include (1) not doing anything, and (2) putting + * a "null FP status word" in the correct place in the FP context. + */ + +#define _CPU_Context_Initialize_fp( _destination ) \ + { \ + *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context; \ + } + +/* end of Context handler macros */ + +/* Fatal Error manager macros */ + +/* + * This routine copies _error into a known place -- typically a stack + * location or a register, optionally disables interrupts, and + * halts/stops the CPU. + */ + +#define _CPU_Fatal_halt( _error ) \ + { \ + } + +/* end of Fatal Error manager macros */ + +/* Bitfield handler macros */ + +/* + * This routine sets _output to the bit number of the first bit + * set in _value. _value is of CPU dependent type Priority_Bit_map_control. + * This type may be either 16 or 32 bits wide although only the 16 + * least significant bits will be used. + * + * There are a number of variables in using a "find first bit" type + * instruction. + * + * (1) What happens when run on a value of zero? + * (2) Bits may be numbered from MSB to LSB or vice-versa. + * (3) The numbering may be zero or one based. + * (4) The "find first bit" instruction may search from MSB or LSB. + * + * RTEMS guarantees that (1) will never happen so it is not a concern. + * (2),(3), (4) are handled by the macros _CPU_Priority_mask() and + * _CPU_Priority_Bits_index(). These three form a set of routines + * which must logically operate together. Bits in the _value are + * set and cleared based on masks built by _CPU_Priority_mask(). + * The basic major and minor values calculated by _Priority_Major() + * and _Priority_Minor() are "massaged" by _CPU_Priority_Bits_index() + * to properly range between the values returned by the "find first bit" + * instruction. This makes it possible for _Priority_Get_highest() to + * calculate the major and directly index into the minor table. + * This mapping is necessary to ensure that 0 (a high priority major/minor) + * is the first bit found. + * + * This entire "find first bit" and mapping process depends heavily + * on the manner in which a priority is broken into a major and minor + * components with the major being the 4 MSB of a priority and minor + * the 4 LSB. Thus (0 << 4) + 0 corresponds to priority 0 -- the highest + * priority. And (15 << 4) + 14 corresponds to priority 254 -- the next + * to the lowest priority. + * + * If your CPU does not have a "find first bit" instruction, then + * there are ways to make do without it. Here are a handful of ways + * to implement this in software: + * + * - a series of 16 bit test instructions + * - a "binary search using if's" + * - _number = 0 + * if _value > 0x00ff + * _value >>=8 + * _number = 8; + * + * if _value > 0x0000f + * _value >=8 + * _number += 4 + * + * _number += bit_set_table[ _value ] + * + * where bit_set_table[ 16 ] has values which indicate the first + * bit set + */ + +#define _CPU_Bitfield_Find_first_bit( _value, _output ) \ + { \ + (_output) = 0; /* do something to prevent warnings */ \ + } + +/* end of Bitfield handler macros */ + +/* + * This routine builds the mask which corresponds to the bit fields + * as searched by _CPU_Bitfield_Find_first_bit(). See the discussion + * for that routine. + */ + +#define _CPU_Priority_Mask( _bit_number ) \ + ( 1 << (_bit_number) ) + +/* + * This routine translates the bit numbers returned by + * _CPU_Bitfield_Find_first_bit() into something suitable for use as + * a major or minor component of a priority. See the discussion + * for that routine. + */ + +#define _CPU_Priority_Bits_index( _priority ) \ + (_priority) + +/* end of Priority handler macros */ + +/* functions */ + +/* + * _CPU_Initialize + * + * This routine performs CPU dependent initialization. + */ + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) +); + +/* + * _CPU_ISR_install_vector + * + * This routine installs an interrupt vector. + */ + +void _CPU_ISR_install_vector( + unsigned32 vector, + proc_ptr new_handler, + proc_ptr *old_handler +); + +/* + * _CPU_Install_interrupt_stack + * + * This routine installs the hardware interrupt stack pointer. + * + * NOTE: It need only be provided if CPU_HAS_HARDWARE_INTERRUPT_STACK + * is TRUE. + */ + +void _CPU_Install_interrupt_stack( void ); + +/* + * _CPU_Internal_threads_Idle_thread_body + * + * This routine is the CPU dependent IDLE thread body. + * + * NOTE: It need only be provided if CPU_PROVIDES_IDLE_THREAD_BODY + * is TRUE. + */ + +void _CPU_Internal_threads_Idle_thread_body( void ); + +/* + * _CPU_Context_switch + * + * This routine switches from the run context to the heir context. + */ + +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 +); + +/* + * _CPU_Context_save_fp + * + * This routine saves the floating point context passed to it. + */ + +void _CPU_Context_save_fp( + void **fp_context_ptr +); + +/* + * _CPU_Context_restore_fp + * + * This routine restores the floating point context passed to it. + */ + +void _CPU_Context_restore_fp( + void **fp_context_ptr +); + +/* The following routine swaps the endian format of an unsigned int. + * It must be static because it is referenced indirectly. + * + * This version will work on any processor, but if there is a better + * way for your CPU PLEASE use it. The most common way to do this is to: + * + * swap least significant two bytes with 16-bit rotate + * swap upper and lower 16-bits + * swap most significant two bytes with 16-bit rotate + * + * Some CPUs have special instructions which swap a 32-bit quantity in + * a single instruction (e.g. i486). It is probably best to avoid + * an "endian swapping control bit" in the CPU. One good reason is + * that interrupts would probably have to be disabled to insure that + * an interrupt does not try to access the same "chunk" with the wrong + * endian. Another good reason is that on some CPUs, the endian bit + * endianness for ALL fetches -- both code and data -- so the code + * will be fetched incorrectly. + */ + +static inline unsigned int CPU_swap_u32( + unsigned int value +) +{ + unsigned32 byte1, byte2, byte3, byte4, swapped; + + byte4 = (value >> 24) & 0xff; + byte3 = (value >> 16) & 0xff; + byte2 = (value >> 8) & 0xff; + byte1 = value & 0xff; + + swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4; + return( swapped ); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/c/src/exec/score/cpu/no_cpu/cpu_asm.c b/c/src/exec/score/cpu/no_cpu/cpu_asm.c new file mode 100644 index 0000000000..26246a93c2 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/cpu/no_cpu/cpu_asm.h b/c/src/exec/score/cpu/no_cpu/cpu_asm.h new file mode 100644 index 0000000000..0f4154a453 --- /dev/null +++ b/c/src/exec/score/cpu/no_cpu/cpu_asm.h @@ -0,0 +1,70 @@ +/* + * cpu_asm.h + * + * Very loose template for an include file for the cpu_asm.? file + * if it is implemented as a ".S" file (preprocessed by cpp) instead + * of a ".s" file (preprocessed by gm4 or gasp). + * + * 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$ + * + */ + +#ifndef __CPU_ASM_h +#define __CPU_ASM_h + +/* pull in the generated offsets */ + +#include + +/* + * Hardware General Registers + */ + +/* put something here */ + +/* + * Hardware Floating Point Registers + */ + +/* put something here */ + +/* + * Hardware Control Registers + */ + +/* put something here */ + +/* + * Calling Convention + */ + +/* put something here */ + +/* + * Temporary registers + */ + +/* put something here */ + +/* + * Floating Point Registers - SW Conventions + */ + +/* put something here */ + +/* + * Temporary floating point registers + */ + +/* put something here */ + +#endif + +/* end of file */ diff --git a/c/src/exec/score/cpu/no_cpu/no_cpu.h b/c/src/exec/score/cpu/no_cpu/no_cpu.h new file mode 100644 index 0000000000..ec973dadcf --- /dev/null +++ b/c/src/exec/score/cpu/no_cpu/no_cpu.h @@ -0,0 +1,86 @@ +/* + * + * + * 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$ + * + */ + +#ifndef _INCLUDE_NO_CPU_h +#define _INCLUDE_NO_CPU_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following define the CPU Family and Model within the family + * + * NOTE: The string "REPLACE_THIS_WITH_THE_CPU_MODEL" is replaced + * with the name of the appropriate macro for this target CPU. + */ + +#define no_cpu +#define REPLACE_THIS_WITH_THE_CPU_MODEL + +/* + * This file contains the information required to build + * RTEMS for a particular member of the "no cpu" + * family when executing in protected mode. It does + * this by setting variables to indicate which implementation + * dependent features are present in a particular member + * of the family. + */ + +#if defined(no_cpu) + +#define RTEMS_MODEL_NAME "no_cpu" +#define NOCPU_HAS_FPU 1 + +#else + +#error "Unsupported CPU Model" + +#endif + +/* + * Define the name of the CPU family. + */ + +#define CPU_NAME "NO CPU" + +/* + * This section defines the basic types for this processor. + */ + +typedef unsigned char unsigned8; /* 8-bit unsigned integer */ +typedef unsigned short unsigned16; /* 16-bit unsigned integer */ +typedef unsigned int unsigned32; /* 32-bit unsigned integer */ +typedef unsigned long long unsigned64; /* 64-bit unsigned integer */ + +typedef unsigned16 Priority_Bit_map_control; + +typedef char signed8; /* 8-bit signed integer */ +typedef short signed16; /* 16-bit signed integer */ +typedef int signed32; /* 32-bit signed integer */ +typedef long long signed64; /* 64-bit signed integer */ + +typedef unsigned32 boolean; /* Boolean value */ + +typedef float single_precision; /* single precision float */ +typedef double double_precision; /* double precision float */ + +typedef void ( *no_cpu_isr_entry )( void ); + +#ifdef __cplusplus +} +#endif + +#endif /* ! _INCLUDE_NO_CPU_h */ +/* end of include file */ diff --git a/c/src/exec/score/cpu/no_cpu/rtems.c b/c/src/exec/score/cpu/no_cpu/rtems.c new file mode 100644 index 0000000000..5415ae9852 --- /dev/null +++ b/c/src/exec/score/cpu/no_cpu/rtems.c @@ -0,0 +1,45 @@ +/* rtems.c ===> rtems.S or rtems.s + * + * This file contains the single entry point code for + * the XXX implementation of RTEMS. + * + * 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" rtems file. + */ + +#include +#include +/* #include "asm.h> */ + +/* + * RTEMS + * + * This routine jumps to the directive indicated in the + * CPU defined register. This routine is used when RTEMS is + * linked by itself and placed in ROM. This routine is the + * first address in the ROM space for RTEMS. The user "calls" + * this address with the directive arguments in the normal place. + * This routine then jumps indirectly to the correct directive + * preserving the arguments. The directive should not realize + * it has been "wrapped" in this way. The table "_Entry_points" + * is used to look up the directive. + */ + +void RTEMS() +{ +} + diff --git a/c/src/exec/score/cpu/unix/cpu.c b/c/src/exec/score/cpu/unix/cpu.c new file mode 100644 index 0000000000..ed94953d58 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/cpu/unix/cpu.h b/c/src/exec/score/cpu/unix/cpu.h new file mode 100644 index 0000000000..e6b29bcd74 --- /dev/null +++ b/c/src/exec/score/cpu/unix/cpu.h @@ -0,0 +1,929 @@ +/* cpu.h + * + * This include file contains information pertaining to the HP + * PA-RISC processor (Level 1.1). + * + * 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$ + */ + +#ifndef __CPU_h +#define __CPU_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* conditional compilation parameters */ + +/* + * Should the calls to _Thread_Enable_dispatch be inlined? + * + * If TRUE, then they are inlined. + * If FALSE, then a subroutine call is made. + * + * Basically this is an example of the classic trade-off of size + * versus speed. Inlining the call (TRUE) typically increases the + * size of RTEMS while speeding up the enabling of dispatching. + * [NOTE: In general, the _Thread_Dispatch_disable_level will + * only be 0 or 1 unless you are in an interrupt handler and that + * interrupt handler invokes the executive.] When not inlined + * something calls _Thread_Enable_dispatch which in turns calls + * _Thread_Dispatch. If the enable dispatch is inlined, then + * one subroutine call is avoided entirely.] + */ + +#define CPU_INLINE_ENABLE_DISPATCH FALSE + +/* + * Should the body of the search loops in _Thread_queue_Enqueue_priority + * be unrolled one time? In unrolled each iteration of the loop examines + * two "nodes" on the chain being searched. Otherwise, only one node + * is examined per iteration. + * + * If TRUE, then the loops are unrolled. + * If FALSE, then the loops are not unrolled. + * + * The primary factor in making this decision is the cost of disabling + * and enabling interrupts (_ISR_Flash) versus the cost of rest of the + * body of the loop. On some CPUs, the flash is more expensive than + * one iteration of the loop body. In this case, it might be desirable + * to unroll the loop. It is important to note that on some CPUs, this + * code is the longest interrupt disable period in RTEMS. So it is + * necessary to strike a balance when setting this parameter. + */ + +#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE + +/* + * Does RTEMS manage a dedicated interrupt stack in software? + * + * If TRUE, then a stack is allocated in _Interrupt_Manager_initialization. + * If FALSE, nothing is done. + * + * If the CPU supports a dedicated interrupt stack in hardware, + * then it is generally the responsibility of the BSP to allocate it + * and set it up. + * + * If the CPU does not support a dedicated interrupt stack, then + * the porter has two options: (1) execute interrupts on the + * stack of the interrupted task, and (2) have RTEMS manage a dedicated + * interrupt stack. + * + * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE. + * + * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and + * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is + * possible that both are FALSE for a particular CPU. Although it + * is unclear what that would imply about the interrupt processing + * procedure on that CPU. + */ + +#define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE + +/* + * Does this CPU have hardware support for a dedicated interrupt stack? + * + * If TRUE, then it must be installed during initialization. + * If FALSE, then no installation is performed. + * + * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE. + * + * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and + * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is + * possible that both are FALSE for a particular CPU. Although it + * is unclear what that would imply about the interrupt processing + * procedure on that CPU. + */ + +#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE + +/* + * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager? + * + * If TRUE, then the memory is allocated during initialization. + * If FALSE, then the memory is allocated during initialization. + * + * This should be TRUE if CPU_HAS_SOFTWARE_INTERRUPT_STACK is TRUE + * or CPU_INSTALL_HARDWARE_INTERRUPT_STACK is TRUE. + */ + +#define CPU_ALLOCATE_INTERRUPT_STACK FALSE + +/* + * Does the CPU have hardware floating point? + * + * If TRUE, then the RTEMS_FLOATING_POINT task attribute is supported. + * If FALSE, then the RTEMS_FLOATING_POINT task attribute is ignored. + * + * If there is a FP coprocessor such as the i387 or mc68881, then + * the answer is TRUE. + * + * The macro name "NO_CPU_HAS_FPU" should be made CPU specific. + * It indicates whether or not this CPU model has FP support. For + * example, it would be possible to have an i386_nofp CPU model + * which set this to false to indicate that you have an i386 without + * an i387 and wish to leave floating point support out of RTEMS. + */ + +#define CPU_HARDWARE_FP TRUE + +/* + * Are all tasks RTEMS_FLOATING_POINT tasks implicitly? + * + * If TRUE, then the RTEMS_FLOATING_POINT task attribute is assumed. + * If FALSE, then the RTEMS_FLOATING_POINT task attribute is followed. + * + * So far, the only CPU in which this option has been used is the + * HP PA-RISC. The HP C compiler and gcc both implicitly use the + * floating point registers to perform integer multiplies. If + * a function which you would not think utilize the FP unit DOES, + * then one can not easily predict which tasks will use the FP hardware. + * In this case, this option should be TRUE. + * + * If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well. + */ + +#define CPU_ALL_TASKS_ARE_FP FALSE + +/* + * Should the IDLE task have a floating point context? + * + * If TRUE, then the IDLE task is created as a RTEMS_FLOATING_POINT task + * and it has a floating point context which is switched in and out. + * If FALSE, then the IDLE task does not have a floating point context. + * + * Setting this to TRUE negatively impacts the time required to preempt + * the IDLE task from an interrupt because the floating point context + * must be saved as part of the preemption. + */ + +#define CPU_IDLE_TASK_IS_FP FALSE + +/* + * Should the saving of the floating point registers be deferred + * until a context switch is made to another different floating point + * task? + * + * If TRUE, then the floating point context will not be stored until + * necessary. It will remain in the floating point registers and not + * disturned until another floating point task is switched to. + * + * If FALSE, then the floating point context is saved when a floating + * point task is switched out and restored when the next floating point + * task is restored. The state of the floating point registers between + * those two operations is not specified. + * + * If the floating point context does NOT have to be saved as part of + * interrupt dispatching, then it should be safe to set this to TRUE. + * + * Setting this flag to TRUE results in using a different algorithm + * for deciding when to save and restore the floating point context. + * The deferred FP switch algorithm minimizes the number of times + * the FP context is saved and restored. The FP context is not saved + * until a context switch is made to another, different FP task. + * Thus in a system with only one FP task, the FP context will never + * be saved or restored. + */ + +#define CPU_USE_DEFERRED_FP_SWITCH TRUE + +/* + * Does this port provide a CPU dependent IDLE task implementation? + * + * If TRUE, then the routine _CPU_Internal_threads_Idle_thread_body + * must be provided and is the default IDLE thread body instead of + * _Internal_threads_Idle_thread_body. + * + * If FALSE, then use the generic IDLE thread body if the BSP does + * not provide one. + * + * This is intended to allow for supporting processors which have + * a low power or idle mode. When the IDLE thread is executed, then + * the CPU can be powered down. + * + * The order of precedence for selecting the IDLE thread body is: + * + * 1. BSP provided + * 2. CPU dependent (if provided) + * 3. generic (if no BSP and no CPU dependent) + */ + +#define CPU_PROVIDES_IDLE_THREAD_BODY TRUE + +/* + * Does the stack grow up (toward higher addresses) or down + * (toward lower addresses)? + * + * If TRUE, then the grows upward. + * If FALSE, then the grows toward smaller addresses. + */ + +#if defined(hppa1_1) +#define CPU_STACK_GROWS_UP TRUE +#elif defined(sparc) +#define CPU_STACK_GROWS_UP FALSE +#else +#error "unknown CPU!!" +#endif + + +/* + * The following is the variable attribute used to force alignment + * of critical RTEMS structures. On some processors it may make + * sense to have these aligned on tighter boundaries than + * the minimum requirements of the compiler in order to have as + * much of the critical data area as possible in a cache line. + * + * The placement of this macro in the declaration of the variables + * is based on the syntactically requirements of the GNU C + * "__attribute__" extension. For example with GNU C, use + * the following to force a structures to a 32 byte boundary. + * + * __attribute__ ((aligned (32))) + * + * NOTE: Currently only the Priority Bit Map table uses this feature. + * To benefit from using this, the data must be heavily + * used so it will stay in the cache and used frequently enough + * in the executive to justify turning this on. + */ + +#define CPU_STRUCTURE_ALIGNMENT __attribute__ ((aligned (32))) + +/* + * The following defines the number of bits actually used in the + * interrupt field of the task mode. How those bits map to the + * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level(). + */ + +#define CPU_MODES_INTERRUPT_MASK 0x00000001 + +#define CPU_NAME "UNIX" + +/* + * Processor defined structures + * + * Examples structures include the descriptor tables from the i386 + * and the processor control structure on the i960ca. + */ + +/* may need to put some structures here. */ + +#if defined(hppa1_1) +/* + * Word indices within a jmp_buf structure + */ + +#ifdef RTEMS_NEWLIB +#define RP_OFF 6 +#define SP_OFF 2 +#define R3_OFF 10 +#define R4_OFF 11 +#define R5_OFF 12 +#define R6_OFF 13 +#define R7_OFF 14 +#define R8_OFF 15 +#define R9_OFF 16 +#define R10_OFF 17 +#define R11_OFF 18 +#define R12_OFF 19 +#define R13_OFF 20 +#define R14_OFF 21 +#define R15_OFF 22 +#define R16_OFF 23 +#define R17_OFF 24 +#define R18_OFF 25 +#define DP_OFF 26 +#endif + +#ifdef RTEMS_UNIXLIB +#define RP_OFF 0 +#define SP_OFF 1 +#define R3_OFF 4 +#define R4_OFF 5 +#define R5_OFF 6 +#define R6_OFF 7 +#define R7_OFF 8 +#define R8_OFF 9 +#define R9_OFF 10 +#define R10_OFF 11 +#define R11_OFF 12 +#define R12_OFF 13 +#define R13_OFF 14 +#define R14_OFF 15 +#define R15_OFF 16 +#define R16_OFF 17 +#define R17_OFF 18 +#define R18_OFF 19 +#define DP_OFF 20 +#endif +#endif + +#if defined(sparc) + +/* + * Word indices within a jmp_buf structure + */ + +#ifdef RTEMS_NEWLIB +#define ADDR_ADJ_OFFSET -8 +#define SP_OFF 0 +#define RP_OFF 1 +#define FP_OFF 2 +#endif + +#ifdef RTEMS_UNIXLIB +#define ADDR_ADJ_OFFSET 0 +#define G0_OFF 0 +#define SP_OFF 1 +#define RP_OFF 2 +#define FP_OFF 3 +#define I7_OFF 4 +#endif + +#endif + +/* + * Contexts + * + * Generally there are 2 types of context to save. + * 1. Interrupt registers to save + * 2. Task level registers to save + * + * This means we have the following 3 context items: + * 1. task level context stuff:: Context_Control + * 2. floating point task stuff:: Context_Control_fp + * 3. special interrupt level context :: Context_Control_interrupt + * + * On some processors, it is cost-effective to save only the callee + * preserved registers during a task context switch. This means + * that the ISR code needs to save those registers which do not + * persist across function calls. It is not mandatory to make this + * distinctions between the caller/callee saves registers for the + * purpose of minimizing context saved during task switch and on interrupts. + * If the cost of saving extra registers is minimal, simplicity is the + * choice. Save the same context on interrupt entry as for tasks in + * this case. + * + * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then + * care should be used in designing the context area. + * + * On some CPUs with hardware floating point support, the Context_Control_fp + * structure will not be used or it simply consist of an array of a + * fixed number of bytes. This is done when the floating point context + * is dumped by a "FP save context" type instruction and the format + * is not really defined by the CPU. In this case, there is no need + * to figure out the exact format -- only the size. Of course, although + * this is enough information for RTEMS, it is probably not enough for + * a debugger such as gdb. But that is another problem. + */ + +typedef struct { + jmp_buf regs; +} Context_Control; + +typedef struct { +} Context_Control_fp; + +typedef struct { +} CPU_Interrupt_frame; + + +/* + * The following table contains the information required to configure + * the XXX processor specific parameters. + * + * NOTE: The interrupt_stack_size field is required if + * CPU_ALLOCATE_INTERRUPT_STACK is defined as TRUE. + * + * The pretasking_hook, predriver_hook, and postdriver_hook, + * and the do_zero_of_workspace fields are required on ALL CPUs. + */ + +typedef struct { + void (*pretasking_hook)( void ); + void (*predriver_hook)( void ); + void (*postdriver_hook)( void ); + void (*idle_task)( void ); + boolean do_zero_of_workspace; + unsigned32 interrupt_stack_size; + unsigned32 extra_system_initialization_stack; +} rtems_cpu_table; + +/* + * This variable is optional. It is used on CPUs on which it is difficult + * to generate an "uninitialized" FP context. It is filled in by + * _CPU_Initialize and copied into the task's FP context area during + * _CPU_Context_Initialize. + */ + +EXTERN Context_Control_fp _CPU_Null_fp_context; + +/* + * On some CPUs, RTEMS supports a software managed interrupt stack. + * This stack is allocated by the Interrupt Manager and the switch + * is performed in _ISR_Handler. These variables contain pointers + * to the lowest and highest addresses in the chunk of memory allocated + * for the interrupt stack. Since it is unknown whether the stack + * grows up or down (in general), this give the CPU dependent + * code the option of picking the version it wants to use. + * + * NOTE: These two variables are required if the macro + * CPU_HAS_SOFTWARE_INTERRUPT_STACK is defined as TRUE. + */ + +EXTERN void *_CPU_Interrupt_stack_low; +EXTERN void *_CPU_Interrupt_stack_high; + +/* + * With some compilation systems, it is difficult if not impossible to + * call a high-level language routine from assembly language. This + * is especially true of commercial Ada compilers and name mangling + * C++ ones. This variable can be optionally defined by the CPU porter + * and contains the address of the routine _Thread_Dispatch. This + * can make it easier to invoke that routine at the end of the interrupt + * sequence (if a dispatch is necessary). + */ + +EXTERN void (*_CPU_Thread_dispatch_pointer)(); + +/* + * Nothing prevents the porter from declaring more CPU specific variables. + */ + +/* XXX: if needed, put more variables here */ + +/* + * The size of the floating point context area. On some CPUs this + * will not be a "sizeof" because the format of the floating point + * area is not defined -- only the size is. This is usually on + * CPUs with a "floating point save context" instruction. + */ + +#define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp ) + +/* + * The size of a frame on the stack + */ + +#if defined(hppa1_1) +#define CPU_FRAME_SIZE (32 * 4) +#elif defined(sparc) +#define CPU_FRAME_SIZE (112) /* based on disassembled test code */ +#else +#error "Unknown CPU!!!" +#endif + +/* + * Amount of extra stack (above minimum stack size) required by + * system initialization thread. Remember that in a multiprocessor + * system the system intialization thread becomes the MP server thread. + */ + +#define CPU_SYSTEM_INITIALIZATION_THREAD_EXTRA_STACK 0 + +/* + * This defines the number of entries in the ISR_Vector_table managed + * by RTEMS. + */ + +#define CPU_INTERRUPT_NUMBER_OF_VECTORS 64 + +/* + * Should be large enough to run all RTEMS tests. This insures + * that a "reasonable" small application should not have any problems. + */ + +#define CPU_STACK_MINIMUM_SIZE (16 * 1024) + +/* + * CPU's worst alignment requirement for data types on a byte boundary. This + * alignment does not take into account the requirements for the stack. + */ + +#define CPU_ALIGNMENT 8 + +/* + * This number corresponds to the byte alignment requirement for the + * heap handler. This alignment requirement may be stricter than that + * for the data types alignment specified by CPU_ALIGNMENT. It is + * common for the heap to follow the same alignment requirement as + * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap, + * then this should be set to CPU_ALIGNMENT. + * + * NOTE: This does not have to be a power of 2. It does have to + * be greater or equal to than CPU_ALIGNMENT. + */ + +#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT + +/* + * This number corresponds to the byte alignment requirement for memory + * buffers allocated by the partition manager. This alignment requirement + * may be stricter than that for the data types alignment specified by + * CPU_ALIGNMENT. It is common for the partition to follow the same + * alignment requirement as CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict + * enough for the partition, then this should be set to CPU_ALIGNMENT. + * + * NOTE: This does not have to be a power of 2. It does have to + * be greater or equal to than CPU_ALIGNMENT. + */ + +#define CPU_PARTITION_ALIGNMENT CPU_ALIGNMENT + +/* + * This number corresponds to the byte alignment requirement for the + * stack. This alignment requirement may be stricter than that for the + * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT + * is strict enough for the stack, then this should be set to 0. + * + * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT. + */ + +#define CPU_STACK_ALIGNMENT 64 + +/* ISR handler macros */ + +/* + * Disable all interrupts for an RTEMS critical section. The previous + * level is returned in _level. + */ + +#define _CPU_ISR_Disable( _level ) \ + do { \ + (_level) = _CPU_Disable_signal(); \ + } while ( 0 ) + +/* + * Enable interrupts to the previous level (returned by _CPU_ISR_Disable). + * This indicates the end of an RTEMS critical section. The parameter + * _level is not modified. + */ + +#define _CPU_ISR_Enable( _level ) \ + do { \ + _CPU_Enable_signal( (_level) ); \ + } while ( 0 ) + +/* + * This temporarily restores the interrupt to _level before immediately + * disabling them again. This is used to divide long RTEMS critical + * sections into two or more parts. The parameter _level is not + * modified. + */ + +#define _CPU_ISR_Flash( _level ) \ + do { \ + register _ignored = 0; \ + _CPU_ISR_Enable( (_level) ); \ + _CPU_ISR_Disable( _ignored ); \ + } while ( 0 ) + +/* + * Map interrupt level in task mode onto the hardware that the CPU + * actually provides. Currently, interrupt levels which do not + * map onto the CPU in a generic fashion are undefined. Someday, + * it would be nice if these were "mapped" by the application + * via a callout. For example, m68k has 8 levels 0 - 7, levels + * 8 - 255 would be available for bsp/application specific meaning. + * This could be used to manage a programmable interrupt controller + * via the rtems_task_mode directive. + */ + +#define _CPU_ISR_Set_level( new_level ) \ + { \ + if ( new_level ) \ + (void) _CPU_Disable_signal(); \ + else \ + _CPU_Enable_signal( 0 ); \ + } + +/* end of ISR handler macros */ + +/* Context handler macros */ + +/* + * This routine is responsible for somehow restarting the currently + * executing task. If you are lucky, then all that is necessary + * is restoring the context. Otherwise, there will need to be + * a special assembly routine which does something special in this + * case. Context_Restore should work most of the time. It will + * not work if restarting self conflicts with the stack frame + * assumptions of restoring a context. + */ + +#define _CPU_Context_Restart_self( _the_context ) \ + _CPU_Context_restore( (_the_context) ); + +/* + * The purpose of this macro is to allow the initial pointer into + * a floating point context area (used to save the floating point + * context) to be at an arbitrary place in the floating point + * context area. + * + * This is necessary because some FP units are designed to have + * their context saved as a stack which grows into lower addresses. + * Other FP units can be saved by simply moving registers into offsets + * from the base of the context area. Finally some FP units provide + * a "dump context" instruction which could fill in from high to low + * or low to high based on the whim of the CPU designers. + */ + +#define _CPU_Context_Fp_start( _base, _offset ) \ + ( (void *) (_base) + (_offset) ) + +/* + * This routine initializes the FP context area passed to it to. + * There are a few standard ways in which to initialize the + * floating point context. The code included for this macro assumes + * that this is a CPU in which a "initial" FP context was saved into + * _CPU_Null_fp_context and it simply copies it to the destination + * context passed to it. + * + * Other models include (1) not doing anything, and (2) putting + * a "null FP status word" in the correct place in the FP context. + */ + +#define _CPU_Context_Initialize_fp( _destination ) \ + { \ + *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context; \ + } + +#define _CPU_Context_save_fp( _fp_context ) \ + _CPU_Save_float_context( *(Context_Control_fp **)(_fp_context)) + +#define _CPU_Context_restore_fp( _fp_context ) \ + _CPU_Restore_float_context( *(Context_Control_fp **)(_fp_context)) + +extern void _CPU_Context_Initialize( + Context_Control *_the_context, + unsigned32 *_stack_base, + unsigned32 _size, + unsigned32 _new_level, + proc_ptr *_entry_point +); + +/* end of Context handler macros */ + +/* Fatal Error manager macros */ + +/* + * This routine copies _error into a known place -- typically a stack + * location or a register, optionally disables interrupts, and + * halts/stops the CPU. + */ + +#define _CPU_Fatal_halt( _error ) \ + _CPU_Fatal_error( _error ) + +/* end of Fatal Error manager macros */ + +/* Bitfield handler macros */ + +/* + * This routine sets _output to the bit number of the first bit + * set in _value. _value is of CPU dependent type Priority_Bit_map_control. + * This type may be either 16 or 32 bits wide although only the 16 + * least significant bits will be used. + * + * There are a number of variables in using a "find first bit" type + * instruction. + * + * (1) What happens when run on a value of zero? + * (2) Bits may be numbered from MSB to LSB or vice-versa. + * (3) The numbering may be zero or one based. + * (4) The "find first bit" instruction may search from MSB or LSB. + * + * RTEMS guarantees that (1) will never happen so it is not a concern. + * (2),(3), (4) are handled by the macros _CPU_Priority_mask() and + * _CPU_Priority_Bits_index(). These three form a set of routines + * which must logically operate together. Bits in the _value are + * set and cleared based on masks built by _CPU_Priority_mask(). + * The basic major and minor values calculated by _Priority_Major() + * and _Priority_Minor() are "massaged" by _CPU_Priority_Bits_index() + * to properly range between the values returned by the "find first bit" + * instruction. This makes it possible for _Priority_Get_highest() to + * calculate the major and directly index into the minor table. + * This mapping is necessary to ensure that 0 (a high priority major/minor) + * is the first bit found. + * + * This entire "find first bit" and mapping process depends heavily + * on the manner in which a priority is broken into a major and minor + * components with the major being the 4 MSB of a priority and minor + * the 4 LSB. Thus (0 << 4) + 0 corresponds to priority 0 -- the highest + * priority. And (15 << 4) + 14 corresponds to priority 254 -- the next + * to the lowest priority. + * + * If your CPU does not have a "find first bit" instruction, then + * there are ways to make do without it. Here are a handful of ways + * to implement this in software: + * + * - a series of 16 bit test instructions + * - a "binary search using if's" + * - _number = 0 + * if _value > 0x00ff + * _value >>=8 + * _number = 8; + * + * if _value > 0x0000f + * _value >=8 + * _number += 4 + * + * _number += bit_set_table[ _value ] + * + * where bit_set_table[ 16 ] has values which indicate the first + * bit set + */ + +#define _CPU_Bitfield_Find_first_bit( _value, _output ) \ + _output = _CPU_ffs( _value ) + +/* end of Bitfield handler macros */ + +/* + * This routine builds the mask which corresponds to the bit fields + * as searched by _CPU_Bitfield_Find_first_bit(). See the discussion + * for that routine. + */ + +#define _CPU_Priority_Mask( _bit_number ) \ + ( 1 << (_bit_number) ) + +/* + * This routine translates the bit numbers returned by + * _CPU_Bitfield_Find_first_bit() into something suitable for use as + * a major or minor component of a priority. See the discussion + * for that routine. + */ + +#define _CPU_Priority_Bits_index( _priority ) \ + (_priority) + +/* end of Priority handler macros */ + +/* functions */ + +/* + * _CPU_Initialize + * + * This routine performs CPU dependent initialization. + */ + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) +); + +/* + * _CPU_ISR_install_vector + * + * This routine installs an interrupt vector. + */ + +void _CPU_ISR_install_vector( + unsigned32 vector, + proc_ptr new_handler, + proc_ptr *old_handler +); + +/* + * _CPU_Install_interrupt_stack + * + * This routine installs the hardware interrupt stack pointer. + * + * NOTE: It need only be provided if CPU_HAS_HARDWARE_INTERRUPT_STACK + * is TRUE. + */ + +void _CPU_Install_interrupt_stack( void ); + +/* + * _CPU_Internal_threads_Idle_thread_body + * + * This routine is the CPU dependent IDLE thread body. + * + * NOTE: It need only be provided if CPU_PROVIDES_IDLE_THREAD_BODY + * is TRUE. + */ + +void _CPU_Internal_threads_Idle_thread_body( void ); + +/* + * _CPU_Context_switch + * + * This routine switches from the run context to the heir context. + */ + +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 +); + +/* + * _CPU_Save_float_context + * + * This routine saves the floating point context passed to it. + */ + +void _CPU_Save_float_context( + Context_Control_fp *fp_context_ptr +); + +/* + * _CPU_Restore_float_context + * + * This routine restores the floating point context passed to it. + */ + +void _CPU_Restore_float_context( + Context_Control_fp *fp_context_ptr +); + + +void _CPU_ISR_Set_signal_level( + unsigned32 level +); + +unsigned32 _CPU_Disable_signal( void ); + +void _CPU_Enable_signal( + unsigned32 level +); + +void _CPU_Fatal_error( + unsigned32 _error +); + +int _CPU_ffs( + unsigned32 _value +); + +/* The following routine swaps the endian format of an unsigned int. + * It must be static because it is referenced indirectly. + * + * This version will work on any processor, but if there is a better + * way for your CPU PLEASE use it. The most common way to do this is to: + * + * swap least significant two bytes with 16-bit rotate + * swap upper and lower 16-bits + * swap most significant two bytes with 16-bit rotate + * + * Some CPUs have special instructions which swap a 32-bit quantity in + * a single instruction (e.g. i486). It is probably best to avoid + * an "endian swapping control bit" in the CPU. One good reason is + * that interrupts would probably have to be disabled to insure that + * an interrupt does not try to access the same "chunk" with the wrong + * endian. Another good reason is that on some CPUs, the endian bit + * endianness for ALL fetches -- both code and data -- so the code + * will be fetched incorrectly. + */ + +static inline unsigned int CPU_swap_u32( + unsigned int value +) +{ + unsigned32 byte1, byte2, byte3, byte4, swapped; + + byte4 = (value >> 24) & 0xff; + byte3 = (value >> 16) & 0xff; + byte2 = (value >> 8) & 0xff; + byte1 = value & 0xff; + + swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4; + return( swapped ); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/c/src/exec/score/cpu/unix/unix.h b/c/src/exec/score/cpu/unix/unix.h new file mode 100644 index 0000000000..823bbcfb34 --- /dev/null +++ b/c/src/exec/score/cpu/unix/unix.h @@ -0,0 +1,90 @@ +/* unix.h + * + * This include file contains the basic type definitions required by RTEMS + * which are typical for a modern UNIX computer using GCC. + * + * 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 __UNIX_h +#define __UNIX_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following define the CPU Family and Model within the family + * + * NOTE: The string "REPLACE_THIS_WITH_THE_CPU_MODEL" is replaced + * with the name of the appropriate macro for this target CPU. + */ + +#define unix +#define REPLACE_THIS_WITH_THE_CPU_FAMILY +#define REPLACE_THIS_WITH_THE_BSP +#define REPLACE_THIS_WITH_THE_CPU_MODEL +#define REPLACE_THIS_WITH_THE_UNIX_FLAVOR + +/* + * This file contains the information required to build + * RTEMS for a particular member of the "unix" + * family when executing in protected mode. It does + * this by setting variables to indicate which implementation + * dependent features are present in a particular member + * of the family. + */ + +#if defined(hpux) + +#define RTEMS_MODEL_NAME "hpux" + +#elif defined(solaris) + +#define RTEMS_MODEL_NAME "solaris" + +#else + +#error "Unsupported CPU Model" + +#endif + +#ifndef ASM + +/* type definitions */ + +typedef unsigned char unsigned8; /* 8-bit unsigned integer */ +typedef unsigned short unsigned16; /* 16-bit unsigned integer */ +typedef unsigned int unsigned32; /* 32-bit unsigned integer */ +typedef unsigned long long unsigned64; /* 64-bit unsigned integer */ + +typedef unsigned16 Priority_Bit_map_control; + +typedef char signed8; /* 8-bit signed integer */ +typedef short signed16; /* 16-bit signed integer */ +typedef int signed32; /* 32-bit signed integer */ +typedef long long signed64; /* 64-bit signed integer */ + +typedef unsigned32 boolean; /* Boolean value */ + +typedef float single_precision; /* single precision float */ +typedef double double_precision; /* double precision float */ + +typedef void ( *unix_isr_entry )( void ); + +#ifdef __cplusplus +} +#endif + +#endif /* !ASM */ +#endif +/* end of include file */ + diff --git a/c/src/exec/score/headers/address.h b/c/src/exec/score/headers/address.h new file mode 100644 index 0000000000..0abd113f63 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/bitfield.h b/c/src/exec/score/headers/bitfield.h new file mode 100644 index 0000000000..a74ea97735 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/chain.h b/c/src/exec/score/headers/chain.h new file mode 100644 index 0000000000..06cc47cc65 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/context.h b/c/src/exec/score/headers/context.h new file mode 100644 index 0000000000..9b8ee92b04 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/copyrt.h b/c/src/exec/score/headers/copyrt.h new file mode 100644 index 0000000000..c711ba09b3 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/debug.h b/c/src/exec/score/headers/debug.h new file mode 100644 index 0000000000..afe6251bbe --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/heap.h b/c/src/exec/score/headers/heap.h new file mode 100644 index 0000000000..9eb348a760 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/isr.h b/c/src/exec/score/headers/isr.h new file mode 100644 index 0000000000..77c3f8663e --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/mpci.h b/c/src/exec/score/headers/mpci.h new file mode 100644 index 0000000000..ca06dd243b --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/mppkt.h b/c/src/exec/score/headers/mppkt.h new file mode 100644 index 0000000000..e0cf6b1967 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/object.h b/c/src/exec/score/headers/object.h new file mode 100644 index 0000000000..50eede9fd7 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/objectmp.h b/c/src/exec/score/headers/objectmp.h new file mode 100644 index 0000000000..0d29fda753 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/priority.h b/c/src/exec/score/headers/priority.h new file mode 100644 index 0000000000..823611b080 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/stack.h b/c/src/exec/score/headers/stack.h new file mode 100644 index 0000000000..a0fce1ef04 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/states.h b/c/src/exec/score/headers/states.h new file mode 100644 index 0000000000..56f67ecc49 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/sysstate.h b/c/src/exec/score/headers/sysstate.h new file mode 100644 index 0000000000..511a26cefc --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/system.h b/c/src/exec/score/headers/system.h new file mode 100644 index 0000000000..3ff3772d11 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/thread.h b/c/src/exec/score/headers/thread.h new file mode 100644 index 0000000000..de07a721ef --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/threadmp.h b/c/src/exec/score/headers/threadmp.h new file mode 100644 index 0000000000..c6e8252030 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/threadq.h b/c/src/exec/score/headers/threadq.h new file mode 100644 index 0000000000..291044ead1 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/tod.h b/c/src/exec/score/headers/tod.h new file mode 100644 index 0000000000..ae7e2b9747 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/tqdata.h b/c/src/exec/score/headers/tqdata.h new file mode 100644 index 0000000000..8c43fa4c72 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/userext.h b/c/src/exec/score/headers/userext.h new file mode 100644 index 0000000000..37131959d9 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/watchdog.h b/c/src/exec/score/headers/watchdog.h new file mode 100644 index 0000000000..5c897615f7 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/headers/wkspace.h b/c/src/exec/score/headers/wkspace.h new file mode 100644 index 0000000000..14bc090291 --- /dev/null +++ b/c/src/exec/score/headers/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/c/src/exec/score/include/rtems/debug.h b/c/src/exec/score/include/rtems/debug.h new file mode 100644 index 0000000000..afe6251bbe --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/address.h b/c/src/exec/score/include/rtems/score/address.h new file mode 100644 index 0000000000..0abd113f63 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/bitfield.h b/c/src/exec/score/include/rtems/score/bitfield.h new file mode 100644 index 0000000000..a74ea97735 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/chain.h b/c/src/exec/score/include/rtems/score/chain.h new file mode 100644 index 0000000000..06cc47cc65 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/context.h b/c/src/exec/score/include/rtems/score/context.h new file mode 100644 index 0000000000..9b8ee92b04 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/copyrt.h b/c/src/exec/score/include/rtems/score/copyrt.h new file mode 100644 index 0000000000..c711ba09b3 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/heap.h b/c/src/exec/score/include/rtems/score/heap.h new file mode 100644 index 0000000000..9eb348a760 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/isr.h b/c/src/exec/score/include/rtems/score/isr.h new file mode 100644 index 0000000000..77c3f8663e --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/mpci.h b/c/src/exec/score/include/rtems/score/mpci.h new file mode 100644 index 0000000000..ca06dd243b --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/mppkt.h b/c/src/exec/score/include/rtems/score/mppkt.h new file mode 100644 index 0000000000..e0cf6b1967 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/object.h b/c/src/exec/score/include/rtems/score/object.h new file mode 100644 index 0000000000..50eede9fd7 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/objectmp.h b/c/src/exec/score/include/rtems/score/objectmp.h new file mode 100644 index 0000000000..0d29fda753 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/priority.h b/c/src/exec/score/include/rtems/score/priority.h new file mode 100644 index 0000000000..823611b080 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/stack.h b/c/src/exec/score/include/rtems/score/stack.h new file mode 100644 index 0000000000..a0fce1ef04 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/states.h b/c/src/exec/score/include/rtems/score/states.h new file mode 100644 index 0000000000..56f67ecc49 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/sysstate.h b/c/src/exec/score/include/rtems/score/sysstate.h new file mode 100644 index 0000000000..511a26cefc --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/thread.h b/c/src/exec/score/include/rtems/score/thread.h new file mode 100644 index 0000000000..de07a721ef --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/threadmp.h b/c/src/exec/score/include/rtems/score/threadmp.h new file mode 100644 index 0000000000..c6e8252030 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/threadq.h b/c/src/exec/score/include/rtems/score/threadq.h new file mode 100644 index 0000000000..291044ead1 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/tod.h b/c/src/exec/score/include/rtems/score/tod.h new file mode 100644 index 0000000000..ae7e2b9747 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/tqdata.h b/c/src/exec/score/include/rtems/score/tqdata.h new file mode 100644 index 0000000000..8c43fa4c72 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/userext.h b/c/src/exec/score/include/rtems/score/userext.h new file mode 100644 index 0000000000..37131959d9 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/watchdog.h b/c/src/exec/score/include/rtems/score/watchdog.h new file mode 100644 index 0000000000..5c897615f7 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/score/wkspace.h b/c/src/exec/score/include/rtems/score/wkspace.h new file mode 100644 index 0000000000..14bc090291 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/include/rtems/system.h b/c/src/exec/score/include/rtems/system.h new file mode 100644 index 0000000000..3ff3772d11 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/address.inl b/c/src/exec/score/inline/address.inl new file mode 100644 index 0000000000..f9189e625e --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/inline/chain.inl b/c/src/exec/score/inline/chain.inl new file mode 100644 index 0000000000..63706544e4 --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/inline/heap.inl b/c/src/exec/score/inline/heap.inl new file mode 100644 index 0000000000..58be9b02af --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/inline/isr.inl b/c/src/exec/score/inline/isr.inl new file mode 100644 index 0000000000..f44880c3b6 --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/inline/mppkt.inl b/c/src/exec/score/inline/mppkt.inl new file mode 100644 index 0000000000..22ec30a28c --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/inline/object.inl b/c/src/exec/score/inline/object.inl new file mode 100644 index 0000000000..9c2110077c --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/inline/objectmp.inl b/c/src/exec/score/inline/objectmp.inl new file mode 100644 index 0000000000..e09a3df528 --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/inline/priority.inl b/c/src/exec/score/inline/priority.inl new file mode 100644 index 0000000000..9e7c159f65 --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/inline/rtems/score/address.inl b/c/src/exec/score/inline/rtems/score/address.inl new file mode 100644 index 0000000000..f9189e625e --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/rtems/score/chain.inl b/c/src/exec/score/inline/rtems/score/chain.inl new file mode 100644 index 0000000000..63706544e4 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/rtems/score/heap.inl b/c/src/exec/score/inline/rtems/score/heap.inl new file mode 100644 index 0000000000..58be9b02af --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/rtems/score/isr.inl b/c/src/exec/score/inline/rtems/score/isr.inl new file mode 100644 index 0000000000..f44880c3b6 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/rtems/score/mppkt.inl b/c/src/exec/score/inline/rtems/score/mppkt.inl new file mode 100644 index 0000000000..22ec30a28c --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/rtems/score/object.inl b/c/src/exec/score/inline/rtems/score/object.inl new file mode 100644 index 0000000000..9c2110077c --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/rtems/score/objectmp.inl b/c/src/exec/score/inline/rtems/score/objectmp.inl new file mode 100644 index 0000000000..e09a3df528 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/rtems/score/priority.inl b/c/src/exec/score/inline/rtems/score/priority.inl new file mode 100644 index 0000000000..9e7c159f65 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/rtems/score/stack.inl b/c/src/exec/score/inline/rtems/score/stack.inl new file mode 100644 index 0000000000..24a6d9d873 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/rtems/score/states.inl b/c/src/exec/score/inline/rtems/score/states.inl new file mode 100644 index 0000000000..316f40e4eb --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/rtems/score/sysstate.inl b/c/src/exec/score/inline/rtems/score/sysstate.inl new file mode 100644 index 0000000000..14d838cb14 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/rtems/score/thread.inl b/c/src/exec/score/inline/rtems/score/thread.inl new file mode 100644 index 0000000000..35b8eeccfe --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/rtems/score/threadmp.inl b/c/src/exec/score/inline/rtems/score/threadmp.inl new file mode 100644 index 0000000000..f4beba59ed --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/rtems/score/tod.inl b/c/src/exec/score/inline/rtems/score/tod.inl new file mode 100644 index 0000000000..dadcdabcda --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/rtems/score/tqdata.inl b/c/src/exec/score/inline/rtems/score/tqdata.inl new file mode 100644 index 0000000000..7ec1e9e186 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/rtems/score/userext.inl b/c/src/exec/score/inline/rtems/score/userext.inl new file mode 100644 index 0000000000..1558da968a --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/rtems/score/watchdog.inl b/c/src/exec/score/inline/rtems/score/watchdog.inl new file mode 100644 index 0000000000..d5d12cbeef --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/rtems/score/wkspace.inl b/c/src/exec/score/inline/rtems/score/wkspace.inl new file mode 100644 index 0000000000..fee7623a6c --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/inline/stack.inl b/c/src/exec/score/inline/stack.inl new file mode 100644 index 0000000000..24a6d9d873 --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/inline/states.inl b/c/src/exec/score/inline/states.inl new file mode 100644 index 0000000000..316f40e4eb --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/inline/sysstate.inl b/c/src/exec/score/inline/sysstate.inl new file mode 100644 index 0000000000..14d838cb14 --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/inline/thread.inl b/c/src/exec/score/inline/thread.inl new file mode 100644 index 0000000000..35b8eeccfe --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/inline/threadmp.inl b/c/src/exec/score/inline/threadmp.inl new file mode 100644 index 0000000000..f4beba59ed --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/inline/tod.inl b/c/src/exec/score/inline/tod.inl new file mode 100644 index 0000000000..dadcdabcda --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/inline/tqdata.inl b/c/src/exec/score/inline/tqdata.inl new file mode 100644 index 0000000000..7ec1e9e186 --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/inline/userext.inl b/c/src/exec/score/inline/userext.inl new file mode 100644 index 0000000000..1558da968a --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/inline/watchdog.inl b/c/src/exec/score/inline/watchdog.inl new file mode 100644 index 0000000000..d5d12cbeef --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/inline/wkspace.inl b/c/src/exec/score/inline/wkspace.inl new file mode 100644 index 0000000000..fee7623a6c --- /dev/null +++ b/c/src/exec/score/inline/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/c/src/exec/score/macros/README b/c/src/exec/score/macros/README new file mode 100644 index 0000000000..b2f0c4d481 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/address.inl b/c/src/exec/score/macros/address.inl new file mode 100644 index 0000000000..f2672f2500 --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/macros/chain.inl b/c/src/exec/score/macros/chain.inl new file mode 100644 index 0000000000..a53b3fc270 --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/macros/heap.inl b/c/src/exec/score/macros/heap.inl new file mode 100644 index 0000000000..6f06478207 --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/macros/isr.inl b/c/src/exec/score/macros/isr.inl new file mode 100644 index 0000000000..93f234c7ff --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/macros/mppkt.inl b/c/src/exec/score/macros/mppkt.inl new file mode 100644 index 0000000000..ff1d51034b --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/macros/object.inl b/c/src/exec/score/macros/object.inl new file mode 100644 index 0000000000..f4fdc39d6e --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/macros/objectmp.inl b/c/src/exec/score/macros/objectmp.inl new file mode 100644 index 0000000000..2f1c5ac7fa --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/macros/priority.inl b/c/src/exec/score/macros/priority.inl new file mode 100644 index 0000000000..7ad1fd909a --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/macros/rtems/score/README b/c/src/exec/score/macros/rtems/score/README new file mode 100644 index 0000000000..b2f0c4d481 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/address.inl b/c/src/exec/score/macros/rtems/score/address.inl new file mode 100644 index 0000000000..f2672f2500 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/chain.inl b/c/src/exec/score/macros/rtems/score/chain.inl new file mode 100644 index 0000000000..a53b3fc270 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/heap.inl b/c/src/exec/score/macros/rtems/score/heap.inl new file mode 100644 index 0000000000..6f06478207 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/isr.inl b/c/src/exec/score/macros/rtems/score/isr.inl new file mode 100644 index 0000000000..93f234c7ff --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/mppkt.inl b/c/src/exec/score/macros/rtems/score/mppkt.inl new file mode 100644 index 0000000000..ff1d51034b --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/object.inl b/c/src/exec/score/macros/rtems/score/object.inl new file mode 100644 index 0000000000..f4fdc39d6e --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/objectmp.inl b/c/src/exec/score/macros/rtems/score/objectmp.inl new file mode 100644 index 0000000000..2f1c5ac7fa --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/priority.inl b/c/src/exec/score/macros/rtems/score/priority.inl new file mode 100644 index 0000000000..7ad1fd909a --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/stack.inl b/c/src/exec/score/macros/rtems/score/stack.inl new file mode 100644 index 0000000000..208503b45f --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/states.inl b/c/src/exec/score/macros/rtems/score/states.inl new file mode 100644 index 0000000000..f69c4ba042 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/sysstate.inl b/c/src/exec/score/macros/rtems/score/sysstate.inl new file mode 100644 index 0000000000..5cc9f9e9f9 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/thread.inl b/c/src/exec/score/macros/rtems/score/thread.inl new file mode 100644 index 0000000000..0e041de5ac --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/threadmp.inl b/c/src/exec/score/macros/rtems/score/threadmp.inl new file mode 100644 index 0000000000..c601862f96 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/tod.inl b/c/src/exec/score/macros/rtems/score/tod.inl new file mode 100644 index 0000000000..9360a588b1 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/tqdata.inl b/c/src/exec/score/macros/rtems/score/tqdata.inl new file mode 100644 index 0000000000..5f657c1a94 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/userext.inl b/c/src/exec/score/macros/rtems/score/userext.inl new file mode 100644 index 0000000000..781f30ad40 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/watchdog.inl b/c/src/exec/score/macros/rtems/score/watchdog.inl new file mode 100644 index 0000000000..1b150d8dab --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/rtems/score/wkspace.inl b/c/src/exec/score/macros/rtems/score/wkspace.inl new file mode 100644 index 0000000000..3c516bfb93 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/macros/stack.inl b/c/src/exec/score/macros/stack.inl new file mode 100644 index 0000000000..208503b45f --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/macros/states.inl b/c/src/exec/score/macros/states.inl new file mode 100644 index 0000000000..f69c4ba042 --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/macros/sysstate.inl b/c/src/exec/score/macros/sysstate.inl new file mode 100644 index 0000000000..5cc9f9e9f9 --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/macros/thread.inl b/c/src/exec/score/macros/thread.inl new file mode 100644 index 0000000000..0e041de5ac --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/macros/threadmp.inl b/c/src/exec/score/macros/threadmp.inl new file mode 100644 index 0000000000..c601862f96 --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/macros/tod.inl b/c/src/exec/score/macros/tod.inl new file mode 100644 index 0000000000..9360a588b1 --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/macros/tqdata.inl b/c/src/exec/score/macros/tqdata.inl new file mode 100644 index 0000000000..5f657c1a94 --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/macros/userext.inl b/c/src/exec/score/macros/userext.inl new file mode 100644 index 0000000000..781f30ad40 --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/macros/watchdog.inl b/c/src/exec/score/macros/watchdog.inl new file mode 100644 index 0000000000..1b150d8dab --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/macros/wkspace.inl b/c/src/exec/score/macros/wkspace.inl new file mode 100644 index 0000000000..3c516bfb93 --- /dev/null +++ b/c/src/exec/score/macros/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/c/src/exec/score/src/chain.c b/c/src/exec/score/src/chain.c new file mode 100644 index 0000000000..88f6759b0b --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/src/coretod.c b/c/src/exec/score/src/coretod.c new file mode 100644 index 0000000000..4689c637d7 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/src/heap.c b/c/src/exec/score/src/heap.c new file mode 100644 index 0000000000..485012ddf7 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/src/mpci.c b/c/src/exec/score/src/mpci.c new file mode 100644 index 0000000000..e8d3803d76 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/src/object.c b/c/src/exec/score/src/object.c new file mode 100644 index 0000000000..71c365fa1e --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/src/objectmp.c b/c/src/exec/score/src/objectmp.c new file mode 100644 index 0000000000..d75a34b150 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/src/thread.c b/c/src/exec/score/src/thread.c new file mode 100644 index 0000000000..2d9fc33e6b --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/src/threadmp.c b/c/src/exec/score/src/threadmp.c new file mode 100644 index 0000000000..5d352e2d25 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/src/threadq.c b/c/src/exec/score/src/threadq.c new file mode 100644 index 0000000000..60ffb5db38 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/src/tod.c b/c/src/exec/score/src/tod.c new file mode 100644 index 0000000000..4689c637d7 --- /dev/null +++ b/c/src/exec/score/src/tod.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/c/src/exec/score/src/watchdog.c b/c/src/exec/score/src/watchdog.c new file mode 100644 index 0000000000..7db26c0cd5 --- /dev/null +++ b/c/src/exec/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/c/src/exec/score/src/wkspace.c b/c/src/exec/score/src/wkspace.c new file mode 100644 index 0000000000..577b0f6c01 --- /dev/null +++ b/c/src/exec/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 */ + diff --git a/c/src/exec/score/tools/hppa1.1/genoffsets.c b/c/src/exec/score/tools/hppa1.1/genoffsets.c new file mode 100644 index 0000000000..6563681f11 --- /dev/null +++ b/c/src/exec/score/tools/hppa1.1/genoffsets.c @@ -0,0 +1,191 @@ +/* + * @(#)genoffsets.c 1.3 - 95/03/15 + * + * + * genoffsets.c + * + * This file generates the offsets.h for the HP PA-RISC port of RTEMS. + * + * NOTE: It only prints the offset for structures actually used + * by the assembly code. + * + * 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$ + * + */ + +#include + +#include + +int main( + int argc, + char **argv +) +{ + unsigned int size; + + /* + * Print the file header + */ + +printf( + "/* offsets.h\n" + " *\n" + " * This include file contains the offsets of elements in the\n" + " * C data structures used by the assembly language code for the\n" + " * HP PA-RISC 1.1 port of RTEMS.\n" + " *\n" + " * NOTE: THIS FILE IS AUTOMATICALLY GENERATED!!!!\n" + " * DO NOT EDIT THIS BY HAND!!!!\n" + " *\n" + " * 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" + " *\n" + " * This material may be reproduced by or for the U.S. Government pursuant\n" + " * to the copyright license under the clause at DFARS 252.227-7013. This\n" + " * notice must appear in all copies of this file and its derivatives.\n" + " */\n" + "\n" + "#ifndef __OFFSETS_h\n" + "#define __OFFSETS_h\n" + "\n" +); + +/* + * Offsets of elements in the Context_control structure. + */ + +#define PRINT_IT( STRING, TYPE, FIELD ) \ + printf( "#define\t%s\t0x%p\t\t/* %d */\n", \ + STRING, \ + &((TYPE)0)->FIELD, \ + (int) &((TYPE)0)->FIELD ); + +#define PRINT_SIZE( STRING, item ) \ + printf( "#define\t%s\t%d\t\t/* 0x%x */\n", \ + STRING, \ + sizeof(item), \ + sizeof(item) ); + +#define PRINT_COMMENT( STRING ) \ + printf( \ + "\n" \ + "/*\n" \ + " * " STRING "\n" \ + " */\n" \ + "\n" \ + ); + + PRINT_COMMENT("Context_Control information"); + + PRINT_IT( "FLAGS_OFFSET", Context_Control *, flags ); + PRINT_IT( "R1_OFFSET", Context_Control *, gr1 ); + PRINT_IT( "R2_OFFSET", Context_Control *, gr2 ); + PRINT_IT( "R3_OFFSET", Context_Control *, gr3 ); + PRINT_IT( "R4_OFFSET", Context_Control *, gr4 ); + PRINT_IT( "R5_OFFSET", Context_Control *, gr5 ); + PRINT_IT( "R6_OFFSET", Context_Control *, gr6 ); + PRINT_IT( "R7_OFFSET", Context_Control *, gr7 ); + PRINT_IT( "R8_OFFSET", Context_Control *, gr8 ); + PRINT_IT( "R9_OFFSET", Context_Control *, gr9 ); + PRINT_IT( "R10_OFFSET", Context_Control *, gr10 ); + PRINT_IT( "R11_OFFSET", Context_Control *, gr11 ); + PRINT_IT( "R12_OFFSET", Context_Control *, gr12 ); + PRINT_IT( "R13_OFFSET", Context_Control *, gr13 ); + PRINT_IT( "R14_OFFSET", Context_Control *, gr14 ); + PRINT_IT( "R15_OFFSET", Context_Control *, gr15 ); + PRINT_IT( "R16_OFFSET", Context_Control *, gr16 ); + PRINT_IT( "R17_OFFSET", Context_Control *, gr17 ); + PRINT_IT( "R18_OFFSET", Context_Control *, gr18 ); + PRINT_IT( "R19_OFFSET", Context_Control *, gr19 ); + PRINT_IT( "R20_OFFSET", Context_Control *, gr20 ); + PRINT_IT( "R21_OFFSET", Context_Control *, gr21 ); + PRINT_IT( "R22_OFFSET", Context_Control *, gr22 ); + PRINT_IT( "R23_OFFSET", Context_Control *, gr23 ); + PRINT_IT( "R24_OFFSET", Context_Control *, gr24 ); + PRINT_IT( "R25_OFFSET", Context_Control *, gr25 ); + PRINT_IT( "R26_OFFSET", Context_Control *, gr26 ); + PRINT_IT( "R27_OFFSET", Context_Control *, gr27 ); + PRINT_IT( "R28_OFFSET", Context_Control *, gr28 ); + PRINT_IT( "R29_OFFSET", Context_Control *, gr29 ); + PRINT_IT( "R30_OFFSET", Context_Control *, sp ); + PRINT_IT( "R31_OFFSET", Context_Control *, gr31 ); + + /* + * And common aliases for the above + */ + + PRINT_COMMENT("Common aliases for above"); + + PRINT_IT( "RP_OFFSET", Context_Control *, gr2 ); + PRINT_IT( "ARG3_OFFSET", Context_Control *, gr23 ); + PRINT_IT( "ARG2_OFFSET", Context_Control *, gr24 ); + PRINT_IT( "ARG1_OFFSET", Context_Control *, gr25 ); + PRINT_IT( "ARG0_OFFSET", Context_Control *, gr26 ); + PRINT_IT( "SP_OFFSET", Context_Control *, sp ); + PRINT_IT( "DP_OFFSET", Context_Control *, gr27 ); + PRINT_IT( "RET0_OFFSET", Context_Control *, gr28 ); + PRINT_IT( "RET1_OFFSET", Context_Control *, gr29 ); + + PRINT_SIZE("CPU_CONTEXT_SIZE", Context_Control); + + PRINT_COMMENT("Context_Control_fp information"); + + PRINT_SIZE("CPU_CONTEXT_FP_SIZE", Context_Control_fp); + + /* + * And the control registers + */ + + PRINT_COMMENT("Control register portion of context"); + + PRINT_IT( "SAR_OFFSET", Context_Control *, sar ); + PRINT_IT( "IPSW_OFFSET", Context_Control *, ipsw ); + PRINT_IT( "IIR_OFFSET", Context_Control *, iir ); + PRINT_IT( "IOR_OFFSET", Context_Control *, ior ); + PRINT_IT( "ISR_OFFSET", Context_Control *, isr ); + PRINT_IT( "PCOQFRONT_OFFSET", Context_Control *, pcoqfront ); + PRINT_IT( "PCOQBACK_OFFSET", Context_Control *, pcoqback ); + PRINT_IT( "PCSQFRONT_OFFSET", Context_Control *, pcsqfront ); + PRINT_IT( "PCSQBACK_OFFSET", Context_Control *, pcsqback ); + PRINT_IT( "ITIMER_OFFSET", Context_Control *, itimer ); + + /* + * Full interrupt frame (integer + float) + */ + PRINT_COMMENT("Interrupt frame information"); + + PRINT_IT( "INTEGER_CONTEXT_OFFSET", CPU_Interrupt_frame *, Integer ); + PRINT_IT( "FP_CONTEXT_OFFSET", CPU_Interrupt_frame *, Floating_Point ); + size = sizeof( CPU_Interrupt_frame ); + + if ( size % CPU_STACK_ALIGNMENT ) + size += CPU_STACK_ALIGNMENT - (size % CPU_STACK_ALIGNMENT); + + printf( "#define\tCPU_INTERRUPT_FRAME_SIZE\t%d\t\t/* 0x%x */\n", size, size ); + +#undef PRINT_IT +#undef PRINT_SIZE +#undef PRINT_COMMENT + + /* + * Print the end of file stuff + */ + + printf( + "\n" + "#endif /* __OFFSETS_h */\n" + "\n" + "/* end of include file */\n" + ); + + return 0; +} -- cgit v1.2.3