This is the mail archive of the
ecos-patches@sourceware.org
mailing list for the eCos project.
new M68K architectural HAL
- From: Bart Veer <bartv at ecoscentric dot com>
- To: ecos-patches at sourceware dot org
- Date: Thu, 20 Nov 2008 22:24:18 +0000
- Subject: new M68K architectural HAL
This patch contributes eCosCentric's hal/m68k/arch architectural HAL,
replacing all the old code in the same directory.
Bart
Index: ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/m68k/arch/current/ChangeLog,v
retrieving revision 1.2
diff -u -p -r1.2 ChangeLog
--- ChangeLog 22 Apr 2004 15:26:39 -0000 1.2
+++ ChangeLog 20 Nov 2008 22:20:22 -0000
@@ -1,13 +1,326 @@
-2004-04-22 Jani Monoses <jani@iv.ro>
+2008-11-18 Bart Veer <bartv@ecoscentric.com>
- * cdl/hal_m68k.cdl :
- Invoke tail with stricter syntax that works in latest coreutils.
+ * whole package. Replace the original M68K port.
+
+2008-11-17 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/m68k.sgml, cdl/hal_m68k.cdl, include/arch.inc,
+ src/hal_arch.S, src/m68k.ld, src/m68k_stub.c: minor clean-ups.
+
+2008-09-11 Bart Veer <bartv@ecoscentric.com>
+
+ * src/hal_arch.S: in the interrupt VSR only lock the scheduler in
+ kernel configurations.
+
+ * include/hal_intr.h (hal_interrupt_handlers): add a define'd
+ alias for cyg_hal_interrupt_handlers, needed by objloader.
+
+2008-05-08 Bart Veer <bartv@ecoscentric.com>
+
+ * include/hal_arch.h: add bset and bclr utility macros.
+
+2008-02-28 Bart Veer <bartv@ecoscentric.com>
+
+ * src/hal_arch.S: call DSRs even in non-kernel configurations.
+
+ * include/arch.inc: include some debug info in assembler functions
+
+ * cdl/hal_m68k.cdl, tests/iram1.c: add test for on-chip memory and
+ the iram linker script section.
+
+2008-02-14 Bart Veer <bartv@ecoscentric.com>
+
+ * include/hal_io.h: cope with being #include'd from inside a
+ linker script.
+
+ * include/hal_intr.h: fix HAL_VSR_SET() macro for
+ autoincrement/decrement pointer argument. Fix HAL_DELAY_US()
+ support for cached vs. uncached execution.
+
+2007-02-04 Bart Veer <bartv@ecoscentric.com>
+
+ * src/plf_stub.h (HAL_STUB_PLATFORM_INIT_SERIAL): do not both with
+ plf_comms_init() if the virtual vector init code has already taken
+ care of it.
+
+2006-12-21 Bart Veer <bartv@ecoscentric.com>
+
+ * src/m68k.ld: ensure the ctors table is properly aligned.
+
+2006-12-13 Bart Veer <bartv@ecoscentric.com>
+
+ * src/m68k.ld: default to placing _stext at the start of
+ .m68k_startup instead of .text, but allow platforms to override
+ this.
+
+ * src/vectors.S: minor code size optimizations to the startup
+ code.
+
+2006-12-03 Bart Veer <bartv@ecoscentric.com>
+
+ * src/vectors.S: allow platforms to suppress the exception vector
+ entries in .ram_vectors while preserving the virtual vectors and
+ any variant/processor/platform-specific data.
+
+ * include/hal_cache.h: allow indirect inclusion from assembler
+ files.
+
+2006-10-12 Bart Veer <bartv@ecoscentric.com>
+
+ * src/m68k.ld (SECTION_iram): fix alignment problems when the
+ on-chip code is not a multiple of 4 bytes
+
+2006-10-11 Nick Garnett <nickg@ecoscentric.com>
+
+ * src/m68k.ld: Removed a stray '.' from _EH_FRAME1_. Added
+ _region_ argument to _EH_FRAME1_ and _GCC_EXCEPT_TABLE1_.
+
+2006-09-25 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/m68k.sgml: update to reflect recent changes in the M68K
+ HALs.
+
+2006-09-25 John Dallaway <jld@ecoscentric.com>
+
+ * cdl/hal_m68k.cdl: Restore CYGBLD_LINKER_SCRIPT - required by the
+ eCos Configuration Tool.
+
+2006-09-13 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/vectors.S: Place hal_m68k_exception_reset in its own
+ section, to avoid its section being at 0x0 which confuses
+ GDB.
+
+2006-09-10 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/hal_m68k.cdl: there is no need for the linker script to be
+ an option.
+
+ * cdl/hal_m68k.cdl, src/plf_stub.h: allow the architectural HAL to
+ provide plf_stub.h at the platform HAL's request, to avoid lots of
+ duplication of the same header.
+
+2006-09-08 Bart Veer <bartv@ecoscentric.com>
+
+ * src/m68k.ld: greatly simplify M68K linker script support. Add
+ support for on-chip RAM.
+
+ * src/vectors.S: tidy up. Add support for on-chip RAM.
+
+ * src/hal_m68k.c: move hal_if_init() up the hierarchy
+
+ * include/hal_io.h: can now be safely #include'd by assembler
+ files.
+
+ * include/hal_arch.h: change gdb stub target_register_t definition
+ to avoid compiler warning.
+
+2006-09-05 Bart Veer <bartv@ecoscentric.com>
+
+ * src/vectors.S: fix fencepost bug in BSS initialization
+
+ * src/m68k.ld: discard exception-related sections unless libstdcxx
+ is in the configuration.
+
+ * src/hal_m68k.c: remove idle thread action function, now defaults
+ to just an empty macro.
+
+ * src/hal_arch.S: tidy up comment.
+
+ * include/hal_intr.h: HAL_VSR_SET() is now optional.
+
+ * include/hal_cache.h: fix default cache definitions.
+
+ * include/hal_arch.h: allow lower-level HAL to provide the LSBIT
+ and MSBIT macros. Do not initialize interrupts in a thread context
+ when building RedBoot, so loaded applications start with ints
+ disabled.
+
+ * cdl/hal_m68k.cdl: fix custom build rules for proper dependency
+ handling.
+
+
+2006-07-10 Bart Veer <bartv@ecoscentric.com>
+
+ * src/m68k.ld, src/vectors.S: distinguish cleanly between the
+ exception vectors and the startup code. Add support for mcf52xx
+ cfm flash security settings.
+
+ * src/hal_m68k.c: rationalize hal_arch_default_isr() &
+ hal_default_isr() functions
+
+ * cdl/hal_m68k.cdl, src/hal_arch.S, include/arch.inc: default to
+ providing startup/interrupt stack in the architectural HAL
+
+ * include/hal_intr.h: default to providing HAL_DELAY_US() in the
+ architectural HAL
+
+2006-06-26 Jonathan Larmour <jifl@ecoscentric.com>
+
+ * cdl/hal_m68k.cdl: Use correct syntax for modern GNU tail.
+
+2006-03-10 John Dallaway <jld@ecoscentric.com>
+
+ * cdl/hal_m68k.cdl: Add reference to M68k architecture documentation.
+
+2006-02-21 Bart Veer <bartv@ecoscentric.com>
+
+ * include/hal_intr.h (HAL_ENABLE_INTERRUPTS): fix
+ DEFAULT_IPL_LEVEL usage.
+
+2005-06-10 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/m68k.ld: gcc_except_table subsections don't need to be
+ kept.
+
+2005-06-03 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/m68k.ld: gcc_except_table needs to be marked KEEP.
+
+2005-05-23 Jonathan Larmour <jifl@eCosCentric.com>
+2005-05-23 Bart Veer <bartv@eCosCentric.com>
+
+ * src/hal_arch.S (hal_m68k_exception_handler): Zero frame pointer
+ to improve GDB backtraces.
+ (hal_interrupt_stack_call_pending_DSRs): Ditto.
+ * src/vectors.S (hal_m68k_exception_reset): Use shorter suba.l
+ instruction to zero frame pointer.
+
+2005-02-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/m68k.ld: Use CYGBLD_HAL_LINKER_GROUPED_LIBS from the common HAL
+ for GROUP() list now.
+
+2004-10-22 Bart Veer <bartv@ecoscentric.com>
+
+ * src/hal_m68k.c (hal_m68k_startup): add more init macros if the
+ platform needs them.
+ * doc/m68k.sgml: document the various init macros
+
+2004-09-22 John Dallaway <jld@ecoscentric.com>
+
+ * src/m68k.ld: Add got, frame and RELOCS sections. Accommodate .bss*
+
+2004-06-24 Bart Veer <bartv@ecoscentric.com>
+
+ * src/vectors.S: extend fixed_vectors with sections for the
+ variant, processor and platform HALs. This makes it easier to
+ share data between RedBoot and the application.
+
+ * src/hal_m68k.c (hal_m68k_startup): support init routines
+ provided by the variant and processor HALs.
+
+2004-02-11 Bart Veer <bartv@ecoscentric.com>
+
+ * src/vectors.S: give .fixed_vectors the right section attributes,
+ and fix comment.
+
+ * src/hal_arch.S (hal_m68k_interrupt_vsr): use new macro
+ hal_context_extract_isr_vector_shl2, saving an instruction in the
+ main interrupt handling path.
+
+ * doc/m68k.sgml: document new macro
+ hal_context_extract_isr_vector_shl2
+
+2004-01-09 John Dallaway <jld@ecoscentric.com>
+
+ * cdl/hal_m68k.cdl:
+ Correct capitalisation of "Variant details" string.
+
+2004-01-05 Bart Veer <bartv@ecoscentric.com>
+
+ * src/hal_m68k.c (cyg_hal_invoke_constructors):
+ This function should not be static. In some configurations it may
+ get called from the libc startup code.
+
+2003-09-30 Bart Veer <bartv@ecoscentric.com>
+
+ * src/hal_arch.S: __profile_mcount() was referenced even if the
+ profiling package was absent. This was only a problem when
+ building without linker garbage collection.
+
+2003-09-26 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/hal_m68k.cdl, src/hal_arch.S, doc/m68k.sgml:
+ The architectural HAL now provides mcount profiling support.
+
+2003-08-01 Bart Veer <bartv@ecoscentric.com>
+
+ * src/hal_arch.S: rework VSR and
+ hal_interrupt_stack_call_pending_DSRs so that interrupts are only
+ re-enabled while running the DSR, not elsewhere in the interrupt
+ handling code. Currently this is the only way to guarantee that
+ stack usage remains bounded.
+
+ * src/hal_m68k.c: define new variable hal_m68k_dsr_ipl_level,
+ the IPL level that should be used when running DSRs.
+
+ * include/hal_intr.h: HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() is
+ now defined even when not running with an interrupt stack, so that
+ DSRs still run with interrupts enabled.
+
+ * doc/m68k.sgml: Minor updates following changes to the interrupt
+ handling.
+
+ * include/hal_arch.h (HAL_THREAD_INIT_CONTEXT): A thread would be
+ initialized with the wrong status register value if the default
+ IPL level was not zero
+
+2003-07-22 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/m68k.sgml: Fix various typos etc.
+
+2003-07-17 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/m68k.sgml: update documentation.
+
+2003-07-06 Bart Veer <bartv@ecoscentric.com>
+
+ * src/hal_arch.S: Add support for kernel interrupt
+ instrumentation.
+
+2003-07-04 Bart Veer <bartv@ecoscentric.com>
+
+ * src/hal_arch.S:
+ Rework interrupt and exception VSR's to make the use of an
+ interrupt stack optional, and to allow interrupt nesting to be
+ disabled.
+
+ * src/hal_m68k.c:
+ * src/vectors.S:
+ hal_m68k_interrupt_nesting count is no longer required. Instead
+ the stack pointer itself is compared with the interrupt stack base
+ and top when deciding whether or not to switch to the interrupt
+ stack.
+
+ * include/hal_intr.h:
+ HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() is only provided if there
+ is an interrupt stack
+
+ * include/hal_arch.h:
+ Adjust stack sizes for different interrupt-related configurations
+
+ * cdl/hal_m68k.cdl:
+ Interrupt stacks and nesting are now optional as on other
+ architectures.
+
+2003-06-25 Bart Veer <bartv@ecoscentric.com>
+
+ * include/hal_arch.h:
+ Eliminate a build warning.
+
+ * include/hal_intr.h:
+ Provide default implementation of HAL_TRANSLATE_VECTOR()
+
+2003-06-04 Bart Veer <bartv@ecoscentric.com>
+
+ * New version of the M68K support
//===========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003, 2004, 2005, 2006 eCosCentric Limited
//
// 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
@@ -31,9 +344,6 @@
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//===========================================================================
Index: cdl/hal_m68k.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/m68k/arch/current/cdl/hal_m68k.cdl,v
retrieving revision 1.2
diff -u -p -r1.2 hal_m68k.cdl
--- cdl/hal_m68k.cdl 22 Apr 2004 15:26:39 -0000 1.2
+++ cdl/hal_m68k.cdl 20 Nov 2008 22:20:22 -0000
@@ -6,72 +6,255 @@
#
# ====================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
-## -------------------------------------------
-## This file is part of eCos, the Embedded Configurable Operating System.
-## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-##
-## eCos is free software; you can redistribute it and/or modify it under
-## the terms of the GNU General Public License as published by the Free
-## Software Foundation; either version 2 or (at your option) any later version.
-##
-## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
-## WARRANTY; without even the implied warranty of MERCHANTABILITY or
-## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-## for more details.
-##
-## You should have received a copy of the GNU General Public License along
-## with eCos; if not, write to the Free Software Foundation, Inc.,
-## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-##
-## As a special exception, if other files instantiate templates or use macros
-## or inline functions from this file, or you compile this file and link it
-## with other works to produce a work based on this file, this file does not
-## by itself cause the resulting work to be covered by the GNU General Public
-## License. However the source code for this file must still be made available
-## in accordance with section (3) of the GNU General Public License.
-##
-## This exception does not invalidate any other reasons why a work based on
-## this file might be covered by the GNU General Public License.
-##
-## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-## at http://sources.redhat.com/ecos/ecos-license/
-## -------------------------------------------
+# -------------------------------------------
+# This file is part of eCos, the Embedded Configurable Operating System.
+# Copyright (C) 2003,2004,2006,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.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+#
+# As a special exception, if other files instantiate templates or use macros
+# or inline functions from this file, or you compile this file and link it
+# with other works to produce a work based on this file, this file does not
+# by itself cause the resulting work to be covered by the GNU General Public
+# License. However the source code for this file must still be made available
+# in accordance with section (3) of the GNU General Public License.
+#
+# This exception does not invalidate any other reasons why a work based on
+# this file might be covered by the GNU General Public License.
+# -------------------------------------------
#####ECOSGPLCOPYRIGHTEND####
# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Date: 2003-06-04
+#
+#####DESCRIPTIONEND####
+#========================================================================
cdl_package CYGPKG_HAL_M68K {
display "m68k architecture"
parent CYGPKG_HAL
+ doc ref/hal-m68k-arch.html
hardware
- include_dir cyg/hal
- define_header hal_m68k.h
description "
- The m68k architecture HAL package provides generic
- support for this processor architecture. It is also
- necessary to select a specific target platform HAL
- package."
-
- cdl_interface CYGINT_HAL_M68K_VARIANT {
- display "Number of variant implementations in this configuration"
- requires 1 == CYGINT_HAL_M68K_VARIANT
+ The m68k architecture HAL package provides generic
+ support for 68000 and ColdFire processors."
+
+ include_dir cyg/hal
+ compile hal_m68k.c hal_arch.S m68k_stub.c
+ define_proc {
+ puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H <pkgconf/hal_m68k.h>"
}
-
- compile hal_startup.c hal_misc.c m68k_stub.c hal_arch.S
-
make {
- <PREFIX>/lib/target.ld: <PACKAGE>/src/m68k.ld
- $(CC) -E -P -Wp,-MD,target.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(CFLAGS) -o $@ $<
+ <PREFIX>/lib/vectors.o : <PACKAGE>/src/vectors.S
+ $(CC) -Wp,-MD,vectors.tmp $(INCLUDE_PATH) $(ACTUAL_CFLAGS) -c -o $@ $<
@echo $@ ": \\" > $(notdir $@).deps
- @tail -n +2 target.tmp >> $(notdir $@).deps
+ @tail -n +2 vectors.tmp >> $(notdir $@).deps
@echo >> $(notdir $@).deps
- @rm target.tmp
+ @rm vectors.tmp
}
- cdl_option CYGBLD_LINKER_SCRIPT {
- display "Linker script"
- flavor data
- no_define
- calculated { "src/m68k.ld" }
+ # callgraph profiling, i.e. compiling with -pg, is supported. However
+ # -pg is incompatible with -fomit-frame-pointer
+ implements CYGINT_PROFILE_HAL_MCOUNT
+ requires { ! (is_substr(CYGBLD_GLOBAL_CFLAGS, " -pg") && is_substr(CYGBLD_GLOBAL_CFLAGS, "-fomit-frame-pointer")) }
+
+ cdl_option CYGNUM_HAL_DEFAULT_INTERRUPT_STACK_SIZE {
+ display "Default size for the startup and interrupt stack"
+ description "
+ The M68K HAL uses a single stack for system startup and for handling
+ interrupts and exceptions. The size of this stack is configurable via
+ the common HAL's CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE option, but
+ this architectural HAL provides a default value."
+ flavor data
+ calculated { is_enabled(CYGNUM_HAL_M68K_PLATFORM_DEFAULT_INTERRUPT_STACK_SIZE) ?
+ CYGNUM_HAL_M68K_PLATFORM_DEFAULT_INTERRUPT_STACK_SIZE :
+ (CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING ? 4096 : 2048) }
}
+ cdl_option CYGNUM_HAL_M68K_STARTUP_STACK_SIZE {
+ display "Stack size to use during startup"
+ active_if !CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+ flavor data
+ default_value 2048
+ description "
+ By default eCos runs with a separate interrupt stack, which also gets
+ used during system startup. This saves memory because it is not necessary
+ to allow for interrupt overheads on every thread stack, but adds a number
+ of instructions to the interrupt processing code. If the interrupt stack
+ is disabled then a separate startup stack is needed. That stack will be
+ used for running system initialization and for running some application
+ code including cyg_start() and C++ static constructions."
+ }
+
+ cdl_component CYGPKG_HAL_M68K_VARIANT {
+ display "Variant details"
+ flavor none
+ description "
+ Various subsystems like the floating point and memory management
+ units are available on some but not all 68000 processors. Variant
+ HAL packages will list which of these subsystems are actually
+ present."
+
+ cdl_interface CYGINT_HAL_M68K_VARIANT_TYPES {
+ display "Data types"
+ flavor bool
+ description "
+ This interface will be implemented if the specific processor
+ being used requires non-default data type definitions."
+ }
+
+ cdl_interface CYGINT_HAL_M68K_VARIANT_FPU {
+ display "Floating point unit"
+ flavor bool
+ description "
+ This interface will be implemented if the specific processor
+ being used has floating point hardware."
+ }
+
+ if { 0 } {
+ # No MMU support available yet
+ cdl_interface CYGINT_HAL_M68K_VARIANT_MMU {
+ display "Floating point unit"
+ flavor bool
+ description "
+ This interface will be implemented if the specific processor
+ being used has a memory management unit."
+ }
+ }
+
+ cdl_interface CYGINT_HAL_M68K_VARIANT_CACHE {
+ display "Cache"
+ flavor bool
+ description "
+ This interface will be implemented if the specific processor
+ being used has an instruction cache, a data cache, or both."
+ }
+
+ cdl_interface CYGINT_HAL_M68K_VARIANT_IRAM {
+ display "On-chip RAM"
+ flavor bool
+ description "
+ This interface will be implemented if the specific processor
+ being used has on-chip RAM."
+ }
+
+ cdl_interface CYGINT_HAL_M68K_USE_STANDARD_PLATFORM_STUB_SUPPORT {
+ display "Use standard platform gdb stub support"
+ flavor bool
+ make -priority 1 {
+ <PREFIX>/include/cyg/hal/plf_stub.h : <PACKAGE>/src/plf_stub.h
+ @cp $< $@
+ }
+ description "
+ For platforms where target-side gdb stub support may be used the
+ platform HAL is expected to provide a header file <cyg/hal/plf_stub.h>.
+ In practice the same header file is applicable to nearly all platforms
+ so the M68K architectural HAL will provide this header when the platform
+ HAL requests this interface."
+ }
+ }
+
+ cdl_component CYGPKG_HAL_M68K_FPU {
+ display "Support for the floating point unit"
+ active_if CYGINT_HAL_M68K_VARIANT_FPU
+ flavor none
+ description "
+ If the target processor has a hardware floating point unit then
+ this component defines additional configuration options related
+ to that unit."
+
+ cdl_option CYGIMP_HAL_M68K_FPU_SAVE {
+ display "Save FPU state during context switch"
+ default_value 1
+ description "
+ By default the floating point context gets saved during a
+ context switch. This can be suppressed if the application
+ does not actually perform any floating point arithmetic, or
+ if it only does so from one thread."
+ }
+
+ cdl_option CYGNUM_HAL_M68K_FPU_CR_DEFAULT {
+ display "Default value for the FPU control register"
+ flavor data
+ default_value 0
+ legal_values 0 to 0x0FFFF
+ description "
+ The FPU control register controls rounding modes, precision,
+ and exceptions. The default value of 0 gives IEE754 standard
+ behaviour. It is assumed that the control register's value is
+ not changed while the system is running, and hence does not
+ have to be saved or restored during a thread switch or when
+ an interrupt happens."
+ }
+ }
+
+ cdl_component CYGPKG_HAL_M68K_OPTIONS {
+ display "Architectural HAL build options"
+ flavor none
+ description "
+ Package-specific build options including control over compiler
+ flags used only when building this package, and details of which
+ tests are built."
+
+ cdl_option CYGPKG_HAL_M68K_CFLAGS_ADD {
+ display "Additional compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for building
+ the architectural HAL package. These flags are used in addition
+ to the set of global flags."
+ }
+
+ cdl_option CYGPKG_HAL_M68K_CFLAGS_REMOVE {
+ display "Suppressed compiler flags"
+ flavor data
+ no_define
+ default_value { "" }
+ description "
+ This option modifies the set of compiler flags for building
+ the architectural HAL package. These flags are removed from
+ the set of global flags if present."
+ }
+
+ cdl_option CYGPKG_HAL_M68K_TESTS {
+ display "Architectural HAL tests"
+ flavor data
+ no_define
+ calculated { (CYGINT_HAL_M68K_VARIANT_IRAM ? "tests/iram1" : "") .
+ ""
+ }
+ description "
+ This option specifies the set of tests for the M68K architectural HAL."
+ }
+
+ cdl_option CYGBLD_LINKER_SCRIPT {
+ display "Linker script"
+ flavor data
+ no_define
+ calculated { "src/m68k.ld" }
+ make {
+ <PREFIX>/lib/target.ld: <PACKAGE>/src/m68k.ld
+ $(CC) -E -P -Wp,-MD,target.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(ACTUAL_CFLAGS) -o $@ $<
+ @echo $@ ": \\" > $(notdir $@).deps
+ @tail -n +2 target.tmp >> $(notdir $@).deps
+ @echo >> $(notdir $@).deps
+ @rm target.tmp
+ }
+ }
+ }
}
Index: doc/m68k.sgml
===================================================================
RCS file: doc/m68k.sgml
diff -N doc/m68k.sgml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ doc/m68k.sgml 20 Nov 2008 22:20:24 -0000
@@ -0,0 +1,878 @@
+<!-- DOCTYPE part PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
+
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- m68k.sgml -->
+<!-- -->
+<!-- m68k architectural documentation. -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####COPYRIGHTBEGIN#### -->
+<!-- -->
+<!-- Copyright (C) 2003,2004,2006,2008 -->
+<!-- Free Software Foundation, Inc. -->
+<!-- This material may be distributed only subject to the terms -->
+<!-- and conditions set forth in the Open Publication License, v1.0 -->
+<!-- or later (the latest version is presently available at -->
+<!-- http://www.opencontent.org/openpub/) -->
+<!-- Distribution of the work or derivative of the work in any -->
+<!-- standard (paper) book form is prohibited unless prior -->
+<!-- permission obtained from the copyright holder -->
+<!-- -->
+<!-- ####COPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- Author(s): bartv -->
+<!-- Contact(s): bartv -->
+<!-- Date: 2003/06/04 -->
+<!-- Version: 0.01 -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="hal-m68k-arch"><title>M68000 Architectural Support</title>
+
+<!-- {{{ Overview -->
+
+<refentry id="m68k">
+ <refmeta>
+ <refentrytitle>Overview</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>Overview</refname>
+ <refpurpose>eCos Support for the M68K Family of Processors</refpurpose>
+ </refnamediv>
+
+ <refsect1 id="m68k-description"><title>Description</title>
+ <para>
+The original Motorola 68000 processor was released in 1979, and
+featured the following:
+ </para>
+ <itemizedlist>
+ <listitem><para>
+Eight general purpose 32-bit data registers, %D0 to %D7. Seven 32-bit
+address registers %A0 to %A6, with %A7 dedicated as the stack pointer.
+A 16-bit status register.
+ </para></listitem>
+ <listitem><para>
+A linear address space, limited to 24-bits because the chip package
+only had 24 address pins. Hence the processor could address 16
+megabytes of memory.
+ </para></listitem>
+ <listitem><para>
+No separate address space for I/O operations. Instead devices are
+accessed just like memory via the main address and data buses.
+ </para></listitem>
+ <listitem><para>
+16-bit external data bus, even though the data registers were 32 bits
+wide.
+ </para></listitem>
+ <listitem><para>
+A CISC variable-length instruction set with no less than 14 different
+addressing modes (although of course the terms RISC and CISC were not
+yet in common use).
+ </para></listitem>
+ <listitem><para>
+Separate supervisor and user modes. The processor actually has two
+distinct stack pointer registers %A7, and the mode determines which one
+gets used.
+ </para></listitem>
+ <listitem><para>
+An interrupt subsystem with support for vectored and prioritized
+interrupts.
+ </para></listitem>
+ </itemizedlist>
+ <para>
+The 68000 processor was used in several microcomputers of its time,
+including the original Apple Macintosh, the Commodore Amiga, and the
+Atari ST. Over the years numerous variants have been developed. The
+core instruction set has remained essentially unchanged. Some of the
+variants have additional instructions. The development of MMUs led to
+changes in exception handling. In more recent variants, notably the
+Freescale ColdFire family, some infrequently used instructions and
+addressing modes have been removed.
+ </para>
+ <itemizedlist>
+ <listitem><para>
+The 68008 reduced the widths of the external data and address buses to
+8 bits and 20 bits respectively, giving the processor slow access to
+only one megabyte.
+ </para></listitem>
+ <listitem><para>
+The 68010 (1982) added virtual memory support.
+ </para></listitem>
+ <listitem><para>
+In the 68020 (1984) both the address and data buses were made 32-bits wide. A
+256-byte instruction cache was added, as were some new instructions
+and addressing modes.
+ </para></listitem>
+ <listitem><para>
+The 68030 (1987) included an on-chip mmu and a 256-byte data cache.
+ </para></listitem>
+ <listitem><para>
+The 68040 (1991) added hardware floating point (previous processors relied on
+an external coprocessor or on software emulation). It also had larger
+caches and an improved mmu.
+ </para></listitem>
+ <listitem><para>
+The 68060 (1994) involved an internally very different superscalar
+implementation of the architecture, but few changes at the interface
+level. It also contained support for power management.
+ </para></listitem>
+ <listitem><para>
+There have been numerous 683xx variants for embedded use, with
+on-chip peripherals like UARTs and timers. The cpu core of these
+variants is also known as cpu32.
+ </para></listitem>
+ <listitem><para>
+The MCFxxxx ColdFire series (1995) resembles a stripped-down 68060,
+with some instructions and addressing modes removed to allow for a
+much smaller and more efficient implementation. Various hardware units
+such as the and FPU and MMU have become optional.
+ </para></listitem>
+ </itemizedlist>
+
+ <para>
+eCos only provides support for some of these variants, although it
+should be possible to add support for additional variants with few or
+no changes to the architectural HAL package.
+ </para>
+ <para>
+The architectural HAL provides support for those features which are
+common to all members of the 68000 and ColdFire families, and for
+certain features which are present on some but not all members. A
+typical eCos configuration will also contain: a variant HAL package
+with support code for a family of processors, for example MCFxxxx;
+possibly a processor HAL package with support for one specific
+processor, for example the MCF5272; and a platform HAL
+which contains the code needed for a specific hardware platform such
+as the m5272c3.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- }}} -->
+<!-- {{{ Configuration -->
+
+<refentry id="m68k-configuration">
+ <refmeta>
+ <refentrytitle>Configuration</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>Options</refname>
+ <refpurpose>Configuring the M68K Architectural Package</refpurpose>
+ </refnamediv>
+
+ <refsect1 id="m68k-config-load"><title>Loading and Unloading the Package</title>
+ <para>
+The M68K architectural HAL package <varname>CYGPKG_HAL_M68K</varname>
+should be loaded automatically when eCos is configured for M68K-based
+target hardware. It should never be necessary to load this package
+explicitly. Unloading the package should only happen as a side effect
+of switching target hardware. <varname>CYGPKG_HAL_M68K</varname>
+serves primarily as a container for lower-level HALs and has only a
+small number of configuration options.
+ </para>
+ </refsect1>
+
+ <refsect1 id="m68k-config-stacks"><title>Stacks</title>
+ <para>
+By default the architectural HAL provides a single block of memory to
+act as both the startup stack and the interrupt stack. The variant,
+processor or platform HAL may override this. For example if there are
+several banks of RAM with different performance characteristics it may
+be desirable to place the interrupt stack in fast RAM rather than in
+ordinary RAM.
+ </para>
+ <para>
+The assembler startup code sets the stack pointer to the startup stack
+before switching to C code. This stack used for all HAL
+initialization, running any C++ static constructors defined either by
+eCos or by the application, and the <function>cyg_start</function>
+entry point. In configurations containing the eCos kernel
+<function>cyg_start</function> will enable interrupts, activate the
+scheduler and threads will then run on their own stacks. In non-kernel
+single-threaded applications the whole system continues to run on the
+startup stack.
+ </para>
+ <para>
+When an interrupt occurs the default behaviour is to switch to a
+separate interrupt stack. This behaviour is controlled by the common
+HAL configuration option
+<varname>CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK</varname>.
+It reduces the stack requirements of all threads in the system, at the
+cost of some extra instructions during interrupt handling. In kernel
+configurations the startup stack is no longer used once the scheduler
+starts running so its memory can be reused for the interrupt stack. To
+handle the possibility of nested interrupts the interrupt handling
+code will detect if it is already on the interrupt stack, so in
+non-kernel configurations it is also safe to use the same area of
+memory for both startup and interrupt stacks. This leads to the
+following scenarios:
+ </para>
+ <orderedlist>
+ <listitem><para>
+If interrupt stacks are enabled via
+<varname>CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK</varname>
+and the interrupt stack is not provided by the variant, processor or
+platform HAL then a single block of memory will be used for both
+startup and interrupt stacks. The size of this block is determined by
+the common HAL configuration option
+<varname>CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE</varname>, with a
+default value
+<varname>CYGNUM_HAL_DEFAULT_INTERRUPT_STACK_SIZE</varname> provided by
+the M68K architectural HAL.
+ </para></listitem>
+ <listitem><para>
+If the use of an interrupt stack is disabled then the M68K
+architectural HAL will provide just the startup stack, unless this is
+done by the variant, processor or platform HAL. The size of the
+startup stack is controlled by
+<varname>CYGNUM_HAL_M68K_STARTUP_STACK_SIZE</varname>.
+ </para></listitem>
+ <listitem><para>
+Otherwise the interrupt and/or startup stacks are provided by other
+packages and it is up to those packages to provide configuration
+options for setting the sizes.
+ </para></listitem>
+ </orderedlist>
+ </refsect1>
+
+ <refsect1 id="m68k-config-fpu"><title>Floating Point Support</title>
+ <para>
+There are many variants of the basic M68K architecture. Some of these
+have hardware floating point support. Originally this came in the form
+of a separate 68881 coprocessor, but with modern variants it will be
+part of the main processor chip. If the processor does not have
+hardware floating point then software emulation will be used instead.
+ </para>
+ <para>
+If the processor on the target hardware has a floating point unit then
+the variant or processor HAL will implement the CDL interface
+<varname>CYGINT_HAL_M68K_VARIANT_FPU</varname>. This allows the
+architectural HAL and other packages to do the right thing on
+different hardware.
+ </para>
+ <para>
+Saving and restoring hardware floating point context increases
+interrupt and dispatch latency, code size, and data size. If the
+application does not actually use floating point then these overheads
+are unnecessary, and can be suppressed by disabling the configuration
+option <varname>CYGIMP_HAL_M68K_FPU_SAVE</varname>. Some applications
+do use floating point but only in one thread. In that scenario it is
+also unnecessary to save the floating point context during interrupts
+and context switches, so the configuration option can be disabled.
+ </para>
+ <para>
+The exact behaviour of the hardware floating point unit is determined
+by the floating point control register <varname>%fpcr</varname>. By
+default this is initialized to 0, giving IEE754 standard behaviour,
+but another initial value can be specified using the configuration
+option <varname>CYGNUM_HAL_M68K_FPU_CR_DEFAULT</varname>. For details
+of the various bits in this control register see appropriate hardware
+documentation. eCos assumes that the control register does not change
+on a per-thread basis and hence the register is not saved or restored
+during interrupt handling or a context switch.
+ </para>
+ <warning>
+ <para>
+At the time of writing eCos has not run on an M68K processor with
+hardware floating point so the support for this is untested.
+ </para>
+ </warning>
+ </refsect1>
+
+ <refsect1 id="m68k-config-other"><title>Other Options</title>
+ <para>
+There are configuration options to change the compiler flags used for
+building this packages.
+The M68K architectural HAL package does not define any other
+configuration options that can be manipulated by the user. It does
+define a number of interfaces such as
+<varname>CYGINT_HAL_M68K_USE_STANDARD_PLATFORM_STUB_SUPPORT</varname>
+which can be used by lower levels of the M68K HAL hierarchy to enable
+certain functionality within the architectural package. Usually these
+are of no interest to application developers.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- }}} -->
+<!-- {{{ HAL Porting Details -->
+
+<refentry id="m68k-port">
+ <refmeta>
+ <refentrytitle>The HAL Port</refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>HAL Port</refname>
+ <refpurpose>Implementation Details</refpurpose>
+ </refnamediv>
+
+ <refsect1 id="m68k-port-description"><title>Description</title>
+ <para>
+This documentation explains how the eCos HAL specification has been
+mapped onto M68K hardware, and should be read in conjunction with
+that specification. It also describes how variant, processor and
+platform HALs can modify the default behaviour.
+ </para>
+ <para>
+eCos support for any given target will involve either three or four
+HAL packages: the architectural HAL, the platform HAL, the variant
+HAL, and optionally a processor HAL. This package, the architectural
+HAL, provides code and definitions that are applicable to all M68K
+processors. The platform HAL provides support for one specific
+board, for example an M5272C3 evaluation board, or possibly for a
+number of almost-identical boards. The processor HAL, if present,
+serves mainly to provide details of on-chip peripherals including the
+interrupt controller. The variant HAL provides functionality that is
+common to a group of processors, for example all MCFxxxx processors
+have very similar UARTs and hence can share HAL diagnostic code.
+There is no fixed specification of what should go into the variant HAL
+versus the processor HAL. For simplicity the description below only
+refers to variant HALs, but the work may actually happen in a
+processor HAL instead.
+ </para>
+ <para>
+As a design goal lower-level HALs can always override functionality
+that is normally provided higher up. For example the architectural HAL
+will provide the required eCos <function>HAL_LSBIT_INDEX</function>
+and <function>HAL_MSBIT_INDEX</function> macros, but these can be
+provided lower down instead. Many but not all ColdFire processors have
+the <literal>ff1</literal> and <literal>bitrev</literal> instructions
+which allow for a more efficient implementation than the default
+architectural ones. In some areas such as handling context switching
+the architectural HAL will usually provide the basic functionality but
+it may be extended by lower HALs, for example to add support for the
+multiply-accumulate units present in certain ColdFire processors.
+ </para>
+ <para>
+The architectural HAL provides header files <filename
+class="headerfile">cyg/hal/hal_arch.h</filename>, <filename
+class="headerfile">cyg/hal/hal_intr.h</filename>, <filename
+class="headerfile">cyg/hal/hal_cache.h</filename>, <filename
+class="headerfile">cyg/hal/hal_io.h</filename> and <filename
+class="headerfile">cyg/hal/arch.inc</filename>. These automatically
+include an equivalent header file from the variant HAL, for example
+<filename class="headerfile">cyg/hal/var_arch.h</filename>. The
+variant HAL header will in turn include processor and
+platform-specific headers. This means that application developers and
+other packages can simply include the architectural HAL headers
+without needing to know about variants or platforms. It also allows
+the variant and platform HALs to override architectural settings.
+ </para>
+ <para>
+The port assumes that eCos and application code always runs in
+supervisor mode, with full access to all hardware and special
+registers.
+ </para>
+
+ <refsect2 id="m68k-port-types"><title>Data Types</title>
+ <para>
+For eCos purposes all M68K processors are big-endian and 32-bit, so
+the default data types in <filename
+class="headerfile">cyg/infra/cyg_type.h</filename> are used. Some
+variants have external bus widths less than 32-bit, but this does not
+affect the architectural HAL.
+ </para>
+ <para>
+When porting to another variant it is possible to override some or all
+of the type definitions. The variant HAL needs to implement the CDL
+interface <varname>CYGINT_HAL_M68K_VARIANT_TYPES</varname> and provide
+a header file <filename
+class="headerfile">cyg/hal/var_basetype.h</filename>.
+ </para>
+ </refsect2>
+
+ <refsect2 id="m68k-port-startup"><title>Startup and Exception Vectors</title>
+ <para>
+The conventional bootstrap mechanism involves a table of exception
+vectors at the base of memory. The first two words of this table give
+the initial program counter and stack pointer. In a typical embedded
+system the hardware is arranged such that non-volatile flash memory is
+found at location 0x0 so it is the start of flash that contains the
+exception vectors and the boot code. The table of exception vectors is
+used subsequently for interrupt handling and for hardware exceptions
+such as attempts to execute an illegal instruction. There are a number
+of common scenarios:
+ </para>
+ <orderedlist>
+ <listitem><para>
+On systems with very limited memory flash may remain mapped at
+location 0 and the table of exception vectors remains mapped there as
+well. The M68K architecture defines the table to have 256 entries and
+hence it occupies 1K of memory, but in reality many of the entries are
+unused so part of the table may get used for code instead. Since the
+whole exception vector table is in read-only memory parts of the eCos
+interrupt and exception handling mechanisms have to be statically
+initialized and macros like <function>HAL_VSR_SET</function> are not
+available.
+ </para></listitem>
+ <listitem><para>
+As a minor variation of the previous case, flash remains at location 0
+but the table of exception vectors gets remapped elsewhere in the
+address space, usually RAM. This allows
+<function>HAL_VSR_SET</function> to operate normally but at the cost
+of increased memory usage. The exception vector table in flash only
+contains two entries, for the initial program counter and stack
+pointer. The exception vector table in RAM typically gets initialized
+at run-time.
+ </para></listitem>
+ <listitem><para>
+On systems with more memory it is conventional to rearrange the
+address map during bootstrap. The flash gets relocated, typically to
+near the end of the address space, and RAM gets placed at location 0
+instead. The exception vector table stays at location 0 but is now in
+RAM and gets initialized at run-time. The bootstrap exception vector
+table in flash again only needs two entries. A variation places the
+RAM elsewhere in the address space and moves the exception vector
+table there, leaving location 0 unused. This provides some protection
+against null pointer accesses in errant code.
+ </para>
+ <para>
+As a further complication, larger systems typically support different
+startup types. The application can be linked against a ROM startup
+configuration and placed directly in flash, as before. Alternatively
+there may be a ROM monitor such as RedBoot in the flash, taking care
+of initial bootstrap. The user's application is linked against a RAM
+startup configuration, loaded into RAM via the ROM monitor, and
+debugged using functionality provided by the ROM monitor. Yet another
+possibility involves a RAM startup application but it gets loaded and
+run via a hardware debug technology such as BDM, and the ROM monitor
+is either missing or not used.
+ </para></listitem>
+ </orderedlist>
+ <para>
+The exact hardware details, the various startup types, the steps
+needed for low-level hardware initialization, and so on are not known
+to the architectural HAL. Hence although the architectural HAL does
+provide the basic framework for startup, much of the work is done via
+macros provided by lower-level HAL packages and those macros are
+likely to depend on various configuration options. Rather than try to
+enumerate all the various combinations here it is better to look at
+the actual code in <filename>vectors.S</filename> and in appropriate
+variant, processor or platform HALs. <filename>vectors.S</filename> is
+responsible for any low-level initialization that needs to happen.
+This includes setting up a standard C environment with the stack
+pointer set to the startup stack in working RAM, making sure all
+statically initialized global variables have the correct values, and
+that all uninitialized global variables are zeroed. Once the C
+environment has been set up the code jumps to
+<function>hal_m68k_c_startup</function> in file
+<filename>hal_m68k.c</filename> which completes the initialization and
+jumps to the application entry point.
+ </para>
+ </refsect2>
+
+ <refsect2 id="m68k-port-interrupts"><title>Interrupt Handling</title>
+ <para>
+The M68K architecture reserves a 1K area of memory for 256 exception
+vectors. These are used for internal and external interrupts,
+exceptions, software traps, and special operations such as reset
+handling. Some of the vectors have well-defined uses. However when it
+comes to interrupt handling the details will depend on the processor
+variant and on the platform, and the appropriate package documentation
+should be consulted for full details. Most platforms will not use the
+full set of 256 vectors, instead re-using some of this memory for
+other purposes.
+ </para>
+ <para>
+By default the exception vectors are located at location 0, but some
+variants allow the vectors to be located elsewhere. This is managed by
+an M68K-specific macro <varname>CYG_HAL_VSR_TABLE</varname>. The
+default value is 0, but a variant HAL can provide an alternative value.
+ </para>
+ <para>
+The standard eCos macros <function>HAL_VSR_GET</function> and
+<function>HAL_VSR_SET</function> just manipulate one of the 256
+entries in the table of exception vectors. Hence it is usually
+possible to replace the default handlers for exceptions and traps in
+addition to interrupt handlers.
+<filename class="headerfile">hal_intr.h</filename>
+provides <literal>#define</literal>'s for the more common exception
+vectors, and additional ones can be provided by the platform or
+variant. It is the responsibility of the platform or variant HAL to
+initialize the table, and to provide the
+<function>HAL_VSR_SET_TO_ECOS_HANDLER</function> macro since that
+requires knowledge of the default table entries.
+ </para>
+ <para>
+It should be noted that in some configurations the table of exception
+vectors may reside in read-only memory so entries cannot be changed.
+If so then the <function>HAL_VSR_SET</function> and
+<function>HAL_VSR_SET_TO_ECOS_HANDLER</function> macros will not be
+defined. Portable code may need to consider this possibility and test
+for the existence of these macros before using them.
+ </para>
+ <para>
+The architectural HAL provides an entry point
+<function>hal_m68k_interrupt_vsr</function> in the file
+<filename>hal_arch.S</filename>. When an interrupt occurs the original
+68000 pushed the program counter and the status register on to the
+stack, and then called the VSR via the exception table. On newer
+variants some additional information is pushed, including details of
+the interrupt source. <function>hal_m68k_interrupt_vsr</function>
+assumes the latter and can be used directly as the VSR on these newer
+variants. On older variants a small trampoline is needed which pushes
+the additional information and then jumps to the generic VSR.
+Interpreting the additional information is handled via an assembler
+macro <function>hal_context_extract_isr_vector_shl2</function>
+which should be defined by the variant, matching the behaviour of the
+hardware or the trampoline.
+ </para>
+ <para>
+At the architecture level there is no fixed mapping between VSR and
+ISR vectors. Instead that is left to the variant or platform HAL. The
+architectural HAL does provide default implementations of
+<function>HAL_INTERRUPT_ATTACH</function>,
+<function>HAL_INTERRUPT_DETACH</function> and
+<function>HAL_INTERRUPT_IN_USE</function> since these just involve
+updating a static table.
+ </para>
+ <para>
+By default the interrupt state control macros
+<function>HAL_DISABLE_INTERRUPTS</function>,
+<function>HAL_RESTORE_INTERRUPTS</function>,
+<function>HAL_ENABLE_INTERRUPTS</function> and
+<function>HAL_QUERY_INTERRUPTS</function> are implemented by the
+architectural HAL, and simply involve updating the status register.
+Disabling interrupts involves setting the three IPL bits to 0x07.
+Enabling interrupts involves setting those bits to a smaller value,
+<varname>CYGNUM_HAL_INTERRUPT_DEFAULT_IPL_LEVEL</varname>, which
+defaults to 0.
+ </para>
+ <para>
+<function>HAL_DISABLE_INTERRUPTS</function> has no effect on
+non-maskable interrupts. This causes a problem because parts of the
+system assume that all normal interrupt sources are affected by this
+macro. If the target hardware can raise non-maskable interrupts then
+it is the responsibility of application code to install a suitable VSR
+and handle non-maskable interrupts entirely within the application,
+bypassing the usual eCos ISR and DSR mechanisms.
+ </para>
+ <para>
+The architectural HAL does not provide any support for the interrupt
+controller management macros like
+<function>HAL_INTERRUPT_MASK</function>. These can only be implemented
+on a per-variant, per-processor or per-platform basis.
+ </para>
+ </refsect2>
+
+ <refsect2 id="m68k-port-exceptions"><title>Exception Handling</title>
+ <para>
+Synchronous exception handling is done in much the same way as
+interrupt handling. The architectural HAL provides a generic entry
+point <function>hal_m68k_exception_vsr</function>. On some variants
+this can be used directly as the exception VSR, on others it will be
+called via a small trampoline.
+ </para>
+ <para>
+The details of exception handling vary widely from one variant to the
+next. Some variants push a great deal of additional information on to
+the stack for certain exceptions, but not all. The pushed program
+counter may correspond to the specific instruction that caused the
+exception, or the next instruction, or there may be only a loose
+correlation because of buffered writes. The architectural HAL makes no
+attempt to cope with all these differences, although some variants may
+provide more advanced support. Otherwise if an exception needs to be
+handled in a very specific way then it is up to the application to
+install a suitable VSR and handle the exception directly.
+ </para>
+ </refsect2>
+
+ <refsect2 id="m68k-port-stacks"><title>Stacks and Stack Sizes</title>
+ <para>
+<filename class="headerfile">cyg/hal/hal_arch.h</filename> defines
+values for minimal and recommended thread stack sizes,
+<varname>CYGNUM_HAL_STACK_SIZE_MINIMUM</varname> and
+<varname>CYGNUM_HAL_STACK_SIZE_TYPICAL</varname>. These values are
+specific to the current configuration, and are affected mainly by
+options related to interrupt handling.
+ </para>
+ <para>
+By default eCos uses a separate interrupt stack, although this can be
+disabled through the configuration option
+<varname>CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK</varname>.
+When an interrupt or exception occurs eCos will save the context on
+the current stack and then switch to the interrupt stack before
+calling the appropriate ISR interrupt handler. This means that thread
+stacks can be significantly smaller because there is no need to worry
+about interrupt handling overheads, just the thread context. However
+switching the stack does require some extra work and hence increases
+the interrupt latency. Disabling the interrupt stack removes this
+processing overhead but requires larger stack sizes. It depends on
+the application whether or not this is a sensible trade off.
+ </para>
+ <para>
+By default eCos does not allow nested interrupts, but this can be
+controlled via the configuration option
+<varname>CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING</varname>.
+Supporting nested interrupts requires larger thread stacks, especially
+if the separate interrupt stack is also disabled.
+ </para>
+ <para>
+Although the M68K has enough registers for typical operation, the
+calling conventions are memory-oriented. In particular all arguments
+are pushed on the stack rather than held in registers, and the return
+address is also pushed rather than ending up in a link register. To
+allow for this the recommended minimum stack sizes are a little bit
+larger than for some other architectures. Variant HALs cannot directly
+affect these stack sizes. However the sizes do depend in part on the
+size of a thread context, so if for example the processor supports
+hardware floating point and support for that is enabled then the stack
+sizes will increase.
+ </para>
+ <para>
+Usually the M68K architectural HAL will provide a single block of
+memory which acts as both the startup and interrupt stack, and there
+are <link linkend="m68k-config-stacks">configuration options</link> to
+control the size of this block. Alternatively a variant, processor or
+platform HAL may define either or both of
+<varname>_HAL_M68K_STARTUP_STACK_</varname> and
+<varname>_HAL_M68K_INTERRUPT_STACK_BASE_</varname> if for some reason
+the stacks should not be placed in ordinary RAM.
+ </para>
+ </refsect2>
+
+ <refsect2 id="m68k-port-context"><title>Thread Contexts and Setjmp/Longjmp</title>
+ <para>
+A typical thread context consists of the following:
+ </para>
+ <orderedlist>
+ <listitem><para>
+The integer context. This consists of the data registers
+<varname>%d0</varname> to <varname>%d7</varname> and the address
+registers <varname>%a0</varname> to <varname>%a6</varname>, The stack
+pointer register <varname>%a7</varname> does not have to be saved
+explicitly since it is implicit in the pointer to the saved context.
+ </para>
+ <para>
+The caller-save registers are <varname>%d0</varname>,
+<varname>%d1</varname>, <varname>%a0</varname>,
+<varname>%a1</varname>, <varname>%a7</varname> and the status
+register. The remaining registers are callee-save. Function arguments
+are always passed on the stack. The result is held in
+<varname>%d0</varname>.
+ </para></listitem>
+ <listitem><para>
+Floating point context, consisting of eight 64-bit floating point
+registers <varname>%fp0</varname> to <varname>%fp7</varname> and two
+support registers <varname>%fpsr</varname> and
+<varname>%fpiar</varname>. Support for this is only relevant if the
+processor variant has a hardware floating point unit, and even then
+saving floating point context is optional and can be disabled using a
+configuration option <varname>CYGIMP_HAL_M68K_FPU_SAVE</varname>. The
+control register <varname>%fpcr</varname> is not saved as part of the
+context. It is assumed that a single <varname>%fpcr</varname> value,
+usually <literal>0</literal>, will be used throughout the application.
+ </para>
+ <para>
+The architectural HAL provides support for the hardware floating point
+unit. The variant or processor HAL should implement the CDL interface
+<varname>CYGINT_HAL_M68K_VARIANT_FPU</varname> if this hardware unit
+is actually present.
+ </para></listitem>
+ <listitem><para>
+Some M68K variants have additional hardware units, for example the
+multiply-accumulate units in certain ColdFire processors. The
+architectural HAL allows the context to be extended through various
+macros such as <varname>HAL_CONTEXT_OTHER</varname>.
+ </para></listitem>
+ <listitem><para>
+The status register <varname>%sr</varname> and the program counter.
+These are special because when an interrupt occurs the hardware
+automatically pushes these onto the stack, but exactly what gets
+pushed depends on the variant.
+ </para></listitem>
+ </orderedlist>
+ <para>
+<function>setjmp</function> and <function>longjmp</function> only deal
+with the integer and fpu contexts. It is assumed that any special
+hardware units will only be used by application code, not by the
+compiler. Hence it is the responsibility of application code to
+define and implement appropriate setjmp semantics for these units.
+The variant HAL package can override the default implementations if
+necessary.
+ </para>
+ <para>
+When porting to a new M68K variant, if this has a hardware floating
+point unit then the variant HAL should implement the CDL interface
+<varname>CYGINT_HAL_M68K_VARIANT_FPU</varname>, thus enabling support
+provided by the architectural HAL. If the variant has additional
+hardware units involving state that should be preserved during a
+context switch or when an interrupt occurs, the variant HAL should
+define a number of macros. The header file <filename
+class="headerfile">cyg/hal/var_arch.h</filename> should define
+<varname>HAL_CONTEXT_OTHER</varname>,
+<varname>HAL_CONTEXT_OTHER_SIZE</varname>, and
+<varname>HAL_CONTEXT_OTHER_INIT</varname>, either directly or via
+<filename class="headerfile">cyg/hal/proc_arch.h</filename>. The
+assembler header file <filename
+class="headerfile">cyg/hal/var.inc</filename> should define a number
+of macros such as <function>hal_context_other_save_caller</function>.
+For details of these macros see the architectural
+<filename>hal_arch.S</filename> file.
+ </para>
+ <para>
+Variants also need to define exactly how the status register and
+program counter are saved onto the stack when an interrupt or
+exception occurs. This is handled through C macros
+<varname>HAL_CONTEXT_PCSR_SIZE</varname>,
+<varname>HAL_CONTEXT_PCSR_RTE_ADJUST</varname>, and
+<function>HAL_CONTEXT_PCSR_INIT</function>, and a number of assembler
+macros such as <function>hal_context_pcsr_save_sr</function>. Again
+the architectural files <filename
+class="headerfile">cyg/hal/hal_arch.h</filename> and
+<filename>hal_arch.S</filename> provide more details of these.
+ </para>
+ </refsect2>
+
+ <refsect2 id="m68k-port-bitindex"><title>Bit Indexing</title>
+ <para>
+For performance reasons the <function>HAL_LSBIT_INDEX</function> and
+<function>HAL_MSBIT_INDEX</function> macros are implemented using
+assembler functions. A variant HAL can override the default
+definitions if, for example, the variant has special instructions to
+perform these operations.
+ </para>
+ </refsect2>
+
+ <refsect2 id="m68k-port-idle"><title>Idle Thread Processing</title>
+ <para>
+The default <function>HAL_IDLE_THREAD_ACTION</function> implementation
+is a no-op. A variant HAL may override this, for example to put the
+processor into sleep mode. Alternative implementations should consider
+exactly how this macro gets used in eCos kernel code.
+ </para>
+ </refsect2>
+
+ <refsect2 id="m68k-port-clock"><title>Clock Support</title>
+ <para>
+The architectural HAL cannot provide the required clock support
+because it does not know what timer hardware may be available on the
+target hardware. Instead this is left to either the variant or
+platform HAL, depending on whether the processor has a suitable
+on-chip timer or whether an off-chip timer has to be used.
+ </para>
+ </refsect2>
+
+ <refsect2 id="m68k-port-io"><title>HAL I/O</title>
+ <para>
+The M68K architecture does not have a separate I/O bus. Instead all
+hardware is assumed to be memory-mapped. Further it is assumed that
+all peripherals on the memory bus are wired appropriately for a
+big-endian processor and that there is no need for any byte swapping.
+Hence the various HAL macros for performing I/O simply involve
+pointers to volatile memory.
+ </para>
+ <para>
+The variant, processor and platform equivalents of the <filename
+class="headerfile">cyg/hal/hal_io.h</filename> header will typically
+also provide details of some or all of the peripherals, for example
+register offsets and the meaning of various bits in those registers.
+ </para>
+ </refsect2>
+
+ <refsect2 id="m68k-port-cache"><title>Cache Handling</title>
+ <para>
+If the processor has a cache then the variant HAL should implement the
+CDL interface <varname>CYGINT_HAL_M68K_VARIANT_CACHE</varname>. This
+causes the architectural header <filename
+class="headerfile">cyg/hal/hal_cache.h</filename> to pick up
+appropriate definitions from <filename
+class="headerfile">cyg/hal/var_cache.h</filename>. The architectural
+header will provide null defaults for anything not defined by the
+variant.
+ </para>
+ </refsect2>
+
+ <refsect2 id="m68k-port-ldscript"><title>Linker Scripts</title>
+ <para>
+The architectural HAL will generate the linker script for eCos
+applications. This involves the architectural file
+<filename>m68k.ld</filename> and a <filename>.ldi</filename> memory
+layout file provided lower down, typically by the platform HAL. It is
+the LDI file which specifies the types and amount of memory available
+and which places code and data in appropriate places, but most of the
+hard work is done via macros provided by the architectural
+<filename>m68k.ld</filename> file.
+ </para>
+ </refsect2>
+
+ <refsect2 id="m68k-port-diag"><title>Diagnostic Support</title>
+ <para>
+The architectural HAL does not implement diagnostic support. Instead
+this is left to the variant or platform HAL, depending on whether
+suitable peripherals are available on-chip or off-chip.
+ </para>
+ </refsect2>
+
+ <refsect2 id="m68k-port-smp"><title>SMP Support</title>
+ <para>
+The M68K port does not have SMP support.
+ </para>
+ </refsect2>
+
+ <refsect2 id="m68k-port-gdb"><title>Debug Support</title>
+ <para>
+The M68K architectural HAL package provides basic support only for gdb
+stubs. There is no support for more advanced debug features like
+hardware watchpoints.
+ </para>
+ <para>
+The generic gdb support in the common HAL requires a platform header
+<filename class="headerfile"><cyg/hal/plf_stub.h</filename>. In
+practice there is rarely any need for the contents of this file to
+change between platforms so the architectural HAL can provide a
+suitable default. It will do so if the CDL interface
+<varname>CYGINT_HAL_M68K_USE_STANDARD_PLATFORM_STUB_SUPPORT</varname>
+is implemented.
+ </para>
+ </refsect2>
+
+ <refsect2 id="m68k-port-delay"><title>HAL_DELAY_US Macro</title>
+ <para>
+The architectural HAL provides a default implementation of the
+standard <function>HAL_DELAY_US</function> macro using a simply busy
+loop. To use this support a lower-level HAL should define
+<varname>_HAL_M68K_DELAY_US_LOOPS_</varname>, typically a small number
+of about 20 but it will need to be calibrated during the porting
+process. If the processor has a cache then the lower-level HAL may
+also define <varname>_HAL_M68K_DELAY_US_LOOPS_UNCACHED_</varname> for
+the case when a delay loop is triggered while the cache is disabled.
+ </para>
+ </refsect2>
+
+ <refsect2 id="m68k-port-profiling"><title>Profiling Support</title>
+ <para>
+The M68K architectural HAL implements the <function>mcount</function>
+function, allowing profiling tools like
+<application>gprof</application> to determine the application's call
+graph. It does not implement the profiling timer. Instead that
+functionality needs to be provided by the variant or platform HAL.
+The implementation of <function>mcount</function> requires a dedicated
+frame pointer register so code should be compiled without the
+<option>-fomit-frame-pointer</option> flag.
+ </para>
+ </refsect2>
+
+ <refsect2 id="m68k-port-other"><title>Other Functionality</title>
+ <para>
+The M68K architectural HAL only implements the functionality provided
+by the eCos HAL specification and does not export any extra
+functionality.
+ </para>
+ </refsect2>
+
+ </refsect1>
+
+</refentry>
+
+<!-- }}} -->
+
+</part>
Index: include/arch.inc
===================================================================
RCS file: include/arch.inc
diff -N include/arch.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ include/arch.inc 20 Nov 2008 22:20:26 -0000
@@ -0,0 +1,86 @@
+##=============================================================================
+##
+## arch.inc
+##
+## M68K architecture assembler header file
+##
+##=============================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 2003,2006,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.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use macros
+## or inline functions from this file, or you compile this file and link it
+## with other works to produce a work based on this file, this file does not
+## by itself cause the resulting work to be covered by the GNU General Public
+## License. However the source code for this file must still be made available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work based on
+## this file might be covered by the GNU General Public License.
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s): bartv
+## Date: 2003-06-04
+######DESCRIPTIONEND####
+##=============================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/var.inc>
+
+// ----------------------------------------------------------------------------
+// Utility macros for defining normal and weak functions.
+
+#define FUNC_START(name) \
+ .section .text. ## name ; \
+ .balign 4 ; \
+ .globl name ; \
+ .type name, @function ; \
+name:
+
+#define FUNC_START_WEAK(name) \
+ .section .text._ ## name ; \
+ .weak name ; \
+ .set name, _ ## name ; \
+ .balign 4 ; \
+ .globl _ ## name ; \
+ .type name, @function ; \
+_ ## name:
+
+// ----------------------------------------------------------------------------
+// Default system and interrupt stack. This is used only if the
+// platform HAL has not already supplied suitable stacks.
+
+#ifndef _HAL_M68K_STARTUP_STACK_
+ .extern _hal_m68k_startup_stack_base_
+ .extern _hal_m68k_startup_stack_
+# define _HAL_M68K_STARTUP_STACK_ # _hal_m68k_startup_stack_
+# define _HAL_M68K_INSTANTIATE_STARTUP_STACK_
+#endif
+#ifndef _HAL_M68K_INTERRUPT_STACK_BASE_
+ .extern _hal_m68k_interrupt_stack_base_
+ .extern _hal_m68k_interrupt_stack_
+# define _HAL_M68K_INTERRUPT_STACK_BASE_ # _hal_m68k_interrupt_stack_base_
+# define _HAL_M68K_INTERRUPT_STACK_ # _hal_m68k_interrupt_stack_
+# define _HAL_M68K_INSTANTIATE_INTERRUPT_STACK_
+#endif
+
+#------------------------------------------------------------------------------
+# end of arch.inc
Index: include/basetype.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/m68k/arch/current/include/basetype.h,v
retrieving revision 1.1
diff -u -p -r1.1 basetype.h
--- include/basetype.h 29 May 2002 18:28:15 -0000 1.1
+++ include/basetype.h 20 Nov 2008 22:20:26 -0000
@@ -8,11 +8,10 @@
// Standard types for this architecture.
//
//=============================================================================
-//####ECOSGPLCOPYRIGHTBEGIN####
-// -------------------------------------------
+//###ECOSGPLCOPYRIGHTBEGIN####
+//-------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-//
+// Copyright (C) 2003,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.
@@ -35,30 +34,32 @@
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//=============================================================================
+//####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Date: 2003-06-04
+//####DESCRIPTIONEND####
+//=============================================================================
-// Include variant specific types.
-#include <cyg/hal/var_basetype.h>
-
-// Include the standard variable sizes.
-#include <cyg/hal/gen_types.h>
+#include <pkgconf/hal_m68k.h>
+#ifdef CYGINT_HAL_M68K_VARIANT_TYPES
+# include <cyg/hal/var_basetype.h>
+#endif
//-----------------------------------------------------------------------------
-// Characterize the architecture
-
-#define CYG_BYTEORDER CYG_MSBFIRST // Big endian
+// Characterize the architecture: big-endian
+#ifndef CYG_BYTEORDER
+# define CYG_BYTEORDER CYG_MSBFIRST
+#endif
//-----------------------------------------------------------------------------
-// 68k does not usually use labels with underscores. Some labels generated
-// by the linker do, so add an underscore where required.
-
-#define CYG_LABEL_NAME(_name_) _##_name_
+// 68k does not usually use labels with underscores.
+#define CYG_LABEL_NAME(_name_) _name_
+// ----------------------------------------------------------------------------
// The 68k architecture uses the default definitions of the base types,
// so we do not need to define any here.
@@ -67,25 +68,12 @@
// Most 68k variants use a 4 byte alignment.
// A few variants (68000) may override this setting to use a 2 byte alignment.
#ifndef CYGARC_ALIGNMENT
-#define CYGARC_ALIGNMENT 4
+# define CYGARC_ALIGNMENT 4
#endif
// the corresponding power of two alignment
#ifndef CYGARC_P2ALIGNMENT
-#define CYGARC_P2ALIGNMENT 2
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Define a compiler-specific rune for saying a function doesn't return
-
-// WARNING: There is a bug in some versions of gcc for the m68k that does
-// not handle the noreturn attribute correctly. It is safe to just disable
-// this attribute.
-
-#ifndef CYGBLD_ATTRIB_NORET
-# define CYGBLD_ATTRIB_NORET
+# define CYGARC_P2ALIGNMENT 2
#endif
//-----------------------------------------------------------------------------
#endif // CYGONCE_HAL_BASETYPE_H
-
Index: include/gen_types.h
===================================================================
RCS file: include/gen_types.h
diff -N include/gen_types.h
--- include/gen_types.h 29 May 2002 18:28:15 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,136 +0,0 @@
-#ifndef _GEN_TYPES_H
-#define _GEN_TYPES_H
-//==========================================================================
-//####ECOSGPLCOPYRIGHTBEGIN####
-// -------------------------------------------
-// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-//
-// eCos is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 2 or (at your option) any later version.
-//
-// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with eCos; if not, write to the Free Software Foundation, Inc.,
-// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-//
-// As a special exception, if other files instantiate templates or use macros
-// or inline functions from this file, or you compile this file and link it
-// with other works to produce a work based on this file, this file does not
-// by itself cause the resulting work to be covered by the GNU General Public
-// License. However the source code for this file must still be made available
-// in accordance with section (3) of the GNU General Public License.
-//
-// This exception does not invalidate any other reasons why a work based on
-// this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
-// -------------------------------------------
-//####ECOSGPLCOPYRIGHTEND####
-//==========================================================================
-
-/*****************************************************************************
-
- *********************
- * *
- * General Types *
- * *
- *********************
-
- Define some simple variable sizes for this platform.
-
- Note that these types are useful for making user threads that are
-not eCos-specific.
-
-*****************************************************************************/
-
-// Include some architecture variant specific types.
-
-#include <cyg/hal/var_gen_types.h>
-
-// Define types to use for specific sized variables. Note that the above
-// include file could have defined some of these types differently. If the
-// type is already defined, always use the previous definition.
-
-#ifndef _GEN_TYPES_I8_T
-#define _GEN_TYPES_I8_T char
-#endif
-#ifndef _GEN_TYPES_I16_T
-#define _GEN_TYPES_I16_T short
-#endif
-#ifndef _GEN_TYPES_I32_T
-#define _GEN_TYPES_I32_T int
-#endif
-#ifndef _GEN_TYPES_I64_T
-#define _GEN_TYPES_I64_T long long
-#endif
-#ifndef _GEN_TYPES_S8_T
-#define _GEN_TYPES_S8_T signed _GEN_TYPES_I8_T
-#endif
-#ifndef _GEN_TYPES_S16_T
-#define _GEN_TYPES_S16_T signed _GEN_TYPES_I16_T
-#endif
-#ifndef _GEN_TYPES_S32_T
-#define _GEN_TYPES_S32_T signed _GEN_TYPES_I32_T
-#endif
-#ifndef _GEN_TYPES_S64_T
-#define _GEN_TYPES_S64_T signed _GEN_TYPES_I64_T
-#endif
-#ifndef _GEN_TYPES_U8_T
-#define _GEN_TYPES_U8_T unsigned _GEN_TYPES_I8_T
-#endif
-#ifndef _GEN_TYPES_U16_T
-#define _GEN_TYPES_U16_T unsigned _GEN_TYPES_I16_T
-#endif
-#ifndef _GEN_TYPES_U32_T
-#define _GEN_TYPES_U32_T unsigned _GEN_TYPES_I32_T
-#endif
-#ifndef _GEN_TYPES_U64_T
-#define _GEN_TYPES_U64_T unsigned _GEN_TYPES_I64_T
-#endif
-#ifndef _GEN_TYPES_ADDR_T
-#define _GEN_TYPES_ADDR_T void *
-#endif
-
-typedef _GEN_TYPES_I8_T i8_t;
-typedef _GEN_TYPES_I16_T i16_t;
-typedef _GEN_TYPES_I32_T i32_t;
-typedef _GEN_TYPES_I64_T i64_t;
-typedef _GEN_TYPES_S8_T s8_t;
-typedef _GEN_TYPES_S16_T s16_t;
-typedef _GEN_TYPES_S32_T s32_t;
-typedef _GEN_TYPES_S64_T s64_t;
-typedef _GEN_TYPES_U8_T u8_t;
-typedef _GEN_TYPES_U16_T u16_t;
-typedef _GEN_TYPES_U32_T u32_t;
-typedef _GEN_TYPES_U64_T u64_t;
-typedef _GEN_TYPES_ADDR_T addr_t;
-
-// Use int_t and uint_t for fast counter variables. The size of these
-// types depends on the architecture but it will always be at least 16 bits.
-// For example, 16-bit numbers are faster on the 68000 but 32-bit numbers are
-// faster on the mcf5200. If you need to assume the size of the variable use
-// u16_t or u32_t instead.
-
-#ifndef _GEN_TYPES_INT_T
-#define _GEN_TYPES_INT_T i32_t
-#endif
-#ifndef _GEN_TYPES_SINT_T
-#define _GEN_TYPES_SINT_T s32_t
-#endif
-#ifndef _GEN_TYPES_UINT_T
-#define _GEN_TYPES_UINT_T u32_t
-#endif
-
-typedef _GEN_TYPES_INT_T int_t;
-typedef _GEN_TYPES_SINT_T sint_t;
-typedef _GEN_TYPES_UINT_T uint_t;
-
-#endif // _GEN_TYPES_H
-
Index: include/hal_arch.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/m68k/arch/current/include/hal_arch.h,v
retrieving revision 1.1
diff -u -p -r1.1 hal_arch.h
--- include/hal_arch.h 29 May 2002 18:28:15 -0000 1.1
+++ include/hal_arch.h 20 Nov 2008 22:20:26 -0000
@@ -8,11 +8,10 @@
// Architecture specific abstractions
//
//=============================================================================
-//####ECOSGPLCOPYRIGHTBEGIN####
-// -------------------------------------------
+//###ECOSGPLCOPYRIGHTBEGIN####
+//-------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-//
+// Copyright (C) 2003,2006,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.
@@ -35,354 +34,436 @@
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//=============================================================================
+//####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Date: 2003-06-04
+//####DESCRIPTIONEND####
+//=============================================================================
+#include <pkgconf/system.h>
#include <pkgconf/hal.h>
-#include <cyg/infra/cyg_type.h>
+#include <pkgconf/hal_m68k.h>
-// Include some variant specific architectural defines.
+#include <cyg/infra/cyg_type.h>
#include <cyg/hal/var_arch.h>
-#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
-#include <cyg/hal/m68k_stub.h>
-#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
-
-#ifndef HAL_NORMAL_SAVED_CONTEXT
-/*****************************************************************************
-HAL_NORMAL_SAVED_CONTEXT -- Saved by a normal context switch
+// ----------------------------------------------------------------------------
+// The default IPL level for when interrupts are enabled. Usually this will
+// be set to 0, but on some platforms it may be appropriate to run with
+// a higher IPL level and effectively leave some interrupts disabled.
- Define a generic structure to save a thread context. Some
-architecture variants will want to redefine this.
-
-*****************************************************************************/
-typedef struct
-{
-
- // Data regs D0-D7
-
- #define HAL_NORMAL_SAVED_NUM_D_REGS 8
- CYG_WORD32 d[HAL_NORMAL_SAVED_NUM_D_REGS];
-
- // Address regs A0-A6
+#ifndef CYGNUM_HAL_INTERRUPT_DEFAULT_IPL_LEVEL
+# define CYGNUM_HAL_INTERRUPT_DEFAULT_IPL_LEVEL 0
+#endif
- #define HAL_NORMAL_SAVED_NUM_A_REGS 7
- CYG_ADDRESS a[HAL_NORMAL_SAVED_NUM_A_REGS];
+// ----------------------------------------------------------------------------
+// setjmp/longjmp support. These only deal with the integer and fpu units.
+// If there are other hardware units then they are unlikely to be used
+// directly by the compiler, only by application code. Hence it is
+// application code that should decide whether or not each unit's state
+// should be preserved across setjmp/longjmp boundaries.
+//
+// Floating point registers have to be saved/restored here even if they
+// are not saved during a context switch, because we are concerned
+// about state within a single thread. The control and status registers
+// are saved as well, but fpiar can be ignored - setjmp() is not going
+// to happen while handling a floating point exception.
+//
+// The default implementation is in assembler and uses weak aliases. That
+// code has to be kept in step with this structure definition.
- // Program Counter
+#ifndef HAL_SETJMP
+#define HAL_SETJMP
+typedef struct {
CYG_ADDRESS pc;
+ CYG_ADDRESS sp;
+ cyg_uint32 d[6]; // d2 to d7, d0 and d1 are caller-save
+ CYG_ADDRESS a[5]; // a2 to a6, a0 and a1 are caller-save, a7 (sp) is separate
+#ifdef CYGINT_HAL_M68K_VARIANT_FPU
+ long double f[6]; // f2 to f7, f0 and f1 are caller-save
+#endif
+} hal_jmp_buf_t;
-} __attribute__ ((aligned, packed)) HAL_SavedRegisters_normal;
-#endif // HAL_NORMAL_SAVED_CONTEXT
-
-#ifndef HAL_GENERIC_SAVED_CONTEXT
-/*****************************************************************************
-HAL_GENERIC_SAVED_CONTEXT -- Generic saved context structure
-
- This is a generic structure that should describe various saved
-processor contexts on this platform.
-
- If the variant HAL does not define this, just define a saved register
-structure with a normal context.
-
-*****************************************************************************/
-#define HAL_GENERIC_SAVED_CONTEXT \
-typedef union \
-{ \
- HAL_SavedRegisters_normal normal; \
-} __attribute__ ((aligned, packed)) HAL_SavedRegisters;
-#endif // HAL_GENERIC_SAVED_CONTEXT
-HAL_GENERIC_SAVED_CONTEXT;
-
-#ifndef HAL_THREAD_SWITCH_CONTEXT
-/*****************************************************************************
-HAL_THREAD_SWITCH_CONTEXT
-
- This macro saves the state of the currently running thread and writes
-its stack pointer to *(_fspptr_).
-
- It then switches to the thread context that *(_tspptr_) points to.
-
-INPUT:
-
- _fspptr_: A pointer to the location to save the current thread's stack
-pointer to.
-
- _tspptr_: A pointer to the location containing the stack pointer of
-the thread context to switch to.
-
-OUTPUT:
-
- *(_fspptr_): Contains the stack pointer of the previous thread's
-context.
-
-*****************************************************************************/
-#define HAL_THREAD_SWITCH_CONTEXT(_fspptr_,_tspptr_) \
-CYG_MACRO_START \
- asm volatile (" pea 1f(%%pc)\n" \
- " lea -(8+7)*4(%%sp),%%sp\n" \
- " movem.l %%d0-%%d7/%%a0-%%a6,(%%sp)\n" \
- " move.l %%sp,%0\n" \
- " move.l %1,%%sp\n" \
- " movem.l (%%sp),%%d0-%%d7/%%a0-%%a6\n" \
- " lea (8+7)*4(%%sp),%%sp\n" \
- " rts\n" \
- "1:\n" \
- : "=g" (*(_fspptr_)) \
- : "g" (*(_tspptr_)) \
- : "memory"); \
-CYG_MACRO_END
-#if HAL_NORMAL_SAVED_NUM_D_REGS != 8
- #error
-#endif
-#if HAL_NORMAL_SAVED_NUM_A_REGS != 7
- #error
-#endif
-#endif // HAL_THREAD_SWITCH_CONTEXT
-
-#ifndef HAL_THREAD_LOAD_CONTEXT
-/*****************************************************************************
-HAL_THREAD_LOAD_CONTEXT
-
- This macro loads the thread context that *(_tspptr_) points to.
-
- This macro does not return.
-
-INPUT:
-
- _tspptr_: A pointer to the location containing the stack pointer of
-the thread context to switch to.
-
-*****************************************************************************/
-#define HAL_THREAD_LOAD_CONTEXT(_tspptr_) \
-CYG_MACRO_START \
- asm volatile (" move.l %0,%%sp\n" \
- " movem.l (%%sp),%%d0-%%d7/%%a0-%%a6\n" \
- " lea (8+7)*4(%%sp),%%sp\n" \
- " rts\n" \
- : \
- : "g" (*(_tspptr_)) \
- : "memory"); \
-CYG_MACRO_END
-#if HAL_NORMAL_SAVED_NUM_D_REGS != 8
- #error
-#endif
-#if HAL_NORMAL_SAVED_NUM_A_REGS != 7
- #error
-#endif
-#endif // HAL_THREAD_LOAD_CONTEXT
-
-#ifndef HAL_THREAD_INIT_CONTEXT
-/*****************************************************************************
-HAL_THREAD_INIT_CONTEXT -- Context Initialization
-
- Initialize the context of a thread.
-
-INPUT:
-
- _sparg_: The name of the variable containing the current sp. This
-will be written with the new sp.
-
- _thread_: The thread object address, passed as argument to entry
-point.
-
- _entry_: The thread's entry point address.
-
- _id_: A bit pattern used in initializing registers, for debugging.
-
-OUTPUT:
-
- _sparg_: Updated with the value of the new sp.
-
-*****************************************************************************/
-#define HAL_THREAD_INIT_CONTEXT(_sparg_, _thread_, _entry_, _id_) \
- CYG_MACRO_START \
- CYG_WORD32 * _sp_ = ((CYG_WORD32*)((CYG_WORD32)(_sparg_) & ~15)); \
- HAL_SavedRegisters_normal * _regs_; \
- int _i_; \
- \
- *(--_sp_) = (CYG_WORD32)(_thread_); /* Thread's parameter. */ \
- *(--_sp_) = (CYG_WORD32)0xDEADC0DE; /* Thread's return addr. */ \
- \
- _regs_ = (HAL_SavedRegisters_normal*) \
- ((CYG_WORD32)_sp_ - sizeof(HAL_SavedRegisters_normal)); \
- \
- for (_i_=0; _i_ < HAL_NORMAL_SAVED_NUM_A_REGS; _i_++) \
- _regs_->a[_i_] = _regs_->d[_i_] = (_id_); \
- _regs_->d[_i_] = (_id_); /* D7 */ \
- /* A6, initial frame pointer should be null */ \
- _regs_->a[HAL_NORMAL_SAVED_NUM_A_REGS-1] = (CYG_ADDRESS)0; \
- /* Thread's starting PC */ \
- _regs_->pc = (CYG_ADDRESS)(_entry_); \
- \
- (_sparg_) = (CYG_ADDRESS)_regs_; \
- CYG_MACRO_END
-#endif // HAL_THREAD_INIT_CONTEXT
-
-//-----------------------------------------------------------------------------
-// Bit manipulation routines
-
-externC cyg_uint32 hal_lsbit_index(cyg_uint32 mask);
-externC cyg_uint32 hal_msbit_index(cyg_uint32 mask);
-
-#define HAL_LSBIT_INDEX(index, mask) (index) = hal_lsbit_index(mask);
+// This type is used by normal routines to pass the address of the
+// structure into our routines without having to explicitly take the
+// address of the structure.
+typedef cyg_uint32 hal_jmp_buf[sizeof(hal_jmp_buf_t) / sizeof(cyg_uint32)];
-#define HAL_MSBIT_INDEX(index, mask) (index) = hal_msbit_index(mask);
+externC int hal_m68k_setjmp(hal_jmp_buf);
+externC void hal_m68k_longjmp(hal_jmp_buf, int);
+#define hal_setjmp(_env) hal_m68k_setjmp(_env)
+#define hal_longjmp(_env, _val) hal_m68k_longjmp(_env, _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.
+#endif // HAL_SETJMP
-externC void hal_idle_thread_action(cyg_uint32 loop_count);
+// ----------------------------------------------------------------------------
+// Thread context support. The implementation is in assembler functions
+// rather than inline macros. That makes it easier to cope with
+// hardware-specific units which have their own context.
+//
+// A thread context consists of an integer part, a floating point part
+// (iff the hardware has a standard FPU and if the configuration makes
+// FPU context part of the save state), and OTHER for extra hardware
+// units.
+
+#define HAL_M68K_SR_C (0x01 << 0)
+#define HAL_M68K_SR_V (0x01 << 1)
+#define HAL_M68K_SR_Z (0x01 << 2)
+#define HAL_M68K_SR_N (0x01 << 3)
+#define HAL_M68K_SR_X (0x01 << 4)
+#define HAL_M68K_SR_S (0x01 << 13)
+#define HAL_M68K_SR_T (0x01 << 15)
+#define HAL_M68K_SR_IPL_MASK (0x07 << 8)
+#define HAL_M68K_SR_IPL_SHIFT 8
-#define HAL_IDLE_THREAD_ACTION(_count_) hal_idle_thread_action(_count_)
+typedef struct {
+ // The integer context, d0-d7,a0-a6
+ cyg_uint32 da[15];
-//-----------------------------------------------------------------------------
-// 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.
+ // FPU context. This is only relevant if the hardware has an FPU,
+ // and then only if the configuration makes the FPU context part
+ // of the save state.
+#ifdef CYGIMP_HAL_M68K_FPU_SAVE
+ cyg_uint32 fpsr;
+ CYG_ADDRESS fpiar;
+ long double f[8];
+#endif
-#define HAL_REORDER_BARRIER() asm volatile ( "" : : : "memory" )
+ // Some m68k variants may have additional state that should be part
+ // of a thread context.
+#ifdef HAL_CONTEXT_OTHER
+ HAL_CONTEXT_OTHER
+#endif
-//-----------------------------------------------------------------------------
-// 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.
+ // Program counter, status register, etc. The exact layout is
+ // determined by the variant. The intention is that the structure
+ // matches the state pushed onto the stack by the hardware when an
+ // interrupt occurs, so the context can overlap this part of the
+ // stack. That avoids having to copy the saved PC and SR registers
+ // from the stack into the context structure. The final step of
+ // a context switch is an rte instruction.
+ HAL_CONTEXT_PCSR
+
+} HAL_SavedRegisters;
+
+#define HAL_CONTEXT_INTEGER_SIZE (15 * 4)
+#ifdef CYGIMP_HAL_M68K_FPU_SAVE
+# define HAL_CONTEXT_FPU_SIZE ((2 * 4) + (8 * 12))
+#else
+# define HAL_CONTEXT_FPU_SIZE 0
+#endif
+#ifndef HAL_CONTEXT_OTHER_SIZE
+# define HAL_CONTEXT_OTHER_SIZE 0
+#endif
+#ifndef HAL_CONTEXT_PCSR_SIZE
+# define HAL_CONTEXT_PCSR_SIZE 8
+#endif
-#define HAL_BREAKPOINT(_label_) \
-asm volatile (" .globl " #_label_ ";" \
- #_label_":" \
- " trap #1" \
- );
+#define HAL_CONTEXT_FULL_SIZE (HAL_CONTEXT_INTEGER_SIZE + HAL_CONTEXT_FPU_SIZE + HAL_CONTEXT_OTHER_SIZE + HAL_CONTEXT_PCSR_SIZE)
-#define HAL_BREAKINST 0x4E41
+// Load and switch are handled by functions in hal_arch.S. One level
+// of indirection is removed here for the destination thread, so that
+// the actual stack pointer gets passed to assembler.
+externC void hal_thread_load_context(CYG_ADDRESS) CYGBLD_ATTRIB_NORET;
+externC void hal_thread_switch_context(CYG_ADDRESS, CYG_ADDRESS);
+
+#define HAL_THREAD_LOAD_CONTEXT(_to_) \
+ CYG_MACRO_START \
+ hal_thread_load_context((CYG_ADDRESS) *(_to_)); \
+ CYG_MACRO_END
-#define HAL_BREAKINST_SIZE 2
+#define HAL_THREAD_SWITCH_CONTEXT(_from_, _to_) \
+ CYG_MACRO_START \
+ hal_thread_switch_context((CYG_ADDRESS)(_from_), (CYG_ADDRESS)*(_to_)); \
+ CYG_MACRO_END
-#if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \
- defined(CYGPKG_HAL_EXCEPTIONS)
+// Init context can be done easily in C.
+//
+// LOAD_CONTEXT and SWITCH_CONTEXT will end up doing an rte, so at the top
+// of the stack we want the SR, return PC, a dummy PC for the entry point's
+// stack frame, and the argument to the function.
+//
+// +----------------+
+// | _thread_ arg |
+// +----------------+
+// | return PC |
+// +----------------+
+// | _entry_ PC |
+// +- - - - - - - - +
+// | SR |
+// SP ----> +- - - - - - - - +
+// | HAL |
+// | SavedRegisters |
+// | |
+//
+// FPU and OTHER contexts are handled by macros which may or may not expand.
+//
+// The PC/SR fields are handled by variant-specific code.
-//-----------------------------------------------------------------------------
-// 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.
+#ifdef CYGIMP_HAL_M68K_FPU_SAVE
+# define HAL_CONTEXT_FPU_INIT(_regs_) \
+ CYG_MACRO_START \
+ int _j_; \
+ (_regs_)->fpsr = 0; \
+ (_regs_)->fpiar = 0; \
+ for (_j_ = 0; _j_ < 8; _j_++) { \
+ (_regs_)->f[_j_] = 0.0; \
+ } \
+ CYG_MACRO_END
+#else
+# define HAL_CONTEXT_FPU_INIT(_regs_)
+#endif
+#ifndef HAL_CONTEXT_OTHER_INIT
+# define HAL_CONTEXT_OTHER_INIT(_regs_)
+#endif
-externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data );
+// Only initialize with ints enabled if CYGPKG_KERNEL. RedBoot does a
+// LoadContext, causing interrupts to be enabled prematurely.
+#ifdef CYGPKG_KERNEL
+# define _HAL_M68K_INIT_CONTEXT_SR_ (0x2000 | (CYGNUM_HAL_INTERRUPT_DEFAULT_IPL_LEVEL<<8))
+#else
+# define _HAL_M68K_INIT_CONTEXT_SR_ (0x2700)
+#endif
-#endif /* defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) */
+#define HAL_THREAD_INIT_CONTEXT( _sparg_, _thread_, _entry_, _id_) \
+ CYG_MACRO_START \
+ cyg_uint32* _sp_ = ((cyg_uint32*) ((cyg_uint32)(_sparg_) & ~(CYGARC_ALIGNMENT - 1))); \
+ HAL_SavedRegisters* _regs_; \
+ int _i_; \
+ *(--_sp_) = (cyg_uint32)(_thread_); \
+ *(--_sp_) = 0xDEADC0DE; \
+ _regs_ = (HAL_SavedRegisters*) ((cyg_uint32)_sp_ - sizeof(HAL_SavedRegisters)); \
+ for (_i_ = 0; _i_ < 14; _i_++) { \
+ _regs_->da[_i_] = _id_; \
+ } \
+ _regs_->da[14] = 0; \
+ HAL_CONTEXT_FPU_INIT(_regs_) \
+ HAL_CONTEXT_OTHER_INIT(_regs_) \
+ HAL_CONTEXT_PCSR_INIT(_regs_, _entry_, _HAL_M68K_INIT_CONTEXT_SR_); \
+ (_sparg_) = (CYG_ADDRESS) (_regs_); \
+ CYG_MACRO_END
-//-----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
// 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.
-// Stack frame overhead per call. 6 data registers, 5 address registers,
-// frame pointer, and return address. We can't guess the local variables so
-// just assume that using all of the registers averages out.
-
-#define CYGNUM_HAL_STACK_FRAME_SIZE ((6 + 5 + 1 + 1) * 4)
-
-// Stack needed for a context switch.
-// All registers + pc + sr + vector
+// Stack frame overhead per call. 6 data registers, 5 address
+// registers, frame pointer, and return address. We can't guess the
+// local variables so just assume that using all of the registers
+// averages out.
+# define CYGNUM_HAL_STACK_FRAME_SIZE ((6 + 5 + 1 + 1) * 4)
+// Stack needed for a context switch. Allow for sr and vector as well.
#ifndef CYGNUM_HAL_STACK_CONTEXT_SIZE
-#define CYGNUM_HAL_STACK_CONTEXT_SIZE ((8+8+1+1+1)*4)
-#endif // CYGNUM_HAL_STACK_CONTEXT_SIZE
+# define CYGNUM_HAL_STACK_CONTEXT_SIZE HAL_CONTEXT_FULL_SIZE
+#endif
-// Interrupt + call to ISR, interrupt_end() and the DSR
+// Interrupt handling. These need to allow for nesting and a
+// separate interrupt stack.
+#ifndef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+# ifndef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
+
+// No interrupt stack, no nesting. Worst case: a saved context, a
+// frame for the interrupt_end() call, six frames for DSR processing,
+// another saved context for an interrupt during the DSRs, and
+// six frames for the ISR.
+# define CYGNUM_HAL_STACK_INTERRUPT_SIZE ((2 * CYGNUM_HAL_STACK_CONTEXT_SIZE) + (13 * CYGNUM_HAL_STACK_FRAME_SIZE))
+
+# else
+// No interrupt stack but nesting. Worst case: a saved context,
+// a frame for interrupt_end(), six frames for DSR processing, then
+// up to five higher priority interrupts each requiring a context
+// and six frames.
+# define CYGNUM_HAL_STACK_INTERRUPT_SIZE ((6 * CYGNUM_HAL_STACK_CONTEXT_SIZE) + (37 * CYGNUM_HAL_STACK_FRAME_SIZE))
+# endif
+
+#else
+
+# ifndef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
+// An interrupt stack but no nesting. Worst case: a saved context,
+// a frame for interrupt_end(), and another saved context. There
+// is no need to worry about ISR or DSR frames since those will
+// be on the interrupt stack. We also need to allow for nested
+// interrupts before these are disabled, which will involve only
+// 2 words rather than a full stack.
+# define CYGNUM_HAL_STACK_INTERRUPT_SIZE ((2 * CYGNUM_HAL_STACK_CONTEXT_SIZE) + (1 * CYGNUM_HAL_STACK_FRAME_SIZE) + (5 * 2 * 4))
+
+# else
+// An interrupt stack and nesting. We need to allow for another five
+// nested contexts because nested interrupts may happen after pushing
+// the current context but before switching to the interrupt stack.
+# define CYGNUM_HAL_STACK_INTERRUPT_SIZE ((7 * CYGNUM_HAL_STACK_CONTEXT_SIZE) + (1 * CYGNUM_HAL_STACK_FRAME_SIZE))
-#define CYGNUM_HAL_STACK_INTERRUPT_SIZE \
- ((CYGNUM_HAL_STACK_CONTEXT_SIZE) + (8*CYGNUM_HAL_STACK_FRAME_SIZE))
+# endif
+#endif
// We define a minimum stack size as the minimum any thread could ever
-// legitimately get away with. We can throw asserts if users ask for less
-// than this. Allow enough for four interrupt sources - clock, serial,
-// nic, and one other
-
-// No separate interrupt stack exists. Make sure all threads contain
-// a stack sufficiently large
-
-#define CYGNUM_HAL_STACK_SIZE_MINIMUM \
- ((4*CYGNUM_HAL_STACK_INTERRUPT_SIZE) \
- + (16*CYGNUM_HAL_STACK_FRAME_SIZE))
-
-// Now make a reasonable choice for a typical thread size. Pluck figures
-// from thin air and say 30 call frames with an average of 16 words of
-// automatic variables per call frame
-
-#define CYGNUM_HAL_STACK_SIZE_TYPICAL \
- (CYGNUM_HAL_STACK_SIZE_MINIMUM + \
- (30 * (CYGNUM_HAL_STACK_FRAME_SIZE+(16*4))))
+// legitimately get away with. We can throw asserts if users ask for
+// less than this. This allows for a saved context for context switching
+// plus eight stack frames for cals, in addition to the interrupt overhead.
+#define CYGNUM_HAL_STACK_SIZE_MINIMUM (CYGNUM_HAL_STACK_INTERRUPT_SIZE + CYGNUM_HAL_STACK_CONTEXT_SIZE + (8 * CYGNUM_HAL_STACK_FRAME_SIZE))
+
+// Now make a reasonable choice for a typical thread size. Allow for
+// another 8 call frames and a K for on-stack buffers, printf(),
+// and debugging overheads.
+#define CYGNUM_HAL_STACK_SIZE_TYPICAL (CYGNUM_HAL_STACK_SIZE_MINIMUM + (8 * CYGNUM_HAL_STACK_FRAME_SIZE) + 1024)
+
+// -----------------------------------------------------------------------------
+// Bit manipulation routines. The vanilla 68000 has no special
+// instructions for this so assembler implementations are used
+// instead. Newer ColdFires do have suitable instructions so will
+// define their own versions of these macro.
+
+#ifndef HAL_LSBIT_INDEX
+externC cyg_uint32 hal_lsbit_index(cyg_uint32 mask);
+#define HAL_LSBIT_INDEX(index, mask) (index) = hal_lsbit_index(mask);
+#endif
+#ifndef HAL_MSBIT_INDEX
+externC cyg_uint32 hal_msbit_index(cyg_uint32 mask);
+#define HAL_MSBIT_INDEX(index, mask) (index) = hal_msbit_index(mask);
+#endif
+
+// There are some useful bit-set and bit-clear instructions which allow
+// for atomic updates of a single byte of memory.
+#define HAL_M68K_BSET(_address_, _bit_) \
+ CYG_MACRO_START \
+ asm volatile("bset %0,(%1)\n" : : "i" (_bit_), "a" (_address_) : "cc", "memory"); \
+ CYG_MACRO_END
+
+#define HAL_M68K_BCLR(_address_, _bit_) \
+ CYG_MACRO_START \
+ asm volatile("bclr %0,(%1)\n" : : "i" (_bit_), "a" (_address_) : "cc", "memory"); \
+ CYG_MACRO_END
+
+//-----------------------------------------------------------------------------
+// Idle thread code. A plain 68000 has no special support, so a no-op
+// function is used. Variants may use this to go into sleep mode.
+
+#ifndef HAL_IDLE_THREAD_ACTION
+# define HAL_IDLE_THREAD_ACTION(_count_) CYG_EMPTY_STATEMENT
+#endif
+
+//-----------------------------------------------------------------------------
+// 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" )
//--------------------------------------------------------------------------
// Macros for switching context between two eCos instances (jump from
-// code in ROM to code in RAM or vice versa).
+// code in ROM to code in RAM or vice versa). The 68000 does not have any
+// relevant global state so these macros are no-ops.
+
#define CYGARC_HAL_SAVE_GP()
#define CYGARC_HAL_RESTORE_GP()
-#ifndef HAL_SETJMP
-#define HAL_SETJMP
-/*****************************************************************************
-hal_setjmp/hal_longjmp
+//-----------------------------------------------------------------------------
+// gdb support
- We do the best we can to define generic setjmp and longjmp routines
-for the m68k architecture. Some architectures will need to override this.
+// Translate a stack pointer as saved by the thread context macros
+// into a pointer to a HAL_SavedRegisters structure. On the 68K
+// these are equivalent.
+#define HAL_THREAD_GET_SAVED_REGISTERS(_stack_, _regs_) \
+ CYG_MACRO_START \
+ (_regs_) = (HAL_SavedRegisters*)(_stack_); \
+ CYG_MACRO_END
-*****************************************************************************/
+// Translate between an eCos context and a gdb register set.
+externC void hal_get_gdb_registers(CYG_ADDRWORD*, HAL_SavedRegisters*);
+externC void hal_set_gdb_registers(HAL_SavedRegisters*, CYG_ADDRWORD*);
+
+#define HAL_GET_GDB_REGISTERS(_regval_, _regs_) \
+ CYG_MACRO_START \
+ hal_get_gdb_registers((CYG_ADDRWORD*)(_regval_), (HAL_SavedRegisters*)(_regs_)); \
+ CYG_MACRO_END
-// We must save all of the registers that are preserved across routine
-// calls. The assembly code assumes that this structure is defined in the
-// following format. Any changes to this structure will result in changes to
-// the assembly code!!
+#define HAL_SET_GDB_REGISTERS(_regs_,_regval_) \
+ CYG_MACRO_START \
+ hal_set_gdb_registers((HAL_SavedRegisters*)(_regs_), (CYG_ADDRWORD*)(_regval_)); \
+ CYG_MACRO_END
-typedef struct {
- cyg_uint32 d2;
- cyg_uint32 d3;
- cyg_uint32 d4;
- cyg_uint32 d5;
- cyg_uint32 d6;
- cyg_uint32 d7;
- cyg_uint32 a2;
- cyg_uint32 a3;
- cyg_uint32 a4;
- cyg_uint32 a5;
- cyg_uint32 a6;
- cyg_uint32 sp;
- cyg_uint32 pc;
-} hal_jmp_buf_t;
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
-// This type is used by normal routines to pass the address of the
-// structure into our routines without having to explicitly take the address
-// of the structure.
+// 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.
-typedef cyg_uint32 hal_jmp_buf[sizeof(hal_jmp_buf_t) / sizeof(cyg_uint32)];
+#define HAL_BREAKPOINT(_label_) \
+__asm__ volatile (" .globl " #_label_ ";" \
+ #_label_":" \
+ " trap #15" \
+ );
-// Define the generic setjmp and longjmp routines.
+#define HAL_BREAKINST 0x4E4F
-externC int hal_m68k_setjmp(hal_jmp_buf env);
-externC void hal_m68k_longjmp(hal_jmp_buf env, int val);
-#define hal_setjmp(_env) hal_m68k_setjmp(_env)
-#define hal_longjmp(_env, _val) hal_m68k_longjmp(_env, _val)
-#endif // HAL_SETJMP
+#define HAL_BREAKINST_SIZE 2
+
+// The GDB register definitions. as per gdb/m68k-stub.c
+// FIXME: more work is needed for floating point support.
+enum regnames {
+ D0, D1, D2, D3, D4, D5, D6, D7,
+ A0, A1, A2, A3, A4, A5, FP, SP,
+ PS, PC,
+#ifdef CYGINT_HAL_M68K_VARIANT_FPU
+ FP0, FP1, FP2, FP3, FP4, FP5, FP6, FP7,
+ FPCONTROL, FPSTATUS, FPIADDR
+#endif
+};
+
+#ifdef CYGINT_HAL_M68K_VARIANT_FPU
+# define NUMREGS 29
+#else
+# define NUMREGS 18
+#endif
+
+#define REGSIZE(_x_) (4)
+
+typedef enum regnames regnames_t;
+typedef CYG_ADDRWORD target_register_t;
+
+externC int __computeSignal(unsigned int trap_number);
+externC int __get_trap_number(void);
+externC void __install_breakpoints(void);
+externC void __clear_breakpoints(void);
+externC void __single_step(void);
+externC void __clear_single_step(void);
+externC void __skipinst(void);
+externC int __is_breakpoint_function(void);
+externC void set_pc(target_register_t);
+
+#define HAL_STUB_PLATFORM_STUBS_FIXUP() \
+ CYG_MACRO_START \
+ if (CYGNUM_HAL_VECTOR_TRAP15 == __get_trap_number()) \
+ put_register(PC, get_register(PC) - 2); \
+ CYG_MACRO_END
+
+#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+//-----------------------------------------------------------------------------
+// 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.
+#if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && defined(CYGPKG_HAL_EXCEPTIONS)
+externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data );
+#endif
//-----------------------------------------------------------------------------
#endif // CYGONCE_HAL_ARCH_H
Index: include/hal_cache.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/m68k/arch/current/include/hal_cache.h,v
retrieving revision 1.1
diff -u -p -r1.1 hal_cache.h
--- include/hal_cache.h 29 May 2002 18:28:15 -0000 1.1
+++ include/hal_cache.h 20 Nov 2008 22:20:26 -0000
@@ -8,11 +8,10 @@
// HAL cache control API
//
//=============================================================================
-//####ECOSGPLCOPYRIGHTBEGIN####
-// -------------------------------------------
+//###ECOSGPLCOPYRIGHTBEGIN####
+//-------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-//
+// Copyright (C) 2003,2006,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.
@@ -35,17 +34,66 @@
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//=============================================================================
+//####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Date: 2003-06-04
+//####DESCRIPTIONEND####
+//=============================================================================
#include <pkgconf/hal.h>
+#include <pkgconf/hal_m68k.h>
+#ifndef __ASSEMBLER__
#include <cyg/infra/cyg_type.h>
+#endif
+
+#ifdef CYGINT_HAL_M68K_VARIANT_CACHE
+# include <cyg/hal/var_cache.h>
+#endif
+
+// Default anything not defined by the variant HAL. Some of these
+// macros get used unconditionally by other code so must be
+// defined, to no-op.
+#ifndef HAL_ICACHE_ENABLE
+# define HAL_ICACHE_ENABLE()
+#endif
+#ifndef HAL_ICACHE_DISABLE
+# define HAL_ICACHE_DISABLE()
+#endif
+#ifndef HAL_ICACHE_SYNC
+# define HAL_ICACHE_SYNC()
+#endif
+#ifndef HAL_ICACHE_INVALIDATE_ALL
+# define HAL_ICACHE_INVALIDATE_ALL()
+#endif
+#ifndef HAL_ICACHE_IS_ENABLED
+# define HAL_ICACHE_IS_ENABLED(_state_) \
+ CYG_MACRO_START \
+ (_state_) = 0; \
+ CYG_MACRO_END
+#endif
-#include <cyg/hal/var_cache.h>
+#ifndef HAL_DCACHE_ENABLE
+# define HAL_DCACHE_ENABLE()
+#endif
+#ifndef HAL_DCACHE_DISABLE
+# define HAL_DCACHE_DISABLE()
+#endif
+#ifndef HAL_DCACHE_SYNC
+# define HAL_DCACHE_SYNC()
+#endif
+#ifndef HAL_DCACHE_INVALIDATE_ALL
+# define HAL_DCACHE_INVALIDATE_ALL()
+#endif
+#ifndef HAL_DCACHE_IS_ENABLED
+# define HAL_DCACHE_IS_ENABLED(_state_) \
+ CYG_MACRO_START \
+ (_state_) = 0; \
+ CYG_MACRO_END
+#endif
//-----------------------------------------------------------------------------
#endif // ifndef CYGONCE_HAL_CACHE_H
Index: include/hal_diag.h
===================================================================
RCS file: include/hal_diag.h
diff -N include/hal_diag.h
--- include/hal_diag.h 7 Jun 2005 18:42:55 -0000 1.2
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,89 +0,0 @@
-#ifndef CYGONCE_HAL_HAL_DIAG_H
-#define CYGONCE_HAL_HAL_DIAG_H
-
-//=============================================================================
-//
-// hal_diag.h
-//
-// HAL Support for Kernel Diagnostic Routines
-//
-//=============================================================================
-//####UNSUPPORTEDBEGIN####
-//
-// -------------------------------------------
-// This source file has been contributed to eCos/Red Hat. It may have been
-// changed slightly to provide an interface consistent with those of other
-// files.
-//
-// The functionality and contents of this file is supplied "AS IS"
-// without any form of support and will not necessarily be kept up
-// to date by Red Hat.
-//
-// All inquiries about this file, or the functionality provided by it,
-// should be directed to the 'ecos-discuss' mailing list (see
-// http://ecos.sourceware.org/ecos/intouch.html for details).
-//
-// Maintained by: <Unmaintained>
-// -------------------------------------------
-//
-//####UNSUPPORTEDEND####
-//=============================================================================
-//####ECOSGPLCOPYRIGHTBEGIN####
-// -------------------------------------------
-// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-//
-// eCos is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 2 or (at your option) any later version.
-//
-// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with eCos; if not, write to the Free Software Foundation, Inc.,
-// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-//
-// As a special exception, if other files instantiate templates or use macros
-// or inline functions from this file, or you compile this file and link it
-// with other works to produce a work based on this file, this file does not
-// by itself cause the resulting work to be covered by the GNU General Public
-// License. However the source code for this file must still be made available
-// in accordance with section (3) of the GNU General Public License.
-//
-// This exception does not invalidate any other reasons why a work based on
-// this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
-// -------------------------------------------
-//####ECOSGPLCOPYRIGHTEND####
-//=============================================================================
-
-#include <pkgconf/hal.h>
-
-#include <cyg/infra/cyg_type.h>
-
-//-----------------------------------------------------------------------------
-// functions implemented in hal_diag.c
-
-externC void hal_diag_init(void);
-
-externC void hal_diag_write_char(cyg_int8 c);
-
-externC cyg_int8 hal_diag_read_char(void);
-
-//-----------------------------------------------------------------------------
-
-#define HAL_DIAG_INIT() hal_diag_init()
-
-#define HAL_DIAG_WRITE_CHAR(_c_) hal_diag_write_char(_c_)
-
-#define HAL_DIAG_READ_CHAR(_c_) ((_c_) = hal_diag_read_char())
-
-//-----------------------------------------------------------------------------
-// end of hal_diag.h
-#endif // CYGONCE_HAL_HAL_DIAG_H
-
Index: include/hal_intr.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/m68k/arch/current/include/hal_intr.h,v
retrieving revision 1.1
diff -u -p -r1.1 hal_intr.h
--- include/hal_intr.h 29 May 2002 18:28:15 -0000 1.1
+++ include/hal_intr.h 20 Nov 2008 22:20:27 -0000
@@ -8,11 +8,10 @@
// m68k Interrupt and clock support
//
//==========================================================================
-//####ECOSGPLCOPYRIGHTBEGIN####
-// -------------------------------------------
+//###ECOSGPLCOPYRIGHTBEGIN####
+//-------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-//
+// Copyright (C) 2003,2006,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.
@@ -35,22 +34,48 @@
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
+//####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Date: 2003-06-04
+//####DESCRIPTIONEND####
+//=============================================================================
#include <pkgconf/hal.h>
#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
#include <cyg/hal/hal_arch.h>
+// Allow variants to override some of these settings.
#include <cyg/hal/var_intr.h>
//--------------------------------------------------------------------------
// m68k exception vectors. These correspond to VSRs and are the values
// to use for HAL_VSR_GET/SET
+
+extern CYG_ADDRESS hal_m68k_vsr_table[];
+
+#ifndef HAL_VSR_GET
+# define HAL_VSR_GET( _vector_, _pvsr_ ) \
+ CYG_MACRO_START \
+ *((CYG_ADDRESS *)(_pvsr_)) = hal_m68k_vsr_table[(_vector_)]; \
+ CYG_MACRO_END
+#endif
+
+#if !defined(HAL_VSR_SET) && !defined(_HAL_M68K_NO_VSR_SET_)
+# define HAL_VSR_SET( _vector_arg_, _vsr_, _poldvsr_arg_ ) \
+ CYG_MACRO_START \
+ cyg_uint32 _vector_ = (cyg_uint32) (_vector_arg_); \
+ CYG_ADDRESS* _poldvsr_ = (CYG_ADDRESS*)(_poldvsr_arg_); \
+ if(_poldvsr_ != (CYG_ADDRESS*)0 ) \
+ *_poldvsr_ = hal_m68k_vsr_table[(_vector_)]; \
+ hal_m68k_vsr_table[(_vector_)] = (CYG_ADDRESS)(_vsr_); \
+ CYG_MACRO_END
+#endif
+
#define CYGNUM_HAL_VECTOR_SSP 0
#define CYGNUM_HAL_VECTOR_RESET 1
#define CYGNUM_HAL_VECTOR_BUSERR 2
@@ -62,8 +87,10 @@
#define CYGNUM_HAL_VECTOR_PRIVVIOLATION 8
#define CYGNUM_HAL_VECTOR_TRACE 9
#define CYGNUM_HAL_VECTOR_L1010 10
+// 12-14 are reserved
#define CYGNUM_HAL_VECTOR_L1111 11
#define CYGNUM_HAL_VECTOR_UNINITINT 15
+// 16-23 are reserved
#define CYGNUM_HAL_VECTOR_SPURINT 24
#define CYGNUM_HAL_VECTOR_AUTOVEC1 25
#define CYGNUM_HAL_VECTOR_AUTOVEC2 26
@@ -73,9 +100,27 @@
#define CYGNUM_HAL_VECTOR_AUTOVEC6 30
#define CYGNUM_HAL_VECTOR_AUTOVEC7 31
#define CYGNUM_HAL_VECTOR_NMI CYGNUM_HAL_VECTOR_AUTOVEC7
+#define CYGNUM_HAL_VECTOR_TRAP0 32
#define CYGNUM_HAL_VECTOR_TRAPFIRST 32
+#define CYGNUM_HAL_VECTOR_TRAP1 33
+#define CYGNUM_HAL_VECTOR_TRAP2 34
+#define CYGNUM_HAL_VECTOR_TRAP3 35
+#define CYGNUM_HAL_VECTOR_TRAP4 36
+#define CYGNUM_HAL_VECTOR_TRAP5 37
+#define CYGNUM_HAL_VECTOR_TRAP6 38
+#define CYGNUM_HAL_VECTOR_TRAP7 39
+#define CYGNUM_HAL_VECTOR_TRAP8 40
+#define CYGNUM_HAL_VECTOR_TRAP9 41
+#define CYGNUM_HAL_VECTOR_TRAP10 42
+#define CYGNUM_HAL_VECTOR_TRAP11 43
+#define CYGNUM_HAL_VECTOR_TRAP12 44
+#define CYGNUM_HAL_VECTOR_TRAP13 45
+#define CYGNUM_HAL_VECTOR_TRAP14 46
+/* TRAP15 is used by gdb stubs */
+#define CYGNUM_HAL_VECTOR_TRAP15 47
+#define CYGNUM_HAL_VECTOR_TRAPLAST CYGNUM_HAL_VECTOR_TRAP15
#define CYGNUM_HAL_VECTOR_NUMTRAPS 16
-#define CYGNUM_HAL_VECTOR_TRAPLAST (CYGNUM_HAL_VECTOR_TRAPFIRST+CYGNUM_HAL_VECTOR_NUMTRAPS-1)
+// 48-63 are reserved
#define CYGNUM_HAL_VECTOR_INTRFIRST 64
#define CYGNUM_HAL_VECTOR_NUMINTRS 192
#define CYGNUM_HAL_VECTOR_INTRLAST (CYGNUM_HAL_VECTOR_INTRFIRST+CYGNUM_HAL_VECTOR_NUMINTRS-1)
@@ -84,176 +129,218 @@
#define CYGNUM_HAL_VSR_MAX CYGNUM_HAL_VECTOR_INTRLAST
#define CYGNUM_HAL_VSR_COUNT (CYGNUM_HAL_VSR_MAX+1)
-//--------------------------------------------------------------------------
-// Interrupt vectors.
-
-#ifndef CYGNUM_HAL_ISR_MAX
-#define CYGNUM_HAL_ISR_MIN 0
-#define CYGNUM_HAL_ISR_MAX 255
-#define CYGNUM_HAL_ISR_COUNT (7+CYGNUM_HAL_VECTOR_NUMINTRS)
-#endif /* CYGNUM_HAL_ISR_MAX */
+// ----------------------------------------------------------------------------
+// Also give details of the defined exceptions. Only some of the exceptions
+// are named explicitly here.
+// NOTE: FPU exceptions should be added
+
+#define CYGNUM_HAL_EXCEPTION_DATA_ACCESS CYGNUM_HAL_VECTOR_BUSERR
+#define CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS CYGNUM_HAL_VECTOR_ADDERR
+#define CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION CYGNUM_HAL_VECTOR_ILLINST
+#define CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO CYGNUM_HAL_VECTOR_ZERODIV
+#define CYGNUM_HAL_EXCEPTION_SYSTEM_ERROR CYGNUM_HAL_VECTOR_CHKINST
+#define CYGNUM_HAL_EXCEPTION_TRACE CYGNUM_HAL_VECTOR_TRACE
+#define CYGNUM_HAL_EXCEPTION_INSTRUCTION_BP CYGNUM_HAL_VECTOR_TRAP15
#ifndef CYGNUM_HAL_EXCEPTION_COUNT
-#define CYGNUM_HAL_EXCEPTION_MIN CYGNUM_HAL_VECTOR_BUSERR
-#define CYGNUM_HAL_EXCEPTION_MAX CYGNUM_HAL_VECTOR_SPURINT
-#define CYGNUM_HAL_EXCEPTION_COUNT ((CYGNUM_HAL_EXCEPTION_MAX-CYGNUM_HAL_EXCEPTION_MIN)+1)
-#endif /* CYGNUM_HAL_EXCEPTION_COUNT */
+# define CYGNUM_HAL_EXCEPTION_MIN CYGNUM_HAL_VECTOR_BUSERR
+# define CYGNUM_HAL_EXCEPTION_MAX CYGNUM_HAL_VECTOR_TRAPLAST
+# define CYGNUM_HAL_EXCEPTION_COUNT ((CYGNUM_HAL_EXCEPTION_MAX-CYGNUM_HAL_EXCEPTION_MIN)+1)
+#endif
//--------------------------------------------------------------------------
-// Static data used by HAL
-
-// ISR tables
-externC volatile CYG_ADDRESS cyg_hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
-externC volatile CYG_ADDRWORD cyg_hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
-externC volatile CYG_ADDRESS cyg_hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];
-
-// VSR table
-externC volatile CYG_ADDRESS cyg_hal_vsr_table[CYGNUM_HAL_VSR_COUNT];
+// ISR vectors.
-//---------------------------------------------------------------------------
-// Translate a vector number into an ISR table index.
-
-#define HAL_TRANSLATE_VECTOR(_vector_,_index_) \
- CYG_MACRO_START \
- switch ((_vector_)) \
- { \
- case CYGNUM_HAL_VECTOR_AUTOVEC1 ... CYGNUM_HAL_VECTOR_AUTOVEC7: \
- (_index_) = ((_vector_) - CYGNUM_HAL_VECTOR_AUTOVEC1); \
- break; \
- case CYGNUM_HAL_VECTOR_INTRFIRST ... CYGNUM_HAL_VECTOR_INTRLAST: \
- (_index_) = ((_vector_) \
- - CYGNUM_HAL_VECTOR_INTRFIRST \
- + (CYGNUM_HAL_VECTOR_AUTOVEC7 \
- - CYGNUM_HAL_VECTOR_AUTOVEC1 \
- + 1)); \
- break; \
- default: \
- CYG_FAIL("Unknown Interrupt!!!"); \
- (_index_) = (typeof(_index_))-1; \
- } \
+#ifndef CYGNUM_HAL_ISR_COUNT
+# error The variant or platform HAL should provide details of ISR vectors.
+#endif
+
+// Default definition of HAL_TRANSLATE_VECTOR()
+#ifndef HAL_TRANSLATE_VECTOR
+# define HAL_TRANSLATE_VECTOR(_vector_, _index_) \
+ ((_index_) = ((_vector_) - CYGNUM_HAL_ISR_MIN))
+#endif
+
+externC volatile CYG_ADDRESS cyg_hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
+externC volatile CYG_ADDRWORD cyg_hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
+externC volatile CYG_ADDRESS cyg_hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];
+externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
+// For consistency with other architectures.
+#define hal_interrupt_handlers cyg_hal_interrupt_handlers
+
+#ifndef HAL_INTERRUPT_IN_USE
+# define HAL_INTERRUPT_IN_USE( _vector_, _state_) \
+ CYG_MACRO_START \
+ if (cyg_hal_interrupt_handlers[(_vector_)] ==(CYG_ADDRESS)&hal_default_isr) \
+ (_state_) = 0; \
+ else \
+ (_state_) = 1; \
CYG_MACRO_END
+#endif
-//--------------------------------------------------------------------------
-// Interrupt state storage
-
-typedef cyg_uint16 CYG_INTERRUPT_STATE;
-
-//---------------------------------------------------------------------------
-// Interrupt and VSR attachment macros
-
-externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
-externC void hal_default_exception_handler(CYG_WORD vector,
- HAL_SavedRegisters *regs);
-
-#define HAL_INTERRUPT_IN_USE( _vector_, _state_) \
- CYG_MACRO_START \
- cyg_uint32 _index_; \
- HAL_TRANSLATE_VECTOR ((_vector_), _index_); \
- \
- if (cyg_hal_interrupt_handlers[_index_] \
- ==(CYG_ADDRESS)&hal_default_isr) \
- (_state_) = 0; \
- else \
- (_state_) = 1; \
+#ifndef HAL_INTERRUPT_ATTACH
+# define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ ) \
+ CYG_MACRO_START \
+ cyg_hal_interrupt_handlers[(_vector_)] = (CYG_ADDRESS)(_isr_); \
+ cyg_hal_interrupt_data[(_vector_)] = (CYG_ADDRWORD)(_data_); \
+ cyg_hal_interrupt_objects[(_vector_)] = (CYG_ADDRESS)(_object_); \
CYG_MACRO_END
+#endif
-#define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ ) \
- CYG_MACRO_START \
- cyg_uint32 _index_; \
- HAL_TRANSLATE_VECTOR((_vector_), _index_); \
- \
- if (cyg_hal_interrupt_handlers[_index_] \
- ==(CYG_ADDRESS)&hal_default_isr) \
- { \
- cyg_hal_interrupt_handlers[_index_] = (CYG_ADDRESS)(_isr_); \
- cyg_hal_interrupt_data[_index_] = (CYG_ADDRWORD)(_data_); \
- cyg_hal_interrupt_objects[_index_] = (CYG_ADDRESS)(_object_); \
- } \
- CYG_MACRO_END
-
-#define HAL_INTERRUPT_DETACH( _vector_, _isr_ ) \
-CYG_MACRO_START \
- cyg_uint32 _index_; \
- HAL_INTERRUPT_MASK(_vector_); \
- HAL_TRANSLATE_VECTOR((_vector_), _index_); \
- if (cyg_hal_interrupt_handlers[_index_] \
- == (CYG_ADDRESS)(_isr_)) \
- { \
- cyg_hal_interrupt_handlers[_index_] = \
- (CYG_ADDRESS)&hal_default_isr; \
- cyg_hal_interrupt_data[_index_] = 0; \
- cyg_hal_interrupt_objects[_index_] = 0; \
- } \
-CYG_MACRO_END
-
-#define HAL_VSR_GET( _vector_, _pvsr_ ) \
- *((CYG_ADDRESS *)(_pvsr_)) = cyg_hal_vsr_table[(_vector_)];
-
-
-#define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ ) \
- CYG_MACRO_START \
- if( (_poldvsr_) != NULL ) \
- *(CYG_ADDRESS *)(_poldvsr_) = cyg_hal_vsr_table[(_vector_)]; \
- cyg_hal_vsr_table[(_vector_)] = (CYG_ADDRESS)(_vsr_); \
+#ifndef HAL_INTERRUPT_DETACH
+# define HAL_INTERRUPT_DETACH( _vector_, _isr_ ) \
+ CYG_MACRO_START \
+ if (cyg_hal_interrupt_handlers[(_vector_)] == (CYG_ADDRESS)(_isr_)) { \
+ cyg_hal_interrupt_handlers[(_vector_)] = (CYG_ADDRESS)&hal_default_isr; \
+ cyg_hal_interrupt_data[(_vector_)] = 0; \
+ cyg_hal_interrupt_objects[(_vector_)] = 0; \
+ } \
CYG_MACRO_END
+#endif
//--------------------------------------------------------------------------
-// Interrupt control macros
+// Interrupt control macros. These just operate on the entire status
+// register.
-// The following interrupt control macros are the default for the 68k
-// architecture. Some architectures will override these definitions by
-// defining them in their var_intr.h file. Some architectures support
-// instructions like andi.w #xxxx,%sr but others (Coldfire) do not.
-// Architectures that support these other instructions will want to define
-// their own macros.
-
-#define HAL_M68K_SET_SR(__newsr__) \
- CYG_MACRO_START \
- asm volatile ("move.w %0,%%sr\n" \
- : \
- : "g" ((CYG_INTERRUPT_STATE)(__newsr__))); \
- CYG_MACRO_END
+typedef cyg_uint16 CYG_INTERRUPT_STATE;
#ifndef HAL_ENABLE_INTERRUPTS
-#define HAL_ENABLE_INTERRUPTS() \
- CYG_MACRO_START \
- CYG_INTERRUPT_STATE _msk_; \
- HAL_QUERY_INTERRUPTS(_msk_); \
- HAL_M68K_SET_SR((_msk_ & (CYG_INTERRUPT_STATE)0xf8ff)); \
+# define HAL_ENABLE_INTERRUPTS() \
+ CYG_MACRO_START \
+ asm volatile ("move.w %0,%%sr\n" \
+ : \
+ : "J" (0x2000 | (CYGNUM_HAL_INTERRUPT_DEFAULT_IPL_LEVEL << 8)) \
+ : "cc"); \
CYG_MACRO_END
#endif // HAL_ENABLE_INTERRUPTS
#ifndef HAL_DISABLE_INTERRUPTS
-#define HAL_DISABLE_INTERRUPTS(_old_) \
+# define HAL_DISABLE_INTERRUPTS(_old_) \
CYG_MACRO_START \
- HAL_QUERY_INTERRUPTS(_old_); \
- HAL_M68K_SET_SR((_old_ | (CYG_INTERRUPT_STATE)0x0700)); \
+ asm volatile ("move.w %%sr,%0\n" \
+ "move.w #0x2700,%%sr\n" : "=d" (_old_) : : "cc"); \
+ CYG_MACRO_END
+#endif // HAL_DISABLE_INTERRUPTS
+
+#ifndef HAL_RESTORE_INTERRUPTS
+# define HAL_RESTORE_INTERRUPTS(_prev_) \
+ CYG_MACRO_START \
+ asm volatile ("move.w %0,%%sr\n" : : "d" (_prev_) : "cc"); \
CYG_MACRO_END
-#endif //HAL_DISABLE_INTERRUPTS
+#endif
-#define HAL_RESTORE_INTERRUPTS(_prev_) \
+#ifndef HAL_QUERY_INTERRUPTS
+# define HAL_QUERY_INTERRUPTS(_old_) \
CYG_MACRO_START \
- CYG_INTERRUPT_STATE _msk_; \
- HAL_QUERY_INTERRUPTS(_msk_); \
- _msk_ &= (CYG_INTERRUPT_STATE)0xf8ff; \
- _msk_ |= (((CYG_INTERRUPT_STATE)(_prev_)) \
- & (CYG_INTERRUPT_STATE)0x0700); \
- asm volatile ("move.w %0,%%sr\n" \
- : \
- : "g" (_msk_)); \
+ asm volatile ("move.w %%sr,%0\n" : "=d" (_old_) : ); \
CYG_MACRO_END
+#endif
-// Use the extra assignment to avoid warnings.
-// The compiler should optimize it out.
-#define HAL_QUERY_INTERRUPTS(__oldmask__) \
+// ----------------------------------------------------------------------------
+// DSR's should always run on the interrupt stack if available.
+// Even if no interrupt stack is in use we still want to go
+// via call_pending_DSRs() so that it can manipulate the IPL
+// level.
+externC void hal_interrupt_stack_call_pending_DSRs(void);
+# define HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() hal_interrupt_stack_call_pending_DSRs()
+
+// ----------------------------------------------------------------------------
+// HAL_DELAY_US(). This implementation should work fine on all M68K
+// processors. The variant/processor/platform HAL may already have
+// supplied an implementation if for some reason this version is
+// inappropriate.
+//
+// Lower-level HALs should define a count _HAL_M68K_DELAY_US_LOOPS_,
+// and optionally _HAL_M68K_DELAY_US_LOOPS_UNCACHED_. These give the
+// number of iterations needed for a single microsecond delay. In
+// theory it can be worked out from the cpu and board specs, but in
+// practice it is easier to do a bit of experimenting and fine-tune
+// the numbers. Good initial values are 20 and 1 respectively. Note
+// that the symbols need not be compile-time constants if e.g. the
+// processor frequency may change at run-time for power management,
+// but it is assumed that the values will not change as a side
+// effect of interrupts or anything like that.
+//
+// An inline assembler version is used for two reasons. First it
+// prevents the compiler from optimizing the code. Second it avoids
+// problems when different versions of the compiler generate slightly
+// better or worse code.
+#ifndef HAL_DELAY_US
+# ifndef _HAL_M68K_DELAY_US_LOOPS_
+# error Variant, processor or platform HAL should supply loop count parameters
+# else
+# ifdef _HAL_M68K_DELAY_US_LOOPS_UNCACHED_
+// A cache-aware version of the macro
+# include <cyg/hal/hal_cache.h>
+# define HAL_DELAY_US(_delay_) \
+ CYG_MACRO_START \
+ int _icache_enabled_; \
+ int _loops_; \
+ HAL_ICACHE_IS_ENABLED(_icache_enabled_); \
+ _loops_ = (_icache_enabled_) ? _HAL_M68K_DELAY_US_LOOPS_ : \
+ _HAL_M68K_DELAY_US_LOOPS_UNCACHED_; \
+ asm volatile ( "move.l %0, %%d0\n" \
+ "1:\n" \
+ "subq.l #1, %%d0\n" \
+ "beq 3f\n" \
+ "move.l %1, %%d1\n" \
+ "2:\n" \
+ "subq.l #1,%%d1\n" \
+ "bne 2b\n" \
+ "bra 1b\n" \
+ "3:\n" \
+ : \
+ : "d" ((_delay_) + 1), "d" ((_loops_)) \
+ : "cc", "d0", "d1"); \
+ CYG_MACRO_END
+# else
+# define HAL_DELAY_US(_delay_) \
+ CYG_MACRO_START \
+ int _loops_ = _HAL_M68K_DELAY_US_LOOPS_; \
+ asm volatile ( "move.l %0, %%d0\n" \
+ "1:\n" \
+ "subq.l #1, %%d0\n" \
+ "beq 3f\n" \
+ "move.l %1, %%d1\n" \
+ "2:\n" \
+ "subq.l #1,%%d1\n" \
+ "bne 2b\n" \
+ "bra 1b\n" \
+ "3:\n" \
+ : \
+ : "d" ((_delay_) + 1), "d" ((_loops_)) \
+ : "cc", "d0", "d1"); \
+ CYG_MACRO_END
+# endif
+# endif
+#endif
+
+// ----------------------------------------------------------------------------
+// Reset support. This is done by disabling all interrupts and indirecting
+// through the exception vector. Where possible variant or processor HALs
+// should instead activate an on-chip reset controller.
+
+#ifndef HAL_PLATFORM_RESET
+# define HAL_PLATFORM_RESET() \
CYG_MACRO_START \
- CYG_INTERRUPT_STATE _omsk_ = (CYG_INTERRUPT_STATE)(__oldmask__); \
- asm volatile ("move.w %%sr,%0\n" \
- : "=g" (_omsk_) \
- : ); \
- (__oldmask__) = (typeof(__oldmask__))_omsk_; \
+ asm volatile ("move.w #0x2700,%%sr\n" \
+ "move.l %0,%%a0\n" \
+ "move.l 0(%%a0),%%a7\n" \
+ "move.l 4(%%a0),%%a1\n" \
+ "jmp (%%a1)\n" \
+ : : "a" (hal_m68k_vsr_table) : "a0", "a1", "memory"); \
CYG_MACRO_END
+#endif
+#ifndef HAL_PLATFORM_RESET_ENTRY
+# define HAL_PLATFORM_RESET_ENTRY (*(cyg_uint32*)0x04)
+#endif
+
+// ----------------------------------------------------------------------------
+// Functions/symbols exported to the variant and platform HAL's
+externC void hal_m68k_exception_reset(void);
+externC void hal_m68k_rte(void);
+externC void hal_m68k_exception_vsr(void);
+externC void hal_m68k_interrupt_vsr(void);
//---------------------------------------------------------------------------
#endif // ifndef CYGONCE_HAL_HAL_INTR_H
-
Index: include/hal_io.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/m68k/arch/current/include/hal_io.h,v
retrieving revision 1.1
diff -u -p -r1.1 hal_io.h
--- include/hal_io.h 29 May 2002 18:28:15 -0000 1.1
+++ include/hal_io.h 20 Nov 2008 22:20:27 -0000
@@ -8,11 +8,10 @@
// HAL device IO register support.
//
//=============================================================================
-//####ECOSGPLCOPYRIGHTBEGIN####
-// -------------------------------------------
+//###ECOSGPLCOPYRIGHTBEGIN####
+//-------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-//
+// Copyright (C) 2003,2006,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.
@@ -35,19 +34,25 @@
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//=============================================================================
+//####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Date: 2003-06-04
+//####DESCRIPTIONEND####
+//=============================================================================
+#if !defined(__ASSEMBLER__) && !defined(__LDI__)
#include <cyg/infra/cyg_type.h>
+#endif
+#include <cyg/hal/var_io.h>
+#if !defined(__ASSEMBLER__) && !defined(__LDI__)
//-----------------------------------------------------------------------------
// IO Register address.
// This type is for recording the address of an IO register.
-
typedef volatile CYG_ADDRWORD HAL_IO_REGISTER;
//-----------------------------------------------------------------------------
@@ -141,6 +146,8 @@ typedef volatile CYG_ADDRWORD HAL_IO_REG
} \
CYG_MACRO_END
+#endif
+
//-----------------------------------------------------------------------------
#endif // ifndef CYGONCE_HAL_HAL_IO_H
// End of hal_io.h
Index: include/hal_startup.h
===================================================================
RCS file: include/hal_startup.h
diff -N include/hal_startup.h
--- include/hal_startup.h 29 May 2002 18:28:15 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,15 +0,0 @@
-#ifndef _HAL_STARTUP_H
-#define _HAL_STARTUP_H
-
-#include <cyg/infra/cyg_type.h>
-
-// Include the variant-specific startup header.
-
-#include <cyg/hal/var_startup.h>
-
-// Declare the routine to call to simulate a hardware reset.
-
-externC void hal_hw_reset(void);
-
-#endif // _HAL_STARTUP_H
-
Index: include/m68k_stub.h
===================================================================
RCS file: include/m68k_stub.h
diff -N include/m68k_stub.h
--- include/m68k_stub.h 29 May 2002 18:28:15 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,129 +0,0 @@
-#ifndef CYGONCE_HAL_M68K_STUB_H
-#define CYGONCE_HAL_M68K_STUB_H
-//========================================================================
-//
-// m68k_stub.h
-//
-// M68K-specific definitions for generic stub
-//
-//========================================================================
-//####ECOSGPLCOPYRIGHTBEGIN####
-// -------------------------------------------
-// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-//
-// eCos is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 2 or (at your option) any later version.
-//
-// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with eCos; if not, write to the Free Software Foundation, Inc.,
-// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-//
-// As a special exception, if other files instantiate templates or use macros
-// or inline functions from this file, or you compile this file and link it
-// with other works to produce a work based on this file, this file does not
-// by itself cause the resulting work to be covered by the GNU General Public
-// License. However the source code for this file must still be made available
-// in accordance with section (3) of the GNU General Public License.
-//
-// This exception does not invalidate any other reasons why a work based on
-// this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
-// -------------------------------------------
-//####ECOSGPLCOPYRIGHTEND####
-//========================================================================
-
-#include <pkgconf/system.h>
-#include <pkgconf/hal.h>
-
-
-
-#ifdef CYGPKG_IO_SERIAL
-#include <pkgconf/io_serial.h>
-#endif
-
-#include <cyg/hal/hal_diag.h>
-
-#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
-
-#include <cyg/infra/cyg_type.h> // CYG_UNUSED_PARAM, externC
-
-#define HAL_STUB_PLATFORM_INIT_SERIAL() HAL_DIAG_INIT()
-
-#define HAL_STUB_PLATFORM_GET_CHAR() \
-((cyg_int8)({ \
- cyg_int8 _ch_; \
- HAL_DIAG_READ_CHAR(_ch_); \
- _ch_; \
-}))
-
-#define HAL_STUB_PLATFORM_PUT_CHAR(c) HAL_DIAG_WRITE_CHAR((c))
-
-#define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int,(baud))
-
-#define HAL_STUB_PLATFORM_RESET() HAL_DIAG_INIT()
-
-#define HAL_STUB_PLATFORM_INIT() HAL_DIAG_INIT()
-
-#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
-
-
-
-#define NUMREGS 18
-
-#define REGSIZE( _x_ ) (4)
-
-typedef unsigned long target_register_t;
-
-enum regnames {
- D0, D1, D2, D3, D4, D5, D6, D7,
- A0, A1, A2, A3, A4, A5, FP, SP,
- PS, PC,
-};
-
-typedef enum regnames regnames_t;
-
-/* Given a trap value TRAP, return the corresponding signal. */
-externC int __computeSignal (unsigned int trap_number);
-
-/* Return the SPARC trap number corresponding to the last-taken trap. */
-externC int __get_trap_number (void);
-
-/* Return the currently-saved value corresponding to register REG. */
-externC target_register_t get_register (regnames_t reg);
-
-/* Store VALUE in the register corresponding to WHICH. */
-externC 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. */
-externC 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. */
-externC void __single_step (void);
-
-/* Clear the single-step state. */
-externC void __clear_single_step (void);
-
-/* If the breakpoint we hit is in the breakpoint() instruction, return a
- non-zero value. */
-externC int __is_breakpoint_function (void);
-
-/* Skip the current instruction. */
-externC void __skipinst (void);
-
-externC void __install_breakpoints (void);
-
-externC void __clear_breakpoints (void);
-
-#endif // ifndef CYGONCE_HAL_M68K_STUB_H
Index: src/hal_arch.S
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/m68k/arch/current/src/hal_arch.S,v
retrieving revision 1.1
diff -u -p -r1.1 hal_arch.S
--- src/hal_arch.S 29 May 2002 18:28:15 -0000 1.1
+++ src/hal_arch.S 20 Nov 2008 22:20:28 -0000
@@ -1,156 +1,760 @@
-##=============================================================================
-#####ECOSGPLCOPYRIGHTBEGIN####
-## -------------------------------------------
-## This file is part of eCos, the Embedded Configurable Operating System.
-## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-##
-## eCos is free software; you can redistribute it and/or modify it under
-## the terms of the GNU General Public License as published by the Free
-## Software Foundation; either version 2 or (at your option) any later version.
-##
-## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
-## WARRANTY; without even the implied warranty of MERCHANTABILITY or
-## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-## for more details.
-##
-## You should have received a copy of the GNU General Public License along
-## with eCos; if not, write to the Free Software Foundation, Inc.,
-## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-##
-## As a special exception, if other files instantiate templates or use macros
-## or inline functions from this file, or you compile this file and link it
-## with other works to produce a work based on this file, this file does not
-## by itself cause the resulting work to be covered by the GNU General Public
-## License. However the source code for this file must still be made available
-## in accordance with section (3) of the GNU General Public License.
-##
-## This exception does not invalidate any other reasons why a work based on
-## this file might be covered by the GNU General Public License.
-##
-## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-## at http://sources.redhat.com/ecos/ecos-license/
-## -------------------------------------------
-#####ECOSGPLCOPYRIGHTEND####
-##=============================================================================
-/*****************************************************************************
-hal_arch.S -- m68k architecture code
-*****************************************************************************/
-
-#include <pkgconf/hal.h>
-
-/*****************************************************************************
-FUNC_START -- Function declaration macro
-*****************************************************************************/
-#define FUNC_START(name) \
- .text; \
- .even; \
- .globl name; \
-name:
-
-/*****************************************************************************
- The following routines assume the hal_jmp_buf structure is defined as
-shown below.
-
-typedef struct {
- cyg_uint32 d2;
- cyg_uint32 d3;
- cyg_uint32 d4;
- cyg_uint32 d5;
- cyg_uint32 d6;
- cyg_uint32 d7;
- cyg_uint32 a2;
- cyg_uint32 a3;
- cyg_uint32 a4;
- cyg_uint32 a5;
- cyg_uint32 a6;
- cyg_uint32 sp;
- cyg_uint32 pc;
-} hal_jmp_buf_t;
-typedef cyg_uint32 hal_jmp_buf[sizeof(hal_jmp_buf_t) / sizeof(cyg_uint32)];
-*****************************************************************************/
-
-/*****************************************************************************
-hal_m68k_setjmp -- Generic setjmp for the m68k architecture
-
-externC int hal_m68k_setjmp(hal_jmp_buf env);
-
-INPUT:
-
- 0(%sp): return address
-
- 4(%sp): env - address of a hal_jmp_buf structure
-
-OUTPUT:
-
- d0, d1, a0, a1 are ours to abuse.
-
-RETURN VALUE:
-
- This routine always returns zero in d0.l.
-
-*****************************************************************************/
-FUNC_START(hal_m68k_setjmp)
-
- lea.l 4(%sp),%a1 /* Get a pointer to the position */
- /* of the stack pointer before this */
- /* call was made. IMPORTANT: The */
- /* longjmp routine and the */
- /* exception handler assume that */
- /* saved stack pointers point to */
- /* the location of the stack before */
- /* the routine/exception occurred. */
-
- move.l (%a1),%a0 /* Get a pointer to the buffer to */
- /* save our state into. */
-
- movem.l %d2-%d7/%a2-%a6,(%a0) /* Write all of the preserved */
- lea (11*4)(%a0),%a0 /* registers, the stack pointer, */
- move.l %a1,(%a0)+ /* and the return address into the */
- move.l (%sp),(%a0) /* structure. */
-
- moveq.l #0,%d0 /* Load a zero return value and */
- rts /* return. */
-
-/*****************************************************************************
-hal_m68k_longjmp -- Generic longjmp for the m68k architecture
-
-externC void hal_m68k_longjmp(hal_jmp_buf env, int val);
-
-INPUT:
-
- 0(%sp): return address
-
- 4(%sp): env - address of a hal_jmp_buf structure
-
- 8(%sp): val - the non-zero value to return
-
-OUTPUT:
-
- d0, d1, a0, a1 are ours to abuse.
-
-RETURN VALUE:
-
- This routine always returns the value from the val parameter in d0.l
-and to the location of the PC in the env structure.
-
-*****************************************************************************/
-FUNC_START(hal_m68k_longjmp)
-
- move.l 8(%sp),%d0 /* Load the return value */
- /* parameter. */
-
- move.l 4(%sp),%a0 /* Get a pointer to the buffer to */
- /* read our state from. */
-
- movem.l (%a0),%d2-%d7/%a2-%a6 /* Load our preserved registers, */
- lea (11*4)(%a0),%a0 /* stack pointer and return address */
- move.l (%a0)+,%d1 /* from the structure. */
- move.l (%a0),%a1
-
- move.l %d1,%sp /* Set the stack pointer from the */
- jmp (%a1) /* structure as out current stack */
- /* pointer and jump to the return */
- /* address from the structure. */
-
+// #========================================================================
+// #
+// # hal_arch.S
+// #
+// # M68K support for contexts, exceptions and interrupts
+// #
+// #========================================================================
+//=============================================================================
+//###ECOSGPLCOPYRIGHTBEGIN####
+//-------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003,2004,2005,2006,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.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//============================================================================
+//###DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Date: 2003-06-04
+//
+//###DESCRIPTIONEND####
+//========================================================================
+ .file "hal_arch.S"
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_m68k.h>
+#ifdef CYGPKG_KERNEL
+ // For instrumentation options
+# include <pkgconf/kernel.h>
+#endif
+#include <cyg/hal/arch.inc>
+
+// ----------------------------------------------------------------------------
+// The system startup and/or interrupt stack, unless the platform HAL
+// provides its own.
+//
+// The default behaviour is a separate interrupt stack via common HAL
+// configuration options, with the interrupt stack reused as the
+// startup stack. If the use of an interrupt stack is disabled then
+// a separate startup stack is needed. Either the startup stack, the
+// interrupt stack, or both can be provided by the platform HAL, for
+// example to place the stack in an area of memory that is not otherwise
+// readily usable.
+
+#if defined(_HAL_M68K_INSTANTIATE_STARTUP_STACK_) || defined(_HAL_M68K_INSTANTIATE_INTERRUPT_STACK_)
+ .section .bss
+ .balign 4
+# ifdef _HAL_M68K_INSTANTIATE_STARTUP_STACK_
+ .global _hal_m68k_startup_stack_base_
+_hal_m68k_startup_stack_base_:
+# endif
+# ifdef _HAL_M68K_INSTANTIATE_INTERRUPT_STACK_
+ .global _hal_m68k_interrupt_stack_base_
+_hal_m68k_interrupt_stack_base_:
+# endif
+# ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+ .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
+ .byte 0
+ .endr
+ .balign 4
+# else
+ .rept CYGNUM_HAL_M68K_STARTUP_STACK_SIZE
+ .byte 0
+ .endr
+ .balign 4
+# endif
+# ifdef _HAL_M68K_INSTANTIATE_STARTUP_STACK_
+ .global _hal_m68k_startup_stack_
+_hal_m68k_startup_stack_:
+# endif
+# ifdef _HAL_M68K_INSTANTIATE_INTERRUPT_STACK_
+ .global _hal_m68k_interrupt_stack_
+_hal_m68k_interrupt_stack_:
+# endif
+
+#endif
+
+// ----------------------------------------------------------------------------
+// M68K calling conventions.
+//
+// The stack pointer always points at the first word of the stack that
+// is currently in use. Pushing additional data requires a predecrement.
+//
+// Frame pointers are not required but the compiler usually defaults to
+// using them, to make debugging easier. This assembler code typically
+// does not use a frame pointer.
+//
+// All arguments are pushed onto the stack, never in registers. D0 is
+// used for return values.
+//
+// According to CALL_USED_REGISTERS in gcc/config/m68k/m68k.h,
+// d0/d1/a0/a1/fp0/fp1 are caller-save, i.e. must be saved in an interrupt
+// handler but can be ignored in a function called from C. The fp status
+// registers are also caller-save.
+//
+// d2-d7/a2-a6/fp2-fp7 are callee-save registers, i.e. must be saved by
+// a C function. fpsr is not callee-save, a C function can perform floating
+// point operations and hence clobber the status. Similarly fpiar is not
+// callee-save. fpcr is
+//
+// Floating point support is only available on some variants. There can also
+// be other hardware units such as multiply-accumulators which may have state
+// that should be saved.
+
+// ----------------------------------------------------------------------------
+// Context switch support.
+//
+// The context consists of generic integer registers, possibly floating
+// point registers, possibly another hardware unit, and space for pc/sr
+// at the end in a variant-specific format.
+
+ .equ hal_context_integer_offset, 0
+ .equ hal_context_integer_d0_offset, 0
+ .equ hal_context_integer_d2_offset, (2 * 4)
+ .equ hal_context_integer_a0_offset, (8 * 4)
+ .equ hal_context_integer_a2_offset, ((8+2) * 4)
+ .equ hal_context_integer_size, (15 * 4)
+
+ .equ hal_context_fpu_offset, (hal_context_integer_offset + hal_context_integer_size)
+#ifdef CYGIMP_HAL_M68K_FPU_SAVE
+ .equ hal_context_fpu_fpsr_offset, (hal_context_fpu_offset + 0)
+ .equ hal_context_fpu_fpiar_offset, (hal_context_fpu_offset + 4)
+ .equ hal_context_fpu_fp0_offset, (hal_context_fpu_offset + 8)
+ .equ hal_context_fpu_fp2_offset, (hal_context_fpu_fp0_offset + (2 * 12))
+ .equ hal_context_fpu_size, ((2 * 4) + (8 * 12))
+#else
+ .equ hal_context_fpu_size, 0
+#endif
+
+ .equ hal_context_other_offset, (hal_context_fpu_offset + hal_context_fpu_size)
+#ifdef HAL_CONTEXT_OTHER_SIZE
+ .equ hal_context_other_size, HAL_CONTEXT_OTHER_SIZE
+#else
+ .equ hal_context_other_size, 0
+#endif
+
+ .equ hal_context_pcsr_offset, (hal_context_other_offset + hal_context_other_size)
+#ifdef HAL_CONTEXT_PCSR_SIZE
+ .equ hal_context_pcsr_size, HAL_CONTEXT_PCSR_SIZE
+#else
+ .equ hal_context_pcsr_size, 8
+#endif
+ .equ hal_context_size, (hal_context_pcsr_offset + hal_context_pcsr_size)
+
+// The offset to be used when switching to a new thread. For some variants
+// this is 0 because the rte instruction will pop the entire pcsr part of
+// the structure. For other variants some additional data may have to be popped.
+#ifdef HAL_CONTEXT_PCSR_RTE_ADJUST
+ .equ hal_context_rte_adjust, (hal_context_pcsr_offset + HAL_CONTEXT_PCSR_RTE_ADJUST)
+#else
+ .equ hal_context_rte_adjust, hal_context_pcsr_offset
+#endif
+
+
+// Definitions for saving/restoring FPU context, if the FPU is part of the
+// saved context. It can be assumed that %sp points at the thread context.
+// FIXME: this code should probably use fsave/frestore to ensure that
+// floating point operations have completed.
+#ifdef CYGIMP_HAL_M68K_FPU_SAVE
+
+ .macro hal_context_fpu_save_caller areg=%sp
+ fmove.l %fpsr, hal_context_fpu_fpsr_offset(\areg)
+ fmove.l %fpiar, hal_context_fpu_fpiar_offset(\areg)
+ fmovem.x %fp0-%fp1, hal_context_fpu_fp0_offset(\areg)
+ .endm
+
+ .macro hal_context_fpu_load_caller areg=%sp
+ fmove.l hal_context_fpu_fpsr_offset(\areg), %fpisr
+ fmove.l hal_context_fpu_fpiar_offset(\areg), %fpiar
+ fmovem.x hal_context_fpu_fp0_offset(\areg),%fp0-%fp1
+ .endm
+
+ .macro hal_context_fpu_save_callee areg=%sp
+ fmovem.x %fp2-%fp7, hal_context_fpu_fp2_offset(\areg)
+ .endm
+
+ .macro hal_context_fpu_load_callee areg=%sp
+ fmovem.x hal_context_fpu_fp2_offset(\areg), %fp2-%fp7
+ .endm
+
+ .macro hal_context_fpu_save_all areg=%sp
+ fmove.l %fpsr, hal_context_fpu_fpsr_offset(\areg)
+ fmove.l %fpiar, hal_context_fpu_fpiar_offset(\areg)
+ fmovem.x %fp0-%fp7, hal_context_fpu_fp0_offset(\areg)
+ .endm
+
+ .macro hal_context_fpu_load_all areg=%sp
+ fmove.l hal_context_fpu_fpsr_offset(\areg), %fpsr
+ fmove.l hal_context_fpu_fpiar_offset(\areg), %fpiar
+ fmovem.x hal_context_fpu_fp0_offset(\areg), %fp0-%fp7
+ .endm
+#else
+ .macro hal_context_fpu_save_caller areg=%sp
+ .endm
+ .macro hal_context_fpu_load_caller areg=%sp
+ .endm
+ .macro hal_context_fpu_save_callee areg=%sp
+ .endm
+ .macro hal_context_fpu_load_callee areg=%sp
+ .endm
+ .macro hal_context_fpu_save_all areg=%sp
+ .endm
+ .macro hal_context_fpu_load_all areg=%sp
+ .endm
+#endif
+
+// No-op defaults for saving/restoring the OTHER context. If there is in fact
+// something to be done then the variant HAL should have defined
+// HAL_CONTEXT_OTHER_SIZE
+#ifndef HAL_CONTEXT_OTHER_SIZE
+ .macro hal_context_other_save_caller areg=%sp
+ .endm
+ .macro hal_context_other_load_caller areg=%sp
+ .endm
+ .macro hal_context_other_save_callee areg=%sp
+ .endm
+ .macro hal_context_other_load_callee areg=%sp
+ .endm
+ .macro hal_context_other_save_all areg=%sp
+ .endm
+ .macro hal_context_other_load_all areg=%sp
+ .endm
+#endif
+
+// ----------------------------------------------------------------------------
+// LOAD_CONTEXT is called to start a new thread, usually only during system
+// startup.
+//
+// void hal_thread_load_context(void* sp)
+
+ FUNC_START(hal_thread_load_context)
+ move.l 4(%sp),%sp
+ hal_context_other_load_all
+ hal_context_fpu_load_all
+ movem.l hal_context_integer_offset(%sp),%d0-%d7/%a0-%a6
+ add.l #hal_context_rte_adjust, %sp
+ rte
+
+// ----------------------------------------------------------------------------
+// void hal_thread_switch_context(void** from, void* to)
+
+ FUNC_START(hal_thread_switch_context)
+
+ // Space for the saved thread context. The PC is already on the
+ // stack. "from" is on the stack immediately after the context,
+ // then "to".
+ mov.l 4(%sp),%a0
+ sub.l # (hal_context_size - 4), %sp
+ mov.l %sp, 0(%a0)
+
+#ifdef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM
+ // Save all the callee-save integer registers, so that they become
+ // available to the other macros.
+ movem.l %d2-%d7, hal_context_integer_d2_offset(%sp)
+ movem.l %a2-%a6, hal_context_integer_a2_offset(%sp)
+
+ // The status register must be saved here, since loading a thread
+ // context always involves an rte instruction. The details are
+ // variant-specific.
+ hal_context_pcsr_save_sr %sp,0,%d0
+
+ // Now the fpu and other contexts can be saved. All registers
+ // are available.
+ hal_context_fpu_save_callee
+ hal_context_other_save_callee
+#else
+ movem.l %d0-%d7/%a0-%a6, hal_context_integer_offset(%sp)
+ hal_context_pcsr_save_sr %sp,0,%d0
+ hal_context_fpu_save_all
+ hal_context_other_save_all
+#endif
+
+ // All thread state has now been saved, so switch to the new one.
+ mov.l (hal_context_size+4)(%sp),%sp
+
+#ifdef CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM
+ hal_context_other_load_callee
+ hal_context_fpu_load_callee
+ movem.l hal_context_integer_d2_offset(%sp),%d2-%d7
+ movem.l hal_context_integer_a2_offset(%sp),%a2-%a6
+#else
+ hal_context_other_load_all
+ hal_context_fpu_load_all
+ movem.l hal_context_integer_offset(%sp),%d0-%d7/%a0-%a6
+#endif
+
+ add.l #hal_context_rte_adjust, %sp
+ rte
+
+// ----------------------------------------------------------------------------
+// setjmp()/longjmp(). See hal_arch.h for details.
+//
+// int hal_m68k_setjmp(hal_jmp_buf);
+// void hal_m68k_longjmp(hal_jmp_buf, val)
+
+ FUNC_START_WEAK(hal_m68k_setjmp)
+ lea.l 4(%sp),%a1 // return stack pointer. longjmp() does an indirect jmp, not an rts
+ move.l 0(%a1),%a0 // the jmp_buf structure
+ move.l 0(%sp),0(%a0) // return pc
+ move.l %a1,4(%a0)
+ movem.l %d2-%d7/%a2-%a6,8(%a0) // 11 longs, occupying offsets 8 to 51
+#ifdef CYGINT_HAL_M68K_VARIANT_FPU
+ fmovem.x %fp2-%fp7,52(%a0)
+#endif
+ clr.l %d0 // setjmp() always returns 0
+ rts
+
+ FUNC_START_WEAK(hal_m68k_longjmp)
+ move.l 8(%sp),%d0 // val argument, and hence return value
+ move.l 4(%sp),%a0 // The jmp_buf structure
+ movem.l 8(%a0),%d2-%d7/%a2-%a6
+#ifdef CYGINT_HAL_M68K_VARIANT_FPU
+ fmovem.x 52(%a0),%fp2-%fp7
+#endif
+ move.l 0(%a0),%a1 // The return pc
+ move.l 4(%a0),%sp
+ jmp (%a1)
+
+// ----------------------------------------------------------------------------
+// Synchronous exceptions. Interrupts are disabled because that could confuse
+// some code like gdb stubs (breakpoints also involve synchronous exceptions).
+// Full state is saved on the current stack, then usually we switch to the
+// interrupt stack and handle the rest of the exception there. That avoids
+// having to worry about gdb stubs stack requirements in every thread context.
+//
+// It is assumed that on entry there is pc/sr context information already
+// on the stack. Some or all of this will have been provided by the hardware.
+// Other bits, e.g. the specific exception number, may have been pushed by
+// software that then jumped here. The hardware may also have pushed some
+// additional state which has already been removed or stashes elsewhere,
+// to keep things simple.
+
+ .extern hal_m68k_exception_handler
+
+ FUNC_START(hal_m68k_exception_vsr)
+ mov.w #0x2700, %sr
+ sub.l #hal_context_pcsr_offset, %sp
+
+ // If CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT is enabled
+ // then only caller-save registers need to be saved here, but
+ // exceptions should be rare and the additional info may prove
+ // useful to higher-level code.
+ movem.l %d0-%d7/%a0-%a6, hal_context_integer_offset(%sp)
+ hal_context_fpu_save_all
+ hal_context_other_save_all
+
+ // Remember the current stack pointer in a callee-save register,
+ // which have all been saved anyway. That makes it easier to restore
+ // the stack later.
+ move.l %sp,%a2
+
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+ // Do we need to switch to the interrupt stack?
+ cmpa.l _HAL_M68K_INTERRUPT_STACK_, %sp
+ jbgt 1f
+ cmpa.l _HAL_M68K_INTERRUPT_STACK_BASE_, %sp
+ jbge 2f
+1:
+ mova.l _HAL_M68K_INTERRUPT_STACK_, %sp
+2:
+#endif
+ // Zero out the frame pointer to encourage GDB to backtrace correctly
+ suba.l %a6, %a6
+
+ // Now call into C with a single argument, the HAL_SavedRegisters
+ mov.l %a2,-(%sp)
+ jbsr hal_m68k_exception_handler
+
+ // We can switch back to the right stack by re-using a2, irrespective
+ // of whether or not we switched to the interrupt stack.
+ move.l %a2,%sp
+
+ // Restore the entire state. In theory only the callee-save registers
+ // should have changed, but some others may have been manipulated by
+ // gdb.
+ hal_context_other_load_all
+ hal_context_fpu_load_all
+ movem.l hal_context_integer_offset(%sp), %d0-%d7/%a0-%a6
+ add.l #hal_context_rte_adjust, %sp
+ rte
+
+// ----------------------------------------------------------------------------
+// Interrupt handling.
+//
+// The current stack may be a thread stack or the interrupt stack.
+// On some variants this code will be called directly by the hardware.
+// On others there will have been a trampoline doing some stack
+// manipulation and then jumping here. We assume that the stack is
+// properly aligned and that the pc/sr part has been correctly saved.
+
+ FUNC_START(hal_m68k_interrupt_vsr)
+
+#ifndef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING
+ // If nesting is not of interest then just disable all interrupts.
+ // Otherwise interrupt nesting is controlled via the M68K IPL
+ move.w #0x2700, %sr
+#endif
+
+ sub.l # hal_context_pcsr_offset, %sp
+#ifdef CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
+ // Even for a minimum context the callee-save a2 register
+ // is saved. This makes it easier to restore the stack
+ // to the right place after the ISR call, allowing for
+ // the optional interrupt stack.
+ movem.l %d0-%d1,hal_context_integer_d0_offset(%sp)
+ movem.l %a0-%a2,hal_context_integer_a0_offset(%sp)
+ hal_context_fpu_save_caller %sp
+ hal_context_other_save_caller %sp
+#else
+ movem.l %d0-%d7/%a0-%a6, hal_context_integer_d0_offset(%sp)
+ hal_context_fpu_save_all %sp
+ hal_context_other_save_all %sp
+#endif
+
+#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
+ // Let gdb stubs know which thread was interrupted, in case this
+ // interrupt was a ctrl-C.
+ .extern hal_saved_interrupt_state
+ move.l %sp, hal_saved_interrupt_state
+#endif
+
+ // d0/d1/a0/a1/a2 are now available.
+ // We want to extract the ISR vector while it is readily accessible.
+ // The details depend the particular M68K variant. The result should
+ // be the vector << 2 to facilitate indexing. On some processors that
+ // actually requires less code than getting the vector itself.
+ hal_context_extract_isr_vector_shl2 %sp,0,%d0
+
+#if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR)
+ // We need to call cyg_instrument(INTR.RAISE, vector, intr_number)
+ // The actual interrupt number is not readily available, it depends
+ // on the variant and possibly the platform, so just instrument 0
+ // instead. The vector is preserved in callee-save a2 since it may
+ // take several instructions to refetch it.
+ movea.l %d0, %a2
+ lsr.l #2, %d0
+ move.l #0, -(%sp)
+ move.l %d0, -(%sp)
+ move.l #0x0301, -(%sp)
+ jbsr cyg_instrument
+ add.l #12, %sp
+ move.l %a2, %d0
+#endif
+
+ // %d0 holds the ISR vector << 2. d1/a0/a1/a2 are available.
+
+#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT
+ // Increment the scheduler lock. In theory the ISR should not look
+ // at this so it could be deferred till just before the interrupt_end()
+ // call, but this provides protection against badly written ISR's.
+ //
+ // This is not sufficient on SMP systems. The test of the scheduler lock
+ // below also needs attention.
+ .extern cyg_scheduler_sched_lock
+ addq.l #1, cyg_scheduler_sched_lock
+#endif
+
+ // At the end of the VSR we need to call interrupt_end().
+ // The last two arguments are cyg_hal_interrupt_objects[vec]
+ // and the saved registers. These are pushed now, while
+ // vec is readily available, at the cost of a slight increase
+ // in interrupt latency but saving some instructions later.
+ move.l %sp,-(%sp)
+ lea cyg_hal_interrupt_objects,%a0
+ move.l 0(%a0,%d0), -(%sp)
+
+ // We want to be able to restore the stack pointer to this location,
+ // irrespective of whether or not an interrupt stack is being used.
+ // Store it in a callee-save register.
+ movea.l %sp, %a2
+
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+ // Switch to the interrupt stack if we are not already running there.
+ cmpa.l _HAL_M68K_INTERRUPT_STACK_, %sp
+ jbgt 1f
+ cmpa.l _HAL_M68K_INTERRUPT_STACK_BASE_, %sp
+ jbge 2f
+1:
+ movea.l _HAL_M68K_INTERRUPT_STACK_, %sp
+2:
+#endif
+ // FIXME: Some variation of the following should be considered to ensure that
+ // GDB can't get permanently lost when doing a backtrace from within an ISR.
+#if 0 && defined(CYGPKG_INFRA_DEBUG) && !defined(CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT)
+ // Zero out the frame pointer to encourage GDB to backtrace correctly
+ // But only if explicitly debugging so that we don't adversely affect
+ // critical ISR latency
+ move.w #0,%a6
+#endif
+
+ // d0 is the isr vector << 2. a2 holds a saved stack pointer. d1/a0/a1 are available.
+ // We need to call (*cyg_hal_interrupt_handlers[vec])(vec, cyg_hal_interrupt_data[vec])
+ lea cyg_hal_interrupt_data,%a0
+ move.l 0(%a0,%d0),-(%sp)
+ lea cyg_hal_interrupt_handlers,%a0
+ move.l 0(%a0,%d0),%a1
+ lsr.l #2,%d0
+ move.l %d0,-(%sp)
+ jbsr (%a1)
+
+ // We now want to return to the right position on the current
+ // stack, or to the thread stack if we switched to the interrupt
+ // stack.
+ movea.l %a2, %sp
+
+ // Next we need to call interrupt_end(). If the scheduler was unlocked
+ // at the time of the interrupt then that will run the DSRs, possibly
+ // cause a context switch, and eventually return to this VSR. If the
+ // scheduler was already locked then interrupt_end() will return to
+ // the VSR almost immediately. The IPL level will be restored when
+ // the VSR executes the final rte.
+ //
+ // DSRs should run with interrupts re-enabled. Ideally we want to
+ // run them with the IPL level of the interrupted thread, and at
+ // the end reset the IPL level to what it is now. That way this
+ // VSR gets to return, without risk of unconstrained stack usage.
+ // However this is very hard: currently the desired IPL levels
+ // cannot be passed on the stack; they cannot be passed via globals
+ // either because of the possibility of a context switch.
+ //
+ // Instead there is a defined IPL level for running all DSRs.
+ // HAL_INTERRUPT_STACK_CALL_PENDING_DSRs() sets the IPL level to
+ // that value, and restores the IPL level when done. For most
+ // applications that will be fine, but it does make it more
+ // difficult to manipulate IPL levels on a per-thread level
+ // or anything similarly fancy.
+
+ // We need to call interrupt_end(isr_return, cyg_hal_interrupt_objects[vec], saved_state_pointer)
+ // The last two have already been pushed onto the stack. d0 holds the return value.
+ move.l %d0,-(%sp)
+ jbsr interrupt_end
+ add.l #12,%sp
+
+#ifdef CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
+ hal_context_other_load_caller %sp
+ hal_context_fpu_load_caller %sp
+ movem.l hal_context_integer_a0_offset(%sp),%a0-%a2
+ movem.l hal_context_integer_d0_offset(%sp),%d0-%d1
+#else
+ hal_context_other_load_all %sp
+ hal_context_fpu_load_all %sp
+ movem.l hal_context_integer_d0_offset(%sp),%d0-%d7/%a0-%a6
+#endif
+ add.l #hal_context_rte_adjust,%sp
+ rte
+
+// ----------------------------------------------------------------------------
+// On configurations with an interrupt stack HAL_INTERRUPT_STACK_CALL_PENDING_DSRS()
+// is used to run the DSRs on the interrupt stack rather than the thread stack,
+// reducing stack size requirements for the latter. It is called only on a thread
+// stack. In addition to the stack switch the IPL level is manipulated here,
+// ensuring that DSRs run with interrupts enabled.
+//
+// On other architectures HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() is only called
+// when a separate interrupt stack is used. If the interrupt stack is disabled
+// then DSRs run with interrupts disabled, which is a bad idea. On the M68K
+// HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() is always defined, thus sorting out
+// the interrupt level, but only does the stack switch if an interrupt stack
+// is actually being used.
+
+ .extern hal_m68k_dsr_ipl_level
+ .extern cyg_interrupt_call_pending_DSRs
+
+ FUNC_START(hal_interrupt_stack_call_pending_DSRs)
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+ // Use callee-save registers to store the current stack and status register
+ // Also store the frame pointer so we can zero it to improve GDB debugging backtraces
+ move.l %a2,-(%sp)
+ move.l %d2,-(%sp)
+ move.l %a6,-(%sp)
+ movea.l %sp,%a2
+ move.w %sr,%d2
+ suba.l %a6,%a6
+
+ // There is a problem if the configuration contains the kernel but interrupts
+ // are enabled while still running the startup code. The kernel's interrupt_end()
+ // rather than the driver API's will be used, so this code gets to run. We now
+ // get to switch to the interrupt stack while still on the startup stack, which
+ // is a shame since the two are the same. This could be easily fixed by checking
+ // the current stack as happens in the interrupt_vsr, but at the cost of an
+ // extra four instructions in the DSR path. The scenario should probably not
+ // arise so those four instructions are left out for now.
+ movea.l _HAL_M68K_INTERRUPT_STACK_, %sp
+ move.l hal_m68k_dsr_ipl_level, %d0
+ move.w %d0, %sr
+
+ jbsr cyg_interrupt_call_pending_DSRs
+
+ move.w %d2, %sr
+ movea.l %a2, %sp
+ movea.l (%sp)+,%a6
+ move.l (%sp)+,%d2
+ movea.l (%sp)+,%a2
+ rts
+#else
+ move.l %d2, -(%sp)
+ move.w %sr, %d2
+ move.l hal_m68k_dsr_ipl_level, %d0
+ move.w %d0, %sr
+ jbsr cyg_interrupt_call_pending_DSRs
+ move.w %d2, %sr
+ move.l (%sp)+, %d2
+ rts
+#endif // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
+
+
+// ----------------------------------------------------------------------------
+// A dummy entry point for unused entries in the system exception vector.
+
+ FUNC_START(hal_m68k_rte)
+ rte
+
+// ----------------------------------------------------------------------------
+// Fast implementations of lsbit_index() and msbit_index()
+
+ FUNC_START(hal_lsbit_index)
+ clr.l %d0 // result
+ mov.l 4(%sp),%d1 // mask
+ bne 1f // special case for 0
+ subq.l #1,%d0 // lsbit_index(0) -> -1
+ rts
+1:
+ tst.w %d1 // anything set in the bottom 16 bits?
+ bne 2f
+ swap %d1 // the top 16 bits only are of interest
+ moveq.l #16, %d0
+2:
+ tst.b %d1 // anything set in the bottom 8 bits?
+ bne 3f
+ addq.l #8, %d0 // bottom byte is 0, switch to next byte
+ lsr.l #8, %d1
+3:
+ move.l %d1, %a0 // backup current data, so that we can manipulate it
+ and.l #0x0F, %d1 // anything in the bottom nibble?
+ bne 4f
+ move.l %a0, %d1 // nope, restore and use the next nibble
+ lsr.l #4, %d1
+ and.l #0x0F, %d1
+ addq.l #4, %d0
+4:
+ // The bottom nibble contains a number between 1 and 15
+ // (not 0, that would have been caught by the test at the top).
+ lea 5f, %a0
+ mov.b 0(%a0,%d1),%d1 // only zap bottom byte, the other bytes are already 0
+ add.l %d1,%d0
+ rts
+5:
+ // Every odd number has an index of 0. The first entry is irrelevent.
+ .byte 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+
+ FUNC_START(hal_msbit_index)
+ clr.l %d0 // result
+ mov.l 4(%sp), %d1 // mask
+ bne 1f // special case for 0
+ subq.l #1, %d0 // msbit_index(0) -> -1
+ rts
+1:
+ cmpi.l #0x0000FFFF,%d1
+ bls 2f
+ moveq.l #16,%d0
+ clr.w %d1
+ swap %d1
+2:
+ cmpi.l #0x00FF, %d1
+ bls 3f
+ addq.l #8, %d0
+ lsr.l #8, %d1
+3:
+ cmpi.l #0x000F, %d1
+ bls 4f
+ addq.l #4, %d0
+ lsr.l #4, %d1
+
+4:
+ lea 5f, %a0
+ mov.b 0(%a0,%d1), %d1
+ add.l %d1,%d0
+ rts
+
+5:
+ .byte 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
+
+// ----------------------------------------------------------------------------
+// Profiling support. When code is compiled with -pg the compiler inserts
+// calls to mcount() at the start of each function. This can be used to
+// build a callgraph of the application. mcount() is tied to the compiler
+// internals and does not always use standard calling conventions.
+//
+// mcount() should call __profile_mcount() with two arguments, caller_pc
+// and callee_pc, where callee_pc refers to the function that calls
+// mcount() and caller_pc refers to the place where that function is
+// called from. callee_pc is readily accessed relative to sp, caller_pc
+// can be accessed using the frame pointer. This assumes the code has
+// not been built with -fomit-frame-pointer, a safe assumption since
+// the compiler disallows combining -pg and -fomit-frame-pointer.
+//
+// The m68k compiler appears to implement mcount() a bit differently
+// from other targets. It reserves a word for every function entry
+// point which presumably is intended to act as the start of a linked
+// list chain. On other targets the PC is used to index a hash table
+// which contains the start of that linked list. That extra word is
+// not used for eCos profiling since it would require customizing the
+// profiling package on a per-target basis, so unfortunately the
+// memory is wasted.
+//
+// It is assumed that d0/d1/a0/a1 (the callee-save registers) are
+// available. a0 is certainly available because that is used to hold
+// the above per-function word. If the assumption is false then this
+// would have to save d0/d1/a1 because the C __profile_mcount() could
+// zap them.
+//
+// This code is conditional on CYGPKG_PROFILE_GPROF since that provides
+// the implementation of __profile_mcount.
+#ifdef CYGPKG_PROFILE_GPROF
+ FUNC_START(mcount)
+ // __profile_mcount() should be called with interrupts disabled.
+ move.w %sr,%d0
+ move.l %d0,-(%sp)
+ // The callee-pc corresponds to the return address on the stack
+ move.l 4(%sp),%a0
+ move.l %a0,-(%sp)
+ // The caller-pc is accessible relative to the frame pointer a6
+ move.l 4(%a6),%a0
+ move.l %a0,-(%sp)
+
+ move.w #0x2700, %sr
+ jbsr __profile_mcount
+
+ move.l 8(%sp),%d0
+ add.l #12, %sp
+ move.w %d0,%sr
+
+ rts
+#endif
+
+ .end
Index: src/hal_m68k.c
===================================================================
RCS file: src/hal_m68k.c
diff -N src/hal_m68k.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/hal_m68k.c 20 Nov 2008 22:20:28 -0000
@@ -0,0 +1,224 @@
+//==========================================================================
+//
+// hal_m68k.c
+//
+// M68K HAL miscellaneous C functions
+//
+//==========================================================================
+//###ECOSGPLCOPYRIGHTBEGIN####
+//-------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003,2004,2006,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.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//###DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Date: 2003-06-04
+//
+//###DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_m68k.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_diag.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_stub.h>
+
+// ----------------------------------------------------------------------------
+// Interrupt support.
+//
+// Space for the interrupt data. These are updated by macros in hal_intr.h
+volatile CYG_ADDRESS cyg_hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
+volatile CYG_ADDRWORD cyg_hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
+volatile CYG_ADDRESS cyg_hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];
+
+// A status register value that should be used while running DSRs.
+cyg_uint32 hal_m68k_dsr_ipl_level = 0x2000 | (CYGNUM_HAL_INTERRUPT_DEFAULT_IPL_LEVEL << 8);
+
+// In virtual vector configurations we can get apparently spurious
+// interrupts in application space when the interrupt will be serviced
+// by RedBoot instead. Hence the virtual vector code in the common HAL
+// provides hal_default_isr() which gets installed as the default
+// handler for all interrupts. If it turns out that RedBoot does not
+// recognize the interrupt either, i.e. it really is spurious, then
+// the virtual vector code will call hal_arch_default_isr().
+//
+// In non-virtual vector configurations hal_default_isr() needs to
+// be provided by the architecture/variant/processor/platform HAL
+// on the off-chance that the interrupt is not entirely spurious
+// and some useful processing can take place.
+
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+# ifndef _HAL_M68K_HAL_ARCH_DEFAULT_ISR_DEFINED_
+cyg_uint32
+hal_arch_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
+{
+ CYG_FAIL("Spurious interrupt!");
+ return 0;
+}
+# endif
+#else
+# ifndef _HAL_M68K_HAL_DEFAULT_ISR_DEFINED_
+cyg_uint32
+hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
+{
+ CYG_FAIL("Spurious interrupt!");
+ return 0;
+}
+# endif
+#endif
+
+// ----------------------------------------------------------------------------
+// Exception handling. The assembler routine calls this C function as
+// soon as possible. Usually exceptions are passed to gdb stubs - if
+// this application does not have gdb stubs included then the relevant
+// entries in the exception vector table will still belong to the stubs.
+
+
+void
+hal_m68k_exception_handler(HAL_SavedRegisters* regs)
+{
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+ // If we caught an exception inside the stubs, see if we were expecting it
+ // and if so jump to the saved address
+ extern void* volatile __mem_fault_handler;
+ if (__mem_fault_handler) {
+ regs->pc = (CYG_ADDRWORD)__mem_fault_handler;
+ return; // Caught an exception inside stubs
+ }
+
+ _hal_registers = regs;
+ __handle_exception();
+
+#elif defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && defined(CYGPKG_HAL_EXCEPTIONS)
+
+ CYG_WORD code;
+ HAL_CONTEXT_PCSR_GET_EXCEPTION(regs, code);
+ cyg_hal_deliver_exception(code, (CYG_ADDRWORD) regs);
+
+#else
+
+ CYG_FAIL("Exception!!!");
+
+#endif
+}
+
+// ----------------------------------------------------------------------------
+// C++ constructor support. The constructors are run in a separate function
+// so that a breakpoint can be set, at the cost of a couple of extra bytes
+// of code.
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+cyg_bool cyg_hal_stop_constructors = 0;
+#endif
+
+typedef void (*pfunc)(void);
+extern pfunc __CTOR_LIST__[];
+extern pfunc __CTOR_END__[];
+
+void
+cyg_hal_invoke_constructors(void)
+{
+#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
+ static pfunc* p = &__CTOR_END__[-1];
+ cyg_hal_stop_constructors = 0;
+ for ( ; p >= __CTOR_LIST__; p--) {
+ (*p)();
+ if (cyg_hal_stop_constructors) {
+ p--;
+ break;
+ }
+ }
+#else
+ pfunc* p;
+ for ( p = &__CTOR_END__[-1]; p >= __CTOR_LIST__; p--) {
+ (*p)();
+ }
+#endif
+}
+
+// ----------------------------------------------------------------------------
+// This entry point is called from vectors.S as soon as the C environment
+// has been set up. We are running on the startup stack, interrupts are
+// disabled, and the hardware is only minimally initialized. Most of
+// the initialization will usually be done by the platform HAL.
+
+externC void cyg_start(void);
+
+void
+hal_m68k_c_startup(void)
+{
+ int i;
+
+ for (i = 0; i < CYGNUM_HAL_ISR_COUNT; i++) {
+ cyg_hal_interrupt_handlers[i] = (CYG_ADDRESS) &hal_default_isr;
+ }
+
+#ifdef HAL_M68K_VAR_INIT
+ HAL_M68K_VAR_INIT();
+#endif
+#ifdef HAL_M68K_PROC_INIT
+ HAL_M68K_PROC_INIT();
+#endif
+#ifdef HAL_M68K_PLATFORM_INIT
+ HAL_M68K_PLATFORM_INIT();
+#endif
+
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ hal_if_init();
+#endif
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+ initialize_stub();
+#endif
+#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
+ {
+ extern void hal_ctrlc_isr_init(void);
+ hal_ctrlc_isr_init();
+ }
+#endif
+
+ cyg_hal_invoke_constructors();
+
+#ifdef HAL_M68K_VAR_INIT2
+ HAL_M68K_VAR_INIT2();
+#endif
+#ifdef HAL_M68K_PROC_INIT2
+ HAL_M68K_PROC_INIT2();
+#endif
+#ifdef HAL_M68K_PLATFORM_INIT2
+ HAL_M68K_PLATFORM_INIT2();
+#endif
+
+ // And call into application-level code
+ cyg_start();
+ for ( ; ; );
+}
Index: src/hal_misc.c
===================================================================
RCS file: src/hal_misc.c
diff -N src/hal_misc.c
--- src/hal_misc.c 29 May 2002 18:28:15 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,195 +0,0 @@
-//==========================================================================
-//
-// hal_misc.c
-//
-// HAL miscellaneous functions
-//
-//==========================================================================
-//####ECOSGPLCOPYRIGHTBEGIN####
-// -------------------------------------------
-// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-//
-// eCos is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 2 or (at your option) any later version.
-//
-// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with eCos; if not, write to the Free Software Foundation, Inc.,
-// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-//
-// As a special exception, if other files instantiate templates or use macros
-// or inline functions from this file, or you compile this file and link it
-// with other works to produce a work based on this file, this file does not
-// by itself cause the resulting work to be covered by the GNU General Public
-// License. However the source code for this file must still be made available
-// in accordance with section (3) of the GNU General Public License.
-//
-// This exception does not invalidate any other reasons why a work based on
-// this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
-// -------------------------------------------
-//####ECOSGPLCOPYRIGHTEND####
-//==========================================================================
-
-#include <pkgconf/hal.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/infra/diag.h> // diag_printf
-
-#include <cyg/hal/hal_arch.h> // HAL header
-
-#include <cyg/hal/hal_intr.h> // VSR/ISR defines
-
-//--------------------------------------------------------------------------
-// ISR tables
-volatile CYG_ADDRESS cyg_hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
-volatile CYG_ADDRWORD cyg_hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
-volatile CYG_ADDRESS cyg_hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];
-
-//--------------------------------------------------------------------------
-// VSR table
-
-// The cyg_hal_vsr_table table is variant-specific. Some processors must
-// have the VSR table at specific locations.
-
-/*****************************************************************************
-hal_default_exception_handler -- First level C exception handler
-
- The assembly default VSR handler calls this routine to handler the
-exception. When this routine returns, the state is restored to the state
-pointed to by regs.
-
- We declare this routine as weak so that other handlers can easily
-become the default exception handler.
-
-INPUT:
-
- vector: The exception vector number.
-
- regs: A pointer to the saved state.
-
-OUTPUT:
-
-RETURN VALUE:
-
- None
-
-*****************************************************************************/
-
-externC void
-hal_default_exception_handler(CYG_WORD vector, HAL_SavedRegisters *regs)
- __attribute__ ((weak));
-
-void hal_default_exception_handler(CYG_WORD vector, HAL_SavedRegisters *regs)
-{
-
-#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
- externC void __handle_exception(void);
- externC HAL_SavedRegisters * _hal_registers;
-
- // Set the pointer to the registers of the current exception
- // context. At entry the GDB stub will expand the
- // HAL_SavedRegisters structure into a (bigger) register array.
- _hal_registers = regs;
-
- __handle_exception();
-
-#elif defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \
- defined(CYGPKG_HAL_EXCEPTIONS)
-
- // We should decode the vector and pass a more appropriate
- // value as the second argument. For now we simply pass a
- // pointer to the saved registers. We should also divert
- // breakpoint and other debug vectors into the debug stubs.
-
- cyg_hal_deliver_exception(vector, (CYG_ADDRWORD)regs);
-
-#else
-
- CYG_FAIL("Exception!!!");
-
-#endif
-
- return;
-}
-
-//---------------------------------------------------------------------------
-// Default ISRs
-
-externC cyg_uint32
-hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
-{
- diag_printf("Spurious Interrupt: %d\n", vector);
-
-// CYG_FAIL("Spurious Interrupt!!!");
- return 0;
-}
-
-//---------------------------------------------------------------------------
-// Idle thread action
-
-void
-hal_idle_thread_action( cyg_uint32 count )
-{
-}
-
-//---------------------------------------------------------------------------
-// Determine the index of the ls bit of the supplied mask.
-
-cyg_uint32
-hal_lsbit_index(cyg_uint32 mask)
-{
- cyg_uint32 n = mask;
-
- static const signed char tab[64] =
- { -1, 0, 1, 12, 2, 6, 0, 13, 3, 0, 7, 0, 0, 0, 0, 14, 10,
- 4, 0, 0, 8, 0, 0, 25, 0, 0, 0, 0, 0, 21, 27 , 15, 31, 11,
- 5, 0, 0, 0, 0, 0, 9, 0, 0, 24, 0, 0 , 20, 26, 30, 0, 0, 0,
- 0, 23, 0, 19, 29, 0, 22, 18, 28, 17, 16, 0
- };
-
- n &= ~(n-1UL);
- n = (n<<16)-n;
- n = (n<<6)+n;
- n = (n<<4)+n;
-
- return tab[n>>26];
-}
-
-//---------------------------------------------------------------------------
-// Determine the index of the ms bit of the supplied mask.
-
-cyg_uint32
-hal_msbit_index(cyg_uint32 mask)
-{
- cyg_uint32 x = mask;
- cyg_uint32 w;
-
- // Phase 1: make word with all ones from that one to the right.
- x |= x >> 16;
- x |= x >> 8;
- x |= x >> 4;
- x |= x >> 2;
- x |= x >> 1;
-
- // Phase 2: calculate number of "1" bits in the word.
- w = (x & 0x55555555) + ((x >> 1) & 0x55555555);
- w = (w & 0x33333333) + ((w >> 2) & 0x33333333);
- w = w + (w >> 4);
- w = (w & 0x000F000F) + ((w >> 8) & 0x000F000F);
- return (cyg_uint32)((w + (w >> 16)) & 0xFF);
-
-}
-
-//---------------------------------------------------------------------------
-
Index: src/hal_startup.c
===================================================================
RCS file: src/hal_startup.c
diff -N src/hal_startup.c
--- src/hal_startup.c 29 May 2002 18:28:15 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,262 +0,0 @@
-//==========================================================================
-//####ECOSGPLCOPYRIGHTBEGIN####
-// -------------------------------------------
-// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-//
-// eCos is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 2 or (at your option) any later version.
-//
-// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with eCos; if not, write to the Free Software Foundation, Inc.,
-// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-//
-// As a special exception, if other files instantiate templates or use macros
-// or inline functions from this file, or you compile this file and link it
-// with other works to produce a work based on this file, this file does not
-// by itself cause the resulting work to be covered by the GNU General Public
-// License. However the source code for this file must still be made available
-// in accordance with section (3) of the GNU General Public License.
-//
-// This exception does not invalidate any other reasons why a work based on
-// this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
-// -------------------------------------------
-//####ECOSGPLCOPYRIGHTEND####
-//==========================================================================
-
-#include <pkgconf/hal.h>
-#include <cyg/hal/hal_startup.h>
-#include <cyg/hal/hal_memmap.h>
-#include <cyg/hal/hal_intr.h>
-#include <cyg/hal/hal_diag.h> // hal_diag_init
-#include <cyg/infra/diag.h> // diag_printf
-#include <string.h> // memcpy, memset
-
-externC void cyg_start(void);
-externC void hw_vsr_reset(void);
-
-#define CYG_HAL_RESET_DEBUG_ENABLE
-#ifdef CYG_HAL_RESET_DEBUG_ENABLE
-#define CYG_HAL_RESET_DEBUG diag_printf
-#else
-#define CYG_HAL_RESET_DEBUG()
-#endif // CYG_HAL_RESET_DEBUG_ENABLE
-
-/*****************************************************************************
-hal_vsr_init -- Initialize the vector table
-
-INPUT:
-
-OUTPUT:
-
-RETURN VALUE:
-
- None
-
-*****************************************************************************/
-static void hal_vsr_init(void)
-{
-
- /* Initialize the HAL's vector table with the ROM vector table. */
-
- memcpy((void*)cyg_hal_vsr_table, __romvec_start,
- (size_t)sizeof(cyg_hal_vsr_table));
-
-}
-
-/*****************************************************************************
-hal_vsr_init -- Initialize the ISRs
-
-INPUT:
-
-OUTPUT:
-
-RETURN VALUE:
-
- None
-
-*****************************************************************************/
-static void hal_isr_init(void)
-{
- int_t i;
-
- // Initialize all ISR entries to default.
-
- for (i = 0; i < CYGNUM_HAL_ISR_COUNT; i++)
- {
- cyg_hal_interrupt_handlers[i] = (CYG_ADDRESS) &hal_default_isr;
- cyg_hal_interrupt_data[i] = (CYG_ADDRWORD)0;
- cyg_hal_interrupt_objects[i] = (CYG_ADDRESS)0;
- }
-}
-
-/*****************************************************************************
-hal_init_ram_sections -- Initialize the RAM sections
-
- Initialize all RAM sections that the C code relies on. data, bss,
-sbss.
-
-INPUT:
-
-OUTPUT:
-
-RETURN VALUE:
-
- None
-
-*****************************************************************************/
-static void hal_init_ram_sections(void)
-{
-
- // Initialize the RAM data section from the ROM image of the data
- // section.
-
- memcpy(__ram_data_start, __rom_data_start, (size_t)__ram_data_size);
-
- // Initialize the bss and sbss sections to zero.
-
- memset(__bss_start, 0, (size_t)__bss_size);
- memset(__sbss_start, 0, (size_t)__sbss_size);
-}
-
-/*****************************************************************************
-cyg_hal_invoke_constructors -- Call static constructors
-
-INPUT:
-
-OUTPUT:
-
-RETURN VALUE:
-
- None
-
-*****************************************************************************/
-#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
-cyg_bool cyg_hal_stop_constructors;
-#endif
-
-typedef void (*pfunc) (void);
-extern pfunc __CTOR_LIST__[];
-extern pfunc __CTOR_END__[];
-
-static void cyg_hal_invoke_constructors(void)
-{
-#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
- static pfunc *p = &__CTOR_END__[-1];
-
- cyg_hal_stop_constructors = 0;
- for (; p >= __CTOR_LIST__; p--) {
- (*p) ();
- if (cyg_hal_stop_constructors) {
- p--;
- break;
- }
- }
-#else
- pfunc *p;
-
- for (p = &__CTOR_END__[-1]; p >= __CTOR_LIST__; p--)
- (*p) ();
-#endif
-}
-
-/*****************************************************************************
-hal_reset -- Reset vector routine
-
- This routine must be called with interrupts disabled and will never
-return.
-
- Only the assembly reset vector routine should call this routine.
-
-INPUT:
-
-OUTPUT:
-
-RETURN VALUE:
-
- None
-
-*****************************************************************************/
-void hal_reset(void) CYGBLD_ATTRIB_NORET;
-void hal_reset(void)
-{
- const char * fname;
-
- fname = __FUNCTION__;
-
- // Initialize the RAM sections that the rest of the C code requires.
-
- hal_init_ram_sections();
-
- // It is now safe to call C functions which may rely on initialized
- // data.
-
- // Initialize the ISR and VSR tables.
-
- hal_isr_init();
- hal_vsr_init();
-
- // Do any variant-specific reset initialization.
-
- var_reset();
-
- // Initialize the diagnostics IO.
-
- HAL_DIAG_INIT();
- CYG_HAL_RESET_DEBUG("%s: RESET\r\n", fname);
-
- // Call C++ constructors.
-
- CYG_HAL_RESET_DEBUG("%s: calling cyg_hal_invoke_constructors\r\n", fname);
- cyg_hal_invoke_constructors();
-
- // It should be safe to enable interrupts now.
-
- CYG_HAL_RESET_DEBUG("%s: lowering interrupt mask\r\n", fname);
- HAL_ENABLE_INTERRUPTS();
-
- // Call cyg_start. This routine should not return.
-
- CYG_HAL_RESET_DEBUG("%s: calling cyg_start\r\n", fname);
- cyg_start();
-
- // If we return, loop and print out a message.
-
- HAL_DIAG_INIT();
- for (;;)
- {
- CYG_HAL_RESET_DEBUG("%s: cyg_start returned!\r\n", fname);
- }
-}
-
-/*****************************************************************************
-hal_hw_reset -- Simulate a hardware reset
-
- This routine will never return.
-
-INPUT:
-
-OUTPUT:
-
-RETURN VALUE:
-
- None
-
-*****************************************************************************/
-void hal_hw_reset(void)
-{
-
- // Give control to the reset vector handler.
-
- hw_vsr_reset();
-}
-
Index: src/m68k.ld
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/m68k/arch/current/src/m68k.ld,v
retrieving revision 1.2
diff -u -p -r1.2 m68k.ld
--- src/m68k.ld 10 Apr 2003 18:07:54 -0000 1.2
+++ src/m68k.ld 20 Nov 2008 22:20:30 -0000
@@ -1,15 +1,14 @@
/*==========================================================================
//
-// m68k.ld
+// m68k.ld
//
-// Linker script
+// Linker script
//
//==========================================================================
-//####ECOSGPLCOPYRIGHTBEGIN####
-// -------------------------------------------
+//###ECOSGPLCOPYRIGHTBEGIN####
+//-------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-//
+// Copyright (C) 2003,2004,2005,2006,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.
@@ -32,24 +31,29 @@
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
+//###DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Date: 2003-06-04
+//
+//###DESCRIPTIONEND####
+//========================================================================
*/
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#define __LDI__ 1
+#include CYGHWR_MEMORY_LAYOUT_H
+
STARTUP(vectors.o)
-ENTRY(__exception_reset)
+ENTRY(hal_m68k_exception_reset)
#ifdef EXTRAS
INPUT(extras.o)
#endif
-#if (__GNUC__ >= 3)
GROUP(libtarget.a libgcc.a libsupc++.a)
-#else
-GROUP(libtarget.a libgcc.a)
-#endif
#define ALIGN_LMA 4
#define FOLLOWING(_section_) AT ((LOADADDR (_section_) + SIZEOF (_section_) + ALIGN_LMA - 1) & ~ (ALIGN_LMA - 1))
@@ -60,146 +64,236 @@ GROUP(libtarget.a libgcc.a)
# define CYG_LABEL_DEFN(_label) _label
#endif
+// Depending on the startup type and issues such as the memory map
+// before and after any remapping, _stext should usually be defined
+// either at the beginning of the .m68k_startup section or at the
+// beginning of the .text section. Or conceivably somewhere else, in
+// which case it is up to the platform-specific linker script or
+// code to define _stext. The platform HAL can specify the desired
+// behaviour via the LAYOUT_H file.
+#if defined(_HAL_M68K_STEXT_AT_M68K_TEXT_)
+# define _HAL_M68K_STARTUP_SECTION_STEXT_
+# define _HAL_TEXT_SECTION_STEXT_ _stext = . ;
+#elif defined(_HAL_M68K_STEXT_ELSEWHERE_)
+# define _HAL_M68K_STARTUP_SECTION_STEXT_
+# define _HAL_TEXT_SECTION_STEXT_
+#else
+# define _HAL_M68K_STARTUP_SECTION_STEXT_ _stext = . ;
+# define _HAL_TEXT_SECTION_STEXT_
+#endif
+
#define SECTIONS_BEGIN
-#define SECTION_text(_region_, _vma_, _lma_) \
- .text _vma_ : _lma_ \
- { _stext = .; \
- *(.text*) *(.gnu.warning) *(.gnu.linkonce*) *(.init) } \
- > _region_ \
- _etext = .; PROVIDE (etext = .);
-
-#define SECTION_fini(_region_, _vma_, _lma_) \
- .fini _vma_ : _lma_ \
- { FORCE_OUTPUT; *(.fini) } \
- > _region_
-
-#define SECTION_rodata1(_region_, _vma_, _lma_) \
- .rodata1 _vma_ : _lma_ \
- { FORCE_OUTPUT; *(.rodata1) } \
- > _region_
-
-#define SECTION_rodata(_region_, _vma_, _lma_) \
- .rodata _vma_ : _lma_ \
- { FORCE_OUTPUT; *(.rodata*) } \
- > _region_
-
-#define SECTION_fixup(_region_, _vma_, _lma_) \
- .fixup _vma_ : _lma_ \
- { __FIXUP_START__ = ABSOLUTE(.); *(.fixup) __FIXUP_END__ = ABSOLUTE(.);}\
- > _region_
-
-#define SECTION_gcc_except_table(_region_, _vma_, _lma_) \
- .gcc_except_table _vma_ : _lma_ \
- { __EXCEPT_START__ = ABSOLUTE(.); *(.gcc_except_table) \
- __EXCEPT_END__ = ABSOLUTE(.);} \
- > _region_
-
-#define SECTION_data(_region_, _vma_, _lma_, _rom_data_addr_) \
- .data _vma_ : _lma_ \
- { \
- __ram_data_start = ABSOLUTE(.); \
- *(.data*) \
- __GOT1_START__ = ABSOLUTE(.); *(.got1) __GOT1_END__ = ABSOLUTE(.); \
- . = ALIGN (4); \
- KEEP(*( SORT (.ecos.table.*))); \
- . = ALIGN (4); \
- __CTOR_LIST__ = ABSOLUTE(.); \
- KEEP(*(SORT(.ctors*))); \
- __CTOR_END__ = ABSOLUTE(.); \
- __DTOR_LIST__ = ABSOLUTE(.); \
- KEEP(*(SORT(.dtors*))) \
- __DTOR_END__ = ABSOLUTE(.); \
- . = ALIGN(8); \
- __GOT2_START__ = ABSOLUTE(.); *(.got2) __GOT2_END__ = ABSOLUTE(.); \
- __GOT_START = ABSOLUTE(.); _GLOBAL_OFFSET_TABLE_ = ABSOLUTE(. + 32768); \
- _SDA_BASE_ = ABSOLUTE(.); *(.got.plt) *(.got) \
- __GOT_END__ = ABSOLUTE(.); *(.dynamic) \
- *(.eh_frame) \
- /* We want the small data sections together, so single-instruction */ \
- /* offsets can access them all, and initialized data all before */ \
- /* uninitialized, so we can shorten the on-disk segment size. */ \
- __SDATA_START__ = ABSOLUTE(.); *(.sdata) \
- __ram_data_end = ABSOLUTE(.); \
- __ram_data_size = ABSOLUTE (.) - ABSOLUTE(__ram_data_start); \
- } \
- > _region_ \
- __rom_data_start = ABSOLUTE(_rom_data_addr_); \
- __rom_data_size = SIZEOF(.data); \
- __rom_data_end = __rom_data_start + __rom_data_size;
-
-#define SECTION_sbss(_region_, _vma_, _lma_) \
- .sbss _vma_ : _lma_ \
- { __sbss_start = ABSOLUTE (.); \
- __SBSS_START__ = ABSOLUTE(.); *(.sbss) __SBSS_END__ = ABSOLUTE(.); \
- *(.scommon) \
- __sbss_end = ABSOLUTE (.); \
- __sbss_size = ABSOLUTE (.) - ABSOLUTE(__sbss_start); \
- } \
- > _region_
-
-#define SECTION_bss(_region_, _vma_, _lma_) \
- .bss _vma_ : _lma_ \
- { __bss_start = ABSOLUTE (.); \
- FORCE_OUTPUT; *(.dynbss) *(.bss) *(COMMON) \
- __bss_end = ABSOLUTE (.); \
- __bss_size = ABSOLUTE (.) - ABSOLUTE(__bss_start); \
- } \
- > _region_
-
-#define SECTION_stab \
- .stab 0 (NOLOAD) : \
- { \
- *(.stab) \
- }
-
-#define SECTION_stabstr \
- .stabstr 0 (NOLOAD) : \
- { \
- *(.stabstr) \
- }
-
-#define SECTION_comment \
- .comment 0 (NOLOAD) : \
- { \
- *(.comment) \
- }
-
-#define SECTION_heap1(_region_, _vma_, _lma_, _minsize_) \
- .heap1 _vma_ : _lma_ \
- { __heap1_start = ABSOLUTE (.); \
- . += (_minsize_); \
- __heap1_end = ABSOLUTE (.); \
- __heap1_size = ABSOLUTE (.) - ABSOLUTE(__heap1_start); \
- } \
- > _region_
-
-#define SECTION_uninvar(_region_, _vma_, _lma_) \
- .uninvar _vma_ : _lma_ \
- { __uninvar_start = ABSOLUTE (.); \
- FORCE_OUTPUT; *(.uninvar) \
- __uninvar_end = ABSOLUTE (.); \
- __uninvar_size = ABSOLUTE (.) - ABSOLUTE(__uninvar_start); \
- } \
- > _region_
-
-#define GENERIC_SECTION(_name_, _region_, _vma_, _lma_, _minsize_) \
- . ## _name_ _vma_ : _lma_ \
- { __ ## _name_ ## _start = ABSOLUTE (.); \
- FORCE_OUTPUT; *(. ## _name_ ## ) \
- __ ## _name_ ## _datasize = (ABSOLUTE (.) - ABSOLUTE(__ ## _name_ ## _start)); \
- . += (_minsize_) > (__ ## _name_ ## _datasize) ? (_minsize_) - (__ ## _name_ ## _datasize) : 0; \
- __ ## _name_ ## _end = ABSOLUTE (.); \
- __ ## _name_ ## _size = (ABSOLUTE (.) - ABSOLUTE(__ ## _name_ ## _start)); \
- } \
- > _region_
-
-#define SECTIONS_END \
- SECTION_stab \
- SECTION_stabstr \
- SECTION_comment \
+// RAM vectors, i.e. the M68K exception table, the virtual vector table,
+// and possibly some data that needs to be shared between eCos and
+// RedBoot. Usually this will be located at 0 but may be at another
+// address via e.g. %vbr. Some platforms in some configurations may
+// have an empty ram vectors section with all the work done in
+// .vectors instead. The section may or may not be loadable.
+
+#define SECTION_ram_vectors(_region_, _vma_) \
+ . = ALIGN( _vma_ , ALIGN_LMA ) ; \
+ _hal_ram_vectors_section_start = . ; \
+ .ram_vectors . : { KEEP (*(.ram_vectors)) } > _region_ \
+ . = ALIGN(ALIGN_LMA) ; \
+ _hal_ram_vectors_section_end = . ; \
+ _hal_ram_vectors_section_size = _hal_ram_vectors_section_end - \
+ _hal_ram_vectors_section_start ;
+
+// .m68k_startup usually contains only the M68K startup code. It may also
+// contain the exception vectors if booting from flash and the exception
+// vectors are held in flash as well. .vectors.0 is for backwards
+// compatibility with older HALs.
+#define SECTION_m68k_start(_region_, _vma_) \
+ . = ALIGN( _vma_ , ALIGN_LMA ) ; \
+ _hal_m68k_start_section_start = . ; \
+ _HAL_M68K_STARTUP_SECTION_STEXT_ \
+ .m68k_start . : { KEEP (*(.m68k_start)) KEEP (*(.m68k_start.*)) KEEP (*(.vectors.0)) } > _region_ \
+ . = ALIGN(ALIGN_LMA) ; \
+ _hal_m68k_start_section_end = . ; \
+ _hal_m68k_start_section_size = _hal_m68k_start_section_end - _hal_m68k_start_section_start ;
+
+// Some coldfires booting from internal flash need a signature block at
+// a magic location
+#define SECTION_mcfxxxx_cfm_security_settings(_region_, _vma_) \
+ . = ALIGN( _vma_ , ALIGN_LMA ) ; \
+ _hal_mcfxxxx_cfm_security_settings_section_start = . ; \
+ .mcfxxxx_cfm_security_settings . : \
+ { \
+ FORCE_OUTPUT; \
+ KEEP (*(.mcfxxxx_cfm_security_settings)); \
+ } > _region_ \
+ . = ALIGN(ALIGN_LMA) ; \
+ _hal_mcfxxxx_cfm_security_settings_section_end = . ; \
+ _hal_mcfxxxx_cfm_security_settings_section_size = _hal_mcfxxxx_cfm_security_settings_section_end - \
+ _hal_mcfxxxx_cfm_security_settings_section_start ;
+
+// ----------------------------------------------------------------------------
+// C++ support. It should always be possible to discard the global destructors
+// since eCos applications are not expected to exit. The exception handling
+// support is normally needed only if linking with libstdc++, otherwise
+// there is no code in the system to use the exception frame info.
+#if defined(CYGINT_HAL_LINKER_SCRIPT_KEEP_DTORS)
+# define _DTORS1_ \
+ __DTOR_LIST__ = ABSOLUTE(.); \
+ KEEP(*(SORT(.dtors*))) \
+ __DTOR_END__ = ABSOLUTE(.); \
+# define _DTORS2_
+#else
+# define _DTORS1_
+# define _DTORS2_ /DISCARD/ : { *(.dtors*) }
+#endif
+
+#if defined(CYGPKG_LIBSTDCXX) || defined(CYGINT_HAL_LINKER_SCRIPT_KEEP_EH_FRAME)
+# define _EH_FRAME1_(_region_) \
+ .eh_frame . : { \
+ FORCE_OUTPUT; __EH_FRAME_BEGIN__ = ABSOLUTE(.); \
+ KEEP(*(.eh_frame)) \
+ . = ALIGN(ALIGN_LMA); \
+ __FRAME_END__ = ABSOLUTE(.); \
+ LONG(0) \
+ LONG(0) \
+ } > _region_ = 0
+# define _EH_FRAME2_
+#else
+# define _EH_FRAME1_(_region_)
+# define _EH_FRAME2_ /DISCARD/ : { *(.eh_frame) }
+#endif
+
+#if defined(CYGPKG_LIBSTDCXX) || defined(CYGINT_HAL_LINKER_SCRIPT_KEEP_GCC_EXCEPT_TABLE)
+# define _GCC_EXCEPT_TABLE1_(_region_) \
+ .gcc_except_table . : { \
+ __EXCEPT_START__ = ABSOLUTE(.); \
+ KEEP(*(.gcc_except_table)) *(.gcc_except_table.*) \
+ __EXCEPT_END__ = ABSOLUTE(.); \
+ } > _region_
+# define _GCC_EXCEPT_TABLE2_
+#else
+# define _GCC_EXCEPT_TABLE1_(_region_)
+# define _GCC_EXCEPT_TABLE2_ /DISCARD/ : { *(.gcc_except_table) *(.gcc_except_table.*) }
+#endif
+
+#define SECTION_code(_region_, _vma_) \
+ . = ALIGN( _vma_ , ALIGN_LMA ) ; \
+ _hal_code_section_start = . ; \
+ _hal_text_section_start = . ; \
+ _HAL_TEXT_SECTION_STEXT_ \
+ .text . : { \
+ *(.text*) *(.gnu.warning) *(.gnu.linkonce.t*) *(.init) \
+ . = ALIGN (4); \
+ __CTOR_LIST__ = ABSOLUTE(.); \
+ KEEP(*(SORT(.ctors*))); \
+ __CTOR_END__ = ABSOLUTE(.); \
+ . = ALIGN (4); \
+ _DTORS1_ \
+ } > _region_ \
+ . = ALIGN(ALIGN_LMA) ; \
+ _etext = . ; PROVIDE (etext = .) ; \
+ _hal_text_section_end = . ; \
+ _hal_text_section_size = _hal_text_section_end - _hal_text_section_start ; \
+ .rodata . : { *(.rodata1) *(.rodata*) *(.gnu.linkonce.r.*) } > _region_ \
+ . = ALIGN(ALIGN_LMA) ; \
+ _EH_FRAME1_(_region_) \
+ . = ALIGN(ALIGN_LMA) ; \
+ _GCC_EXCEPT_TABLE1_(_region_) \
+ . = ALIGN(ALIGN_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_ \
+ .fixup . : { \
+ __FIXUP_START__ = ABSOLUTE(.); \
+ *(.fixup) \
+ __FIXUP_END__ = ABSOLUTE(.); \
+ } > _region_ \
+ .got . : { \
+ FORCE_OUTPUT; *(.got.plt) *(.got) \
+ _GOT1_START_ = ABSOLUTE (.); *(.got1) _GOT1_END_ = ABSOLUTE (.); \
+ _GOT2_START_ = ABSOLUTE (.); *(.got2) _GOT2_END_ = ABSOLUTE (.); \
+ } > _region_ \
+ . = ALIGN(ALIGN_LMA) ; \
+ _hal_code_section_end = . ; \
+ _hal_code_section_size = _hal_code_section_end - _hal_code_section_start ; \
+ _DTORS2_ \
+ _EH_FRAME2_ \
+ _GCC_EXCEPT_TABLE2_
+
+#define SECTION_data(_region_, _vma_, _lma_) \
+ . = ALIGN( _vma_ , ALIGN_LMA ) ; \
+ _hal_data_section_start_vma = . ; \
+ .data . : _lma_ { \
+ *(.shdata*) *(.data*) *(.gnu.linkonce.d.*) *(.sdata) *(.gnu.linkonce.s.*) \
+ . = ALIGN (4); \
+ *(.2ram.*) \
+ . = ALIGN (4); \
+ KEEP(*( SORT (.ecos.table.*))); \
+ . = ALIGN (4); \
+ } > _region_ \
+ . = ALIGN(ALIGN_LMA); \
+ _hal_data_section_start_lma = LOADADDR(.data) ; \
+ _hal_data_section_end_vma = . ; \
+ _hal_data_section_size = _hal_data_section_end_vma - _hal_data_section_start_vma ; \
+ _hal_data_section_end_lma = _hal_data_section_start_lma + _hal_data_section_size ; \
+ _hal_bss_start = . ; \
+ .sbss . : { *(.sbss) *(.gnu.linkonce.sb.*) *(.scommon) } > _region_ \
+ . = ALIGN(ALIGN_LMA) ; \
+ .bss . : { *(.dynbss) *(.shbss) *(.bss*) *(.gnu.linkonce.b.*) *(COMMON) } > _region_ \
+ . = ALIGN(ALIGN_LMA) ; \
+ _hal_bss_end = . ; \
+ _hal_bss_size = _hal_bss_end - _hal_bss_start ;
+
+// Some ColdFire processors have on-chip RAM. Allocate .iram_text, .iram_data
+// .iram_bss in the expected fashion.
+#define SECTION_iram(_region_, _vma_, _lma_) \
+ . = ALIGN( _vma_ , ALIGN_LMA ) ; \
+ _hal_iram_section_start_vma = . ; \
+ _hal_iram_text_section_start_vma = . ; \
+ .iram_text . : _lma_ { *(.iram_text) *(.iram_text.*) } > _region_ =0 \
+ _hal_iram_text_section_start_lma = LOADADDR(.iram_text) ; \
+ . = ALIGN(ALIGN_LMA) ; \
+ _hal_iram_text_section_end_vma = . ; \
+ _hal_iram_text_section_size = _hal_iram_text_section_end_vma - _hal_iram_text_section_start_vma ; \
+ _hal_iram_text_section_end_lma = _hal_iram_text_section_start_lma + _hal_iram_text_section_size ; \
+ _hal_iram_data_section_start_vma = . ; \
+ .iram_data . : AT(_hal_iram_text_section_end_lma) { *(.iram_data) *(.iram_data.*) } > _region_ =0 \
+ . = ALIGN(ALIGN_LMA) ; \
+ _hal_iram_data_section_start_lma = LOADADDR(.iram_data) ; \
+ _hal_iram_data_section_end_vma = . ; \
+ _hal_iram_data_section_size = _hal_iram_data_section_end_vma - _hal_iram_data_section_start_vma ; \
+ _hal_iram_data_section_end_lma = _hal_iram_data_section_start_lma + _hal_iram_data_section_size ; \
+ _hal_iram_bss_section_start = . ; \
+ _iram_bss . (NOLOAD) : { *(.iram_bss) *(.iram_bss.*) } > _region_ =0 \
+ . = ALIGN(ALIGN_LMA) ; \
+ _hal_iram_bss_section_end = . ; \
+ _hal_iram_section_end_vma = . ; \
+ _hal_iram_section_size = _hal_iram_section_end_vma - _hal_iram_section_start_vma ; \
+ _hal_iram_section_start_lma = LOADADDR(.iram_text) ; \
+ _hal_iram_section_end_lma = _hal_iram_section_start_lma + _hal_iram_text_section_size + \
+ _hal_iram_data_section_size ;
+
+#define SECTIONS_END \
+ .stab 0 (NOLOAD) : { *(.stab) } \
+ .stabstr 0 (NOLOAD) : { *(.stabstr) } \
+ .comment 0 (NOLOAD) : { *(.comment) } \
. = ALIGN(4); _end = .; PROVIDE (end = .);
+// These macros are for backwards compatibility. Some are redundant.
+#define SECTION_fixed_vectors(_region_, _vma_, _lma_) SECTION_ram_vectors(_region_, _vma_)
+#define SECTION_vectors(_region_, _vma_, _lma_) SECTION_m68k_start(_region_, _vma_)
+#define SECTION_text(_region_, _vma_, _lma_) SECTION_code(_region_, _vma_)
+#define SECTION_rodata(_region_, _vma_, _lma_) SECTION_constants(_region_, _vma_)
+#define SECTION_rodata1(_region_, _vma_, _lma_)
+#define SECTION_fini(_region_, _vma_, _lma_)
+#define SECTION_fixup(_region_, _vma_, _lma_)
+#define SECTION_RELOCS(_region_, _vma_, _lma_)
+#define SECTION_eh_frame(_region_, _vma_, _lma_)
+#define SECTION_gcc_except_table(_region_, _vma_, _lma)
+#define SECTION_got(_region_, _vma_, _lma_)
+#define SECTION_sbss(_region_, _vma_, _lma_)
+#define SECTION_bss(_region_, _vma_, _lma_)
+
#include <pkgconf/system.h>
#include CYGHWR_MEMORY_LAYOUT_LDI
-
Index: src/m68k_stub.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/m68k/arch/current/src/m68k_stub.c,v
retrieving revision 1.1
diff -u -p -r1.1 m68k_stub.c
--- src/m68k_stub.c 29 May 2002 18:28:15 -0000 1.1
+++ src/m68k_stub.c 20 Nov 2008 22:20:30 -0000
@@ -1,15 +1,14 @@
-//========================================================================
+//==========================================================================
//
// m68k_stub.c
//
-// Helper functions for stub
+// M68K gdb support
//
-//========================================================================
-//####ECOSGPLCOPYRIGHTBEGIN####
-// -------------------------------------------
+//==========================================================================
+//###ECOSGPLCOPYRIGHTBEGIN####
+//-------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
-//
+// Copyright (C) 2003,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.
@@ -32,160 +31,138 @@
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//###DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Date: 2003-06-04
+//
+//###DESCRIPTIONEND####
//========================================================================
-#include <stddef.h>
-
#include <pkgconf/hal.h>
+#include <pkgconf/hal_m68k.h>
-#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
-#include <cyg/hal/hal_stub.h>
-
-#include <cyg/hal/hal_stub.h>
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
#include <cyg/hal/hal_arch.h>
#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_stub.h>
-#ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
-#include <cyg/hal/dbg-threads-api.h> // dbg_currthread_id
-#endif
+// Translate between the eCos save state and what is expected by the gdb
+// stubs. d0-d7/a0-a6 are in the right place already. SR/PS and the program
+// counter need to come from variant-specific macros. The stack pointer
+// can be determined from the saved context.
+externC void
+hal_get_gdb_registers(CYG_ADDRWORD* gdb_regs, HAL_SavedRegisters* ecos_regs)
+{
+ int sr;
+ int pc;
+ int i;
+ for (i = 0; i < 15; i++) {
+ gdb_regs[i] = ecos_regs->da[i];
+ }
+ gdb_regs[15] = (CYG_ADDRWORD) &(ecos_regs[1]);
+ HAL_CONTEXT_PCSR_GET_SR(ecos_regs, sr);
+ HAL_CONTEXT_PCSR_GET_PC(ecos_regs, pc);
+ gdb_regs[16] = sr;
+ gdb_regs[17] = pc;
+}
-/* Given a trap value TRAP, return the corresponding signal. */
+externC void
+hal_set_gdb_registers(HAL_SavedRegisters* ecos_regs, CYG_ADDRWORD* gdb_regs)
+{
+ int i;
+ for (i = 0; i < 15; i++) {
+ ecos_regs->da[i] = gdb_regs[i];
+ }
+ if (gdb_regs[15] != (CYG_ADDRWORD) &(ecos_regs[1])) {
+ CYG_FAIL("gdb has requested a thread context switch - not supported,");
+ }
+ HAL_CONTEXT_PCSR_SET_SR(ecos_regs, gdb_regs[16]);
+ HAL_CONTEXT_PCSR_SET_PC(ecos_regs, gdb_regs[17]);
+}
-int __computeSignal (unsigned int trap_number)
-{
- switch (trap_number)
- {
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
- case CYGNUM_HAL_VECTOR_BUSERR:
- case CYGNUM_HAL_VECTOR_ADDERR:
+externC int
+__computeSignal(unsigned int trap_number)
+{
+ switch(trap_number) {
+ case CYGNUM_HAL_EXCEPTION_DATA_ACCESS:
return SIGBUS;
-
- case CYGNUM_HAL_VECTOR_ILLINST:
+ case CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS:
+ case CYGNUM_HAL_EXCEPTION_SYSTEM_ERROR:
+ return SIGSEGV;
+ case CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION:
return SIGILL;
-
- case CYGNUM_HAL_VECTOR_ZERODIV:
- /* This isn't quite accurate: this is integer division only. */
+ case CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO:
return SIGFPE;
-
- case CYGNUM_HAL_VECTOR_CHKINST:
- case CYGNUM_HAL_VECTOR_TRAPVINST:
- return SIGTRAP;
-
- case CYGNUM_HAL_VECTOR_PRIVVIOLATION:
- return SIGILL;
- case CYGNUM_HAL_VECTOR_TRACE:
- /* Instruction trace */
+ case CYGNUM_HAL_EXCEPTION_TRACE:
+ case CYGNUM_HAL_VECTOR_TRAP0 ... CYGNUM_HAL_VECTOR_TRAP15:
+ default:
return SIGTRAP;
-
- case CYGNUM_HAL_VECTOR_L1010:
- case CYGNUM_HAL_VECTOR_L1111:
- case CYGNUM_HAL_VECTOR_UNINITINT:
- case CYGNUM_HAL_VECTOR_SPURINT:
- return SIGTRAP;
-
- case CYGNUM_HAL_VECTOR_TRAPFIRST ... CYGNUM_HAL_VECTOR_TRAPLAST:
- return SIGTRAP;
-
- case CYGNUM_HAL_VECTOR_AUTOVEC1 ... CYGNUM_HAL_VECTOR_AUTOVEC7:
- case CYGNUM_HAL_VECTOR_INTRFIRST ... CYGNUM_HAL_VECTOR_INTRLAST:
- /* External interrupt */
- return SIGINT;
-
- default:
- return SIGTERM;
}
}
-
-/* Return the trap number corresponding to the last-taken trap. */
-
-int __get_trap_number (void)
+externC int
+__get_trap_number(void)
{
- //extern int hal_m68k_trap_number;
-
- // The vector is not not part of the GDB register set so get it
- // directly from the save context.
- //return hal_m68k_trap_number;
-
- return 1;
+ int result = CYGNUM_HAL_EXCEPTION_SYSTEM_ERROR;
+ if ((HAL_SavedRegisters*)0 != _hal_registers) {
+ HAL_CONTEXT_PCSR_GET_EXCEPTION(_hal_registers, result);
+ }
+ return result;
}
-/* Set the currently-saved pc register value to PC. This also updates NPC
- as needed. */
-
-void set_pc (target_register_t pc)
+externC void
+set_pc(target_register_t pc)
{
- put_register (PC, pc);
+ _registers[PC] = pc;
}
-
-/*----------------------------------------------------------------------
- * Single-step support
- */
-
-/* Set things up so that the next user resume will execute one instruction.
- This may be done by setting breakpoints or setting a single step flag
- in the saved user registers, for example. */
-
-#define SR_TRACE 0x8000
-
-void __single_step (void)
+// Single-stepping just involves setting the trace bit in the status register
+externC void
+__single_step(void)
{
- target_register_t sr = get_register (PS);
-
- // Set trace flag in the exception context.
- sr |= SR_TRACE;
-
- put_register (PS, sr);
+ _registers[PS] |= HAL_M68K_SR_T;
}
-/* Clear the single-step state. */
-
-void __clear_single_step (void)
+externC void
+__clear_single_step(void)
{
- target_register_t sr = get_register (PS);
-
- // Clear single-step flag in the exception context.
- sr &= ~SR_TRACE;
-
- put_register (PS, sr);
+ _registers[PS] &= ~HAL_M68K_SR_T;
}
-
-void __install_breakpoints (void)
+// This breakpoint support is (probably) not needed because
+// single-stepping is supported instead.
+externC void
+__install_breakpoints(void)
{
- /* NOP since single-step HW exceptions are used instead of
- breakpoints. */
}
-void __clear_breakpoints (void)
+externC void
+__clear_breakpoints(void)
{
}
-
-/* If the breakpoint we hit is in the breakpoint() instruction, return a
- non-zero value. */
-
-int
-__is_breakpoint_function ()
+externC int
+__is_breakpoint_function(void)
{
- return get_register (PC) == (target_register_t)&CYG_LABEL_NAME(breakinst);
+ return _registers[PC] == (target_register_t)&_breakinst;
}
-
-/* Skip the current instruction. Since this is only called by the
- stub when the PC points to a breakpoint or trap instruction,
- we can safely just skip 4. */
-
-void __skipinst (void)
+// The 68K has variable length instructions so skipping an instruction
+// is messy. However __skipinst() is only used for a breakpoint
+// instruction or for a trap, and these are always 2 bytes.
+externC void
+__skipinst(void)
{
- put_register (PC, get_register (PC) + 4);
+ _registers[PC] += 2;
}
-#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
-
+#endif
Index: src/plf_stub.h
===================================================================
RCS file: src/plf_stub.h
diff -N src/plf_stub.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/plf_stub.h 20 Nov 2008 22:20:30 -0000
@@ -0,0 +1,72 @@
+#ifndef CYGONCE_HAL_PLF_STUB_H
+#define CYGONCE_HAL_PLF_STUB_H
+
+//=============================================================================
+//
+// plf_stub.h
+//
+// Generic platform header for GDB stub support.
+//
+//=============================================================================
+//###ECOSGPLCOPYRIGHTBEGIN####
+//-------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003,2006,2007,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.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Date: 2003-06-04
+//
+//####DESCRIPTIONEND####
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h> // CYG_UNUSED_PARAM
+#include <cyg/hal/hal_arch.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+//----------------------------------------------------------------------------
+// Define some platform specific communication details. This is mostly
+// handled by hal_if now, but we need to make sure the comms tables are
+// properly initialized.
+
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_COMMS
+# define HAL_STUB_PLATFORM_INIT_SERIAL() CYG_EMPTY_STATEMENT
+#else
+externC void cyg_hal_plf_comms_init(void);
+# define HAL_STUB_PLATFORM_INIT_SERIAL() cyg_hal_plf_comms_init()
+#endif
+
+# define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int, (baud))
+# define HAL_STUB_PLATFORM_INTERRUPTIBLE 0
+# define HAL_STUB_PLATFORM_INIT() CYG_EMPTY_STATEMENT
+
+#endif
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_HAL_PLF_STUB_H
+// End of plf_stub.h
Index: src/vectors.S
===================================================================
RCS file: src/vectors.S
diff -N src/vectors.S
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/vectors.S 20 Nov 2008 22:20:30 -0000
@@ -0,0 +1,251 @@
+// #========================================================================
+// #
+// # vectors.S
+// #
+// # M68K startup and exception handling.
+// #
+// #========================================================================
+//###ECOSGPLCOPYRIGHTBEGIN####
+//-------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003,2004,2005,2006,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.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//###DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Date: 2003-06-04
+//
+//###DESCRIPTIONEND####
+//========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_m68k.h>
+#include CYGBLD_HAL_TARGET_H
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/arch.inc>
+
+// ----------------------------------------------------------------------------
+// These are for compatibility with older HALs
+#ifdef HAL_M68K_EXCEPTION_VECTORS
+# define _HAL_M68K_START_ HAL_M68K_EXCEPTION_VECTORS
+# undef HAL_M68K_EXCEPTION_VECTORS
+#endif
+#ifdef HAL_M68K_COPY_ROM_DATA_TO_RAM
+# define _HAL_M68K_COPY_ROM_DATA_TO_RAM_ 1
+# undef HAL_M68K_COPY_ROM_DATA_TO_RAM
+#endif
+
+// ----------------------------------------------------------------------------
+// Exception vectors. Typically there are two exception vectors. There is
+// one in flash which contains the h/w entry point. This is the section
+// .m68k_start. Then there is the run-time set of exception vectors, typically
+// held in RAM, which is the section .ram_vectors. In addition to the pointers
+// to the exception and interrupt VSRs that section contains the virtual vector
+// table and any data that needs to be shared between RedBoot and the application,
+// for example shadow copies of read-only registers.
+//
+// Typical scenarios include the following:
+//
+// 1) _HAL_M68K_START_ code relocates the flash from its boot location of 0x0
+// to somewhere else. _HAL_M68K_PLATFORM_SETUP1_ initializes SDRAM and
+// places it at 0x0. _HAL_M68K_START_ only contains the two initial exception
+// vector slots for the start address and stack, the RAM vectors are fully
+// populated at run-time by the architectural HAL. This is the typical
+// scenario for "large" systems.
+//
+// 2) for "small" systems where usually there is no RedBoot and the application
+// runs directly from flash, all the exception vectors also reside in flash
+// and are statically initialized. _HAL_M68K_START_ contains the full set
+// of vectors.
+//
+// 3) as a variant of (2) the run-time exception vectors may live in RAM,
+// typically relocated via the VBR register. The vectors will usually be
+// dynamically initialized, but if the application is loaded via gdb then
+// some code may be saved by static initialization.
+
+
+ .section ".m68k_start", "ax"
+ // This will typically be defined by the platform HAL to get the world
+ // in a sane state. It should do one-off initializations like getting
+ // the system into a state matching the memory map. If booting from
+ // flash it should also contain the initial PC and stack exception
+ // vectors.
+#ifdef _HAL_M68K_START_
+ _HAL_M68K_START_
+#endif
+
+ .section ".m68k_start.hal_m68k_exception_reset", "ax"
+ // The actual entry point, as defined in the linker script. The exact
+ // state of the system at this point depends on the configuration and
+ // the processor.
+ .global hal_m68k_exception_reset
+ .type hal_m68k_exception_reset, function
+hal_m68k_exception_reset:
+
+ // Make absolutely sure that the status register is in a
+ // sensible state with interrupts disabled, irrespective of
+ // the platform.
+ mov.w #0x2700,%sr
+
+ // Platform-specific initialization. This will do things like starting
+ // up the SDRAM controller. It may also run variant and processor
+ // initialization code, but the platform HAL gets to decide the order.
+#ifdef _HAL_M68K_PLATFORM_SETUP1_
+ _HAL_M68K_PLATFORM_SETUP1_
+#endif
+
+ // All memory should now be running so we can get the C environment
+ // set up. Clear BSS before switching to C mode
+ .extern _hal_bss_start
+ .extern _hal_bss_end
+ move.l # _hal_bss_start,%a0
+ move.l # _hal_bss_end,%a1
+1:
+ cmp.l %a0,%a1
+ ble 2f
+ clr.l (%a0)+
+ jra 1b
+2:
+
+ // If booting from ROM, move .data from ROM to RAM
+#ifdef _HAL_M68K_COPY_ROM_DATA_TO_RAM_
+ .extern _hal_data_section_start_lma
+ .extern _hal_data_section_end_lma
+ .extern _hal_data_section_start_vma
+ move.l # _hal_data_section_start_lma, %a0
+ move.l # _hal_data_section_end_lma, %a1
+ move.l # _hal_data_section_start_vma, %a2
+1:
+ cmp.l %a0,%a1
+ ble 2f
+ mov.l (%a0)+,(%a2)+
+ jra 1b
+2:
+#endif
+
+ // If there is an FPU, set the default mode
+#ifdef CYGINT_HAL_M68K_VARIANT_FPU
+ mov.w # CYGNUM_HAL_M68K_FPU_CR_DEFAULT, %fpcr
+#endif
+
+ // If there is on-chip RAM, copy code and data there and clear
+ // its BSS.
+#ifdef _HAL_M68K_INITIALIZE_IRAM_
+ .extern _hal_iram_text_section_start_lma
+ .extern _hal_iram_data_section_end_lma
+ .extern _hal_iram_text_section_start_vma
+ .extern _hal_iram_bss_section_start
+ .extern _hal_iram_bss_section_end
+
+ move.l # _hal_iram_text_section_start_lma, %a0
+ move.l # _hal_iram_data_section_end_lma, %a1
+ move.l # _hal_iram_text_section_start_vma, %a2
+1:
+ cmp.l %a0, %a1
+ ble 2f
+ mov.l (%a0)+, (%a2)+
+ jra 1b
+2:
+ move.l # _hal_iram_bss_section_start, %a0
+ move.l # _hal_iram_bss_section_end, %a1
+3:
+ cmp.l %a0, %a1
+ ble 4f
+ clr.l (%a0)+
+ jra 3b
+4:
+#endif
+
+ // Now we just need a valid stack and we can switch to C
+ // for the remaining initialization. Clearing the frame
+ // pointer may make life easier for gdb.
+ mov.l _HAL_M68K_STARTUP_STACK_,%sp
+ suba.l %a6, %a6
+
+ .extern hal_m68k_c_startup
+ jmp hal_m68k_c_startup
+
+// The exception vector table. Usually this will be held in RAM
+// at location 0x0, although it may get moved around via e.g.
+// the %vbr register. In addition to the exception vectors the
+// virtual vector table is held here, as is any data that needs
+// to be shared between RedBoot and eCos.
+//
+// Some targets in some configurations may define their own version
+// of this, if for example the exception vector is held in ROM.
+#if defined(_HAL_M68K_RAM_VECTORS_)
+
+ _HAL_M68K_RAM_VECTORS_
+
+#elif !defined(_HAL_M68K_RAM_VECTORS_DEFINED_)
+ .section ".ram_vectors", "aw", @nobits
+
+# ifndef _HAL_M68K_SUPPRESS_RAM_VECTORS_VSR_TABLE_
+ // Start with the interrupt/exception vectors.
+ .global hal_m68k_vsr_table
+hal_m68k_vsr_table:
+ .rept HAL_M68K_VSR_COUNT
+ .long 0
+ .endr
+# endif
+
+ // Next the virtual vector table. Space for this is usually allocated,
+ // even if virtual vectors are not supported. That avoids confusion
+ // if RedBoot and the application are configured differently. If a
+ // platform will never support RedBoot, e.g. because of lack of memory,
+ // then it can suppress the virtual vectors.
+ //
+ // The size of the table comes from <cyg/hal/hal_if.h>,
+ // CYGNUM_CALL_IF_TABLE_SIZE, but that header cannot easily be included
+ // in assembler.
+# ifndef _HAL_M68K_SUPPRESS_VIRTUAL_VECTOR_
+ .global hal_virtual_vector_table
+hal_virtual_vector_table:
+ .rept 64
+ .long 0
+ .endr
+# endif
+
+ // Allow the variant, processor and platform HALs to store additional
+ // information in the global vectors section. Typically this is used for
+ // data which needs to be shared between RedBoot and the application,
+ // e.g. shadow copies of write-only hardware registers.
+# ifdef _HAL_M68K_VARIANT_RAM_VECTORS_
+ _HAL_M68K_VARIANT_RAM_VECTORS_
+# endif
+# ifdef _HAL_M68K_PROCESSOR_RAM_VECTORS_
+ _HAL_M68K_PROCESSOR_RAM_VECTORS_
+# endif
+# ifdef _HAL_M68K_PLATFORM_RAM_VECTORS_
+ _HAL_M68K_PLATFORM_RAM_VECTORS_
+# endif
+#endif // _HAL_M68K_RAM_VECTORS_DEFINED_
+
+
+// ----------------------------------------------------------------------------
+// end of vectors.S
Index: tests/iram1.c
===================================================================
RCS file: tests/iram1.c
diff -N tests/iram1.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/iram1.c 20 Nov 2008 22:20:30 -0000
@@ -0,0 +1,201 @@
+//=================================================================
+//
+// iram.c
+//
+// Test support for on-chip memory
+//
+//==========================================================================
+//###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.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Date: 2008-01-14
+//
+//####DESCRIPTIONEND####
+//=============================================================================
+
+#include <pkgconf/system.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/testcase.h>
+#include <cyg/infra/diag.h>
+#include <cyg/infra/cyg_ass.h>
+
+#if !defined(CYGMEM_REGION_iram)
+# define NA_MSG "No IRAM memory region defined"
+#elif defined(CYGMEM_REGION_ram) && (CYGMEM_REGION_iram == CYGMEM_REGION_ram)
+# define NA_MSG "IRAM is used as the main RAM memory bank"
+#endif
+
+#ifdef NA_MSG
+
+externC void
+cyg_start( void)
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA(NA_MSG);
+}
+
+#else // NA_MSG
+
+// These are provided by the linker script
+externC cyg_uint8 _hal_iram_section_start_vma[];
+externC cyg_uint8 _hal_iram_bss_section_start[];
+externC cyg_uint8 _hal_iram_section_end_vma[];
+
+// The external declarations which allow the attributes to be
+// specified.
+externC void onchip_fn1(void) CYGBLD_ATTRIB_SECTION(".iram_text.onchip_fn1");
+externC int onchip_fn2(int) CYGBLD_ATTRIB_SECTION(".iram_text.onchip_fn2");
+extern int onchip_data1[8] CYGBLD_ATTRIB_SECTION(".iram_data.onchip_data1");
+extern char onchip_data2 CYGBLD_ATTRIB_SECTION(".iram_data.onchip_data2");
+extern int onchip_data3[1024] CYGBLD_ATTRIB_SECTION(".iram_data.onchip_data3");
+extern int onchip_bss1 CYGBLD_ATTRIB_SECTION(".iram_bss.onchip_bss1");
+extern int onchip_bss2[42] CYGBLD_ATTRIB_SECTION(".iram_bss.onchip_bss2");
+
+// Then the definitions. data3 should be garbage collected by the linker.
+int onchip_data1[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+char onchip_data2 = 42;
+int onchip_data3[1024] = { 1 } ;
+int onchip_bss1;
+int onchip_bss2[42];
+
+void
+onchip_fn1(void)
+{
+ int i, data1_sum, fn2_result;
+
+ diag_printf("PASS:<onchip_fn1 running>\n");
+
+ // Check again that the data has been correctly initialized,
+ // that there are no addressing funnies, and that the data can
+ // be overwritten.
+ for (i = 0, data1_sum = 0; i < 8; i++) {
+ data1_sum += onchip_data1[i];
+ onchip_data1[i] -= i;
+ }
+ if (36 != data1_sum) {
+ diag_printf("FAIL:<onchip data1 array should add up to 36>\n");
+ }
+
+ for (i = 0, data1_sum = 0; i < 8; i++) {
+ data1_sum += onchip_data1[i];
+ }
+ if (8 != data1_sum) {
+ diag_printf("FAIL:<onchip data1 array should now add up to 8>\n");
+ }
+ // Call one on-chip function from another.
+ fn2_result = onchip_fn2(data1_sum);
+ if (861 != fn2_result) {
+ diag_printf("FAIL:<onchip_fn2 should return 903>\n");
+ }
+}
+
+int
+onchip_fn2(int arg)
+{
+ int i;
+ int result;
+ diag_printf("PASS:<onchip_fn2 running>\n");
+
+ // Make sure that the on-chip bss is correctly zero-initialized
+ // and writable.
+ for (i = 0; i < 42; i++) {
+ if (0 != onchip_bss2[i]) {
+ diag_printf("FAIL:<onchip bss2 should be initialized to 0>\n");
+ }
+ onchip_bss2[i] = i;
+ }
+ for (i = 0, result = 0; i < 42; i++) {
+ result += onchip_bss2[i];
+ }
+ return result;
+}
+
+void
+check_addr(void* where)
+{
+ if ((where < (void*)_hal_iram_section_start_vma) || (where >= (void*)_hal_iram_section_end_vma)) {
+ diag_printf("FAIL:<ptr %p is not in IRAM region\n", where);
+ }
+}
+
+externC void
+cyg_start( void)
+{
+ int i;
+ int data1_sum;
+
+ CYG_TEST_INIT();
+ // For human inspection
+ diag_printf("INFO:<IRAM usage : %p -> %p\n", _hal_iram_section_start_vma, _hal_iram_section_end_vma);
+ diag_printf("INFO:<IRAM bss @ %p\n", _hal_iram_bss_section_start);
+ diag_printf("INFO:<RAM : %p -> %p\n", (void*)CYGMEM_REGION_ram, (void*)(CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE));
+ diag_printf("INFO:<onchip_fn1 @ %p>\n", &onchip_fn1);
+ diag_printf("INFO:<onchip_fn2 @ %p>\n", &onchip_fn2);
+ diag_printf("INFO:<onchip_data1 @ %p>\n", &onchip_data1[0]);
+
+ // Make sure that IRAM is really separate from main memory.
+ if ((_hal_iram_section_start_vma >= (cyg_uint8*)CYGMEM_REGION_ram) &&
+ (_hal_iram_section_start_vma < (cyg_uint8*)(CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE))) {
+ CYG_TEST_FAIL("IRAM start overlaps SDRAM");
+ }
+ if ((_hal_iram_section_end_vma >= (cyg_uint8*)CYGMEM_REGION_ram) &&
+ (_hal_iram_section_end_vma < (cyg_uint8*)(CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE))) {
+ CYG_TEST_FAIL("IRAM end overlaps SDRAM");
+ }
+
+ // Make sure that various objects are correctly placed.
+ check_addr(&onchip_fn1);
+ check_addr(&onchip_fn2);
+ check_addr(&onchip_data1[0]);
+ check_addr(&onchip_data2);
+ // Not data3, we want that one to be garbage collected.
+ check_addr(&onchip_bss1);
+ check_addr(&onchip_bss2[0]);
+
+ // Check that on-chip data is correctly initialized.
+ CYG_TEST_CHECK( 42 == onchip_data2, "onchip_data2 should be the answer");
+ for (i = 0, data1_sum = 0; i < 8; i++) {
+ data1_sum += onchip_data1[i];
+ }
+ CYG_TEST_CHECK( 36 == data1_sum, "onchip data1 array should add up to 36");
+
+ // Make sure we can call code located in iram.
+ {
+ void (*onchip_fn1_ptr)(void) = &onchip_fn1;
+ (*onchip_fn1_ptr)();
+ }
+
+ CYG_TEST_PASS_FINISH("IRAM test");
+}
+
+#endif // NA_MSG