Mercurial > ecos
annotate packages/hal/arm/arch/current/include/hal_arch.h @ 36:e97d78785e2d ecos-sw-1999-09-12
Merge from eCos master repository on 1999-09-12-15:40:34-BST
| author | jlarmour |
|---|---|
| date | Sun, 12 Sep 1999 15:26:05 +0000 |
| parents | d376b777e2ce |
| children | e7ba79f6d3a8 |
| rev | line source |
|---|---|
| 2 | 1 #ifndef CYGONCE_HAL_ARCH_H |
| 2 #define CYGONCE_HAL_ARCH_H | |
| 3 | |
| 4 //========================================================================== | |
| 5 // | |
| 6 // hal_arch.h | |
| 7 // | |
| 8 // Architecture specific abstractions | |
| 9 // | |
| 10 //========================================================================== | |
| 11 //####COPYRIGHTBEGIN#### | |
| 12 // | |
| 13 // ------------------------------------------- | |
| 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 | |
| 16 // compliance with the License. You may obtain a copy of the License at | |
| 17 // http://sourceware.cygnus.com/ecos | |
| 18 // | |
| 19 // Software distributed under the License is distributed on an "AS IS" | |
| 20 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the | |
| 21 // License for the specific language governing rights and limitations under | |
| 22 // the License. | |
| 23 // | |
| 24 // The Original Code is eCos - Embedded Cygnus Operating System, released | |
| 25 // September 30, 1998. | |
| 26 // | |
| 27 // The Initial Developer of the Original Code is Cygnus. Portions created | |
| 28 // by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. | |
| 29 // ------------------------------------------- | |
| 30 // | |
| 31 //####COPYRIGHTEND#### | |
| 32 //========================================================================== | |
| 33 //#####DESCRIPTIONBEGIN#### | |
| 34 // | |
| 35 // Author(s): nickg, gthomas | |
| 36 // Contributors: nickg, gthomas | |
| 37 // Date: 1999-02-20 | |
| 38 // Purpose: Define architecture abstractions | |
| 39 // Usage: #include <cyg/hal/hal_arch.h> | |
| 40 | |
| 41 // | |
| 42 //####DESCRIPTIONEND#### | |
| 43 // | |
| 44 //========================================================================== | |
| 45 | |
| 46 #include <pkgconf/hal.h> // To decide on stack usage | |
| 47 #include <cyg/infra/cyg_type.h> | |
| 48 | |
| 49 // | |
| 50 // CPSR Register defines | |
| 51 // | |
| 52 | |
| 53 #define CPSR_IRQ_DISABLE 0x80 // IRQ disabled when =1 | |
| 54 #define CPSR_FIQ_DISABLE 0x40 // FIQ disabled when =1 | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
55 #define CPSR_FIQ_MODE 0x11 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
56 #define CPSR_IRQ_MODE 0x12 |
| 2 | 57 #define CPSR_SUPERVISOR_MODE 0x13 |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
58 #define CPSR_UNDEF_MODE 0x1B |
| 2 | 59 |
| 60 #define CPSR_MODE_BITS 0x1F | |
| 61 | |
| 62 #define CPSR_INITIAL (CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SUPERVISOR_MODE) | |
| 63 #define CPSR_THREAD_INITIAL (CPSR_SUPERVISOR_MODE) | |
| 64 | |
| 65 //-------------------------------------------------------------------------- | |
| 66 // Processor saved states: | |
| 67 // The layout of this structure is also defined in "arm.inc", for assembly | |
| 68 // code, which will be generated automatically if this file changes. | |
| 69 | |
| 70 #define HAL_THREAD_CONTEXT_FIRST 0 | |
| 71 #define HAL_THREAD_CONTEXT_R0 (0-HAL_THREAD_CONTEXT_FIRST) | |
| 72 #define HAL_THREAD_CONTEXT_R4 (4-HAL_THREAD_CONTEXT_FIRST) | |
| 73 #define HAL_THREAD_CONTEXT_R10 (10-HAL_THREAD_CONTEXT_FIRST) | |
| 74 #define HAL_THREAD_CONTEXT_LAST 10 | |
| 75 #define HAL_NUM_THREAD_CONTEXT_REGS (HAL_THREAD_CONTEXT_LAST - \ | |
| 76 HAL_THREAD_CONTEXT_FIRST+1) | |
| 77 | |
| 78 // It seems that r0-r3,r12 are considered scratch by function calls | |
| 79 | |
| 80 typedef struct | |
| 81 { | |
| 82 // These are common to all saved states | |
| 83 cyg_uint32 d[HAL_NUM_THREAD_CONTEXT_REGS] ; // Data regs (r0..r10) | |
| 84 cyg_uint32 fp; // (r11) Frame pointer | |
| 85 cyg_uint32 sp; // (r13) Stack pointer | |
| 86 cyg_uint32 lr; // (r14) Link Reg | |
| 87 cyg_uint32 pc; // (r15) PC place holder | |
| 88 // (never used) | |
| 89 cyg_uint32 cpsr; // Condition Reg | |
| 90 cyg_uint32 ip; // (r12) Previous stack | |
| 91 // pointer | |
| 92 // These are only saved for exceptions and interrupts | |
| 93 cyg_uint32 vector; // Vector number | |
| 94 cyg_uint32 msr; // Machine State Reg | |
| 95 | |
| 96 } HAL_SavedRegisters; | |
| 97 | |
| 98 //------------------------------------------------------------------------- | |
| 99 // Exception handling function. | |
| 100 // This function is defined by the kernel according to this prototype. It is | |
| 101 // invoked from the HAL to deal with any CPU exceptions that the HAL does | |
| 102 // not want to deal with itself. It usually invokes the kernel's exception | |
| 103 // delivery mechanism. | |
| 104 | |
| 105 externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data ); | |
| 106 | |
| 107 //------------------------------------------------------------------------- | |
| 108 // Bit manipulation macros | |
| 109 | |
| 110 externC int hal_lsbindex(int); | |
| 111 externC int hal_msbindex(int); | |
| 112 | |
| 113 #define HAL_LSBIT_INDEX(index, mask) index = hal_lsbindex(mask) | |
| 114 #define HAL_MSBIT_INDEX(index, mask) index = hal_msbindex(mask) | |
| 115 | |
| 116 //------------------------------------------------------------------------- | |
| 117 // Context Initialization | |
| 118 // Initialize the context of a thread. | |
| 119 // Arguments: | |
| 120 // _sparg_ name of variable containing current sp, will be changed to new sp | |
| 121 // _thread_ thread object address, passed as argument to entry point | |
| 122 // _entry_ entry point address. | |
| 123 // _id_ bit pattern used in initializing registers, for debugging. | |
| 124 | |
| 125 #define HAL_THREAD_INIT_CONTEXT( _sparg_, _thread_, _entry_, _id_ ) \ | |
| 126 CYG_MACRO_START \ | |
|
6
d376b777e2ce
Merge from eCos master repository on 1999-05-14-19:27:43-BST
jlarmour
parents:
4
diff
changeset
|
127 register CYG_WORD _sp_ = ((CYG_WORD)_sparg_) &~15; \ |
| 2 | 128 register HAL_SavedRegisters *_regs_; \ |
| 129 int _i_; \ | |
| 130 _regs_ = (HAL_SavedRegisters *)((_sp_) - sizeof(HAL_SavedRegisters)); \ | |
| 131 for( _i_ = HAL_THREAD_CONTEXT_FIRST; _i_ <= HAL_THREAD_CONTEXT_LAST; \ | |
| 132 _i_++ ) \ | |
| 133 (_regs_)->d[_i_] = (_id_)|_i_; \ | |
| 134 (_regs_)->d[00] = (CYG_WORD)(_thread_); /* R0 = arg1 = thread ptr */ \ | |
| 135 (_regs_)->sp = (CYG_WORD)(_sp_); /* SP = top of stack */ \ | |
| 136 (_regs_)->lr = (CYG_WORD)(_entry_); /* LR = entry point */ \ | |
| 137 (_regs_)->pc = (CYG_WORD)(_entry_); /* PC = [initial] entry point */\ | |
| 138 (_regs_)->cpsr = (CPSR_THREAD_INITIAL); /* PSR = Interrupt enabled */ \ | |
| 139 _sparg_ = (CYG_ADDRESS)_regs_; \ | |
| 140 CYG_MACRO_END | |
| 141 | |
| 142 //-------------------------------------------------------------------------- | |
| 143 // Context switch macros. | |
| 144 // The arguments are pointers to locations where the stack pointer | |
| 145 // of the current thread is to be stored, and from where the sp of the | |
| 146 // next thread is to be fetched. | |
| 147 | |
| 148 externC void hal_thread_switch_context( CYG_ADDRESS to, CYG_ADDRESS from ); | |
| 149 externC void hal_thread_load_context( CYG_ADDRESS to ) | |
| 150 __attribute__ ((noreturn)); | |
| 151 | |
| 152 #define HAL_THREAD_SWITCH_CONTEXT(_fspptr_,_tspptr_) \ | |
| 153 hal_thread_switch_context((CYG_ADDRESS)_tspptr_, \ | |
| 154 (CYG_ADDRESS)_fspptr_); | |
| 155 | |
| 156 #define HAL_THREAD_LOAD_CONTEXT(_tspptr_) \ | |
| 157 hal_thread_load_context( (CYG_ADDRESS)_tspptr_ ); | |
| 158 | |
| 159 //-------------------------------------------------------------------------- | |
| 160 // Execution reorder barrier. | |
| 161 // When optimizing the compiler can reorder code. In multithreaded systems | |
| 162 // where the order of actions is vital, this can sometimes cause problems. | |
| 163 // This macro may be inserted into places where reordering should not happen. | |
| 164 | |
| 165 #define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" ) | |
| 166 | |
| 167 //-------------------------------------------------------------------------- | |
| 168 // Breakpoint support | |
| 169 // HAL_BREAKPOINT() is a code sequence that will cause a breakpoint to happen | |
| 170 // if executed. | |
| 171 // HAL_BREAKINST is the value of the breakpoint instruction and | |
| 172 // HAL_BREAKINST_SIZE is its size in bytes. | |
| 173 | |
|
36
e97d78785e2d
Merge from eCos master repository on 1999-09-12-15:40:34-BST
jlarmour
parents:
6
diff
changeset
|
174 #define HAL_BREAKPOINT(_label_) \ |
| 2 | 175 asm volatile (" .globl " #_label_ ";" \ |
| 176 #_label_":" \ | |
| 177 " .word 0xE7FFDEFE" \ | |
| 178 ); | |
| 179 | |
| 180 //#define HAL_BREAKINST {0xFE, 0xDE, 0xFF, 0xE7} | |
| 181 #define HAL_BREAKINST 0xE7FFDEFE | |
| 182 #define HAL_BREAKINST_SIZE 4 | |
| 183 | |
| 184 //-------------------------------------------------------------------------- | |
| 185 // Thread register state manipulation for GDB support. | |
| 186 | |
| 187 // FIX ME!! What does GDB expect? | |
| 188 | |
| 189 // GDB expects the registers in this structure: | |
| 190 // r0..r10, fp, ip, sp, lr, pc - 4 bytes each | |
| 191 // f0..f7 - 12 bytes each (N/A on ARM7) | |
| 192 // fps - 4 bytes (N/A on ARM7) | |
| 193 // ps - 4 bytes | |
| 194 | |
| 195 // Translate a stack pointer as saved by the thread context macros above into | |
| 196 // a pointer to a HAL_SavedRegisters structure. | |
| 197 #define HAL_THREAD_GET_SAVED_REGISTERS( _sp_, _regs_ ) \ | |
| 198 (_regs_) = (HAL_SavedRegisters *)(_sp_) | |
| 199 | |
| 200 // Copy a set of registers from a HAL_SavedRegisters structure into a | |
| 201 // GDB ordered array. | |
| 202 #define HAL_GET_GDB_REGISTERS( _aregval_, _regs_ ) \ | |
| 203 CYG_MACRO_START \ | |
| 204 CYG_ADDRWORD *_regval_ = (CYG_ADDRWORD *)(_aregval_); \ | |
| 205 int _i_; \ | |
| 206 \ | |
| 207 for( _i_ = 0; _i_ <= 10; _i_++ ) \ | |
| 208 _regval_[_i_] = (_regs_)->d[_i_]; \ | |
| 209 \ | |
| 210 _regval_[11] = (_regs_)->fp; \ | |
| 211 _regval_[12] = (_regs_)->ip; \ | |
| 212 _regval_[13] = (_regs_)->sp; \ | |
| 213 _regval_[14] = (_regs_)->lr; \ | |
| 214 _regval_[15] = (_regs_)->pc; \ | |
| 215 _regval_[25] = (_regs_)->cpsr; \ | |
| 216 for( _i_ = 0; _i_ < 8; _i_++ ) \ | |
| 217 _regval_[_i_+16] = 0; \ | |
| 218 CYG_MACRO_END | |
| 219 | |
| 220 // Copy a GDB ordered array into a HAL_SavedRegisters structure. | |
| 221 #define HAL_SET_GDB_REGISTERS( _regs_ , _aregval_ ) \ | |
| 222 CYG_MACRO_START \ | |
| 223 CYG_ADDRWORD *_regval_ = (CYG_ADDRWORD *)(_aregval_); \ | |
| 224 int _i_; \ | |
| 225 \ | |
| 226 for( _i_ = 0; _i_ <= 10; _i_++ ) \ | |
| 227 (_regs_)->d[_i_] = _regval_[_i_]; \ | |
| 228 \ | |
| 229 (_regs_)->fp = _regval_[11]; \ | |
| 230 (_regs_)->ip = _regval_[12]; \ | |
| 231 (_regs_)->sp = _regval_[13]; \ | |
| 232 (_regs_)->lr = _regval_[14]; \ | |
| 233 (_regs_)->pc = _regval_[15]; \ | |
| 234 (_regs_)->cpsr = _regval_[25]; \ | |
| 235 CYG_MACRO_END | |
| 236 | |
| 237 //-------------------------------------------------------------------------- | |
| 238 // HAL setjmp | |
| 239 | |
| 240 #define CYGARC_JMP_BUF_SIZE 16 // Actually 11, but some room left over | |
| 241 | |
| 242 typedef cyg_uint32 hal_jmp_buf[CYGARC_JMP_BUF_SIZE]; | |
| 243 | |
| 244 externC int hal_setjmp(hal_jmp_buf env); | |
| 245 externC void hal_longjmp(hal_jmp_buf env, int val); | |
| 246 | |
| 247 | |
| 248 //-------------------------------------------------------------------------- | |
| 249 // Idle thread code. | |
| 250 // This macro is called in the idle thread loop, and gives the HAL the | |
| 251 // chance to insert code. Typical idle thread behaviour might be to halt the | |
| 252 // processor. | |
| 253 | |
| 254 externC void hal_idle_thread_action(cyg_uint32 loop_count); | |
| 255 | |
| 256 #define HAL_IDLE_THREAD_ACTION(_count_) hal_idle_thread_action(_count_) | |
| 257 | |
| 258 //--------------------------------------------------------------------------- | |
| 259 | |
| 260 // Minimal and sensible stack sizes: the intention is that applications | |
| 261 // will use these to provide a stack size in the first instance prior to | |
| 262 // proper analysis. Idle thread stack should be this big. | |
| 263 | |
| 264 // THESE ARE NOT INTENDED TO BE MICROMETRICALLY ACCURATE FIGURES. | |
| 265 // THEY ARE HOWEVER ENOUGH TO START PROGRAMMING. | |
| 266 // YOU MUST MAKE YOUR STACKS LARGER IF YOU HAVE LARGE "AUTO" VARIABLES! | |
| 267 | |
| 268 // This is not a config option because it should not be adjusted except | |
| 269 // under "enough rope" sort of disclaimers. | |
| 270 | |
| 271 // A minimal, optimized stack frame, rounded up - no autos | |
| 272 #define CYGNUM_HAL_STACK_FRAME_SIZE (4 * 20) | |
| 273 | |
| 274 // Stack needed for a context switch: this is implicit in the estimate for | |
| 275 // interrupts so not explicitly used below: | |
| 276 #define CYGNUM_HAL_STACK_CONTEXT_SIZE (4 * 20) | |
| 277 | |
| 278 // Interrupt + call to ISR, interrupt_end() and the DSR | |
| 279 #define CYGNUM_HAL_STACK_INTERRUPT_SIZE \ | |
| 280 ((4 * 20) + 2 * CYGNUM_HAL_STACK_FRAME_SIZE) | |
| 281 | |
| 282 // Space for the maximum number of nested interrupts, plus room to call functions | |
| 283 #define CYGNUM_HAL_MAX_INTERRUPT_NESTING 4 | |
| 284 | |
| 285 #define CYGNUM_HAL_STACK_SIZE_MINIMUM \ | |
| 286 (CYGNUM_HAL_MAX_INTERRUPT_NESTING * CYGNUM_HAL_STACK_INTERRUPT_SIZE + \ | |
| 287 2 * CYGNUM_HAL_STACK_FRAME_SIZE) | |
| 288 | |
| 289 #define CYGNUM_HAL_STACK_SIZE_TYPICAL \ | |
| 290 (CYGNUM_HAL_STACK_SIZE_MINIMUM + \ | |
| 291 16 * CYGNUM_HAL_STACK_FRAME_SIZE) | |
| 292 | |
| 293 //----------------------------------------------------------------------------- | |
| 294 | |
| 295 #endif // CYGONCE_HAL_ARCH_H | |
| 296 // End of hal_arch.h |
