diff options
Diffstat (limited to 'cpukit/sapi')
41 files changed, 5925 insertions, 0 deletions
diff --git a/cpukit/sapi/.cvsignore b/cpukit/sapi/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/cpukit/sapi/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/cpukit/sapi/Makefile.am b/cpukit/sapi/Makefile.am new file mode 100644 index 0000000000..fb35b914f0 --- /dev/null +++ b/cpukit/sapi/Makefile.am @@ -0,0 +1,36 @@ +## +## $Id$ +## + +include $(top_srcdir)/automake/multilib.am +include $(top_srcdir)/automake/compile.am + +include_rtemsdir = $(includedir)/rtems + +include_rtems_HEADERS = include/confdefs.h +include_rtems_HEADERS += include/rtems/chain.h include/rtems/config.h \ + include/rtems/extension.h include/rtems/fatal.h include/rtems/init.h \ + include/rtems/io.h include/rtems/mptables.h include/rtems/sptables.h + +EXTRA_DIST = include/rtems/README + +include_rtems_HEADERS += inline/rtems/chain.inl \ + inline/rtems/extension.inl + +## src +AM_CPPFLAGS += -D__RTEMS_INSIDE__ + +noinst_LIBRARIES = libsapi.a +project_lib_LIBRARIES = libsapi.a +libsapi_a_SOURCES = src/debug.c src/extension.c src/extensioncreate.c \ + src/extensiondelete.c src/extensionident.c src/fatal.c src/exinit.c \ + src/exshutdown.c src/io.c src/ioclose.c src/iocontrol.c src/iodata.c \ + src/ioinitialize.c src/ioopen.c src/ioread.c src/ioregisterdriver.c \ + src/iounregisterdriver.c src/iowrite.c src/posixapi.c \ + src/rtemsapi.c src/extensiondata.c src/getversionstring.c \ + src/chainappendnotify.c src/chaingetnotify.c src/chaingetwait.c \ + src/chainprependnotify.c +libsapi_a_CPPFLAGS = $(AM_CPPFLAGS) + +include $(srcdir)/preinstall.am +include $(top_srcdir)/automake/local.am diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h new file mode 100644 index 0000000000..ad81403430 --- /dev/null +++ b/cpukit/sapi/include/confdefs.h @@ -0,0 +1,2342 @@ +/** + * @file rtems/confdefs.h + * + * This include file contains the configuration table template that will + * be instantiated by an application based on the setting of a number + * of macros. The macros are documented in the Configuring a System + * chapter of the Classic API User's Guide + * + * The model is to estimate the memory required for each configured item + * and sum those estimates. The estimate can be too high or too low for + * a variety of reasons: + * + * Reasons estimate is too high: + * + FP contexts (not all tasks are FP) + * + * Reasons estimate is too low: + * + stacks greater than minimum size + * + messages + * + application must account for device driver resources + * + application must account for add-on library resource requirements + * + * NOTE: Eventually this may be able to take into account some of + * the above. This procedure has evolved from just enough to + * support the RTEMS Test Suites into something that can be + * used remarkably reliably by most applications. + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef __CONFIGURATION_TEMPLATE_h +#define __CONFIGURATION_TEMPLATE_h + +/* + * Include the executive's configuration + */ +#include <rtems.h> +#include <rtems/score/apimutex.h> + +#ifdef __cplusplus +extern "C" { +#endif + +extern rtems_initialization_tasks_table Initialization_tasks[]; +extern rtems_driver_address_table Device_drivers[]; +extern rtems_configuration_table Configuration; +#if defined(RTEMS_MULTIPROCESSING) + extern rtems_multiprocessing_table Multiprocessing_configuration; +#endif +#ifdef RTEMS_POSIX_API + extern posix_api_configuration_table Configuration_POSIX_API; +#endif + +/** + * This macro determines whether the RTEMS reentrancy support for + * the Newlib C Library is enabled. + */ +#ifdef RTEMS_SCHEDSIM + #undef RTEMS_NEWLIB +#endif + +#if (defined(RTEMS_NEWLIB) && !defined(CONFIGURE_DISABLE_NEWLIB_REENTRANCY)) + #define CONFIGURE_NEWLIB_EXTENSION 1 +#else + #define CONFIGURE_NEWLIB_EXTENSION 0 +#endif + +#ifndef RTEMS_SCHEDSIM +#include <rtems/libio.h> + +#ifdef CONFIGURE_INIT +rtems_libio_init_functions_t rtems_libio_init_helper = + #ifdef CONFIGURE_APPLICATION_DISABLE_FILESYSTEM + NULL; + #else + rtems_libio_init; + #endif + +rtems_libio_supp_functions_t rtems_libio_supp_helper = + #ifdef CONFIGURE_APPLICATION_DISABLE_FILESYSTEM + NULL; + #else + open_dev_console; + #endif + +rtems_fs_init_functions_t rtems_fs_init_helper = + #ifdef CONFIGURE_APPLICATION_DISABLE_FILESYSTEM + NULL; + #else + rtems_filesystem_initialize; + #endif +#endif +#endif + +/* + * If the application disables the filesystem, they will not need + * a mount table, so do not produce one. + */ +#ifdef CONFIGURE_APPLICATION_DISABLE_FILESYSTEM + #define CONFIGURE_HAS_OWN_MOUNT_TABLE +#endif + +/** + * This macro defines the number of POSIX file descriptors allocated + * and managed by libio. These are the "integer" file descriptors that + * are used by calls like open(2) and read(2). + */ +#ifndef CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS + #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 3 +#endif + +/** + * From the number of file descriptors, we can determine how many + * semaphores the implementation will require. + */ +#define CONFIGURE_LIBIO_SEMAPHORES \ + (CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS + 1) + +#ifdef CONFIGURE_INIT + /** + * When instantiating the configuration tables, this variable is + * initialized to specify the maximum number of file descriptors. + */ + uint32_t rtems_libio_number_iops = CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS; +#endif + +/** + * This macro determines if termios is disabled by this application. + * This only means that resources will not be reserved. If you end + * up using termios, it will fail. + */ +#ifdef CONFIGURE_TERMIOS_DISABLED + #define CONFIGURE_TERMIOS_SEMAPHORES 0 +#else + /** + * This macro specifies the number of serial or PTY ports that will + * use termios. + */ + #ifndef CONFIGURE_NUMBER_OF_TERMIOS_PORTS + #define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 1 + #endif + + /** + * This macro reserves the number of semaphores required by termios + * based upon the number of communication ports that will use it. + */ + #define CONFIGURE_TERMIOS_SEMAPHORES \ + ((CONFIGURE_NUMBER_OF_TERMIOS_PORTS * 4) + 1) +#endif + +/** + * This macro specifies the number of PTYs that can be concurrently + * active. + */ +#ifndef CONFIGURE_MAXIMUM_PTYS + #define CONFIGURE_MAXIMUM_PTYS 0 +#endif + +/** + * This variable contains the maximum number of PTYs that can be + * concurrently active. + */ +#ifdef CONFIGURE_INIT + int rtems_telnetd_maximum_ptys = CONFIGURE_MAXIMUM_PTYS; +#else + extern int rtems_telnetd_maximum_ptys; +#endif + +#if defined(RTEMS_SMP) + /* + * If configured for SMP, then we need to know the maximum CPU cores. + */ + #if !defined(CONFIGURE_SMP_APPLICATION) + #if !defined(CONFIGURE_SMP_MAXIMUM_PROCESSORS) + #define CONFIGURE_SMP_MAXIMUM_PROCESSORS 1 + #endif + #else + #if !defined(CONFIGURE_SMP_MAXIMUM_PROCESSORS) + #error "CONFIGURE_SMP_MAXIMUM_PROCESSORS not specified for SMP Application" + #endif + #endif +#endif + +/* + * Filesystems and Mount Table Configuration. + * + * Defines to control the file system: + * + * CONFIGURE_APPLICATION_DISABLE_FILESYSTEM: + * Disable the RTEMS filesystems. You get an empty DEVFS. + * + * CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM: + * Use the DEVFS as the root file system. Limited functions are + * provided when this is used. + * + * CONFIGURE_FILESYSTEM_ALL: + * Add file filesystems to the default filesystem table. + * + * List of available file systems. You can define as many as you like: + * CONFIGURE_FILESYSTEM_MINIIMFS - MiniIMFS, use DEVFS now + * CONFIGURE_FILESYSTEM_IMFS - In Memory File System (IMFS) + * CONFIGURE_FILESYSTEM_DEVFS - Device File System (DSVFS) + * CONFIGURE_FILESYSTEM_TFTPFS - TFTP File System, networking enabled + * CONFIGURE_FILESYSTEM_FTPFS - FTP File System, networking enabled + * CONFIGURE_FILESYSTEM_NFS - Network File System, networking enabled + * CONFIGURE_FILESYSTEM_DOSFS - DOS File System, uses libblock + * CONFIGURE_FILESYSTEM_RFS - RTEMS File System (RFS), uses libblock + * + * Combinations: + * + * - If nothing is defined the base file system is the IMFS. + * + * - If CONFIGURE_APPLICATION_DISABLE_FILESYSTEM is defined all filesystem + * are disabled by force and an empty DEVFS is created. + * + * - If CONFIGURE_USE_DEV_AS_BASE_FILESYSTEM is defined all filesystem + * are disabled by force and DEVFS is defined. + */ + +#ifdef CONFIGURE_INIT + + /* + * Include all file systems. Do this before checking if the filesystem has + * been disabled. + */ + #ifdef CONFIGURE_FILESYSTEM_ALL + #define CONFIGURE_FILESYSTEM_MINIIMFS + #define CONFIGURE_FILESYSTEM_IMFS + #define CONFIGURE_FILESYSTEM_DEVFS + #define CONFIGURE_FILESYSTEM_TFTPFS + #define CONFIGURE_FILESYSTEM_FTPFS + #define CONFIGURE_FILESYSTEM_NFS + #define CONFIGURE_FILESYSTEM_DOSFS + #define CONFIGURE_FILESYSTEM_RFS + #endif + + /* + * If disabling the file system, give a compile error if the user has + * configured other filesystem parameters. + */ + #if defined(CONFIGURE_APPLICATION_DISABLE_FILESYSTEM) + #if defined(CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM) || \ + defined(CONFIGURE_USE_MINIIMFS_AS_BASE_FILESYSTEM) + #error "Filesystem disabled but a base filesystem configured." + #endif + + #if defined(CONFIGURE_FILESYSTEM_MINIIMFS) || \ + defined(CONFIGURE_FILESYSTEM_IMFS) || \ + defined(CONFIGURE_FILESYSTEM_DEVFS) || \ + defined(CONFIGURE_FILESYSTEM_TFTPFS) || \ + defined(CONFIGURE_FILESYSTEM_FTPFS) || \ + defined(CONFIGURE_FILESYSTEM_NFS) || \ + defined(CONFIGURE_FILESYSTEM_DOSFS) || \ + defined(CONFIGURE_FILESYSTEM_RFS) + #error "Configured filesystems but root filesystem was not IMFS!" + #error "Filesystems could be disabled, DEVFS is root, or" + #error " miniIMFS is root!" + #endif + #endif + + /* + * If the base filesystem is DEVFS define it else define IMFS. + * We will have either DEVFS or IMFS defined after this. + */ + #if !defined(CONFIGURE_APPLICATION_DISABLE_FILESYSTEM) + #if defined(CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM) + #define CONFIGURE_FILESYSTEM_DEVFS + #elif defined(CONFIGURE_USE_MINIIMFS_AS_BASE_FILESYSTEM) + #define CONFIGURE_FILESYSTEM_MINIIMFS + #elif !defined(CONFIGURE_FILESYSTEM_IMFS) + #define CONFIGURE_FILESYSTEM_IMFS + #endif + #endif + +#endif + +#ifndef RTEMS_SCHEDSIM +/** + * IMFS + */ +#include <rtems/imfs.h> + +/** + * This specifies the number of bytes per block for files within the IMFS. + * There are a maximum number of blocks per file so this dictates the maximum + * size of a file. This has to be balanced with the unused portion of each + * block that might be wasted. + */ +#ifndef CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK + #define CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK \ + IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK +#endif + +/** + * This defines the miniIMFS file system table entry. + */ +#if !defined(CONFIGURE_FILESYSTEM_ENTRY_miniIMFS) && \ + defined(CONFIGURE_FILESYSTEM_MINIIMFS) + #define CONFIGURE_FILESYSTEM_ENTRY_miniIMFS \ + { RTEMS_FILESYSTEM_TYPE_MINIIMFS, miniIMFS_initialize } +#endif +#endif + +/** + * Internall it is called FIFOs not pipes + */ +#if defined(CONFIGURE_PIPES_ENABLED) + #define CONFIGURE_FIFOS_ENABLED +#endif + +#ifndef RTEMS_SCHEDSIM +/** + * This defines the IMFS file system table entry. + */ +#if !defined(CONFIGURE_FILESYSTEM_ENTRY_IMFS) && \ + defined(CONFIGURE_FILESYSTEM_IMFS) + #if defined(CONFIGURE_FIFOS_ENABLED) + #define CONFIGURE_FILESYSTEM_ENTRY_IMFS \ + { RTEMS_FILESYSTEM_TYPE_IMFS, fifoIMFS_initialize } + #else + #define CONFIGURE_FILESYSTEM_ENTRY_IMFS \ + { RTEMS_FILESYSTEM_TYPE_IMFS, IMFS_initialize } + #endif +#endif +#endif + +/** + * This sets up the resources for the PIPES/FIFOs + */ +#if defined(CONFIGURE_FIFOS_ENABLED) + #if !defined(CONFIGURE_MAXIMUM_FIFOS) && !defined(CONFIGURE_MAXIMUM_PIPES) + #error "No FIFOs or PIPES configured" + #endif + #if !defined(CONFIGURE_MAXIMUM_FIFOS) + #define CONFIGURE_MAXIMUM_FIFOS 0 + #endif + #if !defined(CONFIGURE_MAXIMUM_PIPES) + #define CONFIGURE_MAXIMUM_PIPES 0 + #endif + #define CONFIGURE_BARRIERS_FOR_FIFOS \ + (2 * (CONFIGURE_MAXIMUM_FIFOS + CONFIGURE_MAXIMUM_PIPES)) + #define CONFIGURE_SEMAPHORES_FOR_FIFOS \ + (1 + (CONFIGURE_MAXIMUM_FIFOS + CONFIGURE_MAXIMUM_PIPES)) +#else + #define CONFIGURE_BARRIERS_FOR_FIFOS 0 + #define CONFIGURE_SEMAPHORES_FOR_FIFOS 0 +#endif + +/** + * DEVFS + */ +#if !defined(CONFIGURE_FILESYSTEM_ENTRY_DEVFS) && \ + defined(CONFIGURE_FILESYSTEM_DEVFS) +#include <rtems/devfs.h> + #define CONFIGURE_FILESYSTEM_ENTRY_DEVFS \ + { RTEMS_FILESYSTEM_TYPE_DEVFS, devFS_initialize } +#endif + +#ifdef RTEMS_NETWORKING + /** + * FTPFS + */ + #if !defined(CONFIGURE_FILESYSTEM_ENTRY_FTPFS) && \ + defined(CONFIGURE_FILESYSTEM_FTPFS) + #include <rtems/ftpfs.h> + #define CONFIGURE_FILESYSTEM_ENTRY_FTPFS \ + { RTEMS_FILESYSTEM_TYPE_FTPFS, rtems_ftpfs_initialize } + #endif + + /** + * TFTPFS + */ + #if !defined(CONFIGURE_FILESYSTEM_ENTRY_TFTPFS) && \ + defined(CONFIGURE_FILESYSTEM_TFTPFS) + #include <rtems/tftp.h> + #define CONFIGURE_FILESYSTEM_ENTRY_TFTPFS \ + { RTEMS_FILESYSTEM_TYPE_TFTPFS, rtems_tftpfs_initialize } + #endif + + /** + * NFS + */ + #if !defined(CONFIGURE_FILESYSTEM_ENTRY_NFS) && \ + defined(CONFIGURE_FILESYSTEM_NFS) + #include <librtemsNfs.h> + #define CONFIGURE_FILESYSTEM_ENTRY_NFS \ + { RTEMS_FILESYSTEM_TYPE_NFS, rtems_nfs_initialize } + #endif +#endif + +/** + * DOSFS + */ +#if !defined(CONFIGURE_FILESYSTEM_ENTRY_DOSFS) && \ + defined(CONFIGURE_FILESYSTEM_DOSFS) + #include <rtems/dosfs.h> + #define CONFIGURE_FILESYSTEM_ENTRY_DOSFS \ + { RTEMS_FILESYSTEM_TYPE_DOSFS, rtems_dosfs_initialize } +#endif + +/** + * RFS + */ +#if !defined(CONFIGURE_FILESYSTEM_ENTRY_RFS) && \ + defined(CONFIGURE_FILESYSTEM_RFS) + #include <rtems/rtems-rfs.h> + #define CONFIGURE_FILESYSTEM_ENTRY_RFS \ + { RTEMS_FILESYSTEM_TYPE_RFS, rtems_rfs_rtems_initialise } +#endif + +#ifdef CONFIGURE_INIT + + /* + * DEVFS variables. + */ + #if defined(CONFIGURE_APPLICATION_DISABLE_FILESYSTEM) + #define CONFIGURE_MEMORY_FOR_DEVFS 0 + #elif defined(CONFIGURE_FILESYSTEM_DEVFS) + #ifndef CONFIGURE_MAXIMUM_DEVICES + #define CONFIGURE_MAXIMUM_DEVICES 4 + #endif + #include <rtems/devfs.h> + uint32_t rtems_device_table_size = CONFIGURE_MAXIMUM_DEVICES; + #define CONFIGURE_MEMORY_FOR_DEVFS \ + _Configure_Object_RAM(CONFIGURE_MAXIMUM_DEVICES, \ + sizeof (rtems_device_name_t)) + #else + #define CONFIGURE_MEMORY_FOR_DEVFS 0 + #endif + +#ifndef RTEMS_SCHEDSIM + #if defined(CONFIGURE_FILESYSTEM_IMFS) || \ + defined(CONFIGURE_FILESYSTEM_MINIIMFS) + int imfs_rq_memfile_bytes_per_block = CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK; + #endif +#endif + + /** + * Table termination record. + */ + #define CONFIGURE_FILESYSTEM_NULL { NULL, NULL } + +#ifndef RTEMS_SCHEDSIM + /** + * The default file system table. Must be terminated with the NULL entry if + * you provide your own. + */ + #ifndef CONFIGURE_HAS_OWN_FILESYSTEM_TABLE + const rtems_filesystem_table_t rtems_filesystem_table[] = { + #if defined(CONFIGURE_FILESYSTEM_MINIIMFS) && \ + defined(CONFIGURE_FILESYSTEM_ENTRY_miniIMFS) + CONFIGURE_FILESYSTEM_ENTRY_miniIMFS, + #endif + #if defined(CONFIGURE_FILESYSTEM_IMFS) && \ + defined(CONFIGURE_FILESYSTEM_ENTRY_IMFS) + CONFIGURE_FILESYSTEM_ENTRY_IMFS, + #endif + #if defined(CONFIGURE_FILESYSTEM_DEVFS) && \ + defined(CONFIGURE_FILESYSTEM_ENTRY_DEVFS) + CONFIGURE_FILESYSTEM_ENTRY_DEVFS, + #endif + #if defined(CONFIGURE_FILESYSTEM_TFTPFS) && \ + defined(CONFIGURE_FILESYSTEM_ENTRY_TFTPFS) + CONFIGURE_FILESYSTEM_ENTRY_TFTPFS, + #endif + #if defined(CONFIGURE_FILESYSTEM_FTPFS) && \ + defined(CONFIGURE_FILESYSTEM_ENTRY_FTPFS) + CONFIGURE_FILESYSTEM_ENTRY_FTPFS, + #endif + #if defined(CONFIGURE_FILESYSTEM_NFS) && \ + defined(CONFIGURE_FILESYSTEM_ENTRY_NFS) + CONFIGURE_FILESYSTEM_ENTRY_NFS, + #endif + #if defined(CONFIGURE_FILESYSTEM_DOSFS) && \ + defined(CONFIGURE_FILESYSTEM_ENTRY_DOSFS) + CONFIGURE_FILESYSTEM_ENTRY_DOSFS, + #endif + #if defined(CONFIGURE_FILESYSTEM_RFS) && \ + defined(CONFIGURE_FILESYSTEM_ENTRY_RFS) + CONFIGURE_FILESYSTEM_ENTRY_RFS, + #endif + CONFIGURE_FILESYSTEM_NULL + }; + #endif + + #ifndef CONFIGURE_HAS_OWN_MOUNT_TABLE + const rtems_filesystem_mount_table_t configuration_mount_table = { + #if defined(CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM) + RTEMS_FILESYSTEM_TYPE_DEVFS, + #elif defined(CONFIGURE_USE_MINIIMFS_AS_BASE_FILESYSTEM) + RTEMS_FILESYSTEM_TYPE_MINIIMFS, + #else /* using IMFS as base filesystem */ + RTEMS_FILESYSTEM_TYPE_IMFS, + #endif + RTEMS_FILESYSTEM_READ_WRITE, + NULL, + NULL + }; + + const rtems_filesystem_mount_table_t + *rtems_filesystem_mount_table = &configuration_mount_table; + const int rtems_filesystem_mount_table_size = 1; + #endif + +#endif +#endif + +/* + * STACK_CHECKER_ON was still available in 4.9 so give a warning for now. + */ +#if defined(STACK_CHECKER_ON) + #define CONFIGURE_STACK_CHECKER_ENABLED + #warning "STACK_CHECKER_ON deprecated -- use CONFIGURE_STACK_CHECKER_ENABLED" +#endif + +/** + * This configures the stack checker user extension. + */ +#ifdef CONFIGURE_STACK_CHECKER_ENABLED + #define CONFIGURE_STACK_CHECKER_EXTENSION 1 +#else + #define CONFIGURE_STACK_CHECKER_EXTENSION 0 +#endif + +/** + * @brief Maximum Priority configuration + * + * This configures the maximum priority value that + * a task may have. + * + * The following applies to the data space requirements + * of the Priority Scheduler. + * + * By reducing the number of priorities in a system, + * the amount of RAM required by RTEMS can be significantly + * reduced. RTEMS allocates a Chain_Control structure per + * priority and this structure contains 3 pointers. So + * the default is (256 * 12) = 3K on 32-bit architectures. + * + * This must be one less than a power of 2 between + * 4 and 256. Valid values along with the application + * priority levels and memory saved when pointers are + * 32-bits in size are: + * + * + 3, 2 application priorities, 3024 bytes saved + * + 7, 5 application priorities, 2976 bytes saved + * + 15, 13 application priorities, 2880 bytes saved + * + 31, 29 application priorities, 2688 bytes saved + * + 63, 61 application priorities, 2304 bytes saved + * + 127, 125 application priorities, 1536 bytes saved + * + 255, 253 application priorities, 0 bytes saved + * + * It is specified in terms of Classic API priority values. + */ +#ifndef CONFIGURE_MAXIMUM_PRIORITY + #define CONFIGURE_MAXIMUM_PRIORITY PRIORITY_DEFAULT_MAXIMUM +#endif + +/* + * Scheduler configuration. + * + * The scheduler configuration allows an application to select the + * scheduling policy to use. The supported configurations are: + * CONFIGURE_SCHEDULER_USER - user provided scheduler + * CONFIGURE_SCHEDULER_PRIORITY - Deterministic Priority Scheduler + * CONFIGURE_SCHEDULER_SIMPLE - Light-weight Priority Scheduler + * + * If no configuration is specified by the application, then + * CONFIGURE_SCHEDULER_PRIORITY is assumed to be the default. + * + * An application can define its own scheduling policy by defining + * CONFIGURE_SCHEDULER_USER and the following: + * - CONFIGURE_SCHEDULER_ENTRY_POINTS + * - CONFIGURE_MEMORY_FOR_SCHEDULER - base memory + * - CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER - per task memory + */ +#include <rtems/score/scheduler.h> + +#if defined(CONFIGURE_SCHEDULER_USER) && \ + !defined(CONFIGURE_SCHEDULER_USER_ENTRY_POINTS) + #error "CONFIGURE_ERROR: CONFIGURE_SCHEDULER_USER requires CONFIGURE_SCHEDULER_USER_ENTRY_POINTS" +#endif + +/* If no scheduler is specified, the priority scheduler is default. */ +#if !defined(CONFIGURE_SCHEDULER_USER) && \ + !defined(CONFIGURE_SCHEDULER_PRIORITY) && \ + !defined(CONFIGURE_SCHEDULER_SIMPLE) + #define CONFIGURE_SCHEDULER_PRIORITY +#endif + +/* + * If the Priority Scheduler is selected, then configure for it. + */ +#if defined(CONFIGURE_SCHEDULER_PRIORITY) + #include <rtems/score/schedulerpriority.h> + #define SCHEDULER_ENTRY_POINTS SCHEDULER_PRIORITY_ENTRY_POINTS + + /** + * This defines the memory used by the priority scheduler. + */ + #define CONFIGURE_MEMORY_FOR_SCHEDULER ( \ + _Configure_From_workspace( \ + ((CONFIGURE_MAXIMUM_PRIORITY+1) * sizeof(Chain_Control)) ) \ + ) + #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \ + _Configure_From_workspace(sizeof(Scheduler_priority_Per_thread)) ) +#endif + +/* + * If the Simple Priority Scheduler is selected, then configure for it. + */ +#if defined(CONFIGURE_SCHEDULER_SIMPLE) + #include <rtems/score/schedulersimple.h> + #define SCHEDULER_ENTRY_POINTS SCHEDULER_SIMPLE_ENTRY_POINTS + + /** + * define the memory used by the simple scheduler + */ + #define CONFIGURE_MEMORY_FOR_SCHEDULER ( \ + _Configure_From_workspace( sizeof(Chain_Control) ) \ + ) + #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER (0) +#endif + +/* + * Set up the scheduler entry points table. The scheduling code uses + * this code to know which scheduler is configured by the user. + */ +#ifdef CONFIGURE_INIT + Scheduler_Control _Scheduler = { + NULL, /* Scheduler Specific Data Pointer */ + SCHEDULER_ENTRY_POINTS /* Scheduler Operations */ + }; +#endif + +/* + * If you said the IDLE task was going to do application initialization + * and didn't override the IDLE body, then something is amiss. + */ +#if (defined(CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION) && \ + !defined(CONFIGURE_IDLE_TASK_BODY)) + #error "CONFIGURE_ERROR: You did not override the IDLE task body." +#endif + +/** + * @brief Idle task body configuration + * + * There is a default IDLE thread body provided by RTEMS which + * has the possibility of being CPU specific. There may be a + * BSP specific override of the RTEMS default body and in turn, + * the application may override and provide its own. + */ +#ifndef CONFIGURE_IDLE_TASK_BODY + #if defined(BSP_IDLE_TASK_BODY) + #define CONFIGURE_IDLE_TASK_BODY BSP_IDLE_TASK_BODY + #elif (CPU_PROVIDES_IDLE_THREAD_BODY == TRUE) + #define CONFIGURE_IDLE_TASK_BODY _CPU_Thread_Idle_body + #else + /* only instantiate and compile if used */ + #ifdef CONFIGURE_INIT + void *_Thread_Idle_body(uintptr_t ignored) + { + for( ; ; ) ; + return 0; /* to avoid warning */ + } + #endif + #define CONFIGURE_IDLE_TASK_BODY _Thread_Idle_body + #endif +#endif + +/** + * By default, use the minimum stack size requested by this port. + */ +#ifndef CONFIGURE_MINIMUM_TASK_STACK_SIZE + #define CONFIGURE_MINIMUM_TASK_STACK_SIZE CPU_STACK_MINIMUM_SIZE +#endif + +/** + * @brief Idle task stack size configuration + * + * By default, the IDLE task will have a stack of minimum size. + * The BSP or application may override this value. + */ +#ifndef CONFIGURE_IDLE_TASK_STACK_SIZE + #ifdef BSP_IDLE_TASK_STACK_SIZE + #define CONFIGURE_IDLE_TASK_STACK_SIZE BSP_IDLE_TASK_STACK_SIZE + #else + #define CONFIGURE_IDLE_TASK_STACK_SIZE CONFIGURE_MINIMUM_TASK_STACK_SIZE + #endif +#endif + +/** + * @brief Interrupt stack size configuration + * + * By default, the interrupt stack will be of minimum size. + * The BSP or application may override this value. + */ +#ifndef CONFIGURE_INTERRUPT_STACK_SIZE + #ifdef BSP_INTERRUPT_STACK_SIZE + #define CONFIGURE_INTERRUPT_STACK_SIZE BSP_INTERRUPT_STACK_SIZE + #else + #define CONFIGURE_INTERRUPT_STACK_SIZE CONFIGURE_MINIMUM_TASK_STACK_SIZE + #endif +#endif + +/** + * This reserves memory for the interrupt stack if it is to be allocated + * by RTEMS rather than the BSP. + * + * @todo Try to get to the point where all BSPs support allocating the + * memory from the Workspace. + */ +#if (CPU_ALLOCATE_INTERRUPT_STACK == 0) + #define CONFIGURE_INTERRUPT_STACK_MEMORY 0 +#else + #define CONFIGURE_INTERRUPT_STACK_MEMORY \ + _Configure_From_workspace( CONFIGURE_INTERRUPT_STACK_SIZE ) +#endif + +/** + * Configure the very much optional task stack allocator + */ +#ifndef CONFIGURE_TASK_STACK_ALLOCATOR + #define CONFIGURE_TASK_STACK_ALLOCATOR NULL +#endif + +/** + * Configure the very much optional task stack deallocator + */ +#ifndef CONFIGURE_TASK_STACK_DEALLOCATOR + #define CONFIGURE_TASK_STACK_DEALLOCATOR NULL +#endif + +/** + * Should the RTEMS Workspace and C Program Heap be cleared automatically + * at system start up? + */ +#ifndef CONFIGURE_ZERO_WORKSPACE_AUTOMATICALLY + #ifdef BSP_ZERO_WORKSPACE_AUTOMATICALLY + #define CONFIGURE_ZERO_WORKSPACE_AUTOMATICALLY \ + BSP_ZERO_WORKSPACE_AUTOMATICALLY + #else + #define CONFIGURE_ZERO_WORKSPACE_AUTOMATICALLY FALSE + #endif +#endif + +/* + * RTEMS Malloc configuration + */ + +#include <rtems/malloc.h> + +#ifdef CONFIGURE_INIT + /** + * By default, RTEMS uses separate heaps for the RTEMS Workspace and + * the C Program Heap. On many BSPs, these can be optionally + * combined provided one larger memory pool. This is particularly + * useful in combination with the unlimited objects configuration. + */ + #ifdef CONFIGURE_UNIFIED_WORK_AREAS + #include <rtems/score/wkspace.h> + Heap_Control *RTEMS_Malloc_Heap = &_Workspace_Area; + bool rtems_unified_work_area = true; + #else + Heap_Control RTEMS_Malloc_Area; + Heap_Control *RTEMS_Malloc_Heap = &RTEMS_Malloc_Area; + bool rtems_unified_work_area = false; + #endif +#endif + +#ifdef CONFIGURE_INIT + /** + * This configures the malloc family statistics to be available. + * By default only function call counts are kept. + */ + rtems_malloc_statistics_functions_t *rtems_malloc_statistics_helpers = + #ifndef CONFIGURE_MALLOC_STATISTICS + NULL; + #else + &rtems_malloc_statistics_helpers_table; + #endif +#endif + +#ifdef CONFIGURE_INIT + /** + * This configures the sbrk() support for the malloc family. + * By default it is assumed that the BSP provides all available + * RAM to the malloc family implementation so sbrk()'ing to get + * more memory would always fail anyway. + */ + rtems_malloc_sbrk_functions_t *rtems_malloc_sbrk_helpers = + #ifndef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK + NULL; + #else + &rtems_malloc_sbrk_helpers_table; + #endif +#endif + +#ifdef CONFIGURE_INIT + /** + * This configures the malloc family plugin which dirties memory + * allocated. This is helpful for finding unitialized data structure + * problems. + */ + rtems_malloc_dirtier_t rtems_malloc_dirty_helper = + #if defined(CONFIGURE_MALLOC_DIRTY) + rtems_malloc_dirty_memory; + #else + NULL; + #endif +#endif + +/** + * This is a helper macro used in calculations in this file. It is used + * to noted when an element is allocated from the RTEMS Workspace and adds + * a factor to account for heap overhead plus an alignment factor that + * may be applied. + */ +#define _Configure_From_workspace(_size) \ + (ssize_t)((_size) + (2 * sizeof(uint32_t)) + CPU_ALIGNMENT) + +/** + * Do not use the unlimited bit as part of the multiplication + * for memory usage. + */ +#define _Configure_Max_Objects(_max) \ + ((_max) & ~RTEMS_UNLIMITED_OBJECTS) + +/** + * This macro accounts for how memory for a set of configured objects is + * allocated from the Executive Workspace. + * + * NOTE: It does NOT attempt to address the more complex case of unlimited + * objects. + */ +#define _Configure_Object_RAM(_number, _size) \ + ( _Configure_From_workspace(_Configure_Max_Objects(_number) * (_size)) + \ + _Configure_From_workspace( \ + ((_Configure_Max_Objects(_number) + 1) * sizeof(Objects_Control *)) + \ + (sizeof(void *) + sizeof(uint32_t) + sizeof(Objects_Name *)) \ + ) \ + ) + +/* + * Default User Initialization Task Table. This table guarantees that + * one user initialization table is defined. + */ + +#ifdef CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#ifdef CONFIGURE_HAS_OWN_INIT_TASK_TABLE + +/* + * The user is defining their own table information and setting the + * appropriate variables. + */ + +#else + +#ifndef CONFIGURE_INIT_TASK_NAME + #define CONFIGURE_INIT_TASK_NAME rtems_build_name('U', 'I', '1', ' ') +#endif + +#ifndef CONFIGURE_INIT_TASK_STACK_SIZE + #define CONFIGURE_INIT_TASK_STACK_SIZE CONFIGURE_MINIMUM_TASK_STACK_SIZE +#endif + +#ifndef CONFIGURE_INIT_TASK_PRIORITY + #define CONFIGURE_INIT_TASK_PRIORITY 1 +#endif + +#ifndef CONFIGURE_INIT_TASK_ATTRIBUTES + #define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES +#endif + +#ifndef CONFIGURE_INIT_TASK_ENTRY_POINT + #ifdef __cplusplus + extern "C" { + #endif + rtems_task Init (rtems_task_argument ); + #ifdef __cplusplus + } + #endif + #define CONFIGURE_INIT_TASK_ENTRY_POINT Init + extern const char* bsp_boot_cmdline; + #define CONFIGURE_INIT_TASK_ARGUMENTS ((rtems_task_argument) &bsp_boot_cmdline) +#endif + +#ifndef CONFIGURE_INIT_TASK_INITIAL_MODES + #define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_NO_PREEMPT +#endif + +#ifndef CONFIGURE_INIT_TASK_ARGUMENTS + #define CONFIGURE_INIT_TASK_ARGUMENTS 0 +#endif + +#ifdef CONFIGURE_INIT + rtems_initialization_tasks_table Initialization_tasks[] = { + { CONFIGURE_INIT_TASK_NAME, + CONFIGURE_INIT_TASK_STACK_SIZE, + CONFIGURE_INIT_TASK_PRIORITY, + CONFIGURE_INIT_TASK_ATTRIBUTES, + CONFIGURE_INIT_TASK_ENTRY_POINT, + CONFIGURE_INIT_TASK_INITIAL_MODES, + CONFIGURE_INIT_TASK_ARGUMENTS + } + }; +#endif + +#define CONFIGURE_INIT_TASK_TABLE Initialization_tasks + +#define CONFIGURE_INIT_TASK_TABLE_SIZE \ + sizeof(CONFIGURE_INIT_TASK_TABLE) / sizeof(rtems_initialization_tasks_table) + +#endif /* CONFIGURE_HAS_OWN_INIT_TASK_TABLE */ + +#else /* CONFIGURE_RTEMS_INIT_TASKS_TABLE */ + +#define CONFIGURE_INIT_TASK_TABLE NULL +#define CONFIGURE_INIT_TASK_TABLE_SIZE 0 +#define CONFIGURE_INIT_TASK_STACK_SIZE 0 + +#endif + +/* + * Default Device Driver Table. Each driver needed by the test is explicitly + * choosen by that test. There is always a null driver entry. + */ + +#define NULL_DRIVER_TABLE_ENTRY \ + { NULL, NULL, NULL, NULL, NULL, NULL } + +#ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER + #include <rtems/console.h> +#endif + +#ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + #include <rtems/clockdrv.h> +#endif + +#ifdef CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER + #include <rtems/timerdrv.h> +#endif + +#ifdef CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER + #include <rtems/rtc.h> +#endif + +#ifdef CONFIGURE_APPLICATION_NEEDS_WATCHDOG_DRIVER + #include <rtems/watchdogdrv.h> +#endif + +#ifdef CONFIGURE_APPLICATION_NEEDS_FRAME_BUFFER_DRIVER + #include <rtems/framebuffer.h> +#endif + +#ifdef CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER + #include <rtems/devnull.h> +#endif + +#ifdef CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER + /* the ide driver needs the ATA driver */ + #ifndef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER + #define CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER + #endif + #include <libchip/ide_ctrl.h> +#endif + +#ifdef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER + #include <libchip/ata.h> +#endif + +#ifndef CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE + +#ifdef CONFIGURE_INIT + rtems_driver_address_table Device_drivers[] = { + #ifdef CONFIGURE_BSP_PREREQUISITE_DRIVERS + CONFIGURE_BSP_PREREQUISITE_DRIVERS, + #endif + #ifdef CONFIGURE_APPLICATION_PREREQUISITE_DRIVERS + CONFIGURE_APPLICATION_PREREQUISITE_DRIVERS, + #endif + #ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER + CONSOLE_DRIVER_TABLE_ENTRY, + #endif + #ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + CLOCK_DRIVER_TABLE_ENTRY, + #endif + #ifdef CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER + RTC_DRIVER_TABLE_ENTRY, + #endif + #ifdef CONFIGURE_APPLICATION_NEEDS_WATCHDOG_DRIVER + WATCHDOG_DRIVER_TABLE_ENTRY, + #endif + #ifdef CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER + DEVNULL_DRIVER_TABLE_ENTRY, + #endif + #ifdef CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER + IDE_CONTROLLER_DRIVER_TABLE_ENTRY, + #endif + #ifdef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER + ATA_DRIVER_TABLE_ENTRY, + #endif + #ifdef CONFIGURE_APPLICATION_NEEDS_FRAME_BUFFER_DRIVER + FRAME_BUFFER_DRIVER_TABLE_ENTRY, + #endif + #ifdef CONFIGURE_APPLICATION_EXTRA_DRIVERS + CONFIGURE_APPLICATION_EXTRA_DRIVERS, + #endif + #ifdef CONFIGURE_APPLICATION_NEEDS_NULL_DRIVER + NULL_DRIVER_TABLE_ENTRY + #elif !defined(CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER) && \ + !defined(CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER) && \ + !defined(CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER) && \ + !defined(CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER) && \ + !defined(CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER) && \ + !defined(CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER) && \ + !defined(CONFIGURE_APPLICATION_NEEDS_FRAME_BUFFER_DRIVER) && \ + !defined(CONFIGURE_APPLICATION_EXTRA_DRIVERS) + NULL_DRIVER_TABLE_ENTRY + #endif + }; +#endif + +#endif /* CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE */ + +/* + * Default the number of drivers per node. This value may be + * overridden by the user. + */ + +#define CONFIGURE_NUMBER_OF_DRIVERS \ + ((sizeof(Device_drivers) / sizeof(rtems_driver_address_table))) + +/** + * This specifies the maximum number of device drivers that + * can be installed in the system at one time. It must account + * for both the statically and dynamically installed drivers. + */ +#ifndef CONFIGURE_MAXIMUM_DRIVERS + #define CONFIGURE_MAXIMUM_DRIVERS CONFIGURE_NUMBER_OF_DRIVERS +#endif + + +#ifdef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER + /* + * configure the priority of the ATA driver task + */ + #ifndef CONFIGURE_ATA_DRIVER_TASK_PRIORITY + #define CONFIGURE_ATA_DRIVER_TASK_PRIORITY ATA_DRIVER_TASK_DEFAULT_PRIORITY + #endif + #ifdef CONFIGURE_INIT + rtems_task_priority rtems_ata_driver_task_priority + = CONFIGURE_ATA_DRIVER_TASK_PRIORITY; + #endif /* CONFIGURE_INIT */ +#endif + +/* + * add bdbuf configuration and values for swapout task priority + */ +#ifdef CONFIGURE_APPLICATION_NEEDS_LIBBLOCK + #include <rtems/bdbuf.h> + /* + * configure the bdbuf cache parameters + */ + #ifndef CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS + #define CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS \ + RTEMS_BDBUF_MAX_READ_AHEAD_BLOCKS_DEFAULT + #endif + #ifndef CONFIGURE_BDBUF_MAX_WRITE_BLOCKS + #define CONFIGURE_BDBUF_MAX_WRITE_BLOCKS \ + RTEMS_BDBUF_MAX_WRITE_BLOCKS_DEFAULT + #endif + #ifndef CONFIGURE_SWAPOUT_TASK_PRIORITY + #define CONFIGURE_SWAPOUT_TASK_PRIORITY \ + RTEMS_BDBUF_SWAPOUT_TASK_PRIORITY_DEFAULT + #endif + #ifndef CONFIGURE_SWAPOUT_SWAP_PERIOD + #define CONFIGURE_SWAPOUT_SWAP_PERIOD \ + RTEMS_BDBUF_SWAPOUT_TASK_SWAP_PERIOD_DEFAULT + #endif + #ifndef CONFIGURE_SWAPOUT_BLOCK_HOLD + #define CONFIGURE_SWAPOUT_BLOCK_HOLD \ + RTEMS_BDBUF_SWAPOUT_TASK_BLOCK_HOLD_DEFAULT + #endif + #ifndef CONFIGURE_SWAPOUT_WORKER_TASKS + #define CONFIGURE_SWAPOUT_WORKER_TASKS \ + RTEMS_BDBUF_SWAPOUT_WORKER_TASKS_DEFAULT + #endif + #ifndef CONFIGURE_SWAPOUT_WORKER_TASK_PRIORITY + #define CONFIGURE_SWAPOUT_WORKER_TASK_PRIORITY \ + RTEMS_BDBUF_SWAPOUT_WORKER_TASK_PRIORITY_DEFAULT + #endif + #ifndef CONFIGURE_BDBUF_CACHE_MEMORY_SIZE + #define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE \ + RTEMS_BDBUF_CACHE_MEMORY_SIZE_DEFAULT + #endif + #ifndef CONFIGURE_BDBUF_BUFFER_MIN_SIZE + #define CONFIGURE_BDBUF_BUFFER_MIN_SIZE \ + RTEMS_BDBUF_BUFFER_MIN_SIZE_DEFAULT + #endif + #ifndef CONFIGURE_BDBUF_BUFFER_MAX_SIZE + #define CONFIGURE_BDBUF_BUFFER_MAX_SIZE \ + RTEMS_BDBUF_BUFFER_MAX_SIZE_DEFAULT + #endif + #ifdef CONFIGURE_INIT + const rtems_bdbuf_config rtems_bdbuf_configuration = { + CONFIGURE_BDBUF_MAX_READ_AHEAD_BLOCKS, + CONFIGURE_BDBUF_MAX_WRITE_BLOCKS, + CONFIGURE_SWAPOUT_TASK_PRIORITY, + CONFIGURE_SWAPOUT_SWAP_PERIOD, + CONFIGURE_SWAPOUT_BLOCK_HOLD, + CONFIGURE_SWAPOUT_WORKER_TASKS, + CONFIGURE_SWAPOUT_WORKER_TASK_PRIORITY, + CONFIGURE_BDBUF_CACHE_MEMORY_SIZE, + CONFIGURE_BDBUF_BUFFER_MIN_SIZE, + CONFIGURE_BDBUF_BUFFER_MAX_SIZE + }; + #endif + + /* + * Semaphores: + * o disk lock + * o bdbuf lock + * o bdbuf sync lock + * o bdbuf access condition + * o bdbuf transfer condition + * o bdbuf buffer condition + */ + #define CONFIGURE_LIBBLOCK_SEMAPHORES 6 + + #if defined(CONFIGURE_HAS_OWN_BDBUF_TABLE) || \ + defined(CONFIGURE_BDBUF_BUFFER_SIZE) || \ + defined(CONFIGURE_BDBUF_BUFFER_COUNT) + #error BDBUF Cache does not use a buffer configuration table. Please remove. + #endif +#else + #define CONFIGURE_LIBBLOCK_SEMAPHORES 0 +#endif /* CONFIGURE_APPLICATION_NEEDS_LIBBLOCK */ + +#if defined(RTEMS_MULTIPROCESSING) + /* + * Default Multiprocessing Configuration Table. The defaults are + * appropriate for most of the RTEMS Multiprocessor Test Suite. Each + * value may be overridden within each test to customize the environment. + */ + + #ifdef CONFIGURE_MP_APPLICATION + #define CONFIGURE_TIMER_FOR_SHARED_MEMORY_DRIVER 1 + + #ifndef CONFIGURE_HAS_OWN_MULTIPROCESSING_TABLE + + #ifndef CONFIGURE_MP_NODE_NUMBER + #define CONFIGURE_MP_NODE_NUMBER NODE_NUMBER + #endif + + #ifndef CONFIGURE_MP_MAXIMUM_NODES + #define CONFIGURE_MP_MAXIMUM_NODES 2 + #endif + + #ifndef CONFIGURE_MP_MAXIMUM_GLOBAL_OBJECTS + #define CONFIGURE_MP_MAXIMUM_GLOBAL_OBJECTS 32 + #endif + #define CONFIGURE_MEMORY_FOR_GLOBAL_OBJECTS(_global_objects) \ + _Configure_Object_RAM((_global_objects), sizeof(Objects_MP_Control)) + + #ifndef CONFIGURE_MP_MAXIMUM_PROXIES + #define CONFIGURE_MP_MAXIMUM_PROXIES 32 + #endif + #define CONFIGURE_MEMORY_FOR_PROXIES(_proxies) \ + _Configure_Object_RAM((_proxies) + 1, sizeof(Thread_Proxy_control) ) + + #ifndef CONFIGURE_EXTRA_MPCI_RECEIVE_SERVER_STACK + #define CONFIGURE_EXTRA_MPCI_RECEIVE_SERVER_STACK 0 + #endif + + #ifndef CONFIGURE_MP_MPCI_TABLE_POINTER + #include <mpci.h> + #define CONFIGURE_MP_MPCI_TABLE_POINTER &MPCI_table + #endif + + #ifdef CONFIGURE_INIT + rtems_multiprocessing_table Multiprocessing_configuration = { + CONFIGURE_MP_NODE_NUMBER, /* local node number */ + CONFIGURE_MP_MAXIMUM_NODES, /* maximum # nodes */ + CONFIGURE_MP_MAXIMUM_GLOBAL_OBJECTS, /* maximum # global objects */ + CONFIGURE_MP_MAXIMUM_PROXIES, /* maximum # proxies */ + CONFIGURE_EXTRA_MPCI_RECEIVE_SERVER_STACK, /* MPCI stack > minimum */ + CONFIGURE_MP_MPCI_TABLE_POINTER /* ptr to MPCI config table */ + }; + #endif + + #define CONFIGURE_MULTIPROCESSING_TABLE &Multiprocessing_configuration + + #endif /* CONFIGURE_HAS_OWN_MULTIPROCESSING_TABLE */ + + #else + + #define CONFIGURE_MULTIPROCESSING_TABLE NULL + + #endif /* CONFIGURE_MP_APPLICATION */ +#endif /* RTEMS_MULTIPROCESSING */ + +#ifndef CONFIGURE_TIMER_FOR_SHARED_MEMORY_DRIVER + #define CONFIGURE_TIMER_FOR_SHARED_MEMORY_DRIVER 0 +#endif + + +/* + * Default Configuration Table. + */ + +#ifndef CONFIGURE_HAS_OWN_CONFIGURATION_TABLE + + #ifndef CONFIGURE_MAXIMUM_TASKS + #define CONFIGURE_MAXIMUM_TASKS 0 + #endif + + #ifndef CONFIGURE_DISABLE_CLASSIC_API_NOTEPADS + #define CONFIGURE_NOTEPADS_ENABLED TRUE + #else + #define CONFIGURE_NOTEPADS_ENABLED FALSE + #endif + + #ifndef CONFIGURE_DISABLE_CLASSIC_API_NOTEPADS + #define CONFIGURE_MEMORY_PER_TASK_FOR_CLASSIC_API \ + _Configure_From_workspace( sizeof(RTEMS_API_Control) ) + #else + #define CONFIGURE_MEMORY_PER_TASK_FOR_CLASSIC_API \ + _Configure_From_workspace( sizeof(RTEMS_API_Control) - \ + (RTEMS_NUMBER_NOTEPADS * sizeof(uint32_t))) + #endif + + /** + * This macro calculates the memory required for task variables. + * + * @note Each task variable is individually allocated from the Workspace. + * Hence, we do the multiplication on the configured size. + */ + #ifndef CONFIGURE_MAXIMUM_TASK_VARIABLES + #define CONFIGURE_MAXIMUM_TASK_VARIABLES 0 + #define CONFIGURE_MEMORY_FOR_TASK_VARIABLES(_task_variables) 0 + #else + #define CONFIGURE_MEMORY_FOR_TASK_VARIABLES(_task_variables) \ + (_task_variables) * \ + _Configure_From_workspace(sizeof(rtems_task_variable_t)) + #endif + + #ifndef CONFIGURE_MAXIMUM_TIMERS + #define CONFIGURE_MAXIMUM_TIMERS 0 + #define CONFIGURE_MEMORY_FOR_TIMERS(_timers) 0 + #else + #define CONFIGURE_MEMORY_FOR_TIMERS(_timers) \ + _Configure_Object_RAM(_timers, sizeof(Timer_Control) ) + #endif + + #ifndef CONFIGURE_MAXIMUM_SEMAPHORES + #define CONFIGURE_MAXIMUM_SEMAPHORES 0 + #endif + + #define CONFIGURE_SEMAPHORES \ + (CONFIGURE_MAXIMUM_SEMAPHORES + CONFIGURE_LIBIO_SEMAPHORES + \ + CONFIGURE_TERMIOS_SEMAPHORES + CONFIGURE_LIBBLOCK_SEMAPHORES + \ + CONFIGURE_SEMAPHORES_FOR_FIFOS) + + /* + * If there are no user or support semaphores defined, then we can assume + * that no memory need be allocated at all for semaphores. + */ + #if CONFIGURE_SEMAPHORES == 0 + #define CONFIGURE_MEMORY_FOR_SEMAPHORES(_semaphores) 0 + #else + #define CONFIGURE_MEMORY_FOR_SEMAPHORES(_semaphores) \ + _Configure_Object_RAM(_semaphores, sizeof(Semaphore_Control) ) + #endif + + #ifndef CONFIGURE_MAXIMUM_MESSAGE_QUEUES + #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 0 + #define CONFIGURE_MEMORY_FOR_MESSAGE_QUEUES(_queues) 0 + #else + #define CONFIGURE_MEMORY_FOR_MESSAGE_QUEUES(_queues) \ + _Configure_Object_RAM(_queues, sizeof(Message_queue_Control) ) + #endif + + #ifndef CONFIGURE_MAXIMUM_PARTITIONS + #define CONFIGURE_MAXIMUM_PARTITIONS 0 + #define CONFIGURE_MEMORY_FOR_PARTITIONS(_partitions) 0 + #else + #define CONFIGURE_MEMORY_FOR_PARTITIONS(_partitions) \ + _Configure_Object_RAM(_partitions, sizeof(Partition_Control) ) + #endif + + #ifndef CONFIGURE_MAXIMUM_REGIONS + #define CONFIGURE_MAXIMUM_REGIONS 0 + #define CONFIGURE_MEMORY_FOR_REGIONS(_regions) 0 + #else + #define CONFIGURE_MEMORY_FOR_REGIONS(_regions) \ + _Configure_Object_RAM(_regions, sizeof(Region_Control) ) + #endif + + #ifndef CONFIGURE_MAXIMUM_PORTS + #define CONFIGURE_MAXIMUM_PORTS 0 + #define CONFIGURE_MEMORY_FOR_PORTS(_ports) 0 + #else + #define CONFIGURE_MEMORY_FOR_PORTS(_ports) \ + _Configure_Object_RAM(_ports, sizeof(Dual_ported_memory_Control) ) + #endif + + #ifndef CONFIGURE_MAXIMUM_PERIODS + #define CONFIGURE_MAXIMUM_PERIODS 0 + #define CONFIGURE_MEMORY_FOR_PERIODS(_periods) 0 + #else + #define CONFIGURE_MEMORY_FOR_PERIODS(_periods) \ + _Configure_Object_RAM(_periods, sizeof(Rate_monotonic_Control) ) + #endif + + #ifndef CONFIGURE_MAXIMUM_BARRIERS + #define CONFIGURE_MAXIMUM_BARRIERS 0 + #endif + + #define CONFIGURE_BARRIERS \ + (CONFIGURE_MAXIMUM_BARRIERS + CONFIGURE_BARRIERS_FOR_FIFOS) + + #if CONFIGURE_BARRIERS == 0 + #define CONFIGURE_MEMORY_FOR_BARRIERS(_barriers) 0 + #else + #define CONFIGURE_MEMORY_FOR_BARRIERS(_barriers) \ + _Configure_Object_RAM(_barriers, sizeof(Barrier_Control) ) + #endif + + #ifndef CONFIGURE_MAXIMUM_USER_EXTENSIONS + #define CONFIGURE_MAXIMUM_USER_EXTENSIONS 0 + #define CONFIGURE_MEMORY_FOR_USER_EXTENSIONS(_extensions) 0 + #else + #define CONFIGURE_MEMORY_FOR_USER_EXTENSIONS(_extensions) \ + _Configure_Object_RAM(_extensions, sizeof(Extension_Control) ) + #endif + + #ifndef CONFIGURE_MICROSECONDS_PER_TICK + #define CONFIGURE_MICROSECONDS_PER_TICK \ + RTEMS_MILLISECONDS_TO_MICROSECONDS(10) + #endif + + #ifndef CONFIGURE_TICKS_PER_TIMESLICE + #define CONFIGURE_TICKS_PER_TIMESLICE 50 + #endif + +/* + * Initial Extension Set + */ + +#ifdef CONFIGURE_INIT +#ifdef CONFIGURE_STACK_CHECKER_ENABLED +#include <rtems/stackchk.h> +#endif +#include <rtems/libcsupport.h> + +#if defined(CONFIGURE_INITIAL_EXTENSIONS) || \ + defined(CONFIGURE_STACK_CHECKER_ENABLED) || \ + (defined(RTEMS_NEWLIB) && !defined(CONFIGURE_DISABLE_NEWLIB_REENTRANCY)) + rtems_extensions_table Configuration_Initial_Extensions[] = { + #if !defined(CONFIGURE_DISABLE_NEWLIB_REENTRANCY) + RTEMS_NEWLIB_EXTENSION, + #endif + #if defined(CONFIGURE_STACK_CHECKER_ENABLED) + RTEMS_STACK_CHECKER_EXTENSION, + #endif + #if defined(CONFIGURE_INITIAL_EXTENSIONS) + CONFIGURE_INITIAL_EXTENSIONS, + #endif + }; + + #define CONFIGURE_INITIAL_EXTENSION_TABLE Configuration_Initial_Extensions + #define CONFIGURE_NUMBER_OF_INITIAL_EXTENSIONS \ + ((sizeof(Configuration_Initial_Extensions) / \ + sizeof(rtems_extensions_table))) +#else + #define CONFIGURE_INITIAL_EXTENSION_TABLE NULL + #define CONFIGURE_NUMBER_OF_INITIAL_EXTENSIONS 0 +#endif + + +#endif + +/* + * POSIX API Configuration Parameters + */ + +#ifdef RTEMS_POSIX_API + + #include <sys/types.h> + #include <signal.h> + #include <limits.h> + #include <mqueue.h> + #include <rtems/posix/barrier.h> + #include <rtems/posix/cond.h> + #include <rtems/posix/mqueue.h> + #include <rtems/posix/mutex.h> + #include <rtems/posix/key.h> + #include <rtems/posix/psignal.h> + #include <rtems/posix/rwlock.h> + #include <rtems/posix/semaphore.h> + #include <rtems/posix/spinlock.h> + #include <rtems/posix/threadsup.h> + #include <rtems/posix/timer.h> + + /** + * Account for the object control structures plus the name + * of the object to be duplicated. + */ + #define _Configure_POSIX_Named_Object_RAM(_number, _size) \ + _Configure_Object_RAM( (_number), _size ) + \ + ((_number) + _Configure_From_workspace(NAME_MAX) ) + + #ifndef CONFIGURE_MAXIMUM_POSIX_THREADS + #define CONFIGURE_MAXIMUM_POSIX_THREADS 0 + #endif + + #define CONFIGURE_MEMORY_PER_TASK_FOR_POSIX_API \ + _Configure_From_workspace( \ + CONFIGURE_MINIMUM_TASK_STACK_SIZE + \ + sizeof (POSIX_API_Control) + \ + (sizeof (void *) * (CONFIGURE_MAXIMUM_POSIX_KEYS)) \ + ) + + #ifndef CONFIGURE_MAXIMUM_POSIX_MUTEXES + #define CONFIGURE_MAXIMUM_POSIX_MUTEXES 0 + #define CONFIGURE_MEMORY_FOR_POSIX_MUTEXES(_mutexes) 0 + #else + #define CONFIGURE_MEMORY_FOR_POSIX_MUTEXES(_mutexes) \ + _Configure_Object_RAM(_mutexes, sizeof(POSIX_Mutex_Control) ) + #endif + + #ifndef CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES + #define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 0 + #define CONFIGURE_MEMORY_FOR_POSIX_CONDITION_VARIABLES(_condvars) 0 + #else + #define CONFIGURE_MEMORY_FOR_POSIX_CONDITION_VARIABLES(_condvars) \ + _Configure_Object_RAM(_condvars, \ + sizeof(POSIX_Condition_variables_Control) ) + #endif + + #ifndef CONFIGURE_MAXIMUM_POSIX_KEYS + #define CONFIGURE_MAXIMUM_POSIX_KEYS 0 + #define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys) 0 + #else + #define CONFIGURE_MEMORY_FOR_POSIX_KEYS(_keys) \ + _Configure_Object_RAM(_keys, sizeof(POSIX_Keys_Control) ) + #endif + + #ifndef CONFIGURE_MAXIMUM_POSIX_TIMERS + #define CONFIGURE_MAXIMUM_POSIX_TIMERS 0 + #define CONFIGURE_MEMORY_FOR_POSIX_TIMERS(_timers) 0 + #else + #define CONFIGURE_MEMORY_FOR_POSIX_TIMERS(_timers) \ + _Configure_Object_RAM(_timers, sizeof(POSIX_Timer_Control) ) + #endif + + #ifndef CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS + #define CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS 0 + #define CONFIGURE_MEMORY_FOR_POSIX_QUEUED_SIGNALS(_queued_signals) 0 + #else + #define CONFIGURE_MEMORY_FOR_POSIX_QUEUED_SIGNALS(_queued_signals) \ + _Configure_From_workspace( \ + (_queued_signals) * (sizeof(POSIX_signals_Siginfo_node)) ) + #endif + + #ifndef CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES + #define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES 0 + #define CONFIGURE_MEMORY_FOR_POSIX_MESSAGE_QUEUES(_message_queues) 0 + #define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUE_DESCRIPTORS 0 + #define CONFIGURE_MEMORY_FOR_POSIX_MESSAGE_QUEUE_DESCRIPTORS(_fds) 0 + #else + #define CONFIGURE_MEMORY_FOR_POSIX_MESSAGE_QUEUES(_message_queues) \ + _Configure_POSIX_Named_Object_RAM( \ + _message_queues, sizeof(POSIX_Message_queue_Control) ) + + /* default to same number */ + #ifndef CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUE_DESCRIPTORS + #define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUE_DESCRIPTORS \ + CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES + #endif + + #define CONFIGURE_MEMORY_FOR_POSIX_MESSAGE_QUEUE_DESCRIPTORS(_mqueue_fds) \ + _Configure_POSIX_Named_Object_RAM( \ + _mqueue_fds, sizeof(POSIX_Message_queue_Control_fd) ) + #endif + + #ifndef CONFIGURE_MAXIMUM_POSIX_SEMAPHORES + #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 0 + #define CONFIGURE_MEMORY_FOR_POSIX_SEMAPHORES(_semaphores) 0 + #else + #define CONFIGURE_MEMORY_FOR_POSIX_SEMAPHORES(_semaphores) \ + _Configure_POSIX_Named_Object_RAM( \ + _semaphores, sizeof(POSIX_Semaphore_Control) ) + #endif + + #ifndef CONFIGURE_MAXIMUM_POSIX_BARRIERS + #define CONFIGURE_MAXIMUM_POSIX_BARRIERS 0 + #define CONFIGURE_MEMORY_FOR_POSIX_BARRIERS(_barriers) 0 + #else + #define CONFIGURE_MEMORY_FOR_POSIX_BARRIERS(_barriers) \ + _Configure_Object_RAM(_barriers, sizeof(POSIX_Barrier_Control) ) + #endif + + #ifndef CONFIGURE_MAXIMUM_POSIX_SPINLOCKS + #define CONFIGURE_MAXIMUM_POSIX_SPINLOCKS 0 + #define CONFIGURE_MEMORY_FOR_POSIX_SPINLOCKS(_spinlocks) 0 + #else + #define CONFIGURE_MEMORY_FOR_POSIX_SPINLOCKS(_spinlocks) \ + _Configure_Object_RAM(_spinlocks, sizeof(POSIX_Spinlock_Control) ) + #endif + + #ifndef CONFIGURE_MAXIMUM_POSIX_RWLOCKS + #define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 0 + #define CONFIGURE_MEMORY_FOR_POSIX_RWLOCKS(_rwlocks) 0 + #else + #define CONFIGURE_MEMORY_FOR_POSIX_RWLOCKS(_rwlocks) \ + _Configure_Object_RAM(_rwlocks, sizeof(POSIX_RWLock_Control) ) + #endif + + #ifdef CONFIGURE_POSIX_INIT_THREAD_TABLE + + #ifdef CONFIGURE_POSIX_HAS_OWN_INIT_THREAD_TABLE + + /* + * The user is defining their own table information and setting the + * appropriate variables for the POSIX Initialization Thread Table. + */ + + #else + + #ifndef CONFIGURE_POSIX_INIT_THREAD_ENTRY_POINT + #define CONFIGURE_POSIX_INIT_THREAD_ENTRY_POINT POSIX_Init + #endif + + #ifndef CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE + #define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE \ + (CONFIGURE_MINIMUM_TASK_STACK_SIZE * 2) + #endif + + #ifdef CONFIGURE_INIT + posix_initialization_threads_table POSIX_Initialization_threads[] = { + { CONFIGURE_POSIX_INIT_THREAD_ENTRY_POINT, \ + CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE } + }; + #endif + + #define CONFIGURE_POSIX_INIT_THREAD_TABLE_NAME \ + POSIX_Initialization_threads + + #define CONFIGURE_POSIX_INIT_THREAD_TABLE_SIZE \ + sizeof(CONFIGURE_POSIX_INIT_THREAD_TABLE_NAME) / \ + sizeof(posix_initialization_threads_table) + + #endif /* CONFIGURE_POSIX_HAS_OWN_INIT_TASK_TABLE */ + + #else /* CONFIGURE_POSIX_INIT_THREAD_TABLE */ + + #define CONFIGURE_POSIX_INIT_THREAD_TABLE_NAME NULL + #define CONFIGURE_POSIX_INIT_THREAD_TABLE_SIZE 0 + + #endif + + #define CONFIGURE_MEMORY_FOR_POSIX \ + ( CONFIGURE_MEMORY_FOR_POSIX_MUTEXES( CONFIGURE_MAXIMUM_POSIX_MUTEXES + \ + CONFIGURE_MAXIMUM_GO_CHANNELS + CONFIGURE_GO_INIT_MUTEXES) + \ + CONFIGURE_MEMORY_FOR_POSIX_CONDITION_VARIABLES( \ + CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES + \ + CONFIGURE_MAXIMUM_GO_CHANNELS + CONFIGURE_GO_INIT_CONDITION_VARIABLES) + \ + CONFIGURE_MEMORY_FOR_POSIX_KEYS( CONFIGURE_MAXIMUM_POSIX_KEYS ) + \ + CONFIGURE_MEMORY_FOR_POSIX_QUEUED_SIGNALS( \ + CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS ) + \ + CONFIGURE_MEMORY_FOR_POSIX_MESSAGE_QUEUES( \ + CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES ) + \ + CONFIGURE_MEMORY_FOR_POSIX_MESSAGE_QUEUE_DESCRIPTORS( \ + CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUE_DESCRIPTORS ) + \ + CONFIGURE_MEMORY_FOR_POSIX_SEMAPHORES( \ + CONFIGURE_MAXIMUM_POSIX_SEMAPHORES ) + \ + CONFIGURE_MEMORY_FOR_POSIX_BARRIERS(CONFIGURE_MAXIMUM_POSIX_BARRIERS) + \ + CONFIGURE_MEMORY_FOR_POSIX_SPINLOCKS( \ + CONFIGURE_MAXIMUM_POSIX_SPINLOCKS ) + \ + CONFIGURE_MEMORY_FOR_POSIX_RWLOCKS( \ + CONFIGURE_MAXIMUM_POSIX_RWLOCKS ) + \ + CONFIGURE_MEMORY_FOR_POSIX_TIMERS( CONFIGURE_MAXIMUM_POSIX_TIMERS ) + \ + (CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE) \ + ) +#else + + #define CONFIGURE_MAXIMUM_POSIX_THREADS 0 + #define CONFIGURE_MEMORY_PER_TASK_FOR_POSIX_API 0 + #define CONFIGURE_MEMORY_FOR_POSIX 0 + +#endif /* RTEMS_POSIX_API */ + +#ifndef CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE + #define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE 0 +#endif + +/* + * This block of defines are for applications which use GNAT/RTEMS. + * GNAT implements each Ada task as a POSIX thread. + */ +#ifdef CONFIGURE_GNAT_RTEMS + + /** + * The GNAT run-time needs something less than (10) POSIX mutexes. + * We may be able to get by with less but why bother. + */ + #define CONFIGURE_GNAT_MUTEXES 10 + + /** + * This is the maximum number of Ada tasks which can be concurrently + * in existence. Twenty (20) are required to run all tests in the + * ACATS (formerly ACVC). + */ + #ifndef CONFIGURE_MAXIMUM_ADA_TASKS + #define CONFIGURE_MAXIMUM_ADA_TASKS 20 + #endif + + /** + * This is the number of non-Ada tasks which invoked Ada code. + */ + #ifndef CONFIGURE_MAXIMUM_FAKE_ADA_TASKS + #define CONFIGURE_MAXIMUM_FAKE_ADA_TASKS 0 + #endif + + /** + * Ada tasks are allocated twice the minimum stack space. + */ + #define CONFIGURE_ADA_TASKS_STACK \ + (CONFIGURE_MAXIMUM_ADA_TASKS * \ + (CONFIGURE_MINIMUM_TASK_STACK_SIZE + (6 * 1024))) + +#else + #define CONFIGURE_GNAT_MUTEXES 0 + #define CONFIGURE_MAXIMUM_ADA_TASKS 0 + #define CONFIGURE_MAXIMUM_FAKE_ADA_TASKS 0 + #define CONFIGURE_ADA_TASKS_STACK 0 +#endif + +#ifdef CONFIGURE_ENABLE_GO + + #ifndef CONFIGURE_MAXIMUM_POSIX_THREADS + #define CONFIGURE_MAXIMUM_POSIX_THREADS 1 + #endif + #ifndef CONFIGURE_MAXIMUM_POSIX_MUTEXES + #define CONFIGURE_MAXIMUM_POSIX_MUTEXES 1 + #endif + #ifndef CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES + #define CONFIGURE_MAXIMUM_CONDITION_VARIABLES 1 + #endif + + #define CONFIGURE_GO_INIT_MUTEXES 77 + #define CONFIGURE_GO_INIT_CONDITION_VARIABLES 4 + + #ifndef CONFIGURE_MAXIMUM_GOROUTINES + #define CONFIGURE_MAXIMUM_GOROUTINES 400 + #endif + + #define CONFIGURE_GOROUTINES_TASK_VARIABLES \ + (2 * CONFIGURE_MAXIMUM_GOROUTINES) + + #ifndef CONFIGURE_MAXIMUM_GO_CHANNELS + #define CONFIGURE_MAXIMUM_GO_CHANNELS 500 + #endif + +#else + #define CONFIGURE_GO_INIT_MUTEXES 0 + #define CONFIGURE_GO_INIT_CONDITION_VARIABLES 0 + #define CONFIGURE_MAXIMUM_GOROUTINES 0 + #define CONFIGURE_GOROUTINES_TASK_VARIABLES 0 + #define CONFIGURE_MAXIMUM_GO_CHANNELS 0 +#endif + +#ifndef RTEMS_SCHEDSIM +/** + * This macro specifies the amount of memory to be reserved for the + * Newlib C Library reentrancy structure -- if we are using newlib. + */ + +#if (defined(RTEMS_NEWLIB) && !defined(CONFIGURE_DISABLE_NEWLIB_REENTRANCY)) + #include <reent.h> + + #define CONFIGURE_MEMORY_PER_TASK_FOR_NEWLIB \ + _Configure_From_workspace(sizeof(struct _reent)) +#else + #define CONFIGURE_MEMORY_PER_TASK_FOR_NEWLIB 0 +#endif + +#else + #define CONFIGURE_MEMORY_PER_TASK_FOR_NEWLIB 0 +#endif + + +/* + * Calculate the RAM size based on the maximum number of objects configured. + */ + +#ifndef CONFIGURE_EXECUTIVE_RAM_SIZE + +/** + * Account for allocating the following per object + * + array of object control structures + * + local pointer table -- pointer per object plus a zero'th + * entry in the local pointer table. + */ + +#define CONFIGURE_MEMORY_FOR_TASKS(_tasks, _number_FP_tasks) \ + ( \ + _Configure_Object_RAM(_tasks, sizeof(Thread_Control)) + \ + (_Configure_Max_Objects(_tasks) * \ + (_Configure_From_workspace(CONFIGURE_MINIMUM_TASK_STACK_SIZE) + \ + CONFIGURE_MEMORY_PER_TASK_FOR_CLASSIC_API + \ + CONFIGURE_MEMORY_PER_TASK_FOR_NEWLIB + \ + CONFIGURE_MEMORY_PER_TASK_FOR_POSIX_API + \ + CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER)) + \ + _Configure_From_workspace( \ + _Configure_Max_Objects(_number_FP_tasks) * CONTEXT_FP_SIZE) + \ + _Configure_From_workspace( \ + (CONFIGURE_MAXIMUM_USER_EXTENSIONS + 1) * sizeof(void *)) \ + ) + +/** + * This defines the amount of memory configured for the multiprocessing + * support required by this application. + */ +#ifdef CONFIGURE_MP_APPLICATION + #define CONFIGURE_MEMORY_FOR_MP \ + (CONFIGURE_MEMORY_FOR_PROXIES(CONFIGURE_MP_MAXIMUM_PROXIES) + \ + CONFIGURE_MEMORY_FOR_GLOBAL_OBJECTS( \ + CONFIGURE_MP_MAXIMUM_GLOBAL_OBJECTS) + \ + CONFIGURE_MEMORY_FOR_TASKS(1, 1) + \ + CONFIGURE_EXTRA_MPCI_RECEIVE_SERVER_STACK \ + ) +#else + #define CONFIGURE_MEMORY_FOR_MP 0 +#endif + +/** + * This is so we can account for tasks with stacks greater than minimum + * size. This is in bytes. + */ +#ifndef CONFIGURE_EXTRA_TASK_STACKS + #define CONFIGURE_EXTRA_TASK_STACKS 0 +#endif + +/** + * The following macro is used to calculate the memory allocated by RTEMS + * for the message buffers associated with a particular message queue. + * There is a fixed amount of overhead per message. + */ +#define CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE(_messages, _size) \ + _Configure_From_workspace( \ + (_messages) * ((_size) + sizeof(CORE_message_queue_Buffer_control))) + +/** + * This macros is set to the amount of memory required for pending message + * buffers in bytes. It should be constructed by adding together a + * set of values determined by CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE. + */ +#ifndef CONFIGURE_MESSAGE_BUFFER_MEMORY + #define CONFIGURE_MESSAGE_BUFFER_MEMORY 0 +#endif + +/** + * This macro is available just in case the confdefs.h file underallocates + * memory for a particular application. This lets the user add some extra + * memory in case something broken and underestimates. + * + * It is also possible for cases where confdefs.h overallocates memory, + * you could substract memory from the allocated. The estimate is just + * that, an estimate, and assumes worst case alignment and padding on + * each allocated element. So in some cases it could be too conservative. + * + * @note Historically this was used for message buffers. + */ +#ifndef CONFIGURE_MEMORY_OVERHEAD + #define CONFIGURE_MEMORY_OVERHEAD 0 +#endif + +/** + * On architectures that use Simple Vectored Interrupts, it is RTEMS + * responsibility to allocate the vector table. This avoids reserving + * the memory on architectures that use the Programmable Interrupt + * Controller Vectored Interrupts. + */ +#if (CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE) + /* + * This is a (hopefully) temporary hack. On the mips, the number of + * vectors is NOT statically defined. But it has to be statically + * defined for this to work. This is an issue looking for a nice + * solution. + */ + #if defined(__mips__) + #define CONFIGURE_INTERRUPT_VECTOR_TABLE \ + _Configure_From_workspace( (sizeof(ISR_Handler_entry) * 256)) + #else + #define CONFIGURE_INTERRUPT_VECTOR_TABLE \ + _Configure_From_workspace( \ + (sizeof(ISR_Handler_entry) * ISR_NUMBER_OF_VECTORS)) + #endif +#else + #define CONFIGURE_INTERRUPT_VECTOR_TABLE 0 +#endif + +/** + * RTEMS uses one instance of an internal mutex class. This accounts + * for that mutex + */ +#define CONFIGURE_API_MUTEX_MEMORY \ + _Configure_Object_RAM(1, sizeof(API_Mutex_Control)) + +/** + * This defines the formula used to compute the amount of memory + * reserved for IDLE task control structures and stacks. + */ +#define CONFIGURE_IDLE_TASKS(_count) \ + (CONFIGURE_MEMORY_FOR_TASKS(_count, 0) + \ + _count * _Configure_From_workspace( \ + (CONFIGURE_IDLE_TASK_STACK_SIZE - CONFIGURE_MINIMUM_TASK_STACK_SIZE))) + +/** + * This calculates the amount of memory reserved for the IDLE tasks. + * In an SMP system, each CPU core has its own idle task. + */ +#if defined(RTEMS_SMP) + #define CONFIGURE_MEMORY_FOR_IDLE_TASK \ + CONFIGURE_IDLE_TASKS(CONFIGURE_SMP_MAXIMUM_PROCESSORS) +#else + #define CONFIGURE_MEMORY_FOR_IDLE_TASK \ + CONFIGURE_IDLE_TASKS(1) +#endif + +/** + * This macro accounts for general RTEMS system overhead. + */ +#define CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD \ + ( CONFIGURE_MEMORY_FOR_IDLE_TASK + /* IDLE and stack */ \ + CONFIGURE_MEMORY_FOR_SCHEDULER + /* Scheduler */ \ + CONFIGURE_INTERRUPT_VECTOR_TABLE + /* interrupt vectors */ \ + CONFIGURE_INTERRUPT_STACK_MEMORY + /* interrupt stack */ \ + CONFIGURE_API_MUTEX_MEMORY /* allocation mutex */ \ + ) + +/* + * Now account for any extra memory that initialization tasks or threads + * may have requested. + */ + +/** + * This accounts for any extra memory required by the Classic API + * Initialization Task. + */ +#if (CONFIGURE_INIT_TASK_STACK_SIZE > CONFIGURE_MINIMUM_TASK_STACK_SIZE) + #define CONFIGURE_INITIALIZATION_THREADS_STACKS_CLASSIC_PART \ + (CONFIGURE_INIT_TASK_STACK_SIZE - CONFIGURE_MINIMUM_TASK_STACK_SIZE) +#else + #define CONFIGURE_INITIALIZATION_THREADS_STACKS_CLASSIC_PART 0 +#endif + +/** + * This accounts for any extra memory required by the POSIX API + * Initialization Thread. + */ +#if defined(RTEMS_POSIX_API) && \ + (CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE > CONFIGURE_MINIMUM_TASK_STACK_SIZE) + #define CONFIGURE_INITIALIZATION_THREADS_STACKS_POSIX_PART \ + (CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE - CONFIGURE_MINIMUM_TASK_STACK_SIZE) +#else + #define CONFIGURE_INITIALIZATION_THREADS_STACKS_POSIX_PART 0 +#endif + +/** + * This macro provides a summation of the various initialization task + * and thread stack requirements. + */ +#define CONFIGURE_INITIALIZATION_THREADS_STACKS \ + (CONFIGURE_INITIALIZATION_THREADS_STACKS_CLASSIC_PART + \ + CONFIGURE_INITIALIZATION_THREADS_STACKS_POSIX_PART) + +/** + * This macro provides a summation of the various task and thread + * requirements. + */ +#define CONFIGURE_TOTAL_TASKS_AND_THREADS \ + (CONFIGURE_MAXIMUM_TASKS + \ + CONFIGURE_MAXIMUM_POSIX_THREADS + CONFIGURE_MAXIMUM_ADA_TASKS + \ + CONFIGURE_MAXIMUM_GOROUTINES) + +/** + * This macro reserves the memory required by the statically configured + * user extensions. + */ +#define CONFIGURE_MEMORY_FOR_STATIC_EXTENSIONS \ + ((CONFIGURE_NEWLIB_EXTENSION * \ + _Configure_From_workspace( sizeof(User_extensions_Control))) + \ + (CONFIGURE_STACK_CHECKER_EXTENSION * \ + _Configure_From_workspace( sizeof(User_extensions_Control))) \ + ) + +/** + * This macro provides a summation of the memory required by the + * Classic API as configured. + */ +#define CONFIGURE_MEMORY_FOR_CLASSIC \ + (CONFIGURE_MEMORY_FOR_TASK_VARIABLES(CONFIGURE_MAXIMUM_TASK_VARIABLES + \ + CONFIGURE_GOROUTINES_TASK_VARIABLES) + \ + CONFIGURE_MEMORY_FOR_TIMERS(CONFIGURE_MAXIMUM_TIMERS + \ + CONFIGURE_TIMER_FOR_SHARED_MEMORY_DRIVER ) + \ + CONFIGURE_MEMORY_FOR_SEMAPHORES(CONFIGURE_SEMAPHORES) + \ + CONFIGURE_MEMORY_FOR_MESSAGE_QUEUES(CONFIGURE_MAXIMUM_MESSAGE_QUEUES) + \ + CONFIGURE_MEMORY_FOR_PARTITIONS(CONFIGURE_MAXIMUM_PARTITIONS) + \ + CONFIGURE_MEMORY_FOR_REGIONS( CONFIGURE_MAXIMUM_REGIONS ) + \ + CONFIGURE_MEMORY_FOR_PORTS(CONFIGURE_MAXIMUM_PORTS) + \ + CONFIGURE_MEMORY_FOR_PERIODS(CONFIGURE_MAXIMUM_PERIODS) + \ + CONFIGURE_MEMORY_FOR_BARRIERS(CONFIGURE_BARRIERS) + \ + CONFIGURE_MEMORY_FOR_USER_EXTENSIONS(CONFIGURE_MAXIMUM_USER_EXTENSIONS) \ + ) + +#if defined(RTEMS_SMP) + #define CONFIGURE_MEMORY_FOR_SMP \ + (CONFIGURE_SMP_MAXIMUM_PROCESSORS * \ + _Configure_From_workspace( CONFIGURE_INTERRUPT_STACK_SIZE ) \ + ) +#else + #define CONFIGURE_MEMORY_FOR_SMP 0 +#endif + +#if defined(CONFIGURE_CONFDEFS_DEBUG) && defined(CONFIGURE_INIT) + /** + * This is a debug mechanism, so if you need to, the executable will + * have a structure with various partial values. Add to this as you + * need to. Viewing this structure in gdb combined with dumping + * the Configuration structures generated should help a lot in tracing + * down errors and analyzing where over and under allocations are. + */ + typedef struct { + uint32_t SYSTEM_OVERHEAD; + uint32_t STATIC_EXTENSIONS; + uint32_t INITIALIZATION_THREADS_STACKS; + + uint32_t PER_INTEGER_TASK; + uint32_t FP_OVERHEAD; + uint32_t CLASSIC; + uint32_t POSIX; + + /* System overhead pieces */ + uint32_t INTERRUPT_VECTOR_TABLE; + uint32_t INTERRUPT_STACK_MEMORY; + uint32_t THREAD_READY_CHAINS; + uint32_t MEMORY_FOR_IDLE_TASK; + + /* Classic API Pieces */ + uint32_t CLASSIC_TASKS; + uint32_t TASK_VARIABLES; + uint32_t TIMERS; + uint32_t SEMAPHORES; + uint32_t MESSAGE_QUEUES; + uint32_t PARTITIONS; + uint32_t REGIONS; + uint32_t PORTS; + uint32_t PERIODS; + uint32_t BARRIERS; + uint32_t USER_EXTENSIONS; +#ifdef RTEMS_POSIX_API + /* POSIX API Pieces */ + uint32_t POSIX_MUTEXES; + uint32_t POSIX_CONDITION_VARIABLES; + uint32_t POSIX_KEYS; + uint32_t POSIX_TIMERS; + uint32_t POSIX_QUEUED_SIGNALS; + uint32_t POSIX_MESSAGE_QUEUES; + uint32_t POSIX_SEMAPHORES; + uint32_t POSIX_BARRIERS; + uint32_t POSIX_SPINLOCKS; + uint32_t POSIX_RWLOCKS; +#endif + } Configuration_Debug_t; + + Configuration_Debug_t Configuration_Memory_Debug = { + /* General Information */ + CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD, + CONFIGURE_MEMORY_FOR_STATIC_EXTENSIONS, + CONFIGURE_INITIALIZATION_THREADS_STACKS, + CONFIGURE_MEMORY_FOR_TASKS(1, 0), + CONFIGURE_MEMORY_FOR_TASKS(0, 1), + CONFIGURE_MEMORY_FOR_CLASSIC, + CONFIGURE_MEMORY_FOR_POSIX, + + /* System overhead pieces */ + CONFIGURE_INTERRUPT_VECTOR_TABLE, + CONFIGURE_INTERRUPT_STACK_MEMORY, + CONFIGURE_MEMORY_FOR_THREAD_READY_CHAINS, + CONFIGURE_MEMORY_FOR_IDLE_TASK, + + /* Classic API Pieces */ + CONFIGURE_MEMORY_FOR_TASKS(CONFIGURE_MAXIMUM_TASKS, 0), + CONFIGURE_MEMORY_FOR_TASK_VARIABLES(CONFIGURE_MAXIMUM_TASK_VARIABLES + + CONFIGURE_GOROUTINES_TASK_VARIABLES), + CONFIGURE_MEMORY_FOR_TIMERS(CONFIGURE_MAXIMUM_TIMERS), + CONFIGURE_MEMORY_FOR_SEMAPHORES(CONFIGURE_SEMAPHORES), + CONFIGURE_MEMORY_FOR_MESSAGE_QUEUES(CONFIGURE_MAXIMUM_MESSAGE_QUEUES), + CONFIGURE_MEMORY_FOR_PARTITIONS(CONFIGURE_MAXIMUM_PARTITIONS), + CONFIGURE_MEMORY_FOR_REGIONS( CONFIGURE_MAXIMUM_REGIONS ), + CONFIGURE_MEMORY_FOR_PORTS(CONFIGURE_MAXIMUM_PORTS), + CONFIGURE_MEMORY_FOR_PERIODS(CONFIGURE_MAXIMUM_PERIODS), + CONFIGURE_MEMORY_FOR_BARRIERS(CONFIGURE_BARRIERS), + CONFIGURE_MEMORY_FOR_USER_EXTENSIONS(CONFIGURE_MAXIMUM_USER_EXTENSIONS), + +#ifdef RTEMS_POSIX_API + /* POSIX API Pieces */ + CONFIGURE_MEMORY_FOR_POSIX_MUTEXES( CONFIGURE_MAXIMUM_POSIX_MUTEXES + + CONFIGURE_MAXIMUM_GO_CHANNELS + CONFIGURE_GO_INIT_MUTEXES), + CONFIGURE_MEMORY_FOR_POSIX_CONDITION_VARIABLES( + CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES + + CONFIGURE_MAXIMUM_GO_CHANNELS + CONFIGURE_GO_INIT_CONDITION_VARIABLES), + CONFIGURE_MEMORY_FOR_POSIX_KEYS( CONFIGURE_MAXIMUM_POSIX_KEYS ), + CONFIGURE_MEMORY_FOR_POSIX_QUEUED_SIGNALS( + CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS ), + CONFIGURE_MEMORY_FOR_POSIX_MESSAGE_QUEUES( + CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES ), + CONFIGURE_MEMORY_FOR_POSIX_SEMAPHORES( CONFIGURE_MAXIMUM_POSIX_SEMAPHORES ), + CONFIGURE_MEMORY_FOR_POSIX_BARRIERS( CONFIGURE_MAXIMUM_POSIX_BARRIERS ), + CONFIGURE_MEMORY_FOR_POSIX_SPINLOCKS( CONFIGURE_MAXIMUM_POSIX_SPINLOCKS ), + CONFIGURE_MEMORY_FOR_POSIX_RWLOCKS( CONFIGURE_MAXIMUM_POSIX_RWLOCKS ), + CONFIGURE_MEMORY_FOR_POSIX_TIMERS( CONFIGURE_MAXIMUM_POSIX_TIMERS ), +#endif + }; +#endif + +/** + * This calculates the memory required for the executive workspace. + */ +#define CONFIGURE_EXECUTIVE_RAM_SIZE \ +(( \ + CONFIGURE_MEMORY_FOR_SYSTEM_OVERHEAD + \ + CONFIGURE_MEMORY_FOR_DEVFS + \ + CONFIGURE_MEMORY_FOR_TASKS( \ + CONFIGURE_TOTAL_TASKS_AND_THREADS, CONFIGURE_TOTAL_TASKS_AND_THREADS) + \ + CONFIGURE_MEMORY_FOR_CLASSIC + \ + CONFIGURE_MEMORY_FOR_POSIX + \ + (CONFIGURE_MAXIMUM_POSIX_THREADS * CONFIGURE_MINIMUM_TASK_STACK_SIZE ) + \ + (CONFIGURE_MAXIMUM_GOROUTINES * CONFIGURE_MINIMUM_TASK_STACK_SIZE) + \ + CONFIGURE_INITIALIZATION_THREADS_STACKS + \ + CONFIGURE_MEMORY_FOR_STATIC_EXTENSIONS + \ + CONFIGURE_MEMORY_FOR_MP + \ + CONFIGURE_MEMORY_FOR_SMP + \ + CONFIGURE_MESSAGE_BUFFER_MEMORY + \ + (CONFIGURE_MEMORY_OVERHEAD * 1024) + \ + (CONFIGURE_EXTRA_TASK_STACKS) + (CONFIGURE_ADA_TASKS_STACK) \ +) & ~0x7) +#endif + +#ifdef CONFIGURE_INIT + /** + * This is the Classic API Configuration Table. + */ + rtems_api_configuration_table Configuration_RTEMS_API = { + CONFIGURE_MAXIMUM_TASKS, + CONFIGURE_NOTEPADS_ENABLED, + CONFIGURE_MAXIMUM_TIMERS + CONFIGURE_TIMER_FOR_SHARED_MEMORY_DRIVER, + CONFIGURE_SEMAPHORES, + CONFIGURE_MAXIMUM_MESSAGE_QUEUES, + CONFIGURE_MAXIMUM_PARTITIONS, + CONFIGURE_MAXIMUM_REGIONS, + CONFIGURE_MAXIMUM_PORTS, + CONFIGURE_MAXIMUM_PERIODS, + CONFIGURE_BARRIERS, + CONFIGURE_INIT_TASK_TABLE_SIZE, + CONFIGURE_INIT_TASK_TABLE + }; + + #ifdef RTEMS_POSIX_API + /** + * This is the POSIX API Configuration Table. + */ + posix_api_configuration_table Configuration_POSIX_API = { + CONFIGURE_MAXIMUM_POSIX_THREADS + CONFIGURE_MAXIMUM_ADA_TASKS + + CONFIGURE_MAXIMUM_GOROUTINES, + CONFIGURE_MAXIMUM_POSIX_MUTEXES + CONFIGURE_GNAT_MUTEXES + + CONFIGURE_MAXIMUM_ADA_TASKS + CONFIGURE_MAXIMUM_FAKE_ADA_TASKS + + CONFIGURE_GO_INIT_MUTEXES + CONFIGURE_MAXIMUM_GO_CHANNELS, + CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES + + CONFIGURE_MAXIMUM_ADA_TASKS + CONFIGURE_MAXIMUM_FAKE_ADA_TASKS + + CONFIGURE_GO_INIT_CONDITION_VARIABLES + CONFIGURE_MAXIMUM_GO_CHANNELS, + CONFIGURE_MAXIMUM_POSIX_KEYS, + CONFIGURE_MAXIMUM_POSIX_TIMERS, + CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS, + CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES, + CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUE_DESCRIPTORS, + CONFIGURE_MAXIMUM_POSIX_SEMAPHORES, + CONFIGURE_MAXIMUM_POSIX_BARRIERS, + CONFIGURE_MAXIMUM_POSIX_RWLOCKS, + CONFIGURE_MAXIMUM_POSIX_SPINLOCKS, + CONFIGURE_POSIX_INIT_THREAD_TABLE_SIZE, + CONFIGURE_POSIX_INIT_THREAD_TABLE_NAME + }; + #endif + + /** This variable specifies the minimum stack size for tasks in an RTEMS + * application. + * + * @note This is left as a simple uint32_t so it can be externed as + * needed without requring being high enough logical to + * include the full configuration table. + */ + uint32_t rtems_minimum_stack_size = + CONFIGURE_MINIMUM_TASK_STACK_SIZE; + + /** This variable specifies the maximum priority value that + * a task may have. This must be a power of 2 between 4 + * and 256 and is specified in terms of Classic API + * priority values. + * + * @note This is left as a simple uint8_t so it can be externed as + * needed without requring being high enough logical to + * include the full configuration table. + */ + uint8_t rtems_maximum_priority = CONFIGURE_MAXIMUM_PRIORITY; + + /** + * This is the primary Configuration Table for this application. + */ + rtems_configuration_table Configuration = { + NULL, /* filled in by BSP */ + CONFIGURE_EXECUTIVE_RAM_SIZE, /* required RTEMS workspace */ + CONFIGURE_MAXIMUM_USER_EXTENSIONS, /* maximum dynamic extensions */ + CONFIGURE_MICROSECONDS_PER_TICK, /* microseconds per clock tick */ + CONFIGURE_TICKS_PER_TIMESLICE, /* ticks per timeslice quantum */ + CONFIGURE_IDLE_TASK_BODY, /* user's IDLE task */ + CONFIGURE_IDLE_TASK_STACK_SIZE, /* IDLE task stack size */ + CONFIGURE_INTERRUPT_STACK_SIZE, /* interrupt stack size */ + CONFIGURE_TASK_STACK_ALLOCATOR, /* stack allocator */ + CONFIGURE_TASK_STACK_DEALLOCATOR, /* stack deallocator */ + CONFIGURE_ZERO_WORKSPACE_AUTOMATICALLY, /* true to clear memory */ + CONFIGURE_MAXIMUM_DRIVERS, /* maximum device drivers */ + CONFIGURE_NUMBER_OF_DRIVERS, /* static device drivers */ + Device_drivers, /* pointer to driver table */ + CONFIGURE_NUMBER_OF_INITIAL_EXTENSIONS, /* number of static extensions */ + CONFIGURE_INITIAL_EXTENSION_TABLE, /* pointer to static extensions */ + #if defined(RTEMS_MULTIPROCESSING) + CONFIGURE_MULTIPROCESSING_TABLE, /* pointer to MP config table */ + #endif + }; +#endif + +#endif /* CONFIGURE_HAS_OWN_CONFIGURATION_TABLE */ + +#if defined(RTEMS_SMP) + /** + * Instantiate the variable which specifies the number of CPUs + * in an SMP configuration. + */ + #if defined(CONFIGURE_INIT) + uint32_t rtems_smp_maximum_processors = CONFIGURE_SMP_MAXIMUM_PROCESSORS; + #else + extern uint32_t rtems_smp_maximum_processors; + #endif + /* + * Instantiate the Per CPU information based upon the user configuration. + */ + #if defined(CONFIGURE_INIT) + Per_CPU_Control _Per_CPU_Information[CONFIGURE_SMP_MAXIMUM_PROCESSORS]; + Per_CPU_Control *_Per_CPU_Information_p[CONFIGURE_SMP_MAXIMUM_PROCESSORS]; + #endif + +#endif + +/* + * If the user has configured a set of Classic API Initialization Tasks, + * then we need to install the code that runs that loop. + */ +#ifdef CONFIGURE_INIT + #if defined(CONFIGURE_RTEMS_INIT_TASKS_TABLE) || \ + defined(CONFIGURE_HAS_OWN_INIT_TASK_TABLE) + void (_RTEMS_tasks_Initialize_user_tasks_body)(void); + void (*_RTEMS_tasks_Initialize_user_tasks_p)(void) = + _RTEMS_tasks_Initialize_user_tasks_body; + #else + void (*_RTEMS_tasks_Initialize_user_tasks_p)(void) = NULL; + #endif +#endif + +/* + * If the user has configured a set of POSIX Initialization Threads, + * then we need to install the code that runs that loop. + */ +#ifdef RTEMS_POSIX_API + #ifdef CONFIGURE_INIT + #if defined(CONFIGURE_POSIX_INIT_THREAD_TABLE) || \ + defined(CONFIGURE_POSIX_HAS_OWN_INIT_THREAD_TABLE) + void _POSIX_Threads_Initialize_user_threads_body(void); + void (*_POSIX_Threads_Initialize_user_threads_p)(void) = + _POSIX_Threads_Initialize_user_threads_body; + #else + void (*_POSIX_Threads_Initialize_user_threads_p)(void) = NULL; + #endif + #endif +#endif + +#ifdef __cplusplus +} +#endif + +/****************************************************************** + ****************************************************************** + ****************************************************************** + * CONFIGURATION WARNINGS AND ERROR CHECKING * + ****************************************************************** + ****************************************************************** + ****************************************************************** + */ + +/* + * Make sure a task/thread of some sort is configured. + * + * When analyzing RTEMS to find the smallest possible of memory + * that must be allocated, you probably do want to configure 0 + * tasks/threads so there is a smaller set of calls to _Workspace_Allocate + * to analyze. + */ +#if !defined(CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION) + #if (CONFIGURE_MAXIMUM_TASKS == 0) && \ + (CONFIGURE_MAXIMUM_POSIX_THREADS == 0) && \ + (CONFIGURE_MAXIMUM_ADA_TASKS == 0) && \ + (CONFIGURE_MAXIMUM_GOROUTINES == 0) + #error "CONFIGURATION ERROR: No tasks or threads configured!!" + #endif +#endif + +#ifndef RTEMS_SCHEDSIM +/* + * Make sure at least one of the initialization task/thread + * tables was defined. + */ +#if !defined(CONFIGURE_RTEMS_INIT_TASKS_TABLE) && \ + !defined(CONFIGURE_POSIX_INIT_THREAD_TABLE) && \ + !defined(CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION) +#error "CONFIGURATION ERROR: No initialization tasks or threads configured!!" +#endif +#endif + +/* + * If the user is trying to configure a multiprocessing application and + * RTEMS was not configured and built multiprocessing, then error out. + */ +#if defined(CONFIGURE_MP_APPLICATION) && \ + !defined(RTEMS_MULTIPROCESSING) +#error "CONFIGURATION ERROR: RTEMS not configured for multiprocessing!!" +#endif + +/* + * If an attempt was made to configure POSIX objects and + * the POSIX API was not configured into RTEMS, error out. + */ +#if !defined(RTEMS_POSIX_API) + #if ((CONFIGURE_MAXIMUM_POSIX_THREADS != 0) || \ + (CONFIGURE_MAXIMUM_POSIX_MUTEXES != 0) || \ + (CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES != 0) || \ + (CONFIGURE_MAXIMUM_POSIX_KEYS != 0) || \ + (CONFIGURE_MAXIMUM_POSIX_TIMERS != 0) || \ + (CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS != 0) || \ + (CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES != 0) || \ + (CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUE_DESCRIPTORS != 0) || \ + (CONFIGURE_MAXIMUM_POSIX_SEMAPHORES != 0) || \ + (CONFIGURE_MAXIMUM_POSIX_BARRIERS != 0) || \ + (CONFIGURE_MAXIMUM_POSIX_SPINLOCKS != 0) || \ + (CONFIGURE_MAXIMUM_POSIX_RWLOCKS != 0) || \ + defined(CONFIGURE_POSIX_INIT_THREAD_TABLE)) + #error "CONFIGURATION ERROR: POSIX API support not configured!!" + #endif +#endif + +#ifndef RTEMS_SCHEDSIM +/* + * You must either explicity include or exclude the clock driver. + * It is such a common newbie error to leave it out. Maybe this + * will put an end to it. + * + * NOTE: If you are using the timer driver, it is considered + * mutually exclusive with the clock driver because the + * drivers are assumed to use the same "timer" hardware + * on many boards. + */ +#if !defined(CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE) + #if !defined(CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER) && \ + !defined(CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER) && \ + !defined(CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER) + #error "CONFIGURATION ERROR: Do you want the clock driver or not?!?" + #endif +#endif +#endif + +/* + * These names have been obsoleted so make the user application stop compiling + */ +#if defined(CONFIGURE_TEST_NEEDS_TIMER_DRIVER) || \ + defined(CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER) || \ + defined(CONFIGURE_TEST_NEEDS_CLOCK_DRIVER) || \ + defined(CONFIGURE_TEST_NEEDS_RTC_DRIVER) || \ + defined(CONFIGURE_TEST_NEEDS_STUB_DRIVER) +#error "CONFIGURATION ERROR: CONFIGURE_TEST_XXX constants are obsolete" +#endif + +/* + * Validate the configured maximum priority + */ +#if ((CONFIGURE_MAXIMUM_PRIORITY != 3) && \ + (CONFIGURE_MAXIMUM_PRIORITY != 7) && \ + (CONFIGURE_MAXIMUM_PRIORITY != 15) && \ + (CONFIGURE_MAXIMUM_PRIORITY != 31) && \ + (CONFIGURE_MAXIMUM_PRIORITY != 63) && \ + (CONFIGURE_MAXIMUM_PRIORITY != 127) && \ + (CONFIGURE_MAXIMUM_PRIORITY != 255)) + #error "Maximum priority is not 1 less than a power of 2 between 4 and 256" +#endif + +#if (CONFIGURE_MAXIMUM_PRIORITY > PRIORITY_DEFAULT_MAXIMUM) + #error "Maximum priority configured higher than supported by target." +#endif + +/* + * If you have fewer POSIX Message Queue Descriptors than actual + * POSIX Message Queues, then you will not be able to open all the + * queues. + */ +#if (CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUE_DESCRIPTORS < \ + CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES) + #error "Fewer POSIX Message Queue descriptors than Queues!" +#endif + +#endif +/* end of include file */ diff --git a/cpukit/sapi/include/rtems/README b/cpukit/sapi/include/rtems/README new file mode 100644 index 0000000000..f29bdb45b7 --- /dev/null +++ b/cpukit/sapi/include/rtems/README @@ -0,0 +1,133 @@ +# +# $Id$ +# + +Configuring a System Using the Template in confdefs.h +===================================================== + +The file confdefs.h is a Configuration Template file which can be +used to greatly simplify the creation and maintenance of RTEMS +Configuration Tables. The basic concepts are: + + + confdefs.h provides defaults for all configuration parameters + + + applications specify only those values they wish to override + + + confdefs.h can be the only file which knows the precise layout + of the RTEMS Configuration Tables. + +The Configuration Template setup is used by all RTEMS tests to +simplify the maintenance of the tests. + +Here is the section from the system.h file from test tm21 from +the Timing Test Suite: + + /* configuration information */ + + #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER + #define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER + + #define CONFIGURE_MAXIMUM_TASKS 102 + #define CONFIGURE_MAXIMUM_TIMERS 100 + #define CONFIGURE_MAXIMUM_SEMAPHORES 100 + #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 100 + #define CONFIGURE_MAXIMUM_PARTITIONS 100 + #define CONFIGURE_MAXIMUM_REGIONS 100 + #define CONFIGURE_MAXIMUM_PORTS 100 + #define CONFIGURE_MAXIMUM_PERIODS 100 + + #define CONFIGURE_TICKS_PER_TIMESLICE 0 + + #include <confdefs.h> + + +The above example overrides a number of the configuration parameters. +It informs the template that it is a member of the Timing Suite, +requires a console and timer driver, and that it needs 102 tasks, +100 timers, 100 semaphores, 100 message queues, 100 partitions, +100 regions, 100 ports, and 100 periods. By default, the test +would have gotten no drivers, 10 tasks, and no other RTEMS objects. + +The following shows the configuration tables generated by the +template by default. + + +#include <bsp.h> + +#define NULL_DRIVER_TABLE_ENTRY \ + { NULL, NULL, NULL, NULL, NULL, NULL } + +rtems_driver_address_table Device_drivers[] = { +#ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER + CONSOLE_DRIVER_TABLE_ENTRY, +#endif +#ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + CLOCK_DRIVER_TABLE_ENTRY, +#endif +#ifdef CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER + STUB_DRIVER_TABLE_ENTRY, +#endif + NULL_DRIVER_TABLE_ENTRY, +}; + +rtems_initialization_tasks_table Initialization_tasks[] = { + { rtems_build_name( 'U', 'I', '1', ' ' ), /* init task name */ + RTEMS_MINIMUM_STACK_SIZE, /* init task stack size */ + 1, /* init task priority */ + RTEMS_DEFAULT_ATTRIBUTES, /* init task attributes */ + Init, /* init task entry point */ + RTEMS_NO_PREEMPT, /* init task initial mode */ + 0 /* init task argument list */ + } +}; + +#ifdef CONFIGURE_MP_APPLICATION +/* + * NODE_NUMBER is assumed to be set on the compile line. + */ + +rtems_multiprocessing_table Multiprocessing_configuration = { + NODE_NUMBER, /* local node number */ + 2, /* maximum # nodes in system */ + 32, /* maximum # global objects */ + 32, /* maximum # proxies */ + &MPCI_table /* pointer to MPCI config table */ +}; +#endif + +/* + * CONFIGURE_EXECUTIVE_RAM_SIZE is a rough guess based on the number of + * tasks in the system plus enough extra to get a whole 64K extra. + * + * The NULL address for the workspace area is assumed to be assigned + * at startup time by the BSP. + */ + +rtems_configuration_table Configuration = { + NULL, /* executive RAM work area */ + CONFIGURE_EXECUTIVE_RAM_SIZE, /* executive RAM size */ + 10, /* maximum # tasks */ + 0, /* maximum # timers */ + 0, /* maximum # semaphores */ + 0, /* maximum # message queues */ + 0, /* maximum # messages */ + 0, /* maximum # partitions */ + 0, /* maximum # regions */ + 0, /* maximum # dp memory areas */ + 0, /* maximum # periods */ + 0, /* maximum # user extensions */ + RTEMS_MILLISECONDS_TO_MICROSECONDS(10), /* # us in a tick */ + 50, /* # ticks in a timeslice */ + sizeof (Initialization_tasks) / sizeof(rtems_initialization_tasks_table), + /* number of init tasks */ + Initialization_tasks, /* init task(s) table */ + sizeof (Device_drivers) / sizeof(rtems_driver_address_table), + /* number of device drivers */ + Device_drivers, /* pointer to driver address table */ + NULL, /* pointer to initial extensions */ +#ifdef CONFIGURE_MP_APPLICATION + &Multiprocessing_configuration +#else + NULL /* ptr to MP config table */ +#endif +}; diff --git a/cpukit/sapi/include/rtems/chain.h b/cpukit/sapi/include/rtems/chain.h new file mode 100644 index 0000000000..a80bb9c1e2 --- /dev/null +++ b/cpukit/sapi/include/rtems/chain.h @@ -0,0 +1,140 @@ +/** + * @file + * + * @ingroup ClassicChains + * + * @brief Chain API. + */ + +/* + * Copyright (c) 2010 embedded brains GmbH. + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_CHAIN_H +#define _RTEMS_CHAIN_H + +#include <rtems/system.h> +#include <rtems/score/chain.h> +#include <rtems/rtems/event.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicChains Chains + * + * @ingroup ClassicRTEMS + * + * @brief Chain API. + * + * @{ + */ + +typedef Chain_Node rtems_chain_node; + +typedef Chain_Control rtems_chain_control; + +/** + * @brief Chain initializer for an empty chain with designator @a name. + */ +#define RTEMS_CHAIN_INITIALIZER_EMPTY(name) \ + CHAIN_INITIALIZER_EMPTY(name) + +/** + * @brief Chain definition for an empty chain with designator @a name. + */ +#define RTEMS_CHAIN_DEFINE_EMPTY(name) \ + CHAIN_DEFINE_EMPTY(name) + +/** @} */ + +#include <rtems/chain.inl> + +/** + * @addtogroup ClassicChains + * + * @{ + */ + +/** + * @brief Appends the @a node to the @a chain and sends the @a events to the + * @a task if the @a chain was empty before the append. + * + * @see rtems_chain_append_with_empty_check() and rtems_event_send(). + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ID No such task. + */ +rtems_status_code rtems_chain_append_with_notification( + rtems_chain_control *chain, + rtems_chain_node *node, + rtems_id task, + rtems_event_set events +); + +/** + * @brief Prepends the @a node to the @a chain and sends the @a events to the + * @a task if the @a chain was empty before the prepend. + * + * @see rtems_chain_prepend_with_empty_check() and rtems_event_send(). + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ID No such task. + */ +rtems_status_code rtems_chain_prepend_with_notification( + rtems_chain_control *chain, + rtems_chain_node *node, + rtems_id task, + rtems_event_set events +); + +/** + * @brief Gets the first @a node of the @a chain and sends the @a events to the + * @a task if the @a chain is empty after the get. + * + * @see rtems_chain_get_with_empty_check() and rtems_event_send(). + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ID No such task. + */ +rtems_status_code rtems_chain_get_with_notification( + rtems_chain_control *chain, + rtems_id task, + rtems_event_set events, + rtems_chain_node **node +); + +/** + * @brief Gets the first @a node of the @a chain and sends the @a events to the + * @a task if the @a chain is empty afterwards. + * + * @see rtems_chain_get() and rtems_event_receive(). + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_TIMEOUT Timeout. + */ +rtems_status_code rtems_chain_get_with_wait( + rtems_chain_control *chain, + rtems_event_set events, + rtems_interval timeout, + rtems_chain_node **node +); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/sapi/include/rtems/config.h b/cpukit/sapi/include/rtems/config.h new file mode 100644 index 0000000000..cdf33874d7 --- /dev/null +++ b/cpukit/sapi/include/rtems/config.h @@ -0,0 +1,273 @@ +/** + * @file rtems/config.h + */ + +/* + * This include file contains the table of user defined configuration + * parameters. + * + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_CONFIG_H +#define _RTEMS_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Unlimited object support. Changes the configuration table entry for POSIX + * or RTEMS APIs to bounded only by the memory of the work-space. + * + * Use the macro to define the resource unlimited before placing in + * the configuration table. + */ + +#include <rtems/score/object.h> +#define RTEMS_UNLIMITED_OBJECTS OBJECTS_UNLIMITED_OBJECTS + +#define rtems_resource_unlimited(resource) \ + ( resource | RTEMS_UNLIMITED_OBJECTS ) + +/* + * This is kind of kludgy but it allows targets to totally ignore the + * optional APIs like POSIX safely. + */ + +#ifdef RTEMS_POSIX_API +#include <rtems/posix/config.h> +#else +typedef void *posix_api_configuration_table; +#endif + +#include <rtems/rtems/config.h> + +#include <rtems/extension.h> +#include <rtems/io.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif + +#if defined(RTEMS_MULTIPROCESSING) +/* + * The following records define the Multiprocessor Configuration + * Table. This table defines the multiprocessor system + * characteristics which must be known by RTEMS in a multiprocessor + * system. + */ +typedef struct { + /** This is the local node number. */ + uint32_t node; + /** This is the maximum number of nodes in system. */ + uint32_t maximum_nodes; + /** This is the maximum number of global objects. */ + uint32_t maximum_global_objects; + /** This is the maximum number of proxies. */ + uint32_t maximum_proxies; + + /** The MPCI Receive server is assumed to have a stack of at least + * minimum stack size. This field specifies the amount of extra + * stack this task will be given in bytes. + */ + uint32_t extra_mpci_receive_server_stack; + + /** This is a pointer to User/BSP provided MPCI Table. */ + rtems_mpci_table *User_mpci_table; +} rtems_multiprocessing_table; +#endif + +/* + * The following records define the Configuration Table. The + * information contained in this table is required in all + * RTEMS systems, whether single or multiprocessor. This + * table primarily defines the following: + * + * + location and size of the RTEMS Workspace + * + microseconds per clock tick + * + clock ticks per task timeslice + * + required number of each object type for each API configured + */ +typedef struct { + /** This field specifies the base address of the RTEMS Workspace. + */ + void *work_space_start; + + /** This field specifies the size in bytes of the RTEMS Workspace. + */ + uintptr_t work_space_size; + + /** This field specifies the maximum number of dynamically installed + * used extensions. + */ + uint32_t maximum_extensions; + + /** This field specifies the number of microseconds which elapse + * between clock ticks. This is the basis for RTEMS timing. + */ + uint32_t microseconds_per_tick; + + /** This field specifies the number of ticks in each task's timeslice. + */ + uint32_t ticks_per_timeslice; + + /** This element points to the BSP's optional idle task which may override + * the default one provided with RTEMS. + */ + Thread (*idle_task)( uintptr_t ); + + /** This field specifies the size of the IDLE task's stack. If less than or + * equal to the minimum stack size, then the IDLE task will have the minimum + * stack size. + */ + uint32_t idle_task_stack_size; + + /** This field specifies the size of the interrupt stack. If less than or + * equal to the minimum stack size, then the interrupt stack will be of + * minimum stack size. + */ + uint32_t interrupt_stack_size; + + /** The BSP may want to provide it's own stack allocation routines. + * In this case, the BSP will provide this stack allocation hook. + */ + void * (*stack_allocate_hook)( size_t ); + + /** The BSP may want to provide it's own stack free routines. + * In this case, the BSP will provide this stack free hook. + */ + void (*stack_free_hook)( void *); + + /** If this element is TRUE, then RTEMS will zero the Executive Workspace. + * When this element is FALSE, it is assumed that the BSP or invoking + * environment has ensured that memory was cleared before RTEMS was + * invoked. + */ + bool do_zero_of_workspace; + + uint32_t maximum_drivers; + uint32_t number_of_device_drivers; + rtems_driver_address_table *Device_driver_table; + uint32_t number_of_initial_extensions; + rtems_extensions_table *User_extension_table; + #if defined(RTEMS_MULTIPROCESSING) + rtems_multiprocessing_table *User_multiprocessing_table; + #endif +} rtems_configuration_table; + +/** + * This is the configuration table generated by confdefs.h. + */ +extern rtems_configuration_table Configuration; + +#if defined(RTEMS_MULTIPROCESSING) + /** + * This points to the multiprocessing configuration table. + */ + SAPI_EXTERN rtems_multiprocessing_table *_Configuration_MP_table; +#endif + +#if defined(RTEMS_MULTIPROCESSING) + /** + * @brief RTEMS Multiprocessing Configuration Table + * + * This is the RTEMS Multiprocessing Configuration Table expected to + * be generated by confdefs.h. + */ + extern rtems_multiprocessing_table Multiprocessing_configuration; +#endif + + +/* + * Some handy macros to avoid dependencies on either the BSP + * or the exact format of the configuration table. + */ + +#define rtems_configuration_get_table() \ + (&Configuration) + +#define rtems_configuration_get_work_space_start() \ + (Configuration.work_space_start) + +#define rtems_configuration_get_work_space_size() \ + (Configuration.work_space_size) + +#define rtems_configuration_get_maximum_extensions() \ + (Configuration.maximum_extensions) + +#define rtems_configuration_get_microseconds_per_tick() \ + (Configuration.microseconds_per_tick) +#define rtems_configuration_get_milliseconds_per_tick() \ + (Configuration.microseconds_per_tick / 1000) +#define rtems_configuration_get_nanoseconds_per_tick() \ + (Configuration.microseconds_per_tick * 1000) + +#define rtems_configuration_get_ticks_per_timeslice() \ + (Configuration.ticks_per_timeslice) + +#define rtems_configuration_get_idle_task() \ + (Configuration.idle_task) + +#define rtems_configuration_get_idle_task_stack_size() \ + (Configuration.idle_task_stack_size) + +/* XXX We need to get this from the generated table + * since BSPs need it before the pointer is set. + * Eventually all should be done this way. + */ +extern rtems_configuration_table Configuration; + +#define rtems_configuration_get_interrupt_stack_size() \ + (Configuration.interrupt_stack_size) + +#define rtems_configuration_get_stack_allocate_hook() \ + (Configuration.stack_allocate_hook) + +#define rtems_configuration_get_stack_free_hook() \ + (Configuration.stack_free_hook) + +/** + * This macro assists in accessing the field which indicates whether + * RTEMS is responsible for zeroing the Executive Workspace. + */ +#define rtems_configuration_get_do_zero_of_workspace() \ + (Configuration.do_zero_of_workspace) + +#define rtems_configuration_get_number_of_device_drivers() \ + (Configuration.number_of_device_drivers) + +#define rtems_configuration_get_device_driver_table() \ + (Configuration.Device_driver_table) + +#define rtems_configuration_get_number_of_initial_extensions() \ + (Configuration.number_of_initial_extensions) + +#define rtems_configuration_get_user_extension_table() \ + (Configuration.User_extension_table) + +#if defined(RTEMS_MULTIPROCESSING) + #define rtems_configuration_get_user_multiprocessing_table() \ + (Configuration.User_multiprocessing_table) +#else + #define rtems_configuration_get_user_multiprocessing_table() NULL +#endif + +#define rtems_configuration_get_rtems_api_configuration() \ + (&Configuration_RTEMS_API) + +#define rtems_configuration_get_posix_api_configuration() \ + (&Configuration_POSIX_API) + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/sapi/include/rtems/extension.h b/cpukit/sapi/include/rtems/extension.h new file mode 100644 index 0000000000..4a7e258818 --- /dev/null +++ b/cpukit/sapi/include/rtems/extension.h @@ -0,0 +1,259 @@ +/** + * @file + * + * @ingroup ClassicUserExtensions + * + * @brief User Extensions API. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_EXTENSION_H +#define _RTEMS_EXTENSION_H + +#ifndef SAPI_EXT_EXTERN +#define SAPI_EXT_EXTERN extern +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/score/object.h> +#include <rtems/score/userext.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/types.h> + +SAPI_EXT_EXTERN Objects_Information _Extension_Information; + +typedef struct { + Objects_Control Object; + User_extensions_Control Extension; +} Extension_Control; + +void _Extension_Manager_initialization(void); + +typedef User_extensions_routine + rtems_extension RTEMS_COMPILER_DEPRECATED_ATTRIBUTE; + +/** + * @defgroup ClassicUserExtensions User Extensions + * + * @ingroup ClassicRTEMS + * + * @brief The User Extensions Manager allows the application developer to + * augment the executive by allowing them to supply extension routines which + * are invoked at critical system events. + * + * @section ClassicUserExtensionsSets Extension Sets + * + * An @ref User_extensions_Table "extension set" is defined as a set of + * routines which are invoked at each of the critical system events at which + * user extension routines are invoked. Together a set of these routines + * typically perform a specific functionality such as performance monitoring or + * debugger support. + * + * RTEMS allows the user to have multiple extension sets active at the same + * time. First, a single static extension set may be defined as the + * application's User Extension Table which is included as part of the + * Configuration Table. This extension set is active for the entire life of the + * system and may not be deleted. This extension set is especially important + * because it is the only way the application can provided a fatal error + * extension which is invoked if RTEMS fails during the + * rtems_initialize_data_structures() directive. The static extension set is + * optional and may be configured as @c NULL if no static extension set is + * required. + * + * Second, the user can install dynamic extensions using the + * rtems_extension_create() directive. These extensions are RTEMS objects in + * that they have a name, an ID, and can be dynamically created and deleted. In + * contrast to the static extension set, these extensions can only be created + * and installed after the rtems_initialize_data_structures() directive + * successfully completes execution. Dynamic extensions are useful for + * encapsulating the functionality of an extension set. For example, the + * application could use extensions to manage a special coprocessor, do + * performance monitoring, and to do stack bounds checking. Each of these + * extension sets could be written and installed independently of the others. + * + * All user extensions are optional and RTEMS places no naming restrictions on + * the user. The user extension entry points are copied into an internal RTEMS + * structure. This means the user does not need to keep the table after + * creating it, and changing the handler entry points dynamically in a table + * once created has no effect. Creating a table local to a function can save + * space in space limited applications. + * + * Extension switches do not effect the context switch overhead if no switch + * handler is installed. + * + * @section ClassicUserExtensionsTCB Task Control Block Area + * + * RTEMS provides for a pointer to a user-defined data area for each extension + * set to be linked to each task's control block (TCB). This area is only + * available for the dynamic extensions. This set of pointers is an extension + * of the TCB and can be used to store additional data required by the user's + * extension functions. It is also possible for a user extension to utilize the + * notepad locations associated with each task although this may conflict with + * application usage of those particular notepads. + * + * The TCB extension is an array of pointers in the TCB. The index into the + * table can be obtained from the extension identifier returned when the + * extension is created: + * + * @code + * rtems_tcb *task = some_task; + * size_t index = rtems_object_id_get_index(extension_id); + * void *extension_data = task->extensions [index]; + * @endcode + * + * The number of pointers in the area is the same as the number of user + * extension sets configured. This allows an application to augment the TCB + * with user-defined information. For example, an application could implement + * task profiling by storing timing statistics in the TCB's extended memory + * area. When a task context switch is being executed, the task switch + * extension could read a real-time clock to calculate how long the task being + * swapped out has run as well as timestamp the starting time for the task + * being swapped in. + * + * If used, the extended memory area for the TCB should be allocated and the + * TCB extension pointer should be set at the time the task is created or + * started by either the task create or task start extension. The application + * is responsible for managing this extended memory area for the TCBs. The + * memory may be reinitialized by the task restart extension and should be + * deallocated by the task delete extension when the task is deleted. Since the + * TCB extension buffers would most likely be of a fixed size, the RTEMS + * partition manager could be used to manage the application's extended memory + * area. The application could create a partition of fixed size TCB extension + * buffers and use the partition manager's allocation and deallocation + * directives to obtain and release the extension buffers. + * + * @section ClassicUserExtensionsOrder Order of Invokation + * + * When one of the critical system events occur, the user extensions are + * invoked in either @a forward or @a reverse order. Forward order indicates + * that the static extension set is invoked followed by the dynamic extension + * sets in the order in which they were created. Reverse order means that the + * dynamic extension sets are invoked in the opposite of the order in which + * they were created followed by the static extension set. By invoking the + * extension sets in this order, extensions can be built upon one another. At + * the following system events, the extensions are invoked in forward order: + * + * - Task creation + * - Task start + * - Task restart + * - Task context switch + * - Post task context switch + * - Task begins to execute + * + * At the following system events, the extensions are invoked in reverse order: + * + * - Task exit + * - Task deletion + * - Fatal error detection + * + * At these system events, the extensions are invoked in reverse order to + * insure that if an extension set is built upon another, the more complicated + * extension is invoked before the extension set it is built upon. For example, + * by invoking the static extension set last it is known that the "system" + * fatal error extension will be the last fatal error extension executed. + * Another example is use of the task delete extension by the Standard C + * Library. Extension sets which are installed after the Standard C Library + * will operate correctly even if they utilize the C Library because the C + * Library's task delete extension is invoked after that of the other + * extensions. + * + * @{ + */ + +typedef User_extensions_thread_create_extension rtems_task_create_extension; +typedef User_extensions_thread_delete_extension rtems_task_delete_extension; +typedef User_extensions_thread_start_extension rtems_task_start_extension; +typedef User_extensions_thread_restart_extension rtems_task_restart_extension; +typedef User_extensions_thread_switch_extension rtems_task_switch_extension; +typedef User_extensions_thread_begin_extension rtems_task_begin_extension; +typedef User_extensions_thread_exitted_extension rtems_task_exitted_extension; +typedef User_extensions_fatal_extension rtems_fatal_extension; + +typedef User_extensions_Table rtems_extensions_table; + +/** + * @brief Creates an extension set object. + * + * This directive creates a extension set object from the extension table + * @a extension_table. The assigned extension set identifier is returned in + * @a id. The identifier is used to access this extension set in other + * extension set related directives. The name @a name will be assigned to the + * extension set object. + * + * Newly created extension sets are immediately installed and are invoked upon + * the next system event supporting an extension. + * + * This directive will not cause the calling task to be preempted. + * + * @retval RTEMS_SUCCESSFUL Extension set created successfully. + * @retval RTEMS_INVALID_ADDRESS Identifier pointer is @c NULL. + * @retval RTEMS_INVALID_NAME Invalid extension set name. + * @retval RTEMS_TOO_MANY Too many extension sets created. + */ +rtems_status_code rtems_extension_create( + rtems_name name, + const rtems_extensions_table *extension_table, + rtems_id *id +); + +/** + * @brief Identifies an extension set object by a name. + * + * This directive obtains an extension set identifier in @a id associated with + * the extension set name @a name. If the extension set name is not unique, + * then the extension set identifier will match one of the extension sets with + * that name. However, this extension set identifier is not guaranteed to + * correspond to the desired extension set. The extension set identifier is + * used to access this extension set in other extension set related directives. + * + * This directive will not cause the calling task to be preempted. + * + * @retval RTEMS_SUCCESSFUL Extension set identified successfully. + * @retval RTEMS_INVALID_ADDRESS Identifier pointer is @c NULL. + * @retval RTEMS_INVALID_NAME Extension set name not found or invalid name. + */ +rtems_status_code rtems_extension_ident( + rtems_name name, + rtems_id *id +); + +/** + * @brief Deletes an extension set object specified by the identifier @a id. + * + * Any subsequent references to the extension's name and identifier are + * invalid. + * + * This directive will not cause the calling task to be preempted. + * + * @retval RTEMS_SUCCESSFUL Extension set deleted successfully. + * @retval RTEMS_INVALID_ID Invalid extension set identifier. + */ +rtems_status_code rtems_extension_delete( + rtems_id id +); + +/** @} */ + +#ifndef __RTEMS_APPLICATION__ +#include <rtems/extension.inl> +#endif + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/sapi/include/rtems/fatal.h b/cpukit/sapi/include/rtems/fatal.h new file mode 100644 index 0000000000..63942aad97 --- /dev/null +++ b/cpukit/sapi/include/rtems/fatal.h @@ -0,0 +1,53 @@ +/** + * @file rtems/fatal.h + */ + +/* + * This include file contains constants and prototypes related + * to the Fatal Error Manager. This manager processes all fatal or + * irrecoverable errors. + * + * This manager provides directives to: + * + * + announce a fatal error has occurred + * + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_FATAL_H +#define _RTEMS_FATAL_H + +#include <rtems/score/basedefs.h> /* RTEMS_COMPILER_NO_RETURN_ATTRIBUTE */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * rtems_fatal_error_occurred + * + * DESCRIPTION: + * + * This is the routine which implements the rtems_fatal_error_occurred + * directive. It is invoked when the application or RTEMS + * determines that a fatal error has occurred. + */ + +void rtems_fatal_error_occurred( + uint32_t the_error +) RTEMS_COMPILER_NO_RETURN_ATTRIBUTE; + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/sapi/include/rtems/init.h b/cpukit/sapi/include/rtems/init.h new file mode 100644 index 0000000000..8cc7aa5c31 --- /dev/null +++ b/cpukit/sapi/include/rtems/init.h @@ -0,0 +1,100 @@ +/** + * @file rtems/init.h + * + * + * This include file contains all the constants and structures associated + * with the Initialization Manager. This manager is responsible for + * initializing RTEMS, creating and starting all configured initialization + * tasks, invoking the initialization routine for each user-supplied device + * driver, and initializing the optional multiprocessor layer. + * + * This manager provides directives to: + * + * + initialize the RTEMS executive + * + shutdown the RTEMS executive + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_INIT_H +#define _RTEMS_INIT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/rtems/types.h> +#include <rtems/config.h> +#include <rtems/rtems/intr.h> + +#if defined(RTEMS_MULTIPROCESSING) +/** + * The following defines the default Multiprocessing Configuration + * Table. This table is used in a single processor system. + */ +extern const rtems_multiprocessing_table + _Initialization_Default_multiprocessing_table; +#endif + +/** + * @brief rtems_initialize_data_structures + * + * This routine implements the portion of the RTEMS initializatin process + * that involves initializing data structures to a state that scheduling + * can occur in a consistent manner. + */ +void rtems_initialize_data_structures(void); + +/** + * @brief rtems_initialize_before_drivers + * + * This routine implements the portion of RTEMS initialization that + * is done immediately before device drivers are initialized. + */ +void rtems_initialize_before_drivers(void); + +/** + * @brief rtems_initialize_device_drivers + * + * This routine implements the portion of RTEMS initialization that + * initializes all device drivers. + */ +void rtems_initialize_device_drivers(void); + +/** + * @brief rtems_initialize_start_multitasking + * + * This routine implements the early portion of rtems_initialize_executive + * directive up to the pretasking hook. This directive is invoked at system + * startup to initialize the RTEMS multitasking environment. + */ +void rtems_initialize_start_multitasking(void); + +/** + * @brief rtems_shutdown_executive + * + * This routine implements the rtems_shutdown_executive directive. The + * invocation of this directive results in the RTEMS environment being + * shutdown and multitasking halted. From the application's perspective, + * invocation of this directive results in the rtems_initialize_executive + * directive exitting to the startup code which invoked it. + */ +void rtems_shutdown_executive( + uint32_t result +) RTEMS_COMPILER_NO_RETURN_ATTRIBUTE; + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/sapi/include/rtems/io.h b/cpukit/sapi/include/rtems/io.h new file mode 100644 index 0000000000..e47d66556d --- /dev/null +++ b/cpukit/sapi/include/rtems/io.h @@ -0,0 +1,204 @@ +/** + * @file + * + * @ingroup ClassicIO + * + * @brief Classic Input/Output Manager API. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_IO_H +#define _RTEMS_IO_H + +#ifndef SAPI_IO_EXTERN +#define SAPI_IO_EXTERN extern +#endif + +#include <rtems/rtems/status.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicIO Input/Output + * + * @ingroup ClassicRTEMS + * + * @{ + */ + +typedef uint32_t rtems_device_major_number; + +typedef uint32_t rtems_device_minor_number; + +typedef rtems_status_code rtems_device_driver; + +typedef rtems_device_driver (*rtems_device_driver_entry)( + rtems_device_major_number, + rtems_device_minor_number, + void * +); + +typedef struct { + rtems_device_driver_entry initialization_entry; + rtems_device_driver_entry open_entry; + rtems_device_driver_entry close_entry; + rtems_device_driver_entry read_entry; + rtems_device_driver_entry write_entry; + rtems_device_driver_entry control_entry; +} rtems_driver_address_table; + +/** + * @name Device Driver Maintainance + * + * @{ + */ + +/** + * @brief Returns @c RTEMS_IO_ERROR. + * + * @retval RTEMS_IO_ERROR Only this one. + */ +rtems_status_code rtems_io_driver_io_error( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +); + +/** + * @brief Registers and initializes the device with the device driver table + * @a driver_table and major number @a major. + * + * If the major number equals zero a major number will be obtained. The major + * number of the registered driver will be returned in @a registered_major. + * + * After a successful registration rtems_io_initialize() will be called to + * initialize the device. + * + * @retval RTEMS_SUCCESSFUL Device successfully registered and initialized. + * @retval RTEMS_INVALID_ADDRESS Pointer to driver table or to registered + * major number are invalid. Device driver table is empty. + * @retval RTEMS_INVALID_NUMBER Invalid major number. + * @retval RTEMS_TOO_MANY No major number available. + * @retval RTEMS_RESOURCE_IN_USE Major number in use. + * @retval RTEMS_CALLED_FROM_ISR Called from interrupt context. + * @retval * Status code depends on rtems_io_initialize(). + */ +rtems_status_code rtems_io_register_driver( + rtems_device_major_number major, + const rtems_driver_address_table *driver_table, + rtems_device_major_number *registered_major +); + +/** + * @brief Unregisters the device driver with number @a major. + * + * @retval RTEMS_SUCCESSFUL Device driver successfully unregistered. + * @retval RTEMS_UNSATISFIED Invalid major number. + * @retval RTEMS_CALLED_FROM_ISR Called from interrupt context. + */ +rtems_status_code rtems_io_unregister_driver( + rtems_device_major_number major +); + +/** + * @brief Registers the name @a device_name in the file system for the device + * with number tuple @a major and @a minor. + * + * @retval RTEMS_SUCCESSFUL Name successfully registered. + * @retval RTEMS_TOO_MANY Name already in use or other errors. + */ +rtems_status_code rtems_io_register_name( + const char *device_name, + rtems_device_major_number major, + rtems_device_minor_number minor +); + +/** @} */ + +/** + * @name Device Driver Invocation + * + * @{ + */ + +rtems_status_code rtems_io_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument +); + +rtems_status_code rtems_io_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument +); + +rtems_status_code rtems_io_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument +); + +rtems_status_code rtems_io_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument +); + +rtems_status_code rtems_io_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument +); + +rtems_status_code rtems_io_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument +); + +/** @} */ + +/** @} */ + +typedef struct { + char *device_name; + size_t device_name_length; + rtems_device_major_number major; + rtems_device_minor_number minor; +} rtems_driver_name_t; + +/** + * @deprecated Use stat() instead. + */ +rtems_status_code rtems_io_lookup_name( + const char *name, + rtems_driver_name_t *device_info +) RTEMS_COMPILER_DEPRECATED_ATTRIBUTE; + +SAPI_IO_EXTERN uint32_t _IO_Number_of_drivers; + +SAPI_IO_EXTERN rtems_driver_address_table *_IO_Driver_address_table; + +void _IO_Manager_initialization( void ); + +void _IO_Initialize_all_drivers( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/sapi/include/rtems/mptables.h b/cpukit/sapi/include/rtems/mptables.h new file mode 100644 index 0000000000..bcb51c5e96 --- /dev/null +++ b/cpukit/sapi/include/rtems/mptables.h @@ -0,0 +1,28 @@ +/* mptables.h + * + * This include file contains the executive's pre-initialized tables + * used in a multiprocessor configuration. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_MPTABLES_H +#define _RTEMS_MPTABLES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/sapi/include/rtems/sptables.h b/cpukit/sapi/include/rtems/sptables.h new file mode 100644 index 0000000000..e4fbd226bf --- /dev/null +++ b/cpukit/sapi/include/rtems/sptables.h @@ -0,0 +1,75 @@ +/** + * @file rtems/sptables.h + * + * This include file contains the executive's pre-initialized tables + * used when in a single processor configuration. + */ + +/* + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SPTABLES_H +#define _RTEMS_SPTABLES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/config.h> + +#include <rtems/debug.h> +#include <rtems/fatal.h> +#include <rtems/init.h> +#include <rtems/io.h> +#include <rtems/score/sysstate.h> + +#include <rtems/rtems/intr.h> +#include <rtems/rtems/clock.h> +#include <rtems/rtems/tasks.h> +#include <rtems/rtems/dpmem.h> +#include <rtems/rtems/event.h> +#include <rtems/rtems/message.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/rtems/mp.h> +#endif +#include <rtems/rtems/part.h> +#include <rtems/rtems/ratemon.h> +#include <rtems/rtems/region.h> +#include <rtems/rtems/sem.h> +#include <rtems/rtems/signal.h> +#include <rtems/rtems/timer.h> + +#if defined(RTEMS_MULTIPROCESSING) +/* + * This is the default Multiprocessing Configuration Table. + * It is used in single processor configurations. + */ + #if defined(SAPI_INIT) + const rtems_multiprocessing_table + _Initialization_Default_multiprocessing_table = { + 1, /* local node number */ + 1, /* maximum number nodes in system */ + 0, /* maximum number global objects */ + 0, /* maximum number proxies */ + STACK_MINIMUM_SIZE, /* MPCI receive server stack size */ + NULL, /* pointer to MPCI address table */ + }; + #else + extern const rtems_multiprocessing_table + _Initialization_Default_multiprocessing_table; + #endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/sapi/inline/rtems/chain.inl b/cpukit/sapi/inline/rtems/chain.inl new file mode 100644 index 0000000000..2816e81b41 --- /dev/null +++ b/cpukit/sapi/inline/rtems/chain.inl @@ -0,0 +1,561 @@ +/** + * @file + * + * @ingroup ClassicChains + * + * @brief Chain API. + */ + +/* + * Copyright (c) 2010 embedded brains GmbH. + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_CHAIN_H +# error "Never use <rtems/chain.inl> directly; include <rtems/chain.h> instead." +#endif + +#ifndef _RTEMS_CHAIN_INL +#define _RTEMS_CHAIN_INL + +#include <rtems/score/chain.inl> + +/** + * @addtogroup ClassicChains + * + * @{ + */ + +/** + * @brief Initialize a Chain Header + * + * This routine initializes @a the_chain structure to manage the + * contiguous array of @a number_nodes nodes which starts at + * @a starting_address. Each node is of @a node_size bytes. + * + * @param[in] the_chain specifies the chain to initialize + * @param[in] starting_address is the starting address of the array + * of elements + * @param[in] number_nodes is the number of nodes that will be in the chain + * @param[in] node_size is the size of each node + */ +RTEMS_INLINE_ROUTINE void rtems_chain_initialize( + rtems_chain_control *the_chain, + void *starting_address, + size_t number_nodes, + size_t node_size +) +{ + _Chain_Initialize( the_chain, starting_address, number_nodes, node_size ); +} + +/** + * @brief Initialize this Chain as Empty + * + * This routine initializes the specified chain to contain zero nodes. + * + * @param[in] the_chain is the chain to be initialized. + */ +RTEMS_INLINE_ROUTINE void rtems_chain_initialize_empty( + rtems_chain_control *the_chain +) +{ + _Chain_Initialize_empty( the_chain ); +} + +/** + * @brief Set off chain + * + * This function sets the next and previous fields of the @a node to NULL + * indicating the @a node is not part of a chain. + * + * @param[in] node the node set to off chain. + */ +RTEMS_INLINE_ROUTINE void rtems_chain_set_off_chain( + rtems_chain_node *node +) +{ + _Chain_Set_off_chain( node ); +} + +/** + * @brief Is the Node off Chain + * + * This function returns true if the @a node is not on a chain. A @a node is + * off chain if the next and previous fields are set to NULL. + * + * @param[in] node is the node off chain. + * + * @return This function returns true if the @a node is off chain. + */ +RTEMS_INLINE_ROUTINE bool rtems_chain_is_node_off_chain( + const rtems_chain_node *node +) +{ + return _Chain_Is_node_off_chain( node ); +} + +/** + * @brief Is the Chain Node Pointer NULL + * + * This function returns true if the_node is NULL and false otherwise. + * + * @param[in] the_node is the node pointer to check. + * + * @return This method returns true if the_node is NULL and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool rtems_chain_is_null_node( + const rtems_chain_node *the_node +) +{ + return _Chain_Is_null_node( the_node ); +} + +/** + * @brief Return pointer to Chain Head + * + * This function returns a pointer to the first node on the chain. + * + * @param[in] the_chain is the chain to be operated upon. + * + * @return This method returns the permanent node of the chain. + */ +RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_head( + rtems_chain_control *the_chain +) +{ + return _Chain_Head( the_chain ); +} + +/** + * @brief Return pointer to Chain Tail + * + * This function returns a pointer to the last node on the chain. + * + * @param[in] the_chain is the chain to be operated upon. + * + * @return This method returns the permanent tail node of the chain. + */ +RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_tail( + rtems_chain_control *the_chain +) +{ + return _Chain_Tail( the_chain ); +} + +/** + * @brief Return pointer to Chain's First node after the permanent head. + * + * This function returns a pointer to the first node on the chain after the + * head. + * + * @param[in] the_chain is the chain to be operated upon. + * + * @return This method returns the first node of the chain. + */ +RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_first( + rtems_chain_control *the_chain +) +{ + return _Chain_First( the_chain ); +} + +/** + * @brief Return pointer to Chain's Last node before the permanent tail. + * + * This function returns a pointer to the last node on the chain just before + * the tail. + * + * @param[in] the_chain is the chain to be operated upon. + * + * @return This method returns the last node of the chain. + */ +RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_last( + rtems_chain_control *the_chain +) +{ + return _Chain_Last( the_chain ); +} + +/** + * @brief Return pointer the next node from this node + * + * This function returns a pointer to the next node after this node. + * + * @param[in] the_node is the node to be operated upon. + * + * @return This method returns the next node on the chain. + */ +RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_next( + rtems_chain_node *the_node +) +{ + return _Chain_Next( the_node ); +} + +/** + * @brief Return pointer the previous node from this node + * + * This function returns a pointer to the previous node on this chain. + * + * @param[in] the_node is the node to be operated upon. + * + * @return This method returns the previous node on the chain. + */ +RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_previous( + rtems_chain_node *the_node +) +{ + return _Chain_Previous( the_node ); +} + +/** + * @brief Are Two Nodes Equal + * + * This function returns true if @a left and @a right are equal, + * and false otherwise. + * + * @param[in] left is the node on the left hand side of the comparison. + * @param[in] right is the node on the left hand side of the comparison. + * + * @return This function returns true if @a left and @a right are equal, + * and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool rtems_chain_are_nodes_equal( + const rtems_chain_node *left, + const rtems_chain_node *right +) +{ + return _Chain_Are_nodes_equal( left, right ); +} + +/** + * @brief Is the Chain Empty + * + * This function returns true if there a no nodes on @a the_chain and + * false otherwise. + * + * @param[in] the_chain is the chain to be operated upon. + * + * @return This function returns true if there a no nodes on @a the_chain and + * false otherwise. + */ +RTEMS_INLINE_ROUTINE bool rtems_chain_is_empty( + rtems_chain_control *the_chain +) +{ + return _Chain_Is_empty( the_chain ); +} + +/** + * @brief Is this the First Node on the Chain + * + * This function returns true if the_node is the first node on a chain and + * false otherwise. + * + * @param[in] the_node is the node the caller wants to know if it is + * the first node on a chain. + * + * @return This function returns true if @a the_node is the first node on + * a chain and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool rtems_chain_is_first( + const rtems_chain_node *the_node +) +{ + return _Chain_Is_first( the_node ); +} + +/** + * @brief Is this the Last Node on the Chain + * + * This function returns true if @a the_node is the last node on a chain and + * false otherwise. + * + * @param[in] the_node is the node to check as the last node. + * + * @return This function returns true if @a the_node is the last node on + * a chain and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool rtems_chain_is_last( + const rtems_chain_node *the_node +) +{ + return _Chain_Is_last( the_node ); +} + +/** + * @brief Does this Chain have only One Node + * + * This function returns true if there is only one node on @a the_chain and + * false otherwise. + * + * @param[in] the_chain is the chain to be operated upon. + * + * @return This function returns true if there is only one node on + * @a the_chain and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool rtems_chain_has_only_one_node( + const rtems_chain_control *the_chain +) +{ + return _Chain_Has_only_one_node( the_chain ); +} + +/** + * @brief Is this Node the Chain Head + * + * This function returns true if @a the_node is the head of the_chain and + * false otherwise. + * + * @param[in] the_chain is the chain to be operated upon. + * @param[in] the_node is the node to check for being the Chain Head. + * + * @return This function returns true if @a the_node is the head of + * @a the_chain and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool rtems_chain_is_head( + rtems_chain_control *the_chain, + const rtems_chain_node *the_node +) +{ + return _Chain_Is_head( the_chain, the_node ); +} + +/** + * @brief Is this Node the Chail Tail + * + * This function returns true if the_node is the tail of the_chain and + * false otherwise. + * + * @param[in] the_chain is the chain to be operated upon. + * @param[in] the_node is the node to check for being the Chain Tail. + */ +RTEMS_INLINE_ROUTINE bool rtems_chain_is_tail( + rtems_chain_control *the_chain, + const rtems_chain_node *the_node +) +{ + return _Chain_Is_tail( the_chain, the_node ); +} + +/** + * @brief Extract the specified node from a chain + * + * This routine extracts @a the_node from the chain on which it resides. + * It disables interrupts to ensure the atomicity of the + * extract operation. + * + * @arg the_node specifies the node to extract + */ +RTEMS_INLINE_ROUTINE void rtems_chain_extract( + rtems_chain_node *the_node +) +{ + _Chain_Extract( the_node ); +} + +/** + * @brief Extract the specified node from a chain (unprotected). + * + * This routine extracts @a the_node from the chain on which it resides. + * + * @note It does NOT disable interrupts to ensure the atomicity of the + * append operation. + */ +RTEMS_INLINE_ROUTINE void rtems_chain_extract_unprotected( + rtems_chain_node *the_node +) +{ + _Chain_Extract_unprotected( the_node ); +} + +/** + * @brief Obtain the first node on a chain + * + * This function removes the first node from @a the_chain and returns + * a pointer to that node. If @a the_chain is empty, then NULL is returned. + * + * @return This method returns a pointer a node. If a node was removed, + * then a pointer to that node is returned. If @a the_chain was + * empty, then NULL is returned. + * + * @note It disables interrupts to ensure the atomicity of the get operation. + */ +RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_get( + rtems_chain_control *the_chain +) +{ + return _Chain_Get( the_chain ); +} + +/** + * @brief See _Chain_Get_unprotected(). + */ +RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_get_unprotected( + rtems_chain_control *the_chain +) +{ + return _Chain_Get_unprotected( the_chain ); +} + +/** + * @brief Insert a node on a chain + * + * This routine inserts @a the_node on a chain immediately following + * @a after_node. + * + * @note It disables interrupts to ensure the atomicity + * of the extract operation. + */ +RTEMS_INLINE_ROUTINE void rtems_chain_insert( + rtems_chain_node *after_node, + rtems_chain_node *the_node +) +{ + _Chain_Insert( after_node, the_node ); +} + +/** + * @brief See _Chain_Insert_unprotected(). + */ +RTEMS_INLINE_ROUTINE void rtems_chain_insert_unprotected( + rtems_chain_node *after_node, + rtems_chain_node *the_node +) +{ + _Chain_Insert_unprotected( after_node, the_node ); +} + +/** + * @brief Append a node on the end of a chain + * + * This routine appends @a the_node onto the end of @a the_chain. + * + * @note It disables interrupts to ensure the atomicity of the + * append operation. + */ +RTEMS_INLINE_ROUTINE void rtems_chain_append( + rtems_chain_control *the_chain, + rtems_chain_node *the_node +) +{ + _Chain_Append( the_chain, the_node ); +} + +/** + * @brief Append a node on the end of a chain (unprotected) + * + * This routine appends @a the_node onto the end of @a the_chain. + * + * @note It does NOT disable interrupts to ensure the atomicity of the + * append operation. + */ +RTEMS_INLINE_ROUTINE void rtems_chain_append_unprotected( + rtems_chain_control *the_chain, + rtems_chain_node *the_node +) +{ + _Chain_Append_unprotected( the_chain, the_node ); +} + +/** @brief Prepend a Node + * + * This routine prepends the_node onto the front of the_chain. + * + * @param[in] the_chain is the chain to be operated upon. + * @param[in] the_node is the node to be prepended. + * + * @note It disables interrupts to ensure the atomicity of the + * prepend operation. + */ +RTEMS_INLINE_ROUTINE void rtems_chain_prepend( + rtems_chain_control *the_chain, + rtems_chain_node *the_node +) +{ + _Chain_Prepend( the_chain, the_node ); +} + +/** @brief Prepend a Node (unprotected) + * + * This routine prepends the_node onto the front of the_chain. + * + * @param[in] the_chain is the chain to be operated upon. + * @param[in] the_node is the node to be prepended. + * + * @note It does NOT disable interrupts to ensure the atomicity of the + * prepend operation. + */ +RTEMS_INLINE_ROUTINE void rtems_chain_prepend_unprotected( + rtems_chain_control *the_chain, + rtems_chain_node *the_node +) +{ + _Chain_Prepend_unprotected( the_chain, the_node ); +} + +/** + * @brief Checks if the @a chain is empty and appends the @a node. + * + * Interrupts are disabled to ensure the atomicity of the operation. + * + * @retval true The chain was empty before the append. + * @retval false The chain contained at least one node before the append. + */ +RTEMS_INLINE_ROUTINE bool rtems_chain_append_with_empty_check( + rtems_chain_control *chain, + rtems_chain_node *node +) +{ + return _Chain_Append_with_empty_check( chain, node ); +} + +/** + * @brief Checks if the @a chain is empty and prepends the @a node. + * + * Interrupts are disabled to ensure the atomicity of the operation. + * + * @retval true The chain was empty before the prepend. + * @retval false The chain contained at least one node before the prepend. + */ +RTEMS_INLINE_ROUTINE bool rtems_chain_prepend_with_empty_check( + rtems_chain_control *chain, + rtems_chain_node *node +) +{ + return _Chain_Prepend_with_empty_check( chain, node ); +} + +/** + * @brief Tries to get the first @a node and check if the @a chain is empty + * afterwards. + * + * This function removes the first node from the @a chain and returns a pointer + * to that node in @a node. If the @a chain is empty, then @c NULL is returned. + * + * Interrupts are disabled to ensure the atomicity of the operation. + * + * @retval true The chain is empty after the node removal. + * @retval false The chain contained at least one node after the node removal. + */ +RTEMS_INLINE_ROUTINE bool rtems_chain_get_with_empty_check( + rtems_chain_control *chain, + rtems_chain_node **node +) +{ + return _Chain_Get_with_empty_check( chain, node ); +} + +/** @} */ + +#endif +/* end of include file */ diff --git a/cpukit/sapi/inline/rtems/extension.inl b/cpukit/sapi/inline/rtems/extension.inl new file mode 100644 index 0000000000..36005b7d7f --- /dev/null +++ b/cpukit/sapi/inline/rtems/extension.inl @@ -0,0 +1,52 @@ +/** + * @file + * + * @ingroup ClassicUserExtensions + * + * @brief User Extensions API. + */ + +/* + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef __EXTENSION_MANAGER_inl +#define __EXTENSION_MANAGER_inl + +RTEMS_INLINE_ROUTINE Extension_Control *_Extension_Allocate( void ) +{ + return (Extension_Control *) _Objects_Allocate( &_Extension_Information ); +} + +RTEMS_INLINE_ROUTINE void _Extension_Free ( + Extension_Control *the_extension +) +{ + _Objects_Free( &_Extension_Information, &the_extension->Object ); +} + +RTEMS_INLINE_ROUTINE Extension_Control *_Extension_Get ( + Objects_Id id, + Objects_Locations *location +) +{ + return (Extension_Control *) + _Objects_Get( &_Extension_Information, id, location ); +} + +RTEMS_INLINE_ROUTINE bool _Extension_Is_null ( + Extension_Control *the_extension +) +{ + return ( the_extension == NULL ); +} + +#endif +/* end of include file */ diff --git a/cpukit/sapi/preinstall.am b/cpukit/sapi/preinstall.am new file mode 100644 index 0000000000..975828246c --- /dev/null +++ b/cpukit/sapi/preinstall.am @@ -0,0 +1,78 @@ +## Automatically generated by ampolish3 - Do not edit + +if AMPOLISH3 +$(srcdir)/preinstall.am: Makefile.am + $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am +endif + +PREINSTALL_DIRS = +DISTCLEANFILES = $(PREINSTALL_DIRS) + +all-local: $(TMPINSTALL_FILES) + +TMPINSTALL_FILES = +CLEANFILES = $(TMPINSTALL_FILES) + +all-am: $(PREINSTALL_FILES) + +PREINSTALL_FILES = +CLEANFILES += $(PREINSTALL_FILES) + +$(PROJECT_LIB)/$(dirstamp): + @$(MKDIR_P) $(PROJECT_LIB) + @: > $(PROJECT_LIB)/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp) + +$(PROJECT_INCLUDE)/rtems/$(dirstamp): + @$(MKDIR_P) $(PROJECT_INCLUDE)/rtems + @: > $(PROJECT_INCLUDE)/rtems/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/rtems/$(dirstamp) + +$(PROJECT_INCLUDE)/rtems/confdefs.h: include/confdefs.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/confdefs.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/confdefs.h + +$(PROJECT_INCLUDE)/rtems/chain.h: include/rtems/chain.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/chain.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/chain.h + +$(PROJECT_INCLUDE)/rtems/config.h: include/rtems/config.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/config.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/config.h + +$(PROJECT_INCLUDE)/rtems/extension.h: include/rtems/extension.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/extension.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/extension.h + +$(PROJECT_INCLUDE)/rtems/fatal.h: include/rtems/fatal.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/fatal.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/fatal.h + +$(PROJECT_INCLUDE)/rtems/init.h: include/rtems/init.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/init.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/init.h + +$(PROJECT_INCLUDE)/rtems/io.h: include/rtems/io.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/io.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/io.h + +$(PROJECT_INCLUDE)/rtems/mptables.h: include/rtems/mptables.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/mptables.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/mptables.h + +$(PROJECT_INCLUDE)/rtems/sptables.h: include/rtems/sptables.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/sptables.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/sptables.h + +$(PROJECT_INCLUDE)/rtems/chain.inl: inline/rtems/chain.inl $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/chain.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/chain.inl + +$(PROJECT_INCLUDE)/rtems/extension.inl: inline/rtems/extension.inl $(PROJECT_INCLUDE)/rtems/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/extension.inl +PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/extension.inl + +$(PROJECT_LIB)/libsapi.a: libsapi.a $(PROJECT_LIB)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_LIB)/libsapi.a +TMPINSTALL_FILES += $(PROJECT_LIB)/libsapi.a + diff --git a/cpukit/sapi/src/chainappendnotify.c b/cpukit/sapi/src/chainappendnotify.c new file mode 100644 index 0000000000..df89d74b48 --- /dev/null +++ b/cpukit/sapi/src/chainappendnotify.c @@ -0,0 +1,44 @@ +/** + * @file + * + * @ingroup ClassicChains + * + * @brief rtems_chain_append_with_notification() implementation. + */ + +/* + * Copyright (c) 2010 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/chain.h> + +rtems_status_code rtems_chain_append_with_notification( + rtems_chain_control *chain, + rtems_chain_node *node, + rtems_id task, + rtems_event_set events +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + bool was_empty = rtems_chain_append_with_empty_check( chain, node ); + + if ( was_empty ) { + sc = rtems_event_send( task, events ); + } + + return sc; +} diff --git a/cpukit/sapi/src/chaingetnotify.c b/cpukit/sapi/src/chaingetnotify.c new file mode 100644 index 0000000000..88f411b4f9 --- /dev/null +++ b/cpukit/sapi/src/chaingetnotify.c @@ -0,0 +1,44 @@ +/** + * @file + * + * @ingroup ClassicChains + * + * @brief rtems_chain_get_with_notification() implementation. + */ + +/* + * Copyright (c) 2010 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/chain.h> + +rtems_status_code rtems_chain_get_with_notification( + rtems_chain_control *chain, + rtems_id task, + rtems_event_set events, + rtems_chain_node **node +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + bool is_empty = rtems_chain_get_with_empty_check( chain, node ); + + if ( is_empty ) { + sc = rtems_event_send( task, events ); + } + + return sc; +} diff --git a/cpukit/sapi/src/chaingetwait.c b/cpukit/sapi/src/chaingetwait.c new file mode 100644 index 0000000000..38986bc9c1 --- /dev/null +++ b/cpukit/sapi/src/chaingetwait.c @@ -0,0 +1,55 @@ +/** + * @file + * + * @ingroup ClassicChains + * + * @brief rtems_chain_get_with_wait() implementation. + */ + +/* + * Copyright (c) 2010 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/chain.h> + +rtems_status_code rtems_chain_get_with_wait( + rtems_chain_control *chain, + rtems_event_set events, + rtems_interval timeout, + rtems_chain_node **node_ptr +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + rtems_chain_node *node = NULL; + + while ( + sc == RTEMS_SUCCESSFUL + && (node = rtems_chain_get( chain )) == NULL + ) { + rtems_event_set out; + sc = rtems_event_receive( + events, + RTEMS_EVENT_ALL | RTEMS_WAIT, + timeout, + &out + ); + } + + *node_ptr = node; + + return sc; +} diff --git a/cpukit/sapi/src/chainprependnotify.c b/cpukit/sapi/src/chainprependnotify.c new file mode 100644 index 0000000000..057e4fbde6 --- /dev/null +++ b/cpukit/sapi/src/chainprependnotify.c @@ -0,0 +1,44 @@ +/** + * @file + * + * @ingroup ClassicChains + * + * @brief rtems_chain_prepend_with_notification() implementation. + */ + +/* + * Copyright (c) 2010 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/chain.h> + +rtems_status_code rtems_chain_prepend_with_notification( + rtems_chain_control *chain, + rtems_chain_node *node, + rtems_id task, + rtems_event_set events +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + bool was_empty = rtems_chain_prepend_with_empty_check( chain, node ); + + if (was_empty) { + sc = rtems_event_send( task, events ); + } + + return sc; +} diff --git a/cpukit/sapi/src/debug.c b/cpukit/sapi/src/debug.c new file mode 100644 index 0000000000..fc9d57d874 --- /dev/null +++ b/cpukit/sapi/src/debug.c @@ -0,0 +1,59 @@ +/* + * Debug Manager + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/debug.h> + +/* + * + * _Debug_Manager_initialization + */ +void _Debug_Manager_initialization( void ) +{ + rtems_debug_disable( RTEMS_DEBUG_ALL_MASK ); +} + +/*PAGE + * + * rtems_debug_enable + */ +void rtems_debug_enable ( + rtems_debug_control to_be_enabled +) +{ + _Debug_Level |= to_be_enabled; +} + +/* + * rtems_debug_disable + */ +void rtems_debug_disable ( + rtems_debug_control to_be_disabled +) +{ + _Debug_Level &= ~to_be_disabled; +} + +/* + * rtems_debug_is_enabled + */ +bool rtems_debug_is_enabled( + rtems_debug_control level +) +{ + return (_Debug_Level & level) ? true : false; +} diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c new file mode 100644 index 0000000000..a431669641 --- /dev/null +++ b/cpukit/sapi/src/exinit.c @@ -0,0 +1,242 @@ +/* + * Initialization Manager + * + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* + * SCORE_INIT and SAPI_INIT are defined so all of the super core and + * super API data will be included in this object file. + */ + +#define SAPI_INIT +#define SCORE_INIT + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/debug.h> +#include <rtems/extension.h> +#include <rtems/fatal.h> +#include <rtems/init.h> +#include <rtems/io.h> +#include <rtems/score/sysstate.h> + +#include <rtems/score/apiext.h> +#include <rtems/score/apimutex.h> +#include <rtems/score/copyrt.h> +#include <rtems/score/heap.h> +#include <rtems/score/interr.h> +#include <rtems/score/isr.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/score/mpci.h> +#endif +#include <rtems/score/priority.h> +#include <rtems/score/scheduler.h> +#include <rtems/score/thread.h> +#include <rtems/score/tod.h> +#include <rtems/score/userext.h> +#include <rtems/score/watchdog.h> +#include <rtems/score/wkspace.h> + +#include <rtems/sptables.h> + + +#include <rtems/rtems/rtemsapi.h> +#ifdef RTEMS_POSIX_API + #include <rtems/posix/posixapi.h> +#endif + +#if defined(RTEMS_SMP) + #include <rtems/bspsmp.h> + #include <rtems/score/percpu.h> +#endif + +Objects_Information *_Internal_Objects[ OBJECTS_INTERNAL_CLASSES_LAST + 1 ]; + +void rtems_initialize_data_structures(void) +{ + /* + * Dispatching and interrupts are disabled until the end of the + * initialization sequence. This prevents an inadvertent context + * switch before the executive is initialized. + * + * WARNING: Interrupts should have been disabled by the BSP and + * are disabled by boot_card(). + */ + + #if defined(RTEMS_MULTIPROCESSING) + /* + * Initialize the system state based on whether this is an MP system. + * In an MP configuration, internally we view single processor + * systems as a very restricted multiprocessor system. + */ + _Configuration_MP_table = Configuration.User_multiprocessing_table; + + if ( _Configuration_MP_table == NULL ) { + _Configuration_MP_table = + (void *)&_Initialization_Default_multiprocessing_table; + _System_state_Handler_initialization( FALSE ); + } else { + _System_state_Handler_initialization( TRUE ); + } + #else + _System_state_Handler_initialization( FALSE ); + #endif + + /* + * Initialize any target architecture specific support as early as possible + */ + _CPU_Initialize(); + + #if defined(RTEMS_MULTIPROCESSING) + _Objects_MP_Handler_early_initialization(); + #endif + + /* + * Do this as early as possible to ensure no debugging output + * is even attempted to be printed. + */ + _Debug_Manager_initialization(); + + _API_extensions_Initialization(); + + _Thread_Dispatch_initialization(); + + /* + * Before this is called, we are not allowed to allocate memory + * from the Workspace because it is not initialized. + */ + _Workspace_Handler_initialization(); + + #if defined(RTEMS_SMP) + _SMP_Handler_initialize(); + #endif + + _User_extensions_Handler_initialization(); + _ISR_Handler_initialization(); + + /* + * Initialize the internal support API and allocator Mutex + */ + _Objects_Information_table[OBJECTS_INTERNAL_API] = _Internal_Objects; + + _API_Mutex_Initialization( 1 ); + _API_Mutex_Allocate( &_RTEMS_Allocator_Mutex ); + + _Priority_bit_map_Handler_initialization(); + _Watchdog_Handler_initialization(); + _TOD_Handler_initialization(); + + _Thread_Handler_initialization(); + + _Scheduler_Handler_initialization(); + + #if defined(RTEMS_MULTIPROCESSING) + _Objects_MP_Handler_initialization(); + _MPCI_Handler_initialization( RTEMS_TIMEOUT ); + #endif + +/* MANAGERS */ + + _RTEMS_API_Initialize(); + + _Extension_Manager_initialization(); + + _IO_Manager_initialization(); + + #ifdef RTEMS_POSIX_API + _POSIX_API_Initialize(); + #endif + + /* + * Discover and initialize the secondary cores in an SMP system. + */ + #if defined(RTEMS_SMP) + _SMP_Processor_count = bsp_smp_initialize( rtems_smp_maximum_processors ); + #endif + + _System_state_Set( SYSTEM_STATE_BEFORE_MULTITASKING ); + + /* + * No threads should be created before this point!!! + * _Thread_Executing and _Thread_Heir are not set. + * + * At this point all API extensions are in place. After the call to + * _Thread_Create_idle() _Thread_Executing and _Thread_Heir will be set. + */ + _Thread_Create_idle(); + + /* + * Scheduling can properly occur now as long as we avoid dispatching. + */ +} + +void rtems_initialize_before_drivers(void) +{ + + #if defined(RTEMS_MULTIPROCESSING) + _MPCI_Create_server(); + #endif + + #if defined(FUNCTIONALITY_NOT_CURRENTLY_USED_BY_ANY_API) + /* + * Run the API and BSPs predriver hook. + */ + _API_extensions_Run_predriver(); + #endif +} + +void rtems_initialize_device_drivers(void) +{ + /* + * Initialize all the device drivers and initialize the MPCI layer. + * + * NOTE: The MPCI may be build upon a device driver. + */ + + _IO_Initialize_all_drivers(); + + #if defined(RTEMS_MULTIPROCESSING) + if ( _System_state_Is_multiprocessing ) { + _MPCI_Initialization(); + _MPCI_Internal_packets_Send_process_packet( + MPCI_PACKETS_SYSTEM_VERIFY + ); + } + #endif + + /* + * Run the APIs and BSPs postdriver hooks. + * + * The API extensions are supposed to create user initialization tasks. + */ + _API_extensions_Run_postdriver(); +} + +void rtems_initialize_start_multitasking(void) +{ + + _System_state_Set( SYSTEM_STATE_BEGIN_MULTITASKING ); + + _Thread_Start_multitasking(); + + /******************************************************************* + ******************************************************************* + ******************************************************************* + ****** APPLICATION RUNS HERE ****** + ****** RETURNS WHEN SYSTEM IS SHUT DOWN ****** + ******************************************************************* + ******************************************************************* + *******************************************************************/ +} diff --git a/cpukit/sapi/src/exshutdown.c b/cpukit/sapi/src/exshutdown.c new file mode 100644 index 0000000000..5b0a5a1de1 --- /dev/null +++ b/cpukit/sapi/src/exshutdown.c @@ -0,0 +1,49 @@ +/* + * Initialization Manager + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/thread.h> +#include <rtems/score/interr.h> + +/* + * rtems_shutdown_executive + * + * This kernel routine shutdowns the executive. It halts multitasking + * and returns control to the application execution "thread" which + * initialially invoked the rtems_initialize_executive directive. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void rtems_shutdown_executive( + uint32_t result +) +{ + if ( _System_state_Is_up( _System_state_Get() ) ) { + _System_state_Set( SYSTEM_STATE_SHUTDOWN ); + _Thread_Stop_multitasking(); + } + _Internal_error_Occurred( + INTERNAL_ERROR_CORE, + true, + INTERNAL_ERROR_SHUTDOWN_WHEN_NOT_UP + ); + +} diff --git a/cpukit/sapi/src/extension.c b/cpukit/sapi/src/extension.c new file mode 100644 index 0000000000..993f415fd8 --- /dev/null +++ b/cpukit/sapi/src/extension.c @@ -0,0 +1,52 @@ +/* + * Extension Manager + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/extension.h> + +/*PAGE + * + * _Extension_Manager_initialization + * + * This routine initializes all extension manager related data structures. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void _Extension_Manager_initialization(void) +{ + _Objects_Initialize_information( + &_Extension_Information, + OBJECTS_CLASSIC_API, /* object API */ + OBJECTS_RTEMS_EXTENSIONS, + Configuration.maximum_extensions, + sizeof( Extension_Control ), + false, /* true if the name is a string */ + RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of an object name */ +#if defined(RTEMS_MULTIPROCESSING) + , + false, /* true if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); +} diff --git a/cpukit/sapi/src/extensioncreate.c b/cpukit/sapi/src/extensioncreate.c new file mode 100644 index 0000000000..bb8647e7b9 --- /dev/null +++ b/cpukit/sapi/src/extensioncreate.c @@ -0,0 +1,64 @@ +/** + * @file + * + * @ingroup ClassicUserExtensions + * + * @brief User Extensions Implementation. + */ + +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/extension.h> + +rtems_status_code rtems_extension_create( + rtems_name name, + const rtems_extensions_table *extension_table, + rtems_id *id +) +{ + Extension_Control *the_extension; + + if ( !id ) + return RTEMS_INVALID_ADDRESS; + + if ( !rtems_is_name_valid( name ) ) + return RTEMS_INVALID_NAME; + + _Thread_Disable_dispatch(); /* to prevent deletion */ + + the_extension = _Extension_Allocate(); + + if ( !the_extension ) { + _Thread_Enable_dispatch(); + return RTEMS_TOO_MANY; + } + + _User_extensions_Add_set_with_table( &the_extension->Extension, extension_table ); + + _Objects_Open( + &_Extension_Information, + &the_extension->Object, + (Objects_Name) name + ); + + *id = the_extension->Object.id; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/sapi/src/extensiondata.c b/cpukit/sapi/src/extensiondata.c new file mode 100644 index 0000000000..6057db5ee6 --- /dev/null +++ b/cpukit/sapi/src/extensiondata.c @@ -0,0 +1,23 @@ +/* + * Extension Manager -- Instantiate Data + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* instantiate extension data */ +#define SAPI_EXT_EXTERN + +#include <rtems/system.h> +#include <rtems/extension.h> + diff --git a/cpukit/sapi/src/extensiondelete.c b/cpukit/sapi/src/extensiondelete.c new file mode 100644 index 0000000000..4f5be6337b --- /dev/null +++ b/cpukit/sapi/src/extensiondelete.c @@ -0,0 +1,54 @@ +/** + * @file + * + * @ingroup ClassicUserExtensions + * + * @brief User Extensions Implementation. + */ + +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/extension.h> + +rtems_status_code rtems_extension_delete( + rtems_id id +) +{ + Extension_Control *the_extension; + Objects_Locations location; + + the_extension = _Extension_Get( id, &location ); + switch ( location ) { + case OBJECTS_LOCAL: + _User_extensions_Remove_set( &the_extension->Extension ); + _Objects_Close( &_Extension_Information, &the_extension->Object ); + _Extension_Free( the_extension ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + +#if defined(RTEMS_MULTIPROCESSING) + case OBJECTS_REMOTE: /* should never return this */ +#endif + case OBJECTS_ERROR: + break; + } + + return RTEMS_INVALID_ID; +} diff --git a/cpukit/sapi/src/extensionident.c b/cpukit/sapi/src/extensionident.c new file mode 100644 index 0000000000..e59f39d7dc --- /dev/null +++ b/cpukit/sapi/src/extensionident.c @@ -0,0 +1,45 @@ +/** + * @file + * + * @ingroup ClassicUserExtensions + * + * @brief User Extensions Implementation. + */ + +/* + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/rtems/support.h> +#include <rtems/score/object.h> +#include <rtems/score/thread.h> +#include <rtems/extension.h> + +rtems_status_code rtems_extension_ident( + rtems_name name, + rtems_id *id +) +{ + Objects_Name_or_id_lookup_errors status; + + status = _Objects_Name_to_id_u32( + &_Extension_Information, + name, + OBJECTS_SEARCH_LOCAL_NODE, + id + ); + + return _Status_Object_name_errors_to_status[ status ]; +} diff --git a/cpukit/sapi/src/fatal.c b/cpukit/sapi/src/fatal.c new file mode 100644 index 0000000000..80abde253a --- /dev/null +++ b/cpukit/sapi/src/fatal.c @@ -0,0 +1,40 @@ +/* + * Fatal Error Manager + * + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/fatal.h> +#include <rtems/score/interr.h> + +/* + * rtems_fatal_error_occurred + * + * This directive will invoke the internal fatal error handler. + * + * Input parameters: + * the_error - fatal error status code + * + * Output parameters: NONE + */ + +void rtems_fatal_error_occurred( + uint32_t the_error +) +{ + _Internal_error_Occurred( INTERNAL_ERROR_RTEMS_API, FALSE, the_error ); + +/* will not return from this routine */ +} diff --git a/cpukit/sapi/src/getversionstring.c b/cpukit/sapi/src/getversionstring.c new file mode 100644 index 0000000000..4295be56dc --- /dev/null +++ b/cpukit/sapi/src/getversionstring.c @@ -0,0 +1,21 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> + +const char *rtems_get_version_string(void) +{ + return _RTEMS_version; +} diff --git a/cpukit/sapi/src/io.c b/cpukit/sapi/src/io.c new file mode 100644 index 0000000000..6a752cd527 --- /dev/null +++ b/cpukit/sapi/src/io.c @@ -0,0 +1,101 @@ +/* + * Input/Output Manager - Initialize Device Driver Subsystem + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/config.h> +#include <rtems/io.h> +#include <rtems/score/isr.h> +#include <rtems/score/thread.h> +#include <rtems/score/wkspace.h> + +#include <string.h> + +/* + * _IO_Manager_initialization + * + * The IO manager has been extended to support runtime driver + * registration. The driver table is now allocated in the + * workspace. + * + */ + +void _IO_Manager_initialization(void) +{ + uint32_t index; + rtems_driver_address_table *driver_table; + uint32_t drivers_in_table; + uint32_t number_of_drivers; + + driver_table = Configuration.Device_driver_table; + drivers_in_table = Configuration.number_of_device_drivers; + number_of_drivers = Configuration.maximum_drivers; + + /* + * If the user claims there are less drivers than are actually in + * the table, then let's just go with the table's count. + */ + if ( number_of_drivers <= drivers_in_table ) + number_of_drivers = drivers_in_table; + + /* + * If the maximum number of driver is the same as the number in the + * table, then we do not have to copy the driver table. They can't + * register any dynamically. + */ + if ( number_of_drivers == drivers_in_table ) { + _IO_Driver_address_table = driver_table; + _IO_Number_of_drivers = number_of_drivers; + return; + } + + /* + * The application requested extra slots in the driver table, so we + * have to allocate a new driver table and copy theirs to it. + */ + + _IO_Driver_address_table = (rtems_driver_address_table *) + _Workspace_Allocate_or_fatal_error( + sizeof( rtems_driver_address_table ) * ( number_of_drivers ) + ); + _IO_Number_of_drivers = number_of_drivers; + + memset( + _IO_Driver_address_table, 0, + sizeof( rtems_driver_address_table ) * ( number_of_drivers ) + ); + + for ( index = 0 ; index < drivers_in_table ; index++ ) + _IO_Driver_address_table[index] = driver_table[index]; +} + +/* + * _IO_Initialize_all_drivers + * + * This routine initializes all device drivers + * + * Input Paramters: NONE + * + * Output Parameters: NONE + */ + +void _IO_Initialize_all_drivers( void ) +{ + rtems_device_major_number major; + + for ( major=0 ; major < _IO_Number_of_drivers ; major ++ ) + (void) rtems_io_initialize( major, 0, NULL ); +} diff --git a/cpukit/sapi/src/ioclose.c b/cpukit/sapi/src/ioclose.c new file mode 100644 index 0000000000..65d43f55ec --- /dev/null +++ b/cpukit/sapi/src/ioclose.c @@ -0,0 +1,48 @@ +/* + * Input/Output Manager -- Close Device + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/io.h> + +/* + * rtems_io_close + * + * This routine is the close directive of the IO manager. + * + * Input Paramters: + * major - device driver number + * minor - device number + * argument - pointer to argument(s) + * + * Output Parameters: + * returns - return code + */ + +rtems_status_code rtems_io_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument +) +{ + rtems_device_driver_entry callout; + + if ( major >= _IO_Number_of_drivers ) + return RTEMS_INVALID_NUMBER; + + callout = _IO_Driver_address_table[major].close_entry; + return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL; +} diff --git a/cpukit/sapi/src/iocontrol.c b/cpukit/sapi/src/iocontrol.c new file mode 100644 index 0000000000..1f1d0d38ea --- /dev/null +++ b/cpukit/sapi/src/iocontrol.c @@ -0,0 +1,48 @@ +/* + * Input/Output Manager - Device Control + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/io.h> + +/* + * rtems_io_control + * + * This routine is the control directive of the IO manager. + * + * Input Paramters: + * major - device driver number + * minor - device number + * argument - pointer to argument(s) + * + * Output Parameters: + * returns - return code + */ + +rtems_status_code rtems_io_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument +) +{ + rtems_device_driver_entry callout; + + if ( major >= _IO_Number_of_drivers ) + return RTEMS_INVALID_NUMBER; + + callout = _IO_Driver_address_table[major].control_entry; + return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL; +} diff --git a/cpukit/sapi/src/iodata.c b/cpukit/sapi/src/iodata.c new file mode 100644 index 0000000000..f15de6979d --- /dev/null +++ b/cpukit/sapi/src/iodata.c @@ -0,0 +1,22 @@ +/* + * RTEMS Task Manager -- Instantiate Data + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* instantiate RTEMS IO manager data */ +#define SAPI_IO_EXTERN + +#include <rtems/system.h> +#include <rtems/io.h> diff --git a/cpukit/sapi/src/ioinitialize.c b/cpukit/sapi/src/ioinitialize.c new file mode 100644 index 0000000000..998edbb6b2 --- /dev/null +++ b/cpukit/sapi/src/ioinitialize.c @@ -0,0 +1,48 @@ +/* + * Input/Output Manager - Initialize Device + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/io.h> + +/* + * rtems_io_initialize + * + * This routine is the initialization directive of the IO manager. + * + * Input Paramters: + * major - device driver number + * minor - device number + * argument - pointer to argument(s) + * + * Output Parameters: + * returns - return code + */ + +rtems_status_code rtems_io_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument +) +{ + rtems_device_driver_entry callout; + + if ( major >= _IO_Number_of_drivers ) + return RTEMS_INVALID_NUMBER; + + callout = _IO_Driver_address_table[major].initialization_entry; + return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL; +} diff --git a/cpukit/sapi/src/ioopen.c b/cpukit/sapi/src/ioopen.c new file mode 100644 index 0000000000..f8f1c84a86 --- /dev/null +++ b/cpukit/sapi/src/ioopen.c @@ -0,0 +1,48 @@ +/* + * Input/Output Manager - Open Device + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/io.h> + +/* + * rtems_io_open + * + * This routine is the open directive of the IO manager. + * + * Input Paramters: + * major - device driver number + * minor - device number + * argument - pointer to argument(s) + * + * Output Parameters: + * returns - return code + */ + +rtems_status_code rtems_io_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument +) +{ + rtems_device_driver_entry callout; + + if ( major >= _IO_Number_of_drivers ) + return RTEMS_INVALID_NUMBER; + + callout = _IO_Driver_address_table[major].open_entry; + return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL; +} diff --git a/cpukit/sapi/src/ioread.c b/cpukit/sapi/src/ioread.c new file mode 100644 index 0000000000..3b090ef764 --- /dev/null +++ b/cpukit/sapi/src/ioread.c @@ -0,0 +1,48 @@ +/* + * Input/Output Manager - Device Read + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/io.h> + +/* + * rtems_io_read + * + * This routine is the read directive of the IO manager. + * + * Input Paramters: + * major - device driver number + * minor - device number + * argument - pointer to argument(s) + * + * Output Parameters: + * returns - return code + */ + +rtems_status_code rtems_io_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument +) +{ + rtems_device_driver_entry callout; + + if ( major >= _IO_Number_of_drivers ) + return RTEMS_INVALID_NUMBER; + + callout = _IO_Driver_address_table[major].read_entry; + return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL; +} diff --git a/cpukit/sapi/src/ioregisterdriver.c b/cpukit/sapi/src/ioregisterdriver.c new file mode 100644 index 0000000000..30d10eb808 --- /dev/null +++ b/cpukit/sapi/src/ioregisterdriver.c @@ -0,0 +1,115 @@ +/** + * @file + * + * @ingroup ClassicIO + * + * @brief Classic Input/Output Manager implementation. + */ + +/* + * COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * Copyright (c) 2009 embedded brains GmbH. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/io.h> +#include <rtems/rtems/intr.h> +#include <rtems/score/thread.h> + +static inline bool rtems_io_is_empty_table( + const rtems_driver_address_table *table +) +{ + return table->initialization_entry == NULL && table->open_entry == NULL; +} + +static rtems_status_code rtems_io_obtain_major_number( + rtems_device_major_number *major +) +{ + rtems_device_major_number n = _IO_Number_of_drivers; + rtems_device_major_number m = 0; + + /* major is error checked by caller */ + + for ( m = 0; m < n; ++m ) { + rtems_driver_address_table *const table = _IO_Driver_address_table + m; + + if ( rtems_io_is_empty_table( table ) ) + break; + } + + /* Assigns invalid value in case of failure */ + *major = m; + + if ( m != n ) + return RTEMS_SUCCESSFUL; + + return RTEMS_TOO_MANY; +} + +rtems_status_code rtems_io_register_driver( + rtems_device_major_number major, + const rtems_driver_address_table *driver_table, + rtems_device_major_number *registered_major +) +{ + rtems_device_major_number major_limit = _IO_Number_of_drivers; + + if ( rtems_interrupt_is_in_progress() ) + return RTEMS_CALLED_FROM_ISR; + + if ( registered_major == NULL ) + return RTEMS_INVALID_ADDRESS; + + /* Set it to an invalid value */ + *registered_major = major_limit; + + if ( driver_table == NULL ) + return RTEMS_INVALID_ADDRESS; + + if ( rtems_io_is_empty_table( driver_table ) ) + return RTEMS_INVALID_ADDRESS; + + if ( major >= major_limit ) + return RTEMS_INVALID_NUMBER; + + _Thread_Disable_dispatch(); + + if ( major == 0 ) { + rtems_status_code sc = rtems_io_obtain_major_number( registered_major ); + + if ( sc != RTEMS_SUCCESSFUL ) { + _Thread_Enable_dispatch(); + return sc; + } + major = *registered_major; + } else { + rtems_driver_address_table *const table = _IO_Driver_address_table + major; + + if ( !rtems_io_is_empty_table( table ) ) { + _Thread_Enable_dispatch(); + return RTEMS_RESOURCE_IN_USE; + } + + *registered_major = major; + } + + _IO_Driver_address_table [major] = *driver_table; + + _Thread_Enable_dispatch(); + + return rtems_io_initialize( major, 0, NULL ); +} diff --git a/cpukit/sapi/src/iounregisterdriver.c b/cpukit/sapi/src/iounregisterdriver.c new file mode 100644 index 0000000000..631ffbfd82 --- /dev/null +++ b/cpukit/sapi/src/iounregisterdriver.c @@ -0,0 +1,57 @@ +/* + * Input/Output Manager - Dynamically Unregister Device Driver + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/io.h> +#include <rtems/rtems/intr.h> +#include <rtems/score/thread.h> +#include <string.h> + +/* + * rtems_io_unregister_driver + * + * Unregister a driver from the device driver table. + * + * Input Paramters: + * major - device major number + * + * Output Parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_io_unregister_driver( + rtems_device_major_number major +) +{ + if ( rtems_interrupt_is_in_progress() ) + return RTEMS_CALLED_FROM_ISR; + + if ( major < _IO_Number_of_drivers ) { + _Thread_Disable_dispatch(); + memset( + &_IO_Driver_address_table[major], + 0, + sizeof( rtems_driver_address_table ) + ); + _Thread_Enable_dispatch(); + + return RTEMS_SUCCESSFUL; + } + + return RTEMS_UNSATISFIED; +} diff --git a/cpukit/sapi/src/iowrite.c b/cpukit/sapi/src/iowrite.c new file mode 100644 index 0000000000..9283404e73 --- /dev/null +++ b/cpukit/sapi/src/iowrite.c @@ -0,0 +1,48 @@ +/* + * Input/Output Manager - Device Write + * + * COPYRIGHT (c) 1989-2007. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/io.h> + +/* + * rtems_io_write + * + * This routine is the write directive of the IO manager. + * + * Input Paramters: + * major - device driver number + * minor - device number + * argument - pointer to argument(s) + * + * Output Parameters: + * returns - return code + */ + +rtems_status_code rtems_io_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *argument +) +{ + rtems_device_driver_entry callout; + + if ( major >= _IO_Number_of_drivers ) + return RTEMS_INVALID_NUMBER; + + callout = _IO_Driver_address_table[major].write_entry; + return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL; +} diff --git a/cpukit/sapi/src/posixapi.c b/cpukit/sapi/src/posixapi.c new file mode 100644 index 0000000000..37cbbae8a6 --- /dev/null +++ b/cpukit/sapi/src/posixapi.c @@ -0,0 +1,88 @@ +/* + * RTEMS API Initialization Support + * + * NOTE: + * + * COPYRIGHT (c) 1989-2010. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* + * POSIX_API_INIT is defined so all of the POSIX API + * data will be included in this object file. + */ + +#define POSIX_API_INIT + +#include <rtems/system.h> /* include this before checking RTEMS_POSIX_API */ +#ifdef RTEMS_POSIX_API + +#include <sys/types.h> +#include <mqueue.h> +#include <rtems/config.h> +#include <rtems/score/object.h> +#include <rtems/posix/barrier.h> +#include <rtems/posix/cond.h> +#include <rtems/posix/config.h> +#include <rtems/posix/key.h> +#include <rtems/posix/mqueue.h> +#include <rtems/posix/mutex.h> +#include <rtems/posix/posixapi.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/psignal.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/rwlock.h> +#include <rtems/posix/timer.h> +#include <rtems/posix/semaphore.h> +#include <rtems/posix/spinlock.h> +#include <rtems/posix/time.h> + +/*PAGE + * + * _POSIX_API_Initialize + * + * XXX + */ + +Objects_Information *_POSIX_Objects[ OBJECTS_POSIX_CLASSES_LAST + 1 ]; + +void _POSIX_API_Initialize(void) +{ + /* + * If there are any type size assumptions in the POSIX API, this is + * the appropriate place to place them. + * + * Currently, there are no none type size assumptions. + */ + + /* + * Install our API Object Management Table and initialize the + * various managers. + */ + _Objects_Information_table[OBJECTS_POSIX_API] = _POSIX_Objects; + + _POSIX_signals_Manager_Initialization(); + _POSIX_Threads_Manager_initialization(); + _POSIX_Condition_variables_Manager_initialization(); + _POSIX_Key_Manager_initialization(); + _POSIX_Mutex_Manager_initialization(); + _POSIX_Message_queue_Manager_initialization(); + _POSIX_Semaphore_Manager_initialization(); + _POSIX_Timer_Manager_initialization(); + _POSIX_Barrier_Manager_initialization(); + _POSIX_RWLock_Manager_initialization(); + _POSIX_Spinlock_Manager_initialization(); +} + +#endif +/* end of file */ diff --git a/cpukit/sapi/src/rtemsapi.c b/cpukit/sapi/src/rtemsapi.c new file mode 100644 index 0000000000..fa76c2a966 --- /dev/null +++ b/cpukit/sapi/src/rtemsapi.c @@ -0,0 +1,82 @@ +/* + * POSIX API Initialization Support + * + * NOTE: + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +/* + * RTEMS_API_INIT is defined so all of the RTEMS API + * data will be included in this object file. + */ + +#define RTEMS_API_INIT + +#include <rtems/system.h> +#include <rtems/rtems/status.h> +#include <rtems/rtems/rtemsapi.h> + +#include <rtems/rtems/intr.h> +#include <rtems/rtems/barrier.h> +#include <rtems/rtems/clock.h> +#include <rtems/rtems/tasks.h> +#include <rtems/rtems/dpmem.h> +#include <rtems/rtems/event.h> +#include <rtems/rtems/message.h> +#if defined(RTEMS_MULTIPROCESSING) +#include <rtems/rtems/mp.h> +#endif +#include <rtems/rtems/part.h> +#include <rtems/rtems/ratemon.h> +#include <rtems/rtems/region.h> +#include <rtems/rtems/sem.h> +#include <rtems/rtems/signal.h> +#include <rtems/rtems/timer.h> + +Objects_Information *_RTEMS_Objects[ OBJECTS_RTEMS_CLASSES_LAST + 1 ]; + +/*PAGE + * + * _RTEMS_API_Initialize + * + * XXX + */ + +void _RTEMS_API_Initialize(void) +{ + /* + * Install our API Object Management Table and initialize the + * various managers. + */ + _Objects_Information_table[OBJECTS_CLASSIC_API] = _RTEMS_Objects; + + #if defined(RTEMS_MULTIPROCESSING) + _Multiprocessing_Manager_initialization(); + #endif + + _RTEMS_tasks_Manager_initialization(); + _Timer_Manager_initialization(); + _Signal_Manager_initialization(); + _Event_Manager_initialization(); + _Message_queue_Manager_initialization(); + _Semaphore_Manager_initialization(); + _Partition_Manager_initialization(); + _Region_Manager_initialization(); + _Dual_ported_memory_Manager_initialization(); + _Rate_monotonic_Manager_initialization(); + _Barrier_Manager_initialization(); +} + +/* end of file */ |