Mercurial > flash_v2
annotate packages/hal/powerpc/arch/current/include/hal_arch.h @ 66:bf00f99aec69 ecos-sw-2000-02-02
Merge from eCos master repository on 2000-02-02-19:16:44-GMT
| author | jlarmour |
|---|---|
| date | Wed, 02 Feb 2000 19:57:02 +0000 |
| parents | c38311975d4f |
| children | 435cced73e2f |
| rev | line source |
|---|---|
| 0 | 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#### | |
|
64
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
12 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
13 // ------------------------------------------- |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
14 // The contents of this file are subject to the Red Hat eCos Public License |
|
66
bf00f99aec69
Merge from eCos master repository on 2000-02-02-19:16:44-GMT
jlarmour
parents:
64
diff
changeset
|
15 // Version 1.1 (the "License"); you may not use this file except in |
|
64
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
16 // compliance with the License. You may obtain a copy of the License at |
|
66
bf00f99aec69
Merge from eCos master repository on 2000-02-02-19:16:44-GMT
jlarmour
parents:
64
diff
changeset
|
17 // http://www.redhat.com/ |
|
64
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
18 // |
|
66
bf00f99aec69
Merge from eCos master repository on 2000-02-02-19:16:44-GMT
jlarmour
parents:
64
diff
changeset
|
19 // Software distributed under the License is distributed on an "AS IS" |
|
64
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
20 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
21 // License for the specific language governing rights and limitations under |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
22 // the License. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
23 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
24 // The Original Code is eCos - Embedded Configurable Operating System, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
25 // released September 30, 1998. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
26 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
27 // The Initial Developer of the Original Code is Red Hat. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
28 // Portions created by Red Hat are |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
29 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
30 // All Rights Reserved. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
31 // ------------------------------------------- |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
6
diff
changeset
|
32 // |
| 0 | 33 //####COPYRIGHTEND#### |
| 34 //============================================================================= | |
| 35 //#####DESCRIPTIONBEGIN#### | |
| 36 // | |
| 37 // Author(s): nickg | |
| 38 // Contributors: nickg | |
| 39 // Date: 1997-09-08 | |
| 40 // Purpose: Define architecture abstractions | |
| 41 // Usage: #include <cyg/hal/hal_arch.h> | |
| 42 | |
| 43 // | |
| 44 //####DESCRIPTIONEND#### | |
| 45 // | |
| 46 //============================================================================= | |
| 47 | |
| 2 | 48 #include <pkgconf/hal.h> |
| 0 | 49 #include <cyg/infra/cyg_type.h> |
| 50 | |
| 51 //----------------------------------------------------------------------------- | |
| 52 // Processor saved states: | |
| 53 // The layout of this structure is also defined in "ppc.inc", for assembly | |
| 54 // code. Do not change this without changing that (or vice versa). | |
| 55 | |
| 56 typedef struct | |
| 57 { | |
| 58 // These are common to all saved states | |
| 59 cyg_uint32 d[32]; // Data regs | |
| 60 cyg_uint32 cr; // Condition Reg | |
| 61 cyg_uint32 xer; // XER | |
| 62 cyg_uint32 lr; // Link Reg | |
| 63 cyg_uint32 ctr; // Count Reg | |
| 64 | |
| 2 | 65 // These are saved for exceptions and interrupts, but may also |
| 66 // be saved in a context switch if thread-aware debugging is enabled. | |
| 67 cyg_uint32 msr; // Machine State Reg | |
| 68 cyg_uint32 pc; // Program Counter | |
| 69 | |
| 0 | 70 // These are only saved for exceptions and interrupts |
| 71 cyg_uint32 vector; // Vector number | |
| 72 | |
| 73 // These are only saved for exceptions, and are not restored | |
| 74 // when continued. | |
| 75 cyg_uint32 hid0; // Hw Implementation Dependent | |
| 76 cyg_uint32 dar; // Data Address Reg | |
| 77 cyg_uint32 dsisr; // DSISR | |
| 78 cyg_uint32 pvr; // Processor Version | |
| 79 | |
| 2 | 80 // Eventually add BATs, SRs and FP registers too. |
| 0 | 81 } HAL_SavedRegisters; |
| 82 | |
| 83 //----------------------------------------------------------------------------- | |
| 84 // Exception handling function. | |
| 85 // This function is defined by the kernel according to this prototype. It is | |
| 86 // invoked from the HAL to deal with any CPU exceptions that the HAL does | |
| 87 // not want to deal with itself. It usually invokes the kernel's exception | |
| 88 // delivery mechanism. | |
| 89 | |
| 2 | 90 externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data ); |
| 0 | 91 |
| 92 //----------------------------------------------------------------------------- | |
| 93 // Bit manipulation macros | |
| 94 | |
| 95 #define HAL_LSBIT_INDEX(index, mask) \ | |
| 96 asm ( "neg 11,%1;" \ | |
| 97 "and 11,11,%1;" \ | |
| 98 "cntlzw %0,11;" \ | |
| 99 "subfic %0,%0,31;" \ | |
| 100 : "=r" (index) \ | |
| 101 : "r" (mask) \ | |
| 102 : "r11" \ | |
| 103 ); | |
| 104 | |
| 105 #define HAL_MSBIT_INDEX(index, mask) \ | |
| 106 asm ( "cntlzw %1,%0" : "=r" (mask) : "r" (index) ); | |
| 107 | |
| 108 //----------------------------------------------------------------------------- | |
| 2 | 109 // eABI |
| 110 #define CYGARC_PPC_STACK_FRAME_SIZE 56 // size of a stack frame | |
| 111 | |
| 112 //----------------------------------------------------------------------------- | |
| 0 | 113 // Context Initialization |
| 114 // Initialize the context of a thread. | |
| 115 // Arguments: | |
| 2 | 116 // _sparg_ name of variable containing current sp, will be written with new sp |
| 0 | 117 // _thread_ thread object address, passed as argument to entry point |
| 118 // _entry_ entry point address. | |
| 119 // _id_ bit pattern used in initializing registers, for debugging. | |
| 120 | |
| 2 | 121 #define HAL_THREAD_INIT_CONTEXT( _sparg_, _thread_, _entry_, _id_ ) \ |
| 122 CYG_MACRO_START \ | |
|
6
d376b777e2ce
Merge from eCos master repository on 1999-05-14-19:27:43-BST
jlarmour
parents:
2
diff
changeset
|
123 register CYG_WORD _sp_ = (((CYG_WORD)_sparg_) &~15) \ |
|
d376b777e2ce
Merge from eCos master repository on 1999-05-14-19:27:43-BST
jlarmour
parents:
2
diff
changeset
|
124 - CYGARC_PPC_STACK_FRAME_SIZE; \ |
| 2 | 125 register HAL_SavedRegisters *_regs_; \ |
| 126 int _i_; \ | |
| 127 _regs_ = (HAL_SavedRegisters *)((_sp_) - sizeof(HAL_SavedRegisters)); \ | |
| 128 for( _i_ = 0; _i_ < 32; _i_++ ) (_regs_)->d[_i_] = (_id_)|_i_; \ | |
| 129 (_regs_)->d[01] = (CYG_WORD)(_sp_); /* SP = top of stack */ \ | |
| 130 (_regs_)->d[03] = (CYG_WORD)(_thread_); /* R3 = arg1 = thread ptr */ \ | |
| 131 (_regs_)->cr = 0; /* CR = 0 */ \ | |
| 132 (_regs_)->xer = 0; /* XER = 0 */ \ | |
| 133 (_regs_)->lr = (CYG_WORD)(_entry_); /* LR = entry point */ \ | |
| 134 (_regs_)->pc = (CYG_WORD)(_entry_); /* set PC for thread dbg */ \ | |
| 135 (_regs_)->ctr = 0; /* CTR = 0 */ \ | |
| 136 _sparg_ = (CYG_ADDRESS)_regs_; \ | |
| 0 | 137 CYG_MACRO_END |
| 138 | |
| 139 //----------------------------------------------------------------------------- | |
| 140 // Context switch macros. | |
| 141 // The arguments are pointers to locations where the stack pointer | |
| 142 // of the current thread is to be stored, and from where the sp of the | |
| 143 // next thread is to be fetched. | |
| 144 | |
| 145 externC void hal_thread_switch_context( CYG_ADDRESS to, CYG_ADDRESS from ); | |
| 146 externC void hal_thread_load_context( CYG_ADDRESS to ) | |
| 147 __attribute__ ((noreturn)); | |
| 148 | |
| 149 #define HAL_THREAD_SWITCH_CONTEXT(_fspptr_,_tspptr_) \ | |
| 150 hal_thread_switch_context((CYG_ADDRESS)_tspptr_,(CYG_ADDRESS)_fspptr_); | |
| 151 | |
| 152 #define HAL_THREAD_LOAD_CONTEXT(_tspptr_) \ | |
| 153 hal_thread_load_context( (CYG_ADDRESS)_tspptr_ ); | |
| 154 | |
| 155 //----------------------------------------------------------------------------- | |
| 156 // Execution reorder barrier. | |
| 157 // When optimizing the compiler can reorder code. In multithreaded systems | |
| 158 // where the order of actions is vital, this can sometimes cause problems. | |
| 159 // This macro may be inserted into places where reordering should not happen. | |
| 160 | |
| 161 #define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" ) | |
| 162 | |
| 163 //----------------------------------------------------------------------------- | |
| 164 // Breakpoint support | |
| 165 // HAL_BREAKPOINT() is a code sequence that will cause a breakpoint to happen | |
| 166 // if executed. | |
| 167 // HAL_BREAKINST is the value of the breakpoint instruction and | |
| 168 // HAL_BREAKINST_SIZE is its size in bytes. | |
| 169 | |
| 170 #define HAL_BREAKPOINT(_label_) \ | |
| 171 asm volatile (" .globl " #_label_ ";" \ | |
| 172 #_label_":" \ | |
| 173 " trap" \ | |
| 174 ); | |
| 175 | |
| 176 #define HAL_BREAKINST 0x7d821008 | |
| 177 | |
| 178 #define HAL_BREAKINST_SIZE 4 | |
| 179 | |
| 180 //----------------------------------------------------------------------------- | |
| 181 // Thread register state manipulation for GDB support. | |
| 182 | |
| 183 // Translate a stack pointer as saved by the thread context macros above into | |
| 184 // a pointer to a HAL_SavedRegisters structure. | |
| 185 #define HAL_THREAD_GET_SAVED_REGISTERS( _sp_, _regs_ ) \ | |
| 186 (_regs_) = (HAL_SavedRegisters *)(_sp_) | |
| 187 | |
| 188 // Copy a set of registers from a HAL_SavedRegisters structure into a | |
| 189 // GDB ordered array. | |
| 190 #define HAL_GET_GDB_REGISTERS( _aregval_, _regs_ ) \ | |
| 191 CYG_MACRO_START \ | |
| 192 CYG_ADDRWORD *_regval_ = (CYG_ADDRWORD *)(_aregval_); \ | |
| 193 int _i_; \ | |
| 194 \ | |
| 195 for( _i_ = 0; _i_ < 32; _i_++ ) \ | |
| 196 _regval_[_i_] = (_regs_)->d[_i_]; \ | |
| 197 \ | |
| 198 _regval_[64] = (_regs_)->pc; \ | |
| 199 _regval_[65] = (_regs_)->msr; \ | |
| 200 _regval_[66] = (_regs_)->cr; \ | |
| 201 _regval_[67] = (_regs_)->lr; \ | |
| 202 _regval_[68] = (_regs_)->ctr; \ | |
| 203 _regval_[69] = (_regs_)->xer; \ | |
| 204 CYG_MACRO_END | |
| 205 | |
| 206 // Copy a GDB ordered array into a HAL_SavedRegisters structure. | |
| 207 #define HAL_SET_GDB_REGISTERS( _regs_ , _aregval_ ) \ | |
| 208 CYG_MACRO_START \ | |
| 209 CYG_ADDRWORD *_regval_ = (CYG_ADDRWORD *)(_aregval_); \ | |
| 210 int _i_; \ | |
| 211 \ | |
| 212 for( _i_ = 0; _i_ < 32; _i_++ ) \ | |
| 213 (_regs_)->d[_i_] = _regval_[_i_]; \ | |
| 214 \ | |
| 215 (_regs_)->pc = _regval_[64]; \ | |
| 216 (_regs_)->msr = _regval_[65]; \ | |
| 217 (_regs_)->cr = _regval_[66]; \ | |
| 218 (_regs_)->lr = _regval_[67]; \ | |
| 219 (_regs_)->ctr = _regval_[68]; \ | |
| 220 (_regs_)->xer = _regval_[69]; \ | |
| 221 CYG_MACRO_END | |
| 222 | |
| 223 //----------------------------------------------------------------------------- | |
| 224 // HAL setjmp | |
| 2 | 225 // Note: These definitions are repeated in context.S. If changes are required |
| 226 // remember to update both sets. | |
| 0 | 227 |
| 2 | 228 #define CYGARC_JMP_BUF_SP 0 |
| 229 #define CYGARC_JMP_BUF_R2 1 | |
| 230 #define CYGARC_JMP_BUF_R13 2 | |
| 231 #define CYGARC_JMP_BUF_R14 3 | |
| 232 #define CYGARC_JMP_BUF_R15 4 | |
| 233 #define CYGARC_JMP_BUF_R16 5 | |
| 234 #define CYGARC_JMP_BUF_R17 6 | |
| 235 #define CYGARC_JMP_BUF_R18 7 | |
| 236 #define CYGARC_JMP_BUF_R19 8 | |
| 237 #define CYGARC_JMP_BUF_R20 9 | |
| 238 #define CYGARC_JMP_BUF_R21 10 | |
| 239 #define CYGARC_JMP_BUF_R22 11 | |
| 240 #define CYGARC_JMP_BUF_R23 12 | |
| 241 #define CYGARC_JMP_BUF_R24 13 | |
| 242 #define CYGARC_JMP_BUF_R25 14 | |
| 243 #define CYGARC_JMP_BUF_R26 15 | |
| 244 #define CYGARC_JMP_BUF_R27 16 | |
| 245 #define CYGARC_JMP_BUF_R28 17 | |
| 246 #define CYGARC_JMP_BUF_R29 18 | |
| 247 #define CYGARC_JMP_BUF_R30 19 | |
| 248 #define CYGARC_JMP_BUF_R31 20 | |
| 249 #define CYGARC_JMP_BUF_LR 21 | |
| 250 #define CYGARC_JMP_BUF_CR 22 | |
| 0 | 251 |
| 2 | 252 #define CYGARC_JMP_BUF_SIZE 23 |
| 253 | |
| 254 typedef cyg_uint32 hal_jmp_buf[CYGARC_JMP_BUF_SIZE]; | |
| 0 | 255 |
| 256 externC int hal_setjmp(hal_jmp_buf env); | |
| 257 externC void hal_longjmp(hal_jmp_buf env, int val); | |
| 258 | |
| 259 //----------------------------------------------------------------------------- | |
| 260 // Idle thread code. | |
| 261 // This macro is called in the idle thread loop, and gives the HAL the | |
| 262 // chance to insert code. Typical idle thread behaviour might be to halt the | |
| 263 // processor. | |
| 264 | |
| 265 externC void hal_idle_thread_action(cyg_uint32 loop_count); | |
| 266 | |
| 267 #define HAL_IDLE_THREAD_ACTION(_count_) hal_idle_thread_action(_count_) | |
| 268 | |
| 269 //----------------------------------------------------------------------------- | |
| 2 | 270 // Minimal and sensible stack sizes: the intention is that applications |
| 271 // will use these to provide a stack size in the first instance prior to | |
| 272 // proper analysis. Idle thread stack should be this big. | |
| 273 | |
| 274 // THESE ARE NOT INTENDED TO BE MICROMETRICALLY ACCURATE FIGURES. | |
| 275 // THEY ARE HOWEVER ENOUGH TO START PROGRAMMING. | |
| 276 // YOU MUST MAKE YOUR STACKS LARGER IF YOU HAVE LARGE "AUTO" VARIABLES! | |
| 277 | |
| 278 // This is not a config option because it should not be adjusted except | |
| 279 // under "enough rope" sort of disclaimers. | |
| 280 | |
| 281 // Stack frame overhead per call. The PPC ABI defines regs 13..31 as callee | |
| 282 // saved. callee saved variables are irrelevant for us as they would contain | |
| 283 // automatic variables, so we only count the caller-saved regs here | |
| 284 // So that makes r0..r12 + cr, xer, lr, ctr: | |
| 285 #define CYGNUM_HAL_STACK_FRAME_SIZE (4 * 17) | |
| 286 | |
| 287 // Stack needed for a context switch (ppcref_context_size from ppc.inc) | |
| 288 #define CYGNUM_HAL_STACK_CONTEXT_SIZE (4 * 38) | |
| 289 | |
| 290 // Interrupt + call to ISR, interrupt_end() and the DSR | |
| 291 #define CYGNUM_HAL_STACK_INTERRUPT_SIZE \ | |
| 292 ((43*4 /* sizeof(HAL_SavedRegisters) */) + 2 * CYGNUM_HAL_STACK_FRAME_SIZE) | |
| 293 | |
| 294 // We have lots of registers so no particular amount is added in for | |
| 295 // typical local variable usage. | |
| 296 | |
| 297 // We define a minimum stack size as the minimum any thread could ever | |
| 298 // legitimately get away with. We can throw asserts if users ask for less | |
| 299 // than this. Allow enough for three interrupt sources - clock, serial and | |
| 300 // one other | |
| 301 | |
| 302 #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK | |
| 303 | |
| 304 // An interrupt stack which is large enough for all possible interrupt | |
| 305 // conditions (and only used for that purpose) exists. "User" stacks | |
| 306 // can therefore be much smaller | |
| 307 | |
| 308 # define CYGNUM_HAL_STACK_SIZE_MINIMUM \ | |
| 309 (16*CYGNUM_HAL_STACK_FRAME_SIZE + 2*CYGNUM_HAL_STACK_INTERRUPT_SIZE) | |
| 310 | |
| 311 #else | |
| 312 | |
| 313 // No separate interrupt stack exists. Make sure all threads contain | |
| 314 // a stack sufficiently large | |
| 315 # define CYGNUM_HAL_STACK_SIZE_MINIMUM \ | |
| 316 (((2+3)*CYGNUM_HAL_STACK_INTERRUPT_SIZE) + \ | |
| 317 (16*CYGNUM_HAL_STACK_FRAME_SIZE)) | |
| 318 #endif | |
| 319 | |
| 320 // Now make a reasonable choice for a typical thread size. Pluck figures | |
| 321 // from thin air and say 30 call frames with an average of 16 words of | |
| 322 // automatic variables per call frame | |
| 323 #define CYGNUM_HAL_STACK_SIZE_TYPICAL \ | |
| 324 (CYGNUM_HAL_STACK_SIZE_MINIMUM + \ | |
| 325 30 * (CYGNUM_HAL_STACK_FRAME_SIZE+(16*4))) | |
| 326 | |
| 327 //----------------------------------------------------------------------------- | |
| 0 | 328 #endif // CYGONCE_HAL_ARCH_H |
| 329 // End of hal_arch.h |
