URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/rtos/ecos-2.0/packages/hal/mips/arch
- from Rev 27 to Rev 174
- ↔ Reverse comparison
Rev 27 → Rev 174
/v2_0/cdl/hal_mips.cdl
0,0 → 1,184
# ==================================================================== |
# |
# hal_mips.cdl |
# |
# MIPS 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): jskov |
# Original data: bartv, nickg |
# Contributors: |
# Date: 1999-11-02 |
# |
#####DESCRIPTIONEND#### |
# |
# ==================================================================== |
|
cdl_package CYGPKG_HAL_MIPS { |
display "MIPS architecture" |
parent CYGPKG_HAL |
hardware |
include_dir cyg/hal |
define_header hal_mips.h |
description " |
The MIPS architecture HAL package provides generic support |
for this processor architecture. It is also necessary to |
select a CPU variant and a specific target platform HAL |
package." |
|
cdl_interface CYGINT_HAL_MIPS_VARIANT { |
display "Number of variant implementations in this configuration" |
requires 1 == CYGINT_HAL_MIPS_VARIANT |
} |
|
compile hal_misc.c context.S mips-stub.c mipsfp.c |
compile hal_syscall.c |
|
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 |
} |
|
define_proc { |
puts $::cdl_header "#define HAL_ARCH_PROGRAM_NEW_STACK hal_arch_program_new_stack" |
} |
|
cdl_option CYGHWR_HAL_MIPS_CPU_FREQ { |
display "CPU frequency" |
flavor data |
legal_values 0 to 1000000 |
default_value 50 |
description " |
This option contains the frequency of the CPU in MegaHertz. |
Choose the frequency to match the processor you have. This |
may affect thing like serial device, interval clock and |
memory access speed settings." |
} |
|
cdl_option CYGDBG_HAL_MIPS_DEBUG_GDB_CTRLC_SUPPORT { |
display "Architecture GDB CTRLC support" |
calculated { CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT || CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT } |
active_if { CYGINT_HAL_DEBUG_GDB_CTRLC_UNSUPPORTED == 0 } |
description " |
If either the CTRLC or BREAK support options in hal.h are set |
then set our own option to turn on shared generic support for |
control C handling." |
} |
|
cdl_option CYGSEM_HAL_MIPS_EMULATE_UNIMPLEMENTED_FPU_OPS { |
display "Emulate unimplemented FPU opcodes" |
flavor bool |
default_value 1 |
description " |
Enabling this option will include a hook in the exception |
processing so that Unimplemented Operation FPU exceptions |
may be handled. This option has no effect if there is no |
hardware floating-point unit. Note that not all situations |
in which an exception is raised may be handled. If not, the |
exception will be passed on as normal through the standard |
exception delivery mechanism." |
} |
|
cdl_interface CYGINT_HAL_MIPS_STUB_REPRESENT_32BIT_AS_64BIT { |
display "Represent 32-bit registers as 64-bit to GDB" |
flavor booldata |
description " |
This interface may be implemented by MIPS variant or platform HALs |
to instruct the MIPS stub to interwork correctly with GDB which |
expects 64-bit register values, even in application code which has |
been compiled as 32-bit. Do not use this for real 64-bit code." |
} |
|
cdl_interface CYGINT_HAL_MIPS_INTERRUPT_RETURN_KEEP_SR_IM { |
display "Interrupt return keeps interrupt mask bits in SR" |
description " |
On some MIPS variants, the status register (SR) contains a number |
of interrupt mask bits (IM\[0..7\]). Default behavior is to restore |
the whole SR over an interrupt. This means that if the ISR |
modifies those bits, the change is lost when the interrupt returns. |
If this interface is implemented, changes made to the SR IM bits by |
an ISR will instead be preserved. |
Variants whose HAL_INTERRUPT_MASK() routines (et al) modify the IM |
bits in the SR should implement this interface to get the necessary |
preserving behavior." |
} |
|
cdl_component CYGPKG_REDBOOT_MIPS_OPTIONS { |
display "Redboot for MIPS options" |
flavor none |
no_define |
parent CYGPKG_REDBOOT |
active_if CYGPKG_REDBOOT |
description " |
This option lists the target's requirements for a valid Redboot |
configuration." |
|
cdl_component CYGSEM_REDBOOT_MIPS_LINUX_BOOT { |
active_if CYGBLD_BUILD_REDBOOT_WITH_EXEC |
display "Support booting Linux via RedBoot" |
flavor bool |
default_value 1 |
description " |
This option allows RedBoot to support booting of a Linux kernel." |
compile -library=libextras.a redboot_linux_exec.c |
|
cdl_option CYGDAT_REDBOOT_MIPS_LINUX_BOOT_ENTRY { |
display "Default kernel entry address" |
flavor data |
default_value 0x80100750 |
} |
|
cdl_option CYGDAT_REDBOOT_MIPS_LINUX_BOOT_ARGV_ADDR { |
display "Default argv address" |
flavor data |
default_value 0x80080000 |
} |
|
cdl_option CYGDAT_REDBOOT_MIPS_LINUX_BOOT_COMMAND_LINE { |
display "Default COMMAND_LINE" |
flavor data |
default_value { "" } |
} |
} |
} |
|
} |
/v2_0/include/mips.inc
0,0 → 1,177
#ifndef CYGONCE_HAL_MIPS_INC |
#define CYGONCE_HAL_MIPS_INC |
|
##============================================================================= |
## |
## mips.inc |
## |
## MIPS assembler header file |
## |
##============================================================================= |
#####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 |
## Contributors: nickg |
## Date: 1997-10-16 |
## Purpose: MIPS definitions. |
## Description: This file contains various definitions and macros that are |
## useful for writing assembly code for the MIPS CPU family. |
## Usage: |
## #include <cyg/hal/mips.inc> |
## ... |
## |
## |
######DESCRIPTIONEND#### |
## |
##============================================================================= |
|
##----------------------------------------------------------------------------- |
## Standard MIPS register names: |
|
#define zero $0 |
#define z0 $0 |
#define v0 $2 |
#define v1 $3 |
#define a0 $4 |
#define a1 $5 |
#define a2 $6 |
#define a3 $7 |
#define t0 $8 |
#define t1 $9 |
#define t2 $10 |
#define t3 $11 |
#define t4 $12 |
#define t5 $13 |
#define t6 $14 |
#define t7 $15 |
#define s0 $16 |
#define s1 $17 |
#define s2 $18 |
#define s3 $19 |
#define s4 $20 |
#define s5 $21 |
#define s6 $22 |
#define s7 $23 |
#define t8 $24 |
#define t9 $25 |
#define k0 $26 /* kernel private register 0 */ |
#define k1 $27 /* kernel private register 1 */ |
#define gp $28 /* global data pointer */ |
#define sp $29 /* stack-pointer */ |
#define fp $30 /* frame-pointer */ |
#define ra $31 /* return address */ |
#define pc $pc /* pc, used on mips16 */ |
|
#define f0 $f0 |
#define f1 $f1 |
#define f2 $f2 |
#define f3 $f3 |
#define f4 $f4 |
#define f5 $f5 |
#define f6 $f6 |
#define f7 $f7 |
#define f8 $f8 |
#define f9 $f9 |
#define f10 $f10 |
#define f11 $f11 |
#define f12 $f12 |
#define f13 $f13 |
#define f14 $f14 |
#define f15 $f15 |
#define f16 $f16 |
#define f17 $f17 |
#define f18 $f18 |
#define f19 $f19 |
#define f20 $f20 |
#define f21 $f21 |
#define f22 $f22 |
#define f23 $f23 |
#define f24 $f24 |
#define f25 $f25 |
#define f26 $f26 |
#define f27 $f27 |
#define f28 $f28 |
#define f29 $f29 |
#define f30 $f30 |
#define f31 $f31 |
|
// Coprocessor 0 registers |
|
#define index $0 // TLB entry index register |
#define random $1 // TLB random index register |
#define tlblo0 $2 // TLB even page entry register |
#define tlblo1 $3 // TLB odd page entry register |
#define config $3 // Configuration register (TX39 only) |
#define context $4 // TLB context register |
#define pagemask $5 // TLB page size mask |
#define wired $6 // TLB wired boundary |
#define cachectrl $7 // Cache control |
#define badvr $8 // Bad virtual address |
#define count $9 // Timer cycle count register |
#define tlbhi $10 // TLB virtual address match register |
#define compare $11 // Timer compare register |
#define status $12 // Status register |
#define cause $13 // Exception cause |
#define epc $14 // Exception pc value |
#define prid $15 // processor ID |
#define config0 $16 // Config register 0 |
#define lladdr $17 // LLAdddr |
#define xcontext $20 // XContext register |
#define ecc $26 // Error Checking and Correcting |
#define cache_err $27 // Cache Error and Status |
#define taglo $28 // TagLo |
#define taghi $29 // TagHi |
#define error_epc $30 // Error exception pc value |
|
|
#------------------------------------------------------------------------------ |
|
#define FUNC_START(name) \ |
.type name,@function; \ |
.set push ; \ |
.globl name; \ |
.ent name; \ |
.set noreorder ; \ |
name: |
|
#define FUNC_END(name) \ |
name##_end: \ |
.set pop; \ |
.end name \ |
|
#------------------------------------------------------------------------------ |
#endif // ifndef CYGONCE_HAL_MIPS_INC |
# end of mips.inc |
/v2_0/include/hal_io.h
0,0 → 1,158
#ifndef CYGONCE_HAL_HAL_IO_H |
#define CYGONCE_HAL_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 |
// Contributors: nickg |
// Date: 1998-02-17 |
// 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/hal.h> |
|
#include <cyg/infra/cyg_type.h> |
|
#include <cyg/hal/plf_io.h> |
|
//----------------------------------------------------------------------------- |
// IO Register address. |
// This type is for recording the address of an IO register. |
|
typedef volatile CYG_ADDRWORD HAL_IO_REGISTER; |
|
//----------------------------------------------------------------------------- |
// HAL IO macros. |
#ifndef HAL_IO_MACROS_DEFINED |
|
//----------------------------------------------------------------------------- |
// BYTE Register access. |
// Individual and vectorized access to 8 bit registers. |
|
#define HAL_READ_UINT8( _register_, _value_ ) \ |
((_value_) = *((volatile CYG_BYTE *)(_register_))) |
|
#define HAL_WRITE_UINT8( _register_, _value_ ) \ |
(*((volatile CYG_BYTE *)(_register_)) = (_value_)) |
|
#define HAL_READ_UINT8_VECTOR( _register_, _buf_, _count_, _step_ ) \ |
{ \ |
cyg_count32 _i_,_j_; \ |
for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ |
(_buf_)[_i_] = ((volatile CYG_BYTE *)(_register_))[_j_]; \ |
} |
|
#define HAL_WRITE_UINT8_VECTOR( _register_, _buf_, _count_, _step_ ) \ |
{ \ |
cyg_count32 _i_,_j_; \ |
for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ |
((volatile CYG_BYTE *)(_register_))[_j_] = (_buf_)[_i_]; \ |
} |
|
|
//----------------------------------------------------------------------------- |
// 16 bit access. |
// Individual and vectorized access to 16 bit registers. |
|
#define HAL_READ_UINT16( _register_, _value_ ) \ |
((_value_) = *((volatile CYG_WORD16 *)(_register_))) |
|
#define HAL_WRITE_UINT16( _register_, _value_ ) \ |
(*((volatile CYG_WORD16 *)(_register_)) = (_value_)) |
|
#define HAL_READ_UINT16_VECTOR( _register_, _buf_, _count_, _step_ ) \ |
{ \ |
cyg_count32 _i_,_j_; \ |
for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ |
(_buf_)[_i_] = ((volatile CYG_WORD16 *)(_register_))[_j_]; \ |
} |
|
#define HAL_WRITE_UINT16_VECTOR( _register_, _buf_, _count_, _step_ ) \ |
{ \ |
cyg_count32 _i_,_j_; \ |
for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ |
((volatile CYG_WORD16 *)(_register_))[_j_] = (_buf_)[_i_]; \ |
} |
|
//----------------------------------------------------------------------------- |
// 32 bit access. |
// Individual and vectorized access to 32 bit registers. |
|
#define HAL_READ_UINT32( _register_, _value_ ) \ |
((_value_) = *((volatile CYG_WORD32 *)(_register_))) |
|
#define HAL_WRITE_UINT32( _register_, _value_ ) \ |
(*((volatile CYG_WORD32 *)(_register_)) = (_value_)) |
|
#define HAL_READ_UINT32_VECTOR( _register_, _buf_, _count_, _step_ ) \ |
{ \ |
cyg_count32 _i_,_j_; \ |
for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ |
(_buf_)[_i_] = ((volatile CYG_WORD32 *)(_register_))[_j_]; \ |
} |
|
#define HAL_WRITE_UINT32_VECTOR( _register_, _buf_, _count_, _step_ ) \ |
{ \ |
cyg_count32 _i_,_j_; \ |
for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ |
((volatile CYG_WORD32 *)(_register_))[_j_] = (_buf_)[_i_]; \ |
} |
|
#define HAL_IO_MACROS_DEFINED |
|
#endif |
|
|
//----------------------------------------------------------------------------- |
#endif // ifndef CYGONCE_HAL_HAL_IO_H |
// End of hal_io.h |
/v2_0/include/basetype.h
0,0 → 1,89
#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 |
// Contributors: nickg |
// Date: 1998-02-05 |
// Purpose: Define architecture base types. |
// Usage: Included by <cyg/infra/cyg_types.h>, do not use directly |
// |
//####DESCRIPTIONEND#### |
// |
|
#include <pkgconf/hal.h> |
|
//----------------------------------------------------------------------------- |
// Characterize the architecture |
|
#if defined(CYGPKG_HAL_MIPS_MSBFIRST) |
# define CYG_BYTEORDER CYG_MSBFIRST // Big endian |
#elif defined(CYGPKG_HAL_MIPS_LSBFIRST) |
# define CYG_BYTEORDER CYG_LSBFIRST // Little endian |
#else |
# error MIPS endianess not defined by configuration |
#endif |
|
#if defined(CYGPKG_HAL_MIPS_DOUBLE_MSBFIRST) |
# define CYG_DOUBLE_BYTEORDER CYG_MSBFIRST // Big endian |
#elif defined(CYGPKG_HAL_MIPS_DOUBLE_LSBFIRST) |
# define CYG_DOUBLE_BYTEORDER CYG_LSBFIRST // Little endian |
#else |
# define CYG_DOUBLE_BYTEORDER CYG_BYTEORDER // default to CPU endianess |
#endif |
|
//----------------------------------------------------------------------------- |
// MIPS does not usually use labels with undersores. |
|
//#define CYG_LABEL_NAME(_name_) _name_ |
|
//----------------------------------------------------------------------------- |
// Define the standard variable sizes |
|
// The MIPS architecture uses the default definitions of the base types, |
// so we do not need to define any here. |
|
//----------------------------------------------------------------------------- |
#endif // CYGONCE_HAL_BASETYPE_H |
// End of basetype.h |
/v2_0/include/arch.inc
0,0 → 1,779
#ifndef CYGONCE_HAL_ARCH_INC |
#define CYGONCE_HAL_ARCH_INC |
##============================================================================= |
## |
## arch.inc |
## |
## MIPS assembler header file |
## |
##============================================================================= |
#####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 |
## Contributors: nickg, dmoseley |
## Date: 1997-10-16 |
## Purpose: Architecture definitions. |
## Description: This file contains various definitions and macros that are |
## useful for writing assembly code for the MIPS CPU family. |
## Usage: |
## #include <cyg/hal/arch.inc> |
## ... |
## |
## |
######DESCRIPTIONEND#### |
## |
##============================================================================= |
|
#include <cyg/hal/mips.inc> |
|
#include <cyg/hal/variant.inc> |
|
##----------------------------------------------------------------------------- |
## Set up the value for the initial status register |
|
|
# Either the variant or platform may define an INITIAL_SR of its |
#own. If not then provide a default value here. |
|
#ifndef INITIAL_SR |
|
# Both the variant and platform HALs have the option to add some bits |
# to the default status register. If they do not choose to do so, |
# supply default zeroes here. |
|
# ifndef INITIAL_SR_VAR |
# define INITIAL_SR_VAR 0x00000000 |
# endif |
# ifndef INITIAL_SR_PLF |
# define INITIAL_SR_PLF 0x00000000 |
# endif |
|
#if defined(CYG_HAL_STARTUP_RAM) || defined(CYG_HAL_STARTUP_ROMRAM) |
# if defined(CYGPKG_HAL_MIPS_SIM) || !defined(CYGSEM_HAL_USE_ROM_MONITOR) |
# define INITIAL_SR_ARCH 0x1000ff00 /* CP0 usable, Ints enabled, master interrupt disable */ |
# else |
# define INITIAL_SR_ARCH 0x1040ff00 /* as above + ROM vectors used */ |
# endif |
#elif defined(CYG_HAL_STARTUP_ROM) |
# define INITIAL_SR_ARCH 0x1040ff00 /* as above + ROM vectors used */ |
#endif |
|
#define INITIAL_SR (INITIAL_SR_ARCH|INITIAL_SR_VAR|INITIAL_SR_PLF) |
|
#endif |
|
##----------------------------------------------------------------------------- |
## Setup the initial value for the config0 register |
|
#ifndef INITIAL_CONFIG0 |
|
#define INITIAL_CONFIG0 0x00000002 |
|
#endif |
|
##----------------------------------------------------------------------------- |
## MIPS thread and interrupt saved state. This must match the layout of the |
## HAL_SavedRegisters in hal_arch.h. Do not change this without changing the |
## layout there, or viceversa. |
|
# Size of registers that change size between 32 and 64 bit implementations |
#ifdef CYGHWR_HAL_MIPS_64BIT |
# define mips_regsize 8 |
#else |
# define mips_regsize 4 |
#endif |
|
# Size of registers that stay the same size in all implementations |
# define mips_regsize32 4 |
|
# Size of FPU registers. |
#if defined(CYGHWR_HAL_MIPS_FPU) |
# if defined(CYGHWR_HAL_MIPS_FPU_64BIT) |
# define mips_fpuregsize 8 |
# elif defined(CYGHWR_HAL_MIPS_FPU_32BIT) |
# define mips_fpuregsize 4 |
# else |
# error MIPS FPU register size not defined |
# endif |
#endif |
|
|
#define mipsreg_regs 0 |
#define mipsreg_hi (mips_regsize*32) |
#define mipsreg_lo (mipsreg_hi+mips_regsize) |
#ifdef CYGHWR_HAL_MIPS_FPU |
# define mipsreg_fpureg (mipsreg_lo+mips_regsize) |
# define mipsreg_fcr31 (mipsreg_fpureg+(mips_fpuregsize*32)) |
# define mipsreg_fppad (mipsreg_fcr31+mips_regsize32) |
# define mipsreg_vector (mipsreg_fppad+mips_regsize32) |
#else |
# define mipsreg_vector (mipsreg_lo+mips_regsize) |
#endif |
#define mipsreg_sr (mipsreg_vector+mips_regsize32) |
#define mipsreg_pc (mipsreg_sr+mips_regsize32) |
#define mipsreg_cachectrl (mipsreg_pc+mips_regsize) |
#define mipsreg_cause (mipsreg_cachectrl+mips_regsize32) |
#define mipsreg_badvr (mipsreg_cause+mips_regsize32) |
#define mipsreg_prid (mipsreg_badvr+mips_regsize) |
#define mipsreg_config (mipsreg_prid+mips_regsize32) |
#define mipsreg_size (mipsreg_config+mips_regsize32) |
|
# The following expression ensures that the decrement is always a |
# multiple of 16 bytes. This is a requirement of the MEABI used in |
# MIPS32/64 targets. |
|
#define mips_exception_decrement ((mipsreg_size*2)&~0xF) |
|
##----------------------------------------------------------------------------- |
## Minimal stack frame size uses to call functions from asm. |
|
#define mips_stack_frame_size 32 // 4 (64 bit) args worth |
|
##----------------------------------------------------------------------------- |
## Load Address and Relocate. This macro is used in code that may be linked |
## to execute out of RAM but is actually executed from ROM. If that is the |
## case a suitable version of this macro will have been defined elsewhere. |
## This is just a default version for use when that does not happen. |
|
#ifndef CYGPKG_HAL_MIPS_LAR_DEFINED |
|
.macro lar reg,addr |
la \reg,\addr |
.endm |
|
#define CYGPKG_HAL_MIPS_LAR_DEFINED |
|
#endif |
|
##----------------------------------------------------------------------------- |
## CPU specific macros. These provide a common assembler interface to |
## operations that may have CPU specific implementations on different |
## variants of the architecture. |
|
# Initialize CPU |
.macro hal_cpu_init |
|
#if defined(CYGPKG_HAL_MIPS_MIPS32) || defined(CYGPKG_HAL_MIPS_MIPS64) |
# Initialize/clear watchpoint registers |
mvatc0 zero, C0_WATCHLO |
nop |
nop |
nop |
mtc0 zero, C0_WATCHHI |
nop |
nop |
nop |
#endif /* CYGPKG_HAL_MIPS_MIPS32 || CYGPKG_HAL_MIPS_MIPS64 */ |
mtc0 zero,cause # zero cause reg |
nop |
#if !defined(CYGSEM_HAL_USE_ROM_MONITOR) |
la v0,INITIAL_SR # initialize status register |
mtc0 v0,status |
nop |
nop |
nop |
la v0,INITIAL_CONFIG0 |
mtc0 v0,config0 |
nop |
nop |
nop |
#endif |
.endm |
|
# Enable interrupts |
#ifdef CYG_HAL_MIPS_R3900 |
.macro hal_cpu_int_enable |
mfc0 v0,status |
nop |
nop |
ori v0,v0,0x0001 # set IE bit |
mtc0 v0,status |
nop |
nop |
nop |
.endm |
#else |
.macro hal_cpu_int_enable |
mfc0 v0,status |
la v1,0xFFFFFFF9 |
and v0,v0,v1 # clear EXL and ERL bits |
ori v0,v0,0x0001 # set IE bit |
mtc0 v0,status |
nop |
nop |
nop |
.endm |
#endif |
|
|
# Disable interrupts |
.macro hal_cpu_int_disable |
mfc0 v0,status |
la v1,0xFFFFFFFE |
and v0,v0,v1 |
mtc0 v0,status |
nop |
nop |
nop |
.endm |
|
# Merge the interrupt enable state of the status register in |
# \sr with the current sr. |
#ifdef CYG_HAL_MIPS_R3900 |
#define HAL_SR_INT_MASK 0x00000001 // IEc only |
#else |
#define HAL_SR_INT_MASK 0x00000007 // IE, EXL, ERL |
#endif |
.macro hal_cpu_int_merge sr |
mfc0 v0,status # V0 = current SR |
la v1,HAL_SR_INT_MASK # V1 = SR interrupt bits mask |
and \sr,\sr,v1 # Isolate interrupt bits of \sr |
nor v1,v1,zero # Invert mask |
and v0,v0,v1 # V0 = current SR except int bits |
or v0,v0,\sr # V0 = New SR |
mtc0 v0,status # Return to SR |
.endm |
|
# Enable further exception processing, and disable |
# interrupt processing. |
#ifdef CYG_HAL_MIPS_R3900 |
.macro hal_cpu_except_enable |
hal_cpu_int_disable |
.endm |
#else |
.macro hal_cpu_except_enable |
mfc0 v0,status |
la v1,0xFFFFFFF0 |
and v0,v0,v1 # clear EXL, ERL and IE bits |
mtc0 v0,status |
nop |
nop |
nop |
.endm |
#endif |
|
# Return from exception. |
#ifdef CYG_HAL_MIPS_R3900 |
.macro hal_cpu_eret pc,sr |
mtc0 \sr,status # Load status register |
nop |
nop |
nop |
sync # settle things down |
jr \pc # jump back to interrupted code |
rfe # restore state (delay slot) |
.endm |
#else |
.macro hal_cpu_eret pc,sr |
.set mips3 |
ori \sr,\sr,2 # prevent interrupts until eret |
mtc0 \sr,status # put SR back |
nop |
nop |
nop |
mvatc0 \pc,epc # put PC in EPC |
nop |
nop |
nop |
sync # settle things down |
eret # return |
nop # just to be safe |
.set mips0 |
.endm |
#endif |
|
##----------------------------------------------------------------------------- |
# Default MIPS interrupt decoding macros. This uses the basic interrupt |
# support provided by CP0 in the cause and status registers. If there is |
# a more complex external interrupt controller, or the default stuff is |
# interpreted differently (as in the TX3904) then these macros will be |
# overridden and CYGPKG_HAL_MIPS_INTC_DEFINED will be defined. |
|
#ifndef CYGPKG_HAL_MIPS_INTC_DEFINED |
|
#ifndef CYGPKG_HAL_MIPS_INTC_INIT_DEFINED |
# initialize all interrupts to disabled |
.macro hal_intc_init |
mfc0 v0,status |
nop |
lui v1,0xFFFF |
ori v1,v1,0x00FF |
and v0,v0,v1 # clear the IntMask bits |
mtc0 v0,status |
nop |
nop |
nop |
.endm |
#endif |
|
#ifndef CYGPKG_HAL_MIPS_INTC_DECODE_DEFINED |
.macro hal_intc_decode vnum |
mfc0 v1,status # get status register (interrupt mask) |
nop # delay slot |
mfc0 v0,cause # get cause register |
nop # delay slot |
and v0,v0,v1 # apply interrupt mask |
srl v0,v0,10 # shift interrupt bits down |
andi v0,v0,0x7f # isolate 6 interrupt bits |
la v1,hal_intc_translation_table |
add v0,v0,v1 # index into table |
lb \vnum,0(v0) # pick up vector number |
.endm |
#endif |
|
#ifndef CYGPKG_HAL_MIPS_INTC_TRANSLATE_DEFINED |
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN |
.macro hal_intc_translate inum,vnum |
move \vnum,zero # Just vector zero is supported |
.endm |
#else |
.macro hal_intc_translate inum,vnum |
move \vnum,\inum # Vector == interrupt number |
.endm |
#endif |
#endif |
|
.macro hal_intc_decode_data |
hal_intc_translation_table: |
.byte 0, 0, 1, 0 |
.byte 2, 0, 1, 0 |
.byte 3, 0, 1, 0 |
.byte 2, 0, 1, 0 |
.byte 4, 0, 1, 0 |
.byte 2, 0, 1, 0 |
.byte 3, 0, 1, 0 |
.byte 2, 0, 1, 0 |
.byte 5, 0, 1, 0 |
.byte 2, 0, 1, 0 |
.byte 3, 0, 1, 0 |
.byte 2, 0, 1, 0 |
.byte 4, 0, 1, 0 |
.byte 2, 0, 1, 0 |
.byte 3, 0, 1, 0 |
.byte 2, 0, 1, 0 |
.endm |
#endif |
|
#------------------------------------------------------------------------------ |
# Register save and restore macros. These expect a pointer to a CPU save state |
# area in the register \ptr. The GPR indicated by \reg will be saved into its |
# slot in that structure. |
|
#ifdef CYGHWR_HAL_MIPS_64BIT |
|
.macro sgpr reg,ptr |
sd $\reg,(mipsreg_regs+\reg*mips_regsize)(\ptr) |
.endm |
|
.macro lgpr reg,ptr |
ld $\reg,(mipsreg_regs+\reg*mips_regsize)(\ptr) |
.endm |
|
.macro slo reg,ptr |
sd \reg,(mipsreg_lo)(\ptr) |
.endm |
|
.macro shi reg,ptr |
sd \reg,(mipsreg_hi)(\ptr) |
.endm |
|
.macro llo reg,ptr |
ld \reg,(mipsreg_lo)(\ptr) |
.endm |
|
.macro lhi reg,ptr |
ld \reg,(mipsreg_hi)(\ptr) |
.endm |
|
.macro ssp reg,ptr |
sd \reg,(mipsreg_regs+29*mips_regsize)(\ptr) |
.endm |
|
.macro lsp reg,ptr |
ld \reg,(mipsreg_regs+29*mips_regsize)(\ptr) |
.endm |
|
.macro sva reg,val |
sd \reg,\val |
.endm |
|
.macro lva reg,val |
ld \reg,\val |
.endm |
|
.macro mvafc0 gpr,cpr |
dmfc0 \gpr,\cpr |
.endm |
|
.macro mvatc0 gpr,cpr |
dmtc0 \gpr,\cpr |
.endm |
|
.macro lpc reg,ptr |
ld \reg,(mipsreg_pc)(\ptr) |
.endm |
|
.macro spc reg,ptr |
sd \reg,(mipsreg_pc)(\ptr) |
.endm |
|
#else |
|
.macro sgpr reg,ptr |
sw $\reg,(mipsreg_regs+\reg*mips_regsize)(\ptr) |
.endm |
|
.macro lgpr reg,ptr |
lw $\reg,(mipsreg_regs+\reg*mips_regsize)(\ptr) |
.endm |
|
.macro slo reg,ptr |
sw \reg,(mipsreg_lo)(\ptr) |
.endm |
|
.macro shi reg,ptr |
sw \reg,(mipsreg_hi)(\ptr) |
.endm |
|
.macro llo reg,ptr |
lw \reg,(mipsreg_lo)(\ptr) |
.endm |
|
.macro lhi reg,ptr |
lw \reg,(mipsreg_hi)(\ptr) |
.endm |
|
.macro ssp reg,ptr |
sw \reg,(mipsreg_regs+29*mips_regsize)(\ptr) |
.endm |
|
.macro lsp reg,ptr |
lw \reg,(mipsreg_regs+29*mips_regsize)(\ptr) |
.endm |
|
.macro sva reg,val |
sw \reg,\val |
.endm |
|
.macro lva reg,val |
lw \reg,\val |
.endm |
|
.macro mvafc0 gpr,cpr |
mfc0 \gpr,\cpr |
.endm |
|
.macro mvatc0 gpr,cpr |
mtc0 \gpr,\cpr |
.endm |
|
.macro lpc reg,ptr |
lw \reg,(mipsreg_pc)(\ptr) |
.endm |
|
.macro spc reg,ptr |
sw \reg,(mipsreg_pc)(\ptr) |
.endm |
#endif |
|
#------------------------------------------------------------------------------ |
# FPU macros. |
# The MIPS floating point unit essentially operates in two modes. In the first |
# it supplies 32 32bit FP registers that may be paired into 16 64 bit registers. |
# In the second it supplies 32 64bit registers. Which mode is to be used depends |
# not only on the specific implementation in use, but also on the setting of the |
# FR bit in the status register (if it is implemented) and on the expectations of |
# the toolchain. |
|
#ifndef CYGPKG_HAL_MIPS_FPU_DEFINED |
|
#ifdef CYGHWR_HAL_MIPS_FPU |
|
#if defined(CYGHWR_HAL_MIPS_FPU_64BIT) |
#define sfpr sdc1 |
#define lfpr ldc1 |
#define CYG_HAL_MIPS_FPU_SR_INIT 0x24000000 |
#elif defined(CYGHWR_HAL_MIPS_FPU_32BIT) |
#define sfpr swc1 |
#define lfpr lwc1 |
#define CYG_HAL_MIPS_FPU_SR_INIT 0x20000000 |
#else |
#error MIPS FPU register size not defined |
#endif |
|
#ifndef CYG_HAL_MIPS_FCSR_INIT |
#define CYG_HAL_MIPS_FCSR_INIT 0 |
#endif |
|
.macro hal_fpu_init |
mfc0 v0,status # Get sr |
la v1,0xDBFFFFFF # Clear bits to be changed |
and v0,v0,v1 |
la v1,CYG_HAL_MIPS_FPU_SR_INIT # Set the bits we want |
or v0,v0,v1 # Set sr to required value |
mtc0 v0,status # return to sr |
nop |
nop |
nop |
la v0,CYG_HAL_MIPS_FCSR_INIT # Get initial value for FCR31 |
ctc1 v0,$31 # set Fp control reg |
nop |
.endm |
|
# Save the caller-saved registers as defined by the ABI. |
# These only really need saving during interrupts. |
.macro hal_fpu_save_caller regs |
cfc1 v0,$31 |
sw v0,mipsreg_fcr31(\regs) |
sfpr f0,(mipsreg_fpureg+0*mips_fpuregsize)(\regs) |
sfpr f1,(mipsreg_fpureg+1*mips_fpuregsize)(\regs) |
sfpr f2,(mipsreg_fpureg+2*mips_fpuregsize)(\regs) |
sfpr f3,(mipsreg_fpureg+3*mips_fpuregsize)(\regs) |
sfpr f4,(mipsreg_fpureg+4*mips_fpuregsize)(\regs) |
sfpr f5,(mipsreg_fpureg+5*mips_fpuregsize)(\regs) |
sfpr f6,(mipsreg_fpureg+6*mips_fpuregsize)(\regs) |
sfpr f7,(mipsreg_fpureg+7*mips_fpuregsize)(\regs) |
sfpr f8,(mipsreg_fpureg+8*mips_fpuregsize)(\regs) |
sfpr f9,(mipsreg_fpureg+9*mips_fpuregsize)(\regs) |
sfpr f10,(mipsreg_fpureg+10*mips_fpuregsize)(\regs) |
sfpr f11,(mipsreg_fpureg+11*mips_fpuregsize)(\regs) |
sfpr f12,(mipsreg_fpureg+12*mips_fpuregsize)(\regs) |
sfpr f13,(mipsreg_fpureg+13*mips_fpuregsize)(\regs) |
sfpr f14,(mipsreg_fpureg+14*mips_fpuregsize)(\regs) |
sfpr f15,(mipsreg_fpureg+15*mips_fpuregsize)(\regs) |
sfpr f16,(mipsreg_fpureg+16*mips_fpuregsize)(\regs) |
sfpr f17,(mipsreg_fpureg+17*mips_fpuregsize)(\regs) |
sfpr f18,(mipsreg_fpureg+18*mips_fpuregsize)(\regs) |
sfpr f19,(mipsreg_fpureg+19*mips_fpuregsize)(\regs) |
sfpr f31,(mipsreg_fpureg+31*mips_fpuregsize)(\regs) |
.endm |
|
# Save the callee-saved registers as defined by the ABI. |
# These are the only registers that need to be saved |
# across thread switches. |
.macro hal_fpu_save_callee regs |
sfpr f20,(mipsreg_fpureg+20*mips_fpuregsize)(\regs) |
sfpr f21,(mipsreg_fpureg+21*mips_fpuregsize)(\regs) |
sfpr f22,(mipsreg_fpureg+22*mips_fpuregsize)(\regs) |
sfpr f23,(mipsreg_fpureg+23*mips_fpuregsize)(\regs) |
sfpr f24,(mipsreg_fpureg+24*mips_fpuregsize)(\regs) |
sfpr f25,(mipsreg_fpureg+25*mips_fpuregsize)(\regs) |
sfpr f26,(mipsreg_fpureg+26*mips_fpuregsize)(\regs) |
sfpr f27,(mipsreg_fpureg+27*mips_fpuregsize)(\regs) |
sfpr f28,(mipsreg_fpureg+28*mips_fpuregsize)(\regs) |
sfpr f29,(mipsreg_fpureg+29*mips_fpuregsize)(\regs) |
sfpr f30,(mipsreg_fpureg+30*mips_fpuregsize)(\regs) |
.endm |
|
# General macro to save everything |
.macro hal_fpu_save regs |
hal_fpu_save_caller \regs |
hal_fpu_save_callee \regs |
.endm |
|
# Reload the caller-saved registers. |
.macro hal_fpu_load_caller regs |
lfpr f0,(mipsreg_fpureg+0*mips_fpuregsize)(\regs) |
lfpr f1,(mipsreg_fpureg+1*mips_fpuregsize)(\regs) |
lfpr f2,(mipsreg_fpureg+2*mips_fpuregsize)(\regs) |
lfpr f3,(mipsreg_fpureg+3*mips_fpuregsize)(\regs) |
lfpr f4,(mipsreg_fpureg+4*mips_fpuregsize)(\regs) |
lfpr f5,(mipsreg_fpureg+5*mips_fpuregsize)(\regs) |
lfpr f6,(mipsreg_fpureg+6*mips_fpuregsize)(\regs) |
lfpr f7,(mipsreg_fpureg+7*mips_fpuregsize)(\regs) |
lfpr f8,(mipsreg_fpureg+8*mips_fpuregsize)(\regs) |
lfpr f9,(mipsreg_fpureg+9*mips_fpuregsize)(\regs) |
lfpr f10,(mipsreg_fpureg+10*mips_fpuregsize)(\regs) |
lfpr f11,(mipsreg_fpureg+11*mips_fpuregsize)(\regs) |
lfpr f12,(mipsreg_fpureg+12*mips_fpuregsize)(\regs) |
lfpr f13,(mipsreg_fpureg+13*mips_fpuregsize)(\regs) |
lfpr f14,(mipsreg_fpureg+14*mips_fpuregsize)(\regs) |
lfpr f15,(mipsreg_fpureg+15*mips_fpuregsize)(\regs) |
lfpr f16,(mipsreg_fpureg+16*mips_fpuregsize)(\regs) |
lfpr f17,(mipsreg_fpureg+17*mips_fpuregsize)(\regs) |
lfpr f18,(mipsreg_fpureg+18*mips_fpuregsize)(\regs) |
lfpr f19,(mipsreg_fpureg+19*mips_fpuregsize)(\regs) |
lfpr f31,(mipsreg_fpureg+31*mips_fpuregsize)(\regs) |
lw v0,mipsreg_fcr31(\regs) |
ctc1 v0,$31 |
.endm |
|
# Reload the callee-saved registers. |
.macro hal_fpu_load_callee regs |
lfpr f20,(mipsreg_fpureg+20*mips_fpuregsize)(\regs) |
lfpr f21,(mipsreg_fpureg+21*mips_fpuregsize)(\regs) |
lfpr f22,(mipsreg_fpureg+22*mips_fpuregsize)(\regs) |
lfpr f23,(mipsreg_fpureg+23*mips_fpuregsize)(\regs) |
lfpr f24,(mipsreg_fpureg+24*mips_fpuregsize)(\regs) |
lfpr f25,(mipsreg_fpureg+25*mips_fpuregsize)(\regs) |
lfpr f26,(mipsreg_fpureg+26*mips_fpuregsize)(\regs) |
lfpr f27,(mipsreg_fpureg+27*mips_fpuregsize)(\regs) |
lfpr f28,(mipsreg_fpureg+28*mips_fpuregsize)(\regs) |
lfpr f29,(mipsreg_fpureg+29*mips_fpuregsize)(\regs) |
lfpr f30,(mipsreg_fpureg+30*mips_fpuregsize)(\regs) |
.endm |
|
# Reload everything. |
.macro hal_fpu_load regs |
hal_fpu_load_caller \regs |
hal_fpu_load_callee \regs |
.endm |
#else |
|
# Default macros for non-fpu implementations |
|
.macro hal_fpu_init |
.endm |
|
.macro hal_fpu_save regs |
.endm |
|
.macro hal_fpu_save_caller regs |
.endm |
|
.macro hal_fpu_save_callee regs |
.endm |
|
.macro hal_fpu_load_caller regs |
.endm |
|
.macro hal_fpu_load_callee regs |
.endm |
|
.macro hal_fpu_load regs |
.endm |
|
#endif |
|
#endif |
|
#------------------------------------------------------------------------------ |
# MMU macros. |
|
#ifndef CYGPKG_HAL_MIPS_MMU_DEFINED |
|
.macro hal_mmu_init |
.endm |
|
#endif |
|
#------------------------------------------------------------------------------ |
# MEMC macros. |
|
#ifndef CYGPKG_HAL_MIPS_MEMC_DEFINED |
|
.macro hal_memc_init |
.endm |
|
#endif |
|
#------------------------------------------------------------------------------ |
# Cache macros. |
|
#ifndef CYGPKG_HAL_MIPS_CACHE_DEFINED |
|
#ifdef CYG_HAL_MIPS_R3900 |
.macro hal_cache_init |
mfc0 v0,config # disable cache in config register |
nop |
nop |
la v1,0xffffffcf |
and v0,v0,v1 |
mtc0 v0,config |
nop |
nop |
nop |
.endm |
#else |
.macro hal_cache_init |
|
mfc0 v0,config0 # disable Kseg0 caching in config0 register |
nop |
nop |
la v1,0xfffffff8 |
and v0,v0,v1 |
ori v0,v0,2 |
mtc0 v0,config0 |
nop |
nop |
nop |
|
.endm |
#endif |
|
#endif |
|
#------------------------------------------------------------------------------ |
# Diagnostics macros. |
|
#ifndef CYGPKG_HAL_MIPS_DIAG_DEFINED |
|
.macro hal_diag_init |
.endm |
|
.macro hal_diag_excpt_start |
.endm |
|
.macro hal_diag_intr_start |
.endm |
|
.macro hal_diag_restore |
.endm |
#endif |
|
#------------------------------------------------------------------------------ |
# Timer initialization. |
|
#ifndef CYGPKG_HAL_MIPS_TIMER_DEFINED |
|
.macro hal_timer_init |
.endm |
|
#endif |
|
#------------------------------------------------------------------------------ |
# Monitor initialization. |
|
#ifndef CYGPKG_HAL_MIPS_MON_DEFINED |
|
.macro hal_mon_init |
.endm |
|
#endif |
|
#------------------------------------------------------------------------------ |
#endif // ifndef CYGONCE_HAL_ARCH_INC |
# end of arch.inc |
/v2_0/include/hal_intr.h
0,0 → 1,528
#ifndef CYGONCE_HAL_HAL_INTR_H |
#define CYGONCE_HAL_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 |
// Contributors: nickg, jskov, |
// gthomas, jlarmour |
// Date: 1999-02-16 |
// 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> |
#include <cyg/hal/hal_io.h> |
|
#include <cyg/hal/var_intr.h> |
|
//-------------------------------------------------------------------------- |
// MIPS vectors. |
|
// These are the exception codes presented in the Cause register and |
// correspond to VSRs. These values are the ones to use for HAL_VSR_GET/SET |
|
// External interrupt |
#define CYGNUM_HAL_VECTOR_INTERRUPT 0 |
// TLB modification exception |
#define CYGNUM_HAL_VECTOR_TLB_MOD 1 |
// TLB miss (Load or IFetch) |
#define CYGNUM_HAL_VECTOR_TLB_LOAD_REFILL 2 |
// TLB miss (Store) |
#define CYGNUM_HAL_VECTOR_TLB_STORE_REFILL 3 |
// Address error (Load or Ifetch) |
#define CYGNUM_HAL_VECTOR_LOAD_ADDRESS 4 |
// Address error (store) |
#define CYGNUM_HAL_VECTOR_STORE_ADDRESS 5 |
// Bus error (Ifetch) |
#define CYGNUM_HAL_VECTOR_IBE 6 |
// Bus error (data load or store) |
#define CYGNUM_HAL_VECTOR_DBE 7 |
// System call |
#define CYGNUM_HAL_VECTOR_SYSTEM_CALL 8 |
// Break point |
#define CYGNUM_HAL_VECTOR_BREAKPOINT 9 |
// Reserved instruction |
#define CYGNUM_HAL_VECTOR_RESERVED_INSTRUCTION 10 |
// Coprocessor unusable |
#define CYGNUM_HAL_VECTOR_COPROCESSOR 11 |
// Arithmetic overflow |
#define CYGNUM_HAL_VECTOR_OVERFLOW 12 |
// Reserved |
#define CYGNUM_HAL_VECTOR_RESERVED_13 13 |
// Division-by-zero [reserved vector] |
// This is caused by 'trap 0x7' which GCC puts in the code to check |
// for division by zero. The break_vsr_springboard in vectors.S is the |
// only caller of this vector. |
#define CYGNUM_HAL_VECTOR_DIV_BY_ZERO 14 |
// Floating point exception |
#ifdef CYGHWR_HAL_MIPS_FPU |
#define CYGNUM_HAL_VECTOR_FPE 15 |
#endif |
|
#define CYGNUM_HAL_VSR_MIN CYGNUM_HAL_VECTOR_INTERRUPT |
#ifdef CYGNUM_HAL_VECTOR_FPE |
#define CYGNUM_HAL_VSR_MAX CYGNUM_HAL_VECTOR_FPE |
#else |
#define CYGNUM_HAL_VSR_MAX CYGNUM_HAL_VECTOR_DIV_BY_ZERO |
#endif |
#define CYGNUM_HAL_VSR_COUNT (CYGNUM_HAL_VSR_MAX-CYGNUM_HAL_VSR_MIN+1) |
|
// Exception vectors. These are the values used when passed out to an |
// external exception handler using cyg_hal_deliver_exception() |
|
#define CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_ACCESS CYGNUM_HAL_VECTOR_TLB_MOD |
#define CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS \ |
CYGNUM_HAL_VECTOR_TLB_LOAD_REFILL |
#define CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_WRITE \ |
CYGNUM_HAL_VECTOR_TLB_STORE_REFILL |
#define CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS \ |
CYGNUM_HAL_VECTOR_LOAD_ADDRESS |
#define CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_WRITE \ |
CYGNUM_HAL_VECTOR_STORE_ADDRESS |
#define CYGNUM_HAL_EXCEPTION_CODE_ACCESS CYGNUM_HAL_VECTOR_IBE |
#define CYGNUM_HAL_EXCEPTION_DATA_ACCESS CYGNUM_HAL_VECTOR_DBE |
#define CYGNUM_HAL_EXCEPTION_SYSTEM_CALL CYGNUM_HAL_VECTOR_SYSTEM_CALL |
#define CYGNUM_HAL_EXCEPTION_INSTRUCTION_BP CYGNUM_HAL_VECTOR_BREAKPOINT |
#define CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION \ |
CYGNUM_HAL_VECTOR_RESERVED_INSTRUCTION |
#define CYGNUM_HAL_EXCEPTION_COPROCESSOR CYGNUM_HAL_VECTOR_COPROCESSOR |
#define CYGNUM_HAL_EXCEPTION_OVERFLOW CYGNUM_HAL_VECTOR_OVERFLOW |
#define CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO CYGNUM_HAL_VECTOR_DIV_BY_ZERO |
#ifdef CYGHWR_HAL_MIPS_FPU |
#define CYGNUM_HAL_EXCEPTION_FPU CYGNUM_HAL_VECTOR_FPE |
#endif |
|
#define CYGNUM_HAL_EXCEPTION_INTERRUPT CYGNUM_HAL_VECTOR_BREAKPOINT |
|
#ifdef CYGHWR_HAL_MIPS_FPU |
// decoded exception vectors |
#define CYGNUM_HAL_EXCEPTION_FPU_INEXACT (-1) |
#define CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO (-2) |
#define CYGNUM_HAL_EXCEPTION_FPU_OVERFLOW (-3) |
#define CYGNUM_HAL_EXCEPTION_FPU_UNDERFLOW (-4) |
#define CYGNUM_HAL_EXCEPTION_FPU_INVALID (-5) |
#endif |
|
// Min/Max exception numbers and how many there are |
#ifdef CYGNUM_HAL_EXCEPTION_FPU_INVALID |
#define CYGNUM_HAL_EXCEPTION_MIN CYGNUM_HAL_EXCEPTION_FPU_INVALID |
#else |
#define CYGNUM_HAL_EXCEPTION_MIN CYGNUM_HAL_VSR_MIN |
#endif |
#define CYGNUM_HAL_EXCEPTION_MAX CYGNUM_HAL_VSR_MAX |
|
#define CYGNUM_HAL_EXCEPTION_COUNT \ |
( CYGNUM_HAL_EXCEPTION_MAX - CYGNUM_HAL_EXCEPTION_MIN + 1 ) |
|
|
#ifndef CYGHWR_HAL_INTERRUPT_VECTORS_DEFINED |
|
// the default for all MIPS variants is to use the 6 bits |
// in the cause register. |
|
#define CYGNUM_HAL_INTERRUPT_0 0 |
#define CYGNUM_HAL_INTERRUPT_1 1 |
#define CYGNUM_HAL_INTERRUPT_2 2 |
#define CYGNUM_HAL_INTERRUPT_3 3 |
#define CYGNUM_HAL_INTERRUPT_4 4 |
#define CYGNUM_HAL_INTERRUPT_5 5 |
|
// Min/Max ISR numbers and how many there are |
#define CYGNUM_HAL_ISR_MIN 0 |
#define CYGNUM_HAL_ISR_MAX 5 |
#define CYGNUM_HAL_ISR_COUNT 6 |
|
// The vector used by the Real time clock. The default here is to use |
// interrupt 5, which is connected to the counter/comparator registers |
// in many MIPS variants. |
|
#ifndef CYGNUM_HAL_INTERRUPT_RTC |
#define CYGNUM_HAL_INTERRUPT_RTC CYGNUM_HAL_INTERRUPT_5 |
#endif |
|
#define CYGHWR_HAL_INTERRUPT_VECTORS_DEFINED |
|
#endif |
|
//-------------------------------------------------------------------------- |
// Static data used by HAL |
|
// ISR tables |
externC volatile CYG_ADDRESS hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT]; |
externC volatile CYG_ADDRWORD hal_interrupt_data[CYGNUM_HAL_ISR_COUNT]; |
externC volatile CYG_ADDRESS hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT]; |
|
// VSR table |
externC volatile CYG_ADDRESS hal_vsr_table[CYGNUM_HAL_VSR_MAX+1]; |
|
//-------------------------------------------------------------------------- |
// Default ISR |
// The #define is used to test whether this routine exists, and to allow |
// us 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 |
// Beware of nops in this code. They fill delay slots and avoid CP0 hazards |
// that might otherwise cause following code to run in the wrong state or |
// cause a resource conflict. |
#ifndef CYGHWR_HAL_INTERRUPT_ENABLE_DISABLE_RESTORE_DEFINED |
|
#define HAL_DISABLE_INTERRUPTS(_old_) \ |
{ \ |
asm volatile ( \ |
"mfc0 $8,$12; nop;" \ |
"move %0,$8;" \ |
"and $8,$8,0XFFFFFFFE;" \ |
"mtc0 $8,$12;" \ |
"nop; nop; nop;" \ |
"and %0,%0,0X1;" \ |
: "=r"(_old_) \ |
: \ |
: "$8" \ |
); \ |
} |
|
#define HAL_ENABLE_INTERRUPTS() \ |
{ \ |
asm volatile ( \ |
"mfc0 $8,$12; nop;" \ |
"or $8,$8,1;" \ |
"mtc0 $8,$12;" \ |
"nop; nop; nop;" \ |
: \ |
: \ |
: "$8" \ |
); \ |
} |
|
#define HAL_RESTORE_INTERRUPTS(_old_) \ |
{ \ |
asm volatile ( \ |
"mfc0 $8,$12; nop;" \ |
"and %0,%0,0x1;" \ |
"or $8,$8,%0;" \ |
"mtc0 $8,$12;" \ |
"nop; nop; nop;" \ |
: \ |
: "r"(_old_) \ |
: "$8" \ |
); \ |
} |
|
#define HAL_QUERY_INTERRUPTS( _state_ ) \ |
{ \ |
asm volatile ( \ |
"mfc0 %0,$12; nop;" \ |
"and %0,%0,0x1;" \ |
: "=r"(_state_) \ |
: \ |
: "$8" \ |
); \ |
} |
|
#endif // CYGHWR_HAL_INTERRUPT_ENABLE_DISABLE_RESTORE_DEFINED |
|
//-------------------------------------------------------------------------- |
// 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() |
|
// 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 |
|
//-------------------------------------------------------------------------- |
// Vector translation. |
// For chained interrupts we only have a single vector though which all |
// are passed. For unchained interrupts we have a vector per interrupt. |
|
#ifndef HAL_TRANSLATE_VECTOR |
|
#if defined(CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN) |
|
#define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = 0 |
|
#else |
|
#define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = (_vector_) |
|
#endif |
|
#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_uint32 _index_; \ |
HAL_TRANSLATE_VECTOR( _vector_, _index_ ); \ |
\ |
if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)HAL_DEFAULT_ISR ) \ |
{ \ |
hal_interrupt_handlers[_index_] = (CYG_ADDRESS)_isr_; \ |
hal_interrupt_data[_index_] = (CYG_ADDRWORD)_data_; \ |
hal_interrupt_objects[_index_] = (CYG_ADDRESS)_object_; \ |
} \ |
} |
|
#define HAL_INTERRUPT_DETACH( _vector_, _isr_ ) \ |
{ \ |
cyg_uint32 _index_; \ |
HAL_TRANSLATE_VECTOR( _vector_, _index_ ); \ |
\ |
if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)_isr_ ) \ |
{ \ |
hal_interrupt_handlers[_index_] = (CYG_ADDRESS)HAL_DEFAULT_ISR; \ |
hal_interrupt_data[_index_] = 0; \ |
hal_interrupt_objects[_index_] = 0; \ |
} \ |
} |
|
#define HAL_VSR_GET( _vector_, _pvsr_ ) \ |
*(_pvsr_) = (void (*)())hal_vsr_table[_vector_]; |
|
|
#define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ ) CYG_MACRO_START \ |
if( (void*)_poldvsr_ != NULL) \ |
*(CYG_ADDRESS *)_poldvsr_ = (CYG_ADDRESS)hal_vsr_table[_vector_]; \ |
hal_vsr_table[_vector_] = (CYG_ADDRESS)_vsr_; \ |
CYG_MACRO_END |
|
// This is an ugly name, but what it means is: grab the VSR back to eCos |
// internal handling, or if you like, the default handler. But if |
// cooperating with GDB and CygMon, the default behaviour is to pass most |
// exceptions to CygMon. This macro undoes that so that eCos handles the |
// exception. So use it with care. |
|
externC void __default_exception_vsr(void); |
externC void __default_interrupt_vsr(void); |
externC void __break_vsr_springboard(void); |
|
#define HAL_VSR_SET_TO_ECOS_HANDLER( _vector_, _poldvsr_ ) CYG_MACRO_START \ |
HAL_VSR_SET( _vector_, _vector_ == CYGNUM_HAL_VECTOR_INTERRUPT \ |
? (CYG_ADDRESS)__default_interrupt_vsr \ |
: _vector_ == CYGNUM_HAL_VECTOR_BREAKPOINT \ |
? (CYG_ADDRESS)__break_vsr_springboard \ |
: (CYG_ADDRESS)__default_exception_vsr, \ |
_poldvsr_ ); \ |
CYG_MACRO_END |
|
//-------------------------------------------------------------------------- |
// Interrupt controller access |
// The default code here simply uses the fields present in the CP0 status |
// and cause registers to implement this functionality. |
// Beware of nops in this code. They fill delay slots and avoid CP0 hazards |
// that might otherwise cause following code to run in the wrong state or |
// cause a resource conflict. |
|
#ifndef CYGHWR_HAL_INTERRUPT_CONTROLLER_ACCESS_DEFINED |
|
#define HAL_INTERRUPT_MASK( _vector_ ) \ |
CYG_MACRO_START \ |
asm volatile ( \ |
"mfc0 $3,$12\n" \ |
"la $2,0x00000400\n" \ |
"sllv $2,$2,%0\n" \ |
"nor $2,$2,$0\n" \ |
"and $3,$3,$2\n" \ |
"mtc0 $3,$12\n" \ |
"nop; nop; nop\n" \ |
: \ |
: "r"(_vector_) \ |
: "$2", "$3" \ |
); \ |
CYG_MACRO_END |
|
#define HAL_INTERRUPT_UNMASK( _vector_ ) \ |
CYG_MACRO_START \ |
asm volatile ( \ |
"mfc0 $3,$12\n" \ |
"la $2,0x00000400\n" \ |
"sllv $2,$2,%0\n" \ |
"or $3,$3,$2\n" \ |
"mtc0 $3,$12\n" \ |
"nop; nop; nop\n" \ |
: \ |
: "r"(_vector_) \ |
: "$2", "$3" \ |
); \ |
CYG_MACRO_END |
|
#define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ ) \ |
CYG_MACRO_START \ |
asm volatile ( \ |
"mfc0 $3,$13\n" \ |
"la $2,0x00000400\n" \ |
"sllv $2,$2,%0\n" \ |
"nor $2,$2,$0\n" \ |
"and $3,$3,$2\n" \ |
"mtc0 $3,$13\n" \ |
"nop; nop; nop\n" \ |
: \ |
: "r"(_vector_) \ |
: "$2", "$3" \ |
); \ |
CYG_MACRO_END |
|
#define HAL_INTERRUPT_CONFIGURE( _vector_, _level_, _up_ ) |
|
#define HAL_INTERRUPT_SET_LEVEL( _vector_, _level_ ) |
|
#define CYGHWR_HAL_INTERRUPT_CONTROLLER_ACCESS_DEFINED |
|
#endif |
|
//-------------------------------------------------------------------------- |
// Clock control. |
// This code uses the count and compare registers that are present in many |
// MIPS variants. |
// Beware of nops in this code. They fill delay slots and avoid CP0 hazards |
// that might otherwise cause following code to run in the wrong state or |
// cause a resource conflict. |
|
#ifndef CYGHWR_HAL_CLOCK_CONTROL_DEFINED |
|
externC CYG_WORD32 cyg_hal_clock_period; |
#define CYGHWR_HAL_CLOCK_PERIOD_DEFINED |
|
#define HAL_CLOCK_INITIALIZE( _period_ ) \ |
CYG_MACRO_START \ |
asm volatile ( \ |
"mtc0 $0,$9\n" \ |
"nop; nop; nop\n" \ |
"mtc0 %0,$11\n" \ |
"nop; nop; nop\n" \ |
: \ |
: "r"(_period_) \ |
); \ |
cyg_hal_clock_period = _period_; \ |
CYG_MACRO_END |
|
#define HAL_CLOCK_RESET( _vector_, _period_ ) \ |
CYG_MACRO_START \ |
asm volatile ( \ |
"mtc0 $0,$9\n" \ |
"nop; nop; nop\n" \ |
"mtc0 %0,$11\n" \ |
"nop; nop; nop\n" \ |
: \ |
: "r"(_period_) \ |
); \ |
CYG_MACRO_END |
|
#define HAL_CLOCK_READ( _pvalue_ ) \ |
CYG_MACRO_START \ |
register CYG_WORD32 result; \ |
asm volatile ( \ |
"mfc0 %0,$9\n" \ |
: "=r"(result) \ |
); \ |
*(_pvalue_) = result; \ |
CYG_MACRO_END |
|
#define CYGHWR_HAL_CLOCK_CONTROL_DEFINED |
|
#endif |
|
#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && \ |
!defined(HAL_CLOCK_LATENCY) |
#define HAL_CLOCK_LATENCY( _pvalue_ ) \ |
CYG_MACRO_START \ |
register CYG_WORD32 _cval_; \ |
HAL_CLOCK_READ(&_cval_); \ |
*(_pvalue_) = _cval_ - cyg_hal_clock_period; \ |
CYG_MACRO_END |
#endif |
|
|
//-------------------------------------------------------------------------- |
// Microsecond delay function provided in hal_misc.c |
externC void hal_delay_us(int us); |
|
#define HAL_DELAY_US(n) hal_delay_us(n) |
|
//-------------------------------------------------------------------------- |
#endif // ifndef CYGONCE_HAL_HAL_INTR_H |
// End of hal_intr.h |
/v2_0/include/hal_arch.h
0,0 → 1,509
#ifndef CYGONCE_HAL_HAL_ARCH_H |
#define CYGONCE_HAL_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 |
// Contributors: nickg, dmoseley |
// Date: 1999-02-17 |
// Purpose: Define architecture abstractions |
// Usage: #include <cyg/hal/hal_arch.h> |
// |
//####DESCRIPTIONEND#### |
// |
//========================================================================== |
|
#ifndef __ASSEMBLER__ |
#include <pkgconf/hal.h> |
#include <cyg/infra/cyg_type.h> |
|
#include <cyg/hal/var_arch.h> |
|
//-------------------------------------------------------------------------- |
// Processor saved states: |
// The layout of this structure is also defined in "arch.inc", for assembly |
// code. Do not change this without changing that (or vice versa). |
// Notes: This structure is carefully laid out. It is a multiple of 8 |
// bytes and the pc and badvr fields are positioned to ensure that |
// they are on 8 byte boundaries. |
|
#ifdef CYGHWR_HAL_MIPS_64BIT |
# define CYG_HAL_MIPS_REG CYG_WORD64 |
# define CYG_HAL_MIPS_REG_SIZE 8 |
#else |
# define CYG_HAL_MIPS_REG CYG_WORD32 |
# define CYG_HAL_MIPS_REG_SIZE 4 |
#endif |
|
#if defined(CYGHWR_HAL_MIPS_FPU) |
# if defined(CYGHWR_HAL_MIPS_FPU_64BIT) |
# define CYG_HAL_FPU_REG CYG_WORD64 |
# elif defined(CYGHWR_HAL_MIPS_FPU_32BIT) |
# define CYG_HAL_FPU_REG CYG_WORD32 |
# else |
# error MIPS FPU register size not defined |
# endif |
#endif |
|
typedef struct |
{ |
// These are common to all saved states |
CYG_HAL_MIPS_REG d[32]; /* Data regs */ |
CYG_HAL_MIPS_REG hi; /* hi word of mpy/div reg */ |
CYG_HAL_MIPS_REG lo; /* lo word of mpy/div reg */ |
#ifdef CYGHWR_HAL_MIPS_FPU |
CYG_HAL_FPU_REG f[32]; /* FPU registers */ |
CYG_WORD32 fcr31; /* FPU control/status register */ |
CYG_WORD32 fppad; /* Dummy location to make this */ |
/* structure a multiple of 8 */ |
/* bytes long. */ |
#endif |
|
// These are only saved for exceptions and interrupts |
CYG_WORD32 vector; /* Vector number */ |
CYG_WORD32 sr; /* Status Reg */ |
CYG_HAL_MIPS_REG pc; /* Program Counter */ |
CYG_WORD32 cache; /* Cache control register */ |
|
|
// These are only saved for exceptions, and are not restored |
// when continued. |
CYG_WORD32 cause; /* Exception cause register */ |
CYG_HAL_MIPS_REG badvr; /* Bad virtual address reg */ |
CYG_WORD32 prid; /* Processor Version */ |
CYG_WORD32 config; /* Config register */ |
} 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 cyg_uint32 hal_lsbit_index(cyg_uint32 mask); |
externC cyg_uint32 hal_msbit_index(cyg_uint32 mask); |
|
#define HAL_LSBIT_INDEX(index, mask) index = hal_lsbit_index(mask); |
|
#define HAL_MSBIT_INDEX(index, mask) index = hal_msbit_index(mask); |
|
//-------------------------------------------------------------------------- |
// Context Initialization |
|
|
// Optional FPU context initialization |
#ifdef CYGHWR_HAL_MIPS_FPU |
#define HAL_THREAD_INIT_FPU_CONTEXT( _regs_, _id_ ) \ |
{ \ |
for( _i_ = 0; _i_ < 32; _i_++ ) (_regs_)->f[_i_] = (_id_)|0xFF00|_i_; \ |
(_regs_)->fcr31 = 0x01000000; \ |
} |
#else |
#define HAL_THREAD_INIT_FPU_CONTEXT( _regs_, _id_ ) |
#endif |
|
|
// Initialize the context of a thread. |
// Arguments: |
// _sparg_ name of variable containing current sp, will be written with 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_ ) \ |
{ \ |
register CYG_WORD _sp_ = ((CYG_WORD)_sparg_)-56; \ |
register HAL_SavedRegisters *_regs_; \ |
int _i_; \ |
_sp_ = _sp_ & 0xFFFFFFF0; \ |
_regs_ = (HAL_SavedRegisters *)(((_sp_) - sizeof(HAL_SavedRegisters))&0xFFFFFFF0); \ |
for( _i_ = 0; _i_ < 32; _i_++ ) (_regs_)->d[_i_] = (_id_)|_i_; \ |
HAL_THREAD_INIT_FPU_CONTEXT( _regs_, _id_ ); \ |
(_regs_)->d[29] = (CYG_HAL_MIPS_REG)(_sp_); /* SP = top of stack */ \ |
(_regs_)->d[04] = (CYG_HAL_MIPS_REG)(_thread_); /* R4 = arg1 = thread ptr */ \ |
(_regs_)->lo = 0; /* LO = 0 */ \ |
(_regs_)->hi = 0; /* HI = 0 */ \ |
(_regs_)->d[30] = (CYG_HAL_MIPS_REG)(_sp_); /* FP = top of stack */ \ |
(_regs_)->d[31] = (CYG_HAL_MIPS_REG)(_entry_); /* RA(d[31]) = entry point*/ \ |
(_regs_)->pc = (CYG_WORD)(_entry_); /* PC = entry point */ \ |
(_regs_)->sr = 0x00000001; /* SR = ls 3 bits only */ \ |
_sparg_ = (CYG_ADDRESS)_regs_; \ |
} |
|
//-------------------------------------------------------------------------- |
// 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. |
// The "memory" keyword is potentially unnecessary, but it is harmless to |
// keep it. |
|
#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. |
// HAL_BREAKINST_TYPE is the type. |
|
#define HAL_BREAKPOINT(_label_) \ |
asm volatile (" .globl " #_label_ ";" \ |
#_label_":" \ |
" break 5" \ |
); |
|
#define HAL_BREAKINST 0x0005000d |
|
#define HAL_BREAKINST_SIZE 4 |
|
#define HAL_BREAKINST_TYPE cyg_uint32 |
|
//-------------------------------------------------------------------------- |
// Thread register state manipulation for GDB support. |
|
// Default to a 32 bit register size for GDB register dumps. |
#ifndef CYG_HAL_GDB_REG |
#define CYG_HAL_GDB_REG CYG_WORD32 |
#endif |
|
// 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_) |
|
// If the CPU has an FPU, we also need to move the FPU registers. |
#ifdef CYGHWR_HAL_MIPS_FPU |
#define HAL_GET_GDB_FPU_REGISTERS( _regval_ , _regs_ ) \ |
CYG_MACRO_START \ |
int _i_; \ |
for( _i_ = 0; _i_ < 32; _i_++ ) \ |
_regval_[38+_i_] = (_regs_)->f[_i_]; \ |
_regval_[70] = (_regs_)->fcr31; \ |
CYG_MACRO_END |
#define HAL_SET_GDB_FPU_REGISTERS( _regs_ , _regval_ ) \ |
CYG_MACRO_START \ |
int _i_; \ |
for( _i_ = 0; _i_ < 32; _i_++ ) \ |
(_regs_)->f[_i_] = _regval_[38+_i_]; \ |
(_regs_)->fcr31 = _regval_[70]; \ |
CYG_MACRO_END |
#else |
#define HAL_GET_GDB_FPU_REGISTERS( _regval_ , _regs_ ) |
#define HAL_SET_GDB_FPU_REGISTERS( _regs_ , _regval_ ) |
#endif |
|
// Some targets also report the state of all the coprocessor 0 |
// registers to GDB. If that is the case then |
// CYGPKG_HAL_MIPS_GDB_REPORT_CP0 will be defined and the |
// HAL_[G|S]ET_CP0_REGISTER_*() macros will be defined. |
|
#ifdef CYGPKG_HAL_MIPS_GDB_REPORT_CP0 |
|
#define HAL_GET_GDB_CP0_REGISTERS( _regval_, _regs_ ) \ |
HAL_GET_CP0_REGISTER_32( _regval_[74], 0, 0 ); /* index */ \ |
HAL_GET_CP0_REGISTER_32( _regval_[75], 1, 0 ); /* random */ \ |
HAL_GET_CP0_REGISTER_32( _regval_[76], 2, 0 ); /* EntryLo0 */ \ |
HAL_GET_CP0_REGISTER_32( _regval_[77], 3, 0 ); /* EntryLo1 */ \ |
HAL_GET_CP0_REGISTER_64( _regval_[78], 4, 0 ); /* context */ \ |
HAL_GET_CP0_REGISTER_32( _regval_[79], 5, 0 ); /* PageMask */ \ |
HAL_GET_CP0_REGISTER_32( _regval_[80], 6, 0 ); /* Wired */ \ |
(_regval_)[81] = 0xC0C0C006; \ |
(_regval_)[82] = (_regs_)->badvr; /* BadVr */ \ |
HAL_GET_CP0_REGISTER_32( _regval_[83], 9, 0 ); /* Count */ \ |
HAL_GET_CP0_REGISTER_64( _regval_[84], 10, 0 ); /* EntryHi */ \ |
HAL_GET_CP0_REGISTER_32( _regval_[85], 11, 0 ); /* Compare */ \ |
(_regval_)[86] = (_regs_)->sr; /* Status */ \ |
(_regval_)[87] = (_regs_)->cause; /* Cause */ \ |
HAL_GET_CP0_REGISTER_64( _regval_[88], 14, 0 ); /* EPC */ \ |
HAL_GET_CP0_REGISTER_32( _regval_[89], 15, 0 ); /* PRId */ \ |
HAL_GET_CP0_REGISTER_32( _regval_[90], 16, 0 ); /* Config */ \ |
HAL_GET_CP0_REGISTER_32( _regval_[91], 17, 0 ); /* LLAddr */ \ |
HAL_GET_CP0_REGISTER_64( _regval_[92], 18, 0 ); /* WatchLo */ \ |
HAL_GET_CP0_REGISTER_32( _regval_[93], 19, 0 ); /* WatchHi */ \ |
HAL_GET_CP0_REGISTER_64( _regval_[94], 20, 0 ); /* XContext */ \ |
(_regval_)[95] = 0xC0C0C021; \ |
(_regval_)[96] = 0xC0C0C022; \ |
HAL_GET_CP0_REGISTER_32( _regval_[97], 23, 0 ); /* Debug */ \ |
HAL_GET_CP0_REGISTER_64( _regval_[98], 24, 0 ); /* DEPC */ \ |
(_regval_)[99] = 0xC0C0C025; \ |
HAL_GET_CP0_REGISTER_32( _regval_[100], 26, 0 ); /* ErrCtl */ \ |
HAL_GET_CP0_REGISTER_32( _regval_[101], 27, 0 ); /* CacheErr */ \ |
HAL_GET_CP0_REGISTER_32( _regval_[102], 28, 0 ); /* TagLo */ \ |
HAL_GET_CP0_REGISTER_32( _regval_[103], 29, 0 ); /* TagHi */ \ |
HAL_GET_CP0_REGISTER_64( _regval_[104], 30, 0 ); /* ErrorEPC */ \ |
HAL_GET_CP0_REGISTER_64( _regval_[105], 31, 0 ); /* DESAVE */ \ |
HAL_GET_CP0_REGISTER_32( _regval_[106], 16, 1 ); /* Config1 */ |
|
#define HAL_SET_GDB_CP0_REGISTERS( _regval_, _regs_ ) \ |
HAL_SET_CP0_REGISTER_32( _regval_[74], 0, 0 ); /* index */ \ |
HAL_SET_CP0_REGISTER_32( _regval_[76], 2, 0 ); /* EntryLo0 */ \ |
HAL_SET_CP0_REGISTER_32( _regval_[77], 3, 0 ); /* EntryLo1 */ \ |
HAL_SET_CP0_REGISTER_64( _regval_[78], 4, 0 ); /* context */ \ |
HAL_SET_CP0_REGISTER_32( _regval_[79], 5, 0 ); /* PageMask */ \ |
HAL_SET_CP0_REGISTER_32( _regval_[80], 6, 0 ); /* Wired */ \ |
HAL_SET_CP0_REGISTER_32( _regval_[83], 9, 0 ); /* Count */ \ |
HAL_SET_CP0_REGISTER_64( _regval_[84], 10, 0 ); /* EntryHi */ \ |
HAL_SET_CP0_REGISTER_32( _regval_[85], 11, 0 ); /* Compare */ \ |
HAL_SET_CP0_REGISTER_32( _regval_[90], 16, 0 ); /* Config */ \ |
HAL_SET_CP0_REGISTER_64( _regval_[92], 18, 0 ); /* WatchLo */ \ |
HAL_SET_CP0_REGISTER_32( _regval_[93], 19, 0 ); /* WatchHi */ \ |
HAL_SET_CP0_REGISTER_64( _regval_[94], 20, 0 ); /* XContext */ \ |
HAL_SET_CP0_REGISTER_32( _regval_[97], 23, 0 ); /* Debug */ \ |
HAL_SET_CP0_REGISTER_64( _regval_[98], 24, 0 ); /* DEPC */ \ |
HAL_SET_CP0_REGISTER_32( _regval_[100], 26, 0 ); /* ErrCtl */ \ |
HAL_SET_CP0_REGISTER_32( _regval_[101], 27, 0 ); /* CacheErr */ \ |
HAL_SET_CP0_REGISTER_32( _regval_[102], 28, 0 ); /* TagLo */ \ |
HAL_SET_CP0_REGISTER_32( _regval_[103], 29, 0 ); /* TagHi */ \ |
HAL_SET_CP0_REGISTER_64( _regval_[105], 31, 0 ); /* DESAVE */ |
|
#else |
#define HAL_GET_GDB_CP0_REGISTERS( _regval_, _regs_ ) |
#define HAL_SET_GDB_CP0_REGISTERS( _regval_, _regs_ ) |
#endif |
|
// Copy a set of registers from a HAL_SavedRegisters structure into a |
// GDB ordered array. |
#define HAL_GET_GDB_REGISTERS( _aregval_ , _regs_ ) \ |
{ \ |
CYG_HAL_GDB_REG *_regval_ = (CYG_HAL_GDB_REG *)(_aregval_); \ |
int _i_; \ |
\ |
for( _i_ = 0; _i_ < 32; _i_++ ) \ |
_regval_[_i_] = (_regs_)->d[_i_]; \ |
\ |
HAL_GET_GDB_FPU_REGISTERS( _regval_, _regs_ ); \ |
\ |
_regval_[32] = (_regs_)->sr; \ |
_regval_[33] = (_regs_)->lo; \ |
_regval_[34] = (_regs_)->hi; \ |
_regval_[35] = (_regs_)->badvr; \ |
_regval_[36] = (_regs_)->cause; \ |
_regval_[37] = (_regs_)->pc; \ |
\ |
HAL_GET_GDB_CP0_REGISTERS( _regval_, _regs_ ); \ |
} |
|
// Copy a GDB ordered array into a HAL_SavedRegisters structure. |
#define HAL_SET_GDB_REGISTERS( _regs_ , _aregval_ ) \ |
{ \ |
CYG_HAL_GDB_REG *_regval_ = (CYG_HAL_GDB_REG *)(_aregval_); \ |
int _i_; \ |
\ |
for( _i_ = 0; _i_ < 32; _i_++ ) \ |
(_regs_)->d[_i_] = _regval_[_i_]; \ |
\ |
HAL_SET_GDB_FPU_REGISTERS( _regs_, _regval_ ); \ |
\ |
(_regs_)->sr = _regval_[32]; \ |
(_regs_)->lo = _regval_[33]; \ |
(_regs_)->hi = _regval_[34]; \ |
(_regs_)->badvr = _regval_[35]; \ |
(_regs_)->cause = _regval_[36]; \ |
(_regs_)->pc = _regval_[37]; \ |
\ |
HAL_SET_GDB_CP0_REGISTERS( _regval_, _regs_ ); \ |
} |
|
//-------------------------------------------------------------------------- |
// HAL setjmp |
// Note: These definitions are repeated in hal_arch.h. If changes are |
// required remember to update both sets. |
|
#define CYGARC_JMP_BUF_SP 0 |
#define CYGARC_JMP_BUF_R16 1 |
#define CYGARC_JMP_BUF_R17 2 |
#define CYGARC_JMP_BUF_R18 3 |
#define CYGARC_JMP_BUF_R19 4 |
#define CYGARC_JMP_BUF_R20 5 |
#define CYGARC_JMP_BUF_R21 6 |
#define CYGARC_JMP_BUF_R22 7 |
#define CYGARC_JMP_BUF_R23 8 |
#define CYGARC_JMP_BUF_R28 9 |
#define CYGARC_JMP_BUF_R30 10 |
#define CYGARC_JMP_BUF_R31 11 |
|
#define CYGARC_JMP_BUF_SIZE 12 |
|
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. |
|
// Typical case stack frame size: return link + 4 pushed registers + some locals. |
#define CYGNUM_HAL_STACK_FRAME_SIZE (48) |
|
// Stack needed for a context switch: |
#if defined(CYGHWR_HAL_MIPS_FPU) |
# if defined(CYGHWR_HAL_MIPS_FPU_64BIT) |
#define CYGNUM_HAL_STACK_CONTEXT_SIZE (((32+12)*CYG_HAL_MIPS_REG_SIZE)+(32*8)) |
# elif defined(CYGHWR_HAL_MIPS_FPU_32BIT) |
#define CYGNUM_HAL_STACK_CONTEXT_SIZE (((32+12)*CYG_HAL_MIPS_REG_SIZE)+(32*4)) |
# else |
# error MIPS FPU register size not defined |
# endif |
#else |
#define CYGNUM_HAL_STACK_CONTEXT_SIZE ((32+10)*CYG_HAL_MIPS_REG_SIZE) |
#endif |
|
|
|
// Interrupt + call to ISR, interrupt_end() and the DSR |
#define CYGNUM_HAL_STACK_INTERRUPT_SIZE (4+2*CYGNUM_HAL_STACK_CONTEXT_SIZE) |
|
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK |
|
// An interrupt stack which is large enough for all possible interrupt |
// conditions (and only used for that purpose) exists. "User" stacks |
// can be much smaller |
|
#define CYGNUM_HAL_STACK_SIZE_MINIMUM (CYGNUM_HAL_STACK_CONTEXT_SIZE+ \ |
CYGNUM_HAL_STACK_INTERRUPT_SIZE*2+ \ |
CYGNUM_HAL_STACK_FRAME_SIZE*8) |
#define CYGNUM_HAL_STACK_SIZE_TYPICAL (CYGNUM_HAL_STACK_SIZE_MINIMUM+1024) |
|
#else // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK |
|
// No separate interrupt stack exists. Make sure all threads contain |
// a stack sufficiently large. |
|
#define CYGNUM_HAL_STACK_SIZE_MINIMUM (4096) |
#define CYGNUM_HAL_STACK_SIZE_TYPICAL (4096) |
|
#endif |
|
#endif /* __ASSEMBLER__ */ |
|
// Convenience macros for accessing memory cached or uncached |
#define CYGARC_KSEG_MASK (0xE0000000) |
#define CYGARC_KSEG_CACHED (0x80000000) |
#define CYGARC_KSEG_UNCACHED (0xA0000000) |
#define CYGARC_KSEG_CACHED_BASE (0x80000000) |
#define CYGARC_KSEG_UNCACHED_BASE (0xA0000000) |
#ifndef __ASSEMBLER__ |
#define CYGARC_CACHED_ADDRESS(x) ((((CYG_ADDRESS)(x)) & ~CYGARC_KSEG_MASK) | CYGARC_KSEG_CACHED) |
#define CYGARC_UNCACHED_ADDRESS(x) ((((CYG_ADDRESS)(x)) & ~CYGARC_KSEG_MASK) | CYGARC_KSEG_UNCACHED) |
#define CYGARC_PHYSICAL_ADDRESS(x) (((CYG_ADDRESS)(x)) & ~CYGARC_KSEG_MASK) |
#else // __ASSEMBLER__ |
#define CYGARC_CACHED_ADDRESS(x) ((((x)) & ~CYGARC_KSEG_MASK) | CYGARC_KSEG_CACHED) |
#define CYGARC_UNCACHED_ADDRESS(x) ((((x)) & ~CYGARC_KSEG_MASK) | CYGARC_KSEG_UNCACHED) |
#define CYGARC_PHYSICAL_ADDRESS(x) (((x)) & ~CYGARC_KSEG_MASK) |
#define CYGARC_ADDRESS_REG_CACHED(reg) \ |
and reg, reg, ~CYGARC_KSEG_MASK; \ |
or reg, reg, CYGARC_KSEG_CACHED |
#define CYGARC_ADDRESS_REG_UNCACHED(reg) \ |
and reg, reg, ~CYGARC_KSEG_MASK; \ |
or reg, reg, CYGARC_KSEG_UNCACHED |
#endif /* __ASSEMBLER__ */ |
|
//-------------------------------------------------------------------------- |
// 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() \ |
CYG_MACRO_START \ |
register CYG_ADDRWORD __gp_save; \ |
asm volatile ( "move %0,$28;" \ |
".extern _gp;" \ |
"la $gp,_gp;" \ |
: "=r"(__gp_save)) |
|
#define CYGARC_HAL_RESTORE_GP() \ |
asm volatile ( "move $gp,%0;" :: "r"(__gp_save) ); \ |
CYG_MACRO_END |
|
|
//-------------------------------------------------------------------------- |
// Macro for finding return address. |
#define CYGARC_HAL_GET_RETURN_ADDRESS(_x_, _dummy_) \ |
asm volatile ( "move %0,$31;" : "=r" (_x_) ) |
|
#define CYGARC_HAL_GET_RETURN_ADDRESS_BACKUP(_dummy_) |
|
//-------------------------------------------------------------------------- |
#endif // CYGONCE_HAL_HAL_ARCH_H |
// End of hal_arch.h |
/v2_0/include/mips_opcode.h
0,0 → 1,295
/*- |
* Copyright (c) 1992 The Regents of the University of California. |
* All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Ralph Campbell. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* from: @(#)mips_opcode.h 7.1 (Berkeley) 3/19/92 |
* via: mips_opcode.h,v 1.1 1994/03/10 16:15:10 (algorithmics) |
*/ |
|
/* |
* Define the instruction formats and opcode values for the |
* MIPS instruction set. |
*/ |
|
#ifndef _MIPS_OPCODE_H |
#define _MIPS_OPCODE_H |
|
/* |
* Define the instruction formats. |
*/ |
typedef union { |
unsigned word; |
|
#ifdef MIPSEL |
struct { |
unsigned imm: 16; |
unsigned rt: 5; |
unsigned rs: 5; |
unsigned op: 6; |
} IType; |
|
struct { |
unsigned target: 26; |
unsigned op: 6; |
} JType; |
|
struct { |
unsigned func: 6; |
unsigned shamt: 5; |
unsigned rd: 5; |
unsigned rt: 5; |
unsigned rs: 5; |
unsigned op: 6; |
} RType; |
|
struct { |
unsigned func: 6; |
unsigned fd: 5; |
unsigned fs: 5; |
unsigned ft: 5; |
unsigned fmt: 4; |
unsigned : 1; /* always '1' */ |
unsigned op: 6; /* always '0x11' */ |
} FRType; |
#else |
struct { |
unsigned op: 6; |
unsigned rs: 5; |
unsigned rt: 5; |
unsigned imm: 16; |
} IType; |
|
struct { |
unsigned op: 6; |
unsigned target: 26; |
} JType; |
|
struct { |
unsigned op: 6; |
unsigned rs: 5; |
unsigned rt: 5; |
unsigned rd: 5; |
unsigned shamt: 5; |
unsigned func: 6; |
} RType; |
|
struct { |
unsigned op: 6; /* always '0x11' */ |
unsigned : 1; /* always '1' */ |
unsigned fmt: 4; |
unsigned func: 6; |
unsigned ft: 5; |
unsigned fs: 5; |
unsigned fd: 5; |
} FRType; |
#endif |
} InstFmt; |
|
/* |
* Values for the 'op' field. |
*/ |
#define OP_SPECIAL 000 |
#define OP_REGIMM 001 |
#define OP_J 002 |
#define OP_JAL 003 |
#define OP_BEQ 004 |
#define OP_BNE 005 |
#define OP_BLEZ 006 |
#define OP_BGTZ 007 |
|
#define OP_ADDI 010 |
#define OP_ADDIU 011 |
#define OP_SLTI 012 |
#define OP_SLTIU 013 |
#define OP_ANDI 014 |
#define OP_ORI 015 |
#define OP_XORI 016 |
#define OP_LUI 017 |
|
#define OP_COP0 020 |
#define OP_COP1 021 |
#define OP_COP2 022 |
#define OP_BEQL 024 |
#define OP_BNEL 025 |
#define OP_BLEZL 026 |
#define OP_BGTZL 027 |
|
#define OP_DADDI 030 |
#define OP_DADDIU 031 |
#define OP_LDL 032 |
#define OP_LDR 033 |
|
#define OP_LB 040 |
#define OP_LH 041 |
#define OP_LWL 042 |
#define OP_LW 043 |
#define OP_LBU 044 |
#define OP_LHU 045 |
#define OP_LWR 046 |
#define OP_LWU 047 |
|
#define OP_SB 050 |
#define OP_SH 051 |
#define OP_SWL 052 |
#define OP_SW 053 |
#define OP_SDL 054 |
#define OP_SDR 055 |
#define OP_SWR 056 |
#define OP_CACHE 057 |
|
#define OP_LL 060 |
#define OP_LWC1 061 |
#define OP_LWC2 062 |
#define OP_LLD 064 |
#define OP_LDC1 065 |
#define OP_LDC2 066 |
#define OP_LD 067 |
|
#define OP_SC 070 |
#define OP_SWC1 071 |
#define OP_SWC2 072 |
#define OP_SCD 074 |
#define OP_SDC1 075 |
#define OP_SDC2 076 |
#define OP_SD 077 |
|
/* |
* Values for the 'func' field when 'op' == OP_SPECIAL. |
*/ |
#define OP_SLL 000 |
#define OP_SRL 002 |
#define OP_SRA 003 |
#define OP_SLLV 004 |
#define OP_SRLV 006 |
#define OP_SRAV 007 |
|
#define OP_JR 010 |
#define OP_JALR 011 |
#define OP_SYSCALL 014 |
#define OP_BREAK 015 |
#define OP_SYNC 017 |
|
#define OP_MFHI 020 |
#define OP_MTHI 021 |
#define OP_MFLO 022 |
#define OP_MTLO 023 |
#define OP_DSLLV 024 |
#define OP_DSRLV 026 |
#define OP_DSRAV 027 |
|
#define OP_MULT 030 |
#define OP_MULTU 031 |
#define OP_DIV 032 |
#define OP_DIVU 033 |
#define OP_DMULT 034 |
#define OP_DMULTU 035 |
#define OP_DDIV 036 |
#define OP_DDIVU 037 |
|
#define OP_ADD 040 |
#define OP_ADDU 041 |
#define OP_SUB 042 |
#define OP_SUBU 043 |
#define OP_AND 044 |
#define OP_OR 045 |
#define OP_XOR 046 |
#define OP_NOR 047 |
|
#define OP_SLT 052 |
#define OP_SLTU 053 |
#define OP_DADD 054 |
#define OP_DADDU 055 |
#define OP_DSUB 056 |
#define OP_DSUBU 057 |
|
#define OP_TGE 060 |
#define OP_TGEU 061 |
#define OP_TLT 062 |
#define OP_TLTU 063 |
#define OP_TEQ 064 |
#define OP_TNE 066 |
|
#define OP_DSLL 070 |
#define OP_DSRL 072 |
#define OP_DSRA 073 |
#define OP_DSLL32 074 |
#define OP_DSRL32 076 |
#define OP_DSRA32 077 |
|
/* |
* Values for the 'func' field when 'op' == OP_REGIMM. |
*/ |
#define OP_BLTZ 000 |
#define OP_BGEZ 001 |
#define OP_BLTZL 002 |
#define OP_BGEZL 003 |
|
#define OP_TGEI 010 |
#define OP_TGEIU 011 |
#define OP_TLTI 012 |
#define OP_TLTIU 013 |
#define OP_TEQI 014 |
#define OP_TNEI 016 |
|
#define OP_BLTZAL 020 |
#define OP_BGEZAL 021 |
#define OP_BLTZALL 022 |
#define OP_BGEZALL 023 |
|
/* |
* Values for the 'rs' field when 'op' == OP_COPz. |
*/ |
#define OP_MF 000 |
#define OP_DMF 001 |
#define OP_CF 002 |
#define OP_MT 004 |
#define OP_DMT 005 |
#define OP_CT 006 |
#define OP_BC 010 |
|
/* |
* Values for the 'rt' field when 'op' == OP_COPz and 'rt' == OP_BC. |
*/ |
#define COPz_BCF 0x00 |
#define COPz_BCT 0x01 |
#define COPz_BCFL 0x02 |
#define COPz_BCTL 0x03 |
|
/* |
* Instructions with specal significance to debuggers. |
*/ |
#define BREAK_INSTR 0x0005000d /* instruction code for break */ |
#define NOP_INSTR 0x00000000 /* instruction code for no-op */ |
|
#endif /* _MIPS_OPCODE_H */ |
/v2_0/include/mips-stub.h
0,0 → 1,194
#ifndef CYGONCE_HAL_MIPS_STUB_H |
#define CYGONCE_HAL_MIPS_STUB_H |
//======================================================================== |
// |
// mips-stub.h |
// |
// MIPS-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, nickg |
// Contributors: Red Hat, nickg, dmoseley |
// Date: 1998-06-08 |
// Purpose: |
// Description: MIPS-specific definitions for generic stub |
// Usage: |
// |
//####DESCRIPTIONEND#### |
// |
//======================================================================== |
|
|
#include <pkgconf/system.h> |
#include <pkgconf/hal_mips.h> |
|
#include <cyg/hal/hal_io.h> |
|
#ifdef __cplusplus |
extern "C" { |
#endif |
|
#if defined(CYGPKG_HAL_MIPS_GDB_REPORT_CP0) |
#define NUMREGS 107 |
#else |
#define NUMREGS 90 |
#endif |
|
#if defined(__mips64) |
// The simple case of 64-bit regs represented to GDB as 64-bit regs. |
|
#define REGSIZE(X) 8 |
typedef unsigned long long target_register_t; |
|
# ifdef CYGINT_HAL_MIPS_STUB_REPRESENT_32BIT_AS_64BIT |
# error __mips64 & CYGINT_HAL_MIPS_STUB_REPRESENT_32BIT_AS_64BIT |
# endif |
|
#elif defined(CYGINT_HAL_MIPS_STUB_REPRESENT_32BIT_AS_64BIT) |
|
// This is a catch-all for the common case: |
// Even though we are only working with 32 bit registers, GDB expects 64 bits |
#define REGSIZE(X) 8 |
typedef unsigned long target_register_t; |
// We need to sign-extend the registers so GDB doesn't get confused. |
#define CYGARC_SIGN_EXTEND_REGISTERS |
|
// The following platform-specific cases can be removed as/when/if they |
// get modified to implement CYGINT_HAL_MIPS_STUB_REPRESENT_32BIT_AS_64BIT |
|
#elif defined(CYGPKG_HAL_MIPS_VR4300) |
// Even though we are only working with 32 bit registers, GDB expects 64 bits |
#define REGSIZE(X) 8 |
typedef unsigned long long target_register_t; |
// We need to sign-extend the registers so GDB doesn't get confused. |
#define CYGARC_SIGN_EXTEND_REGISTERS |
#elif defined(CYGPKG_HAL_MIPS_TX49) |
// Even though we are only working with 32 bit registers, GDB expects 64 bits |
#define REGSIZE(X) 8 |
typedef unsigned long target_register_t; |
|
// We need to sign-extend the registers so GDB doesn't get confused. |
#define CYGARC_SIGN_EXTEND_REGISTERS |
#elif defined(CYGPKG_HAL_MIPS_RM7000) |
// Even though we are only working with 32 bit registers, GDB expects 64 bits |
#define REGSIZE(X) 8 |
typedef unsigned long target_register_t; |
|
// We need to sign-extend the registers so GDB doesn't get confused. |
#define CYGARC_SIGN_EXTEND_REGISTERS |
#elif 0 //defined(CYGPKG_HAL_MIPS_MIPS32) |
// Even though we are only working with 32 bit registers, GDB expects 64 bits |
#define REGSIZE(X) 8 |
typedef unsigned long target_register_t; |
|
// We need to sign-extend the registers so GDB doesn't get confused. |
#define CYGARC_SIGN_EXTEND_REGISTERS |
#else |
|
// The simplest case of 32-bit regs represented to GDB as 32-bit regs. |
#define REGSIZE(X) 4 |
typedef unsigned long target_register_t; |
#endif |
|
enum regnames { |
REG_ZERO, REG_AT, REG_V0, REG_V1, REG_A0, REG_A1, REG_A2, REG_A3, |
REG_T0, REG_T1, REG_T2, REG_T3, REG_T4, REG_T5, REG_T6, REG_T7, |
REG_S0, REG_S1, REG_S2, REG_S3, REG_S4, REG_S5, REG_S6, REG_S7, |
REG_T8, REG_T9, REG_K0, REG_K1, REG_GP, REG_SP, REG_S8, REG_RA, |
REG_SR, REG_LO, REG_HI, REG_BAD, REG_CAUSE, REG_PC, |
REG_CONFIG = 84, REG_CACHE, REG_DEBUG, REG_DEPC, REG_EPC |
}; |
#define USE_LONG_NAMES_FOR_ENUM_REGNAMES |
|
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. */ |
#if !defined(SET_PC_PROTOTYPE_EXISTS) && !defined(set_pc) |
#define SET_PC_PROTOTYPE_EXISTS |
extern void set_pc (target_register_t pc); |
#endif |
|
/* 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 __single_step |
void __single_step (void); |
#endif |
|
/* Clear the single-step state. */ |
void __clear_single_step (void); |
|
extern int __is_bsp_syscall(void); |
|
extern int hal_syscall_handler(void); |
|
/* If the breakpoint we hit is in the breakpoint() instruction, return a |
non-zero value. */ |
#ifndef __is_breakpoint_function |
extern int __is_breakpoint_function (void); |
#endif |
|
/* Skip the current instruction. */ |
extern void __skipinst (void); |
|
extern void __install_breakpoints (void); |
|
extern void __clear_breakpoints (void); |
|
extern void __install_breakpoint_list (void); |
|
extern void __clear_breakpoint_list (void); |
|
#ifdef __cplusplus |
} /* extern "C" */ |
#endif |
|
#endif // ifndef CYGONCE_HAL_MIPS_STUB_H |
/v2_0/include/mips-regs.h
0,0 → 1,323
#ifndef CYGONCE_HAL_MIPS_REGS_H |
#define CYGONCE_HAL_MIPS_REGS_H |
//======================================================================== |
// |
// mips-regs.h |
// |
// Register defines for MIPS 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, nickg |
// Contributors: Red Hat, nickg, dmoseley |
// Date: 1998-06-08 |
// Purpose: |
// Description: Register defines for MIPS processors |
// Usage: |
// |
//####DESCRIPTIONEND#### |
// |
//======================================================================== |
|
#include <pkgconf/hal.h> |
|
#ifdef CYGARC_HAL_COMMON_EXPORT_CPU_MACROS |
|
/* This value must agree with NUMREGS in mips-stub.h. */ |
|
#if defined(CYGPKG_HAL_MIPS_GDB_REPORT_CP0) |
#define NUM_REGS 107 |
#else |
#define NUM_REGS 90 |
#endif |
|
#ifdef __mips64 |
#define REG_SIZE 8 |
#else |
#define REG_SIZE 4 |
#endif |
|
/* General register names for assembly code. */ |
|
#define zero $0 |
#define at $1 /* assembler temporary */ |
#define atmp $1 /* assembler temporary */ |
#define v0 $2 /* value holders */ |
#define v1 $3 |
#define a0 $4 /* arguments */ |
#define a1 $5 |
#define a2 $6 |
#define a3 $7 |
#define t0 $8 /* temporaries */ |
#define t1 $9 |
#define t2 $10 |
#define t3 $11 |
#define t4 $12 |
#define t5 $13 |
#define t6 $14 |
#define t7 $15 |
#define s0 $16 /* saved registers */ |
#define s1 $17 |
#define s2 $18 |
#define s3 $19 |
#define s4 $20 |
#define s5 $21 |
#define s6 $22 |
#define s7 $23 |
#define t8 $24 /* temporaries */ |
#define t9 $25 |
#define k0 $26 /* kernel registers */ |
#define k1 $27 |
#define gp $28 /* global pointer */ |
#define sp $29 /* stack pointer */ |
#define s8 $30 /* saved register */ |
#define fp $30 /* frame pointer (obsolete usage) */ |
#define ra $31 /* return address */ |
|
/* MIPS registers, numbered in the order in which gdb expects to see them. */ |
#define ZERO 0 |
#define AT 1 |
#define ATMP 1 |
#define V0 2 |
#define V1 3 |
#define A0 4 |
#define A1 5 |
#define A2 6 |
#define A3 7 |
|
#define T0 8 |
#define T1 9 |
#define T2 10 |
#define T3 11 |
#define T4 12 |
#define T5 13 |
#define T6 14 |
#define T7 15 |
|
#define S0 16 |
#define S1 17 |
#define S2 18 |
#define S3 19 |
#define S4 20 |
#define S5 21 |
#define S6 22 |
#define S7 23 |
|
#define T8 24 |
#define T9 25 |
#define K0 26 |
#define K1 27 |
#define GP 28 |
#define SP 29 |
#define S8 30 |
#define RA 31 |
|
#define SR 32 |
#define LO 33 |
#define HI 34 |
#define BAD_VA 35 |
#define CAUSE 36 |
#define PC 37 |
|
#define F0 38 |
#define F1 39 |
#define F2 40 |
#define F3 41 |
#define F4 42 |
#define F5 43 |
#define F6 44 |
#define F7 45 |
#define F8 46 |
#define F9 47 |
#define F10 48 |
#define F11 49 |
#define F12 50 |
#define F13 51 |
#define F14 52 |
#define F15 53 |
#define F16 54 |
#define F17 55 |
#define F18 56 |
#define F19 57 |
#define F20 58 |
#define F21 59 |
#define F22 60 |
#define F23 61 |
#define F24 62 |
#define F25 63 |
#define F26 64 |
#define F27 65 |
#define F28 66 |
#define F29 67 |
#define F30 68 |
#define F31 69 |
|
#define FCR31 70 |
|
/* System Control Coprocessor (CP0) exception processing registers */ |
#define C0_CONTEXT $4 /* Context */ |
#define C0_BADVADDR $8 /* Bad Virtual Address */ |
#define C0_COUNT $9 /* Count */ |
#define C0_COMPARE $11 /* Compare */ |
#define C0_STATUS $12 /* Processor Status */ |
#define C0_CAUSE $13 /* Exception Cause */ |
#define C0_EPC $14 /* Exception PC */ |
#define C0_WATCHLO $18 /* Watchpoint LO */ |
#define C0_WATCHHI $19 /* Watchpoint HI */ |
#define C0_XCONTEXT $20 /* XContext */ |
#define C0_ECC $26 /* ECC */ |
#define C0_CACHEERR $27 /* CacheErr */ |
#define C0_ERROREPC $30 /* ErrorEPC */ |
|
/* Status register fields */ |
#define SR_CUMASK 0xf0000000 /* Coprocessor usable bits */ |
#define SR_CU3 0x80000000 /* Coprocessor 3 usable */ |
#define SR_CU2 0x40000000 /* coprocessor 2 usable */ |
#define SR_CU1 0x20000000 /* Coprocessor 1 usable */ |
#define SR_CU0 0x10000000 /* Coprocessor 0 usable */ |
|
#define SR_FR 0x04000000 /* Enable 32 floating-point registers */ |
#define SR_RE 0x02000000 /* Reverse Endian in user mode */ |
|
#define SR_BEV 0x00400000 /* Bootstrap Exception Vector */ |
#define SR_TS 0x00200000 /* TLB shutdown (reserved on R4600) */ |
#define SR_SR 0x00100000 /* Soft Reset */ |
|
#define SR_CH 0x00040000 /* Cache Hit */ |
#define SR_CE 0x00020000 /* ECC register modifies check bits */ |
#define SR_DE 0x00010000 /* Disable cache errors */ |
|
#define SR_IMASK 0x0000ff00 /* Interrupt Mask */ |
#define SR_IMASK8 0x00000000 /* Interrupt Mask level=8 */ |
#define SR_IMASK7 0x00008000 /* Interrupt Mask level=7 */ |
#define SR_IMASK6 0x0000c000 /* Interrupt Mask level=6 */ |
#define SR_IMASK5 0x0000e000 /* Interrupt Mask level=5 */ |
#define SR_IMASK4 0x0000f000 /* Interrupt Mask level=4 */ |
#define SR_IMASK3 0x0000f800 /* Interrupt Mask level=3 */ |
#define SR_IMASK2 0x0000fc00 /* Interrupt Mask level=2 */ |
#define SR_IMASK1 0x0000fe00 /* Interrupt Mask level=1 */ |
#define SR_IMASK0 0x0000ff00 /* Interrupt Mask level=0 */ |
|
#define SR_IBIT8 0x00008000 /* (Intr5) */ |
#define SR_IBIT7 0x00004000 /* (Intr4) */ |
#define SR_IBIT6 0x00002000 /* (Intr3) */ |
#define SR_IBIT5 0x00001000 /* (Intr2) */ |
#define SR_IBIT4 0x00000800 /* (Intr1) */ |
#define SR_IBIT3 0x00000400 /* (Intr0) */ |
#define SR_IBIT2 0x00000200 /* (Software Interrupt 1) */ |
#define SR_IBIT1 0x00000100 /* (Software Interrupt 0) */ |
|
#define SR_KX 0x00000080 /* xtlb in kernel mode */ |
#define SR_SX 0x00000040 /* mips3 & xtlb in supervisor mode */ |
#define SR_UX 0x00000020 /* mips3 & xtlb in user mode */ |
|
#define SR_KSU_MASK 0x00000018 /* ksu mode mask */ |
#define SR_KSU_USER 0x00000010 /* user mode */ |
#define SR_KSU_SUPV 0x00000008 /* supervisor mode */ |
#define SR_KSU_KERN 0x00000000 /* kernel mode */ |
|
#define SR_ERL 0x00000004 /* error level */ |
#define SR_EXL 0x00000002 /* exception level */ |
#define SR_IE 0x00000001 /* interrupt enable */ |
|
/* Floating-point unit control/status register (FCR31) */ |
#define FCR31_FS 0x01000000 /* Flush denormalized to zero */ |
#define FCR31_C 0x00800000 /* FP compare result */ |
|
#define FCR31_CAUSE_E 0x00020000 /* Cause - unimplemented operation */ |
#define FCR31_CAUSE_V 0x00010000 /* Cause - invalid operation */ |
#define FCR31_CAUSE_Z 0x00008000 /* Cause - division by zero */ |
#define FCR31_CAUSE_O 0x00004000 /* Cause - overflow */ |
#define FCR31_CAUSE_U 0x00002000 /* Cause - underflow */ |
#define FCR31_CAUSE_I 0x00001000 /* Cause - inexact operation */ |
|
#define FCR31_ENABLES_V 0x00000800 /* Enables - invalid operation */ |
#define FCR31_ENABLES_Z 0x00000400 /* Enables - division by zero */ |
#define FCR31_ENABLES_O 0x00000200 /* Enables - overflow */ |
#define FCR31_ENABLES_U 0x00000100 /* Enables - underflow */ |
#define FCR31_ENABLES_I 0x00000080 /* Enables - inexact operation */ |
|
#define FCR31_FLAGS_V 0x00000040 /* Flags - invalid operation */ |
#define FCR31_FLAGS_Z 0x00000020 /* Flags - division by zero */ |
#define FCR31_FLAGS_O 0x00000010 /* Flags - overflow */ |
#define FCR31_FLAGS_U 0x00000008 /* Flags - underflow */ |
#define FCR31_FLAGS_I 0x00000004 /* Flags - inexact operation */ |
|
#define FCR31_RMMASK 0x00000002 /* Rounding mode mask */ |
#define FCR31_RM_RN 0 /* Round to nearest */ |
#define FCR31_RM_RZ 1 /* Round to zero */ |
#define FCR31_RM_RP 2 /* Round to +infinity */ |
#define FCR31_RM_RM 3 /* Round to -infinity */ |
|
|
/* Cause register fields */ |
#define CAUSE_BD 0x80000000 /* Branch Delay */ |
#define CAUSE_CEMASK 0x30000000 /* Coprocessor Error */ |
#define CAUSE_CESHIFT 28 /* Right justify CE */ |
#define CAUSE_IPMASK 0x0000ff00 /* Interrupt Pending */ |
#define CAUSE_IPSHIFT 8 /* Right justify IP */ |
#define CAUSE_IP8 0x00008000 /* (Intr5) */ |
#define CAUSE_IP7 0x00004000 /* (Intr4) */ |
#define CAUSE_IP6 0x00002000 /* (Intr3) */ |
#define CAUSE_IP5 0x00001000 /* (Intr2) */ |
#define CAUSE_IP4 0x00000800 /* (Intr1) */ |
#define CAUSE_IP3 0x00000400 /* (Intr0) */ |
#define CAUSE_SW2 0x00000200 /* (Software Interrupt 1) */ |
#define CAUSE_SW1 0x00000100 /* (Software Interrupt 0) */ |
#define CAUSE_EXCMASK 0x0000007c /* Exception Code */ |
#define CAUSE_EXCSHIFT 2 /* Right justify EXC */ |
|
/* Exception Codes */ |
#define EXC_INT 0 /* External interrupt */ |
#define EXC_MOD 1 /* TLB modification exception */ |
#define EXC_TLBL 2 /* TLB miss (Load or Ifetch) */ |
#define EXC_TLBS 3 /* TLB miss (Store) */ |
#define EXC_ADEL 4 /* Address error (Load or Ifetch) */ |
#define EXC_ADES 5 /* Address error (Store) */ |
#define EXC_IBE 6 /* Bus error (Ifetch) */ |
#define EXC_DBE 7 /* Bus error (data load or store) */ |
#define EXC_SYS 8 /* System call */ |
#define EXC_BP 9 /* Break point */ |
#define EXC_RI 10 /* Reserved instruction */ |
#define EXC_CPU 11 /* Coprocessor unusable */ |
#define EXC_OVF 12 /* Arithmetic overflow */ |
#define EXC_TRAP 13 /* Trap exception */ |
#define EXC_FPE 15 /* Floating Point Exception */ |
|
#endif // ifdef CYGARC_HAL_COMMON_EXPORT_CPU_MACROS |
|
#endif // ifndef CYGONCE_HAL_MIPS_REGS_H |
/v2_0/include/hal_cache.h
0,0 → 1,430
#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): nickg |
// Contributors: nickg |
// Date: 1998-02-17 |
// 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 <pkgconf/hal.h> |
#include <cyg/infra/cyg_type.h> |
|
#include <cyg/hal/var_cache.h> |
|
// Use this macro to allow the assembler to accept "cache" instructions, |
// which are MIPS ISA 3. This is useful if someone is compiling |
// with -mips2, but the architecture is really MIPS ISA 3. |
|
#define _hal_asm_mips_cpp_stringize( _x_ ) #_x_ |
#define _HAL_ASM_SET_MIPS_ISA( _isal_ ) asm volatile ( \ |
".set mips" _hal_asm_mips_cpp_stringize(_isal_) ) |
|
|
//============================================================================= |
// Default Implementation. This uses the standard MIPS CP0 registers and |
// cache instructions. Note that not all variants will have all of the |
// functionality defined here. |
|
//----------------------------------------------------------------------------- |
// Cache dimensions. |
// These really should be defined in var_cache.h. If they are not, then provide |
// a set of numbers that are typical of many variants. |
|
#ifndef HAL_DCACHE_SIZE |
|
// Data cache |
#define HAL_DCACHE_SIZE 4096 // Size of data cache in bytes |
#define HAL_DCACHE_LINE_SIZE 16 // Size of a data cache line |
#define HAL_DCACHE_WAYS 2 // Associativity of the cache |
|
// Instruction cache |
#define HAL_ICACHE_SIZE 4096 // Size of cache in bytes |
#define HAL_ICACHE_LINE_SIZE 16 // Size of a cache line |
#define HAL_ICACHE_WAYS 2 // Associativity of the cache |
|
#define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS)) |
#define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS)) |
|
#endif |
|
//----------------------------------------------------------------------------- |
// Cache instruction uses LSBs or MSBs (depending on the |
// implementation) of the virtual address to specify which WAY to |
// affect. The _ALL_WAYS macro defines the necessary cache instructions |
// to affect all ways. |
|
#ifdef HAL_MIPS_CACHE_INSN_USES_LSB |
# define _IWAY(_n_) ((_n_)*HAL_ICACHE_SIZE/HAL_ICACHE_WAYS+(_n_)) |
# define _DWAY(_n_) ((_n_)*HAL_DCACHE_SIZE/HAL_DCACHE_WAYS+(_n_)) |
#else |
# define _IWAY(_n_) ((_n_)*HAL_ICACHE_SIZE/HAL_ICACHE_WAYS) |
# define _DWAY(_n_) ((_n_)*HAL_DCACHE_SIZE/HAL_DCACHE_WAYS) |
#endif |
|
#if (HAL_DCACHE_WAYS == 1) |
#define _HAL_ASM_DCACHE_ALL_WAYS( _cmd_ , _addr_ ) \ |
asm volatile ("cache %0,0(%1);" \ |
: : "I" ((_cmd_) | 1), "r"(_addr_) ) |
#elif (HAL_DCACHE_WAYS == 2) |
#define _HAL_ASM_DCACHE_ALL_WAYS( _cmd_ , _addr_ ) \ |
asm volatile ("cache %0,0(%1);" \ |
"cache %0,%2(%1);" \ |
: : "I" ((_cmd_) | 1), "r"(_addr_), \ |
"I" (_DWAY(1))) |
#elif (HAL_DCACHE_WAYS == 4) |
#define _HAL_ASM_DCACHE_ALL_WAYS( _cmd_ , _addr_ ) \ |
asm volatile ("cache %0,0(%1);" \ |
"cache %0,%2(%1);" \ |
"cache %0,%3(%1);" \ |
"cache %0,%4(%1);" \ |
: : "I" ((_cmd_) | 1), "r"(_addr_), \ |
"I" (_DWAY(1)), \ |
"I" (_DWAY(2)), \ |
"I" (_DWAY(3))) |
#else |
# error "Unsupported number of ways" |
#endif |
|
#if (HAL_ICACHE_WAYS == 1) |
#define _HAL_ASM_ICACHE_ALL_WAYS( _cmd_ , _addr_ ) \ |
asm volatile ("cache %0,0(%1);" \ |
: : "I" (_cmd_), "r"(_addr_) ) |
#elif (HAL_ICACHE_WAYS == 2) |
#define _HAL_ASM_ICACHE_ALL_WAYS( _cmd_ , _addr_ ) \ |
asm volatile ("cache %0,0(%1);" \ |
"cache %0,%2(%1);" \ |
: : "I" (_cmd_), "r"(_addr_), \ |
"I" (_IWAY(1))) |
#elif (HAL_ICACHE_WAYS == 4) |
#define _HAL_ASM_ICACHE_ALL_WAYS( _cmd_ , _addr_ ) \ |
asm volatile ("cache %0,0(%1);" \ |
"cache %0,%2(%1);" \ |
"cache %0,%3(%1);" \ |
"cache %0,%4(%1);" \ |
: : "I" (_cmd_), "r"(_addr_), \ |
"I" (_IWAY(1)), \ |
"I" (_IWAY(2)), \ |
"I" (_IWAY(3))) |
#else |
# error "Unsupported number of ways" |
#endif |
|
//----------------------------------------------------------------------------- |
// Address adjustment. |
// Given an address and a size, these macros return the first |
// cacheline containing the requested range and a terminating address. |
|
#define HAL_DCACHE_START_ADDRESS(_addr_) \ |
(((CYG_ADDRESS)(_addr_)) & ~(HAL_DCACHE_LINE_SIZE-1)) |
|
#define HAL_DCACHE_END_ADDRESS(_addr_, _asize_) \ |
((CYG_ADDRESS)((_addr_) + (_asize_))) |
|
#define HAL_ICACHE_START_ADDRESS(_addr_) \ |
(((CYG_ADDRESS)(_addr_)) & ~(HAL_ICACHE_LINE_SIZE-1)) |
|
#define HAL_ICACHE_END_ADDRESS(_addr_, _asize_) \ |
((CYG_ADDRESS)((_addr_) + (_asize_))) |
|
//----------------------------------------------------------------------------- |
// Global control of data cache |
|
// Enable the data cache |
// There is no default mechanism for enabling or disabling the caches. |
#ifndef HAL_DCACHE_ENABLE_DEFINED |
#define HAL_DCACHE_ENABLE() |
#endif |
|
// Disable the data cache |
#ifndef HAL_DCACHE_DISABLE_DEFINED |
#define HAL_DCACHE_DISABLE() |
#endif |
|
#ifndef HAL_DCACHE_IS_ENABLED_DEFINED |
#define HAL_DCACHE_IS_ENABLED(_state_) (_state_) = 1; |
#endif |
|
// Invalidate the entire cache |
// We simply use HAL_DCACHE_SYNC() to do this. For writeback caches this |
// is not quite what we want, but there is no index-invalidate operation |
// available. |
#ifndef HAL_DCACHE_INVALIDATE_ALL_DEFINED |
#define HAL_DCACHE_INVALIDATE_ALL() HAL_DCACHE_SYNC() |
#endif |
|
// Synchronize the contents of the cache with memory. |
// This uses the index-writeback-invalidate operation. |
#ifndef HAL_DCACHE_SYNC_DEFINED |
#define HAL_DCACHE_SYNC() \ |
CYG_MACRO_START \ |
register CYG_ADDRESS _baddr_ = 0x80000000; \ |
register CYG_ADDRESS _addr_ = 0x80000000; \ |
register CYG_WORD _size_ = HAL_DCACHE_SIZE; \ |
_HAL_ASM_SET_MIPS_ISA(3); \ |
for( ; _addr_ <= _baddr_+_size_; _addr_ += HAL_DCACHE_LINE_SIZE ) \ |
{ _HAL_ASM_DCACHE_ALL_WAYS(0x01, _addr_); } \ |
_HAL_ASM_SET_MIPS_ISA(0); \ |
CYG_MACRO_END |
#endif |
|
// 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 |
|
// Load the contents of the given address range into the data cache |
// and then lock the cache so that it stays there. |
// This uses the fetch-and-lock cache operation. |
#ifndef HAL_DCACHE_LOCK_DEFINED |
#define HAL_DCACHE_LOCK(_base_, _asize_) \ |
CYG_MACRO_START \ |
register CYG_ADDRESS _addr_ = HAL_DCACHE_START_ADDRESS(_base_); \ |
register CYG_ADDRESS _eaddr_ = HAL_DCACHE_END_ADDRESS(_base_, _asize_); \ |
register CYG_WORD _state_; \ |
HAL_DCACHE_IS_ENABLED( _state_ ); \ |
if( _state_ ) { \ |
_HAL_ASM_SET_MIPS_ISA(3); \ |
for( ; _addr_ < _eaddr_; _addr_ += HAL_DCACHE_LINE_SIZE ) \ |
{ _HAL_ASM_DCACHE_ALL_WAYS(0x1d, _addr_); } \ |
_HAL_ASM_SET_MIPS_ISA(0); \ |
} \ |
CYG_MACRO_END |
#endif |
|
// Undo a previous lock operation. |
// Do this by flushing the cache, which is defined to clear the lock bit. |
#ifndef HAL_DCACHE_UNLOCK_DEFINED |
#define HAL_DCACHE_UNLOCK(_base_, _size_) \ |
HAL_DCACHE_FLUSH( _base_, _size_ ) |
#endif |
|
// Unlock entire cache |
#ifndef HAL_DCACHE_UNLOCK_ALL_DEFINED |
#define HAL_DCACHE_UNLOCK_ALL() \ |
HAL_DCACHE_INVALIDATE_ALL() |
#endif |
|
//----------------------------------------------------------------------------- |
// 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. |
// This uses the hit-writeback-invalidate cache operation. |
#ifndef HAL_DCACHE_FLUSH_DEFINED |
#define HAL_DCACHE_FLUSH( _base_ , _asize_ ) \ |
CYG_MACRO_START \ |
register CYG_ADDRESS _addr_ = HAL_DCACHE_START_ADDRESS(_base_); \ |
register CYG_ADDRESS _eaddr_ = HAL_DCACHE_END_ADDRESS(_base_, _asize_); \ |
register CYG_WORD _state_; \ |
HAL_DCACHE_IS_ENABLED( _state_ ); \ |
if( _state_ ) { \ |
_HAL_ASM_SET_MIPS_ISA(3); \ |
for( ; _addr_ < _eaddr_; _addr_ += HAL_DCACHE_LINE_SIZE ) \ |
{ _HAL_ASM_DCACHE_ALL_WAYS(0x15, _addr_); } \ |
_HAL_ASM_SET_MIPS_ISA(0); \ |
} \ |
CYG_MACRO_END |
#endif |
|
// Invalidate cache lines in the given range without writing to memory. |
// This uses the hit-invalidate cache operation. |
#ifndef HAL_DCACHE_INVALIDATE_DEFINED |
#define HAL_DCACHE_INVALIDATE( _base_ , _asize_ ) \ |
CYG_MACRO_START \ |
register CYG_ADDRESS _addr_ = HAL_DCACHE_START_ADDRESS(_base_); \ |
register CYG_ADDRESS _eaddr_ = HAL_DCACHE_END_ADDRESS(_base_, _asize_); \ |
_HAL_ASM_SET_MIPS_ISA(3); \ |
for( ; _addr_ < _eaddr_; _addr_ += HAL_DCACHE_LINE_SIZE ) \ |
{ _HAL_ASM_DCACHE_ALL_WAYS(0x11, _addr_); } \ |
_HAL_ASM_SET_MIPS_ISA(0); \ |
CYG_MACRO_END |
#endif |
|
// Write dirty cache lines to memory for the given address range. |
// This uses the hit-writeback cache operation. |
#ifndef HAL_DCACHE_STORE_DEFINED |
#define HAL_DCACHE_STORE( _base_ , _asize_ ) \ |
CYG_MACRO_START \ |
register CYG_ADDRESS _addr_ = HAL_DCACHE_START_ADDRESS(_base_); \ |
register CYG_ADDRESS _eaddr_ = HAL_DCACHE_END_ADDRESS(_base_, _asize_); \ |
register CYG_WORD _state_; \ |
HAL_DCACHE_IS_ENABLED( _state_ ); \ |
if( _state_ ) { \ |
_HAL_ASM_SET_MIPS_ISA(3); \ |
for( ; _addr_ < _eaddr_; _addr_ += HAL_DCACHE_LINE_SIZE ) \ |
{ _HAL_ASM_DCACHE_ALL_WAYS(0x19, _addr_); } \ |
_HAL_ASM_SET_MIPS_ISA(0); \ |
} \ |
CYG_MACRO_END |
#endif |
|
// 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_ ) |
|
//----------------------------------------------------------------------------- |
// Global control of Instruction cache |
|
// Enable the instruction cache |
// There is no default mechanism for enabling or disabling the caches. |
#ifndef HAL_ICACHE_ENABLE_DEFINED |
#define HAL_ICACHE_ENABLE() |
#endif |
|
// Disable the instruction cache |
#ifndef HAL_ICACHE_DISABLE_DEFINED |
#define HAL_ICACHE_DISABLE() |
#endif |
|
#ifndef HAL_ICACHE_IS_ENABLED_DEFINED |
#define HAL_ICACHE_IS_ENABLED(_state_) (_state_) = 1; |
#endif |
|
// Invalidate the entire cache |
// This uses the index-invalidate cache operation. |
#ifndef HAL_ICACHE_INVALIDATE_ALL_DEFINED |
#define HAL_ICACHE_INVALIDATE_ALL() \ |
CYG_MACRO_START \ |
register CYG_ADDRESS _baddr_ = 0x80000000; \ |
register CYG_ADDRESS _addr_ = 0x80000000; \ |
_HAL_ASM_SET_MIPS_ISA(3); \ |
for( ; _addr_ < _baddr_+HAL_ICACHE_SIZE; _addr_ += HAL_ICACHE_LINE_SIZE ) \ |
{ _HAL_ASM_ICACHE_ALL_WAYS(0x00, _addr_); } \ |
_HAL_ASM_SET_MIPS_ISA(0); \ |
CYG_MACRO_END |
#endif |
|
// Synchronize the contents of the cache with memory. |
// Simply force the cache to reload. |
#ifndef HAL_ICACHE_SYNC_DEFINED |
#define HAL_ICACHE_SYNC() HAL_ICACHE_INVALIDATE_ALL() |
#endif |
|
// 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. |
// This uses the fetch-and-lock cache operation. |
#ifndef HAL_ICACHE_LOCK_DEFINED |
#define HAL_ICACHE_LOCK(_base_, _asize_) \ |
CYG_MACRO_START \ |
register CYG_ADDRESS _addr_ = HAL_ICACHE_START_ADDRESS(_base_); \ |
register CYG_ADDRESS _eaddr_ = HAL_ICACHE_END_ADDRESS(_base_, _asize_); \ |
register CYG_WORD _state_; \ |
HAL_ICACHE_IS_ENABLED( _state_ ); \ |
if( _state_ ) { \ |
_HAL_ASM_SET_MIPS_ISA(3); \ |
for( ; _addr_ < _eaddr_; _addr_ += HAL_ICACHE_LINE_SIZE ) \ |
{ _HAL_ASM_ICACHE_ALL_WAYS(0x1c, _addr_); } \ |
_HAL_ASM_SET_MIPS_ISA(0); \ |
} \ |
CYG_MACRO_END |
#endif |
|
// Undo a previous lock operation. |
// Do this by invalidating the cache, which is defined to clear the lock bit. |
#ifndef HAL_ICACHE_UNLOCK_DEFINED |
#define HAL_ICACHE_UNLOCK(_base_, _size_) \ |
HAL_ICACHE_INVALIDATE( _base_, _size_ ) |
#endif |
|
// Unlock entire cache |
//#define HAL_ICACHE_UNLOCK_ALL() |
|
//----------------------------------------------------------------------------- |
// Instruction cache line control |
|
// Invalidate cache lines in the given range without writing to memory. |
// This uses the hit-invalidate cache operation. |
#ifndef HAL_ICACHE_INVALIDATE_DEFINED |
#define HAL_ICACHE_INVALIDATE( _base_ , _asize_ ) \ |
CYG_MACRO_START \ |
register CYG_ADDRESS _addr_ = HAL_ICACHE_START_ADDRESS(_base_); \ |
register CYG_ADDRESS _eaddr_ = HAL_ICACHE_END_ADDRESS(_base_, _asize_); \ |
_HAL_ASM_SET_MIPS_ISA(3); \ |
for( ; _addr_ < _eaddr_; _addr_ += HAL_ICACHE_LINE_SIZE ) \ |
{ _HAL_ASM_ICACHE_ALL_WAYS(0x10, _addr_); } \ |
_HAL_ASM_SET_MIPS_ISA(0); \ |
CYG_MACRO_END |
#endif |
|
//----------------------------------------------------------------------------- |
// Check that a supported configuration has actually defined some macros. |
|
#ifndef HAL_DCACHE_ENABLE |
|
#error Unsupported MIPS configuration |
|
#endif |
|
//----------------------------------------------------------------------------- |
#endif // ifndef CYGONCE_HAL_CACHE_H |
// End of hal_cache.h |
/v2_0/ChangeLog
0,0 → 1,1605
2003-02-27 Nick Garnett <nickg@calivar.com> |
|
* include/mips-stub.h: Disabled option that makes MIPS32 targets |
use 64 bit registers in GDB protocol. The standard GDB does not |
support this, only MIPS own version. |
|
2003-01-31 Mark Salter <msalter@redhat.com> |
|
* src/hal_syscall.c (hal_syscall_handler): Let generic syscall code |
handle exit. |
|
2003-01-09 Tim Michals <t.michals@attbi.com> |
|
* src/hal_misc.c (hal_delay_us): Use HAL_CLOCK_READ instead of inline |
asm, to allow for variant/platform HAL packages overriding. |
|
2002-12-12 Bart Veer <bartv@ecoscentric.com> |
|
* include/hal_cache.h: allow for cache flushes etc. where the base |
address is not aligned to a cacheline boundary. |
|
2002-08-02 Andrew Lunn <Andrew.Lunn@ascom.ch> |
|
* cdl/hal_mips.cdl: Redboot exec command can now be disabled |
by CDL |
|
2002-05-17 Jesper Skov <jskov@redhat.com> |
|
* include/hal_intr.h: Fix CYGNUM_HAL_EXCEPTION_MIN definition so |
it reflects the FPU configuration. |
|
2002-04-30 Jesper Skov <jskov@redhat.com> |
|
* include/hal_intr.h: Only define decoded FPU vectors if these are |
actually used. This allows tests to check for capabilities and do |
N/A when appropriate. |
|
2002-04-15 Jonathan Larmour <jlarmour@redhat.com> |
|
* src/hal_syscall.c (hal_syscall_handler): Add extra sig argument to |
__do_syscall. |
|
2002-03-21 Nick Garnett <nickg@redhat.com> |
|
* include/hal_cache.h: Added macros to adjust the size argument to |
some of the cache macros to a whole multiple of the cache line |
size. Otherwise, for some values of the arguments, we can miss the |
last line. |
|
2001-12-17 Jesper Skov <jskov@redhat.com> |
|
* include/hal_arch.h (CYGARC_HAL_GET_RETURN_ADDRESS, |
(CYGARC_HAL_GET_RETURN_ADDRESS_BACKUP): Added dummy arguments. |
|
* src/hal_misc.c (cyg_hal_exception_handler): Fix warning. |
|
2001-12-04 Nick Garnett <nickg@redhat.com> |
|
* src/hal_misc.c: Added hal_arch_program_new_stack() to support |
running user programs on a new stack placed at the top of RAM. |
|
* src/vectors.S: Added hal_program_new_stack function to support |
hal_arch_program_new_stack(). This does the actual stack |
switching. |
|
* include/mips-stub.h (NUMREGS): |
* include/mips-regs.h (NUM_REGS): |
Added test to correctly define these when the target expects the |
CP0 registers to be reported to GDB |
|
* include/hal_arch.h: Added support for fetching CP0 registers in |
MIPS64 platforms for GDB. Reorganized the code slightly. |
|
* cdl/hal_mips.cdl: |
Added define_proc to define HAL_ARCH_PROGRAM_NEW_STACK. |
|
2001-11-16 Nick Garnett <nickg@redhat.com> |
|
* src/hal_misc.c (hal_msbit_index): Fixed this function so that it |
actually works! |
|
2001-10-24 Nick Garnett <nickg@redhat.com> |
|
* src/vectors.S: |
Change behaviour of __default_exception_vsr to only switch to |
interrupt stack if we are not already on it. This is now similar |
to the way the interrupt VSR operates. This is necessary since it |
is possible to take exceptions (such as TLB miss or address error) |
while running in the GDB stubs. |
|
* src/hal_misc.c (cyg_hal_exception_handler): Ensure that PC |
planted when catching stub exceptions gets sign extended where |
necessary in 64 bit platforms. |
|
2001-10-05 Jesper Skov <jskov@redhat.com> |
|
* include/hal_arch.h: Provide CYGARC_CACHED_ADDRESS() and friends |
without casting for use in assembler files. |
|
2001-09-17 Nick Garnett <nickg@redhat.com> |
|
* src/hal_misc.c (hal_delay_us): Rewrote this routine to work |
correctly in higher speed CPUs. The counter register counts at |
half CPU clock speed. The original ticks calculation could |
overflow very easily. For example in a 133MHz CPU, it overflowed |
with any argument greater than 32! This is another of those "how |
did it ever work?" things. |
|
* include/hal_arch.h: Added casts to CYGARC_PHYSICAL_ADDRESS() and |
friends. |
|
2001-09-07 Nick Garnett <nickg@redhat.com> |
|
* include/mips-stub.h: Returned target_register_t to long long |
type for VR4300 target. This is the only platform that does 64bit |
register saves/restores, and the GDB registers must be full sized. |
|
* include/arch.inc: Added option to select correct initial SR |
value when the startup is ROMRAM. |
Disabled setting of status and config registers when using a ROM |
monitor. The monitor should have already set these to appropriate |
values. |
|
2001-08-22 Gary Thomas <gthomas@redhat.com> |
|
* src/redboot_linux_exec.c: |
printf() is no longer a part of RedBoot. Thus all programs |
must use diag_printf() and related functions instead. |
|
2001-08-01 Hugo Tyson <hmt@redhat.com> |
|
* src/vectors.S (restore_state): (see the change below 2001-07-03) |
Make the code to keep SR IM bits from the ISR conditional on a CDL |
interface so that it is selected on a per-platform or variant basis. |
|
* cdl/hal_mips.cdl (CYGINT_HAL_MIPS_INTERRUPT_RETURN_KEEP_SR_IM): |
New interface to control conditional code. |
|
* include/hal_intr.h (HAL_ENABLE_INTERRUPTS): Make this (et al) |
conditional on CYGHWR_HAL_INTERRUPT_ENABLE_DISABLE_RESTORE_DEFINED |
so that the variant HAL can define these insead, in the usual |
manner. |
|
2001-07-20 Jonathan Larmour <jlarmour@redhat.com> |
|
* src/redboot_linux_exec.c: Adjust below change by getting baud |
rate, thus allowing for runtime baud rate changes, and no |
dependency on platform CDL defines. |
|
2001-07-19 Gary Thomas <gthomas@redhat.com> |
|
* src/redboot_linux_exec.c: Define DEFAULT_BAUD. The supporting |
CDL differs from platform to platform, so this define is used to |
ameliorate the differences. |
|
2001-07-17 David Woodhouse <dwmw2@redhat.com> |
|
* src/redboot_linux_exec.c: Add environment stuff to the 'exec' |
command, also make it use the entry point from the last 'load' |
command if there is one. |
Also add '-w' delay option. |
|
2001-07-09 David Woodhouse <dwmw2@redhat.com> |
|
* src/redboot_linux_exec.c: New 'exec' command for RedBoot, mostly |
copied from the SH version, hacked to pass arguments in argc/argv |
form as that seems to be what most Linux/MIPS kernels expect to |
receive from PMON. |
* cdl/hal_mips.cdl: Add necessary magic for the above. |
|
2001-07-03 Hugo Tyson <hmt@redhat.com> |
|
* src/vectors.S (restore_state): When restoring the CPU status |
register right at the end of interrupt processing, keep the |
current settings of the IM[7:0] bits within the status register. |
Depending on platform, these may be used as interrupt masks, so if |
an ISR or DSR masks interrupts they must be preserved. If they |
are not used, then this does no harm. |
#ifdef'd out for CYG_HAL_MIPS_R3900 anyway 'cos the TX39 does not |
use these bits at all. |
|
2001-06-27 Mark Salter <msalter@redhat.com> |
|
* src/vectors.S (_start): Add code to switch from KSEG1 to KSEG0 if |
CYGARC_START_FUNC_UNCACHED. |
|
2001-06-27 Hugo Tyson <hmt@redhat.com> |
|
* src/hal_misc.c: Include <cyg/hal/hal_if.h> for definition of |
hal_ctrlc_isr() and hence warnings reduced. |
|
2001-06-19 Mark Salter <msalter@redhat.com> |
|
* include/hal_arch.h: Support saving/restoring CP0 registers for GDB. |
|
* include/mips-stub.h (NUMREGS): Use different value for mips32. |
|
2001-06-08 Jesper Skov <jskov@redhat.com> |
|
* include/mips.inc (FUNC_START): Added .noreorder. |
|
2001-06-05 Hugo Tyson <hmt@redhat.com> |
|
* include/mips-stub.h: Configuration messing to avoid the need to |
add a platform-specific clause for every new 32-as-64-to-GDB |
target that we make. The header can now pick REGSIZE, |
target_register_t and so on according to a generic define as well |
as specific platform defs. |
|
* cdl/hal_mips.cdl: Provide interface for the above, so targets |
can implement it. CYGINT_HAL_MIPS_STUB_REPRESENT_32BIT_AS_64BIT |
|
2001-02-27 Chris Morrow <cmorrow@YottaYotta.com> |
|
* src/vectors.S (hal_zero_bss): Oops, allow for bss being multiple |
of block size. And add delay slot. |
|
2001-02-26 Chris Morrow <cmorrow@YottaYotta.com> |
|
* src/vectors.S (hal_zero_bss): Implemented in assembler for speed. |
* src/hal_misc.c (hal_zero_bss): Delete. |
|
2001-02-15 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/hal_misc.c: Added option to call hal_ctrlc_isr() in default |
ISR when in RedBoot. |
|
2001-02-12 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/mips.inc: Added some extra CP0 register names. |
|
2001-02-09 Jesper Skov <jskov@redhat.com> |
|
* src/vectors.S: Small tweak of comments to work around tools problem |
with mipsisa32 tools. |
|
2001-01-31 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/mips-stub.h: Added prototypes for __is_bsp_syscall() and |
hal_syscall_handler(). |
|
* include/hal_arch.h: |
Reorganized HAL_SavedRegisters structure to work properly with a |
64 bit processor. Fields are now correctly sized, and aligned on |
the right boundaries. |
|
* include/arch.inc: |
Added option for variant and platform to supply extra bits to be |
added to INITIAL_SR. |
Reorganized register save area layout to match changes in |
hal_arch.h. |
Added macros sva, lva, mvatc0, mvafc0 to transfer 64 bit items to |
and from memory/CP0 (*va* is used because most such values are |
(virtual) addresses). |
|
* src/vectors.S: Added use of *va* macros where appropriate. |
|
* src/mips-stub.c: Added __is_bsp_syscall() function. |
|
* src/hal_syscall.c: Added this file to support GNUPro system |
calls in RedBoot. |
|
* cdl/hal_mips.cdl: Added hal_syscall.c to compile list. |
|
2001-01-26 Jesper Skov <jskov@redhat.com> |
|
* include/hal_intr.h: Added extern for hal_delay_us. |
|
2001-01-26 Jesper Skov <jskov@redhat.com> |
|
* include/variant.inc: Make hal_intc_decode macro mask the cause |
register with the status (interrupt mask) register. |
|
2001-01-25 Jesper Skov <jskov@redhat.com> |
|
* include/arch.inc: Allow hal_intc_decode to be defined by variant |
or platform. |
|
2000-12-06 Jesper Skov <jskov@redhat.com> |
|
* include/hal_intr.h (HAL_DELAY_US): Added. |
* src/hal_misc.c (hal_delay_us): Added. And fixed to work with an |
incrementer that ticks at the pipeline clock rate. |
|
* include/mips-stub.h: RM7000 is also a 64bit CPU. |
|
2000-12-05 Jonathan Larmour <jlarmour@redhat.com> |
|
* include/hal_cache.h: IWAY->_IWAY, DWAY->_DWAY for namespace |
cleanliness |
|
2000-12-05 Jesper Skov <jskov@redhat.com> |
|
* include/hal_cache.h: Use variant specific method to select cache |
WAY. |
|
2000-10-20 Jesper Skov <jskov@redhat.com> |
|
* src/hal_misc.c: Update __mem_fault_handler declaration. |
|
2000-09-15 Jesper Skov <jskov@redhat.com> |
|
* include/hal_intr.h (HAL_DEFAULT_ISR): Fix warning. |
(HAL_DEFAULT_ISR): Undo that change. |
|
2000-09-14 Jesper Skov <jskov@redhat.com> |
|
* include/hal_intr.h: Only define _FPE when there's a FPU. |
|
2000-09-13 Jesper Skov <jskov@redhat.com> |
|
* include/hal_intr.h (HAL_VSR_SET_TO_ECOS_HANDLER): Fix compiler |
warning. |
|
* src/vectors.S: Fully decode TLB related exceptions. |
* src/hal_misc.c (cyg_hal_exception_handler): Undid below change. |
|
* src/hal_misc.c (cyg_hal_exception_handler): Base vector |
calculation on cause register, not the provided vector value. |
|
2000-09-12 Jesper Skov <jskov@redhat.com> |
|
* include/hal_intr.h: Added definition for decoded FPU |
exceptions. |
|
* src/hal_misc.c (cyg_hal_exception_handler): Decode FPU |
exceptions. |
|
2000-09-07 Jesper Skov <jskov@redhat.com> |
|
* include/basetype.h: Removed change from yesterday. |
|
* include/hal_intr.h (CYGNUM_HAL_EXCEPTION_FPU): Associated to FPE |
exceptions. |
|
2000-09-06 Jesper Skov <jskov@redhat.com> |
|
* include/basetype.h: Override the alignment macros for the MIPS |
architecture. The MIPS compiler only alows a maximum of 4 bytes |
of alignment where as the default is 8 |
|
* include/hal_cache.h (_HAL_ASM_DCACHE_ALL_WAYS): Force d-cache |
selection. |
|
2000-09-01 Jonathan Larmour <jlarmour@redhat.com> |
|
* include/mips-stub.h: No longer need to define |
CYGARC_REGSIZE_DIFFERS_FROM_TARGET_REGISTER_T |
(CYGARC_SIGN_EXTEND_REGISTERS): |
|
* include/mips-stub.h: Change vr4300 register sizes to use 32-bit |
target_register_t, and tell the generic stub to use sign extension. |
Ditto for tx49 |
* include/hal_cache.h (_HAL_ASM_SET_MIPS_ISA): Don't use pasting |
when it doesn't result in a preprocessing token. Just use string |
concatenation. |
|
2000-07-21 Drew Moseley <dmoseley@redhat.com> |
|
* src/vectors.S: Only jump uncached to _start if |
CYGARC_START_FUNC_UNCACHED is defined. |
|
2000-07-20 Drew Moseley <dmoseley@redhat.com> |
|
* include/mips-stub.h: Define CYGARC_REGSIZE_DIFFERS_FROM_TARGET_REGISTER_T |
for the MIPS32 targets since GDB needs 64 bit registers regardless of |
what size we are really storing. |
|
2000-07-19 Drew Moseley <dmoseley@redhat.com> |
|
* include/mips-stub.h (CYGARC_SIGN_EXTEND_REGISTERS): Make sure |
the stub sign-extends the registers before returning them to GDB. |
|
2000-07-14 Drew Moseley <dmoseley@redhat.com> |
|
* src/vectors.S: Added hal_reset_vector_first_code and |
hal_early_init macros. |
|
* src/mips-stub.c (__install_breakpoints): Also install any |
breakpoints in the list. |
|
* include/mips-regs.h: Added a few new register definitions. |
|
* include/hal_intr.h: Added CYGNUM_HAL_EXCEPTION_INTERRUPT. |
|
* include/hal_arch.h: Added some macros for jumping between cached |
and uncached. |
|
* include/mips-stub.h: Renamed some enums to work around namespace |
corruption. Added breakpoint support in the HAL. |
|
2000-07-14 Drew Moseley <dmoseley@redhat.com> |
|
* include/arch.inc: Support for mips3264. |
* include/mips-stub.h: Ditto. |
|
2000-06-21 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/mips-stub.c: Removed use of CYG_LABEL_NAME() and added |
underscore to _breakinst. |
|
* include/basetype.h: Removed definition of CYG_LABEL_NAME(). |
|
2000-06-08 Jesper Skov <jskov@redhat.com> |
|
* src/hal_misc.c (hal_arch_default_isr): Removed what's now a |
generic C-c check in the common HAL. |
|
* include/hal_arch.h (CYGARC_HAL_GET_RETURN_ADDRESS): Defined. |
|
2000-06-08 Jesper Skov <jskov@redhat.com> |
|
* include/hal_arch.h (CYGARC_HAL_SAVE_GP, CYGARC_HAL_RESTORE_GP): |
Added. |
|
2000-05-25 Jesper Skov <jskov@redhat.com> |
|
* include/basetype.h: |
* src/mipsfp.c: |
Support FPU double-LE layout in BE mode. |
|
2000-05-24 Jesper Skov <jskov@redhat.com> |
|
* src/mipsfp.c: Also handle doubles in 32bit FPU mode. |
|
2000-05-23 Jesper Skov <jskov@redhat.com> |
|
* include/arch.inc: |
* src/vectors.S: |
Made exception return safe. |
|
2000-05-22 Jesper Skov <jskov@redhat.com> |
|
* src/vectors.S: Call CTRLC init after stub initialization. |
|
* cdl/hal_mips.cdl: Only include CTRLC support if not prevented |
by platform. |
|
* include/hal_cache.h: When using 'cache' instruction, hit all |
ways, not only way0. |
|
2000-05-18 Jesper Skov <jskov@redhat.com> |
|
* include/hal_io.h: Allow platforms to override IO macro |
definitions. |
|
2000-05-16 Jesper Skov <jskov@redhat.com> |
|
* include/hal_intr.h: |
* src/vectors.S: |
Filter 'break 0x7' (GCC division-by-zero) exceptions out into a |
new vector. |
Fix typo. |
|
2000-05-15 Jesper Skov <jskov@redhat.com> |
|
* src/vectors.S: Allow warm-start to be treated like cold-start if |
platform requires it. |
|
2000-05-11 Jesper Skov <jskov@redhat.com> |
|
* include/mips-stub.h: Added register size for TX49. |
|
2000-05-10 Jesper Skov <jskov@redhat.com> |
|
* include/arch.inc: Force assembler into MIPS3 mode before using |
eret. |
|
* include/basetype.h: Fix comments. |
|
2000-03-20 Jonathan Larmour <jlarmour@redhat.co.uk> |
|
* include/mips-stub.h: Make C++ safe |
|
* include/hal_cache.h (_hal_asm_mips_cpp_stringize): Add as a separate |
macro because the compiler has got more picky |
|
2000-03-16 Jonathan Larmour <jlarmour@redhat.co.uk> |
|
* src/vectors.S (_start): Set return address to 0 and unconditionally |
jump to cyg_start, so that GDB doesn't get confused with backtraces |
|
2000-03-13 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/context.S : |
Added jmpbuf_regsize to insulate jumb buffer from changes in |
mips_regsize. This will need extra work if we go to a full 64 bit |
variant, but for now is the simplest solution to this problem. |
|
2000-02-25 Jonathan Larmour <jlarmour@redhat.co.uk> |
|
* include/arch.inc: Add lpc and spc macros to save and restore PC |
* src/context.S (hal_thread_switch_context): Restore RA into PC |
location in context so that thread debugging works |
|
2000-02-23 Jonathan Larmour <jlarmour@redhat.co.uk> |
|
* src/hal_misc.c (hal_idle_thread_action): |
CYG_HAL_MIPS_SIM -> CYGPKG_HAL_MIPS_SIM |
CYG_HAL_MIPS_JMR3904 -> CYGPKG_HAL_MIPS_TX39_JMR3904 |
|
* include/arch.inc: CYG_HAL_MIPS_SIM -> CYGPKG_HAL_MIPS_SIM |
|
2000-02-16 Jesper Skov <jskov@redhat.com> |
|
* cdl/hal_mips.cdl: removed fix me. |
|
2000-01-14 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/hal_arch.h: |
* include/arch.inc: |
* src/vectors.S: |
* src/context.S: |
Several fixes to allow the GPRs to be saved |
and restored as 64 bit values on some architectures. This is not |
full 64 bit support since it only covers the GPRs, HI and LO, |
there is more to be done in the CP0 registers (however it is a |
start). |
|
1999-12-21 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* src/vectors.S (__default_exception_vsr): Rename |
CYG_HAL_USE_ROM_MONITOR_CYGMON -> CYGSEM_HAL_USE_ROM_MONITOR_CygMon |
Rename CYG_HAL_ROM_MONITOR -> CYGSEM_HAL_ROM_MONITOR |
|
* src/hal_misc.c (hal_default_isr): Rename |
CYG_HAL_USE_ROM_MONITOR_CYGMON -> |
CYGSEM_HAL_USE_ROM_MONITOR_CygMon |
|
* include/arch.inc: Rename CYG_HAL_USE_ROM_MONITOR -> |
CYGSEM_HAL_USE_ROM_MONITOR |
|
1999-12-20 John Dallaway <jld@cygnus.co.uk> |
|
* cdl/hal_mips.cdl: |
|
Fix syntax error. |
|
1999-12-17 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* src/mipsfp.c (flt2reg): New inline function to convert between |
float union and register type |
(reg2flt): Likewise in reverse |
(cyg_hal_mips_process_fpe): Handle endianness correctly using the above |
functions. Avoid possible aliasing problems with the compiler. Ensure |
values are zeroed with the correct sign. Check for denormalized operands |
for all remaining FPU opcodes. |
|
* src/hal_misc.c (cyg_hal_exception_handler): Allow handling of |
unimplemented operation FPU exceptions to be configurable |
* include/pkgconf/hal_mips.h: Provide |
CYGSEM_HAL_MIPS_EMULATE_UNIMPLEMENTED_FPU_OPS to do this |
* cdl/hal_mips.cdl: Likewise |
|
All the above required for cases 102817 and 102820 |
|
1999-12-15 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* include/hal_intr.h (CYGNUM_HAL_EXCEPTION_COUNT): Ensure you can |
handle FPU exceptions if present |
Reported in case 102817 |
|
1999-12-02 John Dallaway <jld@cygnus.co.uk> |
|
* cdl/hal_mips.cdl: |
|
Use the <PACKAGE> token in custom rules. |
|
1999-12-01 John Dallaway <jld@cygnus.co.uk> |
|
* cdl/hal_mips.cdl: |
|
Use the <PREFIX> token in custom rules. |
|
1999-11-04 John Dallaway <jld@cygnus.co.uk> |
|
* cdl/hal_mips.cdl: |
|
Output custom rule dependency information to .deps files in |
the current directory. |
|
Dispense with the need to create a 'src' sub-directory. |
|
1999-11-04 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/vectors.S: Added code in reset vector to reset the config0 |
register to a known state. This is because on some MIPS variants |
the K0 field comes up in an undefined state. |
[Later] Moved this code to just work in the case of a cold boot. |
NMIs and warm boots should leave it as it was. |
|
1999-11-02 Jesper Skov <jskov@cygnus.co.uk> |
|
* cdl/hal_mips.cdl: Added. |
|
1999-10-29 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/pkgconf/hal_mips.h: Added condition to set a |
MIPS-private option (CYGDBG_HAL_MIPS_DEBUG_GDB_CTRLC_SUPPORT) if |
either CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT or |
CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT are defined. In the MIPS HAL |
these are implmented with the same code. |
|
* src/hal_misc.c: Changed CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT to |
CYGDBG_HAL_MIPS_DEBUG_GDB_CTRLC_SUPPORT. |
|
* src/vectors.S: Space for old SP after switching to interrupt |
stack must be 8 bytes to preserve alignment of SP. Otherwise any |
nested interrupts or exceptions will get an address error |
exception if the FP regs are saved, which then recurses. |
Changed CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT to |
CYGDBG_HAL_MIPS_DEBUG_GDB_CTRLC_SUPPORT. |
|
* src/mips-stub.c (__is_breakpoint_function): Fixed comparison |
between PC register and label. On 64 bit CPUs these are both 32 |
bit values in 64 bit types, but the way that they are generated, |
the PC is zero extended and the label is sign extended. This |
caused them to always differ. Fixed by casting label to unsigned |
long before widening. |
|
1999-10-22 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/vectors.S: Replaced ifdef with call to hal_intc_translate |
macro so the behaviour here may be customized by variant or |
platform HALs. |
|
* include/arch.inc: Added default implementations of |
hal_intc_translate macro. |
|
1999-10-05 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/basetype.h: Made definition of CYG_BYTEORDER dependent |
on definition of CYGPKG_HAL_MIPS_[L|M]SBFIRST. |
|
1999-09-17 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* src/vectors.S (__default_exception_vsr): |
Rename exception_handler()->cyg_hal_exception_handler() |
After all, we will just do a jump rather than a jal into |
cyg_hal_exception_handler() |
(restore_state): Make the change below (by Hugo) be conditional |
on CYG_HAL_USE_ROM_MONITOR_CYGMON. |
Add explanatory comment about the additions for Cygmon |
|
* src/hal_misc.c (hal_default_isr): Use new format HAL_DIAG_IRQ_CHECK() |
and check return code is negative; if so, return |
(cyg_hal_exception_handler): Rename from exception_handler() |
Now return cyg_uint32, but default to returning 0 always |
|
1999-09-16 Hugo Tyson <hmt@cygnus.co.uk> |
|
This set of changes with matching ones in jmr3904 comes from Mark |
Salter's work to make jmr3904 CygMon talk Ethernet. |
|
* src/vectors.S (restore_state): Call CygMon for exceptions or |
unhandled interrupts if CYG_HAL_USE_ROM_MONITOR. This is why the |
return value from the ISR is preserved. Don't fully understand |
this. |
|
* src/hal_misc.c (hal_default_isr): Call into hal_diag via |
HAL_DIAG_IRQ_CHECK if it's defined and CYG_HAL_USE_ROM_MONITOR. |
This lets CygMon check for network interrupts &c. |
|
1999-09-09 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/arch.inc: |
Moved code to initialize cache out to variant header since it is |
variant specific. |
|
1999-09-08 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* src/hal_misc.c (exception_handler): Catch exceptions that come from |
within GDB stubs and return if that's what the stubs intend |
|
1999-08-19 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/hal_io.h: Added include of plf_io.h. |
|
1999-08-10 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* src/mipsfp.c (cyg_hal_mips_process_fpe): CYG_REPORT_FUNCNAMETYPE() |
must be first in a C file |
|
1999-07-15 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* include/arch.inc (hal_fpu_save_caller): Save fcr31 first as |
recommended by user's manual |
(hal_fpu_load_caller): Similarly restore fcr31 last |
|
Rename CYG_HAL_MIPS_FSR_INIT to CYG_HAL_MIPS_FCSR_INIT since that's |
closer to its documented name |
|
* include/mips-regs.h: |
Add floating point register definitions, and bitfields/masks for FCR31 |
in particular |
|
* src/mips-stub.c (__single_step): |
Enable FP branch support if the hardware has an FPU. |
|
Change register access to FCR using HAL macro names from mips-regs.h |
|
When comparing branch tests with 0, cast the result of get_register() |
to int so that it works on 64-bit MIPS targets even in 32-bit mode, |
when GDB still insists REG_SIZE must be 8 (in which case negative |
results would otherwise go positive) |
|
* src/mipsfp.c: New file to emulate unimplemented MIPS FP operations |
* src/PKGconf.mak (COMPILE): compile it |
|
* src/hal_misc.c (exception_handler): If we have an FPU and get an FP |
exception, call cyg_hal_mips_process_fpe() from mipsfp.c to process |
it |
|
|
1999-07-09 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* include/mips.inc: |
* include/arch.inc: |
* src/vectors.S: |
Rename "cache" register to "cachectrl" to prevent confusion with |
the "cache" instruction. |
For symmetry therefore also rename mipsreg_cache to mipsreg_cachectrl |
|
* include/arch.inc (hal_cache_init): |
Invalidate caches at startup |
|
* include/hal_cache.h: |
Allow cache invalidation when cache disabled |
Add _HAL_ASM_SET_MIPS_ISA() to allow use of cache macros in code |
compiled with a MIPS ISA below 3 |
|
1999-06-25 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/arch.inc: |
* include/hal_arch.h: |
Added initializer for FPU FSR register. |
|
1999-06-22 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/hal_misc.c (hal_default_isr): When chaining, always try the |
ctrlc ISR, the passed-in vector number can be bogus. |
|
1999-06-18 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/hal_misc.c: |
Added cyg_hal_clock_period variable. |
|
* include/hal_intr.h: |
Modified HAL_CLOCK_LATENCY() macro to do the right thing. |
Added cyg_hal_clock_period variable. |
|
* include/hal_cache.h: Modified implementations of cache macros to |
only do anything if the appropriate cache is enabled. |
|
1999-06-17 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/vectors.S: Added code to discriminate different entry |
conditions to the reset vector. Added code to translate an NMI |
into a standard exception and added a new vector in the VSR table |
for it. |
Made above code not be present in RAM. Tidied away some debug |
code. |
|
1999-06-11 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* src/hal_misc.c: Make sure all symbol addresses are given an |
appropriate type that they won't be relocated relative to $gp |
Fix for CR 100800 |
|
1999-06-10 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/hal_arch.h: Added macros to copy FPU registers between |
HAL and GDB register save states. |
|
1999-06-08 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/vectors.S: Dummy __gccmain did not have a delay slot after |
the "jr ra". |
|
* include/hal_arch.h: Make value of CYGNUM_HAL_STACK_SIZE_TYPICAL |
always be greater than CYGNUM_HAL_STACK_SIZE_MINIMUM. |
|
1999-06-02 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* src/hal_misc.c (cyg_hal_invoke_constructors): |
Rework for new constructor scheme for new compilers. Should work |
with old compilers too. |
|
1999-05-28 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/vectors.S: |
Removed references to CYG_HAL_STARTUP_STUBS. |
Removed some defunct code. |
|
* include/hal_cache.h (HAL_ICACHE_INVALIDATE_ALL): Fixed typo. |
|
1999-05-27 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/vectors.S: |
Move call to hal_diag_intr_start to a more useful place. |
Added a save of the current state pointer to memory for ctrl-c |
support. Ensure that exceptions are enabled before calling the ISR |
to allow breakpoints to function. |
|
* src/mips-stub.c: Imported asynchronous interrupt support from |
libstub/cygmon. |
|
* include/hal_intr.h: Added HAL_DEFAULT_ISR to contain the name of |
the default ISR. |
|
* src/hal_misc.c: Added code to call HAL_CTRLC_ISR to default ISR |
if it is enabled. Added some (disabled) debug code. |
|
* include/hal_cache.h: Added default implementation of |
HAL_DCACHE_IS_ENABLED(). Made use of it in some cache macros. |
Also fixed some typos in some macros. |
|
1999-05-21 Hugo Tyson <hmt@cygnus.co.uk> |
|
* include/hal_intr.h: Define HAL_INTERRUPT_STACK_BASE and |
HAL_INTERRUPT_STACK_TOP so that stack usage macros in |
kernel/.../stackmon.hxx can work. |
|
* src/vectors.S (cyg_interrupt_stack_base): Define this symbol for |
the interrupt stack and its friend for the stack top so that we |
can publish them with nice names. |
|
1999-05-21 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/vectors.S: |
Rationalized use of "at" and "noat" setting. |
Made use of "lar" where necessary. |
|
* src/mips-stub.c (__install_breakpoints): Added cache flushes to |
ensure that the just-set breakpoint is migrated to main memory and |
will be fetched by the instruction cache. |
|
* src/context.S: |
Rationalized use of "at" and "noat" setting. |
|
* include/arch.inc: |
Added initial value for the config0 register and added code to set |
it to hal_cpu_init. |
Added default "lar" macro. |
|
1999-05-16 Gary Thomas <gthomas@cygnus.co.uk> |
|
* include/hal_intr.h (HAL_INTERRUPT_STACK_CALL_PENDING_DSRS): |
Add macro for new DSR handling mechanism (was override of a |
"weak" symbol in kernel). |
|
1999-05-13 Nick Garnett <nickg@cygnus.co.uk> |
The following have been merged from a branch: |
|
1999-05-11 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/hal_arch.h: |
* include/hal_intr.h: |
* include/hal_cache.h: |
* include/arch.inc: |
Changed references to "imp" and "implementation" to "var" and |
"variant" respectively. These are better names for these files and |
functions. |
|
* src/vectors.S: |
Removed or disabled some development/debug code. |
Same imp->var changes as above. |
|
1999-05-06 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/vectors.S: Added call to hal_cpu_except_enable in |
__default_exception_vsr to re-enable nested exceptions. |
|
* src/mips-stub.c: Use _registers[X] rather that register[X] for |
accessing CPU registers, since the former may point to per-thread |
register sets while the latter only refers to the current trap |
register set. |
|
* include/arch.inc: Added hal_cpu_except_enable macro to |
(re-)enable exception processing and disable interrupts. This is |
necessary if we are to allow nested exceptions (like breakpoints |
in exception handlers). |
|
1999-04-29 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/vectors.S: Reenable interrupts while processing exceptions. |
Several temporary kludges to permit us to test ROM code from RAM |
under PMON. |
|
* include/mips.inc: Extended list of CP0 register aliases. |
|
* include/mips-stub.h: The stubs must behave as if we are on a 64 |
bit processor when debugging the VR4300, since that is what GDB |
expects. |
|
* include/arch.inc: Added generic version of hal_cache_init to |
disable kseg0 caching in config0 register. |
|
* include/hal_cache.h: Moved dummy addresses used in index |
operations to 0x80000000, zero caused MMU exceptions. |
Fixed looping bugs in all macros that use them. |
|
1999-04-28 Gary Thomas <gthomas@cygnus.co.uk> |
|
[v1_2_2_beta branch] |
* src/vectors.S: Add dummy "__gccmain()" |
|
1999-04-27 Gary Thomas <gthomas@cygnus.co.uk> |
|
* include/hal_arch.h: Make minimum stack sizes more realistic. |
Also fix size of interrupt stack frame when FPU present. |
|
1999-04-23 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/vectors.S: Added support for floating point register save |
and restore. Fixed hal_interrupt_stack_call_pending_DSRs to use |
hal_cpu_int_merge macro. |
|
* src/context.S: Added support for floating point register save |
and restore. Started some preparations for 64 bit processor |
support. |
|
* include/mips.inc: Added floating point register aliases. Moved |
saved state to arch.inc. |
|
* include/hal_arch.h: Completed support for floating point state |
save and restore. Parameterized GDB support macros a little to |
enable GDB to work properly. |
|
* include/arch.inc: Added support for floating point state save |
and restore. Moved assembler version of saved state layout here |
from mips.inc. |
|
1999-04-22 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/context.S (hal_thread_load_context): Substituted explicit |
code to reload the interrupt enable state with a macro. |
|
* include/hal_cache.h: Removed default implementations of |
HAL_[D/I]CACHE_[EN/DIS]ABLE since these were actually TX39 |
specific. There is aparrently no standard way of implementing |
these function in the MIPS architecture. |
|
* include/mips.inc: Added a comment to point out a TX39-only |
register. |
|
* src/vectors.S: Modified hal_interrupt_stack_call_pending_DSRs() |
to also call DSRs with interrupts enabled. Returns interrupt state |
to original value when finished. |
Use hal_cpu_int_ensable macro in place of explicit code in |
hal_interrupt_stack_call_pending_DSRs(). |
|
1999-04-21 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/arch.inc: Ifdeffed definition of hal_intc_init macro to |
allow it to be defined elsewhere. Added default versions of diag |
macros. |
|
* src/vectors.S: Added some low-level diagnostic macros to show |
HAL events if there is adequate hardware (such as leds). |
Removed interrupt enable/disables in interrupt processing since we |
can now go through a thread switch with interrupts disabled. |
Ifdeffed ISR tables so they can be defined elsewhere. |
Added implementation of hal_interrupt_stack_call_pending_DSRs. |
Added calls to implementation and platform init routines. |
|
* src/hal_misc.c: Many changes to hal_idle_thread_action() to |
print or instrument various CPU registers. Left with code to |
wiggle an led in the idle loop. |
Stripped out TX39 specific code and moved it to plf_misc.c. |
|
* src/context.S: Added code to save and restore the interrupt mask |
state in thread contexts. |
|
* include/hal_intr.h: |
Renamed default interrupts to match the hardware more closely. |
Added ifdef around HAL_TRANSLATE_VECTOR() so it can be made |
platform/variant specific. Added implementation of |
HAL_INTERRUPT_ACKNOWLEDGE(). |
|
* include/hal_arch.h (HAL_THREAD_INIT_CONTEXT): Aligned the |
intitial stack pointer to 16 byte boundary, added an initial value |
for the status register. |
|
* include/arch.inc: Added some nops to eret macros. |
|
1999-04-13 John Dallaway <jld@cygnus.co.uk> |
|
* src/mips.ld: Migrate global MIPS linker script to individual |
MIPS variant directories |
|
1999-04-30 Hugo Tyson <hmt@cygnus.co.uk> |
|
Merge the following changes from the 1.2.1 release branch, |
but without any CDL for CYGDBG_HAL_MIPS_INSTALL_CTRL_C_ISR, |
it is always on. |
|
1999-04-30 Jesper Skov <jskov@cygnus.co.uk> |
* src/hal_misc.c: Added vector decoding to the below. |
1999-04-30 Hugo Tyson <hmt@masala.cygnus.co.uk> |
* src/hal_misc.c (hal_init_ctrlc_intr): Chain onto the old value |
of the ISR when attaching the ctrl-c ISR; this allows chained |
interrupts to work (otherwise a stack-wrecking interrupt loop |
occurs). |
1999-04-29 Hugo Tyson <hmt@cygnus.co.uk> |
* include/pkgconf/hal_tx39.h (CYGDBG_HAL_MIPS_INSTALL_CTRL_C_ISR): |
New config option, on by default. |
* src/hal_misc.c (hal_ctrlc_isr): Enable these features on |
CYGDBG_HAL_MIPS_INSTALL_CTRL_C_ISR new config option. |
|
1999-04-28 Bart Veer <bartv@cygnus.co.uk> |
|
* src/PKGconf.mak: |
Remove the -n argument to tail, it does not appear to be required |
on any supported host and causes problems with some |
implementations of tail. |
|
1999-04-20 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* include/hal_intr.h: Don't sync TRR if platform sim - it doesn't need |
it |
|
* include/pkgconf/hal_tx39.h: |
Allow CYGARC_TX39_PR19846 to override |
CYGHWR_HAL_MIPS_TX3904_TRR_REQUIRES_SYNC so that we can do something |
sensible in the simulators |
|
Related to PR 19846 |
|
1999-04-15 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* src/tx39.ld: Define __bss_end at the end of the BSS |
* src/hal_misc.c (hal_zero_bss): Stop at __bss_end rather than _end |
when clearing BSS |
These fix PR 19750 |
|
1999-04-15 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* src/hal_misc.c: |
* src/vectors.S: |
Separate parts of cyg_hal_invoke_constructors() out into new functions |
cyg_hal_enable_caches() and cyg_hal_debug_init() so that |
cyg_hal_invoke_constructors() can be called again safely if |
necessary |
Related fix to that of PR19642 |
|
1999-04-14 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* src/PKGconf.mak (EXTRAS): Don't generate extras.o here any more |
But do define EXTRAS every time for the linker script |
|
1999-04-13 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* include/hal_intr.h (HAL_CLOCK_READ): |
Add workaround for tx39 bug - needs to sync and wait for the |
write buffer to clear before reading the clock. |
Submitted by akira.yokosawa@toshiba.co.jp |
|
* include/pkgconf/hal_tx39.h |
(CYGHWR_HAL_MIPS_TX3904_TRR_REQUIRES_SYNC): Define this by default |
to implement above |
|
1999-04-12 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* include/hal_intr.h (HAL_VSR_SET_TO_ECOS_HANDLER): Added. |
(HAL_VSR_SET): Cast types to CYG_ADDRESS to prevent warnings |
|
Part of fix for PRs 19731/19607 |
|
1999-04-09 Jesper Skov <jskov@cygnus.co.uk> |
|
* src/mips-stub.c: |
Moved get_register and put_register to hal_stub.c. |
|
1999-04-08 John Dallaway <jld@cygnus.co.uk> |
|
* src/*.ld: Use double underscore substitution for period |
character in SECTION_* macro names (PR 19787) |
|
1999-04-08 John Dallaway <jld@cygnus.co.uk> |
|
* src/*.ld: Revised SECTION_* macro arguments to |
avoid padded output sections (PR 19787) |
|
1999-03-31 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/hal_cache.h: Added include of hal.h and a test that a |
valid set of macros have been added. |
Also moved address used in HAL_DCACHE_INVALIDATE_ALL() to |
0x9fc00000, which is the cached ROM space. |
|
1999-03-24 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/vectors.S: |
Added options to allow different settings for DRAM initialization. |
Fixed some ifdef bugs. |
|
* src/hal_misc.c (cyg_hal_invoke_constructors): |
Added ifdefs to control enabling and disabling of timeout |
exceptions. |
|
* include/pkgconf/hal_tx39.h: |
Added translations from the user friendly CPU speed settings into |
the real CPU frequencies in Hz. |
|
* include/hal_intr.h: |
Added HAL_TX39_DEBUG_TOE_ENABLE() and ...DISABLE, to switch |
timeout exceptions on and off. |
|
1999-03-23 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/hal_arch.h: |
Modified stack size definitions to be more accurate. |
|
1999-03-22 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* include/mips-regs.h: Update copyright |
|
* include/mips-stub.h: Update copyright |
|
* src/mips-stub.c: Update copyright |
|
1999-03-22 Hugo Tyson <hmt@cygnus.co.uk> |
|
* include/hal_arch.h: |
Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of |
CYGNUM_HAL_MINIMUM_STACK_SIZE. |
|
1999-03-17 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* src/hal_misc.c (cyg_hal_user_break): Remove #warning - it doesn't |
really provide any useful info, and may unnecessarily worry a user |
since it fires in normal situations |
|
1999-03-17 John Dallaway <jld@cygnus.co.uk> |
|
* src/PKGconf.mak: Remove dependence on echo '-e' switch. |
|
1999-03-16 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/vectors.S: Removed definition of idle thread stack. |
|
1999-03-15 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/hal_cache.h: |
Changed implementation of HAL_DCACHE_INVALIDATE_ALL() to read from |
ROM space rather than RAM. This fixes PR 19510. |
|
1999-03-12 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/vectors.S: Modified ROMC and SCS settings in line with |
Toshiba's suggestions for compatibility with other CPU variants. |
|
1999-03-12 Gary Thomas <gthomas@cygnus.co.uk> |
|
* include/hal_arch.h: Add definition for 'CYGNUM_HAL_MINIMUM_STACK_SIZE' |
|
1999-03-11 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/hal_misc.c: |
Disabled use of stand-alone ^C detection interrupt. This is now |
done in the serial driver. Added cyg_hal_is_break() and |
cyg_hal_user_break() to detect and provoke ^C processing. These |
are used by the serial driver and will one day interact with the |
BSP/Cygmon/GDB stubs to do the right thing. |
|
1999-03-10 Jesper Skov <jskov@cygnus.co.uk> |
|
* include/hal_intr.h (HAL_INTERRUPT_IN_USE): Added. |
|
1999-03-10 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/pkgconf/hal_tx39.h: |
* src/vectors.S: |
Changed names used to control CPU frequency into something more |
generic. Moved definition into hal_tx39.h from hal_tx39_jmr3904.h. |
|
1999-03-09 Jesper Skov <jskov@cygnus.co.uk> |
PR 19370 |
* src/hal_misc.c (cyg_hal_invoke_constructors): Changed |
constructor loop. |
|
1999-03-05 Gary Thomas <gthomas@cygnus.co.uk> |
|
* src/tx39.ld: |
* src/PKGconf.mak: Clean up I/O package changes. |
|
1999-03-04 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* src/tx39.ld: |
Add INPUT(libextras.a), include libextras.a in GROUP() and include |
new __DEVTAB__ section for new device drivers |
|
1999-02-25 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/vectors.S: |
Changed label used to access scheduler lock to one that is not |
mangled by C++. This is intended to make support for interrupt |
handling in non-kernel configurations easier. |
Added some code to initialize DRAM in ROM-only configurations. |
|
1999-02-23 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/hal_misc.c: |
Added support for SIGINT-causing magic breakpoint. This involves |
passing a third, hidden argument to hal_ctrlc_isr() which is a |
pointer to the saved CPU state. |
|
* src/vectors.S: |
Added support for 66MHz part (untested). |
Added support for SIGINT-causing magic breakpoint to allow |
continuation after ^C. This also relies on CYGMON changes. |
|
1999-02-20 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* include/hal_arch.h: |
Rename deliver_exception() -> cyg_hal_deliver_exception() |
QA improvements |
|
* include/hal_intr.h: |
Reorganise vector/interrupt/exception names according to purpose |
QA improvements |
|
* src/hal_misc.c: |
Rename deliver_exception() -> cyg_hal_deliver_exception() |
Rename CYG_VECTOR_SIO_0 -> CYGNUM_HAL_INTERRUPT_SIO_0 |
|
1999-02-16 Jesper Skov <jskov@cygnus.co.uk> |
|
* src/vectors.S: Added call to initialize_stub. |
|
* src/mips-stub.c: |
* include/mips-stub.h: |
Cleaned up to only include arch specific stub code. |
|
* include/hal_arch.h (HAL_BREAKPOINT): Added SIM breakpoint code |
from (now dead) jmr3904/.../hal_stub.c. |
|
1999-02-05 John Dallaway <jld@cygnus.co.uk> |
|
* src/mips.ld: Rename to tx39.ld since this is the target name |
* src/PKGconf.mak: Process tx39.ld instead of mips.ld |
|
1999-02-05 John Dallaway <jld@cygnus.co.uk> |
|
* src/mips.ld: Add LMA_EQ_VMA macro definition. |
|
1999-02-03 Jesper Skov <jskov@cygnus.co.uk> |
|
* src/hal_misc.c: |
* include/hal_cache.h: |
Moved nested external declarations into top-level scope to avoid |
compiler warnings. |
|
1999-02-02 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/hal_cache.h : |
In HAL_ICACHE_INVALIDATE_ALL() and HAL_ICACHE_INVALIDATE(), fixed |
typos in passing arguments to asm sections. |
Fixes PR 18951. |
|
1999-01-26 Hugo Tyson <hmt@masala.cygnus.co.uk> |
|
* src/mips.ld: |
Add copyright notice. (Though these files will later be generated |
by a tool and so not copyright, these default setups are.) |
|
1999-01-21 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* src/hal_misc.c (cyg_hal_invoke_constructors): |
Add code to deal with CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG |
Tidy up and update description header |
Shorten needlessly long lines |
Remove all traces of non-CYG_KERNEL_USE_INIT_PRIORITY code |
|
1999-01-15 Hugo Tyson <hmt@cygnus.co.uk> |
|
* src/mips.ld: |
Provide alternate definition of macro SECTION_rom_vectors() for |
RAM startup (CYG_HAL_STARTUP_RAM) so that minimal sim testing |
works. Note: this is an instance where two definitions (of |
identical "API") of a macro occur in the prototype <target>.ld |
file; the MLT is required not to be confused by this. |
|
1999-01-15 John Dallaway <jld@cygnus.co.uk> |
|
* src/mips.ld: add section macro for .vsr_table |
|
1999-01-13 John Dallaway <jld@cygnus.co.uk> |
|
* src/mips.ld: add section macro for .rel.dyn |
|
1999-01-13 John Dallaway <jld@cygnus.co.uk> |
|
* src/mips.ld: new linker script for MLT |
* src/PKGconf.mak: add mips.ld rules for MLT |
|
1999-01-13 Gary Thomas <gthomas@cygnus.co.uk> |
|
* include/basetype.h: CYG_DOUBLE_BYTEORDER now in <infra/cyg_type.h> |
|
1999-01-12 Gary Thomas <gthomas@cygnus.co.uk> |
|
* include/basetype.h (CYG_DOUBLE_BYTEORDER): Define ordering |
for words within doubles. |
|
1999-01-12 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/hal_cache.h: |
Modified HAL_DCACHE_INVALIDATE_ALL() to correctly touch all cache |
lines twice to ensure that the cache and memory are |
consistent. This is the best we can do without direct support for |
invalidation. |
|
* src/hal_misc.c: Altered call to patch_dbg_syscalls() to pass |
pointer to base of vector rather than a single vector entry. |
|
1998-12-15 Jesper Skov <jskov@cygnus.co.uk> |
PR 18543 |
|
* include/hal_cache.h (HAL_DCACHE_INVALIDATE): Fixed variable |
name. |
|
1998-12-15 Jesper Skov <jskov@cygnus.co.uk> |
|
* include/hal_arch.h: |
* src/context.S (hal_setjmp, hal_longjump): |
Added CYGARC definitions for jmpbuf entries. |
Corrected jmpbuf size. |
|
1998-12-10 Jesper Skov <jskov@cygnus.co.uk> |
|
* include/hal_cache.h (HAL_DCACHE_UNLOCK_ALL, |
HAL_ICACHE_UNLOCK_ALL): Added. |
|
1998-11-26 Jesper Skov <jskov@cygnus.co.uk> |
|
* include/mips-regs.h: |
* src/mips-stub.c: |
Added use of CYGARC_HAL_COMMON_EXPORT_CPU_MACROS. |
|
1998-11-18 Gary Thomas <gthomas@cygnus.co.uk> |
|
* include/hal_intr.h: Add support for interrupt latency |
measurements, controlled by CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY. |
|
1998-10-27 Jesper Skov <jskov@cygnus.co.uk> |
PR 18033 |
|
* include/hal_intr.h: Replaced CYGIMP_HAL_INTERRUPTS_CHAIN |
with the correct CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN. |
|
1998-10-27 Jesper Skov <jskov@cygnus.co.uk> |
PR 18021 |
* src/hal_misc.c (hal_ctrlc_isr): Removed break; to prevent |
compiler error. |
|
1998-10-25 Jesper Skov <jskov@cygnus.co.uk> |
|
* src/mips-stub.c (__build_t_packet): Replaced |
CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT with |
CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT. |
Fixed #endif comment. |
|
* src/hal_misc.c (hal_ctrlc_isr): Replaced |
CYGDBG_KERNEL_DEBUG_GDB_INCLUDE_STUBS with |
CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS. |
|
* include/hal_intr.h: Replaced CYGIMP_KERNEL_INTERRUPTS_CHAIN with |
CYGIMP_HAL_INTERRUPTS_CHAIN. |
|
1998-10-23 Jesper Skov <jskov@cygnus.co.uk> |
|
* include/hal_intr.h: Include pkgconf/hal.h. |
|
1998-10-16 Bart Veer <bartv@cygnus.co.uk> |
|
* src/vectors.S (__interrupt_stack): |
Made the interrupt stack size configurable. |
|
1998-10-16 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/hal_misc.c: |
Enabled caches by default. |
|
1998-10-14 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/context.S (hal_thread_switch_context): |
Store copy of R31(RA) in PC slot in register state to keep GDB |
happy. |
* include/hal_arch.h (HAL_THREAD_INIT_CONTEXT): |
Intialize PC slot in register state. |
|
* src/hal_misc.c: |
Altered ifdefs to allow building without kernel present. |
|
* include/mips-stub.h: |
Include generic-stub.h from HAL rather than from kernel. |
|
* src/mips-stub.c: |
Added signal definitions to avoid including signal.h. |
|
* include/hal_intr.h: |
Added implementations of HAL_INTERRUPT_ACKNOWLEDGE() and |
HAL_INTERRUPT_SET_LEVEL(). |
|
1998-10-13 Jesper Skov <jskov@cygnus.co.uk> |
|
* src/hal_misc.c: Use GDB array rather than HAL_SavedRegisters |
structure. Rely on generic stub to pack/unpack the array. |
|
* include/hal_arch.h (HAL_GET_GDB_REGISTERS, |
HAL_SET_GDB_REGISTERS): get/set full register set. |
|
1998-10-13 Jesper Skov <jskov@cygnus.co.uk> |
|
* include/mips-stub.h: Moved first use of regnames below |
definition. |
|
Sun Sep 27 12:17:42 1998 Jesper Skov <jskov@cygnus.co.uk> |
|
* include/hal_cache.h (HAL_DCACHE_LOCK): Terminate asm string. |
|
1998-09-26 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/hal_cache.h: |
Cleaned up some compilation errors. |
|
Tue Sep 15 19:13:43 1998 David Moore <dsm@keema.cygnus.co.uk> |
|
* src/vectors.S: Cleaned up comments. |
|
1998-09-15 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/hal_arch.h (HAL_GET_GDB_REGISTERS): |
Initialized R30 to a copy of SP to avoid GDB making bogus memory |
references. |
|
* src/hal_misc.c: |
Added support for Ctrl-C processing when running under Cygmon. |
Fixed a compiler warning. |
|
1998-09-14 Bart Veer <bartv@cygnus.co.uk> |
|
* src/PKGconf.mak: |
Made vectors.o dependent on the various files that can contain |
makefile variables or rules. This is needed after changes to |
pkgconf.tcl for PRs 17195 and 17286. |
|
Mon Sep 14 11:10:20 1998 Jesper Skov <jskov@lassi.cygnus.co.uk> |
PR 17230 |
|
* src/vectors.S: Replaced CYGIMP_KERNEL_INTERRUPTS_CHAIN with new |
CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN. |
|
1998-09-14 Nick Garnett <nickg@cygnus.co.uk> |
PR 17230 |
|
* include/hal_intr.h: |
Added HAL_TRANSLATE_VECTOR() to translate a supplied vector number |
into one that can be used in the HAL. Added calls to it in |
HAL_INTERRUPT_ATTACH() and HAL_INTERRUPT_DETACH(). |
|
1998-09-12 Bart Veer <bartv@cygnus.co.uk> |
|
* include/pkgconf/hal_tx39.h: |
Added missing descriptions (PR 17184) |
|
* src/vectors.S: |
<pkgconf/kernel.h> was being included without properly checking |
that the kernel package was enabled. |
|
* src/hal_misc.c (exception_handler): |
Sort out exception handling options (PR 16953) |
|
1998-09-11 Nick Garnett <nickg@cygnus.co.uk> |
PR 17230 |
|
* src/vectors.S (__default_interrupt_vsr): |
Modified interrupt decode code to preserve raising interrupt |
number to pass to ISR, even when using chained interrupts. |
|
1998-09-03 Bart Veer <bartv@cygnus.co.uk> |
|
* src/mips-stub.c: |
Fixed type in config option name. |
|
1998-09-02 Bart Veer <bartv@cygnus.co.uk> |
|
* include/pkgconf/hal_tx39.h: |
New header file for architecture-specific configuration options |
|
* tests/PKGconf.mak: |
* src/PKGconf.mak: |
Sort out package naming conventions. |
|
Tue Sep 1 19:26:45 1998 Hugo Tyson <hmt@cygnus.co.uk> |
|
* src/hal_misc.c: |
Use CYGDBG_INFRA_DIAG_USE_DEVICE (from infra.h) instead of |
CYG_DIAG_USE_DEVICE (badly named, from kernel.h). |
|
1998-09-01 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/hal_intr.h: |
Added CYG_EXCEPTION_COUNT. |
|
1998-08-28 Bart Veer <bartv@cygnus.co.uk> |
|
* src/vectors.S, src/context.S, src/hal_misc.c, src/mips-stub.c: |
Updated for new kernel configuration option symbol names |
|
Fri Aug 28 10:01:24 1998 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* src/hal_misc.c: |
Rename __main() to cyg_hal_invoke_constructors() to prevent the |
implied link with things called, or related to main(). Remove static |
initialised variable as we can now guarantee it is only called |
once. |
|
* src/vectors.S: |
Instead of calling main(), call cyg_start() which lives in the infra |
package. |
Explicitly invoke constructors as it isn't done magically for us |
any more, now that main() is no longer used. |
|
|
1998-08-25 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/vectors.S: |
Now pass pointer to saved registers as third argument to |
interrupt_end(). |
|
* include/hal_arch.h: |
Added macros to support GDB. |
|
Tue Aug 25 02:33:59 1998 Jonathan Larmour <jlarmour@cygnus.co.uk> |
|
* include/mips_stub.h, src/hal_misc.c: |
Add void to prototypes and typedefs that want it to silence warnings |
|
1998-08-21 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/hal_cache.h: |
Now includes cyg_type.h rather than ktypes.h. |
|
1998-08-18 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/context.S: |
* include/hal_arch.h: |
* include/hal_io.h: |
* include/hal_intr.h: |
Now uses cyg_type.h rather than ktypes.h. |
|
* src/hal_misc.c: |
* src/vectors.S: |
Now uses hal.h rather than kernel.h. |
|
1998-07-23 Nick Garnett <nickg@cygnus.co.uk> |
|
* include/hal_intr.h: Fixed some issues raised bt code review. |
|
* src/context.S: |
* include/hal_arch.h: Fixed some typos raised by code review. |
|
* include/hal_intr.h (HAL_INTERRUPT_MASK): |
* src/vectors.S (hal_interrupt_level): Added hal_interrupt_level |
to allow for interaction between HAL_INTERRUPT_UNMASK() and |
HAL_INTERRUPT_SET_LEVEL(). |
|
|
//=========================================================================== |
//####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#### |
//=========================================================================== |
/v2_0/src/hal_syscall.c
0,0 → 1,108
//============================================================================= |
// |
// 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 |
// 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 CYG_ADDRWORD __do_syscall(CYG_ADDRWORD func, // syscall function number |
CYG_ADDRWORD arg1, CYG_ADDRWORD arg2, // up to four args. |
CYG_ADDRWORD arg3, CYG_ADDRWORD arg4, |
CYG_ADDRWORD *retval, // syscall return value |
CYG_ADDRWORD *sig); // signal to return (or 0) |
|
#define SYS_exit 1 |
#define SYS_interrupt 1000 |
|
int |
hal_syscall_handler(void) |
{ |
CYG_ADDRWORD func, arg1, arg2, arg3, arg4; |
CYG_ADDRWORD err, sig; |
|
func = get_register(REG_A0); |
arg1 = get_register(REG_A1); |
arg2 = get_register(REG_A2); |
arg3 = get_register(REG_A3); |
arg4 = 0; |
|
put_register(REG_PC, get_register(REG_PC)+4); |
|
if (func == SYS_interrupt) { |
// A console interrupt landed us here. |
// Invoke the debug agent so as to cause a SIGINT. |
return SIGINT; |
} |
|
if (__do_syscall(func, arg1, arg2, arg3, arg4, &err, &sig)) { |
put_register(REG_V0, err); |
return (int)sig; |
} |
|
return SIGTRAP; |
} |
|
#endif // CYGSEM_REDBOOT_BSP_SYSCALLS |
/v2_0/src/mipsfp.c
0,0 → 1,835
//========================================================================== |
// |
// mipsfp.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): jlarmour |
// Contributors: jlarmour |
// Date: 1999-07-13 |
// Purpose: Emulate unimplemented FP operations on MIPS architectures |
// Description: This catches the unimplemented operation excetion only, |
// and if possible deals with it so processing can continue |
// as if the MIPS had a proper IEEE FPU |
// |
// |
//####DESCRIPTIONEND#### |
// |
//========================================================================*/ |
|
// CONFIGURATION |
|
#include <pkgconf/hal.h> |
|
#ifdef CYGHWR_HAL_MIPS_FPU |
|
// INCLUDES |
|
#include <cyg/infra/cyg_type.h> // Standard eCos types |
#include <cyg/infra/cyg_ass.h> // Standard eCos assertion support |
#include <cyg/infra/cyg_trac.h> // Standard eCos tracing support |
#include <cyg/hal/hal_intr.h> // HAL interrupt vectors |
#include <cyg/hal/hal_arch.h> // Architecture types such as |
// HAL_SavedRegisters |
#define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS |
#include <cyg/hal/mips-regs.h> // MIPS register and bitmask definitions |
|
// TYPES |
|
// The following types were taken from <sys/ieeefp.h> from libm. |
|
#if (CYG_BYTEORDER == CYG_MSBFIRST) // Big endian |
|
typedef union |
{ |
cyg_int32 asi32[2]; |
|
cyg_int64 asi64; |
|
double value; |
|
struct |
{ |
#if (CYG_DOUBLE_BYTEORDER == CYG_MSBFIRST) |
unsigned int sign : 1; |
unsigned int exponent: 11; |
unsigned int fraction0:4; |
unsigned int fraction1:16; |
unsigned int fraction2:16; |
unsigned int fraction3:16; |
#else |
unsigned int fraction2:16; |
unsigned int fraction3:16; |
unsigned int sign : 1; |
unsigned int exponent: 11; |
unsigned int fraction0:4; |
unsigned int fraction1:16; |
#endif |
} number; |
|
struct |
{ |
#if (CYG_DOUBLE_BYTEORDER == CYG_MSBFIRST) |
unsigned int sign : 1; |
unsigned int exponent: 11; |
unsigned int quiet:1; |
unsigned int function0:3; |
unsigned int function1:16; |
unsigned int function2:16; |
unsigned int function3:16; |
#else |
unsigned int function2:16; |
unsigned int function3:16; |
unsigned int sign : 1; |
unsigned int exponent: 11; |
unsigned int quiet:1; |
unsigned int function0:3; |
unsigned int function1:16; |
#endif |
} nan; |
|
struct |
{ |
#if (CYG_DOUBLE_BYTEORDER == CYG_MSBFIRST) |
cyg_uint32 msw; |
cyg_uint32 lsw; |
#else |
cyg_uint32 lsw; |
cyg_uint32 msw; |
#endif |
} parts; |
|
|
} Cyg_libm_ieee_double_shape_type; |
|
|
typedef union |
{ |
cyg_int32 asi32; |
|
float value; |
|
struct |
{ |
unsigned int sign : 1; |
unsigned int exponent: 8; |
unsigned int fraction0: 7; |
unsigned int fraction1: 16; |
} number; |
|
struct |
{ |
unsigned int sign:1; |
unsigned int exponent:8; |
unsigned int quiet:1; |
unsigned int function0:6; |
unsigned int function1:16; |
} nan; |
|
} Cyg_libm_ieee_float_shape_type; |
|
|
#else // Little endian |
|
typedef union |
{ |
cyg_int32 asi32[2]; |
|
cyg_int64 asi64; |
|
double value; |
|
struct |
{ |
#if (CYG_DOUBLE_BYTEORDER == CYG_MSBFIRST) // Big endian |
unsigned int fraction1:16; |
unsigned int fraction0: 4; |
unsigned int exponent :11; |
unsigned int sign : 1; |
unsigned int fraction3:16; |
unsigned int fraction2:16; |
#else |
unsigned int fraction3:16; |
unsigned int fraction2:16; |
unsigned int fraction1:16; |
unsigned int fraction0: 4; |
unsigned int exponent :11; |
unsigned int sign : 1; |
#endif |
} number; |
|
struct |
{ |
#if (CYG_DOUBLE_BYTEORDER == CYG_MSBFIRST) // Big endian |
unsigned int function1:16; |
unsigned int function0:3; |
unsigned int quiet:1; |
unsigned int exponent: 11; |
unsigned int sign : 1; |
unsigned int function3:16; |
unsigned int function2:16; |
#else |
unsigned int function3:16; |
unsigned int function2:16; |
unsigned int function1:16; |
unsigned int function0:3; |
unsigned int quiet:1; |
unsigned int exponent: 11; |
unsigned int sign : 1; |
#endif |
} nan; |
|
struct |
{ |
#if (CYG_DOUBLE_BYTEORDER == CYG_MSBFIRST) // Big endian |
cyg_uint32 msw; |
cyg_uint32 lsw; |
#else |
cyg_uint32 lsw; |
cyg_uint32 msw; |
#endif |
} parts; |
|
} Cyg_libm_ieee_double_shape_type; |
|
|
typedef union |
{ |
cyg_int32 asi32; |
|
float value; |
|
struct |
{ |
unsigned int fraction0: 7; |
unsigned int fraction1: 16; |
unsigned int exponent: 8; |
unsigned int sign : 1; |
} number; |
|
struct |
{ |
unsigned int function1:16; |
unsigned int function0:6; |
unsigned int quiet:1; |
unsigned int exponent:8; |
unsigned int sign:1; |
} nan; |
|
} Cyg_libm_ieee_float_shape_type; |
|
#endif // little-endian |
|
typedef enum { |
ADD_INSN=0, // 0 |
SUB_INSN, |
MUL_INSN, |
DIV_INSN, |
SQRT_INSN, |
ABS_INSN, // 5 |
MOV_INSN, |
NEG_INSN, |
ROUNDL_INSN, |
TRUNCL_INSN, |
CEILL_INSN, // 10 |
FLOORL_INSN, |
ROUNDW_INSN, |
TRUNCW_INSN, |
CEILW_INSN, |
FLOORW_INSN, // 15 |
// ... |
CVTS_INSN=32, |
CVTD_INSN, |
// ... |
CVTW_INSN=36, |
CVTL_INSN, |
// ... |
// |
// 48-63 are floating point compare - treated separately |
|
} fp_operation; |
|
typedef enum { |
S_FORMAT=16, |
D_FORMAT=17, |
W_FORMAT=20, |
L_FORMAT=21 |
} fp_format; |
|
// FUNCTIONS |
|
#define issubnormal(_x_) ((_x_).number.exponent == 0) |
|
// These functions convert between single precision floating point numbers |
// represented in register or union form. This is required because endian-ness |
// matters when a 32-bit float is in a 64-bit register. |
|
static __inline__ void |
reg2flt( CYG_HAL_FPU_REG *fpu_reg_p, Cyg_libm_ieee_float_shape_type *flt) |
{ |
#if defined(CYGHWR_HAL_MIPS_FPU_32BIT) || (CYG_BYTEORDER == CYG_LSBFIRST) |
flt->asi32 = *(cyg_int32 *)fpu_reg_p; |
#else |
flt->asi32 = *((cyg_int32 *)fpu_reg_p + 1); |
# endif |
} // reg2flt() |
|
static __inline__ void |
flt2reg( Cyg_libm_ieee_float_shape_type *flt, CYG_HAL_FPU_REG *fpu_reg_p ) |
{ |
#if defined(CYGHWR_HAL_MIPS_FPU_32BIT) || (CYG_BYTEORDER == CYG_LSBFIRST) |
*(cyg_int32 *)fpu_reg_p = flt->asi32; |
#else |
*((cyg_int32 *)fpu_reg_p + 1) = flt->asi32; |
# endif |
} // flt2reg() |
|
static __inline__ void |
reg2dbl( CYG_HAL_FPU_REG *fpu_reg_p, Cyg_libm_ieee_double_shape_type *flt) |
{ |
flt->asi64 = *(cyg_int64 *)fpu_reg_p; |
} // reg2dbl() |
|
static __inline__ void |
dbl2reg( Cyg_libm_ieee_double_shape_type *flt, CYG_HAL_FPU_REG *fpu_reg_p ) |
{ |
*(cyg_uint64*)fpu_reg_p = flt->asi64; |
} // dbl2reg() |
|
|
// This function returns non-zero if the exception has been handled |
// successfully. |
|
// FIXME: Arguably we should raise underflow exceptions in some of the cases |
// below e.g. sqrt(subnormal). And perhaps we should round appropriately to |
// +/- 2^^Emin if round to +/- infinity is enabled, as per the FS bit. Not sure. |
|
externC cyg_uint8 |
cyg_hal_mips_process_fpe( HAL_SavedRegisters *regs ) |
{ |
CYG_WORD insn; |
CYG_HAL_FPU_REG *srcreg1, *srcreg2, *dstreg; |
cyg_uint8 handled=0; |
fp_format format; |
cyg_uint8 fp64bit=0; // true if format is 64bit, false if 32bit |
cyg_uint8 fixedpoint=0; // true if format is fixed point, false if |
// floating point |
cyg_uint8 computational_insn=1; // computational FP instruction |
cyg_bool delay_slot; // did it happen in a delay slot |
|
CYG_REPORT_FUNCNAMETYPE("cyg_hal_mips_process_fpe", "returning %d"); |
|
CYG_CHECK_DATA_PTR( regs, |
"cyg_hal_mips_process_fpe() called with invalid regs ptr"); |
|
CYG_PRECONDITION( (regs->vector>>2) == CYGNUM_HAL_VECTOR_FPE, |
"Asked to process non-FPE exception"); |
|
// First of all, we only handle the unimplemented operation exception |
// here, so if we don't have that, we just exit |
if ((regs->fcr31 & FCR31_CAUSE_E) == 0) { |
CYG_REPORT_RETVAL(0); |
return 0; |
} |
|
// Get the contents of the instruction that caused the exception. This |
// may have been in a branch delay slot however, so we have to check |
// the BD bit in the cause register first. |
if (regs->cause & CAUSE_BD) { |
insn = *(((CYG_WORD *) regs->pc) + 1); |
delay_slot = true; |
} else { |
insn = *(CYG_WORD *) regs->pc; |
delay_slot = false; |
} |
|
CYG_TRACE2(true, "exception at pc %08x containing %08x", regs->pc, insn); |
|
CYG_ASSERT( (insn>>26) == 0x11, |
"Instruction at pc doesn't have expected opcode COP1"); |
|
// Determine the format |
format = (insn >> 21) & 0x1f; |
|
switch (format) |
{ |
case S_FORMAT: |
break; |
case D_FORMAT: |
fp64bit++; |
break; |
case W_FORMAT: |
fixedpoint++; |
break; |
case L_FORMAT: |
fixedpoint++; |
fp64bit++; |
break; |
default: |
computational_insn=0; |
break; |
} // switch |
|
// This module only emulates computational floating point instructions |
if (computational_insn && !fixedpoint) { |
|
// Decode the registers used |
dstreg = ®s->f[ (insn >> 6) & 0x1f ]; |
srcreg1 = ®s->f[ (insn >> 11) & 0x1f ]; |
srcreg2 = ®s->f[ (insn >> 16) & 0x1f ]; |
|
// Determine the operation requested |
switch (insn & 0x3f) |
{ |
case ADD_INSN: |
case SUB_INSN: |
case MUL_INSN: |
case DIV_INSN: |
|
if (fp64bit) { |
Cyg_libm_ieee_double_shape_type s1, s2; |
|
reg2dbl( srcreg1, &s1 ); |
reg2dbl( srcreg2, &s2 ); |
|
if ( issubnormal( s1 ) ) { // flush to 0 and restart |
// but preserve sign |
if (s1.number.sign) |
s1.value = -0.0; |
else |
s1.value = 0.0; |
dbl2reg( &s1, srcreg1 ); |
handled++; |
} |
|
// We could try flushing both to 0 at the same time, but |
// that's inadvisable if both numbers are very small. |
// Particularly if this is DIV_INSN, when we could therefore |
// get 0/0 even when the program explicitly checked for |
// denominator != 0. That's also why we check s1 first. |
|
else if ( issubnormal( s2 ) ) { // flush to 0 and restart |
// but preserve sign |
if (s2.number.sign) |
s2.value = -0.0; |
else |
s2.value = 0.0; |
dbl2reg( &s2, srcreg2 ); |
handled++; |
} |
|
} else { // 32-bit |
Cyg_libm_ieee_float_shape_type s1, s2; |
|
reg2flt( srcreg1, &s1 ); |
reg2flt( srcreg2, &s2 ); |
|
if ( issubnormal( s1 )) { // flush to 0 and restart |
// but preserve sign |
if (s1.number.sign) |
s1.value = -0.0; |
else |
s1.value = 0.0; |
flt2reg( &s1, srcreg1 ); |
handled++; |
} |
else if ( issubnormal( s2 ) ) { // flush to 0 and restart |
// but preserve sign |
if (s2.number.sign) |
s2.value = -0.0; |
else |
s2.value = 0.0; |
flt2reg( &s2, srcreg2 ); |
handled++; |
} |
} |
break; |
|
case SQRT_INSN: |
if ( fp64bit ) { |
Cyg_libm_ieee_double_shape_type d, s; |
|
reg2dbl( dstreg, &d ); |
reg2dbl( srcreg1, &s ); |
|
if ( issubnormal( s ) ) { // Sqrt of something tiny is 0 |
// if this is a delay slot, we can't restart properly |
// so if it is subnormal, clear the source register instead |
if ( delay_slot ) { |
// but preserve sign |
if (s.number.sign) |
s.value = -0.0; |
else |
s.value = 0.0; |
dbl2reg( &s, srcreg1 ); |
} else { |
// but preserve sign |
if (s.number.sign) |
d.value = -0.0; |
else |
d.value = 0.0; |
dbl2reg( &d, dstreg ); |
regs->pc += 4; // We've dealt with this so move on |
} |
handled++; |
} |
|
} else { // 32-bit |
Cyg_libm_ieee_float_shape_type d, s; |
|
reg2flt( dstreg, &d ); |
reg2flt( srcreg1, &s ); |
|
if ( issubnormal( s ) ) { // Sqrt of something tiny is 0 |
// if this is a delay slot, we can't restart properly |
// so if it is subnormal, clear the source register instead |
if ( delay_slot ) { |
// but preserve sign |
if (s.number.sign) |
s.value = -0.0; |
else |
s.value = 0.0; |
flt2reg( &s, srcreg1 ); |
} else { |
// but preserve sign |
if (s.number.sign) |
d.value = -0.0; |
else |
d.value = 0.0; |
flt2reg( &d, dstreg ); |
regs->pc += 4; // We've dealt with this so move on |
} |
handled++; |
} |
} |
break; |
|
case ABS_INSN: |
// We may as well do this right if we can |
if ( fp64bit ) { |
Cyg_libm_ieee_double_shape_type d, s; |
|
reg2dbl( dstreg, &d ); |
reg2dbl( srcreg1, &s ); |
|
// if this is a delay slot, we can't restart properly |
// so if it is subnormal, clear the source register instead |
if ( delay_slot ) { |
if ( issubnormal( s ) ) { |
// The sign is still important for abs in case |
// there are any further operations on the same |
// register |
if (s.number.sign) |
s.value = -0.0; |
else |
s.value = 0.0; |
dbl2reg( &s, srcreg1 ); |
handled++; |
} |
} else { |
d.asi64 = s.asi64; |
d.number.sign = 0; |
dbl2reg( &d, dstreg ); |
regs->pc += 4; |
handled++; |
} |
} else { // 32-bit |
Cyg_libm_ieee_float_shape_type d, s; |
|
reg2flt( dstreg, &d ); |
reg2flt( srcreg1, &s ); |
|
// if this is a delay slot, we can't restart properly |
// so if it is subnormal, clear the source register instead |
if ( delay_slot ) { |
if ( issubnormal( s ) ) { |
// The sign is still important for abs in case |
// there are any further operations on the same |
// register |
if (s.number.sign) |
s.value = -0.0; |
else |
s.value = 0.0; |
flt2reg( &s, srcreg1 ); |
handled++; |
} |
} else { |
d.asi32 = s.asi32; |
d.number.sign = 0; |
flt2reg( &d, dstreg ); |
regs->pc += 4; |
handled++; |
} |
} |
break; |
|
case MOV_INSN: |
// We may as well do this right if we can |
if ( fp64bit ) { |
Cyg_libm_ieee_double_shape_type d, s; |
|
reg2dbl( dstreg, &d ); |
reg2dbl( srcreg1, &s ); |
|
// if this is a delay slot, we can't restart properly |
// so if it is subnormal, clear the source register instead |
if ( delay_slot ) { |
if ( issubnormal( s ) ) { |
// but preserve sign |
if (s.number.sign) |
s.value = -0.0; |
else |
s.value = 0.0; |
dbl2reg( &s, srcreg1 ); |
handled++; |
} |
} else { |
d.asi64 = s.asi64; |
dbl2reg( &d, dstreg ); |
regs->pc += 4; |
handled++; |
} |
} else { // 32-bit |
Cyg_libm_ieee_float_shape_type d, s; |
|
reg2flt( dstreg, &d ); |
reg2flt( srcreg1, &s ); |
|
// if this is a delay slot, we can't restart properly |
// so if it is subnormal, clear the source register instead |
if ( delay_slot ) { |
if ( issubnormal( s ) ) { |
// The sign is still important for abs in case |
// there are any further operations on the same |
// register |
if (s.number.sign) |
s.value = -0.0; |
else |
s.value = 0.0; |
flt2reg( &s, srcreg1 ); |
handled++; |
} |
} else { |
d.asi32 = s.asi32; |
flt2reg( &d, dstreg ); |
regs->pc += 4; |
handled++; |
} |
} |
break; |
|
case NEG_INSN: |
// We may as well do this right if we can |
if ( fp64bit ) { |
Cyg_libm_ieee_double_shape_type d, s; |
|
reg2dbl( dstreg, &d ); |
reg2dbl( srcreg1, &s ); |
|
// if this is a delay slot, we can't restart properly |
// so if it is subnormal, clear the source register instead |
if ( delay_slot ) { |
if ( issubnormal( s ) ) { |
// but preserve sign |
if (s.number.sign) |
s.value = -0.0; |
else |
s.value = 0.0; |
dbl2reg( &s, srcreg1 ); |
handled++; |
} |
} else { |
d.asi64 = s.asi64; |
d.number.sign = s.number.sign ? 0 : 1; |
dbl2reg( &d, dstreg ); |
regs->pc += 4; |
handled++; |
} |
} else { // 32-bit |
Cyg_libm_ieee_float_shape_type d, s; |
|
reg2flt( dstreg, &d ); |
reg2flt( srcreg1, &s ); |
|
// if this is a delay slot, we can't restart properly |
// so if it is subnormal, clear the source register instead |
if ( delay_slot ) { |
if ( issubnormal( s ) ) { |
// but preserve sign |
if (s.number.sign) |
s.value = -0.0; |
else |
s.value = 0.0; |
flt2reg( &s, srcreg1 ); |
handled++; |
} |
} else { |
d.asi32 = s.asi32; |
d.number.sign = s.number.sign ? 0 : 1; |
flt2reg( &d, dstreg ); |
regs->pc += 4; |
handled++; |
} |
} |
break; |
|
// We can't do much about floating-point to fixed-point arithmetic |
// without emulating the FPU here ourselves! |
// So simply zero denormalized numbers |
case ROUNDL_INSN: |
case TRUNCL_INSN: |
case CEILL_INSN: |
case FLOORL_INSN: |
case ROUNDW_INSN: |
case TRUNCW_INSN: |
case CEILW_INSN: |
case FLOORW_INSN: |
case CVTS_INSN: |
case CVTD_INSN: |
case CVTW_INSN: |
case CVTL_INSN: |
|
if ( fp64bit ) { |
Cyg_libm_ieee_double_shape_type s; |
|
reg2dbl( srcreg1, &s ); |
|
// just try and 0 the source register if it is subnormal |
if ( issubnormal( s ) ) { |
// but preserve sign |
if (s.number.sign) |
s.value = -0.0; |
else |
s.value = 0.0; |
dbl2reg( &s, srcreg1 ); |
handled++; |
} |
} else { // 32-bit |
Cyg_libm_ieee_float_shape_type s; |
|
reg2flt( srcreg1, &s ); |
|
// just try and 0 the source register if it is subnormal |
if ( issubnormal( s ) ) { |
// but preserve sign |
if (s.number.sign) |
s.value = -0.0; |
else |
s.value = 0.0; |
flt2reg( &s, srcreg1 ); |
handled++; |
} |
} |
break; |
|
default: |
// check for floating-point compare (C.cond.fmt) |
if ( (insn & 0x30) == 0x30 ) { |
if (fp64bit) { |
Cyg_libm_ieee_double_shape_type s1, s2; |
|
reg2dbl( srcreg1, &s1 ); |
reg2dbl( srcreg2, &s2 ); |
|
if ( issubnormal( s1 ) ) { // flush to 0 and restart |
// but preserve sign |
if (s1.number.sign) |
s1.value = -0.0; |
else |
s1.value = 0.0; |
dbl2reg( &s1, srcreg1 ); |
handled++; |
} |
|
if ( issubnormal( s2 ) ) { // flush to 0 and restart |
// but preserve sign |
if (s2.number.sign) |
s2.value = -0.0; |
else |
s2.value = 0.0; |
dbl2reg( &s2, srcreg2 ); |
handled++; |
} |
|
} else { // 32-bit |
Cyg_libm_ieee_float_shape_type s1, s2; |
|
reg2flt( srcreg1, &s1 ); |
reg2flt( srcreg2, &s2 ); |
|
if ( issubnormal( s1 )) { // flush to 0 and restart |
// but preserve sign |
if (s1.number.sign) |
s1.value = -0.0; |
else |
s1.value = 0.0; |
flt2reg( &s1, srcreg1 ); |
handled++; |
} |
if ( issubnormal( s2 ) ) { // flush to 0 and restart |
// but preserve sign |
if (s2.number.sign) |
s2.value = -0.0; |
else |
s2.value = 0.0; |
flt2reg( &s2, srcreg2 ); |
handled++; |
} |
} // else |
} // if |
break; |
} // switch |
} // if (computational_insn && !fixedpoint) |
|
if ( handled != 0) { |
// We must clear the cause and flag bits before restoring FPCR31 |
regs->fcr31 &= ~(FCR31_CAUSE_E | FCR31_CAUSE_V | FCR31_CAUSE_Z | |
FCR31_CAUSE_O | FCR31_CAUSE_U | FCR31_CAUSE_I | |
FCR31_FLAGS_V | FCR31_FLAGS_Z | |
FCR31_FLAGS_O | FCR31_FLAGS_U | FCR31_FLAGS_I); |
|
} |
|
CYG_REPORT_RETVAL( handled ); |
return handled; |
} // cyg_hal_mips_process_fpe() |
|
#endif // ifdef CYGHWR_HAL_MIPS_FPU |
|
// EOF mipsfp.c |
/v2_0/src/hal_misc.c
0,0 → 1,586
//========================================================================== |
// |
// 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 |
// Contributors: nickg, jlarmour |
// Date: 1999-01-21 |
// Purpose: HAL miscellaneous functions |
// Description: This file contains miscellaneous functions provided by the |
// HAL. |
// |
//####DESCRIPTIONEND#### |
// |
//========================================================================*/ |
|
#include <pkgconf/hal.h> |
|
#include <cyg/infra/cyg_type.h> // Base types |
#include <cyg/infra/cyg_trac.h> // tracing macros |
#include <cyg/infra/cyg_ass.h> // assertion macros |
|
#define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS |
#include <cyg/hal/hal_arch.h> // architectural definitions |
|
#include <cyg/hal/hal_intr.h> // Interrupt handling |
|
#include <cyg/hal/hal_cache.h> // Cache handling |
#include <cyg/hal/hal_if.h> // hal_ctrlc_isr() |
#include <cyg/hal/mips-regs.h> // FPU cause register definitions |
|
#include CYGHWR_MEMORY_LAYOUT_H |
|
/*------------------------------------------------------------------------*/ |
/* If required, define a variable to store the clock period. */ |
|
#ifdef CYGHWR_HAL_CLOCK_PERIOD_DEFINED |
|
CYG_WORD32 cyg_hal_clock_period; |
|
#endif |
|
/*------------------------------------------------------------------------*/ |
/* First level C exception handler. */ |
|
externC void __handle_exception (void); |
|
externC HAL_SavedRegisters *_hal_registers; |
|
externC void* volatile __mem_fault_handler; |
|
externC cyg_uint8 cyg_hal_mips_process_fpe( HAL_SavedRegisters *regs ); |
|
externC cyg_uint32 cyg_hal_exception_handler(HAL_SavedRegisters *regs) |
{ |
#if defined(CYGHWR_HAL_MIPS_FPU) || \ |
(defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && defined(CYGPKG_HAL_EXCEPTIONS)) |
int vec = regs->vector>>2; |
#endif |
|
#if defined(CYGHWR_HAL_MIPS_FPU) |
// Special handling of FPU exceptions |
if (CYGNUM_HAL_VECTOR_FPE == vec) { |
|
#if defined(CYGSEM_HAL_MIPS_EMULATE_UNIMPLEMENTED_FPU_OPS) |
// We may be required to emulate certain unimplemented Floating Point |
// operations |
|
// cyg_hal_mips_process_fpe() returns non-zero if it could handle |
// the exception successfully. If so, we just return |
|
if ( cyg_hal_mips_process_fpe(regs) ) |
return 0; |
#endif |
|
// Find the cause of the FPU exception, clear the flag and use |
// the decoded vector number. |
{ |
cyg_uint32 cause = regs->fcr31; |
|
if (cause & FCR31_CAUSE_I) { |
vec = CYGNUM_HAL_EXCEPTION_FPU_INEXACT; |
cause &= ~(FCR31_FLAGS_I | FCR31_CAUSE_I); |
} else if (cause & FCR31_CAUSE_U) { |
vec = CYGNUM_HAL_EXCEPTION_FPU_UNDERFLOW; |
cause &= ~(FCR31_FLAGS_U | FCR31_CAUSE_U); |
} else if (cause & FCR31_CAUSE_O) { |
vec = CYGNUM_HAL_EXCEPTION_FPU_OVERFLOW; |
cause &= ~(FCR31_FLAGS_O | FCR31_CAUSE_O); |
} else if (cause & FCR31_CAUSE_Z) { |
vec = CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO; |
cause &= ~(FCR31_FLAGS_Z | FCR31_CAUSE_Z); |
} else if (cause & FCR31_CAUSE_V) { |
vec = CYGNUM_HAL_EXCEPTION_FPU_INVALID; |
cause &= ~(FCR31_FLAGS_V | FCR31_CAUSE_V); |
} |
regs->fcr31 = cause; |
|
#if 1 |
// Update the FPU status register with the new |
// setting. This is a workaround for the signal2 test |
// which does a longjump in the exception handler and thus |
// never gets around to executing the register restore |
// code. |
asm ("ctc1 %0,$31" : : "r" (cause)); |
#endif |
} |
} |
#endif // CYGHWR_HAL_MIPS_FPU |
|
|
#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) |
|
// If we caught an exception inside the stubs, see if we were expecting it |
// and if so jump to the saved address |
if (__mem_fault_handler) { |
regs->pc = (CYG_HAL_MIPS_REG)(signed long)__mem_fault_handler; |
return 0; // Caught an exception inside stubs |
} |
|
// Set the pointer to the registers of the current exception |
// context. At entry the GDB stub will expand the |
// HAL_SavedRegisters structure into a (bigger) register array. |
_hal_registers = regs; |
__handle_exception(); |
|
#elif defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && defined(CYGPKG_HAL_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( vec, (CYG_ADDRWORD)regs ); |
|
#else |
|
CYG_FAIL("Exception!!!"); |
|
#endif |
return 0; |
} |
|
/*------------------------------------------------------------------------*/ |
/* default ISR */ |
|
#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT |
externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) |
{ |
#if defined(CYGDBG_HAL_MIPS_DEBUG_GDB_CTRLC_SUPPORT) && \ |
defined(CYGHWR_HAL_GDB_PORT_VECTOR) && \ |
defined(HAL_CTRLC_ISR) |
|
#ifndef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN |
if( vector == CYGHWR_HAL_GDB_PORT_VECTOR ) |
#endif |
{ |
cyg_uint32 result = HAL_CTRLC_ISR( vector, data ); |
if( result != 0 ) return result; |
} |
|
#if defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon) |
#if defined(HAL_DIAG_IRQ_CHECK) |
{ |
cyg_uint32 ret; |
/* let ROM monitor handle unexpected interrupts */ |
HAL_DIAG_IRQ_CHECK(vector, ret); |
if (ret<=0) |
return ret; |
} |
#endif // def HAL_DIAG_IRQ_CHECK |
#endif // def CYGSEM_HAL_USE_ROM_MONITOR_CygMon |
#endif |
|
CYG_TRACE1(true, "Interrupt: %d", vector); |
CYG_FAIL("Spurious Interrupt!!!"); |
return 0; |
} |
|
#else // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT |
|
externC cyg_uint32 hal_arch_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) |
{ |
#if defined(CYGDBG_HAL_MIPS_DEBUG_GDB_CTRLC_SUPPORT) && \ |
defined(CYGHWR_HAL_GDB_PORT_VECTOR) && \ |
defined(HAL_CTRLC_ISR) |
|
#if defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon) |
#if defined(HAL_DIAG_IRQ_CHECK) |
{ |
cyg_uint32 ret; |
/* let ROM monitor handle unexpected interrupts */ |
HAL_DIAG_IRQ_CHECK(vector, ret); |
if (ret<=0) |
return ret; |
} |
#endif // def HAL_DIAG_IRQ_CHECK |
#endif // def CYGSEM_HAL_USE_ROM_MONITOR_CygMon |
#endif |
|
#ifdef CYGPKG_REDBOOT |
hal_ctrlc_isr( vector, data ); |
#endif |
|
return 0; |
} |
|
#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT |
|
/*------------------------------------------------------------------------*/ |
/* data copy and bss zero functions */ |
|
typedef void (CYG_SYM_ADDRESS)(void); |
|
// All these must use this type of address to stop them being given relocations |
// relative to $gp (i.e. assuming they would be in .sdata) |
extern CYG_SYM_ADDRESS __ram_data_start; |
extern CYG_SYM_ADDRESS __ram_data_end; |
extern CYG_SYM_ADDRESS __rom_data_start; |
|
#ifdef CYG_HAL_STARTUP_ROM |
void hal_copy_data(void) |
{ |
char *p = (char *)&__ram_data_start; |
char *q = (char *)&__rom_data_start; |
|
while( p != (char *)&__ram_data_end ) |
*p++ = *q++; |
} |
#endif |
|
/*------------------------------------------------------------------------*/ |
|
#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 |
|
} // cyg_hal_invoke_constructors() |
|
/*------------------------------------------------------------------------*/ |
/* Determine the index of the ls bit of the supplied mask. */ |
|
cyg_uint32 hal_lsbit_index(cyg_uint32 mask) |
{ |
cyg_uint32 n = mask; |
|
static const signed char tab[64] = |
{ -1, 0, 1, 12, 2, 6, 0, 13, 3, 0, 7, 0, 0, 0, 0, 14, 10, |
4, 0, 0, 8, 0, 0, 25, 0, 0, 0, 0, 0, 21, 27 , 15, 31, 11, |
5, 0, 0, 0, 0, 0, 9, 0, 0, 24, 0, 0 , 20, 26, 30, 0, 0, 0, |
0, 23, 0, 19, 29, 0, 22, 18, 28, 17, 16, 0 |
}; |
|
n &= ~(n-1UL); |
n = (n<<16)-n; |
n = (n<<6)+n; |
n = (n<<4)+n; |
|
return tab[n>>26]; |
} |
|
/*------------------------------------------------------------------------*/ |
/* Determine the index of the ms bit of the supplied mask. */ |
|
cyg_uint32 hal_msbit_index(cyg_uint32 mask) |
{ |
cyg_uint32 x = mask; |
cyg_uint32 w; |
|
/* Phase 1: make word with all ones from that one to the right */ |
x |= x >> 16; |
x |= x >> 8; |
x |= x >> 4; |
x |= x >> 2; |
x |= x >> 1; |
|
/* Phase 2: calculate number of "1" bits in the word */ |
w = (x & 0x55555555) + ((x >> 1) & 0x55555555); |
w = (w & 0x33333333) + ((w >> 2) & 0x33333333); |
w = w + (w >> 4); |
w = (w & 0x000F000F) + ((w >> 8) & 0x000F000F); |
return (cyg_uint32)((w + (w >> 16)) & 0xFF) - 1; |
|
} |
|
/*------------------------------------------------------------------------*/ |
/* Delay for some number of useconds. */ |
void |
hal_delay_us(int us) |
{ |
cyg_uint32 val1, val2; |
int diff; |
long usticks; |
long ticks; |
|
// Calculate the number of counter register ticks per microsecond. |
|
usticks = (CYGNUM_HAL_RTC_PERIOD * CYGNUM_HAL_RTC_DENOMINATOR) / 1000000; |
|
// Make sure that the value is not zero. This will only happen if the |
// CPU is running at < 2MHz. |
if( usticks == 0 ) usticks = 1; |
|
while( us > 0 ) |
{ |
int us1 = us; |
|
// Wait in bursts of less than 10000us to avoid any overflow |
// problems in the multiply. |
if( us1 > 10000 ) |
us1 = 10000; |
|
us -= us1; |
|
ticks = us1 * usticks; |
|
HAL_CLOCK_READ(&val1); |
while (ticks > 0) { |
do { |
HAL_CLOCK_READ(&val2); |
} while (val1 == val2); |
diff = val2 - val1; |
if (diff < 0) diff += CYGNUM_HAL_RTC_PERIOD; |
ticks -= diff; |
val1 = val2; |
} |
} |
} |
|
/*------------------------------------------------------------------------*/ |
|
void hal_arch_program_new_stack(void *_func) |
{ |
externC void hal_program_new_stack( void *func, CYG_ADDRESS addr); |
hal_program_new_stack( (void *)_func, |
(CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS)) & ~15 ); |
} |
|
/*------------------------------------------------------------------------*/ |
/* Idle thread action */ |
|
#include <cyg/infra/diag.h> |
|
void hal_idle_thread_action( cyg_uint32 count ) |
{ |
#if 0 //def CYGPKG_HAL_MIPS_SIM |
if( (count % 1000) == 0 ) |
{ |
// This code causes a fake interrupt. |
asm volatile ( |
"xor $24,$24,$24;" |
"mtc0 $24,$13;" |
"lui $25,%%hi(1f);" |
"ori $25,$25,%%lo(1f);" |
"j other_vector;" |
"nop;" |
"1:" |
: |
: |
: "t8", "t9" |
); |
} |
#endif |
#if 0 //def CYGPKG_HAL_MIPS_TX39_JMR3904 |
|
if( (count % 100000 ) == 0 ) |
{ |
// cyg_uint32 tval, isr, imr, ilr; |
cyg_uint32 sr = 0, cr = 0, ctr = 0, cpr = 0; |
// HAL_CLOCK_READ( &tval ); |
// HAL_READ_UINT32( 0xFFFFC000, isr ); |
// HAL_READ_UINT32( 0xFFFFC004, imr ); |
// HAL_READ_UINT32( 0xFFFFC01C, ilr ); |
// CYG_TRACE2(1, "Timer value, ISR ",tval, isr); |
// CYG_TRACE2(1, "IMR ILR0 ", imr, ilr); |
|
// asm volatile ( |
// "mfc0 %0,$12;" |
// "nop; nop; nop;" |
// "mfc0 %1,$13;" |
// "nop; nop; nop;" |
// "mfc0 %2,$9;" |
// "nop; nop; nop;" |
// "mfc0 %3,$11;" |
// "nop; nop; nop;" |
// : "=r"(sr), "=r"(cr), "=r"(ctr), "=r"(cpr) |
// ); |
|
|
// diag_printf("Status %08x ", sr ); |
// diag_printf("Cause %08x ", cr ); |
// diag_printf("Counter %08x ", ctr ); |
// diag_printf("Compare %08x\n", cpr); |
|
#if 0 |
asm volatile ( |
"mfc0 %0,$12;" |
"nop; nop; nop;" |
: "=r"(sr) |
); |
diag_write_string("Status "); diag_write_hex( sr ); |
|
asm volatile ( |
"mfc0 %0,$13;" |
"nop; nop; nop;" |
: "=r"(cr) |
); |
diag_write_string(" Cause "); diag_write_hex( cr ); |
|
asm volatile ( |
"mfc0 %0,$9;" |
"nop; nop; nop;" |
: "=r"(ctr) |
); |
diag_write_string(" Counter "); diag_write_hex( ctr ); |
|
asm volatile ( |
"mfc0 %0,$11;" |
"nop; nop; nop;" |
: "=r"(cpr) |
); |
diag_write_string(" Compare "); diag_write_hex( cpr ); |
diag_write_string( "\n" ); |
|
#endif |
#if 1 |
asm volatile ( |
"mfc0 %0,$12;" |
"nop; nop; nop;" |
: "=r"(sr) |
); |
|
asm volatile ( |
"mfc0 %0,$13;" |
"nop; nop; nop;" |
: "=r"(cr) |
); |
|
CYG_INSTRUMENT_USER( 1, sr, cr ); |
|
asm volatile ( |
"mfc0 %0,$9;" |
"nop; nop; nop;" |
: "=r"(ctr) |
); |
|
asm volatile ( |
"mfc0 %0,$11;" |
"nop; nop; nop;" |
: "=r"(cpr) |
); |
|
CYG_INSTRUMENT_USER( 2, ctr, cpr ); |
#endif |
|
// if( count == 4 ) |
// { |
// HAL_ENABLE_INTERRUPTS(); |
// } |
|
// if( count >= 10 ) |
// for(;;); |
} |
#endif |
#if 0 |
{ |
static CYG_WORD32 istat[3] = { 0xffffffff,0xffffffff,0xffffffff }; |
int i; |
for( i = 0; i < 3; i++ ) |
{ |
CYG_WORD32 reg, sr; |
HAL_READ_UINT32( CYGHWR_HAL_MIPS_VRC4373_INTC_STAT0 + i * CYGHWR_HAL_MIPS_VRC4373_INTC_MASK_OFF, reg ); |
if( reg != istat[i] ) |
{ |
hal_diag_ai_write_char('~'); |
hal_diag_ai_write_char('0'+i); |
hal_diag_ai_write_hex8( reg ); |
istat[i] = reg; |
HAL_READ_UINT32( CYGHWR_HAL_MIPS_VRC4373_INTC_MASK0 + i * CYGHWR_HAL_MIPS_VRC4373_INTC_MASK_OFF, reg ); |
hal_diag_ai_write_char('.'); |
hal_diag_ai_write_hex8( reg ); |
#if 0 |
asm volatile ( |
"mfc0 %0,$12;" |
"nop; nop; nop;" |
: "=r"(sr) |
); |
hal_diag_ai_write_char('.'); |
hal_diag_ai_write_hex8( sr ); |
#endif |
} |
} |
} |
{ |
static CYG_WORD32 old_pins = 0; |
CYG_WORD32 reg; |
HAL_READ_UINT32( CYGHWR_HAL_MIPS_VRC4373_INTC_PINS, reg ); |
if( reg != old_pins ) |
{ |
hal_diag_ai_write_char('%'); |
hal_diag_ai_write_hex8( reg ); |
old_pins = reg; |
} |
} |
#endif |
#if 0 //def CYGPKG_HAL_MIPS_VR4300_VRC4373 |
|
// Wiggle one of the leds to show we are running |
|
if( (count % 50000 ) == 0 ) |
{ |
cyg_uint8 lr; |
{ int i; for( i = 0; i < 200; i++ ); } |
HAL_READ_UINT8( 0xc2000008, lr ); |
lr ^= 2; |
{ int i; for( i = 0; i < 200; i++ ); } |
HAL_WRITE_UINT8( 0xc2000008, lr ); |
|
} |
#endif |
} |
|
/*------------------------------------------------------------------------*/ |
/* End of hal_misc.c */ |
/v2_0/src/redboot_linux_exec.c
0,0 → 1,176
//========================================================================== |
// |
// redboot_linux_exec.c |
// |
// RedBoot exec command for Linux booting |
// |
//========================================================================== |
//####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): t@keshi.org |
// Contributors: t@keshi.org, jskov, dwmw2 |
// Date: 2001-07-09 |
// Purpose: RedBoot exec command for Linux booting |
// |
//####DESCRIPTIONEND#### |
// |
//=========================================================================== |
|
#include <redboot.h> |
|
#include <cyg/infra/cyg_type.h> |
#include <cyg/hal/hal_intr.h> |
#include <cyg/hal/hal_cache.h> |
#include <cyg/hal/hal_if.h> |
|
#define xstr(s) str(s) |
#define str(s...) #s |
|
typedef struct |
{ |
char *name; |
char *val; |
} t_env_var; |
|
struct parmblock { |
t_env_var memsize; |
t_env_var modetty0; |
t_env_var ethaddr; |
t_env_var env_end; |
char *argv[2]; |
char text[0]; |
}; |
|
static void do_exec(int argc, char *argv[]); |
RedBoot_cmd("exec", |
"Execute an image", |
"[-b <argv addr>] [-c \"kernel command line\"] [-w <timeout>]\n" |
" [<entry point>]", |
do_exec |
); |
|
static void |
do_exec(int argc, char *argv[]) |
{ |
cyg_uint32 entry = (cyg_uint32)entry_address?:CYGDAT_REDBOOT_MIPS_LINUX_BOOT_ENTRY; |
cyg_uint32 base_addr = CYGDAT_REDBOOT_MIPS_LINUX_BOOT_ARGV_ADDR; |
char *cmd_line = xstr(CYGDAT_REDBOOT_MIPS_LINUX_BOOT_COMMAND_LINE); |
bool base_addr_set, cmd_line_set, wait_time_set; |
int wait_time, res; |
char line[8]; |
|
struct option_info opts[3]; |
char *pcmd; |
struct parmblock *pb; |
void (*linux)(int, char **, void *); |
int oldints; |
hal_virtual_comm_table_t *__chan; |
int baud; |
|
init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, |
(void **)&base_addr, &base_addr_set, "base address"); |
init_opts(&opts[1], 'w', true, OPTION_ARG_TYPE_NUM, |
(void **)&wait_time, (bool *)&wait_time_set, "wait timeout"); |
init_opts(&opts[2], 'c', true, OPTION_ARG_TYPE_STR, |
(void **)&cmd_line, &cmd_line_set, "kernel command line"); |
|
if (!scan_opts(argc, argv, 1, opts, 3, (void *)&entry, |
OPTION_ARG_TYPE_NUM, "entry address")) |
return; |
|
linux = (void *)entry; |
|
__chan = CYGACC_CALL_IF_CONSOLE_PROCS(); |
baud = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD); |
|
diag_printf("Now booting linux kernel:\n"); |
diag_printf(" Base address 0x%08x Entry 0x%08x\n", base_addr, entry); |
diag_printf(" Cmdline : %s\n", cmd_line); |
|
if (wait_time_set) { |
diag_printf("About to start execution at %p - abort with ^C within %d seconds\n", |
(void *)entry, wait_time); |
res = _rb_gets(line, sizeof(line), wait_time*1000); |
if (res == _GETS_CTRLC) { |
return; |
} |
} |
|
HAL_DISABLE_INTERRUPTS(oldints); |
|
pb = (struct parmblock *)base_addr; |
pcmd = pb->text; |
|
pb->memsize.name = pcmd; |
pcmd += diag_sprintf(pcmd, "memsize"); |
pb->memsize.val = ++pcmd; |
pcmd += diag_sprintf(pcmd, "0x%08x", (ram_end - ram_start + 0xFFFFF) & ~0xFFFFF); |
|
pb->modetty0.name = ++pcmd; |
pcmd += diag_sprintf(pcmd, "modetty0"); |
pb->modetty0.val = ++pcmd; |
pcmd += diag_sprintf(pcmd, "%d,n,8,1,hw", baud); |
|
#ifdef CYGPKG_REDBOOT_NETWORKING |
pb->ethaddr.name = ++pcmd; |
pcmd += diag_sprintf(pcmd, "ethaddr"); |
pb->ethaddr.val = ++pcmd; |
pcmd += diag_sprintf(pcmd, "%02x.%02x.%02x.%02x.%02x.%02x", |
__local_enet_addr[0], __local_enet_addr[1], |
__local_enet_addr[2], __local_enet_addr[3], |
__local_enet_addr[4], __local_enet_addr[5]); |
pb->env_end.name = NULL; |
pb->env_end.val = NULL; |
#else |
pb->ethaddr.name = NULL; |
pb->ethaddr.val = NULL; |
#endif |
|
/* Point argv[0] at a handy `\0` */ |
pb->argv[0] = pcmd; |
pb->argv[1] = ++pcmd; |
|
strcpy(pcmd, cmd_line); |
|
HAL_DCACHE_SYNC(); |
HAL_ICACHE_DISABLE(); |
HAL_DCACHE_DISABLE(); |
HAL_DCACHE_SYNC(); |
HAL_ICACHE_INVALIDATE_ALL(); |
HAL_DCACHE_INVALIDATE_ALL(); |
|
linux(2, pb->argv, pb); |
} |
/v2_0/src/mips-stub.c
0,0 → 1,402
//======================================================================== |
// |
// mips-stub.h |
// |
// Helper functions for stub, generic to all MIPS 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, nickg |
// Contributors: Red Hat, nickg |
// Date: 1998-06-08 |
// Purpose: |
// Description: Helper functions for stub, generic to all MIPS processors |
// Usage: |
// |
//####DESCRIPTIONEND#### |
// |
//======================================================================== |
|
#include <stddef.h> |
|
#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> |
|
#define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS |
#include <cyg/hal/mips-regs.h> |
|
#include <cyg/hal/hal_arch.h> |
#include <cyg/hal/hal_intr.h> |
#include <cyg/hal/mips_opcode.h> |
|
typedef unsigned long t_inst; |
|
/*---------------------------------------------------------------------- |
* Asynchronous interrupt support |
*/ |
|
static struct |
{ |
t_inst *targetAddr; |
t_inst savedInstr; |
} asyncBuffer; |
|
/* Called to asynchronously interrupt a running program. |
Must be passed address of instruction interrupted. |
This is typically called in response to a debug port |
receive interrupt. |
*/ |
|
void |
install_async_breakpoint(void *epc) |
{ |
long gp_save; |
|
/* This may be called from a separately linked program, |
so we need to save and restore the incoming gp register |
and setup our stub local gp register. |
Alternatively, we could skip this foolishness if we |
compiled libstub with "-G 0". */ |
|
__asm__ volatile ( "move %0,$28\n" |
".extern _gp\n" |
"la $28,_gp\n" |
: "=r" (gp_save) ); |
|
asyncBuffer.targetAddr = epc; |
asyncBuffer.savedInstr = *(t_inst *)epc; |
*(t_inst *)epc = *(t_inst *)_breakinst; |
__instruction_cache(CACHE_FLUSH); |
__data_cache(CACHE_FLUSH); |
|
__asm__ volatile ( "move $28,%0\n" :: "r"(gp_save) ); |
} |
|
/*--------------------------------------------------------------------*/ |
/* Given a trap value TRAP, return the corresponding signal. */ |
|
int __computeSignal (unsigned int trap_number) |
{ |
switch (trap_number) |
{ |
case EXC_INT: |
/* External interrupt */ |
return SIGINT; |
|
case EXC_RI: |
/* Reserved instruction */ |
case EXC_CPU: |
/* Coprocessor unusable */ |
return SIGILL; |
|
case EXC_BP: |
/* Break point */ |
if (asyncBuffer.targetAddr != NULL) |
{ |
/* BP installed by serial driver to stop running program */ |
*asyncBuffer.targetAddr = asyncBuffer.savedInstr; |
__instruction_cache(CACHE_FLUSH); |
__data_cache(CACHE_FLUSH); |
asyncBuffer.targetAddr = NULL; |
return SIGINT; |
} |
return SIGTRAP; |
|
case EXC_OVF: |
/* Arithmetic overflow */ |
case EXC_TRAP: |
/* Trap exception */ |
case EXC_FPE: |
/* Floating Point Exception */ |
return SIGFPE; |
|
case EXC_IBE: |
/* Bus error (Ifetch) */ |
case EXC_DBE: |
/* Bus error (data load or store) */ |
return SIGBUS; |
|
case EXC_MOD: |
/* TLB modification exception */ |
case EXC_TLBL: |
/* TLB miss (Load or Ifetch) */ |
case EXC_TLBS: |
/* TLB miss (Store) */ |
case EXC_ADEL: |
/* Address error (Load or Ifetch) */ |
case EXC_ADES: |
/* Address error (Store) */ |
return SIGSEGV; |
|
case EXC_SYS: |
/* System call */ |
return SIGSYS; |
|
default: |
return SIGTERM; |
} |
} |
|
/* Return the trap number corresponding to the last-taken trap. */ |
|
int __get_trap_number (void) |
{ |
return (get_register (CAUSE) & CAUSE_EXCMASK) >> CAUSE_EXCSHIFT; |
} |
|
#if defined(CYGSEM_REDBOOT_BSP_SYSCALLS) |
int __is_bsp_syscall(void) |
{ |
return __get_trap_number() == EXC_SYS; |
} |
#endif |
|
/* Set the currently-saved pc register value to PC. This also updates NPC |
as needed. */ |
|
void set_pc (target_register_t pc) |
{ |
put_register (PC, pc); |
} |
|
|
/*---------------------------------------------------------------------- |
* Single-step support |
*/ |
|
/* Saved instruction data for single step support. */ |
|
static struct |
{ |
t_inst *targetAddr; |
t_inst savedInstr; |
} instrBuffer; |
|
|
/* 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) |
{ |
InstFmt inst; |
t_inst *pc = (t_inst *) get_register (PC); |
|
instrBuffer.targetAddr = pc + 1; /* set default */ |
|
inst.word = *pc; /* read the next instruction */ |
|
//diag_printf("pc %08x %08x\n",pc,inst.word); |
|
switch (inst.RType.op) { /* override default if branch */ |
case OP_SPECIAL: |
switch (inst.RType.func) { |
case OP_JR: |
case OP_JALR: |
instrBuffer.targetAddr = (t_inst *) get_register (inst.RType.rs); |
break; |
}; |
break; |
|
case OP_REGIMM: |
switch (inst.IType.rt) { |
case OP_BLTZ: |
case OP_BLTZL: |
case OP_BLTZAL: |
case OP_BLTZALL: |
if ((int)get_register (inst.IType.rs) < 0 ) |
instrBuffer.targetAddr = |
(t_inst *)(((signed short)inst.IType.imm<<2) |
+ (get_register (PC) + 4)); |
else |
instrBuffer.targetAddr = (t_inst *)(get_register (PC) + 8); |
break; |
case OP_BGEZ: |
case OP_BGEZL: |
case OP_BGEZAL: |
case OP_BGEZALL: |
if ((int)get_register (inst.IType.rs) >= 0 ) |
instrBuffer.targetAddr = |
(t_inst *)(((signed short)inst.IType.imm<<2) |
+ (get_register (PC) + 4)); |
else |
instrBuffer.targetAddr = (t_inst *)(get_register (PC) + 8); |
break; |
}; |
break; |
|
case OP_J: |
case OP_JAL: |
instrBuffer.targetAddr = |
(t_inst *)((inst.JType.target<<2) |
+ ((get_register (PC) + 4)&0xf0000000)); |
break; |
|
case OP_BEQ: |
case OP_BEQL: |
if (get_register (inst.IType.rs) == get_register (inst.IType.rt)) |
instrBuffer.targetAddr = |
(t_inst *)(((signed short)inst.IType.imm<<2) |
+ (get_register (PC) + 4)); |
else |
instrBuffer.targetAddr = (t_inst *)(get_register (PC) + 8); |
break; |
case OP_BNE: |
case OP_BNEL: |
if (get_register (inst.IType.rs) != get_register (inst.IType.rt)) |
instrBuffer.targetAddr = |
(t_inst *)(((signed short)inst.IType.imm<<2) |
+ (get_register (PC) + 4)); |
else |
instrBuffer.targetAddr = (t_inst *)(get_register (PC) + 8); |
break; |
case OP_BLEZ: |
case OP_BLEZL: |
if ((int)get_register (inst.IType.rs) <= 0) |
instrBuffer.targetAddr = |
(t_inst *)(((signed short)inst.IType.imm<<2) + (get_register (PC) + 4)); |
else |
instrBuffer.targetAddr = (t_inst *)(get_register (PC) + 8); |
break; |
case OP_BGTZ: |
case OP_BGTZL: |
if ((int)get_register (inst.IType.rs) > 0) |
instrBuffer.targetAddr = |
(t_inst *)(((signed short)inst.IType.imm<<2) + (get_register (PC) + 4)); |
else |
instrBuffer.targetAddr = (t_inst *)(get_register (PC) + 8); |
break; |
|
#ifdef CYGHWR_HAL_MIPS_FPU |
|
case OP_COP1: |
if (inst.RType.rs == OP_BC) |
switch (inst.RType.rt) { |
case COPz_BCF: |
case COPz_BCFL: |
if (get_register (FCR31) & FCR31_C) |
instrBuffer.targetAddr = (t_inst *)(get_register (PC) + 8); |
else |
instrBuffer.targetAddr = |
(t_inst *)(((signed short)inst.IType.imm<<2) |
+ (get_register (PC) + 4)); |
break; |
case COPz_BCT: |
case COPz_BCTL: |
if (get_register (FCR31) & FCR31_C) |
instrBuffer.targetAddr = |
(t_inst *)(((signed short)inst.IType.imm<<2) |
+ (get_register (PC) + 4)); |
else |
instrBuffer.targetAddr = (t_inst *)(get_register (PC) + 8); |
break; |
}; |
break; |
#endif |
|
} |
} |
|
|
/* Clear the single-step state. */ |
|
void __clear_single_step (void) |
{ |
//diag_printf("clear_ss ta %08x\n",instrBuffer.targetAddr); |
if (instrBuffer.targetAddr != NULL) |
{ |
*instrBuffer.targetAddr = instrBuffer.savedInstr; |
instrBuffer.targetAddr = NULL; |
} |
instrBuffer.savedInstr = NOP_INSTR; |
} |
|
|
void __install_breakpoints () |
{ |
//diag_printf("install_bpt ta %08x\n",instrBuffer.targetAddr); |
if (instrBuffer.targetAddr != NULL) |
{ |
instrBuffer.savedInstr = *instrBuffer.targetAddr; |
*instrBuffer.targetAddr = __break_opcode (); |
//diag_printf("ta %08x si %08x *ta %08x\n", |
// instrBuffer.targetAddr,instrBuffer.savedInstr,*instrBuffer.targetAddr); |
|
/* Ensure that the planted breakpoint makes it out to memory and |
is subsequently loaded into the instruction cache. |
*/ |
__data_cache (CACHE_FLUSH) ; |
__instruction_cache (CACHE_FLUSH) ; |
} |
|
/* Install the breakpoints in the breakpoint list */ |
__install_breakpoint_list(); |
} |
|
void __clear_breakpoints (void) |
{ |
__clear_breakpoint_list(); |
} |
|
|
/* 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)(unsigned long)&_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) |
{ |
put_register (PC, get_register (PC) + 4); |
} |
|
#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS |
/v2_0/src/context.S
0,0 → 1,286
##=============================================================================## |
## context.S |
## |
## MIPS 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 |
## Contributors: nickg |
## Date: 1998-04-27 |
## Purpose: MIPS 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 <cyg/hal/arch.inc> |
|
#ifdef at |
#undef at |
#endif |
|
#------------------------------------------------------------------------------ |
# hal_thread_switch_context |
# Switch thread contexts |
# A0 = address of sp of next thread to execute |
# A1 = address of sp save location of current thread |
|
.global hal_thread_switch_context |
hal_thread_switch_context: |
|
addi sp,sp,-mipsreg_size # space for registers |
|
# store GPRs |
.set noat |
#ifndef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM |
sgpr 0,sp |
sgpr 1,sp |
sgpr 2,sp |
sgpr 3,sp |
sgpr 4,sp |
sgpr 5,sp |
sgpr 6,sp |
sgpr 7,sp |
sgpr 8,sp |
sgpr 9,sp |
sgpr 10,sp |
sgpr 11,sp |
sgpr 12,sp |
sgpr 13,sp |
sgpr 14,sp |
sgpr 15,sp |
sgpr 24,sp |
sgpr 25,sp |
sgpr 28,sp # == GP |
#endif |
sgpr 16,sp |
sgpr 17,sp |
sgpr 18,sp |
sgpr 19,sp |
sgpr 20,sp |
sgpr 21,sp |
sgpr 22,sp |
sgpr 23,sp |
# sgpr 26,sp # == K0 |
# sgpr 27,sp # == K1 |
# sgpr 29,sp # == SP |
sgpr 30,sp # == FP |
sgpr 31,sp # == RA |
spc $31,sp # == PC (to help with debugging) |
.set at |
|
#ifndef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM |
|
mflo t0 # save LO and HI regs |
mfhi t1 |
slo t0,sp |
shi t1,sp |
|
#endif |
|
hal_fpu_save_callee sp |
|
#ifndef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM |
|
hal_fpu_save_caller sp |
|
#endif |
|
addi t0,sp,mipsreg_size # save SP in reg dump |
ssp t0,sp |
|
mfc0 t1,status # Save status register |
sw t1,mipsreg_sr(sp) |
|
sw sp,0(a1) # save sp in save loc |
|
# Now load the destination thread by dropping through |
# to hal_thread_load_context |
|
#------------------------------------------------------------------------------ |
# hal_thread_load_context |
# Load thread context |
# A0 = address of sp 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. |
|
.global hal_thread_load_context |
hal_thread_load_context: |
|
lw sp,0(a0) # load new SP directly |
|
#ifndef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM |
|
hal_fpu_load_caller sp |
|
#endif |
|
hal_fpu_load_callee sp |
|
#ifndef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM |
|
lw t0,mipsreg_hi(sp) # load HI and LO regs |
lw t1,mipsreg_lo(sp) |
mthi t0 |
mtlo t1 |
|
#endif |
|
# load GPRs |
.set noat |
# lgpr 0,sp |
lgpr 4,sp # A0, must load for thread startup |
#ifndef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM |
lgpr 1,sp |
lgpr 2,sp |
lgpr 3,sp |
lgpr 5,sp |
lgpr 6,sp |
lgpr 7,sp |
lgpr 8,sp |
lgpr 9,sp |
lgpr 10,sp |
lgpr 11,sp |
lgpr 12,sp |
lgpr 13,sp |
lgpr 14,sp |
lgpr 15,sp |
lgpr 24,sp |
lgpr 25,sp |
#endif |
lgpr 16,sp |
lgpr 17,sp |
lgpr 18,sp |
lgpr 19,sp |
lgpr 20,sp |
lgpr 21,sp |
lgpr 22,sp |
lgpr 23,sp |
# lgpr 26,sp # == K0 |
# lgpr 27,sp # == K1 |
# lgpr 28,sp # == GP |
# lgpr 29,sp # == SP |
lgpr 30,sp # == FP |
lgpr 31,sp # == RA |
.set at |
|
lw a2,mipsreg_sr(sp) # A2 = saved SR |
lsp sp,sp # SP = saved SP |
|
hal_cpu_int_merge a2 # Merge with current SR |
|
jr ra # return via ra |
nop # delay slot - must be nop |
|
#------------------------------------------------------------------------------ |
# HAL longjmp, setjmp implementations |
# hal_setjmp saves only to callee save registers 16-23, 28, 30, 31[ra], 29[sp] |
# into buffer supplied in a0[arg0] |
# Note: These definitions are repeated in hal_arch.h. If changes are required |
# remember to update both sets. |
|
#define CYGARC_JMP_BUF_SP 0 |
#define CYGARC_JMP_BUF_R16 1 |
#define CYGARC_JMP_BUF_R17 2 |
#define CYGARC_JMP_BUF_R18 3 |
#define CYGARC_JMP_BUF_R19 4 |
#define CYGARC_JMP_BUF_R20 5 |
#define CYGARC_JMP_BUF_R21 6 |
#define CYGARC_JMP_BUF_R22 7 |
#define CYGARC_JMP_BUF_R23 8 |
#define CYGARC_JMP_BUF_R28 9 |
#define CYGARC_JMP_BUF_R30 10 |
#define CYGARC_JMP_BUF_R31 11 |
|
#define CYGARC_JMP_BUF_SIZE 12 |
|
// FIXME: The follwing restricts us to using only 32 bit registers |
// in jump buffers. If/when we move to a full 64 bit architecture, |
// this will need to change, as will the instructions that we use to |
// save and restore them. |
|
#define jmpbuf_regsize 4 |
|
.globl hal_setjmp |
.ent hal_setjmp |
hal_setjmp: |
sw $31,CYGARC_JMP_BUF_R31*jmpbuf_regsize(a0) # ra (link) |
sw $30,CYGARC_JMP_BUF_R30*jmpbuf_regsize(a0) |
sw $28,CYGARC_JMP_BUF_R28*jmpbuf_regsize(a0) # gp, optimize out? |
sw $23,CYGARC_JMP_BUF_R23*jmpbuf_regsize(a0) |
sw $22,CYGARC_JMP_BUF_R22*jmpbuf_regsize(a0) |
sw $21,CYGARC_JMP_BUF_R21*jmpbuf_regsize(a0) |
sw $20,CYGARC_JMP_BUF_R20*jmpbuf_regsize(a0) |
sw $19,CYGARC_JMP_BUF_R19*jmpbuf_regsize(a0) |
sw $18,CYGARC_JMP_BUF_R18*jmpbuf_regsize(a0) |
sw $17,CYGARC_JMP_BUF_R17*jmpbuf_regsize(a0) |
sw $16,CYGARC_JMP_BUF_R16*jmpbuf_regsize(a0) |
sw sp,CYGARC_JMP_BUF_SP*jmpbuf_regsize(a0) # $29 |
li v0,0 |
jr ra |
nop # delay slot |
.end hal_setjmp |
|
.globl hal_longjmp |
.ent hal_longjmp |
hal_longjmp: |
lw $31,CYGARC_JMP_BUF_R31*jmpbuf_regsize(a0) # ra (link) |
lw $30,CYGARC_JMP_BUF_R30*jmpbuf_regsize(a0) |
lw $28,CYGARC_JMP_BUF_R28*jmpbuf_regsize(a0) # gp, optimize out? |
lw $23,CYGARC_JMP_BUF_R23*jmpbuf_regsize(a0) |
lw $22,CYGARC_JMP_BUF_R22*jmpbuf_regsize(a0) |
lw $21,CYGARC_JMP_BUF_R21*jmpbuf_regsize(a0) |
lw $20,CYGARC_JMP_BUF_R20*jmpbuf_regsize(a0) |
lw $19,CYGARC_JMP_BUF_R19*jmpbuf_regsize(a0) |
lw $18,CYGARC_JMP_BUF_R18*jmpbuf_regsize(a0) |
lw $17,CYGARC_JMP_BUF_R17*jmpbuf_regsize(a0) |
lw $16,CYGARC_JMP_BUF_R16*jmpbuf_regsize(a0) |
lw sp,CYGARC_JMP_BUF_SP*jmpbuf_regsize(a0) # $29 |
move v0,a1 |
jr ra |
nop # delay slot |
.end hal_longjmp |
|
|
#------------------------------------------------------------------------------ |
# end of context.S |
/v2_0/src/vectors.S
0,0 → 1,1022
##============================================================================= |
## |
## vectors.S |
## |
## MIPS 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): nickg |
## Contributors: nickg, dmoseley |
## Date: 1998-02-04 |
## Purpose: MIPS 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/system.h> |
#include <pkgconf/hal.h> |
|
#ifdef CYGPKG_KERNEL |
# include <pkgconf/kernel.h> |
#endif |
|
#include <cyg/hal/arch.inc> |
#include <cyg/hal/hal_arch.h> |
|
#ifdef at |
#undef at |
#endif |
.extern cyg_instrument |
|
##----------------------------------------------------------------------------- |
## Hardware supplied vectors |
|
.set noreorder |
|
.section ".reset_vector","ax" |
|
# Reset vector at 0xBFC00000 |
|
FUNC_START(reset_vector) |
|
#ifndef CYG_HAL_STARTUP_RAM |
# if defined(CYGPKG_HAL_RESET_VECTOR_FIRST_CODE) |
hal_reset_vector_first_code |
# endif |
# if defined(CYGPKG_HAL_EARLY_INIT) |
hal_early_init |
# endif |
# Decide whether this is an NMI, cold or warm boot. |
|
mfc0 k0,status # get status reg |
lui k1,0x0008 # isolate NMI bit |
and k1,k1,k0 |
beqz k1,1f # skip if zero |
nop |
|
lar k1,__nmi_entry # jump to ROM nmi code |
jalr k1 |
nop |
1: |
lui k1,0x0010 # isolate soft reset bit |
and k1,k1,k0 |
beqz k1,2f # skip if zero |
nop |
|
lar k1,__warm_start # jump to ROM warm_start code |
jr k1 |
nop |
2: |
la k0,INITIAL_CONFIG0 # Set up config0 register |
mtc0 k0,config0 # to disable cache |
#endif |
lar v0,_start # jump to start |
#ifdef CYGARC_START_FUNC_UNCACHED |
CYGARC_ADDRESS_REG_UNCACHED(v0) |
#endif |
|
jr v0 |
nop # (delay slot) |
|
FUNC_END(reset_vector) |
|
.section ".debug_vector","ax" |
|
# Debug vector at 0xBFC00200 |
|
FUNC_START(debug_vector) |
la k0,32*4 |
la k1,hal_vsr_table # Get VSR table |
lw k1,32*4(k1) # load debug vector |
jr k1 # go there |
nop # (delay slot) |
FUNC_END(debug_vector) |
|
.section ".other_vector","ax" |
|
# Common vector at 0x80000080 or 0xBFC00180 |
|
FUNC_START(other_vector) |
mfc0 k0,cause # K0 = exception cause |
nop |
andi k0,k0,0x7F # isolate exception code |
la k1,hal_vsr_table # address of VSR table |
add k1,k1,k0 # offset of VSR entry |
lw k1,0(k1) # k1 = pointer to VSR |
jr k1 # go there |
nop # (delay slot) |
FUNC_END(other_vector) |
|
.section ".utlb_vector","ax" |
|
FUNC_START(utlb_vector) |
mfc0 k0,cause # K0 = exception cause |
nop |
andi k0,k0,0x7F # isolate exception code |
la k1,hal_vsr_table # address of VSR table |
add k1,k1,k0 # offset of VSR entry |
lw k1,0(k1) # k1 = pointer to VSR |
jr k1 # go there |
nop # (delay slot) |
FUNC_END(utlb_vector) |
|
##----------------------------------------------------------------------------- |
## Startup code |
|
.text |
|
FUNC_START(_start) |
|
# Initialize hardware |
hal_cpu_init |
hal_diag_init |
hal_mmu_init |
hal_fpu_init |
hal_memc_init |
hal_intc_init |
hal_cache_init |
hal_timer_init |
|
#ifdef CYGARC_START_FUNC_UNCACHED |
# switch to cached execution address if necessary |
# assumption is that hal_cache_init makes this safe |
lar v0,1f |
jr v0 |
nop |
1: |
#endif |
|
# Load Global Pointer register. |
la gp,_gp |
|
# load initial stack pointer |
la a0,__interrupt_stack |
move sp,a0 |
|
hal_mon_init |
|
#ifdef CYG_HAL_STARTUP_ROM |
# Copy data from ROM to RAM |
|
.extern hal_copy_data |
jal hal_copy_data |
nop |
|
#endif |
|
# Zero BSS |
|
.extern hal_zero_bss |
jal hal_zero_bss |
nop |
|
# Call variant and platform HAL |
# initialization routines. |
|
.extern hal_variant_init |
jal hal_variant_init |
nop |
|
.extern hal_platform_init |
jal hal_platform_init |
nop |
|
# Call constructors |
.extern cyg_hal_invoke_constructors |
jal cyg_hal_invoke_constructors |
nop |
|
#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) |
.extern initialize_stub |
jal initialize_stub |
nop |
#endif |
#if defined(CYGDBG_HAL_MIPS_DEBUG_GDB_CTRLC_SUPPORT) |
.extern hal_ctrlc_isr_init |
jal hal_ctrlc_isr_init |
nop |
#endif |
|
# Call cyg_start |
|
.extern cyg_start |
j cyg_start |
lui ra,0 |
|
FUNC_END(_start ) |
|
|
##----------------------------------------------------------------------------- |
|
FUNC_START(__warm_start) |
|
## The following is debug code left in here for now in case it |
## proves useful in the near future. |
#if 0 |
move s0,t0 |
move s1,a1 |
|
# hal_diag_init |
|
hal_diag_writec '$' |
mvafc0 a0,$30 # get ErrorEPC |
lar k0,hal_diag_ai_write_hex8 |
jalr k0 |
nop |
hal_diag_writec '-' |
move a0,s0 |
jalr k0 |
nop |
hal_diag_writec '-' |
move a0,s1 |
jalr k0 |
nop |
1: |
b 1b |
nop |
#endif |
|
# Treat a warm-start either as a cold-start or an NMI |
#if defined(CYGHWR_HAL_MIPS_WARMSTART_COLDSTART) |
lar v0,_start # jump to start |
jr v0 |
nop # (delay slot) |
#else |
# Defaults to NMI |
b __nmi_entry |
nop |
#endif |
|
FUNC_END(__warm_start) |
|
##----------------------------------------------------------------------------- |
|
FUNC_START(__nmi_entry) |
|
# Clear exception state |
hal_cpu_except_enable |
|
# Move the ErrorEPC register to the EPC register so that the |
# default exception handler saves the right PC value. |
mvafc0 k0,$30 |
nop; nop; nop; |
mvatc0 k0,epc |
nop; nop; nop; |
|
#if (INITIAL_SR & 0x00400000) == 0 |
# Taking this exception will have set the BEV bit to 1. |
# If we normally run with it zero, we must clear it here. |
mfc0 k0,status |
la k1,0xFFBFFFFF |
and k0,k0,k1 |
mtc0 k0,status |
#endif |
|
la k0,34*4 |
la k1,hal_vsr_table # Get VSR table |
lw k1,34*4(k1) # load NMI vector |
jr k1 # go there |
nop # (delay slot) |
|
FUNC_END(__nmi_entry) |
|
##----------------------------------------------------------------------------- |
## Default exception VSR. |
## Saves machine state and calls external handling code. |
|
FUNC_START(__default_exception_vsr) |
|
# We enter here with all of the CPU state still |
# in its registers except: |
# K0 = vector index |
# K1 = address of this function |
|
move k1,sp # K1 = original SP |
|
addi sp,sp,-mips_exception_decrement |
# space for registers + safety margin |
|
sw k0,mipsreg_vector(sp) # store vector |
|
# store GPRs |
.set noat |
sgpr 0,sp |
sgpr 1,sp |
sgpr 2,sp |
sgpr 3,sp |
sgpr 4,sp |
sgpr 5,sp |
sgpr 6,sp |
sgpr 7,sp |
sgpr 8,sp |
sgpr 9,sp |
sgpr 10,sp |
sgpr 11,sp |
sgpr 12,sp |
sgpr 13,sp |
sgpr 14,sp |
sgpr 15,sp |
sgpr 16,sp |
sgpr 17,sp |
sgpr 18,sp |
sgpr 19,sp |
sgpr 20,sp |
sgpr 21,sp |
sgpr 22,sp |
sgpr 23,sp |
sgpr 24,sp |
sgpr 25,sp |
# sgpr 26,sp # == K0 |
# sgpr 27,sp # == K1 |
sgpr 28,sp # == GP |
# sgpr 29,sp # == SP |
sgpr 30,sp # == FP |
sgpr 31,sp # == RA |
.set at |
|
mfhi a0 |
mflo a1 |
shi a0,sp |
slo a1,sp |
|
# K1 contains original SP |
ssp k1,sp # store in reg dump |
|
# save remaining machine state registers |
mfc0 t0,cause |
mfc0 t1,status |
mfc0 t2,cachectrl |
mvafc0 t3,badvr |
mfc0 t4,config |
mfc0 t5,prid |
mvafc0 t6,epc |
|
sw t0,mipsreg_cause(sp) |
sw t1,mipsreg_sr(sp) |
sw t2,mipsreg_cachectrl(sp) |
sva t3,mipsreg_badvr(sp) |
sw t4,mipsreg_config(sp) |
sw t5,mipsreg_prid(sp) |
sva t6,mipsreg_pc(sp) |
|
hal_fpu_save sp |
|
# The machine state is now all saved on the stack. |
|
hal_diag_excpt_start |
|
# Load Global Pointer register. |
la gp,_gp |
|
move s0,sp # save pointer to saved state |
|
#if defined(CYGSEM_HAL_ROM_MONITOR) && \ |
defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK) |
|
la a0,__interrupt_stack # a0 = stack top |
la a1,__interrupt_stack_base # a1 = stack base |
sub a3,sp,a1 # a3 = sp - base |
bltz a3,1f # not on istack if < 0 |
nop # delay slot |
sub t0,a0,sp # t0 = top - sp |
bgtz t0,8f # already on istack if > 0 |
nop # delay slot |
1: |
move sp,a0 # switch to istack |
8: |
addi sp,sp,-8 # space for old SP |
# (8 to keep dword alignment!) |
sw s0,0(sp) # save old SP on stack |
|
#endif |
addi sp,sp,-mips_stack_frame_size # make a null frame |
|
# Need to set up back pointers etc. ??? |
|
hal_cpu_except_enable # reenable exceptions |
|
.extern cyg_hal_exception_handler |
jal cyg_hal_exception_handler # call C code |
move a0,s0 # arg0 = register dump (delay slot) |
|
#if defined(CYGSEM_HAL_ROM_MONITOR) && \ |
defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK) |
|
# If we are returning from the last nested exception, move back |
# to the thread stack. |
# Since we have arranged for the top of stack location to |
# contain the sp we need to go back to here, just pop it off |
# and put it in SP. |
|
lw sp,mips_stack_frame_size(sp) # sp = *sp |
subu sp,sp,mips_stack_frame_size # make a null frame |
#endif |
|
j restore_state |
nop |
|
FUNC_END(__default_exception_vsr) |
|
##------------------------------------------------------------------------------ |
## Default interrupt VSR. |
## Saves machine state and calls appropriate ISR. When done, calls |
## interrupt_end() to finish up and possibly reschedule. |
|
FUNC_START(__default_interrupt_vsr) |
|
|
# We enter here with all of the CPU state still |
# in its registers except: |
# K0 = vector index |
# K1 = address of this function |
|
move k1,sp # K1 = original SP |
|
addi sp,sp,-mips_exception_decrement |
# space for registers + safety margin |
|
sw k0,mipsreg_vector(sp) # store vector |
|
# store GPRs |
.set noat |
sgpr 0,sp |
sgpr 1,sp |
sgpr 2,sp |
sgpr 3,sp |
sgpr 4,sp |
sgpr 5,sp |
sgpr 6,sp |
sgpr 7,sp |
sgpr 8,sp |
sgpr 9,sp |
sgpr 10,sp |
sgpr 11,sp |
sgpr 12,sp |
sgpr 13,sp |
sgpr 14,sp |
sgpr 15,sp |
sgpr 16,sp |
sgpr 17,sp |
sgpr 18,sp |
sgpr 19,sp |
sgpr 20,sp |
sgpr 21,sp |
sgpr 22,sp |
sgpr 23,sp |
sgpr 24,sp |
sgpr 25,sp |
# sgpr 26,sp # == K0 |
# sgpr 27,sp # == K1 |
sgpr 28,sp # == GP |
# sgpr 29,sp # == SP |
sgpr 30,sp # == FP |
sgpr 31,sp # == RA |
.set at |
|
mfhi a0 |
mflo a1 |
shi a0,sp |
slo a1,sp |
|
# K1 contains original SP |
ssp k1,sp # store in reg dump |
|
mfc0 t1,status |
mfc0 t2,cachectrl |
mvafc0 t3,epc |
|
sw t1,mipsreg_sr(sp) |
sw t2,mipsreg_cachectrl(sp) |
sva t3,mipsreg_pc(sp) |
|
hal_fpu_save sp |
|
# The machine state is now all saved on the stack. |
|
# Load Global Pointer register. |
la gp,_gp |
|
#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT |
.extern cyg_scheduler_sched_lock |
la v0,cyg_scheduler_sched_lock |
lw a0,0(v0) |
addi a0,a0,1 |
sw a0,0(v0) |
#endif |
|
move s0,sp # save pointer to saved state |
|
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK |
|
la a0,__interrupt_stack # a0 = stack top |
la a1,__interrupt_stack_base # a1 = stack base |
sub a3,sp,a1 # a3 = sp - base |
bltz a3,1f # not on istack if < 0 |
nop # delay slot |
sub t0,a0,sp # t0 = top - sp |
bgtz t0,8f # already on istack if > 0 |
nop # delay slot |
1: |
move sp,a0 # switch to istack |
8: |
addi sp,sp,-8 # space for old SP |
# (8 to keep dword alignment!) |
sw s0,0(sp) # save old SP on stack |
|
#endif |
|
subu sp,sp,mips_stack_frame_size # make a null frame |
|
# Need to set up back pointers etc. ??? |
|
# Decode external interrupt via interrupt controller |
|
hal_intc_decode s2 |
|
# Here, s2 contains the number of the interrupt being serviced, |
# we need to derive from that the vector number to call in the ISR |
# table. |
|
hal_intc_translate s2,s1 |
|
# Here s1 is the number of the vector to be called and s2 is |
# the number of the interrupt being serviced. |
|
hal_diag_intr_start |
|
#if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR) |
|
# Call cyg_instrument to record that this interrupt is being raised. |
|
li a0,0x0301 # a0 = type = INTR,RAISE |
move a1,s1 # a1 = vector number |
jal cyg_instrument # call instrument function |
move a2,s2 # a2 = interrupt number |
#endif |
|
#if defined(CYGDBG_HAL_MIPS_DEBUG_GDB_CTRLC_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 |
la v0,hal_saved_interrupt_state |
sw s0,0(v0) |
|
#endif |
|
sll s1,s1,2 # s1 = byte offset of vector |
|
hal_cpu_except_enable # reenable exceptions |
|
la t2,hal_interrupt_handlers # handler table |
add t2,t2,s1 # address of ISR ptr |
lw t2,0(t2) # ISR pointer |
|
la a1,hal_interrupt_data # data table |
add a1,a1,s1 # address of data ptr |
lw a1,0(a1) # Data pointer |
|
move a0,s2 # pass interrupt number |
|
jalr t2 # call ISR via t2 |
nop # (delay slot) |
|
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK |
|
# If we are returning from the last nested interrupt, move back |
# to the thread stack. interrupt_end() must be called on the |
# thread stack since it potentially causes a context switch. |
# Since we have arranged for the top of stack location to |
# contain the sp we need to go back to here, just pop it off |
# and put it in SP. |
|
|
lw sp,mips_stack_frame_size(sp) # sp = *sp |
subu sp,sp,mips_stack_frame_size # make a null frame |
#endif |
|
#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT |
|
# We only need to call _interrupt_end() when there is a kernel |
# present to do any tidying up. |
|
# On return v0 bit 1 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. |
|
# Note that s0, s1 and s2 are defined to be preserved across |
# calls by the calling convention, so they still contain |
# the register dump, the vector offset and the interrupt number |
# respectively. |
|
move s2,v0 |
|
la a1,hal_interrupt_objects # interrupt object table |
add a1,a1,s1 # address of object ptr |
lw a1,0(a1) # a1 = object ptr |
|
move a2,s0 # arg3 = saved register dump |
|
.extern interrupt_end |
jal interrupt_end # call into C to finish off |
move a0,v0 # put ISR result in arg0 |
|
move v0,s2 # return value from isr |
#endif |
|
restore_state: |
#if defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon) |
move k0,v0 |
#endif |
|
# All done, restore CPU state and continue |
|
addi sp,sp,mips_stack_frame_size # retrieve CPU state ptr |
|
# Disable interrupts again while we restore state. |
hal_cpu_int_disable |
|
hal_diag_restore |
|
hal_fpu_load sp |
|
lw t0,mipsreg_cachectrl(sp) |
lhi t1,sp |
llo t2,sp |
|
mtc0 t0,cachectrl |
mthi t1 |
mtlo t2 |
|
# load GPRs |
.set noat |
# lgpr 0,sp |
lgpr 1,sp |
lgpr 2,sp |
lgpr 3,sp |
lgpr 4,sp |
lgpr 5,sp |
lgpr 6,sp |
lgpr 7,sp |
lgpr 8,sp |
lgpr 9,sp |
lgpr 10,sp |
lgpr 11,sp |
lgpr 12,sp |
lgpr 13,sp |
lgpr 14,sp |
lgpr 15,sp |
lgpr 16,sp |
lgpr 17,sp |
lgpr 18,sp |
lgpr 19,sp |
lgpr 20,sp |
lgpr 21,sp |
lgpr 22,sp |
lgpr 23,sp |
lgpr 24,sp |
lgpr 25,sp |
# lgpr 26,sp # == K0 |
# lgpr 27,sp # == K1 |
lgpr 28,sp # == GP |
# lgpr 29,sp # == SP |
lgpr 30,sp # == FP |
lgpr 31,sp # == RA |
.set at |
|
#if defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon) |
|
# If we have a Cygmon that wants to listen to network interrupts, then |
# the return code from the earlier call to hal_default_isr() will |
# have been negative to indicate this. So we jump into Cygmon here |
# because Cygmon requires the processor state to be the same as when |
# the interrupt was taken, but with k0 as the exception number. |
|
bgez k0,1f |
nop |
# Check for new cygmon |
sw k0,(mipsreg_regs+26*4)(sp) # save k0 |
la k1,0x80000100 + 41*4 # New cygmon "magic" id |
lw k1,0(k1) |
lui k0,0x55aa |
ori k0,0x4321 |
bne k0,k1,1f |
|
# Need to let cygmon handle this |
la k1,0x80000100 + 39*4 # stub entry vector |
lw k0,(mipsreg_regs+26*4)(sp) # restore k0 |
lw k1,0(k1) |
lw sp,(mipsreg_regs+29*4)(sp) # restore SP |
sll k0,1 # clear bit 31. |
jr k1 |
srl k0,1 |
1: |
#endif |
|
lw k1,mipsreg_sr(sp) # K1 = saved SR |
|
#if 0 < CYGINT_HAL_MIPS_INTERRUPT_RETURN_KEEP_SR_IM |
# Keep the current settings of the IM[7:0] bits within the status |
# register. These may be used as interrupt masks, so if an ISR or |
# DSR masks interrupts they must be preserved. |
# If they are not used, then this does no harm. |
ori k0,zero,0xff00 |
nor k0,k0,k0 # 0xffff00ff |
and k1,k1,k0 # all interrupts disabled |
|
mfc0 k0,status # V0 = current SR |
nop |
nop |
andi k0,k0,0xff00 # preserve interrupt set |
or k1,k1,k0 # insert into "saved SR" |
#endif // 0 < CYGINT_HAL_MIPS_INTERRUPT_RETURN_KEEP_SR_IM |
lva k0,mipsreg_pc(sp) # K0 = return PC |
lsp sp,sp # load SP |
|
# Invoke CPU specific mechanism for returning from this |
# exception |
|
hal_cpu_eret k0,k1 |
|
FUNC_END(__default_interrupt_vsr) |
|
hal_intc_decode_data |
|
##----------------------------------------------------------------------------- |
## Execute pending DSRs on the interrupt stack with interrupts enabled. |
## Note: this can only be called from code running on a thread stack |
|
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK |
.extern cyg_interrupt_call_pending_DSRs |
|
FUNC_START(hal_interrupt_stack_call_pending_DSRs) |
mfc0 t0,status # get status register value |
la v0,__interrupt_stack # v0 = interrupt stack |
move v1,sp # v1 = original stack ptr |
move sp,v0 # sp = interrupt stack |
addi sp,sp,-32 # make a null frame |
sw v1,16(sp) # save old sp |
sw ra,20(sp) # save old ra |
sw t0,24(sp) # save old sr |
|
hal_cpu_int_enable |
|
jal cyg_interrupt_call_pending_DSRs # call back to kernel |
nop |
|
lw a0,24(sp) # get status reg |
|
hal_cpu_int_merge a0 # merge with current SR |
|
lw ra,20(sp) # restore ra |
lw sp,16(sp) # restore sp |
|
jr ra # go back |
nop # delay slot |
|
FUNC_END(hal_interrupt_stack_call_pending_DSRs) |
#endif |
|
##----------------------------------------------------------------------------- |
## Short circuit in case any code tries to use "__gccmain()" |
|
FUNC_START(__gccmain) |
jr ra |
nop |
FUNC_END(__gccmain) |
|
##----------------------------------------------------------------------------- |
## Switch to a new stack. |
## This is used in RedBoot to allow code to execute in a different |
## stack context. |
|
FUNC_START(hal_program_new_stack) |
# Arguments are: |
# a0 = function to call |
# a1 = stack pointer to use |
|
move v1,sp # v1 = original stack ptr |
move sp,a1 # sp = new stack |
addi sp,sp,-32 # make a null frame |
sva v1,8(sp) # save old sp |
sva ra,16(sp) # save old ra |
|
jalr a0 # call function |
nop |
|
lva ra,16(sp) # restore ra |
lva sp,8(sp) # restore sp |
|
jr ra # go back |
nop # delay slot |
|
FUNC_END(hal_program_new_stack) |
|
##----------------------------------------------------------------------------- |
## hal_zero_bss |
## Zero bss. Done in assembler to be optimal rather than using memset, |
## which would risk zeroing bss while using it. |
|
FUNC_START(hal_zero_bss) |
#ifdef CYGHWR_HAL_MIPS_64BIT |
#define STORE_OP sd |
#define BLOCK_SHIFT 6 |
#else |
#define STORE_OP sw |
#define BLOCK_SHIFT 5 |
#endif |
la a0,__bss_start # start of bss |
la a1,__bss_end # end of bss |
andi a2,a0,mips_regsize-1 # is bss aligned? |
bne a2,zero,1f # skip word copy |
nop |
|
# loop with 8 stores per loop |
subu a3,a1,a0 # get length |
srl a3,a3,BLOCK_SHIFT # get number of blocks |
sll a3,a3,BLOCK_SHIFT # get length of blocks |
addu a3,a0,a3 # get end addr of blocks |
2: STORE_OP zero,(mips_regsize*0)(a0) |
STORE_OP zero,(mips_regsize*1)(a0) |
STORE_OP zero,(mips_regsize*2)(a0) |
STORE_OP zero,(mips_regsize*3)(a0) |
STORE_OP zero,(mips_regsize*4)(a0) |
STORE_OP zero,(mips_regsize*5)(a0) |
STORE_OP zero,(mips_regsize*6)(a0) |
STORE_OP zero,(mips_regsize*7)(a0) |
addu a0,a0,mips_regsize*8 # next addr |
bne a3,a0,2b # to next store |
nop |
|
# If length is a multiple of block size then we |
# are done and need to skip the byte loop |
beq a1,a0,3f |
nop |
|
# finish 1 byte at a time |
1: sb zero,0(a0) # zero memory |
addiu a0,a0,1 # next addr |
bne a0,a1,1b # to next store |
nop |
3: jr ra |
nop |
FUNC_END(hal_zero_bss) |
|
|
##----------------------------------------------------------------------------- |
## VSR springboard for break instruction exceptions |
## Both GCC and GDB use break instructions. GCC for division-by-zero |
## notification and GDB for program-flow breakpoints. This springboard |
## looks for the d-b-z kind and directs them to another vector so libc |
## can handle these without affecting the debugger. |
|
FUNC_START(__break_vsr_springboard) |
mvafc0 k0,epc |
mfc0 k1,cause |
bltzl k1,1f |
addi k0,k0,4 # delay slot (only executed if BD set) |
1: lw k1,0(k0) # get break instruction |
la k0,0x0007000d # break 0x7 used by GCC for d-b-z |
bne k0,k1,2f |
nop |
ori k0,$0,14*4 # CYGNUM_HAL_VECTOR_DIV_BY_ZERO |
la k1,hal_vsr_table # address of VSR table |
add k1,k1,k0 # offset of VSR entry |
lw k1,0(k1) # k1 = pointer to VSR |
jr k1 # go there |
nop # (delay slot) |
2: ori k0,$0,9*4 # CYGNUM_HAL_VECTOR_BREAKPOINT |
j __default_exception_vsr |
nop # (delay slot) |
FUNC_END(__break_vsr_springboard) |
|
|
##----------------------------------------------------------------------------- |
## Interrupt Stack. |
## Used during intialization and for executing ISRs. |
|
.bss |
|
.balign 16 |
.global cyg_interrupt_stack_base |
cyg_interrupt_stack_base: |
__interrupt_stack_base: |
.rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE |
.byte 0 |
.endr |
.balign 16 |
.global cyg_interrupt_stack |
cyg_interrupt_stack: |
__interrupt_stack: |
|
.long 0,0,0,0,0,0,0,0 |
|
##----------------------------------------------------------------------------- |
## VSR table. |
## The main interrupt code indirects through here to find the VSR |
## to execute for each architecture defined interrupt. |
## This is only used for simulated targets, on real targets a fixed location VSR |
## table is now allocated at 0x80000100. |
|
#ifndef CYG_HAL_MIPS_VSR_TABLE_DEFINED |
|
## .section ".vsr_table","a" |
|
.data |
|
.globl hal_vsr_table |
|
hal_vsr_table: |
.long __default_interrupt_vsr |
.rept 63 |
.long __default_exception_vsr |
.endr |
|
#endif |
|
#------------------------------------------------------------------------------ |
# Interrupt vector tables. |
# These tables contain the isr, data and object pointers used to deliver |
# interrupts to user code. |
# hal_interrupt_level contains the interrupt level set by |
# HAL_INTERRUPT_CONFIGURE(). |
# This is a default set that provide support only for the 6 external |
# interrupts in the status/cause registers. Platforms or boards are expected |
# to define their own versions of these if they have their own interrupt mappings. |
|
#ifndef CYG_HAL_MIPS_ISR_TABLES_DEFINED |
|
.extern hal_default_isr |
|
.data |
|
.globl hal_interrupt_handlers |
hal_interrupt_handlers: |
.long hal_default_isr |
.long hal_default_isr |
.long hal_default_isr |
.long hal_default_isr |
.long hal_default_isr |
.long hal_default_isr |
|
|
.globl hal_interrupt_data |
hal_interrupt_data: |
.rept 6 |
.long 0 |
.endr |
|
.globl hal_interrupt_objects |
hal_interrupt_objects: |
.rept 6 |
.long 0 |
.endr |
|
#endif |
|
##----------------------------------------------------------------------------- |
## end of vectors.S |
|
|