Mercurial > ecos
comparison packages/hal/calmrisc16/arch/current/src/hal_misc.c @ 208:e0c0827131d1 ecos
Merge from eCos master repository on 2002-05-20-20:11:54-BST
| author | jlarmour |
|---|---|
| date | Mon, 20 May 2002 22:19:26 +0000 |
| parents | |
| children | d2c90368aeef |
comparison
equal
deleted
inserted
replaced
| 207:74c807ddde34 | 208:e0c0827131d1 |
|---|---|
| 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 | |
| 45 // Date: 1999-01-21 | |
| 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> // Base types | |
| 57 #include <cyg/infra/cyg_trac.h> // tracing macros | |
| 58 #include <cyg/infra/cyg_ass.h> // assertion macros | |
| 59 | |
| 60 #define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS | |
| 61 #include <cyg/hal/hal_arch.h> // architectural definitions | |
| 62 | |
| 63 #include <cyg/hal/hal_intr.h> // Interrupt handling | |
| 64 | |
| 65 #include <cyg/hal/hal_cache.h> // Cache handling | |
| 66 | |
| 67 /*------------------------------------------------------------------------*/ | |
| 68 /* If required, define a variable to store the clock period. */ | |
| 69 | |
| 70 #ifdef CYGHWR_HAL_CLOCK_PERIOD_DEFINED | |
| 71 | |
| 72 CYG_WORD32 cyg_hal_clock_period; | |
| 73 | |
| 74 #endif | |
| 75 | |
| 76 /*------------------------------------------------------------------------*/ | |
| 77 /* First level C exception handler. */ | |
| 78 | |
| 79 externC void __handle_exception (void); | |
| 80 | |
| 81 externC HAL_SavedRegisters *_hal_registers; | |
| 82 | |
| 83 externC void* volatile __mem_fault_handler; | |
| 84 | |
| 85 externC cyg_uint32 cyg_hal_exception_handler(HAL_SavedRegisters *regs) | |
| 86 { | |
| 87 int vec = regs->vector; | |
| 88 | |
| 89 // adjust PC after 'break' insns | |
| 90 if (vec == CYGNUM_HAL_VECTOR_IRQ) { | |
| 91 if (__read_prog_uint16((void *)(regs->spc_irq - 2)) == HAL_BREAKINST) | |
| 92 regs->spc_irq -= 2; | |
| 93 } | |
| 94 | |
| 95 #if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) | |
| 96 | |
| 97 // If we caught an exception inside the stubs, see if we were expecting it | |
| 98 // and if so jump to the saved address | |
| 99 if (__mem_fault_handler) { | |
| 100 switch (vec) { | |
| 101 case CYGNUM_HAL_VECTOR_SWI: | |
| 102 regs->a[6] = (CYG_ADDRWORD)__mem_fault_handler; | |
| 103 break; | |
| 104 case CYGNUM_HAL_VECTOR_FIQ: | |
| 105 regs->spc_fiq = (CYG_ADDRWORD)__mem_fault_handler; | |
| 106 break; | |
| 107 default: | |
| 108 regs->spc_irq = (CYG_ADDRWORD)__mem_fault_handler; | |
| 109 break; | |
| 110 } | |
| 111 return 0; // Caught an exception inside stubs | |
| 112 } | |
| 113 | |
| 114 // Set the pointer to the registers of the current exception | |
| 115 // context. At entry the GDB stub will expand the | |
| 116 // HAL_SavedRegisters structure into a (bigger) register array. | |
| 117 _hal_registers = regs; | |
| 118 __handle_exception(); | |
| 119 | |
| 120 #elif defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && defined(CYGPKG_HAL_EXCEPTIONS) | |
| 121 | |
| 122 // We should decode the vector and pass a more appropriate | |
| 123 // value as the second argument. For now we simply pass a | |
| 124 // pointer to the saved registers. We should also divert | |
| 125 // breakpoint and other debug vectors into the debug stubs. | |
| 126 | |
| 127 cyg_hal_deliver_exception( vec, (CYG_ADDRWORD)regs ); | |
| 128 | |
| 129 #else | |
| 130 | |
| 131 CYG_FAIL("Exception!!!"); | |
| 132 | |
| 133 #endif | |
| 134 return 0; | |
| 135 } | |
| 136 | |
| 137 /*------------------------------------------------------------------------*/ | |
| 138 /* default ISR */ | |
| 139 | |
| 140 #ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT | |
| 141 externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) | |
| 142 { | |
| 143 #if defined(CYGDBG_HAL_CALM32_DEBUG_GDB_CTRLC_SUPPORT) && \ | |
| 144 defined(CYGHWR_HAL_GDB_PORT_VECTOR) && \ | |
| 145 defined(HAL_CTRLC_ISR) | |
| 146 | |
| 147 #ifndef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN | |
| 148 if( vector == CYGHWR_HAL_GDB_PORT_VECTOR ) | |
| 149 #endif | |
| 150 { | |
| 151 cyg_uint32 result = HAL_CTRLC_ISR( vector, data ); | |
| 152 if( result != 0 ) return result; | |
| 153 } | |
| 154 | |
| 155 #if defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon) | |
| 156 #if defined(HAL_DIAG_IRQ_CHECK) | |
| 157 { | |
| 158 cyg_uint32 ret; | |
| 159 /* let ROM monitor handle unexpected interrupts */ | |
| 160 HAL_DIAG_IRQ_CHECK(vector, ret); | |
| 161 if (ret<=0) | |
| 162 return ret; | |
| 163 } | |
| 164 #endif // def HAL_DIAG_IRQ_CHECK | |
| 165 #endif // def CYGSEM_HAL_USE_ROM_MONITOR_CygMon | |
| 166 #endif | |
| 167 | |
| 168 CYG_TRACE1(true, "Interrupt: %d", vector); | |
| 169 CYG_FAIL("Spurious Interrupt!!!"); | |
| 170 return 0; | |
| 171 } | |
| 172 | |
| 173 #else // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT | |
| 174 | |
| 175 externC cyg_uint32 hal_arch_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) | |
| 176 { | |
| 177 #if defined(CYGDBG_HAL_CALM16_DEBUG_GDB_CTRLC_SUPPORT) && \ | |
| 178 defined(CYGHWR_HAL_GDB_PORT_VECTOR) && \ | |
| 179 defined(HAL_CTRLC_ISR) | |
| 180 | |
| 181 #if defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon) | |
| 182 #if defined(HAL_DIAG_IRQ_CHECK) | |
| 183 { | |
| 184 cyg_uint32 ret; | |
| 185 /* let ROM monitor handle unexpected interrupts */ | |
| 186 HAL_DIAG_IRQ_CHECK(vector, ret); | |
| 187 if (ret<=0) | |
| 188 return ret; | |
| 189 } | |
| 190 #endif // def HAL_DIAG_IRQ_CHECK | |
| 191 #endif // def CYGSEM_HAL_USE_ROM_MONITOR_CygMon | |
| 192 #endif | |
| 193 | |
| 194 return 0; | |
| 195 } | |
| 196 | |
| 197 #endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT | |
| 198 | |
| 199 /*------------------------------------------------------------------------*/ | |
| 200 /* data copy and bss zero functions */ | |
| 201 | |
| 202 typedef void (CYG_SYM_ADDRESS)(void); | |
| 203 | |
| 204 // All these must use this type of address to stop them being given relocations | |
| 205 // relative to $gp (i.e. assuming they would be in .sdata) | |
| 206 extern CYG_SYM_ADDRESS __ram_data_start; | |
| 207 extern CYG_SYM_ADDRESS __ram_data_end; | |
| 208 extern CYG_SYM_ADDRESS __rom_data_start; | |
| 209 | |
| 210 #ifdef CYG_HAL_STARTUP_ROM | |
| 211 void hal_copy_data(void) | |
| 212 { | |
| 213 short *p = (short *)&__ram_data_start; | |
| 214 short *q = (short *)&__rom_data_start; | |
| 215 short x; | |
| 216 | |
| 217 while( p != (short *)&__ram_data_end ) { | |
| 218 asm volatile( "ldc %0,@%1\n" : "=r"(x) : "r"(q) ); | |
| 219 *p++ = x; | |
| 220 q++; | |
| 221 } | |
| 222 } | |
| 223 #endif | |
| 224 | |
| 225 extern CYG_SYM_ADDRESS __bss_start; | |
| 226 extern CYG_SYM_ADDRESS __bss_end; | |
| 227 | |
| 228 void hal_zero_bss(void) | |
| 229 { | |
| 230 short *p = (short *)&__bss_start; | |
| 231 | |
| 232 while( p != (short *)&__bss_end ) | |
| 233 *p++ = 0; | |
| 234 } | |
| 235 | |
| 236 /*------------------------------------------------------------------------*/ | |
| 237 | |
| 238 #ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG | |
| 239 cyg_bool cyg_hal_stop_constructors; | |
| 240 #endif | |
| 241 | |
| 242 typedef void (*pfunc) (void); | |
| 243 extern pfunc __CTOR_LIST__[]; | |
| 244 extern pfunc __CTOR_END__[]; | |
| 245 | |
| 246 void | |
| 247 cyg_hal_invoke_constructors(void) | |
| 248 { | |
| 249 #ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG | |
| 250 static pfunc *p = &__CTOR_END__[-1]; | |
| 251 | |
| 252 cyg_hal_stop_constructors = 0; | |
| 253 for (; p >= __CTOR_LIST__; p--) { | |
| 254 (*p) (); | |
| 255 if (cyg_hal_stop_constructors) { | |
| 256 p--; | |
| 257 break; | |
| 258 } | |
| 259 } | |
| 260 #else | |
| 261 pfunc *p; | |
| 262 | |
| 263 for (p = &__CTOR_END__[-1]; p >= __CTOR_LIST__; p--) | |
| 264 (*p) (); | |
| 265 #endif | |
| 266 | |
| 267 } // cyg_hal_invoke_constructors() | |
| 268 | |
| 269 /*------------------------------------------------------------------------*/ | |
| 270 /* Determine the index of the ls bit of the supplied mask. */ | |
| 271 | |
| 272 cyg_uint32 hal_lsbit_index(cyg_uint32 mask) | |
| 273 { | |
| 274 cyg_uint32 n = mask; | |
| 275 | |
| 276 static const signed char tab[64] = | |
| 277 { -1, 0, 1, 12, 2, 6, 0, 13, 3, 0, 7, 0, 0, 0, 0, 14, 10, | |
| 278 4, 0, 0, 8, 0, 0, 25, 0, 0, 0, 0, 0, 21, 27 , 15, 31, 11, | |
| 279 5, 0, 0, 0, 0, 0, 9, 0, 0, 24, 0, 0 , 20, 26, 30, 0, 0, 0, | |
| 280 0, 23, 0, 19, 29, 0, 22, 18, 28, 17, 16, 0 | |
| 281 }; | |
| 282 | |
| 283 n &= ~(n-1UL); | |
| 284 n = (n<<16)-n; | |
| 285 n = (n<<6)+n; | |
| 286 n = (n<<4)+n; | |
| 287 | |
| 288 return tab[n>>26]; | |
| 289 } | |
| 290 | |
| 291 /*------------------------------------------------------------------------*/ | |
| 292 /* Determine the index of the ms bit of the supplied mask. */ | |
| 293 | |
| 294 cyg_uint32 hal_msbit_index(cyg_uint32 mask) | |
| 295 { | |
| 296 cyg_uint32 x = mask; | |
| 297 cyg_uint32 w; | |
| 298 | |
| 299 /* Phase 1: make word with all ones from that one to the right */ | |
| 300 x |= x >> 16; | |
| 301 x |= x >> 8; | |
| 302 x |= x >> 4; | |
| 303 x |= x >> 2; | |
| 304 x |= x >> 1; | |
| 305 | |
| 306 /* Phase 2: calculate number of "1" bits in the word */ | |
| 307 w = (x & 0x55555555) + ((x >> 1) & 0x55555555); | |
| 308 w = (w & 0x33333333) + ((w >> 2) & 0x33333333); | |
| 309 w = w + (w >> 4); | |
| 310 w = (w & 0x000F000F) + ((w >> 8) & 0x000F000F); | |
| 311 return (cyg_uint32)((w + (w >> 16)) & 0xFF) - 1; | |
| 312 | |
| 313 } | |
| 314 | |
| 315 /*------------------------------------------------------------------------*/ | |
| 316 /* Idle thread action */ | |
| 317 | |
| 318 #include <cyg/infra/diag.h> | |
| 319 | |
| 320 void hal_idle_thread_action( cyg_uint32 count ) | |
| 321 { | |
| 322 } | |
| 323 | |
| 324 /*------------------------------------------------------------------------*/ | |
| 325 /* End of hal_misc.c */ |
