URL
https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk
Subversion Repositories openrisc_me
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/rtos/ecos-2.0/packages/hal/frv/arch/v2_0
- from Rev 27 to Rev 174
- ↔ Reverse comparison
Rev 27 → Rev 174
/cdl/hal_frv.cdl
0,0 → 1,157
# ==================================================================== |
# |
# hal_frv.cdl |
# |
# FUJITSU architectural HAL package configuration data |
# |
# ==================================================================== |
#####ECOSGPLCOPYRIGHTBEGIN#### |
## ------------------------------------------- |
## This file is part of eCos, the Embedded Configurable Operating System. |
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
## |
## eCos is free software; you can redistribute it and/or modify it under |
## the terms of the GNU General Public License as published by the Free |
## Software Foundation; either version 2 or (at your option) any later version. |
## |
## eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
## WARRANTY; without even the implied warranty of MERCHANTABILITY or |
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
## for more details. |
## |
## You should have received a copy of the GNU General Public License along |
## with eCos; if not, write to the Free Software Foundation, Inc., |
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
## |
## As a special exception, if other files instantiate templates or use macros |
## or inline functions from this file, or you compile this file and link it |
## with other works to produce a work based on this file, this file does not |
## by itself cause the resulting work to be covered by the GNU General Public |
## License. However the source code for this file must still be made available |
## in accordance with section (3) of the GNU General Public License. |
## |
## This exception does not invalidate any other reasons why a work based on |
## this file might be covered by the GNU General Public License. |
## |
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
## at http://sources.redhat.com/ecos/ecos-license/ |
## ------------------------------------------- |
#####ECOSGPLCOPYRIGHTEND#### |
# ==================================================================== |
######DESCRIPTIONBEGIN#### |
# |
# Author(s): bartv |
# Original data: gthomas |
# Contributors: |
# Date: 2001-09-07 |
# |
#####DESCRIPTIONEND#### |
# |
# ==================================================================== |
cdl_package CYGPKG_HAL_FRV { |
display "FUJITSU architecture" |
parent CYGPKG_HAL |
hardware |
include_dir cyg/hal |
define_header hal_frv.h |
description " |
The FUJITSU architecture HAL package provides generic |
support for this processor architecture. It is also |
necessary to select a specific target platform HAL |
package." |
|
compile hal_misc.c context.S frv_stub.c hal_syscall.c |
|
# special rule used to build any include files, etc, used by assembly code |
make -priority 1 { |
frv.inc : <PACKAGE>/src/hal_mk_defs.c |
$(CC) $(CFLAGS) $(INCLUDE_PATH) -Wp,-MD,frv.tmp -o hal_mk_defs.tmp -S $< |
fgrep .equ hal_mk_defs.tmp | sed s/#// | sed s/\\.equ/#define/ > $@ |
@echo $@ ": \\" > $(notdir $@).deps |
@tail +2 frv.tmp >> $(notdir $@).deps |
@echo >> $(notdir $@).deps |
@rm frv.tmp hal_mk_defs.tmp |
} |
|
make { |
<PREFIX>/lib/vectors.o : <PACKAGE>/src/vectors.S |
$(CC) -Wp,-MD,vectors.tmp $(INCLUDE_PATH) $(CFLAGS) -c -o $@ $< |
@echo $@ ": \\" > $(notdir $@).deps |
@tail +2 vectors.tmp >> $(notdir $@).deps |
@echo >> $(notdir $@).deps |
@rm vectors.tmp |
} |
|
make { |
<PREFIX>/lib/target.ld: <PACKAGE>/src/frv.ld |
$(CC) -E -P -Wp,-MD,target.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(CFLAGS) -o $@ $< |
@echo $@ ": \\" > $(notdir $@).deps |
@tail +2 target.tmp >> $(notdir $@).deps |
@echo >> $(notdir $@).deps |
@rm target.tmp |
} |
|
cdl_interface CYGINT_HAL_FRV_ARCH_FR400 { |
display "The CPU architecture supports the FR400 architecture" |
} |
|
cdl_interface CYGINT_HAL_FRV_ARCH_FR500 { |
display "The CPU architecture supports the FR500 architecture" |
} |
|
cdl_option CYGHWR_HAL_FRV_CPU_FAMILY { |
display "FUJITSU CPU family" |
flavor data |
legal_values { (CYGINT_HAL_FRV_ARCH_FR400 != 0) ? "FR400" : "" |
(CYGINT_HAL_FRV_ARCH_FR500 != 0) ? "FR500" : "" |
"" } |
default_value { (CYGINT_HAL_FRV_ARCH_FR400 != 0) ? "FR400" : |
(CYGINT_HAL_FRV_ARCH_FR500 != 0) ? "FR500" : |
"unknown" } |
no_define |
description " |
It is possible to optimize code for different |
FUJITSU CPU families. This option selects which CPU to |
optimize for on boards that support multiple CPU types." |
} |
|
cdl_option CYGBLD_LINKER_SCRIPT { |
display "Linker script" |
flavor data |
no_define |
calculated { "src/frv.ld" } |
} |
|
cdl_interface CYGINT_HAL_FRV_MEM_REAL_REGION_TOP { |
display "Implementations of hal_frv_mem_real_region_top()" |
} |
|
cdl_option CYGNUM_HAL_BREAKPOINT_LIST_SIZE { |
display "Number of breakpoints supported by the HAL." |
flavor data |
default_value 32 |
active_if CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS |
description " |
This option determines the number of breakpoints supported by the HAL." |
} |
|
cdl_option CYGSEM_HAL_FRV_USE_BREAK_INSTRUCTION { |
display "Use 'break' for breakpoints." |
flavor bool |
default_value 1 |
active_if { CYGINT_HAL_FRV_ARCH_FR500 != 0 } |
requires CYGNUM_HAL_BREAKPOINT_LIST_SIZE |
description " |
Select this option to use the 'break' instruction for breakpoints. |
This option can only be used if the GDB stubs use local breakpoints." |
} |
|
cdl_option CYGSEM_HAL_FRV_HW_DEBUG { |
display "Hardware debug features available" |
flavor bool |
default_value 1 |
active_if { CYGINT_HAL_FRV_ARCH_FR500 != 0 } |
description " |
Select this option to enable the use of a hardware debug unit." |
} |
} |
/include/frv_stub.h
0,0 → 1,154
#ifndef CYGONCE_HAL_FRV_STUB_H |
#define CYGONCE_HAL_FRV_STUB_H |
//======================================================================== |
// |
// frv_stub.h |
// |
// FUJITSU-specific definitions for generic stub |
// |
//======================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//======================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): Red Hat, gthomas |
// Contributors: Red Hat, gthomas |
// Date: 2001-09-14 |
// Purpose: |
// Description: FUJITSU-specific definitions for generic stub |
// Usage: |
// |
//####DESCRIPTIONEND#### |
// |
//======================================================================== |
|
#ifdef __cplusplus |
extern "C" { |
#endif |
|
#define NUMREGS (147) |
|
#define REGSIZE( _x_ ) (4) |
|
#define NUMREGBYTES (NUMREGS*4) |
|
#ifndef TARGET_REGISTER_T_DEFINED |
#define TARGET_REGISTER_T_DEFINED |
typedef cyg_uint32 target_register_t; |
#endif |
|
// This information needs to match what GDB wants |
enum regnames { |
R0, R1, R2, R3, R4, R5, R6, R7, |
R8, R9, R10, R11, R12, R13, R14, R15, |
R16, R17, R18, R19, R20, R21, R22, R23, |
R24, R25, R26, R27, R28, R29, R30, R31, |
R32, R33, R34, R35, R36, R37, R38, R39, |
R40, R41, R42, R43, R44, R45, R46, R47, |
R48, R49, R50, R51, R52, R53, R54, R55, |
R56, R57, R58, R59, R60, R61, R62, R63, |
FP0, FP1, FP2, FP3, FP4, FP5, FP6, FP7, |
FP8, FP9, FP10, FP11, FP12, FP13, FP14, FP15, |
FP16, FP17, FP18, FP19, FP20, FP21, FP22, FP23, |
FP24, FP25, FP26, FP27, FP28, FP29, FP30, FP31, |
FP32, FP33, FP34, FP35, FP36, FP37, FP38, FP39, |
FP40, FP41, FP42, FP43, FP44, FP45, FP46, FP47, |
FP48, FP49, FP50, FP51, FP52, FP53, FP54, FP55, |
FP56, FP57, FP58, FP59, FP60, FP61, FP62, FP63, |
PC, PSR, CCR, CCCR, |
_X132, _X133, _X134, _X135, _X136, _X137, _X138, |
_X139, _X140, _X141, _X142, _X143, _X144, |
LR, LCR |
}; |
#define SP R1 |
|
typedef enum regnames regnames_t; |
|
/* Given a trap value TRAP, return the corresponding signal. */ |
extern int __computeSignal (unsigned int trap_number); |
|
/* Return the SPARC trap number corresponding to the last-taken trap. */ |
extern int __get_trap_number (void); |
|
/* Return the currently-saved value corresponding to register REG. */ |
extern target_register_t get_register (regnames_t reg); |
|
/* Store VALUE in the register corresponding to WHICH. */ |
extern void put_register (regnames_t which, target_register_t value); |
|
/* Set the currently-saved pc register value to PC. This also updates NPC |
as needed. */ |
extern void set_pc (target_register_t pc); |
|
/* Set things up so that the next user resume will execute one instruction. |
This may be done by setting breakpoints or setting a single step flag |
in the saved user registers, for example. */ |
void __single_step (void); |
|
/* Clear the single-step state. */ |
void __clear_single_step (void); |
|
/* If the breakpoint we hit is in the breakpoint() instruction, return a |
non-zero value. */ |
extern int __is_breakpoint_function (void); |
|
/* Skip the current instruction. */ |
extern void __skipinst (void); |
|
extern void __install_breakpoints (void); |
|
extern void __clear_breakpoints (void); |
|
extern int __is_bsp_syscall(void); |
|
//------------------------------------------------------------------------ |
// Special definition of CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION |
|
#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT |
// we can only do this at all if break support is enabled: |
|
#define CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION( _old_ ) \ |
do { \ |
HAL_DISABLE_INTERRUPTS(_old_); \ |
cyg_hal_gdb_place_break((target_register_t)&&cyg_hal_gdb_break_place ); \ |
} while ( 0 ) |
|
#endif // CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT |
|
|
#ifdef __cplusplus |
} /* extern "C" */ |
#endif |
|
#endif // ifndef CYGONCE_HAL_FRV_STUB_H |
/include/hal_io.h
0,0 → 1,184
#ifndef CYGONCE_HAL_IO_H |
#define CYGONCE_HAL_IO_H |
|
//============================================================================= |
// |
// hal_io.h |
// |
// HAL device IO register support. |
// |
//============================================================================= |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//============================================================================= |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): nickg, gthomas |
// Contributors: nickg, gthomas |
// Date: 1998-09-11 |
// Purpose: Define IO register support |
// Description: The macros defined here provide the HAL APIs for handling |
// device IO control registers. |
// |
// Usage: |
// #include <cyg/hal/hal_io.h> |
// ... |
// |
// |
//####DESCRIPTIONEND#### |
// |
//============================================================================= |
|
#include <pkgconf/system.h> |
#include <cyg/infra/cyg_type.h> |
|
#include <cyg/hal/basetype.h> |
|
//----------------------------------------------------------------------------- |
// IO Register address. |
// This type is for recording the address of an IO register. |
|
typedef volatile CYG_ADDRWORD HAL_IO_REGISTER; |
|
|
//----------------------------------------------------------------------------- |
// BYTE Register access. |
// Individual and vectorized access to 8 bit registers. |
|
#define HAL_READ_UINT8( _register_, _value_ ) \ |
CYG_MACRO_START \ |
((_value_) = *((volatile CYG_BYTE *)((CYG_ADDRWORD)(_register_)))); \ |
HAL_IO_BARRIER(); \ |
CYG_MACRO_END |
|
#define HAL_WRITE_UINT8( _register_, _value_ ) \ |
CYG_MACRO_START \ |
(*((volatile CYG_BYTE *)((CYG_ADDRWORD)(_register_))) = (_value_)); \ |
HAL_IO_BARRIER(); \ |
CYG_MACRO_END |
|
#define HAL_READ_UINT8_VECTOR( _register_, _buf_, _count_, _step_ ) \ |
CYG_MACRO_START \ |
cyg_count32 _i_,_j_; \ |
volatile CYG_BYTE* _r_ = ((CYG_ADDRWORD)(_register_)); \ |
for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ |
(_buf_)[_i_] = _r_[_j_]; \ |
CYG_MACRO_END |
|
#define HAL_WRITE_UINT8_VECTOR( _register_, _buf_, _count_, _step_ ) \ |
CYG_MACRO_START \ |
cyg_count32 _i_,_j_; \ |
volatile CYG_BYTE* _r_ = ((CYG_ADDRWORD)(_register_)); \ |
for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ |
_r_[_j_] = (_buf_)[_i_]; \ |
CYG_MACRO_END |
|
//----------------------------------------------------------------------------- |
// 16 bit access. |
// Individual and vectorized access to 16 bit registers. |
|
#define HAL_READ_UINT16( _register_, _value_ ) \ |
CYG_MACRO_START \ |
((_value_) = *((volatile CYG_WORD16 *)((CYG_ADDRWORD)(_register_)))); \ |
HAL_IO_BARRIER(); \ |
CYG_MACRO_END |
|
#define HAL_WRITE_UINT16( _register_, _value_ ) \ |
CYG_MACRO_START \ |
(*((volatile CYG_WORD16 *)((CYG_ADDRWORD)(_register_))) = (_value_)); \ |
HAL_IO_BARRIER(); \ |
CYG_MACRO_END |
|
#define HAL_READ_UINT16_VECTOR( _register_, _buf_, _count_, _step_ ) \ |
CYG_MACRO_START \ |
cyg_count32 _i_,_j_; \ |
volatile CYG_WORD16* _r_ = ((CYG_ADDRWORD)(_register_)); \ |
for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ |
(_buf_)[_i_] = _r_[_j_]; \ |
CYG_MACRO_END |
|
#define HAL_WRITE_UINT16_VECTOR( _register_, _buf_, _count_, _step_ ) \ |
CYG_MACRO_START \ |
cyg_count32 _i_,_j_; \ |
volatile CYG_WORD16* _r_ = ((CYG_ADDRWORD)(_register_)); \ |
for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ |
_r_[_j_] = (_buf_)[_i_]; \ |
CYG_MACRO_END |
|
//----------------------------------------------------------------------------- |
// 32 bit access. |
// Individual and vectorized access to 32 bit registers. |
|
// Note: same macros for little- and big-endian systems. |
|
#define HAL_READ_UINT32( _register_, _value_ ) \ |
CYG_MACRO_START \ |
((_value_) = *((volatile CYG_WORD32 *)(_register_))); \ |
HAL_IO_BARRIER(); \ |
CYG_MACRO_END |
|
#define HAL_WRITE_UINT32( _register_, _value_ ) \ |
CYG_MACRO_START \ |
(*((volatile CYG_WORD32 *)(_register_)) = (_value_)); \ |
HAL_IO_BARRIER(); \ |
CYG_MACRO_END |
|
#define HAL_READ_UINT32_VECTOR( _register_, _buf_, _count_, _step_ ) \ |
CYG_MACRO_START \ |
cyg_count32 _i_,_j_; \ |
for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ |
(_buf_)[_i_] = ((volatile CYG_WORD32 *)(_register_))[_j_]; \ |
CYG_MACRO_END |
|
#define HAL_WRITE_UINT32_VECTOR( _register_, _buf_, _count_, _step_ ) \ |
CYG_MACRO_START \ |
cyg_count32 _i_,_j_; \ |
for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ |
((volatile CYG_WORD32 *)(_register_))[_j_] = (_buf_)[_i_]; \ |
CYG_MACRO_END |
|
// Enforce a flow "barrier" to prevent optimizing compiler from reordering |
// operations. |
#define HAL_IO_BARRIER() \ |
__asm__ volatile("membar" : : ); |
|
|
//----------------------------------------------------------------------------- |
// Include plf_io.h for platforms that define it. |
#ifdef CYGBLD_HAL_PLATFORM_IO_H |
#include CYGBLD_HAL_PLATFORM_IO_H |
#endif |
|
//----------------------------------------------------------------------------- |
#endif // ifndef CYGONCE_HAL_IO_H |
// End of hal_io.h |
/include/basetype.h
0,0 → 1,69
#ifndef CYGONCE_HAL_BASETYPE_H |
#define CYGONCE_HAL_BASETYPE_H |
|
//============================================================================= |
// |
// basetype.h |
// |
// Standard types for this architecture. |
// |
//============================================================================= |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//============================================================================= |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): nickg, gthomas |
// Contributors: nickg, gthomas |
// Date: 1998-09-11 |
// Purpose: Define architecture base types. |
// Usage: Included by "cyg_type.h", do not use directly |
|
// |
//####DESCRIPTIONEND#### |
// |
|
//----------------------------------------------------------------------------- |
// Characterize the architecture |
|
#define CYG_BYTEORDER CYG_MSBFIRST // Big endian |
|
//----------------------------------------------------------------------------- |
// ARM does not usually use labels with underscores. |
|
#define CYG_LABEL_NAME(_name_) _name_ |
#define CYG_LABEL_DEFN(_name_) _name_ |
|
//----------------------------------------------------------------------------- |
#endif // CYGONCE_HAL_BASETYPE_H |
// End of basetype.h |
/include/hal_intr.h
0,0 → 1,365
#ifndef CYGONCE_HAL_INTR_H |
#define CYGONCE_HAL_INTR_H |
|
//========================================================================== |
// |
// hal_intr.h |
// |
// HAL Interrupt and clock support |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): nickg, gthomas |
// Contributors: nickg, gthomas, |
// jlarmour |
// Date: 1999-02-20 |
// Purpose: Define Interrupt support |
// Description: The macros defined here provide the HAL APIs for handling |
// interrupts and the clock. |
// |
// Usage: #include <cyg/hal/hal_intr.h> |
// ... |
// |
// |
//####DESCRIPTIONEND#### |
// |
//========================================================================== |
|
#include <pkgconf/hal.h> |
|
#include <cyg/infra/cyg_type.h> |
|
// This is to allow a variant to decide that there is no platform-specific |
// interrupts file; and that in turn can be overridden by a platform that |
// refines the variant's ideas. |
#ifdef CYGBLD_HAL_PLF_INTS_H |
# include CYGBLD_HAL_PLF_INTS_H // should include variant data as required |
#else |
# ifdef CYGBLD_HAL_VAR_INTS_H |
# include CYGBLD_HAL_VAR_INTS_H |
# else |
# include <cyg/hal/plf_ints.h> // default less-complex platforms |
# endif |
#endif |
|
// Spurious interrupt (no interrupt source could be found) |
#define CYGNUM_HAL_INTERRUPT_NONE -1 |
|
//-------------------------------------------------------------------------- |
// FUJITSU exception vectors. |
|
// The Fujitsu FR-V architecture supports up to 256 interrupt/exceptions. |
// Each vectors to a specific VSR which is 16 bytes (4 instructions) long. |
|
// These vectors correspond to VSRs. These values are the ones to use for |
// HAL_VSR_GET/SET |
|
#define CYGNUM_HAL_VECTOR_RESET 0x00 |
#define CYGNUM_HAL_VECTOR_INSTR_ACCESS_MMU_MISS 0x01 |
#define CYGNUM_HAL_VECTOR_INSTR_ACCESS_ERROR 0x02 |
#define CYGNUM_HAL_VECTOR_INSTR_ACCESS_EXCEPTION 0x03 |
#define CYGNUM_HAL_VECTOR_PRIVELEDGED_INSTRUCTION 0x06 |
#define CYGNUM_HAL_VECTOR_ILLEGAL_INSTRUCTION 0x07 |
#define CYGNUM_HAL_VECTOR_REGISTER_EXCEPTION 0x08 |
#define CYGNUM_HAL_VECTOR_FP_DISABLED 0x0A |
#define CYGNUM_HAL_VECTOR_MP_DISABLED 0x0B |
#define CYGNUM_HAL_VECTOR_FP_EXCEPTION 0x0D |
#define CYGNUM_HAL_VECTOR_MP_EXCEPTION 0x0E |
#define CYGNUM_HAL_VECTOR_MEMORY_ADDRESS_NOT_ALIGNED 0x10 |
#define CYGNUM_HAL_VECTOR_DATA_ACCESS_ERROR 0x11 |
#define CYGNUM_HAL_VECTOR_DATA_ACCESS_MMU_MISS 0x12 |
#define CYGNUM_HAL_VECTOR_DATA_ACCESS_EXCEPTION 0x13 |
#define CYGNUM_HAL_VECTOR_DATA_STORE_ERROR 0x14 |
#define CYGNUM_HAL_VECTOR_DIVISION_EXCEPTION 0x17 |
#define CYGNUM_HAL_VECTOR_COMMIT_EXCEPTION 0x19 |
#define CYGNUM_HAL_VECTOR_COMPOUND_EXCEPTION 0x20 |
#define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_1 0x21 |
#define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_2 0x22 |
#define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_3 0x23 |
#define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_4 0x24 |
#define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_5 0x25 |
#define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_6 0x26 |
#define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_7 0x27 |
#define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_8 0x28 |
#define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_9 0x29 |
#define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_10 0x2A |
#define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_11 0x2B |
#define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_12 0x2C |
#define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_13 0x2D |
#define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_14 0x2E |
#define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_15 0x2F |
#define CYGNUM_HAL_VECTOR_SYSCALL 0x80 // tira gr0,#0 |
#define CYGNUM_HAL_VECTOR_BREAKPOINT_TRAP 0x81 // tira gr0,#1 |
#define CYGNUM_HAL_VECTOR_BREAKPOINT 0xFF // break |
|
#define CYGNUM_HAL_VSR_MIN 0 |
#define CYGNUM_HAL_VSR_MAX 255 |
#define CYGNUM_HAL_VSR_COUNT 256 |
#define CYGNUM_HAL_ISR_COUNT 256 // 1-1 mapping |
|
// Exception vectors. These are the values used when passed out to an |
// external exception handler using cyg_hal_deliver_exception() |
|
#define CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION \ |
CYGNUM_HAL_VECTOR_ILLEGAL_INSTRUCTION |
#define CYGNUM_HAL_EXCEPTION_INTERRUPT \ |
CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT |
|
#define CYGNUM_HAL_EXCEPTION_CODE_ACCESS CYGNUM_HAL_VECTOR_INSTR_ACCESS_ERROR |
#define CYGNUM_HAL_EXCEPTION_DATA_ACCESS CYGNUM_HAL_VECTOR_DATA_ACCESS_ERROR |
|
#define CYGNUM_HAL_EXCEPTION_MIN CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION |
#define CYGNUM_HAL_EXCEPTION_MAX CYGNUM_HAL_EXCEPTION_DATA_ACCESS |
#define CYGNUM_HAL_EXCEPTION_COUNT (CYGNUM_HAL_EXCEPTION_MAX - \ |
CYGNUM_HAL_EXCEPTION_MIN + 1) |
|
#define CYGNUM_HAL_ISR_MIN CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_1 |
#define CYGNUM_HAL_ISR_MAX CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_15 |
|
//-------------------------------------------------------------------------- |
// Static data used by HAL |
|
// ISR tables |
externC CYG_ADDRESS hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT]; |
externC CYG_ADDRWORD hal_interrupt_data[CYGNUM_HAL_ISR_COUNT]; |
externC CYG_ADDRESS hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT]; |
|
// VSR table |
externC CYG_ADDRESS hal_vsr_table[CYGNUM_HAL_VSR_COUNT]; |
|
// Platform setup memory size (0 if unknown by hardware) |
externC CYG_ADDRWORD hal_dram_size; |
// what, if anything, this means, is platform dependent: |
externC CYG_ADDRWORD hal_dram_type; |
|
#if CYGINT_HAL_FRV_MEM_REAL_REGION_TOP |
|
externC cyg_uint8 *hal_frv_mem_real_region_top( cyg_uint8 *_regionend_ ); |
|
# define HAL_MEM_REAL_REGION_TOP( _regionend_ ) \ |
hal_frv_mem_real_region_top( _regionend_ ) |
#endif |
|
//-------------------------------------------------------------------------- |
// Default ISR |
// The #define is used to test whether this routine exists, and to allow |
// code outside the HAL to call it. |
|
externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data); |
|
#define HAL_DEFAULT_ISR hal_default_isr |
|
//-------------------------------------------------------------------------- |
// Interrupt state storage |
|
typedef cyg_uint32 CYG_INTERRUPT_STATE; |
|
//-------------------------------------------------------------------------- |
// Interrupt control macros |
|
externC cyg_uint32 hal_disable_interrupts(void); |
externC void hal_enable_interrupts(void); |
externC void hal_restore_interrupts(cyg_uint32); |
externC cyg_uint32 hal_query_interrupts(void); |
|
// On this processor, interrupts are controlled by level. Since eCos |
// only has the notion of "off" and "on", this will be emulated by |
// NONE-level and ALL-level. |
#define HAL_DISABLE_INTERRUPTS(_old_) \ |
CYG_MACRO_START \ |
register cyg_uint32 reg; \ |
asm volatile ( \ |
"movsg psr,%0\n" \ |
"\tsetlos (0x0F<<3),gr5\n" \ |
"\tor %0,gr5,gr5\n" \ |
"\tmovgs gr5,psr\n" \ |
: "=r" (reg) \ |
: \ |
: "gr5" /* Clobber list */ \ |
); \ |
(_old_) = (reg); \ |
CYG_MACRO_END |
|
#define HAL_ENABLE_INTERRUPTS() \ |
CYG_MACRO_START \ |
asm volatile ( \ |
"movsg psr,gr4\n" \ |
"\tsetlos (0x0F<<3),gr5\n" \ |
"\tnot gr5,gr5\n" \ |
"\tand gr4,gr5,gr5\n" \ |
"\tmovgs gr5,psr\n" \ |
: \ |
: \ |
: "gr4","gr5" /* Clobber list */ \ |
); \ |
CYG_MACRO_END |
|
// This should work, but breaks compiler |
#if 0 |
#define HAL_RESTORE_INTERRUPTS(_old_) \ |
CYG_MACRO_START \ |
asm volatile ( \ |
"movsg psr,gr4\n" \ |
"\tsetlos 1,gr5\n" \ |
"\tand %0,gr5,gr5\n" \ |
"\tor gr5,gr4,gr4\n" \ |
"\tmovgs gr4,psr\n" \ |
: \ |
: "g" (_old_) \ |
: "gr4","gr5" /* Clobber list */ \ |
); \ |
CYG_MACRO_END |
#else |
#define HAL_RESTORE_INTERRUPTS(_old_) \ |
hal_restore_interrupts(_old_) |
#endif |
|
#define HAL_QUERY_INTERRUPTS(_old_) \ |
_old_ = hal_query_interrupts() |
|
//-------------------------------------------------------------------------- |
// Routine to execute DSRs using separate interrupt stack |
|
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK |
externC void hal_interrupt_stack_call_pending_DSRs(void); |
#define HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() \ |
hal_interrupt_stack_call_pending_DSRs() |
|
#if 0 // Interrupt stacks not implemented yet |
// these are offered solely for stack usage testing |
// if they are not defined, then there is no interrupt stack. |
#define HAL_INTERRUPT_STACK_BASE cyg_interrupt_stack_base |
#define HAL_INTERRUPT_STACK_TOP cyg_interrupt_stack |
// use them to declare these extern however you want: |
// extern char HAL_INTERRUPT_STACK_BASE[]; |
// extern char HAL_INTERRUPT_STACK_TOP[]; |
// is recommended |
#endif // 0 |
#endif |
|
//-------------------------------------------------------------------------- |
// Vector translation. |
|
#ifndef HAL_TRANSLATE_VECTOR |
#define HAL_TRANSLATE_VECTOR(_vector_,_index_) \ |
(_index_) = (_vector_) |
#endif |
|
//-------------------------------------------------------------------------- |
// Interrupt and VSR attachment macros |
|
#define HAL_INTERRUPT_IN_USE( _vector_, _state_) \ |
CYG_MACRO_START \ |
cyg_uint32 _index_; \ |
HAL_TRANSLATE_VECTOR ((_vector_), _index_); \ |
\ |
if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)hal_default_isr ) \ |
(_state_) = 0; \ |
else \ |
(_state_) = 1; \ |
CYG_MACRO_END |
|
#define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ ) \ |
CYG_MACRO_START \ |
if( hal_interrupt_handlers[_vector_] == (CYG_ADDRESS)hal_default_isr ) \ |
{ \ |
hal_interrupt_handlers[_vector_] = (CYG_ADDRESS)_isr_; \ |
hal_interrupt_data[_vector_] = (CYG_ADDRWORD) _data_; \ |
hal_interrupt_objects[_vector_] = (CYG_ADDRESS)_object_; \ |
} \ |
CYG_MACRO_END |
|
#define HAL_INTERRUPT_DETACH( _vector_, _isr_ ) \ |
CYG_MACRO_START \ |
if( hal_interrupt_handlers[_vector_] == (CYG_ADDRESS)_isr_ ) \ |
{ \ |
hal_interrupt_handlers[_vector_] = (CYG_ADDRESS)hal_default_isr; \ |
hal_interrupt_data[_vector_] = 0; \ |
hal_interrupt_objects[_vector_] = 0; \ |
} \ |
CYG_MACRO_END |
|
#define HAL_VSR_GET( _vector_, _pvsr_ ) \ |
*(CYG_ADDRESS *)(_pvsr_) = hal_vsr_table[_vector_]; |
|
|
#define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ ) \ |
CYG_MACRO_START \ |
if( _poldvsr_ != NULL ) \ |
*(CYG_ADDRESS *)_poldvsr_ = hal_vsr_table[_vector_]; \ |
hal_vsr_table[_vector_] = (CYG_ADDRESS)_vsr_; \ |
CYG_MACRO_END |
|
//-------------------------------------------------------------------------- |
// Interrupt controller access |
|
externC void hal_interrupt_mask(int); |
externC void hal_interrupt_unmask(int); |
externC void hal_interrupt_acknowledge(int); |
externC void hal_interrupt_configure(int, int, int); |
externC void hal_interrupt_set_level(int, int); |
|
#define HAL_INTERRUPT_MASK( _vector_ ) \ |
hal_interrupt_mask( _vector_ ) |
#define HAL_INTERRUPT_UNMASK( _vector_ ) \ |
hal_interrupt_unmask( _vector_ ) |
#define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ ) \ |
hal_interrupt_acknowledge( _vector_ ) |
#define HAL_INTERRUPT_CONFIGURE( _vector_, _level_, _up_ ) \ |
hal_interrupt_configure( _vector_, _level_, _up_ ) |
#define HAL_INTERRUPT_SET_LEVEL( _vector_, _level_ ) \ |
hal_interrupt_set_level( _vector_, _level_ ) |
|
//-------------------------------------------------------------------------- |
// Clock control |
|
externC void hal_clock_initialize(cyg_uint32); |
externC void hal_clock_read(cyg_uint32 *); |
externC void hal_clock_reset(cyg_uint32, cyg_uint32); |
|
#define HAL_CLOCK_INITIALIZE( _period_ ) hal_clock_initialize( _period_ ) |
#define HAL_CLOCK_RESET( _vec_, _period_ ) hal_clock_reset( _vec_, _period_ ) |
#define HAL_CLOCK_READ( _pvalue_ ) hal_clock_read( _pvalue_ ) |
#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY |
# ifndef HAL_CLOCK_LATENCY |
# define HAL_CLOCK_LATENCY( _pvalue_ ) HAL_CLOCK_READ( (cyg_uint32 *)_pvalue_ ) |
# endif |
#endif |
|
//-------------------------------------------------------------------------- |
#endif // ifndef CYGONCE_HAL_INTR_H |
// End of hal_intr.h |
/include/hal_arch.h
0,0 → 1,347
#ifndef CYGONCE_HAL_ARCH_H |
#define CYGONCE_HAL_ARCH_H |
|
//========================================================================== |
// |
// hal_arch.h |
// |
// Architecture specific abstractions |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): nickg, gthomas |
// Contributors: nickg, gthomas |
// Date: 2001-09-07 |
// Purpose: Define architecture abstractions |
// Usage: #include <cyg/hal/hal_arch.h> |
|
// |
//####DESCRIPTIONEND#### |
// |
//========================================================================== |
|
#include <pkgconf/hal.h> // To decide on stack usage |
#include <cyg/infra/cyg_type.h> |
|
#if CYGINT_HAL_FRV_ARCH_FR400 != 0 |
#define _NGPR 32 |
#define _NFPR 32 |
#endif |
#if CYGINT_HAL_FRV_ARCH_FR500 != 0 |
#define _NGPR 64 |
#define _NFPR 64 |
#endif |
|
#ifndef _NGPR |
#error No architecture defined? |
#endif |
|
//-------------------------------------------------------------------------- |
// Common "special" register definitions |
|
// Processor status register |
#define _PSR_PIVL_SHIFT 3 |
#define _PSR_PIVL_MASK (0xF<<(_PSR_PIVL_SHIFT)) // Interrupt mask level |
#define _PSR_S (1<<2) // Supervisor state |
#define _PSR_PS (1<<1) // Previous supervisor state |
#define _PSR_ET (1<<0) // Enable interrupts |
|
#define _PSR_INITIAL (_PSR_S|_PSR_PS|_PSR_ET) // Supervisor mode, exceptions |
|
// Hardware status register |
#define _HSR0_ICE (1<<31) // Instruction cache enable |
#define _HSR0_DCE (1<<30) // Data cache enable |
#define _HSR0_IMMU (1<<26) // Instruction MMU enable |
#define _HSR0_DMMU (1<<25) // Data MMU enable |
|
// Debug Control Register |
#define _DCR_EBE (1 << 30) |
#define _DCR_SE (1 << 29) |
#define _DCR_DRBE0 (1 << 19) |
#define _DCR_DWBE0 (1 << 18) |
#define _DCR_DDBE0 (1 << 17) |
#define _DCR_DRBE1 (1 << 16) |
#define _DCR_DWBE1 (1 << 15) |
#define _DCR_DDBE1 (1 << 14) |
#define _DCR_DRBE2 (1 << 13) |
#define _DCR_DWBE2 (1 << 12) |
#define _DCR_DDBE2 (1 << 11) |
#define _DCR_DRBE3 (1 << 10) |
#define _DCR_DWBE3 (1 << 9) |
#define _DCR_DDBE3 (1 << 8) |
#define _DCR_IBE0 (1 << 7) |
#define _DCR_IBCE0 (1 << 6) |
#define _DCR_IBE1 (1 << 5) |
#define _DCR_IBCE1 (1 << 4) |
#define _DCR_IBE2 (1 << 3) |
#define _DCR_IBCE2 (1 << 2) |
#define _DCR_IBE3 (1 << 1) |
#define _DCR_IBCE3 (1 << 0) |
|
// Initial contents for special registers |
|
#define _CCR_INITIAL 0 |
#define _LCR_INITIAL 0 |
#define _CCCR_INITIAL 0 |
|
//-------------------------------------------------------------------------- |
// |
// Saved thread state |
// |
typedef struct |
{ |
cyg_uint32 gpr[_NGPR]; // Saved general purpose registers |
cyg_uint32 pc; // Current [next] instruction location |
cyg_uint32 psr; // Processor status register |
cyg_uint32 lr; // Link register |
cyg_uint32 ccr; // Condition codes |
cyg_uint32 cccr; |
cyg_uint32 lcr; |
cyg_int32 vector; // Reason for last exception |
} HAL_SavedRegisters; |
|
//------------------------------------------------------------------------- |
// Exception handling function. |
// This function is defined by the kernel according to this prototype. It is |
// invoked from the HAL to deal with any CPU exceptions that the HAL does |
// not want to deal with itself. It usually invokes the kernel's exception |
// delivery mechanism. |
|
externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data ); |
|
//------------------------------------------------------------------------- |
// Bit manipulation macros |
|
externC int hal_lsbindex(int); |
externC int hal_msbindex(int); |
|
#define HAL_LSBIT_INDEX(index, mask) index = hal_lsbindex(mask) |
#define HAL_MSBIT_INDEX(index, mask) index = hal_msbindex(mask) |
|
//------------------------------------------------------------------------- |
// Context Initialization |
// Initialize the context of a thread. |
// Arguments: |
// _sparg_ name of variable containing current sp, will be changed to new sp |
// _thread_ thread object address, passed as argument to entry point |
// _entry_ entry point address. |
// _id_ bit pattern used in initializing registers, for debugging. |
|
#define _HAL_THREAD_INIT_CONTEXT( _sparg_, _thread_, _entry_, _id_ ) \ |
CYG_MACRO_START \ |
register CYG_WORD _sp_ = ((CYG_WORD)_sparg_) &~15; \ |
register HAL_SavedRegisters *_regs_; \ |
int _i_; \ |
_regs_ = (HAL_SavedRegisters *)((_sp_) - sizeof(HAL_SavedRegisters)); \ |
for( _i_ = 1; _i_ < _NGPR; _i_++) \ |
(_regs_)->gpr[_i_] = (_id_)|_i_; \ |
(_regs_)->gpr[8] = (CYG_WORD)(_thread_); /* R8 = arg1 = thread ptr */ \ |
(_regs_)->gpr[1] = (CYG_WORD)(_sp_); /* SP = top of stack */ \ |
(_regs_)->lr = (CYG_WORD)(_entry_); /* LR = entry point */ \ |
(_regs_)->pc = (CYG_WORD)(_entry_); /* PC = [initial] entry point */ \ |
(_regs_)->psr = _PSR_INITIAL; /* PSR = Interrupt enabled */ \ |
(_regs_)->ccr = _CCR_INITIAL; \ |
(_regs_)->lcr = _LCR_INITIAL; \ |
(_regs_)->ccr = _CCCR_INITIAL; \ |
_sparg_ = (CYG_ADDRESS)_regs_; \ |
CYG_MACRO_END |
|
//-------------------------------------------------------------------------- |
// Context switch macros. |
// The arguments are pointers to locations where the stack pointer |
// of the current thread is to be stored, and from where the sp of the |
// next thread is to be fetched. |
|
externC void hal_thread_switch_context( CYG_ADDRESS to, CYG_ADDRESS from ); |
externC void hal_thread_load_context( CYG_ADDRESS to ) |
__attribute__ ((noreturn)); |
|
#define HAL_THREAD_SWITCH_CONTEXT(_fspptr_,_tspptr_) \ |
hal_thread_switch_context((CYG_ADDRESS)_tspptr_, \ |
(CYG_ADDRESS)_fspptr_); |
|
#define HAL_THREAD_LOAD_CONTEXT(_tspptr_) \ |
hal_thread_load_context( (CYG_ADDRESS)_tspptr_ ); |
|
//-------------------------------------------------------------------------- |
// Execution reorder barrier. |
// When optimizing the compiler can reorder code. In multithreaded systems |
// where the order of actions is vital, this can sometimes cause problems. |
// This macro may be inserted into places where reordering should not happen. |
|
#define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" ) |
|
//-------------------------------------------------------------------------- |
// Breakpoint support |
// HAL_BREAKPOINT() is a code sequence that will cause a breakpoint to happen |
// if executed. |
// HAL_BREAKINST is the value of the breakpoint instruction and |
// HAL_BREAKINST_SIZE is its size in bytes. |
|
// The choices for breakpoints seem to be: |
// break 0x801000C0 |
// tira gr0,#1 0xC0700001 |
#ifdef CYGSEM_HAL_FRV_USE_BREAK_INSTRUCTION |
#define HAL_BREAKPOINT(_label_) \ |
asm volatile (" .globl " #_label_ "\n" \ |
#_label_":\tbreak\n" \ |
); |
|
#define HAL_BREAKINST 0x801000C0 |
#else |
#define HAL_BREAKPOINT(_label_) \ |
asm volatile (" .globl " #_label_ "\n" \ |
#_label_":\ttira\tgr0,#1\n" \ |
); |
|
#define HAL_BREAKINST 0xC0700001 |
#endif |
#define HAL_BREAKINST_SIZE 4 |
#define HAL_BREAKINST_TYPE cyg_uint32 |
|
//-------------------------------------------------------------------------- |
// Thread register state manipulation for GDB support. |
|
// GDB expects the registers in this structure: |
// gr0..gr31, gr32..gr63 - 4 bytes each |
// fpr0..fpr31, fpr32..fpr63 - 4 bytes each |
// pc, psr, ccr, cccr - 4 bytes each |
// 14 <unused> - 4 bytes each |
// lr, lcr - 4 bytes each |
|
// Translate a stack pointer as saved by the thread context macros above into |
// a pointer to a HAL_SavedRegisters structure. |
#define HAL_THREAD_GET_SAVED_REGISTERS( _sp_, _regs_ ) \ |
(_regs_) = (HAL_SavedRegisters *)(_sp_) |
|
// Copy a set of registers from a HAL_SavedRegisters structure into a |
// GDB ordered array. |
#define HAL_GET_GDB_REGISTERS( _aregval_, _regs_ ) \ |
CYG_MACRO_START \ |
CYG_ADDRWORD *_regval_ = (CYG_ADDRWORD *)(_aregval_); \ |
int _i_; \ |
\ |
for( _i_ = 0; _i_ <= _NGPR; _i_++ ) \ |
_regval_[_i_] = (_regs_)->gpr[_i_]; \ |
_regval_[128] = (_regs_)->pc; \ |
_regval_[129] = (_regs_)->psr; \ |
_regval_[130] = (_regs_)->ccr; \ |
_regval_[135] = (_regs_)->vector; \ |
_regval_[145] = (_regs_)->lr; \ |
_regval_[146] = (_regs_)->lcr; \ |
CYG_MACRO_END |
|
// Copy a GDB ordered array into a HAL_SavedRegisters structure. |
#define HAL_SET_GDB_REGISTERS( _regs_ , _aregval_ ) \ |
CYG_MACRO_START \ |
CYG_ADDRWORD *_regval_ = (CYG_ADDRWORD *)(_aregval_); \ |
int _i_; \ |
\ |
for( _i_ = 0; _i_ <= _NGPR; _i_++ ) \ |
(_regs_)->gpr[_i_] = _regval_[_i_]; \ |
\ |
(_regs_)->pc = _regval_[128]; \ |
(_regs_)->psr = _regval_[129]; \ |
(_regs_)->ccr = _regval_[130]; \ |
(_regs_)->lr = _regval_[145]; \ |
(_regs_)->lcr = _regval_[146]; \ |
CYG_MACRO_END |
|
//-------------------------------------------------------------------------- |
// HAL setjmp |
|
#define CYGARC_JMP_BUF_SIZE 0x110 |
|
typedef cyg_uint32 hal_jmp_buf[CYGARC_JMP_BUF_SIZE]; |
|
externC int hal_setjmp(hal_jmp_buf env); |
externC void hal_longjmp(hal_jmp_buf env, int val); |
|
//-------------------------------------------------------------------------- |
// Idle thread code. |
// This macro is called in the idle thread loop, and gives the HAL the |
// chance to insert code. Typical idle thread behaviour might be to halt the |
// processor. |
|
externC void hal_idle_thread_action(cyg_uint32 loop_count); |
|
#define HAL_IDLE_THREAD_ACTION(_count_) hal_idle_thread_action(_count_) |
|
//--------------------------------------------------------------------------- |
|
// Minimal and sensible stack sizes: the intention is that applications |
// will use these to provide a stack size in the first instance prior to |
// proper analysis. Idle thread stack should be this big. |
|
// THESE ARE NOT INTENDED TO BE MICROMETRICALLY ACCURATE FIGURES. |
// THEY ARE HOWEVER ENOUGH TO START PROGRAMMING. |
// YOU MUST MAKE YOUR STACKS LARGER IF YOU HAVE LARGE "AUTO" VARIABLES! |
|
// This is not a config option because it should not be adjusted except |
// under "enough rope" sort of disclaimers. |
|
// A minimal, optimized stack frame, rounded up - no autos |
#define CYGNUM_HAL_STACK_FRAME_SIZE (4 * 150) |
|
// Stack needed for a context switch: this is implicit in the estimate for |
// interrupts so not explicitly used below: |
#define CYGNUM_HAL_STACK_CONTEXT_SIZE (4 * 150) |
|
// Interrupt + call to ISR, interrupt_end() and the DSR |
#define CYGNUM_HAL_STACK_INTERRUPT_SIZE \ |
((4 * 150) + 2 * CYGNUM_HAL_STACK_FRAME_SIZE) |
|
// Space for the maximum number of nested interrupts, plus room to call functions |
#define CYGNUM_HAL_MAX_INTERRUPT_NESTING 4 |
|
#define CYGNUM_HAL_STACK_SIZE_MINIMUM \ |
(CYGNUM_HAL_MAX_INTERRUPT_NESTING * CYGNUM_HAL_STACK_INTERRUPT_SIZE + \ |
2 * CYGNUM_HAL_STACK_FRAME_SIZE) |
|
#define CYGNUM_HAL_STACK_SIZE_TYPICAL \ |
(CYGNUM_HAL_STACK_SIZE_MINIMUM + \ |
16 * CYGNUM_HAL_STACK_FRAME_SIZE) |
|
|
//-------------------------------------------------------------------------- |
// Macros for switching context between two eCos instances (jump from |
// code in ROM to code in RAM or vice versa). |
#define CYGARC_HAL_SAVE_GP() |
#define CYGARC_HAL_RESTORE_GP() |
|
#endif // CYGONCE_HAL_ARCH_H |
// End of hal_arch.h |
/include/hal_cache.h
0,0 → 1,298
#ifndef CYGONCE_HAL_CACHE_H |
#define CYGONCE_HAL_CACHE_H |
|
//============================================================================= |
// |
// hal_cache.h |
// |
// HAL cache control API |
// |
//============================================================================= |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//============================================================================= |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): gthomas |
// Contributors:hmt |
// Date: 2000-05-08 |
// Purpose: Cache control API |
// Description: The macros defined here provide the HAL APIs for handling |
// cache control operations. |
// Usage: |
// #include <cyg/hal/hal_cache.h> |
// ... |
// |
// |
//####DESCRIPTIONEND#### |
// |
//============================================================================= |
|
#include <cyg/infra/cyg_type.h> |
#include CYGBLD_HAL_PLF_DEFS_H |
#include <cyg/hal/plf_cache.h> // Platform (model) details |
|
//----------------------------------------------------------------------------- |
// Global control of Instruction cache |
|
// Enable the instruction cache |
#define HAL_ICACHE_ENABLE() \ |
CYG_MACRO_START \ |
cyg_uint32 mask = _HSR0_ICE; \ |
asm volatile ( \ |
"movsg hsr0,gr4\n" \ |
"\tor gr4,%0,gr4\n" \ |
"\tmovgs gr4,hsr0\n" \ |
: \ |
: "r"(mask) \ |
: "gr4" /* Clobber list */ \ |
); \ |
CYG_MACRO_END |
|
// Disable the instruction cache (and invalidate it, required semanitcs) |
#define HAL_ICACHE_DISABLE() \ |
CYG_MACRO_START \ |
cyg_uint32 mask = ~_HSR0_ICE; \ |
asm volatile ( \ |
"movsg hsr0,gr4\n" \ |
"\tand gr4,%0,gr4\n" \ |
"\tmovgs gr4,hsr0\n" \ |
: \ |
: "r"(mask) \ |
: "gr4" /* Clobber list */ \ |
); \ |
CYG_MACRO_END |
|
// Query the state of the instruction cache |
#define HAL_ICACHE_IS_ENABLED(_state_) \ |
CYG_MACRO_START \ |
register cyg_uint32 reg; \ |
asm volatile ("movsg hsr0,%0" \ |
: "=r"(reg) \ |
: \ |
); \ |
(_state_) = (0 != (_HSR0_ICE & reg)); \ |
CYG_MACRO_END |
|
// Invalidate the entire cache |
#define HAL_ICACHE_INVALIDATE_ALL() \ |
CYG_MACRO_START \ |
asm volatile ("icei @(gr4,gr0),1" \ |
: \ |
: \ |
); \ |
CYG_MACRO_END |
|
// Synchronize the contents of the cache with memory. |
// (which includes flushing out pending writes) |
#define HAL_ICACHE_SYNC() \ |
CYG_MACRO_START \ |
HAL_DCACHE_SYNC(); /* ensure data gets to RAM */ \ |
HAL_ICACHE_INVALIDATE_ALL(); /* forget all we know */ \ |
CYG_MACRO_END |
|
// Set the instruction cache refill burst size |
//#define HAL_ICACHE_BURST_SIZE(_size_) |
|
// Load the contents of the given address range into the instruction cache |
// and then lock the cache so that it stays there. |
//#define HAL_ICACHE_LOCK(_base_, _size_) |
|
// Undo a previous lock operation |
//#define HAL_ICACHE_UNLOCK(_base_, _size_) |
|
// Unlock entire cache |
//#define HAL_ICACHE_UNLOCK_ALL() |
|
//----------------------------------------------------------------------------- |
// Instruction cache line control |
|
// Invalidate cache lines in the given range without writing to memory. |
#define HAL_ICACHE_INVALIDATE( _base_ , _size_ ) \ |
CYG_MACRO_START \ |
cyg_uint32 _b = _base_; \ |
cyg_uint32 _s = _size_; \ |
while (_s > HAL_DCACHE_LINE_SIZE) { \ |
asm volatile ("ici @(%0,gr0)" \ |
: \ |
: "r"(_b) \ |
); \ |
_s -= HAL_DCACHE_LINE_SIZE; \ |
_b += HAL_DCACHE_LINE_SIZE; \ |
} \ |
CYG_MACRO_END |
|
//----------------------------------------------------------------------------- |
// Global control of data cache |
|
// Enable the data cache |
#define HAL_DCACHE_ENABLE() \ |
CYG_MACRO_START \ |
cyg_uint32 mask = _HSR0_DCE; \ |
asm volatile ( \ |
"movsg hsr0,gr4\n" \ |
"\tor gr4,%0,gr4\n" \ |
"\tmovgs gr4,hsr0\n" \ |
: \ |
: "r"(mask) \ |
: "gr4" /* Clobber list */ \ |
); \ |
CYG_MACRO_END |
|
// Disable the data cache (and invalidate it, required semanitcs) |
#define HAL_DCACHE_DISABLE() \ |
CYG_MACRO_START \ |
cyg_uint32 mask = ~_HSR0_DCE; \ |
asm volatile ( \ |
"movsg hsr0,gr4\n" \ |
"\tand gr4,%0,gr4\n" \ |
"\tmovgs gr4,hsr0\n" \ |
: \ |
: "r"(mask) \ |
: "gr4" /* Clobber list */ \ |
); \ |
CYG_MACRO_END |
|
// Query the state of the data cache |
#define HAL_DCACHE_IS_ENABLED(_state_) \ |
CYG_MACRO_START \ |
register cyg_uint32 reg; \ |
asm volatile ("movsg hsr0,%0" \ |
: "=r"(reg) \ |
: \ |
); \ |
(_state_) = (0 != (_HSR0_DCE & reg)); \ |
CYG_MACRO_END |
|
// Flush (invalidate) the entire dcache |
#define HAL_DCACHE_INVALIDATE_ALL() \ |
CYG_MACRO_START \ |
asm volatile ("dcei @(gr4,gr0),1" \ |
: \ |
: \ |
); \ |
CYG_MACRO_END |
|
// Synchronize the contents of the cache with memory. |
#define HAL_DCACHE_SYNC() \ |
CYG_MACRO_START \ |
asm volatile ("dcef @(gr4,gr0),1" \ |
: \ |
: \ |
); \ |
CYG_MACRO_END |
|
// Set the data cache refill burst size |
//#define HAL_DCACHE_BURST_SIZE(_size_) |
|
// Set the data cache write mode |
//#define HAL_DCACHE_WRITE_MODE( _mode_ ) |
|
#define HAL_DCACHE_WRITETHRU_MODE 0 |
#define HAL_DCACHE_WRITEBACK_MODE 1 |
|
// Get the current writeback mode - or only writeback mode if fixed |
#define HAL_DCACHE_QUERY_WRITE_MODE( _mode_ ) CYG_MACRO_START \ |
_mode_ = HAL_DCACHE_WRITETHRU_MODE; \ |
CYG_MACRO_END |
|
// Load the contents of the given address range into the data cache |
// and then lock the cache so that it stays there. |
//#define HAL_DCACHE_LOCK(_base_, _size_) |
|
// Undo a previous lock operation |
//#define HAL_DCACHE_UNLOCK(_base_, _size_) |
|
// Unlock entire cache |
//#define HAL_DCACHE_UNLOCK_ALL() |
|
//----------------------------------------------------------------------------- |
// Data cache line control |
|
// Allocate cache lines for the given address range without reading its |
// contents from memory. |
//#define HAL_DCACHE_ALLOCATE( _base_ , _size_ ) |
|
// Write dirty cache lines to memory and invalidate the cache entries |
// for the given address range. |
#define HAL_DCACHE_FLUSH( _base_ , _size_ ) \ |
CYG_MACRO_START \ |
HAL_DCACHE_STORE( _base_ , _size_ ); \ |
HAL_DCACHE_INVALIDATE( _base_ , _size_ ); \ |
CYG_MACRO_END |
|
// Invalidate cache lines in the given range without writing to memory. |
#define HAL_DCACHE_INVALIDATE( _base_ , _size_ ) \ |
CYG_MACRO_START \ |
cyg_uint32 _b = _base_; \ |
cyg_uint32 _s = _size_; \ |
while (_s > HAL_DCACHE_LINE_SIZE) { \ |
asm volatile ("dci @(%0,gr0)" \ |
: \ |
: "r"(_b) \ |
); \ |
_s -= HAL_DCACHE_LINE_SIZE; \ |
_b += HAL_DCACHE_LINE_SIZE; \ |
} \ |
CYG_MACRO_END |
|
// Write dirty cache lines to memory for the given address range. |
#define HAL_DCACHE_STORE( _base_ , _size_ ) \ |
CYG_MACRO_START \ |
cyg_uint32 _b = _base_; \ |
cyg_uint32 _s = _size_; \ |
while (_s > HAL_DCACHE_LINE_SIZE) { \ |
asm volatile ("dcf @(%0,gr0)" \ |
: \ |
: "r"(_b) \ |
); \ |
_s -= HAL_DCACHE_LINE_SIZE; \ |
_b += HAL_DCACHE_LINE_SIZE; \ |
} \ |
CYG_MACRO_END |
|
// Preread the given range into the cache with the intention of reading |
// from it later. |
//#define HAL_DCACHE_READ_HINT( _base_ , _size_ ) |
|
// Preread the given range into the cache with the intention of writing |
// to it later. |
//#define HAL_DCACHE_WRITE_HINT( _base_ , _size_ ) |
|
// Allocate and zero the cache lines associated with the given range. |
//#define HAL_DCACHE_ZERO( _base_ , _size_ ) |
|
//----------------------------------------------------------------------------- |
|
#endif // ifndef CYGONCE_HAL_CACHE_H |
// End of hal_cache.h |
/src/hal_syscall.c
0,0 → 1,107
//============================================================================= |
// |
// hal_syscall.c |
// |
// |
// |
//============================================================================= |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//============================================================================= |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): msalter |
// Contributors:msalter, gthomas |
// Date: 2000-11-5 |
// Purpose: |
// Description: |
// |
// |
// |
//####DESCRIPTIONEND#### |
// |
//============================================================================= |
|
#include <pkgconf/hal.h> |
|
#ifdef CYGPKG_REDBOOT |
#include <pkgconf/redboot.h> |
#endif |
|
#if defined(CYGSEM_REDBOOT_BSP_SYSCALLS) |
|
#include <cyg/hal/hal_stub.h> // Our header |
#include <cyg/hal/hal_arch.h> // HAL_BREAKINST |
#include <cyg/hal/hal_cache.h> // HAL_xCACHE_x |
#include <cyg/hal/hal_intr.h> // interrupt disable/restore |
|
#include <cyg/hal/hal_if.h> // ROM calling interface |
#include <cyg/hal/hal_misc.h> // Helper functions |
|
extern int __do_syscall(int func, // syscall function number |
long arg1, long arg2, // up to four args. |
long arg3, long arg4, |
int *retval, // syscall return value |
int *sig); // signal to return (or 0) |
|
#define SYS_exit 1 |
#define SYS_interrupt 1000 |
|
int |
hal_syscall_handler(void) |
{ |
int func, arg1, arg2, arg3, arg4; |
int err, res, sig; |
|
func = get_register(R7); |
arg1 = get_register(R8); |
arg2 = get_register(R9); |
arg3 = get_register(R10); |
arg4 = get_register(R11); |
|
if (func == SYS_interrupt) { |
// A console interrupt landed us here. |
// Invoke the debug agent so as to cause a SIGINT. |
return SIGINT; |
} |
|
if ((res = __do_syscall(func, arg1, arg2, arg3, arg4, &err, &sig)) != 0) { |
// Skip over trap instruction |
put_register(PC, get_register(PC)+4); |
put_register(R8, err); |
return sig; |
} |
|
return SIGTRAP; |
} |
#endif // CYGSEM_REDBOOT_BSP_SYSCALLS |
/src/hal_misc.c
0,0 → 1,275
/*========================================================================== |
// |
// hal_misc.c |
// |
// HAL miscellaneous functions |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//========================================================================== |
//#####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_frv.h> |
#ifdef CYGPKG_KERNEL |
#include <pkgconf/kernel.h> |
#endif |
#ifdef CYGPKG_CYGMON |
#include <pkgconf/cygmon.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/infra/diag.h> |
|
#include <cyg/hal/hal_arch.h> // HAL header |
#include <cyg/hal/hal_intr.h> // HAL header |
#include <cyg/hal/hal_cache.h> // HAL header |
|
/*------------------------------------------------------------------------*/ |
/* First level C exception handler. */ |
|
externC void __handle_exception (void); |
|
externC HAL_SavedRegisters *_hal_registers; |
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS |
// Historical - this datum is defined by the GDB stubs if present |
externC |
#endif |
void* volatile __mem_fault_handler; |
|
#if 0 |
#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. |
Note: the interrupt vectors are _not_ preempted as the stubs probably can't |
handle them properly. |
*/ |
|
#define ARM_VECTORS 8 |
extern unsigned long vectors[]; // exception vectors as defined by the stubs |
|
#if !defined(CYGPKG_CYGMON) |
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) |
{ |
hold_vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH] = hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH]; |
hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH] = vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH]; |
hold_vectors[CYGNUM_HAL_VECTOR_ABORT_DATA] = hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_DATA]; |
hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_DATA] = vectors[CYGNUM_HAL_VECTOR_ABORT_DATA]; |
} |
|
static void |
__restore_debug_traps(void) |
{ |
hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH] = hold_vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH]; |
hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_DATA] = hold_vectors[CYGNUM_HAL_VECTOR_ABORT_DATA]; |
} |
#endif // !CYGPKG_CYGMON |
#endif |
|
#endif // if 0 |
|
void |
exception_handler(HAL_SavedRegisters *regs) |
{ |
// Special case handler for code which has chosen to take care |
// of data exceptions (i.e. code which expects them to happen) |
// This is common in discovery code, e.g. checking for a particular |
// device which may generate an exception when probing if the |
// device is not present |
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 defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) && !defined(CYGPKG_CYGMON) |
//?? if (++exception_level == 1) __take_over_debug_traps(); |
|
_hal_registers = regs; |
__handle_exception(); |
|
//?? if (--exception_level == 0) __restore_debug_traps(); |
|
#elif defined(CYGPKG_KERNEL_EXCEPTIONS) |
|
// 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. |
|
cyg_hal_deliver_exception( regs->vector, (CYG_ADDRWORD)regs ); |
|
#else |
|
CYG_FAIL("Exception!!!"); |
|
#endif |
|
return; |
} |
|
void hal_spurious_IRQ(HAL_SavedRegisters *regs) CYGBLD_ATTRIB_WEAK; |
void |
hal_spurious_IRQ(HAL_SavedRegisters *regs) |
{ |
#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) |
exception_handler(regs); |
#else |
CYG_FAIL("Spurious interrupt!!"); |
#endif |
} |
|
/*------------------------------------------------------------------------*/ |
/* 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 |
} |
|
/*------------------------------------------------------------------------*/ |
/* Architecture default ISR */ |
|
externC cyg_uint32 |
hal_arch_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) |
{ |
CYG_TRACE1(true, "Interrupt: %d", vector); |
|
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 = 31; i >= 0; i--) { |
if (mask & (1<<i)) return (i); |
} |
return (-1); |
} |
|
/*------------------------------------------------------------------------*/ |
// EOF hal_misc.c |
/src/context.S
0,0 → 1,369
// #=========================================================================== |
// # |
// # context.S |
// # |
// # FUJITSU context switch code |
// # |
// #=========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
// #=========================================================================== |
// ######DESCRIPTIONBEGIN#### |
// # |
// # Author(s): nickg, gthomas |
// # Contributors: nickg, gthomas |
// # Date: 1998-09-15 |
// # Purpose: FUJITSU context switch code |
// # Description: This file contains implementations of the thread context |
// # switch routines. It also contains the longjmp() and setjmp() |
// # routines. |
// # |
// #####DESCRIPTIONEND#### |
// # |
// #=========================================================================== |
|
#include <pkgconf/hal.h> |
|
#include "frv.inc" |
|
.text |
|
// ---------------------------------------------------------------------------- |
// hal_thread_switch_context(new, old) |
// Switch thread contexts |
// new = address of context of next thread to execute |
// old = address of context save location of current thread |
// thread state is saved on the current stack |
|
.globl hal_thread_switch_context |
hal_thread_switch_context: |
subi sp,_TS_size,sp // Space for saved frame |
sti gr2,@(sp,_TS_GPR2) // Save registers |
sti gr3,@(sp,_TS_GPR3) |
sti gr4,@(sp,_TS_GPR4) |
sti gr5,@(sp,_TS_GPR5) |
sti gr6,@(sp,_TS_GPR6) |
sti gr7,@(sp,_TS_GPR7) |
sti gr8,@(sp,_TS_GPR8) |
sti gr9,@(sp,_TS_GPR9) |
sti gr10,@(sp,_TS_GPR10) |
sti gr11,@(sp,_TS_GPR11) |
sti gr12,@(sp,_TS_GPR12) |
sti gr13,@(sp,_TS_GPR13) |
sti gr14,@(sp,_TS_GPR14) |
sti gr15,@(sp,_TS_GPR15) |
sti gr16,@(sp,_TS_GPR16) |
sti gr17,@(sp,_TS_GPR17) |
sti gr18,@(sp,_TS_GPR18) |
sti gr19,@(sp,_TS_GPR19) |
sti gr20,@(sp,_TS_GPR20) |
sti gr21,@(sp,_TS_GPR21) |
sti gr22,@(sp,_TS_GPR22) |
sti gr23,@(sp,_TS_GPR23) |
sti gr24,@(sp,_TS_GPR24) |
sti gr25,@(sp,_TS_GPR25) |
sti gr26,@(sp,_TS_GPR26) |
sti gr27,@(sp,_TS_GPR27) |
sti gr28,@(sp,_TS_GPR28) |
sti gr29,@(sp,_TS_GPR29) |
sti gr30,@(sp,_TS_GPR30) |
sti gr31,@(sp,_TS_GPR31) |
#if _NGPR != 32 |
sti gr32,@(sp,_TS_GPR32) |
sti gr33,@(sp,_TS_GPR33) |
sti gr34,@(sp,_TS_GPR34) |
sti gr35,@(sp,_TS_GPR35) |
sti gr36,@(sp,_TS_GPR36) |
sti gr37,@(sp,_TS_GPR37) |
sti gr38,@(sp,_TS_GPR38) |
sti gr39,@(sp,_TS_GPR39) |
sti gr40,@(sp,_TS_GPR40) |
sti gr41,@(sp,_TS_GPR41) |
sti gr42,@(sp,_TS_GPR42) |
sti gr43,@(sp,_TS_GPR43) |
sti gr44,@(sp,_TS_GPR44) |
sti gr45,@(sp,_TS_GPR45) |
sti gr46,@(sp,_TS_GPR46) |
sti gr47,@(sp,_TS_GPR47) |
sti gr48,@(sp,_TS_GPR48) |
sti gr49,@(sp,_TS_GPR49) |
sti gr50,@(sp,_TS_GPR50) |
sti gr51,@(sp,_TS_GPR51) |
sti gr52,@(sp,_TS_GPR52) |
sti gr53,@(sp,_TS_GPR53) |
sti gr54,@(sp,_TS_GPR54) |
sti gr55,@(sp,_TS_GPR55) |
sti gr56,@(sp,_TS_GPR56) |
sti gr57,@(sp,_TS_GPR57) |
sti gr58,@(sp,_TS_GPR58) |
sti gr59,@(sp,_TS_GPR59) |
sti gr60,@(sp,_TS_GPR60) |
sti gr61,@(sp,_TS_GPR61) |
sti gr62,@(sp,_TS_GPR62) |
sti gr63,@(sp,_TS_GPR63) |
#endif |
movsg psr,gr4 |
sti gr4,@(sp,_TS_PSR) |
movsg lr,gr4 |
sti gr4,@(sp,_TS_PC) |
movsg ccr,gr4 |
sti gr4,@(sp,_TS_CCR) |
movsg lcr,gr4 |
sti gr4,@(sp,_TS_LCR) |
movsg cccr,gr4 |
sti gr4,@(sp,_TS_CCCR) |
addi sp,_TS_size,gr4 |
sti gr4,@(sp,_TS_SP) |
sti sp,@(gr9,0) // Pointer to saved context |
|
# Now load the destination thread by dropping through |
# to hal_thread_load_context |
|
// ---------------------------------------------------------------------------- |
// hal_thread_load_context(new) |
// Load thread context |
// new = address of context of next thread to execute |
// Note that this function is also the second half of |
// hal_thread_switch_context and is simply dropped into from it. |
|
.globl hal_thread_load_context |
hal_thread_load_context: |
ldi @(gr8,0),sp // Saved context |
ldi @(sp,_TS_PSR),gr8 |
setlos #~_PSR_ET,gr9 // Turn off exceptions |
and gr8,gr9,gr8 |
setlos #_PSR_PS|_PSR_S,gr9 // Stay in supervisor mode |
or gr8,gr9,gr8 |
movgs gr8,psr |
ldi @(sp,_TS_PC),gr8 |
movgs gr8,pcsr |
ldi @(sp,_TS_CCR),gr8 |
movgs gr8,ccr |
ldi @(sp,_TS_LCR),gr8 |
movgs gr8,lcr |
ldi @(sp,_TS_CCCR),gr8 |
movgs gr8,cccr |
ldi @(sp,_TS_GPR2),gr2 // Restore registers |
ldi @(sp,_TS_GPR3),gr3 |
ldi @(sp,_TS_GPR4),gr4 |
ldi @(sp,_TS_GPR5),gr5 |
ldi @(sp,_TS_GPR6),gr6 |
ldi @(sp,_TS_GPR7),gr7 |
ldi @(sp,_TS_GPR8),gr8 |
ldi @(sp,_TS_GPR9),gr9 |
ldi @(sp,_TS_GPR10),gr10 |
ldi @(sp,_TS_GPR11),gr11 |
ldi @(sp,_TS_GPR12),gr12 |
ldi @(sp,_TS_GPR13),gr13 |
ldi @(sp,_TS_GPR14),gr14 |
ldi @(sp,_TS_GPR15),gr15 |
ldi @(sp,_TS_GPR16),gr16 |
ldi @(sp,_TS_GPR17),gr17 |
ldi @(sp,_TS_GPR18),gr18 |
ldi @(sp,_TS_GPR19),gr19 |
ldi @(sp,_TS_GPR20),gr20 |
ldi @(sp,_TS_GPR21),gr21 |
ldi @(sp,_TS_GPR22),gr22 |
ldi @(sp,_TS_GPR23),gr23 |
ldi @(sp,_TS_GPR24),gr24 |
ldi @(sp,_TS_GPR25),gr25 |
ldi @(sp,_TS_GPR26),gr26 |
ldi @(sp,_TS_GPR27),gr27 |
ldi @(sp,_TS_GPR28),gr28 |
ldi @(sp,_TS_GPR29),gr29 |
ldi @(sp,_TS_GPR30),gr30 |
ldi @(sp,_TS_GPR31),gr31 |
#if _NGPR != 32 |
ldi @(sp,_TS_GPR32),gr32 |
ldi @(sp,_TS_GPR33),gr33 |
ldi @(sp,_TS_GPR34),gr34 |
ldi @(sp,_TS_GPR35),gr35 |
ldi @(sp,_TS_GPR36),gr36 |
ldi @(sp,_TS_GPR37),gr37 |
ldi @(sp,_TS_GPR38),gr38 |
ldi @(sp,_TS_GPR39),gr39 |
ldi @(sp,_TS_GPR40),gr40 |
ldi @(sp,_TS_GPR41),gr41 |
ldi @(sp,_TS_GPR42),gr42 |
ldi @(sp,_TS_GPR43),gr43 |
ldi @(sp,_TS_GPR44),gr44 |
ldi @(sp,_TS_GPR45),gr45 |
ldi @(sp,_TS_GPR46),gr46 |
ldi @(sp,_TS_GPR47),gr47 |
ldi @(sp,_TS_GPR48),gr48 |
ldi @(sp,_TS_GPR49),gr49 |
ldi @(sp,_TS_GPR50),gr50 |
ldi @(sp,_TS_GPR51),gr51 |
ldi @(sp,_TS_GPR52),gr52 |
ldi @(sp,_TS_GPR53),gr53 |
ldi @(sp,_TS_GPR54),gr54 |
ldi @(sp,_TS_GPR55),gr55 |
ldi @(sp,_TS_GPR56),gr56 |
ldi @(sp,_TS_GPR57),gr57 |
ldi @(sp,_TS_GPR58),gr58 |
ldi @(sp,_TS_GPR59),gr59 |
ldi @(sp,_TS_GPR60),gr60 |
ldi @(sp,_TS_GPR61),gr61 |
ldi @(sp,_TS_GPR62),gr62 |
ldi @(sp,_TS_GPR63),gr63 |
#endif |
ldi @(sp,_TS_SP),sp |
rett #0 |
|
// ---------------------------------------------------------------------------- |
// HAL longjmp, setjmp implementations - based on newlib |
// Register jmpbuf offset |
// R16-R31 0x0-0x03c |
// R48-R63 0x40-0x7c |
// FR16-FR31 0x80-0xbc |
// FR48-FR63 0xc0-0xfc |
// LR 0x100 |
// SP 0x104 |
// FP 0x108 |
// |
// R8 contains the pointer to jmpbuf |
|
.text |
.global hal_setjmp |
.type hal_setjmp,@function |
hal_setjmp: |
stdi gr16, @(gr8,0) |
stdi gr18, @(gr8,8) |
stdi gr20, @(gr8,16) |
stdi gr22, @(gr8,24) |
stdi gr24, @(gr8,32) |
stdi gr26, @(gr8,40) |
stdi gr28, @(gr8,48) |
stdi gr30, @(gr8,56) |
#if _NGPR != 32 |
stdi gr48, @(gr8,64) |
stdi gr50, @(gr8,72) |
stdi gr52, @(gr8,80) |
stdi gr54, @(gr8,88) |
stdi gr56, @(gr8,96) |
stdi gr58, @(gr8,104) |
stdi gr60, @(gr8,112) |
stdi gr62, @(gr8,120) |
#endif |
|
#if _NFPR != 0 |
stdfi fr16, @(gr8,128) |
stdfi fr18, @(gr8,136) |
stdfi fr20, @(gr8,144) |
stdfi fr22, @(gr8,152) |
stdfi fr24, @(gr8,160) |
stdfi fr26, @(gr8,168) |
stdfi fr28, @(gr8,176) |
stdfi fr30, @(gr8,184) |
#if _NFPR != 32 |
stdfi fr48, @(gr8,192) |
stdfi fr50, @(gr8,200) |
stdfi fr52, @(gr8,208) |
stdfi fr54, @(gr8,216) |
stdfi fr56, @(gr8,224) |
stdfi fr58, @(gr8,232) |
stdfi fr60, @(gr8,240) |
stdfi fr62, @(gr8,248) |
#endif |
#endif |
|
movsg lr, gr4 |
sti gr4, @(gr8,256) |
sti sp, @(gr8,260) |
sti fp, @(gr8,264) |
|
mov gr0,gr8 |
ret |
.Lend1: |
.size hal_setjmp,.Lend1-hal_setjmp |
|
.global hal_longjmp |
.type hal_longjmp,@function |
hallongjmp: |
lddi @(gr8,0), gr16 |
lddi @(gr8,8), gr18 |
lddi @(gr8,16), gr20 |
lddi @(gr8,24), gr22 |
lddi @(gr8,32), gr24 |
lddi @(gr8,40), gr26 |
lddi @(gr8,48), gr28 |
lddi @(gr8,56), gr30 |
#if _NGPR != 32 |
lddi @(gr8,64), gr48 |
lddi @(gr8,72), gr50 |
lddi @(gr8,80), gr52 |
lddi @(gr8,88), gr54 |
lddi @(gr8,96), gr56 |
lddi @(gr8,104), gr58 |
lddi @(gr8,112), gr60 |
lddi @(gr8,120), gr62 |
#endif |
|
#if _NFPR != 0 |
lddfi @(gr8,128), fr16 |
lddfi @(gr8,136), fr18 |
lddfi @(gr8,144), fr20 |
lddfi @(gr8,152), fr22 |
lddfi @(gr8,160), fr24 |
lddfi @(gr8,168), fr26 |
lddfi @(gr8,176), fr28 |
lddfi @(gr8,184), fr30 |
#if _NFPR != 32 |
lddfi @(gr8,192), fr48 |
lddfi @(gr8,200), fr50 |
lddfi @(gr8,208), fr52 |
lddfi @(gr8,216), fr54 |
lddfi @(gr8,224), fr56 |
lddfi @(gr8,232), fr58 |
lddfi @(gr8,240), fr60 |
lddfi @(gr8,248), fr62 |
#endif |
#endif |
|
ldi @(gr8,256), gr4 |
movgs gr4,lr |
|
ldi @(gr8,260), sp |
ldi @(gr8,264), fp |
|
# Value to return is in r9. If zero, return 1 |
cmp gr9, gr0, icc0 |
setlos #1, gr8 |
ckne icc0, cc4 |
cmov gr9, gr8, cc4, 1 |
ret |
.Lend2: |
.size hal_longjmp,.Lend2-hal_longjmp2 |
|
// ---------------------------------------------------------------------------- |
// end of context.S |
/src/vectors.S
0,0 → 1,853
// #======================================================================== |
// # |
// # vectors.S |
// # |
// # Fujitsu exception vectors |
// # |
// #======================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
// #======================================================================== |
// ######DESCRIPTIONBEGIN#### |
// # |
// # Author(s): gthomas |
// # Contributors: gthomas |
// # Date: 2001-09-16 |
// # Purpose: Fujitsu exception vectors |
// # Description: This file defines the code placed into the exception |
// # vectors. It also contains the first level default VSRs |
// # that save and restore state for both exceptions and |
// # interrupts. |
// # |
// #####DESCRIPTIONEND#### |
// # |
// #======================================================================== |
|
#include <pkgconf/hal.h> |
#include CYGBLD_HAL_PLF_DEFS_H |
#include "frv.inc" |
#include <cyg/hal/platform.inc> |
|
.macro lda a r |
sethi #gprelhi(\a),\r |
setlo #gprello(\a),\r |
add \r,gr16,\r |
.endm |
|
.macro li v r |
sethi #((\v)>>16),\r |
setlo #((\v)&0xFFFF),\r |
.endm |
|
.macro save_GDB_exception_regs base,orig |
// 'orig' points to an area where some registers were already saved |
// orig+0: GPR4 |
// orig+4: GPR5 |
// orig+8: GPR6 |
// orig+12: GPR16 |
// orig+16: LR |
// orig+20: CCR |
sti gr4,@(\base,_TS_VECTOR) |
addi \orig,24,gr5 |
sti gr5,@(\base,_TS_SP) |
ldi @(\orig,0),gr5 |
sti gr5,@(\base,_TS_GPR4) |
ldi @(\orig,4),gr5 |
sti gr5,@(\base,_TS_GPR5) |
ldi @(\orig,8),gr5 |
sti gr5,@(\base,_TS_GPR6) |
ldi @(\orig,12),gr5 |
sti gr5,@(\base,_TS_GPR16) |
ldi @(\orig,16),gr5 |
sti gr5,@(\base,_TS_LR) |
ldi @(\orig,20),gr5 |
sti gr5,@(\base,_TS_CCR) |
.endm |
|
.macro save_exception_regs base |
sti gr4,@(\base,_TS_VECTOR) |
sti gr5,@(\base,_TS_GPR5) |
addi sp,_TS_size,gr5 |
sti gr5,@(\base,_TS_SP) |
sti gr6,@(\base,_TS_GPR6) |
sti gr16,@(\base,_TS_GPR16) |
movsg lr,gr5 |
sti gr5,@(\base,_TS_LR) |
movsg ccr,gr5 |
sti gr5,@(\base,_TS_CCR) |
.endm |
|
// Save the machine state after an interrupt/exception |
// Note: it might be possible to use stdi/lddi instructions here, |
// but it would require that the stack pointer always be 64 bit |
// (doubleword) aligned. |
.macro save_state base |
sti gr0,@(\base,_TS_GPR0) |
sti gr2,@(\base,_TS_GPR2) |
sti gr3,@(\base,_TS_GPR3) |
sti gr7,@(\base,_TS_GPR7) |
sti gr8,@(\base,_TS_GPR8) |
sti gr9,@(\base,_TS_GPR9) |
sti gr10,@(\base,_TS_GPR10) |
sti gr11,@(\base,_TS_GPR11) |
sti gr12,@(\base,_TS_GPR12) |
sti gr13,@(\base,_TS_GPR13) |
sti gr14,@(\base,_TS_GPR14) |
sti gr15,@(\base,_TS_GPR15) |
sti gr17,@(\base,_TS_GPR17) |
sti gr18,@(\base,_TS_GPR18) |
sti gr19,@(\base,_TS_GPR19) |
sti gr20,@(\base,_TS_GPR20) |
sti gr21,@(\base,_TS_GPR21) |
sti gr22,@(\base,_TS_GPR22) |
sti gr23,@(\base,_TS_GPR23) |
sti gr24,@(\base,_TS_GPR24) |
sti gr25,@(\base,_TS_GPR25) |
sti gr26,@(\base,_TS_GPR26) |
sti gr27,@(\base,_TS_GPR27) |
sti gr28,@(\base,_TS_GPR28) |
sti gr29,@(\base,_TS_GPR29) |
sti gr30,@(\base,_TS_GPR30) |
sti gr31,@(\base,_TS_GPR31) |
#if _NGPR != 32 |
sti gr32,@(\base,_TS_GPR32) |
sti gr33,@(\base,_TS_GPR33) |
sti gr34,@(\base,_TS_GPR34) |
sti gr35,@(\base,_TS_GPR35) |
sti gr36,@(\base,_TS_GPR36) |
sti gr37,@(\base,_TS_GPR37) |
sti gr38,@(\base,_TS_GPR38) |
sti gr39,@(\base,_TS_GPR39) |
sti gr40,@(\base,_TS_GPR40) |
sti gr41,@(\base,_TS_GPR41) |
sti gr42,@(\base,_TS_GPR42) |
sti gr43,@(\base,_TS_GPR43) |
sti gr44,@(\base,_TS_GPR44) |
sti gr45,@(\base,_TS_GPR45) |
sti gr46,@(\base,_TS_GPR46) |
sti gr47,@(\base,_TS_GPR47) |
sti gr48,@(\base,_TS_GPR48) |
sti gr49,@(\base,_TS_GPR49) |
sti gr50,@(\base,_TS_GPR50) |
sti gr51,@(\base,_TS_GPR51) |
sti gr52,@(\base,_TS_GPR52) |
sti gr53,@(\base,_TS_GPR53) |
sti gr54,@(\base,_TS_GPR54) |
sti gr55,@(\base,_TS_GPR55) |
sti gr56,@(\base,_TS_GPR56) |
sti gr57,@(\base,_TS_GPR57) |
sti gr58,@(\base,_TS_GPR58) |
sti gr59,@(\base,_TS_GPR59) |
sti gr60,@(\base,_TS_GPR60) |
sti gr61,@(\base,_TS_GPR61) |
sti gr62,@(\base,_TS_GPR62) |
sti gr63,@(\base,_TS_GPR63) |
#endif |
movsg psr,gr5 |
sti gr5,@(\base,_TS_PSR) |
movsg lcr,gr5 |
sti gr5,@(\base,_TS_LCR) |
movsg cccr,gr5 |
sti gr5,@(\base,_TS_CCCR) |
movsg bpcsr,gr5 |
#if defined( CYGSEM_HAL_FRV_HW_DEBUG ) || defined(CYGPKG_HAL_FRV_FRV400) |
cmpi gr4,#CYGNUM_HAL_VECTOR_BREAKPOINT,icc0 |
beq icc0,0,10f |
#endif |
5: movsg pcsr,gr5 |
cmpi gr4,#CYGNUM_HAL_VECTOR_SYSCALL,icc0 |
blt icc0,0,10f |
6: subi gr5,#4,gr5 // traps show PC+4 |
10: sti gr5,@(\base,_TS_PC) |
.endm |
|
// Restore the machine state after an interrupt/exception |
.macro restore_state base,pcreg,retv |
ldi @(\base,_TS_PC),gr5 |
movgs gr5,\pcreg |
ldi @(\base,_TS_CCR),gr5 |
movgs gr5,ccr |
ldi @(\base,_TS_LR),gr5 |
movgs gr5,lr |
ldi @(\base,_TS_PSR),gr5 |
movgs gr5,psr |
ldi @(\base,_TS_LCR),gr5 |
movgs gr5,lcr |
ldi @(\base,_TS_CCCR),gr5 |
movgs gr5,cccr |
ldi @(\base,_TS_GPR2),gr2 |
ldi @(\base,_TS_GPR3),gr3 |
ldi @(\base,_TS_GPR4),gr4 |
ldi @(\base,_TS_GPR5),gr5 |
ldi @(\base,_TS_GPR6),gr6 |
ldi @(\base,_TS_GPR7),gr7 |
ldi @(\base,_TS_GPR8),gr8 |
ldi @(\base,_TS_GPR9),gr9 |
ldi @(\base,_TS_GPR10),gr10 |
ldi @(\base,_TS_GPR11),gr11 |
ldi @(\base,_TS_GPR12),gr12 |
ldi @(\base,_TS_GPR13),gr13 |
ldi @(\base,_TS_GPR14),gr14 |
ldi @(\base,_TS_GPR15),gr15 |
ldi @(\base,_TS_GPR16),gr16 |
ldi @(\base,_TS_GPR17),gr17 |
ldi @(\base,_TS_GPR18),gr18 |
ldi @(\base,_TS_GPR19),gr19 |
ldi @(\base,_TS_GPR20),gr20 |
ldi @(\base,_TS_GPR21),gr21 |
ldi @(\base,_TS_GPR22),gr22 |
ldi @(\base,_TS_GPR23),gr23 |
ldi @(\base,_TS_GPR24),gr24 |
ldi @(\base,_TS_GPR25),gr25 |
ldi @(\base,_TS_GPR26),gr26 |
ldi @(\base,_TS_GPR27),gr27 |
ldi @(\base,_TS_GPR28),gr28 |
ldi @(\base,_TS_GPR29),gr29 |
ldi @(\base,_TS_GPR30),gr30 |
ldi @(\base,_TS_GPR31),gr31 |
#if _NGPR != 32 |
ldi @(\base,_TS_GPR32),gr32 |
ldi @(\base,_TS_GPR33),gr33 |
ldi @(\base,_TS_GPR34),gr34 |
ldi @(\base,_TS_GPR35),gr35 |
ldi @(\base,_TS_GPR36),gr36 |
ldi @(\base,_TS_GPR37),gr37 |
ldi @(\base,_TS_GPR38),gr38 |
ldi @(\base,_TS_GPR39),gr39 |
ldi @(\base,_TS_GPR40),gr40 |
ldi @(\base,_TS_GPR41),gr41 |
ldi @(\base,_TS_GPR42),gr42 |
ldi @(\base,_TS_GPR43),gr43 |
ldi @(\base,_TS_GPR44),gr44 |
ldi @(\base,_TS_GPR45),gr45 |
ldi @(\base,_TS_GPR46),gr46 |
ldi @(\base,_TS_GPR47),gr47 |
ldi @(\base,_TS_GPR48),gr48 |
ldi @(\base,_TS_GPR49),gr49 |
ldi @(\base,_TS_GPR50),gr50 |
ldi @(\base,_TS_GPR51),gr51 |
ldi @(\base,_TS_GPR52),gr52 |
ldi @(\base,_TS_GPR53),gr53 |
ldi @(\base,_TS_GPR54),gr54 |
ldi @(\base,_TS_GPR55),gr55 |
ldi @(\base,_TS_GPR56),gr56 |
ldi @(\base,_TS_GPR57),gr57 |
ldi @(\base,_TS_GPR58),gr58 |
ldi @(\base,_TS_GPR59),gr59 |
ldi @(\base,_TS_GPR60),gr60 |
ldi @(\base,_TS_GPR61),gr61 |
ldi @(\base,_TS_GPR62),gr62 |
ldi @(\base,_TS_GPR63),gr63 |
#endif |
ldi @(\base,_TS_SP),gr1 // This has to be last - Stack pointer |
rett #\retv |
.endm |
|
#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM) |
|
.macro exception_VSR |
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS |
subi sp,24,sp |
sti gr4,@(sp,0) |
#else |
subi sp,_TS_size,sp |
sti gr4,@(sp,_TS_GPR4) |
#endif |
addi gr0,#((.-8)-_vectors)/16,gr4 |
bra _exception |
.endm |
|
#if defined(CYGPKG_HAL_FRV_FRV400) && defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) |
.macro break_VSR |
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS |
subi sp,24,sp |
sti gr4,@(sp,0) |
#else |
subi sp,_TS_size,sp |
sti gr4,@(sp,_TS_GPR4) |
#endif |
addi gr0,#((.-8)-_vectors)/16,gr4 |
bra _break |
.endm |
#endif // CYGPKG_HAL_FRV_FRV400 && STUBS |
|
.macro interrupt_VSR |
subi sp,_TS_size,sp |
sti gr4,@(sp,_TS_GPR4) |
addi gr0,#((.-8)-_vectors)/16,gr4 |
bra _interrupt |
.endm |
|
.section ".rom_vectors","ax" |
_vectors: |
call reset_vector |
nop // I hate fencepost stuff like this.... |
nop // (NEXT_INDEX_AFTER_THIS - 1) - (PREVIOUS_INDEX_FILLED) |
nop // (LAST_INDEX_TO_FILL) - (PREVIOUS_INDEX_FILLED) |
.rept (CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_1-1)-0 |
exception_VSR |
.endr |
.rept (CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_15) - (CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_1-1) |
interrupt_VSR |
.endr |
.rept (254) - CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_15 |
exception_VSR |
.endr |
#if defined(CYGPKG_HAL_FRV_FRV400) && defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) |
break_VSR // in index 255 |
#else |
exception_VSR // another one |
#endif // CYGPKG_HAL_FRV_FRV400 && STUBS |
|
// |
// Handle a break |
// |
// just like _exception, but it calls break_handler instead. |
// |
#if defined(CYGPKG_HAL_FRV_FRV400) && defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) |
_break: |
// Save current register state |
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS |
sti gr5,@(sp,4) |
|
// First, check BRR to see whether we're processing a break |
// instruction. The stub uses this instruction to enter debug mode. |
movsg brr,gr5 |
andicc gr5,#2,gr0,icc0 |
beq icc0,#0,1f |
|
// It is a break instruction. Clear BRR to acknowledge it. |
movgs gr0,brr |
|
// Set LR to the address of the instruction after the break. |
// Since software breaks are post-execution ones, BPCSR already |
// contains the right address. |
movsg bpcsr,gr5 |
movgs gr5,lr |
|
// Restore the other registers and return as if the break were a |
// call. Don't worry, the user of the break instruction knows |
// that LR will be clobbered! |
ldi @(sp,0),gr4 |
ldi @(sp,4),gr5 |
addi sp,#24,sp |
ret |
|
1: |
// We didn't come here from a break instruction so assume a |
// breakpoint or watchpoint has been triggered. Since the |
// interrupt and exception handlers save their registers on the |
// application stack, there's a chance that these handlers could |
// trigger watchpoints accidentally. We should just ignore |
// the watchpoint when that happens. |
|
// Use the previous value of SPR:ET to decide whether the break |
// was triggered by stub or user code. The stub runs with traps |
// disabled, while any user code that disables traps will not be |
// debuggable. |
movsg bpsr,gr5 |
andicc gr5,#1,gr0,icc0 |
bne icc0,#2,1f |
|
// Hmm, it looks like the GDB stub has triggered an old watchpoint. |
// Acknowledge it by clearing brr and return as if nothing had |
// happened. |
movgs gr0,brr |
ldi @(sp,0),gr4 |
ldi @(sp,4),gr5 |
addi sp,#24,sp |
rett #1 |
1: |
sti gr6,@(sp,8) |
sti gr16,@(sp,12) |
movsg lr,gr5 |
sti gr5,@(sp,16) |
movsg ccr,gr5 |
sti gr5,@(sp,20) |
// Set the global offset register (gr16) |
call .Lbrk |
.Lbrk: movsg lr,gr16 |
sethi #gprelhi(.Lbrk),gr5 |
setlo #gprello(.Lbrk),gr5 |
sub gr16,gr5,gr16 |
mov sp,gr6 // Original stack pointer |
lda __GDB_stack,gr5 // already on GDB stack? |
cmp sp,gr5,icc0 |
bhi icc0,0,10f // no - need to switch |
lda __GDB_stack_base,gr5 |
cmp sp,gr5,icc0 |
bhi icc0,0,11f |
10: lda __GDB_stack,sp // already on GDB stack? |
11: |
subi sp,_TS_size,sp // Space for scratch saves |
save_GDB_exception_regs sp,gr6 |
save_state sp |
#else |
save_exception_regs sp |
save_state sp |
#endif |
LED 0x0FFF |
add sp,gr0,gr8 |
call break_handler |
restore_state sp,bpcsr,1 |
#endif // CYGPKG_HAL_FRV_FRV400 && STUBS |
|
// |
// Handle an exception |
// |
_exception: |
// Save current register state |
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS |
sti gr5,@(sp,4) |
sti gr6,@(sp,8) |
sti gr16,@(sp,12) |
movsg lr,gr5 |
sti gr5,@(sp,16) |
movsg ccr,gr5 |
sti gr5,@(sp,20) |
// Set the global offset register (gr16) |
call .Lexp |
.Lexp: movsg lr,gr16 |
sethi #gprelhi(.Lexp),gr5 |
setlo #gprello(.Lexp),gr5 |
sub gr16,gr5,gr16 |
mov sp,gr6 // Original stack pointer |
lda __GDB_stack,gr5 // already on GDB stack? |
cmp sp,gr5,icc0 |
bhi icc0,0,10f // no - need to switch |
lda __GDB_stack_base,gr5 |
cmp sp,gr5,icc0 |
bhi icc0,0,11f |
10: lda __GDB_stack,sp // already on GDB stack? |
11: |
subi sp,_TS_size,sp // Space for scratch saves |
save_GDB_exception_regs sp,gr6 |
save_state sp |
#else |
save_exception_regs sp |
save_state sp |
#endif |
LED 0x0FFF |
add sp,gr0,gr8 |
call exception_handler |
bra _exception_return |
|
// |
// Handle an interrupt |
// Separated from exception handling to support eCos multi-level |
// (ISR/DSR) interrupt structure. |
// |
_interrupt: |
save_exception_regs sp |
save_state sp |
|
mov gr4,gr30 // save vector # |
|
// Set the global offset register (gr16) |
call .Lexp1 |
.Lexp1: movsg lr,gr16 |
sethi #gprelhi(.Lexp1),gr5 |
setlo #gprello(.Lexp1),gr5 |
sub gr16,gr5,gr16 |
LED 0x0700 |
|
lda hal_vsr_table,gr8 |
slli gr30,#2,gr4 // Vector in GR30 |
ld @(gr8,gr4),gr8 // Handler (VSR) defined? |
cmpi gr8,0,icc0 |
beq icc0,0,10f // No - use default |
LED 0x0702 |
callil @(gr8,0) // Yes - call it |
bra _exception_return |
|
// |
// Default interrupt processing |
// |
10: |
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \ |
|| defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) |
// If we are supporting Ctrl-C interrupts from GDB, we must squirrel |
// away a pointer to the save interrupt state here so that we can |
// plant a breakpoint at some later time. |
|
.extern hal_saved_interrupt_state |
lda hal_saved_interrupt_state,gr5 |
sti sp,@(gr5,0) |
#endif |
lda hal_interrupt_data,gr5 |
lda hal_interrupt_handlers,gr6 |
mov gr30,gr8 // Interrupt vector # |
slli gr30,#2,gr4 |
ld @(gr5,gr4),gr9 // data pointer |
ld @(gr6,gr4),gr6 // function |
callil @(gr6,0) |
LED 0x0701 |
// FIXME - no DSR processing |
|
// |
// Return from an exception/interrupt |
// |
_exception_return: |
LED 0x0000 |
restore_state sp,pcsr,0 |
|
.global reset_vector |
reset_vector: |
|
// Make sure the CPU is in the proper mode (system), interrupts disabled |
movsg psr,gr4 |
li ~(_PSR_ET|_PSR_PS|_PSR_PIVL_MASK),gr5 |
and gr4,gr5,gr4 |
li (_PSR_S|_PSR_ET|(0x0F<<_PSR_PIVL_SHIFT)),gr5 |
or gr4,gr5,gr4 |
movgs gr4,psr |
|
// Make sure caches, MMUs are disabled |
movsg hsr0,gr4 |
li ~(_HSR0_ICE|_HSR0_DCE|_HSR0_IMMU|_HSR0_DMMU),gr5 |
and gr4,gr5,gr4 |
movgs gr4,hsr0 |
|
// Initialize hardware platform - this macro only contains |
// code which must be run before any "normal" accesses are |
// allowed, such as enabling DRAM controllers, etc. |
platform_init |
|
#if defined(CYG_HAL_STARTUP_ROMRAM) |
// Relocate code from ROM to static RAM |
call 10f // Actual address loaded at |
5: .long _vectors |
.long 20f |
.long 5b-_vectors |
.long __rom_data_end |
10: movsg lr,gr4 |
ldi @(gr4,0),gr6 |
ldi @(gr4,4),gr10 |
ldi @(gr4,8),gr7 |
ldi @(gr4,12),gr8 |
sub gr4,gr7,gr4 // GR4 - absolute base address |
subi gr4,#4,gr4 |
subi gr6,#4,gr6 |
setlos #4,gr7 |
15: ldu @(gr4,gr7),gr5 |
stu gr5,@(gr6,gr7) |
cmp gr6,gr8,icc0 |
bne icc0,0,15b |
jmpl @(gr10,gr0) |
20: nop |
#endif |
|
// Fall through to normal program startup |
|
#endif // CYG_HAL_STARTUP_ROM |
|
.text |
|
.global _start |
_start: |
// Set the global offset register (gr16) |
call .Lcall |
.Lcall: |
movsg lr,gr4 |
sethi #gprelhi(.Lcall),gr5 |
setlo #gprello(.Lcall),gr5 |
sub gr4,gr5,gr16 |
|
LED 0x0000 |
|
#if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM) |
// Set up trap base register |
lda _vectors,gr4 |
movgs gr4,tbr |
|
LED 0x0001 |
|
// Relocate [copy] data from ROM to RAM |
lda __rom_data_start,gr4 |
lda __ram_data_start,gr5 |
lda __ram_data_end,gr6 |
cmp gr5,gr6,icc0 |
beq icc0,0,2f |
setlos #4,gr7 |
sub gr4,gr7,gr4 |
sub gr5,gr7,gr5 |
1: ldu @(gr4,gr7),gr8 |
stu gr8,@(gr5,gr7) |
cmp gr5,gr6,icc0 |
bne icc0,0,1b |
2: |
#endif |
|
// Set up stack, initial environment |
lda __startup_stack,gr4 |
mov gr4,sp |
|
// Enable caches early, based on configuration |
#ifdef CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP |
icei @(gr4,gr0),1 // purges current contents |
movsg hsr0,gr4 |
li _HSR0_ICE,gr5 // enable instruction cache |
or gr4,gr5,gr4 |
movgs gr4,hsr0 |
#endif |
#ifdef CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP |
dcef @(gr4,gr0),1 // flush contents to memory |
dcei @(gr4,gr0),1 // purges current contents |
movsg hsr0,gr4 |
li _HSR0_DCE,gr5 // enable data cache |
or gr4,gr5,gr4 |
movgs gr4,hsr0 |
#endif |
|
LED 0x0002 |
|
// Clear BSS space |
lda __bss_start,gr4 |
lda __bss_end,gr5 |
1: sti gr0,@(gr4,0) |
addi gr4,#4,gr4 |
cmp gr4,gr5,icc0 |
bne icc0,0,1b |
|
// Initialize interrupt handlers, etc |
li CYGNUM_HAL_ISR_COUNT,gr4 |
lda hal_interrupt_handlers,gr5 |
subi gr5,4,gr5 |
lda hal_default_isr,gr6 |
lda hal_vsr_table,gr8 |
subi gr8,4,gr8 |
// Note: this should be controlled by a CDL option |
lda _handle_interrupt,gr9 |
setlos #4,gr7 |
10: stu gr6,@(gr5,gr7) |
stu gr9,@(gr8,gr7) |
subi gr4,1,gr4 |
cmp gr4,gr0,icc0 |
bne icc0,0,10b |
|
LED 0x0003 |
|
// Initialize hardware |
call hal_hardware_init |
|
LED 0x0004 |
|
// Run any C++ initializations |
call cyg_hal_invoke_constructors |
|
LED 0x0005 |
|
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS |
call initialize_stub |
#endif |
|
LED 0x0006 |
|
// Start eCos application |
call cyg_start |
|
0: LED 0x0999 // Should never get here |
bra 0b |
|
// |
// Interrupt processing |
// |
_handle_interrupt: |
mov sp,gr31 // Save pointer to state frame |
movsg lr,gr29 |
|
// Set the global offset register (gr16) |
call 10f |
10: movsg lr,gr4 |
sethi #gprelhi(10b),gr5 |
setlo #gprello(10b),gr5 |
sub gr4,gr5,gr16 |
|
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK |
// Switch to interrupt stack |
#endif |
// The entire CPU state is now stashed on the stack, |
// increment the scheduler lock and handle the interrupt |
|
#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT |
.extern cyg_scheduler_sched_lock |
lda cyg_scheduler_sched_lock,gr8 |
ldi @(gr8,0),gr9 |
addi gr9,1,gr9 |
sti gr9,@(gr8,0) |
#endif |
|
#if defined(CYGPKG_KERNEL_INSTRUMENT) && \ |
defined(CYGDBG_KERNEL_INSTRUMENT_INTR) |
setlos #RAISE_INTR,gr8 // arg0 = type = INTR,RAISE |
ldi @(gr31,_TS_VECTOR),gr9 // arg1 = vector |
mov gr0,gr10 // arg2 = 0 |
call cyg_instrument // call instrument function |
#endif |
|
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \ |
|| defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) |
// If we are supporting Ctrl-C interrupts from GDB, we must squirrel |
// away a pointer to the save interrupt state here so that we can |
// plant a breakpoint at some later time. |
|
.extern hal_saved_interrupt_state |
lda hal_saved_interrupt_state,gr5 |
sti sp,@(gr5,0) |
#endif |
lda hal_interrupt_data,gr5 |
lda hal_interrupt_handlers,gr7 |
mov gr30,gr8 // Interrupt vector # |
slli gr30,#2,gr4 |
ld @(gr5,gr4),gr9 // data pointer |
ld @(gr7,gr4),gr6 // function |
callil @(gr6,0) |
LED 0x0701 |
|
#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT |
// The return value from the handler (in gr8) will indicate whether a |
// DSR is to be posted. Pass this together with a pointer to the |
// interrupt object we have just used to the interrupt tidy up routine. |
|
lda hal_interrupt_objects,gr5 |
slli gr30,#2,gr4 |
ld @(gr5,gr4),gr9 |
mov gr31,gr10 // register frame |
|
call interrupt_end // post any bottom layer handler |
// threads and call scheduler |
#endif |
movgs gr29,lr |
ret |
|
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK |
// Execute pending DSRs the interrupt stack |
// Note: this can only be called from code running on a thread stack |
.globl hal_interrupt_stack_call_pending_DSRs |
hal_interrupt_stack_call_pending_DSRs: |
subi sp,32,sp // Save important registers |
movsg lr,gr8 |
sti gr8,@(sp,0) |
// Turn on interrupts, switch to interrupt stack |
call cyg_interrupt_call_pending_DSRs |
// Turn off interrupts, switch back to thread stack |
ldi @(sp,0),gr8 |
movgs gr8,lr |
addi sp,32,sp |
ret |
#endif // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK |
|
// |
// Restore interrupt state |
// GR8 has state |
// |
.global hal_restore_interrupts |
hal_restore_interrupts: |
movsg psr,gr4 |
setlos _PSR_PIVL_MASK,gr5 |
and gr8,gr5,gr8 // Save level being restored |
not gr5,gr5 |
and gr4,gr5,gr4 // Clear out current level |
or gr8,gr4,gr4 // Insert new level |
movgs gr4,psr |
ret |
|
.global hal_query_interrupts |
hal_query_interrupts: |
movsg psr,gr8 |
setlos _PSR_PIVL_MASK,gr5 |
and gr8,gr5,gr8 |
ret |
|
// |
// "Vectors" - fixed location data items |
// This section contains any data which might be shared between |
// an eCos application and any other environment, e.g. the debug |
// ROM. |
// |
.section ".fixed_vectors" |
|
// Space for the virtual vectors |
.balign 16 |
// Vectors used to communicate between eCos and ROM environments |
.globl hal_virtual_vector_table |
hal_virtual_vector_table: |
.rept CYGNUM_CALL_IF_TABLE_SIZE |
.long 0 |
.endr |
|
.globl hal_vsr_table |
hal_vsr_table: |
.rept CYGNUM_HAL_ISR_COUNT // exceptions & interrupts |
.long 0 |
.endr |
|
.section ".data" |
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS |
.balign 16 |
__GDB_stack_base: |
.rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE // rather than 1k |
.byte 0 |
.endr |
__GDB_stack: |
#endif |
.balign 16 |
__startup_stack_base: |
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK |
.rept 512 |
#else |
.rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE |
#endif |
.byte 0 |
.endr |
.balign 16 |
.global __startup_stack |
__startup_stack: |
|
.globl hal_interrupt_handlers |
hal_interrupt_handlers: |
.rept CYGNUM_HAL_ISR_COUNT |
.long 0 |
.endr |
|
.globl hal_interrupt_data |
hal_interrupt_data: |
.rept CYGNUM_HAL_ISR_COUNT |
.long 0 |
.endr |
|
.globl hal_interrupt_objects |
hal_interrupt_objects: |
.rept CYGNUM_HAL_ISR_COUNT |
.long 0 |
.endr |
/src/frv_stub.c
0,0 → 1,382
//======================================================================== |
// |
// frv_stub.c |
// |
// Helper functions for stub, generic to all FUJITSU processors |
// |
//======================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//======================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): Red Hat, gthomas |
// Contributors: Red Hat, gthomas, jskov, msalter |
// Date: 2001-09-16 |
// Purpose: |
// Description: Helper functions for stub, generic to all FUJITSU processors |
// Usage: |
// |
//####DESCRIPTIONEND#### |
// |
//======================================================================== |
|
#include <pkgconf/hal.h> |
|
#ifdef CYGPKG_REDBOOT |
#include <pkgconf/redboot.h> |
#endif |
|
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS |
|
#include <cyg/hal/hal_stub.h> |
#include <cyg/hal/hal_arch.h> |
#include <cyg/hal/hal_intr.h> |
#include <cyg/hal/hal_cache.h> |
|
#ifndef FALSE |
#define FALSE 0 |
#define TRUE 1 |
#endif |
|
#ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT |
#include <cyg/hal/dbg-threads-api.h> // dbg_currthread_id |
#endif |
|
#if defined(CYGNUM_HAL_BREAKPOINT_LIST_SIZE) && (CYGNUM_HAL_BREAKPOINT_LIST_SIZE > 0) |
cyg_uint32 __frv_breakinst = HAL_BREAKINST; |
#endif |
|
// Sadly, this doesn't seem to work on the FRV400 either |
//#define USE_HW_STEP |
|
#ifdef CYGSEM_HAL_FRV_HW_DEBUG |
static inline unsigned __get_dcr(void) |
{ |
unsigned retval; |
|
asm volatile ( |
"movsg dcr,%0\n" |
: "=r" (retval) |
: /* no inputs */ ); |
|
return retval; |
} |
|
static inline void __set_dcr(unsigned val) |
{ |
asm volatile ( |
"movgs %0,dcr\n" |
: /* no outputs */ |
: "r" (val) ); |
} |
|
#endif |
|
/* Given a trap value TRAP, return the corresponding signal. */ |
|
int __computeSignal (unsigned int trap_number) |
{ |
// should also catch CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION here but we |
// can't tell the different between a real one and a breakpoint :-( |
switch (trap_number) { |
// Interrupts |
case CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_1 ... CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_15: |
return SIGINT; |
case CYGNUM_HAL_VECTOR_INSTR_ACCESS_MMU_MISS: |
case CYGNUM_HAL_VECTOR_INSTR_ACCESS_ERROR: |
case CYGNUM_HAL_VECTOR_INSTR_ACCESS_EXCEPTION: |
case CYGNUM_HAL_VECTOR_MEMORY_ADDRESS_NOT_ALIGNED: |
case CYGNUM_HAL_VECTOR_DATA_ACCESS_ERROR: |
case CYGNUM_HAL_VECTOR_DATA_ACCESS_MMU_MISS: |
case CYGNUM_HAL_VECTOR_DATA_ACCESS_EXCEPTION: |
case CYGNUM_HAL_VECTOR_DATA_STORE_ERROR: |
return SIGBUS; |
case CYGNUM_HAL_VECTOR_PRIVELEDGED_INSTRUCTION: |
case CYGNUM_HAL_VECTOR_ILLEGAL_INSTRUCTION: |
case CYGNUM_HAL_VECTOR_REGISTER_EXCEPTION: |
case CYGNUM_HAL_VECTOR_FP_DISABLED: |
case CYGNUM_HAL_VECTOR_MP_DISABLED: |
case CYGNUM_HAL_VECTOR_FP_EXCEPTION: |
case CYGNUM_HAL_VECTOR_MP_EXCEPTION: |
case CYGNUM_HAL_VECTOR_DIVISION_EXCEPTION: |
case CYGNUM_HAL_VECTOR_COMMIT_EXCEPTION: |
case CYGNUM_HAL_VECTOR_COMPOUND_EXCEPTION: |
return SIGILL; |
default: |
return SIGTRAP; |
} |
} |
|
|
/* Return the trap number corresponding to the last-taken trap. */ |
int __get_trap_number (void) |
{ |
// The vector is not not part of the GDB register set so get it |
// directly from the save context. |
return _hal_registers->vector; |
} |
|
|
#if defined(CYGSEM_REDBOOT_BSP_SYSCALLS) |
int __is_bsp_syscall(void) |
{ |
// Might want to be more specific here |
return (_hal_registers->vector == CYGNUM_HAL_VECTOR_SYSCALL); |
} |
#endif // defined(CYGSEM_REDBOOT_BSP_SYSCALLS) |
|
/* Set the currently-saved pc register value to PC. */ |
|
void set_pc (target_register_t pc) |
{ |
put_register (PC, pc); |
} |
|
|
/*---------------------------------------------------------------------- |
* Single-step support |
*/ |
|
/* Set things up so that the next user resume will execute one instruction. |
This may be done by setting breakpoints or setting a single step flag |
in the saved user registers, for example. */ |
|
#ifndef CYGSEM_HAL_FRV_HW_DEBUG |
#if CYGINT_HAL_FRV_ARCH_FR400 == 1 |
#define VLIW_DEPTH 2 |
#endif |
#if CYGINT_HAL_FRV_ARCH_FR500 == 1 |
#define VLIW_DEPTH 4 |
#endif |
/* |
* Structure to hold opcodes hoisted when breakpoints are |
* set for single-stepping or async interruption. |
*/ |
struct _bp_save { |
unsigned long *addr; |
unsigned long opcode; |
}; |
|
/* |
* We single-step by setting breakpoints. |
* |
* This is where we save the original instructions. |
*/ |
static struct _bp_save step_bp[VLIW_DEPTH+1]; |
|
//************************************************************** |
//************ CAUTION!! *************************************** |
//************************************************************** |
// |
// Attempt to analyze the current instruction. This code is not |
// perfect in the case of VLIW sequences, although it's close. |
// Consider these sequences: |
// |
// ldi.p @(gr5,0),gr4 |
// jmpl @(gr4,gr0) |
// and |
// |
// ldi.p @(gr5,0),gr4 |
// add.p gr6,gr7,gr8 |
// jmpl @(gr4,gr0) |
// |
// In these cases, the only way to effectively calculate the |
// target address (of the jump) would be to simulate the actions |
// of the pipelined instructions which come beforehand. |
// |
// Of course, this only affects single stepping through a VLIW |
// sequence which contains such pipelined effects and a branch. |
// Hopefully this is rare. |
// |
// Note: testing of the above sequence on the FR400 yielded an |
// illegal instruction (invalid VLIW sequence), so this may not |
// turn out to be a problem in practice, just theory. |
// |
//************************************************************** |
//************************************************************** |
|
static int |
_analyze_instr(unsigned long pc, unsigned long *targ, |
unsigned long *next, int *is_vliw) |
{ |
unsigned long opcode; |
int n, is_branch = 0; |
|
opcode = *(unsigned long *)pc; |
switch ((opcode >> 18) & 0x7f) { |
case 6: |
case 7: |
/* bcc, fbcc */ |
is_branch = 1; |
n = (int)(opcode << 16); |
n >>= 16; |
*targ = pc + n*4; |
pc += 4; |
break; |
case 12: |
/* jmpl */ |
n = (int)(get_register((opcode>>12)&63)); |
n += (int)(get_register(opcode&63)); |
pc = n; |
break; |
case 13: |
/* jmpil */ |
n = (int)(get_register((opcode>>12)&63)); |
n += (((int)(opcode << 20)) >> 20); |
pc = n; |
break; |
case 15: |
/* call */ |
n = (opcode >> 25) << 18; |
n |= (opcode & 0x3ffff); |
n <<= 8; |
n >>= 8; |
pc += n*4; |
break; |
case 14: |
/* ret */ |
is_branch = 1; |
*targ = get_register(LR); |
pc += 4; |
break; |
default: |
pc += 4; |
break; |
} |
*next = pc; |
*is_vliw = (opcode & 0x80000000) == 0; |
return is_branch; |
} |
#endif |
|
void __single_step (void) |
{ |
#ifdef CYGSEM_HAL_FRV_HW_DEBUG |
__set_dcr(__get_dcr() | _DCR_SE); |
diag_printf("Setting single step - DCR: %x\n", __get_dcr()); |
#else |
unsigned long pc, targ, next_pc; |
int i, is_branch = 0; |
int is_vliw; |
|
for (i = 0; i < VLIW_DEPTH+1; i++) { |
step_bp[i].addr = NULL; |
} |
|
pc = get_register(PC); |
i = 1; |
while (i < (VLIW_DEPTH+1)) { |
is_branch = _analyze_instr(pc, &targ, &next_pc, &is_vliw); |
if (is_branch && next_pc != targ) { |
step_bp[i].addr = (unsigned long *)targ; |
step_bp[i].opcode = *(unsigned long *)targ; |
*(unsigned long *)targ = HAL_BREAKINST; |
HAL_DCACHE_STORE(targ, 4); |
HAL_ICACHE_INVALIDATE(targ, 4); |
} |
if (is_vliw) { |
pc += 4; |
i++; |
} else { |
break; |
} |
} |
step_bp[0].addr = (unsigned long *)next_pc; |
step_bp[0].opcode = *(unsigned long *)next_pc; |
*(unsigned long *)next_pc = HAL_BREAKINST; |
HAL_DCACHE_STORE(next_pc, 4); |
HAL_ICACHE_INVALIDATE(next_pc, 4); |
#endif |
} |
|
/* Clear the single-step state. */ |
|
void __clear_single_step (void) |
{ |
#ifdef CYGSEM_HAL_FRV_HW_DEBUG |
__set_dcr(__get_dcr() & ~_DCR_SE); |
#else |
struct _bp_save *p; |
int i; |
|
for (i = 0; i < VLIW_DEPTH+1; i++) { |
p = &step_bp[i]; |
if (p->addr) { |
*(p->addr) = p->opcode; |
HAL_DCACHE_STORE((cyg_uint32)p->addr, 4); |
HAL_ICACHE_INVALIDATE((cyg_uint32)p->addr, 4); |
p->addr = NULL; |
} |
} |
#endif |
} |
|
void __install_breakpoints (void) |
{ |
#if defined(CYGNUM_HAL_BREAKPOINT_LIST_SIZE) && (CYGNUM_HAL_BREAKPOINT_LIST_SIZE > 0) |
/* Install the breakpoints in the breakpoint list */ |
__install_breakpoint_list(); |
#endif |
} |
|
void __clear_breakpoints (void) |
{ |
#if defined(CYGNUM_HAL_BREAKPOINT_LIST_SIZE) && (CYGNUM_HAL_BREAKPOINT_LIST_SIZE > 0) |
__clear_breakpoint_list(); |
#endif |
} |
|
/* If the breakpoint we hit is in the breakpoint() instruction, return a |
non-zero value. */ |
|
int |
__is_breakpoint_function () |
{ |
return get_register (PC) == (target_register_t)&_breakinst; |
} |
|
|
/* Skip the current instruction. Since this is only called by the |
stub when the PC points to a breakpoint or trap instruction, |
we can safely just skip 4. */ |
|
void __skipinst (void) |
{ |
unsigned long pc = get_register(PC); |
|
pc += 4; |
put_register(PC, pc); |
} |
|
#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS |
/src/frv.ld
0,0 → 1,158
//============================================================================= |
// |
// MLT linker script for Fujitsu (FR-V) |
// |
//============================================================================= |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//============================================================================= |
|
#include <pkgconf/system.h> |
|
STARTUP(vectors.o) |
ENTRY(_start) |
#ifdef EXTRAS |
INPUT(extras.o) |
#endif |
#if (__GNUC__ >= 3) |
GROUP(libtarget.a libgcc.a libsupc++.a) |
#else |
GROUP(libtarget.a libgcc.a) |
#endif |
|
#define ALIGN_LMA 8 |
#define FOLLOWING(_section_) AT ((LOADADDR (_section_) + SIZEOF (_section_) + ALIGN_LMA - 1) & ~ (ALIGN_LMA - 1)) |
#define LMA_EQ_VMA |
#define FORCE_OUTPUT . = . |
|
#define SECTIONS_BEGIN \ |
/* Debug information */ \ |
.debug_aranges 0 : { *(.debug_aranges) } \ |
.debug_pubnames 0 : { *(.debug_pubnames) } \ |
.debug_info 0 : { *(.debug_info) } \ |
.debug_abbrev 0 : { *(.debug_abbrev) } \ |
.debug_line 0 : { *(.debug_line) } \ |
.debug_frame 0 : { *(.debug_frame) } \ |
.debug_str 0 : { *(.debug_str) } \ |
.debug_loc 0 : { *(.debug_loc) } \ |
.debug_macinfo 0 : { *(.debug_macinfo) } |
|
#define SECTION_fixed_vectors(_region_, _vma_, _lma_) \ |
.fixed_vectors _vma_ : _lma_ \ |
{ FORCE_OUTPUT; KEEP (*(.fixed_vectors)) } \ |
> _region_ |
|
#define SECTION_rom_vectors(_region_, _vma_, _lma_) \ |
.rom_vectors _vma_ : _lma_ \ |
{ FORCE_OUTPUT; KEEP (*(.rom_vectors)) } \ |
> _region_ |
|
#define SECTION_text(_region_, _vma_, _lma_) \ |
.text _vma_ : _lma_ \ |
{ _stext = ABSOLUTE(.); \ |
PROVIDE (__stext = ABSOLUTE(.)); \ |
*(.text*) *(.gnu.warning) *(.gnu.linkonce*) *(.init) \ |
*(.glue_7) *(.glue_7t) \ |
} > _region_ \ |
_etext = .; PROVIDE (__etext = .); |
|
#define SECTION_fini(_region_, _vma_, _lma_) \ |
.fini _vma_ : _lma_ \ |
{ FORCE_OUTPUT; *(.fini) } \ |
> _region_ |
|
#define SECTION_rodata(_region_, _vma_, _lma_) \ |
.rodata _vma_ : _lma_ \ |
{ FORCE_OUTPUT; *(.rodata*) } \ |
> _region_ |
|
#define SECTION_rodata1(_region_, _vma_, _lma_) \ |
.rodata1 _vma_ : _lma_ \ |
{ FORCE_OUTPUT; *(.rodata1) } \ |
> _region_ |
|
#define SECTION_fixup(_region_, _vma_, _lma_) \ |
.fixup _vma_ : _lma_ \ |
{ FORCE_OUTPUT; *(.fixup) } \ |
> _region_ |
|
#define SECTION_gcc_except_table(_region_, _vma_, _lma_) \ |
.gcc_except_table _vma_ : _lma_ \ |
{ FORCE_OUTPUT; *(.gcc_except_table) } \ |
> _region_ |
|
#define SECTION_mmu_tables(_region_, _vma_, _lma_) \ |
.mmu_tables _vma_ : _lma_ \ |
{ FORCE_OUTPUT; *(.mmu_tables) } \ |
> _region_ |
|
#define SECTION_sram(_region_, _vma_, _lma_) \ |
.sram _vma_ : _lma_ \ |
{ FORCE_OUTPUT; *(.sram*) } \ |
> _region_ |
|
#define SECTION_data(_region_, _vma_, _lma_) \ |
.data _vma_ : _lma_ \ |
{ __ram_data_start = ABSOLUTE (.); *(.data*) *(.data1) \ |
. = ALIGN (8); \ |
KEEP(*( SORT (.ecos.table.*))) ; \ |
. = ALIGN (8); \ |
__CTOR_LIST__ = ABSOLUTE (.); KEEP (*(SORT (.ctors*))) __CTOR_END__ = ABSOLUTE (.); \ |
__DTOR_LIST__ = ABSOLUTE (.); KEEP (*(SORT (.dtors*))) __DTOR_END__ = ABSOLUTE (.); \ |
*(.sdata*) \ |
*(.eh_frame) \ |
. = ALIGN (8); *(.2ram.*) \ |
/* Global pointer stuff */ \ |
. = ALIGN(8); _gp = . + 2048; __global = _gp; \ |
_GOT_START_ = ABSOLUTE (.); *(.got) _GOT_END_ = ABSOLUTE (.); \ |
_GOT_PLT_START_ = ABSOLUTE (.); *(.got_plt) _GOT_PLT_END_ = ABSOLUTE (.); \ |
_GOT1_START_ = ABSOLUTE (.); *(.got1) _GOT1_END_ = ABSOLUTE (.); \ |
_GOT2_START_ = ABSOLUTE (.); *(.got2) _GOT2_END_ = ABSOLUTE (.); \ |
_DYNAMIC_ = ABSOLUTE (.); *(.dynamic) _DYNAMIC_ = ABSOLUTE (.); \ |
} \ |
> _region_ \ |
__rom_data_start = LOADADDR (.data); \ |
__ram_data_end = .; PROVIDE (__ram_data_end = .); _edata = .; PROVIDE (edata = .); \ |
__rom_data_end = LOADADDR (.data) + SIZEOF(.data); |
|
#define SECTION_bss(_region_, _vma_, _lma_) \ |
.bss _vma_ : _lma_ \ |
{ __bss_start = ABSOLUTE (.); \ |
*(.scommon) *(.dynbss) *(.sbss) *(.sbss.*) *(.bss*) *(.bss.*) *(COMMON) \ |
__bss_end = ABSOLUTE (.); } \ |
> _region_ |
|
#define SECTIONS_END . = ALIGN(8); _end = .; PROVIDE (end = .); |
|
#include <pkgconf/hal_frv.h> |
#include CYGHWR_MEMORY_LAYOUT_LDI |
/src/hal_mk_defs.c
0,0 → 1,193
/*========================================================================== |
// |
// hal_mk_defs.c |
// |
// HAL (architecture) "make defs" program |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): gthomas |
// Contributors: gthomas |
// Date: 2001-09-07 |
// Purpose: FUJISTU architecture dependent definition generator |
// Description: This file contains code that can be compiled by the target |
// compiler and used to generate machine specific definitions |
// suitable for use in assembly code. |
// |
//####DESCRIPTIONEND#### |
// |
//========================================================================*/ |
|
#include <pkgconf/hal.h> |
|
#include <cyg/hal/hal_arch.h> // HAL header |
#include <cyg/hal/hal_intr.h> // HAL header |
#ifdef CYGPKG_KERNEL |
# include <pkgconf/kernel.h> |
# include <cyg/kernel/instrmnt.h> |
#endif |
#include <cyg/hal/hal_if.h> |
|
/* |
* This program is used to generate definitions needed by |
* assembly language modules. |
* |
* This technique was first used in the OSF Mach kernel code: |
* generate asm statements containing #defines, |
* compile this file to assembler, and then extract the |
* #defines from the assembly-language output. |
*/ |
|
#define DEFINE(sym, val) \ |
asm volatile("\n.equ\t" #sym " %0" : : "i" (val)) |
|
int |
main(void) |
{ |
#ifdef CYGPKG_KERNEL |
DEFINE(RAISE_INTR, CYG_INSTRUMENT_CLASS_INTR|CYG_INSTRUMENT_EVENT_INTR_RAISE); |
#endif |
#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT) |
DEFINE(CYGNUM_CALL_IF_TABLE_SIZE, CYGNUM_CALL_IF_TABLE_SIZE); |
#endif |
DEFINE(CYGNUM_HAL_INTERRUPT_NONE, CYGNUM_HAL_INTERRUPT_NONE); |
DEFINE(CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE, CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE); |
DEFINE(CYGNUM_HAL_ISR_COUNT, CYGNUM_HAL_ISR_COUNT); |
DEFINE(CYGNUM_HAL_VECTOR_SYSCALL, CYGNUM_HAL_VECTOR_SYSCALL); |
DEFINE(CYGNUM_HAL_VECTOR_BREAKPOINT, CYGNUM_HAL_VECTOR_BREAKPOINT); |
DEFINE(CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_1, CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_1); |
DEFINE(CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_15, CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_15); |
|
// Register state |
DEFINE(_TS_GPR0, offsetof(HAL_SavedRegisters, gpr[0])); |
DEFINE(_TS_GPR1, offsetof(HAL_SavedRegisters, gpr[1])); |
DEFINE(_TS_SP, offsetof(HAL_SavedRegisters, gpr[1])); |
DEFINE(_TS_GPR2, offsetof(HAL_SavedRegisters, gpr[2])); |
DEFINE(_TS_GPR3, offsetof(HAL_SavedRegisters, gpr[3])); |
DEFINE(_TS_GPR4, offsetof(HAL_SavedRegisters, gpr[4])); |
DEFINE(_TS_GPR5, offsetof(HAL_SavedRegisters, gpr[5])); |
DEFINE(_TS_GPR6, offsetof(HAL_SavedRegisters, gpr[6])); |
DEFINE(_TS_GPR7, offsetof(HAL_SavedRegisters, gpr[7])); |
DEFINE(_TS_GPR8, offsetof(HAL_SavedRegisters, gpr[8])); |
DEFINE(_TS_GPR9, offsetof(HAL_SavedRegisters, gpr[9])); |
DEFINE(_TS_GPR10, offsetof(HAL_SavedRegisters, gpr[10])); |
DEFINE(_TS_GPR11, offsetof(HAL_SavedRegisters, gpr[11])); |
DEFINE(_TS_GPR12, offsetof(HAL_SavedRegisters, gpr[12])); |
DEFINE(_TS_GPR13, offsetof(HAL_SavedRegisters, gpr[13])); |
DEFINE(_TS_GPR14, offsetof(HAL_SavedRegisters, gpr[14])); |
DEFINE(_TS_GPR15, offsetof(HAL_SavedRegisters, gpr[15])); |
DEFINE(_TS_GPR16, offsetof(HAL_SavedRegisters, gpr[16])); |
DEFINE(_TS_GPR17, offsetof(HAL_SavedRegisters, gpr[17])); |
DEFINE(_TS_GPR18, offsetof(HAL_SavedRegisters, gpr[18])); |
DEFINE(_TS_GPR19, offsetof(HAL_SavedRegisters, gpr[19])); |
DEFINE(_TS_GPR20, offsetof(HAL_SavedRegisters, gpr[20])); |
DEFINE(_TS_GPR21, offsetof(HAL_SavedRegisters, gpr[21])); |
DEFINE(_TS_GPR22, offsetof(HAL_SavedRegisters, gpr[22])); |
DEFINE(_TS_GPR23, offsetof(HAL_SavedRegisters, gpr[23])); |
DEFINE(_TS_GPR24, offsetof(HAL_SavedRegisters, gpr[24])); |
DEFINE(_TS_GPR25, offsetof(HAL_SavedRegisters, gpr[25])); |
DEFINE(_TS_GPR26, offsetof(HAL_SavedRegisters, gpr[26])); |
DEFINE(_TS_GPR27, offsetof(HAL_SavedRegisters, gpr[27])); |
DEFINE(_TS_GPR28, offsetof(HAL_SavedRegisters, gpr[28])); |
DEFINE(_TS_GPR29, offsetof(HAL_SavedRegisters, gpr[29])); |
DEFINE(_TS_GPR30, offsetof(HAL_SavedRegisters, gpr[30])); |
DEFINE(_TS_GPR31, offsetof(HAL_SavedRegisters, gpr[31])); |
#if _NGPR != 32 |
DEFINE(_TS_GPR32, offsetof(HAL_SavedRegisters, gpr[32])); |
DEFINE(_TS_GPR33, offsetof(HAL_SavedRegisters, gpr[33])); |
DEFINE(_TS_GPR34, offsetof(HAL_SavedRegisters, gpr[34])); |
DEFINE(_TS_GPR35, offsetof(HAL_SavedRegisters, gpr[35])); |
DEFINE(_TS_GPR36, offsetof(HAL_SavedRegisters, gpr[36])); |
DEFINE(_TS_GPR37, offsetof(HAL_SavedRegisters, gpr[37])); |
DEFINE(_TS_GPR38, offsetof(HAL_SavedRegisters, gpr[38])); |
DEFINE(_TS_GPR39, offsetof(HAL_SavedRegisters, gpr[39])); |
DEFINE(_TS_GPR40, offsetof(HAL_SavedRegisters, gpr[40])); |
DEFINE(_TS_GPR41, offsetof(HAL_SavedRegisters, gpr[41])); |
DEFINE(_TS_GPR42, offsetof(HAL_SavedRegisters, gpr[42])); |
DEFINE(_TS_GPR43, offsetof(HAL_SavedRegisters, gpr[43])); |
DEFINE(_TS_GPR44, offsetof(HAL_SavedRegisters, gpr[44])); |
DEFINE(_TS_GPR45, offsetof(HAL_SavedRegisters, gpr[45])); |
DEFINE(_TS_GPR46, offsetof(HAL_SavedRegisters, gpr[46])); |
DEFINE(_TS_GPR47, offsetof(HAL_SavedRegisters, gpr[47])); |
DEFINE(_TS_GPR48, offsetof(HAL_SavedRegisters, gpr[48])); |
DEFINE(_TS_GPR49, offsetof(HAL_SavedRegisters, gpr[49])); |
DEFINE(_TS_GPR50, offsetof(HAL_SavedRegisters, gpr[50])); |
DEFINE(_TS_GPR51, offsetof(HAL_SavedRegisters, gpr[51])); |
DEFINE(_TS_GPR52, offsetof(HAL_SavedRegisters, gpr[52])); |
DEFINE(_TS_GPR53, offsetof(HAL_SavedRegisters, gpr[53])); |
DEFINE(_TS_GPR54, offsetof(HAL_SavedRegisters, gpr[54])); |
DEFINE(_TS_GPR55, offsetof(HAL_SavedRegisters, gpr[55])); |
DEFINE(_TS_GPR56, offsetof(HAL_SavedRegisters, gpr[56])); |
DEFINE(_TS_GPR57, offsetof(HAL_SavedRegisters, gpr[57])); |
DEFINE(_TS_GPR58, offsetof(HAL_SavedRegisters, gpr[58])); |
DEFINE(_TS_GPR59, offsetof(HAL_SavedRegisters, gpr[59])); |
DEFINE(_TS_GPR60, offsetof(HAL_SavedRegisters, gpr[60])); |
DEFINE(_TS_GPR61, offsetof(HAL_SavedRegisters, gpr[61])); |
DEFINE(_TS_GPR62, offsetof(HAL_SavedRegisters, gpr[62])); |
DEFINE(_TS_GPR63, offsetof(HAL_SavedRegisters, gpr[63])); |
#endif |
DEFINE(_TS_PC, offsetof(HAL_SavedRegisters, pc)); |
DEFINE(_TS_PSR, offsetof(HAL_SavedRegisters, psr)); |
DEFINE(_TS_LR, offsetof(HAL_SavedRegisters, lr)); |
DEFINE(_TS_CCR, offsetof(HAL_SavedRegisters, ccr)); |
DEFINE(_TS_LCR, offsetof(HAL_SavedRegisters, lcr)); |
DEFINE(_TS_CCCR, offsetof(HAL_SavedRegisters, cccr)); |
DEFINE(_TS_LR, offsetof(HAL_SavedRegisters, lr)); |
DEFINE(_TS_VECTOR, offsetof(HAL_SavedRegisters, vector)); |
#define _roundup(n,s) ((((n)+(s-1))/s)*s) |
DEFINE(_TS_size, _roundup(sizeof(HAL_SavedRegisters),8)); |
|
DEFINE(_NGPR, _NGPR); |
DEFINE(_NFPR, _NFPR); |
|
DEFINE(_PSR_ET, _PSR_ET); |
DEFINE(_PSR_S, _PSR_S); |
DEFINE(_PSR_PS, _PSR_PS); |
DEFINE(_PSR_PIVL_MASK, _PSR_PIVL_MASK); |
DEFINE(_PSR_PIVL_SHIFT, _PSR_PIVL_SHIFT); |
|
DEFINE(_HSR0_ICE, _HSR0_ICE); |
DEFINE(_HSR0_DCE, _HSR0_DCE); |
DEFINE(_HSR0_IMMU, _HSR0_IMMU); |
DEFINE(_HSR0_DMMU, _HSR0_DMMU); |
|
return 0; |
} |
|
|
/*------------------------------------------------------------------------*/ |
// EOF hal_mk_defs.c |
/ChangeLog
0,0 → 1,130
2003-04-10 Nick Garnett <nickg@balti.calivar.com> |
|
* src/frv.ld: |
Added .eh_frame to data section. This is a stopgap fix to allow |
C++ programs that define exceptions to link and run. It does not |
allow them to actually throw exceptions, since that depends on |
compiler changes that have not been made. Further, more |
far-reaching, linker script changes will also be needs when that |
happens. |
Added libsupc++.a to GROUP() directive for GCC versions later than |
3.0. |
|
2003-01-31 Mark Salter <msalter@redhat.com> |
|
* src/hal_syscall.c (hal_syscall_handler): Let generic syscall code |
handle exit. |
|
2002-04-15 Jonathan Larmour <jlarmour@redhat.com> |
|
* src/hal_syscall.c (hal_syscall_handler): Add extra sig argument to |
__do_syscall. |
|
2001-12-10 Richard Sandiford <rsandifo@redhat.com> |
|
* src/vectors.S (save_state): Remove unnecessary DDR diddling when |
handling breaks. Use BPCSR rather than BPCSR-4 as the break address. |
(restore_state): Take two new arguments: the register that the |
PC should be loaded into, and the argument to the rett instruction. |
(_break): If handling a break instruction, return to the following |
instruction using a normal "ret". Ignore other kinds of break if |
they were triggered when traps were disabled; assume that an |
interrupt or exception handler has triggered a stack watchpoint |
accidentally. Correct GP calculation. Return using "rett #1" |
rather than "rett #0". |
|
2001-11-28 Hugo Tyson <hmt@redhat.com> |
|
* src/vectors.S (_vectors): if defined(CYGPKG_HAL_FRV_FRV400) && |
defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS), add macro break_VSR |
to create a VSR entry which leaps to _break; rearrange the |
initialization of the VSR table so that the counts are correct; |
use break_VSR in slot 255; define _break which calls break_handler() |
much akin to exception handler(). |
|
Note that there is no need to define CYGSEM_HAL_FRV_HW_DEBUG for |
the FRV_FRV400 target; while we do use Hardware Debug, we don't |
use *that* sort of hardware debug, specifically we do not use |
hardware single-step, because it breaks as soon as we exit debug |
mode, ie whilst we are still within the stub. But vectors.S does |
the same tidy-up of machine state, conditioned on FVR400 instead. |
|
2001-10-17 Gary Thomas <gthomas@redhat.com> |
|
* src/frv_stub.c: Slight cleanup - only need |VLIW|+1 possible |
breakpoint locations. |
|
2001-10-16 Gary Thomas <gthomas@redhat.com> |
|
* src/vectors.S (_exception_return): Remove *bad* workaround code |
now that single step VLIW works properly. |
|
* src/frv_stub.c (__clear_single_step): |
(__single_step): Restructure to support VLIW sequences. |
|
2001-10-15 Gary Thomas <gthomas@redhat.com> |
|
* include/hal_arch.h: Remove [bogus] CYG_HAL_TABLE macros since |
the common ones work fine on this architecture. |
|
* src/vectors.S: |
* src/frv_stub.c: |
* cdl/hal_frv.cdl: Add CDL to describe various [hardware] debug |
options. |
|
2001-10-01 Gary Thomas <gthomas@redhat.com> |
|
* src/vectors.S: [FRV400] can't return from exception to a packed |
instruction - this yields illegal instruction. |
|
2001-10-11 Gary Thomas <gthomas@redhat.com> |
|
* cdl/hal_frv.cdl: |
* include/basetype.h: |
* include/hal_arch.h: |
* include/hal_intr.h: |
* include/frv_stub.h: |
* include/hal_io.h: |
* include/hal_cache.h: |
* src/frv_stub.c: |
* src/hal_mk_defs.c: |
* src/frv.ld: |
* src/hal_misc.c: |
* src/vectors.S: |
* src/context.S: |
* src/hal_syscall.c: New port for FRV architecture. |
|
//=========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//=========================================================================== |