Mercurial > flash_v2
diff packages/hal/arm/arch/current/src/hal_misc.c @ 2:443894e2e912 ecos-v1_2_1-release
Block commit of eCos version 1.2.1
| author | jlarmour |
|---|---|
| date | Tue, 11 May 1999 12:24:34 +0000 |
| parents | |
| children | 5f5102441818 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/packages/hal/arm/arch/current/src/hal_misc.c @@ -0,0 +1,381 @@ +/*========================================================================== +// +// hal_misc.c +// +// HAL miscellaneous functions +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Cygnus eCos Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://sourceware.cygnus.com/ecos +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Cygnus Operating System, released +// September 30, 1998. +// +// The Initial Developer of the Original Code is Cygnus. Portions created +// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): nickg, gthomas +// Contributors: nickg, gthomas +// Date: 1999-02-20 +// Purpose: HAL miscellaneous functions +// Description: This file contains miscellaneous functions provided by the +// HAL. +// +//####DESCRIPTIONEND#### +// +//=========================================================================*/ + +#include <pkgconf/hal.h> +#include <pkgconf/hal_arm.h> +#ifdef CYGPKG_KERNEL +#include <pkgconf/kernel.h> +#endif + +#include <cyg/infra/cyg_type.h> +#include <cyg/infra/cyg_trac.h> // tracing macros +#include <cyg/infra/cyg_ass.h> // assertion macros + +#include <cyg/hal/hal_arch.h> // HAL header +#include <cyg/hal/hal_intr.h> // HAL header + +externC void diag_printf(const char *fmt, ...); + +/*------------------------------------------------------------------------*/ +/* First level C exception handler. */ + +externC void __handle_exception (void); + +externC HAL_SavedRegisters *_hal_registers; +extern void *__mem_fault_handler; + +#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS +/* Force exception handling into the GDB stubs. This is done by taking over + the exception vectors while executing in the stubs. This allows for the + debugged program to handle exceptions itself, except while the GDB + processing is underway. The only vector that can't be handled this way + is the illegal instruction vector which is used for breakpoint/single-step + and must be maintained by the stubs at all times. +*/ + +#define ARM_VECTORS 8 +extern unsigned long vectors[]; // exception vectors as defined by the stubs +static unsigned long *hardware_vectors = (unsigned long *)0x20; +static unsigned long hold_vectors[ARM_VECTORS]; + +static int exception_level; + +static void +__take_over_debug_traps(void) +{ + int i; + for (i = 0; i < ARM_VECTORS; i++) { + hold_vectors[i] = hardware_vectors[i]; + hardware_vectors[i] = vectors[i]; + } +} + +static void +__restore_debug_traps(void) +{ + int i; + for (i = 0; i < ARM_VECTORS; i++) { + hardware_vectors[i] = hold_vectors[i]; + } +} +#endif + +void +exception_handler(HAL_SavedRegisters *regs) +{ +#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS + if (__mem_fault_handler && + regs->vector == CYGNUM_HAL_EXCEPTION_DATA_ACCESS) { + regs->pc = (unsigned long)__mem_fault_handler; + return; // Caught an exception inside stubs + } + + if (++exception_level == 1) __take_over_debug_traps(); + + _hal_registers = regs; + __handle_exception(); + + // We should decode the vector and pass a more appropriate + // value as the second argument. For now we simply pass a + // pointer to the saved registers. We should also divert + // breakpoint and other debug vectors into the debug stubs. + + if (--exception_level == 0) __restore_debug_traps(); + +#elif defined(CYGPKG_KERNEL_EXCEPTIONS) + + cyg_hal_deliver_exception( regs->vector, (CYG_ADDRWORD)regs ); + +#else + + CYG_FAIL("Exception!!!"); + +#endif + + return; +} + +/*------------------------------------------------------------------------*/ +/* C++ support - run initial constructors */ + +#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG +cyg_bool cyg_hal_stop_constructors; +#endif + +typedef void (*pfunc) (void); +extern pfunc __CTOR_LIST__[]; +extern pfunc __CTOR_END__[]; + +void +cyg_hal_invoke_constructors (void) +{ + +#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG + static pfunc *p = &__CTOR_END__[-1]; + + cyg_hal_stop_constructors = 0; + for (; p >= __CTOR_LIST__; p--) { + (*p) (); + if (cyg_hal_stop_constructors) { + p--; + break; + } + } +#else + pfunc *p; + + for (p = &__CTOR_END__[-1]; p >= __CTOR_LIST__; p--) + (*p) (); +#endif +} + +/*------------------------------------------------------------------------*/ +/* default ISR */ + +externC cyg_uint32 +hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) +{ + CYG_TRACE1(true, "Interrupt: %d", vector); + diag_printf("Spurious Interrupt!!! - vector: %d, data: %x\n", vector, + data); + CYG_FAIL("Spurious Interrupt!!!"); + return 0; +} + +/*------------------------------------------------------------------------*/ +/* Idle thread action */ + +void +hal_idle_thread_action( cyg_uint32 count ) +{ +} + +/*-------------------------------------------------------------------------*/ +/* Misc functions */ + +#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS +/* This function will generate a breakpoint exception. It is used at the + beginning of a program to sync up with a debugger and can be used + otherwise as a quick means to stop program execution and "break" into + the debugger. */ + +void +breakpoint(void) +{ + HAL_BREAKPOINT(breakinst); +} + + +/* This function returns the opcode for a 'trap' instruction. */ + +unsigned long +__break_opcode (void) +{ + return HAL_BREAKINST; +} +#endif + +int +hal_lsbindex(int mask) +{ + int i; + for (i = 0; i < 32; i++) { + if (mask & (1<<i)) return (i); + } + return (-1); +} + +int +hal_msbindex(int mask) +{ + int i; + for (i = 32; i >= 0; i++) { + if (mask & (1<<i)) return (i); + } + return (-1); +} + +void +dump_buf_with_offset(unsigned char *p, + int s, + unsigned char *base) +{ + int i, c; + if ((unsigned int)s > (unsigned int)p) { + s = (unsigned int)s - (unsigned int)p; + } + while (s > 0) { + if (base) { + diag_printf("%08X: ", (int)p - (int)base); + } else { + diag_printf("%08X: ", p); + } + for (i = 0; i < 16; i++) { + if (i < s) { + diag_printf("%02X", p[i] & 0xFF); + } else { + diag_printf(" "); + } + if ((i % 2) == 1) diag_printf(" "); + if ((i % 8) == 7) diag_printf(" "); + } + diag_printf(" |"); + for (i = 0; i < 16; i++) { + if (i < s) { + c = p[i] & 0xFF; + if ((c < 0x20) || (c >= 0x7F)) c = '.'; + } else { + c = ' '; + } + diag_printf("%c", c); + } + diag_printf("|\n"); + s -= 16; + p += 16; + } +} + +void +dump_buf(unsigned char *p, int s) +{ + dump_buf_with_offset(p, s, 0); +} + +#ifdef CYGHWR_HAL_ARM_DUMP_EXCEPTIONS +void +dump_frame(unsigned char *frame) +{ + HAL_SavedRegisters *rp = (HAL_SavedRegisters *)frame; + int i; + dump_buf(frame, 128); + diag_printf("Registers:\n"); + for (i = 0; i <= 10; i++) { + if ((i == 0) || (i == 6)) diag_printf("R%d: ", i); + diag_printf("%08X ", rp->d[i]); + if ((i == 5) || (i == 10)) diag_printf("\n"); + } + diag_printf("FP: %08X, SP: %08X, LR: %08X, PC: %08X, PSR: %08X\n", + rp->fp, rp->sp, rp->lr, rp->pc, rp->cpsr); +} +#endif + +#if 0 +void +show_frame_in(HAL_SavedRegisters *frame) +{ + int old; + HAL_DISABLE_INTERRUPTS(old); + diag_printf("[IN] IRQ Frame:\n"); + dump_frame((unsigned char *)frame); + HAL_RESTORE_INTERRUPTS(old); +} + +void +show_frame_out(HAL_SavedRegisters *frame) +{ + int old; + HAL_DISABLE_INTERRUPTS(old); + diag_printf("[OUT] IRQ Frame:\n"); + dump_frame((unsigned char *)frame); + HAL_RESTORE_INTERRUPTS(old); +} +#endif + +#ifdef CYGHWR_HAL_ARM_DUMP_EXCEPTIONS +// Debug routines +void undefined_instruction(HAL_SavedRegisters *frame) +{ + int old; + HAL_DISABLE_INTERRUPTS(old); + diag_printf("[UNDEFINED INSTRUCTION] Frame:\n"); + dump_frame((unsigned char *)frame); + HAL_RESTORE_INTERRUPTS(old); +} + +void software_interrupt(HAL_SavedRegisters *frame) +{ + int old; + HAL_DISABLE_INTERRUPTS(old); + diag_printf("[SOFTWARE INTERRUPT] Frame:\n"); + dump_frame((unsigned char *)frame); + HAL_RESTORE_INTERRUPTS(old); +} + +void abort_prefetch(HAL_SavedRegisters *frame) +{ + int old; + HAL_DISABLE_INTERRUPTS(old); + diag_printf("[ABORT PREFETCH] Frame:\n"); + dump_frame((unsigned char *)frame); + HAL_RESTORE_INTERRUPTS(old); +} + +void abort_data(HAL_SavedRegisters *frame) +{ + int old; + HAL_DISABLE_INTERRUPTS(old); + diag_printf("[ABORT DATA] Frame:\n"); + dump_frame((unsigned char *)frame); + HAL_RESTORE_INTERRUPTS(old); +} + +void FIQ(HAL_SavedRegisters *frame) +{ + int old; + HAL_DISABLE_INTERRUPTS(old); + diag_printf("[FIQ] Frame:\n"); + dump_frame((unsigned char *)frame); + HAL_RESTORE_INTERRUPTS(old); +} + +void exception_handler_returned(HAL_SavedRegisters *frame) +{ + int old; + HAL_DISABLE_INTERRUPTS(old); + diag_printf("Exception handler returned!\n"); + dump_frame((unsigned char *)frame); + HAL_RESTORE_INTERRUPTS(old); +} +#endif + +/*------------------------------------------------------------------------*/ +// EOF hal_misc.c
