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