diff options
author | Michael Gielda <mgielda@antmicro.com> | 2014-04-03 14:53:04 +0200 |
---|---|---|
committer | Michael Gielda <mgielda@antmicro.com> | 2014-04-03 14:53:04 +0200 |
commit | ae1e4e08a1005a0c487f03ba189d7536e7fdcba6 (patch) | |
tree | f1c296f8a966a9a39876b0e98e16d9c5da1776dd /ecos/packages/hal/cortexm/arch | |
parent | f157da5337118d3c5cd464266796de4262ac9dbd (diff) |
Added the OS files
Diffstat (limited to 'ecos/packages/hal/cortexm/arch')
23 files changed, 5194 insertions, 0 deletions
diff --git a/ecos/packages/hal/cortexm/arch/current/ChangeLog b/ecos/packages/hal/cortexm/arch/current/ChangeLog new file mode 100644 index 0000000..7aee9ff --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/ChangeLog @@ -0,0 +1,214 @@ +2014-02-28 John Dallaway <john@dallaway.org.uk> + + * src/mcount.S: Add mcount functions for call-graph profiling. + * cdl/hal_cortexm.cdl: Add option to build mcount functions. + [ Bugzilla 1001954 ] + +2013-08-25 Ilija Kocho <ilijak@siva.com.mk> + + * cdl/hal_cortexm_fpu.cdl, include/fpv4_sp_d16_libm.h: Define Cortex-M4F + architecture specific builtin mathematical functions. [ Bugzilla 1001539 ] + +2013-04-29 Ilija Kocho <ilijak@siva.com.mk> + + * include/cortexm_stub.h: Remove unwanted diag_printf(). + +2013-02-10 Ilija Kocho <ilijak@siva.com.mk> + Jonathan Larmour <jifl@eCosCentric.com> + + * cdl/hal_cortexm.cdl: + * cdl/hal_cortexm_fpu.cdl: New + * include/cortexm_core.h: New + * include/cortexm_fpu.h: New + * include/cortexm_regs.h: + * include/cortexm_stub.h: + * include/fpv4_sp_d16.h: New + * include/hal_arch.h: + * include/hal_arch.inc: New + * include/hal_io.h: + * src/context.S: + * src/cortexm_fpu.c: New + * src/cortexm_stub.c: + * src/fpv4_sp_d16.c: New + * src/hal_misc.c: + * src/vectors.S: + Add: hardware floating point support for Cortex-M4F [ Bugzilla 1001607 ] + +2012-04-23 Ilija Kocho <ilijak@siva.com.mk> + + * cdl/hal_cortexm.cdl: + * include/basetype.h: + * include/cortexm_stub.h: + * include/hal_arch.h: + * include/hal_intr.h: + * include/hal_io.h: + * src/context.S: + * src/cortexm_stub.c: + * src/hal_misc.c: + * src/vectors.S: + Whitespace cleanup [Bugzilla 1001569] + +2012-03-06 Ilija Kocho <ilijak@siva.com.mk> + + * include/hal_intr.h: Fix compiler warning about unused variables. + [Bugzilla 1001520] + +2012-02-05 Jonathan Larmour <jifl@eCosCentric.com> + + * src/hal_misc.c (hal_reset_vsr): Ensure we only init intr vectors + up to top of VSR table. + +2011-08-23 Ilija Kocho <ilijak@siva.com.mk> + + * cdl/hal_cortexm.cdl: New CDL option CYGIMP_HAL_ARCH_ENDIAN + * include/cortexm_endian.h: New file + * include/cortexm_regs.h: New file + [ Bugzilla 1001275 ] + +2011-04-06 Nick Garnett <nickg@ecoscentric.com> + + * cdl/cortexm.cdl: Remove M1 CPU family from architecture config + file (as not supported for now). [Bugzilla 1001186] + +2011-04-02 Ilija Kocho <ilijak@siva.com.mk> + * cdl/cortexm.cdl: Add M4 CPU family to CYGHWR_HAL_CORTEXM. Add + FPU (Floating Point Unit) interface. + * include/hal_io.h: Add CYGHWR_HAL_CORTEXM_M4 to some preprocessor + conditions. [Bugzilla 1001186] + +2011-04-01 Ilija Kocho <ilijak@siva.com.mk> + + * include/hal_intr.h: Remove double inclusion of var_intr.h + header and include it at proper place. [ Bugzilla 1001184 ] + +2011-02-17 John Dallaway <john@dallaway.org.uk> + + * include/hal_intr.h (HAL_DISABLE_INTERRUPTS): Mark operand as + an earlyclobber operand to ensure correct register usage. Issue + reported by both Ulrich Holeschak and Stanislav Meduna. + [ Bugzilla 1001154 ] + +2011-02-16 Ilija Kocho <ilijak@siva.com.mk> + + * src/cortexm.ld: Added USER_SECTION() macro. [Bugzilla 1001142 ] + +2011-01-20 Christophe Coutand <ccoutand@stmi.com> + + * include/hal_intr.h: + * cdl/hal_cortexm.cdl: + Allow variant or platform to define their own RTC clock. Add + CDL entry to select SysTick clock source. [ Bugzilla 1001090 ] + +2010-12-28 Ilija Kocho <ilijak@siva.com.mk> + + * include/hal_io.h: conditional VTOR setting. + +2011-01-13 John Dallaway <john@dallaway.org.uk> + + * src/vectors.S (hal_default_interrupt_vsr): Save interrupt state + if CYGINT_HAL_COMMON_SAVED_INTERRUPT_STATE_REQUIRED is implemented. + [ Bugzilla 1001111 ] + +2011-01-02 Sergei Gavrikov <sergei.gavrikov@gmail.com> + + * cdl/hal_cortexm.cdl: Eliminate some warnings. [ Bugzilla + 1001083 ] + +2010-05-17 Spencer Oliver <spen@spen-soft.co.uk> + + * include/hal_intr.h (HAL_INTERRUPT_STACK_CALL_PENDING_DSRS): + * src/hal_misc.c (hal_reset_vsr): Add 0 argument to SWI. + + * src/vectors.S (hal_switch_state_vsr): Eliminate "msr psp,sp", + which is now deprecated. + (hal_pendable_svc_vsr): Add 0 argument to SWI. + +2009-02-27 Simon Kallweit <simon.kallweit@intefo.ch> + + * include/hal_io.h: Added system control register definitions + +2009-02-13 Nick Garnett <nickg@ecoscentric.com> + + * include/hal_arch.h: Add include for var_arch.h. + (HAL_IDLE_THREAD_ACTION): Tidy up debug code left in by mistake. + +2009-02-07 Chris Holgate <chris@zynaptic.com> + + * src/hal_misc.c: + * src/cortexm.ld: + Modified SRAM linker section to support initialisation from ROM. + +2008-12-03 Nick Garnett <nickg@ecoscentric.com> + + * src/hal_misc.c (hal_deliver_interrupt): Fix instrumentation call + to allow it to compile properly. + +2008-11-24 Simon Kallweit <simon.kallweit@intefo.ch> + + * include/hal_io.c: Fixed MASK_ macro. + +2008-11-04 Simon Kallweit <simon.kallweit@intefo.ch> + + * include/hal_intr.h: + Fixed load value of SysTick counter. + * src/hal_misc.c: + Fixed wrap-around in hal_delay_us(). + +2008-11-04 Simon Kallweit <simon.kallweit@intefo.ch> + + * include/hal_intr.h: + Fixed base address in reset function. + +2008-10-16 Nick Garnett <nickg@ecoscentric.com> + + * src/vectors.S: + * src/hal_misc.c: Tidy some comments and code. + +2008-10-10 Nick Garnett <nickg@ecoscentric.com> + + * src/hal_misc.c (hal_deliver_interrupt): Add support for chained + interrupts. + (hal_interrupt_end): Only increment scheduler lock when the kernel + is present. + + * include/hal_arch.h (HAL_THREAD_INIT_CONTEXT): Add end-stop to + new thread states to terminate GDB backtraces. + +2008-10-06 Nick Garnett <nickg@ecoscentric.com> + + * hal_cortexm.cdl: + * include/basetype.h: + * include/hal_arch.h: + * include/hal_intr.h: + * include/hal_io.h: + * include/cortex_stub.h: + * src/vectors.S: + * src/context.S: + * src/cortexm.ld: + * src/cortexm_stub.c: + * src/hal_misc.c: + New package -- Cortex-M architecture HAL. + +//=========================================================================== +// ####GPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2008, 2011, 2014 Free Software Foundation, Inc. +// +// This program 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. +// +// This program 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 this program; if not, write to the +// Free Software Foundation, Inc., 51 Franklin Street, +// Fifth Floor, Boston, MA 02110-1301, USA. +// ------------------------------------------- +// ####GPLCOPYRIGHTEND#### +//=========================================================================== diff --git a/ecos/packages/hal/cortexm/arch/current/cdl/hal_cortexm.cdl b/ecos/packages/hal/cortexm/arch/current/cdl/hal_cortexm.cdl new file mode 100644 index 0000000..cab81bc --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/cdl/hal_cortexm.cdl @@ -0,0 +1,275 @@ +##========================================================================== +## +## hal_cortexm.cdl +## +## Cortex-M architectural HAL configuration data +## +##========================================================================== +## ####ECOSGPLCOPYRIGHTBEGIN#### +## ------------------------------------------- +## This file is part of eCos, the Embedded Configurable Operating System. +## Copyright (C) 2008, 2011, 2014 Free Software Foundation, 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., +## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +## +## This exception does not invalidate any other reasons why a work based +## on this file might be covered by the GNU General Public License. +## ------------------------------------------- +## ####ECOSGPLCOPYRIGHTEND#### +##========================================================================== +#######DESCRIPTIONBEGIN#### +## +## Author(s): nickg +## Contributor(s): jld +## Date: 2008-07-30 +## +######DESCRIPTIONEND#### +## +##========================================================================== + +cdl_package CYGPKG_HAL_CORTEXM { + display "Cortex-M Architecture" + parent CYGPKG_HAL + hardware + include_dir cyg/hal + define_header hal_cortexm.h + description " + This package provides generic support for the ARM Cortex-M architecture. + It is also necessary to select a variant and platform HAL package." + + implements CYGINT_PROFILE_HAL_MCOUNT + + compile hal_misc.c context.S cortexm_stub.c + + requires { CYGHWR_HAL_CORTEXM_BIGENDIAN implies + is_substr(CYGBLD_GLOBAL_CFLAGS, " -mbig-endian ") && + is_substr(CYGBLD_GLOBAL_LDFLAGS, " -mbig-endian ") } + requires { !CYGHWR_HAL_CORTEXM_BIGENDIAN implies + !is_substr(CYGBLD_GLOBAL_CFLAGS, " -mbig-endian ") && + !is_substr(CYGBLD_GLOBAL_LDFLAGS, " -mbig-endian ") } + + make { + <PREFIX>/lib/vectors.o : <PACKAGE>/src/vectors.S + $(CC) -Wp,-MD,vectors.tmp $(INCLUDE_PATH) $(CFLAGS) -c -o $@ $< + @echo $@ ": \\" > $(notdir $@).deps + @tail -n +2 vectors.tmp >> $(notdir $@).deps + @echo >> $(notdir $@).deps + @rm vectors.tmp + } + + make { + <PREFIX>/lib/target.ld: <PACKAGE>/src/cortexm.ld + $(CC) -E -P -Wp,-MD,target.tmp -xc $(INCLUDE_PATH) $(ACTUAL_CFLAGS) -o $@ $< + @echo $@ ": \\" > $(notdir $@).deps + @tail -n +2 target.tmp >> $(notdir $@).deps + @echo >> $(notdir $@).deps + @rm target.tmp + } + + cdl_interface CYGINT_HAL_CORTEXM_BIGENDIAN { + display "The platform and architecture supports Big Endian operation" + } + + cdl_option CYGHWR_HAL_CORTEXM_BIGENDIAN { + display "Use big-endian mode" + active_if { CYGINT_HAL_CORTEXM_BIGENDIAN != 0 } + default_value 0 + description " + Use the CPU in big-endian mode." + } + + cdl_option CYGHWR_HAL_CORTEXM { + display "Cortex-M CPU family" + flavor data + legal_values { "M3" "M4" } + default_value { "M3" } + description " + The Cortex-M architecture has two variants at present. The + M3 and M4 are based on the ARMV7 architecture specification + and execute the Thumb2 instruction set. The M4 in addition + to M3 instruction set has SIMD and optional single precision + floating point instructions." + } + + cdl_option CYGHWR_HAL_CORTEXM_SYSTICK_CLK_SOURCE { + display "System tick timer clock" + flavor data + legal_values { "EXTERNAL" "INTERNAL" } + default_value { "EXTERNAL" } + description "Select the Cortex-M system tick timer clock source." + } + + cdl_component CYGPKG_HAL_CORTEXM_FPU { + display "Floating Point Support" + flavor data + calculated { !CYGHWR_HAL_CORTEXM_FPU ? "SOFT" : + "HARD: " . CYGHWR_HAL_CORTEXM_FPU_SWITCH } + no_define + active_if { CYGHWR_HAL_CORTEXM == "M4" } + description " + Floating point arithmetics can be executed in software or, + on devices with floating point unit - FPU, in hardware. + FPU is optional on Cortex-M4 architecture, and is present + on Cortex-M4F cores." + + script hal_cortexm_fpu.cdl + } + + cdl_option CYGIMP_HAL_ARCH_ENDIAN { + display "Architecture optimized endian functions" + flavor bool + default_value 1 + description " + Cortex-M architecture implements instructions for endian + manipulation (byte swapping). If enabled, this feature + can produce shorter and faster code for that." + + define_proc { + puts $::cdl_system_header "#define CYGBLD_HAL_ENDIAN_H <cyg/hal/cortexm_endian.h>" + } + } + + cdl_option CYGNUM_HAL_CORTEXM_PRIORITY_MAX { + display "Maximum usable priority" + flavor data + calculated 1<<(8-CYGNUM_HAL_CORTEXM_PRIORITY_LEVEL_BITS) + description " + Calculate the maximum exception priority that can be set by interrupts. + Higher priorities are reserved for the DEBUG and SVC traps." + } + + cdl_option CYGBLD_HAL_CORTEXM_MCOUNT { + display "Support call-graph profiling" + flavor bool + no_define + active_if CYGPKG_PROFILE_GPROF + calculated CYGPKG_PROFILE_CALLGRAPH + compile mcount.S + description " + Calculate whether mcount functions should be built + to support call-graph profiling." + } + + cdl_option CYGBLD_LINKER_SCRIPT { + display "Linker script" + flavor data + no_define + calculated { "src/cortexm.ld" } + } + + cdl_option CYGNUM_HAL_BREAKPOINT_LIST_SIZE { + display "Number of breakpoints supported by the HAL." + flavor data + default_value 8 + description " + This option determines the number of breakpoints supported by the HAL." + } + + cdl_component CYGBLD_ARCH_CPUFLAGS { + display "Architecture related build flags" + flavor data + no_define + + calculated { CYGHWR_HAL_CORTEXM == "M3" ? " -mcpu=cortex-m3" : + CYGHWR_HAL_CORTEXM_FPU ? " -mcpu=cortex-m4" : " " } + + description "This component defines flags that code generation dependent on specific + CPU type or CPU features." + + cdl_option CYGBLD_ARCH_CPUFLAGX_M3 { + display "Exclude Cortex-M3 build flag" + flavor data + no_define + + calculated { CYGHWR_HAL_CORTEXM_FPU ? "-mcpu=cortex-m3" : "no_exclude" } + } + + cdl_option CYGBLD_ARCH_CPUFLAGX_M4 { + display "Exclude Cortex-M4 build flag" + flavor data + no_define + + calculated { (CYGHWR_HAL_CORTEXM != "M4") ? "-mcpu=cortex-m4" : "no_exclude" } + } + + cdl_component CYGBLD_ARCH_CPUFLAG_FLOAT_ABI { + display "Float ABI build flags" + flavor data + no_define + calculated { CYGHWR_HAL_CORTEXM_FPU ? " -mfloat-abi=hard" : "" } + + cdl_option CYGBLD_ARCH_CPUFLAGX_FLOAT_ABI { + display "Float ABI flag to exclude" + flavor data + no_define + calculated { CYGHWR_HAL_CORTEXM_FPU ? "-mfloat-abi=soft" : "-mfloat-abi=hard" } + } + + cdl_option CYGBLD_ARCH_CPUFLAGX_HARDSOFT_FLOAT { + display "Alt. float flag to exclude" + flavor data + no_define + calculated { CYGHWR_HAL_CORTEXM_FPU ? "-msoft-float" : "-mhard-float" } + } + + cdl_component CYGBLD_ARCH_CPUFLAG_FPV4SPD16 { + display "FPv4-SP-D16 flags" + flavor data + no_define + calculated { CYGHWR_HAL_FPV4_SP_D16 ? " -mfpu=fpv4-sp-d16" : "" } + + cdl_option CYGBLD_ARCH_CPUFLAGX_FPV4SPD16 { + display "Exclude FPv4-SP-D16 flag" + flavor data + no_define + calculated { CYGHWR_HAL_FPV4_SP_D16 ? "do_not_exclude" : "-mfpu=fpv4-sp-d16" } + } + } + } + + requires { + !is_substr(CYGBLD_GLOBAL_CFLAGS, CYGBLD_ARCH_CPUFLAGX_M3) && + !is_substr(CYGBLD_GLOBAL_CFLAGS, CYGBLD_ARCH_CPUFLAGX_M4) && + !is_substr(CYGBLD_GLOBAL_CFLAGS, CYGBLD_ARCH_CPUFLAGX_FLOAT_ABI) && + !is_substr(CYGBLD_GLOBAL_CFLAGS, CYGBLD_ARCH_CPUFLAGX_HARDSOFT_FLOAT) && + !is_substr(CYGBLD_GLOBAL_CFLAGS, CYGBLD_ARCH_CPUFLAGX_FPV4SPD16) && + + is_substr(CYGBLD_GLOBAL_CFLAGS, CYGBLD_ARCH_CPUFLAGS) && + is_substr(CYGBLD_GLOBAL_CFLAGS, CYGBLD_ARCH_CPUFLAG_FLOAT_ABI) && + is_substr(CYGBLD_GLOBAL_CFLAGS, CYGBLD_ARCH_CPUFLAG_FPV4SPD16) + } + requires { + !is_substr(CYGBLD_GLOBAL_LDFLAGS, CYGBLD_ARCH_CPUFLAGX_M3) && + !is_substr(CYGBLD_GLOBAL_LDFLAGS, CYGBLD_ARCH_CPUFLAGX_M4) && + !is_substr(CYGBLD_GLOBAL_LDFLAGS, CYGBLD_ARCH_CPUFLAGX_FLOAT_ABI) && + !is_substr(CYGBLD_GLOBAL_LDFLAGS, CYGBLD_ARCH_CPUFLAGX_HARDSOFT_FLOAT) && + !is_substr(CYGBLD_GLOBAL_LDFLAGS, CYGBLD_ARCH_CPUFLAGX_FPV4SPD16) && + + is_substr(CYGBLD_GLOBAL_LDFLAGS, CYGBLD_ARCH_CPUFLAGS) && + is_substr(CYGBLD_GLOBAL_LDFLAGS, CYGBLD_ARCH_CPUFLAG_FLOAT_ABI) && + is_substr(CYGBLD_GLOBAL_LDFLAGS, CYGBLD_ARCH_CPUFLAG_FPV4SPD16) + } + } +} + +# EOF hal_cortexm.cdl diff --git a/ecos/packages/hal/cortexm/arch/current/cdl/hal_cortexm_fpu.cdl b/ecos/packages/hal/cortexm/arch/current/cdl/hal_cortexm_fpu.cdl new file mode 100644 index 0000000..69b3bf7 --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/cdl/hal_cortexm_fpu.cdl @@ -0,0 +1,136 @@ +##========================================================================== +## +## hal_cortexm_fpu.cdl +## +## Cortex-M HAL Floating Point configuration data +## +##========================================================================== +## ####ECOSGPLCOPYRIGHTBEGIN#### +## ------------------------------------------- +## This file is part of eCos, the Embedded Configurable Operating System. +## Copyright (C) 2012 Free Software Foundation, 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., +## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +## +## This exception does not invalidate any other reasons why a work based +## on this file might be covered by the GNU General Public License. +## ------------------------------------------- +## ####ECOSGPLCOPYRIGHTEND#### +##========================================================================== +#######DESCRIPTIONBEGIN#### +## +## Author(s): ilijak +## Date: 2012-03-03 +## Usage: script hal_cortexm_fpu.cdl +## +######DESCRIPTIONEND#### +## +##========================================================================== + + #cdl_component CYGPKG_HAL_CORTEXM_FPU { + #display "Floating Point Unit" + #flavor none + #no_define + + cdl_interface CYGINT_HAL_FPV4_SP_D16 { + display "FPU is FPv4-SP-D16" + flavor bool + implements CYGINT_HAL_CORTEXM_FPU + } + + cdl_interface CYGINT_HAL_CORTEXM_FPU { + display "FPU present." + flavor data + } + + cdl_component CYGHWR_HAL_CORTEXM_FPU { + display "Use hardware FPU" + flavor bool + active_if { CYGINT_HAL_CORTEXM_FPU } + default_value 0 + compile cortexm_fpu.c + + description " + Cortex-M4F cores have a single precision floating point unit. + This option enables FPU usage and provides related FPU control + options. + Hardware FPU enable, implies Cortex-M4 code generation, and + build flags shall be set accordingly, including -mcpu=cortex-m4. + As a side effect, the Cortex_M4 build flag will remain \(sticky\) + even if hardware FPU is subsequently disabled. + " + + cdl_option CYGHWR_HAL_CORTEXM_FPU_SWITCH { + display "FPU context switch" + flavor data + legal_values { "ALL" "LAZY" "NONE" } + default_value { "LAZY" } + + requires { is_active (CYGPKG_KERNEL) implies + CYGTST_KERNEL_SKIP_MULTI_THREAD_FP_TEST == + (CYGHWR_HAL_CORTEXM_FPU_SWITCH == "NONE") } + + description " + This option selects the FPU context switching scheme. + Straight-forward behaviour is to save and + restore FPU state on every CPU context save/restore. + While simple, robust and deterministic, this + approach can be expensive if the FPU is used by + few threads. The alternative schemes, available by this + option, are to use hardware features that allow either: + - LAZY: Save FPU context only if the thread makes use of + the FPU. Where only few threads use FPU this should give + shorter average context switching delay compared to ALL + scheme. If more than one threads use FPU, the worst context + switching time is typically worse than the one for ALL + scheme. + - ALL: Save FPU context for all threads. This is a simple + scheme, which if all, or majority of threads use FPU may + give better average context switching time than LAZY. + This scheme also includes Lazy Stacking of FPU state + for exceptions/interrupts. + - NONE: No FPU state saving, this scheme adds no additional + delay for saving of FPU state to context switching, but is + only suitable if maximum one thread uses floating point." + } + + cdl_option CYGHWR_HAL_FPV4_SP_D16 { + flavor bool + active_if { CYGINT_HAL_FPV4_SP_D16 } + calculated { CYGINT_HAL_FPV4_SP_D16 && CYGHWR_HAL_CORTEXM_FPU } + display "FPv4-SP-D16" + no_define + compile fpv4_sp_d16.c + + define_proc { + puts $::cdl_system_header "#define CYGBLD_HAL_LIBM_H <cyg/hal/fpv4_sp_d16_libm.h>" + } + + description " + FPv4-SP-D16 is ARMv7 architecture single precision floating + point unit with 16 double precision / 32 single precision + registers. It is found on Cortex-M4F and Cortex-R5 cores." + } + #} + +# EOF hal_cortexm_fpu.cdl diff --git a/ecos/packages/hal/cortexm/arch/current/include/basetype.h b/ecos/packages/hal/cortexm/arch/current/include/basetype.h new file mode 100644 index 0000000..6ed8532 --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/include/basetype.h @@ -0,0 +1,71 @@ +#ifndef CYGONCE_HAL_BASETYPE_H +#define CYGONCE_HAL_BASETYPE_H +/*========================================================================== +// +// hal_intr.h +// +// Cortex-M standard types +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2008 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): nickg +// Date: 2008-07-30 +// Description: Define architecture base types +// +//####DESCRIPTIONEND#### +// +//======================================================================== +*/ + +#define CYG_BYTEORDER CYG_LSBFIRST // Little endian +#define CYG_DOUBLE_BYTEORDER CYG_LSBFIRST + +//----------------------------------------------------------------------------- +// Cortex-M does not usually use labels with underscores. + +#define CYG_LABEL_NAME(_name_) _name_ +#define CYG_LABEL_DEFN(_name_) _name_ + +//----------------------------------------------------------------------------- +// Define the standard variable sizes + +// The ARM 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 diff --git a/ecos/packages/hal/cortexm/arch/current/include/cortexm_core.h b/ecos/packages/hal/cortexm/arch/current/include/cortexm_core.h new file mode 100644 index 0000000..cf64721 --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/include/cortexm_core.h @@ -0,0 +1,77 @@ +#ifndef CYGONCE_CORTEXM_CORE_H +#define CYGONCE_CORTEXM_CORE_H +//========================================================================== +// +// cortexm_core.h +// +// Cortex-M some core registers +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2012 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): ilijak +// Contributor(s): +// Date: 2012-06-26 +// Description: Some Cortex-M core register definitions +// +//####DESCRIPTIONEND#### +// +//======================================================================== + + +// Coprocessor Access Control Register +#define CYGARC_REG_FPU_CPACR 0xE000ED88 + +#define CYGARC_REG_FPU_CPACR_ACCESS_DENIED 0 +#define CYGARC_REG_FPU_CPACR_ACCESS_PRIVILEGED 1 +#define CYGARC_REG_FPU_CPACR_ACCESS_RESERVED 2 +#define CYGARC_REG_FPU_CPACR_ACCESS_FULL (CYGARC_REG_FPU_CPACR_ACCESS_PRIVILEGED | \ + CYGARC_REG_FPU_CPACR_ACCESS_RESERVED) + +#define CYGARC_REG_FPU_CPACR_CP10(_access) ((_access) << 20) +#define CYGARC_REG_FPU_CPACR_CP11(_access) ((_access) << 22) + +#define CYGARC_REG_FPU_CPACR_ENABLE \ + (CYGARC_REG_FPU_CPACR_CP10(CYGARC_REG_FPU_CPACR_ACCESS_FULL) | \ + CYGARC_REG_FPU_CPACR_CP11(CYGARC_REG_FPU_CPACR_ACCESS_FULL)) + +// CONTROL register +// The CONTROL register is not memory mapped. Use CYGARC_MSR() and CYGARC_MRS(). +#define CYGARC_REG_CONTROL_PRIV_M 0x1 +#define CYGARC_REG_CONTROL_SPSEL_M 0x2 +#define CYGARC_REG_CONTROL_FPCA_M 0x4 + +//========================================================================== +#endif //CYGONCE_CORTEXM_CORE_H diff --git a/ecos/packages/hal/cortexm/arch/current/include/cortexm_endian.h b/ecos/packages/hal/cortexm/arch/current/include/cortexm_endian.h new file mode 100644 index 0000000..67b3801 --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/include/cortexm_endian.h @@ -0,0 +1,77 @@ +#ifndef CYGONCE_CORTEXM_ENDIAN_H +#define CYGONCE_CORTEXM_ENDIAN_H +//========================================================================== +// +// cortexm_endian.h +// +// Cortex-M architecture endian conversion macros/functions. +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2011 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): Ilija Kocho <ilijak@siva.com.mk> +// Sergei Gavrikov +// Date: 2011-08-20 +// Description: Endian conversion macros/functions optimized for Cortex-M +// Usage: #include <cyg/hal/cortexm_endian.h> +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include <cyg/hal/cortexm_regs.h> + +//=========================================================================== +// Endian operations optimized for Cortex-M architecture. + +static __inline__ cyg_uint32 cyg_hal_swap32(cyg_uint32 original) +{ + cyg_uint32 swapped; + CYGARC_REV(swapped, original); + return swapped; +} + +static __inline__ cyg_uint16 cyg_hal_swap16(cyg_uint16 original) +{ + cyg_uint16 swapped; + CYGARC_REV16(swapped, original); + return swapped; +} + +#define CYG_SWAP32(__val) cyg_hal_swap32(__val) +#define CYG_SWAP16(__val) cyg_hal_swap16(__val) + +//========================================================================== +#endif //CYGONCE_CORTEXM_ENDIAN_H diff --git a/ecos/packages/hal/cortexm/arch/current/include/cortexm_fpu.h b/ecos/packages/hal/cortexm/arch/current/include/cortexm_fpu.h new file mode 100644 index 0000000..ccc1687 --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/include/cortexm_fpu.h @@ -0,0 +1,98 @@ +#ifndef CYGONCE_CORTEXM_FPU_H +#define CYGONCE_CORTEXM_FPU_H +//========================================================================== +// +// cortexm_fpu.h +// +// Cortex-M General Floating Point Unit definitions +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2012 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): ilijak +// Contributor(s): +// Date: 2012-04-25 +// Description: Cortex-M4F General Floating Point Unit definitions and macros +// Usage: include <cyg/hal/cortexm_fpu.h> +// +//####DESCRIPTIONEND#### +// +//======================================================================== + + +//=========================================================================== +// Floating Point Unit +// +// FPU is optional unit of Cortex-M4 + +#include <pkgconf/hal.h> +#include <pkgconf/hal_cortexm.h> +#include <cyg/hal/cortexm_core.h> + +#ifdef CYGHWR_HAL_CORTEXM_FPU + +# if defined CYGSEM_HAL_ROM_MONITOR || defined CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS +# define CYGSEM_HAL_DEBUG_FPU +# endif + +# ifdef CYGINT_HAL_FPV4_SP_D16 +# include <cyg/hal/fpv4_sp_d16.h> +# else +# error "Unknown FPU unit!" +# endif + +#else // CYGHWR_HAL_CORTEXM_FPU + +# define CYGARC_CORTEXM_GDB_REG_FPA + +# define GDB_STUB_SAVEDREG_FRAME_TYPE(__type) (__type->u.type) + +# define HAL_SAVEDREG_AUTO_FRAME_SIZE (8*4) + +# define HAL_SAVEDREG_FPU_THREAD_S +# define HAL_SAVEDREG_MAN_FPU_EXCEPTION_S +# define HAL_SAVEDREG_AUTO_FPU_EXCEPTION_S +# define HAL_THREAD_INIT_FPU_CONTEXT(__regs) CYG_EMPTY_STATEMENT + +# define GDB_STUB_SAVEDREG_FPU_THREAD_GET(__gdbreg,__regs) CYG_EMPTY_STATEMENT +# define GDB_STUB_SAVEDREG_FPU_THREAD_SET(__gdbreg,__regs) CYG_EMPTY_STATEMENT +# define GDB_STUB_SAVEDREG_FPU_EXCEPTION_GET(__gdbreg,__regs) CYG_EMPTY_STATEMENT +# define GDB_STUB_SAVEDREG_FPU_EXCEPTION_SET(__gdbreg,__regs) CYG_EMPTY_STATEMENT + +#endif// CYGHWR_HAL_CORTEXM_FPU + + +//========================================================================== +#endif //CYGONCE_CORTEXM_FPU_H diff --git a/ecos/packages/hal/cortexm/arch/current/include/cortexm_regs.h b/ecos/packages/hal/cortexm/arch/current/include/cortexm_regs.h new file mode 100644 index 0000000..4bb4c86 --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/include/cortexm_regs.h @@ -0,0 +1,118 @@ +#ifndef CYGONCE_CORTEXM_REGS_H +#define CYGONCE_CORTEXM_REGS_H +//========================================================================== +// +// cortexm_regs.h +// +// Cortex-M architecture, special machine instruction wrappers +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2011 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): Ilija Kocho <ilijak@siva.com.mk> +// Sergei Gavrikov +// Date: 2011-06-18 +// Description: C wrappers for some special architecture instructions. +// +//####DESCRIPTIONEND#### +// +//========================================================================= + +#ifndef __ASSEMBLER__ + +//-------------------------------------------------------------------------- +// No operation +#define CYGARC_NOP() { __asm__ volatile( "nop" ); } + + +//--------------------------------------------------------------------------- +// Change processor state instructions + +// Disable / enable interrupts +#define CYGARC_CPSID( _flags_ ) __asm__ volatile ("cpsid " #_flags_ "\n") + +// Enable interrupts and fault handlers (clear FAULTMASK) +#define CYGARC_CPSIE( _flags_ ) __asm__ volatile ("cpsie " #_flags_ "\n") + +//--------------------------------------------------------------------------- +// Byte swapping instructions + +// Reverse word +#define CYGARC_REV( _swapped_, _origin_ ) \ + __asm__ volatile ("rev %0, %1\n" : "=r"(_swapped_) : "r"(_origin_)) + +// Reverse halfwords +#define CYGARC_REV16( _swapped_, _origin_ ) \ + __asm__ volatile ("rev16 %0, %1\n" : "=r"(_swapped_) : "r"(_origin_)) + +// Reverse signed halfword +#define CYGARC_REVSH( _swapped_, _origin_ ) \ + __asm__ volatile ("revsh %0, %1\n" : "=r"(_swapped_) : "r"(_origin_)) + +//------------------------------------------------------------------------ +// Barrier instructions +// Data Synchronization Barrier +#define CYGARC_DSB() __asm__ volatile( "dsb" ) +// Instruction Synchronization Barrier +#define CYGARC_ISB() __asm__ volatile( "isb" ) + +#define HAL_MEMORY_BARRIER() \ +CYG_MACRO_START \ + CYGARC_DSB(); \ + CYGARC_ISB(); \ +CYG_MACRO_END + +//---------------------------------------------------------------------------- +// MSR instuctions +// Special register instructions +#define CYGARC_MSR(_reg_, _val_) \ + __asm__ volatile ("msr " #_reg_", %0\n" : : "r"(_val_)) + +#define CYGARC_MRS(_val_, _reg_) \ + __asm__ volatile ("mrs %0," #_reg_ "\n" : "=r"(_val_) : ) + +//---------------------------------------------------------------------------- +// VFP instuctions +// Special floating point unit register instructions +#define CYGARC_VMSR(_reg_, _val_) \ + __asm__ volatile ("vmsr " #_reg_", %0\n" : : "r"(_val_)) + +#define CYGARC_VMRS(_val_, _reg_) \ + __asm__ volatile ("vmrs %0," #_reg_ "\n" : "=r"(_val_) : ) + +#endif // __ASSEMBLER__ + +//========================================================================== +#endif // CYGONCE_CORTEXM_REGS_H diff --git a/ecos/packages/hal/cortexm/arch/current/include/cortexm_stub.h b/ecos/packages/hal/cortexm/arch/current/include/cortexm_stub.h new file mode 100644 index 0000000..9ec3b6a --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/include/cortexm_stub.h @@ -0,0 +1,161 @@ +#ifndef CYGONCE_HAL_CORTEXM_STUB_H +#define CYGONCE_HAL_CORTEXM_STUB_H +/*========================================================================== +// +// cortexm_stub.h +// +// Cortex-M GDB stub support +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2008, 2012 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): nickg +// Contributor(s): ilijak +// Date: 2008-07-30 +// +//####DESCRIPTIONEND#### +// +//======================================================================== +*/ + +#include <pkgconf/system.h> +#include <pkgconf/hal.h> + +#ifdef CYGHWR_HAL_CORTEXM_FPU +#include <cyg/hal/cortexm_fpu.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif +#ifndef CYGHWR_HAL_CORTEXM_FPU +// The ARM has float (and possibly other coprocessor) registers that are +// larger than it can hold in a target_register_t. +# define TARGET_HAS_LARGE_REGISTERS + +// ARM stub has special needs for register handling (not all regs are the +// the same size), so special put_register and get_register are provided. +# define CYGARC_STUB_REGISTER_ACCESS_DEFINED 1 + +# define NUMREGS (16+8+2) // 16 GPR, 8 FPR (unused), 2 PS + +# define REGSIZE( _x_ ) (((_x_) < F0 || (_x_) >= FPS) ? 4 : 12) + +# ifndef TARGET_REGISTER_T_DEFINED +# define TARGET_REGISTER_T_DEFINED +typedef unsigned long target_register_t; +# endif + +enum regnames { + R0, R1, R2, R3, R4, R5, R6, R7, + R8, R9, R10, FP, IP, SP, LR, PC, + F0, F1, F2, F3, F4, F5, F6, F7, + FPS, PS +}; + +#endif // CYGHWR_HAL_CORTEXM_FPU + +# define HAL_STUB_REGISTERS_SIZE \ + ((sizeof(HAL_CORTEXM_GDB_Registers) + sizeof(target_register_t) - 1) / sizeof(target_register_t)) + +# define PS_N 0x80000000 +# define PS_Z 0x40000000 +# define PS_C 0x20000000 +# define PS_V 0x10000000 + +typedef enum regnames regnames_t; + +//------------------------------------------------------------------------ + +/* Given a trap value TRAP, return the corresponding signal. */ +extern int __computeSignal (unsigned int trap_number); + +/* Return the trap number corresponding to the last-taken trap. */ +extern int __get_trap_number (void); + +/* Return the currently-saved value corresponding to register REG. */ +extern target_register_t get_register (regnames_t reg); + +/* Store VALUE in the register corresponding to WHICH. */ +extern void put_register (regnames_t which, target_register_t value); + +/* Set the currently-saved pc register value to PC. This also updates NPC + as needed. */ +extern void set_pc (target_register_t pc); + +/* Set things up so that the next user resume will execute one instruction. + This may be done by setting breakpoints or setting a single step flag + in the saved user registers, for example. */ +void __single_step (void); + +/* Clear the single-step state. */ +void __clear_single_step (void); + +/* If the breakpoint we hit is in the breakpoint() instruction, return a + non-zero value. */ +extern int __is_breakpoint_function (void); + +/* Skip the current instruction. */ +extern void __skipinst (void); + +extern void __install_breakpoints (void); + +extern void __clear_breakpoints (void); + +extern int __is_bsp_syscall(void); + +//------------------------------------------------------------------------ +// Special definition of CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION + +#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT +// we can only do this at all if break support is enabled: + +// If this macro is used from Thumb code, we need to pass this information +// along to the place_break function so it can do the right thing. +#define CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION( _old_ ) \ +do { \ + HAL_DISABLE_INTERRUPTS(_old_); \ + cyg_hal_gdb_place_break((target_register_t)((unsigned long)&&cyg_hal_gdb_break_place));\ +} while ( 0 ) + +#endif // CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +//========================================================================== +#endif // ifndef CYGONCE_HAL_CORTEXM_STUB_H diff --git a/ecos/packages/hal/cortexm/arch/current/include/fpv4_sp_d16.h b/ecos/packages/hal/cortexm/arch/current/include/fpv4_sp_d16.h new file mode 100644 index 0000000..d11cf07 --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/include/fpv4_sp_d16.h @@ -0,0 +1,285 @@ +#ifndef CYGONCE_FPV4_SP_D16_H +#define CYGONCE_FPV4_SP_D16_H +//========================================================================== +// +// fpv4_sp_d16.h +// +// FPv4spD16 Floating Point Unit definitions +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2012 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): ilijak +// Contributor(s): +// Date: 2012-04-25 +// Description: FPv4spD16 Floating Point Unit definitions and macros +// Usage: include <cyg/hal/fpv4_sp_d16.h> +// +//####DESCRIPTIONEND#### +// +//======================================================================== + +#if defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_ALL +#define CYGARC_CORTEXM_FPU_EXC_AUTOSAVE +#endif + +//=========================================================================== +// Floating-point Context Control Register +#define CYGARC_REG_FPU_FPCCR 0xE000EF34 + +#define CYGARC_REG_FPU_FPCCR_LSPACT 0x1 +#define CYGARC_REG_FPU_FPCCR_USER 0x2 +#define CYGARC_REG_FPU_FPCCR_THREAD 0x8 +#define CYGARC_REG_FPU_FPCCR_HFRDY 0x10 +#define CYGARC_REG_FPU_FPCCR_MMRDY 0x20 +#define CYGARC_REG_FPU_FPCCR_BFRDY 0x40 +#define CYGARC_REG_FPU_FPCCR_MONRDY 0x100 +#define CYGARC_REG_FPU_FPCCR_LSPEN 0x40000000 +#define CYGARC_REG_FPU_FPCCR_ASPEN 0x80000000 + +#define HAL_CORTEXM_FPU_ENABLE() \ +CYG_MACRO_START \ + cyg_uint32 regval; \ + HAL_READ_UINT32(CYGARC_REG_FPU_CPACR, regval); \ + regval |= CYGARC_REG_FPU_CPACR_ENABLE; \ + HAL_WRITE_UINT32(CYGARC_REG_FPU_CPACR, regval); \ + HAL_MEMORY_BARRIER(); \ +CYG_MACRO_END + +#define HAL_CORTEXM_FPU_DISABLE() \ +CYG_MACRO_START \ + cyg_uint32 regval; \ + HAL_READ_UINT32(CYGARC_REG_FPU_CPACR, regval); \ + regval &= ~CYGARC_REG_FPU_CPACR_ENABLE; \ + HAL_WRITE_UINT32(CYGARC_REG_FPU_CPACR, regval); \ + HAL_MEMORY_BARRIER(); \ +CYG_MACRO_END + +#ifndef __ASSEMBLER__ +__externC void hal_init_fpu(void); +#endif + +// Floating-point Context Address Register +#define CYGARC_REG_FPU_FPCAR 0xE000EF38 + +// Floating-point Default Status Control Register +#define CYGARC_REG_FPU_FPDSCR 0xE000EF3C + +#define CYGARC_REG_FPU_FPDSCR_FZ BIT_(24) +#define CYGARC_REG_FPU_FPDSCR_DN BIT_(25) +#define CYGARC_REG_FPU_FPDSCR_AHP BIT_(26) + +#define CYGARC_REG_FPU_FPDSCR_ROUND(__mode) VALUE_(22, (__mode)) +// where __mode is: +#define CYGARC_REG_FPU_FPDSCR_ROUND_RN 0 +#define CYGARC_REG_FPU_FPDSCR_ROUND_RP 1 +#define CYGARC_REG_FPU_FPDSCR_ROUND_RM 2 +#define CYGARC_REG_FPU_FPDSCR_ROUND_RZ 3 + +//========================================================================== +// FPU Context +#define HAL_SAVEDREGISTERS_WITH_FPU 0x80 + +#define HAL_SAVEDREGISTERS_THREAD_FPU (HAL_SAVEDREGISTERS_THREAD | \ + HAL_SAVEDREGISTERS_WITH_FPU) + +#define HAL_SAVEDREGISTERS_EXCEPTION_FPU (HAL_SAVEDREGISTERS_EXCEPTION | \ + HAL_SAVEDREGISTERS_WITH_FPU) + +#ifndef CYGARC_CORTEXM_FPU_EXC_AUTOSAVE + +// Without automatic contex saving during exception or interrupt +# define HAL_SAVEDREGISTERS_FPU_THREAD_CONTEXT_SIZE (HAL_SAVEDREG_THREAD_FPU_N*4+4) +# define HAL_SAVEDREG_AUTO_FRAME_SIZE (8*4) + +# define HAL_SAVEDREG_AUTO_FPU_EXCEPTION_S + +#else // !CYGARC_CORTEXM_FPU_EXC_AUTOSAVE + +// With automatic contex saving during exception or interrupt enabled +# if defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_ALL + +# define HAL_SAVEDREG_AUTO_EXCEPTION_FPU_N 16 +# define HAL_SAVEDREG_AUTO_FRAME_SIZE (8*4 + 16*4 + 4 + 4) + +// HAL_SavedRegisters entries for floating point registers +// see hal_arch.h for HAL_SavedRegisters definition. + +# define HAL_SAVEDREG_AUTO_FPU_EXCEPTION_S \ + cyg_uint32 s_auto[HAL_SAVEDREG_AUTO_EXCEPTION_FPU_N]; \ + cyg_uint32 fpscr_auto; \ + cyg_uint32 aligner + +# else // defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_ALL +# error "Automatic FPU context saving is not supported in LAZY and NONE modes." +# endif // defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_ALL +#endif // !CYGARC_CORTEXM_FPU_EXC_AUTOSAVE + +// Common for AUTOSAVE and non AUTOSAVE +#if defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_ALL || defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_LAZY + +// HAL_SavedRegisters entries for floating point registers +// see hal_arch.h for HAL_SavedRegisters definition. + +# define HAL_SAVEDREG_THREAD_FPU_N 32 +# define HAL_SAVEDREG_EXCEPTION_FPU_N 32 + +# define HAL_SAVEDREG_FPU_THREAD_S \ + cyg_uint32 fpscr; \ + cyg_uint32 s[HAL_SAVEDREG_THREAD_FPU_N] + +# define HAL_SAVEDREG_FPU_EXCEPTION_S \ + cyg_uint32 s[HAL_SAVEDREG_EXCEPTION_FPU_N]; \ + cyg_uint32 fpscr; \ + cyg_uint32 cpacr + +// Thread FP context initialization +# define HAL_THREAD_INIT_FPU_REGS(__regs_p) \ +CYG_MACRO_START \ + int __reg_i; \ + for(__reg_i = 0; __reg_i < HAL_SAVEDREG_THREAD_FPU_N; __reg_i++) \ + (__regs_p)->u.thread.s[__reg_i] = 0; \ +CYG_MACRO_END + +# define HAL_THREAD_INIT_FPU_CONTEXT(__regs_p) \ +CYG_MACRO_START \ + HAL_THREAD_INIT_FPU_REGS(__regs_p); \ + (__regs_p)->u.thread.fpscr = 0; \ +CYG_MACRO_END +#else //defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_ALL || defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_LAZY + +# define HAL_SAVEDREG_FPU_THREAD_S +# define HAL_THREAD_INIT_FPU_CONTEXT(__regs) CYG_EMPTY_STATEMENT + +#endif //defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_ALL || defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_LAZY +//========================================================================== +// hal_arch.h GDB stub support + +// Register layout expected by GDB VFP +#ifndef __ASSEMBLER__ +typedef struct { + cyg_uint32 gpr[16]; + cyg_uint32 xpsr; + cyg_uint32 s[32]; + cyg_uint32 fpscr; +} HAL_CORTEXM_GDB_Registers; +#endif + +#if defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_ALL || defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_LAZY + +# define GDB_STUB_SAVEDREG_FRAME_TYPE(__regs) \ + ((__regs)->u.type & ~HAL_SAVEDREGISTERS_WITH_FPU) + +# define GDB_STUB_SAVEDREG_FPU_THREAD_GET(__gdbreg,__regs) \ +CYG_MACRO_START \ + cyg_uint32 reg_i; \ + for( reg_i = 0; reg_i < HAL_SAVEDREG_THREAD_FPU_N; reg_i++ ) \ + (__gdbreg)->s[reg_i] = (__regs)->u.thread.s[reg_i]; \ + (__gdbreg)->fpscr = (__regs)->u.thread.fpscr; \ +CYG_MACRO_END + +# define GDB_STUB_SAVEDREG_FPU_THREAD_SET(__gdbreg,__regs) \ +CYG_MACRO_START \ + cyg_uint32 reg_i; \ + for( reg_i = 0; reg_i < HAL_SAVEDREG_THREAD_FPU_N; reg_i++ ) \ + (__regs)->u.thread.s[reg_i] = (__gdbreg)->s[reg_i]; \ + (__regs)->u.thread.fpscr = (__gdbreg)->fpscr; \ +CYG_MACRO_END + +#else // defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_ALL || defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_LAZY + +# define GDB_STUB_SAVEDREG_FRAME_TYPE(__regs) ((__regs)->u.type) +# define GDB_STUB_SAVEDREG_FPU_THREAD_GET(__gdbreg,__regs) CYG_EMPTY_STATEMENT +# define GDB_STUB_SAVEDREG_FPU_THREAD_SET(__gdbreg,__regs) CYG_EMPTY_STATEMENT + +#endif // defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_ALL || defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_LAZY + +#define GDB_STUB_SAVEDREG_FPU_EXCEPTION_GET(__gdbreg,__regs) \ +CYG_MACRO_START \ + cyg_uint32 reg_i; \ + for( reg_i = 0; reg_i < HAL_SAVEDREG_EXCEPTION_FPU_N; reg_i++ ) \ + (__gdbreg)->s[reg_i] = (__regs)->u.exception.s[reg_i]; \ + (__gdbreg)->fpscr = (__regs)->u.exception.fpscr; \ +CYG_MACRO_END + +#define GDB_STUB_SAVEDREG_FPU_EXCEPTION_SET(__gdbreg,__regs) \ +CYG_MACRO_START \ + cyg_uint32 reg_i; \ + for( reg_i = 0; reg_i < HAL_SAVEDREG_EXCEPTION_FPU_N; reg_i++ ) \ + (__regs)->u.exception.s[reg_i] = (__gdbreg)->s[reg_i]; \ + (__regs)->u.exception.fpscr = (__gdbreg)->fpscr; \ + if(*(cyg_uint32 *)CYGARC_REG_FPU_FPCCR & CYGARC_REG_FPU_FPCCR_ASPEN) { \ + for( reg_i = 0; reg_i < HAL_SAVEDREG_AUTO_EXCEPTION_FPU_N; reg_i++ ) \ + (__regs)->u.exception.s_auto[reg_i] = (__regs)->u.exception.s[reg_i]; \ + (__regs)->u.exception.fpscr_auto = (__regs)->u.exception.fpscr; \ + } \ +CYG_MACRO_END + +//========================================================================== +// hal_arch.h Minimal and sensible stack sizes: +// Override value in hal_arch.h +#define CYGNUM_HAL_STACK_CONTEXT_SIZE (4 * (20+32+4+4)) + +// GDB stub ================================================================== +// cortexm_stub.h definitions for FPV4-SP-D16 + +// The Cortex-M4F double registers are larger then target_register_t. +#define TARGET_HAS_LARGE_REGISTERS + +// Cortex-M4F stub register handling macros +#define CYGARC_STUB_REGISTER_ACCESS_DEFINED 1 +#define NUMREGS (FPSCR+1) // 16 GPR, XPSR, 10 non existent, 16 VFP, FPSCR +#define REGSIZE( _x_ ) (_x_ <= PC ? 4 : \ + (_x_ < XPSR ? 0 : \ + (_x_ == XPSR ? 4 : \ + (((_x_ >= VD0) && (_x_ <= VD15)) ? 8 : \ + (_x_ == FPSCR ? 4 : 0 ))))) +#ifndef __ASSEMBLER__ +# ifndef TARGET_REGISTER_T_DEFINED +# define TARGET_REGISTER_T_DEFINED +typedef unsigned long target_register_t; +# endif + +enum regnames { + R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, SP, LR, PC, + XPSR = 25, + VD0 = 26, VD1, VD2, VD3, VD4, VD5, VD6, VD7, + VD8, VD9, VD10, VD11, VD12, VD13, VD14, VD15, + FPSCR +}; +#endif // __ASSEMBLER__ + +//========================================================================== +#endif //CYGONCE_FPV4_SP_D16_H diff --git a/ecos/packages/hal/cortexm/arch/current/include/fpv4_sp_d16_libm.h b/ecos/packages/hal/cortexm/arch/current/include/fpv4_sp_d16_libm.h new file mode 100644 index 0000000..57e70b8 --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/include/fpv4_sp_d16_libm.h @@ -0,0 +1,62 @@ +#ifndef CYGONCE_FPV4_SP_D16_LIBM_H +#define CYGONCE_FPV4_SP_D16_LIBM_H +//========================================================================== +// +// fpv4_sp_d16_libm.h +// +// FPv4spD16 Floating Point Unit mathematical functions +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2013 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): ilijak +// Contributor(s): +// Date: 2013-06-10 +// Description: FPv4spD16 Floating Point Unit builtin mathematical functions. +// Usage: include <cyg/hal/fpv4_sp_d16_libm.h> +// +//####DESCRIPTIONEND#### +// +//======================================================================== + +#ifdef CYGSEM_LIBM_IEEE_API_INLINE + +// Builtin mathematical functions +#define __ieee754_sqrtf(__x) __builtin_sqrtf(__x) + +#endif // CYGSEM_LIBM_IEEE_API_INLINE + +//========================================================================== +#endif //CYGONCE_FPV4_SP_D16_LIBM_H diff --git a/ecos/packages/hal/cortexm/arch/current/include/hal_arch.h b/ecos/packages/hal/cortexm/arch/current/include/hal_arch.h new file mode 100644 index 0000000..f8e73e3 --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/include/hal_arch.h @@ -0,0 +1,390 @@ +#ifndef CYGONCE_HAL_ARCH_H +#define CYGONCE_HAL_ARCH_H +/*========================================================================== +// +// hal_arch.h +// +// Cortex-M architecture abstractions +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2008, 2012 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): nickg +// Contributor(s): ilijak +// Date: 2008-07-30 +// Description: Define architecture abstractions +// +//####DESCRIPTIONEND#### +// +//======================================================================== +*/ + +#ifndef __ASSEMBLER__ + +#include <pkgconf/system.h> +#include <pkgconf/hal.h> +#include <cyg/infra/cyg_type.h> + +#include <cyg/hal/var_arch.h> +#include <cyg/hal/cortexm_regs.h> + +#include <cyg/hal/cortexm_fpu.h> + +#endif //__ASSEMBLER__ + +//========================================================================== +// CPU save state +// +// This is a discriminated union of different save states for threads, +// exceptions and interrupts. State is saved in the most efficient way +// for each context. This makes the GDB state get/put slightly more +// complex, but that is a suitable compromise. + +#define HAL_SAVEDREGISTERS_EXCEPTION 1 +#define HAL_SAVEDREGISTERS_THREAD 2 +#define HAL_SAVEDREGISTERS_INTERRUPT 3 + +#ifndef __ASSEMBLER__ + +typedef struct +{ + union + { + cyg_uint32 type; // State type + + // Thread + struct + { + cyg_uint32 type; // State type + cyg_uint32 basepri; // BASEPRI + cyg_uint32 sp; // SP (R13) + + HAL_SAVEDREG_FPU_THREAD_S; // Floating Point Unit context + + cyg_uint32 r[13]; // R0..R12 + cyg_uint32 pc; // PC/LR + } thread; + + // Exception + struct + { + cyg_uint32 type; // State type + cyg_uint32 vector; // Exception vector number + cyg_uint32 basepri; // BASEPRI + + cyg_uint32 r4_11[8]; // Remaining CPU registers + cyg_uint32 xlr; // Exception return LR +#ifdef CYGSEM_HAL_DEBUG_FPU + HAL_SAVEDREG_FPU_EXCEPTION_S; // Floating Point Unit context +#endif + // The following are saved and restored automatically by the CPU + // for exceptions or interrupts. + + cyg_uint32 r0; + cyg_uint32 r1; + cyg_uint32 r2; + cyg_uint32 r3; + cyg_uint32 r12; + cyg_uint32 lr; + cyg_uint32 pc; + cyg_uint32 psr; + + HAL_SAVEDREG_AUTO_FPU_EXCEPTION_S; // Floating Point Unit context + } exception; + + // Interrupt + struct + { + cyg_uint32 type; // State type + + // The following are saved and restored automatically by the CPU + // for exceptions or interrupts. + + cyg_uint32 r0; + cyg_uint32 r1; + cyg_uint32 r2; + cyg_uint32 r3; + cyg_uint32 r12; + cyg_uint32 lr; + cyg_uint32 pc; + cyg_uint32 psr; + + HAL_SAVEDREG_AUTO_FPU_EXCEPTION_S; // Floating Point Unit context + } interrupt; + } u; + +} HAL_SavedRegisters; + +//========================================================================== +// Thread context initialization + +#ifndef HAL_THREAD_INIT_FPU_CONTEXT +#define HAL_THREAD_INIT_FPU_CONTEXT(__regs) CYG_EMPTY_STATEMENT +#endif + +#define HAL_THREAD_INIT_CONTEXT( __sparg, __thread, __entry, __id ) \ +CYG_MACRO_START \ + register CYG_WORD __sp = ((CYG_WORD)__sparg) & ~7; \ + register CYG_WORD *__ep = (CYG_WORD *)(__sp -= sizeof(CYG_WORD)); \ + register HAL_SavedRegisters *__regs; \ + int __i; \ + __sp = ((CYG_WORD)__sp) &~15; \ + __regs = (HAL_SavedRegisters *)((__sp) - sizeof(__regs->u.thread)); \ + __regs->u.type = HAL_SAVEDREGISTERS_THREAD; \ + for( __i = 1; __i < 13; __i++ ) \ + __regs->u.thread.r[__i] = 0; \ + HAL_THREAD_INIT_FPU_CONTEXT(__regs); \ + *__ep = (CYG_WORD)(__entry); \ + __regs->u.thread.sp = (CYG_WORD)(__sp); \ + __regs->u.thread.r[0] = (CYG_WORD)(__thread); \ + __regs->u.thread.r[1] = (CYG_WORD)(__id); \ + __regs->u.thread.r[11] = (CYG_WORD)(__ep); \ + __regs->u.thread.pc = (CYG_WORD)__entry; \ + __regs->u.thread.basepri = 0; \ + __sparg = (CYG_ADDRESS)__regs; \ +CYG_MACRO_END + +//========================================================================== +// Context switch macros. +// The arguments are pointers to locations where the stack pointer +// of the current thread is to be stored, and from where the SP of the +// next thread is to be fetched. + +__externC void hal_thread_switch_context( CYG_ADDRESS to, CYG_ADDRESS from ); +__externC void hal_thread_load_context( CYG_ADDRESS to ) __attribute__ ((noreturn)); + +#define HAL_THREAD_SWITCH_CONTEXT(__fspptr,__tspptr) \ + hal_thread_switch_context((CYG_ADDRESS)__tspptr, \ + (CYG_ADDRESS)__fspptr); + +#define HAL_THREAD_LOAD_CONTEXT(__tspptr) \ + hal_thread_load_context( (CYG_ADDRESS)__tspptr ); + + +//========================================================================== +// Fetch PC from saved state +#if defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_ALL || \ + defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_LAZY +#define CYGARC_HAL_GET_PC_REG(__regs,__val) \ +{ \ + switch(GDB_STUB_SAVEDREG_FRAME_TYPE(__regs)) \ + { \ + case HAL_SAVEDREGISTERS_THREAD: (__val) = (__regs)->u.thread.pc; break; \ + case HAL_SAVEDREGISTERS_EXCEPTION: (__val) = (__regs)->u.exception.pc; break; \ + case HAL_SAVEDREGISTERS_INTERRUPT: (__val) = (__regs)->u.interrupt.pc; break; \ + default: (__val) = 0; \ + } \ +} +#else +#define CYGARC_HAL_GET_PC_REG(__regs,__val) \ +{ \ + switch( (__regs)->u.type ) \ + { \ + case HAL_SAVEDREGISTERS_THREAD : (__val) = (__regs)->u.thread.pc; break; \ + case HAL_SAVEDREGISTERS_EXCEPTION: (__val) = (__regs)->u.exception.pc; break; \ + case HAL_SAVEDREGISTERS_INTERRUPT: (__val) = (__regs)->u.interrupt.pc; break; \ + default: (__val) = 0; \ + } \ +} +#endif +//========================================================================== +// 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 + +#define HAL_LSBIT_INDEX(__index, __mask) \ +{ \ + register cyg_uint32 __bit = (__mask); \ + register int __count; \ + __bit = __bit & -__bit; \ + __asm__ volatile ("clz %0,%1" : "=r"(__count) : "r"(__bit) ); \ + (__index) = 31-__count; \ +} + +#define HAL_MSBIT_INDEX(__index, __mask) \ +{ \ + register cyg_uint32 __bit = (__mask); \ + register int __count; \ + __asm__ volatile ("clz %0,%1" : "=r"(__count) : "r"(__bit) ); \ + (__index) = 31-__count; \ +} + +//========================================================================== +// Execution reorder barrier. +// When optimizing the compiler can reorder code. In multithreaded systems +// where the order of actions is vital, this can sometimes cause problems. +// This macro may be inserted into places where reordering should not happen. + +#define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" ) + +//========================================================================== +// Breakpoint support +// HAL_BREAKPOINT() is a code sequence that will cause a breakpoint to happen +// if executed. +// HAL_BREAKINST is the value of the breakpoint instruction and +// HAL_BREAKINST_SIZE is its size in bytes. + +#define HAL_BREAKINST 0xbebe // BKPT + +# define HAL_BREAKINST_SIZE 2 +# define HAL_BREAKINST_TYPE cyg_uint16 + +#define _stringify1(__arg) #__arg +#define _stringify(__arg) _stringify1(__arg) + +# define HAL_BREAKPOINT(_label_) \ +__asm__ volatile (" .globl " #_label_ ";" \ + #_label_":" \ + " .short " _stringify(HAL_BREAKINST) \ + ); + +//========================================================================== +// GDB support + +#ifdef CYGARC_CORTEXM_GDB_REG_FPA +// Register layout expected by GDB FPA +typedef struct +{ + cyg_uint32 gpr[16]; + cyg_uint32 f0[3]; + cyg_uint32 f1[3]; + cyg_uint32 f2[3]; + cyg_uint32 f3[3]; + cyg_uint32 f4[3]; + cyg_uint32 f5[3]; + cyg_uint32 f6[3]; + cyg_uint32 f7[3]; + cyg_uint32 fps; + cyg_uint32 xpsr; +} HAL_CORTEXM_GDB_Registers; +#endif + +// Translate a stack pointer as saved by the thread context macros +// into a pointer to a HAL_SavedRegisters structure. On the Cortex-M +// these are equivalent. + +#define HAL_THREAD_GET_SAVED_REGISTERS(__stack, __regs) \ + CYG_MACRO_START \ + (__regs) = (HAL_SavedRegisters*)(__stack); \ + CYG_MACRO_END + + +__externC void hal_get_gdb_registers( HAL_CORTEXM_GDB_Registers *gdbreg, HAL_SavedRegisters *regs ); +__externC void hal_set_gdb_registers( HAL_CORTEXM_GDB_Registers *gdbreg, HAL_SavedRegisters *regs ); + +#define HAL_GET_GDB_REGISTERS(__regval, __regs) hal_get_gdb_registers( (HAL_CORTEXM_GDB_Registers *)(__regval), (HAL_SavedRegisters *)(__regs) ) +#define HAL_SET_GDB_REGISTERS(__regs, __regval) hal_set_gdb_registers( (HAL_CORTEXM_GDB_Registers *)(__regval), (HAL_SavedRegisters *)(__regs) ) + +//========================================================================== +// HAL setjmp + +#define CYGARC_JMP_BUF_SIZE 16 + +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. Here we only supply a default fallback if the variant/platform +// doesn't define anything. + +#ifndef HAL_IDLE_THREAD_ACTION +#define HAL_IDLE_THREAD_ACTION(__count) __asm__ volatile ( "wfi\n" ) +#endif + +//========================================================================== +// Minimal and sensible stack sizes: the intention is that applications +// will use these to provide a stack size in the first instance prior to +// proper analysis. Idle thread stack should be this big. + +// THESE ARE NOT INTENDED TO BE MICROMETRICALLY ACCURATE FIGURES. +// THEY ARE HOWEVER ENOUGH TO START PROGRAMMING. +// YOU MUST MAKE YOUR STACKS LARGER IF YOU HAVE LARGE "AUTO" VARIABLES! + +// This is not a config option because it should not be adjusted except +// under "enough rope" sort of disclaimers. + +// A minimal, optimized stack frame - space for return link plus four +// arguments or local variables. +#define CYGNUM_HAL_STACK_FRAME_SIZE (4 * 20) + +// Stack needed for a context switch +#if !defined CYGNUM_HAL_STACK_CONTEXT_SIZE +#define CYGNUM_HAL_STACK_CONTEXT_SIZE (4 * 20) +#endif + +// Interrupt + call to ISR, interrupt_end() and the DSR +#define CYGNUM_HAL_STACK_INTERRUPT_SIZE \ + (CYGNUM_HAL_STACK_CONTEXT_SIZE + 2 * CYGNUM_HAL_STACK_FRAME_SIZE) + +// Space for the maximum number of nested interrupts, plus room to call functions +#define CYGNUM_HAL_MAX_INTERRUPT_NESTING 4 + +// Minimum stack size. Space for the given number of nested +// interrupts, plus a thread context switch plus a couple of function +// calls. +#define CYGNUM_HAL_STACK_SIZE_MINIMUM \ + ((CYGNUM_HAL_MAX_INTERRUPT_NESTING+1) * CYGNUM_HAL_STACK_INTERRUPT_SIZE + \ + 2 * CYGNUM_HAL_STACK_FRAME_SIZE) + +// Typical stack size -- used mainly for test programs. The minimum +// stack size plus enough space for some function calls. +#define CYGNUM_HAL_STACK_SIZE_TYPICAL \ + (CYGNUM_HAL_STACK_SIZE_MINIMUM + 32 * CYGNUM_HAL_STACK_FRAME_SIZE) + +//========================================================================== +// Macros for switching context between two eCos instances (jump from +// code in ROM to code in RAM or vice versa). + +#define CYGARC_HAL_SAVE_GP() +#define CYGARC_HAL_RESTORE_GP() + +#endif // __ASSEMBLER__ + +//========================================================================== +#endif //CYGONCE_HAL_ARCH_H diff --git a/ecos/packages/hal/cortexm/arch/current/include/hal_arch.inc b/ecos/packages/hal/cortexm/arch/current/include/hal_arch.inc new file mode 100644 index 0000000..bef2e52 --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/include/hal_arch.inc @@ -0,0 +1,115 @@ +/*========================================================================== +// +// hal_arch.inc +// +// Cortex-M exception vector macros +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2012 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): ilijak +// Contributors(s): +// Date: 2012-07-08 +// Description: This file defines some GAS macros exception VSRs. +// +//####DESCRIPTIONEND#### +// +//======================================================================== +*/ + +#ifdef CYGHWR_HAL_CORTEXM_FPU + +# ifdef CYGINT_HAL_FPV4_SP_D16 + +//============================================================================ +// LAZY context switching scheme keeps FPU disabled for the threads that +// don't use floating point. We need to enable it before we save FPU context +// in order to avoid Usage Fault exception. + + .macro hal_fpu_enable + ldr r1,=CYGARC_REG_FPU_CPACR + ldr r2,[r1] + stmdb r0!,{r2} // Save thread's CPACR state + orr r2,#CYGARC_REG_FPU_CPACR_ENABLE + str r2,[r1] + .endm + +//============================================================================ +// Restore thread's FPU usage state. +// undo hal_fpu_enable + + .macro hal_fpu_undo_enable + ldmia r0!,{r2} // Retrieve previous thread's CPACR state + ldr r1,=CYGARC_REG_FPU_CPACR + str r2,[r1] + .endm + +//============================================================================ +// Store FPU context during exception if FPU was disabled then enamble it. + + .macro hal_fpu_exc_push + hal_fpu_enable + vmrs r1,fpscr + stmdb r0!,{r1} + vstmdb.f64 r0!,{d0-d15} + .endm + +//============================================================================ +// Restore FPU context during exception and undo FPU enable. + + .macro hal_fpu_exc_pop + vldmia.f64 r0!,{d0-d15} + ldmia r0!,{r1} + vmsr fpscr,r1 + hal_fpu_undo_enable + .endm + +//============================================================================ +// Make fake fpu frame for hal_pendable_svc_vsr + + .macro hal_fpu_isr_fake_frame_push + sub r12,#4 + vmrs r1,fpscr + stmdb r12!,{r1} + vstmdb.f32 r12!,{s0-s15} + .endm + +# else // CYGINT_HAL_FPV4_SP_D16 +# error Unknown Floating Point Unit! +# endif // CYGINT_HAL_FPV4_SP_D16 + +#endif //CYGHWR_HAL_CORTEXM_FPU + +// end of hal_arch.inc diff --git a/ecos/packages/hal/cortexm/arch/current/include/hal_intr.h b/ecos/packages/hal/cortexm/arch/current/include/hal_intr.h new file mode 100644 index 0000000..21745bd --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/include/hal_intr.h @@ -0,0 +1,409 @@ +#ifndef CYGONCE_HAL_INTR_H +#define CYGONCE_HAL_INTR_H +/*========================================================================== +// +// hal_intr.h +// +// Cortex-M interrupt and clock abstractions +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2008, 2011 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): nickg +// Date: 2008-07-30 +// Description: Define interrupt and clock abstractions +// +//####DESCRIPTIONEND#### +// +//======================================================================== +*/ + +#include <pkgconf/system.h> +#include <pkgconf/hal.h> + +#include <cyg/infra/cyg_type.h> + +#include <cyg/hal/hal_io.h> + +//========================================================================== +// Exception vectors +// +// These are the common vectors defined by all Cortex-M CPUs. The +// exact number of vectors is variant specific, so the limits will be +// defined in var_intr.h. + + +#define CYGNUM_HAL_VECTOR_STACK 0 // Reset stack pointer +#define CYGNUM_HAL_VECTOR_RESET 1 // Reset entry point +#define CYGNUM_HAL_VECTOR_NMI 2 // Non-Maskable Interrupt +#define CYGNUM_HAL_VECTOR_HARD_FAULT 3 // Hard fault +#define CYGNUM_HAL_VECTOR_MEMORY_MAN 4 // Memory management (M3) +#define CYGNUM_HAL_VECTOR_BUS_FAULT 5 // Bus Fault +#define CYGNUM_HAL_VECTOR_USAGE_FAULT 6 // Usage Fault +#define CYGNUM_HAL_VECTOR_RESERVED_07 7 +#define CYGNUM_HAL_VECTOR_RESERVED_08 8 +#define CYGNUM_HAL_VECTOR_RESERVED_09 9 +#define CYGNUM_HAL_VECTOR_RESERVED_10 10 +#define CYGNUM_HAL_VECTOR_SERVICE 11 // System service call +#define CYGNUM_HAL_VECTOR_DEBUG 12 // Debug monitor (M3) +#define CYGNUM_HAL_VECTOR_RESERVED_13 13 +#define CYGNUM_HAL_VECTOR_PENDSV 14 // Pendable svc request +#define CYGNUM_HAL_VECTOR_SYS_TICK 15 // System timer tick +#define CYGNUM_HAL_VECTOR_EXTERNAL 16 // Base of external interrupts + + +//========================================================================== +// Interrupt vectors +// +// The system tick interrupt is mapped to vector 0 and all external +// interrupts are mapped from vector 1 up. + +#define CYGNUM_HAL_INTERRUPT_SYS_TICK 0 +#define CYGNUM_HAL_INTERRUPT_EXTERNAL 1 + + +//========================================================================== +// Include variant definitions here. + +#include <cyg/hal/var_intr.h> + +// Variant or platform allowed to override these definitions to use +// a different RTC +#ifndef CYGNUM_HAL_INTERRUPT_RTC +#define CYGNUM_HAL_INTERRUPT_RTC CYGNUM_HAL_INTERRUPT_SYS_TICK +#endif + +//========================================================================== +// 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_TLBMISS_ACCESS CYGNUM_HAL_VECTOR_MEMORY_MAN +#define CYGNUM_HAL_EXCEPTION_CODE_TLBMISS_ACCESS CYGNUM_HAL_VECTOR_MEMORY_MAN +#define CYGNUM_HAL_EXCEPTION_DATA_ACCESS CYGNUM_HAL_VECTOR_BUS_FAULT +#define CYGNUM_HAL_EXCEPTION_CODE_ACCESS CYGNUM_HAL_VECTOR_BUS_FAULT +#define CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION CYGNUM_HAL_VECTOR_USAGE_FAULT +#define CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS CYGNUM_HAL_VECTOR_USAGE_FAULT +#define CYGNUM_HAL_EXCEPTION_INTERRUPT CYGNUM_HAL_VECTOR_SERVICE + + +#define CYGNUM_HAL_EXCEPTION_MIN CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS +#define CYGNUM_HAL_EXCEPTION_MAX CYGNUM_HAL_EXCEPTION_INTERRUPT +#define CYGNUM_HAL_EXCEPTION_COUNT (CYGNUM_HAL_EXCEPTION_MAX - \ + CYGNUM_HAL_EXCEPTION_MIN + 1) + + +//========================================================================== +// VSR handling + +__externC volatile CYG_ADDRESS hal_vsr_table[CYGNUM_HAL_VSR_COUNT]; + +#ifndef HAL_VSR_GET +#define HAL_VSR_GET( __vector, __pvsr ) \ + *(CYG_ADDRESS *)(__pvsr) = hal_vsr_table[__vector]; +#endif + +#ifndef HAL_VSR_SET +#define HAL_VSR_SET( __vector, __vsr, __poldvsr ) \ +CYG_MACRO_START \ + if( __poldvsr != NULL ) \ + *(CYG_ADDRESS *)__poldvsr = hal_vsr_table[__vector]; \ + hal_vsr_table[__vector] = (CYG_ADDRESS)__vsr; \ +CYG_MACRO_END +#endif + +#ifndef HAL_VSR_SET_TO_ECOS_HANDLER +__externC void hal_default_interrupt_vsr( void ); +__externC void hal_default_exception_vsr( void ); +# define HAL_VSR_SET_TO_ECOS_HANDLER( __vector, __poldvsr ) \ +CYG_MACRO_START \ + cyg_uint32 __vector2 = (cyg_uint32) (__vector); \ + CYG_ADDRESS* __poldvsr2 = (CYG_ADDRESS*)(__poldvsr); \ + if( __vector2 < CYGNUM_HAL_VECTOR_SYS_TICK ) \ + HAL_VSR_SET(__vector2, &hal_default_exception_vsr, __poldvsr2); \ + else \ + HAL_VSR_SET(__vector2, &hal_default_interrupt_vsr, __poldvsr2); \ +CYG_MACRO_END +#endif + +// Default definition of HAL_TRANSLATE_VECTOR(), a no-op +#ifndef HAL_TRANSLATE_VECTOR +# define HAL_TRANSLATE_VECTOR(__vector, __index) ((__index) = (__vector)) +#endif + +//========================================================================== +// ISR handling +// +// Interrupt handler/data/object tables plus functions and macros to +// manipulate them. + +__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]; + +//-------------------------------------------------------------------------- +// Interrupt delivery +// +// This function is used by the HAL to deliver an interrupt, and post +// a DSR if required. It may also be used to deliver secondary +// interrupts from springboard ISRs. + +__externC void hal_deliver_interrupt( cyg_uint32 vector ); + +//-------------------------------------------------------------------------- +// Default ISR The #define is used to test whether this routine +// exists, and to allow code outside the HAL to call it. + +externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data); +#define HAL_DEFAULT_ISR hal_default_isr + +//-------------------------------------------------------------------------- + +#define HAL_INTERRUPT_IN_USE( _vector_, _state_) \ +{ \ + cyg_uint32 _index_; \ + HAL_TRANSLATE_VECTOR ((_vector_), _index_); \ + \ + if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)hal_default_isr ) \ + (_state_) = 0; \ + else \ + (_state_) = 1; \ +} + +#define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ ) \ +{ \ + if( hal_interrupt_handlers[_vector_] == (CYG_ADDRESS)hal_default_isr ) \ + { \ + hal_interrupt_handlers[_vector_] = (CYG_ADDRESS)_isr_; \ + hal_interrupt_data[_vector_] = (CYG_ADDRWORD) _data_; \ + hal_interrupt_objects[_vector_] = (CYG_ADDRESS)_object_; \ + } \ +} + +#define HAL_INTERRUPT_DETACH( _vector_, _isr_ ) \ +{ \ + if( hal_interrupt_handlers[_vector_] == (CYG_ADDRESS)_isr_ ) \ + { \ + hal_interrupt_handlers[_vector_] = (CYG_ADDRESS)hal_default_isr; \ + hal_interrupt_data[_vector_] = 0; \ + hal_interrupt_objects[_vector_] = 0; \ + } \ +} + +//-------------------------------------------------------------------------- +// CPU interrupt control. +// +// We use the BASEPRI register to control delivery of interrupts. The +// register is set to the second highest implemented priority for this +// Cortex-M implementation to mask interrupts. It is set to zero to +// enable interrupts, which will disable the BASEPRI mechanism. + +#ifndef __ASSEMBLER__ +typedef cyg_uint32 CYG_INTERRUPT_STATE; +#endif + +#ifndef HAL_DISABLE_INTERRUPTS +# define HAL_DISABLE_INTERRUPTS(__old) \ + __asm__ volatile ( \ + "mrs %0, basepri \n" \ + "mov r1,%1 \n" \ + "msr basepri,r1 \n" \ + : "=&r" (__old) \ + : "r" (CYGNUM_HAL_CORTEXM_PRIORITY_MAX)\ + : "r1" \ + ); +#endif + +#ifndef HAL_RESTORE_INTERRUPTS +# define HAL_RESTORE_INTERRUPTS(__old) \ + __asm__ volatile ( \ + "msr basepri, %0 \n" \ + : \ + : "r" (__old) \ + ); +#endif + +#ifndef HAL_ENABLE_INTERRUPTS +# define HAL_ENABLE_INTERRUPTS() \ + __asm__ volatile ( \ + "mov r1,#0 \n" \ + "msr basepri,r1 \n" \ + : \ + : \ + : "r1" \ + ); +#endif + +#ifndef HAL_QUERY_INTERRUPTS +#define HAL_QUERY_INTERRUPTS(__state) \ + __asm__ volatile ( \ + "mrs %0, basepri \n" \ + : "=r" (__state) \ + ); +#endif + +//-------------------------------------------------------------------------- +// Interrupt masking and unmasking +// +// This is mostly done via the architecture defined NVIC. The +// HAL_VAR_*() macros allow the variant HAL to provide extended +// support for additional interrupt sources supported by supplementary +// interrupt controllers. + +__externC void hal_interrupt_mask( cyg_uint32 vector ); +__externC void hal_interrupt_unmask( cyg_uint32 vector ); +__externC void hal_interrupt_set_level( cyg_uint32 vector, cyg_uint32 level ); +__externC void hal_interrupt_acknowledge( cyg_uint32 vector ); +__externC void hal_interrupt_configure( cyg_uint32 vector, cyg_uint32 level, cyg_uint32 up ); + + +#define HAL_INTERRUPT_MASK( __vector ) hal_interrupt_mask( __vector ) +#define HAL_INTERRUPT_UNMASK( __vector ) hal_interrupt_unmask( __vector ) +#define HAL_INTERRUPT_SET_LEVEL( __vector, __level ) hal_interrupt_set_level( __vector, __level ) +#define HAL_INTERRUPT_ACKNOWLEDGE( __vector ) hal_interrupt_acknowledge( __vector ) +#define HAL_INTERRUPT_CONFIGURE( __vector, __level, __up ) hal_interrupt_configure( __vector, __level, __up ) + +//-------------------------------------------------------------------------- +// Routine to execute DSRs using separate interrupt stack + +__externC void hal_call_dsrs_vsr(void); +#define HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() \ +{ \ + __asm__ volatile ( \ + "ldr r3,=hal_call_dsrs_vsr \n" \ + "swi 0 \n" \ + : \ + : \ + : "r3" \ + ); \ +} + +//-------------------------------------------------------------------------- + +#if 0 +// 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 + +//========================================================================== +// Clock control +// +// This uses the CPU SysTick timer. Variant or platform allowed to override +// these definitions + +#ifndef CYGHWR_HAL_CLOCK_DEFINED + +__externC cyg_uint32 hal_cortexm_systick_clock; + +// Select the clock source of the system tick timer +#ifdef CYGHWR_HAL_CORTEXM_SYSTICK_CLK_SOURCE_EXTERNAL + #define CYGARC_REG_SYSTICK_CSR_CLK_SRC CYGARC_REG_SYSTICK_CSR_CLK_EXT +#elif defined(CYGHWR_HAL_CORTEXM_SYSTICK_CLK_SOURCE_INTERNAL) + #define CYGARC_REG_SYSTICK_CSR_CLK_SRC CYGARC_REG_SYSTICK_CSR_CLK_INT +#endif + +#define HAL_CLOCK_INITIALIZE( __period ) \ +{ \ + cyg_uint32 __p = __period; \ + __p = hal_cortexm_systick_clock / ( 1000000 / __p ) - 1; \ + HAL_WRITE_UINT32(CYGARC_REG_SYSTICK_BASE+CYGARC_REG_SYSTICK_RELOAD, \ + __p ); \ + HAL_WRITE_UINT32(CYGARC_REG_SYSTICK_BASE+CYGARC_REG_SYSTICK_CSR, \ + CYGARC_REG_SYSTICK_CSR_ENABLE | \ + CYGARC_REG_SYSTICK_CSR_CLK_SRC ); \ +} + +#define HAL_CLOCK_RESET( __vector, __period ) \ +{ \ + cyg_uint32 __csr CYGBLD_ATTRIB_UNUSED; \ + HAL_READ_UINT32(CYGARC_REG_SYSTICK_BASE+CYGARC_REG_SYSTICK_CSR, __csr ); \ +} + +#define HAL_CLOCK_READ( __pvalue ) \ +{ \ + cyg_uint32 __period, __value; \ + HAL_READ_UINT32(CYGARC_REG_SYSTICK_BASE+CYGARC_REG_SYSTICK_RELOAD, __period ); \ + HAL_READ_UINT32(CYGARC_REG_SYSTICK_BASE+CYGARC_REG_SYSTICK_VALUE, __value ); \ + __value = ( __period + 1 ) - __value; \ + __value /= (hal_cortexm_systick_clock / 1000000 ); \ + *(__pvalue) = __value; \ +} + +#define HAL_CLOCK_READ_NS( __pvalue ) \ +CYG_MACRO_START \ + cyg_uint32 __period, __value; \ + HAL_READ_UINT32(CYGARC_REG_SYSTICK_BASE+CYGARC_REG_SYSTICK_RELOAD, __period ); \ + HAL_READ_UINT32(CYGARC_REG_SYSTICK_BASE+CYGARC_REG_SYSTICK_VALUE, __value ); \ + __value = (( __period + 1 ) - __value) * 1000; \ + __value /= (hal_cortexm_systick_clock / 1000000 ); \ + *(__pvalue) = __value; \ +CYG_MACRO_END + +#define HAL_CLOCK_LATENCY( __pvalue ) HAL_CLOCK_READ( __pvalue ) + +#endif // CYGHWR_HAL_CLOCK_DEFINED + +//========================================================================== +// HAL_DELAY_US(). +// + +__externC void hal_delay_us( cyg_int32 us ); +#define HAL_DELAY_US( __us ) hal_delay_us( __us ) + +//========================================================================== +// Reset. +// +// This uses the SYSRESETREQ bit in the Cortex-M3 NVIC. + +#define HAL_PLATFORM_RESET() \ +{ \ + HAL_WRITE_UINT32(CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_AIRCR, \ + CYGARC_REG_NVIC_AIRCR_KEY| \ + CYGARC_REG_NVIC_AIRCR_SYSRESETREQ ); \ + for(;;); \ +} + +__externC void hal_reset_vsr( void ); +#define HAL_PLATFORM_RESET_ENTRY &hal_reset_vsr + +//========================================================================== +#endif //CYGONCE_HAL_INTR_H diff --git a/ecos/packages/hal/cortexm/arch/current/include/hal_io.h b/ecos/packages/hal/cortexm/arch/current/include/hal_io.h new file mode 100644 index 0000000..c5df099 --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/include/hal_io.h @@ -0,0 +1,417 @@ +#ifndef CYGONCE_HAL_IO_H +#define CYGONCE_HAL_IO_H +/*========================================================================== +// +// hal_io.h +// +// Cortex-M architecture IO register definitions +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2008 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): nickg +// Date: 2008-07-30 +// Description: Define IO registers +// +//####DESCRIPTIONEND#### +// +//======================================================================== +*/ + +#include <pkgconf/system.h> +#include <pkgconf/hal.h> + +#include <cyg/infra/cyg_type.h> + +#include <cyg/hal/var_io.h> + +//========================================================================== +// Handy macros for defining register bits and fields: +// + +#define BIT_(__n) (1<<(__n)) +#define MASK_(__n,__s) (((1<<(__s))-1)<<(__n)) +#define VALUE_(__n,__v) ((__v)<<(__n)) + +//========================================================================== +// SysTick timer +// +// This is really part of the NVIC, but we break it out into a +// separate definition for convenience. + +#define CYGARC_REG_SYSTICK_BASE 0xE000E010 + +#define CYGARC_REG_SYSTICK_CSR 0 +#define CYGARC_REG_SYSTICK_RELOAD 4 +#define CYGARC_REG_SYSTICK_VALUE 8 +#define CYGARC_REG_SYSTICK_CAL 12 + +#define CYGARC_REG_SYSTICK_CSR_COUNTFLAG BIT_(16) +#define CYGARC_REG_SYSTICK_CSR_CLK_EXT VALUE_(2,0) +#define CYGARC_REG_SYSTICK_CSR_CLK_INT VALUE_(2,1) +#define CYGARC_REG_SYSTICK_CSR_TICKINT BIT_(1) +#define CYGARC_REG_SYSTICK_CSR_ENABLE BIT_(0) + +#define CYGARC_REG_SYSTICK_CAL_NOREF BIT_(31) +#define CYGARC_REG_SYSTICK_CAL_SKEW BIT_(30) +#define CYGARC_REG_SYSTICK_CAL_TENMS MASK_(0,23) + +//========================================================================== +// NVIC registers + +#define CYGARC_REG_NVIC_BASE 0xE000E000 + +#if defined(CYGHWR_HAL_CORTEXM_M3) || defined(CYGHWR_HAL_CORTEXM_M4) +#define CYGARC_REG_NVIC_TYPE 0x004 +#endif + +#define CYGARC_REG_NVIC_SER0 0x100 +#define CYGARC_REG_NVIC_CER0 0x180 +#define CYGARC_REG_NVIC_SPR0 0x200 +#define CYGARC_REG_NVIC_CPR0 0x280 +#define CYGARC_REG_NVIC_ABR0 0x300 +#define CYGARC_REG_NVIC_PR0 0x400 + +// Generate address of 32 bit control register for interrupt +#define CYGARC_REG_NVIC_SER(__intr) (CYGARC_REG_NVIC_SER0+4*((__intr)>>5)) +#define CYGARC_REG_NVIC_CER(__intr) (CYGARC_REG_NVIC_CER0+4*((__intr)>>5)) +#define CYGARC_REG_NVIC_SPR(__intr) (CYGARC_REG_NVIC_SPR0+4*((__intr)>>5)) +#define CYGARC_REG_NVIC_CPR(__intr) (CYGARC_REG_NVIC_CPR0+4*((__intr)>>5)) +#define CYGARC_REG_NVIC_ABR(__intr) (CYGARC_REG_NVIC_ABR0+4*((__intr)>>5)) + +// Generate bit in register for interrupt +#define CYGARC_REG_NVIC_IBIT(__intr) BIT_((__intr)&0x1F) + +// Generate byte address of interrupt's priority register. +#define CYGARC_REG_NVIC_PR(__intr) (CYGARC_REG_NVIC_PR0+(__intr)) + + +#if defined(CYGHWR_HAL_CORTEXM_M3) || defined(CYGHWR_HAL_CORTEXM_M4) + +#define CYGARC_REG_NVIC_CPUID 0xD00 +#define CYGARC_REG_NVIC_ICSR 0xD04 +#define CYGARC_REG_NVIC_VTOR 0xD08 +#define CYGARC_REG_NVIC_AIRCR 0xD0C +#define CYGARC_REG_NVIC_SCR 0xD10 +#define CYGARC_REG_NVIC_CCR 0xD14 +#define CYGARC_REG_NVIC_SHPR0 0xD18 +#define CYGARC_REG_NVIC_SHPR1 0xD1C +#define CYGARC_REG_NVIC_SHPR2 0xD20 +#define CYGARC_REG_NVIC_SHCSR 0xD24 +#define CYGARC_REG_NVIC_CFSR 0xD28 +#define CYGARC_REG_NVIC_HFSR 0xD2C +#define CYGARC_REG_NVIC_DFSR 0xD30 +#define CYGARC_REG_NVIC_MMAR 0xD34 +#define CYGARC_REG_NVIC_BFAR 0xD38 +#define CYGARC_REG_NVIC_AFSR 0xD3C +#define CYGARC_REG_NVIC_PFR0 0xD40 +#define CYGARC_REG_NVIC_PFR1 0xD44 +#define CYGARC_REG_NVIC_DFR0 0xD48 +#define CYGARC_REG_NVIC_AFR0 0xD4C +#define CYGARC_REG_NVIC_MMFR0 0xD50 +#define CYGARC_REG_NVIC_MMFR1 0xD54 +#define CYGARC_REG_NVIC_MMFR2 0xD58 +#define CYGARC_REG_NVIC_MMFR3 0xD5C +#define CYGARC_REG_NVIC_ISAR0 0xD60 +#define CYGARC_REG_NVIC_ISAR1 0xD64 +#define CYGARC_REG_NVIC_ISAR2 0xD68 +#define CYGARC_REG_NVIC_ISAR3 0xD6C +#define CYGARC_REG_NVIC_ISAR4 0xD70 +#define CYGARC_REG_NVIC_STIR 0xF00 +#define CYGARC_REG_NVIC_PID4 0xFD0 +#define CYGARC_REG_NVIC_PID5 0xFD4 +#define CYGARC_REG_NVIC_PID6 0xFD8 +#define CYGARC_REG_NVIC_PID7 0xFDC +#define CYGARC_REG_NVIC_PID0 0xFE0 +#define CYGARC_REG_NVIC_PID1 0xFE4 +#define CYGARC_REG_NVIC_PID2 0xFE8 +#define CYGARC_REG_NVIC_PID3 0xFEC +#define CYGARC_REG_NVIC_CID0 0xFF0 +#define CYGARC_REG_NVIC_CID1 0xFF4 +#define CYGARC_REG_NVIC_CID2 0xFF8 +#define CYGARC_REG_NVIC_CID3 0xFFC + +// ICSR + +#define CYGARC_REG_NVIC_ICSR_NMIPENDSET BIT_(31) +#define CYGARC_REG_NVIC_ICSR_PENDSVSET BIT_(28) +#define CYGARC_REG_NVIC_ICSR_PENDSVCLR BIT_(27) +#define CYGARC_REG_NVIC_ICSR_PENDSTSET BIT_(26) +#define CYGARC_REG_NVIC_ICSR_PENDSTCLR BIT_(25) +#define CYGARC_REG_NVIC_ICSR_ISRPREEMPT BIT_(23) +#define CYGARC_REG_NVIC_ICSR_ISRPENDING BIT_(22) +#define CYGARC_REG_NVIC_ICSR_VECTPENDING MASK_(12,9) +#define CYGARC_REG_NVIC_ICSR_RETTOBASE BIT_(11) +#define CYGARC_REG_NVIC_ICSR_VECTACTIVE MASK_(0,9) + +// VTOR + +#define CYGARC_REG_NVIC_VTOR_TBLOFF(__o) VALUE_(7,__o) +#define CYGARC_REG_NVIC_VTOR_TBLBASE_CODE 0 +#ifndef CYGARC_REG_NVIC_VTOR_TBLBASE_SRAM +#define CYGARC_REG_NVIC_VTOR_TBLBASE_SRAM BIT_(29) +#endif + +// AI/RCR + +#define CYGARC_REG_NVIC_AIRCR_KEY VALUE_(16,0x5FA) +#define CYGARC_REG_NVIC_AIRCR_BIGENDIAN BIT_(15) +#define CYGARC_REG_NVIC_AIRCR_PRIGROUP(__p) VALUE_(8,__p) +#define CYGARC_REG_NVIC_AIRCR_SYSRESETREQ BIT_(2) +#define CYGARC_REG_NVIC_AIRCR_VECTCLRACTIVE BIT_(1) +#define CYGARC_REG_NVIC_AIRCR_VECTRESET BIT_(0) + +// SCR + +#define CYGARC_REG_NVIC_SCR_SLEEPONEXIT BIT_(1) +#define CYGARC_REG_NVIC_SCR_DEEPSLEEP BIT_(2) +#define CYGARC_REG_NVIC_SCR_SEVONPEND BIT_(4) + +// SHCSR + +#define CYGARC_REG_NVIC_SHCSR_USGFAULTENA BIT_(18) +#define CYGARC_REG_NVIC_SHCSR_BUSFAULTENA BIT_(17) +#define CYGARC_REG_NVIC_SHCSR_MEMFAULTENA BIT_(16) +#define CYGARC_REG_NVIC_SHCSR_SVCALLPENDED BIT_(15) +#define CYGARC_REG_NVIC_SHCSR_BUSFAULTPENDED BIT_(14) +#define CYGARC_REG_NVIC_SHCSR_MEMFAULTPENDED BIT_(13) +#define CYGARC_REG_NVIC_SHCSR_USGFAULTPENDED BIT_(12) +#define CYGARC_REG_NVIC_SHCSR_SYSTICKACT BIT_(11) +#define CYGARC_REG_NVIC_SHCSR_PENDSVACT BIT_(10) +#define CYGARC_REG_NVIC_SHCSR_MONITORACT BIT_(8) +#define CYGARC_REG_NVIC_SHCSR_SVCALLACT BIT_(7) +#define CYGARC_REG_NVIC_SHCSR_USGFAULTACT BIT_(3) +#define CYGARC_REG_NVIC_SHCSR_BUSFAULTACT BIT_(1) +#define CYGARC_REG_NVIC_SHCSR_MEMFAULTACT BIT_(0) + +// Usage Fault register + +#define CYGARC_REG_UFSR 0xE000ED2A +#define CYGARC_REG_UFSR_DIVBYZERO BIT_(9) +#define CYGARC_REG_UFSR_UNALIGNED BIT_(8) +#define CYGARC_REG_UFSR_NOCP BIT_(3) +#define CYGARC_REG_UFSR_INVPC BIT_(2) +#define CYGARC_REG_UFSR_INVSTATE BIT_(1) +#define CYGARC_REG_UFSR_UNDEFINSTR BIT_(0) + +#endif + +//========================================================================== +// Debug registers + +#if defined(CYGHWR_HAL_CORTEXM_M3) || defined(CYGHWR_HAL_CORTEXM_M4) + +#define CYGARC_REG_DEBUG_BASE 0xE000EDF0 + +#define CYGARC_REG_DEBUG_DHSR 0x00 +#define CYGARC_REG_DEBUG_DCRSR 0x04 +#define CYGARC_REG_DEBUG_DCRDR 0x08 +#define CYGARC_REG_DEBUG_DEMCR 0x0C + + +#define CYGARC_REG_DEBUG_DHSR_DBGKEY VALUE_(16,0xA05F) +#define CYGARC_REG_DEBUG_DHSR_S_RESET BIT_(25) +#define CYGARC_REG_DEBUG_DHSR_S_RETIRE BIT_(24) +#define CYGARC_REG_DEBUG_DHSR_S_LOCKUP BIT_(19) +#define CYGARC_REG_DEBUG_DHSR_S_SLEEP BIT_(18) +#define CYGARC_REG_DEBUG_DHSR_S_HALT BIT_(17) +#define CYGARC_REG_DEBUG_DHSR_S_REGRDY BIT_(16) +#define CYGARC_REG_DEBUG_DHSR_C_SNAPSTALL BIT_(5) +#define CYGARC_REG_DEBUG_DHSR_C_MASKINTS BIT_(3) +#define CYGARC_REG_DEBUG_DHSR_C_STEP BIT_(2) +#define CYGARC_REG_DEBUG_DHSR_C_HALT BIT_(1) +#define CYGARC_REG_DEBUG_DHSR_C_DEBUGEN BIT_(0) + + +#define CYGARC_REG_DEBUG_DCRSR_REG_WRITE BIT_(16) +#define CYGARC_REG_DEBUG_DCRSR_REG_READ 0 +#define CYGARC_REG_DEBUG_DCRSR_REG(__x) VALUE_(0,__x) + + +#define CYGARC_REG_DEBUG_DEMCR_TRCENA BIT_(24) +#define CYGARC_REG_DEBUG_DEMCR_MON_REQ BIT_(19) +#define CYGARC_REG_DEBUG_DEMCR_MON_STEP BIT_(18) +#define CYGARC_REG_DEBUG_DEMCR_MON_PEND BIT_(17) +#define CYGARC_REG_DEBUG_DEMCR_MON_EN BIT_(16) +#define CYGARC_REG_DEBUG_DEMCR_VC_HARDERR BIT_(10) +#define CYGARC_REG_DEBUG_DEMCR_VC_INTERR BIT_(9) +#define CYGARC_REG_DEBUG_DEMCR_VC_BUSERR BIT_(8) +#define CYGARC_REG_DEBUG_DEMCR_VC_STATERR BIT_(7) +#define CYGARC_REG_DEBUG_DEMCR_VC_CHKERR BIT_(6) +#define CYGARC_REG_DEBUG_DEMCR_VC_NOCPERR BIT_(5) +#define CYGARC_REG_DEBUG_DEMCR_VC_MMERR BIT_(4) +#define CYGARC_REG_DEBUG_DEMCR_VC_CORERESET BIT_(0) + +#endif + +//========================================================================== +// 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_MACRO_START \ + cyg_count32 _i_,_j_; \ + for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ + (_buf_)[_i_] = ((volatile CYG_BYTE *)(_register_))[_j_]; \ + CYG_MACRO_END + +#define HAL_WRITE_UINT8_VECTOR( _register_, _buf_, _count_, _step_ ) \ + CYG_MACRO_START \ + cyg_count32 _i_,_j_; \ + for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ + ((volatile CYG_BYTE *)(_register_))[_j_] = (_buf_)[_i_]; \ + CYG_MACRO_END + +#define HAL_READ_UINT8_STRING( _register_, _buf_, _count_ ) \ + CYG_MACRO_START \ + cyg_count32 _i_; \ + for( _i_ = 0; _i_ < (_count_); _i_++) \ + (_buf_)[_i_] = ((volatile CYG_BYTE *)(_register_))[_i_]; \ + CYG_MACRO_END + +#define HAL_WRITE_UINT8_STRING( _register_, _buf_, _count_ ) \ + CYG_MACRO_START \ + cyg_count32 _i_; \ + for( _i_ = 0; _i_ < (_count_); _i_++) \ + ((volatile CYG_BYTE *)(_register_)) = (_buf_)[_i_]; \ + CYG_MACRO_END + +//----------------------------------------------------------------------------- +// 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_MACRO_START \ + cyg_count32 _i_,_j_; \ + for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ + (_buf_)[_i_] = ((volatile CYG_WORD16 *)(_register_))[_j_]; \ + CYG_MACRO_END + +#define HAL_WRITE_UINT16_VECTOR( _register_, _buf_, _count_, _step_ ) \ + CYG_MACRO_START \ + cyg_count32 _i_,_j_; \ + for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ + ((volatile CYG_WORD16 *)(_register_))[_j_] = (_buf_)[_i_]; \ + CYG_MACRO_END + +#define HAL_READ_UINT16_STRING( _register_, _buf_, _count_) \ + CYG_MACRO_START \ + cyg_count32 _i_; \ + for( _i_ = 0; _i_ < (_count_); _i_++) \ + (_buf_)[_i_] = ((volatile CYG_WORD16 *)(_register_))[_i_]; \ + CYG_MACRO_END + +#define HAL_WRITE_UINT16_STRING( _register_, _buf_, _count_) \ + CYG_MACRO_START \ + cyg_count32 _i_; \ + for( _i_ = 0; _i_ < (_count_); _i_++) \ + ((volatile CYG_WORD16 *)(_register_))[_i_] = (_buf_)[_i_]; \ + CYG_MACRO_END + +//----------------------------------------------------------------------------- +// 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_MACRO_START \ + cyg_count32 _i_,_j_; \ + for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ + (_buf_)[_i_] = ((volatile CYG_WORD32 *)(_register_))[_j_]; \ + CYG_MACRO_END + +#define HAL_WRITE_UINT32_VECTOR( _register_, _buf_, _count_, _step_ ) \ + CYG_MACRO_START \ + cyg_count32 _i_,_j_; \ + for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ + ((volatile CYG_WORD32 *)(_register_))[_j_] = (_buf_)[_i_]; \ + CYG_MACRO_END + +#define HAL_READ_UINT32_STRING( _register_, _buf_, _count_) \ + CYG_MACRO_START \ + cyg_count32 _i_; \ + for( _i_ = 0; _i_ < (_count_); _i_++) \ + (_buf_)[_i_] = ((volatile CYG_WORD32 *)(_register_))[_i_]; \ + CYG_MACRO_END + +#define HAL_WRITE_UINT32_STRING( _register_, _buf_, _count_) \ + CYG_MACRO_START \ + cyg_count32 _i_; \ + for( _i_ = 0; _i_ < (_count_); _i_++) \ + ((volatile CYG_WORD32 *)(_register_))[_i_] = (_buf_)[_i_]; \ + CYG_MACRO_END + + +#define HAL_IO_MACROS_DEFINED + +#endif // !HAL_IO_MACROS_DEFINED + +// Enforce a flow "barrier" to prevent optimizing compiler from reordering +// operations. +#define HAL_IO_BARRIER() + + +//========================================================================== +#endif //CYGONCE_HAL_IO_H diff --git a/ecos/packages/hal/cortexm/arch/current/src/context.S b/ecos/packages/hal/cortexm/arch/current/src/context.S new file mode 100644 index 0000000..0ebe186 --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/src/context.S @@ -0,0 +1,267 @@ +/*========================================================================== +// +// context.S +// +// Cortex-M context switch code +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2008, 2012 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): nickg, ilijak (FPU support) +// Contributor(s): +// Date: 2008-07-30 +// Description: This file contains thread context switch code. +// +//####DESCRIPTIONEND#### +// +//======================================================================== +*/ + +#include <pkgconf/system.h> +#include <pkgconf/hal.h> +#include <pkgconf/hal_cortexm.h> +#ifdef CYGPKG_KERNEL +#include <pkgconf/kernel.h> +#endif + +#ifdef CYGHWR_HAL_CORTEXM_FPU +#include <cyg/hal/hal_arch.h> +#include <cyg/hal/cortexm_fpu.h> // Optional Floating Point Unit + +#endif + +//========================================================================== + + .syntax unified + .thumb + .text + +//========================================================================== +// Context switch +// +// R0 contains a pointer to the SP of the thread to load, R1 contains +// a pointer to the SP of the current thread. + +#ifdef CYGHWR_HAL_CORTEXM_FPU_SWITCH_LAZY +//========================================================================== +// LAZY Context switch +// +// Save the FPU registers only for threads that use FPU. +// + + .globl hal_thread_switch_context + .thumb + .thumb_func + .type hal_thread_switch_context, %function +hal_thread_switch_context: + + push {r0-r12,lr} // Push all savable register + ldr r7,=CYGARC_REG_FPU_CPACR // + ldr r6,[r7] + tst r6,#CYGARC_REG_FPU_CPACR_ENABLE // Is FPU enabled? + beq lazy_float_push // N: Be lazy. + vmrs r5,fpscr // Y: Save FPU context + vpush.f64 {d0-d15} // Push FPU registers + push {r5} // together with FPSCR + mov r2,#HAL_SAVEDREGISTERS_THREAD_FPU // Set state type: thread with FPU + b float_push_join + lazy_float_push: + mov r2,#HAL_SAVEDREGISTERS_THREAD + sub sp,#HAL_SAVEDREGISTERS_FPU_THREAD_CONTEXT_SIZE + float_push_join: + mrs r3,basepri // Get priority base register + mov r4,sp // Get SP (for info only) + push {r2-r4} // Push them + str sp,[r1] // Save SP + // Fall through + +//-------------------------------------------------------------------------- +// Load context +// +// This is used to load a thread context, abandoning the current one. Following +// function part is the second half of hal_thread_switch_context. + + + .globl hal_thread_load_context + .thumb + .thumb_func + .type hal_thread_load_context, %function +hal_thread_load_context_common: + + ldr sp,[r0] // Load SP + pop {r2-r4} // Pop type, basepri, SP(discarded) and FPSCR + msr basepri,r3 // Set BASEPRI + cmp r2,#HAL_SAVEDREGISTERS_THREAD_FPU // Is state type a FP thread? + beq real_float_pop // Y: + // N: Be lazy + and r6,#~CYGARC_REG_FPU_CPACR_ENABLE + add sp,#HAL_SAVEDREGISTERS_FPU_THREAD_CONTEXT_SIZE + str r6,[r7] + pop {r0-r12,pc} // Pop all registers and return to an non-FP thread + + real_float_pop: // Restore floating point context for FP thread. + orr r6,#CYGARC_REG_FPU_CPACR_ENABLE + pop {r5} // Retrieve FPU status register + str r6,[r7] + dsb + isb + vpop.f64 {d0-d15} // Pestore FPU registers + vmsr fpscr,r5 // Restore FPU status register + pop {r0-r12,pc} // Pop all registers and return to a FP thread. + +// Load context entry point +// Load context initially needs CPACR register, so it is provided here. +hal_thread_load_context: + ldr r7,=CYGARC_REG_FPU_CPACR + ldr r6,[r7] + b hal_thread_load_context_common + +#elif defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_ALL + +//========================================================================== +// ALL Context switch +// +// Save the FPU registers for all threads. +// + + .globl hal_thread_switch_context + .thumb + .thumb_func + .type hal_thread_switch_context, %function +hal_thread_switch_context: + + push {r0-r12,lr} // Push all savable register + vmrs r5,fpscr + mov r2,#HAL_SAVEDREGISTERS_THREAD_FPU // Set state type == thread + vpush.f64 {d0-d15} // Push FPU registers + sub r4,sp,#4 // Get SP (for info only) + mrs r3,basepri // Get priority base register + push {r2-r5} // Push them + str sp,[r1] // Save SP + // Fall through + +//-------------------------------------------------------------------------- +// Load context +// +// This is used to load a thread context, abandoning the current one. This +// function is also the second half of hal_thread_switch_context. + + + .globl hal_thread_load_context + .thumb + .thumb_func + .type hal_thread_load_context, %function +hal_thread_load_context: + + ldr sp,[r0] // Load SP + pop {r2-r5} // Pop type, basepri,SP(discarded) and FPSCR + msr basepri,r3 // Set BASEPRI + vpop.f64 {d0-d15} // Pop FPU registers + vmsr fpscr,r5 // and FPU status register + pop {r0-r12,pc} // Pop all register and return + +#else + +//========================================================================== +// NONE Context switch +// +// No FPU or NONE context saving scheme. Do not save FPU registers. +// + + .globl hal_thread_switch_context + .thumb + .thumb_func + .type hal_thread_switch_context, %function +hal_thread_switch_context: + + push {r0-r12,lr} // Push all savable register + mov r2,#2 // Set state type == thread + mrs r3,basepri // Get priority base register + mov r4,sp // Get SP (for info only) + push {r2-r4} // Push them + + str sp,[r1] // Save SP + + // Fall through + +//-------------------------------------------------------------------------- +// Load context +// +// This is used to load a thread context, abandoning the current one. This +// function is also the second half of hal_thread_switch_context. + + .globl hal_thread_load_context + .thumb + .thumb_func + .type hal_thread_load_context, %function +hal_thread_load_context: + + ldr sp,[r0] // Load SP + pop {r2-r4} // Pop type, basepri and SP (discarded) + msr basepri,r3 // Set BASEPRI + pop {r0-r12,pc} // Pop all register and return + +#endif + +//========================================================================== +// HAL longjmp, setjmp implementations +// +// hal_setjmp saves only to callee save registers R4-14 +// and LR into buffer supplied in r0[arg0]. + + .globl hal_setjmp + .thumb + .thumb_func + .type hal_setjmp, %function +hal_setjmp: + mov r3,sp + stmea r0,{r3-r12,r14} + mov r0,#0 + bx lr + +// hal_longjmp loads state from r0[arg0] and returns + + .globl hal_longjmp + .thumb + .thumb_func + .type hal_longjmp, %function +hal_longjmp: + ldmfd r0,{r3-r12,r14} + mov sp,r3 + mov r0,r1 // return [arg1] + bx lr + +//========================================================================== +// EOF context.S diff --git a/ecos/packages/hal/cortexm/arch/current/src/cortexm.ld b/ecos/packages/hal/cortexm/arch/current/src/cortexm.ld new file mode 100644 index 0000000..9b6c65c --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/src/cortexm.ld @@ -0,0 +1,279 @@ +//============================================================================= +// +// MLT linker script for Cortex-M +// +//============================================================================= +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2008, 2011 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//============================================================================= + +#include <pkgconf/system.h> +#include <pkgconf/hal.h> + +STARTUP(vectors.o) +ENTRY(reset_vector) +INPUT(extras.o) +GROUP(libtarget.a libgcc.a libsupc++.a) + +#if defined(__ARMEB__) +OUTPUT_FORMAT(elf32-bigarm) +#endif + +// ALIGN_LMA is 4, but the AAPCS now requires that double word types +// be aligned to 8, which means some input sections can be marked as needing +// 8-byte alignment, even text ones (consider literal data). + +#define ALIGN_LMA 4 +#define AAPCS_ALIGN 8 +#define FOLLOWING_ALIGNED(_section_, _align_) AT ((LOADADDR (_section_) + SIZEOF (_section_) + (_align_) - 1) & ~ ((_align_) - 1)) +#define FOLLOWING(_section_) FOLLOWING_ALIGNED(_section_, ALIGN_LMA) + +#define LMA_EQ_VMA +#define FORCE_OUTPUT . = . + +// Some versions of gcc define "arm" which causes problems with .note.arm.ident +#undef arm +#define SECTIONS_BEGIN \ + /* Debug information */ \ + .debug_aranges 0 : { *(.debug_aranges) } \ + .debug_pubnames 0 : { *(.debug_pubnames) } \ + .debug_info 0 : { *(.debug_info) } \ + .debug_abbrev 0 : { *(.debug_abbrev) } \ + .debug_line 0 : { *(.debug_line) } \ + .debug_frame 0 : { *(.debug_frame) } \ + .debug_str 0 : { *(.debug_str) } \ + .debug_loc 0 : { *(.debug_loc) } \ + .debug_macinfo 0 : { *(.debug_macinfo) } \ + .note.arm.ident 0 : { KEEP (*(.note.arm.ident)) } \ + /DISCARD/ 0 : { *(.fini_array*) } + + +// Following not used unless CYGHWR_HAL_ARM_SEPARATE_VSR_TABLE +// defined in hal_platform_setup.h. Otherwise vsr table +// goes in .fixed_vectors. +#define SECTION_hal_vsr_table(_region_, _vma_, _lma_) \ + .hal_vsr_table _vma_ : _lma_ \ + { FORCE_OUTPUT; KEEP (*(.hal_vsr_table)) } \ + > _region_ + +#define SECTION_fixed_vectors(_region_, _vma_, _lma_) \ + .fixed_vectors _vma_ : _lma_ \ + { FORCE_OUTPUT; KEEP (*(.fixed_vectors)) } \ + > _region_ + +#define SECTION_rom_vectors(_region_, _vma_, _lma_) \ + .rom_vectors _vma_ : _lma_ \ + { __rom_vectors_vma = ABSOLUTE(.); \ + FORCE_OUTPUT; KEEP (*(.vectors)) } \ + > _region_ \ + __rom_vectors_lma = LOADADDR(.rom_vectors); + +// We slot in the .ARM.extab and .ARM.exidx sections first. They +// need to be close to .text due to their relocations which may +// want small offsets - .rodata may be somewhere very different. +// This approach also allows forward compatibility with targets +// which haven't used the EABI before (no new SECTION_xxx definition +// to use). +// One glitch is that the AAPCS can require up to 8-byte alignment +// for double word types. For sections after the first (for which we +// "trust" the MLT files (probably a mistake)), we need to +// ensure the subsequent sections' VMA and LMA move in sync, which +// means keeping the same alignment, and thus since for example literal +// data in .text can require up to 8 byte alignment, the LMA must also +// be 8 byte aligned. +#define SECTION_text(_region_, _vma_, _lma_) \ + .ARM.extab _vma_ : _lma_ \ + { PROVIDE (__stext = ABSOLUTE(.));_stext = ABSOLUTE(.) ; \ + FORCE_OUTPUT; \ + *(.ARM.extab* .gnu.linkonce.armextab.*) } > _region_ \ + . = ALIGN(AAPCS_ALIGN); \ + __exidx_start = ABSOLUTE(.); \ + .ARM.exidx ALIGN(AAPCS_ALIGN) : FOLLOWING_ALIGNED(.ARM.extab, AAPCS_ALIGN) { \ + *(.ARM.exidx* .gnu.linkonce.armexidx.*) \ + FORCE_OUTPUT; \ + } > _region_ \ + __exidx_end = ABSOLUTE(.);\ + .text ALIGN(AAPCS_ALIGN) : FOLLOWING_ALIGNED(.ARM.exidx, AAPCS_ALIGN) \ + { \ + *(.text*) *(.gnu.warning) *(.gnu.linkonce.t.*) *(.init) \ + *(.glue_7) *(.glue_7t) \ + __CTOR_LIST__ = ABSOLUTE (.); KEEP (*(SORT (.ctors*))) __CTOR_END__ = ABSOLUTE (.); \ + __DTOR_LIST__ = ABSOLUTE (.); KEEP (*(SORT (.dtors*))) __DTOR_END__ = ABSOLUTE (.); \ + } > _region_ \ + _etext = .; PROVIDE (__etext = .); + +#define SECTION_fini(_region_, _vma_, _lma_) \ + .fini _vma_ : _lma_ \ + { FORCE_OUTPUT; *(.fini) } \ + > _region_ + +#define SECTION_rodata(_region_, _vma_, _lma_) \ + .rodata _vma_ : _lma_ \ + { FORCE_OUTPUT; *(.rodata*) *(.gnu.linkonce.r.*) } \ + > _region_ + +#define SECTION_rodata1(_region_, _vma_, _lma_) \ + .rodata1 _vma_ : _lma_ \ + { FORCE_OUTPUT; *(.rodata1) } \ + > _region_ + +#define SECTION_fixup(_region_, _vma_, _lma_) \ + .fixup _vma_ : _lma_ \ + { FORCE_OUTPUT; *(.fixup) } \ + > _region_ + +#define SECTION_gcc_except_table(_region_, _vma_, _lma_) \ + .gcc_except_table _vma_ : _lma_ \ + { FORCE_OUTPUT; \ + KEEP(*(.gcc_except_table)) \ + *(.gcc_except_table.*) \ + } > _region_ + +#define SECTION_eh_frame(_region_, _vma_, _lma_) \ + .eh_frame _vma_ : _lma_ \ + { \ + FORCE_OUTPUT; __EH_FRAME_BEGIN__ = .; \ + KEEP(*(.eh_frame)) \ + __FRAME_END__ = .; \ + . = . + 8; \ + } > _region_ = 0 + +#define SECTION_RELOCS(_region_, _vma_, _lma_) \ + .rel.text : \ + { \ + *(.rel.text) \ + *(.rel.text.*) \ + *(.rel.gnu.linkonce.t*) \ + } > _region_ \ + .rela.text : \ + { \ + *(.rela.text) \ + *(.rela.text.*) \ + *(.rela.gnu.linkonce.t*) \ + } > _region_ \ + .rel.data : \ + { \ + *(.rel.data) \ + *(.rel.data.*) \ + *(.rel.gnu.linkonce.d*) \ + } > _region_ \ + .rela.data : \ + { \ + *(.rela.data) \ + *(.rela.data.*) \ + *(.rela.gnu.linkonce.d*) \ + } > _region_ \ + .rel.rodata : \ + { \ + *(.rel.rodata) \ + *(.rel.rodata.*) \ + *(.rel.gnu.linkonce.r*) \ + } > _region_ \ + .rela.rodata : \ + { \ + *(.rela.rodata) \ + *(.rela.rodata.*) \ + *(.rela.gnu.linkonce.r*) \ + } > _region_ \ + .rel.got : { *(.rel.got) } > _region_ \ + .rela.got : { *(.rela.got) } > _region_ \ + .rel.ctors : { *(.rel.ctors) } > _region_ \ + .rela.ctors : { *(.rela.ctors) } > _region_ \ + .rel.dtors : { *(.rel.dtors) } > _region_ \ + .rela.dtors : { *(.rela.dtors) } > _region_ \ + .rel.init : { *(.rel.init) } > _region_ \ + .rela.init : { *(.rela.init) } > _region_ \ + .rel.fini : { *(.rel.fini) } > _region_ \ + .rela.fini : { *(.rela.fini) } > _region_ \ + .rel.bss : { *(.rel.bss) } > _region_ \ + .rela.bss : { *(.rela.bss) } > _region_ \ + .rel.plt : { *(.rel.plt) } > _region_ \ + .rela.plt : { *(.rela.plt) } > _region_ \ + .rel.dyn : { *(.rel.dyn) } > _region_ + +#define SECTION_got(_region_, _vma_, _lma_) \ + .got _vma_ : _lma_ \ + { \ + FORCE_OUTPUT; *(.got.plt) *(.got) \ + _GOT1_START_ = ABSOLUTE (.); *(.got1) _GOT1_END_ = ABSOLUTE (.); \ + _GOT2_START_ = ABSOLUTE (.); *(.got2) _GOT2_END_ = ABSOLUTE (.); \ + } > _region_ + +#define SECTION_mmu_tables(_region_, _vma_, _lma_) \ + .mmu_tables _vma_ : _lma_ \ + { FORCE_OUTPUT; *(.mmu_tables) } \ + > _region_ + +#define SECTION_sram(_region_, _vma_, _lma_) \ + .sram _vma_ : _lma_ \ + { __sram_data_start = ABSOLUTE (.); \ + *(.sram*) . = ALIGN (4); } \ + > _region_ \ + __srom_data_start = LOADADDR (.sram); \ + __sram_data_end = .; PROVIDE (__sram_data_end = .); \ + PROVIDE (__srom_data_end = LOADADDR (.sram) + SIZEOF(.sram)); + +#define SECTION_data(_region_, _vma_, _lma_) \ + .data _vma_ : _lma_ \ + { __ram_data_start = ABSOLUTE (.); \ + *(.data*) *(.data1) *(.gnu.linkonce.d.*) \ + . = ALIGN (4); \ + KEEP(*( SORT (.ecos.table.*))) ; \ + . = ALIGN (4); \ + __init_array_start__ = ABSOLUTE (.); KEEP (*(SORT (.init_array.*))) \ + KEEP (*(SORT (.init_array))) __init_array_end__ = ABSOLUTE (.); \ + *(.dynamic) *(.sdata*) *(.gnu.linkonce.s.*) \ + . = ALIGN (4); *(.2ram.*) } \ + > _region_ \ + __rom_data_start = LOADADDR (.data); \ + __ram_data_end = .; PROVIDE (__ram_data_end = .); _edata = .; PROVIDE (edata = .); \ + PROVIDE (__rom_data_end = LOADADDR (.data) + SIZEOF(.data)); + +#define SECTION_bss(_region_, _vma_, _lma_) \ + .bss _vma_ : _lma_ \ + { __bss_start = ABSOLUTE (.); \ + *(.scommon) *(.dynsbss) *(.sbss*) *(.gnu.linkonce.sb.*) \ + *(.dynbss) *(.bss*) *(.gnu.linkonce.b.*) *(COMMON) \ + __bss_end = ABSOLUTE (.); } \ + > _region_ + +#define USER_SECTION(_name_, _region_, _vma_, _lma_) \ + ._name_ _vma_ : _lma_ \ + { __ ## _name_ ## _start = ABSOLUTE (.); \ + *(._name_*) \ + __ ## _name_ ## _end = ABSOLUTE (.); } \ + > _region_ + +#define SECTIONS_END . = ALIGN(4); _end = .; PROVIDE (end = .); + +#include <pkgconf/hal_cortexm.h> +#include CYGHWR_MEMORY_LAYOUT_LDI diff --git a/ecos/packages/hal/cortexm/arch/current/src/cortexm_fpu.c b/ecos/packages/hal/cortexm/arch/current/src/cortexm_fpu.c new file mode 100644 index 0000000..dd0975e --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/src/cortexm_fpu.c @@ -0,0 +1,97 @@ +/*========================================================================== +// +// cortexm_fpu.c +// +// Cortex-M exception vectors +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2012 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): ilijak +// Contributor(s): +// Date: 2012-05-30 +// +//####DESCRIPTIONEND#### +// +//======================================================================== +*/ + +#include <pkgconf/hal.h> +#include <pkgconf/hal_cortexm.h> + +#include <cyg/infra/diag.h> +#include <cyg/infra/cyg_type.h> +#include <cyg/infra/cyg_trac.h> // tracing macros +#include <cyg/infra/cyg_ass.h> // assertion macros + +#include <cyg/hal/hal_arch.h> // HAL header +#include <cyg/hal/hal_intr.h> // HAL header +#include <cyg/hal/cortexm_regs.h> // Special Cortex-M asm instructions + +#include <cyg/hal/cortexm_fpu.h> // Optional Floating Point Unit + +#ifdef CYGHWR_HAL_CORTEXM_FPU_SWITCH_LAZY +//============================================================================ +// FPU Usage Fault VSR handler +// Execution of Floating Point instruction when FPU is disabled +// generates usage fault exception. In LAZY context switching scheme +// it is used for detection of FPU usage by threads. +// +cyg_uint32 hal_deliver_usagefault_fpu_exception(void) { + cyg_uint32 regval; + + HAL_READ_UINT32(CYGARC_REG_FPU_CPACR, regval); + if(!((regval & CYGARC_REG_FPU_CPACR_ENABLE) ^ CYGARC_REG_FPU_CPACR_ENABLE)){ + CYG_FAIL("Usage fault exception other than FPU!!!"); + } else { + HAL_READ_UINT32(CYGARC_REG_UFSR, regval); + if(regval & CYGARC_REG_UFSR_NOCP){ + // Floating point instruction has occured + // Enable FPU + HAL_CORTEXM_FPU_ENABLE(); + CYGARC_VMSR(fpscr, 0); + HAL_MEMORY_BARRIER(); + HAL_WRITE_UINT32(CYGARC_REG_UFSR, CYGARC_REG_UFSR_NOCP); + } else { + CYG_FAIL("Usage fault exception other than FPU/NOCP!!!"); + } + } + HAL_READ_UINT32(CYGARC_REG_UFSR, regval); + return regval; +} +#endif // CYGHWR_HAL_CORTEXM_FPU_SWITCH_LAZY + +//========================================================================== +// EOF cortexm_fpu.c diff --git a/ecos/packages/hal/cortexm/arch/current/src/cortexm_stub.c b/ecos/packages/hal/cortexm/arch/current/src/cortexm_stub.c new file mode 100644 index 0000000..e232c9e --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/src/cortexm_stub.c @@ -0,0 +1,290 @@ +/*========================================================================== +// +// cortexm_stub.c +// +// Cortex-M GDB stub support +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2008, 2012 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): nickg +// Contributor(s): ilijak, jifl +// Date: 2008-07-30 +// +//####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_arch.h> +#include <cyg/hal/hal_intr.h> +#include <cyg/hal/hal_stub.h> + +//========================================================================== + +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +#ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT +#include <cyg/hal/dbg-threads-api.h> // dbg_currthread_id +#endif + +//========================================================================== +/* Given a trap value TRAP, return the corresponding signal. */ + +int __computeSignal (unsigned int trap_number) +{ + switch (trap_number) + { + case CYGNUM_HAL_VECTOR_BUS_FAULT: // Fall through + case CYGNUM_HAL_VECTOR_MEMORY_MAN: // Fall through + return SIGBUS; + case CYGNUM_HAL_VECTOR_NMI: + case CYGNUM_HAL_VECTOR_SYS_TICK: + return SIGINT; + case CYGNUM_HAL_VECTOR_USAGE_FAULT: + return SIGFPE; + default: + return SIGTRAP; + } +} + + +//========================================================================== +/* Return the trap number corresponding to the last-taken trap. */ + +int __get_trap_number (void) +{ + // The vector is not not part of the GDB register set so get it + // directly from the save context. + return _hal_registers->u.exception.vector; +} + + +//========================================================================== +// Set the currently-saved pc register value to PC. + +void set_pc (target_register_t pc) +{ + put_register (PC, pc); +} + +//========================================================================== +// Calculate byte offset a given register from start of register save area. + +static int +reg_offset(regnames_t reg) +{ + int reg_i, offset = 0; + + for(reg_i = 0; reg_i < NUMREGS; reg_i++) { + if(reg_i == reg) + break; + offset += REGSIZE(reg_i); + } + return (NUMREGS == reg_i || 0 == REGSIZE(reg_i)) ? -1 : offset; +} + +//========================================================================== +// Return the currently-saved value corresponding to register REG of +// the exception context. + +target_register_t +get_register (regnames_t reg) +{ + target_register_t val; + int offset = reg_offset(reg); + + if (REGSIZE(reg) > sizeof(target_register_t) || offset == -1) + return -1; + + val = _registers[offset/sizeof(target_register_t)]; + + return val; +} + +//========================================================================== +// Store VALUE in the register corresponding to WHICH in the exception +// context. + +void +put_register (regnames_t which, target_register_t value) +{ + int offset = reg_offset(which); + + if (REGSIZE(which) > sizeof(target_register_t) || offset == -1) + return; + + _registers[offset/sizeof(target_register_t)] = value; +} + +//========================================================================== +// Write the contents of register WHICH into VALUE as raw bytes. This +// is only used for registers larger than sizeof(target_register_t). +// Return non-zero if it is a valid register. + +int +get_register_as_bytes (regnames_t which, char *value) +{ + int offset = reg_offset(which); + + if (offset != -1) { + memcpy (value, (char *)_registers + offset, REGSIZE(which)); + return 1; + } + return 0; +} + +//========================================================================== +// Alter the contents of saved register WHICH to contain VALUE. This +// is only used for registers larger than sizeof(target_register_t). +// Return non-zero if it is a valid register. + +int +put_register_as_bytes (regnames_t which, char *value) +{ + int offset = reg_offset(which); + + if (offset != -1) { + memcpy ((char *)_registers + offset, value, REGSIZE(which)); + return 1; + } + return 0; +} + +//========================================================================== +// Single step the processor. +// +// We do this by setting the MON_STEP bit in the DEMCR. So long as we +// are in a DebugMonitor exception this will single step the CPU on +// return. +// We also need to block all pending interrupts by setting basepri +// before doing the step. Otherwise an interrupt may be delivered +// before the step happens, and may cause unpleasant things to happen. + +cyg_uint32 __single_step_basepri = 0; + +void __single_step (void) +{ + CYG_ADDRESS base = CYGARC_REG_DEBUG_BASE; + cyg_uint32 demcr; + + // Save basepri and set it to mask all interrupts. + __single_step_basepri = _hal_registers->u.exception.basepri; + _hal_registers->u.exception.basepri = CYGNUM_HAL_CORTEXM_PRIORITY_MAX; + + // Set MON_STEP + HAL_READ_UINT32( base+CYGARC_REG_DEBUG_DEMCR, demcr ); + demcr |= CYGARC_REG_DEBUG_DEMCR_MON_STEP; + HAL_WRITE_UINT32( base+CYGARC_REG_DEBUG_DEMCR, demcr ); + + // Clear any bits set in DFSR + base = CYGARC_REG_NVIC_BASE; + HAL_WRITE_UINT32( base+CYGARC_REG_NVIC_DFSR, 0xFFFFFFFF ); + +} + +//========================================================================== +// Clear the single-step state. + +void __clear_single_step (void) +{ + CYG_ADDRESS base = CYGARC_REG_DEBUG_BASE; + cyg_uint32 demcr; + + // Restore basepri + _hal_registers->u.exception.basepri = __single_step_basepri; + + // Clear MON_STEP + HAL_READ_UINT32( base+CYGARC_REG_DEBUG_DEMCR, demcr ); + demcr &= ~CYGARC_REG_DEBUG_DEMCR_MON_STEP; + HAL_WRITE_UINT32( base+CYGARC_REG_DEBUG_DEMCR, demcr ); + + // Clear any bits set in DFSR + base = CYGARC_REG_NVIC_BASE; + HAL_WRITE_UINT32( base+CYGARC_REG_NVIC_DFSR, 0xFFFFFFFF ); +} + +//========================================================================== + +void __install_breakpoints (void) +{ + __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)&_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 2. */ + +void __skipinst (void) +{ + unsigned long pc = get_register(PC); + pc += 2; + put_register(PC, pc); +} + +//========================================================================== +#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS diff --git a/ecos/packages/hal/cortexm/arch/current/src/fpv4_sp_d16.c b/ecos/packages/hal/cortexm/arch/current/src/fpv4_sp_d16.c new file mode 100644 index 0000000..6348590 --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/src/fpv4_sp_d16.c @@ -0,0 +1,105 @@ +//========================================================================== +// +// fpv4_sp_d16.c +// +// FPv4-SP-D16 support +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2012 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): ilijak +// Contributor(s): +// Date: 2012-05-30 +// +//####DESCRIPTIONEND#### +// +//======================================================================== + +#include <pkgconf/hal.h> +#include <pkgconf/hal_cortexm.h> + +#include <cyg/infra/diag.h> +#include <cyg/infra/cyg_type.h> +#include <cyg/infra/cyg_trac.h> // tracing macros +#include <cyg/infra/cyg_ass.h> // assertion macros + +#include <cyg/hal/hal_arch.h> // HAL header +#include <cyg/hal/hal_intr.h> // HAL header +#include <cyg/hal/cortexm_regs.h> // Special Cortex-M asm instructions + +#include <cyg/hal/cortexm_fpu.h> // Optional Floating Point Unit + + +#define CYGARC_REG_NVIC_ACTLR (CYGARC_REG_NVIC_BASE + 0x008) +#define CYGARC_REG_NVIC_ACTLR_DISFCA BIT_(8) +//========================================================================== +// FPU is disbled upon reset. Dependent on FPU context switching model it +// may be enabled. + +void hal_init_fpu(void) +{ + cyg_uint32 regval; + + // Initialize FPU according to context switch model. + // Disable FPU so we could access FPCCR + HAL_CORTEXM_FPU_DISABLE(); + +#if defined CYGARC_CORTEXM_FPU_EXC_AUTOSAVE + // Enable automatic exception FPU context saving. + HAL_READ_UINT32(CYGARC_REG_FPU_FPCCR, regval); + regval |= CYGARC_REG_FPU_FPCCR_LSPEN | CYGARC_REG_FPU_FPCCR_ASPEN; + HAL_WRITE_UINT32(CYGARC_REG_FPU_FPCCR, regval); + HAL_MEMORY_BARRIER(); +#else + // Disable automatic exception FPU context saving. + CYGARC_MRS(regval, control); + regval &= ~CYGARC_REG_CONTROL_FPCA_M; + CYGARC_MSR(control, regval); + HAL_READ_UINT32(CYGARC_REG_FPU_FPCCR, regval); + regval &= ~(CYGARC_REG_FPU_FPCCR_LSPEN | CYGARC_REG_FPU_FPCCR_ASPEN); + HAL_WRITE_UINT32(CYGARC_REG_FPU_FPCCR, regval); + HAL_MEMORY_BARRIER(); +#endif + +#if defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_NONE || \ + defined CYGHWR_HAL_CORTEXM_FPU_SWITCH_ALL + // Enable FPU + HAL_CORTEXM_FPU_ENABLE(); + CYGARC_VMSR(fpscr, 0); +#endif +} + +//========================================================================== +// EOF fpv4_sp_d16.c diff --git a/ecos/packages/hal/cortexm/arch/current/src/hal_misc.c b/ecos/packages/hal/cortexm/arch/current/src/hal_misc.c new file mode 100644 index 0000000..6e74852 --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/src/hal_misc.c @@ -0,0 +1,720 @@ +/*========================================================================== +// +// hal_misc.c +// +// Cortex-M exception vectors +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2008, 2012 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): nickg +// Contributor(s): ilijak +// Date: 2008-07-30 +// +//####DESCRIPTIONEND#### +// +//======================================================================== +*/ + +#include <pkgconf/hal.h> +#include <pkgconf/hal_cortexm.h> +#ifdef CYGPKG_KERNEL +#include <pkgconf/kernel.h> +#endif + +#include <cyg/infra/diag.h> +#include <cyg/infra/cyg_type.h> +#include <cyg/infra/cyg_trac.h> // tracing macros +#include <cyg/infra/cyg_ass.h> // assertion macros + +#include <cyg/hal/hal_arch.h> // HAL header +#include <cyg/hal/hal_intr.h> // HAL header +#include <cyg/hal/cortexm_regs.h> // Special Cortex-M asm instructions +#include <cyg/hal/drv_api.h> + +#ifdef CYGHWR_HAL_CORTEXM_FPU +#include <cyg/hal/cortexm_fpu.h> // Optional Floating Point Unit +#endif + +#if defined(CYGPKG_KERNEL_INSTRUMENT) && \ + defined(CYGDBG_KERNEL_INSTRUMENT_INTR) +#include <cyg/kernel/instrmnt.h> +#endif + +//========================================================================== + +typedef cyg_uint32 cyg_isr(cyg_uint32 vector, CYG_ADDRWORD data); + +//========================================================================== +// External references + +// VSRs in vectors.S +__externC void hal_default_exception_vsr( void ); +__externC void hal_default_interrupt_vsr( void ); +__externC void hal_default_svc_vsr( void ); +__externC void hal_pendable_svc_vsr( void ); +__externC void hal_switch_state_vsr( void ); +#ifdef CYGHWR_HAL_CORTEXM_FPU_SWITCH_LAZY +__externC void hal_usagefault_exception_vsr( void ); +#endif + +// HAL and eCos functions +__externC void hal_system_init( void ); +__externC void hal_variant_init( void ); +__externC void hal_platform_init( void ); +__externC void hal_ctrlc_isr_init( void ); +__externC void initialize_stub( void ); +__externC void cyg_hal_invoke_constructors( void ); +__externC void cyg_start( void ); +__externC void cyg_interrupt_post_dsr( CYG_ADDRWORD intr_obj ); +__externC void interrupt_end(cyg_uint32 isr_ret, CYG_ADDRWORD intr, HAL_SavedRegisters *regs ); + +// DATA and BSS locations +__externC cyg_uint32 __ram_data_start; +__externC cyg_uint32 __ram_data_end; +__externC cyg_uint32 __rom_data_start; +__externC cyg_uint32 __sram_data_start; +__externC cyg_uint32 __sram_data_end; +__externC cyg_uint32 __srom_data_start; +__externC cyg_uint32 __bss_start; +__externC cyg_uint32 __bss_end; + +// Scheduler lock +__externC volatile cyg_uint32 cyg_scheduler_sched_lock; + +//========================================================================== +// Interrupt tables + +volatile CYG_ADDRESS hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT]; +volatile CYG_ADDRWORD hal_interrupt_data [CYGNUM_HAL_ISR_COUNT]; +volatile CYG_ADDRESS hal_interrupt_objects [CYGNUM_HAL_ISR_COUNT]; + +//========================================================================== +// Main entry point +// +// Enter here from reset via slot 1 of VSR table. The stack pointer is +// already set to the value in VSR slot 0, usually the top of internal +// SRAM. + +void hal_reset_vsr( void ) +{ + // Call system init routine. This should do the minimum necessary + // for the rest of the initialization to complete. For example set + // up GPIO, the SRAM, power management etc. This routine is + // usually supplied by the platform HAL. Calls to + // hal_variant_init() and hal_platform_init() later will perform + // the main initialization. + + hal_system_init(); +#if defined CYGHWR_HAL_CORTEXM_FPU + // Floating Point Unit is disabled after reset. + // Enable it unless for LAZY context switching scheme. + hal_init_fpu(); +#endif + + // Initialize vector table in base of SRAM. + { + register int i; + +#if !defined(CYG_HAL_STARTUP_RAM) + + // Only install the exception vectors for non-RAM startup. For + // RAM startup we want these to continue to point to the original + // VSRs, which will belong to RedBoot or GDB stubs. + + for( i = 2; i < 15; i++ ) + hal_vsr_table[i] = (CYG_ADDRESS)hal_default_exception_vsr; +#endif // !defined(CYG_HAL_STARTUP_RAM) + // Always point SVC and PENDSVC vectors to our local versions + + hal_vsr_table[CYGNUM_HAL_VECTOR_SERVICE] = (CYG_ADDRESS)hal_default_svc_vsr; + hal_vsr_table[CYGNUM_HAL_VECTOR_PENDSV] = (CYG_ADDRESS)hal_pendable_svc_vsr; +#ifdef CYGHWR_HAL_CORTEXM_FPU_SWITCH_LAZY + // Install UsageFault and HardFault to trap the FPU usage exceptions. + HAL_VSR_SET(CYGNUM_HAL_VECTOR_USAGE_FAULT, hal_usagefault_exception_vsr, NULL); + HAL_VSR_SET(CYGNUM_HAL_VECTOR_HARD_FAULT, hal_usagefault_exception_vsr, NULL); +#endif // CYGHWR_HAL_CORTEXM_FPU_SWITCH_LAZY + + // For all startup type, redirect interrupt vectors to our VSR. + for( i = CYGNUM_HAL_VECTOR_SYS_TICK ; + i < CYGNUM_HAL_VSR_MAX; + i++ ) + hal_vsr_table[i] = (CYG_ADDRESS)hal_default_interrupt_vsr; + } + +#if !defined(CYG_HAL_STARTUP_RAM) + + // Ensure that the CPU will use the vector table we have just set + // up. + +# if defined(CYGHWR_HAL_CORTEXM_M3) || defined(CYGHWR_HAL_CORTEXM_M4) + + // On M3 and M4 parts, the NVIC contains a vector table base register. + // We program this to relocate the vector table base to the base of SRAM. + + HAL_WRITE_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_VTOR, + CYGARC_REG_NVIC_VTOR_TBLOFF(0)| + CYGARC_REG_NVIC_VTOR_TBLBASE_SRAM ); + +# else + +# error Unknown SRAM/VECTAB remap mechanism + +# endif + + // Use SVC to switch our state to thread mode running on the PSP. + // We don't need to do this for RAM startup since the ROM code + // will have already done it. + + hal_vsr_table[CYGNUM_HAL_VECTOR_SERVICE] = (CYG_ADDRESS)hal_switch_state_vsr; + + __asm__ volatile( "swi 0" ); + + hal_vsr_table[CYGNUM_HAL_VECTOR_SERVICE] = (CYG_ADDRESS)hal_default_svc_vsr; + +#endif // !defined(CYG_HAL_STARTUP_RAM) + +#if defined(CYG_HAL_STARTUP_ROM) + // Relocate data from ROM to RAM + { + register cyg_uint32 *p, *q; + for( p = &__ram_data_start, q = &__rom_data_start; + p < &__ram_data_end; + p++, q++ ) + *p = *q; + } + + // Relocate data from ROM to SRAM + { + register cyg_uint32 *p, *q; + for( p = &__sram_data_start, q = &__srom_data_start; + p < &__sram_data_end; + p++, q++ ) + *p = *q; + } +#endif + + // Clear BSS + { + register cyg_uint32 *p; + for( p = &__bss_start; p < &__bss_end; p++ ) + *p = 0; + } + + // Initialize interrupt vectors. Set the levels for all interrupts + // to default values. Also set the default priorities of the + // system handlers: all exceptions maximum priority except SVC and + // PendSVC which are lowest priority. + { + register int i; + + HAL_WRITE_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_SHPR0, 0x00000000 ); + HAL_WRITE_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_SHPR1, 0xFF000000 ); + HAL_WRITE_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_SHPR2, 0x00FF0000 ); + + hal_interrupt_handlers[CYGNUM_HAL_INTERRUPT_SYS_TICK] = (CYG_ADDRESS)hal_default_isr; + + for( i = 1; i < CYGNUM_HAL_ISR_COUNT; i++ ) + { + hal_interrupt_handlers[i] = (CYG_ADDRESS)hal_default_isr; + HAL_WRITE_UINT8( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_PR(i-CYGNUM_HAL_INTERRUPT_EXTERNAL), 0x80 ); + } + } + +#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) + // Enable DebugMonitor exceptions. This is needed to enable single + // step. This only has an effect if no external JTAG device is + // attached. + { + CYG_ADDRESS base = CYGARC_REG_DEBUG_BASE; + cyg_uint32 demcr; + + HAL_READ_UINT32( base+CYGARC_REG_DEBUG_DEMCR, demcr ); + demcr |= CYGARC_REG_DEBUG_DEMCR_MON_EN; + HAL_WRITE_UINT32( base+CYGARC_REG_DEBUG_DEMCR, demcr ); + } +#endif + +#if !defined(CYG_HAL_STARTUP_RAM) + // Enable Usage, Bus and Mem fault handlers. Do this for ROM and + // JTAG startups. For RAM startups, this will have already been + // done by the ROM monitor. + { + CYG_ADDRESS base = CYGARC_REG_NVIC_BASE; + cyg_uint32 shcsr; + + HAL_READ_UINT32( base+CYGARC_REG_NVIC_SHCSR, shcsr ); + shcsr |= CYGARC_REG_NVIC_SHCSR_USGFAULTENA; + shcsr |= CYGARC_REG_NVIC_SHCSR_BUSFAULTENA; + shcsr |= CYGARC_REG_NVIC_SHCSR_MEMFAULTENA; + HAL_WRITE_UINT32( base+CYGARC_REG_NVIC_SHCSR, shcsr ); + } +#endif + + // Call variant and platform init routines + hal_variant_init(); + hal_platform_init(); + + // Start up the system clock + HAL_CLOCK_INITIALIZE( CYGNUM_HAL_RTC_PERIOD ); + +#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS + + initialize_stub(); + +#endif + +#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) || \ + defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) + + hal_ctrlc_isr_init(); + +#endif + + // Run through static constructors + cyg_hal_invoke_constructors(); + + // Finally call into application + cyg_start(); + for(;;); +} + +//========================================================================== +// Handle Exceptions +// +// Exceptions are passed here from the initial VSR. We pass the +// exception on to GDB stubs or the kernel as appropriate. + +__externC void __handle_exception (void); + +__externC HAL_SavedRegisters *_hal_registers; +#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS +__externC void* volatile __mem_fault_handler; +#endif + +void hal_deliver_exception( HAL_SavedRegisters *regs ) +{ + // Special case handler for code which has chosen to take care + // of data exceptions (i.e. code which expects them to happen) + // This is common in discovery code, e.g. checking for a particular + // device which may generate an exception when probing if the + // device is not present + +#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS + if (__mem_fault_handler ) + { + regs->u.exception.pc = (unsigned long)__mem_fault_handler; + return; // Caught an exception inside stubs + } +#endif + +#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) + + _hal_registers = regs; + __handle_exception(); + +#elif defined(CYGPKG_KERNEL_EXCEPTIONS) + + cyg_hal_deliver_exception( regs->u.exception.vector, (CYG_ADDRWORD)regs ); + +#else + + CYG_FAIL("Exception!!!"); + +#endif +} + +//========================================================================== +// Handle Interrupts +// +// Interrupts are passed here from the low-level VSR in vectors.S. We +// look up the ISR in the interrupt table, call it and if it requests +// it, post a DSR. If necessary we also then cause the pendable SVC to +// be requested. +// +// This function is also callable from ISR springboards that decode +// additional interrupts via external controllers to deliver an +// interrupt to a secondary vector. + +void hal_deliver_interrupt( cyg_uint32 vector ) +{ + register cyg_uint32 isr_result; + register cyg_isr *isr; + cyg_bool pendsvc = false; + +#if defined(CYGPKG_KERNEL_INSTRUMENT) && \ + defined(CYGDBG_KERNEL_INSTRUMENT_INTR) + CYG_INSTRUMENT_INTR(RAISE, vector, 0); +#endif + isr = (cyg_isr *)hal_interrupt_handlers[vector]; + + // Call the ISR + isr_result = isr( vector, hal_interrupt_data[vector] ); + + +#if !defined(CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN) + // If the ISR has returned the CALL_DSR bit, post the DSR and set + // the pendable SVC exception pending. + if( isr_result & CYG_ISR_CALL_DSR ) + { + cyg_interrupt_post_dsr( hal_interrupt_objects[vector] ); + + // Post the pendable SVC to call interrupt_end(). But only if + // the scheduler lock is currently zero. If it is non zero + // then interrupt_end will do nothing useful, so avoid calling + // it. + if( cyg_scheduler_sched_lock == 0 ) + pendsvc = true; + } +#else + // When chaining we don't know here whether the nested interrupt + // has posted a DSR, so we have to run interrupt_end() regardless. + // However, the same considerations as above regarding the + // scheduler lock still apply. + if( cyg_scheduler_sched_lock == 0 ) + pendsvc = true; +#endif + + // Post the pendable SVC if required. + if( pendsvc ) + { + cyg_uint32 icsr; + HAL_READ_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_ICSR, icsr ); + icsr |= CYGARC_REG_NVIC_ICSR_PENDSVSET; + HAL_WRITE_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_ICSR, icsr ); + } +} + +//========================================================================== +// Call interrupt_end() +// +// This is called on the thread stack as a result of the pendable +// SVC. interrupt_end() decrements the scheduler lock, calls DSRs and +// optionally switches thread context. So before calling, we must +// increment the lock. The actual interrupt end processing has already +// been done above in hal_default_interrupt_vsr1(), so the arguments +// are zero. + +__externC void hal_interrupt_end( void ) +{ +#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT + cyg_scheduler_sched_lock++; +#endif + + interrupt_end(0,0,0); +} + +//========================================================================== +// Interrupt masking and configuration + +#ifndef HAL_VAR_INTERRUPT_MASK +#define HAL_VAR_INTERRUPT_MASK( __vector ) CYG_EMPTY_STATEMENT +#define HAL_VAR_INTERRUPT_UNMASK( __vector ) CYG_EMPTY_STATEMENT +#define HAL_VAR_INTERRUPT_SET_LEVEL( __vector, __level ) CYG_EMPTY_STATEMENT +#define HAL_VAR_INTERRUPT_ACKNOWLEDGE( __vector ) CYG_EMPTY_STATEMENT +#define HAL_VAR_INTERRUPT_CONFIGURE( __vector, __level, __up ) CYG_EMPTY_STATEMENT +#endif + +//-------------------------------------------------------------------------- + +__externC void hal_interrupt_mask( cyg_uint32 vector ) +{ + if( vector >= CYGNUM_HAL_INTERRUPT_EXTERNAL && + vector <= CYGNUM_HAL_INTERRUPT_NVIC_MAX ) + HAL_WRITE_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_CER(vector-CYGNUM_HAL_INTERRUPT_EXTERNAL), + CYGARC_REG_NVIC_IBIT(vector-CYGNUM_HAL_INTERRUPT_EXTERNAL) ); + else if( vector == CYGNUM_HAL_INTERRUPT_SYS_TICK ) + { + cyg_uint32 csr; + HAL_READ_UINT32(CYGARC_REG_SYSTICK_BASE+CYGARC_REG_SYSTICK_CSR, csr ); + csr &= ~CYGARC_REG_SYSTICK_CSR_TICKINT; + HAL_WRITE_UINT32(CYGARC_REG_SYSTICK_BASE+CYGARC_REG_SYSTICK_CSR, csr ); + } + HAL_VAR_INTERRUPT_MASK( vector ); +} + +//-------------------------------------------------------------------------- + +__externC void hal_interrupt_unmask( cyg_uint32 vector ) +{ + if( vector >= CYGNUM_HAL_INTERRUPT_EXTERNAL && + vector <= CYGNUM_HAL_INTERRUPT_NVIC_MAX ) + HAL_WRITE_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_SER(vector-CYGNUM_HAL_INTERRUPT_EXTERNAL), + CYGARC_REG_NVIC_IBIT(vector-CYGNUM_HAL_INTERRUPT_EXTERNAL) ); + else if( vector == CYGNUM_HAL_INTERRUPT_SYS_TICK ) + { + cyg_uint32 csr; + HAL_READ_UINT32(CYGARC_REG_SYSTICK_BASE+CYGARC_REG_SYSTICK_CSR, csr ); + csr |= CYGARC_REG_SYSTICK_CSR_TICKINT; + HAL_WRITE_UINT32(CYGARC_REG_SYSTICK_BASE+CYGARC_REG_SYSTICK_CSR, csr ); + } + HAL_VAR_INTERRUPT_UNMASK( vector ); +} + +//-------------------------------------------------------------------------- + +__externC void hal_interrupt_acknowledge( cyg_uint32 vector ) +{ + HAL_VAR_INTERRUPT_ACKNOWLEDGE( vector ); +} + +//-------------------------------------------------------------------------- + +__externC void hal_interrupt_configure( cyg_uint32 vector, cyg_uint32 level, cyg_uint32 up ) +{ + HAL_VAR_INTERRUPT_CONFIGURE( vector, level, up ); +} + +//-------------------------------------------------------------------------- + +__externC void hal_interrupt_set_level( cyg_uint32 vector, cyg_uint32 level ) +{ + cyg_uint32 l = (level)+CYGNUM_HAL_CORTEXM_PRIORITY_MAX; + if( l > 0xFF ) l = 0xFF; /* clamp to 0xFF */ + if( vector >= CYGNUM_HAL_INTERRUPT_EXTERNAL && + vector <= CYGNUM_HAL_INTERRUPT_NVIC_MAX ) + { + HAL_WRITE_UINT8( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_PR(vector-CYGNUM_HAL_INTERRUPT_EXTERNAL), + l ); + } + else if ( vector == CYGNUM_HAL_INTERRUPT_SYS_TICK ) + { + cyg_uint32 shpr2; + HAL_READ_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_SHPR2, shpr2 ); + shpr2 &= ~0xFF000000; + shpr2 |= (l)<<24; + HAL_WRITE_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_SHPR2, shpr2 ); + } + HAL_VAR_INTERRUPT_SET_LEVEL( vector, level ); +} + +//========================================================================== +// Microsecond delay +// +// The system RTC is set up to tick at 1MHz so all we need to do here +// is count ticks. + +__externC void hal_delay_us( cyg_int32 us ) +{ + cyg_uint32 t0, t1; + + HAL_CLOCK_READ( &t0 ); + while ( us > 0 ) + { + HAL_CLOCK_READ( &t1 ); + if( t1 < t0 ) + us -= (t1 + CYGNUM_HAL_RTC_PERIOD - t0); + else + us -= t1 - t0; + t0 = t1; + } +} + +//========================================================================== +// C++ support - run initial constructors + +#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG +cyg_bool cyg_hal_stop_constructors; +#endif + +typedef void (*pfunc) (void); + +extern pfunc __init_array_start__[]; +extern pfunc __init_array_end__[]; +#define CONSTRUCTORS_START (__init_array_start__[0]) +#define CONSTRUCTORS_END (__init_array_end__) +#define NEXT_CONSTRUCTOR(c) ((c)++) + +void +cyg_hal_invoke_constructors (void) +{ +#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG + static pfunc *p = &CONSTRUCTORS_START; + + cyg_hal_stop_constructors = 0; + for (; p != CONSTRUCTORS_END; NEXT_CONSTRUCTOR(p)) { + (*p)(); + if (cyg_hal_stop_constructors) { + NEXT_CONSTRUCTOR(p); + break; + } + } +#else + pfunc *p; + + for (p = &CONSTRUCTORS_START; p != CONSTRUCTORS_END; NEXT_CONSTRUCTOR(p)) + (*p)(); +#endif +} + +//========================================================================== +// Architecture default ISR + +__externC cyg_uint32 +hal_arch_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) +{ + CYG_TRACE1(true, "Interrupt: %d", vector); + + CYG_FAIL("Spurious Interrupt!!!"); + + return 0; +} + +//========================================================================== +// GDB support +// +// These functions translate between HAL saved contexts and GDB +// register dumps. + +__externC void hal_get_gdb_registers( HAL_CORTEXM_GDB_Registers *gdbreg, HAL_SavedRegisters *regs ) +{ + int i; + + switch(GDB_STUB_SAVEDREG_FRAME_TYPE(regs)) + { + case HAL_SAVEDREGISTERS_THREAD: + for( i = 0; i < 13; i++ ) + gdbreg->gpr[i] = regs->u.thread.r[i]; + gdbreg->gpr[13] = regs->u.thread.sp; + gdbreg->gpr[14] = regs->u.thread.pc; + gdbreg->gpr[15] = regs->u.thread.pc; + gdbreg->xpsr = 0x01000000; + + GDB_STUB_SAVEDREG_FPU_THREAD_GET(gdbreg, regs); + break; + + case HAL_SAVEDREGISTERS_EXCEPTION: + gdbreg->gpr[0] = regs->u.exception.r0; + gdbreg->gpr[1] = regs->u.exception.r1; + gdbreg->gpr[2] = regs->u.exception.r2; + gdbreg->gpr[3] = regs->u.exception.r3; + for( i = 0; i < 8; i++ ) + gdbreg->gpr[i+4] = regs->u.exception.r4_11[i]; + gdbreg->gpr[12] = regs->u.exception.r12; + gdbreg->gpr[13] = ((cyg_uint32)regs)+sizeof(regs->u.exception); + gdbreg->gpr[14] = regs->u.exception.lr; + gdbreg->gpr[15] = regs->u.exception.pc; + gdbreg->xpsr = regs->u.exception.psr; +#ifdef CYGSEM_HAL_DEBUG_FPU + GDB_STUB_SAVEDREG_FPU_EXCEPTION_GET(gdbreg, regs); +#endif + break; + + case HAL_SAVEDREGISTERS_INTERRUPT: + gdbreg->gpr[0] = regs->u.interrupt.r0; + gdbreg->gpr[1] = regs->u.interrupt.r1; + gdbreg->gpr[2] = regs->u.interrupt.r2; + gdbreg->gpr[3] = regs->u.interrupt.r3; + gdbreg->gpr[12] = regs->u.interrupt.r12; + gdbreg->gpr[13] = ((cyg_uint32)regs)+sizeof(regs->u.interrupt); + gdbreg->gpr[14] = regs->u.interrupt.lr; + gdbreg->gpr[15] = regs->u.interrupt.pc; + gdbreg->xpsr = regs->u.interrupt.psr; + break; + } +#ifdef CYGARC_CORTEXM_GDB_REG_FPA + // Clear FP state, which we don't use + { + cyg_uint32 *p = gdbreg->f0; + for( i = 0; i < (8*3+1); i++ ) + p[i] = 0; + } +#endif +} + +__externC void hal_set_gdb_registers( HAL_CORTEXM_GDB_Registers *gdbreg, HAL_SavedRegisters *regs ) +{ + int i; + + switch(GDB_STUB_SAVEDREG_FRAME_TYPE(regs)) + { + case HAL_SAVEDREGISTERS_THREAD: + for( i = 0; i < 13; i++ ) + regs->u.thread.r[i] = gdbreg->gpr[i]; + regs->u.thread.sp = gdbreg->gpr[13]; + regs->u.thread.pc = gdbreg->gpr[14]; + regs->u.thread.pc = gdbreg->gpr[15]; + + GDB_STUB_SAVEDREG_FPU_THREAD_SET(gdbreg, regs); + break; + + case HAL_SAVEDREGISTERS_EXCEPTION: + regs->u.exception.r0 = gdbreg->gpr[0]; + regs->u.exception.r1 = gdbreg->gpr[1]; + regs->u.exception.r2 = gdbreg->gpr[2]; + regs->u.exception.r3 = gdbreg->gpr[3]; + for( i = 0; i < 8; i++ ) + regs->u.exception.r4_11[i] = gdbreg->gpr[i+4]; + regs->u.exception.r12 = gdbreg->gpr[12]; + regs->u.exception.lr = gdbreg->gpr[14]; + regs->u.exception.pc = gdbreg->gpr[15]; + regs->u.exception.psr = gdbreg->xpsr; +#ifdef CYGSEM_HAL_DEBUG_FPU + GDB_STUB_SAVEDREG_FPU_EXCEPTION_SET(gdbreg, regs); +#endif + break; + + case HAL_SAVEDREGISTERS_INTERRUPT: + regs->u.interrupt.r0 = gdbreg->gpr[0]; + regs->u.interrupt.r1 = gdbreg->gpr[1]; + regs->u.interrupt.r2 = gdbreg->gpr[2]; + regs->u.interrupt.r3 = gdbreg->gpr[3]; + regs->u.interrupt.r12 = gdbreg->gpr[12]; + regs->u.interrupt.lr = gdbreg->gpr[14]; + regs->u.interrupt.pc = gdbreg->gpr[15]; + regs->u.interrupt.psr = gdbreg->xpsr; + break; + } +} + +//========================================================================== +// When compiling C++ code with static objects the compiler +// inserts a call to __cxa_atexit() with __dso_handle as one of the +// arguments. __cxa_atexit() would normally be provided by glibc, and +// __dso_handle is part of crtstuff.c. eCos applications +// are linked rather differently, so either a differently-configured +// compiler is needed or dummy versions of these symbols should be +// provided. If these symbols are not actually used then providing +// them is still harmless, linker garbage collection will remove them. + +void +__cxa_atexit(void (*arg1)(void*), void* arg2, void* arg3) +{ +} + +void* __dso_handle = (void*) &__dso_handle; + +//========================================================================== +// EOF hal_misc.c diff --git a/ecos/packages/hal/cortexm/arch/current/src/mcount.S b/ecos/packages/hal/cortexm/arch/current/src/mcount.S new file mode 100644 index 0000000..33e4539 --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/src/mcount.S @@ -0,0 +1,138 @@ +/*========================================================================== +// +// mcount.S +// +// Cortex-M mcount implementation +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2014 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jld +// Contributor(s): +// Date: 2014-02-28 +// Description: This file provides mcount functions used for +// call-graph profiling. +// +//####DESCRIPTIONEND#### +// +//======================================================================== +*/ + +#include <pkgconf/hal_cortexm.h> + +/* +// GCC inserts mcount code at the start of every function when compiling +// with "-pg". For GCC prior to version 4.4 targeting Cortex-M, +// the following code is inserted: +// +// mov r12, lr +// bl mcount +// .word <data pointer> +// +// For GCC version 4.4 and later targeting Cortex-M, the following code is +// inserted: +// +// push { lr } +// bl __gnu_mcount_nc +// +// We provide implementations of both mcount() and __gnu_mcount_nc() to +// call the eCos __profile_mcount() function. +*/ + + .syntax unified + .globl mcount + .section .text.mcount + .thumb_func +mcount: + // resume execution beyond the data pointer on return to caller + add lr, lr, #4 + + // caller assumes r0-r3 will be preserved (non-AAPCS), we use + // r6 and must preserve lr across our __profile_mcount() call + push { r0, r1, r2, r3, r6, lr } + + // set up parameters for __profile_mcount() + sub r0, r12, #2 + bic r0, r0, #1 + bic r1, lr, #1 + + // disable interrupts + mov r2, #CYGNUM_HAL_CORTEXM_PRIORITY_MAX + mrs r6, basepri + msr basepri, r2 + + // call eCos __profile_mcount() + // r6 is preserved across the call per AAPCS + bl __profile_mcount + + // restore interrupts + msr basepri, r6 + + // restore registers and return + pop { r0, r1, r2, r3, r6, pc } + + + .globl __gnu_mcount_nc + .section .text.__gnu_mcount_nc + .thumb_func +__gnu_mcount_nc: + // caller assumes r0-r3 will be preserved (non-AAPCS), we use + // r6 and must preserve lr across our __profile_mcount() call + push { r0, r1, r2, r3, r6, lr } + + // set up parameters for __profile_mcount() + ldr r0, [ sp, #24 ] + sub r0, r0, #2 + bic r0, r0, #1 + bic r1, lr, #1 + + // disable interrupts + mov r2, #CYGNUM_HAL_CORTEXM_PRIORITY_MAX + mrs r6, basepri + msr basepri, r2 + + // call eCos __profile_mcount() + // r6 is preserved across the call per AAPCS + bl __profile_mcount + + // restore interrupts + msr basepri, r6 + + // restore registers and return + pop { r0, r1, r2, r3, r6, r12, lr } + bx r12 + +//========================================================================== +// end of mcount.S diff --git a/ecos/packages/hal/cortexm/arch/current/src/vectors.S b/ecos/packages/hal/cortexm/arch/current/src/vectors.S new file mode 100644 index 0000000..8564bdb --- /dev/null +++ b/ecos/packages/hal/cortexm/arch/current/src/vectors.S @@ -0,0 +1,393 @@ +/*========================================================================== +// +// vectors.S +// +// Cortex-M exception vectors +// +//========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2008, 2011, 2012 Free Software Foundation, 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., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): nickg +// Contributors(s): ilijak +// Date: 2008-07-30 +// Description: This file defines the code placed into the exception +// vectors. It also contains the first level default VSRs +// that save and restore state for both exceptions and +// interrupts. +// +//####DESCRIPTIONEND#### +// +//======================================================================== +*/ + +#include <pkgconf/hal.h> +#include <pkgconf/hal_cortexm.h> +#ifdef CYGPKG_KERNEL +#include <pkgconf/kernel.h> +#endif + +#include <cyg/hal/cortexm_fpu.h> +#ifdef CYGHWR_HAL_CORTEXM_FPU +# include <cyg/hal/hal_arch.inc> +#endif + +#include <cyg/hal/variant.inc> + +//========================================================================== + + .syntax unified + .thumb + +//========================================================================== +// Initial exception vector table +// +// This only contains the stack and entry point for reset. The table +// to be used at runtime is constructed by code in hal_reset_vsr(). + + .section ".vectors","ax" + + .global hal_vsr_table +hal_vsr_table_init: + + .long hal_startup_stack // 0 Reset stack + .long hal_reset_vsr // 1 Reset entry + +//========================================================================== + + .text + .thumb + +//========================================================================== +// Fake entry point. +// +// The ELF file entry point points here. When loading an executable +// via RedBoot/Stubs or via JTAG the PC will be set to this address. +// The code here sets up the SP and branches to the reset VSR in +// emulation of the hardware reset behaviour. + + .align 2 + .global reset_vector + .thumb + .thumb_func + .type reset_vector, %function +reset_vector: + + ldr sp,=hal_startup_stack + b hal_reset_vsr + + .pool + +#if !defined(CYG_HAL_STARTUP_RAM) +//========================================================================== +// State switch VSR +// +// This is called from the init code to switch execution from the main +// stack to the process stack. We also take the opportunity to do some +// other things that are best done in asm code such as disabling interrupts +// and setting the control register. +// +// The adjustment to MSP by 1/2 interrupt stack size allows code to +// throw exceptions without corrupting the execution stack. This is +// only necessary for non-kernel configurations (e.g. RedBoot, Stubs) +// since kernel configurations will switch to a thread stack before +// they should throw an exception. + + .global hal_switch_state_vsr + .thumb + .thumb_func + .type hal_switch_state_vsr, %function +hal_switch_state_vsr: + + mov r0,#CYGNUM_HAL_CORTEXM_PRIORITY_MAX + msr basepri,r0 + + mov r0,#2 // Set CONTROL register to 2 + msr control,r0 + isb // Insert a barrier + + mov r0,sp + msr psp,r0 // Copy SP to PSP + +#if !defined(CYGPKG_KERNEL) + sub sp,#(CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE/2) +#endif + + orr lr,#0xD // Adjust return link + bx lr // Return to init code on PSP now + +#endif + +//========================================================================== +// Default exception VSR +// +// This is attached to all exception vectors. It saves the entire +// machine state and calls into the eCos exception handling code. +// +// NOTE: At present this implementation does not permit an exception +// handler to suspend the faulting thread and enter the scheduler to +// switch elsewhere. However, I know of no code that does anything +// like this. If there is then this may need treating in the same way +// as the interrupt end code. + + .global hal_default_exception_vsr + .thumb + .thumb_func + .type hal_default_exception_vsr, %function +hal_default_exception_vsr: + + mrs r0,psp // Get process stack + +#ifdef CYGSEM_HAL_DEBUG_FPU + hal_fpu_exc_push // Save Floating Point Unit context +#endif + sub r1,r0,#(4*12) // Make space for saved state + msr psp,r1 // Ensure PSP is up to date + + mov r1,#1 // R1 = exception state type + mrs r2,ipsr // R2 = vector number + mrs r3,basepri // R3 = basepri + stmfd r0!,{r1-r11,lr} // Push type, vector, basepri, r4-11 + mov r4,r0 // R4 = saved state pointer + + bl hal_deliver_exception + + mov r0,r4 // R0 = state saved across call + ldmfd r0!,{r1-r11,lr} // Pop type, vec, basepri, registers and LR + +#ifdef CYGSEM_HAL_DEBUG_FPU + hal_fpu_exc_pop // Update Floating Point Unit context +#endif + msr psp,r0 // Restore PSP + msr basepri,r3 // Restore basepri + + bx lr // Return + + .pool + +//========================================================================== +// Default interrupt VSR +// +// This is a trampoline that translates from the hardware defined entry point +// to the ISR defined by eCos. The CPU will switch automatically to the main +// (interrupt) stack with the process state saved on the process stack. Apart +// from saving a pointer to the interrupt state for Ctrl-C support, and fetching +// the vector number, most of the work is actually done in hal_deliver_interrupt(). + + + .global hal_default_interrupt_vsr + .thumb + .thumb_func + .type hal_default_interrupt_vsr, %function +hal_default_interrupt_vsr: + + push {lr} // Save return link + sub sp,#4 // Realign SP to 8 bytes + +#if CYGINT_HAL_COMMON_SAVED_INTERRUPT_STATE_REQUIRED > 0 + // If we are supporting Ctrl-C interrupts from GDB, we must squirrel + // away a pointer to the saved interrupt state here so that we can + // plant a breakpoint at some later time. + + .extern hal_saved_interrupt_state + mrs r1,psp // Get PSP + mov r0,#3 // Interrupt state type + stmfd r1!,{r0} // Push interrupt type + ldr r12,=hal_saved_interrupt_state + str r1,[r12] +#endif + + mrs r0,ipsr // R0 = arg0 = vector number + sub r0,#15 // Adjust to interrupt range + + bl hal_deliver_interrupt + + add sp,#4 // pop alignment padding + pop {pc} // Pop LR and return + + .pool + +//========================================================================== +// Pendable SVC VSR +// +// This is invoked if an interrupt posts a DSR. It calls the DSR +// and finalizes interrupt processing by calling interrupt_end(). We want +// to run interrupt_end() on the PSP of the current thread. So we push +// a fake exception frame onto the PSP which will take us to hal_interrupt_end(), +// which will make the call. The return link loaded by that frame takes us +// back to hal_interrupt_end_done which will unwind the real exception +// frame that is still on the PSP. + + + .global hal_pendable_svc_vsr + .thumb + .thumb_func + .type hal_pendable_svc_vsr, %function +hal_pendable_svc_vsr: + + mrs r12,psp // R12 = thread's PSP + sub r0,r12,#HAL_SAVEDREG_AUTO_FRAME_SIZE // Make space for frame + msr psp,r0 // Put it back + +#ifdef CYGARC_CORTEXM_FPU_EXC_AUTOSAVE + hal_fpu_isr_fake_frame_push +#endif // CYGARC_CORTEXM_FPU_EXC_AUTOSAVE + ldr r3,=0x01000000 // R3 = PSR = thumb bit set + ldr r2,=hal_interrupt_end // R2 = PC = interrupt end entry point + ldr r1,=hal_interrupt_end_done // R1 = LR = restore code + stmfd r12!,{r0-r3} // Save fake R12, LR, PC, PSR + stmfd r12!,{r0-r3} // Save fake R0-R3 + + bx lr // Return to hal_interrupt_end + + .pool + +//========================================================================== +// Interrupt end done +// +// After calling interrupt end a thread returns here to unstack the +// exception frame used to enter hal_pendable_svc_vsr. We can only +// successfully unstack a frame by doing a proper exception return +// from handler mode, so we use a SWI which will discard its own +// frame and restore the saved one. + + + .global hal_interrupt_end_done + .thumb + .thumb_func + .type hal_interrupt_end_done, %function +hal_interrupt_end_done: + + ldr r3,=hal_interrupt_end_vsr + swi 0 + +//========================================================================== +// Interrupt end VSR +// +// This is the SVC VSR invoked by hal_interrupt_end_done to restore the +// original exception frame from a pendable SVC entry. It does this +// by discarding its own frame and using the one below it on the +// stack to return. + + .global hal_interrupt_end_vsr + .thumb + .thumb_func + .type hal_interrupt_end_vsr, %function +hal_interrupt_end_vsr: + + mrs r12,psp // R12 = thread's PSP + add r12,#HAL_SAVEDREG_AUTO_FRAME_SIZE // Skip our saved state + msr psp,r12 // Restore thread's PSP + + bx lr // And return + +//========================================================================== +// Run DSRs VSR +// +// This is invoked from the kernel via a SWI to run DSRs on the +// interrupt/main stack. It merely branches to +// cyg_interrupt_call_pending_DSRs() which will then directly return +// from the SVC exception. + + .global hal_call_dsrs_vsr + .thumb + .thumb_func + .type hal_call_dsrs_vsr, %function + +hal_call_dsrs_vsr: + + .extern cyg_interrupt_call_pending_DSRs + b cyg_interrupt_call_pending_DSRs + +//========================================================================== +// SVC VSR +// +// The SVC VSR is used as a general-purpose mechanism for running code +// in handler mode. R3 contains the address of a piece of code to run, +// R0-R2 contain any arguments. Once entered the code is responsible for +// handling the system state and returning to thread mode. +// +// Note that R0-R3 must be explicitly restored from their stacked +// copies since a late arriving interrupt can preempt the SVC entry +// and corrupt these registers before we get here. + + .global hal_default_svc_vsr + .thumb + .thumb_func + .type hal_default_svc_vsr, %function +hal_default_svc_vsr: + + mrs r12,psp + ldmfd r12,{r0-r3} + bx r3 // Jump to routine in R3 + + .pool + +#ifdef CYGHWR_HAL_CORTEXM_FPU_SWITCH_LAZY +//========================================================================== +// Usage Fault VSR +// Note: This VSR is also attached to HardFault vector. +// At present this VSR is used to detect FPU usage for Lazy context switch. +// after saving processor context on the process stack call +// hal_deliver_usagefault_fpu_exception() to do the job and retun result in r0. +// If result indicates no FPU activity then jump in hal_default_exception_vsr. + .global hal_usagefault_exception_vsr + .thumb + .thumb_func + .type hal_usagefault_exception_vsr, %function +hal_usagefault_exception_vsr: + + mrs r0,psp // Get process stack + sub r1,r0,#(2*4) // Make space for saved state + msr psp,r1 // Ensure PSP is up to date + stmfd r0!,{r4,lr} // save registers + mov r4,r0 // R4 = saved state pointer + + bl hal_deliver_usagefault_fpu_exception + + mov r1,r4 // R0 = state saved across call + ldmfd r1!,{r4,lr} // Restore registers + msr psp,r1 // Restore PSP + + cmp r0,#0 // Exception other than FPU? + bne hal_default_exception_vsr // Y: - process it + + bx lr // N: Return + + .pool + +#endif // CYGHWR_HAL_CORTEXM_FPU_SWITCH_LAZY + +//========================================================================== +// end of vectors.S |