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