OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [i386/] [arch/] [v2_0/] [include/] [hal_arch.h] - Blame information for rev 229

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
#ifndef CYGONCE_HAL_HAL_ARCH_H
2
#define CYGONCE_HAL_HAL_ARCH_H
3
 
4
//=============================================================================
5
//
6
//      hal_arch.h
7
//
8
//      Architecture specific abstractions
9
//
10
//=============================================================================
11
//####ECOSGPLCOPYRIGHTBEGIN####
12
// -------------------------------------------
13
// This file is part of eCos, the Embedded Configurable Operating System.
14
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
15
//
16
// eCos is free software; you can redistribute it and/or modify it under
17
// the terms of the GNU General Public License as published by the Free
18
// Software Foundation; either version 2 or (at your option) any later version.
19
//
20
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
21
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
22
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
23
// for more details.
24
//
25
// You should have received a copy of the GNU General Public License along
26
// with eCos; if not, write to the Free Software Foundation, Inc.,
27
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
28
//
29
// As a special exception, if other files instantiate templates or use macros
30
// or inline functions from this file, or you compile this file and link it
31
// with other works to produce a work based on this file, this file does not
32
// by itself cause the resulting work to be covered by the GNU General Public
33
// License. However the source code for this file must still be made available
34
// in accordance with section (3) of the GNU General Public License.
35
//
36
// This exception does not invalidate any other reasons why a work based on
37
// this file might be covered by the GNU General Public License.
38
//
39
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
40
// at http://sources.redhat.com/ecos/ecos-license/
41
// -------------------------------------------
42
//####ECOSGPLCOPYRIGHTEND####
43
//=============================================================================
44
//#####DESCRIPTIONBEGIN####
45
//
46
// Author(s):   proven
47
// Contributors:proven, pjo, nickg
48
// Date:        1998-10-05
49
// Purpose:     Define architecture abstractions
50
// Usage:       #include <cyg/hal/hal_arch.h>
51
//
52
//####DESCRIPTIONEND####
53
//
54
//=============================================================================
55
 
56
#include <pkgconf/hal.h>
57
#include <cyg/infra/cyg_type.h>
58
 
59
#include <cyg/hal/var_arch.h>
60
 
61
//-----------------------------------------------------------------------------
62
// Processor saved states. This structure is also defined in i386.inc for
63
// assembly code. Do not change this without changing that (or vice versa).
64
 
65
#ifdef CYGHWR_HAL_I386_FPU
66
 
67
typedef struct
68
{
69
    cyg_uint32  fpstate_valid;
70
    cyg_uint32  fpstate[108/sizeof(cyg_uint32)];
71
#ifdef CYGHWR_HAL_I386_PENTIUM_SSE
72
    cyg_uint32  xmm0[4];
73
    cyg_uint32  xmm1[4];
74
    cyg_uint32  xmm2[4];
75
    cyg_uint32  xmm3[4];
76
    cyg_uint32  xmm4[4];
77
    cyg_uint32  xmm5[4];
78
    cyg_uint32  xmm6[4];
79
    cyg_uint32  xmm7[4];
80
    cyg_uint32  mxcsr;
81
#endif
82
} HAL_FPU_Context;
83
 
84
#endif
85
 
86
typedef struct
87
{
88
#ifdef CYGHWR_HAL_I386_FPU
89
#ifdef CYGHWR_HAL_I386_FPU_SWITCH_LAZY
90
    HAL_FPU_Context     *fpucontext;
91
#else
92
    HAL_FPU_Context     fpucontext;
93
#endif    
94
#endif    
95
    cyg_uint32  edi;
96
    cyg_uint32  esi;
97
    cyg_uint32  ebp;
98
    cyg_uint32  esp;
99
    cyg_uint32  ebx;
100
    cyg_uint32  edx;
101
    cyg_uint32  ecx;
102
    cyg_uint32  eax;
103
    cyg_uint32  vector; // if saved on interrupt contains intr vector
104
    cyg_uint32  pc;
105
    cyg_uint32  cs;
106
    cyg_uint32  eflags;
107
} HAL_SavedRegisters;
108
 
109
 
110
//-----------------------------------------------------------------------------
111
// Exception handling function.
112
// This function is defined by the kernel according to this prototype. It is
113
// invoked from the HAL to deal with any CPU exceptions that the HAL does
114
// not want to deal with itself. It usually invokes the kernel's exception
115
// delivery mechanism.
116
externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data );
117
 
118
//-----------------------------------------------------------------------------
119
// Bit manipulation routines
120
 
121
#define HAL_LSBIT_INDEX(index, mask)            \
122
CYG_MACRO_START                                 \
123
    asm volatile( "bsfl %1,%0\n"                \
124
                  : "=r" (index)                \
125
                  : "r" (mask)                  \
126
                );                              \
127
CYG_MACRO_END
128
 
129
#define HAL_MSBIT_INDEX(index, mask)            \
130
CYG_MACRO_START                                 \
131
    asm volatile( "bsrl %1,%0\n"                \
132
                  : "=r" (index)                \
133
                  : "r" (mask)                  \
134
                );                              \
135
CYG_MACRO_END
136
 
137
//-----------------------------------------------------------------------------
138
// Context Initialization
139
// Initialize the context of a thread.
140
// Arguments:
141
// _sp_ name of variable containing current sp, will be written with new sp
142
// _thread_ thread object address, passed as argument to entry point
143
// _entry_ entry point address.
144
// _id_ bit pattern used in initializing registers, for debugging.
145
 
146
#ifndef CYG_HAL_DEFAULT_CS
147
#define CYG_HAL_DEFAULT_CS 0x0008
148
#endif
149
 
150
#ifdef CYGHWR_HAL_I386_FPU
151
# ifdef CYGHWR_HAL_I386_FPU_SWITCH_LAZY
152
# define HAL_THREAD_INIT_FPU_CONTEXT_SPACE( __sp, __fpspace )   \
153
         __sp -= sizeof(HAL_FPU_Context);                       \
154
         __fpspace = __sp;
155
# define HAL_THREAD_INIT_FPU_CONTEXT( __regs, __fpspace )                               \
156
CYG_MACRO_START                                                                         \
157
    cyg_ucount8 __i;                                                                    \
158
    HAL_FPU_Context *__fpspace_ = (HAL_FPU_Context *)(__fpspace);                       \
159
    (__regs)->fpucontext = __fpspace_;                                                  \
160
    __fpspace_->fpstate_valid = 0;                                                      \
161
    for( __i = 0; __i < (sizeof(__fpspace_->fpstate)/sizeof(cyg_uint32)); __i++ )       \
162
        __fpspace_->fpstate[__i] = 0;                                                   \
163
CYG_MACRO_END
164
# else
165
# define HAL_THREAD_INIT_FPU_CONTEXT_SPACE( __sp, __fpspace )                   \
166
         (__fpspace) = (__fpspace);
167
# define HAL_THREAD_INIT_FPU_CONTEXT( __regs, __fpspace )                               \
168
CYG_MACRO_START                                                                         \
169
    cyg_ucount8 __i;                                                                    \
170
    HAL_FPU_Context *__fpspace_ = &((__regs)->fpucontext);                              \
171
    __fpspace_->fpstate_valid = 0;                                                      \
172
    for( __i = 0; __i < (sizeof(__fpspace_->fpstate)/sizeof(cyg_uint32)); __i++ )       \
173
        __fpspace_->fpstate[__i] = 0;                                                   \
174
CYG_MACRO_END
175
# endif
176
#else
177
# define HAL_THREAD_INIT_FPU_CONTEXT_SPACE( __sp, __fpspace )                   \
178
         (__fpspace) = (__fpspace);
179
# define HAL_THREAD_INIT_FPU_CONTEXT( __regs, __fpspace )
180
#endif
181
 
182
 
183
#define HAL_THREAD_INIT_CONTEXT( _sparg_, _thread_, _entry_, _id_ )     \
184
CYG_MACRO_START                                                         \
185
    register CYG_WORD* _sp_ = ((CYG_WORD*)((_sparg_) &~15));            \
186
    register CYG_WORD *_fpspace_ = NULL;                                \
187
    register HAL_SavedRegisters *_regs_;                                \
188
                                                                        \
189
    HAL_THREAD_INIT_FPU_CONTEXT_SPACE( _sp_, _fpspace_ );               \
190
    *(--_sp_) = (CYG_WORD)(0);                                          \
191
    *(--_sp_) = (CYG_WORD)(0);                                          \
192
    *(--_sp_) = (CYG_WORD)(_thread_);                                   \
193
    *(--_sp_) = (CYG_WORD)(0);                                          \
194
                                                                        \
195
    _regs_ = (HAL_SavedRegisters *)                                     \
196
               ((unsigned long)_sp_ - sizeof(HAL_SavedRegisters));      \
197
    HAL_THREAD_INIT_FPU_CONTEXT( _regs_, _fpspace_ );                   \
198
    _regs_->eflags = (CYG_WORD)(0x00000200);                            \
199
    _regs_->cs     = (CYG_WORD)(CYG_HAL_DEFAULT_CS);                    \
200
    _regs_->pc     = (CYG_WORD)(_entry_);                               \
201
    _regs_->vector = (CYG_WORD)(_id_);                                  \
202
    _regs_->esp    = (CYG_WORD) _sp_-4;                                 \
203
    _regs_->ebp    = (CYG_WORD)(_id_);                                  \
204
    _regs_->esi    = (CYG_WORD)(_id_);                                  \
205
    _regs_->edi    = (CYG_WORD)(_id_);                                  \
206
    _regs_->eax    = (CYG_WORD)(_id_);                                  \
207
    _regs_->ebx    = (CYG_WORD)(_id_);                                  \
208
    _regs_->ecx    = (CYG_WORD)(_id_);                                  \
209
    _regs_->edx    = (CYG_WORD)(_id_);                                  \
210
    (_sparg_)      = (CYG_ADDRESS) _regs_;                              \
211
CYG_MACRO_END
212
 
213
//-----------------------------------------------------------------------------
214
// Context switch macros.
215
// The arguments are pointers to locations where the stack pointer
216
// of the current thread is to be stored, and from where the sp of the
217
// next thread is to be fetched.
218
 
219
externC void hal_thread_switch_context( CYG_ADDRESS to, CYG_ADDRESS from );
220
externC void hal_thread_load_context( CYG_ADDRESS to )
221
    __attribute__ ((noreturn));
222
 
223
#define HAL_THREAD_SWITCH_CONTEXT(_fspptr_,_tspptr_)                    \
224
        hal_thread_switch_context((CYG_ADDRESS)_tspptr_,(CYG_ADDRESS)_fspptr_);
225
 
226
#define HAL_THREAD_LOAD_CONTEXT(_tspptr_)                               \
227
        hal_thread_load_context( (CYG_ADDRESS)_tspptr_ );
228
 
229
//-----------------------------------------------------------------------------
230
// Execution reorder barrier.
231
// When optimizing the compiler can reorder code. In multithreaded systems
232
// where the order of actions is vital, this can sometimes cause problems.
233
// This macro may be inserted into places where reordering should not happen.
234
 
235
#define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" )
236
 
237
//-----------------------------------------------------------------------------
238
// Breakpoint support
239
// HAL_BREAKPOINT() is a code sequence that will cause a breakpoint to happen 
240
// if executed.
241
// HAL_BREAKINST is the value of the breakpoint instruction and 
242
// HAL_BREAKINST_SIZE is its size in bytes.
243
 
244
#define HAL_BREAKPOINT(_label_)                 \
245
CYG_MACRO_START                                 \
246
    asm volatile (" .globl  " #_label_ ";"      \
247
                  #_label_":"                   \
248
                  "int $3"                      \
249
        );                                      \
250
CYG_MACRO_END
251
 
252
#define HAL_BREAKINST                    0xCC
253
#define HAL_BREAKINST_SIZE               1
254
 
255
//-----------------------------------------------------------------------------
256
// Thread register state manipulation for GDB support.
257
 
258
// Translate a stack pointer as saved by the thread context macros above into
259
// a pointer to a HAL_SavedRegisters structure.
260
#define HAL_THREAD_GET_SAVED_REGISTERS( _sp_, _regs_ )  \
261
        (_regs_) = (HAL_SavedRegisters *)(_sp_)
262
 
263
// Copy a set of registers from a HAL_SavedRegisters structure into a
264
// GDB ordered array.    
265
 
266
externC void hal_get_gdb_registers(CYG_ADDRWORD *, HAL_SavedRegisters *);
267
externC void hal_set_gdb_registers(HAL_SavedRegisters *, CYG_ADDRWORD *);
268
 
269
#define HAL_GET_GDB_REGISTERS( _aregval_, _regs_ ) \
270
                hal_get_gdb_registers((CYG_ADDRWORD *)(_aregval_), (_regs_))
271
 
272
// Copy a GDB ordered array into a HAL_SavedRegisters structure.
273
#define HAL_SET_GDB_REGISTERS( _regs_ , _aregval_ ) \
274
                hal_set_gdb_registers((_regs_), (CYG_ADDRWORD *)(_aregval_))
275
 
276
//-----------------------------------------------------------------------------
277
// HAL setjmp
278
 
279
#define CYGARC_JMP_BUF_SP        0
280
#define CYGARC_JMP_BUF_EBP       1
281
#define CYGARC_JMP_BUF_EBX       2
282
#define CYGARC_JMP_BUF_ESI       3
283
#define CYGARC_JMP_BUF_EDI       4
284
#define CYGARC_JMP_BUF_PC        5
285
 
286
#define CYGARC_JMP_BUF_SIZE      6
287
 
288
typedef cyg_uint32 hal_jmp_buf[CYGARC_JMP_BUF_SIZE];
289
 
290
externC int hal_setjmp(hal_jmp_buf env);
291
externC void hal_longjmp(hal_jmp_buf env, int val);
292
 
293
//-----------------------------------------------------------------------------
294
// Idle thread code.
295
// This macro is called in the idle thread loop, and gives the HAL the
296
// chance to insert code. Typical idle thread behaviour might be to halt the
297
// processor.
298
 
299
externC void hal_idle_thread_action(cyg_uint32 loop_count);
300
 
301
#define HAL_IDLE_THREAD_ACTION(_count_) hal_idle_thread_action(_count_)
302
 
303
//-----------------------------------------------------------------------------
304
// Minimal and sensible stack sizes: the intention is that applications
305
// will use these to provide a stack size in the first instance prior to
306
// proper analysis.  Idle thread stack should be this big.
307
 
308
//    THESE ARE NOT INTENDED TO BE MICROMETRICALLY ACCURATE FIGURES.
309
//           THEY ARE HOWEVER ENOUGH TO START PROGRAMMING.
310
// YOU MUST MAKE YOUR STACKS LARGER IF YOU HAVE LARGE "AUTO" VARIABLES!
311
 
312
// This is not a config option because it should not be adjusted except
313
// under "enough rope" sort of disclaimers.
314
 
315
// Stack frame overhead per call. Four arguments, 3 local registers
316
// (edi, esi, ebx), four local variables and return address.
317
#define CYGNUM_HAL_STACK_FRAME_SIZE (12 * 4)
318
 
319
// Stack needed for a context switch ( sizeof(HAL_SavedRegisters) ).
320
#ifdef CYGHWR_HAL_I386_FPU
321
# define CYGNUM_HAL_STACK_CONTEXT_SIZE ((4 * 12) + 108)
322
#else
323
# define CYGNUM_HAL_STACK_CONTEXT_SIZE (4 * 12)
324
#endif
325
 
326
// Interrupt + call to ISR, interrupt_end() and the DSR
327
#define CYGNUM_HAL_STACK_INTERRUPT_SIZE \
328
    ((4*CYGNUM_HAL_STACK_CONTEXT_SIZE) + 4 * CYGNUM_HAL_STACK_FRAME_SIZE)
329
 
330
// We define a minimum stack size as the minimum any thread could ever
331
// legitimately get away with. We can throw asserts if users ask for less
332
// than this. Allow enough for three interrupt sources - clock, serial and
333
// one other
334
 
335
#if defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK)
336
 
337
// An interrupt stack which is large enough for all possible interrupt
338
// conditions (and only used for that purpose) exists.  "User" stacks
339
// can therefore be much smaller
340
 
341
# define CYGNUM_HAL_STACK_SIZE_MINIMUM \
342
         (2*CYGNUM_HAL_STACK_FRAME_SIZE + 2*CYGNUM_HAL_STACK_INTERRUPT_SIZE)
343
 
344
#else
345
 
346
// No separate interrupt stack exists.  Make sure all threads contain
347
// a stack sufficiently large
348
 
349
# define CYGNUM_HAL_STACK_SIZE_MINIMUM                  \
350
        (((2+3+10)*CYGNUM_HAL_STACK_INTERRUPT_SIZE) +   \
351
         (2*CYGNUM_HAL_STACK_FRAME_SIZE))
352
 
353
#endif
354
 
355
// Now make a reasonable choice for a typical thread size. Pluck figures
356
// from thin air and say 15 call frames with an average of 16 words of
357
// automatic variables per call frame
358
 
359
#define CYGNUM_HAL_STACK_SIZE_TYPICAL                \
360
        (CYGNUM_HAL_STACK_SIZE_MINIMUM +             \
361
         15 * (CYGNUM_HAL_STACK_FRAME_SIZE+(16*4)))
362
 
363
//--------------------------------------------------------------------------
364
// Memory access macros
365
 
366
#define CYGARC_CACHED_ADDRESS(x)                       (x)
367
#define CYGARC_UNCACHED_ADDRESS(x)                     (x)
368
#define CYGARC_PHYSICAL_ADDRESS(x)                     (x)
369
 
370
//--------------------------------------------------------------------------
371
// Region size finder
372
 
373
#if CYGINT_HAL_I386_MEM_REAL_REGION_TOP
374
 
375
externC cyg_uint8 *hal_i386_mem_real_region_top( cyg_uint8 *_regionend_ );
376
 
377
# define HAL_MEM_REAL_REGION_TOP( _regionend_ ) \
378
    hal_i386_mem_real_region_top( _regionend_ )
379
#endif
380
 
381
//--------------------------------------------------------------------------
382
// Macros for switching context between two eCos instances (jump from
383
// code in ROM to code in RAM or vice versa).
384
 
385
#define CYGARC_HAL_SAVE_GP()
386
#define CYGARC_HAL_RESTORE_GP()
387
 
388
//--------------------------------------------------------------------------
389
#endif // CYGONCE_HAL_HAL_ARCH_H
390
// End of hal_arch.h

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.