comparison packages/hal/mips/arch/current/src/hal_misc.c @ 0:3111d98ba7b3 ecos-v1_1-release

Initial commit of eCos version 1.1
author jlarmour
date Tue, 11 May 1999 11:16:07 +0000
parents
children 443894e2e912
comparison
equal deleted inserted replaced
-1:000000000000 0:3111d98ba7b3
1 //=============================================================================
2 //
3 // hal_misc.c
4 //
5 // HAL miscellaneous functions
6 //
7 //=============================================================================
8 //####COPYRIGHTBEGIN####
9 //
10 // -------------------------------------------
11 // The contents of this file are subject to the Cygnus eCos Public License
12 // Version 1.0 (the "License"); you may not use this file except in
13 // compliance with the License. You may obtain a copy of the License at
14 // http://sourceware.cygnus.com/ecos
15 //
16 // Software distributed under the License is distributed on an "AS IS"
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
18 // License for the specific language governing rights and limitations under
19 // the License.
20 //
21 // The Original Code is eCos - Embedded Cygnus Operating System, released
22 // September 30, 1998.
23 //
24 // The Initial Developer of the Original Code is Cygnus. Portions created
25 // by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved.
26 // -------------------------------------------
27 //
28 //####COPYRIGHTEND####
29 //=============================================================================
30 //#####DESCRIPTIONBEGIN####
31 //
32 // Author(s): nickg
33 // Contributors: nickg
34 // Date: 1998-02-05
35 // Purpose: HAL miscellaneous functions
36 // Description: This file contains miscellaneous functions provided by the
37 // HAL.
38 //
39 //####DESCRIPTIONEND####
40 //
41 //===========================================================================*/
42
43 #include <pkgconf/hal.h>
44
45 #include <cyg/infra/cyg_type.h> // Base types
46 #include <cyg/infra/cyg_trac.h> // tracing macros
47 #include <cyg/infra/cyg_ass.h> // assertion macros
48
49 #include <cyg/hal/hal_arch.h> // architectural definitions
50
51 #include <cyg/hal/hal_intr.h> // Interrupt handling
52
53 #include <cyg/hal/hal_cache.h> // Cache handling
54
55 /*---------------------------------------------------------------------------*/
56 /* First level C exception handler. */
57
58 externC void __handle_exception (void);
59
60 externC HAL_SavedRegisters *_hal_registers;
61
62 externC void exception_handler(HAL_SavedRegisters *regs)
63 {
64 #if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
65
66 // Set the pointer to the registers of the current exception
67 // context. At entry the GDB stub will expand the
68 // HAL_SavedRegisters structure into a (bigger) register array.
69 _hal_registers = regs;
70 __handle_exception();
71
72 #elif defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && defined(CYGPKG_HAL_EXCEPTIONS)
73
74 // We should decode the vector and pass a more appropriate
75 // value as the second argument. For now we simply pass a
76 // pointer to the saved registers. We should also divert
77 // breakpoint and other debug vectors into the debug stubs.
78
79 deliver_exception( regs->vector>>2, (CYG_ADDRWORD)regs );
80
81 #else
82
83 CYG_FAIL("Exception!!!");
84
85 #endif
86 return;
87 }
88
89 /*---------------------------------------------------------------------------*/
90 /* default ISR */
91
92 externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
93 {
94 CYG_TRACE1(true, "Interrupt: %d", vector);
95 CYG_FAIL("Spurious Interrupt!!!");
96 return 0;
97 }
98
99 /*---------------------------------------------------------------------------*/
100 /* data copy and bss zero functions */
101
102 typedef void (CYG_ROM_ADDRESS)(void);
103
104 #ifdef CYG_HAL_STARTUP_ROM
105 void hal_copy_data(void)
106 {
107 extern char __ram_data_start;
108 extern char __ram_data_end;
109 extern CYG_ROM_ADDRESS __rom_data_start;
110 char *p = &__ram_data_start;
111 char *q = (char *)&__rom_data_start;
112
113 while( p != (char *)&__ram_data_end )
114 *p++ = *q++;
115 }
116 #endif
117
118 void hal_zero_bss(void)
119 {
120 extern CYG_ROM_ADDRESS __bss_start;
121 extern CYG_ROM_ADDRESS _end;
122 char *p = (char *)&__bss_start;
123
124 while( p != (char *)&_end )
125 *p++ = 0;
126 }
127
128 /*---------------------------------------------------------------------------*/
129
130 void fake_ctor(void) {};
131
132 void
133 cyg_hal_invoke_constructors (void)
134 {
135 #ifdef CYG_KERNEL_USE_INIT_PRIORITY
136
137 typedef void (*pfunc) (void);
138 extern pfunc __CTOR_LIST__[];
139 long i = (long)(__CTOR_LIST__[0]);
140 pfunc p;
141
142 for ( ; i > 0; i-- )
143 {
144 p = __CTOR_LIST__[i];
145 p ();
146 }
147
148 #else
149
150 typedef void (CYG_CODE_ADDRESS)();
151 extern CYG_CODE_ADDRESS __sched_text_start;
152 extern CYG_CODE_ADDRESS __sched_text_end;
153 extern CYG_CODE_ADDRESS __clock_text_start;
154 extern CYG_CODE_ADDRESS __clock_text_end;
155 extern CYG_CODE_ADDRESS __thread_text_start;
156 extern CYG_CODE_ADDRESS __thread_text_end;
157
158 typedef void (*pfunc) ();
159 extern pfunc __CTOR_LIST__[];
160 pfunc *p;
161
162 for (p = __CTOR_LIST__+1; *p != 0; p++)
163 {
164 CYG_ADDRESS *pp = (CYG_ADDRESS *)*p;
165
166 if( pp > (CYG_ADDRESS *)&__sched_text_start &&
167 pp < (CYG_ADDRESS *)&__sched_text_end )
168 {
169 (*p) ();
170 *p = fake_ctor;
171 }
172 }
173
174 for (p = __CTOR_LIST__+1; *p != 0; p++)
175 {
176 CYG_ADDRESS *pp = (CYG_ADDRESS *)*p;
177
178 if( pp > (CYG_ADDRESS *)&__clock_text_start &&
179 pp < (CYG_ADDRESS *)&__clock_text_end )
180 {
181 (*p) ();
182 *p = fake_ctor;
183 }
184 }
185
186 for (p = __CTOR_LIST__+1; *p != 0; p++)
187 {
188 CYG_ADDRESS *pp = (CYG_ADDRESS *)*p;
189
190 if( pp > (CYG_ADDRESS *)&__thread_text_start &&
191 pp < (CYG_ADDRESS *)&__thread_text_end )
192 {
193 (*p) ();
194 *p = fake_ctor;
195 }
196 }
197
198 for (p = __CTOR_LIST__+1; *p != 0; p++)
199 {
200 (*p) ();
201 *p = fake_ctor;
202 }
203
204 #endif
205
206 #ifdef CYG_HAL_MIPS_TX3904
207
208 // On the real hardware we also enable the cache.
209 // doing this here is a temporary measure until we
210 // have a proper platform specific place to do it.
211
212 HAL_ICACHE_INVALIDATE_ALL();
213 HAL_ICACHE_ENABLE();
214 HAL_DCACHE_INVALIDATE_ALL();
215 HAL_DCACHE_ENABLE();
216
217 #endif
218
219 #if defined(CYG_HAL_USE_ROM_MONITOR) && \
220 !defined(CYGDBG_INFRA_DIAG_USE_DEVICE) && \
221 defined(CYG_HAL_TX39_JMR3904)
222
223 {
224 static void hal_init_ctrlc_intr(void);
225 hal_init_ctrlc_intr();
226 }
227
228 #endif
229 #if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \
230 defined(CYG_HAL_USE_ROM_MONITOR) && \
231 defined(CYG_HAL_USE_ROM_MONITOR_CYGMON)
232 {
233 extern void patch_dbg_syscalls(void * vector);
234 #define DBG_SYSCALL_VEC_NUM 15
235 patch_dbg_syscalls( (void *)(&hal_vsr_table[DBG_SYSCALL_VEC_NUM]) );
236 }
237 #endif
238 }
239
240 /*---------------------------------------------------------------------------*/
241 /* Determine the index of the ls bit of the supplied mask. */
242
243 cyg_uint32 hal_lsbit_index(cyg_uint32 mask)
244 {
245 cyg_uint32 n = mask;
246
247 static const signed char tab[64] =
248 { -1, 0, 1, 12, 2, 6, 0, 13, 3, 0, 7, 0, 0, 0, 0, 14, 10,
249 4, 0, 0, 8, 0, 0, 25, 0, 0, 0, 0, 0, 21, 27 , 15, 31, 11,
250 5, 0, 0, 0, 0, 0, 9, 0, 0, 24, 0, 0 , 20, 26, 30, 0, 0, 0,
251 0, 23, 0, 19, 29, 0, 22, 18, 28, 17, 16, 0
252 };
253
254 n &= ~(n-1UL);
255 n = (n<<16)-n;
256 n = (n<<6)+n;
257 n = (n<<4)+n;
258
259 return tab[n>>26];
260 }
261
262 /*---------------------------------------------------------------------------*/
263 /* Determine the index of the ms bit of the supplied mask. */
264
265 cyg_uint32 hal_msbit_index(cyg_uint32 mask)
266 {
267 cyg_uint32 x = mask;
268 cyg_uint32 w;
269
270 /* Phase 1: make word with all ones from that one to the right */
271 x |= x >> 16;
272 x |= x >> 8;
273 x |= x >> 4;
274 x |= x >> 2;
275 x |= x >> 1;
276
277 /* Phase 2: calculate number of "1" bits in the word */
278 w = (x & 0x55555555) + ((x >> 1) & 0x55555555);
279 w = (w & 0x33333333) + ((w >> 2) & 0x33333333);
280 w = w + (w >> 4);
281 w = (w & 0x000F000F) + ((w >> 8) & 0x000F000F);
282 return (cyg_uint32)((w + (w >> 16)) & 0xFF);
283
284 }
285
286 /*---------------------------------------------------------------------------*/
287 /* Idle thread action */
288
289 void hal_idle_thread_action( cyg_uint32 count )
290 {
291 #if 0 //def CYG_HAL_MIPS_SIM
292 if( (count % 1000) == 0 )
293 {
294 // This code causes a fake interrupt.
295 asm volatile (
296 "xor $24,$24,$24;"
297 "mtc0 $24,$13;"
298 "lui $25,%%hi(1f);"
299 "ori $25,$25,%%lo(1f);"
300 "j other_vector;"
301 "nop;"
302 "1:"
303 :
304 :
305 : "t8", "t9"
306 );
307 }
308 #endif
309 #if 0 //def CYG_HAL_MIPS_JMR3904
310
311 {
312 // cyg_uint32 tval, isr, imr, ilr;
313 cyg_uint32 sr, cr;
314 // HAL_CLOCK_READ( &tval );
315 // HAL_READ_UINT32( 0xFFFFC000, isr );
316 // HAL_READ_UINT32( 0xFFFFC004, imr );
317 // HAL_READ_UINT32( 0xFFFFC01C, ilr );
318 // CYG_TRACE2(1, "Timer value, ISR ",tval, isr);
319 // CYG_TRACE2(1, "IMR ILR0 ", imr, ilr);
320
321 asm volatile (
322 "mfc0 %0,$12;"
323 "mfc0 %1,$13;"
324 : "=r"(sr), "=r"(cr)
325 );
326
327 CYG_TRACE2(1, "Status Cause ", sr, cr);
328
329 // if( count == 4 )
330 // {
331 // HAL_ENABLE_INTERRUPTS();
332 // }
333
334 // if( count >= 10 )
335 // for(;;);
336 }
337 #endif
338 }
339
340 /*---------------------------------------------------------------------------*/
341 /* This code installs an interrupt handler to capture Ctrl-C. */
342 /* It's here for lack of anywhere more suitable to put it. */
343
344 #if defined(CYG_HAL_USE_ROM_MONITOR) && \
345 !defined(CYGDBG_INFRA_DIAG_USE_DEVICE) && \
346 defined(CYG_HAL_TX39_JMR3904)
347
348 #define DIAG_BASE 0xfffff300
349 #define DIAG_SLCR (DIAG_BASE+0x00)
350 #define DIAG_SLSR (DIAG_BASE+0x04)
351 #define DIAG_SLDICR (DIAG_BASE+0x08)
352 #define DIAG_SLDISR (DIAG_BASE+0x0C)
353 #define DIAG_SFCR (DIAG_BASE+0x10)
354 #define DIAG_SBRG (DIAG_BASE+0x14)
355 #define DIAG_TFIFO (DIAG_BASE+0x20)
356 #define DIAG_RFIFO (DIAG_BASE+0x30)
357
358 #define BRG_T0 0x0000
359 #define BRG_T2 0x0100
360 #define BRG_T4 0x0200
361 #define BRG_T5 0x0300
362
363 static cyg_uint32 hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
364 {
365 char c;
366 CYG_WORD16 disr;
367
368 HAL_READ_UINT16( DIAG_SLDISR , disr );
369
370 if( disr & 0x0001 )
371 {
372
373 disr = disr & ~0x0001;
374
375 HAL_READ_UINT8( DIAG_RFIFO, c );
376
377 HAL_WRITE_UINT16( DIAG_SLDISR , disr );
378
379 #if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
380 if( c == 3 )
381 {
382 // Ctrl-C: breakpoint.
383 extern void breakpoint(void);
384 breakpoint();
385 }
386 #elif defined(CYG_HAL_USE_ROM_MONITOR) && defined(CYG_HAL_USE_ROM_MONITOR_GDB_STUBS)
387 if( c == 3 )
388 {
389 // Ctrl-C: breakpoint.
390 // HAL_BREAKPOINT(_breakinst);
391 typedef void bpt_fn(void);
392 bpt_fn *bfn = ((bpt_fn **)0x80000100)[61];
393
394 bfn();
395 }
396 #elif defined(CYG_HAL_USE_ROM_MONITOR) && defined(CYG_HAL_USE_ROM_MONITOR_CYGMON)
397 if( c == 3 )
398 {
399 // Ctrl-C: breakpoint.
400 HAL_BREAKPOINT(_breakinst1);
401 }
402 #endif
403 }
404
405 return 0;
406 }
407
408
409 static void hal_init_ctrlc_intr(void)
410 {
411 CYG_WORD16 dicr;
412
413 HAL_INTERRUPT_ATTACH( CYG_VECTOR_SIO_0, hal_ctrlc_isr, NULL, NULL );
414
415 HAL_INTERRUPT_UNMASK( CYG_VECTOR_SIO_0 );
416
417 HAL_READ_UINT16( DIAG_SLDICR , dicr );
418 dicr = 0x0001;
419 HAL_WRITE_UINT16( DIAG_SLDICR , dicr );
420 }
421
422 #endif
423
424 /*---------------------------------------------------------------------------*/
425 /* End of hal_misc.c */