]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/hal/mn10300/arch/v2_0/src/hal_misc.c
Initial revision
[karo-tx-redboot.git] / packages / hal / mn10300 / arch / v2_0 / src / hal_misc.c
1 /*==========================================================================
2 //
3 //      hal_misc.c
4 //
5 //      HAL miscellaneous functions
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):    nickg
44 // Contributors: nickg, jlarmour, dmoseley
45 // Date:         1999-02-18
46 // Purpose:      HAL miscellaneous functions
47 // Description:  This file contains miscellaneous functions provided by the
48 //               HAL.
49 //
50 //####DESCRIPTIONEND####
51 //
52 //========================================================================*/
53
54 #include <pkgconf/hal.h>
55
56 #include <cyg/infra/cyg_type.h>
57 #include <cyg/infra/cyg_trac.h>
58
59 #include <cyg/hal/hal_arch.h>
60
61 #include <cyg/hal/hal_intr.h>
62
63 #include <cyg/hal/hal_cache.h>
64
65 #if 0
66 void trace( CYG_ADDRWORD tag, CYG_ADDRWORD a1, CYG_ADDRWORD a2)
67 {
68     CYG_ADDRWORD **pp = (CYG_ADDRWORD **)0x48100000;
69     CYG_ADDRWORD *ix = (CYG_ADDRWORD *)0x4810000C;
70     CYG_ADDRWORD *p = *pp;
71     *p++ = tag;
72     *ix = *ix + 1;
73     *p++ = *ix;
74     *p++ = a1;
75     *p++ = a2;
76     *pp = p;
77 }
78 #endif
79
80 /*------------------------------------------------------------------------*/
81
82 #ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
83 cyg_bool cyg_hal_stop_constructors;
84 #endif
85
86 void
87 cyg_hal_invoke_constructors(void)
88 {
89     typedef void (*pfunc) (void);
90     extern pfunc _CTOR_LIST__[];
91     extern pfunc _CTOR_END__[];
92
93 #ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
94     static pfunc *p = &_CTOR_END__[-1];
95     
96     cyg_hal_stop_constructors = 0;
97     for (; p >= _CTOR_LIST__; p--) {
98         (*p) ();
99         if (cyg_hal_stop_constructors) {
100             p--;
101             break;
102         }
103     }
104 #else
105     pfunc *p;
106
107     for (p = &_CTOR_END__[-1]; p >= _CTOR_LIST__; p--)
108         (*p) ();
109 #endif
110
111 } // cyg_hal_invoke_constructors()
112
113 /*------------------------------------------------------------------------*/
114 /* Determine the index of the ls bit of the supplied mask.                */
115
116 cyg_uint32
117 hal_lsbit_index(cyg_uint32 mask)
118 {
119     cyg_uint32 n = mask;
120
121     static const signed char tab[64] =
122     { -1, 0, 1, 12, 2, 6, 0, 13, 3, 0, 7, 0, 0, 0, 0, 14, 10,
123       4, 0, 0, 8, 0, 0, 25, 0, 0, 0, 0, 0, 21, 27 , 15, 31, 11,
124       5, 0, 0, 0, 0, 0, 9, 0, 0, 24, 0, 0 , 20, 26, 30, 0, 0, 0,
125       0, 23, 0, 19, 29, 0, 22, 18, 28, 17, 16, 0
126     };
127
128     n &= ~(n-1UL);
129     n = (n<<16)-n;
130     n = (n<<6)+n;
131     n = (n<<4)+n;
132
133     return tab[n>>26];
134 }
135
136 /*------------------------------------------------------------------------*/
137 /* Determine the index of the ms bit of the supplied mask.                */
138
139 cyg_uint32
140 hal_msbit_index(cyg_uint32 mask)
141 {
142     cyg_uint32 x = mask;    
143     cyg_uint32 w;
144
145     /* Phase 1: make word with all ones from that one to the right */
146     x |= x >> 16;
147     x |= x >> 8;
148     x |= x >> 4;
149     x |= x >> 2;
150     x |= x >> 1;
151
152     /* Phase 2: calculate number of "1" bits in the word        */
153     w = (x & 0x55555555) + ((x >> 1) & 0x55555555);
154     w = (w & 0x33333333) + ((w >> 2) & 0x33333333);
155     w = w + (w >> 4);
156     w = (w & 0x000F000F) + ((w >> 8) & 0x000F000F);
157     return (cyg_uint32)((w + (w >> 16)) & 0xFF) - 1;
158 }
159
160 /*------------------------------------------------------------------------*/
161 /* First level C exception handler.                                       */
162
163 externC void __handle_exception (void);
164
165 externC HAL_SavedRegisters *_hal_registers;
166
167 #if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
168 externC void* volatile __mem_fault_handler;
169 #endif
170
171 externC cyg_uint32
172 cyg_hal_exception_handler(HAL_SavedRegisters *regs, CYG_WORD32 isr)
173 {
174     CYG_WORD vector = regs->vector;
175
176 #if defined(CYGNUM_HAL_EXCEPTION_SYSTEM_ERROR) && defined(CYGNUM_HAL_EXCEPTION_JTAG) 
177     if( vector == CYGNUM_HAL_EXCEPTION_SYSTEM_ERROR )
178     {
179         // Translate vector number via ISR bits into the full
180         // set.
181         vector = CYGNUM_HAL_EXCEPTION_JTAG+hal_lsbit_index( isr );
182
183         regs->vector = vector;
184     }
185 #endif
186     
187 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
188
189     // If we caught an exception inside the stubs, see if we were expecting it
190     // and if so jump to the saved address
191     if (__mem_fault_handler) {
192         regs->pc = (CYG_ADDRWORD)__mem_fault_handler;
193         return 0; // Caught an exception inside stubs        
194     }
195
196     // Set the pointer to the registers of the current exception
197     // context. At entry the GDB stub will expand the
198     // HAL_SavedRegisters structure into a (bigger) register array.
199     _hal_registers = regs;
200
201     __handle_exception();
202
203 #elif defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT)
204     
205     if( vector == CYGNUM_HAL_EXCEPTION_WATCHDOG )
206     {
207         // Special case the watchdog timer exception, look for an
208         // ISR for it and call it if present. Otherwise pass on to
209         // the exception system.
210         
211         cyg_uint32 (*isr)(CYG_ADDRWORD,CYG_ADDRWORD);
212         cyg_uint32 index;
213
214         HAL_TRANSLATE_VECTOR( CYGNUM_HAL_INTERRUPT_WATCHDOG, index );
215         
216         isr = (cyg_uint32 (*)(CYG_ADDRWORD,CYG_ADDRWORD))
217             (hal_interrupt_handlers[index]);
218
219         if( isr != 0 )
220         {
221             isr(CYGNUM_HAL_INTERRUPT_WATCHDOG,
222                 hal_interrupt_data[CYGNUM_HAL_INTERRUPT_WATCHDOG]
223                 );
224             return 0;
225         }
226     }
227
228 #if defined(CYGPKG_HAL_EXCEPTIONS)
229
230     // We should decode the vector and pass a more appropriate
231     // value as the second argument. For now we simply pass a
232     // pointer to the saved registers. We should also divert
233     // breakpoint and other debug vectors into the debug stubs.
234
235     cyg_hal_deliver_exception( vector, (CYG_ADDRWORD)regs );
236
237 #endif
238
239 #endif
240     
241     return 0;
242 }
243
244 /*------------------------------------------------------------------------*/
245 /* default ISR                                                            */
246
247 #ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
248 externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
249 {
250 #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) &&      \
251     defined(CYGHWR_HAL_GDB_PORT_VECTOR) &&              \
252     defined(HAL_CTRLC_ISR)
253
254 #ifndef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN    
255     if( vector == CYGHWR_HAL_GDB_PORT_VECTOR )
256 #endif        
257     {
258         cyg_uint32 result = HAL_CTRLC_ISR( vector, data );
259         if( result != 0 ) return result;
260     }
261     
262 #endif
263     
264     CYG_TRACE1(true, "Interrupt: %d", vector);
265     CYG_FAIL("Spurious Interrupt!!!");
266     return 0;
267 }
268
269 #else // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
270
271 #include <cyg/hal/plf_io.h>
272 externC cyg_uint32 hal_arch_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
273 {
274 #if defined(CYGDBG_HAL_MN10300_DEBUG_GDB_CTRLC_SUPPORT) &&      \
275     defined(CYGHWR_HAL_GDB_PORT_VECTOR) &&              \
276     defined(HAL_CTRLC_ISR)
277
278 #if defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon)
279 #if defined(HAL_DIAG_IRQ_CHECK)
280     {
281         cyg_uint32 ret;
282         /* let ROM monitor handle unexpected interrupts */
283         HAL_DIAG_IRQ_CHECK(vector, ret);
284         if (ret<=0)
285             return ret;
286     }
287 #endif // def HAL_DIAG_IRQ_CHECK
288 #endif // def CYGSEM_HAL_USE_ROM_MONITOR_CygMon
289 #endif
290
291     return 0;
292 }
293 #endif
294
295 /*------------------------------------------------------------------------*/
296 /* Idle thread activity.                                                  */
297    
298 externC void hal_idle_thread_action(cyg_uint32 loop_count)
299 {
300 }
301
302 /*------------------------------------------------------------------------*/
303 /* End of hal_misc.c                                                      */