Mercurial > ecos
comparison packages/hal/mips/arch/current/include/hal_arch.h @ 2:443894e2e912 ecos-v1_2_1-release
Block commit of eCos version 1.2.1
| author | jlarmour |
|---|---|
| date | Tue, 11 May 1999 12:24:34 +0000 |
| parents | 3111d98ba7b3 |
| children | d376b777e2ce |
comparison
equal
deleted
inserted
replaced
| 1:72f549f0d891 | 2:443894e2e912 |
|---|---|
| 1 #ifndef CYGONCE_HAL_HAL_ARCH_H | 1 #ifndef CYGONCE_HAL_HAL_ARCH_H |
| 2 #define CYGONCE_HAL_HAL_ARCH_H | 2 #define CYGONCE_HAL_HAL_ARCH_H |
| 3 | 3 |
| 4 //============================================================================= | 4 //========================================================================== |
| 5 // | 5 // |
| 6 // hal_arch.h | 6 // hal_arch.h |
| 7 // | 7 // |
| 8 // Architecture specific abstractions | 8 // Architecture specific abstractions |
| 9 // | 9 // |
| 10 //============================================================================= | 10 //========================================================================== |
| 11 //####COPYRIGHTBEGIN#### | 11 //####COPYRIGHTBEGIN#### |
| 12 // | 12 // |
| 13 // ------------------------------------------- | 13 // ------------------------------------------- |
| 14 // The contents of this file are subject to the Cygnus eCos Public License | 14 // The contents of this file are subject to the Cygnus eCos Public License |
| 15 // Version 1.0 (the "License"); you may not use this file except in | 15 // Version 1.0 (the "License"); you may not use this file except in |
| 23 // | 23 // |
| 24 // The Original Code is eCos - Embedded Cygnus Operating System, released | 24 // The Original Code is eCos - Embedded Cygnus Operating System, released |
| 25 // September 30, 1998. | 25 // September 30, 1998. |
| 26 // | 26 // |
| 27 // The Initial Developer of the Original Code is Cygnus. Portions created | 27 // The Initial Developer of the Original Code is Cygnus. Portions created |
| 28 // by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved. | 28 // by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. |
| 29 // ------------------------------------------- | 29 // ------------------------------------------- |
| 30 // | 30 // |
| 31 //####COPYRIGHTEND#### | 31 //####COPYRIGHTEND#### |
| 32 //============================================================================= | 32 //========================================================================== |
| 33 //#####DESCRIPTIONBEGIN#### | 33 //#####DESCRIPTIONBEGIN#### |
| 34 // | 34 // |
| 35 // Author(s): nickg | 35 // Author(s): nickg |
| 36 // Contributors: nickg | 36 // Contributors: nickg |
| 37 // Date: 1998-02-05 | 37 // Date: 1999-02-17 |
| 38 // Purpose: Define architecture abstractions | 38 // Purpose: Define architecture abstractions |
| 39 // Usage: #include <cyg/hal/hal_arch.h> | 39 // Usage: #include <cyg/hal/hal_arch.h> |
| 40 // | 40 // |
| 41 //####DESCRIPTIONEND#### | 41 //####DESCRIPTIONEND#### |
| 42 // | 42 // |
| 43 //============================================================================= | 43 //========================================================================== |
| 44 | 44 |
| 45 #include <pkgconf/hal.h> | |
| 45 #include <cyg/infra/cyg_type.h> | 46 #include <cyg/infra/cyg_type.h> |
| 46 | 47 |
| 47 //----------------------------------------------------------------------------- | 48 //-------------------------------------------------------------------------- |
| 48 // Processor saved states: | 49 // Processor saved states: |
| 49 // The layout of this structure is also defined in "mips.inc", for assembly | 50 // The layout of this structure is also defined in "mips.inc", for assembly |
| 50 // code. Do not change this without changing that (or vice versa). | 51 // code. Do not change this without changing that (or vice versa). |
| 51 | 52 |
| 52 typedef struct | 53 typedef struct |
| 69 cyg_uint32 badvr; /* Bad virtual address reg */ | 70 cyg_uint32 badvr; /* Bad virtual address reg */ |
| 70 cyg_uint32 prid; /* Processor Version */ | 71 cyg_uint32 prid; /* Processor Version */ |
| 71 cyg_uint32 config; /* Config register */ | 72 cyg_uint32 config; /* Config register */ |
| 72 } HAL_SavedRegisters; | 73 } HAL_SavedRegisters; |
| 73 | 74 |
| 74 //----------------------------------------------------------------------------- | 75 //-------------------------------------------------------------------------- |
| 75 // Exception handling function. | 76 // Exception handling function. |
| 76 // This function is defined by the kernel according to this prototype. It is | 77 // This function is defined by the kernel according to this prototype. It is |
| 77 // invoked from the HAL to deal with any CPU exceptions that the HAL does | 78 // invoked from the HAL to deal with any CPU exceptions that the HAL does |
| 78 // not want to deal with itself. It usually invokes the kernel's exception | 79 // not want to deal with itself. It usually invokes the kernel's exception |
| 79 // delivery mechanism. | 80 // delivery mechanism. |
| 80 | 81 |
| 81 externC void deliver_exception( CYG_WORD code, CYG_ADDRWORD data ); | 82 externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data ); |
| 82 | 83 |
| 83 //----------------------------------------------------------------------------- | 84 //-------------------------------------------------------------------------- |
| 84 // Bit manipulation macros | 85 // Bit manipulation macros |
| 85 | 86 |
| 86 externC cyg_uint32 hal_lsbit_index(cyg_uint32 mask); | 87 externC cyg_uint32 hal_lsbit_index(cyg_uint32 mask); |
| 87 externC cyg_uint32 hal_msbit_index(cyg_uint32 mask); | 88 externC cyg_uint32 hal_msbit_index(cyg_uint32 mask); |
| 88 | 89 |
| 89 #define HAL_LSBIT_INDEX(index, mask) index = hal_lsbit_index(mask); | 90 #define HAL_LSBIT_INDEX(index, mask) index = hal_lsbit_index(mask); |
| 90 | 91 |
| 91 #define HAL_MSBIT_INDEX(index, mask) index = hal_msbit_index(mask); | 92 #define HAL_MSBIT_INDEX(index, mask) index = hal_msbit_index(mask); |
| 92 | 93 |
| 93 //----------------------------------------------------------------------------- | 94 //-------------------------------------------------------------------------- |
| 94 // Context Initialization | 95 // Context Initialization |
| 95 // Initialize the context of a thread. | 96 // Initialize the context of a thread. |
| 96 // Arguments: | 97 // Arguments: |
| 97 // _sparg_ name of variable containing current sp, will be written with new sp | 98 // _sparg_ name of variable containing current sp, will be written with new sp |
| 98 // _thread_ thread object address, passed as argument to entry point | 99 // _thread_ thread object address, passed as argument to entry point |
| 99 // _entry_ entry point address. | 100 // _entry_ entry point address. |
| 100 // _id_ bit pattern used in initializing registers, for debugging. | 101 // _id_ bit pattern used in initializing registers, for debugging. |
| 101 | 102 |
| 102 #define HAL_THREAD_INIT_CONTEXT( _sparg_, _thread_, _entry_, _id_ ) \ | 103 #define HAL_THREAD_INIT_CONTEXT( _sparg_, _thread_, _entry_, _id_ ) \ |
| 103 { \ | 104 { \ |
| 104 register CYG_WORD _sp_ = ((CYG_WORD)_sparg_)-56; \ | 105 register CYG_WORD _sp_ = ((CYG_WORD)_sparg_)-56; \ |
| 105 register HAL_SavedRegisters *_regs_; \ | 106 register HAL_SavedRegisters *_regs_; \ |
| 106 int _i_; \ | 107 int _i_; \ |
| 107 _regs_ = (HAL_SavedRegisters *)((_sp_) - sizeof(HAL_SavedRegisters)); \ | 108 _regs_ = (HAL_SavedRegisters *)((_sp_) - sizeof(HAL_SavedRegisters)); \ |
| 108 for( _i_ = 0; _i_ < 32; _i_++ ) (_regs_)->d[_i_] = (_id_)|_i_; \ | 109 for( _i_ = 0; _i_ < 32; _i_++ ) (_regs_)->d[_i_] = (_id_)|_i_; \ |
| 109 (_regs_)->d[29] = (CYG_WORD)(_sp_); /* SP = top of stack */ \ | 110 (_regs_)->d[29] = (CYG_WORD)(_sp_); /* SP = top of stack */ \ |
| 110 (_regs_)->d[04] = (CYG_WORD)(_thread_); /* R4 = arg1 = thread ptr */ \ | 111 (_regs_)->d[04] = (CYG_WORD)(_thread_); /* R4 = arg1 = thread ptr */ \ |
| 111 (_regs_)->lo = 0; /* LO = 0 */ \ | 112 (_regs_)->lo = 0; /* LO = 0 */ \ |
| 112 (_regs_)->hi = 0; /* HI = 0 */ \ | 113 (_regs_)->hi = 0; /* HI = 0 */ \ |
| 113 (_regs_)->d[30] = (CYG_WORD)(_sp_); /* FP = top of stack */ \ | 114 (_regs_)->d[30] = (CYG_WORD)(_sp_); /* FP = top of stack */ \ |
| 114 (_regs_)->d[31] = (CYG_WORD)(_entry_); /* LR(d[31]) = entry point */ \ | 115 (_regs_)->d[31] = (CYG_WORD)(_entry_); /* LR(d[31]) = entry point*/ \ |
| 115 (_regs_)->pc = (CYG_WORD)(_entry_); /* PC = entry point */ \ | 116 (_regs_)->pc = (CYG_WORD)(_entry_); /* PC = entry point */ \ |
| 116 _sparg_ = (CYG_ADDRESS)_regs_; \ | 117 _sparg_ = (CYG_ADDRESS)_regs_; \ |
| 117 } | 118 } |
| 118 | 119 |
| 119 //----------------------------------------------------------------------------- | 120 //-------------------------------------------------------------------------- |
| 120 // Context switch macros. | 121 // Context switch macros. |
| 121 // The arguments are pointers to locations where the stack pointer | 122 // The arguments are pointers to locations where the stack pointer |
| 122 // of the current thread is to be stored, and from where the sp of the | 123 // of the current thread is to be stored, and from where the sp of the |
| 123 // next thread is to be fetched. | 124 // next thread is to be fetched. |
| 124 | 125 |
| 125 externC void hal_thread_switch_context( CYG_ADDRESS to, CYG_ADDRESS from ); | 126 externC void hal_thread_switch_context( CYG_ADDRESS to, CYG_ADDRESS from ); |
| 126 externC void hal_thread_load_context( CYG_ADDRESS to ) | 127 externC void hal_thread_load_context( CYG_ADDRESS to ) |
| 127 __attribute__ ((noreturn)); | 128 __attribute__ ((noreturn)); |
| 128 | 129 |
| 129 #define HAL_THREAD_SWITCH_CONTEXT(_fspptr_,_tspptr_) \ | 130 #define HAL_THREAD_SWITCH_CONTEXT(_fspptr_,_tspptr_) \ |
| 130 hal_thread_switch_context((CYG_ADDRESS)_tspptr_,(CYG_ADDRESS)_fspptr_); | 131 hal_thread_switch_context( (CYG_ADDRESS)_tspptr_, \ |
| 132 (CYG_ADDRESS)_fspptr_); | |
| 131 | 133 |
| 132 #define HAL_THREAD_LOAD_CONTEXT(_tspptr_) \ | 134 #define HAL_THREAD_LOAD_CONTEXT(_tspptr_) \ |
| 133 hal_thread_load_context( (CYG_ADDRESS)_tspptr_ ); | 135 hal_thread_load_context( (CYG_ADDRESS)_tspptr_ ); |
| 134 | 136 |
| 135 //----------------------------------------------------------------------------- | 137 //-------------------------------------------------------------------------- |
| 136 // Execution reorder barrier. | 138 // Execution reorder barrier. |
| 137 // When optimizing the compiler can reorder code. In multithreaded systems | 139 // When optimizing the compiler can reorder code. In multithreaded systems |
| 138 // where the order of actions is vital, this can sometimes cause problems. | 140 // where the order of actions is vital, this can sometimes cause problems. |
| 139 // This macro may be inserted into places where reordering should not happen. | 141 // This macro may be inserted into places where reordering should not happen. |
| 140 // The "memory" keyword is potentially unnecessary, but it is harmless to | 142 // The "memory" keyword is potentially unnecessary, but it is harmless to |
| 141 // keep it. | 143 // keep it. |
| 142 | 144 |
| 143 #define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" ) | 145 #define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" ) |
| 144 | 146 |
| 145 //----------------------------------------------------------------------------- | 147 //-------------------------------------------------------------------------- |
| 146 // Breakpoint support | 148 // Breakpoint support |
| 147 // HAL_BREAKPOINT() is a code sequence that will cause a breakpoint to happen if | 149 // HAL_BREAKPOINT() is a code sequence that will cause a breakpoint to |
| 148 // executed. | 150 // happen if executed. |
| 149 // HAL_BREAKINST is the value of the breakpoint instruction and HAL_BREAKINST_SIZE | 151 // HAL_BREAKINST is the value of the breakpoint instruction and |
| 150 // is its size in bytes. | 152 // HAL_BREAKINST_SIZE is its size in bytes. |
| 151 | 153 |
| 154 #ifdef CYG_HAL_MIPS_SIM | |
| 155 #define HAL_BREAKPOINT(_label_) \ | |
| 156 /* This code causes a fake breakpoint. */ \ | |
| 157 asm volatile ( \ | |
| 158 "lui $24,0x0000;" \ | |
| 159 "ori $24,0x0024;" \ | |
| 160 "mtc0 $24,$13;" \ | |
| 161 "lui $25,%%hi(1f);" \ | |
| 162 "ori $25,$25,%%lo(1f);" \ | |
| 163 "j other_vector;" \ | |
| 164 "nop;" \ | |
| 165 ".global " #_label_ ";" \ | |
| 166 #_label_":" \ | |
| 167 "1: nop;" \ | |
| 168 : \ | |
| 169 : \ | |
| 170 : "t8", "t9" \ | |
| 171 ); | |
| 172 #else | |
| 152 #define HAL_BREAKPOINT(_label_) \ | 173 #define HAL_BREAKPOINT(_label_) \ |
| 153 asm volatile (" .globl " #_label_ ";" \ | 174 asm volatile (" .globl " #_label_ ";" \ |
| 154 #_label_":" \ | 175 #_label_":" \ |
| 155 " break 5" \ | 176 " break 5" \ |
| 156 ); | 177 ); |
| 178 #endif // CYG_HAL_MIPS_SIM | |
| 157 | 179 |
| 158 #define HAL_BREAKINST 0x0005000d | 180 #define HAL_BREAKINST 0x0005000d |
| 159 | 181 |
| 160 #define HAL_BREAKINST_SIZE 4 | 182 #define HAL_BREAKINST_SIZE 4 |
| 161 | 183 |
| 162 //----------------------------------------------------------------------------- | 184 //-------------------------------------------------------------------------- |
| 163 // Thread register state manipulation for GDB support. | 185 // Thread register state manipulation for GDB support. |
| 164 | 186 |
| 165 // Translate a stack pointer as saved by the thread context macros above into | 187 // Translate a stack pointer as saved by the thread context macros above into |
| 166 // a pointer to a HAL_SavedRegisters structure. | 188 // a pointer to a HAL_SavedRegisters structure. |
| 167 #define HAL_THREAD_GET_SAVED_REGISTERS( _sp_, _regs_ ) \ | 189 #define HAL_THREAD_GET_SAVED_REGISTERS( _sp_, _regs_ ) \ |
| 168 (_regs_) = (HAL_SavedRegisters *)(_sp_) | 190 (_regs_) = (HAL_SavedRegisters *)(_sp_) |
| 169 | 191 |
| 170 // Copy a set of registers from a HAL_SavedRegisters structure into a | 192 // Copy a set of registers from a HAL_SavedRegisters structure into a |
| 171 // GDB ordered array. | 193 // GDB ordered array. |
| 172 #define HAL_GET_GDB_REGISTERS( _aregval_ , _regs_ ) \ | 194 #define HAL_GET_GDB_REGISTERS( _aregval_ , _regs_ ) \ |
| 200 (_regs_)->badvr = _regval_[35]; \ | 222 (_regs_)->badvr = _regval_[35]; \ |
| 201 (_regs_)->cause = _regval_[36]; \ | 223 (_regs_)->cause = _regval_[36]; \ |
| 202 (_regs_)->pc = _regval_[37]; \ | 224 (_regs_)->pc = _regval_[37]; \ |
| 203 } | 225 } |
| 204 | 226 |
| 205 //----------------------------------------------------------------------------- | 227 //-------------------------------------------------------------------------- |
| 206 // HAL setjmp | 228 // HAL setjmp |
| 207 | 229 // Note: These definitions are repeated in hal_arch.h. If changes are |
| 208 #define HAL_JMP_BUF_SIZE 11 | 230 // required remember to update both sets. |
| 209 | 231 |
| 210 typedef cyg_uint32 hal_jmp_buf[HAL_JMP_BUF_SIZE]; | 232 #define CYGARC_JMP_BUF_SP 0 |
| 233 #define CYGARC_JMP_BUF_R16 1 | |
| 234 #define CYGARC_JMP_BUF_R17 2 | |
| 235 #define CYGARC_JMP_BUF_R18 3 | |
| 236 #define CYGARC_JMP_BUF_R19 4 | |
| 237 #define CYGARC_JMP_BUF_R20 5 | |
| 238 #define CYGARC_JMP_BUF_R21 6 | |
| 239 #define CYGARC_JMP_BUF_R22 7 | |
| 240 #define CYGARC_JMP_BUF_R23 8 | |
| 241 #define CYGARC_JMP_BUF_R28 9 | |
| 242 #define CYGARC_JMP_BUF_R30 10 | |
| 243 #define CYGARC_JMP_BUF_R31 11 | |
| 244 | |
| 245 #define CYGARC_JMP_BUF_SIZE 12 | |
| 246 | |
| 247 typedef cyg_uint32 hal_jmp_buf[CYGARC_JMP_BUF_SIZE]; | |
| 211 | 248 |
| 212 externC int hal_setjmp(hal_jmp_buf env); | 249 externC int hal_setjmp(hal_jmp_buf env); |
| 213 externC void hal_longjmp(hal_jmp_buf env, int val); | 250 externC void hal_longjmp(hal_jmp_buf env, int val); |
| 214 | 251 |
| 215 //----------------------------------------------------------------------------- | 252 //------------------------------------------------------------------------- |
| 216 // Idle thread code. | 253 // Idle thread code. |
| 217 // This macro is called in the idle thread loop, and gives the HAL the | 254 // This macro is called in the idle thread loop, and gives the HAL the |
| 218 // chance to insert code. Typical idle thread behaviour might be to halt the | 255 // chance to insert code. Typical idle thread behaviour might be to halt the |
| 219 // processor. | 256 // processor. |
| 220 | 257 |
| 221 externC void hal_idle_thread_action(cyg_uint32 loop_count); | 258 externC void hal_idle_thread_action(cyg_uint32 loop_count); |
| 222 | 259 |
| 223 #define HAL_IDLE_THREAD_ACTION(_count_) hal_idle_thread_action(_count_) | 260 #define HAL_IDLE_THREAD_ACTION(_count_) hal_idle_thread_action(_count_) |
| 224 | 261 |
| 225 //----------------------------------------------------------------------------- | 262 //-------------------------------------------------------------------------- |
| 263 // Minimal and sensible stack sizes: the intention is that applications | |
| 264 // will use these to provide a stack size in the first instance prior to | |
| 265 // proper analysis. Idle thread stack should be this big. | |
| 266 | |
| 267 // THESE ARE NOT INTENDED TO BE MICROMETRICALLY ACCURATE FIGURES. | |
| 268 // THEY ARE HOWEVER ENOUGH TO START PROGRAMMING. | |
| 269 // YOU MUST MAKE YOUR STACKS LARGER IF YOU HAVE LARGE "AUTO" VARIABLES! | |
| 270 | |
| 271 // We define quite large stack needs for SPARClite, for it requires 576 | |
| 272 // bytes (144 words) to process an interrupt and thread-switch, and | |
| 273 // momentarily, but needed in case of recursive interrupts, it needs 208 | |
| 274 // words - if a sequence of saves to push out other regsets is interrupted. | |
| 275 | |
| 276 // This is not a config option because it should not be adjusted except | |
| 277 // under "enough rope" sort of disclaimers. | |
| 278 | |
| 279 // Worst case stack frame size: return link + 5 pushed registers. | |
| 280 #define CYGNUM_HAL_STACK_FRAME_SIZE (24) | |
| 281 | |
| 282 // Stack needed for a context switch: | |
| 283 #define CYGNUM_HAL_STACK_CONTEXT_SIZE (42*4) | |
| 284 | |
| 285 // Interrupt + call to ISR, interrupt_end() and the DSR | |
| 286 #define CYGNUM_HAL_STACK_INTERRUPT_SIZE (4+2*CYGNUM_HAL_STACK_CONTEXT_SIZE) | |
| 287 | |
| 288 #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK | |
| 289 | |
| 290 // An interrupt stack which is large enough for all possible interrupt | |
| 291 // conditions (and only used for that purpose) exists. "User" stacks | |
| 292 // can be much smaller | |
| 293 | |
| 294 #define CYGNUM_HAL_STACK_SIZE_MINIMUM (CYGNUM_HAL_STACK_CONTEXT_SIZE+ \ | |
| 295 CYGNUM_HAL_STACK_INTERRUPT_SIZE*2+ \ | |
| 296 CYGNUM_HAL_STACK_FRAME_SIZE*4) | |
| 297 #define CYGNUM_HAL_STACK_SIZE_TYPICAL (2048) | |
| 298 | |
| 299 #else // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK | |
| 300 | |
| 301 // No separate interrupt stack exists. Make sure all threads contain | |
| 302 // a stack sufficiently large. | |
| 303 | |
| 304 #define CYGNUM_HAL_STACK_SIZE_MINIMUM (4096) | |
| 305 #define CYGNUM_HAL_STACK_SIZE_TYPICAL (4096) | |
| 306 | |
| 307 #endif | |
| 308 | |
| 309 //-------------------------------------------------------------------------- | |
| 226 #endif // CYGONCE_HAL_HAL_ARCH_H | 310 #endif // CYGONCE_HAL_HAL_ARCH_H |
| 227 // End of hal_arch.h | 311 // End of hal_arch.h |
| 228 | |
| 229 |
