Mercurial > flash_v2
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 */ |
