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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [cortexm/] [arch/] [current/] [include/] [hal_arch.h] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
#ifndef CYGONCE_HAL_ARCH_H
2
#define CYGONCE_HAL_ARCH_H
3
/*==========================================================================
4
//
5
//      hal_arch.h
6
//
7
//      Cortex-M architecture abstractions
8
//
9
//==========================================================================
10
// ####ECOSGPLCOPYRIGHTBEGIN####
11
// -------------------------------------------
12
// This file is part of eCos, the Embedded Configurable Operating System.
13
// Copyright (C) 2008 Free Software Foundation, 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
18
// version.
19
//
20
// eCos is distributed in the hope that it will be useful, but WITHOUT
21
// ANY 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
26
// along with eCos; if not, write to the Free Software Foundation, Inc.,
27
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
28
//
29
// As a special exception, if other files instantiate templates or use
30
// macros or inline functions from this file, or you compile this file
31
// and link it with other works to produce a work based on this file,
32
// this file does not by itself cause the resulting work to be covered by
33
// the GNU General Public License. However the source code for this file
34
// must still be made available in accordance with section (3) of the GNU
35
// General Public License v2.
36
//
37
// This exception does not invalidate any other reasons why a work based
38
// on this file might be covered by the GNU General Public License.
39
// -------------------------------------------
40
// ####ECOSGPLCOPYRIGHTEND####
41
//==========================================================================
42
//#####DESCRIPTIONBEGIN####
43
//
44
// Author(s):    nickg
45
// Date:         2008-07-30
46
// Description:  Define architecture abstractions
47
//
48
//####DESCRIPTIONEND####
49
//
50
//========================================================================*/
51
 
52
#include <pkgconf/system.h>
53
#include <pkgconf/hal.h>
54
#include <cyg/infra/cyg_type.h>
55
 
56
#include <cyg/hal/var_arch.h>
57
 
58
//==========================================================================
59
// CPU save state
60
//
61
// This is a discriminated union of different save states for threads,
62
// exceptions and interrupts. State is saved in the most efficient way
63
// for each context. This makes the GDB state get/put slightly more
64
// complex, but that is a suitable compromise.
65
 
66
typedef struct
67
{
68
    union
69
    {
70
        cyg_uint32              type;           // State type
71
 
72
        struct
73
        {
74
            cyg_uint32          type;           // State type
75
            cyg_uint32          basepri;        // BASEPRI
76
            cyg_uint32          sp;             // SP (R13)
77
            cyg_uint32          r[13];          // R0..R12
78
            cyg_uint32          pc;             // PC/LR
79
        } thread;
80
 
81
        struct
82
        {
83
            cyg_uint32          type;           // State type
84
            cyg_uint32          vector;         // Exception vector number
85
            cyg_uint32          basepri;        // BASEPRI
86
 
87
            cyg_uint32          r4_11[8];       // Remaining CPU registers
88
            cyg_uint32          xlr;            // Exception return LR
89
 
90
            // The following are saved and restored automatically by the CPU
91
            // for exceptions or interrupts.
92
 
93
            cyg_uint32          r0;
94
            cyg_uint32          r1;
95
            cyg_uint32          r2;
96
            cyg_uint32          r3;
97
            cyg_uint32          r12;
98
            cyg_uint32          lr;
99
            cyg_uint32          pc;
100
            cyg_uint32          psr;
101
        } exception;
102
 
103
        struct
104
        {
105
            cyg_uint32          type;           // State type
106
 
107
            // The following are saved and restored automatically by the CPU
108
            // for exceptions or interrupts.
109
 
110
            cyg_uint32          r0;
111
            cyg_uint32          r1;
112
            cyg_uint32          r2;
113
            cyg_uint32          r3;
114
            cyg_uint32          r12;
115
            cyg_uint32          lr;
116
            cyg_uint32          pc;
117
            cyg_uint32          psr;
118
 
119
        } interrupt;
120
    } u;
121
 
122
} HAL_SavedRegisters;
123
 
124
#define HAL_SAVEDREGISTERS_EXCEPTION    1
125
#define HAL_SAVEDREGISTERS_THREAD       2
126
#define HAL_SAVEDREGISTERS_INTERRUPT    3
127
 
128
//==========================================================================
129
// Thread context initialization
130
 
131
#define HAL_THREAD_INIT_CONTEXT( __sparg, __thread, __entry, __id )     \
132
{                                                                       \
133
    register CYG_WORD __sp = ((CYG_WORD)__sparg) & ~7;                  \
134
    register CYG_WORD *__ep = (CYG_WORD *)(__sp -= sizeof(CYG_WORD));   \
135
    register HAL_SavedRegisters *__regs;                                \
136
    int __i;                                                            \
137
    __sp = ((CYG_WORD)__sp) &~15;                                       \
138
    __regs = (HAL_SavedRegisters *)((__sp) - sizeof(__regs->u.thread)); \
139
    __regs->u.type = HAL_SAVEDREGISTERS_THREAD;                         \
140
    for( __i = 1; __i < 13; __i++ )                                     \
141
        __regs->u.thread.r[__i] = 0;                                    \
142
    *__ep = (CYG_WORD)(__entry);                                        \
143
    __regs->u.thread.sp       = (CYG_WORD)(__sp);                       \
144
    __regs->u.thread.r[0]     = (CYG_WORD)(__thread);                   \
145
    __regs->u.thread.r[1]     = (CYG_WORD)(__id);                       \
146
    __regs->u.thread.r[11]     = (CYG_WORD)(__ep);                      \
147
    __regs->u.thread.pc       = (CYG_WORD)__entry;                      \
148
    __regs->u.thread.basepri  = 0;                                      \
149
    __sparg = (CYG_ADDRESS)__regs;                                      \
150
}
151
 
152
//==========================================================================
153
// Context switch macros.
154
// The arguments are pointers to locations where the stack pointer
155
// of the current thread is to be stored, and from where the SP of the
156
// next thread is to be fetched.
157
 
158
__externC void hal_thread_switch_context( CYG_ADDRESS to, CYG_ADDRESS from );
159
__externC void hal_thread_load_context( CYG_ADDRESS to ) __attribute__ ((noreturn));
160
 
161
#define HAL_THREAD_SWITCH_CONTEXT(__fspptr,__tspptr)                    \
162
        hal_thread_switch_context((CYG_ADDRESS)__tspptr,                \
163
                                  (CYG_ADDRESS)__fspptr);
164
 
165
#define HAL_THREAD_LOAD_CONTEXT(__tspptr)                               \
166
        hal_thread_load_context( (CYG_ADDRESS)__tspptr );
167
 
168
 
169
//==========================================================================
170
// Fetch PC from saved state
171
 
172
#define CYGARC_HAL_GET_PC_REG(__regs,__val)                             \
173
{                                                                       \
174
    switch( (__regs)->u.type )                                          \
175
    {                                                                   \
176
    case HAL_SAVEDREGISTERS_THREAD   : (__val) = (__regs)->u.thread.pc; break; \
177
    case HAL_SAVEDREGISTERS_EXCEPTION: (__val) = (__regs)->u.exception.pc; break; \
178
    case HAL_SAVEDREGISTERS_INTERRUPT: (__val) = (__regs)->u.interrupt.pc; break; \
179
    }                                                                   \
180
}
181
 
182
//==========================================================================
183
// Exception handling function
184
// This function is defined by the kernel according to this prototype. It is
185
// invoked from the HAL to deal with any CPU exceptions that the HAL does
186
// not want to deal with itself. It usually invokes the kernel's exception
187
// delivery mechanism.
188
 
189
externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data );
190
 
191
//==========================================================================
192
// Bit manipulation macros
193
 
194
#define HAL_LSBIT_INDEX(__index, __mask)                                \
195
{                                                                       \
196
    register cyg_uint32 __bit = (__mask);                               \
197
    register int __count;                                               \
198
    __bit = __bit & -__bit;                                             \
199
    __asm__ volatile ("clz %0,%1" : "=r"(__count) : "r"(__bit) );       \
200
    (__index) = 31-__count;                                             \
201
}
202
 
203
#define HAL_MSBIT_INDEX(__index, __mask)                                \
204
{                                                                       \
205
    register cyg_uint32 __bit = (__mask);                               \
206
    register int __count;                                               \
207
    __asm__ volatile ("clz %0,%1" : "=r"(__count) : "r"(__bit) );       \
208
    (__index) = 31-__count;                                             \
209
}
210
 
211
//==========================================================================
212
// Execution reorder barrier.
213
// When optimizing the compiler can reorder code. In multithreaded systems
214
// where the order of actions is vital, this can sometimes cause problems.
215
// This macro may be inserted into places where reordering should not happen.
216
 
217
#define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" )
218
 
219
//==========================================================================
220
// Breakpoint support
221
// HAL_BREAKPOINT() is a code sequence that will cause a breakpoint to happen
222
// if executed.
223
// HAL_BREAKINST is the value of the breakpoint instruction and 
224
// HAL_BREAKINST_SIZE is its size in bytes.
225
 
226
#define HAL_BREAKINST           0xbebe         // BKPT
227
 
228
# define HAL_BREAKINST_SIZE      2
229
# define HAL_BREAKINST_TYPE      cyg_uint16
230
 
231
#define _stringify1(__arg) #__arg
232
#define _stringify(__arg) _stringify1(__arg)
233
 
234
# define HAL_BREAKPOINT(_label_)                        \
235
__asm__ volatile (" .globl  " #_label_ ";"              \
236
              #_label_":"                               \
237
              " .short  " _stringify(HAL_BREAKINST)     \
238
    );
239
 
240
//==========================================================================
241
// GDB support
242
 
243
// Register layout expected by GDB
244
typedef struct
245
{
246
    cyg_uint32  gpr[16];
247
    cyg_uint32  f0[3];
248
    cyg_uint32  f1[3];
249
    cyg_uint32  f2[3];
250
    cyg_uint32  f3[3];
251
    cyg_uint32  f4[3];
252
    cyg_uint32  f5[3];
253
    cyg_uint32  f6[3];
254
    cyg_uint32  f7[3];
255
    cyg_uint32  fps;
256
    cyg_uint32  ps;
257
} HAL_CORTEXM_GDB_Registers;
258
 
259
// Translate a stack pointer as saved by the thread context macros
260
// into a pointer to a HAL_SavedRegisters structure. On the Cortex-M
261
// these are equivalent.
262
 
263
#define HAL_THREAD_GET_SAVED_REGISTERS(__stack, __regs) \
264
    CYG_MACRO_START                                     \
265
    (__regs)    = (HAL_SavedRegisters*)(__stack);       \
266
    CYG_MACRO_END
267
 
268
 
269
__externC void hal_get_gdb_registers( HAL_CORTEXM_GDB_Registers *gdbreg, HAL_SavedRegisters *regs );
270
__externC void hal_set_gdb_registers( HAL_CORTEXM_GDB_Registers *gdbreg, HAL_SavedRegisters *regs );
271
 
272
#define HAL_GET_GDB_REGISTERS(__regval, __regs) hal_get_gdb_registers( (HAL_CORTEXM_GDB_Registers *)(__regval), (HAL_SavedRegisters *)(__regs) )
273
#define HAL_SET_GDB_REGISTERS(__regs, __regval) hal_set_gdb_registers( (HAL_CORTEXM_GDB_Registers *)(__regval), (HAL_SavedRegisters *)(__regs) )
274
 
275
//==========================================================================
276
// HAL setjmp
277
 
278
#define CYGARC_JMP_BUF_SIZE     16
279
 
280
typedef cyg_uint32 hal_jmp_buf[CYGARC_JMP_BUF_SIZE];
281
 
282
__externC int hal_setjmp(hal_jmp_buf env);
283
__externC void hal_longjmp(hal_jmp_buf env, int val);
284
 
285
 
286
//==========================================================================
287
// Idle thread code.
288
//
289
// This macro is called in the idle thread loop, and gives the HAL the
290
// chance to insert code. Typical idle thread behaviour might be to halt the
291
// processor. Here we only supply a default fallback if the variant/platform
292
// doesn't define anything.
293
 
294
#ifndef HAL_IDLE_THREAD_ACTION
295
#define HAL_IDLE_THREAD_ACTION(__count) __asm__ volatile ( "wfi\n" )
296
#endif
297
 
298
//==========================================================================
299
// Minimal and sensible stack sizes: the intention is that applications
300
// will use these to provide a stack size in the first instance prior to
301
// proper analysis.  Idle thread stack should be this big.
302
 
303
//    THESE ARE NOT INTENDED TO BE MICROMETRICALLY ACCURATE FIGURES.
304
//           THEY ARE HOWEVER ENOUGH TO START PROGRAMMING.
305
// YOU MUST MAKE YOUR STACKS LARGER IF YOU HAVE LARGE "AUTO" VARIABLES!
306
 
307
// This is not a config option because it should not be adjusted except
308
// under "enough rope" sort of disclaimers.
309
 
310
// A minimal, optimized stack frame - space for return link plus four
311
// arguments or local variables.
312
#define CYGNUM_HAL_STACK_FRAME_SIZE (4 * 20)
313
 
314
// Stack needed for a context switch
315
#define CYGNUM_HAL_STACK_CONTEXT_SIZE (4 * 20)
316
 
317
// Interrupt + call to ISR, interrupt_end() and the DSR
318
#define CYGNUM_HAL_STACK_INTERRUPT_SIZE \
319
    (CYGNUM_HAL_STACK_CONTEXT_SIZE + 2 * CYGNUM_HAL_STACK_FRAME_SIZE)
320
 
321
// Space for the maximum number of nested interrupts, plus room to call functions
322
#define CYGNUM_HAL_MAX_INTERRUPT_NESTING 4
323
 
324
// Minimum stack size. Space for the given number of nested
325
// interrupts, plus a thread context switch plus a couple of function
326
// calls.
327
#define CYGNUM_HAL_STACK_SIZE_MINIMUM \
328
        ((CYGNUM_HAL_MAX_INTERRUPT_NESTING+1) * CYGNUM_HAL_STACK_INTERRUPT_SIZE + \
329
         2 * CYGNUM_HAL_STACK_FRAME_SIZE)
330
 
331
// Typical stack size -- used mainly for test programs. The minimum
332
// stack size plus enough space for some function calls.
333
#define CYGNUM_HAL_STACK_SIZE_TYPICAL \
334
        (CYGNUM_HAL_STACK_SIZE_MINIMUM + 32 * CYGNUM_HAL_STACK_FRAME_SIZE)
335
 
336
//==========================================================================
337
// Macros for switching context between two eCos instances (jump from
338
// code in ROM to code in RAM or vice versa).
339
 
340
#define CYGARC_HAL_SAVE_GP()
341
#define CYGARC_HAL_RESTORE_GP()
342
 
343
//==========================================================================
344
#endif //CYGONCE_HAL_ARCH_H
345
 

powered by: WebSVN 2.1.0

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