Mercurial > ecos
comparison packages/hal/h8300/arch/current/include/hal_arch.h @ 208:e0c0827131d1 ecos
Merge from eCos master repository on 2002-05-20-20:11:54-BST
| author | jlarmour |
|---|---|
| date | Mon, 20 May 2002 22:19:26 +0000 |
| parents | |
| children | d2c90368aeef |
comparison
equal
deleted
inserted
replaced
| 207:74c807ddde34 | 208:e0c0827131d1 |
|---|---|
| 1 #ifndef CYGONCE_HAL_HAL_ARCH_H | |
| 2 #define CYGONCE_HAL_HAL_ARCH_H | |
| 3 //========================================================================== | |
| 4 // | |
| 5 // hal_arch.h | |
| 6 // | |
| 7 // Architecture specific abstractions | |
| 8 // | |
| 9 //========================================================================== | |
| 10 //####ECOSGPLCOPYRIGHTBEGIN#### | |
| 11 // ------------------------------------------- | |
| 12 // This file is part of eCos, the Embedded Configurable Operating System. | |
| 13 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. | |
| 14 // | |
| 15 // eCos is free software; you can redistribute it and/or modify it under | |
| 16 // the terms of the GNU General Public License as published by the Free | |
| 17 // Software Foundation; either version 2 or (at your option) any later version. | |
| 18 // | |
| 19 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY | |
| 20 // WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 21 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 22 // for more details. | |
| 23 // | |
| 24 // You should have received a copy of the GNU General Public License along | |
| 25 // with eCos; if not, write to the Free Software Foundation, Inc., | |
| 26 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | |
| 27 // | |
| 28 // As a special exception, if other files instantiate templates or use macros | |
| 29 // or inline functions from this file, or you compile this file and link it | |
| 30 // with other works to produce a work based on this file, this file does not | |
| 31 // by itself cause the resulting work to be covered by the GNU General Public | |
| 32 // License. However the source code for this file must still be made available | |
| 33 // in accordance with section (3) of the GNU General Public License. | |
| 34 // | |
| 35 // This exception does not invalidate any other reasons why a work based on | |
| 36 // this file might be covered by the GNU General Public License. | |
| 37 // | |
| 38 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. | |
| 39 // at http://sources.redhat.com/ecos/ecos-license | |
| 40 // ------------------------------------------- | |
| 41 //####ECOSGPLCOPYRIGHTEND#### | |
| 42 //========================================================================== | |
| 43 //#####DESCRIPTIONBEGIN#### | |
| 44 // | |
| 45 // Author(s): nickg | |
| 46 // Contributors: nickg | |
| 47 // Date: 1999-02-18 | |
| 48 // Purpose: Define architecture abstractions | |
| 49 // Usage: #include <cyg/hal/hal_arch.h> | |
| 50 // | |
| 51 //####DESCRIPTIONEND#### | |
| 52 // | |
| 53 //========================================================================== | |
| 54 | |
| 55 #include <pkgconf/hal.h> | |
| 56 #include <cyg/infra/cyg_type.h> | |
| 57 | |
| 58 #include <cyg/hal/var_arch.h> | |
| 59 | |
| 60 //-------------------------------------------------------------------------- | |
| 61 // Exception handling function. | |
| 62 // This function is defined by the kernel according to this prototype. It is | |
| 63 // invoked from the HAL to deal with any CPU exceptions that the HAL does | |
| 64 // not want to deal with itself. It usually invokes the kernel's exception | |
| 65 // delivery mechanism. | |
| 66 | |
| 67 externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data ); | |
| 68 | |
| 69 //-------------------------------------------------------------------------- | |
| 70 // Bit manipulation routines | |
| 71 | |
| 72 externC cyg_uint32 hal_lsbit_index(cyg_uint32 mask); | |
| 73 externC cyg_uint32 hal_msbit_index(cyg_uint32 mask); | |
| 74 | |
| 75 #define HAL_LSBIT_INDEX(index, mask) index = hal_lsbit_index(mask); | |
| 76 | |
| 77 #define HAL_MSBIT_INDEX(index, mask) index = hal_msbit_index(mask); | |
| 78 | |
| 79 //-------------------------------------------------------------------------- | |
| 80 // Context Initialization | |
| 81 // Initialize the context of a thread. | |
| 82 // Arguments: | |
| 83 // _sp_ name of variable containing current sp, will be written with new sp | |
| 84 // _thread_ thread object address, passed as argument to entry point | |
| 85 // _entry_ entry point address. | |
| 86 // _id_ bit pattern used in initializing registers, for debugging. | |
| 87 | |
| 88 #ifndef HAL_THREAD_INIT_CONTEXT_EXTRA | |
| 89 #define HAL_THREAD_INIT_CONTEXT_EXTRA(_regs_, _id_) | |
| 90 #endif | |
| 91 | |
| 92 #define HAL_THREAD_INIT_CONTEXT( _sp_, _thread_, _entry_, _id_ ) \ | |
| 93 { \ | |
| 94 register HAL_SavedRegisters *_regs_; \ | |
| 95 _regs_ = (HAL_SavedRegisters *)(((CYG_ADDRWORD)(_sp_)&~15) - \ | |
| 96 sizeof(HAL_SavedRegisters)*2); \ | |
| 97 HAL_THREAD_INIT_CONTEXT_EXTRA(_regs_, _id_); \ | |
| 98 _regs_->er0 = (CYG_WORD)(_thread_); \ | |
| 99 _regs_->er1 = (_id_)|0xddd1; \ | |
| 100 _regs_->er2 = (_id_)|0xddd2; \ | |
| 101 _regs_->er3 = (_id_)|0xddd3; \ | |
| 102 _regs_->er4 = (_id_)|0xddd4; \ | |
| 103 _regs_->er5 = (_id_)|0xddd5; \ | |
| 104 _regs_->er6 = (_id_)|0xddd6; \ | |
| 105 _regs_->ccr = 0x00; \ | |
| 106 _regs_->pc = (CYG_WORD)(_entry_); \ | |
| 107 _sp_ = (CYG_ADDRESS)_regs_; \ | |
| 108 } | |
| 109 | |
| 110 //-------------------------------------------------------------------------- | |
| 111 // Context switch macros. | |
| 112 // The arguments are pointers to locations where the stack pointer | |
| 113 // of the current thread is to be stored, and from where the sp of the | |
| 114 // next thread is to be fetched. | |
| 115 | |
| 116 externC void hal_thread_switch_context( CYG_ADDRESS to, CYG_ADDRESS from ); | |
| 117 externC void hal_thread_load_context( CYG_ADDRESS to ) | |
| 118 __attribute__ ((noreturn)); | |
| 119 | |
| 120 #define HAL_THREAD_SWITCH_CONTEXT(_fspptr_,_tspptr_) \ | |
| 121 hal_thread_switch_context((CYG_ADDRESS)_tspptr_, \ | |
| 122 (CYG_ADDRESS)_fspptr_); | |
| 123 | |
| 124 #define HAL_THREAD_LOAD_CONTEXT(_tspptr_) \ | |
| 125 hal_thread_load_context( (CYG_ADDRESS)_tspptr_ ); | |
| 126 | |
| 127 //-------------------------------------------------------------------------- | |
| 128 // Execution reorder barrier. | |
| 129 // When optimizing the compiler can reorder code. In multithreaded systems | |
| 130 // where the order of actions is vital, this can sometimes cause problems. | |
| 131 // This macro may be inserted into places where reordering should not happen. | |
| 132 | |
| 133 #define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" ) | |
| 134 | |
| 135 //-------------------------------------------------------------------------- | |
| 136 // Breakpoint support | |
| 137 // HAL_BREAKPOINT() is a code sequence that will cause a breakpoint to | |
| 138 // happen if executed. | |
| 139 // HAL_BREAKINST is the value of the breakpoint instruction and | |
| 140 // HAL_BREAKINST_SIZE is its size in bytes. | |
| 141 | |
| 142 #define __HAL_BREAKPOINT(_label_) # _label_ | |
| 143 #define HAL_BREAKPOINT(_label_) \ | |
| 144 asm volatile (" .globl " __HAL_BREAKPOINT(_label_) "\n" \ | |
| 145 __HAL_BREAKPOINT(_label_) ":\n\t" \ | |
| 146 "trapa #3" \ | |
| 147 ); | |
| 148 | |
| 149 #define HAL_BREAKINST 0x5703 | |
| 150 | |
| 151 #define HAL_BREAKINST_SIZE 2 | |
| 152 | |
| 153 //-------------------------------------------------------------------------- | |
| 154 // Thread register state manipulation for GDB support. | |
| 155 | |
| 156 // Translate a stack pointer as saved by the thread context macros above into | |
| 157 // a pointer to a HAL_SavedRegisters structure. | |
| 158 #define HAL_THREAD_GET_SAVED_REGISTERS( _sp_, _regs_ ) \ | |
| 159 (_regs_) = (HAL_SavedRegisters *)(_sp_) | |
| 160 | |
| 161 #ifndef HAL_GET_GDB_EXTRA_REGISTERS | |
| 162 #define HAL_GET_GDB_EXTRA_REGISTERS( _regval_, _regs_ ) | |
| 163 #endif | |
| 164 #ifndef HAL_SET_GDB_EXTRA_REGISTERS | |
| 165 #define HAL_SET_GDB_EXTRA_REGISTERS( _regs_, _regval_ ) | |
| 166 #endif | |
| 167 | |
| 168 | |
| 169 // Copy a set of registers from a HAL_SavedRegisters structure into a | |
| 170 // GDB ordered array. | |
| 171 #define HAL_GET_GDB_REGISTERS( _aregval_ , _regs_ ) \ | |
| 172 { \ | |
| 173 CYG_ADDRWORD *_regval_ = (CYG_ADDRWORD *)(_aregval_); \ | |
| 174 \ | |
| 175 _regval_[0] = (_regs_)->er0; \ | |
| 176 _regval_[1] = (_regs_)->er1; \ | |
| 177 _regval_[2] = (_regs_)->er2; \ | |
| 178 _regval_[3] = (_regs_)->er3; \ | |
| 179 _regval_[4] = (_regs_)->er4; \ | |
| 180 _regval_[5] = (_regs_)->er5; \ | |
| 181 _regval_[6] = (_regs_)->er6; \ | |
| 182 \ | |
| 183 _regval_[7] = (CYG_ADDRWORD)(_regs_) + \ | |
| 184 sizeof(HAL_SavedRegisters); \ | |
| 185 _regval_[8] = (_regs_)->pc; \ | |
| 186 _regval_[9] = (_regs_)->ccr; \ | |
| 187 \ | |
| 188 HAL_GET_GDB_EXTRA_REGISTERS( _regval_, _regs_ ); \ | |
| 189 } | |
| 190 | |
| 191 // Copy a GDB ordered array into a HAL_SavedRegisters structure. | |
| 192 #define HAL_SET_GDB_REGISTERS( _regs_ , _aregval_ ) \ | |
| 193 { \ | |
| 194 CYG_ADDRWORD *_regval_ = (CYG_ADDRWORD *)(_aregval_); \ | |
| 195 \ | |
| 196 (_regs_)->er0 = _regval_[0]; \ | |
| 197 (_regs_)->er1 = _regval_[1]; \ | |
| 198 (_regs_)->er2 = _regval_[2]; \ | |
| 199 (_regs_)->er3 = _regval_[3]; \ | |
| 200 (_regs_)->er4 = _regval_[4]; \ | |
| 201 (_regs_)->er5 = _regval_[5]; \ | |
| 202 (_regs_)->er6 = _regval_[6]; \ | |
| 203 \ | |
| 204 (_regs_)->pc = _regval_[8]; \ | |
| 205 (_regs_)->ccr = _regval_[9]; \ | |
| 206 \ | |
| 207 /* We do not allow the SP or PSW to be set. Changing the SP will \ | |
| 208 * mess up the saved state. No PSW is saved on thread context \ | |
| 209 * switches, so there is nowhere to save it to. \ | |
| 210 */ \ | |
| 211 \ | |
| 212 HAL_SET_GDB_EXTRA_REGISTERS( _regs_, _regval_ ); \ | |
| 213 } | |
| 214 | |
| 215 //------------------------------------------------------------------------- | |
| 216 // HAL setjmp | |
| 217 // Note: These definitions are repeated in context.S. If changes are required | |
| 218 // remember to update both sets. | |
| 219 | |
| 220 #define CYGARC_JMP_BUF_SP 0 | |
| 221 #define CYGARC_JMP_BUF_ER3 1 | |
| 222 #define CYGARC_JMP_BUF_ER4 2 | |
| 223 #define CYGARC_JMP_BUF_ER5 3 | |
| 224 #define CYGARC_JMP_BUF_ER6 4 | |
| 225 #define CYGARC_JMP_BUF_PC 5 | |
| 226 | |
| 227 #define CYGARC_JMP_BUF_SIZE 6 | |
| 228 | |
| 229 typedef cyg_uint32 hal_jmp_buf[CYGARC_JMP_BUF_SIZE]; | |
| 230 | |
| 231 externC int hal_setjmp(hal_jmp_buf env); | |
| 232 externC void hal_longjmp(hal_jmp_buf env, int val); | |
| 233 | |
| 234 //------------------------------------------------------------------------- | |
| 235 // Idle thread code. | |
| 236 // This macro is called in the idle thread loop, and gives the HAL the | |
| 237 // chance to insert code. Typical idle thread behaviour might be to halt the | |
| 238 // processor. | |
| 239 | |
| 240 externC void hal_idle_thread_action(cyg_uint32 loop_count); | |
| 241 | |
| 242 #define HAL_IDLE_THREAD_ACTION(_count_) hal_idle_thread_action(_count_) | |
| 243 | |
| 244 //----------------------------------------------------------------------------- | |
| 245 // Minimal and sensible stack sizes: the intention is that applications | |
| 246 // will use these to provide a stack size in the first instance prior to | |
| 247 // proper analysis. Idle thread stack should be this big. | |
| 248 | |
| 249 // THESE ARE NOT INTENDED TO BE MICROMETRICALLY ACCURATE FIGURES. | |
| 250 // THEY ARE HOWEVER ENOUGH TO START PROGRAMMING. | |
| 251 // YOU MUST MAKE YOUR STACKS LARGER IF YOU HAVE LARGE "AUTO" VARIABLES! | |
| 252 | |
| 253 // We define quite large stack needs for SPARClite, for it requires 576 | |
| 254 // bytes (144 words) to process an interrupt and thread-switch, and | |
| 255 // momentarily, but needed in case of recursive interrupts, it needs 208 | |
| 256 // words - if a sequence of saves to push out other regsets is interrupted. | |
| 257 | |
| 258 // This is not a config option because it should not be adjusted except | |
| 259 // under "enough rope" sort of disclaimers. | |
| 260 | |
| 261 // Worst case stack frame size: return link + 4 args + 4 pushed registers. | |
| 262 #define CYGNUM_HAL_STACK_FRAME_SIZE (40) | |
| 263 | |
| 264 // Stack needed for a context switch: | |
| 265 #define CYGNUM_HAL_STACK_CONTEXT_SIZE (60) | |
| 266 | |
| 267 // Interrupt + call to ISR, interrupt_end() and the DSR | |
| 268 #define CYGNUM_HAL_STACK_INTERRUPT_SIZE (128) | |
| 269 | |
| 270 #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK | |
| 271 | |
| 272 // An interrupt stack which is large enough for all possible interrupt | |
| 273 // conditions (and only used for that purpose) exists. "User" stacks | |
| 274 // can be much smaller | |
| 275 | |
| 276 #define CYGNUM_HAL_STACK_SIZE_MINIMUM (CYGNUM_HAL_STACK_CONTEXT_SIZE+ \ | |
| 277 CYGNUM_HAL_STACK_INTERRUPT_SIZE*2+ \ | |
| 278 CYGNUM_HAL_STACK_FRAME_SIZE*16) | |
| 279 #define CYGNUM_HAL_STACK_SIZE_TYPICAL (2048) | |
| 280 | |
| 281 #else // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK | |
| 282 | |
| 283 // No separate interrupt stack exists. Make sure all threads contain | |
| 284 // a stack sufficiently large. | |
| 285 | |
| 286 #define CYGNUM_HAL_STACK_SIZE_MINIMUM (4096) | |
| 287 #define CYGNUM_HAL_STACK_SIZE_TYPICAL (4096) | |
| 288 | |
| 289 #endif | |
| 290 | |
| 291 #define CYGARC_HAL_SAVE_GP() | |
| 292 #define CYGARC_HAL_RESTORE_GP() | |
| 293 //-------------------------------------------------------------------------- | |
| 294 #endif // CYGONCE_HAL_HAL_ARCH_H | |
| 295 // EOF hal_arch.h |
