diff options
Diffstat (limited to 'cpukit/score/cpu/epiphany/include/rtems/score/cpu.h')
-rw-r--r-- | cpukit/score/cpu/epiphany/include/rtems/score/cpu.h | 614 |
1 files changed, 0 insertions, 614 deletions
diff --git a/cpukit/score/cpu/epiphany/include/rtems/score/cpu.h b/cpukit/score/cpu/epiphany/include/rtems/score/cpu.h deleted file mode 100644 index 70a9790606..0000000000 --- a/cpukit/score/cpu/epiphany/include/rtems/score/cpu.h +++ /dev/null @@ -1,614 +0,0 @@ -/** - * @file - */ - -/* - * - * Copyright (c) 2015 University of York. - * Hesham ALMatary <hmka501@york.ac.uk> - * - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _EPIPHANY_CPU_H -#define _EPIPHANY_CPU_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <rtems/score/basedefs.h> -#include <rtems/score/epiphany.h> /* pick up machine definitions */ -#ifndef ASM -#include <rtems/bspIo.h> -#include <stdint.h> -#include <stdio.h> /* for printk */ -#endif - -/** - * @addtogroup RTEMSScoreCPUEpiphany - */ -/**@{**/ - -/* conditional compilation parameters */ - -/* - * Does the RTEMS invoke the user's ISR with the vector number and - * a pointer to the saved interrupt frame (1) or just the vector - * number (0)? - * - */ - -#define CPU_ISR_PASSES_FRAME_POINTER TRUE - -#define CPU_HARDWARE_FP FALSE - -#define CPU_SOFTWARE_FP FALSE - -#define CPU_ALL_TASKS_ARE_FP FALSE - -#define CPU_IDLE_TASK_IS_FP FALSE - -#define CPU_USE_DEFERRED_FP_SWITCH FALSE - -#define CPU_ENABLE_ROBUST_THREAD_DISPATCH FALSE - -/* - * Does the stack grow up (toward higher addresses) or down - * (toward lower addresses)? - * - * If TRUE, then the grows upward. - * If FALSE, then the grows toward smaller addresses. - * - */ - -#define CPU_STACK_GROWS_UP FALSE - -/* FIXME: Is this the right value? */ -#define CPU_CACHE_LINE_BYTES 64 - -#define CPU_STRUCTURE_ALIGNMENT RTEMS_ALIGNED( CPU_CACHE_LINE_BYTES ) - -/* - * The following defines the number of bits actually used in the - * interrupt field of the task mode. How those bits map to the - * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level(). - * - */ - -#define CPU_MODES_INTERRUPT_MASK 0x00000001 - -/* - * Processor defined structures required for cpukit/score. - */ - -/* - * Contexts - * - * Generally there are 2 types of context to save. - * 1. Interrupt registers to save - * 2. Task level registers to save - * - * This means we have the following 3 context items: - * 1. task level context stuff:: Context_Control - * 2. floating point task stuff:: Context_Control_fp - * 3. special interrupt level context :: Context_Control_interrupt - * - * On some processors, it is cost-effective to save only the callee - * preserved registers during a task context switch. This means - * that the ISR code needs to save those registers which do not - * persist across function calls. It is not mandatory to make this - * distinctions between the caller/callee saves registers for the - * purpose of minimizing context saved during task switch and on interrupts. - * If the cost of saving extra registers is minimal, simplicity is the - * choice. Save the same context on interrupt entry as for tasks in - * this case. - * - * Additionally, if gdb is to be made aware of RTEMS tasks for this CPU, then - * care should be used in designing the context area. - * - * On some CPUs with hardware floating point support, the Context_Control_fp - * structure will not be used or it simply consist of an array of a - * fixed number of bytes. This is done when the floating point context - * is dumped by a "FP save context" type instruction and the format - * is not really defined by the CPU. In this case, there is no need - * to figure out the exact format -- only the size. Of course, although - * this is enough information for RTEMS, it is probably not enough for - * a debugger such as gdb. But that is another problem. - * - * - */ -#ifndef ASM - -typedef struct { - uint32_t r[64]; - - uint32_t status; - uint32_t config; - uint32_t iret; - -#ifdef RTEMS_SMP - /** - * @brief On SMP configurations the thread context must contain a boolean - * indicator to signal if this context is executing on a processor. - * - * This field must be updated during a context switch. The context switch - * to the heir must wait until the heir context indicates that it is no - * longer executing on a processor. The context switch must also check if - * a thread dispatch is necessary to honor updates of the heir thread for - * this processor. This indicator must be updated using an atomic test and - * set operation to ensure that at most one processor uses the heir - * context at the same time. - * - * @code - * void _CPU_Context_switch( - * Context_Control *executing, - * Context_Control *heir - * ) - * { - * save( executing ); - * - * executing->is_executing = false; - * memory_barrier(); - * - * if ( test_and_set( &heir->is_executing ) ) { - * do { - * Per_CPU_Control *cpu_self = _Per_CPU_Get_snapshot(); - * - * if ( cpu_self->dispatch_necessary ) { - * heir = _Thread_Get_heir_and_make_it_executing( cpu_self ); - * } - * } while ( test_and_set( &heir->is_executing ) ); - * } - * - * restore( heir ); - * } - * @endcode - */ - volatile bool is_executing; -#endif -} Context_Control; - -#define _CPU_Context_Get_SP( _context ) \ - (_context)->r[13] - -typedef Context_Control CPU_Interrupt_frame; - -/* - * Amount of extra stack (above minimum stack size) required by - * MPCI receive server thread. Remember that in a multiprocessor - * system this thread must exist and be able to process all directives. - * - */ - -#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0 - -/* - * Should be large enough to run all RTEMS tests. This insures - * that a "reasonable" small application should not have any problems. - * - */ - -#define CPU_STACK_MINIMUM_SIZE 4096 - -/* - * CPU's worst alignment requirement for data types on a byte boundary. This - * alignment does not take into account the requirements for the stack. - * - */ - -#define CPU_ALIGNMENT 8 - -/* - * This is defined if the port has a special way to report the ISR nesting - * level. Most ports maintain the variable _ISR_Nest_level. - */ -#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE - -/* - * This number corresponds to the byte alignment requirement for the - * heap handler. This alignment requirement may be stricter than that - * for the data types alignment specified by CPU_ALIGNMENT. It is - * common for the heap to follow the same alignment requirement as - * CPU_ALIGNMENT. If the CPU_ALIGNMENT is strict enough for the heap, - * then this should be set to CPU_ALIGNMENT. - * - * NOTE: This does not have to be a power of 2 although it should be - * a multiple of 2 greater than or equal to 2. The requirement - * to be a multiple of 2 is because the heap uses the least - * significant field of the front and back flags to indicate - * that a block is in use or free. So you do not want any odd - * length blocks really putting length data in that bit. - * - * On byte oriented architectures, CPU_HEAP_ALIGNMENT normally will - * have to be greater or equal to than CPU_ALIGNMENT to ensure that - * elements allocated from the heap meet all restrictions. - * - */ - -#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT - -/* - * This number corresponds to the byte alignment requirement for the - * stack. This alignment requirement may be stricter than that for the - * data types alignment specified by CPU_ALIGNMENT. If the CPU_ALIGNMENT - * is strict enough for the stack, then this should be set to 0. - * - * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT. - * - */ - -#define CPU_STACK_ALIGNMENT 8 - -#define CPU_INTERRUPT_STACK_ALIGNMENT CPU_CACHE_LINE_BYTES - -/* ISR handler macros */ - -/* - * Support routine to initialize the RTEMS vector table after it is allocated. - * - * NO_CPU Specific Information: - * - * XXX document implementation including references if appropriate - */ - -#define _CPU_Initialize_vectors() - -/* - * Disable all interrupts for an RTEMS critical section. The previous - * level is returned in _level. - * - */ - -static inline uint32_t epiphany_interrupt_disable( void ) -{ - uint32_t sr; - __asm__ __volatile__ ("movfs %[sr], status \n" : [sr] "=r" (sr):); - __asm__ __volatile__("gid \n"); - return sr; -} - -static inline void epiphany_interrupt_enable(uint32_t level) -{ - __asm__ __volatile__("gie \n"); - __asm__ __volatile__ ("movts status, %[level] \n" :: [level] "r" (level):); -} - -#define _CPU_ISR_Disable( _level ) \ - _level = epiphany_interrupt_disable() - -/* - * Enable interrupts to the previous level (returned by _CPU_ISR_Disable). - * This indicates the end of an RTEMS critical section. The parameter - * _level is not modified. - * - */ - -#define _CPU_ISR_Enable( _level ) \ - epiphany_interrupt_enable( _level ) - -/* - * This temporarily restores the interrupt to _level before immediately - * disabling them again. This is used to divide long RTEMS critical - * sections into two or more parts. The parameter _level is not - * modified. - * - */ - -#define _CPU_ISR_Flash( _level ) \ - do{ \ - if ( (_level & 0x2) != 0 ) \ - _CPU_ISR_Enable( _level ); \ - epiphany_interrupt_disable(); \ - } while(0) - -RTEMS_INLINE_ROUTINE bool _CPU_ISR_Is_enabled( uint32_t level ) -{ - return ( level & 0x2 ) != 0; -} - -/* - * Map interrupt level in task mode onto the hardware that the CPU - * actually provides. Currently, interrupt levels which do not - * map onto the CPU in a generic fashion are undefined. Someday, - * it would be nice if these were "mapped" by the application - * via a callout. For example, m68k has 8 levels 0 - 7, levels - * 8 - 255 would be available for bsp/application specific meaning. - * This could be used to manage a programmable interrupt controller - * via the rtems_task_mode directive. - * - * The get routine usually must be implemented as a subroutine. - * - */ - -void _CPU_ISR_Set_level( uint32_t level ); - -uint32_t _CPU_ISR_Get_level( void ); - -/* end of ISR handler macros */ - -/* Context handler macros */ - -/* - * Initialize the context to a state suitable for starting a - * task after a context restore operation. Generally, this - * involves: - * - * - setting a starting address - * - preparing the stack - * - preparing the stack and frame pointers - * - setting the proper interrupt level in the context - * - initializing the floating point context - * - * This routine generally does not set any unnecessary register - * in the context. The state of the "general data" registers is - * undefined at task start time. - * - * NOTE: This is_fp parameter is TRUE if the thread is to be a floating - * point thread. This is typically only used on CPUs where the - * FPU may be easily disabled by software such as on the SPARC - * where the PSR contains an enable FPU bit. - * - */ - -/** - * @brief Account for GCC red-zone - * - * The following macro is used when initializing task's stack - * to account for GCC red-zone. - */ - -#define EPIPHANY_GCC_RED_ZONE_SIZE 128 - -/** - * @brief Initializes the CPU context. - * - * The following steps are performed: - * - setting a starting address - * - preparing the stack - * - preparing the stack and frame pointers - * - setting the proper interrupt level in the context - * - * @param[in] context points to the context area - * @param[in] stack_area_begin is the low address of the allocated stack area - * @param[in] stack_area_size is the size of the stack area in bytes - * @param[in] new_level is the interrupt level for the task - * @param[in] entry_point is the task's entry point - * @param[in] is_fp is set to @c true if the task is a floating point task - * @param[in] tls_area is the thread-local storage (TLS) area - */ -void _CPU_Context_Initialize( - Context_Control *context, - void *stack_area_begin, - size_t stack_area_size, - uint32_t new_level, - void (*entry_point)( void ), - bool is_fp, - void *tls_area -); - -/* - * This routine is responsible for somehow restarting the currently - * executing task. If you are lucky, then all that is necessary - * is restoring the context. Otherwise, there will need to be - * a special assembly routine which does something special in this - * case. Context_Restore should work most of the time. It will - * not work if restarting self conflicts with the stack frame - * assumptions of restoring a context. - * - */ - -#define _CPU_Context_Restart_self( _the_context ) \ - _CPU_Context_restore( (_the_context) ) - -/* end of Context handler macros */ - -/* Fatal Error manager macros */ - -/* - * This routine copies _error into a known place -- typically a stack - * location or a register, optionally disables interrupts, and - * halts/stops the CPU. - * - */ - -#include <inttypes.h> - -#define _CPU_Fatal_halt(_source, _error ) \ - printk("Fatal Error %d.%" PRIu32 " Halted\n",_source, _error); \ - asm("trap 3" :: "r" (_error)); \ - for(;;) - -/* end of Fatal Error manager macros */ - -#define CPU_USE_GENERIC_BITFIELD_CODE TRUE - -#define CPU_USE_LIBC_INIT_FINI_ARRAY FALSE - -#endif /* ASM */ - -/** - * Size of a pointer. - * - * This must be an integer literal that can be used by the assembler. This - * value will be used to calculate offsets of structure members. These - * offsets will be used in assembler code. - */ -#define CPU_SIZEOF_POINTER 4 -#define CPU_EXCEPTION_FRAME_SIZE 260 - -#define CPU_MAXIMUM_PROCESSORS 32 - -#ifndef ASM - -typedef struct { - uint32_t r[62]; - uint32_t status; - uint32_t config; - uint32_t iret; -} CPU_Exception_frame; - -/** - * @brief Prints the exception frame via printk(). - * - * @see rtems_fatal() and RTEMS_FATAL_SOURCE_EXCEPTION. - */ -void _CPU_Exception_frame_print( const CPU_Exception_frame *frame ); - - -/* end of Priority handler macros */ - -/* functions */ - -/* - * _CPU_Initialize - * - * This routine performs CPU dependent initialization. - * - */ - -void _CPU_Initialize( - void -); - -void *_CPU_Thread_Idle_body( uintptr_t ignored ); - -/* - * _CPU_Context_switch - * - * This routine switches from the run context to the heir context. - * - * epiphany Specific Information: - * - * Please see the comments in the .c file for a description of how - * this function works. There are several things to be aware of. - */ - -void _CPU_Context_switch( - Context_Control *run, - Context_Control *heir -); - -/* - * _CPU_Context_restore - * - * This routine is generally used only to restart self in an - * efficient manner. It may simply be a label in _CPU_Context_switch. - * - * NOTE: May be unnecessary to reload some registers. - * - */ - -void _CPU_Context_restore( - Context_Control *new_context -) RTEMS_NO_RETURN; - -/* - * _CPU_Context_save_fp - * - * This routine saves the floating point context passed to it. - * - */ - -void _CPU_Context_save_fp( - void **fp_context_ptr -); - -/* - * _CPU_Context_restore_fp - * - * This routine restores the floating point context passed to it. - * - */ - -void _CPU_Context_restore_fp( - void **fp_context_ptr -); - -/* The following routine swaps the endian format of an unsigned int. - * It must be static because it is referenced indirectly. - * - * This version will work on any processor, but if there is a better - * way for your CPU PLEASE use it. The most common way to do this is to: - * - * swap least significant two bytes with 16-bit rotate - * swap upper and lower 16-bits - * swap most significant two bytes with 16-bit rotate - * - * Some CPUs have special instructions which swap a 32-bit quantity in - * a single instruction (e.g. i486). It is probably best to avoid - * an "endian swapping control bit" in the CPU. One good reason is - * that interrupts would probably have to be disabled to insure that - * an interrupt does not try to access the same "chunk" with the wrong - * endian. Another good reason is that on some CPUs, the endian bit - * endianness for ALL fetches -- both code and data -- so the code - * will be fetched incorrectly. - * - */ - -static inline unsigned int CPU_swap_u32( - unsigned int value -) -{ - uint32_t byte1, byte2, byte3, byte4, swapped; - - byte4 = (value >> 24) & 0xff; - byte3 = (value >> 16) & 0xff; - byte2 = (value >> 8) & 0xff; - byte1 = value & 0xff; - - swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4; - return( swapped ); -} - -#define CPU_swap_u16( value ) \ - (((value&0xff) << 8) | ((value >> 8)&0xff)) - -typedef uint32_t CPU_Counter_ticks; - -uint32_t _CPU_Counter_frequency( void ); - -CPU_Counter_ticks _CPU_Counter_read( void ); - -static inline CPU_Counter_ticks _CPU_Counter_difference( - CPU_Counter_ticks second, - CPU_Counter_ticks first -) -{ - return second - first; -} - -/** Type that can store a 32-bit integer or a pointer. */ -typedef uintptr_t CPU_Uint32ptr; - -#endif /* ASM */ - -#ifdef __cplusplus -} -#endif - -#endif - -/**@}*/ |