From ac7d5ef06a6d6e8d84abbd1f0b82162725f98326 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 11 May 1995 17:39:37 +0000 Subject: Initial revision --- cpukit/score/cpu/hppa1.1/cpu.c | 313 ++++++++++ cpukit/score/cpu/i386/asm.h | 131 +++++ cpukit/score/cpu/i386/cpu.c | 121 ++++ cpukit/score/cpu/i386/rtems/asm.h | 131 +++++ cpukit/score/cpu/i960/asm.h | 107 ++++ cpukit/score/cpu/i960/cpu.c | 124 ++++ cpukit/score/cpu/m68k/asm.h | 127 ++++ cpukit/score/cpu/m68k/cpu.c | 97 ++++ cpukit/score/cpu/m68k/rtems/asm.h | 127 ++++ cpukit/score/cpu/no_cpu/asm.h | 98 ++++ cpukit/score/cpu/no_cpu/cpu.c | 132 +++++ cpukit/score/cpu/no_cpu/cpu_asm.c | 152 +++++ cpukit/score/cpu/no_cpu/rtems/asm.h | 98 ++++ cpukit/score/cpu/unix/cpu.c | 529 +++++++++++++++++ cpukit/score/include/rtems/debug.h | 98 ++++ cpukit/score/include/rtems/score/address.h | 122 ++++ cpukit/score/include/rtems/score/bitfield.h | 49 ++ cpukit/score/include/rtems/score/chain.h | 432 ++++++++++++++ cpukit/score/include/rtems/score/context.h | 133 +++++ cpukit/score/include/rtems/score/copyrt.h | 42 ++ cpukit/score/include/rtems/score/heap.h | 396 +++++++++++++ cpukit/score/include/rtems/score/isr.h | 239 ++++++++ cpukit/score/include/rtems/score/mpci.h | 171 ++++++ cpukit/score/include/rtems/score/mppkt.h | 123 ++++ cpukit/score/include/rtems/score/object.h | 380 ++++++++++++ cpukit/score/include/rtems/score/objectmp.h | 165 ++++++ cpukit/score/include/rtems/score/priority.h | 195 +++++++ cpukit/score/include/rtems/score/stack.h | 95 +++ cpukit/score/include/rtems/score/states.h | 337 +++++++++++ cpukit/score/include/rtems/score/sysstate.h | 143 +++++ cpukit/score/include/rtems/score/thread.h | 721 +++++++++++++++++++++++ cpukit/score/include/rtems/score/threadmp.h | 134 +++++ cpukit/score/include/rtems/score/threadq.h | 264 +++++++++ cpukit/score/include/rtems/score/tod.h | 300 ++++++++++ cpukit/score/include/rtems/score/tqdata.h | 90 +++ cpukit/score/include/rtems/score/userext.h | 213 +++++++ cpukit/score/include/rtems/score/watchdog.h | 471 +++++++++++++++ cpukit/score/include/rtems/score/wkspace.h | 99 ++++ cpukit/score/include/rtems/system.h | 132 +++++ cpukit/score/inline/rtems/score/address.inl | 109 ++++ cpukit/score/inline/rtems/score/chain.inl | 292 ++++++++++ cpukit/score/inline/rtems/score/heap.inl | 203 +++++++ cpukit/score/inline/rtems/score/isr.inl | 70 +++ cpukit/score/inline/rtems/score/mppkt.inl | 49 ++ cpukit/score/inline/rtems/score/object.inl | 198 +++++++ cpukit/score/inline/rtems/score/objectmp.inl | 62 ++ cpukit/score/inline/rtems/score/priority.inl | 168 ++++++ cpukit/score/inline/rtems/score/stack.inl | 63 ++ cpukit/score/inline/rtems/score/states.inl | 285 +++++++++ cpukit/score/inline/rtems/score/sysstate.inl | 103 ++++ cpukit/score/inline/rtems/score/thread.inl | 252 ++++++++ cpukit/score/inline/rtems/score/threadmp.inl | 53 ++ cpukit/score/inline/rtems/score/tod.inl | 72 +++ cpukit/score/inline/rtems/score/tqdata.inl | 47 ++ cpukit/score/inline/rtems/score/userext.inl | 268 +++++++++ cpukit/score/inline/rtems/score/watchdog.inl | 296 ++++++++++ cpukit/score/inline/rtems/score/wkspace.inl | 104 ++++ cpukit/score/macros/README | 18 + cpukit/score/macros/rtems/score/README | 18 + cpukit/score/macros/rtems/score/address.inl | 79 +++ cpukit/score/macros/rtems/score/chain.inl | 200 +++++++ cpukit/score/macros/rtems/score/heap.inl | 136 +++++ cpukit/score/macros/rtems/score/isr.inl | 60 ++ cpukit/score/macros/rtems/score/mppkt.inl | 41 ++ cpukit/score/macros/rtems/score/object.inl | 146 +++++ cpukit/score/macros/rtems/score/objectmp.inl | 50 ++ cpukit/score/macros/rtems/score/priority.inl | 144 +++++ cpukit/score/macros/rtems/score/stack.inl | 50 ++ cpukit/score/macros/rtems/score/states.inl | 201 +++++++ cpukit/score/macros/rtems/score/sysstate.inl | 77 +++ cpukit/score/macros/rtems/score/thread.inl | 193 ++++++ cpukit/score/macros/rtems/score/threadmp.inl | 50 ++ cpukit/score/macros/rtems/score/tod.inl | 59 ++ cpukit/score/macros/rtems/score/tqdata.inl | 39 ++ cpukit/score/macros/rtems/score/userext.inl | 184 ++++++ cpukit/score/macros/rtems/score/watchdog.inl | 202 +++++++ cpukit/score/macros/rtems/score/wkspace.inl | 101 ++++ cpukit/score/src/chain.c | 202 +++++++ cpukit/score/src/coretod.c | 236 ++++++++ cpukit/score/src/heap.c | 478 +++++++++++++++ cpukit/score/src/mpci.c | 237 ++++++++ cpukit/score/src/object.c | 228 ++++++++ cpukit/score/src/objectmp.c | 250 ++++++++ cpukit/score/src/thread.c | 805 ++++++++++++++++++++++++++ cpukit/score/src/threadmp.c | 229 ++++++++ cpukit/score/src/threadq.c | 837 +++++++++++++++++++++++++++ cpukit/score/src/watchdog.c | 225 +++++++ cpukit/score/src/wkspace.c | 47 ++ 88 files changed, 16347 insertions(+) create mode 100644 cpukit/score/cpu/hppa1.1/cpu.c create mode 100644 cpukit/score/cpu/i386/asm.h create mode 100644 cpukit/score/cpu/i386/cpu.c create mode 100644 cpukit/score/cpu/i386/rtems/asm.h create mode 100644 cpukit/score/cpu/i960/asm.h create mode 100644 cpukit/score/cpu/i960/cpu.c create mode 100644 cpukit/score/cpu/m68k/asm.h create mode 100644 cpukit/score/cpu/m68k/cpu.c create mode 100644 cpukit/score/cpu/m68k/rtems/asm.h create mode 100644 cpukit/score/cpu/no_cpu/asm.h create mode 100644 cpukit/score/cpu/no_cpu/cpu.c create mode 100644 cpukit/score/cpu/no_cpu/cpu_asm.c create mode 100644 cpukit/score/cpu/no_cpu/rtems/asm.h create mode 100644 cpukit/score/cpu/unix/cpu.c create mode 100644 cpukit/score/include/rtems/debug.h create mode 100644 cpukit/score/include/rtems/score/address.h create mode 100644 cpukit/score/include/rtems/score/bitfield.h create mode 100644 cpukit/score/include/rtems/score/chain.h create mode 100644 cpukit/score/include/rtems/score/context.h create mode 100644 cpukit/score/include/rtems/score/copyrt.h create mode 100644 cpukit/score/include/rtems/score/heap.h create mode 100644 cpukit/score/include/rtems/score/isr.h create mode 100644 cpukit/score/include/rtems/score/mpci.h create mode 100644 cpukit/score/include/rtems/score/mppkt.h create mode 100644 cpukit/score/include/rtems/score/object.h create mode 100644 cpukit/score/include/rtems/score/objectmp.h create mode 100644 cpukit/score/include/rtems/score/priority.h create mode 100644 cpukit/score/include/rtems/score/stack.h create mode 100644 cpukit/score/include/rtems/score/states.h create mode 100644 cpukit/score/include/rtems/score/sysstate.h create mode 100644 cpukit/score/include/rtems/score/thread.h create mode 100644 cpukit/score/include/rtems/score/threadmp.h create mode 100644 cpukit/score/include/rtems/score/threadq.h create mode 100644 cpukit/score/include/rtems/score/tod.h create mode 100644 cpukit/score/include/rtems/score/tqdata.h create mode 100644 cpukit/score/include/rtems/score/userext.h create mode 100644 cpukit/score/include/rtems/score/watchdog.h create mode 100644 cpukit/score/include/rtems/score/wkspace.h create mode 100644 cpukit/score/include/rtems/system.h create mode 100644 cpukit/score/inline/rtems/score/address.inl create mode 100644 cpukit/score/inline/rtems/score/chain.inl create mode 100644 cpukit/score/inline/rtems/score/heap.inl create mode 100644 cpukit/score/inline/rtems/score/isr.inl create mode 100644 cpukit/score/inline/rtems/score/mppkt.inl create mode 100644 cpukit/score/inline/rtems/score/object.inl create mode 100644 cpukit/score/inline/rtems/score/objectmp.inl create mode 100644 cpukit/score/inline/rtems/score/priority.inl create mode 100644 cpukit/score/inline/rtems/score/stack.inl create mode 100644 cpukit/score/inline/rtems/score/states.inl create mode 100644 cpukit/score/inline/rtems/score/sysstate.inl create mode 100644 cpukit/score/inline/rtems/score/thread.inl create mode 100644 cpukit/score/inline/rtems/score/threadmp.inl create mode 100644 cpukit/score/inline/rtems/score/tod.inl create mode 100644 cpukit/score/inline/rtems/score/tqdata.inl create mode 100644 cpukit/score/inline/rtems/score/userext.inl create mode 100644 cpukit/score/inline/rtems/score/watchdog.inl create mode 100644 cpukit/score/inline/rtems/score/wkspace.inl create mode 100644 cpukit/score/macros/README create mode 100644 cpukit/score/macros/rtems/score/README create mode 100644 cpukit/score/macros/rtems/score/address.inl create mode 100644 cpukit/score/macros/rtems/score/chain.inl create mode 100644 cpukit/score/macros/rtems/score/heap.inl create mode 100644 cpukit/score/macros/rtems/score/isr.inl create mode 100644 cpukit/score/macros/rtems/score/mppkt.inl create mode 100644 cpukit/score/macros/rtems/score/object.inl create mode 100644 cpukit/score/macros/rtems/score/objectmp.inl create mode 100644 cpukit/score/macros/rtems/score/priority.inl create mode 100644 cpukit/score/macros/rtems/score/stack.inl create mode 100644 cpukit/score/macros/rtems/score/states.inl create mode 100644 cpukit/score/macros/rtems/score/sysstate.inl create mode 100644 cpukit/score/macros/rtems/score/thread.inl create mode 100644 cpukit/score/macros/rtems/score/threadmp.inl create mode 100644 cpukit/score/macros/rtems/score/tod.inl create mode 100644 cpukit/score/macros/rtems/score/tqdata.inl create mode 100644 cpukit/score/macros/rtems/score/userext.inl create mode 100644 cpukit/score/macros/rtems/score/watchdog.inl create mode 100644 cpukit/score/macros/rtems/score/wkspace.inl create mode 100644 cpukit/score/src/chain.c create mode 100644 cpukit/score/src/coretod.c create mode 100644 cpukit/score/src/heap.c create mode 100644 cpukit/score/src/mpci.c create mode 100644 cpukit/score/src/object.c create mode 100644 cpukit/score/src/objectmp.c create mode 100644 cpukit/score/src/thread.c create mode 100644 cpukit/score/src/threadmp.c create mode 100644 cpukit/score/src/threadq.c create mode 100644 cpukit/score/src/watchdog.c create mode 100644 cpukit/score/src/wkspace.c (limited to 'cpukit/score') diff --git a/cpukit/score/cpu/hppa1.1/cpu.c b/cpukit/score/cpu/hppa1.1/cpu.c new file mode 100644 index 0000000000..b69a172b4e --- /dev/null +++ b/cpukit/score/cpu/hppa1.1/cpu.c @@ -0,0 +1,313 @@ +/* + * HP PA-RISC Dependent Source + * + * COPYRIGHT (c) 1994 by Division Incorporated + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Division Incorporated not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * Division Incorporated makes no representations about the + * suitability of this software for any purpose. + * + * $Id$ + */ + +#include +#include +#include +#include +#include + +rtems_status_code hppa_external_interrupt_initialize(void); +void hppa_external_interrupt_enable(unsigned32); +void hppa_external_interrupt_disable(unsigned32); +void hppa_external_interrupt(unsigned32, CPU_Interrupt_frame *); + +/* + * Our interrupt handlers take a 2nd argument: + * a pointer to a CPU_Interrupt_frame + * So we use our own prototype instead of rtems_isr_entry + */ + +typedef rtems_isr ( *hppa_rtems_isr_entry )( + rtems_vector_number, + CPU_Interrupt_frame * + ); + + +/* + * who are we? cpu number + * Not used by executive proper, just kept (or not) as a convenience + * for libcpu and libbsp stuff that wants it. + * + * Defaults to 0. If the BSP doesn't like it, it can change it. + */ + +int cpu_number; /* from 0; cpu number in a multi cpu system */ + + +/* _CPU_Initialize + * + * This routine performs processor dependent initialization. + * + * INPUT PARAMETERS: + * cpu_table - CPU table to initialize + * thread_dispatch - address of disptaching routine + * + */ + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) /* ignored on this CPU */ +) +{ + register unsigned8 *fp_context; + unsigned32 iva; + unsigned32 iva_table; + int i; + + extern void IVA_Table(void); + + if ( cpu_table == NULL ) + rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED ); + + /* + * XXX; need to setup fpsr smarter perhaps + */ + + fp_context = (unsigned8*) &_CPU_Null_fp_context; + for (i=0 ; i= HPPA_INTERRUPT_EXTERNAL_BASE) + { + unsigned32 external_vector; + + external_vector = vector - HPPA_INTERRUPT_EXTERNAL_BASE; + if (new_handler) + hppa_external_interrupt_enable(external_vector); + else + /* XXX this can never happen due to _ISR_Is_valid_user_handler */ + hppa_external_interrupt_disable(external_vector); + } +} + + +/* + * Support for external and spurious interrupts on HPPA + * + * TODO: + * delete interrupt.c etc. + * Count interrupts + * make sure interrupts disabled properly + * should handler check again for more interrupts before exit? + * How to enable interrupts from an interrupt handler? + * Make sure there is an entry for everything in ISR_Vector_Table + */ + +#define DISMISS(mask) set_eirr(mask) +#define DISABLE(mask) set_eiem(get_eiem() & ~(mask)) +#define ENABLE(mask) set_eiem(get_eiem() | (mask)) +#define VECTOR_TO_MASK(v) (1 << (31 - (v))) + +/* + * Init the external interrupt scheme + * called by bsp_start() + */ + +rtems_status_code +hppa_external_interrupt_initialize(void) +{ + rtems_isr_entry ignore; + + /* mark them all unused */ + + DISABLE(~0); + DISMISS(~0); + + /* install the external interrupt handler */ + rtems_interrupt_catch((rtems_isr_entry) hppa_external_interrupt, + HPPA_INTERRUPT_EXTERNAL_INTERRUPT, &ignore) ; + + return RTEMS_SUCCESSFUL; +} + +/* + * Enable a specific external interrupt + */ + +void +hppa_external_interrupt_enable(unsigned32 v) +{ + unsigned32 isrlevel; + + _CPU_ISR_Disable(isrlevel); + ENABLE(VECTOR_TO_MASK(v)); + _CPU_ISR_Enable(isrlevel); +} + +/* + * Does not clear or otherwise affect any pending requests + */ + +void +hppa_external_interrupt_disable(unsigned32 v) +{ + unsigned32 isrlevel; + + _CPU_ISR_Disable(isrlevel); + DISABLE(VECTOR_TO_MASK(v)); + _CPU_ISR_Enable(isrlevel); +} + +void +hppa_external_interrupt_spurious_handler(unsigned32 vector, + CPU_Interrupt_frame *iframe) +{ +/* XXX should not be printing :) + printf("spurious external interrupt: %d at pc 0x%x; disabling\n", + vector, iframe->Interrupt.pcoqfront); +*/ + DISMISS(VECTOR_TO_MASK(vector)); + DISABLE(VECTOR_TO_MASK(vector)); +} + +void +hppa_external_interrupt_report_spurious(unsigned32 spurious, + CPU_Interrupt_frame *iframe) +{ + int v; + for (v=0; v < HPPA_EXTERNAL_INTERRUPTS; v++) + if (VECTOR_TO_MASK(v) & spurious) + hppa_external_interrupt_spurious_handler(v, iframe); + DISMISS(spurious); +} + + +/* + * External interrupt handler. + * This is installed as cpu interrupt handler for + * HPPA_INTERRUPT_EXTERNAL_INTERRUPT. It vectors out to + * specific external interrupt handlers. + */ + +void +hppa_external_interrupt(unsigned32 vector, + CPU_Interrupt_frame *iframe) +{ + unsigned32 mask; + unsigned32 *vp, *max_vp; + unsigned32 external_vector; + unsigned32 global_vector; + hppa_rtems_isr_entry handler; + + max_vp = &_CPU_Table.external_interrupt[_CPU_Table.external_interrupts]; + while ( (mask = (get_eirr() & get_eiem())) ) + { + for (vp = _CPU_Table.external_interrupt; (vp < max_vp) && mask; vp++) + { + unsigned32 m; + + external_vector = *vp; + global_vector = external_vector + HPPA_INTERRUPT_EXTERNAL_BASE; + m = VECTOR_TO_MASK(external_vector); + handler = (hppa_rtems_isr_entry) _ISR_Vector_table[global_vector]; + if ((m & mask) && handler) + { + DISMISS(m); + mask &= ~m; + (*handler)(global_vector, iframe); + } + } + + if (mask != 0) { + if ( _CPU_Table.spurious_handler ) + (*((hppa_rtems_isr_entry) _CPU_Table.spurious_handler))( + mask, + iframe + ); + else + hppa_external_interrupt_report_spurious(mask, iframe); + } + } +} + +/* + * Halt the system. + * Called by the _CPU_Fatal_halt macro + * + * XXX + * Later on, this will allow us to return to the prom. + * For now, we just ignore 'type_of_halt' + */ + +void +hppa_cpu_halt(unsigned32 type_of_halt, + unsigned32 the_error) +{ + unsigned32 isrlevel; + + _CPU_ISR_Disable(isrlevel); + + asm volatile( "copy %0,%%r1" : : "r" (the_error) ); + HPPA_ASM_BREAK(1, 0); +} diff --git a/cpukit/score/cpu/i386/asm.h b/cpukit/score/cpu/i386/asm.h new file mode 100644 index 0000000000..f123defcd9 --- /dev/null +++ b/cpukit/score/cpu/i386/asm.h @@ -0,0 +1,131 @@ +/* asm.h + * + * This include file attempts to address the problems + * caused by incompatible flavors of assemblers and + * toolsets. It primarily addresses variations in the + * use of leading underscores on symbols and the requirement + * that register names be preceded by a %. + * + * + * NOTE: The spacing in the use of these macros + * is critical to them working as advertised. + * + * COPYRIGHT: + * + * This file is based on similar code found in newlib available + * from ftp.cygnus.com. The file which was used had no copyright + * notice. This file is freely distributable as long as the source + * of the file is noted. This file is: + * + * COPYRIGHT (c) 1994. + * On-Line Applications Research Corporation (OAR). + * + * $Id$ + */ + +#ifndef __i386_ASM_h +#define __i386_ASM_h + +/* + * Indicate we are in an assembly file and get the basic CPU definitions. + */ + +#define ASM +#include + +/* + * Recent versions of GNU cpp define variables which indicate the + * need for underscores and percents. If not using GNU cpp or + * the version does not support this, then you will obviously + * have to define these as appropriate. + */ + +#ifndef __USER_LABEL_PREFIX__ +#define __USER_LABEL_PREFIX__ _ +#endif + +/* + * Looks like there is a bug in gcc 2.6.2 where this is not + * defined correctly when configured as i386-coff and + * i386-aout. + */ + +#undef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ % + +/* +#ifndef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ +#endif +*/ + +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ + +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +/* Use the right prefix for registers. */ + +#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) + +#define eax REG (eax) +#define ebx REG (ebx) +#define ecx REG (ecx) +#define edx REG (edx) +#define esi REG (esi) +#define edi REG (edi) +#define esp REG (esp) +#define ebp REG (ebp) + +#define ax REG (ax) +#define bx REG (bx) +#define cx REG (cx) +#define dx REG (dx) +#define si REG (si) +#define di REG (di) +#define sp REG (sp) +#define bp REG (bp) + +#define ah REG (ah) +#define al REG (al) + +#define cs REG (cs) +#define ds REG (ds) +#define es REG (es) +#define fs REG (fs) +#define gs REG (gs) +#define ss REG (ss) + +/* + * Define macros to handle section beginning and ends. + */ + + +#define BEGIN_CODE_DCL .text +#define END_CODE_DCL +#define BEGIN_DATA_DCL .data +#define END_DATA_DCL +#define BEGIN_CODE .text +#define END_CODE +#define BEGIN_DATA +#define END_DATA +#define BEGIN_BSS +#define END_BSS +#define END + +/* + * Following must be tailor for a particular flavor of the C compiler. + * They may need to put underscores in front of the symbols. + */ + +#define PUBLIC(sym) .globl SYM (sym) +#define EXTERN(sym) .globl SYM (sym) + +#endif +/* end of include file */ + + diff --git a/cpukit/score/cpu/i386/cpu.c b/cpukit/score/cpu/i386/cpu.c new file mode 100644 index 0000000000..05a836f7e3 --- /dev/null +++ b/cpukit/score/cpu/i386/cpu.c @@ -0,0 +1,121 @@ +/* + * Intel i386 Dependent Source + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include + +/* _CPU_Initialize + * + * This routine performs processor dependent initialization. + * + * INPUT PARAMETERS: + * cpu_table - CPU table to initialize + * thread_dispatch - address of disptaching routine + */ + + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) /* ignored on this CPU */ +) +{ + register unsigned16 fp_status asm ("ax"); + register unsigned8 *fp_context; + + if ( cpu_table == NULL ) + rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED ); + + _CPU_Table = *cpu_table; + + /* + * The following code saves a NULL i387 context which is given + * to each task at start and restart time. The following code + * is based upon that provided in the i386 Programmer's + * Manual and should work on any coprocessor greater than + * the i80287. + * + * NOTE: The NO RTEMS_WAIT form of the coprocessor instructions + * MUST be used in case there is not a coprocessor + * to wait for. + */ + + fp_status = 0xa5a5; + asm volatile( "fninit" ); + asm volatile( "fnstsw %0" : "=a" (fp_status) : "0" (fp_status) ); + + if ( fp_status == 0 ) { + + fp_context = _CPU_Null_fp_context; + + asm volatile( "fsave (%0)" : "=r" (fp_context) + : "0" (fp_context) + ); + } +} + +/* _CPU_ISR_install_vector + * + * This kernel routine installs the RTEMS handler for the + * specified vector. + * + * Input parameters: + * vector - interrupt vector number + * old_handler - former ISR for this vector number + * new_handler - replacement ISR for this vector number + * + * Output parameters: NONE + * + */ + +void _ISR_Handler_0(), _ISR_Handler_1(); + +#define PER_ISR_ENTRY \ + (((unsigned32) _ISR_Handler_1 - (unsigned32) _ISR_Handler_0)) + +#define _Interrupt_Handler_entry( _vector ) \ + (((unsigned32)_ISR_Handler_0) + ((_vector) * PER_ISR_ENTRY)) + +void _CPU_ISR_install_vector( + unsigned32 vector, + proc_ptr new_handler, + proc_ptr *old_handler +) +{ + i386_IDT_slot idt; + unsigned32 unique_handler; + + /* calculate the unique entry point for this vector */ + unique_handler = _Interrupt_Handler_entry( vector ); + + /* build the IDT entry */ + idt.offset_0_15 = ((unsigned32) unique_handler) & 0xffff; + idt.segment_selector = i386_get_cs(); + idt.reserved = 0x00; + idt.p_dpl = 0x8e; /* present, ISR */ + idt.offset_16_31 = ((unsigned32) unique_handler) >> 16; + + /* install the IDT entry */ + i386_Install_idt( + (unsigned32) &idt, + _CPU_Table.interrupt_table_segment, + (unsigned32) _CPU_Table.interrupt_table_offset + (8 * vector) + ); + + /* "portable" part */ + *old_handler = _ISR_Vector_table[ vector ]; + _ISR_Vector_table[ vector ] = new_handler; +} diff --git a/cpukit/score/cpu/i386/rtems/asm.h b/cpukit/score/cpu/i386/rtems/asm.h new file mode 100644 index 0000000000..f123defcd9 --- /dev/null +++ b/cpukit/score/cpu/i386/rtems/asm.h @@ -0,0 +1,131 @@ +/* asm.h + * + * This include file attempts to address the problems + * caused by incompatible flavors of assemblers and + * toolsets. It primarily addresses variations in the + * use of leading underscores on symbols and the requirement + * that register names be preceded by a %. + * + * + * NOTE: The spacing in the use of these macros + * is critical to them working as advertised. + * + * COPYRIGHT: + * + * This file is based on similar code found in newlib available + * from ftp.cygnus.com. The file which was used had no copyright + * notice. This file is freely distributable as long as the source + * of the file is noted. This file is: + * + * COPYRIGHT (c) 1994. + * On-Line Applications Research Corporation (OAR). + * + * $Id$ + */ + +#ifndef __i386_ASM_h +#define __i386_ASM_h + +/* + * Indicate we are in an assembly file and get the basic CPU definitions. + */ + +#define ASM +#include + +/* + * Recent versions of GNU cpp define variables which indicate the + * need for underscores and percents. If not using GNU cpp or + * the version does not support this, then you will obviously + * have to define these as appropriate. + */ + +#ifndef __USER_LABEL_PREFIX__ +#define __USER_LABEL_PREFIX__ _ +#endif + +/* + * Looks like there is a bug in gcc 2.6.2 where this is not + * defined correctly when configured as i386-coff and + * i386-aout. + */ + +#undef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ % + +/* +#ifndef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ +#endif +*/ + +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ + +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +/* Use the right prefix for registers. */ + +#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) + +#define eax REG (eax) +#define ebx REG (ebx) +#define ecx REG (ecx) +#define edx REG (edx) +#define esi REG (esi) +#define edi REG (edi) +#define esp REG (esp) +#define ebp REG (ebp) + +#define ax REG (ax) +#define bx REG (bx) +#define cx REG (cx) +#define dx REG (dx) +#define si REG (si) +#define di REG (di) +#define sp REG (sp) +#define bp REG (bp) + +#define ah REG (ah) +#define al REG (al) + +#define cs REG (cs) +#define ds REG (ds) +#define es REG (es) +#define fs REG (fs) +#define gs REG (gs) +#define ss REG (ss) + +/* + * Define macros to handle section beginning and ends. + */ + + +#define BEGIN_CODE_DCL .text +#define END_CODE_DCL +#define BEGIN_DATA_DCL .data +#define END_DATA_DCL +#define BEGIN_CODE .text +#define END_CODE +#define BEGIN_DATA +#define END_DATA +#define BEGIN_BSS +#define END_BSS +#define END + +/* + * Following must be tailor for a particular flavor of the C compiler. + * They may need to put underscores in front of the symbols. + */ + +#define PUBLIC(sym) .globl SYM (sym) +#define EXTERN(sym) .globl SYM (sym) + +#endif +/* end of include file */ + + diff --git a/cpukit/score/cpu/i960/asm.h b/cpukit/score/cpu/i960/asm.h new file mode 100644 index 0000000000..1c40601473 --- /dev/null +++ b/cpukit/score/cpu/i960/asm.h @@ -0,0 +1,107 @@ +/* asm.h + * + * This include file attempts to address the problems + * caused by incompatible flavors of assemblers and + * toolsets. It primarily addresses variations in the + * use of leading underscores on symbols and the requirement + * that register names be preceded by a %. + * + * + * NOTE: The spacing in the use of these macros + * is critical to them working as advertised. + * + * COPYRIGHT: + * + * This file is based on similar code found in newlib available + * from ftp.cygnus.com. The file which was used had no copyright + * notice. This file is freely distributable as long as the source + * of the file is noted. This file is: + * + * COPYRIGHT (c) 1994. + * On-Line Applications Research Corporation (OAR). + * + * $Id$ + */ + +#ifndef __i960_ASM_h +#define __i960_ASM_h + +/* + * Indicate we are in an assembly file and get the basic CPU definitions. + */ + +#define ASM +#include + +/* + * Recent versions of GNU cpp define variables which indicate the + * need for underscores and percents. If not using GNU cpp or + * the version does not support this, then you will obviously + * have to define these as appropriate. + */ + +#ifndef __USER_LABEL_PREFIX__ +#define __USER_LABEL_PREFIX__ _ +#endif + +#ifndef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ +#endif + +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ + +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +/* Use the right prefix for registers. */ + +#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) + +#define g0 REG (g0) +#define g1 REG (g1) +#define g2 REG (g2) +#define g3 REG (g3) +#define g4 REG (g4) +#define g5 REG (g5) +#define g6 REG (g6) +#define g7 REG (g7) +#define g8 REG (g8) +#define g9 REG (g9) +#define g10 REG (g10) +#define g11 REG (g11) +#define g12 REG (g12) +#define g13 REG (g13) +#define g14 REG (g14) +#define g15 REG (g15) + +/* + * Define macros to handle section beginning and ends. + */ + + +#define BEGIN_CODE_DCL .text +#define END_CODE_DCL +#define BEGIN_DATA_DCL .data +#define END_DATA_DCL +#define BEGIN_CODE .text +#define END_CODE +#define BEGIN_DATA +#define END_DATA +#define BEGIN_BSS +#define END_BSS +#define END + +/* + * Following must be tailor for a particular flavor of the C compiler. + * They may need to put underscores in front of the symbols. + */ + +#define PUBLIC(sym) .globl SYM (sym) +#define EXTERN(sym) .globl SYM (sym) + +#endif +/* end of include file */ diff --git a/cpukit/score/cpu/i960/cpu.c b/cpukit/score/cpu/i960/cpu.c new file mode 100644 index 0000000000..68ecb0525c --- /dev/null +++ b/cpukit/score/cpu/i960/cpu.c @@ -0,0 +1,124 @@ +/* + * Intel i960CA Dependent Source + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#if defined(__i960CA__) || defined(__i960_CA__) || defined(__i960CA) +#else +#warning "*** ENTIRE FILE IMPLEMENTED & TESTED FOR CA ONLY ***" +#warning "*** THIS FILE WILL NOT COMPILE ON ANOTHER FAMILY MEMBER ***" +#endif + +#include +#include +#include + +/* _CPU_Initialize + * + * This routine performs processor dependent initialization. + * + * INPUT PARAMETERS: + * cpu_table - CPU table to initialize + * thread_dispatch - address of disptaching routine + * + * OUTPUT PARAMETERS: NONE + */ + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) /* ignored on this CPU */ +) +{ + + if ( cpu_table == NULL ) + rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED ); + + _CPU_Table = *cpu_table; + +} + +/* _CPU__ISR_Install_vector + * + * Install the RTEMS vector wrapper in the CPU's interrupt table. + * + * Input parameters: + * vector - interrupt vector number + * old_handler - former ISR for this vector number + * new_handler - replacement ISR for this vector number + * + * Output parameters: NONE + * + */ + +#define _Is_vector_caching_enabled( _prcb ) \ + ((_prcb)->control_tbl->icon & 0x2000) + +void _CPU_ISR_install_vector( + unsigned32 vector, + proc_ptr new_handler, + proc_ptr *old_handler +) +{ + i960ca_PRCB *prcb = _CPU_Table.Prcb; + proc_ptr *cached_intr_tbl = NULL; + +/* The i80960CA does not support vectors 0-7. The first 9 entries + * in the Interrupt Table are used to manage pending interrupts. + * Thus vector 8, the first valid vector number, is actually in + * slot 9 in the table. + */ + + *old_handler = _ISR_Vector_table[ vector ]; + + _ISR_Vector_table[ vector ] = new_handler; + + prcb->intr_tbl[ vector + 1 ] = _ISR_Handler; + if ( _Is_vector_caching_enabled( prcb ) ) + if ( (vector & 0xf) == 0x2 ) /* cacheable? */ + cached_intr_tbl[ vector >> 4 ] = _ISR_Handler; +} + +/*PAGE + * + * _CPU_Install_interrupt_stack + */ + +#define soft_reset( prcb ) \ + { register i960ca_PRCB *_prcb = (prcb); \ + register unsigned32 *_next=0; \ + register unsigned32 _cmd = 0x30000; \ + asm volatile( "lda next,%1; \ + sysctl %0,%1,%2; \ + next: mov g0,g0" \ + : "=d" (_cmd), "=d" (_next), "=d" (_prcb) \ + : "0" (_cmd), "1" (_next), "2" (_prcb) ); \ + } + +void _CPU_Install_interrupt_stack( void ) +{ + i960ca_PRCB *prcb = _CPU_Table.Prcb; + unsigned32 level; + + /* + * Set the Interrupt Stack in the PRCB and force a reload of it. + * Interrupts are disabled for safety. + */ + + _CPU_ISR_Disable( level ); + + prcb->intr_stack = _CPU_Interrupt_stack_low; + + soft_reset( prcb ); + + _CPU_ISR_Enable( level ); +} diff --git a/cpukit/score/cpu/m68k/asm.h b/cpukit/score/cpu/m68k/asm.h new file mode 100644 index 0000000000..068c58058c --- /dev/null +++ b/cpukit/score/cpu/m68k/asm.h @@ -0,0 +1,127 @@ +/* asm.h + * + * This include file attempts to address the problems + * caused by incompatible flavors of assemblers and + * toolsets. It primarily addresses variations in the + * use of leading underscores on symbols and the requirement + * that register names be preceded by a %. + * + * + * NOTE: The spacing in the use of these macros + * is critical to them working as advertised. + * + * COPYRIGHT: + * + * This file is based on similar code found in newlib available + * from ftp.cygnus.com. The file which was used had no copyright + * notice. This file is freely distributable as long as the source + * of the file is noted. This file is: + * + * COPYRIGHT (c) 1994. + * On-Line Applications Research Corporation (OAR). + * + * $Id$ + */ + +#ifndef __M68k_ASM_h +#define __M68k_ASM_h + +/* + * Indicate we are in an assembly file and get the basic CPU definitions. + */ + +#define ASM +#include + +/* + * Recent versions of GNU cpp define variables which indicate the + * need for underscores and percents. If not using GNU cpp or + * the version does not support this, then you will obviously + * have to define these as appropriate. + */ + +#ifndef __USER_LABEL_PREFIX__ +#define __USER_LABEL_PREFIX__ _ +#endif + +#ifndef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ +#endif + +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ + +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +/* Use the right prefix for registers. */ + +#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) + +#define d0 REG (d0) +#define d1 REG (d1) +#define d2 REG (d2) +#define d3 REG (d3) +#define d4 REG (d4) +#define d5 REG (d5) +#define d6 REG (d6) +#define d7 REG (d7) +#define a0 REG (a0) +#define a1 REG (a1) +#define a2 REG (a2) +#define a3 REG (a3) +#define a4 REG (a4) +#define a5 REG (a5) +#define a6 REG (a6) +#define a7 REG (a7) + +#define msp REG (msp) +#define usp REG (usp) +#define isp REG (isp) +#define sr REG (sr) + +#define fp0 REG (fp0) +#define fp1 REG (fp1) +#define fp2 REG (fp2) +#define fp3 REG (fp3) +#define fp4 REG (fp4) +#define fp5 REG (fp5) +#define fp6 REG (fp6) +#define fp7 REG (fp7) + +#define fpc REG (fpc) +#define fpi REG (fpi) +#define fps REG (fps) + +/* + * Define macros to handle section beginning and ends. + */ + + +#define BEGIN_CODE_DCL .text +#define END_CODE_DCL +#define BEGIN_DATA_DCL .data +#define END_DATA_DCL +#define BEGIN_CODE .text +#define END_CODE +#define BEGIN_DATA +#define END_DATA +#define BEGIN_BSS +#define END_BSS +#define END + +/* + * Following must be tailor for a particular flavor of the C compiler. + * They may need to put underscores in front of the symbols. + */ + +#define PUBLIC(sym) .globl SYM (sym) +#define EXTERN(sym) .globl SYM (sym) + +#endif +/* end of include file */ + + diff --git a/cpukit/score/cpu/m68k/cpu.c b/cpukit/score/cpu/m68k/cpu.c new file mode 100644 index 0000000000..45484da1f4 --- /dev/null +++ b/cpukit/score/cpu/m68k/cpu.c @@ -0,0 +1,97 @@ +/* + * Motorola MC68020 Dependent Source + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +/* _CPU_Initialize + * + * This routine performs processor dependent initialization. + * + * INPUT PARAMETERS: + * cpu_table - CPU table to initialize + * thread_dispatch - entry pointer to thread dispatcher + * + * OUTPUT PARAMETERS: NONE + */ + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) /* ignored on this CPU */ +) +{ + + if ( cpu_table == NULL ) + rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED ); + + _CPU_Table = *cpu_table; + +} + +/* _CPU_ISR_install_vector + * + * This kernel routine installs the RTEMS handler for the + * specified vector. + * + * Input parameters: + * vector - interrupt vector number + * new_handler - replacement ISR for this vector number + * old_handler - former ISR for this vector number + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +void _CPU_ISR_install_vector( + unsigned32 vector, + proc_ptr new_handler, + proc_ptr *old_handler +) +{ + proc_ptr *interrupt_table = NULL; + + m68k_get_vbr( interrupt_table ); + + *old_handler = _ISR_Vector_table[ vector ]; + + _ISR_Vector_table[ vector ] = new_handler; + interrupt_table[ vector ] = _ISR_Handler; +} + + +/*PAGE + * + * _CPU_Install_interrupt_stack + */ + +void _CPU_Install_interrupt_stack( void ) +{ +#if ( M68K_HAS_SEPARATE_STACKS == 1 ) + void *isp = _CPU_Interrupt_stack_high; + + asm volatile ( "movec %0,%%isp" : "=r" (isp) : "0" (isp) ); +#else +#warning "FIX ME... HOW DO I INSTALL THE INTERRUPT STACK!!!" +#endif +} + diff --git a/cpukit/score/cpu/m68k/rtems/asm.h b/cpukit/score/cpu/m68k/rtems/asm.h new file mode 100644 index 0000000000..068c58058c --- /dev/null +++ b/cpukit/score/cpu/m68k/rtems/asm.h @@ -0,0 +1,127 @@ +/* asm.h + * + * This include file attempts to address the problems + * caused by incompatible flavors of assemblers and + * toolsets. It primarily addresses variations in the + * use of leading underscores on symbols and the requirement + * that register names be preceded by a %. + * + * + * NOTE: The spacing in the use of these macros + * is critical to them working as advertised. + * + * COPYRIGHT: + * + * This file is based on similar code found in newlib available + * from ftp.cygnus.com. The file which was used had no copyright + * notice. This file is freely distributable as long as the source + * of the file is noted. This file is: + * + * COPYRIGHT (c) 1994. + * On-Line Applications Research Corporation (OAR). + * + * $Id$ + */ + +#ifndef __M68k_ASM_h +#define __M68k_ASM_h + +/* + * Indicate we are in an assembly file and get the basic CPU definitions. + */ + +#define ASM +#include + +/* + * Recent versions of GNU cpp define variables which indicate the + * need for underscores and percents. If not using GNU cpp or + * the version does not support this, then you will obviously + * have to define these as appropriate. + */ + +#ifndef __USER_LABEL_PREFIX__ +#define __USER_LABEL_PREFIX__ _ +#endif + +#ifndef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ +#endif + +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ + +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +/* Use the right prefix for registers. */ + +#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) + +#define d0 REG (d0) +#define d1 REG (d1) +#define d2 REG (d2) +#define d3 REG (d3) +#define d4 REG (d4) +#define d5 REG (d5) +#define d6 REG (d6) +#define d7 REG (d7) +#define a0 REG (a0) +#define a1 REG (a1) +#define a2 REG (a2) +#define a3 REG (a3) +#define a4 REG (a4) +#define a5 REG (a5) +#define a6 REG (a6) +#define a7 REG (a7) + +#define msp REG (msp) +#define usp REG (usp) +#define isp REG (isp) +#define sr REG (sr) + +#define fp0 REG (fp0) +#define fp1 REG (fp1) +#define fp2 REG (fp2) +#define fp3 REG (fp3) +#define fp4 REG (fp4) +#define fp5 REG (fp5) +#define fp6 REG (fp6) +#define fp7 REG (fp7) + +#define fpc REG (fpc) +#define fpi REG (fpi) +#define fps REG (fps) + +/* + * Define macros to handle section beginning and ends. + */ + + +#define BEGIN_CODE_DCL .text +#define END_CODE_DCL +#define BEGIN_DATA_DCL .data +#define END_DATA_DCL +#define BEGIN_CODE .text +#define END_CODE +#define BEGIN_DATA +#define END_DATA +#define BEGIN_BSS +#define END_BSS +#define END + +/* + * Following must be tailor for a particular flavor of the C compiler. + * They may need to put underscores in front of the symbols. + */ + +#define PUBLIC(sym) .globl SYM (sym) +#define EXTERN(sym) .globl SYM (sym) + +#endif +/* end of include file */ + + diff --git a/cpukit/score/cpu/no_cpu/asm.h b/cpukit/score/cpu/no_cpu/asm.h new file mode 100644 index 0000000000..69b1f0f825 --- /dev/null +++ b/cpukit/score/cpu/no_cpu/asm.h @@ -0,0 +1,98 @@ +/* asm.h + * + * This include file attempts to address the problems + * caused by incompatible flavors of assemblers and + * toolsets. It primarily addresses variations in the + * use of leading underscores on symbols and the requirement + * that register names be preceded by a %. + * + * + * NOTE: The spacing in the use of these macros + * is critical to them working as advertised. + * + * COPYRIGHT: + * + * This file is based on similar code found in newlib available + * from ftp.cygnus.com. The file which was used had no copyright + * notice. This file is freely distributable as long as the source + * of the file is noted. This file is: + * + * COPYRIGHT (c) 1994. + * On-Line Applications Research Corporation (OAR). + * + * $Id$ + */ + +#ifndef __NO_CPU_ASM_h +#define __NO_CPU_ASM_h + +/* + * Indicate we are in an assembly file and get the basic CPU definitions. + */ + +#define ASM +#include + +/* + * Recent versions of GNU cpp define variables which indicate the + * need for underscores and percents. If not using GNU cpp or + * the version does not support this, then you will obviously + * have to define these as appropriate. + */ + +#ifndef __USER_LABEL_PREFIX__ +#define __USER_LABEL_PREFIX__ _ +#endif + +#ifndef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ +#endif + +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ + +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +/* Use the right prefix for registers. */ + +#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) + +/* + * define macros for all of the registers on this CPU + * + * EXAMPLE: #define d0 REG (d0) + */ + +/* + * Define macros to handle section beginning and ends. + */ + + +#define BEGIN_CODE_DCL .text +#define END_CODE_DCL +#define BEGIN_DATA_DCL .data +#define END_DATA_DCL +#define BEGIN_CODE .text +#define END_CODE +#define BEGIN_DATA +#define END_DATA +#define BEGIN_BSS +#define END_BSS +#define END + +/* + * Following must be tailor for a particular flavor of the C compiler. + * They may need to put underscores in front of the symbols. + */ + +#define PUBLIC(sym) .globl SYM (sym) +#define EXTERN(sym) .globl SYM (sym) + +#endif +/* end of include file */ + + diff --git a/cpukit/score/cpu/no_cpu/cpu.c b/cpukit/score/cpu/no_cpu/cpu.c new file mode 100644 index 0000000000..f09d935c2d --- /dev/null +++ b/cpukit/score/cpu/no_cpu/cpu.c @@ -0,0 +1,132 @@ +/* + * XXX CPU Dependent Source + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include + +/* _CPU_Initialize + * + * This routine performs processor dependent initialization. + * + * INPUT PARAMETERS: + * cpu_table - CPU table to initialize + * thread_dispatch - address of disptaching routine + */ + + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) /* ignored on this CPU */ +) +{ + if ( cpu_table == NULL ) + rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED ); + + /* + * The thread_dispatch argument is the address of the entry point + * for the routine called at the end of an ISR once it has been + * decided a context switch is necessary. On some compilation + * systems it is difficult to call a high-level language routine + * from assembly. This allows us to trick these systems. + * + * If you encounter this problem save the entry point in a CPU + * dependent variable. + */ + + _CPU_Thread_dispatch_pointer = thread_dispatch; + + /* + * XXX; If there is not an easy way to initialize the FP context + * during Context_Initialize, then it is usually easier to + * save an "uninitialized" FP context here and copy it to + * the task's during Context_Initialize. + */ + + /* XXX: FP context initialization support */ + + _CPU_Table = *cpu_table; +} + +/* _CPU_ISR_install_vector + * + * This kernel routine installs the RTEMS handler for the + * specified vector. + * + * Input parameters: + * vector - interrupt vector number + * old_handler - former ISR for this vector number + * new_handler - replacement ISR for this vector number + * + * Output parameters: NONE + * + */ + + +void _CPU_ISR_install_vector( + unsigned32 vector, + proc_ptr new_handler, + proc_ptr *old_handler +) +{ + *old_handler = _ISR_Vector_table[ vector ]; + + /* + * If the interrupt vector table is a table of pointer to isr entry + * points, then we need to install the appropriate RTEMS interrupt + * handler for this vector number. + */ + + /* + * We put the actual user ISR address in '_ISR_vector_table'. This will + * be used by the _ISR_Handler so the user gets control. + */ + + _ISR_Vector_table[ vector ] = new_handler; +} + +/*PAGE + * + * _CPU_Install_interrupt_stack + */ + +void _CPU_Install_interrupt_stack( void ) +{ +} + +/*PAGE + * + * _CPU_Internal_threads_Idle_thread_body + * + * NOTES: + * + * 1. This is the same as the regular CPU independent algorithm. + * + * 2. If you implement this using a "halt", "idle", or "shutdown" + * instruction, then don't forget to put it in an infinite loop. + * + * 3. Be warned. Some processors with onboard DMA have been known + * to stop the DMA if the CPU were put in IDLE mode. This might + * also be a problem with other on-chip peripherals. So use this + * hook with caution. + */ + +void _CPU_Internal_threads_Idle_thread_body( void ) +{ + + for( ; ; ) + /* insert your "halt" instruction here */ ; +} diff --git a/cpukit/score/cpu/no_cpu/cpu_asm.c b/cpukit/score/cpu/no_cpu/cpu_asm.c new file mode 100644 index 0000000000..26246a93c2 --- /dev/null +++ b/cpukit/score/cpu/no_cpu/cpu_asm.c @@ -0,0 +1,152 @@ +/* cpu_asm.c ===> cpu_asm.S or cpu_asm.s + * + * This file contains the basic algorithms for all assembly code used + * in an specific CPU port of RTEMS. These algorithms must be implemented + * in assembly language + * + * NOTE: This is supposed to be a .S or .s file NOT a C file. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +/* + * This is supposed to be an assembly file. This means that system.h + * and cpu.h should not be included in a "real" cpu_asm file. An + * implementation in assembly should include "cpu_asm.h> + */ + +#include +#include +/* #include "cpu_asm.h> */ + +/* + * _CPU_Context_save_fp_context + * + * This routine is responsible for saving the FP context + * at *fp_context_ptr. If the point to load the FP context + * from is changed then the pointer is modified by this routine. + * + * Sometimes a macro implementation of this is in cpu.h which dereferences + * the ** and a similarly named routine in this file is passed something + * like a (Context_Control_fp *). The general rule on making this decision + * is to avoid writing assembly language. + */ + +void _CPU_Context_save_fp( + void **fp_context_ptr +) +{ +} + +/* + * _CPU_Context_restore_fp_context + * + * This routine is responsible for restoring the FP context + * at *fp_context_ptr. If the point to load the FP context + * from is changed then the pointer is modified by this routine. + * + * Sometimes a macro implementation of this is in cpu.h which dereferences + * the ** and a similarly named routine in this file is passed something + * like a (Context_Control_fp *). The general rule on making this decision + * is to avoid writing assembly language. + */ + +void _CPU_Context_restore_fp( + void **fp_context_ptr +) +{ +} + +/* _CPU_Context_switch + * + * This routine performs a normal non-FP context switch. + */ + +void _CPU_Context_switch( + Context_Control *run, + Context_Control *heir +) +{ +} + +/* + * _CPU_Context_restore + * + * This routine is generallu used only to restart self in an + * efficient manner. It may simply be a label in _CPU_Context_switch. + * + * NOTE: May be unnecessary to reload some registers. + */ + +void _CPU_Context_restore( + Context_Control *new_context +) +{ +} + +/* void __ISR_Handler() + * + * This routine provides the RTEMS interrupt management. + * + */ + +void _ISR_Handler() +{ + /* + * This discussion ignores a lot of the ugly details in a real + * implementation such as saving enough registers/state to be + * able to do something real. Keep in mind that the goal is + * to invoke a user's ISR handler which is written in C and + * uses a certain set of registers. + * + * Also note that the exact order is to a large extent flexible. + * Hardware will dictate a sequence for a certain subset of + * _ISR_Handler while requirements for setting + */ + + /* + * At entry to "common" _ISR_Handler, the vector number must be + * available. On some CPUs the hardware puts either the vector + * number or the offset into the vector table for this ISR in a + * known place. If the hardware does not give us this information, + * then the assembly portion of RTEMS for this port will contain + * a set of distinct interrupt entry points which somehow place + * the vector number in a known place (which is safe if another + * interrupt nests this one) and branches to _ISR_Handler. + * + * save some or all context on stack + * may need to save some special interrupt information for exit + * + * #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE ) + * if ( _ISR_Nest_level == 0 ) + * switch to software interrupt stack + * #endif + * + * _ISR_Nest_level++; + * + * _Thread_Dispatch_disable_level++; + * + * (*_ISR_Vector_table[ vector ])( vector ); + * + * if ( --__ISR_Nest_level == 0 ) { + * if ( _Context_Switch_necessary || _ISR_Signals_to_thread_executing ) + * call _Thread_Dispatch() or prepare to return to _ISR_Dispatch + * #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE ) + * restore stack + * #endif + * } + * + * prepare to get out of interrupt + * return from interrupt + * + */ +} + diff --git a/cpukit/score/cpu/no_cpu/rtems/asm.h b/cpukit/score/cpu/no_cpu/rtems/asm.h new file mode 100644 index 0000000000..69b1f0f825 --- /dev/null +++ b/cpukit/score/cpu/no_cpu/rtems/asm.h @@ -0,0 +1,98 @@ +/* asm.h + * + * This include file attempts to address the problems + * caused by incompatible flavors of assemblers and + * toolsets. It primarily addresses variations in the + * use of leading underscores on symbols and the requirement + * that register names be preceded by a %. + * + * + * NOTE: The spacing in the use of these macros + * is critical to them working as advertised. + * + * COPYRIGHT: + * + * This file is based on similar code found in newlib available + * from ftp.cygnus.com. The file which was used had no copyright + * notice. This file is freely distributable as long as the source + * of the file is noted. This file is: + * + * COPYRIGHT (c) 1994. + * On-Line Applications Research Corporation (OAR). + * + * $Id$ + */ + +#ifndef __NO_CPU_ASM_h +#define __NO_CPU_ASM_h + +/* + * Indicate we are in an assembly file and get the basic CPU definitions. + */ + +#define ASM +#include + +/* + * Recent versions of GNU cpp define variables which indicate the + * need for underscores and percents. If not using GNU cpp or + * the version does not support this, then you will obviously + * have to define these as appropriate. + */ + +#ifndef __USER_LABEL_PREFIX__ +#define __USER_LABEL_PREFIX__ _ +#endif + +#ifndef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ +#endif + +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ + +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +/* Use the right prefix for registers. */ + +#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) + +/* + * define macros for all of the registers on this CPU + * + * EXAMPLE: #define d0 REG (d0) + */ + +/* + * Define macros to handle section beginning and ends. + */ + + +#define BEGIN_CODE_DCL .text +#define END_CODE_DCL +#define BEGIN_DATA_DCL .data +#define END_DATA_DCL +#define BEGIN_CODE .text +#define END_CODE +#define BEGIN_DATA +#define END_DATA +#define BEGIN_BSS +#define END_BSS +#define END + +/* + * Following must be tailor for a particular flavor of the C compiler. + * They may need to put underscores in front of the symbols. + */ + +#define PUBLIC(sym) .globl SYM (sym) +#define EXTERN(sym) .globl SYM (sym) + +#endif +/* end of include file */ + + diff --git a/cpukit/score/cpu/unix/cpu.c b/cpukit/score/cpu/unix/cpu.c new file mode 100644 index 0000000000..ed94953d58 --- /dev/null +++ b/cpukit/score/cpu/unix/cpu.c @@ -0,0 +1,529 @@ +/* + * HP PA-RISC CPU Dependent Source + * + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Division Incorporated not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * Division Incorporated makes no representations about the + * suitability of this software for any purpose. + * + * $Id$ + */ + +#include +#include +#include +#include +/* + * In order to get the types and prototypes used in this file under + * Solaris 2.3, it is necessary to pull the following magic. + */ + +#if defined(solaris) +#warning "Ignore the undefining __STDC__ warning" +#undef __STDC__ +#define __STDC__ 0 +#undef _POSIX_C_SOURCE +#endif + +#include +#include +#include +#include +#include +#include + +extern void set_vector(proc_ptr, int, int); +extern void _Thread_Dispatch(void); + +extern unsigned32 _Thread_Dispatch_disable_level; +extern unsigned32 _SYSTEM_ID; +extern boolean _Context_Switch_necessary; + + +rtems_status_code signal_initialize(void); +void Stray_signal(int); +void signal_enable(unsigned32); +void signal_disable(unsigned32); +void interrupt_handler(); + +sigset_t UNIX_SIGNAL_MASK; +jmp_buf default_context; + +/* + * Which cpu are we? Used by libcpu and libbsp. + */ + +int cpu_number; + +/* _CPU_Initialize + * + * This routine performs processor dependent initialization. + * + * INPUT PARAMETERS: + * cpu_table - CPU table to initialize + * thread_dispatch - address of disptaching routine + */ + + +void _CPU_Initialize( + rtems_cpu_table *cpu_table, + void (*thread_dispatch) /* ignored on this CPU */ +) +{ + unsigned32 i; + + if ( cpu_table == NULL ) + rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED ); + + /* + * The thread_dispatch argument is the address of the entry point + * for the routine called at the end of an ISR once it has been + * decided a context switch is necessary. On some compilation + * systems it is difficult to call a high-level language routine + * from assembly. This allows us to trick these systems. + * + * If you encounter this problem save the entry point in a CPU + * dependent variable. + */ + + _CPU_Thread_dispatch_pointer = thread_dispatch; + + /* + * XXX; If there is not an easy way to initialize the FP context + * during Context_Initialize, then it is usually easier to + * save an "uninitialized" FP context here and copy it to + * the task's during Context_Initialize. + */ + + /* XXX: FP context initialization support */ + + _CPU_Table = *cpu_table; + +#if defined(hppa1_1) && defined(RTEMS_UNIXLIB) + /* + * HACK - set the _SYSTEM_ID to 0x20c so that setjmp/longjmp + * will handle the full 32 floating point registers. + * + * NOTE: Is this a bug in HPUX9? + */ + + _SYSTEM_ID = 0x20c; +#endif + + /* + * get default values to use in _CPU_Context_Initialize() + */ + + setjmp(default_context); + + /* + * Block all the signals except SIGTRAP for the debugger + * and SIGABRT for fatal errors. + */ + + _CPU_ISR_Set_signal_level(1); + + sigfillset(&UNIX_SIGNAL_MASK); + sigdelset(&UNIX_SIGNAL_MASK, SIGTRAP); + sigdelset(&UNIX_SIGNAL_MASK, SIGABRT); + sigdelset(&UNIX_SIGNAL_MASK, SIGIOT); + sigdelset(&UNIX_SIGNAL_MASK, SIGCONT); + + sigprocmask(SIG_BLOCK, &UNIX_SIGNAL_MASK, 0); + + /* + * Set the handler for all signals to be signal_handler + * which will then vector out to the correct handler + * for whichever signal actually happened. Initially + * set the vectors to the stray signal handler. + */ + + for (i = 0; i < 32; i++) + (void)set_vector(Stray_signal, i, 1); + + signal_initialize(); +} + +/* _CPU_ISR_install_vector + * + * This kernel routine installs the RTEMS handler for the + * specified vector. + * + * Input parameters: + * vector - interrupt vector number + * old_handler - former ISR for this vector number + * new_handler - replacement ISR for this vector number + * + * Output parameters: NONE + * + */ + + +void _CPU_ISR_install_vector( + unsigned32 vector, + proc_ptr new_handler, + proc_ptr *old_handler +) +{ + *old_handler = _ISR_Vector_table[ vector ]; + + /* + * If the interrupt vector table is a table of pointer to isr entry + * points, then we need to install the appropriate RTEMS interrupt + * handler for this vector number. + */ + + /* + * We put the actual user ISR address in '_ISR_vector_table'. This will + * be used by the _ISR_Handler so the user gets control. + */ + + _ISR_Vector_table[ vector ] = new_handler; +} + +/*PAGE + * + * _CPU_Install_interrupt_stack + */ + +void _CPU_Install_interrupt_stack( void ) +{ +} + +/*PAGE + * + * _CPU_Internal_threads_Idle_thread_body + * + * NOTES: + * + * 1. This is the same as the regular CPU independent algorithm. + * + * 2. If you implement this using a "halt", "idle", or "shutdown" + * instruction, then don't forget to put it in an infinite loop. + * + * 3. Be warned. Some processors with onboard DMA have been known + * to stop the DMA if the CPU were put in IDLE mode. This might + * also be a problem with other on-chip peripherals. So use this + * hook with caution. + */ + +void _CPU_Internal_threads_Idle_thread_body( void ) +{ + while (1) + pause(); +} + +void _CPU_Context_Initialize( + Context_Control *_the_context, + unsigned32 *_stack_base, + unsigned32 _size, + unsigned32 _new_level, + proc_ptr *_entry_point +) +{ + unsigned32 *addr; + unsigned32 jmp_addr; + unsigned32 _stack; + unsigned32 _the_size; + + jmp_addr = (unsigned32) _entry_point; + + _stack = ((unsigned32)(_stack_base) + CPU_STACK_ALIGNMENT); + _stack &= ~(CPU_STACK_ALIGNMENT - 1); + + _the_size = _size & ~(CPU_STACK_ALIGNMENT - 1); + + /* + * Slam our jmp_buf template into the context we are creating + */ + + memcpy(_the_context, default_context, sizeof(jmp_buf)); + + addr = (unsigned32 *)_the_context; + +#if defined(hppa1_1) + *(addr + RP_OFF) = jmp_addr; + *(addr + SP_OFF) = (unsigned32)(_stack + CPU_FRAME_SIZE); + + /* + * See if we are using shared libraries by checking + * bit 30 in 24 off of newp. If bit 30 is set then + * we are using shared libraries and the jump address + * is at what 24 off of newp points to so shove that + * into 24 off of newp instead. + */ + + if (jmp_addr & 0x40000000) { + jmp_addr &= 0xfffffffc; + *(addr + RP_OFF) = (unsigned32)*(unsigned32 *)jmp_addr; + } +#elif defined(sparc) + + /* + * See /usr/include/sys/stack.h in Solaris 2.3 for a nice + * diagram of the stack. + */ + + asm ("ta 0x03"); /* flush registers */ + + *(addr + RP_OFF) = jmp_addr + ADDR_ADJ_OFFSET; + *(addr + SP_OFF) = (unsigned32)(_stack +_the_size - CPU_FRAME_SIZE); + *(addr + FP_OFF) = (unsigned32)(_stack +_the_size); +#else +#error "UNKNOWN CPU!!!" +#endif + + if (_new_level) + _CPU_ISR_Set_signal_level(1); + else + _CPU_ISR_Set_signal_level(0); + +} + +void _CPU_Context_restore( + Context_Control *next +) +{ + longjmp(next->regs, 0); +} + +void _CPU_Context_switch( + Context_Control *current, + Context_Control *next +) +{ + /* + * Save the current context + */ + + if (setjmp(current->regs) == 0) { + + /* + * Switch to the new context + */ + + longjmp(next->regs, 0); + } +} + +void _CPU_Save_float_context( + Context_Control_fp *fp_context +) +{ +} + +void _CPU_Restore_float_context( + Context_Control_fp *fp_context +) +{ +} + +void _CPU_ISR_Set_signal_level(unsigned32 level) +{ + if (level) + _CPU_Disable_signal(); + else + _CPU_Enable_signal(0); +} + + +unsigned32 _CPU_Disable_signal(void) +{ + sigset_t old_mask; + sigset_t empty_mask; + + sigemptyset(&empty_mask); + sigemptyset(&old_mask); + sigprocmask(SIG_BLOCK, &UNIX_SIGNAL_MASK, &old_mask); + + if (memcmp((char *)&empty_mask, (char *)&old_mask, sizeof(sigset_t)) != 0) + return 1; + + return 0; +} + + +void _CPU_Enable_signal(unsigned32 level) +{ + if (level == 0) + sigprocmask(SIG_UNBLOCK, &UNIX_SIGNAL_MASK, 0); +} + + +/* + * Support for external and spurious interrupts on HPPA + * + * TODO: + * delete interrupt.c etc. + * Count interrupts + * make sure interrupts disabled properly + * should handler check again for more interrupts before exit? + * How to enable interrupts from an interrupt handler? + * Make sure there is an entry for everything in ISR_Vector_Table + */ + +/* + * Init the external interrupt scheme + * called by bsp_start() + */ + +rtems_status_code +signal_initialize(void) +{ + struct sigaction act; + sigset_t mask; + + /* mark them all active except for TraceTrap and Abort */ + + sigfillset(&mask); + sigdelset(&mask, SIGTRAP); + sigdelset(&mask, SIGABRT); + sigdelset(&mask, SIGIOT); + sigdelset(&mask, SIGCONT); + sigprocmask(SIG_UNBLOCK, &mask, 0); + + act.sa_handler = interrupt_handler; + act.sa_mask = mask; +#if defined(solaris) + act.sa_flags = SA_RESTART; +#else + act.sa_flags = 0; +#endif + + sigaction(SIGHUP, &act, 0); + sigaction(SIGINT, &act, 0); + sigaction(SIGQUIT, &act, 0); + sigaction(SIGILL, &act, 0); + sigaction(SIGEMT, &act, 0); + sigaction(SIGFPE, &act, 0); + sigaction(SIGKILL, &act, 0); + sigaction(SIGBUS, &act, 0); + sigaction(SIGSEGV, &act, 0); + sigaction(SIGSYS, &act, 0); + sigaction(SIGPIPE, &act, 0); + sigaction(SIGALRM, &act, 0); + sigaction(SIGTERM, &act, 0); + sigaction(SIGUSR1, &act, 0); + sigaction(SIGUSR2, &act, 0); + sigaction(SIGCHLD, &act, 0); + sigaction(SIGCLD, &act, 0); + sigaction(SIGPWR, &act, 0); + sigaction(SIGVTALRM, &act, 0); + sigaction(SIGPROF, &act, 0); + sigaction(SIGIO, &act, 0); + sigaction(SIGWINCH, &act, 0); + sigaction(SIGSTOP, &act, 0); + sigaction(SIGTTIN, &act, 0); + sigaction(SIGTTOU, &act, 0); + sigaction(SIGURG, &act, 0); +/* + * XXX: Really should be on HPUX. + */ + +#if defined(hppa1_1) + sigaction(SIGLOST, &act, 0); +#endif + + return RTEMS_SUCCESSFUL; +} + + +/* + * External interrupt handler. + * This is installed as cpu interrupt handler. + * It vectors out to specific external interrupt handlers. + */ + +void +interrupt_handler(int vector) +{ + if (_ISR_Nest_level++ == 0) { + /* switch to interrupt stack */ + } + + _Thread_Dispatch_disable_level++; + + if (_ISR_Vector_table[vector]) { + _ISR_Vector_table[vector](vector); + } + else { + Stray_signal(vector); + } + + if (_ISR_Nest_level-- == 0) { + /* switch back to original stack */ + } + + _Thread_Dispatch_disable_level--; + + if (_Thread_Dispatch_disable_level == 0 && + (_Context_Switch_necessary || _ISR_Signals_to_thread_executing)) { + _CPU_Enable_signal(0); + _Thread_Dispatch(); + } +} + + +void +Stray_signal(int sig_num) +{ + char buffer[ 80 ]; + + /* + * We avoid using the stdio section of the library. + * The following is generally safe. + */ + + write( + 2, + buffer, + sprintf( buffer, "Stray signal %d\n", sig_num ) + ); + + /* + * If it was a "fatal" signal, then exit here + * If app code has installed a hander for one of these, then + * we won't call Stray_signal, so this is ok. + */ + + switch (sig_num) + { + case SIGINT: + case SIGHUP: + case SIGQUIT: + case SIGILL: + case SIGEMT: + case SIGKILL: + case SIGBUS: + case SIGSEGV: + case SIGTERM: + _CPU_Fatal_error(0x100 + sig_num); + } +} + + +void +_CPU_Fatal_error(unsigned32 error) +{ + setitimer(ITIMER_REAL, 0, 0); + + _exit(error); +} + +int +_CPU_ffs(unsigned32 value) +{ + int output; + + output = ffs(value); + output = output - 1; + + return(output); +} diff --git a/cpukit/score/include/rtems/debug.h b/cpukit/score/include/rtems/debug.h new file mode 100644 index 0000000000..afe6251bbe --- /dev/null +++ b/cpukit/score/include/rtems/debug.h @@ -0,0 +1,98 @@ +/* debug.h + * + * This include file contains the information pertaining to the debug + * support within RTEMS. It is currently cast in the form of a + * Manager since it is externally accessible. + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_DEBUG_h +#define __RTEMS_DEBUG_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following type is used to manage the debug mask. + */ + +typedef unsigned32 rtems_debug_control; + +/* + * These constants represent various classes of debugging. + */ + +#define RTEMS_DEBUG_ALL_MASK 0xffffffff +#define RTEMS_DEBUG_REGION 0x00000001 + +/* + * This variable contains the current debug level. + */ + +EXTERN rtems_debug_control _Debug_Level; + +/* + * _Debug_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. + */ + +void _Debug_Manager_initialization( void ); + +/* + * rtems_debug_enable + * + * DESCRIPTION: + * + * This routine enables the specified types of debug checks. + */ + +void rtems_debug_enable ( + rtems_debug_control to_be_enabled +); + +/* + * rtems_debug_disable + * + * DESCRIPTION: + * + * This routine disables the specified types of debug checks. + */ + +void rtems_debug_disable ( + rtems_debug_control to_be_disabled +); + +/* + * + * _Debug_Is_enabled + * + * DESCRIPTION: + * + * This routine returns TRUE if the requested debug level is + * enabled, and FALSE otherwise. + */ + +boolean _Debug_Is_enabled( + rtems_debug_control level +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/address.h b/cpukit/score/include/rtems/score/address.h new file mode 100644 index 0000000000..0abd113f63 --- /dev/null +++ b/cpukit/score/include/rtems/score/address.h @@ -0,0 +1,122 @@ +/* address.h + * + * This include file contains the information required to manipulate + * physical addresses. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_ADDRESSES_h +#define __RTEMS_ADDRESSES_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * _Addresses_Add_offset + * + * DESCRIPTION: + * + * This function is used to add an offset to a base address. + * It returns the resulting address. This address is typically + * converted to an access type before being used further. + */ + +STATIC INLINE void *_Addresses_Add_offset ( + void *base, + unsigned32 offset +); + +/* + * _Addresses_Subtract_offset + * + * DESCRIPTION: + * + * This function is used to subtract an offset from a base + * address. It returns the resulting address. This address is + * typically converted to an access type before being used further. + */ + +STATIC INLINE void *_Addresses_Subtract_offset( + void *base, + unsigned32 offset +); + +/* + * _Addresses_Add + * + * DESCRIPTION: + * + * This function is used to add two addresses. It returns the + * resulting address. This address is typically converted to an + * access type before being used further. + */ + +STATIC INLINE void *_Addresses_Add ( + void *left, + void *right +); + +/* + * _Addresses_Subtract + * + * DESCRIPTION: + * + * This function is used to subtract two addresses. It returns the + * resulting offset. + */ + +STATIC INLINE unsigned32 _Addresses_Subtract ( + void *left, + void *right +); + +/* + * _Addresses_Is_aligned + * + * DESCRIPTION: + * + * This function returns TRUE if the given address is correctly + * aligned for this processor and FALSE otherwise. Proper alignment + * is based on correctness and efficiency. + */ + +STATIC INLINE boolean _Addresses_Is_aligned ( + void *address +); + +/* + * _Addresses_Is_in_range + * + * DESCRIPTION: + * + * This function returns TRUE if the given address is within the + * memory range specified and FALSE otherwise. base is the address + * of the first byte in the memory range and limit is the address + * of the last byte in the memory range. The base address is + * assumed to be lower than the limit address. + */ + +STATIC INLINE boolean _Addresses_Is_in_range ( + void *address, + void *base, + void *limit +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/bitfield.h b/cpukit/score/include/rtems/score/bitfield.h new file mode 100644 index 0000000000..a74ea97735 --- /dev/null +++ b/cpukit/score/include/rtems/score/bitfield.h @@ -0,0 +1,49 @@ +/* bitfield.h + * + * This include file contains all bit field manipulation routines. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_BITFIELD_h +#define __RTEMS_BITFIELD_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * _Bitfield_Find_first_bit + * + * DESCRIPTION: + * + * This routine returns the bit_number of the first bit set + * in the specified value. The correspondence between bit_number + * and actual bit position is processor dependent. The search for + * the first bit set may run from most to least significant bit + * or vice-versa. + * + * NOTE: + * + * This routine is used when the executing thread is removed + * from the ready state and, as a result, its performance has a + * significant impact on the performance of the executive as a whole. + */ + +#define _Bitfield_Find_first_bit( _value, _bit_number ) \ + _CPU_Bitfield_Find_first_bit( _value, _bit_number ) + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/chain.h b/cpukit/score/include/rtems/score/chain.h new file mode 100644 index 0000000000..06cc47cc65 --- /dev/null +++ b/cpukit/score/include/rtems/score/chain.h @@ -0,0 +1,432 @@ +/* chain.h + * + * This include file contains all the constants and structures associated + * with the Doubly Linked Chain Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_CHAIN_h +#define __RTEMS_CHAIN_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * This is used to manage each element (node) which is placed + * on a chain. + * + * NOTE: Typically, a more complicated structure will use the + * chain package. The more complicated structure will + * include a chain node as the first element in its + * control structure. It will then call the chain package + * with a pointer to that node element. The node pointer + * and the higher level structure start at the same address + * so the user can cast the pointers back and forth. + * + */ + +typedef struct Chain_Node_struct Chain_Node; + +struct Chain_Node_struct { + Chain_Node *next; + Chain_Node *previous; +}; + +/* + * This is used to manage a chain. A chain consists of a doubly + * linked list of zero or more nodes. + * + * NOTE: This implementation does not require special checks for + * manipulating the first and last elements on the chain. + * To accomplish this the chain control structure is + * treated as two overlapping chain nodes. The permanent + * head of the chain overlays a node structure on the + * first and permanent_null fields. The permanent tail + * of the chain overlays a node structure on the + * permanent_null and last elements of the structure. + * + */ + +typedef struct { + Chain_Node *first; + Chain_Node *permanent_null; + Chain_Node *last; +} Chain_Control; + +/* + * _Chain_Initialize + * + * DESCRIPTION: + * + * This routine initializes the_chain structure to manage the + * contiguous array of number_nodes nodes which starts at + * starting_address. Each node is of node_size bytes. + * + */ + +void _Chain_Initialize( + Chain_Control *the_chain, + void *starting_address, + unsigned32 number_nodes, + unsigned32 node_size +); + +/* + * _Chain_Initialize_empty + * + * DESCRIPTION: + * + * This routine initializes the specified chain to contain zero nodes. + * + */ + +STATIC INLINE void _Chain_Initialize_empty( + Chain_Control *the_chain +); + +/* + * _Chain_Are_nodes_equal + * + * DESCRIPTION: + * + * This function returns TRUE if LEFT and RIGHT are equal, + * and FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Are_nodes_equal( + Chain_Node *left, + Chain_Node *right +); + +/* + * _Chain_Extract_unprotected + * + * DESCRIPTION: + * + * This routine extracts the_node from the chain on which it resides. + * It does NOT disable interrupts to insure the atomicity of the + * extract operation. + * + */ + +STATIC INLINE void _Chain_Extract_unprotected( + Chain_Node *the_node +); + +/* + * _Chain_Extract + * + * DESCRIPTION: + * + * This routine extracts the_node from the chain on which it resides. + * It disables interrupts to insure the atomicity of the + * extract operation. + * + */ + +void _Chain_Extract( + Chain_Node *the_node +); + +/* + * _Chain_Get_unprotected + * + * DESCRIPTION: + * + * This function removes the first node from the_chain and returns + * a pointer to that node. If the_chain is empty, then NULL is returned. + * It does NOT disable interrupts to insure the atomicity of the + * get operation. + * + */ + +STATIC INLINE Chain_Node *_Chain_Get_unprotected( + Chain_Control *the_chain +); + +/* + * _Chain_Get + * + * DESCRIPTION: + * + * This function removes the first node from the_chain and returns + * a pointer to that node. If the_chain is empty, then NULL is returned. + * It disables interrupts to insure the atomicity of the + * get operation. + * + */ + +Chain_Node *_Chain_Get( + Chain_Control *the_chain +); + +/* + * _Chain_Get_first_unprotected + * + * DESCRIPTION: + * + * This function removes the first node from the_chain and returns + * a pointer to that node. It does NOT disable interrupts to insure + * the atomicity of the get operation. + * + */ + +STATIC INLINE Chain_Node *_Chain_Get_first_unprotected( + Chain_Control *the_chain +); + +/* + * _Chain_Insert_unprotected + * + * DESCRIPTION: + * + * This routine inserts the_node on a chain immediately following + * after_node. It does NOT disable interrupts to insure the atomicity + * of the extract operation. + * + */ + +STATIC INLINE void _Chain_Insert_unprotected( + Chain_Node *after_node, + Chain_Node *the_node +); + +/* + * _Chain_Insert + * + * DESCRIPTION: + * + * This routine inserts the_node on a chain immediately following + * after_node. It disables interrupts to insure the atomicity + * of the extract operation. + * + */ + +void _Chain_Insert( + Chain_Node *after_node, + Chain_Node *the_node +); + +/* + * _Chain_Append_unprotected + * + * DESCRIPTION: + * + * This routine appends the_node onto the end of the_chain. + * It does NOT disable interrupts to insure the atomicity of the + * append operation. + * + */ + +STATIC INLINE void _Chain_Append_unprotected( + Chain_Control *the_chain, + Chain_Node *the_node +); + +/* + * _Chain_Append + * + * DESCRIPTION: + * + * This routine appends the_node onto the end of the_chain. + * It disables interrupts to insure the atomicity of the + * append operation. + * + */ + +void _Chain_Append( + Chain_Control *the_chain, + Chain_Node *the_node +); + +/* + * _Chain_Prepend_unprotected + * + * DESCRIPTION: + * + * This routine prepends the_node onto the front of the_chain. + * It does NOT disable interrupts to insure the atomicity of the + * prepend operation. + * + */ + +STATIC INLINE void _Chain_Prepend_unprotected( + Chain_Control *the_chain, + Chain_Node *the_node +); + +/* + * _Chain_Prepend + * + * DESCRIPTION: + * + * This routine prepends the_node onto the front of the_chain. + * It disables interrupts to insure the atomicity of the + * prepend operation. + * + */ + +STATIC INLINE void _Chain_Prepend( + Chain_Control *the_chain, + Chain_Node *the_node +); + +/* + * _Chain_Head + * + * DESCRIPTION: + * + * This function returns a pointer to the first node on the chain. + * + */ + +STATIC INLINE Chain_Node *_Chain_Head( + Chain_Control *the_chain +); + +/* + * _Chain_Tail + * + * DESCRIPTION: + * + * This function returns a pointer to the last node on the chain. + * + */ + +STATIC INLINE Chain_Node *_Chain_Tail( + Chain_Control *the_chain +); + +/* + * _Chain_Is_head + * + * DESCRIPTION: + * + * This function returns TRUE if the_node is the head of the_chain and + * FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Is_head( + Chain_Control *the_chain, + Chain_Node *the_node +); + +/* + * _Chain_Is_tail + * + * DESCRIPTION: + * + * This function returns TRUE if the_node is the tail of the_chain and + * FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Is_tail( + Chain_Control *the_chain, + Chain_Node *the_node +); + +/* + * _Chain_Is_first + * + * DESCRIPTION: + * + * This function returns TRUE if the_node is the first node on a chain and + * FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Is_first( + Chain_Node *the_node +); + +/* + * _Chain_Is_last + * + * DESCRIPTION: + * + * This function returns TRUE if the_node is the last node on a chain and + * FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Is_last( + Chain_Node *the_node +); + +/* + * _Chain_Is_empty + * + * DESCRIPTION: + * + * This function returns TRUE if there a no nodes on the_chain and + * FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Is_empty( + Chain_Control *the_chain +); + +/* + * _Chain_Has_only_one_node + * + * DESCRIPTION: + * + * This function returns TRUE if there is only one node on the_chain and + * FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Has_only_one_node( + Chain_Control *the_chain +); + +/* + * _Chain_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_chain is NULL and FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Is_null( + Chain_Control *the_chain +); + +/* + * _Chain_Is_null_node + * + * DESCRIPTION: + * + * This function returns TRUE if the_node is NULL and FALSE otherwise. + * + */ + +STATIC INLINE boolean _Chain_Is_null_node( + Chain_Node *the_node +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/context.h b/cpukit/score/include/rtems/score/context.h new file mode 100644 index 0000000000..9b8ee92b04 --- /dev/null +++ b/cpukit/score/include/rtems/score/context.h @@ -0,0 +1,133 @@ +/* context.h + * + * This include file contains all information about a context. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_CONTEXT_h +#define __RTEMS_CONTEXT_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * The following constant defines the number of bytes required + * to store a full floating point context. + */ + +#define CONTEXT_FP_SIZE CPU_CONTEXT_FP_SIZE + +/* + * The following variable is set to TRUE when a reschedule operation + * has determined that the processor should be taken away from the + * currently executing thread and given to the heir thread. + */ + +EXTERN boolean _Context_Switch_necessary; + +/* + * _Context_Initialize + * + * DESCRIPTION: + * + * This routine initializes THE_CONTEXT such that the stack + * pointer, interrupt level, and entry point are correct for the + * thread's initial state. + */ + +#define _Context_Initialize( _the_context, _stack, _size, _isr, _entry ) \ + _CPU_Context_Initialize( _the_context, _stack, _size, _isr, _entry ) + +/* + * _Context_Switch + * + * DESCRIPTION: + * + * This routine saves the current context into the EXECUTING + * context record and restores the context specified by HEIR. + */ + +#define _Context_Switch( _executing, _heir ) \ + _CPU_Context_switch( _executing, _heir ) + +/* + * _Context_Restart_self + * + * DESCRIPTION: + * + * This routine restarts the calling thread by restoring its initial + * stack pointer and returning to the thread's entry point. + */ + +#define _Context_Restart_self( _the_context ) \ + _CPU_Context_Restart_self( _the_context ) + +/* + * _Context_Fp_start + * + * DESCRIPTION: + * + * This function returns the starting address of the floating + * point context save area. It is assumed that the are reserved + * for the floating point save area is large enough. + */ + +#define _Context_Fp_start( _base, _offset ) \ + _CPU_Context_Fp_start( (_base), (_offset) ) + +/* + * _Context_Initialize_fp + * + * DESCRIPTION: + * + * This routine initializes the floating point context save + * area to contain an initial known state. + */ + +#define _Context_Initialize_fp( _fp_area ) \ + _CPU_Context_Initialize_fp( _fp_area ) + +/* + * _Context_Restore_fp + * + * DESCRIPTION: + * + * This routine restores the floating point context contained + * in the FP_CONTEXT area. It is assumed that the current + * floating point context has been saved by a previous invocation + * of SAVE_FP. + */ + +#define _Context_Restore_fp( _fp ) \ + _CPU_Context_restore_fp( _fp ) + +/* + * _Context_Save_fp + * + * DESCRIPTION: + * + * This routine saves the current floating point context + * in the FP_CONTEXT area. + */ + +#define _Context_Save_fp( _fp ) \ + _CPU_Context_save_fp( _fp ) + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/copyrt.h b/cpukit/score/include/rtems/score/copyrt.h new file mode 100644 index 0000000000..c711ba09b3 --- /dev/null +++ b/cpukit/score/include/rtems/score/copyrt.h @@ -0,0 +1,42 @@ +/* copyrt.h + * + * This include file contains the copyright notice for RTEMS + * which is included in every binary copy of the executive. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_COPYRIGHT_h +#define __RTEMS_COPYRIGHT_h + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef INIT + +const char _Copyright_Notice[] = +"COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.\n\ +On-Line Applications Research Corporation (OAR).\n\ +All rights assigned to U.S. Government, 1994.\n"; + +#else + +extern const char _Copyright_Notice[]; + +#endif + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/heap.h b/cpukit/score/include/rtems/score/heap.h new file mode 100644 index 0000000000..9eb348a760 --- /dev/null +++ b/cpukit/score/include/rtems/score/heap.h @@ -0,0 +1,396 @@ +/* heap.h + * + * This include file contains the information pertaining to the Heap + * Handler. A heap is a doubly linked list of variable size + * blocks which are allocated using the first fit method. Garbage + * collection is performed each time a block is returned to the heap by + * coalescing neighbor blocks. Control information for both allocated + * and unallocated blocks is contained in the heap space. A heap header + * contains control information for the heap. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_HEAP_h +#define __RTEMS_HEAP_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Status codes for heap_extend + */ + +typedef enum { + HEAP_EXTEND_SUCCESSFUL, + HEAP_EXTEND_ERROR, + HEAP_EXTEND_NOT_IMPLEMENTED +} Heap_Extend_status; + +/* + * Constants used in the size/used field of each heap block to + * indicate when a block is free or in use. + */ + +#define HEAP_BLOCK_USED 1 /* indicates block is in use */ +#define HEAP_BLOCK_FREE 0 /* indicates block is free */ + +/* + * The size/used field value for the dummy front and back flags. + */ + +#define HEAP_DUMMY_FLAG (0 + HEAP_BLOCK_USED) + +/* + * The following constants reflect various requirements of the + * heap data structures which impact the management of a heap. + * + * NOTE: Because free block overhead is greater than used block + * overhead AND a portion of the allocated space is from + * the extra free block overhead, the absolute lower bound + * of the minimum fragment size is equal to the size of + * the free block overhead. + */ + +#define HEAP_OVERHEAD \ + (sizeof( unsigned32 ) * 2) /* size dummy first and last blocks */ +#define HEAP_BLOCK_USED_OVERHEAD \ + (sizeof( void * ) * 2) /* num bytes overhead in used block */ +#define HEAP_MINIMUM_SIZE \ + (HEAP_OVERHEAD + sizeof (Heap_Block)) + /* min number of bytes the user may */ + /* specify for the heap size */ + +/* + * The following defines the data structure used to manage + * individual blocks in a heap. When the block is allocated, the + * next and previous fields are not used by the Heap Handler + * and thus the address returned for the block starts at + * the address of the next field. + * + * NOTE: The next and previous pointers are only valid when the + * block is free. Caution must be exercised to insure that + * allocated blocks are large enough to contain them and + * that they are not accidentally overwritten when the + * block is actually allocated. + */ + +typedef struct Heap_Block_struct Heap_Block; + +struct Heap_Block_struct { + unsigned32 back_flag; /* size and status of prev block */ + unsigned32 front_flag; /* size and status of block */ + Heap_Block *next; /* pointer to next block */ + Heap_Block *previous; /* pointer to previous block */ +}; + +/* + * The following defines the control block used to manage each heap. + * + * NOTE: + * + * This structure is layed out such that it can be used a a dummy + * first and last block on the free block chain. The extra padding + * insures the dummy last block is the correct size. + * + * The first Heap_Block starts at first while the second starts at + * final. This is effectively the same trick as is used in the Chain + * Handler. + */ + +typedef struct { + Heap_Block *start; /* first valid block address in heap */ + Heap_Block *final; /* last valid block address in heap */ + + Heap_Block *first; /* pointer to first block in heap */ + Heap_Block *permanent_null; /* always NULL pointer */ + Heap_Block *last; /* pointer to last block in heap */ + unsigned32 page_size; /* allocation unit */ + unsigned32 reserved; +} Heap_Control; + +/* + * _Heap_Initialize + * + * DESCRIPTION: + * + * This routine initializes the_heap record to manage the + * contiguous heap of size bytes which starts at starting_address. + * Blocks of memory are allocated from the heap in multiples of + * page_size byte units. + */ + +unsigned32 _Heap_Initialize( + Heap_Control *the_heap, + void *starting_address, + unsigned32 size, + unsigned32 page_size +); + +/* + * _Heap_Extend + * + * DESCRIPTION: + * + * This routine grows the_heap memory area using the size bytes which + * begin at starting_address. + */ + +Heap_Extend_status _Heap_Extend( + Heap_Control *the_heap, + void *starting_address, + unsigned32 size, + unsigned32 *amount_extended +); + +/* + * _Heap_Allocate + * + * DESCRIPTION: + * + * DESCRIPTION: + * + * This function attempts to allocate a block of size bytes from + * the_heap. If insufficient memory is free in the_heap to allocate + * a block of the requested size, then NULL is returned. + */ + +void *_Heap_Allocate( + Heap_Control *the_heap, + unsigned32 size +); + +/* + * _Heap_Size_of_user_area + * + * DESCRIPTION: + * + * This kernel routine sets size to the size of the given heap block. + * It returns TRUE if the starting_address is in the heap, and FALSE + * otherwise. + */ + +boolean _Heap_Size_of_user_area( + Heap_Control *the_heap, + void *starting_address, + unsigned32 *size +); + +/* + * _Heap_Free + * + * DESCRIPTION: + * + * This routine returns the block of memory which begins + * at starting_address to the_heap. Any coalescing which is + * possible with the freeing of this routine is performed. + */ + +boolean _Heap_Free( + Heap_Control *the_heap, + void *start_address +); + +/* + * _Heap_Walk + * + * DESCRIPTION: + * + * This routine walks the heap to verify its integrity. + */ + +void _Heap_Walk( + Heap_Control *the_heap, + int source, + boolean do_dump +); + +/* + * _Heap_Head + * + * DESCRIPTION: + * + * This function returns the head of the specified heap. + */ + +STATIC INLINE Heap_Block *_Heap_Head ( + Heap_Control *the_heap +); + +/* + * _Heap_Tail + * + * DESCRIPTION: + * + * This function returns the tail of the specified heap. + */ + +STATIC INLINE Heap_Block *_Heap_Tail ( + Heap_Control *the_heap +); + +/* + * _Heap_Previous_block + * + * DESCRIPTION: + * + * This function returns the address of the block which physically + * precedes the_block in memory. + */ + +STATIC INLINE Heap_Block *_Heap_Previous_block ( + Heap_Block *the_block +); + +/* + * _Heap_Next_block + * + * DESCRIPTION: + * + * This function returns the address of the block which physically + * follows the_block in memory. + */ + +STATIC INLINE Heap_Block *_Heap_Next_block ( + Heap_Block *the_block +); + +/* + * _Heap_Block_at + * + * DESCRIPTION: + * + * This function calculates and returns a block's location (address) + * in the heap based upad a base address and an offset. + */ + +STATIC INLINE Heap_Block *_Heap_Block_at( + void *base, + unsigned32 offset +); + +/* + * _Heap_Is_previous_block_free + * + * DESCRIPTION: + * + * This function returns TRUE if the previous block of the_block + * is free, and FALSE otherwise. + */ + +STATIC INLINE boolean _Heap_Is_previous_block_free ( + Heap_Block *the_block +); + +/* + * _Heap_Is_block_free + * + * DESCRIPTION: + * + * This function returns TRUE if the block is free, and FALSE otherwise. + */ + +STATIC INLINE boolean _Heap_Is_block_free ( + Heap_Block *the_block +); + +/* + * _Heap_Is_block_used + * + * DESCRIPTION: + * + * This function returns TRUE if the block is currently allocated, + * and FALSE otherwise. + */ + +STATIC INLINE boolean _Heap_Is_block_used ( + Heap_Block *the_block +); + +/* + * _Heap_Block_size + * + * DESCRIPTION: + * + * This function returns the size of the_block in bytes. + */ + +STATIC INLINE unsigned32 _Heap_Block_size ( + Heap_Block *the_block +); + +/* + * _Heap_Start_of_user_area + * + * DESCRIPTION: + * + * This function returns the starting address of the portion of the block + * which the user may access. + */ + +STATIC INLINE void *_Heap_Start_of_user_area ( + Heap_Block *the_block +); + +/* + * _Heap_Is_block_in + * + * DESCRIPTION: + * + * This function returns TRUE if the_block is within the memory area + * managed by the_heap, and FALSE otherwise. + */ + +STATIC INLINE boolean _Heap_Is_block_in ( + Heap_Control *the_heap, + Heap_Block *the_block +); + + +/* + * _Heap_Is_page_size_valid + * + * DESCRIPTION: + * + * This function validates a specified heap page size. If the page size + * is 0 or if lies outside a page size alignment boundary it is invalid + * and FALSE is returned. Otherwise, the page size is valid and TRUE is + * returned. + */ + +STATIC INLINE boolean _Heap_Is_page_size_valid( + unsigned32 page_size +); + +/* + * _Heap_Build_flag + * + * DESCRIPTION: + * + * This function returns the block flag composed of size and in_use_flag. + * The flag returned is suitable for use as a back or front flag in a + * heap block. + */ + +STATIC INLINE unsigned32 _Heap_Build_flag ( + unsigned32 size, + unsigned32 in_use_flag +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/isr.h b/cpukit/score/include/rtems/score/isr.h new file mode 100644 index 0000000000..77c3f8663e --- /dev/null +++ b/cpukit/score/include/rtems/score/isr.h @@ -0,0 +1,239 @@ +/* isr.h + * + * This include file contains all the constants and structures associated + * with the management of processor interrupt levels. This handler + * supports interrupt critical sections, vectoring of user interrupt + * handlers, nesting of interrupts, and manipulating interrupt levels. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_ISR_h +#define __RTEMS_ISR_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following type defines the control block used to manage + * the interrupt level portion of the status register. + */ + +typedef unsigned32 ISR_Level; + +/* + * The following type defines the control block used to manage + * the vectors. + */ + +typedef unsigned32 rtems_vector_number; + +/* + * Return type for ISR Handler + */ + +typedef void rtems_isr; + +/* + * Pointer to an ISR Handler + */ + +typedef rtems_isr ( *rtems_isr_entry )( + rtems_vector_number + ); +/* + * The following is TRUE if signals have been sent to the currently + * executing thread by an ISR handler. + */ + +EXTERN boolean _ISR_Signals_to_thread_executing; + +/* + * The following contains the interrupt service routine nest level. + * When this variable is zero, a thread is executing. + */ + +EXTERN unsigned32 _ISR_Nest_level; + +/* + * The following declares the RTEMS Vector Table. Application + * interrupt service routines are vectored by RTEMS via this table. + */ + +EXTERN rtems_isr_entry _ISR_Vector_table[CPU_INTERRUPT_NUMBER_OF_VECTORS]; + +/* + * _ISR_Handler_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this handler. + */ + +STATIC INLINE void _ISR_Handler_initialization ( void ); + +/* + * _ISR_Disable + * + * DESCRIPTION: + * + * This routine disables all interrupts so that a critical section + * of code can be executing without being interrupted. Upon return, + * the argument _level will contain the previous interrupt mask level. + */ + +#define _ISR_Disable( _level ) \ + _CPU_ISR_Disable( _level ) + +/* + * _ISR_Enable + * + * DESCRIPTION: + * + * This routine enables interrupts to the previous interrupt mask + * LEVEL. It is used at the end of a critical section of code to + * enable interrupts so they can be processed again. + */ + +#define _ISR_Enable( _level ) \ + _CPU_ISR_Enable( _level ) + +/* + * _ISR_Flash + * + * DESCRIPTION: + * + * This routine temporarily enables interrupts to the previous + * interrupt mask level and then disables all interrupts so that + * the caller can continue into the second part of a critical + * section. This routine is used to temporarily enable interrupts + * during a long critical section. It is used in long sections of + * critical code when a point is reached at which interrupts can + * be temporarily enabled. Deciding where to flash interrupts + * in a long critical section is often difficult and the point + * must be selected with care to insure that the critical section + * properly protects itself. + */ + +#define _ISR_Flash( _level ) \ + _CPU_ISR_Flash( _level ) + +/* + * _ISR_Is_in_progress + * + * DESCRIPTION: + * + * This function returns TRUE if the processor is currently servicing + * and interrupt and FALSE otherwise. A return value of TRUE indicates + * that the caller is an interrupt service routine, NOT a thread. The + * directives available to an interrupt service routine are restricted. + */ + +STATIC INLINE boolean _ISR_Is_in_progress( void ); + +/* + * _ISR_Install_vector + * + * DESCRIPTION: + * + * This routine installs new_handler as the interrupt service routine + * for the specified vector. The previous interrupt service routine is + * returned as old_handler. + */ + +#define _ISR_Install_vector( _vector, _new_handler, _old_handler ) \ + _CPU_ISR_install_vector( _vector, _new_handler, _old_handler ) + +/* + * _ISR_Set_level + * + * DESCRIPTION: + * + * This routine sets the current interrupt level to that specified + * by new_level. The new interrupt level is effective when the + * routine exits. + */ + +#define _ISR_Set_level( _new_level ) \ + _CPU_ISR_Set_level( _new_level ) + +/* + * _ISR_Is_vector_number_valid + * + * DESCRIPTION: + * + * This function returns TRUE if the vector is a valid vector number + * for this processor and FALSE otherwise. + */ + +STATIC INLINE boolean _ISR_Is_vector_number_valid ( + rtems_vector_number vector +); + +/* + * _ISR_Is_valid_user_handler + * + * DESCRIPTION: + * + * This function returns TRUE if handler is the entry point of a valid + * use interrupt service routine and FALSE otherwise. + */ + +STATIC INLINE boolean _ISR_Is_valid_user_handler ( + void *handler +); + +/* + * _ISR_Handler + * + * DESCRIPTION: + * + * This routine is the RTEMS interrupt dispatcher. ALL interrupts + * are vectored to this routine so that minimal context can be saved + * and setup performed before the application's high-level language + * interrupt service routine is invoked. After the application's + * interrupt service routine returns control to this routine, it + * will determine if a thread dispatch is necessary. If so, it will + * insure that the necessary thread scheduling operations are + * performed when the outermost interrupt service routine exits. + * + * NOTE: Implemented in assembly language. + */ + +void _ISR_Handler( void ); + +/* + * _ISR_Dispatch + * + * DESCRIPTION: + * + * This routine provides a wrapper so that the routine + * _Thread_Dispatch can be invoked when a reschedule is necessary + * at the end of the outermost interrupt service routine. This + * wrapper is necessary to establish the processor context needed + * by _Thread_Dispatch and to save the processor context which is + * corrupted by _Thread_Dispatch. This context typically consists + * of registers which are not preserved across routine invocations. + * + * NOTE: Implemented in assembly language. + */ + +void _ISR_Dispatch( void ); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/mpci.h b/cpukit/score/include/rtems/score/mpci.h new file mode 100644 index 0000000000..ca06dd243b --- /dev/null +++ b/cpukit/score/include/rtems/score/mpci.h @@ -0,0 +1,171 @@ +/* mpci.h + * + * This include file contains all the constants and structures associated + * with the MPCI layer. It provides mechanisms to utilize packets. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_MPCI_h +#define __RTEMS_MPCI_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include + +/* + * The following defines the node number used when a broadcast is desired. + */ + +#define MPCI_ALL_NODES 0 + +/* + * For packets associated with requests that don't already have a timeout, + * use the one specified by this MPCI driver. The value specified by + * the MPCI driver sets an upper limit on how long a remote request + * should take to complete. + */ + +#define MPCI_DEFAULT_TIMEOUT 0xFFFFFFFF + +/* + * _MPCI_Handler_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this handler. + */ + +void _MPCI_Handler_initialization ( void ); + +/* + * _MPCI_Initialization + * + * DESCRIPTION: + * + * This routine initializes the MPCI driver by + * invoking the user provided MPCI initialization callout. + */ + +void _MPCI_Initialization ( void ); + +/* + * _MPCI_Get_packet + * + * DESCRIPTION: + * + * This function obtains a packet by invoking the user provided + * MPCI get packet callout. + */ + +rtems_packet_prefix *_MPCI_Get_packet ( void ); + +/* + * _MPCI_Return_packet + * + * DESCRIPTION: + * + * This routine returns a packet by invoking the user provided + * MPCI return packet callout. + */ + +void _MPCI_Return_packet ( + rtems_packet_prefix *the_packet +); + +/* + * _MPCI_Send_process_packet + * + * DESCRIPTION: + * + * This routine sends a process packet by invoking the user provided + * MPCI send callout. + */ + +void _MPCI_Send_process_packet ( + unsigned32 destination, + rtems_packet_prefix *the_packet +); + +/* + * _MPCI_Send_request_packet + * + * DESCRIPTION: + * + * This routine sends a request packet by invoking the user provided + * MPCI send callout. + */ + +rtems_status_code _MPCI_Send_request_packet ( + unsigned32 destination, + rtems_packet_prefix *the_packet, + States_Control extra_state +); + +/* + * _MPCI_Send_response_packet + * + * DESCRIPTION: + * + * This routine sends a response packet by invoking the user provided + * MPCI send callout. + */ + +void _MPCI_Send_response_packet ( + unsigned32 destination, + rtems_packet_prefix *the_packet +); + +/* + * _MPCI_Receive_packet + * + * DESCRIPTION: + * + * This routine receives a packet by invoking the user provided + * MPCI receive callout. + */ + +rtems_packet_prefix *_MPCI_Receive_packet ( void ); + +/* + * _MPCI_Process_response + * + * DESCRIPTION: + * + * This routine obtains a packet by invoking the user provided + * MPCI get packet callout. + */ + +Thread_Control *_MPCI_Process_response ( + rtems_packet_prefix *the_packet +); + +/* + * The following thread queue is used to maintain a list of tasks + * which currently have outstanding remote requests. + */ + +EXTERN Thread_queue_Control _MPCI_Remote_blocked_threads; + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/mppkt.h b/cpukit/score/include/rtems/score/mppkt.h new file mode 100644 index 0000000000..e0cf6b1967 --- /dev/null +++ b/cpukit/score/include/rtems/score/mppkt.h @@ -0,0 +1,123 @@ +/* mppkt.h + * + * This package is the specification for the Packet Handler. + * This handler defines the basic RTEMS packet and provides + * mechanisms to utilize packets based on this prefix. + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_MP_PACKET_h +#define __RTEMS_MP_PACKET_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* + * The following enumerated type defines the packet classes + * supported by RTEMS. + * + * NOTE: In general, each class corresponds to a manager + * which supports global operations. Each manager + * defines the set of supported operations. + */ + +typedef enum { + RTEMS_MP_PACKET_INTERNAL_THREADS = 0, + RTEMS_MP_PACKET_TASKS = 1, + RTEMS_MP_PACKET_MESSAGE_QUEUE = 2, + RTEMS_MP_PACKET_SEMAPHORE = 3, + RTEMS_MP_PACKET_PARTITION = 4, + RTEMS_MP_PACKET_REGION = 5, + RTEMS_MP_PACKET_EVENT = 6, + RTEMS_MP_PACKET_SIGNAL = 7 +} rtems_mp_packet_classes; + +#define MP_PACKET_CLASSES_FIRST RTEMS_MP_PACKET_INTERNAL_THREADS +#define MP_PACKET_CLASSES_LAST RTEMS_MP_PACKET_SIGNAL + +/* + * The following record contains the prefix for every packet + * passed between RTEMS nodes. + * + * NOTE: This structure is padded to insure that anything + * following it is on a 16 byte boundary. This is + * the most stringent structure alignment rule + * the RTEMS project has encountered yet (i960CA). + */ + +typedef struct { + rtems_mp_packet_classes the_class; + Objects_Id id; + Objects_Id source_tid; + rtems_task_priority source_priority; + rtems_status_code return_code; + unsigned32 length; + unsigned32 to_convert; + rtems_interval timeout; +} rtems_packet_prefix; + +/* + * An MPCI must support packets of at least this size. + */ + +#define RTEMS_MINIMUM_PACKET_SIZE 64 + +/* + * The following constant defines the number of unsigned32's + * in a packet which must be converted to native format in a + * heterogeneous system. In packets longer than + * RTEMS_MINIMUN_HETERO_CONVERSION unsigned32's, some of the "extra" data + * may a user message buffer which is not automatically endian swapped. + */ + +#define RTEMS_MINIMUN_HETERO_CONVERSION ( sizeof( rtems_packet_prefix ) / 4 ) + +/* + * _Mp_packet_Is_valid_packet_class + * + * DESCRIPTION: + * + * This function returns TRUE if the the_packet_class is valid, + * and FALSE otherwise. + */ + +STATIC INLINE boolean _Mp_packet_Is_valid_packet_class ( + rtems_mp_packet_classes the_packet_class +); + +/* + * _Mp_packet_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the the_packet_class is null, + * and FALSE otherwise. + */ + +STATIC INLINE boolean _Mp_packet_Is_null ( + rtems_packet_prefix *the_packet +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/object.h b/cpukit/score/include/rtems/score/object.h new file mode 100644 index 0000000000..50eede9fd7 --- /dev/null +++ b/cpukit/score/include/rtems/score/object.h @@ -0,0 +1,380 @@ +/* object.h + * + * This include file contains all the constants and structures associated + * with the RTEMS Object Handler. This Handler provides mechanisms which + * can be used to initialize and manipulate all RTEMS objects. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_OBJECTS_h +#define __RTEMS_OBJECTS_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * The following type defines the control block used to manage + * object names. + */ + +typedef unsigned32 Objects_Name; + +/* + * The following type defines the control block used to manage + * object IDs. + */ + +typedef unsigned32 Objects_Id; + +/* + * This enumerated type lists the locations which may be returned + * by _Objects_Get. These codes indicate the success of locating + * an object with the specified ID. + */ + +typedef enum { + OBJECTS_LOCAL = 0, /* object is local */ + OBJECTS_REMOTE = 1, /* object is remote */ + OBJECTS_ERROR = 2 /* id was invalid */ +} Objects_Locations; + +/* + * The following defines the Object Control Block used to manage + * each object local to this node. + */ + +typedef struct { + Chain_Node Node; + Objects_Id id; +} Objects_Control; + +/* + * The following defines the structure for the information used to + * manage each class of objects. + */ + +typedef struct { + Objects_Id minimum_id; /* minimum valid id of this type */ + Objects_Id maximum_id; /* maximum valid id of this type */ + unsigned32 maximum; /* maximum number of objects */ + Objects_Control **local_table; /* table of local object pointers */ + Objects_Name *name_table; /* table of local object names */ + Chain_Control *global_table; /* pointer to global table */ + Chain_Control Inactive; /* chain of inactive ctl blocks */ +} Objects_Information; + +/* + * The following defines the data storage which contains the + * node number of the local node. + */ + +EXTERN unsigned32 _Objects_Local_node; + +/* + * The following defines the constant which may be used + * with _Objects_Get to manipulate the calling task. + * + */ + +#define OBJECTS_ID_OF_SELF 0 + +/* + * The following define the constants which may be used in name searches. + */ + +#define RTEMS_SEARCH_ALL_NODES 0 +#define RTEMS_SEARCH_OTHER_NODES 0x7FFFFFFE +#define RTEMS_SEARCH_LOCAL_NODE 0x7FFFFFFF +#define RTEMS_WHO_AM_I 0 + +/* + * _Objects_Handler_initialization + * + * DESCRIPTION: + * + * This function performs the initialization necessary for this handler. + * + */ + +void _Objects_Handler_initialization( + unsigned32 node, + unsigned32 maximum_global_objects +); + +/* + * _Objects_Initialize_information + * + * DESCRIPTION: + * + * This function initializes an object class information record. + * SUPPORTS_GLOBAL is TRUE if the object class supports global + * objects, and FALSE otherwise. Maximum indicates the number + * of objects required in this class and size indicates the size + * in bytes of each control block for this object class. + * + */ + +void _Objects_Initialize_information ( + Objects_Information *information, + boolean supports_global, + unsigned32 maximum, + unsigned32 size +); + +/* + * _Objects_Name_to_id + * + * DESCRIPTION: + * + * This function implements the common portion of the object + * identification directives. This directive returns the object + * id associated with name. If more than one object of this class + * is named name, then the object to which the id belongs is + * arbitrary. Node indicates the extent of the search for the + * id of the object named name. If the object class supports global + * objects, then the search can be limited to a particular node + * or allowed to encompass all nodes. + * + */ + +rtems_status_code _Objects_Name_to_id( + Objects_Information *information, + Objects_Name name, + unsigned32 node, + Objects_Id *id +); + +/* + * _Objects_Get + * + * DESCRIPTION: + * + * This function maps object ids to object control blocks. + * If id corresponds to a local object, then it returns + * the_object control pointer which maps to id and location + * is set to OBJECTS_LOCAL. If the object class supports global + * objects and the object id is global and resides on a remote + * node, then location is set to OBJECTS_REMOTE, and the_object + * is undefined. Otherwise, location is set to OBJECTS_ERROR + * and the_object is undefined. + * + */ + +Objects_Control *_Objects_Get ( + Objects_Information *information, + Objects_Id id, + Objects_Locations *location +); + +/* + * _Objects_Is_name_valid + * + * DESCRIPTION: + * + * This function returns TRUE if the name is valid, and FALSE otherwise. + */ + +STATIC INLINE boolean _Objects_Is_name_valid ( + Objects_Name name +); + +/* + * rtems_build_name + * + * DESCRIPTION: + * + * This function returns an object name composed of the four characters + * C1, C2, C3, and C4. + * + * NOTE: + * + * This must be implemented as a macro for use in Configuration Tables. + * + */ + +#define rtems_build_name( _C1, _C2, _C3, _C4 ) \ + ( (_C1) << 24 | (_C2) << 16 | (_C3) << 8 | (_C4) ) + +/* + * rtems_name_to_characters + * + * DESCRIPTION: + * + * This function breaks the object name into the four component + * characters C1, C2, C3, and C4. + * + */ + +STATIC INLINE void rtems_name_to_characters( + Objects_Name name, + char *c1, + char *c2, + char *c3, + char *c4 +); + +/* + * _Objects_Build_id + * + * DESCRIPTION: + * + * This function builds an object's id from the processor node and index + * values specified. + * + */ + +STATIC INLINE Objects_Id _Objects_Build_id( + unsigned32 node, + unsigned32 index +); + +/* + * rtems_get_node + * + * DESCRIPTION: + * + * This function returns the node portion of the ID. + * + */ + +STATIC INLINE unsigned32 rtems_get_node( + Objects_Id id +); + +/* + * rtems_get_index + * + * DESCRIPTION: + * + * This function returns the index portion of the ID. + * + */ + +STATIC INLINE unsigned32 rtems_get_index( + Objects_Id id +); + +/* + * _Objects_Is_local_node + * + * DESCRIPTION: + * + * This function returns TRUE if the node is of the local object, and + * FALSE otherwise. + * + */ + +STATIC INLINE boolean _Objects_Is_local_node( + unsigned32 node +); + +/* + * _Objects_Is_local_id + * + * DESCRIPTION: + * + * This function returns TRUE if the id is of a local object, and + * FALSE otherwise. + * + */ + +STATIC INLINE boolean _Objects_Is_local_id( + Objects_Id id +); + +/* + * _Objects_Are_ids_equal + * + * DESCRIPTION: + * + * This function returns TRUE if left and right are equal, + * and FALSE otherwise. + * + */ + +STATIC INLINE boolean _Objects_Are_ids_equal( + Objects_Id left, + Objects_Id right +); + +/* + * _Objects_Allocate + * + * DESCRIPTION: + * + * This function allocates a object control block from + * the inactive chain of free object control blocks. + * + */ + +STATIC INLINE Objects_Control *_Objects_Allocate( + Objects_Information *information +); + +/* + * _Objects_Free + * + * DESCRIPTION: + * + * This function frees a object control block to the + * inactive chain of free object control blocks. + * + */ + +STATIC INLINE void _Objects_Free( + Objects_Information *information, + Objects_Control *the_object +); + +/* + * _Objects_Open + * + * DESCRIPTION: + * + * This function places the_object control pointer and object name + * in the Local Pointer and Local Name Tables, respectively. + * + */ + +STATIC INLINE void _Objects_Open( + Objects_Information *information, + Objects_Control *the_object, + Objects_Name name +); + +/* + * _Objects_Close + * + * DESCRIPTION: + * + * This function removes the_object control pointer and object name + * in the Local Pointer and Local Name Tables. + * + */ + +STATIC INLINE void _Objects_Close( + Objects_Information *information, + Objects_Control *the_object +); + +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/objectmp.h b/cpukit/score/include/rtems/score/objectmp.h new file mode 100644 index 0000000000..0d29fda753 --- /dev/null +++ b/cpukit/score/include/rtems/score/objectmp.h @@ -0,0 +1,165 @@ +/* objectmp.h + * + * This include file contains all the constants and structures associated + * with the manipulation of Global RTEMS Objects. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_OBJECTS_MP_h +#define __RTEMS_OBJECTS_MP_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This defines the Global Object Control Block used to manage + * objects resident on other nodes. + */ + +typedef struct { + Objects_Control Object; + Objects_Name name; +} Objects_MP_Control; + +/* + * _Objects_MP_Handler_initialization + * + * DESCRIPTION: + * + * This routine intializes the inactive global object chain + * based on the maximum number of global objects configured. + */ + +void _Objects_MP_Handler_initialization ( + unsigned32 maximum_global_objects +); + +/* + * _Objects_MP_Allocate_global_object + * + * DESCRIPTION: + * + * This function allocates a Global Object control block. + */ + +STATIC INLINE Objects_MP_Control *_Objects_MP_Allocate_global_object ( + void +); + +/* + * _Objects_MP_Free_global_object + * + * DESCRIPTION: + * + * This routine deallocates a Global Object control block. + */ + +STATIC INLINE void _Objects_MP_Free_global_object ( + Objects_MP_Control *the_object +); + +/* + * _Objects_MP_Is_null_global_object + * + * DESCRIPTION: + * + * This function returns whether the global object is NULL or not. + */ + +STATIC INLINE boolean _Objects_MP_Is_null_global_object ( + Objects_MP_Control *the_object +); + +/* + * _Objects_MP_Open + * + * DESCRIPTION: + * + * This routine allocates a global object control block + * and places it in the specified information table. If the + * allocation fails, then is_fatal_error determines the + * error processing actions taken. + */ + +boolean _Objects_MP_Open ( + Objects_Information *information, + Objects_Name the_name, + Objects_Id the_id, + boolean is_fatal_error +); + +/* + * _Objects_MP_Close + * + * DESCRIPTION: + * + * This routine removes a global object from the specified + * information table and deallocates the global object control block. + */ + +void _Objects_MP_Close ( + Objects_Information *information, + Objects_Id the_id +); + +/* + * _Objects_MP_Global_name_search + * + * DESCRIPTION: + * + * This routine looks for the object with the_name in the global + * object tables indicated by information. It returns the ID of the + * object with that name if one is found. + */ + +rtems_status_code _Objects_MP_Global_name_search ( + Objects_Information *information, + Objects_Name the_name, + unsigned32 nodes_to_search, + Objects_Id *the_id +); + +/* + * _Objects_MP_Is_remote + * + * DESCRIPTION: + * + * This function searches the Global Object Table managed + * by information for the object indicated by ID. If the object + * is found, then location is set to objects_remote, otherwise + * location is set to objects_error. In both cases, the_object + * is undefined. + */ + +void _Objects_MP_Is_remote ( + Objects_Information *information, + Objects_Id the_id, + Objects_Locations *location, + Objects_Control **the_object +); + +/* + * The following chain header is used to manage the set of + * inactive global object control blocks. + */ + +EXTERN Chain_Control _Objects_MP_Inactive_global_objects; + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/priority.h b/cpukit/score/include/rtems/score/priority.h new file mode 100644 index 0000000000..823611b080 --- /dev/null +++ b/cpukit/score/include/rtems/score/priority.h @@ -0,0 +1,195 @@ +/* priority.h + * + * This include file contains all thread priority manipulation routines. + * This Handler provides mechanisms which can be used to + * initialize and manipulate RTEMS priorities. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_PRIORITY_h +#define __RTEMS_PRIORITY_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following type defines the control block used to manage + * thread priorities. + * + * NOTE: Priority 0 is reserved for internal threads only. + */ + +typedef unsigned32 rtems_task_priority; + +#define RTEMS_MINIMUM_PRIORITY 1 /* highest thread priority */ +#define RTEMS_MAXIMUM_PRIORITY 255 /* lowest thread priority */ + +/* + * The following record defines the information associated with + * each thread to manage its interaction with the priority bit maps. + */ + +typedef struct { + Priority_Bit_map_control *minor; /* addr of minor bit map slot */ + Priority_Bit_map_control ready_major; /* priority bit map ready mask */ + Priority_Bit_map_control ready_minor; /* priority bit map ready mask */ + Priority_Bit_map_control block_major; /* priority bit map block mask */ + Priority_Bit_map_control block_minor; /* priority bit map block mask */ +} Priority_Information; + +/* + * The following data items are the priority bit map. + * Each of the sixteen bits used in the _Priority_Major_bit_map is + * associated with one of the sixteen entries in the _Priority_Bit_map. + * Each bit in the _Priority_Bit_map indicates whether or not there are + * threads ready at a particular priority. The mapping of + * individual priority levels to particular bits is processor + * dependent as is the value of each bit used to indicate that + * threads are ready at that priority. + */ + +EXTERN volatile Priority_Bit_map_control _Priority_Major_bit_map; +EXTERN Priority_Bit_map_control _Priority_Bit_map[16] CPU_STRUCTURE_ALIGNMENT; + +/* + * The following constants are useful when manipulating priority. + */ + +#define RTEMS_CURRENT_PRIORITY 0 /* obtain current priority */ + +/* + * The definition of the Priority_Bit_map_control type is CPU dependent. + * + */ + +/* + * _Priority_Handler_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this handler. + */ + +STATIC INLINE void _Priority_Handler_initialization( void ); + +/* + * _Priority_Is_valid + * + * DESCRIPTION: + * + * This function returns TRUE if the_priority if valid for a + * user task, and FALSE otherwise. + */ + +STATIC INLINE boolean _Priority_Is_valid ( + rtems_task_priority the_priority +); + +/* + * _Priority_Major + * + * DESCRIPTION: + * + * This function returns the major portion of the_priority. + */ + +STATIC INLINE unsigned32 _Priority_Major ( + rtems_task_priority the_priority +); + +/* + * _Priority_Minor + * + * DESCRIPTION: + * + * This function returns the minor portion of the_priority. + */ + +STATIC INLINE unsigned32 _Priority_Minor ( + rtems_task_priority the_priority +); + +/* + * _Priority_Add_to_bit_map + * + * DESCRIPTION: + * + * This routine uses the_priority_map to update the priority + * bit maps to indicate that a thread has been readied. + */ + +STATIC INLINE void _Priority_Add_to_bit_map ( + Priority_Information *the_priority_map +); + +/* + * _Priority_Remove_from_bit_map + * + * DESCRIPTION: + * + * This routine uses the_priority_map to update the priority + * bit maps to indicate that a thread has been removed from the + * ready state. + */ + +STATIC INLINE void _Priority_Remove_from_bit_map ( + Priority_Information *the_priority_map +); + +/* + * _Priority_Get_highest + * + * DESCRIPTION: + * + * This function returns the priority of the highest priority + * ready thread. + */ + +STATIC INLINE rtems_task_priority _Priority_Get_highest( void ); + +/* + * _Priority_Initialize_information + * + * DESCRIPTION: + * + * This routine initializes the_priority_map so that it + * contains the information necessary to manage a thread + * at new_priority. + */ + +STATIC INLINE void _Priority_Initialize_information( + Priority_Information *the_priority_map, + rtems_task_priority new_priority +); + +/* + * _Priority_Is_group_empty + * + * DESCRIPTION: + * + * This function returns TRUE if the priority GROUP is empty, and + * FALSE otherwise. + */ + +STATIC INLINE boolean _Priority_Is_group_empty ( + rtems_task_priority the_priority +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/stack.h b/cpukit/score/include/rtems/score/stack.h new file mode 100644 index 0000000000..a0fce1ef04 --- /dev/null +++ b/cpukit/score/include/rtems/score/stack.h @@ -0,0 +1,95 @@ +/* stack.h + * + * This include file contains all information about the thread + * Stack Handler. This Handler provides mechanisms which can be used to + * initialize and utilize stacks. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_STACK_h +#define __RTEMS_STACK_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following constant defines the minimum stack size which every + * thread must exceed. + */ + +#define RTEMS_MINIMUM_STACK_SIZE CPU_STACK_MINIMUM_SIZE + +/* + * The following defines the control block used to manage each stack. + */ + +typedef struct { + unsigned32 size; /* stack size */ + void *area; /* low memory addr of stack */ +} Stack_Control; + +/* + * _Stack_Initialize + * + * DESCRIPTION: + * + * This routine initializes the_stack record to indicate that + * size bytes of memory starting at starting_address have been + * reserved for a stack. + */ + +STATIC INLINE void _Stack_Initialize ( + Stack_Control *the_stack, + void *starting_address, + unsigned32 size +); + +/* + * _Stack_Is_enough + * + * DESCRIPTION: + * + * This function returns TRUE if size bytes is enough memory for + * a valid stack area on this processor, and FALSE otherwise. + */ + +STATIC INLINE boolean _Stack_Is_enough ( + unsigned32 size +); + +/* + * _Stack_Adjust_size + * + * DESCRIPTION: + * + * This function increases the stack size to insure that the thread + * has the desired amount of stack space after the initial stack + * pointer is determined based on alignment restrictions. + * + * NOTE: + * + * The amount of adjustment for alignment is CPU dependent. + */ + +STATIC INLINE unsigned32 _Stack_Adjust_size ( + unsigned32 size +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/states.h b/cpukit/score/include/rtems/score/states.h new file mode 100644 index 0000000000..56f67ecc49 --- /dev/null +++ b/cpukit/score/include/rtems/score/states.h @@ -0,0 +1,337 @@ +/* states.h + * + * This include file contains all RTEMS state information. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_STATES_h +#define __RTEMS_STATES_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following type defines the control block used to manage a + * thread's state. + */ + +typedef unsigned32 States_Control; + +/* + * The following constants define the individual states which may be + * be used to compose and manipulate a thread's state. + */ + +#define STATES_ALL_SET 0xffff /* all states */ +#define STATES_READY 0x0000 /* ready to run */ +#define STATES_DORMANT 0x0001 /* created but not started */ +#define STATES_SUSPENDED 0x0002 /* waiting to be resumed */ +#define STATES_TRANSIENT 0x0004 /* thread in transition */ +#define STATES_DELAYING 0x0008 /* wait for timeout */ +#define STATES_WAITING_FOR_BUFFER 0x0010 /* wait for partition buffer */ +#define STATES_WAITING_FOR_SEGMENT 0x0020 /* wait for region segment */ +#define STATES_WAITING_FOR_MESSAGE 0x0040 /* wait for message */ +#define STATES_WAITING_FOR_EVENT 0x0080 /* wait for event */ +#define STATES_WAITING_FOR_SEMAPHORE 0x0100 /* wait for semaphore */ +#define STATES_WAITING_FOR_TIME 0x0200 /* wait for specific TOD */ +#define STATES_WAITING_FOR_RPC_REPLY 0x0400 /* wait for rpc reply */ +#define STATES_WAITING_FOR_PERIOD 0x0800 /* rate monotonic delay */ + +#define STATES_LOCALLY_BLOCKED ( STATES_WAITING_FOR_BUFFER | \ + STATES_WAITING_FOR_SEGMENT | \ + STATES_WAITING_FOR_MESSAGE | \ + STATES_WAITING_FOR_SEMAPHORE ) + +#define STATES_WAITING_ON_THREAD_QUEUE \ + ( STATES_LOCALLY_BLOCKED | \ + STATES_WAITING_FOR_RPC_REPLY ) + +#define STATES_BLOCKED ( STATES_DELAYING | \ + STATES_WAITING_FOR_TIME | \ + STATES_WAITING_FOR_PERIOD | \ + STATES_WAITING_FOR_EVENT | \ + STATES_WAITING_ON_THREAD_QUEUE ) + +/* + * _States_Set + * + * DESCRIPTION: + * + * This function sets the given states_to_set into the current_state + * passed in. The result is returned to the user in current_state. + */ + +STATIC INLINE States_Control _States_Set ( + States_Control states_to_set, + States_Control current_state +); + +/* + * _States_Clear + * + * DESCRIPTION: + * + * This function clears the given states_to_clear into the current_state + * passed in. The result is returned to the user in current_state. + */ + +STATIC INLINE States_Control _States_Clear ( + States_Control states_to_clear, + States_Control current_state +); + +/* + * _States_Is_ready + * + * DESCRIPTION: + * + * This function returns TRUE if the_states indicates that the + * state is READY, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_ready ( + States_Control the_states +); + +/* + * _States_Is_only_dormant + * + * DESCRIPTION: + * + * This function returns TRUE if the DORMANT state is the ONLY state + * set in the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_only_dormant ( + States_Control the_states +); + +/* + * _States_Is_dormant + * + * DESCRIPTION: + * + * This function returns TRUE if the DORMANT state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_dormant ( + States_Control the_states +); + +/* + * _States_Is_suspended + * + * DESCRIPTION: + * + * This function returns TRUE if the SUSPENDED state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_suspended ( + States_Control the_states +); + +/* + * _States_Is_Transient + * + * DESCRIPTION: + * + * This function returns TRUE if the TRANSIENT state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_transient ( + States_Control the_states +); + +/* + * _States_Is_delaying + * + * DESCRIPTION: + * + * This function returns TRUE if the DELAYING state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_delaying ( + States_Control the_states +); + +/* + * _States_Is_waiting_for_buffer + * + * DESCRIPTION: + * + * This function returns TRUE if the WAITING_FOR_BUFFER state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_waiting_for_buffer ( + States_Control the_states +); + +/* + * _States_Is_waiting_for_segment + * + * DESCRIPTION: + * + * This function returns TRUE if the WAITING_FOR_SEGMENT state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_waiting_for_segment ( + States_Control the_states +); + +/* + * _States_Is_waiting_for_message + * + * DESCRIPTION: + * + * This function returns TRUE if the WAITING_FOR_MESSAGE state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_waiting_for_message ( + States_Control the_states +); + +/* + * _States_Is_waiting_for_event + * + * DESCRIPTION: + * + * This function returns TRUE if the WAITING_FOR_EVENT state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_waiting_for_event ( + States_Control the_states +); + +/* + * _States_Is_waiting_for_semaphore + * + * DESCRIPTION: + * + * This function returns TRUE if the WAITING_FOR_SEMAPHORE state + * is set in the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_waiting_for_semaphore ( + States_Control the_states +); + +/* + * _States_Is_waiting_for_time + * + * DESCRIPTION: + * + * This function returns TRUE if the WAITING_FOR_TIME state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_waiting_for_time ( + States_Control the_states +); + +/* + * _States_Is_waiting_for_rpc_reply + * + * DESCRIPTION: + * + * This function returns TRUE if the WAITING_FOR_TIME state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_waiting_for_rpc_reply ( + States_Control the_states +); + +/* + * _States_Is_waiting_for_period + * + * DESCRIPTION: + * + * This function returns TRUE if the WAITING_FOR_PERIOD state is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_waiting_for_period ( + States_Control the_states +); + +/* + * _States_Is_locally_blocked + * + * DESCRIPTION: + * + * This function returns TRUE if one of the states which indicates + * that a task is blocked waiting for a local resource is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_locally_blocked ( + States_Control the_states +); + +/* + * _States_Is_waiting_on_thread_queue + * + * DESCRIPTION: + * + * This function returns TRUE if one of the states which indicates + * that a task is blocked waiting for a local resource is set in + * the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_waiting_on_thread_queue ( + States_Control the_states +); + +/* + * _States_Is_blocked + * + * DESCRIPTION: + * + * This function returns TRUE if one of the states which indicates + * that a task is blocked is set in the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Is_blocked ( + States_Control the_states +); + +/* + * _States_Are_set + * + * DESCRIPTION: + * + * This function returns TRUE if any of the states in the mask + * are set in the_states, and FALSE otherwise. + */ + +STATIC INLINE boolean _States_Are_set ( + States_Control the_states, + States_Control mask +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/sysstate.h b/cpukit/score/include/rtems/score/sysstate.h new file mode 100644 index 0000000000..511a26cefc --- /dev/null +++ b/cpukit/score/include/rtems/score/sysstate.h @@ -0,0 +1,143 @@ +/* sysstates.h + * + * This include file contains information regarding the system state. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_SYSTEM_STATE_h +#define __RTEMS_SYSTEM_STATE_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* types */ + +/* enumerated constants */ + +/* + * The following type defines the possible system states. + */ + +typedef enum { + SYSTEM_STATE_BEFORE_INITIALIZATION, /* start -> end of 1st init part */ + SYSTEM_STATE_BEFORE_MULTITASKING, /* end of 1st -> beginning of 2nd */ + SYSTEM_STATE_BEGIN_MULTITASKING, /* beginning of 2nd -> end of SYSI */ + SYSTEM_STATE_UP, /* normal operation */ + SYSTEM_STATE_FAILED /* fatal error occurred */ +} System_state_Codes; + +#define SYSTEM_STATE_CODES_FIRST SYSTEM_STATE_BEFORE_INITIALIZATION +#define SYSTEM_STATE_CODES_LAST SYSTEM_STATE_FAILED + +/* + * The following variable contains the current system state. + */ + +EXTERN System_state_Codes _System_state_Current; + +/* + * _System_state_Set + * + * DESCRIPTION: + * + * This routine sets the current system state to that specified by + * the called. + */ + +STATIC INLINE void _System_state_Set ( + System_state_Codes state +); + +/* + * _System_state_Get + * + * DESCRIPTION: + * + * This function returns the current system state. + */ + +STATIC INLINE System_state_Codes _System_state_Get ( void ); + +/* + * _System_state_Is_before_initialization + * + * DESCRIPTION: + * + * This function returns TRUE if the state is equal to the + * "before initialization" state, and FALSE otherwise. + */ + +STATIC INLINE boolean _System_state_Is_before_initialization ( + System_state_Codes state +); + +/* + * _System_state_Is_before_multitasking + * + * DESCRIPTION: + * + * This function returns TRUE if the state is equal to the + * "before multitasking" state, and FALSE otherwise. + */ + +STATIC INLINE boolean _System_state_Is_before_multitasking ( + System_state_Codes state +); + +/* + * _System_state_Is_begin_multitasking + * + * DESCRIPTION: + * + * This function returns TRUE if the state is equal to the + * "begin multitasking" state, and FALSE otherwise. + */ + +STATIC INLINE boolean _System_state_Is_begin_multitasking ( + System_state_Codes state +); + +/* + * _System_state_Is_up + * + * DESCRIPTION: + * + * This function returns TRUE if the state is equal to the + * "up" state, and FALSE otherwise. + */ + +STATIC INLINE boolean _System_state_Is_up ( + System_state_Codes state +); + +/* + * _System_state_Is_failed + * + * DESCRIPTION: + * + * This function returns TRUE if the state is equal to the + * "failed" state, and FALSE otherwise. + */ + +STATIC INLINE boolean _System_state_Is_failed ( + System_state_Codes state +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h new file mode 100644 index 0000000000..de07a721ef --- /dev/null +++ b/cpukit/score/include/rtems/score/thread.h @@ -0,0 +1,721 @@ +/* thread.h + * + * This include file contains all constants and structures associated + * with the thread control block. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_THREAD_h +#define __RTEMS_THREAD_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Notepads constants (indices into notepad array) + */ + +#define RTEMS_NOTEPAD_FIRST 0 /* lowest numbered notepad */ +#define RTEMS_NOTEPAD_0 0 /* notepad location 0 */ +#define RTEMS_NOTEPAD_1 1 /* notepad location 1 */ +#define RTEMS_NOTEPAD_2 2 /* notepad location 2 */ +#define RTEMS_NOTEPAD_3 3 /* notepad location 3 */ +#define RTEMS_NOTEPAD_4 4 /* notepad location 4 */ +#define RTEMS_NOTEPAD_5 5 /* notepad location 5 */ +#define RTEMS_NOTEPAD_6 6 /* notepad location 6 */ +#define RTEMS_NOTEPAD_7 7 /* notepad location 7 */ +#define RTEMS_NOTEPAD_8 8 /* notepad location 8 */ +#define RTEMS_NOTEPAD_9 9 /* notepad location 9 */ +#define RTEMS_NOTEPAD_10 10 /* notepad location 10 */ +#define RTEMS_NOTEPAD_11 11 /* notepad location 11 */ +#define RTEMS_NOTEPAD_12 12 /* notepad location 12 */ +#define RTEMS_NOTEPAD_13 13 /* notepad location 13 */ +#define RTEMS_NOTEPAD_14 14 /* notepad location 14 */ +#define RTEMS_NOTEPAD_15 15 /* notepad location 15 */ +#define RTEMS_NOTEPAD_LAST RTEMS_NOTEPAD_15 /* highest numbered notepad */ + +/* + * The following defines the "return type" of an RTEMS thread. + * + * NOTE: Keep both types for internal threads. + */ + +typedef void rtems_task; +typedef void Thread; + +/* + * The following defines the argument to an RTEMS thread. + */ + +typedef unsigned32 rtems_task_argument; +typedef unsigned32 Thread_Argument; + +/* + * The following defines the type for the entry point of an RTEMS thread. + */ + +typedef rtems_task ( *rtems_task_entry )( + rtems_task_argument + ); + +typedef Thread ( *Thread_Entry )( + Thread_Argument + ); + +/* + * The following structure contains the information which defines + * the starting state of a thread. + */ + +typedef struct { + Thread_Entry entry_point; /* starting thread address */ + unsigned32 initial_argument; /* initial argument */ + rtems_mode initial_modes; /* initial mode */ + rtems_task_priority initial_priority; /* initial priority */ + void *fp_context; /* initial FP context area address */ + Stack_Control Initial_stack; /* stack information */ +} Thread_Start_information; + +/* + * The following structure contains the information necessary to manage + * a thread which it is waiting for a resource. + */ + +typedef struct { + Objects_Id id; /* waiting on this object */ + rtems_option option_set; /* wait mode */ + union { + unsigned32 segment_size; /* size of segment requested */ + rtems_event_set event_condition; + } Extra; + void *return_argument; /* address of user return param */ + rtems_status_code return_code; /* status for thread awakened */ + Chain_Control Block2n; /* 2 - n priority blocked chain */ + Thread_queue_Control *queue; /* pointer to thread queue */ +} Thread_Wait_information; + +/* + * The following defines the control block used to manage + * each thread proxy. + * + * NOTE: It is critical that proxies and threads have identical + * memory images for the shared part. + */ + +typedef struct { + Objects_Control Object; + Objects_Name name; + States_Control current_state; + rtems_task_priority current_priority; + rtems_task_priority real_priority; + unsigned32 resource_count; + Thread_Wait_information Wait; + Watchdog_Control Timer; + rtems_packet_prefix *receive_packet; + /****************** end of common block ********************/ + Chain_Node Active; +} Thread_Proxy_control; + + +/* + * The following record defines the control block used + * to manage each thread. + * + * NOTE: It is critical that proxies and threads have identical + * memory images for the shared part. + */ + +typedef struct { + Objects_Control Object; + Objects_Name name; + States_Control current_state; + rtems_task_priority current_priority; + rtems_task_priority real_priority; + unsigned32 resource_count; + Thread_Wait_information Wait; + Watchdog_Control Timer; + rtems_packet_prefix *receive_packet; + /****************** end of common block ********************/ + Chain_Control *ready; + Priority_Information Priority_map; + rtems_event_set pending_events; + rtems_event_set events_out; + Thread_Start_information Start; + ASR_Information Signal; + rtems_mode current_modes; + rtems_attribute attribute_set; + Context_Control Registers; + void *fp_context; + unsigned32 Notepads[ 16 ]; + void *extension; +} Thread_Control; + +/* + * External API name for Thread_Control + */ + +typedef Thread_Control rtems_tcb; + +/* + * The following declares the dispatch critical section nesting + * counter which is used to prevent context switches at inopportune + * moments. + */ + +EXTERN unsigned32 _Thread_Dispatch_disable_level; + +/* + * The following data items are used to manage timeslicing. + */ + +EXTERN unsigned32 _Thread_Ticks_remaining_in_timeslice; +EXTERN unsigned32 _Thread_Ticks_per_timeslice; + +/* + * The following points to the array of FIFOs used to manage the + * set of ready threads. + */ + +EXTERN Chain_Control *_Thread_Ready_chain; + +/* + * The following points to the thread which is currently executing. + * This thread is implicitly manipulated by numerous directives. + */ + +EXTERN Thread_Control *_Thread_Executing; + +/* + * The following points to the highest priority ready thread + * in the system. Unless the current thread is RTEMS_NO_PREEMPT, + * then this thread will be context switched to when the next + * dispatch occurs. + */ + +EXTERN Thread_Control *_Thread_Heir; + +/* + * The following points to the thread whose floating point + * context is currently loaded. + */ + +EXTERN Thread_Control *_Thread_Allocated_fp; + +/* + * The following defines the information control block used to + * manage this class of objects. + */ + +EXTERN Objects_Information _Thread_Information; + +/* + * The following context area contains the context of the "thread" + * which invoked rtems_initialize_executive. This context is restored + * as the last action of the rtems_shutdown_executive directive. Thus + * control of the processor can be returned to the environment + * which initiated RTEMS. + */ + +EXTERN Context_Control _Thread_BSP_context; + +/* + * _Thread_Handler_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this handler. + */ + +void _Thread_Handler_initialization ( + unsigned32 maximum_tasks, + unsigned32 ticks_per_timeslice, + unsigned32 maximum_proxies +); + +/* + * _Thread_Start_multitasking + * + * DESCRIPTION: + * + * This routine initiates multitasking. It is invoked only as + * part of initialization and its invocation is the last act of + * the rtems_initialize_executive directive. + */ + +void _Thread_Start_multitasking ( + Thread_Control *system_thread, + Thread_Control *idle_thread +); + +/* + * _Thread_Stop_multitasking + * + * DESCRIPTION: + * + * This routine halts multitasking and returns control to + * the "thread" which initially invoked the rtems_initialize_executive + * directive. + */ + +STATIC INLINE void _Thread_Stop_multitasking( void ); + +/* + * _Thread_Dispatch_initialization + * + * DESCRIPTION: + * + * This routine initializes the thread dispatching subsystem. + */ + +STATIC INLINE void _Thread_Dispatch_initialization( void ); + +/* + * _Thread_Dispatch + * + * DESCRIPTION: + * + * This routine is responsible for transferring control of the + * processor from the executing thread to the heir thread. As part + * of this process, it is responsible for the following actions: + * + * + saving the context of the executing thread + * + restoring the context of the heir thread + * + dispatching any signals for the resulting executing thread + */ + +void _Thread_Dispatch( void ); + +/* + * _Thread_Ready + * + * DESCRIPTION: + * + * This routine removes any set states for the_thread. It performs + * any necessary scheduling operations including the selection of + * a new heir thread. + */ + +void _Thread_Ready( + Thread_Control *the_thread +); + +/* + * _Thread_Clear_state + * + * DESCRIPTION: + * + * This routine clears the indicated STATES for the_thread. It performs + * any necessary scheduling operations including the selection of + * a new heir thread. + */ + +void _Thread_Clear_state( + Thread_Control *the_thread, + States_Control state +); + +/* + * _Thread_Set_state + * + * DESCRIPTION: + * + * This routine sets the indicated states for the_thread. It performs + * any necessary scheduling operations including the selection of + * a new heir thread. + * + */ + +void _Thread_Set_state( + Thread_Control *the_thread, + States_Control state +); + +/* + * _Thread_Set_transient + * + * DESCRIPTION: + * + * This routine sets the TRANSIENT state for the_thread. It performs + * any necessary scheduling operations including the selection of + * a new heir thread. + */ + +void _Thread_Set_transient( + Thread_Control *the_thread +); + +/* + * _Thread_Reset_timeslice + * + * DESCRIPTION: + * + * This routine is invoked upon expiration of the currently + * executing thread's timeslice. If no other thread's are ready + * at the priority of the currently executing thread, then the + * executing thread's timeslice is reset. Otherwise, the + * currently executing thread is placed at the rear of the + * RTEMS_FIFO for this priority and a new heir is selected. + */ + +void _Thread_Reset_timeslice( void ); + +/* + * _Thread_Tickle_timeslice + * + * DESCRIPTION: + * + * This routine is invoked as part of processing each clock tick. + * It is responsible for determining if the current thread allows + * timeslicing and, if so, when its timeslice expires. + */ + +void _Thread_Tickle_timeslice( void ); + +/* + * _Thread_Yield_processor + * + * DESCRIPTION: + * + * This routine is invoked when a thread wishes to voluntarily + * transfer control of the processor to another thread of equal + * or greater priority. + */ + +void _Thread_Yield_processor( void ); + +/* + * _Thread_Is_executing + * + * DESCRIPTION: + * + * This function returns TRUE if the_thread is the currently executing + * thread, and FALSE otherwise. + */ + +STATIC INLINE boolean _Thread_Is_executing ( + Thread_Control *the_thread +); + +/* + * _Thread_Is_heir + * + * DESCRIPTION: + * + * This function returns TRUE if the_thread is the heir + * thread, and FALSE otherwise. + */ + +STATIC INLINE boolean _Thread_Is_executing ( + Thread_Control *the_thread +); + +/* + * _Thread_Is_executing_also_the_heir + * + * DESCRIPTION: + * + * This function returns TRUE if the currently executing thread + * is also the heir thread, and FALSE otherwise. + */ + +STATIC INLINE boolean _Thread_Is_executing_also_the_heir( void ); + +/* + * _Thread_Load_environment + * + * DESCRIPTION: + * + * This routine initializes the context of the_thread to its + * appropriate starting state. + */ + +void _Thread_Load_environment( + Thread_Control *the_thread +); + +/* + * _Thread_Handler + * + * DESCRIPTION: + * + * This routine is the wrapper function for all threads. It is + * the starting point for all threads. The user provided thread + * entry point is invoked by this routine. Operations + * which must be performed immediately before and after the user's + * thread executes are found here. + */ + +void _Thread_Handler( void ); + +/* + * _Thread_Delay_ended + * + * DESCRIPTION: + * + * This routine is invoked when a thread must be unblocked at the + * end of a delay such as the rtems_task_wake_after and rtems_task_wake_when + * directives. + */ + +void _Thread_Delay_ended( + Objects_Id id, + void *ignored +); + +/* + * _Thread_Change_priority + * + * DESCRIPTION: + * + * This routine changes the current priority of the_thread to + * new_priority. It performs any necessary scheduling operations + * including the selection of a new heir thread. + */ + +void _Thread_Change_priority ( + Thread_Control *the_thread, + rtems_task_priority new_priority +); + +/* + * _Thread_Set_priority + * + * DESCRIPTION: + * + * This routine updates the priority related fields in the_thread + * control block to indicate the current priority is now new_priority. + */ + +void _Thread_Set_priority( + Thread_Control *the_thread, + rtems_task_priority new_priority +); + +/* + * _Thread_Change_mode + * + * DESCRIPTION: + * + * This routine changes the current values of the modes + * indicated by mask of the calling thread are changed to that + * indicated in mode_set. The former mode of the thread is + * returned in mode_set. If the changes in the current mode + * indicate that a thread dispatch operation may be necessary, + * then need_dispatch is TRUE, otherwise it is FALSE. + */ + +boolean _Thread_Change_mode( + rtems_mode new_mode_set, + rtems_mode mask, + rtems_mode *old_mode_set +); + +/* + * _Thread_Resume + * + * DESCRIPTION: + * + * This routine clears the SUSPENDED state for the_thread. It performs + * any necessary scheduling operations including the selection of + * a new heir thread. + */ + +STATIC INLINE void _Thread_Resume ( + Thread_Control *the_thread +); + +/* + * _Thread_Unblock + * + * DESCRIPTION: + * + * This routine clears any blocking state for the_thread. It performs + * any necessary scheduling operations including the selection of + * a new heir thread. + */ + +STATIC INLINE void _Thread_Unblock ( + Thread_Control *the_thread +); + +/* + * _Thread_Restart_self + * + * DESCRIPTION: + * + * This routine resets the current context of the calling thread + * to that of its initial state. + */ + +STATIC INLINE void _Thread_Restart_self( void ); + +/* + * _Thread_Calculate_heir + * + * DESCRIPTION: + * + * This function returns a pointer to the highest priority + * ready thread. + */ + +STATIC INLINE void _Thread_Calculate_heir( void ); + +/* + * _Thread_Is_allocated_fp + * + * DESCRIPTION: + * + * This function returns TRUE if the floating point context of + * the_thread is currently loaded in the floating point unit, and + * FALSE otherwise. + */ + +STATIC INLINE boolean _Thread_Is_allocated_fp ( + Thread_Control *the_thread +); + +/* + * _Thread_Deallocate_fp + * + * DESCRIPTION: + * + * This routine is invoked when the currently loaded floating + * point context is now longer associated with an active thread. + */ + +STATIC INLINE void _Thread_Deallocate_fp( void ); + +/* + * _Thread_Disable_dispatch + * + * DESCRIPTION: + * + * This routine prevents dispatching. + */ + +STATIC INLINE void _Thread_Disable_dispatch( void ); + +/* + * _Thread_Enable_dispatch + * + * DESCRIPTION: + * + * This routine allows dispatching to occur again. If this is + * the outer most dispatching critical section, then a dispatching + * operation will be performed and, if necessary, control of the + * processor will be transferred to the heir thread. + */ + +#if ( CPU_INLINE_ENABLE_DISPATCH == TRUE ) + +STATIC INLINE void _Thread_Enable_dispatch(); + +#endif + +#if ( CPU_INLINE_ENABLE_DISPATCH == FALSE ) + +void _Thread_Enable_dispatch( void ); + +#endif + +/* + * _Thread_Unnest_dispatch + * + * DESCRIPTION: + * + * This routine allows dispatching to occur again. However, + * no dispatching operation is performed even if this is the outer + * most dispatching critical section. + */ + +STATIC INLINE void _Thread_Unnest_dispatch( void ); + +/* + * _Thread_Is_dispatching_enabled + * + * DESCRIPTION: + * + * This function returns TRUE if dispatching is disabled, and FALSE + * otherwise. + */ + +STATIC INLINE boolean _Thread_Is_dispatching_enabled( void ); + +/* + * _Thread_Is_context_switch_necessary + * + * DESCRIPTION: + * + * This function returns TRUE if dispatching is disabled, and FALSE + * otherwise. + */ + +STATIC INLINE boolean _Thread_Is_context_switch_necessary( void ); + +/* + * _Thread_Is_null + * + * DESCRIPTION: + * + * This function returns TRUE if the_thread is NULL and FALSE otherwise. + */ + +STATIC INLINE boolean _Thread_Is_null ( + Thread_Control *the_thread +); + +/* + * _Thread_Get + * + * DESCRIPTION: + * + * This function maps thread IDs to thread control + * blocks. If ID corresponds to a local thread, then it + * returns the_thread control pointer which maps to ID + * and location is set to OBJECTS_LOCAL. If the thread ID is + * global and resides on a remote node, then location is set + * to OBJECTS_REMOTE, and the_thread is undefined. + * Otherwise, location is set to OBJECTS_ERROR and + * the_thread is undefined. + */ + +STATIC INLINE Thread_Control *_Thread_Get ( + Objects_Id id, + Objects_Locations *location +); + +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/threadmp.h b/cpukit/score/include/rtems/score/threadmp.h new file mode 100644 index 0000000000..c6e8252030 --- /dev/null +++ b/cpukit/score/include/rtems/score/threadmp.h @@ -0,0 +1,134 @@ +/* threadmp.h + * + * This include file contains the specification for all routines + * and data specific to the multiprocessing portion of the thread package. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_THREAD_MP_h +#define __RTEMS_THREAD_MP_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * _Thread_MP_Handler_initialization + * + * DESCRIPTION: + * + * This package is the specification for the Thread Handler's + * multiprocessing specific support routines. + */ + +void _Thread_MP_Handler_initialization ( + unsigned32 maximum_proxies +); + +/* + * _Thread_MP_Is_receive + * + * DESCRIPTION: + * + * This function returns true if the thread in question is the + * multiprocessing receive thread. + */ + +STATIC INLINE boolean _Thread_MP_Is_receive ( + Thread_Control *the_thread +); + +/* + * _Thread_MP_Allocate_proxy + * + * DESCRIPTION: + * + * This allocates a proxy control block from + * the inactive chain of free proxy control blocks. + * + * NOTE: This function returns a thread control pointer + * because proxies are substitutes for remote threads. + */ + +Thread_Control *_Thread_MP_Allocate_proxy ( + States_Control the_state +); + +/* + * _Thread_MP_Free_proxy + * + * DESCRIPTION: + * + * This routine frees a proxy control block to the + * inactive chain of free proxy control blocks. + */ + +STATIC INLINE void _Thread_MP_Free_proxy ( + Thread_Control *the_thread +); + +/* + * _Thread_MP_Find_proxy + * + * DESCRIPTION: + * + * This function removes the proxy control block for the specified + * id from the active chain of proxy control blocks. + */ + +Thread_Control *_Thread_MP_Find_proxy ( + Objects_Id the_id +); + +/* + * _Thread_MP_Block + * + * DESCRIPTION: + * + * This routine blocks the MP Receive server thread. + */ + +void _Thread_MP_Block( void ); + +/* + * _Thread_MP_Ready + * + * DESCRIPTION: + * + * This routine readies the MP Receive server thread. + */ + +void _Thread_MP_Ready( void ); + +/* + * The following is used to determine when the multiprocessing receive + * thread is executing so that a proxy can be allocated instead of + * blocking the multiprocessing receive thread. + */ + +EXTERN Thread_Control *_Thread_MP_Receive; + +/* + * The following chains are used to manage proxies. + */ + +EXTERN Chain_Control _Thread_MP_Active_proxies; +EXTERN Chain_Control _Thread_MP_Inactive_proxies; + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/threadq.h b/cpukit/score/include/rtems/score/threadq.h new file mode 100644 index 0000000000..291044ead1 --- /dev/null +++ b/cpukit/score/include/rtems/score/threadq.h @@ -0,0 +1,264 @@ +/* threadq.h + * + * This include file contains all the constants and structures associated + * with the manipulation of objects. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_THREAD_QUEUE_h +#define __RTEMS_THREAD_QUEUE_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include +#include + +/* + * The following type defines the callout used when a remote task + * is extracted from a local thread queue. + */ + +typedef void ( *Thread_queue_Flush_callout )( + Thread_Control * + ); + +/* + * _Thread_queue_Dequeue + * + * DESCRIPTION: + * + * This function returns a pointer to a thread waiting on + * the_thread_queue. The selection of this thread is based on + * the discipline of the_thread_queue. If no threads are waiting + * on the_thread_queue, then NULL is returned. + */ + +Thread_Control *_Thread_queue_Dequeue( + Thread_queue_Control *the_thread_queue +); + +/* + * _Thread_queue_Enqueue + * + * DESCRIPTION: + * + * This routine enqueues the currently executing thread on + * the_thread_queue with an optional timeout. + */ + +void _Thread_queue_Enqueue( + Thread_queue_Control *the_thread_queue, + rtems_interval timeout +); + +/* + * _Thread_queue_Extract + * + * DESCRIPTION: + * + * This routine removes the_thread from the_thread_queue + * and cancels any timeouts associated with this blocking. + */ + +void _Thread_queue_Extract( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread +); + +/* + * _Thread_queue_First + * + * DESCRIPTION: + * + * This function returns a pointer to the "first" thread + * on the_thread_queue. The "first" thread is selected + * based on the discipline of the_thread_queue. + */ + +Thread_Control *_Thread_queue_First( + Thread_queue_Control *the_thread_queue +); + +/* + * _Thread_queue_Flush + * + * DESCRIPTION: + * + * This routine unblocks all threads blocked on the_thread_queue + * and cancels any associated timeouts. + */ + +void _Thread_queue_Flush( + Thread_queue_Control *the_thread_queue, + Thread_queue_Flush_callout remote_extract_callout +); + +/* + * _Thread_queue_Initialize + * + * DESCRIPTION: + * + * This routine initializes the_thread_queue based on the + * discipline indicated in attribute_set. The state set on + * threads which block on the_thread_queue is state. + */ + +void _Thread_queue_Initialize( + Thread_queue_Control *the_thread_queue, + rtems_attribute attribute_set, + States_Control state +); + +/* + * _Thread_queue_Dequeue_priority + * + * DESCRIPTION: + * + * This function returns a pointer to the highest priority + * thread waiting on the_thread_queue. If no threads are waiting + * on the_thread_queue, then NULL is returned. + */ + +Thread_Control *_Thread_queue_Dequeue_priority( + Thread_queue_Control *the_thread_queue +); + +/* + * _Thread_queue_Enqueue_priority + * + * DESCRIPTION: + * + * This routine enqueues the currently executing thread on + * the_thread_queue with an optional timeout using the + * priority discipline. + */ + +void _Thread_queue_Enqueue_priority( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread, + rtems_interval timeout +); + +/* + * _Thread_queue_Extract_priority + * + * DESCRIPTION: + * + * This routine removes the_thread from the_thread_queue + * and cancels any timeouts associated with this blocking. + */ + +void _Thread_queue_Extract_priority( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread +); + +/* + * _Thread_queue_First_priority + * + * DESCRIPTION: + * + * This function returns a pointer to the "first" thread + * on the_thread_queue. The "first" thread is the highest + * priority thread waiting on the_thread_queue. + */ + +Thread_Control *_Thread_queue_First_priority( + Thread_queue_Control *the_thread_queue +); + +/* + * _Thread_queue_Dequeue_FIFO + * + * DESCRIPTION: + * + * This function returns a pointer to the thread which has + * been waiting the longest on the_thread_queue. If no + * threads are waiting on the_thread_queue, then NULL is returned. + */ + +Thread_Control *_Thread_queue_Dequeue_fifo( + Thread_queue_Control *the_thread_queue +); + +/* + * _Thread_queue_Enqueue_FIFO + * + * DESCRIPTION: + * + * This routine enqueues the currently executing thread on + * the_thread_queue with an optional timeout using the + * RTEMS_FIFO discipline. + */ + +void _Thread_queue_Enqueue_fifo( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread, + rtems_interval timeout +); + +/* + * _Thread_queue_Extract_FIFO + * + * DESCRIPTION: + * + * This routine removes the_thread from the_thread_queue + * and cancels any timeouts associated with this blocking. + */ + +void _Thread_queue_Extract_fifo( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread +); + +/* + * _Thread_queue_First_FIFO + * + * DESCRIPTION: + * + * This function returns a pointer to the "first" thread + * on the_thread_queue. The first thread is the thread + * which has been waiting longest on the_thread_queue. + */ + +Thread_Control *_Thread_queue_First_fifo( + Thread_queue_Control *the_thread_queue +); + +/* + * _Thread_queue_timeout + * + * DESCRIPTION: + * + * This routine is invoked when a task's request has not + * been satisfied after the timeout interval specified to + * enqueue. The task represented by ID will be unblocked and + * its status code will be set in it's control block to indicate + * that a timeout has occurred. + */ + +void _Thread_queue_Timeout ( + Objects_Id id, + void *ignored +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/tod.h b/cpukit/score/include/rtems/score/tod.h new file mode 100644 index 0000000000..ae7e2b9747 --- /dev/null +++ b/cpukit/score/include/rtems/score/tod.h @@ -0,0 +1,300 @@ +/* tod.h + * + * This include file contains all the constants and structures associated + * with the Time of Day Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_TIME_OF_DAY_h +#define __RTEMS_TIME_OF_DAY_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + * The following constants are related to the time of day. + */ + +#define TOD_SECONDS_PER_MINUTE 60 +#define TOD_MINUTES_PER_HOUR 60 +#define TOD_MONTHS_PER_YEAR 12 +#define TOD_DAYS_PER_YEAR 365 +#define TOD_HOURS_PER_DAY 24 +#define TOD_SECONDS_PER_DAY (TOD_SECONDS_PER_MINUTE * \ + TOD_MINUTES_PER_HOUR * \ + TOD_HOURS_PER_DAY) + +#define TOD_MICROSECONDS_PER_SECOND 1000000 +#define TOD_MILLISECONDS_PER_SECOND 1000 + +/* + * The following constant define the earliest year to which an + * RTEMS time of day can be initialized. This is considered the + * epoch. + */ + +#define TOD_BASE_YEAR 1988 + +/* + * The following record defines the time of control block. This + * control block is used to maintain the current time of day. + */ + +typedef struct { /* RTEID style time/date */ + unsigned32 year; /* year, A.D. */ + unsigned32 month; /* month, 1 -> 12 */ + unsigned32 day; /* day, 1 -> 31 */ + unsigned32 hour; /* hour, 0 -> 23 */ + unsigned32 minute; /* minute, 0 -> 59 */ + unsigned32 second; /* second, 0 -> 59 */ + unsigned32 ticks; /* elapsed ticks between secs */ +} rtems_time_of_day; + +/* + * The following contains the current time of day. + */ + +EXTERN rtems_time_of_day _TOD_Current; + +/* + * The following contains the number of seconds from 00:00:00 + * January 1, TOD_BASE_YEAR until the current time of day. + */ + +EXTERN rtems_interval _TOD_Seconds_since_epoch; + +/* + * The following contains the number of ticks since the + * system was booted. + */ + +EXTERN rtems_interval _TOD_Ticks_since_boot; + +/* + * The following contains the number of microseconds per tick. + */ + +EXTERN unsigned32 _TOD_Microseconds_per_tick; + +/* + * The following contains the number of clock ticks per second. + * + * NOTE: + * + * If one second is NOT evenly divisible by the number of microseconds + * per clock tick, this value will contain only the integer portion + * of the division. This means that the interval between clock ticks + * can be a source of error in the current time of day. + */ + +EXTERN unsigned32 _TOD_Ticks_per_second; + +/* + * This is the control structure for the watchdog timer which + * fires to service the seconds chain. + */ + +EXTERN Watchdog_Control _TOD_Seconds_watchdog; + +#ifdef INIT + +/* + * The following array contains the number of days in all months. + * The first dimension should be 1 for leap years, and 0 otherwise. + * The second dimension should range from 1 to 12 for January to + * February, respectively. + */ + +const unsigned32 _TOD_Days_per_month[ 2 ][ 13 ] = { + { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +}; + +/* + * The following array contains the number of days in all months + * up to the month indicated by the index of the second dimension. + * The first dimension should be 1 for leap years, and 0 otherwise. + */ + +const unsigned16 _TOD_Days_to_date[2][13] = { + { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }, + { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 } +}; + +/* + * The following array contains the number of days in the years + * since the last leap year. The index should be 0 for leap + * years, and the number of years since the beginning of a leap + * year otherwise. + */ + +const unsigned16 _TOD_Days_since_last_leap_year[4] = { 0, 366, 761, 1126 }; + +#else + +extern const unsigned16 _TOD_Days_to_date[2][13]; /* Julian days */ +extern const unsigned16 _TOD_Days_since_last_leap_year[4]; +extern const unsigned32 _TOD_Days_per_month[2][13]; + +#endif + +/* + * _TOD_Handler_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this handler. + */ + +void _TOD_Handler_initialization( + unsigned32 microseconds_per_tick +); + +/* + * _TOD_Set + * + * DESCRIPTION: + * + * This routine sets the current time of day to THE_TOD and + * the equivalent SECONDS_SINCE_EPOCH. + */ + +void _TOD_Set( + rtems_time_of_day *the_tod, + rtems_interval seconds_since_epoch +); + +/* + * _TOD_Validate + * + * DESCRIPTION: + * + * This function returns STATUS.RTEMS_SUCCESSFUL if THE_TOD contains + * a valid time of day, and FALSE otherwise. + */ + +rtems_status_code _TOD_Validate( + rtems_time_of_day *the_tod +); + +/* + * _TOD_To_seconds + * + * DESCRIPTION: + * + * This function returns the number seconds between the epoch and THE_TOD. + */ + +rtems_interval _TOD_To_seconds( + rtems_time_of_day *the_tod +); + +/* + * _TOD_Is_set + * + * DESCRIPTION: + * + * This function returns TRUE if the application has set the current + * time of day, and FALSE otherwise. + */ + +STATIC INLINE boolean _TOD_Is_set( void ); + +/* + * _TOD_Tickle_ticks + * + * DESCRIPTION: + * + * This routine increments the ticks field of the current time of + * day at each clock tick. + */ + +STATIC INLINE void _TOD_Tickle_ticks( void ); + +/* + * _TOD_Deactivate + * + * DESCRIPTION: + * + * This routine deactivates updating of the current time of day. + */ + +STATIC INLINE void _TOD_Deactivate( void ); + +/* + * _TOD_Activate + * + * DESCRIPTION: + * + * This routine deactivates updating of the current time of day. + */ + +STATIC INLINE void _TOD_Activate( + rtems_interval ticks +); + +/* + * _TOD_Tickle + * + * DESCRIPTION: + * + * This routine is scheduled as a watchdog function and is invoked at + * each second boundary. It updates the current time of day to indicate + * that a second has passed and processes the seconds watchdog chain. + */ + +void _TOD_Tickle( + Objects_Id id, + void *ignored +); + +/* + * RTEMS_MILLISECONDS_TO_MICROSECONDS + * + * DESCRIPTION: + * + * This routine converts an interval expressed in milliseconds to microseconds. + * + * NOTE: + * + * This must be a macro so it can be used in "static" tables. + */ + +#define RTEMS_MILLISECONDS_TO_MICROSECONDS(_ms) ((_ms) * 1000) + +/* + * RTEMS_MILLISECONDS_TO_TICKS + * + * DESCRIPTION: + * + * This routine converts an interval expressed in milliseconds to ticks. + * + * NOTE: + * + * This must be a macro so it can be used in "static" tables. + */ + +#define RTEMS_MILLISECONDS_TO_TICKS(_ms) \ + (RTEMS_MILLISECONDS_TO_MICROSECONDS(_ms) / _TOD_Microseconds_per_tick) + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/tqdata.h b/cpukit/score/include/rtems/score/tqdata.h new file mode 100644 index 0000000000..8c43fa4c72 --- /dev/null +++ b/cpukit/score/include/rtems/score/tqdata.h @@ -0,0 +1,90 @@ +/* tqdata.h + * + * This include file contains all the constants and structures + * needed to declare a thread queue. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_THREAD_QUEUE_DATA_h +#define __RTEMS_THREAD_QUEUE_DATA_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* + * The following enumerated type details all of the disciplines + * supported by the Thread Queue Handler. + */ + +typedef enum { + THREAD_QUEUE_DATA_FIFO_DISCIPLINE, /* RTEMS_FIFO queue discipline */ + THREAD_QUEUE_DATA_PRIORITY_DISCIPLINE, /* RTEMS_PRIORITY queue discipline */ +} Thread_queue_Disciplines; + +/* + * The following record defines the control block used + * to manage each thread. + */ + +#define TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS 4 /* # of pri groups */ + +typedef struct { + union { + Chain_Control Fifo; /* FIFO discipline list */ + Chain_Control Priority[TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS]; + /* priority discipline list */ + } Queues; + boolean sync; /* alloc/dealloc critical section */ + Thread_queue_Disciplines discipline; /* queue discipline */ + States_Control state; /* state of threads on Thread_q */ +} Thread_queue_Control; + +/* + * _Thread_queue_Header_number + * + * DESCRIPTION: + * + * This function returns the index of the priority chain on which + * a thread of the_priority should be placed. + */ + +STATIC INLINE unsigned32 _Thread_queue_Header_number ( + rtems_task_priority the_priority +); + +/* + * _Thread_queue_Is_reverse_search + * + * DESCRIPTION: + * + * This function returns TRUE if the_priority indicates that the + * enqueue search should start at the front of this priority + * group chain, and FALSE if the search should start at the rear. + */ + +STATIC INLINE boolean _Thread_queue_Is_reverse_search ( + rtems_task_priority the_priority +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/userext.h b/cpukit/score/include/rtems/score/userext.h new file mode 100644 index 0000000000..37131959d9 --- /dev/null +++ b/cpukit/score/include/rtems/score/userext.h @@ -0,0 +1,213 @@ +/* userext.h + * + * This include file contains all information about user extensions. This + * Handler provides mechanisms which can be used to initialize and manipulate + * all RTEMS user extensions. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_USER_EXTENSIONS_h +#define __RTEMS_USER_EXTENSIONS_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + * The following is used to manage each user extension set. + */ + +typedef struct { + Chain_Node Node; + rtems_extensions_table Callouts; +} User_extensions_Control; + +/* + * The following contains the static extension set which may be + * configured by the application. + */ + +EXTERN User_extensions_Control _User_extensions_Initial; + +/* + * The following is used to manage the list of active extensions. + */ + +EXTERN Chain_Control _User_extensions_List; + + +/* + * _User_extensions_Handler_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this handler. + */ + +STATIC INLINE void _User_extensions_Handler_initialization ( + rtems_extensions_table *initial_extensions +); + +/* + * _User_extensions_Add_set + * + * DESCRIPTION: + * + * This routine is used to add a user extension set to the active list. + */ + +STATIC INLINE void _User_extensions_Add_set ( + User_extensions_Control *the_extension, + rtems_extensions_table *extension_table +); + +/* + * _User_extensions_Remove_set + * + * DESCRIPTION: + * + * This routine is used to remove a user extension set from the active list. + */ + +STATIC INLINE void _User_extensions_Remove_set ( + User_extensions_Control *the_extension +); + +/* + * _User_extensions_Task_create + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension for + * the rtems_task_create directive. + */ + +STATIC INLINE void _User_extensions_Task_create ( + Thread_Control *the_thread +); + +/* + * _User_extensions_Task_delete + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension for + * the rtems_task_delete directive. + */ + +STATIC INLINE void _User_extensions_Task_delete ( + Thread_Control *the_thread +); + +/* + * _User_extensions_Task_start + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension for + * the rtems_task_start directive. + */ + +STATIC INLINE void _User_extensions_Task_start ( + Thread_Control *the_thread +); + +/* + * _User_extensions_Task_restart + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension for + * the rtems_task_restart directive. + */ + +STATIC INLINE void _User_extensions_Task_restart ( + Thread_Control *the_thread +); + +/* + * _User_extensions_Task_switch + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension which + * is invoked when a context switch occurs. + */ + +STATIC INLINE void _User_extensions_Task_switch ( + Thread_Control *executing, + Thread_Control *heir +); + +/* + * _User_extensions_Task_begin + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension which + * is invoked when a task begins. + */ + +STATIC INLINE void _User_extensions_Task_begin ( + Thread_Control *executing +); + +/* + * _User_extensions_Task_exitted + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension which + * is invoked when a task exits. + */ + +STATIC INLINE void _User_extensions_Task_exitted ( + Thread_Control *executing +); + +/* + * _User_extensions_Task_exitted + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension which + * is invoked when a task exits. + */ + +STATIC INLINE void _User_extensions_Task_exitted ( + Thread_Control *executing +); + +/* + * _User_extensions_Fatal + * + * DESCRIPTION: + * + * This routine is used to invoke the user extension for + * the rtems_fatal_error_occurred directive. + */ + +STATIC INLINE void _User_extensions_Fatal ( + unsigned32 the_error +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/watchdog.h b/cpukit/score/include/rtems/score/watchdog.h new file mode 100644 index 0000000000..5c897615f7 --- /dev/null +++ b/cpukit/score/include/rtems/score/watchdog.h @@ -0,0 +1,471 @@ +/* watchdog.h + * + * This include file contains all the constants and structures associated + * with watchdog timers. This Handler provides mechanisms which can be + * used to initialize and manipulate watchdog timers. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_WATCHDOG_h +#define __RTEMS_WATCHDOG_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * The following type defines the control block used to manage + * intervals. + */ + +typedef unsigned32 rtems_interval; + +/* + * The following types define a pointer to a watchdog/timer service routine. + */ + +typedef void rtems_timer_service_routine; + +typedef rtems_timer_service_routine ( *rtems_timer_service_routine_entry )( + Objects_Id, + void * + ); + +/* + * Constant for indefinite wait. (actually an illegal interval) + */ + +#define RTEMS_NO_TIMEOUT 0 + +/* + * The following enumerated type details the modes in which the + * Watchdog_Insert routine may operate. The watchdog may be + * activated automatically at insert time or later, explicitly + * by the caller. + */ + +typedef enum { + WATCHDOG_ACTIVATE_NOW, /* activate watchdog as part of insertion */ + WATCHDOG_NO_ACTIVATE /* watchdog will be explicitly activated */ +} Watchdog_Insert_modes; + +/* + * The following enumerated type lists the states in which a + * watchdog timer may be at any given time. + */ + +typedef enum { + WATCHDOG_INACTIVE, /* off all chains */ + WATCHDOG_ACTIVE, /* on chain, allowed to fire */ + WATCHDOG_REINSERT, /* on chain, reset without firing if expires */ + WATCHDOG_REMOVE_IT /* on chain, remove without firing if expires */ +} Watchdog_States; + +/* + * The following enumerated type details the manner in which + * a watchdog chain may be adjusted by the Watchdog_Adjust + * routine. The direction indicates a movement FORWARD + * or BACKWARD in time. + */ + +typedef enum { + WATCHDOG_FORWARD, /* adjust delta value forward */ + WATCHDOG_BACKWARD /* adjust delta value backward */ +} Watchdog_Adjust_directions; + +/* + * The following record defines the control block used + * to manage each watchdog timer. + */ + +typedef struct { + Chain_Node Node; + Watchdog_States state; + rtems_interval initial; + rtems_interval delta_interval; + rtems_timer_service_routine_entry routine; + Objects_Id id; + void *user_data; +} Watchdog_Control; + +/* + * The following type is used for synchronization purposes + * during an insert on a watchdog delta chain. + * + * NOTE: Watchdog_Pointer is only used to insure that + * Watchdog_Synchronization_pointer is a pointer + * which is volatile rather than a pointer to a + * volatile block of memory. + */ + +typedef Watchdog_Control *Watchdog_Pointer; +typedef volatile Watchdog_Pointer Watchdog_Synchronization_pointer; + +/* + * The following defines the watchdog chains which are managed + * on ticks and second boundaries. + */ + +EXTERN Chain_Control _Watchdog_Ticks_chain; +EXTERN Chain_Control _Watchdog_Seconds_chain; + +/* + * The following defines the synchronization variable used to + * allow interrupts to be enabled while inserting a watchdog + * on a watchdog chain. + */ + +EXTERN Watchdog_Synchronization_pointer _Watchdog_Sync; + +/* + * _Watchdog_Handler_initialization + * + * DESCRIPTION: + * + * This routine initializes the watchdog handler. The watchdog + * synchronization flag is initialized and the watchdog chains are + * initialized and emptied. + */ + +void _Watchdog_Handler_initialization( void ); + +/* + * + * _Watchdog_Initialize + * + * DESCRIPTION: + * + * This routine initializes the specified watchdog. The watchdog is + * made inactive, the watchdog id and handler routine are set to the + * specified values. + */ + +STATIC INLINE void _Watchdog_Initialize( + Watchdog_Control *the_watchdog, + rtems_timer_service_routine_entry routine, + Objects_Id id, + void *user_data +); + +/* + * _Watchdog_Remove + * + * DESCRIPTION: + * + * This routine removes THE_WATCHDOG from the watchdog chain on which + * it resides and returns the state THE_WATCHDOG timer was in. + */ + +Watchdog_States _Watchdog_Remove ( + Watchdog_Control *the_watchdog +); + +/* + * + * _Watchdog_Is_active + * + * DESCRIPTION: + * + * This routine returns TRUE if the watchdog timer is in the ACTIVE + * state, and FALSE otherwise. + */ + +STATIC INLINE boolean _Watchdog_Is_active( + Watchdog_Control *the_watchdog +); + +/* + * + * _Watchdog_Activate + * + * DESCRIPTION: + * + * This routine activates THE_WATCHDOG timer which is already + * on a watchdog chain. + */ + +STATIC INLINE void _Watchdog_Activate( + Watchdog_Control *the_watchdog +); + +/* + * + * _Watchdog_Deactivate + * + * DESCRIPTION: + * + * This routine deactivates THE_WATCHDOG timer which will remain + * on a watchdog chain. + */ + +STATIC INLINE void _Watchdog_Deactivate( + Watchdog_Control *the_watchdog +); + +/* + * + * _Watchdog_Tickle_ticks + * + * DESCRIPTION: + * + * This routine is invoked at each clock tick to update the ticks + * watchdog chain. + */ + +STATIC INLINE void _Watchdog_Tickle_ticks( void ); + +/* + * + * _Watchdog_Tickle_seconds + * + * DESCRIPTION: + * + * This routine is invoked at each clock tick to update the seconds + * watchdog chain. + */ + +STATIC INLINE void _Watchdog_Tickle_seconds( void ); + +/* + * + * _Watchdog_Insert_ticks + * + * DESCRIPTION: + * + * This routine inserts THE_WATCHDOG into the ticks watchdog chain + * for a time of UNITS ticks. The INSERT_MODE indicates whether + * THE_WATCHDOG is to be activated automatically or later, explicitly + * by the caller. + */ + +STATIC INLINE void _Watchdog_Insert_ticks( + Watchdog_Control *the_watchdog, + rtems_interval units, + Watchdog_Insert_modes insert_mode +); + +/* + * + * _Watchdog_Insert_seconds + * + * DESCRIPTION: + * + * This routine inserts THE_WATCHDOG into the seconds watchdog chain + * for a time of UNITS seconds. The INSERT_MODE indicates whether + * THE_WATCHDOG is to be activated automatically or later, explicitly + * by the caller. + */ + +STATIC INLINE void _Watchdog_Insert_seconds( + Watchdog_Control *the_watchdog, + rtems_interval units, + Watchdog_Insert_modes insert_mode +); + +/* + * + * _Watchdog_Adjust_seconds + * + * DESCRIPTION: + * + * This routine adjusts the seconds watchdog chain in the forward + * or backward DIRECTION for UNITS seconds. This is invoked when the + * current time of day is changed. + */ + +STATIC INLINE void _Watchdog_Adjust_seconds( + Watchdog_Adjust_directions direction, + rtems_interval units +); + +/* + * + * _Watchdog_Adjust_ticks + * + * DESCRIPTION: + * + * This routine adjusts the ticks watchdog chain in the forward + * or backward DIRECTION for UNITS ticks. + */ + +STATIC INLINE void _Watchdog_Adjust_ticks( + Watchdog_Adjust_directions direction, + rtems_interval units +); + +/* + * + * _Watchdog_Reset + * + * DESCRIPTION: + * + * This routine resets THE_WATCHDOG timer to its state at INSERT + * time. This routine is valid only on interval watchdog timers + * and is used to make an interval watchdog timer fire "every" so + * many ticks. + */ + +STATIC INLINE void _Watchdog_Reset( + Watchdog_Control *the_watchdog +); + +/* + * + * _Watchdog_Next + * + * DESCRIPTION: + * + * This routine returns a pointer to the watchdog timer following + * THE_WATCHDOG on the watchdog chain. + */ + +STATIC INLINE Watchdog_Control *_Watchdog_Next( + Watchdog_Control *the_watchdog +); + +/* + * + * _Watchdog_Previous + * + * DESCRIPTION: + * + * This routine returns a pointer to the watchdog timer preceding + * THE_WATCHDOG on the watchdog chain. + */ + +STATIC INLINE Watchdog_Control *_Watchdog_Previous( + Watchdog_Control *the_watchdog +); + +/* + * + * _Watchdog_First + * + * DESCRIPTION: + * + * This routine returns a pointer to the first watchdog timer + * on the watchdog chain HEADER. + */ + +STATIC INLINE Watchdog_Control *_Watchdog_First( + Chain_Control *header +); + +/* + * + * _Watchdog_Last + * + * DESCRIPTION: + * + * This routine returns a pointer to the last watchdog timer + * on the watchdog chain HEADER. + */ +STATIC INLINE Watchdog_Control *_Watchdog_Last( + Chain_Control *header +); + +/* + * + * _Watchdog_Get_sync + * + * DESCRIPTION: + * + * This routine returns the current synchronization timer. This + * routine is used so that interrupts can be enabled while a + * watchdog timer is being inserted into a watchdog chain. + */ + +STATIC INLINE Watchdog_Control *_Watchdog_Get_sync( void ); + +/* + * + * _Watchdog_Set_sync + * + * DESCRIPTION: + * + * This routine sets the current synchronization timer. This + * routine is used so that interrupts can be enabled while a + * watchdog timer is being inserted into a watchdog chain. + */ + +STATIC INLINE void _Watchdog_Set_sync( + Watchdog_Control *the_watchdog +); + +/* + * + * _Watchdog_Clear_sync + * + * DESCRIPTION: + * + * This routine will set the watchdog synchronization flag to a + * NULL address indicating synchronization is unnecessary. + */ + +STATIC INLINE void _Watchdog_Clear_sync( void ); + +/* + * _Watchdog_Adjust + * + * DESCRIPTION: + * + * This routine adjusts the HEADER watchdog chain in the forward + * or backward DIRECTION for UNITS ticks. + */ + +void _Watchdog_Adjust ( + Chain_Control *header, + Watchdog_Adjust_directions direction, + rtems_interval units +); + +/* + * _Watchdog_Insert + * + * DESCRIPTION: + * + * This routine inserts THE_WATCHDOG into the HEADER watchdog chain + * for a time of UNITS. The INSERT_MODE indicates whether + * THE_WATCHDOG is to be activated automatically or later, explicitly + * by the caller. + * + */ + +void _Watchdog_Insert ( + Chain_Control *header, + Watchdog_Control *the_watchdog, + Watchdog_Insert_modes insert_mode +); + +/* + * _Watchdog_Tickle + * + * DESCRIPTION: + * + * This routine is invoked at appropriate intervals to update + * the HEADER watchdog chain. + */ + +void _Watchdog_Tickle ( + Chain_Control *header +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/score/wkspace.h b/cpukit/score/include/rtems/score/wkspace.h new file mode 100644 index 0000000000..14bc090291 --- /dev/null +++ b/cpukit/score/include/rtems/score/wkspace.h @@ -0,0 +1,99 @@ +/* wkspace.h + * + * This include file contains information related to the RTEMS + * RAM Workspace. This Handler provides mechanisms which can be used to + * define, initialize and manipulate the RTEMS workspace. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_WORKSPACE_h +#define __RTEMS_WORKSPACE_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* + * The following is used to manage the RTEMS Workspace. + * + */ + +EXTERN Heap_Control _Workspace_Area; /* executive heap header */ + +/* + * _Workspace_Handler_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this handler. + */ + +STATIC INLINE void _Workspace_Handler_initialization( + void *starting_address, + unsigned32 size +); + +/* + * _Workspace_Allocate + * + * DESCRIPTION: + * + * This routine returns the address of a block of memory of size + * bytes. If a block of the appropriate size cannot be allocated + * from the workspace, then NULL is returned. + */ + +STATIC INLINE void *_Workspace_Allocate( + unsigned32 size +); + +/* + * _Workspace_Allocate_or_fatal_error + * + * DESCRIPTION: + * + * This routine returns the address of a block of memory of size + * bytes. If a block of the appropriate size cannot be allocated + * from the workspace, then the rtems_fatal_error_occurred directive + * is invoked. + */ + +STATIC INLINE void *_Workspace_Allocate_or_fatal_error( + unsigned32 size +); + +/* + * _Workspace_Free + * + * DESCRIPTION: + * + * This function frees the specified block of memory. If the block + * belongs to the Workspace and can be successfully freed, then + * TRUE is returned. Otherwise FALSE is returned. + */ + +STATIC INLINE boolean _Workspace_Free( + void *block +); + +#include + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/include/rtems/system.h b/cpukit/score/include/rtems/system.h new file mode 100644 index 0000000000..3ff3772d11 --- /dev/null +++ b/cpukit/score/include/rtems/system.h @@ -0,0 +1,132 @@ +/* system.h + * + * This include file contains information that is included in every + * function in the executive. This must be the first include file + * included in all internal RTEMS files. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __RTEMS_SYSTEM_h +#define __RTEMS_SYSTEM_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following define the CPU Family and Model within the family + * + * NOTE: The string "REPLACE_THIS_WITH_USE_INLINE_OR_MACROS" is replaced + * with either "USE_INLINES" or "USE_MACROS" based upon the + * whether this target configuration uses the inline or + * macro implementations of the inlined RTEMS routines. + */ + + +#define REPLACE_THIS_WITH_USE_INLINE_OR_MACROS + +/* + * The following insures that all data is declared in the space + * of the Initialization Manager. It is referenced as "external" + * in every other file. + */ + +#ifdef INIT +#undef EXTERN +#define EXTERN +#else +#undef EXTERN +#define EXTERN extern +#endif + +/* + * The following (in conjunction with compiler arguments) are used + * to choose between the use of static inline functions and macro + * functions. The static inline implementation allows better + * type checking with no cost in code size or execution speed. + */ + +#ifdef USE_INLINES +#define STATIC static +#define INLINE __inline__ +#else +/* +#error Only the GNU C compiler is currently supported!!! +*/ +#define STATIC +#define INLINE +#endif + +/* + * Include a base set of files. + */ + +/* + * XXX: Eventually proc_ptr needs to disappear!!! + */ + +typedef void * proc_ptr; + +#include /* processor specific information */ +#include /* RTEMS status codes */ + +/* + * Define NULL + */ + +#ifndef NULL +#define NULL 0 /* NULL value */ +#endif + +/* + * Boolean constants + */ + +#if !defined( TRUE ) || (TRUE != 1) +#undef TRUE +#define TRUE (1) +#endif + +#if !defined( FALSE ) || (FALSE != 0) +#undef FALSE +#define FALSE (0) +#endif + +#define stringify( _x ) # _x + +/* + * The following is the extern for the RTEMS version string. + * The contents of this string are CPU specific. + */ + +extern const char _RTEMS_version[]; /* RTEMS version string */ +extern const char _Copyright_Notice[]; /* RTEMS copyright string */ + +/* + * The jump table of entry points into RTEMS directives. + */ + +#define NUMBER_OF_ENTRY_POINTS 79 +extern const void * _Entry_points[ NUMBER_OF_ENTRY_POINTS + 1 ]; + +/* + * The following defines the CPU dependent information table. + */ + +EXTERN rtems_cpu_table _CPU_Table; /* CPU dependent info */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/address.inl b/cpukit/score/inline/rtems/score/address.inl new file mode 100644 index 0000000000..f9189e625e --- /dev/null +++ b/cpukit/score/inline/rtems/score/address.inl @@ -0,0 +1,109 @@ +/* inline/address.inl + * + * This include file contains the bodies of the routines + * about addresses which are inlined. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INLINE_ADDRESSES_inl +#define __INLINE_ADDRESSES_inl + +/*PAGE + * + * _Addresses_Add_offset + * + */ + +STATIC INLINE void *_Addresses_Add_offset ( + void *base, + unsigned32 offset +) +{ + return (base + offset); +} + +/*PAGE + * + * _Addresses_Subtract_offset + * + */ + +STATIC INLINE void *_Addresses_Subtract_offset ( + void *base, + unsigned32 offset +) +{ + return (base - offset); +} + +/*PAGE + * + * _Addresses_Add + * + * NOTE: The cast of an address to an unsigned32 makes this code + * dependent on an addresses being thirty two bits. + */ + +STATIC INLINE void *_Addresses_Add ( + void *left, + void *right +) +{ + return (left + (unsigned32)right); +} + +/*PAGE + * + * _Addresses_Subtract + * + * NOTE: The cast of an address to an unsigned32 makes this code + * dependent on an addresses being thirty two bits. + */ + +STATIC INLINE unsigned32 _Addresses_Subtract ( + void *left, + void *right +) +{ + return (left - right); +} + +/*PAGE + * + * _Addresses_Is_aligned + * + */ + +STATIC INLINE boolean _Addresses_Is_aligned ( + void *address +) +{ + return ( ( (unsigned32)address % CPU_ALIGNMENT ) == 0 ); +} + +/*PAGE + * + * _Addresses_Is_in_range + * + */ + +STATIC INLINE boolean _Addresses_Is_in_range ( + void *address, + void *base, + void *limit +) +{ + return ( address >= base && address <= limit ); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/chain.inl b/cpukit/score/inline/rtems/score/chain.inl new file mode 100644 index 0000000000..63706544e4 --- /dev/null +++ b/cpukit/score/inline/rtems/score/chain.inl @@ -0,0 +1,292 @@ +/* inline/chain.inl + * + * This include file contains the bodies of the routines which are + * associated with doubly linked chains and inlined. + * + * NOTE: The routines in this file are ordered from simple + * to complex. No other Chain Handler routine is referenced + * unless it has already been defined. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INLINE_CHAIN_inl +#define __INLINE_CHAIN_inl + +/*PAGE + * + * _Chain_Are_nodes_equal + */ + +STATIC INLINE boolean _Chain_Are_nodes_equal( + Chain_Node *left, + Chain_Node *right +) +{ + return left == right; +} + +/*PAGE + * + * _Chain_Is_null + */ + +STATIC INLINE boolean _Chain_Is_null( + Chain_Control *the_chain +) +{ + return ( the_chain == NULL ); +} + +/*PAGE + * + * _Chain_Is_null_node + */ + +STATIC INLINE boolean _Chain_Is_null_node( + Chain_Node *the_node +) +{ + return ( the_node == NULL ); +} + +/*PAGE + * + * _Chain_Head + */ + +STATIC INLINE Chain_Node *_Chain_Head( + Chain_Control *the_chain +) +{ + return (Chain_Node *) the_chain; +} + +/*PAGE + * + * _Chain_Tail + */ + +STATIC INLINE Chain_Node *_Chain_Tail( + Chain_Control *the_chain +) +{ + return (Chain_Node *) &the_chain->permanent_null; +} + +/*PAGE + * + * _Chain_Is_empty + */ + +STATIC INLINE boolean _Chain_Is_empty( + Chain_Control *the_chain +) +{ + return ( the_chain->first == _Chain_Tail( the_chain ) ); +} + +/*PAGE + * + * _Chain_Is_first + */ + +STATIC INLINE boolean _Chain_Is_first( + Chain_Node *the_node +) +{ + return ( the_node->previous == NULL ); +} + +/*PAGE + * + * _Chain_Is_last + */ + +STATIC INLINE boolean _Chain_Is_last( + Chain_Node *the_node +) +{ + return ( the_node->next == NULL ); +} + +/*PAGE + * + * _Chain_Has_only_one_node + */ + +STATIC INLINE boolean _Chain_Has_only_one_node( + Chain_Control *the_chain +) +{ + return ( the_chain->first == the_chain->last ); +} + +/*PAGE + * + * _Chain_Is_head + */ + +STATIC INLINE boolean _Chain_Is_head( + Chain_Control *the_chain, + Chain_Node *the_node +) +{ + return ( the_node == _Chain_Head( the_chain ) ); +} + +/*PAGE + * + * _Chain_Is_tail + */ + +STATIC INLINE boolean _Chain_Is_tail( + Chain_Control *the_chain, + Chain_Node *the_node +) +{ + return ( the_node == _Chain_Tail( the_chain ) ); +} + +/*PAGE + * + * Chain_Initialize_empty + */ + +STATIC INLINE void _Chain_Initialize_empty( + Chain_Control *the_chain +) +{ + the_chain->first = _Chain_Tail( the_chain ); + the_chain->permanent_null = NULL; + the_chain->last = _Chain_Head( the_chain ); +} + +/*PAGE + * + * _Chain_Extract_unprotected + */ + +STATIC INLINE void _Chain_Extract_unprotected( + Chain_Node *the_node +) +{ + Chain_Node *next; + Chain_Node *previous; + + next = the_node->next; + previous = the_node->previous; + next->previous = previous; + previous->next = next; +} + +/*PAGE + * + * _Chain_Get_first_unprotected + */ + +STATIC INLINE Chain_Node *_Chain_Get_first_unprotected( + Chain_Control *the_chain +) +{ + Chain_Node *return_node; + Chain_Node *new_first; + + return_node = the_chain->first; + new_first = return_node->next; + the_chain->first = new_first; + new_first->previous = _Chain_Head( the_chain ); + + return return_node; +} + +/*PAGE + * + * Chain_Get_unprotected + */ + +STATIC INLINE Chain_Node *_Chain_Get_unprotected( + Chain_Control *the_chain +) +{ + if ( !_Chain_Is_empty( the_chain ) ) + return _Chain_Get_first_unprotected( the_chain ); + else + return NULL; +} + +/*PAGE + * + * _Chain_Insert_unprotected + */ + +STATIC INLINE void _Chain_Insert_unprotected( + Chain_Node *after_node, + Chain_Node *the_node +) +{ + Chain_Node *before_node; + + the_node->previous = after_node; + before_node = after_node->next; + after_node->next = the_node; + the_node->next = before_node; + before_node->previous = the_node; +} + +/*PAGE + * + * _Chain_Append_unprotected + */ + +STATIC INLINE void _Chain_Append_unprotected( + Chain_Control *the_chain, + Chain_Node *the_node +) +{ + Chain_Node *old_last_node; + + the_node->next = _Chain_Tail( the_chain ); + old_last_node = the_chain->last; + the_chain->last = the_node; + old_last_node->next = the_node; + the_node->previous = old_last_node; +} + +/*PAGE + * + * _Chain_Prepend_unprotected + */ + +STATIC INLINE void _Chain_Prepend_unprotected( + Chain_Control *the_chain, + Chain_Node *the_node +) +{ + _Chain_Insert_unprotected( _Chain_Head( the_chain ), the_node ); + +} + +/*PAGE + * + * _Chain_Prepend + */ + +STATIC INLINE void _Chain_Prepend( + Chain_Control *the_chain, + Chain_Node *the_node +) +{ + _Chain_Insert( _Chain_Head( the_chain ), the_node ); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/heap.inl b/cpukit/score/inline/rtems/score/heap.inl new file mode 100644 index 0000000000..58be9b02af --- /dev/null +++ b/cpukit/score/inline/rtems/score/heap.inl @@ -0,0 +1,203 @@ +/* heap.inl + * + * This file contains the static inline implementation of the inlined + * routines from the heap handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __HEAP_inl +#define __HEAP_inl + +#include + +/*PAGE + * + * _Heap_Head + * + */ + +STATIC INLINE Heap_Block *_Heap_Head ( + Heap_Control *the_heap +) +{ + return (Heap_Block *)&the_heap->start; +} + +/*PAGE + * + * _Heap_Tail + * + */ + +STATIC INLINE Heap_Block *_Heap_Tail ( + Heap_Control *the_heap +) +{ + return (Heap_Block *)&the_heap->final; +} + +/*PAGE + * + * _Heap_Previous_block + * + */ + +STATIC INLINE Heap_Block *_Heap_Previous_block ( + Heap_Block *the_block +) +{ + return (Heap_Block *) _Addresses_Subtract_offset( + (void *)the_block, + the_block->back_flag & ~ HEAP_BLOCK_USED + ); +} + +/*PAGE + * + * _Heap_Next_block + * + * NOTE: Next_block assumes that the block is free. + */ + +STATIC INLINE Heap_Block *_Heap_Next_block ( + Heap_Block *the_block +) +{ + return (Heap_Block *) _Addresses_Add_offset( + (void *)the_block, + the_block->front_flag & ~ HEAP_BLOCK_USED + ); +} + +/*PAGE + * + * _Heap_Block_at + * + */ + +STATIC INLINE Heap_Block *_Heap_Block_at( + void *base, + unsigned32 offset +) +{ + return (Heap_Block *) _Addresses_Add_offset( (void *)base, offset ); +} + +/*PAGE + * + * _Heap_Is_previous_block_free + * + */ + +STATIC INLINE boolean _Heap_Is_previous_block_free ( + Heap_Block *the_block +) +{ + return !(the_block->back_flag & HEAP_BLOCK_USED); +} + +/*PAGE + * + * _Heap_Is_block_free + * + */ + +STATIC INLINE boolean _Heap_Is_block_free ( + Heap_Block *the_block +) +{ + return !(the_block->front_flag & HEAP_BLOCK_USED); +} + +/*PAGE + * + * _Heap_Is_block_used + * + */ + +STATIC INLINE boolean _Heap_Is_block_used ( + Heap_Block *the_block +) +{ + return (the_block->front_flag & HEAP_BLOCK_USED); +} + +/*PAGE + * + * _Heap_Block_size + * + */ + +STATIC INLINE unsigned32 _Heap_Block_size ( + Heap_Block *the_block +) +{ + return (the_block->front_flag & ~HEAP_BLOCK_USED); +} + +/*PAGE + * + * _Heap_Start_of_user_area + * + */ + +STATIC INLINE void *_Heap_Start_of_user_area ( + Heap_Block *the_block +) +{ + return (void *) &the_block->next; +} + +/*PAGE + * + * _Heap_Is_block_in + * + */ + +STATIC INLINE boolean _Heap_Is_block_in ( + Heap_Control *the_heap, + Heap_Block *the_block +) +{ + return _Addresses_Is_in_range( the_block, the_heap->start, the_heap->final ); +} + +/*PAGE + * + * _Heap_Is_page_size_valid + * + */ + +STATIC INLINE boolean _Heap_Is_page_size_valid( + unsigned32 page_size +) +{ + return ((page_size != 0) && + ((page_size % CPU_HEAP_ALIGNMENT) == 0)); +} + +/*PAGE + * + * _Heap_Build_flag + * + */ + +STATIC INLINE unsigned32 _Heap_Build_flag ( + unsigned32 size, + unsigned32 in_use_flag +) +{ + return size | in_use_flag; +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/isr.inl b/cpukit/score/inline/rtems/score/isr.inl new file mode 100644 index 0000000000..f44880c3b6 --- /dev/null +++ b/cpukit/score/inline/rtems/score/isr.inl @@ -0,0 +1,70 @@ +/* isr.inl + * + * This include file contains the static implementation of all + * inlined routines in the Interrupt Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __ISR_inl +#define __ISR_inl + +/*PAGE + * + * _ISR_Handler_initialization + * + */ + +STATIC INLINE void _ISR_Handler_initialization ( void ) +{ + _ISR_Signals_to_thread_executing = FALSE; + _ISR_Nest_level = 0; +} + +/*PAGE + * + * _ISR_Is_in_progress + * + */ + +STATIC INLINE boolean _ISR_Is_in_progress( void ) +{ + return (_ISR_Nest_level != 0); +} + +/*PAGE + * + * _ISR_Is_vector_number_valid + * + */ + +STATIC INLINE boolean _ISR_Is_vector_number_valid ( + unsigned32 vector +) +{ + return ( vector < CPU_INTERRUPT_NUMBER_OF_VECTORS ); +} + +/*PAGE + * + * _ISR_Is_valid_user_handler + * + */ + +STATIC INLINE boolean _ISR_Is_valid_user_handler ( + void *handler +) +{ + return ( handler != NULL); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/mppkt.inl b/cpukit/score/inline/rtems/score/mppkt.inl new file mode 100644 index 0000000000..22ec30a28c --- /dev/null +++ b/cpukit/score/inline/rtems/score/mppkt.inl @@ -0,0 +1,49 @@ +/* inline/mppkt.inl + * + * This package is the implementation of the Packet Handler + * routines which are inlined. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INLINE_MP_PACKET_inl +#define __INLINE_MP_PACKET_inl + +/*PAGE + * + * _Mp_packet_Is_valid_packet_class + * + * NOTE: Check for lower bounds (MP_PACKET_CLASSES_FIRST ) is unnecessary + * because this enum starts at lower bound of zero. + */ + +STATIC INLINE boolean _Mp_packet_Is_valid_packet_class ( + rtems_mp_packet_classes the_packet_class +) +{ + return ( the_packet_class <= MP_PACKET_CLASSES_LAST ); +} + +/*PAGE + * + * _Mp_packet_Is_null + * + */ + +STATIC INLINE boolean _Mp_packet_Is_null ( + rtems_packet_prefix *the_packet +) +{ + return the_packet == NULL; +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/object.inl b/cpukit/score/inline/rtems/score/object.inl new file mode 100644 index 0000000000..9c2110077c --- /dev/null +++ b/cpukit/score/inline/rtems/score/object.inl @@ -0,0 +1,198 @@ +/* object.inl + * + * This include file contains the static inline implementation of all + * of the inlined routines in the Object Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __OBJECTS_inl +#define __OBJECTS_inl + +/*PAGE + * + * _Objects_Is_name_valid + * + */ + +STATIC INLINE boolean _Objects_Is_name_valid ( + Objects_Name name +) +{ + return ( name != 0 ); +} + +/*PAGE + * + * rtems_name_to_characters + * + */ + +STATIC INLINE void rtems_name_to_characters( + Objects_Name name, + char *c1, + char *c2, + char *c3, + char *c4 +) +{ + *c1 = (name >> 24) & 0xff; + *c2 = (name >> 16) & 0xff; + *c3 = (name >> 8) & 0xff; + *c4 = name & 0xff; +} + +/*PAGE + * + * _Objects_Build_id + * + */ + +STATIC INLINE Objects_Id _Objects_Build_id( + unsigned32 node, + unsigned32 index +) +{ + return ( (node << 16) | index ); +} + +/*PAGE + * + * rtems_get_node + * + */ + +STATIC INLINE unsigned32 rtems_get_node( + Objects_Id id +) +{ + return (id >> 16); +} + +/*PAGE + * + * rtems_get_index + * + */ + +STATIC INLINE unsigned32 rtems_get_index( + Objects_Id id +) +{ + return (id &0xFFFF); +} + +/*PAGE + * + * _Objects_Is_local_node + * + */ + +STATIC INLINE boolean _Objects_Is_local_node( + unsigned32 node +) +{ + return ( node == _Objects_Local_node ); +} + +/*PAGE + * + * _Objects_Is_local_id + * + */ + +STATIC INLINE boolean _Objects_Is_local_id( + Objects_Id id +) +{ + return _Objects_Is_local_node( rtems_get_node(id) ); +} + +/*PAGE + * + * _Objects_Are_ids_equal + * + */ + +STATIC INLINE boolean _Objects_Are_ids_equal( + Objects_Id left, + Objects_Id right +) +{ + return ( left == right ); +} + +/*PAGE + * + * _Objects_Allocate + * + */ + +STATIC INLINE Objects_Control *_Objects_Allocate( + Objects_Information *information +) +{ + return (Objects_Control *) _Chain_Get( &information->Inactive ); +} + +/*PAGE + * + * _Objects_Free + * + */ + +STATIC INLINE void _Objects_Free( + Objects_Information *information, + Objects_Control *the_object +) +{ + _Chain_Append( &information->Inactive, &the_object->Node ); +} + +/*PAGE + * + * _Objects_Open + * + */ + +STATIC INLINE void _Objects_Open( + Objects_Information *information, + Objects_Control *the_object, + Objects_Name name +) +{ + unsigned32 index; + + index = rtems_get_index( the_object->id ); + information->local_table[ index ] = the_object; + information->name_table[ index ] = name; +} + +/*PAGE + * + * _Objects_Close + * + */ + +STATIC INLINE void _Objects_Close( + Objects_Information *information, + Objects_Control *the_object +) +{ + unsigned32 index; + + index = rtems_get_index( the_object->id ); + information->local_table[ index ] = NULL; + information->name_table[ index ] = 0; +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/objectmp.inl b/cpukit/score/inline/rtems/score/objectmp.inl new file mode 100644 index 0000000000..e09a3df528 --- /dev/null +++ b/cpukit/score/inline/rtems/score/objectmp.inl @@ -0,0 +1,62 @@ +/* inline/objectmp.inl + * + * This include file contains the bodies of all inlined routines + * which deal with global objects. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INLINE_MP_OBJECTS_inl +#define __INLINE_MP_OBJECTS_inl + +/*PAGE + * + * _Objects_MP_Allocate_global_object + * + */ + +STATIC INLINE Objects_MP_Control *_Objects_MP_Allocate_global_object ( + void +) +{ + return (Objects_MP_Control *) + _Chain_Get( &_Objects_MP_Inactive_global_objects ); +} + +/*PAGE + * _Objects_MP_Free_global_object + * + */ + +STATIC INLINE void _Objects_MP_Free_global_object ( + Objects_MP_Control *the_object +) +{ + _Chain_Append( + &_Objects_MP_Inactive_global_objects, + &the_object->Object.Node + ); +} + +/*PAGE + * _Objects_MP_Is_null_global_object + * + */ + +STATIC INLINE boolean _Objects_MP_Is_null_global_object ( + Objects_MP_Control *the_object +) +{ + return( the_object == NULL ); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/priority.inl b/cpukit/score/inline/rtems/score/priority.inl new file mode 100644 index 0000000000..9e7c159f65 --- /dev/null +++ b/cpukit/score/inline/rtems/score/priority.inl @@ -0,0 +1,168 @@ +/* priority.inl + * + * This file contains the static inline implementation of all inlined + * routines in the Priority Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __PRIORITY_inl +#define __PRIORITY_inl + +#include + +/*PAGE + * + * _Priority_Handler_initialization + * + */ + +STATIC INLINE void _Priority_Handler_initialization( void ) +{ + unsigned32 index; + + _Priority_Major_bit_map = 0; + for ( index=0 ; index <16 ; index++ ) + _Priority_Bit_map[ index ] = 0; +} + +/*PAGE + * + * _Priority_Is_valid + * + */ + +STATIC INLINE boolean _Priority_Is_valid ( + rtems_task_priority the_priority +) +{ + return ( ( the_priority >= RTEMS_MINIMUM_PRIORITY ) && + ( the_priority <= RTEMS_MAXIMUM_PRIORITY ) ); +} + +/*PAGE + * + * _Priority_Major + * + */ + +STATIC INLINE unsigned32 _Priority_Major ( + rtems_task_priority the_priority +) +{ + return ( the_priority / 16 ); +} + +/*PAGE + * + * _Priority_Minor + * + */ + +STATIC INLINE unsigned32 _Priority_Minor ( + rtems_task_priority the_priority +) +{ + return ( the_priority % 16 ); +} + +/*PAGE + * + * _Priority_Add_to_bit_map + * + */ + +STATIC INLINE void _Priority_Add_to_bit_map ( + Priority_Information *the_priority_map +) +{ + *the_priority_map->minor |= the_priority_map->ready_minor; + _Priority_Major_bit_map |= the_priority_map->ready_major; +} + +/*PAGE + * + * _Priority_Remove_from_bit_map + * + */ + +STATIC INLINE void _Priority_Remove_from_bit_map ( + Priority_Information *the_priority_map +) +{ + *the_priority_map->minor &= the_priority_map->block_minor; + if ( *the_priority_map->minor == 0 ) + _Priority_Major_bit_map &= the_priority_map->block_major; +} + +/*PAGE + * + * _Priority_Get_highest + * + */ + +STATIC INLINE rtems_task_priority _Priority_Get_highest( void ) +{ + Priority_Bit_map_control minor; + Priority_Bit_map_control major; + + _Bitfield_Find_first_bit( _Priority_Major_bit_map, major ); + _Bitfield_Find_first_bit( _Priority_Bit_map[major], minor ); + + return (_CPU_Priority_Bits_index( major ) << 4) + + _CPU_Priority_Bits_index( minor ); +} + +/*PAGE + * + * _Priority_Initialize_information + * + */ + +STATIC INLINE void _Priority_Initialize_information( + Priority_Information *the_priority_map, + rtems_task_priority new_priority +) +{ + Priority_Bit_map_control major; + Priority_Bit_map_control minor; + Priority_Bit_map_control mask; + + major = _Priority_Major( new_priority ); + minor = _Priority_Minor( new_priority ); + + the_priority_map->minor = + &_Priority_Bit_map[ _CPU_Priority_Bits_index(major) ]; + + mask = _CPU_Priority_Mask( major ); + the_priority_map->ready_major = mask; + the_priority_map->block_major = ~mask; + + mask = _CPU_Priority_Mask( minor ); + the_priority_map->ready_minor = mask; + the_priority_map->block_minor = ~mask; +} + +/*PAGE + * + * _Priority_Is_group_empty + * + */ + +STATIC INLINE boolean _Priority_Is_group_empty ( + rtems_task_priority the_priority +) +{ + return the_priority == 0; +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/stack.inl b/cpukit/score/inline/rtems/score/stack.inl new file mode 100644 index 0000000000..24a6d9d873 --- /dev/null +++ b/cpukit/score/inline/rtems/score/stack.inl @@ -0,0 +1,63 @@ +/* stack.inl + * + * This file contains the static inline implementation of the inlined + * routines from the Stack Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __STACK_inl +#define __STACK_inl + +/*PAGE + * + * _Stack_Initialize + * + */ + +STATIC INLINE void _Stack_Initialize ( + Stack_Control *the_stack, + void *starting_address, + unsigned32 size +) +{ + the_stack->area = starting_address; + the_stack->size = size; +} + +/*PAGE + * + * _Stack_Is_enough + * + */ + +STATIC INLINE boolean _Stack_Is_enough ( + unsigned32 size +) +{ + return ( size >= RTEMS_MINIMUM_STACK_SIZE ); +} + +/*PAGE + * + * _Stack_Adjust_size + * + */ + +STATIC INLINE unsigned32 _Stack_Adjust_size ( + unsigned32 size +) +{ + return size + CPU_STACK_ALIGNMENT; +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/states.inl b/cpukit/score/inline/rtems/score/states.inl new file mode 100644 index 0000000000..316f40e4eb --- /dev/null +++ b/cpukit/score/inline/rtems/score/states.inl @@ -0,0 +1,285 @@ +/* states.inl + * + * This file contains the macro implementation of the inlined + * routines associated with RTEMS state information. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __STATES_inl +#define __STATES_inl + +/*PAGE + * + * _States_Set + * + */ + +STATIC INLINE States_Control _States_Set ( + States_Control states_to_set, + States_Control current_state +) +{ + return (current_state | states_to_set); +} + +/*PAGE + * + * _States_Clear + * + */ + +STATIC INLINE States_Control _States_Clear ( + States_Control states_to_clear, + States_Control current_state +) +{ + return (current_state & ~states_to_clear); +} + +/*PAGE + * + * _States_Is_ready + * + */ + +STATIC INLINE boolean _States_Is_ready ( + States_Control the_states +) +{ + return (the_states == STATES_READY); +} + +/*PAGE + * + * _States_Is_only_dormant + * + */ + +STATIC INLINE boolean _States_Is_only_dormant ( + States_Control the_states +) +{ + return (the_states == STATES_DORMANT); +} + +/*PAGE + * + * _States_Is_dormant + * + */ + +STATIC INLINE boolean _States_Is_dormant ( + States_Control the_states +) +{ + return (the_states & STATES_DORMANT); +} + +/*PAGE + * + * _States_Is_suspended + * + */ + +STATIC INLINE boolean _States_Is_suspended ( + States_Control the_states +) +{ + return (the_states & STATES_SUSPENDED); +} + +/*PAGE + * + * _States_Is_Transient + * + */ + +STATIC INLINE boolean _States_Is_transient ( + States_Control the_states +) +{ + return (the_states & STATES_TRANSIENT); +} + +/*PAGE + * + * _States_Is_delaying + * + */ + +STATIC INLINE boolean _States_Is_delaying ( + States_Control the_states +) +{ + return (the_states & STATES_DELAYING); +} + +/*PAGE + * + * _States_Is_waiting_for_buffer + * + */ + +STATIC INLINE boolean _States_Is_waiting_for_buffer ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_BUFFER); +} + +/*PAGE + * + * _States_Is_waiting_for_segment + * + */ + +STATIC INLINE boolean _States_Is_waiting_for_segment ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_SEGMENT); +} + +/*PAGE + * + * _States_Is_waiting_for_message + * + */ + +STATIC INLINE boolean _States_Is_waiting_for_message ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_MESSAGE); +} + +/*PAGE + * + * _States_Is_waiting_for_event + * + */ + +STATIC INLINE boolean _States_Is_waiting_for_event ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_EVENT); +} + +/*PAGE + * + * _States_Is_waiting_for_semaphore + * + */ + +STATIC INLINE boolean _States_Is_waiting_for_semaphore ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_SEMAPHORE); +} + +/*PAGE + * + * _States_Is_waiting_for_time + * + */ + +STATIC INLINE boolean _States_Is_waiting_for_time ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_TIME); +} + +/*PAGE + * + * _States_Is_waiting_for_rpc_reply + * + */ + +STATIC INLINE boolean _States_Is_waiting_for_rpc_reply ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_RPC_REPLY); +} + +/*PAGE + * + * _States_Is_waiting_for_period + * + */ + +STATIC INLINE boolean _States_Is_waiting_for_period ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_PERIOD); +} + +/*PAGE + * + * _States_Is_locally_blocked + * + */ + +STATIC INLINE boolean _States_Is_locally_blocked ( + States_Control the_states +) +{ + return (the_states & STATES_LOCALLY_BLOCKED); +} + +/*PAGE + * + * _States_Is_waiting_on_thread_queue + * + */ + +STATIC INLINE boolean _States_Is_waiting_on_thread_queue ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_ON_THREAD_QUEUE); +} + +/*PAGE + * + * _States_Is_blocked + * + */ + +STATIC INLINE boolean _States_Is_blocked ( + States_Control the_states +) +{ + return (the_states & STATES_BLOCKED); +} + +/*PAGEPAGE + * + * + * _States_Are_set + * + */ + +STATIC INLINE boolean _States_Are_set ( + States_Control the_states, + States_Control mask +) +{ + return ( (the_states & mask) != STATES_READY); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/sysstate.inl b/cpukit/score/inline/rtems/score/sysstate.inl new file mode 100644 index 0000000000..14d838cb14 --- /dev/null +++ b/cpukit/score/inline/rtems/score/sysstate.inl @@ -0,0 +1,103 @@ +/* sysstates.inl + * + * This file contains the inline implementation of routines regarding the + * system state. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __SYSTEM_STATE_inl +#define __SYSTEM_STATE_inl + +/*PAGE + * + * _System_state_Set + */ + +STATIC INLINE void _System_state_Set ( + System_state_Codes state +) +{ + _System_state_Current = state; +} + +/*PAGE + * + * _System_state_Get + */ + +STATIC INLINE System_state_Codes _System_state_Get ( void ) +{ + return _System_state_Current; +} + +/*PAGE + * + * _System_state_Is_before_initialization + */ + +STATIC INLINE boolean _System_state_Is_before_initialization ( + System_state_Codes state +) +{ + return (state == SYSTEM_STATE_BEFORE_INITIALIZATION); +} + +/*PAGE + * + * _System_state_Is_before_multitasking + */ + +STATIC INLINE boolean _System_state_Is_before_multitasking ( + System_state_Codes state +) +{ + return (state == SYSTEM_STATE_BEFORE_MULTITASKING); +} + +/*PAGE + * + * _System_state_Is_begin_multitasking + */ + +STATIC INLINE boolean _System_state_Is_begin_multitasking ( + System_state_Codes state +) +{ + return (state == SYSTEM_STATE_BEGIN_MULTITASKING); +} + +/*PAGE + * + * _System_state_Is_up + */ + +STATIC INLINE boolean _System_state_Is_up ( + System_state_Codes state +) +{ + return (state == SYSTEM_STATE_UP); +} + +/*PAGE + * + * _System_state_Is_failed + */ + +STATIC INLINE boolean _System_state_Is_failed ( + System_state_Codes state +) +{ + return (state == SYSTEM_STATE_FAILED); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/thread.inl b/cpukit/score/inline/rtems/score/thread.inl new file mode 100644 index 0000000000..35b8eeccfe --- /dev/null +++ b/cpukit/score/inline/rtems/score/thread.inl @@ -0,0 +1,252 @@ +/* thread.inl + * + * This file contains the macro implementation of the inlined + * routines from the Thread handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __THREAD_inl +#define __THREAD_inl + +/*PAGE + * + * _Thread_Stop_multitasking + * + */ + +STATIC INLINE void _Thread_Stop_multitasking( void ) +{ + _Context_Switch( &_Thread_Executing->Registers, &_Thread_BSP_context ); +} + +/*PAGE + * + * _Thread_Is_executing + * + */ + +STATIC INLINE boolean _Thread_Is_executing ( + Thread_Control *the_thread +) +{ + return ( the_thread == _Thread_Executing ); +} + +/*PAGE + * + * _Thread_Is_heir + * + */ + +STATIC INLINE boolean _Thread_Is_heir ( + Thread_Control *the_thread +) +{ + return ( the_thread == _Thread_Heir ); +} + +/*PAGE + * + * _Thread_Is_executing_also_the_heir + * + */ + +STATIC INLINE boolean _Thread_Is_executing_also_the_heir( void ) +{ + return ( _Thread_Executing == _Thread_Heir ); +} + +/*PAGE + * + * _Thread_Resume + * + */ + +STATIC INLINE void _Thread_Resume ( + Thread_Control *the_thread +) +{ + _Thread_Clear_state( the_thread, STATES_SUSPENDED ); +} + +/*PAGE + * + * _Thread_Unblock + * + */ + +STATIC INLINE void _Thread_Unblock ( + Thread_Control *the_thread +) +{ + _Thread_Clear_state( the_thread, STATES_BLOCKED ); +} + +/*PAGE + * + * _Thread_Restart_self + * + */ + +STATIC INLINE void _Thread_Restart_self( void ) +{ + if ( _Thread_Executing->fp_context != NULL ) + _Context_Restore_fp( &_Thread_Executing->fp_context ); + + _CPU_Context_Restart_self( &_Thread_Executing->Registers ); +} + +/*PAGE + * + * _Thread_Calculate_heir + * + */ + +STATIC INLINE void _Thread_Calculate_heir( void ) +{ + _Thread_Heir = (Thread_Control *) + _Thread_Ready_chain[ _Priority_Get_highest() ].first; +} + +/*PAGE + * + * _Thread_Is_allocated_fp + * + */ + +STATIC INLINE boolean _Thread_Is_allocated_fp ( + Thread_Control *the_thread +) +{ + return ( the_thread == _Thread_Allocated_fp ); +} + +/*PAGE + * + * _Thread_Deallocate_fp + * + */ + +STATIC INLINE void _Thread_Deallocate_fp( void ) +{ + _Thread_Allocated_fp = NULL; +} + +/*PAGE + * + * _Thread_Disable_dispatch + * + */ + +STATIC INLINE void _Thread_Disable_dispatch( void ) +{ + _Thread_Dispatch_disable_level += 1; +} + +/*PAGE + * + * _Thread_Enable_dispatch + * + */ + +#if ( CPU_INLINE_ENABLE_DISPATCH == TRUE ) +STATIC INLINE void _Thread_Enable_dispatch() +{ + if ( (--_Thread_Dispatch_disable_level) == 0 ) + _Thread_Dispatch(); +} +#endif + +#if ( CPU_INLINE_ENABLE_DISPATCH == FALSE ) +void _Thread_Enable_dispatch( void ); +#endif + +/*PAGE + * + * _Thread_Unnest_dispatch + * + */ + +STATIC INLINE void _Thread_Unnest_dispatch( void ) +{ + _Thread_Dispatch_disable_level -= 1; +} + +/*PAGE + * + * _Thread_Is_dispatching_enabled + * + */ + +STATIC INLINE boolean _Thread_Is_dispatching_enabled( void ) +{ + return ( _Thread_Dispatch_disable_level == 0 ); +} + +/*PAGE + * + * _Thread_Is_context_switch_necessary + * + */ + +STATIC INLINE boolean _Thread_Is_context_switch_necessary( void ) +{ + return ( _Context_Switch_necessary ); +} + +/*PAGE + * + * _Thread_Dispatch_initialization + * + */ + +STATIC INLINE void _Thread_Dispatch_initialization( void ) +{ + _Thread_Dispatch_disable_level = 1; +} + +/*PAGE + * + * _Thread_Is_null + * + */ + +STATIC INLINE boolean _Thread_Is_null ( + Thread_Control *the_thread +) +{ + return ( the_thread == NULL ); +} + +/*PAGE + * + * _Thread_Get + * + */ + +STATIC INLINE Thread_Control *_Thread_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ) { + _Thread_Disable_dispatch(); + *location = OBJECTS_LOCAL; + return( _Thread_Executing ); + } + + return (Thread_Control *) + _Objects_Get( &_Thread_Information, id, location ); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/threadmp.inl b/cpukit/score/inline/rtems/score/threadmp.inl new file mode 100644 index 0000000000..f4beba59ed --- /dev/null +++ b/cpukit/score/inline/rtems/score/threadmp.inl @@ -0,0 +1,53 @@ +/* inline/threadmp.inl + * + * This include file contains the bodies of all inlined routines + * for the multiprocessing part of thread package. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INLINE_MP_THREAD_inl +#define __INLINE_MP_THREAD_inl + +/*PAGE + * + * _Thread_MP_Is_receive + * + */ + +STATIC INLINE boolean _Thread_MP_Is_receive ( + Thread_Control *the_thread +) +{ + return the_thread == _Thread_MP_Receive; +} + +/*PAGE + * + * _Thread_MP_Free_proxy + * + */ + +STATIC INLINE void _Thread_MP_Free_proxy ( + Thread_Control *the_thread +) +{ + Thread_Proxy_control *the_proxy; + + the_proxy = (Thread_Proxy_control *) the_thread; + + _Chain_Extract( &the_proxy->Active ); + + _Chain_Append( &_Thread_MP_Inactive_proxies, &the_thread->Object.Node ); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/tod.inl b/cpukit/score/inline/rtems/score/tod.inl new file mode 100644 index 0000000000..dadcdabcda --- /dev/null +++ b/cpukit/score/inline/rtems/score/tod.inl @@ -0,0 +1,72 @@ +/* tod.inl + * + * This file contains the static inline implementation of the inlined routines + * from the Time of Day Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __TIME_OF_DAY_inl +#define __TIME_OF_DAY_inl + +/*PAGE + * + * _TOD_Is_set + * + */ + +STATIC INLINE boolean _TOD_Is_set( void ) +{ + return _Watchdog_Is_active( &_TOD_Seconds_watchdog ); +} + +/*PAGE + * + * _TOD_Tickle_ticks + * + */ + +STATIC INLINE void _TOD_Tickle_ticks( void ) +{ + _TOD_Current.ticks += 1; + _TOD_Ticks_since_boot += 1; +} + +/*PAGE + * + * _TOD_Deactivate + * + */ + +STATIC INLINE void _TOD_Deactivate( void ) +{ + _Watchdog_Remove( &_TOD_Seconds_watchdog ); +} + +/*PAGE + * + * _TOD_Activate + * + */ + +STATIC INLINE void _TOD_Activate( + rtems_interval ticks +) +{ + _Watchdog_Insert_ticks( + &_TOD_Seconds_watchdog, + ticks, + WATCHDOG_ACTIVATE_NOW + ); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/tqdata.inl b/cpukit/score/inline/rtems/score/tqdata.inl new file mode 100644 index 0000000000..7ec1e9e186 --- /dev/null +++ b/cpukit/score/inline/rtems/score/tqdata.inl @@ -0,0 +1,47 @@ +/* tqdata.inl + * + * This file contains the static inline implementation of the inlined + * routines needed to support the Thread Queue Data. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __THREAD_QUEUE_DATA_inl +#define __THREAD_QUEUE_DATA_inl + +/*PAGE + * + * _Thread_queue_Header_number + * + */ + +STATIC INLINE unsigned32 _Thread_queue_Header_number ( + rtems_task_priority the_priority +) +{ + return ( the_priority >> 6 ); +} + +/*PAGE + * + * _Thread_queue_Is_reverse_search + * + */ + +STATIC INLINE boolean _Thread_queue_Is_reverse_search ( + rtems_task_priority the_priority +) +{ + return ( the_priority & 0x20 ); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/userext.inl b/cpukit/score/inline/rtems/score/userext.inl new file mode 100644 index 0000000000..1558da968a --- /dev/null +++ b/cpukit/score/inline/rtems/score/userext.inl @@ -0,0 +1,268 @@ +/* userext.inl + * + * This file contains the macro implementation of the inlined routines + * from the User Extension Handler + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __USER_EXTENSIONS_inl +#define __USER_EXTENSIONS_inl + +/*PAGE + * + * _User_extensions_Handler_initialization + * + */ + +STATIC INLINE void _User_extensions_Handler_initialization ( + rtems_extensions_table *initial_extensions +) +{ + _Chain_Initialize_empty( &_User_extensions_List ); + + if ( initial_extensions ) { + _User_extensions_Initial.Callouts = *initial_extensions; + _Chain_Append( &_User_extensions_List, &_User_extensions_Initial.Node ); + } +} + +/*PAGE + * + * _User_extensions_Add_set + */ + +STATIC INLINE void _User_extensions_Add_set ( + User_extensions_Control *the_extension, + rtems_extensions_table *extension_table +) +{ + the_extension->Callouts = *extension_table; + + _Chain_Append( &_User_extensions_List, &the_extension->Node ); +} + +/*PAGE + * + * _User_extensions_Remove_set + */ + +STATIC INLINE void _User_extensions_Remove_set ( + User_extensions_Control *the_extension +) +{ + _Chain_Extract( &the_extension->Node ); +} + +/*PAGE + * + * _User_extensions_Task_create + * + */ + +STATIC INLINE void _User_extensions_Task_create ( + Thread_Control *the_thread +) +{ + Chain_Node *the_node; + User_extensions_Control *the_extension; + + for ( the_node = _User_extensions_List.first ; + !_Chain_Is_tail( &_User_extensions_List, the_node ) ; + the_node = the_node->next ) { + + the_extension = (User_extensions_Control *) the_node; + + if ( the_extension->Callouts.rtems_task_create != NULL ) + (*the_extension->Callouts.rtems_task_create)( + _Thread_Executing, + the_thread + ); + } +} + +/*PAGE + * + * _User_extensions_Task_delete + */ + +STATIC INLINE void _User_extensions_Task_delete ( + Thread_Control *the_thread +) +{ + Chain_Node *the_node; + User_extensions_Control *the_extension; + + for ( the_node = _User_extensions_List.last ; + !_Chain_Is_head( &_User_extensions_List, the_node ) ; + the_node = the_node->previous ) { + + the_extension = (User_extensions_Control *) the_node; + + if ( the_extension->Callouts.rtems_task_delete != NULL ) + (*the_extension->Callouts.rtems_task_delete)( + _Thread_Executing, + the_thread + ); + } +} + +/*PAGE + * + * _User_extensions_Task_start + * + */ + +STATIC INLINE void _User_extensions_Task_start ( + Thread_Control *the_thread +) +{ + Chain_Node *the_node; + User_extensions_Control *the_extension; + + for ( the_node = _User_extensions_List.first ; + !_Chain_Is_tail( &_User_extensions_List, the_node ) ; + the_node = the_node->next ) { + + the_extension = (User_extensions_Control *) the_node; + + if ( the_extension->Callouts.rtems_task_start != NULL ) + (*the_extension->Callouts.rtems_task_start)( + _Thread_Executing, + the_thread + ); + } +} + +/*PAGE + * + * _User_extensions_Task_restart + * + */ + +STATIC INLINE void _User_extensions_Task_restart ( + Thread_Control *the_thread +) +{ + Chain_Node *the_node; + User_extensions_Control *the_extension; + + for ( the_node = _User_extensions_List.first ; + !_Chain_Is_tail( &_User_extensions_List, the_node ) ; + the_node = the_node->next ) { + + the_extension = (User_extensions_Control *) the_node; + + if ( the_extension->Callouts.rtems_task_restart != NULL ) + (*the_extension->Callouts.rtems_task_restart)( + _Thread_Executing, + the_thread + ); + } +} + +/*PAGE + * + * _User_extensions_Task_switch + * + */ + +STATIC INLINE void _User_extensions_Task_switch ( + Thread_Control *executing, + Thread_Control *heir +) +{ + Chain_Node *the_node; + User_extensions_Control *the_extension; + + for ( the_node = _User_extensions_List.first ; + !_Chain_Is_tail( &_User_extensions_List, the_node ) ; + the_node = the_node->next ) { + + the_extension = (User_extensions_Control *) the_node; + + if ( the_extension->Callouts.task_switch != NULL ) + (*the_extension->Callouts.task_switch)( executing, heir ); + } +} + +/*PAGE + * + * _User_extensions_Task_begin + * + */ + +STATIC INLINE void _User_extensions_Task_begin ( + Thread_Control *executing +) +{ + Chain_Node *the_node; + User_extensions_Control *the_extension; + + for ( the_node = _User_extensions_List.first ; + !_Chain_Is_tail( &_User_extensions_List, the_node ) ; + the_node = the_node->next ) { + + the_extension = (User_extensions_Control *) the_node; + + if ( the_extension->Callouts.task_begin != NULL ) + (*the_extension->Callouts.task_begin)( executing ); + } +} + +/*PAGE + * + * _User_extensions_Task_exitted + */ + +STATIC INLINE void _User_extensions_Task_exitted ( + Thread_Control *executing +) +{ + Chain_Node *the_node; + User_extensions_Control *the_extension; + + for ( the_node = _User_extensions_List.last ; + !_Chain_Is_head( &_User_extensions_List, the_node ) ; + the_node = the_node->previous ) { + + the_extension = (User_extensions_Control *) the_node; + + if ( the_extension->Callouts.task_exitted != NULL ) + (*the_extension->Callouts.task_exitted)( executing ); + } +} + +/*PAGE + * + * _User_extensions_Fatal + */ + +STATIC INLINE void _User_extensions_Fatal ( + unsigned32 the_error +) +{ + Chain_Node *the_node; + User_extensions_Control *the_extension; + + for ( the_node = _User_extensions_List.last ; + !_Chain_Is_head( &_User_extensions_List, the_node ) ; + the_node = the_node->previous ) { + + the_extension = (User_extensions_Control *) the_node; + + if ( the_extension->Callouts.fatal != NULL ) + (*the_extension->Callouts.fatal)( the_error ); + } +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/watchdog.inl b/cpukit/score/inline/rtems/score/watchdog.inl new file mode 100644 index 0000000000..d5d12cbeef --- /dev/null +++ b/cpukit/score/inline/rtems/score/watchdog.inl @@ -0,0 +1,296 @@ +/* watchdog.inl + * + * This file contains the static inline implementation of all inlined + * routines in the Watchdog Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __WATCHDOG_inl +#define __WATCHDOG_inl + +/*PAGE + * + * _Watchdog_Initialize + * + */ + +STATIC INLINE void _Watchdog_Initialize( + Watchdog_Control *the_watchdog, + rtems_timer_service_routine_entry routine, + Objects_Id id, + void *user_data +) +{ + the_watchdog->state = WATCHDOG_INACTIVE; + the_watchdog->routine = routine; + the_watchdog->id = id; + the_watchdog->user_data = user_data; +} + +/*PAGE + * + * _Watchdog_Is_active + * + */ + +STATIC INLINE boolean _Watchdog_Is_active( + Watchdog_Control *the_watchdog +) +{ + + return ( the_watchdog->state == WATCHDOG_ACTIVE ); + +} + +/*PAGE + * + * _Watchdog_Activate + * + */ + +STATIC INLINE void _Watchdog_Activate( + Watchdog_Control *the_watchdog +) +{ + + the_watchdog->state = WATCHDOG_ACTIVE; + +} + +/*PAGE + * + * _Watchdog_Deactivate + * + */ + +STATIC INLINE void _Watchdog_Deactivate( + Watchdog_Control *the_watchdog +) +{ + + the_watchdog->state = WATCHDOG_REMOVE_IT; + +} + +/*PAGE + * + * _Watchdog_Tickle_ticks + * + */ + +STATIC INLINE void _Watchdog_Tickle_ticks( void ) +{ + + _Watchdog_Tickle( &_Watchdog_Ticks_chain ); + +} + +/*PAGE + * + * _Watchdog_Tickle_seconds + * + */ + +STATIC INLINE void _Watchdog_Tickle_seconds( void ) +{ + + _Watchdog_Tickle( &_Watchdog_Seconds_chain ); + +} + +/*PAGE + * + * _Watchdog_Insert_ticks + * + */ + +STATIC INLINE void _Watchdog_Insert_ticks( + Watchdog_Control *the_watchdog, + rtems_interval units, + Watchdog_Insert_modes insert_mode +) +{ + + the_watchdog->initial = units; + + _Watchdog_Insert( &_Watchdog_Ticks_chain, the_watchdog, insert_mode ); + +} + +/*PAGE + * + * _Watchdog_Insert_seconds + * + */ + +STATIC INLINE void _Watchdog_Insert_seconds( + Watchdog_Control *the_watchdog, + rtems_interval units, + Watchdog_Insert_modes insert_mode +) +{ + + the_watchdog->initial = units; + + _Watchdog_Insert( &_Watchdog_Seconds_chain, the_watchdog, insert_mode ); + +} + +/*PAGE + * + * _Watchdog_Adjust_seconds + * + */ + +STATIC INLINE void _Watchdog_Adjust_seconds( + Watchdog_Adjust_directions direction, + rtems_interval units +) +{ + + _Watchdog_Adjust( &_Watchdog_Seconds_chain, direction, units ); + +} + +/*PAGE + * + * _Watchdog_Adjust_ticks + * + */ + +STATIC INLINE void _Watchdog_Adjust_ticks( + Watchdog_Adjust_directions direction, + rtems_interval units +) +{ + + _Watchdog_Adjust( &_Watchdog_Ticks_chain, direction, units ); + +} + +/*PAGE + * + * _Watchdog_Reset + * + */ + +STATIC INLINE void _Watchdog_Reset( + Watchdog_Control *the_watchdog +) +{ + + (void) _Watchdog_Remove( the_watchdog ); + + _Watchdog_Insert( + &_Watchdog_Ticks_chain, + the_watchdog, + WATCHDOG_ACTIVATE_NOW + ); + +} + +/*PAGE + * + * _Watchdog_Next + * + */ + +STATIC INLINE Watchdog_Control *_Watchdog_Next( + Watchdog_Control *the_watchdog +) +{ + + return ( (Watchdog_Control *) the_watchdog->Node.next ); + +} + +/*PAGE + * + * _Watchdog_Previous + * + */ + +STATIC INLINE Watchdog_Control *_Watchdog_Previous( + Watchdog_Control *the_watchdog +) +{ + + return ( (Watchdog_Control *) the_watchdog->Node.previous ); + +} + +/*PAGE + * + * _Watchdog_First + * + */ + +STATIC INLINE Watchdog_Control *_Watchdog_First( + Chain_Control *header +) +{ + + return ( (Watchdog_Control *) header->first ); + +} + +/*PAGE + * + * _Watchdog_Last + * + */ +STATIC INLINE Watchdog_Control *_Watchdog_Last( + Chain_Control *header +) +{ + + return ( (Watchdog_Control *) header->last ); + +} + +/*PAGE + * + * _Watchdog_Get_sync + * + */ + +STATIC INLINE Watchdog_Control *_Watchdog_Get_sync( void ) +{ + return (Watchdog_Control *) _Watchdog_Sync; +} + +/*PAGE + * + * _Watchdog_Set_sync + * + */ + +STATIC INLINE void _Watchdog_Set_sync( + Watchdog_Control *the_watchdog +) +{ + _Watchdog_Sync = (Watchdog_Synchronization_pointer) the_watchdog; +} + +/*PAGE + * + * _Watchdog_Clear_sync + * + */ + +STATIC INLINE void _Watchdog_Clear_sync( void ) +{ + _Watchdog_Sync = NULL; +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/wkspace.inl b/cpukit/score/inline/rtems/score/wkspace.inl new file mode 100644 index 0000000000..fee7623a6c --- /dev/null +++ b/cpukit/score/inline/rtems/score/wkspace.inl @@ -0,0 +1,104 @@ +/* wkspace.inl + * + * This include file contains the bodies of the routines which contains + * information related to the RTEMS RAM Workspace. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __WORKSPACE_inl +#define __WORKSPACE_inl + +/*PAGE + * + * _Workspace_Handler_initialization + * + */ + +STATIC INLINE void _Workspace_Handler_initialization( + void *starting_address, + unsigned32 size +) +{ + unsigned32 *zero_out_array; + unsigned32 index; + unsigned32 memory_available; + + if ( (starting_address == NULL) || + !_Addresses_Is_aligned( starting_address ) ) + rtems_fatal_error_occurred( RTEMS_INVALID_ADDRESS ); + + if ( _CPU_Table.do_zero_of_workspace ) { + for( zero_out_array = (unsigned32 *) starting_address, index = 0 ; + index < size / 4 ; + index++ ) + zero_out_array[ index ] = 0; + } + + memory_available = _Heap_Initialize( + &_Workspace_Area, + starting_address, + size, + CPU_HEAP_ALIGNMENT + ); + + if ( memory_available == 0 ) + rtems_fatal_error_occurred( RTEMS_UNSATISFIED ); +} + +/*PAGE + * + * _Workspace_Allocate + * + */ + +STATIC INLINE void *_Workspace_Allocate( + unsigned32 size +) +{ + return _Heap_Allocate( &_Workspace_Area, size ); +} + +/*PAGE + * + * _Workspace_Allocate_or_fatal_error + * + */ + +STATIC INLINE void *_Workspace_Allocate_or_fatal_error( + unsigned32 size +) +{ + void *memory; + + memory = _Workspace_Allocate( size ); + + if ( memory == NULL ) + rtems_fatal_error_occurred( RTEMS_UNSATISFIED ); + + return memory; +} + +/*PAGE + * + * _Workspace_Free + * + */ + +STATIC INLINE boolean _Workspace_Free( + void *block +) +{ + return _Heap_Free( &_Workspace_Area, block ); +} + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/README b/cpukit/score/macros/README new file mode 100644 index 0000000000..b2f0c4d481 --- /dev/null +++ b/cpukit/score/macros/README @@ -0,0 +1,18 @@ +# +# $Id$ +# + +The files in this directory are not considered the "primary" source +of inlined routines for RTEMS. The "inline" directory contains +the implementations of the inlined basis which are regularly +tested. In general, an effort is made to keep the contents of +this directory up to date but testing is only performed irregularly +and even then it is usually with a single target processor and BSP. + +The primary purpose of the code in this directory is to insure +that RTEMS can be compiled using a C compiler which does not support +static inline routines. + +These were last successfully tested on 2/1/95 on a prerelease version +of 3.2.0. The testing was done only on the Force CPU386 i386 target board. +No testing was done on version of the code in the final release. diff --git a/cpukit/score/macros/rtems/score/README b/cpukit/score/macros/rtems/score/README new file mode 100644 index 0000000000..b2f0c4d481 --- /dev/null +++ b/cpukit/score/macros/rtems/score/README @@ -0,0 +1,18 @@ +# +# $Id$ +# + +The files in this directory are not considered the "primary" source +of inlined routines for RTEMS. The "inline" directory contains +the implementations of the inlined basis which are regularly +tested. In general, an effort is made to keep the contents of +this directory up to date but testing is only performed irregularly +and even then it is usually with a single target processor and BSP. + +The primary purpose of the code in this directory is to insure +that RTEMS can be compiled using a C compiler which does not support +static inline routines. + +These were last successfully tested on 2/1/95 on a prerelease version +of 3.2.0. The testing was done only on the Force CPU386 i386 target board. +No testing was done on version of the code in the final release. diff --git a/cpukit/score/macros/rtems/score/address.inl b/cpukit/score/macros/rtems/score/address.inl new file mode 100644 index 0000000000..f2672f2500 --- /dev/null +++ b/cpukit/score/macros/rtems/score/address.inl @@ -0,0 +1,79 @@ +/* macros/address.h + * + * This include file contains the bodies of the routines + * about addresses which are inlined. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MACROS_ADDRESSES_h +#define __MACROS_ADDRESSES_h + +/*PAGE + * + * _Addresses_Add_offset + * + */ + +#define _Addresses_Add_offset( _base, _offset ) \ + ((void *)(_base) + (_offset)) + +/*PAGE + * + * _Addresses_Subtract_offset + * + */ + +#define _Addresses_Subtract_offset( _base, _offset ) \ + ((void *)(_base) - (_offset)) + +/*PAGE + * + * _Addresses_Add + * + * NOTE: The cast of an address to an unsigned32 makes this code + * dependent on an addresses being thirty two bits. + */ + +#define _Addresses_Add( _left, _right ) \ + ((void *)(_left) + (unsigned32)(_right)) + +/*PAGE + * + * _Addresses_Subtract + * + * NOTE: The cast of an address to an unsigned32 makes this code + * dependent on an addresses being thirty two bits. + */ + +#define _Addresses_Subtract( _left, _right ) \ + ((void *)(_left) - (void *)(_right)) + +/*PAGE + * + * _Addresses_Is_aligned + * + */ + +#define _Addresses_Is_aligned( _address ) \ + ( ( (unsigned32)(_address) % 4 ) == 0 ) + +/*PAGE + * + * _Addresses_Is_in_range + * + */ + +#define _Addresses_Is_in_range( _address, _base, _limit ) \ + ( (_address) >= (_base) && (_address) <= (_limit) ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/chain.inl b/cpukit/score/macros/rtems/score/chain.inl new file mode 100644 index 0000000000..a53b3fc270 --- /dev/null +++ b/cpukit/score/macros/rtems/score/chain.inl @@ -0,0 +1,200 @@ +/* macros/chain.h + * + * This include file contains the bodies of the routines which are + * associated with doubly linked chains and inlined. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MACROS_CHAIN_h +#define __MACROS_CHAIN_h + +/*PAGE + * + * _Chain_Are_nodes_equal + */ + +#define _Chain_Are_nodes_equal( _left, _right ) \ + ( (_left) == (_right) ) + +/*PAGE + * + * _Chain_Is_null + */ + +#define _Chain_Is_null( _the_chain ) \ + ( (_the_chain) == NULL ) + +/*PAGE + * + * _Chain_Is_null_node + */ + +#define _Chain_Is_null_node( _the_node ) \ + ( (_the_node) == NULL ) + +/*PAGE + * + * _Chain_Head + */ + +#define _Chain_Head( _the_chain ) \ + ((Chain_Node *) (_the_chain)) + +/*PAGE + * + * _Chain_Tail + */ + +#define _Chain_Tail( _the_chain ) \ + ((Chain_Node *) &(_the_chain)->permanent_null) + +/*PAGE + * + * _Chain_Is_empty + */ + +#define _Chain_Is_empty( _the_chain ) \ + ( (_the_chain)->first == _Chain_Tail( (_the_chain) ) ) + +/*PAGE + * + * _Chain_Is_first + */ + +#define _Chain_Is_first( _the_node ) \ + ( (the_node)->previous == NULL ) + +/*PAGE + * + * _Chain_Is_last + */ + +#define _Chain_Is_last( _the_node ) \ + ( (_the_node)->next == NULL ) + +/*PAGE + * + * _Chain_Has_only_one_node + */ + +#define _Chain_Has_only_one_node( _the_chain ) \ + ( (_the_chain)->first == (_the_chain)->last ) + +/*PAGE + * + * _Chain_Is_head + */ + +#define _Chain_Is_head( _the_chain, _the_node ) \ + ( (_the_node) == _Chain_Head( (_the_chain) ) ) + +/*PAGE + * + * _Chain_Is_tail + */ + +#define _Chain_Is_tail( _the_chain, _the_node ) \ + ( (_the_node) == _Chain_Tail( (_the_chain) ) ) + +/*PAGE + * + * Chain_Initialize_empty + */ + +#define _Chain_Initialize_empty( _the_chain ) \ +{ \ + (_the_chain)->first = _Chain_Tail( (_the_chain) ); \ + (_the_chain)->permanent_null = NULL; \ + (_the_chain)->last = _Chain_Head( (_the_chain) ); \ +} + +/*PAGE + * + * _Chain_Extract_unprotected + */ + +#define _Chain_Extract_unprotected( _the_node ) \ +{ \ + Chain_Node *_next; \ + Chain_Node *_previous; \ + \ + _next = (_the_node)->next; \ + _previous = (_the_node)->previous; \ + _next->previous = _previous; \ + _previous->next = _next; \ +} + +/*PAGE + * + * _Chain_Get_unprotected + */ + +/*PAGE + * + * Chain_Get_unprotected + */ + +#define _Chain_Get_unprotected( _the_chain ) \ + (( !_Chain_Is_empty( (_the_chain) ) ) \ + ? _Chain_Get_unprotected( (_the_chain) ) \ + : NULL) + +/*PAGE + * + * _Chain_Insert_unprotected + */ + +#define _Chain_Insert_unprotected( _after_node, _the_node ) \ +{ \ + Chain_Node *_before_node; \ + \ + (_the_node)->previous = (_after_node); \ + _before_node = (_after_node)->next; \ + (_after_node)->next = (_the_node); \ + (_the_node)->next = _before_node; \ + _before_node->previous = (_the_node); \ +} + +/*PAGE + * + * _Chain_Append_unprotected + */ + +#define _Chain_Append_unprotected( _the_chain, _the_node ) \ +{ \ + Chain_Node *_old_last_node; \ + \ + (_the_node)->next = _Chain_Tail( (_the_chain) ); \ + _old_last_node = (_the_chain)->last; \ + (_the_chain)->last = (_the_node); \ + _old_last_node->next = (_the_node); \ + (_the_node)->previous = _old_last_node; \ +} + +/*PAGE + * + * _Chain_Prepend_unprotected + */ + +#define _Chain_Prepend_unprotected( _the_chain, _the_node ) \ + _Chain_Insert_unprotected( _Chain_Head( (_the_chain) ), (_the_node) ) + +/*PAGE + * + * _Chain_Prepend + */ + +#define _Chain_Prepend( _the_chain, _the_node ) \ + _Chain_Insert( _Chain_Head( (_the_chain) ), (_the_node) ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/heap.inl b/cpukit/score/macros/rtems/score/heap.inl new file mode 100644 index 0000000000..6f06478207 --- /dev/null +++ b/cpukit/score/macros/rtems/score/heap.inl @@ -0,0 +1,136 @@ +/* heap.inl + * + * This file contains the macro implementation of the inlined + * routines from the heap handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __HEAP_inl +#define __HEAP_inl + +#include + +/*PAGE + * + * _Heap_Head + */ + +#define _Heap_Head( _the_heap ) \ + ((Heap_Block *)&(_the_heap)->start) + +/*PAGE + * + * _Heap_Tail + */ + +#define _Heap_Tail( _the_heap ) \ + ((Heap_Block *)&(_the_heap)->final) + +/*PAGE + * + * _Heap_Previous_block + */ + +#define _Heap_Previous_block( _the_block ) \ + ( (Heap_Block *) _Addresses_Subtract_offset( \ + (void *)(_the_block), \ + (_the_block)->back_flag & ~ HEAP_BLOCK_USED \ + ) + +/*PAGE + * + * _Heap_Next_block + */ + +#define _Heap_Next_block( _the_block ) \ + ( (Heap_Block *) _Addresses_Add_offset( \ + (void *)(_the_block), \ + (_the_block)->front_flag & ~ HEAP_BLOCK_USED \ + ) + +/*PAGE + * + * _Heap_Block_at + */ + +#define _Heap_Block_at( _base, _offset ) \ + ( (Heap_Block *) \ + _Addresses_Add_offset( (void *)(_base), (_offset) ) ) + +/*PAGE + * + * _Heap_Is_previous_block_free + */ + +#define _Heap_Is_previous_block_free( _the_block ) \ + ( !((_the_block)->back_flag & HEAP_BLOCK_USED) ) + +/*PAGE + * + * _Heap_Is_block_free + */ + +#define _Heap_Is_block_free( _the_block ) \ + ( !((_the_block)->front_flag & HEAP_BLOCK_USED) ) + +/*PAGE + * + * _Heap_Is_block_used + */ + +#define _Heap_Is_block_used( _the_block ) \ + ((_the_block)->front_flag & HEAP_BLOCK_USED) + +/*PAGE + * + * _Heap_Block_size + */ + +#define _Heap_Block_size( _the_block ) \ + ((_the_block)->front_flag & ~HEAP_BLOCK_USED) + +/*PAGE + * + * _Heap_Start_of_user_area + */ + +#define _Heap_Start_of_user_area( _the_block ) \ + ((void *) &(_the_block)->next) + +/*PAGE + * + * _Heap_Is_block_in + */ + +#define _Heap_Is_block_in( _the_heap, _the_block ) \ + ( ((_the_block) >= (_the_heap)->start) && \ + ((_the_block) <= (_the_heap)->final) ) + +/*PAGE + * + * _Heap_Is_page_size_valid + */ + +#define _Heap_Is_page_size_valid( _page_size ) \ + ( ((_page_size) != 0) && \ + (((_page_size) % CPU_HEAP_ALIGNMENT) == 0) ) + +/*PAGE + * + * _Heap_Build_flag + */ + +#define _Heap_Build_flag( _size, _in_use_flag ) \ + ( (_size) | (_in_use_flag)) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/isr.inl b/cpukit/score/macros/rtems/score/isr.inl new file mode 100644 index 0000000000..93f234c7ff --- /dev/null +++ b/cpukit/score/macros/rtems/score/isr.inl @@ -0,0 +1,60 @@ +/* isr.inl + * + * This include file contains the macro implementation of all + * inlined routines in the Interrupt Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __ISR_inl +#define __ISR_inl + +/*PAGE + * + * _ISR_Handler_initialization + * + */ + +#define _ISR_Handler_initialization() \ + { \ + _ISR_Signals_to_thread_executing = FALSE; \ + _ISR_Nest_level = 0; \ + } + +/*PAGE + * + * _ISR_Is_in_progress + * + */ + +#define _ISR_Is_in_progress() \ + (_ISR_Nest_level != 0) + +/*PAGE + * + * _ISR_Is_vector_number_valid + * + */ + +#define _ISR_Is_vector_number_valid( _vector ) \ + ( (_vector) < CPU_INTERRUPT_NUMBER_OF_VECTORS ) + +/*PAGE + * + * _ISR_Is_valid_user_handler + * + */ + +#define _ISR_Is_valid_user_handler( _handler ) \ + ((_handler) != NULL) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/mppkt.inl b/cpukit/score/macros/rtems/score/mppkt.inl new file mode 100644 index 0000000000..ff1d51034b --- /dev/null +++ b/cpukit/score/macros/rtems/score/mppkt.inl @@ -0,0 +1,41 @@ +/* macros/mppkt.h + * + * This package is the implementation of the Packet Handler + * routines which are inlined. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MACROS_MP_PACKET_h +#define __MACROS_MP_PACKET_h + +/*PAGE + * + * _Mp_packet_Is_valid_packet_class + * + * NOTE: Check for lower bounds (MP_PACKET_CLASSES_FIRST ) is unnecessary + * because this enum starts at lower bound of zero. + */ + +#define _Mp_packet_Is_valid_packet_class( _the_packet_class ) \ + ( (_the_packet_class) <= MP_PACKET_CLASSES_LAST ) + +/*PAGE + * + * _Mp_packet_Is_null + * + */ + +#define _Mp_packet_Is_null ( _the_packet ) \ + ( (_the_packet) == NULL ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/object.inl b/cpukit/score/macros/rtems/score/object.inl new file mode 100644 index 0000000000..f4fdc39d6e --- /dev/null +++ b/cpukit/score/macros/rtems/score/object.inl @@ -0,0 +1,146 @@ +/* object.inl + * + * This include file contains the macro implementation of all + * of the inlined routines in the Object Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __OBJECTS_inl +#define __OBJECTS_inl + +/*PAGE + * + * _Objects_Is_name_valid + * + */ + +#define _Objects_Is_name_valid( _name ) \ + ( (_name) != 0 ) + +/* + * rtems_name_to_characters + * + */ + +#define rtems_name_to_characters( _name, _c1, _c2, _c3, _c4 ) \ + { \ + (*(_c1) = ((_name) >> 24) & 0xff; \ + (*(_c2) = ((_name) >> 16) & 0xff; \ + (*(_c3) = ((_name) >> 8) & 0xff; \ + (*(_c4) = ((_name)) & 0xff; \ + } +); + +/*PAGE + * + * _Objects_Build_id + * + */ + +#define _Objects_Build_id( _node, _index ) \ + ( ((_node) << 16) | (_index) ) + +/*PAGE + * + * rtems_get_node + * + */ + +#define rtems_get_node( _id ) \ + ((_id) >> 16) + +/*PAGE + * + * rtems_get_index + * + */ + +#define rtems_get_index( _id ) \ + ((_id) & 0xFFFF) + +/*PAGE + * + * _Objects_Is_local_node + * + */ + +#define _Objects_Is_local_node( _node ) \ + ( (_node) == _Objects_Local_node ) + +/*PAGE + * + * _Objects_Is_local_id + * + */ + +#define _Objects_Is_local_id( _id ) \ + _Objects_Is_local_node( rtems_get_node(_id) ) + +/*PAGE + * + * _Objects_Are_ids_equal + * + */ + +#define _Objects_Are_ids_equal( _left, _right ) \ + ( (_left) == (_right) ) + +/*PAGE + * + * _Objects_Allocate + * + */ + +#define _Objects_Allocate( _information ) \ + (Objects_Control *) _Chain_Get( &(_information)->Inactive ) + +/*PAGE + * + * _Objects_Free + * + */ + +#define _Objects_Free( _information, _the_object ) \ + _Chain_Append( &(_information)->Inactive, &(_the_object)->Node ) + +/*PAGE + * + * _Objects_Open + * + */ + +#define _Objects_Open( _information, _the_object, _name ) \ + { \ + unsigned32 _index; \ + \ + _index = rtems_get_index( (_the_object)->id ); \ + (_information)->local_table[ _index ] = (_the_object); \ + (_information)->name_table[ _index ] = (_name); \ + } + +/*PAGE + * + * _Objects_Close + * + */ + +#define _Objects_Close( _information, _the_object ) \ + { \ + unsigned32 _index; \ + \ + _index = rtems_get_index( (_the_object)->id ); \ + (_information)->local_table[ _index ] = NULL; \ + (_information)->name_table[ _index ] = 0; \ + } + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/objectmp.inl b/cpukit/score/macros/rtems/score/objectmp.inl new file mode 100644 index 0000000000..2f1c5ac7fa --- /dev/null +++ b/cpukit/score/macros/rtems/score/objectmp.inl @@ -0,0 +1,50 @@ +/* macros/objectmp.inl + * + * This include file contains the bodies of all inlined routines + * which deal with global objects. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MACROS_MP_OBJECTS_inl +#define __MACROS_MP_OBJECTS_inl + +/*PAGE + * + * _Objects_MP_Allocate_global_object + * + */ + +#define _Objects_MP_Allocate_global_object() \ + (Objects_MP_Control *) \ + _Chain_Get( &_Objects_MP_Inactive_global_objects ) + +/*PAGE + * _Objects_MP_Free_global_object + * + */ + +#define _Objects_MP_Free_global_object( _the_object ) \ + _Chain_Append( \ + &_Objects_MP_Inactive_global_objects, \ + &(_the_object)->Object.Node \ + ) + +/*PAGE + * _Objects_MP_Is_null_global_object + * + */ + +#define _Objects_MP_Is_null_global_object( _the_object ) \ + ( (_the_object) == NULL ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/priority.inl b/cpukit/score/macros/rtems/score/priority.inl new file mode 100644 index 0000000000..7ad1fd909a --- /dev/null +++ b/cpukit/score/macros/rtems/score/priority.inl @@ -0,0 +1,144 @@ +/* priority.inl + * + * This file contains the macro implementation of all inlined routines + * in the Priority Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __PRIORITY_inl +#define __PRIORITY_inl + +#include + +/*PAGE + * + * _Priority_Handler_initialization + * + */ + +#define _Priority_Handler_initialization() \ + { \ + unsigned32 index; \ + \ + _Priority_Major_bit_map = 0; \ + for ( index=0 ; index <16 ; index++ ) \ + _Priority_Bit_map[ index ] = 0; \ + } + +/*PAGE + * + * _Priority_Is_valid + * + */ + +#define _Priority_Is_valid( _the_priority ) \ + ( ( (_the_priority) >= RTEMS_MINIMUM_PRIORITY ) && \ + ( (_the_priority) <= RTEMS_MAXIMUM_PRIORITY ) ) + +/*PAGE + * + * _Priority_Major + * + */ + +#define _Priority_Major( _the_priority ) ( (_the_priority) / 16 ) + +/*PAGE + * + * _Priority_Minor + * + */ + +#define _Priority_Minor( _the_priority ) ( (_the_priority) % 16 ) + +/*PAGE + * + * _Priority_Add_to_bit_map + * + */ + +#define _Priority_Add_to_bit_map( _the_priority_map ) \ + { \ + *(_the_priority_map)->minor |= (_the_priority_map)->ready_minor; \ + _Priority_Major_bit_map |= (_the_priority_map)->ready_major; \ + } + +/*PAGE + * + * _Priority_Remove_from_bit_map + * + */ + +#define _Priority_Remove_from_bit_map( _the_priority_map ) \ + { \ + *(_the_priority_map)->minor &= (_the_priority_map)->block_minor; \ + if ( *(_the_priority_map)->minor == 0 ) \ + _Priority_Major_bit_map &= (_the_priority_map)->block_major; \ + } + +/*PAGE + * + * _Priority_Get_highest + * + */ + +#define _Priority_Get_highest( _high_priority ) \ + { \ + Priority_Bit_map_control minor; \ + Priority_Bit_map_control major; \ + \ + _Bitfield_Find_first_bit( _Priority_Major_bit_map, major ); \ + _Bitfield_Find_first_bit( _Priority_Bit_map[major], minor ); \ + \ + (_high_priority) = (_CPU_Priority_Bits_index( major ) * 16) + \ + _CPU_Priority_Bits_index( minor ); \ + } + +/*PAGE + * + * _Priority_Initialize_information + * + */ + +#define _Priority_Initialize_information( \ + _the_priority_map, _new_priority ) \ + { \ + Priority_Bit_map_control _major; \ + Priority_Bit_map_control _minor; \ + Priority_Bit_map_control _mask; \ + \ + _major = _Priority_Major( (_new_priority) ); \ + _minor = _Priority_Minor( (_new_priority) ); \ + \ + (_the_priority_map)->minor = \ + &_Priority_Bit_map[ _CPU_Priority_Bits_index(_major) ]; \ + \ + _mask = _CPU_Priority_Mask( _major ); \ + (_the_priority_map)->ready_major = _mask; \ + (_the_priority_map)->block_major = ~_mask; \ + \ + _mask = _CPU_Priority_Mask( _minor ); \ + (_the_priority_map)->ready_minor = _mask; \ + (_the_priority_map)->block_minor = ~_mask; \ + } + +/*PAGE + * + * _Priority_Is_group_empty + * + */ + +#define _Priority_Is_group_empty ( _the_priority ) \ + ( (_the_priority) == 0 ) +} +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/stack.inl b/cpukit/score/macros/rtems/score/stack.inl new file mode 100644 index 0000000000..208503b45f --- /dev/null +++ b/cpukit/score/macros/rtems/score/stack.inl @@ -0,0 +1,50 @@ +/* stack.inl + * + * This file contains the macro implementation of the inlined + * routines from the Stack Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __STACK_inl +#define __STACK_inl + +/*PAGE + * + * _Stack_Initialize + * + */ + +#define _Stack_Initialize( _the_stack, _starting_address, _size ) \ + { \ + (_the_stack)->area = (_starting_address); \ + (_the_stack)->size = (_size); \ + } + +/*PAGE + * + * _Stack_Is_enough + * + */ + +#define _Stack_Is_enough( _size ) \ + ( (_size) >= RTEMS_MINIMUM_STACK_SIZE ) + +/*PAGE + * + * _Stack_Adjust_size + */ + +#define _Stack_Adjust_size( _size ) \ + ((_size) + CPU_STACK_ALIGNMENT) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/states.inl b/cpukit/score/macros/rtems/score/states.inl new file mode 100644 index 0000000000..f69c4ba042 --- /dev/null +++ b/cpukit/score/macros/rtems/score/states.inl @@ -0,0 +1,201 @@ +/* states.inl + * + * This file contains the macro implementation of the inlined + * routines associated with RTEMS state information. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __STATES_inl +#define __STATES_inl + +/*PAGE + * + * _States_Set + * + */ + +#define _States_Set( _states_to_set, _current_state ) \ + ((_current_state) | (_states_to_set)) + +/*PAGE + * + * _States_Clear + * + */ + +#define _States_Clear( _states_to_clear, _current_state ) \ + ((_current_state) & ~(_states_to_clear)) + +/*PAGE + * + * _States_Is_ready + * + */ + +#define _States_Is_ready( _the_states ) \ + ( (_the_states) == STATES_READY ) + +/*PAGE + * + * _States_Is_only_dormant + * + */ + +#define _States_Is_only_dormant( _the_states ) \ + ( (_the_states) == STATES_DORMANT ) + +/*PAGE + * + * _States_Is_dormant + * + */ + +#define _States_Is_dormant( _the_states ) \ + ( (_the_states) & STATES_DORMANT ) + +/*PAGE + * + * _States_Is_suspended + * + */ + +#define _States_Is_suspended( _the_states ) \ + ( (_the_states) & STATES_SUSPENDED ) + +/*PAGE + * + * _States_Is_Transient + * + */ + +#define _States_Is_transient( _the_states ) \ + ( (_the_states) & STATES_TRANSIENT ) + +/*PAGE + * + * _States_Is_delaying + * + */ + +#define _States_Is_delaying( _the_states ) \ + ( (_the_states) & STATES_DELAYING ) + +/*PAGE + * + * _States_Is_waiting_for_buffer + * + */ + +#define _States_Is_waiting_for_buffer( _the_states ) \ + ( (_the_states) & STATES_WAITING_FOR_BUFFER ) + +/*PAGE + * + * _States_Is_waiting_for_segment + * + */ + +#define _States_Is_waiting_for_segment( _the_states ) \ + ( (_the_states) & STATES_WAITING_FOR_SEGMENT ) + +/*PAGE + * + * _States_Is_waiting_for_message + * + */ + +#define _States_Is_waiting_for_message( _the_states ) \ + ( (_the_states) & STATES_WAITING_FOR_MESSAGE ) + +/*PAGE + * + * _States_Is_waiting_for_event + * + */ + +#define _States_Is_waiting_for_event( _the_states ) \ + ( (_the_states) & STATES_WAITING_FOR_EVENT ) + +/*PAGE + * + * _States_Is_waiting_for_semaphore + * + */ + +#define _States_Is_waiting_for_semaphore( _the_states ) \ + ( (_the_states) & STATES_WAITING_FOR_SEMAPHORE ) + +/*PAGE + * + * _States_Is_waiting_for_time + * + */ + +#define _States_Is_waiting_for_time( _the_states ) \ + ( (_the_states) & STATES_WAITING_FOR_TIME ) + +/*PAGE + * + * _States_Is_waiting_for_rpc_reply + * + */ + +#define _States_Is_waiting_for_rpc_reply( _the_states ) \ + ( (_the_states) & STATES_WAITING_FOR_RPC_REPLY ) + +/*PAGE + * + * _States_Is_waiting_for_period + * + */ + +#define _States_Is_waiting_for_period( _the_states ) \ + ( (_the_states) & STATES_WAITING_FOR_PERIOD ) + +/*PAGE + * + * _States_Is_locally_blocked + * + */ + +#define _States_Is_locally_blocked( _the_states ) \ + ( (_the_states) & STATES_LOCALLY_BLOCKED ) + +/*PAGE + * + * _States_Is_waiting_on_thread_queue + * + */ + +#define _States_Is_waiting_on_thread_queue( _the_states ) \ + ( (_the_states) & STATES_WAITING_ON_THREAD_QUEUE ) + +/*PAGE + * + * _States_Is_blocked + * + */ + +#define _States_Is_blocked( _the_states ) \ + ( (_the_states) & STATES_BLOCKED ) + +/*PAGE + * + * _States_Are_set + * + */ + +#define _States_Are_set( _the_states, _mask ) \ + ( ((_the_states) & (_mask)) != STATES_READY ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/sysstate.inl b/cpukit/score/macros/rtems/score/sysstate.inl new file mode 100644 index 0000000000..5cc9f9e9f9 --- /dev/null +++ b/cpukit/score/macros/rtems/score/sysstate.inl @@ -0,0 +1,77 @@ +/* sysstates.inl + * + * This file contains the macro implementation of routines regarding the + * system state. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __SYSTEM_STATE_inl +#define __SYSTEM_STATE_inl + +/*PAGE + * + * _System_state_Set + */ + +#define _System_state_Set( _state ) \ + _System_state_Current = (_state) + +/*PAGE + * + * _System_state_Get + */ + +#define _System_state_Get( void ) \ + (_System_state_Current) + +/*PAGE + * + * _System_state_Is_before_initialization + */ + +#define _System_state_Is_before_initialization( _state ) \ + ((_state) == SYSTEM_STATE_BEFORE_INITIALIZATION) + +/*PAGE + * + * _System_state_Is_before_multitasking + */ + +#define _System_state_Is_before_multitasking( _state ) \ + ((_state) == SYSTEM_STATE_BEFORE_MULTITASKING) + +/*PAGE + * + * _System_state_Is_begin_multitasking + */ + +#define _System_state_Is_begin_multitasking( _state ) \ + ((_state) == SYSTEM_STATE_BEGIN_MULTITASKING) + +/*PAGE + * + * _System_state_Is_up + */ + +#define _System_state_Is_up( _state ) \ + ((_state) == SYSTEM_STATE_UP) + +/*PAGE + * + * _System_state_Is_failed + */ + +#define _System_state_Is_failed( _state ) \ + ((_state) == SYSTEM_STATE_FAILED) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/thread.inl b/cpukit/score/macros/rtems/score/thread.inl new file mode 100644 index 0000000000..0e041de5ac --- /dev/null +++ b/cpukit/score/macros/rtems/score/thread.inl @@ -0,0 +1,193 @@ +/* thread.inl + * + * This file contains the macro implementation of the inlined + * routines from the Thread handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __THREAD_inl +#define __THREAD_inl + +/*PAGE + * + * _Thread_Stop_multitasking + * + */ + +#define _Thread_Stop_multitasking() \ + _Context_Switch( &_Thread_Executing->Registers, &_Thread_BSP_context ); + +/*PAGE + * + * _Thread_Is_executing + * + */ + +#define _Thread_Is_executing( _the_thread ) \ + ( (_the_thread) == _Thread_Executing ) + +/*PAGE + * + * _Thread_Is_heir + * + */ + +#define _Thread_Is_heir( _the_thread ) \ + ( (_the_thread) == _Thread_Heir ) + +/*PAGE + * + * _Thread_Is_executing_also_the_heir + * + */ + +#define _Thread_Is_executing_also_the_heir() \ + ( _Thread_Executing == _Thread_Heir ) + +/*PAGE + * + * _Thread_Resume + * + */ + +#define _Thread_Resume( _the_thread ) \ + _Thread_Clear_state( (_the_thread), STATES_SUSPENDED ) + +/*PAGE + * + * _Thread_Unblock + * + */ + +#define _Thread_Unblock( _the_thread ) \ + _Thread_Clear_state( (_the_thread), STATES_BLOCKED ); + +/*PAGE + * + * _Thread_Restart_self + * + */ + +#define _Thread_Restart_self() \ + { \ + if ( _Thread_Executing->fp_context != NULL ) \ + _Context_Restore_fp( &_Thread_Executing->fp_context ); \ + \ + _CPU_Context_Restart_self( &_Thread_Executing->Registers ); \ + } + +/*PAGE + * + * _Thread_Calculate_heir + * + */ + +#define _Thread_Calculate_heir() \ + { \ + rtems_task_priority highest; \ + \ + _Priority_Get_highest( highest ); \ + \ + _Thread_Heir = (Thread_Control *) _Thread_Ready_chain[ highest ].first; \ + } + +/*PAGE + * + * _Thread_Is_allocated_fp + * + */ + +#define _Thread_Is_allocated_fp( _the_thread ) \ + ( (_the_thread) == _Thread_Allocated_fp ) + +/*PAGE + * + * _Thread_Deallocate_fp + * + */ + +#define _Thread_Deallocate_fp() \ + _Thread_Allocated_fp = NULL + +/*PAGE + * + * _Thread_Disable_dispatch + * + */ + +#define _Thread_Disable_dispatch() \ + _Thread_Dispatch_disable_level += 1 + +/*PAGE + * + * _Thread_Enable_dispatch + * + */ + +#if ( CPU_INLINE_ENABLE_DISPATCH == TRUE ) +#define _Thread_Enable_dispatch() \ + { if ( (--_Thread_Dispatch_disable_level) == 0 ) \ + _Thread_Dispatch(); \ + } +#endif + +#if ( CPU_INLINE_ENABLE_DISPATCH == FALSE ) +void _Thread_Enable_dispatch( void ); +#endif + +/*PAGE + * + * _Thread_Unnest_dispatch + * + */ + +#define _Thread_Unnest_dispatch() \ + _Thread_Dispatch_disable_level -= 1 + +/*PAGE + * + * _Thread_Is_dispatching_enabled + * + */ + +#define _Thread_Is_dispatching_enabled() \ + ( _Thread_Dispatch_disable_level == 0 ) + +/*PAGE + * + * _Thread_Is_context_switch_necessary + * + */ + +#define _Thread_Is_context_switch_necessary() \ + ( _Context_Switch_necessary == TRUE ) + +/*PAGE + * + * _Thread_Dispatch_initialization + * + */ + +#define _Thread_Dispatch_initialization() \ + _Thread_Dispatch_disable_level = 1 + +/*PAGE + * + * _Thread_Is_null + * + */ + +#define _Thread_Is_null( _the_thread ) \ + ( (_the_thread) == NULL ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/threadmp.inl b/cpukit/score/macros/rtems/score/threadmp.inl new file mode 100644 index 0000000000..c601862f96 --- /dev/null +++ b/cpukit/score/macros/rtems/score/threadmp.inl @@ -0,0 +1,50 @@ +/* macros/threadmp.h + * + * This include file contains the bodies of all inlined routines + * for the multiprocessing part of thread package. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MACROS_MP_THREAD_h +#define __MACROS_MP_THREAD_h + +/*PAGE + * + * _Thread_MP_Is_receive + * + */ + +#define _Thread_MP_Is_receive( _the_thread ) \ + ( (_the_thread) == _Thread_MP_Receive) + +/*PAGE + * + * _Thread_MP_Free_proxy + * + */ + +#define _Thread_MP_Free_proxy( _the_thread ) \ +{ \ + Thread_Proxy_control *_the_proxy; \ + \ + _the_proxy = (Thread_Proxy_control *) (_the_thread); \ + \ + _Chain_Extract( &_the_proxy->Active ); \ + \ + _Chain_Append( \ + &_Thread_MP_Inactive_proxies, \ + &(_the_thread)->Object.Node \ + ); \ +} + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/tod.inl b/cpukit/score/macros/rtems/score/tod.inl new file mode 100644 index 0000000000..9360a588b1 --- /dev/null +++ b/cpukit/score/macros/rtems/score/tod.inl @@ -0,0 +1,59 @@ +/* tod.inl + * + * This file contains the macro implementation of the inlined routines + * from the Time of Day Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __TIME_OF_DAY_inl +#define __TIME_OF_DAY_inl + +/*PAGE + * + * _TOD_Is_set + * + */ + +#define _TOD_Is_set() \ + _Watchdog_Is_active( &_TOD_Seconds_watchdog ) + +/*PAGE + * + * _TOD_Tickle_ticks + * + */ + +#define _TOD_Tickle_ticks() \ + _TOD_Current.ticks++; \ + _TOD_Ticks_since_boot++ + +/*PAGE + * + * _TOD_Deactivate + * + */ + +#define _TOD_Deactivate() \ + _Watchdog_Remove( &_TOD_Seconds_watchdog ) + +/*PAGE + * + * _TOD_Activate + * + */ + +#define _TOD_Activate( ticks ) \ + _Watchdog_Insert_ticks( &_TOD_Seconds_watchdog, \ + (ticks), WATCHDOG_ACTIVATE_NOW ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/tqdata.inl b/cpukit/score/macros/rtems/score/tqdata.inl new file mode 100644 index 0000000000..5f657c1a94 --- /dev/null +++ b/cpukit/score/macros/rtems/score/tqdata.inl @@ -0,0 +1,39 @@ +/* tqdata.inl + * + * This file contains the macro implementation of the inlined + * routines needed to support the Thread Queue Data. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __THREAD_QUEUE_DATA_inl +#define __THREAD_QUEUE_DATA_inl + +/*PAGE + * + * _Thread_queue_Header_number + * + */ + +#define _Thread_queue_Header_number( _the_priority ) \ + ( (_the_priority) >> 6 ) + +/*PAGE + * + * _Thread_queue_Is_reverse_search + * + */ + +#define _Thread_queue_Is_reverse_search( _the_priority ) \ + ( (_the_priority) & 0x20 ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/userext.inl b/cpukit/score/macros/rtems/score/userext.inl new file mode 100644 index 0000000000..781f30ad40 --- /dev/null +++ b/cpukit/score/macros/rtems/score/userext.inl @@ -0,0 +1,184 @@ +/* userext.inl + * + * This file contains the macro implementation of the inlined routines + * from the User Extension Handler + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __USER_EXTENSIONS_inl +#define __USER_EXTENSIONS_inl + +/*PAGE + * + * _User_extensions_Handler_initialization + * + */ + +#define _User_extensions_Handler_initialization( _initial_extensions ) \ + { \ + _Chain_Initialize_empty( &_User_extensions_List ); \ + \ + if ( (_initial_extensions) ) { \ + _User_extensions_Initial.Callouts = *(_initial_extensions); \ + _Chain_Append( \ + &_User_extensions_List, &_User_extensions_Initial.Node ); \ + } \ + } + +/*PAGE + * + * _User_extensions_Add_set + */ + +#define _User_extensions_Add_set( _the_extension, _extension_table ) \ + { \ + (_the_extension)->Callouts = *(_extension_table); \ + \ + _Chain_Append( &_User_extensions_List, &(_the_extension)->Node ); \ + } + +/*PAGE + * + * _User_extensions_Remove_set + */ + +#define _User_extensions_Remove_set( _the_extension ) \ + _Chain_Extract( &(_the_extension)->Node ) + +/*PAGE + * + * _User_extensions_Run_list_forward + * + * NOTE: No parentheses around macro names here to avoid + * messing up the name and function call expansion. + */ + +#define _User_extensions_Run_list_forward( _name, _arguments ) \ + do { \ + Chain_Node *the_node; \ + User_extensions_Control *the_extension; \ + \ + for ( the_node = _User_extensions_List.first ; \ + !_Chain_Is_tail( &_User_extensions_List, the_node ) ; \ + the_node = the_node->next ) { \ + the_extension = (User_extensions_Control *) the_node; \ + \ + if ( the_extension->Callouts.## _name != NULL ) \ + (*the_extension->Callouts.## _name) _arguments; \ + \ + } \ + \ + } while ( 0 ) + +/*PAGE + * + * _User_extensions_Run_list_backward + * + * NOTE: No parentheses around macro names here to avoid + * messing up the name and function call expansion. + */ + +#define _User_extensions_Run_list_backward( _name, _arguments ) \ + do { \ + Chain_Node *the_node; \ + User_extensions_Control *the_extension; \ + \ + for ( the_node = _User_extensions_List.last ; \ + !_Chain_Is_head( &_User_extensions_List, the_node ) ; \ + the_node = the_node->previous ) { \ + the_extension = (User_extensions_Control *) the_node; \ + \ + if ( the_extension->Callouts.## _name != NULL ) \ + (*the_extension->Callouts.## _name) _arguments; \ + \ + } \ + \ + } while ( 0 ) + +/*PAGE + * + * _User_extensions_Task_create + * + */ + +#define _User_extensions_Task_create( _the_thread ) \ + _User_extensions_Run_list_forward(rtems_task_create, \ + (_Thread_Executing, _the_thread) ) + +/*PAGE + * + * _User_extensions_Task_delete + * + */ + +#define _User_extensions_Task_delete( _the_thread ) \ + _User_extensions_Run_list_backward(rtems_task_delete, \ + (_Thread_Executing, _the_thread) ) + +/*PAGE + * + * _User_extensions_Task_start + * + */ + +#define _User_extensions_Task_start( _the_thread ) \ + _User_extensions_Run_list_forward(rtems_task_start, \ + (_Thread_Executing, _the_thread) ) + +/*PAGE + * + * _User_extensions_Task_restart + * + */ + +#define _User_extensions_Task_restart( _the_thread ) \ + _User_extensions_Run_list_forward(rtems_task_restart,\ + (_Thread_Executing, _the_thread) ) + +/*PAGE + * + * _User_extensions_Task_switch + * + */ + +#define _User_extensions_Task_switch( _executing, _heir ) \ + _User_extensions_Run_list_forward(task_switch, (_executing, _heir) ) + +/*PAGE + * + * _User_extensions_Task_begin + * + */ + +#define _User_extensions_Task_begin( _executing ) \ + _User_extensions_Run_list_forward(task_begin, (_executing) ) + +/*PAGE + * + * _User_extensions_Task_exitted + * + */ + +#define _User_extensions_Task_exitted( _executing ) \ + _User_extensions_Run_list_backward(task_exitted, (_executing) ) + +/*PAGE + * + * _User_extensions_Fatal + * + */ + +#define _User_extensions_Fatal( _the_error ) \ + _User_extensions_Run_list_backward(fatal, (_the_error) ) + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/watchdog.inl b/cpukit/score/macros/rtems/score/watchdog.inl new file mode 100644 index 0000000000..1b150d8dab --- /dev/null +++ b/cpukit/score/macros/rtems/score/watchdog.inl @@ -0,0 +1,202 @@ +/* watchdog.inl + * + * This file contains the macro implementation of all inlined routines + * in the Watchdog Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __WATCHDOG_inl +#define __WATCHDOG_inl + +#include + +/*PAGE + * + * _Watchdog_Initialize + * + */ + +#define _Watchdog_Initialize( _the_watchdog, _routine, _id, _user_data ) \ + { \ + (_the_watchdog)->state = WATCHDOG_INACTIVE; \ + (_the_watchdog)->routine = (_routine); \ + (_the_watchdog)->id = (_id); \ + (_the_watchdog)->user_data = (_user_data); \ + } + +/*PAGE + * + * _Watchdog_Is_active + * + */ + +#define _Watchdog_Is_active( _the_watchdog ) \ + ( (_the_watchdog)->state == WATCHDOG_ACTIVE ) + +/*PAGE + * + * _Watchdog_Activate + * + */ + +#define _Watchdog_Activate( _the_watchdog ) \ + (_the_watchdog)->state = WATCHDOG_ACTIVE + +/*PAGE + * + * _Watchdog_Deactivate + * + */ + +#define _Watchdog_Deactivate( _the_watchdog ) \ + (_the_watchdog)->state = WATCHDOG_REMOVE_IT + +/*PAGE + * + * _Watchdog_Tickle_ticks + * + */ + +#define _Watchdog_Tickle_ticks() \ + _Watchdog_Tickle( &_Watchdog_Ticks_chain ) + +/*PAGE + * + * _Watchdog_Tickle_seconds + * + */ + +#define _Watchdog_Tickle_seconds() \ + _Watchdog_Tickle( &_Watchdog_Seconds_chain ) + +/*PAGE + * + * _Watchdog_Insert_ticks + * + */ + +#define _Watchdog_Insert_ticks( _the_watchdog, _units, _insert_mode ) \ + { \ + (_the_watchdog)->initial = (_units); \ + _Watchdog_Insert( &_Watchdog_Ticks_chain, \ + (_the_watchdog), (_insert_mode) ); \ + } + +/*PAGE + * + * _Watchdog_Insert_seconds + * + */ + +#define _Watchdog_Insert_seconds( _the_watchdog, _units, _insert_mode ) \ + { \ + (_the_watchdog)->initial = (_units); \ + _Watchdog_Insert( &_Watchdog_Seconds_chain, \ + (_the_watchdog), (_insert_mode) ); \ + } + +/*PAGE + * + * _Watchdog_Adjust_seconds + * + */ + +#define _Watchdog_Adjust_seconds( _direction, _units ) \ + _Watchdog_Adjust( &_Watchdog_Seconds_chain, (_direction), (_units) ) + +/*PAGE + * + * _Watchdog_Adjust_ticks + * + */ + +#define _Watchdog_Adjust_ticks( _direction, _units ) \ + _Watchdog_Adjust( &_Watchdog_Ticks_chain, (_direction), (_units) ) + +/*PAGE + * + * _Watchdog_Reset + * + */ + +#define _Watchdog_Reset( _the_watchdog ) \ + { \ + (void) _Watchdog_Remove( (_the_watchdog) ); \ + _Watchdog_Insert( &_Watchdog_Ticks_chain, \ + (_the_watchdog), WATCHDOG_ACTIVATE_NOW ); \ + } + +/*PAGE + * + * _Watchdog_Next + * + */ + +#define _Watchdog_Next( _watchdog ) \ + ((Watchdog_Control *) (_watchdog)->Node.next) + +/*PAGE + * + * _Watchdog_Previous + * + */ + +#define _Watchdog_Previous( _watchdog ) \ + ((Watchdog_Control *) (_watchdog)->Node.previous) + +/*PAGE + * + * _Watchdog_First + * + */ + +#define _Watchdog_First( _header ) \ + ((Watchdog_Control *) (_header)->first) + +/*PAGE + * + * _Watchdog_Last + * + */ + +#define _Watchdog_Last( _header ) \ + ((Watchdog_Control *) (_header)->last) + +/*PAGE + * + * _Watchdog_Get_sync + * + */ + +#define _Watchdog_Get_sync() \ + ((Watchdog_Control *) _Watchdog_Sync) + +/*PAGE + * + * _Watchdog_Set_sync + * + */ + +#define _Watchdog_Set_sync( _the_watchdog ) \ + _Watchdog_Sync = (Watchdog_Synchronization_pointer) (_the_watchdog) + +/*PAGE + * + * _Watchdog_Clear_sync + * + */ + +#define _Watchdog_Clear_sync() \ + _Watchdog_Sync = NULL; + +#endif +/* end of include file */ diff --git a/cpukit/score/macros/rtems/score/wkspace.inl b/cpukit/score/macros/rtems/score/wkspace.inl new file mode 100644 index 0000000000..3c516bfb93 --- /dev/null +++ b/cpukit/score/macros/rtems/score/wkspace.inl @@ -0,0 +1,101 @@ +/* wkspace.inl + * + * This file contains the macro implementation of the inlined routines + * from the RTEMS RAM Workspace Handler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __WORKSPACE_inl +#define __WORKSPACE_inl + +#include +#include +#include + +/*PAGE + * + * _Workspace_Handler_initialization + * + */ + +#define _Workspace_Handler_initialization( _starting_address, _size ) \ +{ \ + unsigned32 *zero_out_array; \ + unsigned32 index; \ + unsigned32 memory_available; \ + \ + if ( ((_starting_address) == NULL) || \ + !_Addresses_Is_aligned( (_starting_address) ) ) \ + rtems_fatal_error_occurred( RTEMS_INVALID_ADDRESS ); \ + \ + if ( _CPU_Table.do_zero_of_workspace ) { \ + for( zero_out_array = (unsigned32 *) (_starting_address), index = 0 ; \ + index < (_size) / 4 ; \ + index++ ) \ + zero_out_array[ index ] = 0; \ + } \ + \ + memory_available = _Heap_Initialize( \ + &_Workspace_Area, \ + (_starting_address), \ + (_size), \ + CPU_ALIGNMENT \ + ); \ + \ + if ( memory_available == 0 ) \ + rtems_fatal_error_occurred( RTEMS_UNSATISFIED ); \ +} + +/*PAGE + * + * _Workspace_Allocate + * + */ + +#define _Workspace_Allocate( _size ) \ + _Heap_Allocate( &_Workspace_Area, (_size) ) + +/*PAGE + * + * _Workspace_Allocate_or_fatal_error + * + * NOTE: XXX FIX ME + * + * When not using static inlines, this should really be a function + * somewhere. + */ + +static inline void _Workspace_Allocate_or_fatal_error( + unsigned32 size +) +{ + void *memory; + + memory = _Workspace_Allocate( size ); + + if ( memory == NULL ) + rtems_fatal_error_occurred( RTEMS_UNSATISFIED ); + + return memory; +} + +/*PAGE + * + * _Workspace_Free + * + */ + +#define _Workspace_Free( _block ) \ + _Heap_Free( &_Workspace_Area, (_block) ) + +#endif +/* end of include file */ diff --git a/cpukit/score/src/chain.c b/cpukit/score/src/chain.c new file mode 100644 index 0000000000..88f6759b0b --- /dev/null +++ b/cpukit/score/src/chain.c @@ -0,0 +1,202 @@ +/* + * Chain Handler + * + * NOTE: + * + * The order of this file is to allow proper compilation due to the + * order of inlining required by the compiler. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include + +/*PAGE + * + * _Chain_Initialize + * + * This kernel routine initializes a doubly linked chain. + * + * Input parameters: + * the_chain - pointer to chain header + * starting_address - starting address of first node + * number_nodes - number of nodes in chain + * node_size - size of node in bytes + * + * Output parameters: NONE + */ + +void _Chain_Initialize( + Chain_Control *the_chain, + void *starting_address, + unsigned32 number_nodes, + unsigned32 node_size +) +{ + unsigned32 count; + Chain_Node *current; + Chain_Node *next; + + count = number_nodes; + current = _Chain_Head( the_chain ); + the_chain->permanent_null = NULL; + next = (Chain_Node *)starting_address; + while ( count-- ) { + current->next = next; + next->previous = current; + current = next; + next = (Chain_Node *) + _Addresses_Add_offset( (void *) next, node_size ); + } + current->next = _Chain_Tail( the_chain ); + the_chain->last = current; +} + +/*PAGE + * + * _Chain_Get_first_unprotected + */ + +#ifndef USE_INLINES +Chain_Node *_Chain_Get_first_unprotected( + Chain_Control *the_chain +) +{ + Chain_Node *return_node; + Chain_Node *new_first; + + return_node = the_chain->first; + new_first = return_node->next; + the_chain->first = new_first; + new_first->previous = _Chain_Head( the_chain ); + + return return_node; +} +#endif /* USE_INLINES */ + +/*PAGE + * + * _Chain_Get + * + * This kernel routine returns a pointer to a node taken from the + * given chain. + * + * Input parameters: + * the_chain - pointer to chain header + * + * Output parameters: + * return_node - pointer to node in chain allocated + * CHAIN_END - if no nodes available + * + * INTERRUPT LATENCY: + * only case + */ + +Chain_Node *_Chain_Get( + Chain_Control *the_chain +) +{ + ISR_Level level; + Chain_Node *return_node; + + return_node = NULL; + _ISR_Disable( level ); + if ( !_Chain_Is_empty( the_chain ) ) + return_node = _Chain_Get_first_unprotected( the_chain ); + _ISR_Enable( level ); + return return_node; +} + +/*PAGE + * + * _Chain_Append + * + * This kernel routine puts a node on the end of the specified chain. + * + * Input parameters: + * the_chain - pointer to chain header + * node - address of node to put at rear of chain + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * only case + */ + +void _Chain_Append( + Chain_Control *the_chain, + Chain_Node *node +) +{ + ISR_Level level; + + _ISR_Disable( level ); + _Chain_Append_unprotected( the_chain, node ); + _ISR_Enable( level ); +} + +/*PAGE + * + * _Chain_Extract + * + * This kernel routine deletes the given node from a chain. + * + * Input parameters: + * node - pointer to node in chain to be deleted + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * only case + */ + +void _Chain_Extract( + Chain_Node *node +) +{ + ISR_Level level; + + _ISR_Disable( level ); + _Chain_Extract_unprotected( node ); + _ISR_Enable( level ); +} + +/*PAGE + * + * _Chain_Insert + * + * This kernel routine inserts a given node after a specified node + * a requested chain. + * + * Input parameters: + * after_node - pointer to node in chain to be inserted after + * node - pointer to node to be inserted + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * only case + */ + +void _Chain_Insert( + Chain_Node *after_node, + Chain_Node *node +) +{ + ISR_Level level; + + _ISR_Disable( level ); + _Chain_Insert_unprotected( after_node, node ); + _ISR_Enable( level ); +} diff --git a/cpukit/score/src/coretod.c b/cpukit/score/src/coretod.c new file mode 100644 index 0000000000..4689c637d7 --- /dev/null +++ b/cpukit/score/src/coretod.c @@ -0,0 +1,236 @@ +/* + * Time of Day (TOD) Handler + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include + +/*PAGE + * + * _TOD_Handler_initialization + * + * This routine initializes the time of day handler. + * + * Input parameters: + * microseconds_per_tick - microseconds between clock ticks + * + * Output parameters: NONE + */ + +void _TOD_Handler_initialization( + unsigned32 microseconds_per_tick +) +{ + _TOD_Microseconds_per_tick = microseconds_per_tick; + + _TOD_Ticks_since_boot = 0; + _TOD_Seconds_since_epoch = 0; + + _TOD_Current.year = TOD_BASE_YEAR; + _TOD_Current.month = 1; + _TOD_Current.day = 1; + _TOD_Current.hour = 0; + _TOD_Current.minute = 0; + _TOD_Current.second = 0; + _TOD_Current.ticks = 0; + + if ( microseconds_per_tick == 0 ) + _TOD_Ticks_per_second = 0; + else + _TOD_Ticks_per_second = + TOD_MICROSECONDS_PER_SECOND / microseconds_per_tick; + + _Watchdog_Initialize( &_TOD_Seconds_watchdog, _TOD_Tickle, 0, NULL ); +} + +/*PAGE + * + * _TOD_Set + * + * This rountine sets the current date and time with the specified + * new date and time structure. + * + * Input parameters: + * the_tod - pointer to the time and date structure + * seconds_since_epoch - seconds since system epoch + * + * Output parameters: NONE + */ + +void _TOD_Set( + rtems_time_of_day *the_tod, + rtems_interval seconds_since_epoch +) +{ + rtems_interval ticks_until_next_second; + + _Thread_Disable_dispatch(); + _TOD_Deactivate(); + + if ( seconds_since_epoch < _TOD_Seconds_since_epoch ) + _Watchdog_Adjust_seconds( WATCHDOG_BACKWARD, + _TOD_Seconds_since_epoch - seconds_since_epoch ); + else + _Watchdog_Adjust_seconds( WATCHDOG_FORWARD, + seconds_since_epoch - _TOD_Seconds_since_epoch ); + + ticks_until_next_second = _TOD_Ticks_per_second; + if ( ticks_until_next_second > _TOD_Current.ticks ) + ticks_until_next_second -= _TOD_Current.ticks; + + _TOD_Current = *the_tod; + _TOD_Seconds_since_epoch = seconds_since_epoch; + _TOD_Activate( ticks_until_next_second ); + + _Thread_Enable_dispatch(); +} + +/*PAGE + * + * _TOD_Validate + * + * This kernel routine checks the validity of a date and time structure. + * + * Input parameters: + * the_tod - pointer to a time and date structure + * + * Output parameters: + * RTEMS_SUCCESSFUL - if the date, time, and tick are valid + * RTEMS_INVALID_CLOCK - if the the_tod is invalid + * + * NOTE: This routine only works for leap-years through 2099. + */ + +rtems_status_code _TOD_Validate( + rtems_time_of_day *the_tod +) +{ + unsigned32 days_in_month; + + if ((the_tod->ticks >= _TOD_Ticks_per_second) || + (the_tod->second >= TOD_SECONDS_PER_MINUTE) || + (the_tod->minute >= TOD_MINUTES_PER_HOUR) || + (the_tod->hour >= TOD_HOURS_PER_DAY) || + (the_tod->month == 0) || + (the_tod->month > TOD_MONTHS_PER_YEAR) || + (the_tod->year < TOD_BASE_YEAR) || + (the_tod->day == 0) ) + return RTEMS_INVALID_CLOCK; + + if ( (the_tod->year % 4) == 0 ) + days_in_month = _TOD_Days_per_month[ 1 ][ the_tod->month ]; + else + days_in_month = _TOD_Days_per_month[ 0 ][ the_tod->month ]; + + if ( the_tod->day > days_in_month ) + return RTEMS_INVALID_CLOCK; + + return RTEMS_SUCCESSFUL; +} + +/*PAGE + * + * _TOD_To_seconds + * + * This routine returns the seconds from the epoch until the + * current date and time. + * + * Input parameters: + * the_tod - pointer to the time and date structure + * + * Output parameters: + * returns - seconds since epoch until the_tod + */ + +unsigned32 _TOD_To_seconds( + rtems_time_of_day *the_tod +) +{ + unsigned32 time; + unsigned32 year_mod_4; + + time = the_tod->day - 1; + year_mod_4 = the_tod->year & 3; + + if ( year_mod_4 == 0 ) + time += _TOD_Days_to_date[ 1 ][ the_tod->month ]; + else + time += _TOD_Days_to_date[ 0 ][ the_tod->month ]; + + time += ( (the_tod->year - TOD_BASE_YEAR) / 4 ) * + ( (TOD_DAYS_PER_YEAR * 4) + 1); + + time += _TOD_Days_since_last_leap_year[ year_mod_4 ]; + + time *= TOD_SECONDS_PER_DAY; + + time += ((the_tod->hour * TOD_MINUTES_PER_HOUR) + the_tod->minute) + * TOD_SECONDS_PER_MINUTE; + + time += the_tod->second; + + return( time ); +} + +/*PAGE + * + * _TOD_Tickle + * + * This routine updates the calendar time and tickles the + * per second watchdog timer chain. + * + * Input parameters: + * ignored - this parameter is ignored + * + * Output parameters: NONE + * + * NOTE: This routine only works for leap-years through 2099. + */ + +void _TOD_Tickle( + Objects_Id id, + void *ignored +) +{ + unsigned32 leap; + + _TOD_Current.ticks = 0; + ++_TOD_Seconds_since_epoch; + if ( ++_TOD_Current.second >= TOD_SECONDS_PER_MINUTE ) { + _TOD_Current.second = 0; + if ( ++_TOD_Current.minute >= TOD_MINUTES_PER_HOUR ) { + _TOD_Current.minute = 0; + if ( ++_TOD_Current.hour >= TOD_HOURS_PER_DAY ) { + _TOD_Current.hour = 0; + if ( _TOD_Current.year & 0x3 ) leap = 0; + else leap = 1; + if ( ++_TOD_Current.day > + _TOD_Days_per_month[ leap ][ _TOD_Current.month ]) { + _TOD_Current.day = 1; + if ( ++_TOD_Current.month > TOD_MONTHS_PER_YEAR ) { + _TOD_Current.month = 1; + _TOD_Current.year++; + } + } + } + } + } + + _Watchdog_Tickle_seconds(); + _Watchdog_Insert_ticks( &_TOD_Seconds_watchdog, _TOD_Ticks_per_second, + WATCHDOG_ACTIVATE_NOW ); +} diff --git a/cpukit/score/src/heap.c b/cpukit/score/src/heap.c new file mode 100644 index 0000000000..485012ddf7 --- /dev/null +++ b/cpukit/score/src/heap.c @@ -0,0 +1,478 @@ +/* + * Heap Handler + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + + +#include +#include +#include + +/*PAGE + * + * _Heap_Initialize + * + * This kernel routine initializes a heap. + * + * Input parameters: + * the_heap - pointer to heap header + * starting_address - starting address of heap + * size - size of heap + * page_size - allocatable unit of memory + * + * Output parameters: + * returns - maximum memory available if RTEMS_SUCCESSFUL + * 0 - otherwise + * + * This is what a heap looks like in memory immediately + * after initialization: + * + * +--------------------------------+ + * 0 | size = 0 | status = used | a.k.a. dummy back flag + * +--------------------------------+ + * 4 | size = size-8 | status = free | a.k.a. front flag + * +--------------------------------+ + * 8 | next = PERM HEAP_TAIL | + * +--------------------------------+ + * 12 | previous = PERM HEAP_HEAD | + * +--------------------------------+ + * | | + * | memory available | + * | for allocation | + * | | + * +--------------------------------+ + * size - 8 | size = size-8 | status = free | a.k.a. back flag + * +--------------------------------+ + * size - 4 | size = 0 | status = used | a.k.a. dummy front flag + * +--------------------------------+ + */ + +unsigned32 _Heap_Initialize( + Heap_Control *the_heap, + void *starting_address, + unsigned32 size, + unsigned32 page_size +) +{ + Heap_Block *the_block; + unsigned32 the_size; + + if ( !_Heap_Is_page_size_valid( page_size ) || + (size < HEAP_MINIMUM_SIZE) ) + return 0; + + the_heap->page_size = page_size; + the_size = size - HEAP_OVERHEAD; + + the_block = (Heap_Block *) starting_address; + the_block->back_flag = HEAP_DUMMY_FLAG; + the_block->front_flag = the_size; + the_block->next = _Heap_Tail( the_heap ); + the_block->previous = _Heap_Head( the_heap ); + + the_heap->start = the_block; + the_heap->first = the_block; + the_heap->permanent_null = NULL; + the_heap->last = the_block; + + the_block = _Heap_Next_block( the_block ); + the_block->back_flag = the_size; + the_block->front_flag = HEAP_DUMMY_FLAG; + the_heap->final = the_block; + + return ( the_size - HEAP_BLOCK_USED_OVERHEAD ); +} + +/*PAGE + * + * _Heap_Extend + * + * This routine grows the_heap memory area using the size bytes which + * begin at starting_address. + * + * Input parameters: + * the_heap - pointer to heap header. + * starting_address - pointer to the memory area. + * size - size in bytes of the memory block to allocate. + * + * Output parameters: + * *amount_extended - amount of memory added to the_heap + */ + +Heap_Extend_status _Heap_Extend( + Heap_Control *the_heap, + void *starting_address, + unsigned32 size, + unsigned32 *amount_extended +) +{ + Heap_Block *the_block; + Heap_Block *next_block; + Heap_Block *previous_block; + + /* + * There are five possibilities for the location of starting + * address: + * + * 1. non-contiguous lower address (NOT SUPPORTED) + * 2. contiguous lower address (NOT SUPPORTED) + * 3. in the heap (ERROR) + * 4. contiguous higher address (SUPPORTED) + * 5. non-contiguous higher address (NOT SUPPORTED) + * + * As noted, this code only supports (4). + */ + + if ( starting_address >= (void *) the_heap->start && /* case 3 */ + starting_address <= (void *) the_heap->final + ) + return HEAP_EXTEND_ERROR; + + if ( starting_address < (void *) the_heap->start ) { /* cases 1 and 2 */ + + return HEAP_EXTEND_NOT_IMPLEMENTED; /* cases 1 and 2 */ + + } else { /* cases 4 and 5 */ + + the_block = (Heap_Block *) (starting_address - HEAP_OVERHEAD); + if ( the_block != the_heap->final ) + return HEAP_EXTEND_NOT_IMPLEMENTED; /* case 5 */ + } + + /* + * Currently only case 4 should make it to this point. + */ + + *amount_extended = size - HEAP_BLOCK_USED_OVERHEAD; + + previous_block = the_heap->last; + + the_block = (Heap_Block *) starting_address; + the_block->front_flag = size; + the_block->next = previous_block->next; + the_block->previous = previous_block; + + previous_block->next = the_block; + the_heap->last = the_block; + + next_block = _Heap_Next_block( the_block ); + next_block->back_flag = size; + next_block->front_flag = HEAP_DUMMY_FLAG; + the_heap->final = next_block; + + return HEAP_EXTEND_SUCCESSFUL; +} + +/*PAGE + * + * _Heap_Allocate + * + * This kernel routine allocates the requested size of memory + * from the specified heap. + * + * Input parameters: + * the_heap - pointer to heap header. + * size - size in bytes of the memory block to allocate. + * + * Output parameters: + * returns - starting address of memory block allocated + */ + +void *_Heap_Allocate( + Heap_Control *the_heap, + unsigned32 size +) +{ + unsigned32 excess; + unsigned32 the_size; + Heap_Block *the_block; + Heap_Block *next_block; + Heap_Block *temporary_block; + + excess = size % the_heap->page_size; + the_size = size + HEAP_BLOCK_USED_OVERHEAD; + + if ( excess ) + the_size += the_heap->page_size - excess; + + if ( the_size < sizeof( Heap_Block ) ) + the_size = sizeof( Heap_Block ); + + for ( the_block = the_heap->first; + ; + the_block = the_block->next ) { + if ( the_block == _Heap_Tail( the_heap ) ) + return( NULL ); + if ( the_block->front_flag >= the_size ) + break; + } + + if ( (the_block->front_flag - the_size) > + (the_heap->page_size + HEAP_BLOCK_USED_OVERHEAD) ) { + the_block->front_flag -= the_size; + next_block = _Heap_Next_block( the_block ); + next_block->back_flag = the_block->front_flag; + + temporary_block = _Heap_Block_at( next_block, the_size ); + temporary_block->back_flag = + next_block->front_flag = _Heap_Build_flag( the_size, + HEAP_BLOCK_USED ); + return( _Heap_Start_of_user_area( next_block ) ); + } else { + next_block = _Heap_Next_block( the_block ); + next_block->back_flag = _Heap_Build_flag( the_block->front_flag, + HEAP_BLOCK_USED ); + the_block->front_flag = next_block->back_flag; + the_block->next->previous = the_block->previous; + the_block->previous->next = the_block->next; + return( _Heap_Start_of_user_area( the_block ) ); + } +} + +/*PAGE + * + * _Heap_Size_of_user_area + * + * This kernel routine returns the size of the memory area + * given heap block. + * + * Input parameters: + * the_heap - pointer to heap header + * starting_address - starting address of the memory block to free. + * size - pointer to size of area + * + * Output parameters: + * size - size of area filled in + * TRUE - if starting_address is valid heap address + * FALSE - if starting_address is invalid heap address + */ + +boolean _Heap_Size_of_user_area( + Heap_Control *the_heap, + void *starting_address, + unsigned32 *size +) +{ + Heap_Block *the_block; + Heap_Block *next_block; + unsigned32 the_size; + + the_block = _Heap_Block_at( starting_address, - (sizeof( void * ) * 2) ); + + if ( !_Heap_Is_block_in( the_heap, the_block ) || + _Heap_Is_block_free( the_block ) ) + return( FALSE ); + + the_size = _Heap_Block_size( the_block ); + next_block = _Heap_Block_at( the_block, the_size ); + + if ( !_Heap_Is_block_in( the_heap, next_block ) || + (the_block->front_flag != next_block->back_flag) ) + return( FALSE ); + + *size = the_size; + return( TRUE ); +} + +/*PAGE + * + * _Heap_Free + * + * This kernel routine returns the memory designated by the + * given heap and given starting address to the memory pool. + * + * Input parameters: + * the_heap - pointer to heap header + * starting_address - starting address of the memory block to free. + * + * Output parameters: + * TRUE - if starting_address is valid heap address + * FALSE - if starting_address is invalid heap address + */ + +boolean _Heap_Free( + Heap_Control *the_heap, + void *starting_address +) +{ + Heap_Block *the_block; + Heap_Block *next_block; + Heap_Block *new_next_block; + Heap_Block *previous_block; + Heap_Block *temporary_block; + unsigned32 the_size; + + the_block = _Heap_Block_at( starting_address, - (sizeof( void * ) * 2) ); + + if ( !_Heap_Is_block_in( the_heap, the_block ) || + _Heap_Is_block_free( the_block ) ) { + return( FALSE ); + } + + the_size = _Heap_Block_size( the_block ); + next_block = _Heap_Block_at( the_block, the_size ); + + if ( !_Heap_Is_block_in( the_heap, next_block ) || + (the_block->front_flag != next_block->back_flag) ) { + return( FALSE ); + } + + if ( _Heap_Is_previous_block_free( the_block ) ) { + previous_block = _Heap_Previous_block( the_block ); + + if ( !_Heap_Is_block_in( the_heap, previous_block ) ) { + return( FALSE ); + } + + if ( _Heap_Is_block_free( next_block ) ) { /* coalesce both */ + previous_block->front_flag += next_block->front_flag + the_size; + temporary_block = _Heap_Next_block( previous_block ); + temporary_block->back_flag = previous_block->front_flag; + next_block->next->previous = next_block->previous; + next_block->previous->next = next_block->next; + } + else { /* coalesce prev */ + previous_block->front_flag = + next_block->back_flag = previous_block->front_flag + the_size; + } + } + else if ( _Heap_Is_block_free( next_block ) ) { /* coalesce next */ + the_block->front_flag = the_size + next_block->front_flag; + new_next_block = _Heap_Next_block( the_block ); + new_next_block->back_flag = the_block->front_flag; + the_block->next = next_block->next; + the_block->previous = next_block->previous; + next_block->previous->next = the_block; + next_block->next->previous = the_block; + + if (the_heap->first == next_block) + the_heap->first = the_block; + } + else { /* no coalesce */ + next_block->back_flag = + the_block->front_flag = the_size; + the_block->previous = _Heap_Head( the_heap ); + the_block->next = the_heap->first; + the_heap->first = the_block; + the_block->next->previous = the_block; + } + + return( TRUE ); +} + +/*PAGE + * + * _Heap_Walk + * + * This kernel routine walks the heap and verifies its correctness. + * + * Input parameters: + * the_heap - pointer to heap header + * source - a numeric indicator of the invoker of this routine + * do_dump - when TRUE print the information + * + * Output parameters: NONE + */ + +#include +#include + +void _Heap_Walk( + Heap_Control *the_heap, + int source, + boolean do_dump +) +{ + Heap_Block *the_block; + Heap_Block *next_block; + int notdone = 1; + + /* + * We don't want to allow walking the heap until we have + * transferred control to the user task so we watch the + * system state. + */ + + if ( !_System_state_Is_up( _System_state_Get() ) ) + return; + + the_block = the_heap->start; + + if (do_dump == TRUE) { + printf("\nPASS: %d start @ 0x%p final 0x%p, first 0x%p last 0x%p\n", + source, the_heap->start, the_heap->final, + the_heap->first, the_heap->last + ); + } + + /* + * Handle the 1st block + */ + + if (the_block->back_flag != HEAP_DUMMY_FLAG) { + printf("PASS: %d Back flag of 1st block isn't HEAP_DUMMY_FLAG\n", source); + } + + while (notdone) { + if (do_dump == TRUE) { + printf("PASS: %d Block @ 0x%p Back %d, Front %d", + source, the_block, + the_block->back_flag, the_block->front_flag); + if ( _Heap_Is_block_free(the_block) ) { + printf( " Prev 0x%p, Next 0x%p\n", + the_block->previous, the_block->next); + } else { + printf("\n"); + } + } + + /* + * Handle the last block + */ + + if ( the_block->front_flag != HEAP_DUMMY_FLAG ) { + next_block = _Heap_Next_block(the_block); + if ( the_block->front_flag != next_block->back_flag ) { + printf("PASS: %d Front and back flags don't match\n", source); + printf(" Current Block: Back - %d, Front - %d", + the_block->back_flag, the_block->front_flag); + if (do_dump == TRUE) { + if (_Heap_Is_block_free(the_block)) { + printf(" Prev 0x%p, Next 0x%p\n", + the_block->previous, the_block->next); + } else { + printf("\n"); + } + } else { + printf("\n"); + } + printf(" Next Block: Back - %d, Front - %d", + next_block->back_flag, next_block->front_flag); + if (do_dump == TRUE) { + if (_Heap_Is_block_free(next_block)) { + printf(" Prev 0x%p, Next 0x%p\n", + the_block->previous, the_block->next); + } else { + printf("\n"); + } + } else { + printf("\n"); + } + } + } + + if (the_block->front_flag == HEAP_DUMMY_FLAG) + notdone = 0; + else + the_block = next_block; + } +} diff --git a/cpukit/score/src/mpci.c b/cpukit/score/src/mpci.c new file mode 100644 index 0000000000..e8d3803d76 --- /dev/null +++ b/cpukit/score/src/mpci.c @@ -0,0 +1,237 @@ +/* + * Multiprocessing Communications Interface (MPCI) Handler + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _MPCI_Handler_initialization + * + * This subprogram performs the initialization necessary for this handler. + */ + +void _MPCI_Handler_initialization ( void ) +{ + _Thread_queue_Initialize( + &_MPCI_Remote_blocked_threads, + RTEMS_FIFO, + STATES_WAITING_FOR_RPC_REPLY + ); +} + +/*PAGE + * + * _MPCI_Initialization + * + * This subprogram initializes the MPCI driver by + * invoking the user provided MPCI initialization callout. + */ + +void _MPCI_Initialization ( void ) +{ + (*_Configuration_MPCI_table->initialization)( + _Configuration_Table, + &_CPU_Table, + _Configuration_MP_table + ); +} + +/*PAGE + * + * _MPCI_Get_packet + * + * This subprogram obtains a packet by invoking the user provided + * MPCI get packet callout. + */ + +rtems_packet_prefix *_MPCI_Get_packet ( void ) +{ + rtems_packet_prefix *the_packet; + + (*_Configuration_MPCI_table->get_packet)( &the_packet ); + + if ( the_packet == NULL ) + rtems_fatal_error_occurred( RTEMS_UNSATISFIED ); + + /* + * Put in a default timeout that will be used for + * all packets that do not otherwise have a timeout. + */ + + the_packet->timeout = MPCI_DEFAULT_TIMEOUT; + + return the_packet; +} + +/*PAGE + * + * _MPCI_Return_packet + * + * This subprogram returns a packet by invoking the user provided + * MPCI return packet callout. + */ + +void _MPCI_Return_packet ( + rtems_packet_prefix *the_packet +) +{ + (*_Configuration_MPCI_table->return_packet)( the_packet ); +} + +/*PAGE + * + * _MPCI_Send_process_packet + * + * This subprogram sends a process packet by invoking the user provided + * MPCI send callout. + */ + +void _MPCI_Send_process_packet ( + unsigned32 destination, + rtems_packet_prefix *the_packet +) +{ + the_packet->source_tid = _Thread_Executing->Object.id; + the_packet->to_convert = + ( the_packet->to_convert - sizeof(rtems_packet_prefix) ) / + sizeof(unsigned32); + + (*_Configuration_MPCI_table->send_packet)( destination, the_packet ); +} + +/*PAGE + * + * _MPCI_Send_request_packet + * + * This subprogram sends a request packet by invoking the user provided + * MPCI send callout. + */ + +rtems_status_code _MPCI_Send_request_packet ( + unsigned32 destination, + rtems_packet_prefix *the_packet, + States_Control extra_state +) +{ + the_packet->source_tid = _Thread_Executing->Object.id; + the_packet->source_priority = _Thread_Executing->current_priority; + the_packet->to_convert = + ( the_packet->to_convert - sizeof(rtems_packet_prefix) ) / + sizeof(unsigned32); + + _Thread_Executing->Wait.id = the_packet->id; + + _Thread_Executing->Wait.queue = &_MPCI_Remote_blocked_threads; + + _Thread_Disable_dispatch(); + + (*_Configuration_MPCI_table->send_packet)( destination, the_packet ); + + _MPCI_Remote_blocked_threads.sync = TRUE; + + /* + * See if we need a default timeout + */ + + if (the_packet->timeout == MPCI_DEFAULT_TIMEOUT) + the_packet->timeout = _Configuration_MPCI_table->default_timeout; + + _Thread_queue_Enqueue( &_MPCI_Remote_blocked_threads, the_packet->timeout ); + + _Thread_Executing->current_state = + _States_Set( extra_state, _Thread_Executing->current_state ); + + _Thread_Enable_dispatch(); + + return _Thread_Executing->Wait.return_code; +} + +/*PAGE + * + * _MPCI_Send_response_packet + * + * This subprogram sends a response packet by invoking the user provided + * MPCI send callout. + */ + +void _MPCI_Send_response_packet ( + unsigned32 destination, + rtems_packet_prefix *the_packet +) +{ + the_packet->source_tid = _Thread_Executing->Object.id; + + (*_Configuration_MPCI_table->send_packet)( destination, the_packet ); +} + +/*PAGE + * + * _MPCI_Receive_packet + * + * This subprogram receives a packet by invoking the user provided + * MPCI receive callout. + */ + +rtems_packet_prefix *_MPCI_Receive_packet ( void ) +{ + rtems_packet_prefix *the_packet; + + (*_Configuration_MPCI_table->receive_packet)( &the_packet ); + + return the_packet; +} + +/*PAGE + * + * _MPCI_Process_response + * + * This subprogram obtains a packet by invoking the user provided + * MPCI get packet callout. + */ + +Thread_Control *_MPCI_Process_response ( + rtems_packet_prefix *the_packet +) +{ + Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( the_packet->id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + case OBJECTS_REMOTE: + the_thread = NULL; /* IMPOSSIBLE */ + break; + case OBJECTS_LOCAL: + _Thread_queue_Extract( &_MPCI_Remote_blocked_threads, the_thread ); + the_thread->Wait.return_code = the_packet->return_code; + _Thread_Unnest_dispatch(); + break; + } + + return the_thread; +} + +/* end of file */ diff --git a/cpukit/score/src/object.c b/cpukit/score/src/object.c new file mode 100644 index 0000000000..71c365fa1e --- /dev/null +++ b/cpukit/score/src/object.c @@ -0,0 +1,228 @@ +/* + * Object Handler + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Objects_Handler_initialization + * + * This routine initializes the object handler. + * + * Input parameters: + * node - local node + * maximum_global_objects - number of configured global objects + * + * Output parameters: NONE + */ + +void _Objects_Handler_initialization( + unsigned32 node, + unsigned32 maximum_global_objects +) +{ + _Objects_Local_node = node; + + _Objects_MP_Handler_initialization( maximum_global_objects ); +} + +/*PAGE + * + * _Objects_Initialize_information + * + * This routine initializes all object information related data structures. + * + * Input parameters: + * information - object class + * supports_global - TRUE if this is a global object class + * maximum - maximum objects of this class + * size - size of this object's control block + * + * Output parameters: NONE + */ + +void _Objects_Initialize_information( + Objects_Information *information, + boolean supports_global, + unsigned32 maximum, + unsigned32 size +) +{ + unsigned32 minimum_index; + unsigned32 index; + Objects_Control *the_object; + + information->maximum = maximum; + + if ( maximum == 0 ) minimum_index = 0; + else minimum_index = 1; + + information->minimum_id = + _Objects_Build_id( _Objects_Local_node, minimum_index ); + + information->maximum_id = + _Objects_Build_id( _Objects_Local_node, maximum ); + + information->local_table = _Workspace_Allocate_or_fatal_error( + (maximum + 1) * sizeof(Objects_Control *) + ); + + information->name_table = _Workspace_Allocate_or_fatal_error( + (maximum + 1) * sizeof(Objects_Name) + ); + + for ( index=0 ; index < maximum ; index++ ) { + information->local_table[ index ] = NULL; + information->name_table[ index ] = 0; + } + + if ( maximum == 0 ) { + _Chain_Initialize_empty( &information->Inactive ); + } else { + + + _Chain_Initialize( + &information->Inactive, + _Workspace_Allocate_or_fatal_error( maximum * size ), + maximum, + size + ); + + the_object = (Objects_Control *) information->Inactive.first; + for ( index=1; + index <= maximum ; + index++ ) { + the_object->id = _Objects_Build_id( _Objects_Local_node, index ); + the_object = (Objects_Control *) the_object->Node.next; + } + + } + + if ( supports_global == TRUE && _Configuration_Is_multiprocessing() ) { + + information->global_table = _Workspace_Allocate_or_fatal_error( + (_Configuration_MP_table->maximum_nodes + 1) * sizeof(Chain_Control) + ); + + for ( index=1; + index <= _Configuration_MP_table->maximum_nodes ; + index++ ) + _Chain_Initialize_empty( &information->global_table[ index ] ); + } + else + information->global_table = NULL; +} + +/*PAGE + * + * _Objects_Name_to_id + * + * These kernel routines search the object table(s) for the given + * object name and returns the associated object id. + * + * Input parameters: + * information - object information + * name - user defined object name + * node - node indentifier (0 indicates any node) + * id - address of return ID + * + * Output parameters: + * obj_id - object id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code _Objects_Name_to_id( + Objects_Information *information, + Objects_Name name, + unsigned32 node, + Objects_Id *id +) +{ + Objects_Name *names; + unsigned32 index; + + if ( name == 0 ) + return( RTEMS_INVALID_NAME ); + + if ( (information->maximum != 0) && + (node == RTEMS_SEARCH_ALL_NODES || + node == RTEMS_SEARCH_LOCAL_NODE || + _Objects_Is_local_node( node )) ) { + for ( names = information->name_table, index = 1; + index <= information->maximum; + index++ + ) + if ( name == names[ index ] ) { + *id = _Objects_Build_id( _Objects_Local_node, index ); + return( RTEMS_SUCCESSFUL ); + } + } + + if ( _Objects_Is_local_node( node ) || node == RTEMS_SEARCH_LOCAL_NODE ) + return( RTEMS_INVALID_NAME ); + + return ( _Objects_MP_Global_name_search( information, name, node, id ) ); +} + +/*PAGE + * + * _Objects_Get + * + * This routine sets the object pointer for the given + * object id based on the given object information structure. + * + * Input parameters: + * information - pointer to entry in table for this class + * id - object id to search for + * location - address of where to store the location + * + * Output parameters: + * returns - address of object if local + * location - one of the following: + * OBJECTS_ERROR - invalid object ID + * OBJECTS_REMOTE - remote object + * OBJECTS_LOCAL - local object + */ + +Objects_Control *_Objects_Get( + Objects_Information *information, + Objects_Id id, + Objects_Locations *location +) +{ + Objects_Control *the_object; + unsigned32 index; + + index = id - information->minimum_id; + if ( information->maximum >= index ) { + _Thread_Disable_dispatch(); + if ( (the_object = information->local_table[index+1]) != NULL ) { + *location = OBJECTS_LOCAL; + return( the_object ); + } + _Thread_Enable_dispatch(); + *location = OBJECTS_ERROR; + return( NULL ); + } + *location = OBJECTS_ERROR; + _Objects_MP_Is_remote( information, id, location, &the_object ); + return the_object; +} diff --git a/cpukit/score/src/objectmp.c b/cpukit/score/src/objectmp.c new file mode 100644 index 0000000000..d75a34b150 --- /dev/null +++ b/cpukit/score/src/objectmp.c @@ -0,0 +1,250 @@ +/* + * Multiprocessing Support for the Object Handler + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include + +/*PAGE + * + * _Objects_MP_Handler_initialization + * + */ + +void _Objects_MP_Handler_initialization ( + unsigned32 maximum_global_objects +) +{ + + if ( maximum_global_objects == 0 ) { + _Chain_Initialize_empty( &_Objects_MP_Inactive_global_objects ); + return; + } + + _Chain_Initialize( + &_Objects_MP_Inactive_global_objects, + _Workspace_Allocate_or_fatal_error( + maximum_global_objects * sizeof( Objects_MP_Control ) + ), + maximum_global_objects, + sizeof( Objects_MP_Control ) + ); + +} + +/*PAGE + * + * _Objects_MP_Open + * + */ + +boolean _Objects_MP_Open ( + Objects_Information *information, + Objects_Name the_name, + Objects_Id the_id, + boolean is_fatal_error +) +{ + Objects_MP_Control *the_global_object; + + the_global_object = _Objects_MP_Allocate_global_object(); + if ( _Objects_MP_Is_null_global_object( the_global_object ) ) { + + if ( is_fatal_error == FALSE ) + return FALSE; + + rtems_fatal_error_occurred( RTEMS_TOO_MANY ); + + } + + the_global_object->Object.id = the_id; + the_global_object->name = the_name; + + _Chain_Prepend( + &information->global_table[ rtems_get_node( the_id ) ], + &the_global_object->Object.Node + ); + + return TRUE; +} + +/*PAGE + * + * _Objects_MP_Close + * + */ + +void _Objects_MP_Close ( + Objects_Information *information, + Objects_Id the_id +) +{ + Chain_Control *the_chain; + Chain_Node *the_node; + Objects_MP_Control *the_object; + + the_chain = &information->global_table[ rtems_get_node( the_id ) ]; + + for ( the_node = the_chain->first ; + !_Chain_Is_tail( the_chain, the_node ) ; + the_node = the_node->next ) { + + the_object = (Objects_MP_Control *) the_node; + + if ( _Objects_Are_ids_equal( the_object->Object.id, the_id ) ) { + + _Chain_Extract( the_node ); + _Objects_MP_Free_global_object( the_object ); + + return; + + } + + } + + rtems_fatal_error_occurred( RTEMS_INVALID_ID ); + + +} + +/*PAGE + * + * _Objects_MP_Global_name_search + * + */ + +rtems_status_code _Objects_MP_Global_name_search ( + Objects_Information *information, + Objects_Name the_name, + unsigned32 nodes_to_search, + Objects_Id *the_id +) +{ + unsigned32 low_node; + unsigned32 high_node; + unsigned32 node_index; + Chain_Control *the_chain; + Chain_Node *the_node; + Objects_MP_Control *the_object; + + + if ( nodes_to_search > _Configuration_MP_table->maximum_nodes ) + return ( RTEMS_INVALID_NODE ); + + if ( information->global_table == NULL ) + return ( RTEMS_INVALID_NAME ); + + if ( nodes_to_search == RTEMS_SEARCH_ALL_NODES || + nodes_to_search == RTEMS_SEARCH_OTHER_NODES ) { + low_node = 1; + high_node = _Configuration_MP_table->maximum_nodes; + } else { + low_node = + high_node = nodes_to_search; + } + + _Thread_Disable_dispatch(); + + for ( node_index = low_node ; node_index <= high_node ; node_index++ ) { + + /* + * NOTE: The local node was search (if necessary) by + * _Objects_Name_to_id before this was invoked. + */ + + if ( !_Objects_Is_local_node( node_index ) ) { + the_chain = &information->global_table[ node_index ]; + + for ( the_node = the_chain->first ; + !_Chain_Is_tail( the_chain, the_node ) ; + the_node = the_node->next ) { + + the_object = (Objects_MP_Control *) the_node; + + if ( the_object->name == the_name ) { + *the_id = the_object->Object.id; + _Thread_Enable_dispatch(); + return ( RTEMS_SUCCESSFUL ); + } + } + } + } + + _Thread_Enable_dispatch(); + return ( RTEMS_INVALID_NAME ); +} + +/*PAGE + * + * _Objects_MP_Is_remote + * + */ + +void _Objects_MP_Is_remote ( + Objects_Information *information, + Objects_Id the_id, + Objects_Locations *location, + Objects_Control **the_object +) +{ + unsigned32 node; + Chain_Control *the_chain; + Chain_Node *the_node; + Objects_MP_Control *the_global_object; + + node = rtems_get_node( the_id ); + + /* + * NOTE: The local node was search (if necessary) by + * _Objects_Name_to_id before this was invoked. + * + * The NODE field of an object id cannot be 0 + * because 0 is an invalid node number. + */ + + if ( node == 0 || + _Objects_Is_local_node( node ) || + node > _Configuration_MP_table->maximum_nodes || + information->global_table == NULL ) { + + *location = OBJECTS_ERROR; + *the_object = NULL; + return; + } + + _Thread_Disable_dispatch(); + + the_chain = &information->global_table[ node ]; + + for ( the_node = the_chain->first ; + !_Chain_Is_tail( the_chain, the_node ) ; + the_node = the_node->next ) { + + the_global_object = (Objects_MP_Control *) the_node; + + if ( _Objects_Are_ids_equal( the_global_object->Object.id, the_id ) ) { + _Thread_Unnest_dispatch(); + *location = OBJECTS_REMOTE; + *the_object = (Objects_Control *) the_global_object; + return; + } + } + + _Thread_Enable_dispatch(); + *location = OBJECTS_ERROR; + *the_object = NULL; + +} diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c new file mode 100644 index 0000000000..2d9fc33e6b --- /dev/null +++ b/cpukit/score/src/thread.c @@ -0,0 +1,805 @@ +/* + * Thread Handler + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Thread_Handler_initialization + * + * This routine initializes all thread manager related data structures. + * + * Input parameters: + * maximum_tasks - number of tasks to initialize + * ticks_per_timeslice - clock ticks per quantum + * + * Output parameters: NONE + */ + +void _Thread_Handler_initialization( + unsigned32 maximum_tasks, + unsigned32 ticks_per_timeslice, + unsigned32 maximum_proxies +) +{ + unsigned32 index; + + _Context_Switch_necessary = FALSE; + _Thread_Executing = NULL; + _Thread_Heir = NULL; + _Thread_Allocated_fp = NULL; + + _Thread_Ticks_remaining_in_timeslice = ticks_per_timeslice; + _Thread_Ticks_per_timeslice = ticks_per_timeslice; + + _Objects_Initialize_information( + &_Thread_Information, + TRUE, + maximum_tasks, + sizeof( Thread_Control ) + ); + + _Thread_Ready_chain = _Workspace_Allocate_or_fatal_error( + (RTEMS_MAXIMUM_PRIORITY + 1) * sizeof(Chain_Control) + ); + + for ( index=0; index <= RTEMS_MAXIMUM_PRIORITY ; index++ ) + _Chain_Initialize_empty( &_Thread_Ready_chain[ index ] ); + + _Thread_MP_Handler_initialization( maximum_proxies ); +} + +/*PAGE + * + * _Thread_Start_multitasking + * + * This kernel routine readies the requested thread, the thread chain + * is adjusted. A new heir thread may be selected. + * + * Input parameters: + * system_thread - pointer to system initialization thread control block + * idle_thread - pointer to idle thread control block + * + * Output parameters: NONE + * + * NOTE: This routine uses the "blocking" heir selection mechanism. + * This insures the correct heir after a thread restart. + * + * INTERRUPT LATENCY: + * ready chain + * select heir + */ + +void _Thread_Start_multitasking( + Thread_Control *system_thread, + Thread_Control *idle_thread +) +{ + + _Thread_Executing = + _Thread_Heir = + _Thread_MP_Receive = system_thread; + + /* + * Scheduling will not work "correctly" until the above + * statements have been executed. + */ + + _Thread_Ready( system_thread ); + _Thread_Ready( idle_thread ); + + _Context_Switch_necessary = FALSE; + + _Context_Switch( &_Thread_BSP_context, &system_thread->Registers ); + +} + +/*PAGE + * + * _Thread_Dispatch + * + * This kernel routine determines if a dispatch is needed, and if so + * dispatches to the heir thread. Once the heir is running an attempt + * is made to dispatch any ASRs. + * + * ALTERNATE ENTRY POINTS: + * void _Thread_Enable_dispatch(); + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * dispatch thread + * no dispatch thread + */ + +#if ( CPU_INLINE_ENABLE_DISPATCH == FALSE ) +void _Thread_Enable_dispatch( void ) +{ + if ( --_Thread_Dispatch_disable_level ) + return; + _Thread_Dispatch(); +} +#endif + +void _Thread_Dispatch( void ) +{ + Thread_Control *executing; + Thread_Control *heir; + ISR_Level level; + rtems_signal_set signal_set; + rtems_mode previous_mode; + + executing = _Thread_Executing; + _ISR_Disable( level ); + while ( _Context_Switch_necessary == TRUE ) { + heir = _Thread_Heir; + _Thread_Dispatch_disable_level = 1; + _Context_Switch_necessary = FALSE; + _Thread_Executing = heir; + _ISR_Enable( level ); + + _User_extensions_Task_switch( executing, heir ); + + _Thread_Ticks_remaining_in_timeslice = _Thread_Ticks_per_timeslice; + + /* + * If the CPU has hardware floating point, then we must address saving + * and restoring it as part of the context switch. + * + * The second conditional compilation section selects the algorithm used + * to context switch between floating point tasks. The deferred algorithm + * can be significantly better in a system with few floating point tasks + * because it reduces the total number of save and restore FP context + * operations. However, this algorithm can not be used on all CPUs due + * to unpredictable use of FP registers by some compilers for integer + * operations. + */ + +#if ( CPU_HARDWARE_FP == TRUE ) +#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE ) + if ( (heir->fp_context != NULL) && !_Thread_Is_allocated_fp( heir ) ) { + if ( _Thread_Allocated_fp != NULL ) + _Context_Save_fp( &_Thread_Allocated_fp->fp_context ); + _Context_Restore_fp( &heir->fp_context ); + _Thread_Allocated_fp = heir; + } +#else + if ( executing->fp_context != NULL ) + _Context_Save_fp( &executing->fp_context ); + + if ( heir->fp_context != NULL ) + _Context_Restore_fp( &heir->fp_context ); +#endif +#endif + + _Context_Switch( &executing->Registers, &heir->Registers ); + + executing = _Thread_Executing; + _ISR_Disable( level ); + } + + _Thread_Dispatch_disable_level = 0; + + if ( _ASR_Are_signals_pending( &executing->Signal ) ) { + signal_set = executing->Signal.signals_posted; + executing->Signal.signals_posted = 0; + _ISR_Enable( level ); + + executing->Signal.nest_level += 1; + if (_Thread_Change_mode( executing->Signal.mode_set, + RTEMS_ALL_MODE_MASKS, &previous_mode )) + _Thread_Dispatch(); + + (*executing->Signal.handler)( signal_set ); + + executing->Signal.nest_level -= 1; + if (_Thread_Change_mode( previous_mode, + RTEMS_ALL_MODE_MASKS, &previous_mode )) + _Thread_Dispatch(); + } + else + _ISR_Enable( level ); +} + +/*PAGE + * + * _Thread_Ready + * + * This kernel routine readies the requested thread, the thread chain + * is adjusted. A new heir thread may be selected. + * + * Input parameters: + * the_thread - pointer to thread control block + * + * Output parameters: NONE + * + * NOTE: This routine uses the "blocking" heir selection mechanism. + * This insures the correct heir after a thread restart. + * + * INTERRUPT LATENCY: + * ready chain + * select heir + */ + +void _Thread_Ready( + Thread_Control *the_thread +) +{ + ISR_Level level; + Thread_Control *heir; + + _ISR_Disable( level ); + + the_thread->current_state = STATES_READY; + + _Priority_Add_to_bit_map( &the_thread->Priority_map ); + + _Chain_Append_unprotected( the_thread->ready, &the_thread->Object.Node ); + + _ISR_Flash( level ); + + _Thread_Calculate_heir(); + + heir = _Thread_Heir; + + if ( !_Thread_Is_executing( heir ) && + _Modes_Is_preempt( _Thread_Executing->current_modes ) ) + _Context_Switch_necessary = TRUE; + + _ISR_Enable( level ); +} + +/*PAGE + * + * _Thread_Clear_state + * + * This kernel routine clears the appropriate states in the + * requested thread. The thread ready chain is adjusted if + * necessary and the Heir thread is set accordingly. + * + * Input parameters: + * the_thread - pointer to thread control block + * state - state set to clear + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * priority map + * select heir + */ + +void _Thread_Clear_state( + Thread_Control *the_thread, + States_Control state +) +{ + ISR_Level level; + + _ISR_Disable( level ); + the_thread->current_state = + _States_Clear( state, the_thread->current_state ); + + if ( _States_Is_ready( the_thread->current_state ) ) { + + _Priority_Add_to_bit_map( &the_thread->Priority_map ); + + _Chain_Append_unprotected( the_thread->ready, &the_thread->Object.Node ); + + _ISR_Flash( level ); + + if ( the_thread->current_priority < _Thread_Heir->current_priority ) { + _Thread_Heir = the_thread; + if ( _Modes_Is_preempt( _Thread_Executing->current_modes ) ) + _Context_Switch_necessary = TRUE; + } + } + _ISR_Enable( level ); +} + +/*PAGE + * + * _Thread_Set_state + * + * This kernel routine sets the requested state in the THREAD. The + * THREAD chain is adjusted if necessary. + * + * Input parameters: + * the_thread - pointer to thread control block + * state - state to be set + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * ready chain + * select map + */ + +void _Thread_Set_state( + Thread_Control *the_thread, + States_Control state +) +{ + ISR_Level level; + Chain_Control *ready; + + ready = the_thread->ready; + _ISR_Disable( level ); + if ( !_States_Is_ready( the_thread->current_state ) ) { + the_thread->current_state = + _States_Set( state, the_thread->current_state ); + _ISR_Enable( level ); + return; + } + + the_thread->current_state = state; + + if ( _Chain_Has_only_one_node( ready ) ) { + + _Chain_Initialize_empty( ready ); + _Priority_Remove_from_bit_map( &the_thread->Priority_map ); + + } else + _Chain_Extract_unprotected( &the_thread->Object.Node ); + + _ISR_Flash( level ); + + if ( _Thread_Is_heir( the_thread ) ) + _Thread_Calculate_heir(); + + if ( _Thread_Is_executing( the_thread ) ) + _Context_Switch_necessary = TRUE; + + _ISR_Enable( level ); +} + +/*PAGE + * + * _Thread_Set_transient + * + * This kernel routine places the requested thread in the transient state + * which will remove it from the ready queue, if necessary. No + * rescheduling is necessary because it is assumed that the transient + * state will be cleared before dispatching is enabled. + * + * Input parameters: + * the_thread - pointer to thread control block + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * only case + */ + +void _Thread_Set_transient( + Thread_Control *the_thread +) +{ + ISR_Level level; + unsigned32 old_state; + Chain_Control *ready; + + ready = the_thread->ready; + _ISR_Disable( level ); + + old_state = the_thread->current_state; + the_thread->current_state = _States_Set( STATES_TRANSIENT, old_state ); + + if ( _States_Is_ready( old_state ) ) { + if ( _Chain_Has_only_one_node( ready ) ) { + + _Chain_Initialize_empty( ready ); + _Priority_Remove_from_bit_map( &the_thread->Priority_map ); + + } else + _Chain_Extract_unprotected( &the_thread->Object.Node ); + } + + _ISR_Enable( level ); + +} + +/*PAGE + * + * _Thread_Reset_timeslice + * + * This routine will remove the running thread from the ready chain + * and place it immediately at the rear of this chain and then the + * timeslice counter is reset. The heir THREAD will be updated if + * the running is also the currently the heir. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * ready chain + * select heir + */ + +void _Thread_Reset_timeslice( void ) +{ + ISR_Level level; + Thread_Control *executing; + Chain_Control *ready; + + executing = _Thread_Executing; + ready = executing->ready; + _ISR_Disable( level ); + if ( _Chain_Has_only_one_node( ready ) ) { + _Thread_Ticks_remaining_in_timeslice = _Thread_Ticks_per_timeslice; + _ISR_Enable( level ); + return; + } + _Chain_Extract_unprotected( &executing->Object.Node ); + _Chain_Append_unprotected( ready, &executing->Object.Node ); + + _ISR_Flash( level ); + + if ( _Thread_Is_heir( executing ) ) + _Thread_Heir = (Thread_Control *) ready->first; + + _Context_Switch_necessary = TRUE; + + _ISR_Enable( level ); +} + +/*PAGE + * + * _Thread_Tickle_timeslice + * + * This scheduler routine determines if timeslicing is enabled + * for the currently executing thread and, if so, updates the + * timeslice count and checks for timeslice expiration. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _Thread_Tickle_timeslice( void ) +{ + if ( ( _Modes_Is_timeslice(_Thread_Executing->current_modes) ) && + ( _States_Is_ready( _Thread_Executing->current_state ) ) && + ( --_Thread_Ticks_remaining_in_timeslice == 0 ) ) { + _Thread_Reset_timeslice(); + } +} + +/*PAGE + * + * _Thread_Yield_processor + * + * This kernel routine will remove the running THREAD from the ready chain + * and place it immediatly at the rear of this chain. Reset timeslice + * and yield the processor functions both use this routine, therefore if + * reset is TRUE and this is the only thread on the chain then the + * timeslice counter is reset. The heir THREAD will be updated if the + * running is also the currently the heir. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * ready chain + * select heir + */ + +void _Thread_Yield_processor( void ) +{ + ISR_Level level; + Thread_Control *executing; + Chain_Control *ready; + + executing = _Thread_Executing; + ready = executing->ready; + _ISR_Disable( level ); + if ( !_Chain_Has_only_one_node( ready ) ) { + _Chain_Extract_unprotected( &executing->Object.Node ); + _Chain_Append_unprotected( ready, &executing->Object.Node ); + + _ISR_Flash( level ); + + if ( _Thread_Is_heir( executing ) ) + _Thread_Heir = (Thread_Control *) ready->first; + _Context_Switch_necessary = TRUE; + } + else if ( !_Thread_Is_heir( executing ) ) + _Context_Switch_necessary = TRUE; + + _ISR_Enable( level ); +} + +/*PAGE + * + * _Thread_Load_environment + * + * Load starting environment for another thread from its start area in the + * thread. Only called from t_restart and t_start. + * + * Input parameters: + * the_thread - thread control block pointer + * + * Output parameters: NONE + */ + +void _Thread_Load_environment( + Thread_Control *the_thread +) +{ + if ( the_thread->Start.fp_context ) { + the_thread->fp_context = the_thread->Start.fp_context; + _Context_Initialize_fp( &the_thread->fp_context ); + } + + _Context_Initialize( + &the_thread->Registers, + the_thread->Start.Initial_stack.area, + the_thread->Start.Initial_stack.size, + _Modes_Get_interrupt_level( the_thread->Start.initial_modes ), + _Thread_Handler + ); + +} + +/*PAGE + * + * _Thread_Handler + * + * This routine is the default thread exitted error handler. It is + * returned to when a thread exits. The configured fatal error handler + * is invoked to process the exit. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _Thread_Handler( void ) +{ + Thread_Control *executing; + + executing = _Thread_Executing; + + _Thread_Dispatch_disable_level = 0; + + /* + * Do the 'begin' here instead of after the context switch. + * This ensures 'switch' extensions can not be called before + * 'begin' extensions. + */ + + _User_extensions_Task_begin( executing ); + + if ( _Thread_Is_context_switch_necessary() ) + _Thread_Dispatch(); + + (*executing->Start.entry_point)( executing->Start.initial_argument ); + + _User_extensions_Task_exitted( executing ); + + rtems_fatal_error_occurred( RTEMS_TASK_EXITTED ); +} + +/*PAGE + * + * _Thread_Delay_ended + * + * This routine processes a thread whose delay period has ended. + * It is called by the watchdog handler. + * + * Input parameters: + * id - thread id + * + * Output parameters: NONE + */ + +void _Thread_Delay_ended( + Objects_Id id, + void *ignored +) +{ + Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + case OBJECTS_REMOTE: /* impossible */ + break; + case OBJECTS_LOCAL: + _Thread_Unblock( the_thread ); + _Thread_Unnest_dispatch(); + break; + } +} + +/*PAGE + * + * _Thread_Change_priority + * + * This kernel routine changes the priority of the thread. The + * thread chain is adjusted if necessary. + * + * Input parameters: + * the_thread - pointer to thread control block + * new_priority - ultimate priority + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * ready chain + * select heir + */ + +void _Thread_Change_priority( + Thread_Control *the_thread, + rtems_task_priority new_priority +) +{ + ISR_Level level; + + _Thread_Set_transient( the_thread ); + + if ( the_thread->current_priority != new_priority ) + _Thread_Set_priority( the_thread, new_priority ); + + _ISR_Disable( level ); + + the_thread->current_state = + _States_Clear( STATES_TRANSIENT, the_thread->current_state ); + + if ( ! _States_Is_ready( the_thread->current_state ) ) { + _ISR_Enable( level ); + return; + } + + _Priority_Add_to_bit_map( &the_thread->Priority_map ); + _Chain_Append_unprotected( the_thread->ready, &the_thread->Object.Node ); + + _ISR_Flash( level ); + + _Thread_Calculate_heir(); + + if ( !_Thread_Is_executing_also_the_heir() && + _Modes_Is_preempt(_Thread_Executing->current_modes) ) + _Context_Switch_necessary = TRUE; + + _ISR_Enable( level ); +} + +/*PAGE + * + * _Thread_Set_priority + * + * This directive enables and disables several modes of + * execution for the requesting thread. + * + * Input parameters: + * the_thread - pointer to thread priority + * new_priority - new priority + * + * Output: NONE + */ + +void _Thread_Set_priority( + Thread_Control *the_thread, + rtems_task_priority new_priority +) +{ + the_thread->current_priority = new_priority; + the_thread->ready = &_Thread_Ready_chain[ new_priority ]; + + _Priority_Initialize_information( &the_thread->Priority_map, new_priority ); +} + +/*PAGE + * + * _Thread_Change_mode + * + * This routine enables and disables several modes of + * execution for the requesting thread. + * + * Input parameters: + * mode - new mode + * mask - mask + * old_mode_set - address of previous mode + * + * Output: + * *old_mode_set - previous mode + * returns TRUE if scheduling necessary + * + * INTERRUPT LATENCY: + * only one case + */ + +boolean _Thread_Change_mode( + unsigned32 new_mode_set, + unsigned32 mask, + unsigned32 *old_mode_set +) +{ + rtems_mode changed; + rtems_mode threads_new_mode_set; + Thread_Control *executing; + boolean need_dispatch; + + executing = _Thread_Executing; + *old_mode_set = executing->current_modes; + + _Modes_Change( executing->current_modes, + new_mode_set, mask, &threads_new_mode_set, &changed ); + + _Modes_Set_interrupt_level( threads_new_mode_set ); + + if ( _Modes_Mask_changed( changed, RTEMS_ASR_MASK ) ) + _ASR_Swap_signals( &executing->Signal ); + + executing->current_modes = threads_new_mode_set; + need_dispatch = TRUE; + + if ( !_States_Is_ready( executing->current_state ) || + ( !_Thread_Is_heir( executing ) && + _Modes_Is_preempt(threads_new_mode_set) ) ) + + _Context_Switch_necessary = TRUE; + + else if ( !_ASR_Are_signals_pending( &executing->Signal ) ) + + need_dispatch = FALSE; + + return need_dispatch; +} + +/*PAGE + * + * _Thread_Get + * + * NOTE: If we are not using static inlines, this must be a real + * subroutine call. + */ + +#ifndef USE_INLINES + +STATIC INLINE Thread_Control *_Thread_Get ( + Objects_Id id, + unsigned32 *location +) +{ + if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ) { + _Thread_Disable_dispatch(); + *location = OBJECTS_LOCAL; + return( _Thread_Executing ); + } + + return (Thread_Control *) _Objects_Get( &_Thread_Information, id, location ); +} +#endif + diff --git a/cpukit/score/src/threadmp.c b/cpukit/score/src/threadmp.c new file mode 100644 index 0000000000..5d352e2d25 --- /dev/null +++ b/cpukit/score/src/threadmp.c @@ -0,0 +1,229 @@ +/* + * Multiprocessing Support for the Thread Handler + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include + +/*PAGE + * + * _Thread_MP_Handler_initialization + * + */ + +void _Thread_MP_Handler_initialization ( + unsigned32 maximum_proxies +) +{ + + _Chain_Initialize_empty( &_Thread_MP_Active_proxies ); + + if ( maximum_proxies == 0 ) { + _Chain_Initialize_empty( &_Thread_MP_Inactive_proxies ); + return; + } + + + _Chain_Initialize( + &_Thread_MP_Inactive_proxies, + _Workspace_Allocate_or_fatal_error( + maximum_proxies * sizeof( Thread_Proxy_control ) + ), + maximum_proxies, + sizeof( Thread_Proxy_control ) + ); + +} + +/*PAGE + * + * _Thread_MP_Allocate_proxy + * + */ + +Thread_Control *_Thread_MP_Allocate_proxy ( + States_Control the_state +) +{ + Thread_Control *the_thread; + Thread_Proxy_control *the_proxy; + + the_thread = (Thread_Control *)_Chain_Get( &_Thread_MP_Inactive_proxies ); + + if ( !_Thread_Is_null( the_thread ) ) { + + the_proxy = (Thread_Proxy_control *) the_thread; + + _Thread_Executing->Wait.return_code = RTEMS_PROXY_BLOCKING; + + the_proxy->receive_packet = _Thread_MP_Receive->receive_packet; + + the_proxy->Object.id = _Thread_MP_Receive->receive_packet->source_tid; + + the_proxy->current_priority = + _Thread_MP_Receive->receive_packet->source_priority; + + the_proxy->current_state = _States_Set( STATES_DORMANT, the_state ); + + the_proxy->Wait = _Thread_Executing->Wait; + + _Chain_Append( &_Thread_MP_Active_proxies, &the_proxy->Active ); + + return the_thread; + } + + rtems_fatal_error_occurred( RTEMS_TOO_MANY ); + + /* + * NOTE: The following return insures that the compiler will + * think that all paths return a value. + */ + + return NULL; +} + +/*PAGE + * + * _Thread_MP_Find_proxy + * + */ + +/* + * The following macro provides the offset of the Active element + * in the Thread_Proxy_control structure. This is the logical + * equivalent of the POSITION attribute in Ada. + */ + +#define _Thread_MP_Proxy_Active_offset \ + ((unsigned32)&(((Thread_Proxy_control *)0))->Active) + +Thread_Control *_Thread_MP_Find_proxy ( + Objects_Id the_id +) +{ + + Chain_Node *proxy_node; + Thread_Control *the_thread; + ISR_Level level; + +restart: + + _ISR_Disable( level ); + + for ( proxy_node = _Thread_MP_Active_proxies.first; + !_Chain_Is_tail( &_Thread_MP_Active_proxies, proxy_node ) ; + ) { + + the_thread = _Addresses_Subtract_offset( + proxy_node, + _Thread_MP_Proxy_Active_offset + ); + + if ( _Objects_Are_ids_equal( the_thread->Object.id, the_id ) ) { + _ISR_Enable( level ); + return the_thread; + } + + _ISR_Flash( level ); + + proxy_node = proxy_node->next; + + /* + * A proxy which is only dormant is not in a blocking state. + * Therefore, we are looking at proxy which has been moved from + * active to inactive chain (by an ISR) and need to restart + * the search. + */ + + if ( _States_Is_only_dormant( the_thread->current_state ) ) { + _ISR_Enable( level ); + goto restart; + } + } + + _ISR_Enable( level ); + return NULL; +} + +/*PAGE + * + * _Thread_MP_Block + * + */ + +void _Thread_MP_Block( void ) +{ + ISR_Level level; + + _ISR_Disable( level ); + + if ( _Thread_MP_Receive->Notepads[ 0 ] != 0 ) { + _Priority_Remove_from_bit_map( &_Thread_MP_Receive->Priority_map ); + + _Thread_MP_Receive->current_state = STATES_SUSPENDED; + + _ISR_Flash( level ); + + _Thread_Calculate_heir(); + + _Context_Switch_necessary = TRUE; + + _ISR_Enable( level ); + + _Thread_Dispatch_disable_level = 0; + + _Thread_Dispatch(); + + return; + + } + _ISR_Enable( level ); + +} + +/*PAGE + * + * _Thread_MP_Ready + * + */ + +void _Thread_MP_Ready( void ) +{ + ISR_Level level; + + _ISR_Disable( level ); + + if ( _States_Is_suspended( _Thread_MP_Receive->current_state ) ) { + _Priority_Add_to_bit_map( &_Thread_MP_Receive->Priority_map ); + + _Thread_MP_Receive->current_state = STATES_READY; + + _Thread_Heir = _Thread_MP_Receive; + + _Context_Switch_necessary = TRUE; + + _ISR_Enable( level ); + + if ( _Thread_Is_dispatching_enabled() ) + _Thread_Dispatch(); + + } else { + + _Thread_MP_Receive->Notepads[ 0 ] = 0; + _ISR_Enable( level ); + + } +} diff --git a/cpukit/score/src/threadq.c b/cpukit/score/src/threadq.c new file mode 100644 index 0000000000..60ffb5db38 --- /dev/null +++ b/cpukit/score/src/threadq.c @@ -0,0 +1,837 @@ +/* + * Thread Queue Handler + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * _Thread_queue_Initialize + * + * This routine initializes the specified threadq. + * + * Input parameters: + * the_thread_queue - pointer to a threadq header + * attribute_set - used to determine queueing discipline + * state - state of waiting threads + * + * Output parameters: NONE + */ + +void _Thread_queue_Initialize( + Thread_queue_Control *the_thread_queue, + rtems_attribute attribute_set, + States_Control state +) +{ + unsigned32 index; + + if ( _Attributes_Is_priority( attribute_set ) ) { + the_thread_queue->discipline = THREAD_QUEUE_DATA_PRIORITY_DISCIPLINE; + for( index=0 ; + index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ; + index++) + _Chain_Initialize_empty( &the_thread_queue->Queues.Priority[index] ); + } + else { + the_thread_queue->discipline = THREAD_QUEUE_DATA_FIFO_DISCIPLINE; + _Chain_Initialize_empty( &the_thread_queue->Queues.Fifo ); + } + + the_thread_queue->state = state; + +} + +/*PAGE + * + * _Thread_queue_Enqueue + * + * This routine blocks a thread, places it on a thread, and optionally + * starts a timeout timer. + * + * Input parameters: + * the_thread_queue - pointer to threadq + * timeout - interval to wait + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * only case + */ + +void _Thread_queue_Enqueue( + Thread_queue_Control *the_thread_queue, + rtems_interval timeout +) +{ + Thread_Control *the_thread; + + the_thread = _Thread_Executing; + + if ( _Thread_MP_Is_receive( the_thread ) ) + the_thread = _Thread_MP_Allocate_proxy( the_thread_queue->state ); + else + _Thread_Set_state( the_thread, the_thread_queue->state ); + + if ( timeout ) { + _Watchdog_Initialize( + &the_thread->Timer, + _Thread_queue_Timeout, + the_thread->Object.id, + NULL + ); + + _Watchdog_Insert_ticks( + &the_thread->Timer, + timeout, + WATCHDOG_NO_ACTIVATE + ); + } + + switch( the_thread_queue->discipline ) { + case THREAD_QUEUE_DATA_FIFO_DISCIPLINE: + _Thread_queue_Enqueue_fifo( the_thread_queue, the_thread, timeout ); + break; + case THREAD_QUEUE_DATA_PRIORITY_DISCIPLINE: + _Thread_queue_Enqueue_priority( + the_thread_queue, the_thread, timeout ); + break; + } +} + +/*PAGE + * + * _Thread_queue_Dequeue + * + * This routine removes a thread from the specified threadq. If the + * threadq discipline is RTEMS_FIFO, it unblocks a thread, and cancels its + * timeout timer. Priority discipline is processed elsewhere. + * + * Input parameters: + * the_thread_queue - pointer to threadq + * + * Output parameters: + * returns - thread dequeued or NULL + * + * INTERRUPT LATENCY: + * check sync + * RTEMS_FIFO + */ + +Thread_Control *_Thread_queue_Dequeue( + Thread_queue_Control *the_thread_queue +) +{ + Thread_Control *the_thread; + ISR_Level level; + + switch ( the_thread_queue->discipline ) { + case THREAD_QUEUE_DATA_FIFO_DISCIPLINE: + the_thread = _Thread_queue_Dequeue_fifo( the_thread_queue ); + break; + case THREAD_QUEUE_DATA_PRIORITY_DISCIPLINE: + the_thread = _Thread_queue_Dequeue_priority( the_thread_queue ); + break; + default: /* this is only to prevent warnings */ + the_thread = NULL; + break; + } + + if ( !_Thread_Is_null( the_thread ) ) + return( the_thread ); + + _ISR_Disable( level ); + if ( the_thread_queue->sync == FALSE ) { + _ISR_Enable( level ); + return( NULL ); + } + + the_thread_queue->sync = FALSE; + _ISR_Enable( level ); + return( _Thread_Executing ); +} + +/*PAGE + * + * _Thread_queue_Extract + * + * This routine removes a specific thread from the specified threadq, + * deletes any timeout, and unblocks the thread. + * + * Input parameters: + * the_thread_queue - pointer to a threadq header + * the_thread - pointer to a thread control block + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: NONE + */ + +void _Thread_queue_Extract( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread +) +{ + switch ( the_thread_queue->discipline ) { + case THREAD_QUEUE_DATA_FIFO_DISCIPLINE: + _Thread_queue_Extract_fifo( the_thread_queue, the_thread ); + break; + case THREAD_QUEUE_DATA_PRIORITY_DISCIPLINE: + _Thread_queue_Extract_priority( the_thread_queue, the_thread ); + break; + } +} + +/*PAGE + * + * _Thread_queue_Flush + * + * This kernel routine flushes the given thread queue. + * + * Input parameters: + * the_thread_queue - pointer to threadq to be flushed + * + * Output parameters: NONE + */ + +void _Thread_queue_Flush( + Thread_queue_Control *the_thread_queue, + Thread_queue_Flush_callout remote_extract_callout +) +{ + Thread_Control *the_thread; + + while ( (the_thread = _Thread_queue_Dequeue( the_thread_queue )) ) { + if ( _Objects_Is_local_id( the_thread->Object.id ) ) + the_thread->Wait.return_code = RTEMS_OBJECT_WAS_DELETED; + else + ( *remote_extract_callout )( the_thread ); + } +} + +/*PAGE + * + * _Thread_queue_First + * + * This routines returns a pointer to the first thread on the + * specified threadq. + * + * Input parameters: + * the_thread_queue - pointer to thread queue + * + * Output parameters: + * returns - first thread or NULL + */ + +Thread_Control *_Thread_queue_First( + Thread_queue_Control *the_thread_queue +) +{ + Thread_Control *the_thread; + + switch ( the_thread_queue->discipline ) { + case THREAD_QUEUE_DATA_FIFO_DISCIPLINE: + the_thread = _Thread_queue_First_fifo( the_thread_queue ); + break; + case THREAD_QUEUE_DATA_PRIORITY_DISCIPLINE: + the_thread = _Thread_queue_First_priority( the_thread_queue ); + break; + default: /* this is only to prevent warnings */ + the_thread = NULL; + break; + } + + return the_thread; +} + +/*PAGE + * + * _Thread_queue_Timeout + * + * This routine processes a thread which timeouts while waiting on + * a thread queue. It is called by the watchdog handler. + * + * Input parameters: + * id - thread id + * + * Output parameters: NONE + */ + +void _Thread_queue_Timeout( + Objects_Id id, + void *ignored +) +{ + Thread_Control *the_thread; + Objects_Locations location; + + the_thread = _Thread_Get( id, &location ); + switch ( location ) { + case OBJECTS_ERROR: + case OBJECTS_REMOTE: /* impossible */ + break; + case OBJECTS_LOCAL: + the_thread->Wait.return_code = RTEMS_TIMEOUT; + _Thread_queue_Extract( the_thread->Wait.queue, the_thread ); + _Thread_Unnest_dispatch(); + break; + } +} + +/*PAGE + * + * _Thread_queue_Enqueue_fifo + * + * This routine blocks a thread, places it on a thread, and optionally + * starts a timeout timer. + * + * Input parameters: + * the_thread_queue - pointer to threadq + * the_thread - pointer to the thread to block + * timeout - interval to wait + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * only case + */ + +void _Thread_queue_Enqueue_fifo ( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread, + rtems_interval timeout +) +{ + ISR_Level level; + + _ISR_Disable( level ); + if ( the_thread_queue->sync == TRUE ) { + the_thread_queue->sync = FALSE; + + _Chain_Append_unprotected( + &the_thread_queue->Queues.Fifo, + &the_thread->Object.Node + ); + + if ( timeout != RTEMS_NO_TIMEOUT ) + _Watchdog_Activate( &the_thread->Timer ); + + _ISR_Enable( level ); + return; + } + + if ( !_Watchdog_Is_active( &the_thread->Timer ) ) { + _ISR_Enable( level ); + _Thread_Unblock( the_thread ); + } else { + _Watchdog_Deactivate( &the_thread->Timer ); + _ISR_Enable( level ); + (void) _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + } + + if ( !_Objects_Is_local_id( the_thread->Object.id ) ) + _Thread_MP_Free_proxy( the_thread ); + +} + +/*PAGE + * + * _Thread_queue_Dequeue_fifo + * + * This routine removes a thread from the specified threadq. + * + * Input parameters: + * the_thread_queue - pointer to threadq + * + * Output parameters: + * returns - thread dequeued or NULL + * + * INTERRUPT LATENCY: + * check sync + * RTEMS_FIFO + */ + +Thread_Control *_Thread_queue_Dequeue_fifo( + Thread_queue_Control *the_thread_queue +) +{ + ISR_Level level; + Thread_Control *the_thread; + + _ISR_Disable( level ); + if ( !_Chain_Is_empty( &the_thread_queue->Queues.Fifo ) ) { + + the_thread = (Thread_Control *) + _Chain_Get_first_unprotected( &the_thread_queue->Queues.Fifo ); + + if ( !_Watchdog_Is_active( &the_thread->Timer ) ) { + _ISR_Enable( level ); + _Thread_Unblock( the_thread ); + } else { + _Watchdog_Deactivate( &the_thread->Timer ); + _ISR_Enable( level ); + (void) _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + } + + if ( !_Objects_Is_local_id( the_thread->Object.id ) ) + _Thread_MP_Free_proxy( the_thread ); + + return( the_thread ); + } + _ISR_Enable( level ); + return( NULL ); +} + +/*PAGE + * + * _Thread_queue_Extract_fifo + * + * This routine removes a specific thread from the specified threadq, + * deletes any timeout, and unblocks the thread. + * + * Input parameters: + * the_thread_queue - pointer to a threadq header + * the_thread - pointer to the thread to block + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * EXTRACT_FIFO + */ + +void _Thread_queue_Extract_fifo( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread +) +{ + ISR_Level level; + + _ISR_Disable( level ); + + if ( !_States_Is_waiting_on_thread_queue( the_thread->current_state ) ) { + _ISR_Enable( level ); + return; + } + + _Chain_Extract_unprotected( &the_thread->Object.Node ); + + if ( !_Watchdog_Is_active( &the_thread->Timer ) ) { + _ISR_Enable( level ); + _Thread_Unblock( the_thread ); + } else { + _Watchdog_Deactivate( &the_thread->Timer ); + _ISR_Enable( level ); + (void) _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + } + + if ( !_Objects_Is_local_id( the_thread->Object.id ) ) + _Thread_MP_Free_proxy( the_thread ); +} + +/*PAGE + * + * _Thread_queue_First_fifo + * + * This routines returns a pointer to the first thread on the + * specified threadq. + * + * Input parameters: + * the_thread_queue - pointer to threadq + * + * Output parameters: + * returns - first thread or NULL + */ + +Thread_Control *_Thread_queue_First_fifo( + Thread_queue_Control *the_thread_queue +) +{ + if ( !_Chain_Is_empty( &the_thread_queue->Queues.Fifo ) ) + return (Thread_Control *) the_thread_queue->Queues.Fifo.first; + + return NULL; +} + +/*PAGE + * + * _Thread_queue_Enqueue_priority + * + * This routine blocks a thread, places it on a thread, and optionally + * starts a timeout timer. + * + * Input parameters: + * the_thread_queue - pointer to threadq + * thread - thread to insert + * timeout - timeout interval in ticks + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * forward less than + * forward equal + */ + +void _Thread_queue_Enqueue_priority( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread, + rtems_interval timeout +) +{ + rtems_task_priority search_priority; + Thread_Control *search_thread; + ISR_Level level; + Chain_Control *header; + unsigned32 header_index; + Chain_Node *the_node; + Chain_Node *next_node; + Chain_Node *previous_node; + Chain_Node *search_node; + rtems_task_priority priority; + States_Control block_state; + + _Chain_Initialize_empty( &the_thread->Wait.Block2n ); + + priority = the_thread->current_priority; + header_index = _Thread_queue_Header_number( priority ); + header = &the_thread_queue->Queues.Priority[ header_index ]; + block_state = the_thread_queue->state; + + if ( _Thread_queue_Is_reverse_search( priority ) ) + goto restart_reverse_search; + +restart_forward_search: + search_priority = RTEMS_MINIMUM_PRIORITY - 1; + _ISR_Disable( level ); + search_thread = (Thread_Control *) header->first; + while ( !_Chain_Is_tail( header, (Chain_Node *)search_thread ) ) { + search_priority = search_thread->current_priority; + if ( priority <= search_priority ) + break; + +#if ( CPU_UNROLL_ENQUEUE_PRIORITY == TRUE ) + search_thread = (Thread_Control *) search_thread->Object.Node.next; + if ( _Chain_Is_tail( header, (Chain_Node *)search_thread ) ) + break; + search_priority = search_thread->current_priority; + if ( priority <= search_priority ) + break; +#endif + _ISR_Flash( level ); + if ( !_States_Are_set( search_thread->current_state, block_state) ) { + _ISR_Enable( level ); + goto restart_forward_search; + } + search_thread = + (Thread_Control *)search_thread->Object.Node.next; + } + if ( the_thread_queue->sync == FALSE ) + goto syncronize; + + the_thread_queue->sync = FALSE; + if ( timeout != RTEMS_NO_TIMEOUT ) + _Watchdog_Activate( &the_thread->Timer ); + + if ( priority == search_priority ) + goto equal_priority; + + search_node = (Chain_Node *) search_thread; + previous_node = search_node->previous; + the_node = (Chain_Node *) the_thread; + + the_node->next = search_node; + the_node->previous = previous_node; + previous_node->next = the_node; + search_node->previous = the_node; + _ISR_Enable( level ); + return; + +restart_reverse_search: + search_priority = RTEMS_MAXIMUM_PRIORITY + 1; + + _ISR_Disable( level ); + search_thread = (Thread_Control *) header->last; + while ( !_Chain_Is_head( header, (Chain_Node *)search_thread ) ) { + search_priority = search_thread->current_priority; + if ( priority >= search_priority ) + break; +#if ( CPU_UNROLL_ENQUEUE_PRIORITY == TRUE ) + search_thread = (Thread_Control *) search_thread->Object.Node.previous; + if ( _Chain_Is_head( header, (Chain_Node *)search_thread ) ) + break; + search_priority = search_thread->current_priority; + if ( priority >= search_priority ) + break; +#endif + _ISR_Flash( level ); + if ( !_States_Are_set( search_thread->current_state, block_state) ) { + _ISR_Enable( level ); + goto restart_reverse_search; + } + search_thread = (Thread_Control *) + search_thread->Object.Node.previous; + } + if ( !the_thread_queue->sync ) + goto syncronize; + + the_thread_queue->sync = FALSE; + if ( timeout != RTEMS_NO_TIMEOUT ) + _Watchdog_Activate( &the_thread->Timer ); + + if ( priority == search_priority ) + goto equal_priority; + + search_node = (Chain_Node *) search_thread; + next_node = search_node->next; + the_node = (Chain_Node *) the_thread; + + the_node->next = next_node; + the_node->previous = search_node; + search_node->next = the_node; + next_node->previous = the_node; + _ISR_Enable( level ); + return; + +equal_priority: /* add at end of priority group */ + search_node = _Chain_Tail( &search_thread->Wait.Block2n ); + previous_node = search_node->previous; + the_node = (Chain_Node *) the_thread; + + the_node->next = search_node; + the_node->previous = previous_node; + previous_node->next = the_node; + search_node->previous = the_node; + _ISR_Enable( level ); + return; + +syncronize: + if ( !_Watchdog_Is_active( &the_thread->Timer ) ) { + _ISR_Enable( level ); + _Thread_Unblock( the_thread ); + } else { + _Watchdog_Deactivate( &the_thread->Timer ); + _ISR_Enable( level ); + (void) _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + } + if ( !_Objects_Is_local_id( the_thread->Object.id ) ) + _Thread_MP_Free_proxy( the_thread ); +} + +/*PAGE + * + * _Thread_queue_Dequeue_priority + * + * This routine removes a thread from the specified RTEMS_PRIORITY based + * threadq, unblocks it, and cancels its timeout timer. + * + * Input parameters: + * the_thread_queue - pointer to thread queue + * + * Output parameters: + * returns - thread dequeued or NULL + * + * INTERRUPT LATENCY: + * only case + */ + +Thread_Control *_Thread_queue_Dequeue_priority( + Thread_queue_Control *the_thread_queue +) +{ + unsigned32 index; + ISR_Level level; + Thread_Control *the_thread; + Thread_Control *new_first_thread; + Chain_Node *new_first_node; + Chain_Node *new_second_node; + Chain_Node *last_node; + Chain_Node *next_node; + Chain_Node *previous_node; + + for( index=0 ; + index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ; + index++ ) { + _ISR_Disable( level ); + if ( !_Chain_Is_empty( &the_thread_queue->Queues.Priority[ index ] ) ) { + the_thread = (Thread_Control *) + the_thread_queue->Queues.Priority[ index ].first; + goto dequeue; + } + _ISR_Enable( level ); + } + return NULL; + +dequeue: + new_first_node = the_thread->Wait.Block2n.first; + new_first_thread = (Thread_Control *) new_first_node; + next_node = the_thread->Object.Node.next; + previous_node = the_thread->Object.Node.previous; + + if ( !_Chain_Is_empty( &the_thread->Wait.Block2n ) ) { + last_node = the_thread->Wait.Block2n.last; + new_second_node = new_first_node->next; + + previous_node->next = new_first_node; + next_node->previous = new_first_node; + new_first_node->next = next_node; + new_first_node->previous = previous_node; + + if ( !_Chain_Has_only_one_node( &the_thread->Wait.Block2n ) ) { + /* > two threads on 2-n */ + new_second_node->previous = + _Chain_Head( &new_first_thread->Wait.Block2n ); + + new_first_thread->Wait.Block2n.first = new_second_node; + new_first_thread->Wait.Block2n.last = last_node; + + last_node->next = _Chain_Tail( &new_first_thread->Wait.Block2n ); + } + } else { + previous_node->next = next_node; + next_node->previous = previous_node; + } + + if ( !_Watchdog_Is_active( &the_thread->Timer ) ) { + _ISR_Enable( level ); + _Thread_Unblock( the_thread ); + } else { + _Watchdog_Deactivate( &the_thread->Timer ); + _ISR_Enable( level ); + (void) _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + } + + if ( !_Objects_Is_local_id( the_thread->Object.id ) ) + _Thread_MP_Free_proxy( the_thread ); + return( the_thread ); +} + +/*PAGE + * + * _Thread_queue_Extract_priority + * + * This routine removes a specific thread from the specified threadq, + * deletes any timeout, and unblocks the thread. + * + * Input parameters: + * the_thread_queue - pointer to a threadq header + * the_thread - pointer to a thread control block + * + * Output parameters: NONE + * + * INTERRUPT LATENCY: + * EXTRACT_PRIORITY + */ + +void _Thread_queue_Extract_priority( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread +) +{ + ISR_Level level; + Chain_Node *the_node; + Chain_Node *next_node; + Chain_Node *previous_node; + Thread_Control *new_first_thread; + Chain_Node *new_first_node; + Chain_Node *new_second_node; + Chain_Node *last_node; + + the_node = (Chain_Node *) the_thread; + _ISR_Disable( level ); + if ( _States_Is_waiting_on_thread_queue( the_thread->current_state ) ) { + next_node = the_node->next; + previous_node = the_node->previous; + + if ( !_Chain_Is_empty( &the_thread->Wait.Block2n ) ) { + new_first_node = the_thread->Wait.Block2n.first; + new_first_thread = (Thread_Control *) new_first_node; + last_node = the_thread->Wait.Block2n.last; + new_second_node = new_first_node->next; + + previous_node->next = new_first_node; + next_node->previous = new_first_node; + new_first_node->next = next_node; + new_first_node->previous = previous_node; + + if ( !_Chain_Has_only_one_node( &the_thread->Wait.Block2n ) ) { + /* > two threads on 2-n */ + new_second_node->previous = + _Chain_Head( &new_first_thread->Wait.Block2n ); + new_first_thread->Wait.Block2n.first = new_second_node; + + new_first_thread->Wait.Block2n.last = last_node; + last_node->next = _Chain_Tail( &new_first_thread->Wait.Block2n ); + } + } else { + previous_node->next = next_node; + next_node->previous = previous_node; + } + + if ( !_Watchdog_Is_active( &the_thread->Timer ) ) { + _ISR_Enable( level ); + _Thread_Unblock( the_thread ); + } else { + _Watchdog_Deactivate( &the_thread->Timer ); + _ISR_Enable( level ); + (void) _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + } + + if ( !_Objects_Is_local_id( the_thread->Object.id ) ) + _Thread_MP_Free_proxy( the_thread ); + } + else + _ISR_Enable( level ); +} + +/*PAGE + * + * _Thread_queue_First_priority + * + * This routines returns a pointer to the first thread on the + * specified threadq. + * + * Input parameters: + * the_thread_queue - pointer to thread queue + * + * Output parameters: + * returns - first thread or NULL + */ + +Thread_Control *_Thread_queue_First_priority ( + Thread_queue_Control *the_thread_queue +) +{ + unsigned32 index; + + for( index=0 ; + index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ; + index++ ) { + if ( !_Chain_Is_empty( &the_thread_queue->Queues.Priority[ index ] ) ) + return (Thread_Control *) + the_thread_queue->Queues.Priority[ index ].first; + } + return NULL; +} diff --git a/cpukit/score/src/watchdog.c b/cpukit/score/src/watchdog.c new file mode 100644 index 0000000000..7db26c0cd5 --- /dev/null +++ b/cpukit/score/src/watchdog.c @@ -0,0 +1,225 @@ +/* + * Watchdog Handler + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +/*PAGE + * + * _Watchdog_Handler_initialization + * + * This routine initializes the watchdog handler. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _Watchdog_Handler_initialization( void ) +{ + _Watchdog_Clear_sync(); + _Chain_Initialize_empty( &_Watchdog_Ticks_chain ); + _Chain_Initialize_empty( &_Watchdog_Seconds_chain ); +} + +/*PAGE + * + * _Watchdog_Remove + * + * The routine removes a watchdog from a delta chain and updates + * the delta counters of the remaining watchdogs. + */ + +Watchdog_States _Watchdog_Remove( + Watchdog_Control *the_watchdog +) +{ + ISR_Level level; + Watchdog_States previous_state; + Watchdog_Control *next_watchdog; + + _ISR_Disable( level ); + previous_state = the_watchdog->state; + switch ( previous_state ) { + case WATCHDOG_INACTIVE: + break; + case WATCHDOG_ACTIVE: + case WATCHDOG_REINSERT: + case WATCHDOG_REMOVE_IT: + + the_watchdog->state = WATCHDOG_INACTIVE; + next_watchdog = _Watchdog_Next( the_watchdog ); + + if ( _Watchdog_Next(next_watchdog) ) + next_watchdog->delta_interval += the_watchdog->delta_interval; + + if ( the_watchdog == _Watchdog_Sync ) + _Watchdog_Sync = _Watchdog_Previous( the_watchdog ); + + _Chain_Extract_unprotected( &the_watchdog->Node ); + break; + } + _ISR_Enable( level ); + return( previous_state ); +} + +/*PAGE + * + * _Watchdog_Adjust + * + * This routine adjusts the delta chain backward or forward in response + * to a time change. + * + * Input parameters: + * header - pointer to the delta chain to be adjusted + * direction - forward or backward adjustment to delta chain + * units - units to adjust + * + * Output parameters: + */ + +void _Watchdog_Adjust( + Chain_Control *header, + Watchdog_Adjust_directions direction, + rtems_interval units +) +{ + if ( !_Chain_Is_empty( header ) ) { + switch ( direction ) { + case WATCHDOG_BACKWARD: + _Watchdog_First( header )->delta_interval += units; + break; + case WATCHDOG_FORWARD: + while ( units ) { + if ( units < _Watchdog_First( header )->delta_interval ) { + _Watchdog_First( header )->delta_interval -= units; + break; + } else { + units -= _Watchdog_First( header )->delta_interval; + _Watchdog_First( header )->delta_interval = 1; + _Watchdog_Tickle( header ); + if ( _Chain_Is_empty( header ) ) + break; + } + } + break; + } + } +} + +/*PAGE + * + * _Watchdog_Insert + * + * This routine inserts a watchdog timer on to the appropriate delta + * chain while updating the delta interval counters. + */ + +void _Watchdog_Insert( + Chain_Control *header, + Watchdog_Control *the_watchdog, + Watchdog_Insert_modes insert_mode +) +{ + ISR_Level level; + Watchdog_Control *after; + + the_watchdog->state = WATCHDOG_REINSERT; + the_watchdog->delta_interval = the_watchdog->initial; + + _ISR_Disable( level ); + + for ( after = _Watchdog_First( header ) ; + ; + after = _Watchdog_Next( _Watchdog_Get_sync() ) ) { + + if ( the_watchdog->delta_interval == 0 || !_Watchdog_Next( after ) ) + break; + + if ( the_watchdog->delta_interval < after->delta_interval ) { + after->delta_interval -= the_watchdog->delta_interval; + break; + } + + the_watchdog->delta_interval -= after->delta_interval; + _Watchdog_Set_sync( after ); + + /* + * If you experience problems comment out the _ISR_Flash line. Under + * certain circumstances, this flash allows interrupts to execute + * which violate the design assumptions. The critical section + * mechanism used here must be redesigned to address this. + */ + + _ISR_Flash( level ); + } + + if ( insert_mode == WATCHDOG_ACTIVATE_NOW ) + _Watchdog_Activate( the_watchdog ); + + _Chain_Insert_unprotected( after->Node.previous, &the_watchdog->Node ); + + _Watchdog_Clear_sync(); + + _ISR_Enable( level ); +} + +/*PAGE + * + * _Watchdog_Tickle + * + * This routine decrements the delta counter in response to a tick. The + * delta chain is updated accordingly. + * + * Input parameters: + * header - pointer to the delta chain to be tickled + * + * Output parameters: NONE + */ + +void _Watchdog_Tickle( + Chain_Control *header +) +{ + Watchdog_Control *the_watchdog; + + if ( _Chain_Is_empty( header ) ) + return; + + the_watchdog = _Watchdog_First( header ); + the_watchdog->delta_interval--; + if ( the_watchdog->delta_interval != 0 ) + return; + + do { + switch( _Watchdog_Remove( the_watchdog ) ) { + case WATCHDOG_ACTIVE: + (*the_watchdog->routine)( + the_watchdog->id, + the_watchdog->user_data + ); + break; + case WATCHDOG_REINSERT: + _Watchdog_Insert( header, the_watchdog, WATCHDOG_ACTIVATE_NOW ); + break; + case WATCHDOG_INACTIVE: + case WATCHDOG_REMOVE_IT: + break; + } + the_watchdog = _Watchdog_First( header ); + } while ( !_Chain_Is_empty( header ) && + (the_watchdog->delta_interval == 0) ); +} diff --git a/cpukit/score/src/wkspace.c b/cpukit/score/src/wkspace.c new file mode 100644 index 0000000000..577b0f6c01 --- /dev/null +++ b/cpukit/score/src/wkspace.c @@ -0,0 +1,47 @@ +/* + * Workspace Handler + * + * NOTE: + * + * This file only exists to contain the one function which cannot + * be written as a macro when "static inlines" are not used. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +#ifndef USE_INLINES + +/*PAGE + * + * _Workspace_Allocate_or_fatal_error + * + */ + +void *_Workspace_Allocate_or_fatal_error( + unsigned32 size +) +{ + void *memory; + + memory = _Workspace_Allocate( size ); + + if ( memory == NULL ) + rtems_fatal_error_occurred( RTEMS_UNSATISFIED ); + + return memory; +} + +#endif /* USE_INLINES */ + -- cgit v1.2.3