[b7185613] | 1 | /** |
---|
| 2 | * @file |
---|
[ac7d5ef0] | 3 | * |
---|
[b7185613] | 4 | * @brief Motorola MC68xxx Dependent Source |
---|
| 5 | */ |
---|
| 6 | |
---|
| 7 | /* |
---|
[08311cc3] | 8 | * COPYRIGHT (c) 1989-1999. |
---|
[ac7d5ef0] | 9 | * On-Line Applications Research Corporation (OAR). |
---|
| 10 | * |
---|
[98e4ebf5] | 11 | * The license and distribution terms for this file may be |
---|
| 12 | * found in the file LICENSE in this distribution or at |
---|
[c499856] | 13 | * http://www.rtems.org/license/LICENSE. |
---|
[ac7d5ef0] | 14 | */ |
---|
| 15 | |
---|
[febaa8a] | 16 | #ifdef HAVE_CONFIG_H |
---|
| 17 | #include "config.h" |
---|
| 18 | #endif |
---|
| 19 | |
---|
[5e9b32b] | 20 | #include <rtems/score/isr.h> |
---|
[48fed9a] | 21 | #include <rtems/score/percpu.h> |
---|
[022851a] | 22 | #include <rtems/score/tls.h> |
---|
[511dc4b] | 23 | #include <rtems/config.h> |
---|
[ac7d5ef0] | 24 | |
---|
[18a5db2] | 25 | #if ( M68K_HAS_VBR == 0 ) |
---|
| 26 | |
---|
| 27 | /* |
---|
| 28 | * Table of ISR handler entries that resides in RAM. The FORMAT/ID is |
---|
| 29 | * pushed onto the stack. This is not is the same order as VBR processors. |
---|
| 30 | * The ISR handler takes the format and uses it for dispatching the user |
---|
| 31 | * handler. |
---|
| 32 | */ |
---|
| 33 | |
---|
| 34 | typedef struct { |
---|
| 35 | uint16_t move_a7; /* move #FORMAT_ID,%a7@- */ |
---|
| 36 | uint16_t format_id; |
---|
| 37 | uint16_t jmp; /* jmp _ISR_Handlers */ |
---|
| 38 | uint32_t isr_handler; |
---|
| 39 | } _CPU_ISR_handler_entry; |
---|
| 40 | |
---|
| 41 | #define M68K_MOVE_A7 0x3F3C |
---|
| 42 | #define M68K_JMP 0x4EF9 |
---|
| 43 | |
---|
| 44 | /* points to jsr-exception-table in targets wo/ VBR register */ |
---|
| 45 | static _CPU_ISR_handler_entry |
---|
| 46 | _CPU_ISR_jump_table[ CPU_INTERRUPT_NUMBER_OF_VECTORS ]; |
---|
| 47 | |
---|
| 48 | #endif /* M68K_HAS_VBR */ |
---|
| 49 | |
---|
| 50 | #if (M68K_HAS_FPSP_PACKAGE == 1) |
---|
| 51 | int (*_FPSP_install_raw_handler)( |
---|
| 52 | uint32_t vector, |
---|
| 53 | proc_ptr new_handler, |
---|
| 54 | proc_ptr *old_handler |
---|
| 55 | ); |
---|
| 56 | #endif |
---|
| 57 | |
---|
[3b7e9bc] | 58 | #if defined( __mcoldfire__ ) && ( M68K_HAS_FPU == 1 ) |
---|
| 59 | uint32_t _CPU_cacr_shadow; |
---|
| 60 | #endif |
---|
| 61 | |
---|
[511dc4b] | 62 | static void m68k_install_interrupt_stack( void ) |
---|
| 63 | { |
---|
| 64 | #if ( M68K_HAS_SEPARATE_STACKS == 1 ) |
---|
[ff081aee] | 65 | uintptr_t isp = (uintptr_t) _ISR_Stack_area_end; |
---|
[511dc4b] | 66 | |
---|
| 67 | __asm__ volatile ( "movec %0,%%isp" : "=r" (isp) : "0" (isp) ); |
---|
| 68 | #endif |
---|
| 69 | } |
---|
| 70 | |
---|
[c03e2bc] | 71 | void _CPU_Initialize(void) |
---|
[ac7d5ef0] | 72 | { |
---|
[f4b7e297] | 73 | #if ( M68K_HAS_VBR == 0 ) |
---|
| 74 | /* fill the isr redirect table with the code to place the format/id |
---|
| 75 | onto the stack */ |
---|
| 76 | |
---|
[d86bae8] | 77 | uint32_t slot; |
---|
[f4b7e297] | 78 | |
---|
| 79 | for (slot = 0; slot < CPU_INTERRUPT_NUMBER_OF_VECTORS; slot++) |
---|
| 80 | { |
---|
| 81 | _CPU_ISR_jump_table[slot].move_a7 = M68K_MOVE_A7; |
---|
| 82 | _CPU_ISR_jump_table[slot].format_id = slot << 2; |
---|
| 83 | _CPU_ISR_jump_table[slot].jmp = M68K_JMP; |
---|
[edb1810e] | 84 | _CPU_ISR_jump_table[slot].isr_handler = (uint32_t) 0xDEADDEAD; |
---|
[f4b7e297] | 85 | } |
---|
| 86 | #endif /* M68K_HAS_VBR */ |
---|
[511dc4b] | 87 | |
---|
| 88 | m68k_install_interrupt_stack(); |
---|
[ac7d5ef0] | 89 | } |
---|
| 90 | |
---|
[d86bae8] | 91 | uint32_t _CPU_ISR_Get_level( void ) |
---|
[3a4ae6c] | 92 | { |
---|
[d86bae8] | 93 | uint32_t level; |
---|
[3a4ae6c] | 94 | |
---|
| 95 | m68k_get_interrupt_level( level ); |
---|
| 96 | |
---|
| 97 | return level; |
---|
| 98 | } |
---|
| 99 | |
---|
[3dc9afb6] | 100 | /* |
---|
[637df35] | 101 | * _CPU_ISR_install_raw_handler |
---|
| 102 | */ |
---|
[5bb38e15] | 103 | |
---|
[637df35] | 104 | void _CPU_ISR_install_raw_handler( |
---|
[d86bae8] | 105 | uint32_t vector, |
---|
[637df35] | 106 | proc_ptr new_handler, |
---|
| 107 | proc_ptr *old_handler |
---|
| 108 | ) |
---|
| 109 | { |
---|
| 110 | proc_ptr *interrupt_table = NULL; |
---|
| 111 | |
---|
[5bf6ffb] | 112 | #if (M68K_HAS_FPSP_PACKAGE == 1) |
---|
| 113 | /* |
---|
| 114 | * If this vector being installed is one related to FP, then the |
---|
| 115 | * FPSP will install the handler itself and handle it completely |
---|
| 116 | * with no intervention from RTEMS. |
---|
| 117 | */ |
---|
| 118 | |
---|
| 119 | if (*_FPSP_install_raw_handler && |
---|
| 120 | (*_FPSP_install_raw_handler)(vector, new_handler, *old_handler)) |
---|
| 121 | return; |
---|
| 122 | #endif |
---|
[637df35] | 123 | |
---|
[f4b7e297] | 124 | |
---|
[5bf6ffb] | 125 | /* |
---|
| 126 | * On CPU models without a VBR, it is necessary for there to be some |
---|
| 127 | * header code for each ISR which saves a register, loads the vector |
---|
[5bb38e15] | 128 | * number, and jumps to _ISR_Handler. |
---|
[5bf6ffb] | 129 | */ |
---|
| 130 | |
---|
| 131 | m68k_get_vbr( interrupt_table ); |
---|
[f4b7e297] | 132 | #if ( M68K_HAS_VBR == 1 ) |
---|
[c533372] | 133 | *old_handler = interrupt_table[ vector ]; |
---|
[637df35] | 134 | interrupt_table[ vector ] = new_handler; |
---|
[38ffa0c] | 135 | #else |
---|
[5ede9706] | 136 | |
---|
| 137 | /* |
---|
| 138 | * Install handler into RTEMS jump table and if VBR table is in |
---|
| 139 | * RAM, install the pointer to the appropriate jump table slot. |
---|
| 140 | * If the VBR table is in ROM, it is the BSP's responsibility to |
---|
| 141 | * load it appropriately to vector to the RTEMS jump table. |
---|
| 142 | */ |
---|
| 143 | |
---|
[86e1c26] | 144 | *old_handler = (proc_ptr) _CPU_ISR_jump_table[vector].isr_handler; |
---|
[edb1810e] | 145 | _CPU_ISR_jump_table[vector].isr_handler = (uint32_t) new_handler; |
---|
| 146 | if ( (uint32_t) interrupt_table != 0xFFFFFFFF ) |
---|
[5ede9706] | 147 | interrupt_table[ vector ] = (proc_ptr) &_CPU_ISR_jump_table[vector]; |
---|
[38ffa0c] | 148 | #endif /* M68K_HAS_VBR */ |
---|
[637df35] | 149 | } |
---|
| 150 | |
---|
[ac7d5ef0] | 151 | void _CPU_ISR_install_vector( |
---|
[d86bae8] | 152 | uint32_t vector, |
---|
[ac7d5ef0] | 153 | proc_ptr new_handler, |
---|
| 154 | proc_ptr *old_handler |
---|
| 155 | ) |
---|
| 156 | { |
---|
[926a05e] | 157 | proc_ptr ignored = 0; /* to avoid warning */ |
---|
[ac7d5ef0] | 158 | |
---|
| 159 | *old_handler = _ISR_Vector_table[ vector ]; |
---|
| 160 | |
---|
[637df35] | 161 | _CPU_ISR_install_raw_handler( vector, _ISR_Handler, &ignored ); |
---|
| 162 | |
---|
[ac7d5ef0] | 163 | _ISR_Vector_table[ vector ] = new_handler; |
---|
| 164 | } |
---|
| 165 | |
---|
[9e86dd7d] | 166 | #if ( M68K_HAS_BFFFO != 1 ) |
---|
| 167 | /* |
---|
[38ffa0c] | 168 | * Returns table for duplication of the BFFFO instruction (16 bits only) |
---|
[9e86dd7d] | 169 | */ |
---|
[60a3fa0c] | 170 | const unsigned char _CPU_m68k_BFFFO_table[256] = { |
---|
[38ffa0c] | 171 | 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, |
---|
| 172 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, |
---|
| 173 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
---|
| 174 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
---|
| 175 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
---|
| 176 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
---|
| 177 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
---|
| 178 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
---|
| 179 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
| 180 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
| 181 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
| 182 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
| 183 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
| 184 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
| 185 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
---|
| 186 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
---|
[9e86dd7d] | 187 | }; |
---|
| 188 | #endif |
---|
[00d2a828] | 189 | |
---|
[3dc9afb6] | 190 | /* |
---|
[00d2a828] | 191 | * The following code context switches the software FPU emulation |
---|
| 192 | * code provided with GCC. |
---|
| 193 | */ |
---|
| 194 | |
---|
| 195 | #if (CPU_SOFTWARE_FP == TRUE) |
---|
| 196 | extern Context_Control_fp _fpCCR; |
---|
| 197 | |
---|
[3b7e9bc] | 198 | void _CPU_Context_save_fp (Context_Control_fp **fp_context_ptr) |
---|
[00d2a828] | 199 | { |
---|
| 200 | Context_Control_fp *fp; |
---|
| 201 | |
---|
[14865ec7] | 202 | fp = *fp_context_ptr; |
---|
[00d2a828] | 203 | |
---|
| 204 | *fp = _fpCCR; |
---|
| 205 | } |
---|
| 206 | |
---|
[3b7e9bc] | 207 | void _CPU_Context_restore_fp (Context_Control_fp **fp_context_ptr) |
---|
[00d2a828] | 208 | { |
---|
| 209 | Context_Control_fp *fp; |
---|
| 210 | |
---|
[14865ec7] | 211 | fp = *fp_context_ptr; |
---|
[00d2a828] | 212 | |
---|
| 213 | _fpCCR = *fp; |
---|
| 214 | } |
---|
| 215 | #endif |
---|
[022851a] | 216 | |
---|
| 217 | void _CPU_Context_Initialize( |
---|
| 218 | Context_Control *the_context, |
---|
| 219 | void *stack_area_begin, |
---|
| 220 | size_t stack_area_size, |
---|
| 221 | uint32_t new_level, |
---|
| 222 | void (*entry_point)( void ), |
---|
| 223 | bool is_fp, |
---|
| 224 | void *tls_area |
---|
| 225 | ) |
---|
| 226 | { |
---|
| 227 | uint32_t stack; |
---|
| 228 | |
---|
| 229 | the_context->sr = 0x3000 | (new_level << 8); |
---|
| 230 | stack = (uint32_t)stack_area_begin + stack_area_size - 4; |
---|
| 231 | the_context->a7_msp = (void *)stack; |
---|
| 232 | *(void **)stack = (void *)entry_point; |
---|
| 233 | |
---|
| 234 | #if (defined(__mcoldfire__) && ( M68K_HAS_FPU == 1 )) |
---|
| 235 | the_context->fpu_dis = is_fp ? 0x00 : 0x10; |
---|
| 236 | #endif |
---|
| 237 | |
---|
| 238 | if ( tls_area != NULL ) { |
---|
[320faf8e] | 239 | _TLS_TCB_before_TLS_block_initialize( tls_area ); |
---|
[022851a] | 240 | } |
---|
| 241 | } |
---|