summaryrefslogtreecommitdiff
path: root/ecos/packages/hal/common
diff options
context:
space:
mode:
authorMichael Gielda <mgielda@antmicro.com>2014-04-03 14:53:04 +0200
committerMichael Gielda <mgielda@antmicro.com>2014-04-03 14:53:04 +0200
commitae1e4e08a1005a0c487f03ba189d7536e7fdcba6 (patch)
treef1c296f8a966a9a39876b0e98e16d9c5da1776dd /ecos/packages/hal/common
parentf157da5337118d3c5cd464266796de4262ac9dbd (diff)
Added the OS files
Diffstat (limited to 'ecos/packages/hal/common')
-rw-r--r--ecos/packages/hal/common/current/ChangeLog2403
-rw-r--r--ecos/packages/hal/common/current/cdl/common.cdl194
-rw-r--r--ecos/packages/hal/common/current/cdl/debugging.cdl169
-rw-r--r--ecos/packages/hal/common/current/cdl/hal.cdl481
-rw-r--r--ecos/packages/hal/common/current/cdl/interrupts.cdl142
-rw-r--r--ecos/packages/hal/common/current/doc/hal.sgml3159
-rw-r--r--ecos/packages/hal/common/current/doc/porting.sgml4391
-rw-r--r--ecos/packages/hal/common/current/include/dbg-thread-syscall.h110
-rw-r--r--ecos/packages/hal/common/current/include/dbg-threads-api.h160
-rw-r--r--ecos/packages/hal/common/current/include/drv_api.h250
-rw-r--r--ecos/packages/hal/common/current/include/generic-stub.h364
-rw-r--r--ecos/packages/hal/common/current/include/hal_arbiter.h139
-rw-r--r--ecos/packages/hal/common/current/include/hal_endian.h109
-rw-r--r--ecos/packages/hal/common/current/include/hal_if.h756
-rw-r--r--ecos/packages/hal/common/current/include/hal_misc.h122
-rw-r--r--ecos/packages/hal/common/current/include/hal_spd.h77
-rw-r--r--ecos/packages/hal/common/current/include/hal_stub.h406
-rw-r--r--ecos/packages/hal/common/current/include/hal_tables.h116
-rw-r--r--ecos/packages/hal/common/current/src/board.h69
-rw-r--r--ecos/packages/hal/common/current/src/bplist-dynamic.c449
-rw-r--r--ecos/packages/hal/common/current/src/dbg-threads-syscall.c216
-rw-r--r--ecos/packages/hal/common/current/src/drv_api.c943
-rw-r--r--ecos/packages/hal/common/current/src/dummy.c53
-rw-r--r--ecos/packages/hal/common/current/src/gdb-fileio.c728
-rw-r--r--ecos/packages/hal/common/current/src/gdb-fileio.h139
-rw-r--r--ecos/packages/hal/common/current/src/generic-stub.c2057
-rw-r--r--ecos/packages/hal/common/current/src/hal_if.c1116
-rw-r--r--ecos/packages/hal/common/current/src/hal_misc.c200
-rw-r--r--ecos/packages/hal/common/current/src/hal_stub.c1037
-rw-r--r--ecos/packages/hal/common/current/src/stubrom/stubrom.c60
-rw-r--r--ecos/packages/hal/common/current/src/thread-packets.c1414
-rw-r--r--ecos/packages/hal/common/current/src/thread-pkts.h105
-rw-r--r--ecos/packages/hal/common/current/tests/basic.c109
-rw-r--r--ecos/packages/hal/common/current/tests/cache.c240
-rw-r--r--ecos/packages/hal/common/current/tests/context.c120
-rw-r--r--ecos/packages/hal/common/current/tests/cpp1.c108
-rw-r--r--ecos/packages/hal/common/current/tests/intr.c156
-rw-r--r--ecos/packages/hal/common/current/tests/vaargs.c156
38 files changed, 23023 insertions, 0 deletions
diff --git a/ecos/packages/hal/common/current/ChangeLog b/ecos/packages/hal/common/current/ChangeLog
new file mode 100644
index 0000000..03a7c83
--- /dev/null
+++ b/ecos/packages/hal/common/current/ChangeLog
@@ -0,0 +1,2403 @@
+2013-06-13 Ilija Kocho <ilijak@siva.com.mk>
+
+ * tests/cache.c : Fix compiler warning about variable set but not used.
+ [ Bugzilla 1001865 ]
+
+2012-04-25 Ilija Kocho <ilijak@siva.com.mk>
+
+ * include/hal_stub.h, src/hal_stub.c, src/thread-packets.c:
+ NUMREGS replaced by HAL_STUB_REGISTERS_SIZE in thread-packets.c
+ [Bugzilla 1001558]
+
+2012-03-14 Grant Edwards <grant.b.edwards@gmail.com>
+
+ * src/generic-stub.c (process_query): Fix compiler warning about
+ variable that is set but not used (only used in conditionally
+ compiled code). [ Bugzilla 1001535 ]
+
+2012-03-09 Sergei Gavrikov <sergei.gavrikov@gmail.com>
+
+ * src/hal_if.c (hal_ctrlc_check): Fix compiler warning about
+ variable that is set but not used (isr_ret has been removed).
+
+2011-01-13 John Dallaway <john@dallaway.org.uk>
+
+ * cdl/hal.cdl: Add a CDL interface to control whether interrupt
+ state must be saved. [ Bugzilla 1001111 ]
+ * cdl/debugging.cdl: Implement the new interface within GDB Ctrl-C
+ break options.
+ * src/hal_if.c: Make declaration of the hal_saved_interrupt_state
+ variable conditional on an implementation of the new CDL interface.
+
+2010-11-20 John Dallaway <john@dallaway.org.uk>
+
+ * cdl/hal.cdl: Suppress -fprofile-arcs (which implies -lgcov) when
+ generating extras.o.
+
+2010-10-09 John Dallaway <john@dallaway.org.uk>
+
+ * doc/porting.sgml: Delete references to the memory layout editor.
+
+2009-02-02 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/hal.cdl: add CYGBLD_GLOBAL_WARNFLAGS, as part of global
+ compiler flags update.
+
+2008-11-21 Bart Veer <bartv@ecoscentric.com>
+
+ * include/hal_if.h (CYGNUM_CALL_IF_available_x): fix typo in
+ previous patch.
+
+2008-11-20 Bart Veer <bartv@ecoscentric.com>
+
+ * cdl/hal.cdl, include/hal_if.h, src/hal_if.c: expunge
+ CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_CACHE and the corresponding code.
+
+2008-05-20 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/thread-packets.c (threadmatch): Silence pointer signedness
+ warning.
+ (threadref_to_int): Ditto.
+ * src/generic-stub.c (__mem2hex): Ditto.
+ (__mem2hex_safe): Ditto.
+ (__hex2mem): Ditto.
+ (__hex2mem_safe): Ditto.
+ * src/hal_if.c (delay_us): Ditto.
+ * include/hal_stub.h (CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION):
+ Instead of using a local variable to avoid compiler reordering
+ when taking the address of a label, instead call an external function.
+ (NB making the variable volatile isn't sufficient).
+
+2008-05-13 Chris Zimman <czimman@bloomberg.com>
+
+ * cdl/hal.cdl: Work around problem with current ARM EABI tools by
+ using /dev/null as linker script. Should be safe with other tools.
+
+2007-11-27 Bart Veer <bartv@ecoscentric.com>
+
+ * src/hal_if.c (delay_us): use HAL_DELAY_US() rather than the
+ fancy implementation if the port cannot provide HAL_CLOCK_READ()
+
+2007-09-27 Grant Edwards <grante@visi.com>
+
+ * include/hal_endian.h (SWAP16): Fix "return value" so
+ that it only returns data in lower 16 bits instead of 24.
+
+2006-05-09 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * src/hal_if.c (cyg_hal_diag_mangler_gdb_flush): Fix compiler
+ warning about signed/unsigned.
+
+2006-04-19 Alexander Neundorf <alexander.neundorf@jenoptik.com
+
+ * include/hal_if.h, src/hal_if.c: add a VV call for modifying
+ the FIS table from eCos applications
+
+2005-06-27 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * include/hal_tables.h (CYG_HAL_TABLE_{QUALIFIED_}ENTRY): added
+ CYGBLD_ATTRIB_USED so that gcc 3.4.4 does not discard entries
+ which are not refereced explicitly. Problem reported by
+ Oliver Munz.
+
+2005-06-26 Bart Veer <bartv@ecoscentric.com>
+
+ * doc/hal.sgml: make HAL_DELAY_US() mandatory and define it to be
+ thread-safe.
+
+2005-05-19 Peter Korsgaard <jacmet@sunsite.dk>
+
+ * doc/porting.sgml: Changed dead sourceware.cygnus.com links to
+ ecos.sourceware.org.
+
+2005-04-27 Enrico Piria <epiria@libero.it>
+
+ * src/hal_if.c Added missing declarations of tries when compiling
+ with CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0.
+
+2005-02-17 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/common.cdl: Add CYGBLD_HAL_LINKER_GROUPED_LIBS to allow
+ CDL setting of libraries used for GROUP() directive in linker
+ script.
+
+2004-11-20 Andrew Lunn <andrew.lunn@ascom.ch>
+
+ * tests/intr.c: Make the ISR call the DSR to make sure this works
+ correctly.
+
+2004-08-22 Gary Thomas <gary@mlbassoc.com>
+
+ * doc/porting.sgml: Replace [very misleading dated] comments
+ about CygMon and platforms which use/need GDB stubs.
+
+2004-08-12 Jani Monoses <jani@iv.ro>
+
+ * include/hal_if.h: Make monitor locking work with CYGPKG_LWIP.
+
+2004-05-19 John Newlin <jnewlin@stretchinc.com>
+
+ * src/hal_stub.c:
+ (cyg_hal_gdb_interrupt)
+ (cyg_hal_gdb_remove_break): Changed both to use
+ _read_mem_safe/__write_mem_safe for inserting a breakpoint, and
+ restoring the original instruction.
+ The Xtensa architecture (and others maybe?) can have unaligned
+ instructions, which caused unaligned load/store exception.
+
+2004-04-22 Jani Monoses <jani@iv.ro>
+
+ * cdl/hal.cdl :
+ Invoke tail with stricter syntax that works in latest coreutils.
+
+2004-02-23 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/debugging.cdl (CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS): Included
+ stubs should always mean saving full context both on interrupts
+ and context swaps, so make it explicit.
+
+2004-01-05 Gary Thomas <gary@mlbassoc.com>
+
+ * include/hal_if.h: Minor fixup - new 'fconfig' functions broke
+ existing uses of CYGACC_CALL_IF_FLASH_CFG_OP. Added a new macro
+ CYGACC_CALL_IF_FLASH_CFG_OP2 which handles new API and a wrapper
+ to handle the old way (backwards compatability).
+
+2003-12-21 Gary Thomas <gary@mlbassoc.com>
+
+ * src/hal_if.c (flash_config_op):
+ * include/hal_if.h: New expanded functions for RedBoot 'fconfig'
+ database.
+
+2003-09-04 Patrick Doyle <wpd@dtccom.com>
+
+ * include/hal_if.h:
+ * src/hal_if.c (flash_fis_op): Added support for the rest of the
+ FIS operations.
+
+2003-08-06 Bob Koninckx <bob.koninckx@mech.kuleuven.ac.be>
+
+ * src/drv_api.c: Added definition of cyg_interrupt_post_dsr() for
+ use in those HALs that need it.
+
+ * include/hal_arbiter.h (hal_call_isr): Removed ifdef on
+ CYGFUN_HAL_COMMON_KERNEL_SUPPORT around test and call to
+ cyg_interrupt_post_dsr().
+
+2003-07-21 Nick Garnett <nickg@balti.calivar.com>
+
+ * doc/hal.sgml: Reorganized description of clock and timer related
+ stuff into their own section and added a piece about how to change
+ the clock frequency.
+
+2003-06-25 Nick Garnett <nickg@balti.calivar.com>
+
+ * src/hal_if.c (delay_us): The first test against
+ CYGNUM_KERNEL_COUNTERS_RTC_PERIOD is now against the period
+ divided by two. By the time we get to this test we know that usecs
+ can never be > usec_per_period/2 so we can double the range of
+ period values that we can handle without overflow and use the more
+ efficient approximation. The second test is not changed since we
+ cannot make the same assumptions about the elapsed count.
+
+2003-06-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * src/generic-stub.c (crc32): Fix crctable option name typo.
+
+ * src/hal_if.c (hal_if_init): Remove kill_by_reset.
+ (kill_by_reset): Remove, unused.
+ (reset): ifdef test on HAL_PLATFORM_RESET and assert on reset failure.
+
+ * cdl/interrupts.cdl (CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE): No
+ reason to forbid people setting this quite small.
+
+2003-06-19 Nick Garnett <nickg@balti.calivar.com>
+
+ * src/hal_if.c (delay_us): Reorganized to cope with high frequency
+ timers by eliminating a source of arithmetic overflow.
+
+2003-05-06 Mark Salter <msalter@redhat.com>
+
+ * src/hal_stub.c (handle_exception_exit): Call sys_profile_reset from
+ here. Setup to return through return_from_stub() when appropriate.
+ (return_from_stub): New function to call CYGACC_CALL_IF_MONITOR_RETURN
+ from thread context.
+
+ * src/generic-stub.c (__handle_exception): Call exit_vec if
+ hal_syscall_handler returns negative number.
+
+2003-04-08 Mark Salter <msalter@redhat.com>
+
+ * src/hal_misc.c (hal_default_isr): Allow HAL to override default
+ GDB vector matching test.
+
+2003-04-08 Yoshinori Sato <qzb04471@nifty.ne.jp>
+2003-04-08 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/debugging.cdl: Allow CRC to be allocated in ROM as well as RAM.
+ * src/generic-stub.c: as above.
+
+2003-04-02 Gary Thomas <gary@mlbassoc.com>
+
+ * src/generic-stub.c:
+ * include/generic-stub.h: Cleanup when program args are not
+ supported (remove some unused static storage).
+
+2003-03-03 Knud Woehler <knud.woehler@microplex.de>
+
+ * src/hal_if.c:
+ * include/hal_if.h: Add CYGNUM_CALL_IF_FLASH_FIS_OP. FIS read
+ via the virtual vector table.
+
+2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
+
+ * cdl/hal.cdl: Fix doc links.
+
+ * doc/hal.sgml: hal-common-current-doc-porting-sgml entity ->
+ hal-common-porting-sgml in line with other docs.
+
+2003-02-13 Mark Salter <msalter@redhat.com>
+
+ * src/gdb-fileio.h (FILEIO_O_BINARY): New flag.
+ (FILEIO_O_TEXT): New flag.
+
+2003-01-31 Mark Salter <msalter@redhat.com>
+
+ * include/hal_if.h: Add CYGNUM_CALL_IF_MONITOR_RETURN.
+
+2002-12-04 Gary Thomas <gthomas@ecoscentric.com>
+
+ * cdl/hal.cdl: RAM applications should not claim (reset) version
+ string by default.
+
+2002-12-03 Gary Thomas <gthomas@ecoscentric.com>
+
+ * src/hal_if.c (hal_if_init):
+ * include/hal_if.h:
+ * cdl/hal.cdl: Allow monitor (RedBoot) version string to be exported
+ via the virtual vector table.
+
+2002-11-13 Gary Thomas <gthomas@ecoscentric.com>
+
+ * cdl/hal.cdl: Add CDL control over DATA cache startup mode.
+
+2002-09-11 Mark Salter <msalter@redhat.com>
+
+ * include/hal_if.h: Add __COMMCTL_ENABLE_LINE_FLUSH and
+ __COMMCTL_DISABLE_LINE_FLUSH.
+
+2002-08-29 Mark Salter <msalter@redhat.com>
+
+ * include/generic-stub.h: Add defines for Z packet types.
+ * src/bplist-dynamic.c: Add support for deferred hardware breakpoint
+ and watchpoint insertion/deletion. This gets around gdb problem where
+ gdb tries accessing watched memory before removing watchpoint.
+ * src/generic-stub.c (__process_packet): Ditto.
+ * include/hal_stub.h: Ditto.
+
+2002-05-23 Jesper Skov <jskov@redhat.com>
+
+ * cdl/hal.cdl: Don't build tests that are not applicable with the
+ current configuration.
+ Added CYGINT_HAL_TESTS_NO_CACHES which allows cache tests to be
+ suppressed.
+
+2002-05-13 Jesper Skov <jskov@redhat.com>
+
+ * cdl/hal.cdl: Removed
+ CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT_NOT_GUARANTEED option and its
+ dependencies.
+
+2002-05-02 Nick Garnett <nickg@redhat.com>
+
+ * doc/hal.sgml: Added description of HAL_DELAY_US().
+
+ * doc/porting.sgml: Expanded section on architecture porting.
+
+2002-04-30 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/gdb-fileio.c (cyg_hal_gdbfileio_process_F_packet): Reset
+ retcode/errno/ctrlc status every F packet.
+
+2002-04-23 Jesper Skov <jskov@redhat.com>
+
+ * doc/porting.sgml: Fix some typos.
+
+2002-04-22 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/generic-stub.h: Prototype __getpacket().
+ * src/generic-stub.c: Rename getpacket() -> __getpacket(),
+ remcomInBuffer -> __remcomInBuffer, and
+ remcomOutBuffer -> __remcomOutBuffer throughout file, and export
+ them (i.e. not file local).
+ (__process_packet): Handle $F packets file I/O protocol responses.
+
+ * src/gdb-fileio.c: New file to implement file I/O operations over
+ the GDB remote protocol.
+ * src/gdb-fileio.h: New file. Header for above.
+
+2002-03-15 Nick Garnett <nickg@redhat.com>
+
+ * doc/porting.sgml: Platform HAL porting guide tidied up and
+ expanded somewhat. Some work also done on variant
+ guide. Architecture guided needs a lot more work.
+
+ * doc/hal.sgml: Changed explicit section tags to recursive section
+ tags to make any future restructuring easier.
+
+2002-03-14 Nick Garnett <nickg@redhat.com>
+
+ * src/hal_stub.c: Add calls to HAL memory access check macros in
+ memory access functions.
+
+ * include/hal_stub.h: Added default definitions for HAL memory access
+ check macros.
+
+2002-03-06 Nick Garnett <nickg@redhat.com>
+
+ * tests/cache.c: Changed tests so that zero sized caches and HALs
+ that define HAL_DCACHE_PURGE_ALL() don't cause this test to throw
+ a compilation error.
+
+2002-02-28 Jesper Skov <jskov@redhat.com>
+
+ * src/generic-stub.c (__handle_exception): Pay attention to return
+ value from hal_syscall_handler.
+
+2002-02-21 Mark Salter <msalter@redhat.com>
+
+ * src/hal_if.c (cyg_hal_diag_mangler_gdb_flush): Don't do anything
+ if buffer is empty.
+
+2002-02-20 Nick Garnett <nickg@redhat.com>
+
+ * doc/hal.sgml: Updated and tidied. Now includes porting guide
+ from a separate file.
+
+ * doc/porting.sgml: Added this file to contain the porting guide
+ section of the HAL document. This is currently largely a
+ conversion of Jesper's porting guide from the website.
+ Unfortunately I have had no time to do much more than include it
+ wholesale, with only minor edits. There are some notes at the end
+ of the file describing what I would like to do.
+
+2002-02-18 Nick Garnett <nickg@redhat.com>
+
+ * doc/hal.sgml: Restructured most of this document and rewrote
+ large chunks of the basic HAL description stuff. Only the skeleton
+ of the porting guided is currently done. This checkin in mostly
+ for safety and to let others read the current state.
+
+2002-02-06 Mark Salter <msalter@redhat.com>
+
+ * src/hal_if.c (cyg_hal_diag_mangler_gdb_control): Add flush support.
+ (cyg_hal_diag_mangler_gdb_flush): New function to flush mangler output.
+ (cyg_hal_diag_mangler_gdb_putc): Use new function to flush output.
+
+2002-01-30 Hugo Tyson <hmt@redhat.com>
+
+ * include/hal_if.h (CYGNUM_FLASH_CFG_OP_CONFIG_INT): New defines for
+ getting Flash Config options out of RedBoot using VV call
+ CYGACC_CALL_IF_FLASH_CFG_OP(). These need to be kept uptodate
+ with (or must override) those in RedBoot's flash_config.h
+ Previously only used for getting an ESA.
+
+2002-01-25 Hugo Tyson <hmt@redhat.com>
+
+ * src/generic-stub.c (__process_packet): If detach or kill, call
+ sys_profile_reset() if BSP_SYSCALLS_GPROF are enabled, to clear
+ out any dangerous state there. Such as a callback function
+ pointer into application code.
+
+2002-01-23 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/drv_api.h: Add cyg_drv_interrupt_mask/unmask_intunsafe
+ * src/drv_api.c: Ditto. And modify
+ cyg_drv_interrupt_mask/unmask to be interrupt safe.
+
+2002-01-21 Mark Salter <msalter@redhat.com>
+
+ * include/hal_spd.h: New file. Definitions for SDRAM module SPD.
+
+2002-01-18 Jesper Skov <jskov@redhat.com>
+
+ * src/hal_stub.c (__build_t_packet): don't declare extend_val
+ twice.
+
+2001-12-12 Jesper Skov <jskov@redhat.com>
+
+ * include/hal_stub.h: Add goto to the used label.
+ * src/hal_misc.c: Added (dummy) got for label used in
+ CYGARC_HAL_GET_RETURN_ADDRESS_BACKUP.
+
+2001-12-05 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/dbg-threads-syscall.c (dbg_thread_syscall): Don't bother to
+ deref a func ptr. The opcode could theoretically be 0x0!
+
+2001-12-04 Richard Sandiford <rsandifo@redhat.com>
+
+ * src/generic-stub.c (__add_char_to_packet): Reverse check for
+ end of buffer and end of packet to fix potential buffer overrun.
+
+2001-12-01 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/dbg-threads-syscall.c (dbg_thread_syscall): check for
+ NULL dbg_syscall_ptr.
+
+ * cdl/hal.cdl: require CYGPKG_INFRA since all HALs do!
+
+2001-11-29 Hugo Tyson <hmt@redhat.com>
+
+ * src/hal_stub.c: Enable HAL_STUB_HW_SEND_STOP_REASON_TEXT for
+ XScale architectures per Mark's request; XScale GDB needs to know
+ what's happening with watchpoints (= work around previous change)
+
+2001-11-29 Hugo Tyson <hmt@redhat.com>
+
+ * src/hal_stub.c: Condition out sending the reason for hardware
+ watchpoint stop in the stop packet as $T05watch:01234568;... most
+ GDBs do not understand it and in fact object to it.
+
+2001-11-23 Nick Garnett <nickg@redhat.com>
+
+ * src/generic-stub.c (__process_packet): Fixed bogosity in
+ handling of 'r' packet. It tried to send two replies, messing up
+ the protocol and confusing GDB.
+
+2001-11-02 Hugo Tyson <hmt@redhat.com>
+
+ * include/hal_stub.h (CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION):
+ Permit this too to be defined externally ie. in a platform HAL.
+
+2001-10-25 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/hal.cdl:
+ * cdl/debugging.cdl: Reorg CDL a little so that GDB stub routines
+ are only compiled when needed (instead of being compiled "empty").
+
+2001-10-24 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/hal.cdl: Add 'basic' test.
+
+ * tests/basic.c: New test of some minimal HAL functionality.
+
+2001-10-18 Gary Thomas <gthomas@redhat.com>
+
+ * src/hal_if.c (cyg_hal_diag_mangler_gdb_putc):
+ * cdl/debugging.cdl: CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES is now
+ defined as CDL 'data' flavor (tested via #if vs. #ifdef)
+
+2001-10-17 Jesper Skov <jskov@redhat.com>
+
+ * src/generic-stub.c: Prefixed local version of memcpy and memset
+ with _.
+
+2001-10-17 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/debugging.cdl:
+ * src/hal_if.c (cyg_hal_diag_mangler_gdb_putc): Make retry/abort optional,
+ only attemped if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES is configured to
+ be non-zero (default now 0).
+
+2001-10-16 Jesper Skov <jskov@redhat.com>
+
+ * include/hal_stub.h: Allow ISOINFRA/LIBC to provide string
+ functions.
+
+2001-10-16 Gary Thomas <gthomas@redhat.com>
+
+ * include/generic-stub.h: Add prototypes for breakpoint_list functions.
+
+2001-10-15 David Howells <dhowells@redhat.com>
+
+ * include/hal_stub.h: put semicolon between goto-label and close curly.
+
+2001-10-12 Mark Salter <msalter@redhat.com>
+
+ * src/thread-packets.c: Don't specify array sizes in extern decls.
+
+ * src/hal_stub.c: Use HAL_STUB_REGISTERS_SIZE to set number of elements
+ in register save areas. Default to NUMREGS if not defined by HAL.
+ Allow HALs to provide specialized get_register()/put_register().
+
+ * src/generic-stub.c (stub_format_registers): Support 'p' packet.
+ (__process_packet): Rearrange ifdefs so error is sent for unsupported
+ Z packet types.
+ (process_query): Add hook for HAL specific queries.
+ (process_set): Add hook for HAL specific sets.
+
+ * include/generic-stub.h: Add extern decls to quiet compiler warnings.
+
+2001-10-11 Gary Thomas <gthomas@redhat.com>
+
+ * include/generic-stub.h:
+ * src/generic-stub.c: Improve error handling more. Make sure that
+ packets are consumed, even if they are going to be tossed (overflow).
+ This keeps TCP based connections going, even when the data is bad.
+ (getpacket): Only send NAK in case of overflow.
+
+2001-10-09 Jesper Skov <jskov@redhat.com>
+
+ * src/hal_if.c (flash_config_op): Protect with
+ CYGARC_HAL_SAVE_GP.
+
+2001-10-04 Jesper Skov <jskov@redhat.com>
+
+ * include/hal_endian.h: Added.
+ Fix typo.
+
+2001-10-03 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/hal_tables.h (CYG_HAL_TABLE_BEGIN): Use plain "object"
+ because some (only some though) MIPS tools complain with %object.
+ (CYG_HAL_TABLE_END): Ditto.
+
+2001-10-02 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/hal_tables.h (CYG_HAL_TABLE_BEGIN): Use %object syntax
+ rather than @object since @ is a comment character on ARM. gas
+ accepts either syntax.
+ (CYG_HAL_TABLE_END): Ditto.
+
+2001-10-01 Gary Thomas <gthomas@redhat.com>
+
+ * src/generic-stub.c (getpacket): Send back error response (E01) if
+ packet received which overflows buffers. GDB doesn't always do much
+ with this error, but at least it keeps the protocol moving.
+
+2001-09-26 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/common.cdl: New interface CYGINT_HAL_SUPPORTS_MMU_TABLES which
+ indicates if the HAL supports MMU tables (few do).
+
+2001-09-25 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/common.cdl (CYGSEM_HAL_INSTALL_MMU_TABLES): Change to be
+ default for ROM startup.
+
+2001-09-20 Jesper Skov <jskov@redhat.com>
+
+ * tests/vaargs.c (cyg_start): Call CYG_TEST_INIT.
+
+2001-09-10 Nick Garnett <nickg@redhat.com>
+
+ * include/hal_stub.h (strlen): Changed return type to size_t from
+ int so it matches <string.h>. For some reason the compiler has
+ suddenly started complaining about the type mismatch. Strange.
+
+2001-09-07 Nick Garnett <nickg@redhat.com>
+
+ * src/hal_stub.c (put_register): Added kludge for VR4300 targets
+ to sign extent the PC when it is being set. This is due to the
+ age of the VR4300 toolchain and the fact that the VR4300 is the
+ only target to do full 64bit register saves/restores.
+
+2001-09-07 Jesper Skov <jskov@redhat.com>
+
+ * include/hal_if.h: Fix typo in below change.
+
+2001-09-07 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/hal_if.h (CYGACC_CALL_IF_DBG_SYSCALL): Define and call
+ with correct arguments.
+
+2001-08-24 Mark Salter <msalter@redhat.com>
+
+ * src/generic-stub.c (__process_packet): Add support for 'D' packet.
+ (__process_packet): Check for impossible mem write length.
+
+2001-08-17 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/hal.cdl: Add CYGINT_HAL_VIRTUAL_VECTOR_COMM_BAUD_SUPPORT
+ interface.
+
+2001-08-16 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/hal.cdl: Add CDL options to control GDB protocol retries.
+
+2001-08-14 Gary Thomas <gthomas@redhat.com>
+
+ * src/hal_if.c (cyg_hal_diag_mangler_gdb_putc): Use timeout
+ functions to allow for retries. This should improve the case
+ where [for whatever reason] the host GDB misses or ignores
+ a $O packet - it will get resent after a reasonable timeout.
+
+2001-08-03 Gary Thomas <gthomas@redhat.com>
+2001-08-03 Jesper Skov <jskov@redhat.com>
+
+ * include/hal_if.h: Use inline functions for calls - allowing
+ interrupts to be disabled while services are called
+ [CYGACC_COMM_IF_CONTROL is an exception since it's using variable
+ arguments - so it's still a macro].
+ Pruned unused IF vectors: ICTRL_TABLE, EXC_TABLE, DBG_VECTOR,
+ CPU_DATA, BOARD_DATA, SYSINFO, SET_SERIAL_BAUD.
+ Note: this should fix bug CR 902745-CR.
+
+ * cdl/hal.cdl: Removed CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_ICTRL.
+ * src/hal_if.c (hal_if_init): Removed initialization of
+ ICTRL_TABLE, EXC_TABLE, CPU_DATA and BOARD_DATA entries.
+
+2001-08-03 Nick Garnett <nickg@redhat.com>
+
+ Imported from a development branch:
+
+ 2001-07-11 Nick Garnett <nickg@redhat.com>
+
+ * include/drv_api.h:
+ * src/drv_api.c:
+ Added API for controlling routing of interrupts to CPUs in SMP
+ configurations.
+
+ 2001-06-29 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/drv_api.h:
+ * src/drv_api.c:
+ Added API for using spinlocks.
+
+2001-08-03 Jesper Skov <jskov@redhat.com>
+
+ * tests/vaargs.c: Added.
+ * cdl/hal.cdl: Added CYGPKG_HAL_BUILD_COMPILER_TESTS to allow cpp1
+ and vaargs tests to be compiled conditionally.
+
+2001-07-27 Jesper Skov <jskov@redhat.com>
+
+ * tests/intr.c: Set up interrupt ISR using driver API so it works
+ properly in chained mode in the presence of arbiters.
+
+ * src/drv_api.c (chain_isr): Call default ISR when
+ appropriate. Return ISR return value.
+
+ * include/hal_arbiter.h (hal_call_isr): Added version to be used
+ with interrupt chaining.
+
+2001-07-24 Mark Salter <msalter@redhat.com>
+
+ * cdl/hal.cdl (CYGINT_HAL_PLF_IF_IDE): New interface which
+ indicates platform supports IDE controller I/F macros.
+
+2001-06-29 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/hal.cdl (CYGPKG_HAL_TESTS): Remove redundant .c extension
+
+2001-06-29 Jesper Skov <jskov@redhat.com>
+
+ * include/hal_misc.h: Moved arbiter helper to
+ * include/hal_arbiter.h: this file to avoid header file inclusion
+ order problems.
+
+2001-06-28 Jesper Skov <jskov@redhat.com>
+
+ * include/hal_misc.h (hal_call_isr): Added. Used by ISR arbiters.
+
+2001-06-22 Gary Thomas <gthomas@redhat.com>
+
+ * src/generic-stub.c (BUFMAX): Define as platform specific, thus
+ reducing memory requirements.
+ (__process_packet): Eliminate program arguments support until eCos
+ makes use of them (more memory savings).
+
+2001-06-22 Mark Salter <msalter@redhat.com>
+
+ * src/hal_stub.c (__do_copy_mem): Add goto statement to prevent
+ compiler from moving instructions across 'err' label.
+
+2001-06-14 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/generic-stub.c (__process_packet): Don't reset the board
+ straight away with a 'r' packet. Let a 'k' packet do it instead.
+
+ * src/hal_stub.c (__install_traps): Remove redundant comment.
+
+2001-06-11 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/hal_if.c (delay_us): Revert below change of 2001-05-17
+
+2001-06-05 Hugo Tyson <hmt@redhat.com>
+
+ * src/hal_if.c (cyg_hal_diag_mangler_gdb_putc): The nesting of
+ CYGARC_HAL_SAVE_GP() and the instant-out if sending a carriage
+ return "\r" was wrong - it scrambled the gp for the caller! Since
+ the return-test is trivial, I simply re-ordered rather than making
+ the exit clause complex with a restore in it.
+
+2001-05-17 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/hal_if.c (delay_us): Warn if using default
+
+2001-05-14 Jonathan Larmour <jlarmour@redhat.com>
+
+ * cdl/interrupts.cdl (CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE):
+ Default stack size to 32K for non-kernel configs, and describe
+ why.
+
+2001-05-07 Gary Thomas <gthomas@redhat.com>
+
+ * src/hal_if.c (hal_ctrlc_check): Only return 'true' if the ISR/DSR
+ actually processes a ^C. Otherwise, interrupts/date can be lost on
+ a shared channel (like an ethernet device).
+
+2001-04-30 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/hal.cdl: Add configury to control initial cache behaviour.
+
+2001-04-30 Hugo Tyson <hmt@redhat.com>
+
+ * cdl/hal.cdl: Add tests/cpp1.c to the tests list.
+
+ * tests/cpp1.c: New test, to test for regressions in the tools.
+ This one is for a CPP bug in the XScale tools where '+' binds too
+ strongly following a ')' because it is mistaken for unary plus.
+
+2001-04-25 Bart Veer <bartv@redhat.com>
+
+ * tests/cache.c:
+ Fix test for cache presence.
+
+ * src/drv_api.c (cyg_drv_interrupt_detach):
+ Added missing indirection.
+
+2001-03-28 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/dbg-threads-api.h: Add dbg_thread_id() function prototype.
+
+2001-03-21 Mark Salter <msalter@redhat.com>
+
+ * src/hal_if.c (hal_if_init): Add explicit typecast when setting
+ version. Needed when sizeof(int) < sizeof(CYG_ADDRWORD).
+
+2001-03-21 Jesper Skov <jskov@redhat.com>
+
+ * src/hal_if.c (hal_if_init): Added warning about debugging.
+
+2001-03-20 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/hal_if.h: Add argument names to __call_if_flash_cfg_op_fn_t
+
+2001-03-16 Mark Salter <msalter@redhat.com>
+
+ * src/hal_stub.c (__build_t_packet): Add hook for adding arch-specific
+ registers to T packet.
+ (handle_exception_cleanup): Skip orig_registers past breakpoint so we
+ return to original context rather than hit breakpoint again.
+
+2001-03-16 Hugo Tyson <hmt@redhat.com>
+
+ * include/hal_if.h: Define types and slots and macros themed with
+ the phrase CALL_IF_FLASH_CFG_OP following the pattern of what's
+ there for the other slots. Thus CYGNUM_CALL_IF_FLASH_CFG_OP,
+ CYGACC_CALL_IF_FLASH_CFG_OP(...) and __call_if_flash_cfg_op_fn_t
+ are all newly defined. Also CYGNUM_CALL_IF_FLASH_CFG_GET which is
+ the only operation supported in this initial version.
+
+ Also changed many typedef'd function pointers to not include the
+ pointerness; that way the type can be used to validate the
+ correctness of arguments in the called function.
+
+ * src/hal_stub.c (__reset): Minor change to reset function
+ handling; pointerness of typedef removed.
+
+ * src/hal_if.c (flash_config_op): New function to call flash ops
+ in RedBoot. This is so that RedBoot can manage ethernet addresses
+ for you, and the application can get at the data "cleanly".
+ (hal_if_init): Install flash_config_op() in the table if defined.
+
+2001-03-12 Mark Salter <msalter@redhat.com>
+
+ * src/hal_misc.c (cyg_hal_user_break): Use macro to find PC
+ in saved regs.
+
+ * src/generic-stub.c: Add support for harvard memories.
+ * src/bplist-dynamic.c: Ditto.
+ * include/generic-stub.h: Ditto.
+ * include/hal_stub.h: Add dummy harvard memory macros for
+ princeton memory systems.
+
+2001-03-12 Jesper Skov <jskov@redhat.com>
+
+ * src/drv_api.c (cyg_drv_interrupt_detach): Fix missing intr->
+ change.
+
+2001-03-08 Jesper Skov <jskov@redhat.com>
+
+ * cdl/hal.cdl: Change sense of
+ CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT_GUARANTEED to new
+ CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT_NOT_GUARANTEED.
+
+2001-03-07 Jesper Skov <jskov@redhat.com>
+
+ * src/drv_api.c: Use macro to provide symbol alias.
+
+2001-03-05 Jesper Skov <jskov@redhat.com>
+
+ * src/hal_if.c (hal_if_diag_init): Ensure the function only
+ executes once.
+
+2001-03-02 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/hal.cdl:
+ * include/hal_if.h:
+ * src/hal_if.c (hal_if_init):
+ Support platform specific initializations.
+
+2001-02-26 Mark Salter <msalter@redhat.com>
+
+ * src/generic-stub.c (__process_packet): Change 'k' packet to cause
+ return to original context. Change 'r' packet to respond with empty
+ packet before resetting board.
+
+ * src/hal_stub.c (handle_exception_exit): New function. Restores
+ original context saved when stub was entered for the first time.
+ (handle_exception_cleanup): Save original context.
+ (__install_traps): Set __process_exit_vec to handle_exception_exit.
+
+2001-02-09 Jesper Skov <jskov@redhat.com>
+
+ * cdl/debugging.cdl: Make CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT and
+ CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT options have sensible defaults.
+
+2001-02-08 Jesper Skov <jskov@redhat.com>
+
+ * cdl/hal.cdl: Added CYGSEM_HAL_VIRTUAL_VECTOR_INHERIT_CONSOLE and
+ CHANNEL_CONFIGURABLE options.
+ * cdl/common.cdl: Added CYGDBG_HAL_DIAG_TO_DEBUG_CHAN option.
+ * src/hal_if.c: Changes to respect new options. Always do platform
+ driver init from CLAIM_COMMS code.
+ * src/hal_stub.c: Leave channel setup to CLAIM_COMMS code.
+
+ * src/hal_if.c: Added null mangler that gets called via the
+ virtual vector console comms entry and just forwards IO to the
+ debug comms entries. This differs from setting the console
+ channel to the same as the debug channel in that console output
+ will go to the debug channel even if the debug channel is changed.
+
+2001-02-07 Jesper Skov <jskov@redhat.com>
+
+ * include/hal_if.h: Allow architecture to override COMM and CALL
+ accessor macros.
+
+2001-02-03 Gary Thomas <gthomas@redhat.com>
+
+ * src/bplist-dynamic.c (__set_breakpoint, __remove_breakpoint):
+ Fix error introduced below when no breakpoint list defined.
+
+2001-02-02 Mark Salter <msalter@redhat.com>
+
+ * src/generic-stub.c: __set_breakpoint and __remove_breakpoint now
+ take a length argument.
+
+ * src/bplist-dynamic.c: Support breakpoint length. Use
+ HAL_BREAKINST_ADDR macro (if defined) to get actual breakpoint based
+ on breakpoint length.
+
+ * include/hal_stub.h: Add len argument to __set_breakpoint and
+ __remove_breakpoint.
+
+2001-02-01 Jesper Skov <jskov@redhat.com>
+
+ * src/drv_api.c: Make it build with chaining.
+
+ * include/hal_if.h: Introduce macros for legal version range and
+ special hacked version number used by ctrlc magic.
+ * src/hal_if.c (hal_ctrlc_isr_init): Be more careful with how the
+ version number is checked (and trashed) by the ctrlc init code.
+ * src/hal_misc.c (hal_default_isr): Same.
+
+ * src/hal_stub.c: Moved mangling code to hal_if.c
+ * src/hal_if.c: New policies for when and how to initialize the
+ IO channels. Mangler code now set up by diag_init to allow for
+ mangling when no stub is included.
+
+ * include/hal_if.h: Added COMM version in upper 16 bits of version
+ word. Removed CYGPRI_HAL_IMPLEMENTS_IF_SERVICES.
+ * src/hal_misc.c: Use masks when checking vv versions.
+
+ * cdl/hal.cdl: Add new options for selecting which parts of the
+ virtual vector table to initialize.
+ * src/hal_if.c: Matching granularity in initialization code.
+ Extra checking of services before using these.
+
+ * cdl/debugging.cdl: Require channel initialization when enabling
+ stubs.
+
+2001-01-31 Jesper Skov <jskov@redhat.com>
+
+ * cdl/common.cdl: Get rid of CYGDBG_HAL_DIAG_DISABLE_GDB_PROTOCOL
+ options. They are replaced by the CYGSEM_HAL_DIAG_MANGLER option.
+
+2001-01-31 Hugo Tyson <hmt@redhat.com>
+
+ * include/hal_if.h: Make it possible to build logical ether driver
+ even without virtual vectors present, by defining a dummy
+ HAL_CTRLC_CHECK in that case; other code invokes it if debugging
+ per se is enabled.
+
+2001-01-26 Jesper Skov <jskov@redhat.com>
+
+ * src/hal_stub.c (__reset): Rename HAL_STUB_PLATFORM_RESETx macros
+ to HAL_PLATFORM_RESETx.
+ * src/hal_if.c (reset): Same.
+
+2001-01-15 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/drv_api.c: Initialized isr_disable_counter to 1 so that it
+ indicates that interrupts are initially disabled.
+
+2000-12-15 Gary Thomas <gthomas@redhat.com>
+
+ * src/generic-stub.c: Define 'version' string to be a weak
+ symbol that can be easily overridden (e.g. by RedBoot).
+
+2000-12-11 Gary Thomas <gthomas@redhat.com>
+
+ * src/hal_if.c: Remove unnecessary (polluting) include file.
+
+ * include/hal_stub.h: Support platform/variant supplied
+ include files. <cyg/hal/plf_XXX.h> can now be layered
+ as <cyg/hal/var_XXX.h> which includes <cyg/hal/plf_XXX.h>.
+
+2000-12-06 Jesper Skov <jskov@redhat.com>
+
+ * src/hal_if.c (delay_us): Ensure proper _GP save/restore.
+ Reduce number of loops in fall-back code.
+
+2000-12-05 Drew Moseley <dmoseley@redhat.com>
+
+ * src/hal_stub.c (__build_t_packet): Handle
+ CYGARC_REGSIZE_DIFFERS_FROM_TARGET_REGISTER_T with Little Endian
+ target.
+
+ * include/hal_misc.h: Added BIT and SZ_ defines.
+
+2000-11-22 Mark Salter <msalter@redhat.com>
+
+ * src/hal_misc.c (hal_default_isr): Version check only when
+ CYGSEM_HAL_ROM_MONITOR not defined.
+
+2000-11-20 Mark Salter <msalter@redhat.com>
+
+ * src/hal_stub.c (hal_flush_output): New function to flush debug
+ comm interface.
+
+ * src/generic-stub.c (__process_packet): Use hal_flush_output when
+ killing or continuing.
+
+ * include/hal_stub.h: Add declaration for hal_flush_output().
+
+ * include/hal_if.h (__COMMCTL_FLUSH_OUTPUT): New comm control cmd.
+
+2000-11-17 Jesper Skov <jskov@redhat.com>
+
+ * src/hal_if.c (delay_us): Add dummy loop.
+ Duh! Take usecs argment into account.
+
+2000-11-06 Mark Salter <msalter@redhat.com>
+
+ * src/generic-stub.c (__handle_exception): Add support for GNUPro bsp
+ syscall handling.
+
+ * src/board.h: Include pkgconf/redboot.h for CYGSEM_REDBOOT_BSP_SYSCALLS.
+
+2000-11-06 Jesper Skov <jskov@redhat.com>
+
+ * src/hal_if.c (hal_if_diag_write_char): Clear interrupt flag before
+ setting breakpoint.
+
+2000-11-04 Mark Salter <msalter@redhat.com>
+
+ * src/hal_stub.c (__build_t_packet): Report reason and data
+ address if stopped by hw watchpoint.
+
+ * src/generic-stub.c (__process_packet): Remove experimental
+ support for type 5 Z packet.
+
+ * include/hal_stub.h: Define HAL_STUB_STOP_* reasons returned
+ by HAL_IS_STOPPED_BY_HARDWARE.
+
+2000-10-27 Mark Salter <msalter@redhat.com>
+
+ * src/generic-stub.c: Fixed preprocessor warning.
+
+2000-10-27 Gary Thomas <gthomas@redhat.com>
+
+ * src/generic-stub.c (__process_packet): Remove warnings when
+ hardware breakpoint support (Z packet) not enabled.
+
+2000-10-26 Mark Salter <msalter@redhat.com>
+
+ * src/generic-stub.c (__process_packet): Add Z packet support.
+
+ * src/bplist-dynamic.c: Include <pkgconf/hal.h> to pick up
+ CYGNUM_HAL_BREAKPOINT_LIST_SIZE.
+
+2000-10-24 Jesper Skov <jskov@redhat.com>
+
+ * src/generic-stub.c (__process_packet): Disable buffer size
+ z-packet.
+
+2000-10-23 Jesper Skov <jskov@redhat.com>
+
+ * src/hal_stub.c: Made __mem_fault_handler pointer volatile.
+
+2000-10-20 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/drv_api.h (cyg_interrupt): Make dsr_count volatile to
+ prevent compilers optimizing accesses in the wrong place.
+
+2000-10-20 Jesper Skov <jskov@redhat.com>
+
+ * include/drv_api.h: Correct location of volatile keyword.
+ * src/drv_api.c: Same.
+
+2000-10-19 Gary Thomas <gthomas@redhat.com>
+
+ * src/generic-stub.c (__process_packet): Add RedBoot identifier
+ in maintenance 'd' packet reply.
+
+2000-10-18 Jesper Skov <jskov@redhat.com>
+
+ * include/hal_if.h (CYGPRI_HAL_IMPLEMENTS_IF_SERVICES): Set for
+ all non-RAM startup types.
+
+2000-10-13 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/stubrom/stubrom.c (cyg_start): Remove unnecessary call to
+ initialize_stub()
+
+2000-09-11 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/hal_tables.h (CYG_HAL_TABLE_EXTRA): Use new definition of
+ CYGBLD_ATTRIB_SECTION, and fix the string name up better.
+ (CYG_HAL_TABLE_ENTRY): Ditto
+ (CYG_HAL_TABLE_QUALIFIED_ENTRY): Ditto
+
+2000-09-07 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/hal_tables.h: Fix non-standard use of paste operator to
+ remove warnings with recent gcc
+
+2000-09-04 Jonathan Larmour <jlarmour@redhat.com>
+
+ * include/hal_tables.h (CYG_HAL_TABLE_END): Use CYGARC_P2ALIGNMENT
+ to align label
+ (CYG_HAL_TABLE_TYPE): Define
+
+2000-09-01 Jonathan Larmour <jlarmour@redhat.com>
+
+ * src/hal_stub.c (__build_t_packet): Ensure sign extension applies
+ in the higher word, not the lower.
+ (__build_t_packet): Don't need to conditionalize on
+ CYGARC_REGSIZE_DIFFERS_FROM_TARGET_REGISTER_T as there should be no
+ problems with the current code.
+ * src/generic-stub.c (stub_format_registers): Likewise
+
+ * include/hal_if.h (CYGACC_COMM_IF_CONTROL): Remove warning due to
+ unnecessary use of cpp paste operator
+
+2000-08-28 Gary Thomas <gthomas@redhat.com>
+
+ * src/hal_if.c:
+ * include/hal_if.h (hal_ctrlc_check): Define new routine to be
+ called by interrupt handlers (DSRs) which may be using hardware
+ shared with a debug channel. In particular, network adaptors
+ need to call this function to see if a ^C has occurred on the
+ network debug connection.
+
+2000-08-24 Gary Thomas <gthomas@redhat.com>
+
+ * include/hal_tables.h: Need descriminated tables (for proper sorting).
+
+2000-08-14 Drew Moseley <dmoseley@redhat.com>
+
+ * src/hal_if.c: Added an extern declaration for
+ cyg_hal_plf_comms_init.
+
+ * src/bplist-dynamic.c: Only use breakpoint lists when building
+ stubs.
+
+2000-08-10 Drew Moseley <dmoseley@redhat.com>
+
+ * include/generic-stub.h: Added support for register validity
+ checking.
+ * src/generic-stub.c: Ditto.
+ * src/hal_stub.c: Ditto.
+
+ * include/drv_api.h: Added cyg_code_t.
+
+2000-08-03 Gary Thomas <gthomas@redhat.com>
+
+ * include/hal_if.h (CYGNUM_CALL_IF_DBG_DATA): Move to avoid
+ conflict.
+
+2000-07-26 Gary Thomas <gthomas@redhat.com>
+
+ * src/hal_stub.c (cyg_hal_gdb_diag_putc): Ignore any characters
+ other than the protocol chars of ACK/NAK/^C.
+
+ * src/hal_if.c (hal_if_diag_init): Only reset console channel
+ if user has configured a non-default choice.
+
+2000-07-24 Drew Moseley <dmoseley@redhat.com>
+
+ * src/bplist-dynamic.c (__install_breakpoint_list): Call
+ HAL_ICACHE_SYNC() rather than HAL_ICACHE_INVALIDATE_ALL().
+
+2000-07-21 Drew Moseley <dmoseley@cygnus.com>
+
+ * src/hal_stub.c: Cleanup of #define's.
+
+ * src/generic-stub.c: Rearrange the linkage between Cygmon and HAL so
+ that Cygmon needs HAL but not vice-versa. ie HAL no longer calls
+ any Cygmon functions.
+ * src/hal_misc.c: Ditto.
+
+ * src/bplist-dynamic.c: Use HAL macros rather than Cygmon
+ functions for flushing the cache.
+ Also handle the case where target_register_t is not defined.
+
+2000-07-21 Gary Thomas <gthomas@redhat.com>
+
+ * src/hal_if.c (CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS): Define to allow
+ the number of channels to be extended by "AUX" packages.
+
+2000-07-20 Drew Moseley <dmoseley@redhat.com>
+
+ * src/generic-stub.c (stub_format_registers): Make the previous patch
+ effective only if CYGARC_REGSIZE_DIFFERS_FROM_TARGET_REGISTER_T is
+ defined so as to not affect any other targets.
+ * src/hal_stub.c: Ditto.
+
+2000-07-19 Drew Moseley <dmoseley@redhat.com>
+
+ * src/generic-stub.c (stub_format_registers): Handle the case
+ where GDB is expecting registers larger than we are storing. ie
+ MIPS gdb expects 64 bit registers even if we are on a 32 bit
+ architecture. Also, handle the sign-extension correctly if
+ necessary.
+ * src/hal_stub.c (__build_t_packet): Ditto.
+
+2000-07-18 Jesper Skov <jskov@redhat.com>
+
+ * src/hal_misc.c (hal_default_isr):
+ Version gets hacked by hal_if_init - check for the hacked value.
+
+2000-07-18 Jesper Skov <jskov@redhat.com>
+
+ * src/hal_stub.c (__mem_fault_handler): Made volatile.
+
+2000-07-14 Drew Moseley <dmoseley@redhat.com>
+
+ * src/generic-stub.c: Cleanups for better coexistence with Cygmon.
+ * include/generic-stub.h: Ditto.
+ * include/hal_if.h: Ditto.
+ * include/hal_stub.h: Ditto.
+ * src/hal_stub.c: Ditto.
+
+ * cdl/hal.cdl: Compile bplist-dynamic.c.
+
+ * src/bplist-dynamic.c: New file for supporting breakpoints in the HAL.
+
+2000-07-14 Gary Thomas <gthomas@redhat.com>
+
+ * src/hal_if.c (delay_us): Use HAL_DELAY_US() if defined.
+
+2000-07-07 Jesper Skov <jskov@redhat.com>
+
+ * src/hal_stub.c (initHardware): Fix #endif location.
+
+ * src/hal_if.c (hal_ctrlc_isr_init): Added hack to work around a
+ silly but critical problem.
+
+ * src/hal_stub.c: Removed some CygMon conditional exclusions.
+
+ * src/hal_if.c (hal_ctrlc_isr_init): Don't enable interrupts when
+ configured as ROM monitor.
+
+2000-07-05 Jesper Skov <jskov@redhat.com>
+
+ * cdl/debugging.cdl: Only allow CTRLC support if there's stubs or
+ a ROM monitor to handle it. (Haruki Kashiwaya (kashiwaya at redhat
+ dot com)).
+
+2000-06-30 Jesper Skov <jskov@redhat.com>
+
+ * include/hal_if.h: Make CYGACC macros call functions. May have to
+ add some _GET macros at some time if anyone needs to access the
+ function pointers.
+
+ * src/hal_stub.c:
+ * src/hal_misc.c:
+ * src/hal_if.c:
+ Matching changes of CYGACC clients.
+
+2000-06-29 Jesper Skov <jskov@redhat.com>
+
+ * src/hal_stub.c (cyg_hal_gdb_diag_putc): Check console interrupt
+ flag and breakpoint if set.
+
+2000-06-28 Jesper Skov <jskov@redhat.com>
+
+ * src/hal_stub.c (cyg_hal_gdb_diag_putc): Don't try to set
+ breakpoints in ROM startup - just disable interrupts. Also, use
+ procs table function to disable device interrupts.
+
+ * include/hal_if.h: Mark vector/comms arrays volatile to avoid
+ compiler confusion.
+
+ * include/dbg-threads-api.h: Fix C/C++ declaration issues.
+
+ * src/hal_stub.c: Moved stub platform init call below vector table
+ setup.
+
+ * src/hal_misc.c:
+ * src/hal_if.c:
+ * include/hal_if.h: DBG_ISR_VECTOR and SET_TIMEOUT functions added
+ to comms table. Added DELAY_US function to vector table. Made
+ switching of debug channel dis/enable Ctrl-c interrupts as
+ well. Made ctrlc_isr code use new vector entries. All this amounts
+ to a properly switchable debug channel.
+
+2000-06-21 Jesper Skov <jskov@redhat.com>
+
+ * src/hal_stub.c: Fixed clients of vector procs tables to pass
+ in the correct arguments. Hook O-packetizer up on procs slot
+ reserved for IO mangler. Install mangler when necessary.
+
+ * src/hal_if.c: Extended set procs functions to allow temporarily
+ switching console procs in a safe manner. Removed debug and
+ console wrappers - all IO happens via drivers hooked up in tables
+ rather than through hardwired macros. Proper initialization of
+ console proc entry. Fixed clients of vector procs tables to pass
+ in the correct arguments. Stub now does its own vector table
+ initialization. Added special procs slot for IO manglers.
+
+ * include/hal_if.h: Define special IDs used by the set procs
+ functions. PROCS_HANDLED removed since the procs table will now
+ always service any port.
+
+2000-06-21 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/hal_stub.h: Added underscore to breakinst().
+
+ * include/hal_tables.h:
+ Added this file to contain macros for defining datatables in a
+ systematic and extensible way.
+
+2000-06-19 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/hal.cdl: Revert change below - GUARANTEED can exist
+ with STUBS defined.
+
+2000-06-18 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/hal.cdl: Use of virtual vector functions for diagnostic
+ output must be disabled when building with stubs. Note: this
+ lets stubs be built for platforms with guaranteed virtual
+ vector support.
+
+2000-06-16 Jesper Skov <jskov@redhat.com>
+
+ * include/hal_if.h: All vector-dependant features hidden when
+ config option not enabled.
+
+ * src/hal_if.c (hal_if_init): Fix warning.
+
+2000-06-15 Jesper Skov <jskov@redhat.com>
+
+ * include/hal_if.h: Added console-include decision logic.
+
+2000-06-15 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/drv_api.c:
+ * include/drv_api.h: Added boolean result to cyg_drv_cond_wait()
+ to match change to the kernel and KAPI functionality.
+
+2000-06-14 Jesper Skov <jskov@redhat.com>
+
+ * src/hal_stub.c: Added O-packetizer used by GDB stubs for virtual
+ vector table configs.
+
+ * src/hal_misc.c (hal_default_isr): Check Ctrlc for both CTRLC
+ or BREAK options.
+
+ * src/hal_if.c:
+ * include/hal_if.h:
+ Define console wrappers when necessary. Platform HALs can use
+ these by providing raw IO functions and some config data.
+
+2000-06-09 Jesper Skov <jskov@redhat.com>
+
+ * src/hal_if.c: Implemented most of the remaining services. Some
+ just don't have an eCos equivalent at the moment.
+
+ * cdl/hal.cdl: Allow virtual_vector options to have sensible
+ default values depending on when the platform HAL port was
+ written.
+
+ * src/hal_misc.c (cyg_hal_user_break): Also expect CygMon to
+ provide the breakpoint service.
+
+ * src/stubrom/stubrom.c (cyg_start): Reverted change. Now handled
+ by hal_if_init.
+
+ * cdl/hal.cdl: Added option for controlling use of diag services
+ in the virtual vector table.
+
+2000-06-08 Jesper Skov <jskov@redhat.com>
+
+ * src/stubrom/stubrom.c: Call hal_diag_init to ensure IF table
+ entries related to diag IO get initialized.
+
+ * src/hal_stub.c (cyg_hal_gdb_interrupt): save/restore GP so it
+ can be used by MIPS platforms.
+ Use reset function in ROM if available.
+
+ * src/hal_misc.c:
+ * include/hal_misc.h: Functions shared between HALs. More
+ functions are likely to be moved here if appropriate.
+
+ * src/hal_if.c: Interfacing related functions: table init code and
+ function wrappers.
+
+ * include/hal_if.h: ROM/RAM calling interface table
+ definitions. The layout is a combination of libbsp and vectors
+ already in use by some eCos platforms.
+
+
+ * cdl/hal.cdl: Added CYGxxx_HAL_VIRTUAL_VECTOR_SUPPORT
+ options. These are used to control whether a platform uses the new
+ ROM/RAM calling interface. All platforms will be converted to use
+ this, but piecemeal over a period of time, thus the requirement
+ for selecting behavior.
+
+2000-06-04 Gary Thomas <gthomas@redhat.com>
+
+ * cdl/hal.cdl: Support variant 'pkgconf' headers. This will allow
+ [variant] common symbols to be defined, rather than duplicating
+ them over all platforms using that variant.
+
+2000-05-25 Jesper Skov <jskov@redhat.com>
+
+ * cdl/debugging.cdl: Allow thread support to included for ROM
+ monitor builds.
+
+2000-05-22 Jesper Skov <jskov@redhat.com>
+
+ * cdl/debugging.cdl: Allow platform to prevent CTRLC inclusion.
+
+2000-04-12 Jesper Skov <jskov@redhat.com>
+
+ * cdl/debugging.cdl: Don't let interfaces define anything.
+
+2000-04-07 Jesper Skov <jskov@redhat.com>
+
+ * cdl/hal.cdl: Fix dependencies for stub.
+
+2000-03-28 Jesper Skov <jskov@redhat.com>
+
+ * src/generic-stub.c (__process_packet): Added 'z' packet reply.
+
+2000-03-28 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/hal.cdl:
+
+ Adjust documentation URLs.
+
+2000-03-24 Jesper Skov <jskov@redhat.com>
+
+ * include/hal_stub.h: Fixed a bad function name. Made it opssible
+ for archs to define CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION.
+
+2000-03-20 Jesper Skov <jskov@redhat.com>
+
+ * cdl/debugging.cdl: Preclude USE_MONITOR when including stubs.
+
+2000-03-01 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/common.cdl:
+ Define CYGINT_HAL_DIAG_DISABLE_GDB_PROTOCOL_SUPPORTED as an
+ 'interface' so implementations can be properly specified.
+
+2000-02-29 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/common.cdl: Option to disable GDB protocol now supported
+ by QUICC based PowerPC systems.
+
+2000-02-29 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * include/generic-stub.h: Make header C++ safe
+
+2000-02-16 Jesper Skov <jskov@redhat.com>
+
+ * include/hal_stub.h: fixed endian definitions.
+
+2000-02-10 Jesper Skov <jskov@redhat.com>
+
+ * include/pkgconf/hal.h: Added CYGSEM_HAL_ROM_MONITOR
+ * src/hal_stub.c (initHardware): CYG_HAL_STARTUP_STUBS ->
+ CYGSEM_HAL_ROM_MONITOR.
+ Removed HAL_STUB_PLATFORM_STUBS_INIT.
+
+2000-02-09 Jesper Skov <jskov@redhat.com>
+
+ * cdl/hal.cdl: Added remaining build dependencies.
+
+2000-02-04 Jesper Skov <jskov@redhat.com>
+
+ * cdl/hal.cdl: Fix test list display.
+
+2000-02-03 Jesper Skov <jskov@redhat.com>
+
+ * include/pkgconf/hal.h: CYG_HAL_POWERPC_x->CYGPKG_...
+
+2000-02-03 Jesper Skov <jskov@redhat.com>
+
+ * cdl/debugging.cdl: Use interfaces for stub capabilities instead
+ of exclude list.
+ * cdl/hal.cdl: Add extra dependencies to common stub build rule.
+
+2000-02-02 Jesper Skov <jskov@redhat.com>
+
+ * cdl/hal.cdl: Added HAL tests.
+
+2000-01-31 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/hal.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-28 Simon FitzMaurice <sdf@cygnus.co.uk>
+ * cdl/hal.cdl:
+
+ Adjust help URLs in line with new doc layout.
+
+2000-01-27 Jesper Skov <jskov@redhat.com>
+
+ * cdl/hal.cdl: Added simple build rules for common stub.
+
+2000-01-26 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * src/hal_stub.c (__reset): Replace CYGDAT_CYGMON_ENABLE
+ dependency with just CYGPKG_CYGMON
+ (initHardware): Likewise
+ (__set_baud_rate): Likewise
+ (putDebugChar): Likewise
+
+2000-01-17 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/common.cdl,
+ cdl/debugging.cdl:
+
+ Modify the default_value attribute for
+ CYGFUN_HAL_COMMON_KERNEL_SUPPORT, CYGPKG_HAL_EXCEPTIONS
+ and CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT to do the right
+ thing in the absence of the eCos kernel package.
+
+1999-12-22 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/hal.cdl:
+
+ Add CFLAGS to the custom rule for extras.o to accommodate
+ arm big-endian targets.
+
+1999-12-21 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Rename all CYG_HAL_USE_ROM_MONITOR_GDB_STUBS
+ -> CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs
+ Rename all CYG_HAL_USE_ROM_MONITOR_CYGMON ->
+ CYGSEM_HAL_USE_ROM_MONITOR_CygMon
+ Rename all CYG_HAL_USE_ROM_MONITOR -> CYGSEM_HAL_USE_ROM_MONITOR
+ Don't need to define CYG_HAL_SH_SH7708 any more
+
+ * cdl/hal.cdl: Add CYGPKG_HAL_ROM_MONITOR container package for
+ platforms to put ROM-monitor related options into
+ Move all ROM-monitor related options into individual platform CDL
+
+1999-12-02 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/hal.cdl:
+
+ Use '$<' to reference custom rule dependency.
+
+1999-12-01 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/hal.cdl:
+
+ Use the <PREFIX> token in custom rules.
+
+1999-11-29 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/hal.cdl:
+
+ Use wildcard in the custom rule for extras.o to
+ accommodate 'make -n'.
+
+1999-11-23 Simon Fitzmaurice <sdf@cygnus.co.uk>
+ * cdl\common.cdl: Correct example of illiteracy
+
+1999-11-20 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/common.cdl: Add MMU tables options.
+
+ * include/pkgconf/hal.h (CYGSEM_HAL_INSTALL_MMU_TABLES):
+ (CYGSEM_HAL_STATIC_MMU_TABLES): New options to control MMU table
+ flavour and placement.
+
+1999-11-15 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/dbg-threads-api.h, include/generic-stub.h,
+ include/hal_stub.h: Add comments to explain these header files should
+ not be included by user programs
+
+1999-11-09 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * cdl/common.cdl: Add CYGDBG_HAL_DIAG_DISABLE_GDB_PROTOCOL.
+
+ * include/pkgconf/hal.h (CYGDBG_HAL_DIAG_DISABLE_GDB_PROTOCOL):
+ New option which [explicitly] controls use of GDB protocol
+ for diagnostic I/O.
+
+1999-11-03 Jesper Skov <jskov@cygnus.co.uk>
+
+ * cdl/hal.cdl: More crud out + mn10300 fixes.
+
+1999-11-02 Jesper Skov <jskov@cygnus.co.uk>
+
+ * cdl/hal.cdl: Cleaned out some of the CPU config entries.
+
+1999-10-29 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * tests/PKGconf.mak: Add cache tests for Cirrus Logic boards.
+
+1999-10-29 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/cache.c: Made safe for targets with no cache.
+
+ * tests/PKGconf.mak: Don't build cache test for ARM unless
+ explicitly enabled.
+
+1999-10-28 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/cache.c: Fix array size.
+
+1999-10-27 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/hal_stub.c: Fix typo (CYGDAT_CYGMON_ENABLE). Also need
+ to include <pkgconf/cygmon.h>
+
+1999-10-27 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/hal_stub.c: Add explicit enable for CygMon package.
+
+1999-10-27 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * src/hal_stub.c (cyg_hal_gdb_interrupt): Bugfix to previous: ^Cs
+ were being ignored when received by the diag output code, because
+ there was already a break in place. Solution is to let
+ cyg_hal_gdb_interrupt() override any previous break, and tidy up
+ state of course.
+
+1999-10-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * include/hal_stub.h (CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION): Place
+ the break at the address of a label within the calling context
+ [normally hal_diag_write_char()]; this is neater and more
+ portable; it's supported for more targets. Also use
+ cyg_hal_place_break() to place it, define that, &c.
+
+ * src/hal_stub.c (cyg_hal_gdb_place_break): New routine to
+ specially handle the inline breakpoint. It basically does the
+ same as cyg_hal_gdb_interrupt(), except on some platforms where
+ you must do different things to set a bp from a non-interrupt
+ context.
+
+1999-10-25 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/hal_stub.c (putDebugChar, getDebugChar): When building with
+ CygMon, these functions are defined by CygMon.
+
+1999-10-26 John Dallaway <jld@cygnus.co.uk>
+
+ * cdl/hal.cdl:
+
+ Modify custom make rule to specify file paths relative
+ to the package version directory.
+
+1999-10-22 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * include/hal_stub.h (CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION):
+ (CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION): new macros to be invoked
+ in hal_diag routines to make atomic the code that outputs a
+ complete GDB $O packet. This is required so that watching
+ variables (which is implemented by stepping) and stepping itself
+ does not try to ss through that $O output code. CASE 102327.
+
+ * src/hal_stub.c (cyg_hal_gdb_break_is_set): new routine to query
+ whether a break is set: used by step in the stubs to decide to
+ continue instead, because we are in a critical region.
+ (cyg_hal_gdb_running_step): communication between generic stub and
+ here: if set, a step has been converted into a continue, so we do
+ NOT obey cyg_hal_gdb_remove_break until it is cleared, in
+ handle_exception_cleanup().
+
+ * src/generic-stub.c (__process_packet): If there is a break set
+ by the hal_stub.c, convert a step to continue, and set
+ cyg_hal_gdb_running_step to say we did so.
+
+1999-10-22 Jesper Skov <jskov@cygnus.co.uk>
+ Case 102379
+ * src/generic-stub.c (__handle_exception): Flush and clear caches
+ after cleaning up after single-stepping.
+
+ (memcpy, memset): Added to prevent stub hanging if user puts
+ breakpoints in either function.
+
+1999-10-19 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Added monitor configury for Brother
+ board.
+
+1999-10-10 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/thread-packets.c (stub_pkt_currthread): Fix typo in comment.
+
+ * src/generic-stub.c: Reorg to expose register get/set functions.
+
+1999-10-08 Simon Fitzmaurice <sdf@cygnus.co.uk>
+ * cdl\interrupts.cdl: Quoted '[' and ']' (significant in TCL and thus CDL)
+
+1999-10-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * cdl/interrupts.cdl: Added
+ CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS.
+
+1999-09-22 Simon FitzMaurice <sdf@cygnus.co.uk>
+
+ * cdl\hal.cdl : add priority field to "extras.o" rule
+
+1999-09-21 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/thread-packets.c: Fix some typos in comments.
+
+1999-09-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/hal_stub.c: Override generic GDB interrupt functions for
+ ARM. Need them to be thumb aware.
+
+1999-09-13 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Add new config option to allow spurious
+ interrupts to be ignored by the HAL.
+
+ * src/generic-stub.c (__process_packet): Build in version string
+ (date/time) for stubs in ROM to be returned via 'd' packet.
+
+1999-09-09 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/hal.h (CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS): Rename
+ CYGPKG_HAL_MN10300_SIM to CYGPKG_HAL_MN10300_AM31_SIM
+
+1999-09-07 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/dbg-threads-syscall.c (dbg_currthread_id): Fixed to return
+ zero if dbg_currthread() returns false. Previously it could have
+ returned a random value which would have made GDB think there had
+ been a thread switch when there hadn't. It was particularly prone
+ to do this in configurations where the kernel was absent.
+
+1999-09-01 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Always include target and platform package
+ include (pkgconf) files.
+
+1999-08-26 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/generic-stub.c (__hex2mem_helper):
+ Use target_register_t when casting to address type, rather than long
+ Since the compiler can choose arbitrary alignment of unions, force
+ to use byte array only
+ Restore use of loop termination test for *hexMemSrc, just in case
+ since that's how it used to be
+ Increment destination, not source at end of loop
+
+ (__mem2hex_helper):
+ Use target_register_t when casting to address type, rather than long.
+ Since the compiler can choose arbitrary alignment of unions, force
+ to use byte array only. Therefore use single __read_mem_safe() call
+
+ * src/hal_stub.c (__do_copy_mem): Reassign back from dst/src at start
+ of each "if" clause in case we go round the loop again.
+
+1999-08-24 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/hal_stub.c (__do_copy_mem): Move temp variables to top of
+ function - potentially safer if there is an error.
+
+1999-08-23 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * src/generic-stub.c (__process_packet): For 'g' and 'G' packets,
+ when the register size differs from sizeof(target_register_t) we must
+ adjust according to the endianness
+
+ * include/hal_stub.h: Ensure __LITTLE_ENDIAN__ is defined on
+ little-endian targets
+
+ * src/hal_stub.c (__build_t_packet): Use the correct register sizes
+ for PC and SP rather than assuming they are the same as target_register_t
+
+1999-08-23 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * include/generic-stub.h: Change prototypes for internal functions.
+
+ * src/hal_stub.c (__do_copy_mem):
+ * src/generic-stub.c (__mem2hex_helper): Rework to perform aligned,
+ multi-byte operations when conditions allow. This should handle
+ most "hardware register" access cases. Note: there currently is
+ no good way to force GDB to require/use such accesses.
+
+1999-08-17 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * tests/intr.c (cyg_start): Use CYG_TEST_NA rather than a pass saying
+ it's inapplicable
+
+1999-08-16 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Rename CYG_HAL_MN10300_AM32_STDEVAL1 to
+ CYG_HAL_MN10300_AM31_STDEVAL1
+
+1999-08-13 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/hal_stub.c: Removed superfluous trace() extern.
+
+1999-08-12 Nick Garnett <nickg@cygnus.co.uk>
+
+ Imported following changes from AM33 branch:
+
+ 1999-07-27 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/hal_stub.c: Added support for 1 byte breakpoints.
+ Removed invalidates for cache flushes - I am not entirely sure why
+ we have these here, since HAL_DCACHE_SYNC() should do what we
+ need, and these invalidates are causing a problem on the MIPS and
+ MN10300 targets.
+
+ * include/pkgconf/hal.h: Added Monitor selection for AM33.
+
+ 1999-06-29 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Modified to match new MN10300 HAL
+ organization.
+
+1999-08-06 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/generic-stub.c (__process_packet): FLush and clear caches
+ after call to __single_step.
+
+1999-07-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/intr.c: Don't use kernel's RTC definitions.
+
+1999-07-02 Jesper Skov <jskov@cygnus.co.uk>
+ PR20157
+ * tests/cache.c: Print stride values, preventing timeout on slow
+ targets.
+
+1999-06-28 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h (CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT):
+ Fixed parent.
+
+1999-06-24 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Clarify descriptions of
+ CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT and
+ CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT.
+
+1999-06-17 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Added CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT
+ to enable inclusion of ^C interrupt handler. Added CDL to control
+ it.
+
+1999-06-10 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Add support for the PowerPC target MBX860
+ platform, CYG_HAL_POWERPC_MBX.
+
+1999-06-10 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/hal_stub.c: Need to init register pointer.
+
+1999-06-08 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Added CYG_HAL_ROM_MONITOR for EDK7708.
+
+1999-05-31 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/hal_stub.c: Respect HAL_BREAKINST_SIZE setting.
+
+1999-05-28 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Renamed SH platform package to edk7708.
+
+1999-05-28 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/hal_stub.c (initHardware): Added call to
+ HAL_STUB_PLATFORM_INIT if it is defined.
+
+ * include/pkgconf/hal.h: Added a #undef for CYG_HAL_ROM_MONITOR,
+ largely so that a stubrom permutation can define it.
+
+1999-05-27 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/hal_stub.c: Do not call HAL_ICACHE_INVALIDATE_ALL() and
+ HAL_DCACHE_INVALIDATE_ALL() in __instruction_cache() and
+ __data_cache() for MIPS targets. These macros are simply
+ duplicates.
+
+1999-05-27 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/cache.c: Added handling of unified caches.
+
+1999-05-25 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * tests/cache.c: Use HAL_DCACHE_SYNC if available
+
+1999-05-24 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Added CPU specifier for EDK board.
+
+1999-05-21 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/hal_stub.c (__install_traps): Set exit vector to __reset.
+
+1999-05-21 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Switched VR4300 over to using GDB STUBS
+ monitor from PMON.
+
+1999-05-21 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/intr.c: Get RTC values from CYGBLD_HAL_PLATFORM_H.
+ Ensure there are fallback definitions.
+
+ * src/hal_stub.c (handle_exception_cleanup): Added optional call
+ of HAL_STUB_PLATFORM_STUBS_FIXUP macro.
+
+1999-05-18 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/hal_stub.c (hal_output_gdb_string): Added missing ;
+
+1999-05-13 Nick Garnett <nickg@cygnus.co.uk>
+
+ The following changes were all made on a branch and imported into
+ the main trunk later.
+
+ 1999-05-11 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ tidied up all MIPS targets to include CYGBLD_HAL_TARGET_H. This
+ will eventually apply to all configurations.
+
+ 1999-05-06 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/PKGconf.mak (COMPILE): Added dbg-threads-syscall.c.
+
+ * include/dbg-thread-syscall.h:
+ * src/dbg-threads-syscall.c:
+ Files added to enable support for thread-awareness in GDB stub
+ ROMs. The .h file has been moved from kernel/src/debug.
+
+ 1999-04-28 Nick Garnett <nickg@cygnus.co.uk>
+
+ * src/hal_stub.c (__build_t_packet): Changed sp variable to a
+ non-pointer type to force it to be installed in the T packet with
+ the right size.
+
+ * src/drv_api.c: Added cyg_interrupt_call_pending_DSRs() to keep
+ HAL happy in non-kernel configurations.
+
+ 1999-04-21 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ Added VR4300 configury for ROM monitor use and inclusion of
+ variant-specific configuration header. This needs some further
+ tidying up.
+
+1999-04-28 Bart Veer <bartv@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ Use the new rules for generating libextras.a
+
+1999-04-27 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: GDB_BREAK support now available for ARM
+ targets.
+
+1999-04-16 Bart Veer <bartv@cygnus.co.uk>
+
+ * src/PKGconf.mak:
+ * src/dummy.c:
+ New file that can always be added to libextras.a without
+ affecting image sizes.
+
+1999-04-14 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/hal_stub.h:
+ Make sure all functions have C linkage even in C++
+
+1999-04-14 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19845
+ * src/generic-stub.c (__process_packet): Reset _register pointer
+ to the exception state before attempting to set up single-step
+ magic.
+
+1999-04-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/hal_stub.h: Added declaration for __stub_copy_registers.
+
+1999-04-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/hal_stub.c: Use HAL_xCACHE_IS_ENABLED if defined.
+
+1999-04-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/hal_stub.c:
+ Moved get_register and put_register here. Made them access the
+ currently selected register set.
+
+1999-03-22 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/dbg-threads-api.h: Update copyright
+
+ * src/generic-stub.c: Change Cygnus Support->Cygnus Solutions
+
+ * src/thread-packets.c: Update copyright
+
+ * src/thread-pkts.h: Update copyright
+
+1999-03-19 Nick Garnett <nickg@cygnus.co.uk>
+
+ * tests/cache.c: Added interrupt disable and enable to cache state
+ change blocks, in line with similar changes to kcache1.
+
+1999-03-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/hal_stub.c (hal_output_gdb_string): Use disable/restore
+ macros to make sure it works even when interruptible() is a NOP
+ function.
+
+1999-03-10 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ Changed include of hal_tx39_jmr3904.h to hal_tx39.h.
+
+1999-03-05 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/drv_api.h:
+ * src/drv_api.c:
+ Fixed some typos in non-kernel configuration support.
+
+1999-03-04 Jesper Skov <jskov@cygnus.co.uk>
+ PR 19367
+ * include/pkgconf/hal.h: Exclude GDB stubs on sparc.
+
+1999-02-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/generic-stub.c:
+ * include/generic-stub.h:
+ Added binary download patches from libstub.
+
+1999-02-25 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/drv_api.h:
+ * src/drv_api.c:
+ Added these files to define driver API.
+
+1999-02-23 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ Added include of <pkgconf/hal_tx39_jmr3904.h> to get TX39 speed
+ configuration options.
+
+1999-02-20 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * tests/intr.c:
+ Rename CYGNUM_VECTOR_RTC -> CYGNUM_HAL_INTERRUPT_RTC in line with
+ HAL changes
+
+1999-02-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/hal_stub.c:
+ * src/generic-stub.c (__handle_exception):
+ Only include cyg_hal_gdb_break magic when stub is configured to
+ handle GDB BREAK signals.
+
+1999-02-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/generic-stub.c (__handle_exception): Moved special signal
+ handling here to avoid duplication for all architectures.
+
+1999-02-16 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/stubrom/stubrom.c: Changed set_debug_traps to initialize_stub.
+
+ * include/hal_stub.h: [added]
+ * include/generic-stub.h:
+ * src/hal_stub.c: [added]
+ * src/board.h: [added]
+ * src/thread-pkts.h:
+ * src/thread-packets.c:
+ * src/generic-stub.c:
+ * src/PKGconf.mak:
+ Merged in latest libstub changes. Moved most eCos specific changes
+ into hal_stub.[ch], reducing effort required for further
+ merging/integration.
+
+1999-02-05 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Cleaned up the MPC8xx configuration.
+
+1999-01-29 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Added simple MPC8xx configuration.
+
+1999-01-26 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * tests/cache.c (time0): Waste much less time if running in a
+ simulator. Do only 40 loops instead of 4000.
+ In consequence the nasty meddling with MAX_STRIDE depending on
+ HAL_xxx_SIM package definitions can go.
+
+1999-01-22 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Renamed CYG_HAL_POWERPC_FADS to
+ CYGPKG_HAL_POWERPC_FADS.
+
+1999-01-21 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ Tidy up and update description
+ Add new CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG option to allow default
+ priority static constructors to be deferred
+ Remove all traces of non-CYG_KERNEL_USE_INIT_PRIORITY code
+
+1999-01-21 Jesper Skov <jskov@cygnus.co.uk>
+ Merge with FADS branch.
+
+ 1998-12-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Don't allow GDB BREAK support on FADS.
+ Define _MPC860, not _MP860.
+
+ 1998-12-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ Added FADS entry from Kevin Hester <KHester@opticworks.com>.
+
+ 1999-01-19 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ Add CYG_KERNEL_USE_INIT_PRIORITY for SPARCLITE.
+
+1999-01-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 18823
+ * include/pkgconf/hal.h: Don't allow GDB stubs to be configured
+ for Linux target.
+
+1999-01-18 Jesper Skov <jskov@cygnus.co.uk>
+ PR 18822
+ * include/pkgconf/hal.h: GDB_BREAK support not available for ARM
+ targets.
+
+1999-01-14 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/stubrom/PKGconf.mak: Rename 'TESTS' to 'PROGS' due to
+ changes in 'makrules.prv'.
+
+1999-01-14 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/stubrom/stubrom.c (cyg_start): Fix compiler warning.
+
+ * include/dbg-threads-api.h: Include cyg_type.h to get externC
+ definition.
+
+1999-01-14 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/dbg-threads-api.h: Added prototype for dbg_scheduler().
+
+1999-01-13 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/generic-stub.c (__output_hex_value): Change buffer size
+ [2048 was rather large] and make stack based. Also don't
+ allow for string to exceed buffer.
+
+1999-01-13 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/generic-stub.c (strcpy): Terminate copied string.
+
+1999-01-11 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/intr.c (CYGNUM_KERNEL_COUNTERS_RTC_PERIOD): Added RTC data
+ for Linux.
+
+Wed Dec 9 14:07:30 GMT 1998 Chris Provenzano <proven@cygnus.com>
+
+ * include/pkgconf/hal.h: Compile the i386 linux target with
+ CYG_KERNEL_USE_INIT_PRIORITY defined.
+
+1999-01-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/generic-stub.c (interruptible): Cleaned up a bit.
+
+1999-01-04 Jesper Skov <jskov@cygnus.co.uk>
+ PR 18572
+
+ * tests/cache.c: Purge data cache before invalidating it.
+
+1998-12-09 Gary Thomas <gthomas@cygnus.co.uk>
+
+ * src/generic-stub.c: Better handling of errors while stubs
+ are accessing memory on behalf of GDB. Requires support for
+ GCC 'computed goto label' in top-level exception handler.
+
+1998-12-09 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Removed the
+ CYGARC_HAL_COMMON_EXPORT_CPU_MACROS option. Causing failures in
+ permutation tests.
+
+1998-12-07 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/generic-stub.c (process_exception): Send an acknowledge char
+ on first entry so GDB doesn't timeout before resending its initial
+ packet.
+
+1998-11-26 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Added
+ CYGARC_HAL_COMMON_EXPORT_CPU_MACROS.
+
+1998-11-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/cache.c: Only run with stride 1 on SIMs.
+
+1998-11-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Define SIM as a 603 CPU.
+
+1998-11-19 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/intr.c:
+ Make the test do nothing if kernel real-time clock is enabled.
+ Added different timer constants for PPC SIM and HW.
+
+1998-11-17 Jesper Skov <jskov@cygnus.co.uk>
+
+ * tests/intr.c:
+ * include/pkgconf/hal.h:
+ Renamed CYG_HAL_POWERPC_MP860 to CYG_HAL_POWERPC_MPC860.
+
+1998-11-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Made CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT a
+ sub-option of CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS.
+
+1998-11-16 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Allow GDB stubs to be configured for
+ MN10300 HW. Allow GDB_BREAK for all but tx39.
+
+1998-11-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Made CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT a
+ sub-option of CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS.
+
+1998-11-04 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/generic-stub.c (process_packet): Flush D cache before
+ invalidating I cache.
+
+1998-11-02 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/generic-stub.c (__handle_exception): Check for breakpoints
+ set by GDB interrupt handler.
+
+1998-10-25 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/thread-packets.c: Fixed closing #endif comment.
+
+ * src/generic-stub.c: Fixed closing #endif comment.
+
+1998-10-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * src/hal_common.c: Removed. We can't use weak default functions
+ when they may conflict with strong functions in the library.
+
+1998-10-23 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/generic-stub.h: Added __interruptible_control.
+
+1998-10-23 Jesper Skov <jskov@cygnus.co.uk>
+ PR 17460, PR 17913
+
+ * include/pkgconf/hal.h: Let HAL exception support require Kernel
+ exception support.
+
+1998-10-21 Jesper Skov <jskov@cygnus.co.uk>
+ PR 17842
+
+ * include/pkgconf/hal.h: Let HAL GDB thread support require Kernel
+ GDB thread support.
+
+1998-10-20 Jesper Skov <jskov@lassi.cygnus.co.uk>
+ PR 17460
+
+ * src/hal_common.c: Added. Includes a weak handle_exception
+ definition.
+
+1998-10-20 Jesper Skov <jskov@cygnus.co.uk>
+ PR 17885, 17880, 17841
+
+ * include/pkgconf/hal.h: Don't allow GDB stubs to be configured
+ for SIMs or MN10300.
+
+1998-10-19 Jesper Skov <jskov@lassi.cygnus.co.uk>
+
+ * src/thread-packets.c: Sync'd with libstub source.
+
+1998-10-16 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/hal.h (CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE):
+ Added new configuration option for interrupt stack size.
+
+Thu Oct 15 21:25:55 1998 Jonathan Larmour <jlarmour@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ Make CYGFUN_HAL_COMMON_KERNEL_SUPPORT require the kernel, as it
+ is enabling this is eCos-kernel specific, and relies on
+ configuration options defined only in the kernel
+ Required for PR 17229
+
+1998-10-15 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h (CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT):
+ Added config option.
+
+1998-10-14 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ Move some configury from kernel.h to here. Particularly the
+ support for GDB stubs.
+
+ * tests/cache.c:
+ * tests/context.c:
+ * tests/intr.c:
+ * tests/PKGconf.mak:
+ New directory of HAL-only test programs. Currently contains some
+ very basic test programs.
+
+ * include/generic-stub.h:
+ * include/dbg-threads-api.h:
+ * src/generic-stub.c:
+ * src/thread-packets.c:
+ * src/thread-pkts.h:
+ * src/stubrom/PKGconf.mak:
+ * src/stubrom/stubrom.c:
+ Moved these files here from kernel.
+
+1998-10-08 Gary Thomas <gthomas@penang.cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ Add support for new architecture.
+
+1998-09-23 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ Switched TX39 over to using CYGMON from GDB stubs.
+
+Tue Sep 15 19:13:04 1998 David Moore <dsm@keema.cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Cleaned up comments.
+
+Mon Sep 14 11:08:26 1998 Jesper Skov <jskov@lassi.cygnus.co.uk>
+ PR 17230
+
+ * include/pkgconf/hal.h: Added IMP_HAL_COMMON_INTERRUPTS_CHAIN
+ option.
+
+1998-09-14 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ Fixed typo in description.
+
+1998-09-12 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ Sort out exception handling options (PR 16953)
+ Added missing descriptions (PR 17184)
+
+Tue Sep 8 17:16:39 1998 Hugo Tyson <hmt@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ Elide some spurious redefines of CYG_HAL_MN10300_STDEVAL1 and
+ CYG_HAL_MN10300_SIM within ifdefs conditioned on same.
+
+1998-09-03 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ CYGPKG_HAL_COMMON is now a component, not a package.
+
+1998-09-02 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ Moved target and platform specific configuration data to
+ the appropriate packages.
+
+ Symbols identifying the target hardware should be just defined,
+ not given a value, as per the coding standards.
+
+Mon Aug 31 09:16:08 1998 Jesper Skov <jskov@cygnus.co.uk>
+
+ * include/pkgconf/hal.h: Added INIT_PRIORITY default setting for
+ powerpc.
+
+1998-08-28 Bart Veer <bartv@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ Added configuration data.
+
+1998-08-20 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ Moved definition of CYG_KERNEL_USE_INIT_PRIORITY here from
+ kernel.h.
+
+1998-08-18 Nick Garnett <nickg@cygnus.co.uk>
+
+ * include/pkgconf/hal.h:
+ Created this file to contain HAL config options.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2010, 2011 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 or (at your option) any
+// later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc., 51 Franklin Street,
+// Fifth Floor, Boston, MA 02110-1301, USA.
+// -------------------------------------------
+// ####GPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/ecos/packages/hal/common/current/cdl/common.cdl b/ecos/packages/hal/common/current/cdl/common.cdl
new file mode 100644
index 0000000..245f731
--- /dev/null
+++ b/ecos/packages/hal/common/current/cdl/common.cdl
@@ -0,0 +1,194 @@
+# ====================================================================
+#
+# common.cdl
+#
+# HAL common configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: nickg,jskov,jlarmour
+# Contributors:
+# Date: 1999-07-02
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_option CYGFUN_HAL_COMMON_KERNEL_SUPPORT {
+ display "Provide eCos kernel support"
+ requires CYGPKG_KERNEL
+ default_value CYGPKG_KERNEL
+ description "
+ The HAL can be configured to either support the full eCos
+ kernel, or to support only very simple applications which do
+ not require a full kernel. If kernel support is not required
+ then some of the startup, exception, and interrupt handling
+ code can be eliminated."
+}
+
+# NOTE: The requirement for kernel exception support is bogus in that
+# the user can supply a deliver_exception function herself. In that
+# case, however, it is easy to force the kernel option off while leaving
+# this one on. Having the requirement prevents accidental invalid
+# configurations of the kernel.
+cdl_option CYGPKG_HAL_EXCEPTIONS {
+ display "HAL exception support"
+ requires CYGPKG_KERNEL_EXCEPTIONS
+ default_value CYGPKG_KERNEL_EXCEPTIONS
+ description "
+ When a processor exception occurs, for example an attempt to
+ execute an illegal instruction or to perform a divide by
+ zero, this exception may be handled in a number of different
+ ways. If the target system has gdb support then typically
+ the exception will be handled by gdb code. Otherwise if the
+ HAL exception support is enabled then the HAL will invoke a
+ routine deliver_exception(). Typically this routine will be
+ provided by the eCos kernel, but it is possible for
+ application code to provide its own implementation. If the
+ HAL exception support is not enabled and a processor
+ exception occurs then the behaviour of the system is
+ undefined."
+}
+
+cdl_option CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG {
+ display "Stop calling constructors early"
+ requires CYGSEM_LIBC_INVOKE_DEFAULT_STATIC_CONSTRUCTORS
+ default_value 0
+ description "
+ This option supports environments where some constructors
+ must be run in the context of a thread rather than at
+ simple system startup time. A boolean flag named
+ cyg_hal_stop_constructors is set to 1 when constructors
+ should no longer be invoked. It is up to some other
+ package to deal with the rest of the constructors.
+ In the current version this is only possible with the
+ C library."
+}
+
+cdl_interface CYGINT_HAL_SUPPORTS_MMU_TABLES {
+ display "HAL uses the MMU and allows for CDL manipulation of it's use"
+}
+
+cdl_option CYGSEM_HAL_INSTALL_MMU_TABLES {
+ display "Install MMU tables."
+ default_value { CYG_HAL_STARTUP != "RAM" }
+ active_if CYGINT_HAL_SUPPORTS_MMU_TABLES
+ description "This option controls whether this application installs
+ its own Memory Management Unit (MMU) tables, or relies on the
+ existing environment to run."
+}
+
+cdl_option CYGSEM_HAL_STATIC_MMU_TABLES {
+ display "Use static MMU tables."
+ default_value 0
+ requires CYGSEM_HAL_INSTALL_MMU_TABLES
+ description "This option defines an environment where any Memory
+ Management Unit (MMU) tables are constant. Normally used by ROM
+ based environments, this provides a way to save RAM usage which
+ would otherwise be required for these tables."
+}
+
+cdl_component CYGDBG_HAL_DIAG_TO_DEBUG_CHAN {
+ display "Route diagnostic output to debug channel"
+ default_value { (CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS \
+ || CYG_HAL_STARTUP == "RAM") ? 1 : 0}
+ active_if !CYGSEM_HAL_VIRTUAL_VECTOR_INHERIT_CONSOLE
+ active_if { CYGPKG_HAL_ARM || CYGPKG_HAL_POWERPC_MPC8xx \
+ || CYGPKG_HAL_V85X_V850 || CYGSEM_HAL_VIRTUAL_VECTOR_DIAG }
+ description "
+ If not inheriting the console setup from the ROM monitor,
+ it is possible to redirect diagnostic output to the debug
+ channel by enabling this option. Depending on the debugger
+ used it may also be necessary to select a mangler for the
+ output to be displayed by the debugger."
+
+ cdl_option CYGSEM_HAL_DIAG_MANGLER {
+ display "Mangler used on diag output"
+ flavor data
+ legal_values {"GDB" "None"}
+ default_value { "GDB" }
+ description "
+ It is sometimes necessary to mangle (encode) the
+ diag ASCII text output in order for it to show up at the
+ other end. In particular, GDB may silently ignore raw
+ ASCII text."
+ }
+}
+
+cdl_component CYGBLD_HAL_LINKER_GROUPED_LIBS {
+ display "Grouped libraries for linking"
+ flavor data
+ default_value CYGBLD_HAL_LINKER_GROUPED_LIBS_DEFAULT
+ requires { is_substr(CYGBLD_HAL_LINKER_GROUPED_LIBS, "libtarget.a") }
+ description "
+ This option provides a list of libraries used to satisfy
+ linker dependencies, but necessary for building eCos. It is passed
+ to a GROUP() directive in the linker script, which is analogous
+ to using the \"-(\" aka \"--start-group\", and \"-)\" aka
+ \"--end-group\" options on the linker command line.
+
+ It provides a similar function to adding \"-llibname\" to the
+ linker, but with the added feature that each library in the group
+ is scanned in turn for unresolved symbols, and this process is
+ repeated until there are no more unresolved symbols. This is important
+ for system libraries as there are often mutual dependencies.
+
+ This option should not be used for adding application specific
+ libraries. That should be done in the application's own makefile
+ or link line.
+
+ Users wishing to use the GNU Compiler prior to GCC 3.0 will
+ need to remove libsupc++.a from this option.
+
+ Note that libtarget.a is always required to build eCos."
+
+ cdl_option CYGBLD_HAL_LINKER_GROUPED_LIBS_DEFAULT {
+ display "Default setting"
+ flavor data
+ default_value { "libtarget.a libgcc.a libsupc++.a" }
+ description "
+ This option is intended to be used by other eCos packages (including
+ HAL packages) to provide a different default value for
+ CYGBLD_HAL_LINKER_GROUPED_LIBS.
+
+ This is separated into its own option to continue to
+ allow the user to make customisations to the grouped library
+ list."
+ }
+}
+
+# EOF common.cdl
diff --git a/ecos/packages/hal/common/current/cdl/debugging.cdl b/ecos/packages/hal/common/current/cdl/debugging.cdl
new file mode 100644
index 0000000..d5fa559
--- /dev/null
+++ b/ecos/packages/hal/common/current/cdl/debugging.cdl
@@ -0,0 +1,169 @@
+# ====================================================================
+#
+# debugging.cdl
+#
+# HAL debugging configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: nickg,jskov,jlarmour
+# Contributors: jld
+# Date: 1999-07-02
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_interface CYGINT_HAL_DEBUG_GDB_STUBS {
+ display "Support for GDB stubs"
+ no_define
+ description "
+ The HAL implements GDB stubs for the target."
+}
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS {
+ display "Include GDB stubs in HAL"
+ active_if CYGINT_HAL_DEBUG_GDB_STUBS
+ default_value 0
+ requires ! CYGSEM_HAL_USE_ROM_MONITOR
+ requires ! CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
+ requires ! CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM
+ requires { !CYGSEM_HAL_VIRTUAL_VECTOR_DIAG \
+ || CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_COMMS }
+ description "
+ This option causes a set of GDB stubs to be included into the
+ system. On some target systems the GDB support will be
+ provided by other means, for example by a ROM monitor. On
+ other targets, especially when building a ROM-booting system,
+ the necessary support has to go into the target library
+ itself. When GDB stubs are include in a configuration, HAL
+ serial drivers must also be included."
+
+ compile generic-stub.c thread-packets.c hal_stub.c drv_api.c bplist-dynamic.c
+}
+
+cdl_interface CYGINT_HAL_DEBUG_GDB_STUBS_BREAK {
+ display "Support for external break support in GDB stubs"
+ no_define
+ description "
+ The HAL implements external break (or asynchronous interrupt)
+ in the GDB stubs for the target."
+}
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT {
+ display "Include GDB external break support for stubs"
+ active_if CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
+ requires CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+ default_value CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+ implements CYGINT_HAL_COMMON_SAVED_INTERRUPT_STATE_REQUIRED
+ description "
+ This option causes the GDB stub to add a serial interrupt handler
+ which will listen for GDB break packets. This lets you stop the
+ target asynchronously when using GDB, usually by hitting Control+C
+ or pressing the STOP button. This option differs from
+ CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT in that it is used when
+ GDB stubs are present."
+}
+
+cdl_interface CYGINT_HAL_DEBUG_GDB_CTRLC_UNSUPPORTED {
+ display "Platform does not support CTRLC"
+ no_define
+}
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT {
+ display "Include GDB external break support when no stubs"
+ requires !CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+ active_if { CYGSEM_HAL_USE_ROM_MONITOR || CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS }
+ active_if { CYGINT_HAL_DEBUG_GDB_CTRLC_UNSUPPORTED == 0 }
+ default_value { !CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS }
+ implements CYGINT_HAL_COMMON_SAVED_INTERRUPT_STATE_REQUIRED
+ description "
+ This option adds an interrupt handler for the GDB serial line
+ which will listen for GDB break packets. This lets you stop the
+ target asynchronously when using GDB, usually by hitting Control+C
+ or pressing the STOP button. This option differs from
+ CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT in that it is used when the GDB
+ stubs are NOT present."
+}
+
+cdl_option CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT {
+ display "Include GDB multi-threading debug support"
+ active_if { CYGSEM_HAL_ROM_MONITOR || CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT }
+ default_value 1
+ description "
+ This option enables some extra HAL code which is needed
+ to support multi-threaded source level debugging."
+
+ compile dbg-threads-syscall.c
+}
+
+cdl_option CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES {
+ display "Number of times to retry sending a \$O packet"
+ default_value 0
+ flavor data
+ description "
+ This option controls the number of attempts that eCos programs
+ will make to send a \$O packet to a host GDB process. If it is
+ set non-zero, then the target process will attempt to resend the
+ \$O packet data up to this number of retries. Caution: use of
+ this option is not recommended as it can thoroughly confuse the
+ host GDB process."
+}
+
+cdl_option CYGNUM_HAL_DEBUG_GDB_PROTOCOL_TIMEOUT {
+ display "Timeout period for GDB packets"
+ default_value 500
+ flavor data
+ description "
+ This option controls the time (in milliseconds) that eCos programs
+ will wait for a response when sending packets to a host GDB process.
+ If this time elapses, then the packet will be resent, up to some
+ maximum number of times (CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES)."
+}
+
+cdl_option CYGDBG_HAL_CRCTABLE_LOCATION {
+ display "Location of CRC32 table"
+ flavor data
+ legal_values {"ROM" "RAM"}
+ default_value {"RAM"}
+ description "
+ The stubs use a 1 kilobyte CRC table that can either be pregenerated
+ and placed in ROM, or generated at runtime in RAM. Depending on
+ your memory constraints, one of these options may be better."
+}
+
+# EOF debugging.cdl
diff --git a/ecos/packages/hal/common/current/cdl/hal.cdl b/ecos/packages/hal/common/current/cdl/hal.cdl
new file mode 100644
index 0000000..3bc2d8f
--- /dev/null
+++ b/ecos/packages/hal/common/current/cdl/hal.cdl
@@ -0,0 +1,481 @@
+# ====================================================================
+#
+# hal.cdl
+#
+# HAL configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2010, 2011 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): bartv
+# Original data: nickg,jskov,jlarmour
+# Contributors: dmoseley, jld
+# Date: 1999-06-13
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_HAL {
+ display "eCos HAL"
+ include_dir cyg/hal
+ description "
+ The eCos HAL package provide a porting layer for
+ higher-level parts of the system such as the kernel and the
+ C library. Each installation should have HAL packages for
+ one or more architectures, and for each architecture there
+ may be one or more supported platforms. It is necessary to
+ select one target architecture and one platform for that
+ architecture. There are also a number of configuration
+ options that are common to all HAL packages."
+ doc ref/the-ecos-hardware-abstraction-layer.html
+
+ compile drv_api.c
+ compile -library=libextras.a dummy.c
+
+ requires CYGPKG_INFRA
+
+ make -priority 250 {
+ <PREFIX>/lib/extras.o: <PREFIX>/lib/libextras.a
+ $(CC) $(CFLAGS) -fno-profile-arcs -nostdlib -Wl,-r -T /dev/null -Wl,--whole-archive -o $@ $<
+ }
+
+ cdl_option CYGBLD_GLOBAL_WARNFLAGS {
+ display "Standard compiler warning flags"
+ parent CYGBLD_GLOBAL_OPTIONS
+ flavor data
+ no_define
+ calculated { "-Wall -Wpointer-arith -Wstrict-prototypes -Wundef -Woverloaded-virtual -Wno-write-strings " }
+ description "
+ This option specifies the default warning-related compiler flags used
+ on all eCos platforms."
+ }
+
+ cdl_component CYGPKG_HAL_COMMON {
+ display "Platform-independent HAL options"
+ flavor none
+ description "
+ A number of configuration options are common to most or all
+ HAL packages, for example options controlling how much state
+ should be saved during a context switch. The implementations
+ of these options will vary from architecture to architecture."
+
+ script common.cdl
+ }
+
+ cdl_component CYGPKG_HAL_COMMON_INTERRUPTS {
+ display "HAL interrupt handling"
+ flavor none
+ description "
+ A number of configuration options related to interrupt
+ handling are common to most or all HAL packages, even though
+ the implementations will vary from architecture to
+ architecture."
+
+ script interrupts.cdl
+ }
+
+ cdl_component CYGPKG_HAL_COMMON_CONTEXT {
+ display "HAL context switch support"
+ flavor none
+ description "
+ A number of configuration options related to thread contexts
+ are common to most or all HAL packages, even though the
+ implementations will vary from architecture to architecture."
+
+ cdl_option CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM {
+ display "Use minimum thread context"
+ parent CYGPKG_HAL_COMMON_CONTEXT
+ default_value 1
+ description "
+ The thread context switch code can exploit the calling
+ conventions defined for a given architecture to reduce the
+ amount of state that has to be saved during a context
+ switch. Generally this improves performance and reduces
+ code size. However it can make source-level debugging more
+ difficult."
+ }
+ }
+
+ cdl_component CYGPKG_HAL_CACHE_CONTROL {
+ display "Explicit control over cache behaviour"
+ flavor none
+ no_define
+ description "
+ These options let the default behaviour of the caches
+ be easily configurable."
+
+ cdl_component CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP {
+ display "Enable DATA cache on startup"
+ default_value 1
+ description "
+ Enabling this option will cause the data cache to be enabled
+ as soon as practicable when eCos starts up. One would choose
+ to disable this if the data cache cannot safely be turned on,
+ such as a case where the cache(s) require additional platform
+ specific setup."
+ cdl_option CYGSEM_HAL_DCACHE_STARTUP_MODE {
+ display "DATA cache mode on startup"
+ flavor data
+ legal_values { "COPYBACK" "WRITETHRU" }
+ default_value { "COPYBACK" }
+ description "
+ This option controls the mode the cache will be set to
+ when enabled on startup."
+ }
+ }
+
+ cdl_option CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP {
+ display "Enable INSTRUCTION cache on startup"
+ default_value 1
+ description "
+ Enabling this option will cause the instruction cache to be enabled
+ as soon as practicable when eCos starts up. One would choose
+ to disable this if the instruction cache cannot safely be turned on,
+ such as a case where the cache(s) require additional platform
+ specific setup."
+ }
+ }
+
+ cdl_component CYGPKG_HAL_DEBUG {
+ display "Source-level debugging support"
+ flavor none
+ description "
+ If the source level debugger gdb is to be used for debugging
+ application code then it may be necessary to configure in support
+ for this in the HAL."
+
+ script debugging.cdl
+ }
+
+ cdl_component CYGPKG_HAL_ROM_MONITOR {
+ display "ROM monitor support"
+ flavor none
+ no_define
+ description "
+ Support for ROM monitors can be built in to your application.
+ It may also be relevant to build your application as a ROM monitor
+ itself. Such options are contained here if relevant for your chosen
+ platform. The options and ROM monitors available to choose are
+ platform-dependent."
+
+
+
+ cdl_interface CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT {
+ display "Target has virtual vector support"
+ no_define
+ }
+
+
+ cdl_interface CYGINT_HAL_VIRTUAL_VECTOR_COMM_BAUD_SUPPORT {
+ display "Target supports baud rate control via vectors"
+ no_define
+ description "
+ Whether this target supports the __COMMCTL_GETBAUD
+ and __COMMCTL_SETBAUD virtual vector comm control operations."
+ }
+
+ cdl_component CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT {
+ display "Enable use of virtual vector calling interface"
+ active_if CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT
+ calculated 1
+ description "
+ Virtual vector support allows the HAL to let the ROM
+ monitor handle certain operations. The virtual vector table
+ defines a calling interface between applications running in
+ RAM and the ROM monitor."
+ compile hal_if.c hal_misc.c
+
+
+ cdl_option CYGSEM_HAL_VIRTUAL_VECTOR_INHERIT_CONSOLE {
+ display "Inherit console settings from ROM monitor"
+ active_if CYGSEM_HAL_USE_ROM_MONITOR
+ default_value { !CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_COMMS }
+ description "
+ When this option is set, the application will inherit
+ the console as set up by the ROM monitor. This means
+ that the application will use whatever channel and
+ mangling style was used by the ROM monitor when
+ the application was launched."
+ }
+
+ cdl_option CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE {
+ display "Debug channel is configurable"
+ calculated { CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_COMMS }
+ description "
+ This option is a configuration hint - it is enabled
+ when the HAL initialization code will make use
+ of the debug channel configuration option."
+ }
+
+ cdl_option CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE {
+ display "Console channel is configurable"
+ calculated { !CYGSEM_HAL_VIRTUAL_VECTOR_INHERIT_CONSOLE \
+ && !CYGDBG_HAL_DIAG_TO_DEBUG_CHAN }
+ description "
+ This option is a configuration hint - it is enabled
+ when the HAL initialization code will make use
+ of the console channel configuration option."
+ }
+
+
+ cdl_option CYGSEM_HAL_VIRTUAL_VECTOR_INIT_WHOLE_TABLE {
+ display "Initialize whole of virtual vector table"
+ default_value { CYG_HAL_STARTUP != "RAM" || !CYGSEM_HAL_USE_ROM_MONITOR }
+ requires CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_RESET
+ requires CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_DELAY_US
+ requires CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_DATA
+ requires CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_COMMS
+ description "
+ This option will cause the whole of the virtual
+ vector table to be initialized with dummy values on
+ startup. When this option is enabled, all the
+ options below must also be enabled - or the
+ table would be empty when the application
+ launches.
+
+ On targets where older ROM monitors without
+ virtual vector support may still be in use, it is
+ necessary for RAM applictions to initialize the
+ table (since all HAL diagnostics and debug IO
+ happens via the table)."
+ }
+
+ cdl_option CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_DEFAULT {
+ display "Claim virtual vector table entries by default"
+ active_if !CYGSEM_HAL_VIRTUAL_VECTOR_INIT_WHOLE_TABLE
+ default_value 1
+ description "
+ By default most virtual vectors will be claimed by
+ RAM startup configurations, meaning that the RAM
+ application will provide the services. The
+ exception is COMMS support (HAL
+ diagnostics/debugging IO) which is left in the
+ control of the ROM monitor.
+
+ The reasoning behind this is to get as much of the
+ code exercised during regular development so it
+ is known to be working the few times a new ROM
+ monitor or a ROM production configuration is used
+ - COMMS are excluded only by necessity in order to
+ avoid breaking an existing debugger connections
+ (there may be ways around this).
+
+ For production RAM configurations this option can
+ be switched off, causing the appliction to rely on
+ the ROM monitor for these services, thus
+ saving some space.
+
+ Individual vectors may also be left unclaimed,
+ controlled by the below options (meaning that the
+ associated service provided by the ROM monitor
+ will be used)."
+ }
+
+ cdl_option CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_RESET {
+ display "Claim reset virtual vectors"
+ default_value { CYGSEM_HAL_VIRTUAL_VECTOR_INIT_WHOLE_TABLE \
+ || CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_DEFAULT }
+ description "
+ This option will cause the reset and kill_by_reset
+ virtual vectors to be claimed."
+ }
+
+ cdl_option CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_VERSION {
+ display "Claim version virtual vectors"
+ default_value { CYGSEM_HAL_VIRTUAL_VECTOR_INIT_WHOLE_TABLE }
+ description "
+ This option will cause the version
+ virtual vectors to be claimed."
+ }
+
+ cdl_option CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_DELAY_US {
+ display "Claim delay_us virtual vector"
+ default_value { CYGSEM_HAL_VIRTUAL_VECTOR_INIT_WHOLE_TABLE \
+ || CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_DEFAULT }
+ description "
+ This option will cause the delay_us
+ virtual vector to be claimed."
+ }
+
+ cdl_option CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_DATA {
+ display "Claim data virtual vectors"
+ default_value { CYGSEM_HAL_VIRTUAL_VECTOR_INIT_WHOLE_TABLE \
+ || CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_DEFAULT }
+ description "
+ This option will cause the data virtual vectors
+ to be claimed. At present there is only one, used
+ by the RedBoot ethernet driver to share diag output."
+ }
+
+ cdl_option CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_COMMS {
+ display "Claim comms virtual vectors"
+ default_value { CYGSEM_HAL_VIRTUAL_VECTOR_INIT_WHOLE_TABLE \
+ || CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS }
+ description "
+ This option will cause the communication tables
+ that are part of the virtual vectors mechanism to
+ be claimed. Note that doing this may cause an
+ existing ROM monitor communication connection to
+ be closed. For this reason, the option is disabled
+ per default for normal application
+ configurations."
+ }
+
+ cdl_option CYGSEM_HAL_VIRTUAL_VECTOR_DIAG {
+ display "Do diagnostic IO via virtual vector table"
+ calculated 1
+ description "
+ All HAL IO happens via the virtual vector table / comm
+ tables when those tables are supported by the HAL.
+
+ If so desired, the low-level IO functions can
+ still be provided by the RAM application by
+ enabling the CLAIM_COMMS option."
+ }
+ }
+
+ cdl_option CYGBLD_BUILD_COMMON_GDB_STUBS {
+ display "Build common GDB stub ROM image"
+ default_value 0
+ parent CYGBLD_GLOBAL_OPTIONS
+ requires CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+ no_define
+ description "
+ Unless a target board has specific requirements to the
+ stub implementation, it can use a simple common stub.
+ This option, which gets enabled by platform HALs as
+ appropriate, controls the building of the common stub."
+
+ make -priority 315 {
+ <PREFIX>/bin/gdb_module.img : <PACKAGE>/src/stubrom/stubrom.c <PREFIX>/lib/extras.o <PREFIX>/lib/libtarget.a <PREFIX>/lib/target.ld <PREFIX>/lib/vectors.o
+ @sh -c "mkdir -p src/stubrom $(dir $@)"
+ $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o src/stubrom/gdb_module.o $<
+ @echo $@ ": \\" > $(notdir $@).deps
+ @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps
+ @tail -n +2 deps.tmp >> $(notdir $@).deps
+ @echo >> $(notdir $@).deps
+ @rm deps.tmp
+ $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ src/stubrom/gdb_module.o
+ }
+ }
+
+
+ }
+
+ # Does platform need special I/O initializations?
+ cdl_interface CYGINT_HAL_PLF_IF_INIT {
+ display "Platform defined I/O channels"
+ description "
+ Platforms which provide additional I/O channels can implement
+ this interface, indicating that the function plf_if_init()
+ needs to be called."
+ }
+
+ # Does platform provide IDE I/O macros?
+ cdl_interface CYGINT_HAL_PLF_IF_IDE {
+ display "Platform IDE I/O support"
+ description "
+ Platforms which provide IDE controllers can implement
+ this interface, indicating that IDE I/O macros are
+ available."
+ }
+
+ # Does anything require access to saved interrupt state?
+ cdl_interface CYGINT_HAL_COMMON_SAVED_INTERRUPT_STATE_REQUIRED {
+ display "Saved interrupt state required"
+ description "
+ Components requiring access to saved interrupt state via the
+ hal_saved_interrupt_state symbol should implement this
+ interface."
+ }
+
+ cdl_option CYGPKG_HAL_GDB_FILEIO {
+ display "File I/O operations via GDB"
+ default_value 0
+ active_if CYGSEM_REDBOOT_BSP_SYSCALLS
+ requires CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+ compile gdb-fileio.c
+ description "This option enables support for various file I/O
+ operations using the GDB remote protocol to communicate
+ with GDB. The operations are then performed on the
+ debugging host by proxy. These operations are only
+ currently available by using a system call interface
+ to RedBoot. This may change in the future."
+ }
+
+ define_proc {
+ puts $::cdl_header "/***** proc output start *****/"
+ puts $::cdl_header "#include <pkgconf/system.h>"
+
+ puts $::cdl_header "#include CYGBLD_HAL_TARGET_H"
+ puts $::cdl_header "#ifdef CYGBLD_HAL_VARIANT_H"
+ puts $::cdl_header "#include CYGBLD_HAL_VARIANT_H"
+ puts $::cdl_header "#endif"
+ puts $::cdl_header "#include CYGBLD_HAL_PLATFORM_H"
+
+ puts $::cdl_header "/****** proc output end ******/"
+
+ }
+
+ cdl_option CYGPKG_HAL_BUILD_COMPILER_TESTS {
+ display "Build Compiler sanity checking tests"
+ description "
+ Enabling this option causes compiler tests to be built."
+ }
+
+ cdl_component CYGPKG_HAL_TESTS {
+ display "Common HAL tests"
+ flavor data
+ no_define
+ calculated { "tests/context tests/basic"
+ . ((!CYGINT_HAL_TESTS_NO_CACHES) ? " tests/cache" : "")
+ . ((CYGPKG_HAL_BUILD_COMPILER_TESTS) ? " tests/cpp1 tests/vaargs" : "")
+ . ((!CYGVAR_KERNEL_COUNTERS_CLOCK) ? " tests/intr" : "") }
+ description "
+ This option specifies the set of tests for the common HAL."
+
+
+ cdl_interface CYGINT_HAL_TESTS_NO_CACHES {
+ display "Interface for cache presence"
+ flavor booldata
+ description "
+ Some architectures and/or platforms do not have caches. By
+ implementing this interface, these can disable the various
+ cache-related tests."
+ }
+
+ }
+}
diff --git a/ecos/packages/hal/common/current/cdl/interrupts.cdl b/ecos/packages/hal/common/current/cdl/interrupts.cdl
new file mode 100644
index 0000000..e9bd1df
--- /dev/null
+++ b/ecos/packages/hal/common/current/cdl/interrupts.cdl
@@ -0,0 +1,142 @@
+# ====================================================================
+#
+# interrupts.cdl
+#
+# HAL interrupt configuration data
+#
+# ====================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free
+## Software Foundation; either version 2 or (at your option) any later
+## version.
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+## for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with eCos; if not, write to the Free Software Foundation, Inc.,
+## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+## As a special exception, if other files instantiate templates or use
+## macros or inline functions from this file, or you compile this file
+## and link it with other works to produce a work based on this file,
+## this file does not by itself cause the resulting work to be covered by
+## the GNU General Public License. However the source code for this file
+## must still be made available in accordance with section (3) of the GNU
+## General Public License v2.
+##
+## This exception does not invalidate any other reasons why a work based
+## on this file might be covered by the GNU General Public License.
+## -------------------------------------------
+## ####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s): jskov
+# Original data: nickg,jskov,jlarmour
+# Contributors:
+# Date: 1999-07-02
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_option CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK {
+ display "Use separate stack for interrupts"
+ default_value 1
+ description "
+ When an interrupt occurs this interrupt can be handled either
+ on the current stack or on a separate stack maintained by the
+ HAL. Using a separate stack requires a small number of extra
+ instructions in the interrupt handling code, but it has the
+ advantage that it is no longer necessary to allow extra space
+ in every thread stack for the interrupt handlers. The amount
+ of extra space required depends on the interrupt handlers
+ that are being used."
+}
+
+# NOTE: various parts of the system such as device drivers should
+# impose lower bounds on this. The actual lower bound depends on a
+# platform-specific value for startup overheads, and the minimum
+# sizes specified by the various device drivers. If interrupts are
+# not handled on a separate stack then only the startup overheads
+# are significant. If nested interrupts are disabled then the
+# lower bound is the maximum of the individual sizes, otherwise
+# it is the sum of these sizes. It is not currently possible to
+# express a relationship like this.
+cdl_option CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE {
+ display "Interrupt stack size"
+ flavor data
+ default_value { CYGPKG_KERNEL ? 4096 : 32768 }
+ legal_values 128 to 1048576
+ description "
+ This configuration option specifies the stack size in bytes
+ for the interrupt stack. Typically this should be a multiple
+ of 16, but the exact requirements will vary from architecture
+ to architecture. The interrupt stack serves two separate
+ purposes. It is used as the stack during system
+ initialization. In addition, if the interrupt system is
+ configured to use a separate stack then all interrupts will
+ be processed on this stack. The exact memory requirements
+ will vary from application to application, and will depend
+ heavily on whether or not other interrupt-related options,
+ for example nested interrupts, are enabled. On most targets,
+ in a configuration with no kernel this stack will also be
+ the stack used to invoke the application, and must obviously
+ be appropriately large in that case."
+}
+
+cdl_option CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING {
+ display "Allow nested interrupts"
+ default_value 0
+ description "
+ When an interrupt occurs the HAL interrupt handling code can
+ either leave interrupts disabled for the duration of the
+ interrupt handling code, or by doing some extra work it can
+ reenable interrupts before invoking the interrupt handler and
+ thus allow nested interrupts to happen. If all the interrupt
+ handlers being used are small and do not involve any loops
+ then it is usually better to disallow nested interrupts.
+ However if any of the interrupt handlers are more complicated
+ than nested interrupts will usually be required."
+}
+
+cdl_option CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT {
+ display "Save minimum context on interrupt"
+ default_value 1
+ description "
+ The HAL interrupt handling code can exploit the calling conventions
+ defined for a given architecture to reduce the amount of state
+ that has to be saved. Generally this improves performance and
+ reduces code size. However it can make source-level debugging
+ more difficult."
+}
+
+cdl_option CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN {
+ display "Chain all interrupts together"
+ default_value 0
+ description "
+ Interrupts can be attached to vectors either singly, or be
+ chained together. The latter is necessary if there is no way
+ of discovering which device has interrupted without
+ inspecting the device itself. It can also reduce the amount
+ of RAM needed for interrupt decoding tables and code."
+}
+
+cdl_option CYGIMP_HAL_COMMON_INTERRUPTS_IGNORE_SPURIOUS {
+ display "Ignore spurious \[fleeting\] interrupts"
+ default_value 0
+ description "
+ On some hardware, interrupt sources may not be de-bounced or
+ de-glitched. Rather than try to handle these interrupts (no
+ handling may be possible), this option allows the HAL to simply
+ ignore them. In most cases, if the interrupt is real it will
+ reoccur in a detectable form."
+}
diff --git a/ecos/packages/hal/common/current/doc/hal.sgml b/ecos/packages/hal/common/current/doc/hal.sgml
new file mode 100644
index 0000000..f5caf8e
--- /dev/null
+++ b/ecos/packages/hal/common/current/doc/hal.sgml
@@ -0,0 +1,3159 @@
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- HAL.sgml -->
+<!-- -->
+<!-- eCos common HAL documentation -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="the-ecos-hardware-abstraction-layer">
+<title>The eCos Hardware Abstraction Layer (HAL)</title>
+
+<!-- {{{ Intro -->
+
+<chapter id=hal-introduction>
+<title>Introduction</title>
+<PARA>
+This is an initial specification of the <EMPHASIS>eCos</EMPHASIS> <!--
+<index></index> -->Hardware Abstraction Layer (HAL). The HAL abstracts
+the underlying hardware of a processor architecture and/or the
+platform to a level sufficient for the eCos kernel to be ported onto
+that platform.
+</PARA>
+
+<note>
+<title>Caveat</title>
+<PARA>
+This document is an informal description of the HAL capabilities and
+is not intended to be full documentation, although it may be used as a
+source for such. It also describes the HAL as it is currently
+implemented for the architectures targeted in this release. It most
+closely describes the HALs for the MIPS, I386 and PowerPC HALs. Other
+architectures are similar but may not be organized precisely as
+described here.
+</PARA>
+</note>
+
+</chapter>
+
+<!-- }}} -->
+<!-- {{{ Architecture, Variant and Platform -->
+
+<CHAPTER id="hal-architecture-variant-and-platform">
+<TITLE>Architecture, Variant and Platform</TITLE>
+
+<para>
+We have identified three levels at which the HAL must operate.
+</para>
+
+<itemizedlist>
+ <listitem>
+ <para>
+ The <!-- <index></index> --><firstterm>architecture
+ HAL</firstterm> abstracts the basic CPU architecture and includes
+ things like interrupt delivery, context switching, CPU startup
+ etc.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The <!-- <index></index> --> <firstterm>variant HAL</firstterm>
+ encapsulates features of the CPU variant such as caches, MMU and
+ FPU features. It also deals with any on-chip peripherals such as
+ memory and interrupt controllers. For architectural variations,
+ the actual implementation of the variation is often in the
+ architectural HAL, and the variant HAL simply provides the correct
+ configuration definitions.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The <!-- <index></index> --><firstterm>platform HAL</firstterm>
+ abstracts the properties of the current platform and includes
+ things like platform startup, timer devices, I/O register access
+ and interrupt controllers.
+ </para>
+ </listitem>
+
+</itemizedlist>
+
+<para>
+The boundaries between these three HAL levels are necessarily blurred
+since functionality shifts between levels on a target-by-target basis.
+For example caches and MMU may be either an architecture feature or a
+variant feature. Similarly, memory and interrupt controllers may be
+on-chip and in the variant HAL, or off-chip and in the platform HAL.
+</para>
+<para>
+Generally there is a separate package for each of the architecture,
+variant and package HALs for a target. For some of the older targets,
+or where it would be essentially empty, the variant HAL is omitted.
+</para>
+</CHAPTER>
+
+<!-- }}} -->
+<!-- {{{ General Principles -->
+
+<CHAPTER id="hal-general-principles">
+<TITLE>General principles</TITLE>
+
+<PARA>
+The HAL has been implemented according to the following general
+principles:
+</PARA>
+<ORDEREDLIST>
+<LISTITEM>
+<PARA> The HAL is implemented in C and assembler, although the
+ eCos kernel is largely implemented in C&plus;&plus;.
+ This is to permit the HAL the widest possible
+ applicability.</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>All interfaces to the HAL are implemented by
+ CPP macros. This allows them to be implemented as inline
+ C code, inline assembler or function calls to external C
+ or assembler code. This allows the most efficient
+ implementation to be selected without affecting the
+ interface. It also allows them to be redefined if the
+ platform or variant HAL needs to replace or enhance a definition
+ from the architecture HAL.</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>The HAL provides simple, portable mechanisms for dealing
+with the hardware of a wide range of architectures and platforms.
+It is always possible to bypass the HAL and program the hardware
+directly, but this may lead to a loss of portability. </PARA>
+</LISTITEM>
+</ORDEREDLIST>
+</CHAPTER>
+
+<!-- }}} -->
+<!-- {{{ HAL Interfaces -->
+
+<CHAPTER id="hal-interfaces">
+<TITLE><!-- <index></index> --><!-- <xref> -->HAL Interfaces</TITLE>
+
+<para>
+This section describes the main HAL interfaces.
+</para>
+
+<!-- {{{ Base Definitions -->
+
+<SECTION id="hal-base-definitions">
+<TITLE>Base Definitions</TITLE>
+
+<para>
+These are definitions that characterize the properties of the base
+architecture that are used to compile the portable parts of the
+kernel. They are concerned with such things a portable type
+definitions, endianness, and labeling.
+</para>
+
+<PARA>
+These definitions are supplied by the
+<filename>cyg/hal/basetype.h</filename> header file which is supplied
+by the architecture HAL. It is included automatically by
+<FILENAME>cyg/infra/cyg_type.h</FILENAME>.
+</PARA>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Byte order</TITLE>
+<VARIABLELIST>
+ <VARLISTENTRY>
+ <TERM><VARNAME>CYG_BYTEORDER</VARNAME></TERM>
+ <LISTITEM>
+ <PARA>
+ This defines the byte order of the target and must be set to either
+ <varname>CYG_LSBFIRST</varname> or <varname>CYG_MSBFIRST</varname>.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+</VARIABLELIST>
+</SECTION>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Label Translation</TITLE>
+
+<VARIABLELIST>
+ <VARLISTENTRY>
+ <TERM><FUNCTION>CYG_LABEL_NAME(name)</FUNCTION></TERM>
+ <LISTITEM>
+
+ <PARA>
+ This is a wrapper used in some C and C&plus;&plus; files which
+ use labels defined in assembly code or the linker script.
+ It need only be defined if the default implementation in
+ <filename>cyg/infra/cyg_type.h</filename>, which passes the name
+ argument unaltered, is inadequate. It should be paired with
+ <function>CYG_LABEL_DEFN()</function>.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+ <VARLISTENTRY>
+ <TERM><FUNCTION>CYG_LABEL_DEFN(name)</FUNCTION></TERM>
+ <LISTITEM>
+
+ <PARA>
+ This is a wrapper used in assembler sources and linker scripts
+ which define labels. It need only be defined if the default
+ implementation in
+ <filename>cyg/infra/cyg_type.h</filename>, which passes the name
+ argument unaltered, is inadequate. The most usual alternative
+ definition of this macro prepends an underscore to the label
+ name.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+</VARIABLELIST>
+</SECTION>
+
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Base types</TITLE>
+<PROGRAMLISTING>
+ cyg_halint8
+ cyg_halint16
+ cyg_halint32
+ cyg_halint64
+ cyg_halcount8
+ cyg_halcount16
+ cyg_halcount32
+ cyg_halcount64
+ cyg_halbool
+</PROGRAMLISTING>
+<PARA>
+These macros define the C base types that should be used to define
+variables of the given size. They only need to be defined if the
+default types specified in <filename>cyg/infra/cyg_type.h</filename>
+cannot be used. Note that these are only the base types, they will be
+composed with <literal>signed</literal> and
+<literal>unsigned</literal> to form full type specifications.
+</PARA>
+</SECTION>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Atomic types</TITLE>
+<PROGRAMLISTING>
+ cyg_halatomic CYG_ATOMIC
+</PROGRAMLISTING>
+<PARA>
+These types are guaranteed to be read or written in a single
+uninterruptible operation. It is architecture defined what size this
+type is, but it will be at least a byte.
+</PARA>
+</SECTION>
+
+</SECTION>
+
+<!-- }}} -->
+<!-- {{{ Architecture Characterization -->
+
+<SECTION id="hal-architecture-characterization">
+<TITLE>Architecture Characterization</TITLE>
+
+<para>
+These are definition that are related to the basic architecture of the
+CPU. These include the CPU context save format, context switching, bit
+twiddling, breakpoints, stack sizes and address translation.
+</para>
+
+<PARA>
+Most of these definition are found in
+<filename>cyg/hal/hal_arch.h</filename>. This file is supplied by the
+architecture HAL. If there are variant or platform specific
+definitions then these will be found in
+<filename>cyg/hal/var_arch.h</filename> or
+<filename>cyg/hal/plf_arch.h</filename>. These files are include
+automatically by this header, so need not be included explicitly.
+</PARA>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Register Save Format</TITLE>
+<PROGRAMLISTING>
+typedef struct HAL_SavedRegisters
+{
+ /* architecture-dependent list of registers to be saved */
+} HAL_SavedRegisters;
+</PROGRAMLISTING>
+<PARA>
+This structure describes the layout of a saved machine state on the
+stack. Such states are saved during thread context switches,
+interrupts and exceptions. Different quantities of state may be saved
+during each of these, but usually a thread context state is a subset
+of the interrupt state which is itself a subset of an exception state.
+For debugging purposes, the same structure is used for all three
+purposes, but where these states are significantly different, this
+structure may contain a union of the three states.
+</PARA>
+</SECTION>
+
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Thread Context Initialization</TITLE>
+
+<PROGRAMLISTING>
+HAL_THREAD_INIT_CONTEXT( sp, arg, entry, id )
+</PROGRAMLISTING>
+
+<PARA>
+This macro initializes a thread's context so that
+it may be switched to by <FUNCTION>HAL_THREAD_SWITCH_CONTEXT()</FUNCTION>.
+The arguments are:
+</PARA>
+<VARIABLELIST>
+ <VARLISTENTRY>
+ <TERM>sp</TERM>
+ <LISTITEM>
+ <PARA>
+ A location containing the current value of the thread's stack
+ pointer. This should be a variable or a structure field. The SP
+ value will be read out of here and an adjusted value written
+ back.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>arg</TERM>
+ <LISTITEM>
+ <PARA>
+ A value that is passed as the first argument to the entry
+ point function.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+ <VARLISTENTRY>
+ <TERM>entry</TERM>
+ <LISTITEM>
+ <PARA>
+ The address of an entry point function. This will be called
+ according the C calling conventions, and the value of
+ <parameter>arg</parameter> will be passed as the first
+ argument. This function should have the following type signature
+ <function>void entry(CYG_ADDRWORD arg)</function>.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+ <VARLISTENTRY>
+ <TERM>id</TERM>
+ <LISTITEM>
+ <PARA>
+ A thread id value. This is only used for debugging purposes,
+ it is ORed into the initialization pattern for unused registers
+ and may be used to help identify the thread from its register dump.
+ The least significant 16 bits of this value should be zero to allow
+ space for a register identifier.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+</VARIABLELIST>
+</SECTION>
+
+<!-- =================================================================== -->
+
+<SECTION id="hal-context-switch">
+<TITLE>Thread Context Switching</TITLE>
+
+<PROGRAMLISTING>
+HAL_THREAD_LOAD_CONTEXT( to )
+HAL_THREAD_SWITCH_CONTEXT( from, to )
+</PROGRAMLISTING>
+<PARA>
+These macros implement the thread switch code. The arguments are:
+</PARA>
+
+<VARIABLELIST>
+ <VARLISTENTRY>
+ <TERM>from</TERM>
+ <LISTITEM>
+ <PARA>
+ A pointer to a location where the stack pointer of the current
+ thread will be stored.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+ <VARLISTENTRY>
+ <TERM>to</TERM>
+ <LISTITEM>
+ <PARA>
+ A pointer to a location from where the stack pointer of the next
+ thread will be read.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+</VARIABLELIST>
+
+<para>
+For <function>HAL_THREAD_LOAD_CONTEXT()</function> the current CPU
+state is discarded and the state of the destination thread is
+loaded. This is only used once, to load the first thread when the
+scheduler is started.
+</para>
+
+<PARA>
+For <function>HAL_THREAD_SWITCH_CONTEXT()</function> the state of the
+current thread is saved onto its stack, using the current value of the
+stack pointer, and the address of the saved state placed in
+<parameter>*from</parameter>. The value in
+<parameter>*to</parameter> is then read and the state of the new
+thread is loaded from it.
+</PARA>
+
+<para>
+While these two operations may be implemented with inline assembler,
+they are normally implemented as calls to assembly code functions in
+the HAL. There are two advantages to doing it this way. First, the
+return link of the call provides a convenient PC value to be used in
+the saved context. Second, the calling conventions mean that the
+compiler will have already saved the caller-saved registers before the
+call, so the HAL need only save the callee-saved registers.
+</para>
+
+<para>
+The implementation of <function>HAL_THREAD_SWITCH_CONTEXT()</function>
+saves the current CPU state on the stack, including the current
+interrupt state (or at least the register that contains it). For
+debugging purposes it is useful to save the entire register set, but
+for performance only the ABI-defined callee-saved registers need be
+saved. If it is implemented, the option
+<literal>CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM</literal> controls
+how many registers are saved.
+</para>
+
+<para>
+The implementation of <function>HAL_THREAD_LOAD_CONTEXT()</function>
+loads a thread context, destroying the current context. With a little
+care this can be implemented by sharing code with
+<function>HAL_THREAD_SWITCH_CONTEXT()</function>. To load a thread
+context simply requires the saved registers to be restored from the
+stack and a jump or return made back to the saved PC.
+</para>
+
+<PARA>
+Note that interrupts are not disabled during this process, any
+interrupts that occur will be delivered onto the stack to which the
+current CPU stack pointer points. Hence the stack pointer
+should never be invalid, or loaded with a value that might cause the
+saved state to become corrupted by an interrupt. However, the current
+interrupt state is saved and restored as part of the thread
+context. If a thread disables interrupts and does something to cause a
+context switch, interrupts may be re-enabled on switching to another
+thread. Interrupts will be disabled again when the original thread
+regains control.
+</PARA>
+
+</SECTION>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Bit indexing</TITLE>
+
+<PROGRAMLISTING>
+HAL_LSBIT_INDEX( index, mask )
+HAL_MSBIT_INDEX( index, mask )
+</PROGRAMLISTING>
+
+<PARA>
+These macros place in <parameter>index</parameter> the bit index of
+the least significant bit in <parameter>mask</parameter>. Some
+architectures have instruction level support for one or other of these
+operations. If no architectural support is available, then these
+macros may call C functions to do the job.
+</PARA>
+</SECTION>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Idle thread activity</TITLE>
+
+<PROGRAMLISTING>
+HAL_IDLE_THREAD_ACTION( count )
+</PROGRAMLISTING>
+
+<PARA>
+It may be necessary under some circumstances for the HAL to execute
+code in the kernel idle thread's loop. An example might be to execute
+a processor halt instruction. This macro provides a portable way of
+doing this. The argument is a copy of the idle thread's loop counter,
+and may be used to trigger actions at longer intervals than every
+loop.
+</PARA>
+</SECTION>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Reorder barrier</TITLE>
+
+<PROGRAMLISTING>
+HAL_REORDER_BARRIER()
+</PROGRAMLISTING>
+
+<PARA>
+When optimizing the compiler can reorder code. In some parts of
+multi-threaded 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 and prevents code being migrated across
+it by the compiler optimizer. It should be placed between statements
+that must be executed in the order written in the code.
+</PARA>
+</SECTION>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Breakpoint support</TITLE>
+
+<PROGRAMLISTING>
+HAL_BREAKPOINT( label )
+HAL_BREAKINST
+HAL_BREAKINST_SIZE
+</PROGRAMLISTING>
+
+<PARA>
+These macros provide support for breakpoints.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_BREAKPOINT()</FUNCTION> executes a breakpoint
+instruction. The label is defined at the breakpoint instruction so
+that exception code can detect which breakpoint was executed.
+</PARA>
+
+<PARA>
+<literal>HAL_BREAKINST</literal> contains the breakpoint instruction
+code as an integer value. <literal>HAL_BREAKINST_SIZE</literal> is
+the size of that breakpoint instruction in bytes. Together these
+may be used to place a breakpoint in any code.
+</PARA>
+</SECTION>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>GDB support</TITLE>
+
+<PROGRAMLISTING>
+HAL_THREAD_GET_SAVED_REGISTERS( sp, regs )
+HAL_GET_GDB_REGISTERS( regval, regs )
+HAL_SET_GDB_REGISTERS( regs, regval )
+</PROGRAMLISTING>
+
+<PARA>
+These macros provide support for interfacing GDB to the HAL.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_THREAD_GET_SAVED_REGISTERS()</FUNCTION> extracts a
+pointer to a <STRUCTNAME>HAL_SavedRegisters</STRUCTNAME> structure
+from a stack pointer value. The stack pointer passed in should be the
+value saved by the thread context macros. The macro will assign a
+pointer to the <STRUCTNAME>HAL_SavedRegisters</STRUCTNAME> structure
+to the variable passed as the second argument.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_GET_GDB_REGISTERS()</FUNCTION> translates a register
+state as saved by the HAL and into a register dump in the format
+expected by GDB. It takes a pointer to a
+<STRUCTNAME>HAL_SavedRegisters</STRUCTNAME> structure in the
+<parameter>regs</parameter> argument and a pointer to the memory to
+contain the GDB register dump in the <parameter>regval</parameter>
+argument.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_SET_GDB_REGISTERS()</FUNCTION> translates a GDB format
+register dump into a the format expected by the HAL. It takes a
+pointer to the memory containing the GDB register dump in the
+<parameter>regval</parameter> argument and a pointer to a
+<STRUCTNAME>HAL_SavedRegisters</STRUCTNAME> structure
+in the <parameter>regs</parameter> argument.
+</PARA>
+</SECTION>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Setjmp and longjmp support</TITLE>
+
+<PROGRAMLISTING>
+CYGARC_JMP_BUF_SIZE
+hal_jmp_buf[CYGARC_JMP_BUF_SIZE]
+hal_setjmp( hal_jmp_buf env )
+hal_longjmp( hal_jmp_buf env, int val )
+</PROGRAMLISTING>
+
+<PARA>
+These functions provide support for the C
+<FUNCTION>setjmp()</FUNCTION> and <FUNCTION>longjmp()</FUNCTION>
+functions. Refer to the C library for further information.
+</PARA>
+
+</SECTION>
+
+<!-- =================================================================== -->
+
+<section>
+<title>Stack Sizes</title>
+<programlisting>
+CYGNUM_HAL_STACK_SIZE_MINIMUM
+CYGNUM_HAL_STACK_SIZE_TYPICAL
+</programlisting>
+
+<para>
+The values of these macros define the minimum and typical sizes of
+thread stacks.
+</para>
+
+<para>
+<literal>CYGNUM_HAL_STACK_SIZE_MINIMUM</literal> defines the minimum
+size of a thread stack. This is enough for the thread to function
+correctly within eCos and allows it to take interrupts and context
+switches. There should also be enough space for a simple thread entry
+function to execute and call basic kernel operations on objects like
+mutexes and semaphores. However there will not be enough room for much
+more than this. When creating stacks for their own threads,
+applications should determine the stack usage needed for application
+purposes and then add
+<literal>CYGNUM_HAL_STACK_SIZE_MINIMUM</literal>.
+</para>
+
+<para>
+<literal>CYGNUM_HAL_STACK_SIZE_TYPICAL</literal> is a reasonable increment over
+<literal>CYGNUM_HAL_STACK_SIZE_MINIMUM</literal>, usually about 1kB. This should be
+adequate for most modest thread needs. Only threads that need to
+define significant amounts of local data, or have very deep call trees
+should need to use a larger stack size.
+</para>
+
+</section>
+
+
+<!-- =================================================================== -->
+
+<section>
+<title>Address Translation</title>
+
+<programlisting>
+CYGARC_CACHED_ADDRESS(addr)
+CYGARC_UNCACHED_ADDRESS(addr)
+CYGARC_PHYSICAL_ADDRESS(addr)
+</programlisting>
+
+<para>
+These macros provide address translation between different views of
+memory. In many architectures a given memory location may be visible
+at different addresses in both cached and uncached forms. It is also
+possible that the MMU or some other address translation unit in the
+CPU presents memory to the program at a different virtual address to
+its physical address on the bus.
+</para>
+
+<para>
+<function>CYGARC_CACHED_ADDRESS()</function> translates the given
+address to its location in cached memory. This is typically where the
+application will access the memory.
+</para>
+
+<para>
+<function>CYGARC_UNCACHED_ADDRESS()</function> translates the given
+address to its location in uncached memory. This is typically where
+device drivers will access the memory to avoid cache problems. It may
+additionally be necessary for the cache to be flushed before the
+contents of this location is fully valid.
+</para>
+
+<para>
+<function>CYGARC_PHYSICAL_ADDRESS()</function> translates the given
+address to its location in the physical address space. This is
+typically the address that needs to be passed to device hardware such
+as a DMA engine, ethernet device or PCI bus bridge. The physical
+address may not be directly accessible to the program, it may be
+re-mapped by address translation.
+</para>
+
+</section>
+
+
+<!-- =================================================================== -->
+
+<section>
+<title>Global Pointer</title>
+
+<programlisting>
+CYGARC_HAL_SAVE_GP()
+CYGARC_HAL_RESTORE_GP()
+</programlisting>
+
+<para>
+These macros insert code to save and restore any global data pointer
+that the ABI uses. These are necessary when switching context between
+two eCos instances - for example between an eCos application and
+RedBoot.
+</para>
+
+</section>
+
+</SECTION>
+
+<!-- }}} -->
+<!-- {{{ Interrupt Handling -->
+
+<SECTION id="hal-interrupt-handling">
+<TITLE>Interrupt Handling</TITLE>
+
+<para>
+These interfaces contain definitions related to interrupt
+handling. They include definitions of exception and interrupt numbers,
+interrupt enabling and masking.
+</para>
+
+<PARA>
+These definitions are normally found in
+<FILENAME>cyg/hal/hal_intr.h</FILENAME>. This file is supplied by the
+architecture HAL. Any variant or platform specific definitions will
+be found in <filename>cyg/hal/var_intr.h</filename>,
+<filename>cyg/hal/plf_intr.h</filename> or
+<filename>cyg/hal/hal_platform_ints.h</filename> in the variant or platform
+HAL, depending on the exact target. These files are include
+automatically by this header, so need not be included explicitly.
+</PARA>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Vector numbers</TITLE>
+
+<PROGRAMLISTING>
+CYGNUM_HAL_VECTOR_XXXX
+CYGNUM_HAL_VSR_MIN
+CYGNUM_HAL_VSR_MAX
+CYGNUM_HAL_VSR_COUNT
+
+CYGNUM_HAL_INTERRUPT_XXXX
+CYGNUM_HAL_ISR_MIN
+CYGNUM_HAL_ISR_MAX
+CYGNUM_HAL_ISR_COUNT
+
+CYGNUM_HAL_EXCEPTION_XXXX
+CYGNUM_HAL_EXCEPTION_MIN
+CYGNUM_HAL_EXCEPTION_MAX
+CYGNUM_HAL_EXCEPTION_COUNT
+</PROGRAMLISTING>
+
+<PARA>
+All possible VSR, interrupt and exception vectors are specified here,
+together with maximum and minimum values for range checking. While the
+VSR and exception numbers will be defined in this file, the interrupt
+numbers will normally be defined in the variant or platform HAL file
+that is included by this header.
+</PARA>
+
+<PARA>
+There are two ranges of numbers, those for the vector service
+routines and those for the interrupt service routines. The relationship
+between these two ranges is undefined, and no equivalence should
+be assumed if vectors from the two ranges coincide.
+</PARA>
+
+<PARA>
+The VSR vectors correspond to the set of exception vectors that can be
+delivered by the CPU architecture, many of these will be internal
+exception traps. The ISR vectors correspond to the set of external
+interrupts that can be delivered and are usually determined by extra
+decoding of the interrupt controller by the interrupt VSR.
+</PARA>
+
+<PARA>
+Where a CPU supports synchronous exceptions, the range of such
+exceptions allowed are defined by <literal>CYGNUM_HAL_EXCEPTION_MIN</literal> and
+<literal>CYGNUM_HAL_EXCEPTION_MAX</literal>. The
+<literal>CYGNUM_HAL_EXCEPTION_XXXX</literal> definitions are
+standard names used by target independent code to test for the
+presence of particular exceptions in the architecture. The actual
+exception numbers will normally correspond to the VSR exception
+range. In future other exceptions generated by the system software
+(such as stack overflow) may be added.
+</PARA>
+
+<PARA>
+<literal>CYGNUM_HAL_ISR_COUNT</literal>, <literal>CYGNUM_HAL_VSR_COUNT</literal> and
+<literal>CYGNUM_HAL_EXCEPTION_COUNT</literal> define the number of
+ISRs, VSRs and EXCEPTIONs respectively for the purposes of defining
+arrays etc. There might be a translation from the supplied vector
+numbers into array offsets. Hence
+<literal>CYGNUM_HAL_XXX_COUNT</literal> may not simply be
+<literal>CYGNUM_HAL_XXX_MAX</literal> - <literal>CYGNUM_HAL_XXX_MIN</literal> or <literal>CYGNUM_HAL_XXX_MAX</literal>&plus;1.
+</PARA>
+
+</SECTION>
+
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Interrupt state control</TITLE>
+
+<PROGRAMLISTING>
+CYG_INTERRUPT_STATE
+HAL_DISABLE_INTERRUPTS( old )
+HAL_RESTORE_INTERRUPTS( old )
+HAL_ENABLE_INTERRUPTS()
+HAL_QUERY_INTERRUPTS( state )
+</PROGRAMLISTING>
+
+<PARA>
+These macros provide control over the state of the CPUs interrupt mask
+mechanism. They should normally manipulate a CPU status register to
+enable and disable interrupt delivery. They should not access an
+interrupt controller.
+</PARA>
+
+
+<para>
+<literal>CYG_INTERRUPT_STATE</literal> is a data type that should be
+used to store the interrupt state returned by
+<function>HAL_DISABLE_INTERRUPTS()</function> and
+<function>HAL_QUERY_INTERRUPTS()</function> and passed to
+<function>HAL_RESTORE_INTERRUPTS()</function>.
+</para>
+
+<PARA>
+<FUNCTION>HAL_DISABLE_INTERRUPTS()</FUNCTION> disables the delivery of
+interrupts and stores the original state of the interrupt mask in the
+variable passed in the <parameter>old</parameter> argument.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_RESTORE_INTERRUPTS()</FUNCTION> restores the state of
+the interrupt mask to that recorded in <parameter>old</parameter>.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_ENABLE_INTERRUPTS()</FUNCTION> simply enables interrupts
+regardless of the current state of the mask.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_QUERY_INTERRUPTS()</FUNCTION> stores the state of the
+interrupt mask in the variable passed in the <parameter>
+state</parameter> argument. The state stored here should also be
+capable of being passed to
+<function>HAL_RESTORE_INTERRUPTS()</function> at a later point.
+</PARA>
+
+<PARA>
+It is at the HAL implementer&rsquo;s discretion exactly
+which interrupts are masked by this mechanism. Where a CPU has more
+than one interrupt type that may be masked separately (e.g. the
+ARM's IRQ and FIQ) only those that can raise DSRs need
+to be masked here. A separate architecture specific mechanism may
+then be used to control the other interrupt types.
+</PARA>
+
+</SECTION>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>ISR and VSR management</TITLE>
+
+<PROGRAMLISTING>
+HAL_INTERRUPT_IN_USE( vector, state )
+HAL_INTERRUPT_ATTACH( vector, isr, data, object )
+HAL_INTERRUPT_DETACH( vector, isr )
+HAL_VSR_SET( vector, vsr, poldvsr )
+HAL_VSR_GET( vector, pvsr )
+HAL_VSR_SET_TO_ECOS_HANDLER( vector, poldvsr )
+</PROGRAMLISTING>
+
+<PARA>
+These macros manage the attachment of interrupt and vector service
+routines to interrupt and exception vectors respectively.
+</PARA>
+
+<para>
+<function>HAL_INTERRUPT_IN_USE()</function> tests the state of the
+supplied interrupt vector and sets the value of the state parameter to
+either 1 or 0 depending on whether there is already an ISR attached to
+the vector. The HAL will only allow one ISR to be attached to each
+vector, so it is a good idea to use this function before using
+<function>HAL_INTERRUPT_ATTACH()</function>.
+</para>
+
+<PARA>
+<FUNCTION>HAL_INTERRUPT_ATTACH()</FUNCTION> attaches
+the ISR, data pointer and object pointer to the given
+<parameter>vector</parameter>. When an interrupt occurs on this
+vector the ISR is called using the C calling convention and the vector
+number and data pointer are passed to it as the first and second
+arguments respectively.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_INTERRUPT_DETACH()</FUNCTION> detaches the ISR from the
+vector.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_VSR_SET()</FUNCTION> replaces the VSR attached to the
+<parameter>vector</parameter> with the replacement supplied in
+<parameter>vsr</parameter>. The old VSR is returned in the location
+pointed to by <parameter>pvsr</parameter>.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_VSR_GET()</FUNCTION> assigns
+a copy of the VSR to the location pointed to by <parameter>pvsr</parameter>.
+</PARA>
+
+<para>
+<function>HAL_VSR_SET_TO_ECOS_HANDLER()</function> ensures that the
+VSR for a specific exception is pointing at the eCos exception VSR and
+not one for RedBoot or some other ROM monitor. The default when
+running under RedBoot is for exceptions to be handled by RedBoot and
+passed to GDB. This macro diverts the exception to eCos so that it may
+be handled by application code. The arguments are the VSR vector to be
+replaces, and a location in which to store the old VSR pointer, so
+that it may be replaced at a later point.
+</para>
+
+</SECTION>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Interrupt controller management</TITLE>
+
+<PROGRAMLISTING>
+HAL_INTERRUPT_MASK( vector )
+HAL_INTERRUPT_UNMASK( vector )
+HAL_INTERRUPT_ACKNOWLEDGE( vector )
+HAL_INTERRUPT_CONFIGURE( vector, level, up )
+HAL_INTERRUPT_SET_LEVEL( vector, level )
+</PROGRAMLISTING>
+
+<PARA>
+These macros exert control over any prioritized interrupt
+controller that is present. If no priority controller exists, then
+these macros should be empty.
+</para>
+
+<note>
+ <para>
+ These macros may not be reentrant, so care should be taken to
+ prevent them being called while interrupts are enabled. This means
+ that they can be safely used in initialization code before
+ interrupts are enabled, and in ISRs. In DSRs, ASRs and thread code,
+ however, interrupts must be disabled before these macros are
+ called. Here is an example for use in a DSR where the interrupt
+ source is unmasked after data processing:
+ </para>
+<PROGRAMLISTING>
+ ...
+ HAL_DISABLE_INTERRUPTS(old);
+ HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_ETH);
+ HAL_RESTORE_INTERRUPTS(old);
+ ...
+</PROGRAMLISTING>
+</note>
+
+<PARA>
+<FUNCTION>HAL_INTERRUPT_MASK()</FUNCTION> causes the interrupt
+associated with the given vector to be blocked.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_INTERRUPT_UNMASK()</FUNCTION> causes the interrupt
+associated with the given vector to be unblocked.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_INTERRUPT_ACKNOWLEDGE()</FUNCTION> acknowledges the
+current interrupt from the given vector. This is usually executed from
+the ISR for this vector when it is prepared to allow further
+interrupts. Most interrupt controllers need some form of acknowledge
+action before the next interrupt is allowed through. Executing this
+macro may cause another interrupt to be delivered. Whether this
+interrupts the current code depends on the state of the CPU interrupt
+mask.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_INTERRUPT_CONFIGURE()</FUNCTION> provides
+control over how an interrupt signal is detected. The arguments
+are:
+</PARA>
+<VARIABLELIST>
+ <VARLISTENTRY>
+ <TERM>vector</TERM>
+ <LISTITEM>
+ <PARA>The interrupt vector to be configured.</PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>level</TERM>
+ <LISTITEM>
+ <PARA>
+ Set to <varname>true</varname> if the interrupt is detected by
+ level, and <varname>false</varname> if it is edge triggered.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>up</TERM>
+ <LISTITEM>
+ <PARA>
+ If the interrupt is set to level detect, then if this is
+ <VARNAME>true</VARNAME> it is detected by a high signal level,
+ and if <VARNAME>false</VARNAME> by a low signal level. If the
+ interrupt is set to edge triggered, then if this is
+ <VARNAME>true</VARNAME> it is triggered by a rising edge and if
+ <VARNAME>false</VARNAME> by a falling edge.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+</VARIABLELIST>
+
+<PARA>
+<FUNCTION>HAL_INTERRUPT_SET_LEVEL()</FUNCTION> provides control over
+the hardware priority of the interrupt. The arguments are:
+</PARA>
+
+<VARIABLELIST>
+ <VARLISTENTRY>
+ <TERM>vector</TERM>
+ <LISTITEM>
+ <PARA>The interrupt whose level is to be set.</PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>level</TERM>
+ <LISTITEM>
+ <PARA>
+ The priority level to which the interrupt is to set. In some
+ architectures the masking of an interrupt is achieved by
+ changing its priority level. Hence this function,
+ <FUNCTION>HAL_INTERRUPT_MASK()</FUNCTION> and
+ <FUNCTION>HAL_INTERRUPT_UNMASK()</FUNCTION> may interfere with
+ each other.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+</VARIABLELIST>
+
+</SECTION>
+
+</SECTION>
+
+<!-- }}} -->
+<!-- {{{ Clocks and Timers -->
+
+<SECTION id="hal-clocks-and-timers">
+<TITLE>Clocks and Timers</TITLE>
+
+<para>
+These interfaces contain definitions related to clock and timer
+handling. They include interfaces to initialize and read a clock for
+generating regular interrupts, definitions for setting the frequency of
+the clock, and support for short timed delays.
+</para>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Clock Control</TITLE>
+
+<PROGRAMLISTING>
+HAL_CLOCK_INITIALIZE( period )
+HAL_CLOCK_RESET( vector, period )
+HAL_CLOCK_READ( pvalue )
+</PROGRAMLISTING>
+
+<PARA>
+These macros provide control over a clock or timer device that may be
+used by the kernel to provide time-out, delay and scheduling
+services. The clock is assumed to be implemented by some form of
+counter that is incremented or decremented by some external source and
+which raises an interrupt when it reaches a predetermined value.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_CLOCK_INITIALIZE()</FUNCTION> initializes the timer
+device to interrupt at the given period. The period is essentially the
+value used to initialize the timer counter and must be calculated from
+the timer frequency and the desired interrupt rate. The timer device
+should generate an interrupt every <varname>period</varname> cycles.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_CLOCK_RESET()</FUNCTION> re-initializes the timer to
+provoke the next interrupt. This macro is only really necessary when
+the timer device needs to be reset in some way after each interrupt.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_CLOCK_READ()</FUNCTION> reads the current value of the
+timer counter and puts the value in the location pointed to by
+<parameter>pvalue</parameter>. The value stored will always be the
+number of timer cycles since the last interrupt, and hence ranges
+between zero and the initial period value. If this is a count-down
+cyclic timer, some arithmetic may be necessary to generate this value.
+</PARA>
+
+</SECTION>
+
+<!-- =================================================================== -->
+
+<section>
+<title>Microsecond Delay</title>
+
+<programlisting width=72>
+HAL_DELAY_US(us)
+</programlisting>
+
+<para>
+This macro provides a busy loop delay for the given number of
+microseconds. It is intended mainly for controlling hardware that
+needs short delays between operations. Code which needs longer delays,
+of the order of milliseconds, should instead use higher-level
+functions such as <function>cyg_thread_delay</function>. The macro
+implementation should be thread-safe. It can also be used in ISRs or
+DSRs, although such usage is undesirable because of the impact on
+interrupt and dispatch latency.
+</para>
+
+<para>
+The macro should never delay for less than the specified amount of
+time. It may delay for somewhat longer, although since the macro uses
+a busy loop this is a waste of cpu cycles. Of course the code invoking
+<function>HAL_DELAY_US</function> may get interrupted or timesliced,
+in which case the delay may be much longer than intended. If this is
+unacceptable then the calling code must take preventative action
+such as disabling interrupts or locking the scheduler.
+</para>
+
+<para>
+There are three main ways of implementating the macro:
+</para>
+
+<orderedlist>
+ <listitem><para>
+a counting loop, typically written in inline assembler, using an outer
+loop for the microseconds and an inner loop that consumes
+approximately 1us. This implementation is automatically thread-safe
+and does not impose any dependencies on the rest of the system, for
+example it does not depend on the system clock having been started.
+However it assumes that the cpu clock speed is known at compile-time
+or can be easily determined at run-time.
+ </para></listitem>
+ <listitem><para>
+monitor one of the hardware clocks, usually the system clock. Usually
+this clock ticks at a rate independent of the cpu so calibration is
+easier. However the implementation relies on the system clock having
+been started, and assumes that no other code is manipulating the clock
+hardware. There can also be complications when the system clock wraps
+around.
+ </para></listitem>
+ <listitem><para>
+a combination of the previous two. The system clock is used during
+system initialization to determine the cpu clock speed, and the result
+is then used to calibrate a counting loop. This has the disadvantage
+of significantly increasing the system startup time, which may be
+unacceptable to some applications. There are also complications if the
+system startup code normally runs with the cache disabled because the
+instruction cache will greatly affect any calibration loop.
+ </para></listitem>
+</orderedlist>
+
+</section>
+
+<!-- =================================================================== -->
+
+<section>
+<title>Clock Frequency Definition</title>
+
+<programlisting width=72>
+CYGNUM_HAL_RTC_NUMERATOR
+CYGNUM_HAL_RTC_DENOMINATOR
+CYGNUM_HAL_RTC_PERIOD
+</programlisting>
+
+<para>
+These macros are defined in the CDL for each platform and supply the
+necessary parameters to specify the frequency at which the clock
+interrupts. These parameters are usually found in the CDL definitions
+for the target platform, or in some cases the CPU variant.
+</para>
+
+<para>
+<literal>CYGNUM_HAL_RTC_NUMERATOR</literal> and
+<literal>CYGNUM_HAL_RTC_DENOMINATOR</literal> specify the resolution
+of the clock interrupt. This resolution involves two separate values,
+the numerator and the denominator. The result of dividing the
+numerator by the denominator should correspond to the number of
+nanoseconds between clock interrupts. For example a numerator of
+1000000000 and a denominator of 100 means that there are 10000000
+nanoseconds (or 10 milliseconds) between clock interrupts. Expressing
+the resolution as a fraction minimizes clock drift even for
+frequencies that cannot be expressed as a simple integer. For example
+a frequency of 60Hz corresponds to a clock resolution of
+16666666.66... nanoseconds. This can be expressed accurately as
+1000000000 over 60.
+</para>
+
+<para>
+<literal>CYGNUM_HAL_RTC_PERIOD</literal> specifies the exact value
+used to initialize the clock hardware, it is the value passed as a
+parameter to <literal>HAL_CLOCK_INITIALIZE()</literal> and
+<literal>HAL_CLOCK_RESET()</literal>. The exact meaning of the value
+and the range of legal values therefore depends on the target
+hardware, and the hardware documentation should be consulted for
+further details.
+</para>
+
+<para>
+The default values for these macros in all HALs are calculated to give
+a clock interrupt frequency of 100Hz, or 10ms between interrupts. To
+change the clock frequency, the period needs to be changed, and the
+resolution needs to be adjusted accordingly. As an example consider
+the i386 PC target. The default values for these macros are:
+</para>
+
+<programlisting width=72>
+CYGNUM_HAL_RTC_NUMERATOR 1000000000
+CYGNUM_HAL_RTC_DENOMINATOR 100
+CYGNUM_HAL_RTC_PERIOD 11932
+</programlisting>
+
+<para>
+To change to, say, a 200Hz clock the period needs to be halved to
+5966, and to compensate the denominator needs to be doubled to 200. To
+change to a 1KHz interrupt rate change the period to 1193 and the
+denominator to 1000.
+</para>
+
+<para>
+Some HALs make this process a little easier by deriving the period
+arithmetically from the denominator. This calculation may also involve
+the CPU clock frequency and possibly other factors. For example in the
+ARM AT91 variant HAL the period is defined by the following
+expression:
+</para>
+
+<programlisting width=72>
+((CYGNUM_HAL_ARM_AT91_CLOCK_SPEED/32) / CYGNUM_HAL_RTC_DENOMINATOR)
+</programlisting>
+
+<para>
+In this case it is not necessary to change the period at all, just
+change the denominator to select the desired clock frequency. However,
+note that for certain choices of frequency, rounding errors in this
+calculation may result in a small clock drift over time. This is
+usually negligible, but if perfect accuracy is required, it may be
+necessary to adjust the frequency or period by hand.
+</para>
+
+</section>
+
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Input and Output -->
+
+<SECTION id="hal-input-and-output">
+<TITLE>HAL I/O</TITLE>
+
+<PARA>
+This section contains definitions for supporting access
+to device control registers in an architecture neutral
+fashion.
+</PARA>
+
+<para>
+These definitions are normally found in the header file
+<FILENAME>cyg/hal/hal_io.h</FILENAME>. This file itself contains
+macros that are generic to the architecture. If there are variant or
+platform specific IO access macros then these will be found in
+<filename>cyg/hal/var_io.h</filename> and
+<filename>cyg/hal/plf_io.h</filename> in the variant or platform HALs
+respectively. These files are include automatically by this header, so
+need not be included explicitly.
+</para>
+
+<para>
+This header (or more likely <filename>cyg/hal/plf_io.h</filename>) also
+defines the PCI access macros. For more information on these see <xref
+linkend="pci-library-reference">.
+</para>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Register address</TITLE>
+
+<PROGRAMLISTING>
+HAL_IO_REGISTER
+</PROGRAMLISTING>
+
+<PARA>
+This type is used to store the address of an I/O register. It will
+normally be a memory address, an integer port address or an offset
+into an I/O space. More complex architectures may need to code an
+address space plus offset pair into a single word, or may represent it
+as a structure.
+</PARA>
+
+<PARA>
+Values of variables and constants of this type will usually be
+supplied by configuration mechanisms or in target specific headers.
+</PARA>
+
+</SECTION>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Register read</TITLE>
+
+<PROGRAMLISTING>
+HAL_READ_XXX( register, value )
+HAL_READ_XXX_VECTOR( register, buffer, count, stride )
+</PROGRAMLISTING>
+
+<PARA>
+These macros support the reading of I/O registers in various
+sizes. The <replaceable>XXX</replaceable> component of the name may be
+<literal>UINT8</literal>, <literal>UINT16</literal>,
+<literal>UINT32</literal>.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_READ_XXX()</FUNCTION> reads the appropriately sized
+value from the register and stores it in the variable passed as the
+second argument.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_READ_XXX_VECTOR()</FUNCTION> reads
+<parameter>count</parameter> values of the appropriate size into
+<parameter>buffer</parameter>. The <parameter>stride</parameter>
+controls how the pointer advances through the register space. A stride
+of zero will read the same register repeatedly, and a stride of one
+will read adjacent registers of the given size. Greater strides will
+step by larger amounts, to allow for sparsely mapped registers for
+example.</PARA>
+</SECTION>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Register write</TITLE>
+
+<PROGRAMLISTING>
+HAL_WRITE_XXX( register, value )
+HAL_WRITE_XXX_VECTOR( register, buffer,count, stride )
+</PROGRAMLISTING>
+
+<PARA>
+These macros support the writing of I/O registers in various
+sizes. The <replaceable>XXX</replaceable> component of the name may be
+<LITERAL>UINT8</LITERAL>, <LITERAL>UINT16</LITERAL>,
+<LITERAL>UINT32</LITERAL>.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_WRITE_XXX()</FUNCTION> writes
+the appropriately sized value from the variable passed as the second argument
+stored it in the register.</PARA>
+<PARA><FUNCTION>HAL_WRITE_XXX_VECTOR()</FUNCTION> writes
+<parameter>count</parameter> values of the appropriate size from <parameter>
+buffer</parameter>. The <parameter>stride</parameter> controls
+how the pointer advances through the register space. A stride of
+zero will write the same register repeatedly, and a stride of one
+will write adjacent registers of the given size. Greater strides
+will step by larger amounts, to allow for sparsely mapped registers
+for example.</PARA>
+</SECTION>
+</SECTION>
+
+<!-- }}} -->
+<!-- {{{ Cache Control -->
+
+<SECTION id="hal-cache-control">
+<TITLE>Cache Control</TITLE>
+
+<PARA>This section contains definitions for supporting control
+of the caches on the CPU.
+</PARA>
+
+<para>
+These definitions are usually found in the header file
+<FILENAME>cyg/hal/hal_cache.h</FILENAME>. This file may be defined in
+the architecture, variant or platform HAL, depending on where the
+caches are implemented for the target. Often there will be a generic
+implementation of the cache control macros in the architecture HAL
+with the ability to override or undefine them in the variant or
+platform HAL. Even when the implementation of the cache macros is in
+the architecture HAL, the cache dimensions will be defined in the
+variant or platform HAL. As with other files, the variant or platform
+specific definitions are usually found in
+<filename>cyg/hal/var_cache.h</filename> and
+<filename>cyg/hal/plf_cache.h</filename> respectively. These files
+are include automatically by this header, so need not be included
+explicitly.
+</para>
+
+<PARA>
+There are versions of the macros defined here for both the Data and
+Instruction caches. these are distinguished by the use of either
+<literal>DCACHE</literal> or <literal>ICACHE</literal> in the macro
+names. Some architectures have a unified cache, where both data and
+instruction share the same cache. In these cases the control macros
+use <literal>UCACHE</literal> and the <literal>DCACHE</literal> and
+<literal>ICACHE</literal> macros will just be calls to the
+<literal>UCACHE</literal> version. In the following descriptions,
+<literal>XCACHE</literal> is used to stand for any of these. Where
+there are issues specific to a particular cache, this will be
+explained in the text.
+</PARA>
+
+<PARA>
+There might be target specific restrictions on the use of some of the
+macros which it is the user's responsibility to comply with. Such
+restrictions are documented in the header file with the macro
+definition.
+</PARA>
+
+<PARA>
+Note that destructive cache macros should be used with caution.
+Preceding a cache invalidation with a cache synchronization is not
+safe in itself since an interrupt may happen after the synchronization
+but before the invalidation. This might cause the state of dirty data
+lines created during the interrupt to be lost.
+</PARA>
+
+<PARA>
+Depending on the architecture's capabilities, it may be possible to
+temporarily disable the cache while doing the synchronization and
+invalidation which solves the problem (no new data would be cached
+during an interrupt). Otherwise it is necessary to disable interrupts
+while manipulating the cache which may take a long time.
+</PARA>
+
+<PARA>
+Some platform HALs now support a pair of cache state query
+macros: <function>HAL_ICACHE_IS_ENABLED( x )</function> and
+<function>HAL_DCACHE_IS_ENABLED( x )</function> which set the argument
+to true if the instruction or data cache is enabled,
+respectively. Like most cache control macros, these are optional,
+because the capabilities of different targets and boards can vary
+considerably. Code which uses them, if it is to be considered
+portable, should test for their existence first by means of
+<literal>#ifdef</literal>. Be sure to include
+<filename>&lt;cyg/hal/hal_cache.h&gt;</filename> in order to do this
+test and (maybe) use the macros.
+</PARA>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Cache Dimensions</TITLE>
+
+<PROGRAMLISTING>
+HAL_XCACHE_SIZE
+HAL_XCACHE_LINE_SIZE
+HAL_XCACHE_WAYS
+HAL_XCACHE_SETS
+</PROGRAMLISTING>
+<PARA>
+These macros define the size and dimensions of the Instruction
+and Data caches.
+</PARA>
+
+<VARIABLELIST>
+ <VARLISTENTRY>
+ <TERM>HAL_XCACHE_SIZE </TERM>
+ <LISTITEM>
+ <PARA>Defines the total size of the cache in bytes.</PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>HAL_XCACHE_LINE_SIZE </TERM>
+ <LISTITEM>
+ <PARA>Defines the cache line size in bytes.</PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>HAL_XCACHE_WAYS </TERM>
+ <LISTITEM>
+ <PARA>
+ Defines the number of ways in each set and defines its level
+ of associativity. This would be 1 for a direct mapped
+ cache, 2 for a 2-way cache, 4 for 4-way and so on.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>HAL_XCACHE_SETS </TERM>
+ <LISTITEM>
+ <PARA>
+ Defines the number of sets in the cache, and is calculated from
+ the previous values.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+</VARIABLELIST>
+
+</SECTION>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Global Cache Control</TITLE>
+
+<PROGRAMLISTING>
+HAL_XCACHE_ENABLE()
+HAL_XCACHE_DISABLE()
+HAL_XCACHE_INVALIDATE_ALL()
+HAL_XCACHE_SYNC()
+HAL_XCACHE_BURST_SIZE( size )
+HAL_DCACHE_WRITE_MODE( mode )
+HAL_XCACHE_LOCK( base, size )
+HAL_XCACHE_UNLOCK( base, size )
+HAL_XCACHE_UNLOCK_ALL()
+</PROGRAMLISTING>
+
+<PARA>
+These macros affect the state of the entire cache, or a large part of
+it.
+</PARA>
+
+<VARIABLELIST>
+ <VARLISTENTRY>
+ <TERM>HAL_XCACHE_ENABLE() and HAL_XCACHE_DISABLE()</TERM>
+ <LISTITEM>
+ <PARA>Enable and disable the cache.</PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>HAL_XCACHE_INVALIDATE_ALL()</TERM>
+ <LISTITEM>
+ <PARA>
+ Causes the entire contents of the cache to be invalidated.
+ Depending on the hardware, this may require the cache to be disabled
+ during the invalidation process. If so, the implementation must
+ use <function>HAL_XCACHE_IS_ENABLED()</function> to save and
+ restore the previous state.
+ </PARA>
+ <note>
+ <para>
+ If this macro is called after
+ <function>HAL_XCACHE_SYNC()</function> with the intention of clearing
+ the cache (invalidating the cache after writing dirty data back to
+ memory), you must prevent interrupts from happening between the two
+ calls:
+ </para>
+<PROGRAMLISTING>
+ ...
+ HAL_DISABLE_INTERRUPTS(old);
+ HAL_XCACHE_SYNC();
+ HAL_XCACHE_INVALIDATE_ALL();
+ HAL_RESTORE_INTERRUPTS(old);
+ ...
+</PROGRAMLISTING>
+ <para>
+ Since the operation may take a very long time, real-time
+ responsiveness could be affected, so only do this when it is
+ absolutely required and you know the delay will not interfere
+ with the operation of drivers or the application.
+ </para>
+ </note>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>HAL_XCACHE_SYNC()</TERM>
+ <LISTITEM>
+ <PARA>
+ Causes the contents of the cache to be brought into synchronization
+ with the contents of memory. In some implementations this may be
+ equivalent to <function>HAL_XCACHE_INVALIDATE_ALL()</function>.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>HAL_XCACHE_BURST_SIZE()</TERM>
+ <LISTITEM>
+ <PARA>
+ Allows the size of cache to/from memory bursts to
+ be controlled. This macro will only be defined if this functionality
+ is available.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>HAL_DCACHE_WRITE_MODE()</TERM>
+ <LISTITEM>
+ <PARA>
+ Controls the way in which data cache lines are written back to
+ memory. There will be definitions for the possible
+ modes. Typical definitions are
+ <literal>HAL_DCACHE_WRITEBACK_MODE</literal> and
+ <literal>HAL_DCACHE_WRITETHRU_MODE</literal>. This macro will
+ only be defined if this functionality is available.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>HAL_XCACHE_LOCK()</TERM>
+ <LISTITEM>
+ <PARA>
+ Causes data to be locked into the cache. The base and size
+ arguments define the memory region that will be locked into the
+ cache. It is architecture dependent whether more than one locked
+ region is allowed at any one time, and whether this operation
+ causes the cache to cease acting as a cache for addresses
+ outside the region during the duration of the lock. This macro
+ will only be defined if this functionality is available.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>HAL_XCACHE_UNLOCK()</TERM>
+ <LISTITEM>
+ <PARA>
+ Cancels the locking of the memory region given. This should
+ normally correspond to a region supplied in a matching lock
+ call. This macro will only be defined if this functionality is
+ available.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>HAL_XCACHE_UNLOCK_ALL()</TERM>
+ <LISTITEM>
+ <PARA>
+ Cancels all existing locked memory regions. This may be required
+ as part of the cache initialization on some architectures. This
+ macro will only be defined if this functionality is available.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+</VARIABLELIST>
+
+</SECTION>
+
+<!-- =================================================================== -->
+
+<SECTION>
+<TITLE>Cache Line Control</TITLE>
+
+<PROGRAMLISTING>
+HAL_DCACHE_ALLOCATE( base , size )
+HAL_DCACHE_FLUSH( base , size )
+HAL_XCACHE_INVALIDATE( base , size )
+HAL_DCACHE_STORE( base , size )
+HAL_DCACHE_READ_HINT( base , size )
+HAL_DCACHE_WRITE_HINT( base , size )
+HAL_DCACHE_ZERO( base , size )
+</PROGRAMLISTING>
+
+<PARA>
+All of these macros apply a cache operation to all cache lines that
+match the memory address region defined by the base and size
+arguments. These macros will only be defined if the described
+functionality is available. Also, it is not guaranteed that the cache
+function will only be applied to just the described regions, in some
+architectures it may be applied to the whole cache.
+</PARA>
+
+<VARIABLELIST>
+ <VARLISTENTRY>
+ <TERM>HAL_DCACHE_ALLOCATE()</TERM>
+ <LISTITEM>
+ <PARA>
+ Allocates lines in the cache for the given region without
+ reading their contents from memory, hence the contents of the lines
+ is undefined. This is useful for preallocating lines which are to
+ be completely overwritten, for example in a block copy
+ operation.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>HAL_DCACHE_FLUSH()</TERM>
+ <LISTITEM>
+ <PARA>
+ Invalidates all cache lines in the region after writing any
+ dirty lines to memory.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>HAL_XCACHE_INVALIDATE() </TERM>
+ <LISTITEM>
+ <PARA>
+ Invalidates all cache lines in the region. Any dirty lines
+ are invalidated without being written to memory.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>HAL_DCACHE_STORE() </TERM>
+ <LISTITEM>
+ <PARA>
+ Writes all dirty lines in the region to memory, but does not
+ invalidate any lines.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>HAL_DCACHE_READ_HINT() </TERM>
+ <LISTITEM>
+ <PARA>
+ Hints to the cache that the region is going to be read from
+ in the near future. This may cause the region to be speculatively
+ read into the cache.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>HAL_DCACHE_WRITE_HINT() </TERM>
+ <LISTITEM>
+ <PARA>
+ Hints to the cache that the region is going to be written
+ to in the near future. This may have the identical behavior to
+ HAL_DCACHE_READ_HINT().
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>HAL_DCACHE_ZERO()</TERM>
+ <LISTITEM>
+ <PARA>
+ Allocates and zeroes lines in the cache for the given
+ region without reading memory. This is useful if a large area of
+ memory is to be cleared.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+</VARIABLELIST>
+
+</SECTION>
+</SECTION>
+
+<!-- }}} -->
+<!-- {{{ Linker Scripts -->
+
+<SECTION id="hal-linker-scripts">
+<TITLE><!-- <xref> -->Linker Scripts</TITLE>
+
+<para>
+When an eCos application is linked it must be done under the control
+of a linker script. This script defines the memory areas, addresses
+and sized, into which the code and data are to be put, and allocates
+the various sections generated by the compiler to these.
+</para>
+
+<para>
+The linker script actually used is in
+<filename>lib/target.ld</filename> in the install directory. This is
+actually manufactured out of two other files: a base linker script and
+an <literal>.ldi</literal> file that was generated by the memory
+layout tool.
+</para>
+
+<para>
+The base linker script is usually supplied either by the architecture
+HAL or the variant HAL. It consists of a set of linker script
+fragments, in the form of C preprocessor macros, that define the major
+output sections to be generated by the link operation. The
+<literal>.ldi</literal> file, which is <literal>#include'ed</literal>
+by the base linker script, uses these macro definitions to assign the
+output sections to the required memory areas and link addresses.
+</para>
+
+<para>
+The <literal>.ldi</literal> file is supplied by the platform HAL, and
+contains knowledge of the memory layout of the target platform. These
+files generally conform to a standard naming convention, each file
+being of the form:
+</para>
+<para>
+<filename>pkgconf/mlt_&lt;architecture&gt;_&lt;variant&gt;_&lt;platform&gt;_&lt;startup&gt;.ldi</filename>
+</para>
+<para>
+where <literal>&lt;architecture&gt;</literal>,
+<literal>&lt;variant&gt;</literal> and
+<literal>&lt;platform&gt;</literal> are the respective HAL package
+names and <literal>&lt;startup&gt;</literal> is the startup type which
+is usually one of <literal>ROM</literal>, <literal>RAM</literal> or
+<literal>ROMRAM</literal>.
+</para>
+
+<para>
+In addition to the <literal>.ldi</literal> file, there is also a
+congruously name <literal>.h</literal> file. This may be used by the
+application to access information defined in the
+<literal>.ldi</literal> file. Specifically it contains the memory
+layout defined there, together with any additional section names
+defined by the user. Examples of the latter are heap areas or PCI bus
+memory access windows.
+</para>
+
+<para>
+The <literal>.ldi</literal> is manufactured by the <application>Memory
+Layout Tool</application> (MLT). The <application>MLT</application> saves the memory
+configuration into a file named
+</para>
+<para>
+<filename>include/pkgconf/mlt_&lt;architecture&gt;_&lt;variant&gt;_&lt;platform&gt;_&lt;startup&gt;.mlt</filename>
+</para>
+<para>
+in the platform HAL. This file is used by the
+<application>MLT</application> to manufacture both the
+<literal>.ldi</literal> and <literal>.h</literal> files. Users should
+beware that direct edits the either of these files may be overwritten
+if the <application>MLT</application> is run and regenerates them from the
+<literal>.mlt</literal> file.
+</para>
+
+<para>
+The names of the <literal>.ldi</literal> and <literal>.h</literal>
+files are defined by macro definitions in
+<FILENAME>pkgconf/system.h</FILENAME>. These are
+<literal>CYGHWR_MEMORY_LAYOUT_LDI</literal> and
+<literal>CYGHWR_MEMORY_LAYOUT_H</literal> respectively. While there
+will be little need for the application to refer to the
+<literal>.ldi</literal> file directly, it may include the
+<literal>.h</literal> file as follows:
+</para>
+
+<programlisting>
+#include CYGHWR_MEMORY_LAYOUT_H
+</programlisting>
+
+</SECTION>
+
+<!-- }}} -->
+<!-- {{{ Diagnostic Support -->
+
+<SECTION id="hal-diagnostic-support">
+<TITLE>Diagnostic Support</TITLE>
+
+<para>
+The HAL provides support for low level diagnostic IO. This is
+particularly useful during early development as an aid to bringing up
+a new platform. Usually this diagnostic channel is a UART or some
+other serial IO device, but it may equally be a a memory
+buffer, a simulator supported output channel, a ROM emulator virtual
+UART, and LCD panel, a memory mapped video buffer or any other output
+device.
+</para>
+
+<PARA>
+<FUNCTION>HAL_DIAG_INIT()</FUNCTION> performs any initialization
+required on the device being used to generate diagnostic output. This
+may include, for a UART, setting baud rate, and stop, parity and
+character bits. For other devices it may include initializing a
+controller or establishing contact with a remote device.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_DIAG_WRITE_CHAR(c)</FUNCTION> writes
+the character supplied to the diagnostic output device.
+</PARA>
+
+<PARA>
+<FUNCTION>HAL_DIAG_READ_CHAR(c)</FUNCTION> reads a character from the
+diagnostic device into the supplied variable. This is not supported
+for all diagnostic devices.
+</PARA>
+
+<para>
+These macros are defined in the header file
+<filename>cyg/hal/hal_diag.h</filename>. This file is usually supplied
+by the variant or platform HAL, depending on where the IO device being
+used is located. For example for on-chip UARTs it would be in the
+variant HAL, but for a board-level LCD panel it would be in the
+platform HAL.
+</para>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ SMP Support -->
+
+<section id="hal-smp-support">
+<TITLE>SMP Support</TITLE>
+
+<para>
+eCos contains support for limited Symmetric Multi-Processing
+(SMP). This is only available on selected architectures and platforms.
+</para>
+
+<section>
+<title>Target Hardware Limitations</title>
+
+<para>
+To allow a reasonable implementation of SMP, and to reduce the
+disruption to the existing source base, a number of assumptions have
+been made about the features of the target hardware.
+</para>
+
+<itemizedlist>
+<listitem>
+<para>
+Modest multiprocessing. The typical number of CPUs supported is two
+to four, with an upper limit around eight. While there are no
+inherent limits in the code, hardware and algorithmic limitations
+will probably become significant beyond this point.
+</para>
+</listitem>
+
+<listitem>
+<para>
+SMP synchronization support. The hardware must supply a mechanism to
+allow software on two CPUs to synchronize. This is normally provided
+as part of the instruction set in the form of test-and-set,
+compare-and-swap or load-link/store-conditional instructions. An
+alternative approach is the provision of hardware semaphore
+registers which can be used to serialize implementations of these
+operations. Whatever hardware facilities are available, they are
+used in eCos to implement spinlocks.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Coherent caches. It is assumed that no extra effort will be required
+to access shared memory from any processor. This means that either
+there are no caches, they are shared by all processors, or are
+maintained in a coherent state by the hardware. It would be too
+disruptive to the eCos sources if every memory access had to be
+bracketed by cache load/flush operations. Any hardware that requires
+this is not supported.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Uniform addressing. It is assumed that all memory that is
+shared between CPUs is addressed at the same location from all
+CPUs. Like non-coherent caches, dealing with CPU-specific address
+translation is considered too disruptive to the eCos source
+base. This does not, however, preclude systems with non-uniform
+access costs for different CPUs.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Uniform device addressing. As with access to memory, it is assumed
+that all devices are equally accessible to all CPUs. Since device
+access is often made from thread contexts, it is not possible to
+restrict access to device control registers to certain CPUs, since
+there is currently no support for binding or migrating threads to CPUs.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Interrupt routing. The target hardware must have an interrupt
+controller that can route interrupts to specific CPUs. It is
+acceptable for all interrupts to be delivered to just one CPU, or
+for some interrupts to be bound to specific CPUs, or for some
+interrupts to be local to each CPU. At present dynamic routing,
+where a different CPU may be chosen each time an interrupt is
+delivered, is not supported. ECos cannot support hardware where all
+interrupts are delivered to all CPUs simultaneously with the
+expectation that software will resolve any conflicts.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Inter-CPU interrupts. A mechanism to allow one CPU to interrupt
+another is needed. This is necessary so that events on one CPU can
+cause rescheduling on other CPUs.
+</para>
+</listitem>
+
+<listitem>
+<para>
+CPU Identifiers. Code running on a CPU must be able to determine
+which CPU it is running on. The CPU Id is usually provided either in
+a CPU status register, or in a register associated with the
+inter-CPU interrupt delivery subsystem. ECos expects CPU Ids to be
+small positive integers, although alternative representations, such
+as bitmaps, can be converted relatively easily. Complex mechanisms
+for getting the CPU Id cannot be supported. Getting the CPU Id must
+be a cheap operation, since it is done often, and in performance
+critical places such as interrupt handlers and the scheduler.
+</para>
+</listitem>
+</itemizedlist>
+
+</section>
+
+<section>
+<title>HAL Support</title>
+
+<para>
+SMP support in any platform depends on the HAL supplying the
+appropriate operations. All HAL SMP support is defined in the
+<filename>cyg/hal/hal_smp.h</filename> header. Variant and platform
+specific definitions will be in <filename>cyg/hal/var_smp.h</filename>
+and <filename>cyg/hal/plf_smp.h</filename> respectively. These files
+are include automatically by this header, so need not be included
+explicitly.
+</para>
+
+<para>
+SMP support falls into a number of functional groups.
+</para>
+
+<section>
+<title>CPU Control</title>
+
+<para>
+This group consists of descriptive and control macros for managing the
+CPUs in an SMP system.
+</para>
+
+<variablelist>
+<varlistentry>
+<term><literal>HAL_SMP_CPU_TYPE</literal></term>
+<listitem>
+<para>
+A type that can contain a CPU id. A CPU id is
+usually a small integer that is used to index
+arrays of variables that are managed on an
+per-CPU basis.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_SMP_CPU_MAX</literal></term>
+<listitem>
+<para>
+The maximum number of CPUs that can be
+supported. This is used to provide the size of
+any arrays that have an element per CPU.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_SMP_CPU_COUNT()</literal></term>
+<listitem>
+<para>
+Returns the number of CPUs currently
+operational. This may differ from
+HAL_SMP_CPU_MAX depending on the runtime
+environment.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_SMP_CPU_THIS()</literal></term>
+<listitem>
+<para>
+Returns the CPU id of the current CPU.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_SMP_CPU_NONE</literal></term>
+<listitem>
+<para>
+A value that does not match any real CPU
+id. This is uses where a CPU type variable
+must be set to a null value.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_SMP_CPU_START( cpu )</literal></term>
+<listitem>
+<para>
+Starts the given CPU executing at a defined
+HAL entry point. After performing any HAL
+level initialization, the CPU calls up into
+the kernel at <function>cyg_kernel_cpu_startup()</function>.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_SMP_CPU_RESCHEDULE_INTERRUPT( cpu, wait )</literal></term>
+<listitem>
+<para>
+Sends the CPU a reschedule interrupt, and if
+<parameter>wait</parameter> is non-zero, waits for an
+acknowledgment. The interrupted CPU should call
+<function>cyg_scheduler_set_need_reschedule()</function> in its DSR to
+cause the reschedule to occur.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_SMP_CPU_TIMESLICE_INTERRUPT( cpu, wait )</literal></term>
+<listitem>
+<para>
+Sends the CPU a timeslice interrupt, and if
+<parameter>wait</parameter> is non-zero, waits for an
+acknowledgment. The interrupted CPU should call
+<function>cyg_scheduler_timeslice_cpu()</function> to cause the
+timeslice event to be processed.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</section>
+
+
+<section>
+<title>Test-and-set Support</title>
+
+<para>
+Test-and-set is the foundation of the SMP synchronization
+mechanisms.
+</para>
+
+<variablelist>
+<varlistentry>
+<term><literal>HAL_TAS_TYPE</literal></term>
+<listitem>
+<para>
+The type for all test-and-set variables. The
+test-and-set macros only support operations on
+a single bit (usually the least significant
+bit) of this location. This allows for maximum
+flexibility in the implementation.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_TAS_SET( tas, oldb )</literal></term>
+<listitem>
+<para>
+Performs a test and set operation on the
+location <parameter>tas</parameter>. <parameter>oldb</parameter> will contain <literal>true</literal> if
+the location was already set, and <literal>false</literal> if
+it was clear.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_TAS_CLEAR( tas, oldb )</literal></term>
+<listitem>
+<para>
+Performs a test and clear operation on the
+location <parameter>tas</parameter>. <parameter>oldb</parameter> will contain <literal>true</literal> if
+the location was already set, and <literal>false</literal> if
+it was clear.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</section>
+<section>
+
+<title>Spinlocks</title>
+
+<para>
+Spinlocks provide inter-CPU locking. Normally they will be implemented
+on top of the test-and-set mechanism above, but may also be
+implemented by other means if, for example, the hardware has more
+direct support for spinlocks.
+</para>
+
+<variablelist>
+<varlistentry>
+<term><literal>HAL_SPINLOCK_TYPE</literal></term>
+<listitem>
+<para>
+The type for all spinlock variables.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_SPINLOCK_INIT_CLEAR</literal></term>
+<listitem>
+<para>
+A value that may be assigned to a spinlock
+variable to initialize it to clear.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_SPINLOCK_INIT_SET</literal></term>
+<listitem>
+<para>
+A value that may be assigned to a spinlock
+variable to initialize it to set.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_SPINLOCK_SPIN( lock )</literal></term>
+<listitem>
+<para>
+The caller spins in a busy loop waiting for
+the lock to become clear. It then sets it and
+continues. This is all handled atomically, so
+that there are no race conditions between CPUs.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_SPINLOCK_CLEAR( lock )</literal></term>
+<listitem>
+<para>
+The caller clears the lock. One of any waiting
+spinners will then be able to proceed.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_SPINLOCK_TRY( lock, val )</literal></term>
+<listitem>
+<para>
+Attempts to set the lock. The value put in
+<parameter>val</parameter> will be <literal>true</literal> if the lock was
+claimed successfully, and <literal>false</literal> if it was
+not.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_SPINLOCK_TEST( lock, val )</literal></term>
+<listitem>
+<para>
+Tests the current value of the lock. The value
+put in <parameter>val</parameter> will be <literal>true</literal> if the lock is
+claimed and <literal>false</literal> of it is clear.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</section>
+<section>
+
+<title>Scheduler Lock</title>
+
+<para>
+The scheduler lock is the main protection for all kernel data
+structures. By default the kernel implements the scheduler lock itself
+using a spinlock. However, if spinlocks cannot be supported by the
+hardware, or there is a more efficient implementation available, the
+HAL may provide macros to implement the scheduler lock.
+</para>
+
+<variablelist>
+<varlistentry>
+<term><literal>HAL_SMP_SCHEDLOCK_DATA_TYPE</literal></term>
+<listitem>
+<para>
+A data type, possibly a structure, that
+contains any data items needed by the
+scheduler lock implementation. A variable of
+this type will be instantiated as a static
+member of the Cyg_Scheduler_SchedLock class
+and passed to all the following macros.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_SMP_SCHEDLOCK_INIT( lock, data )</literal></term>
+<listitem>
+<para>
+Initialize the scheduler lock. The <parameter>lock</parameter>
+argument is the scheduler lock counter and the
+<parameter>data</parameter> argument is a variable of
+HAL_SMP_SCHEDLOCK_DATA_TYPE type.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_SMP_SCHEDLOCK_INC( lock, data )</literal></term>
+<listitem>
+<para>
+Increment the scheduler lock. The first
+increment of the lock from zero to one for any
+CPU may cause it to wait until the lock is
+zeroed by another CPU. Subsequent increments
+should be less expensive since this CPU
+already holds the lock.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_SMP_SCHEDLOCK_ZERO( lock, data )</literal></term>
+<listitem>
+<para>
+Zero the scheduler lock. This operation will
+also clear the lock so that other CPUs may
+claim it.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_SMP_SCHEDLOCK_SET( lock, data, new )</literal></term>
+<listitem>
+<para>
+Set the lock to a different value, in
+<parameter>new</parameter>. This is only called when the lock is
+already known to be owned by the current CPU. It is never called to
+zero the lock, or to increment it from zero.
+</para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</section>
+<section>
+
+<title>Interrupt Routing</title>
+
+<para>
+The routing of interrupts to different CPUs is supported by two new
+interfaces in hal_intr.h.
+</para>
+
+<para>
+Once an interrupt has been routed to a new CPU, the existing vector
+masking and configuration operations should take account of the CPU
+routing. For example, if the operation is not invoked on the
+destination CPU itself, then the HAL may need to arrange to transfer
+the operation to the destination CPU for correct application.
+</para>
+
+<variablelist>
+<varlistentry>
+<term><literal>HAL_INTERRUPT_SET_CPU( vector, cpu )</literal></term>
+<listitem>
+<para>
+Route the interrupt for the given <parameter>vector</parameter> to
+the given <parameter>cpu</parameter>.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><literal>HAL_INTERRUPT_GET_CPU( vector, cpu )</literal></term>
+<listitem>
+<para>
+Set <parameter>cpu</parameter> to the id of the CPU to which this
+vector is routed.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+
+</section>
+
+</section>
+
+
+</section>
+
+<!-- }}} -->
+
+</CHAPTER>
+
+<!-- }}} -->
+<!-- {{{ Exception Handling -->
+
+<CHAPTER id="hal-exception-handling">
+<TITLE>Exception Handling</TITLE>
+
+<!-- {{{ Intro -->
+
+<para>
+Most of the HAL consists of simple macros or functions that are
+called via the interfaces described in the previous section. These
+just perform whatever operation is required by accessing the hardware
+and then return. The exception to this is the handling of exceptions:
+either synchronous hardware traps or asynchronous device
+interrupts. Here control is passed first to the HAL, which then passed
+it on to eCos or the application. After eCos has finished with it,
+control is then passed back to the HAL for it to tidy up the CPU state
+and resume processing from the point at which the exception occurred.
+</para>
+
+<PARA>
+The HAL exceptions handling code is usually found in the file
+<FILENAME>vectors.S</FILENAME> in the architecture HAL. Since the
+reset entry point is usually implemented as one of these it also deals
+with system startup.
+</PARA>
+
+<PARA>
+The exact implementation of this code is under the control of the HAL
+implementer. So long as it interacts correctly with the interfaces
+defined previously it may take any form. However, all current
+implementation follow the same pattern, and there should be a very
+good reason to break with this. The rest of this section describes
+these operate.
+</PARA>
+
+<para>
+Exception handling normally deals with the following broad areas of
+functionality:
+</para>
+
+<ITEMIZEDLIST>
+ <LISTITEM>
+ <PARA>Startup and initialization.</PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>Hardware exception delivery.</PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>Default handling of synchronous exceptions.</PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>Default handling of asynchronous interrupts.</PARA>
+ </LISTITEM>
+</ITEMIZEDLIST>
+
+<!-- }}} -->
+<!-- {{{ HAL Startup -->
+
+<SECTION id="hal-startup">
+<TITLE><!-- <index></index> --><!-- <xref> -->HAL Startup</TITLE>
+
+<PARA>
+Execution normally begins at the reset vector with
+the machine in a minimal startup state. From here the HAL needs to get
+the machine running, set up the execution environment for the
+application, and finally invoke its entry point.
+</PARA>
+
+<PARA>
+The following is a list of the jobs that need to be done in
+approximately the order in which they should be accomplished. Many
+of these will not be needed in some configurations.
+</PARA>
+
+<ITEMIZEDLIST>
+ <listitem>
+ <para>
+ Initialize the hardware. This may involve initializing several
+ subsystems in both the architecture, variant and platform
+ HALs. These include:
+ </para>
+ <itemizedlist>
+ <LISTITEM>
+ <PARA>
+ Initialize various CPU status registers. Most importantly, the CPU
+ interrupt mask should be set to disable interrupts.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Initialize the MMU, if it is used. On many platforms it is
+ only possible to control the cacheability of address ranges
+ via the MMU. Also, it may be necessary to remap RAM and device
+ registers to locations other than their defaults. However, for
+ simplicity, the mapping should be kept as close to one-to-one
+ physical-to-virtual as possible.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Set up the memory controller to access RAM, ROM and I/O devices
+ correctly. Until this is done it may not be possible to access
+ RAM. If this is a ROMRAM startup then the program code can
+ now be copied to its RAM address and control transferred to it.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Set up any bus bridges and support chips. Often access to
+ device registers needs to go through various bus bridges and
+ other intermediary devices. In many systems these are combined
+ with the memory controller, so it makes sense to set these up
+ together. This is particularly important if early diagnostic
+ output needs to go through one of these devices.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Set up diagnostic mechanisms. If the platform includes an LED or
+ LCD output device, it often makes sense to output progress
+ indications on this during startup. This helps with diagnosing
+ hardware and software errors.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Initialize floating point and other extensions such as SIMD
+ and multimedia engines. It is usually necessary to enable
+ these and maybe initialize control and exception registers for
+ these extensions.
+ </PARA>
+ </LISTITEM>
+
+
+ <LISTITEM>
+ <PARA>
+ Initialize interrupt controller. At the very least, it should
+ be configured to mask all interrupts. It may also be necessary
+ to set up the mapping from the interrupt controller's vector
+ number space to the CPU's exception number space. Similar
+ mappings may need to be set up between primary and secondary
+ interrupt controllers.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Disable and initialize the caches. The caches should not
+ normally be enabled at this point, but it may be necessary to
+ clear or initialize them so that they can be enabled
+ later. Some architectures require that the caches be
+ explicitly reinitialized after a power-on reset.
+ </PARA>
+ </LISTITEM>
+
+
+ <LISTITEM>
+ <PARA>
+ Initialize the timer, clock etc. While the timer used for RTC
+ interrupts will be initialized later, it may be necessary to
+ set up the clocks that drive it here.
+ </PARA>
+ </LISTITEM>
+
+ </itemizedlist>
+ <para>
+ The exact order in which these initializations is done is
+ architecture or variant specific. It is also often not necessary
+ to do anything at all for some of these options. These fragments
+ of code should concentrate on getting the target up and running so
+ that C function calls can be made and code can be run. More
+ complex initializations that cannot be done in assembly code may
+ be postponed until calls to
+ <function>hal_variant_init()</function> or
+ <function>hal_platform_init()</function> are made.
+ </para>
+
+ <para>
+ Not all of these initializations need to be done for all startup
+ types. In particular, RAM startups can reasonably assume that the
+ ROM monitor or loader has already done most of this work.
+ </para>
+
+ </listitem>
+
+ <LISTITEM>
+ <PARA>
+ Set up the stack pointer, this allows subsequent initialization
+ code to make proper procedure calls. Usually the interrupt stack
+ is used for this purpose since it is available, large enough, and
+ will be reused for other purposes later.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Initialize any global pointer register needed for access to
+ globally defined variables. This allows subsequent initialization
+ code to access global variables.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ If the system is starting from ROM, copy the ROM template of the
+ <filename>.data</filename> section out to its correct position in
+ RAM. (<xref linkend="hal-linker-scripts">).
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Zero the <filename>.bss</filename> section.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Create a suitable C call stack frame. This may involve making
+ stack space for call frames, and arguments, and initializing the
+ back pointers to halt a GDB backtrace operation.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Call <function>hal_variant_init()</function> and
+ <function>hal_platform_init()</function>. These will perform any
+ additional initialization needed by the variant and platform. This
+ typically includes further initialization of the interrupt
+ controller, PCI bus bridges, basic IO devices and enabling the
+ caches.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Call <FUNCTION>cyg_hal_invoke_constructors()</FUNCTION> to run any
+ static constructors.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Call <FUNCTION>cyg_start()</FUNCTION>. If
+ <FUNCTION>cyg_start()</FUNCTION> returns, drop into an infinite
+ loop.
+ </PARA>
+ </LISTITEM>
+</ITEMIZEDLIST>
+
+</SECTION>
+
+<!-- }}} -->
+<!-- {{{ Vectors and VSRs -->
+
+<SECTION id="hal-vectors-and-vsrs"><!-- <index></index> -->
+<TITLE>Vectors and VSRs</TITLE>
+
+<PARA>
+The CPU delivers all <!-- <index></index> --> exceptions, whether
+synchronous faults or asynchronous interrupts, to a set of hardware
+defined vectors. Depending on the architecture, these may be
+implemented in a number of different ways. Examples of existing
+mechanisms are:
+</PARA>
+
+<VARIABLELIST>
+ <VARLISTENTRY>
+ <TERM>PowerPC</TERM>
+ <LISTITEM>
+ <PARA>
+ Exceptions are vectored to locations 256 bytes apart starting at
+ either zero or <literal>0xFFF00000</literal>. There are 16 such
+ vectors defined by the basic architecture and extra vectors may
+ be defined by specific variants. One of the base vectors is for
+ all external interrupts, and another is for the architecture
+ defined timer.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>MIPS</TERM>
+ <LISTITEM>
+ <PARA>
+ Most exceptions and all interrupts are vectored to a single
+ address at either <literal>0x80000000</literal> or
+ <literal>0xBFC00180</literal>. Software is responsible for
+ reading the exception code from the CPU <literal>cause</literal>
+ register to discover its true source. Some TLB and debug
+ exceptions are delivered to different vector addresses, but
+ these are not used currently by eCos. One of the exception codes
+ in the <literal>cause</literal> register indicates an external
+ interrupt. Additional bits in the <literal>cause</literal>
+ register provide a first-level decode for the interrupt source,
+ one of which represents an architecture defined timer.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>IA32</TERM>
+ <LISTITEM>
+ <PARA>
+ Exceptions are delivered via an Interrupt Descriptor Table (IDT)
+ which is essentially an indirection table indexed by exception
+ number. The IDT may be placed anywhere in memory. In PC hardware
+ the standard interrupt controller can be programmed to deliver
+ the external interrupts to a block of 16 vectors at any offset
+ in the IDT. There is no hardware supplied mechanism for
+ determining the vector taken, other than from the address jumped
+ to.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>ARM</TERM>
+ <LISTITEM>
+ <PARA>
+ All exceptions, including the FIQ and IRQ interrupts, are
+ vectored to locations four bytes apart starting at zero. There
+ is only room for one instruction here, which must immediately
+ jump out to handling code higher in memory. Interrupt sources
+ have to be decoded entirely from the interrupt controller.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+</VARIABLELIST>
+
+
+<para>
+With such a wide variety of hardware approaches, it is not possible to
+provide a generic mechanism for the substitution of exception vectors
+directly. Therefore, eCos translates all of these mechanisms in to a
+common approach that can be used by portable code on all platforms.
+</para>
+
+<para>
+The mechanism implemented is to attach to each hardware vector a short
+piece of trampoline code that makes an indirect jump via a table to
+the actual handler for the exception. This handler is called the
+Vector Service Routine (VSR) and the table is called the VSR table.
+</para>
+
+<para>
+The trampoline code performs the absolute minimum processing necessary
+to identify the exception source, and jump to the VSR. The VSR is then
+responsible for saving the CPU state and taking the necessary actions
+to handle the exception or interrupt. The entry conditions for the VSR
+are as close to the raw hardware exception entry state as possible -
+although on some platforms the trampoline will have had to move or
+reorganize some registers to do its job.
+</para>
+
+<para>
+To make this more concrete, consider how the trampoline code operates
+in each of the architectures described above:
+</para>
+
+
+<VARIABLELIST>
+ <VARLISTENTRY>
+ <TERM>PowerPC</TERM>
+ <LISTITEM>
+ <PARA>
+ A separate trampoline is contained in each of the vector
+ locations. This code saves a few work registers away to the
+ special purposes registers available, loads the exception number
+ into a register and then uses that to index the VSR table and
+ jump to the VSR. The VSR is entered with some registers move to
+ the SPRs, and one of the data register containing the number of
+ the vector taken.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>MIPS</TERM>
+ <LISTITEM>
+ <PARA>
+ A single trampoline routine attached to the common vector reads
+ the exception code out of the <literal>cause</literal> register
+ and uses that value to index the VSR table and jump to the VSR.
+ The trampoline uses the two registers defined in the ABI for
+ kernel use to do this, one of these will contain the exception
+ vector number for the VSR.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>IA32</TERM>
+ <LISTITEM>
+ <PARA>
+ There is a separate 3 or 4 instruction trampoline pointed to by
+ each active IDT table entry. The trampoline for exceptions that
+ also have an error code pop it from the stack and put it into a
+ memory location. Trampolines for non-error-code exceptions just
+ zero the memory location. Then all trampolines push an
+ interrupt/exception number onto the stack, and take an indirect
+ jump through a precalculated offset in the VSR table. This is
+ all done without saving any registers, using memory-only
+ operations. The VSR is entered with the vector number pushed
+ onto the stack on top of the standard hardware saved state.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+
+ <VARLISTENTRY>
+ <TERM>ARM</TERM>
+ <LISTITEM>
+ <PARA>
+ The trampoline consists solely of the single instruction at the
+ exception entry point. This is an indirect jump via a location
+ 32 bytes higher in memory. These locations, from
+ <literal>0x20</literal> up, form the VSR table. Since each VSR
+ is entered in a different CPU mode
+ (<literal>SVC,UNDEF,ABORT,IRQ or FIQ</literal>) there has to be a
+ different VSR for each exception that knows how to save the CPU
+ state correctly.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+</VARIABLELIST>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Synchronous Exception Handling -->
+
+<SECTION id="hal-default-synchronous-exception-handling">
+<TITLE><!-- <index></index> -->Default Synchronous Exception Handling</TITLE>
+
+<PARA>
+Most synchronous exception VSR table entries will point to a default
+exception VSR which is responsible for handling all exceptions in a
+generic manner. The default VSR simply saves the CPU state, makes any
+adjustments to the CPU state that is necessary, and calls
+<function>cyg_hal_exception_handler()</function>.
+</PARA>
+
+<PARA>
+<function>cyg_hal_exception_handler()</function> needs to pass the
+exception on to some handling code. There are two basic destinations:
+enter GDB or pass the exception up to eCos. Exactly which
+destination is taken depends on the configuration. When the GDB stubs are
+included then the exception is passed to them, otherwise it is passed
+to eCos.
+</PARA>
+
+<para>
+If an eCos application has been loaded by RedBoot then the VSR table
+entries will all point into RedBoot's exception VSR, and will
+therefore enter GDB if an exception occurs. If the eCos application
+wants to handle an exception itself, it needs to replace the the VSR
+table entry with one pointing to its own VSR. It can do this with the
+<function>HAL_VSR_SET_TO_ECOS_HANDLER()</function> macro.
+</para>
+
+</SECTION>
+
+<!-- }}} -->
+<!-- {{{ Interrupt Handling -->
+
+<SECTION id="hal-default-interrupt-handling">
+<TITLE><!-- <index></index> -->Default Interrupt Handling</TITLE>
+
+<PARA>
+Most asynchronous external interrupt vectors will point to a default
+interrupt VSR which decodes the actual interrupt being delivered from
+the interrupt controller and invokes the appropriate ISR.
+</PARA>
+
+<PARA>
+The default interrupt VSR has a number of responsibilities if it is
+going to interact with the Kernel cleanly and allow interrupts to
+cause thread preemption.
+</PARA>
+
+<PARA>
+To support this VSR an ISR vector table is needed. For each valid
+vector three pointers need to be stored: the ISR, its data pointer and
+an opaque (to the HAL) interrupt object pointer needed by the
+kernel. It is implementation defined whether these are stored in a
+single table of triples, or in three separate tables.
+</PARA>
+
+<PARA>
+The VSR follows the following approximate plan:
+</PARA>
+
+<ORDEREDLIST>
+ <LISTITEM>
+ <PARA>
+ Save the CPU state. In non-debug configurations, it may be
+ possible to get away with saving less than the entire machine
+ state. The option
+ <literal>CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT</literal>
+ is supported in some targets to do this.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Increment the kernel scheduler lock. This is a static member of
+ the Cyg_Scheduler class, however it has also been aliased to
+ <literal>cyg_scheduler_sched_lock</literal> so that it can be
+ accessed from assembly code.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ (Optional) Switch to an interrupt stack if not already running on
+ it. This allows nested interrupts to be delivered without needing
+ every thread to have a stack large enough to take the maximum
+ possible nesting. It is implementation defined how to detect
+ whether this is a nested interrupt but there are two basic
+ techniques. The first is to inspect the stack pointer and switch
+ only if it is not currently within the interrupt stack range; the
+ second is to maintain a counter of the interrupt nesting level and
+ switch only if it is zero. The option
+ <literal>CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK</literal>
+ controls whether this happens.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Decode the actual external interrupt being delivered from
+ the interrupt controller. This will yield the ISR vector
+ number. The code to do this usually needs to come from the
+ variant or platform HAL, so is usually present in the form of a
+ macro or procedure callout.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ (Optional) Re-enable interrupts to permit nesting. At this point
+ we can potentially allow higher priority interrupts to occur. It
+ depends on the interrupt architecture of the CPU and platform
+ whether more interrupts will occur at this point, or whether they
+ will only be delivered after the current interrupt has been
+ acknowledged (by a call to
+ <function>HAL_INTERRUPT_ACKNOWLEDGE()</function> in the ISR).
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Using the ISR vector number as an index, retrieve the
+ ISR pointer and its data pointer from the ISR vector table.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Construct a C call stack frame. This may involve making stack
+ space for call frames, and arguments, and initializing the back
+ pointers to halt a GDB backtrace operation.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Call the ISR, passing the vector number and data pointer. The
+ vector number and a pointer to the saved state should be preserved
+ across this call, preferably by storing them in registers that are
+ defined to be callee-saved by the calling conventions.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ If this is an un-nested interrupt and a separate interrupt
+ stack is being used, switch back to the interrupted thread's
+ own stack.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Use the saved ISR vector number to get the interrupt object
+ pointer from the ISR vector table.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ Call <FUNCTION>interrupt_end()</FUNCTION> passing it the return
+ value from the ISR, the interrupt object pointer and a pointer to
+ the saved CPU state. This function is implemented by the Kernel
+ and is responsible for finishing off the interrupt
+ handling. Specifically, it may post a DSR depending on the ISR
+ return value, and will decrement the scheduler lock. If the lock
+ is zeroed by this operation then any posted DSRs may be called and
+ may in turn result in a thread context switch.
+ </PARA>
+ </LISTITEM>
+
+ <LISTITEM>
+ <PARA>
+ The return from <FUNCTION>interrupt_end()</FUNCTION> may occur
+ some time after the call. Many other threads may have executed in
+ the meantime. So here all we may do is restore the machine state
+ and resume execution of the interrupted thread. Depending on the
+ architecture, it may be necessary to disable interrupts again for
+ part of this.
+ </PARA>
+ </LISTITEM>
+
+</ORDEREDLIST>
+
+<PARA>
+The detailed order of these steps may vary slightly depending on the
+architecture, in particular where interrupts are enabled and disabled.
+</PARA>
+
+</SECTION>
+
+<!-- }}} -->
+
+</CHAPTER>
+
+<!-- }}} -->
+<!-- {{{ Porting Guide -->
+
+&hal-common-porting-sgml;
+
+<!-- }}} -->
+<!-- {{{ Future Developments -->
+
+<CHAPTER id="hal-future-developments">
+<TITLE><!-- <index></index> --><!-- <xref> -->Future developments</TITLE>
+
+<PARA>
+The HAL is not complete, and will evolve and increase over
+time. Among the intended developments are:
+</PARA>
+<ITEMIZEDLIST>
+<LISTITEM>
+<PARA>Common macros for interpreting the contents of a saved
+machine context. These would allow portable code, such as debug
+stubs, to extract such values as the program counter and stack pointer
+from a state without having to interpret a <STRUCTNAME>HAL_SavedRegisters</STRUCTNAME> structure
+directly.</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>Debugging support. Macros to set and clear hardware and
+software breakpoints. Access to other areas of machine state may
+also be supported.</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>Static initialization support. The current HAL provides a
+dynamic interface to things like thread context initialization and ISR
+attachment. We also need to be able to define the system entirely
+statically so that it is ready to go on restart, without needing to
+run code. This will require extra macros to define these
+initializations. Such support may have a consequential effect on the
+current HAL specification.</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>CPU state control. Many CPUs have both kernel and user
+states. Although it is not intended to run any code in user state
+for the foreseeable future, it is possible that this may happen
+eventually. If this is the case, then some minor changes may be needed
+to the current HAL API to accommodate this. These should mostly
+be extensions, but minor changes in semantics may also be required.</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>Physical memory management. Many embedded systems have
+multiple memory areas with varying properties such as base address,
+size, speed, bus width, cacheability and persistence. An API is
+needed to support the discovery of this information about the machine's
+physical memory map.</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>Memory management control. Some embedded processors have
+a memory management unit. In some cases this must be enabled to
+allow the cache to be controlled, particularly if different regions
+of memory must have different caching properties. For some purposes,
+in some systems, it will be useful to manipulate the MMU settings
+dynamically.</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>Power management. Macros to access and control any power
+management mechanisms available on the CPU implementation. These
+would provide a substrate for a more general power management system
+that also involved device drivers and other hardware components.</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>Generic serial line macros. Most serial line devices operate
+in the same way, the only real differences being exactly which bits
+in which registers perform the standard functions. It should be
+possible to develop a set of HAL macros that provide basic serial
+line services such as baud rate setting, enabling interrupts, polling
+for transmit or receive ready, transmitting and receiving data etc.
+Given these it should be possible to create a generic serial line
+device driver that will allow rapid bootstrapping on any new platform.
+It may be possible to extend this mechanism to other device types.</PARA>
+</LISTITEM>
+</ITEMIZEDLIST>
+</CHAPTER>
+
+<!-- }}} -->
+
+</part>
diff --git a/ecos/packages/hal/common/current/doc/porting.sgml b/ecos/packages/hal/common/current/doc/porting.sgml
new file mode 100644
index 0000000..792150f
--- /dev/null
+++ b/ecos/packages/hal/common/current/doc/porting.sgml
@@ -0,0 +1,4391 @@
+<!-- {{{ Banner -->
+
+<!-- =============================================================== -->
+<!-- -->
+<!-- porting.sgml -->
+<!-- -->
+<!-- eCos common HAL documentation -->
+<!-- -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTBEGIN#### -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2010 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 -->
+<!-- =============================================================== -->
+<!-- ####ECOSDOCCOPYRIGHTEND#### -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN#### -->
+<!-- -->
+<!-- ####DESCRIPTIONEND#### -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<CHAPTER id="hal-porting-guide">
+<TITLE><!-- <index></index> --> Porting Guide</TITLE>
+
+<!-- {{{ Intro -->
+
+<section id="hal-porting-intro">
+<title>Introduction</title>
+
+<para>
+eCos has been designed to be fairly easy to port to new targets. A
+target is a specific platform (board) using a given architecture (CPU
+type). The porting is facilitated by the hierarchical layering of the
+eCos sources - all architecture and platform specific code is
+implemented in a HAL (hardware abstraction layer).
+</para>
+
+<para>
+By porting the eCos HAL to a new target the core functionality of eCos
+(infra, kernel, uITRON, etc) will be able to run on the target. It may
+be necessary to add further platform specific code such as serial
+drivers, display drivers, ethernet drivers, etc. to get a fully
+capable system.
+</para>
+
+<para>
+This document is intended as a help to the HAL porting process. Due to
+the nature of a porting job, it is impossible to give a complete
+description of what has to be done for each and every potential
+target. This should not be considered a clear-cut recipe - you will
+probably need to make some implementation decisions, tweak a few
+things, and just plain have to rely on common sense.
+</para>
+
+<para>
+However, what is covered here should be a large part of the
+process. If you get stuck, you are advised to read the
+<ulink url="http://ecos.sourceware.org/ml/ecos-discuss/">
+ecos-discuss archive
+</ulink>
+where you may find discussions which apply to the problem at
+hand. You are also invited to ask questions on the
+<ulink url="http://ecos.sourceware.org/intouch.html">
+ecos-discuss mailing list
+</ulink>
+to help you resolve problems - but as is always the case
+with community lists, do not consider it an oracle for any and all
+questions. Use common sense - if you ask too many questions which
+could have been answered by reading the
+<ulink
+url="http://ecos.sourceware.org/ecos/docs-latest/">documentation</ulink>,
+<ulink url="http://ecos.sourceware.org/fom/ecos">FAQ</ulink> or
+<ulink url="http://ecos.sourceware.org/cgi-bin/cvsweb.cgi/ecos/packages/?cvsroot=ecos">
+source code
+</ulink>, you are likely to be ignored.
+</para>
+
+<para>
+This document will be continually improved by Red Hat engineers as
+time allows. Feedback and help with improving the document is sought,
+so if you have any comments at all, please do not hesitate to post
+them on
+<ulink url="mailto:ecos-discuss@ecos.sourceware.org?subject=[porting]<subject>">
+ecos-discuss
+</ulink>
+(please prefix the subject with [porting]).
+</para>
+
+<para>
+At the moment this document is mostly an outline. There are many
+details to fill in before it becomes complete. Many places you'll just
+find a list of keywords / concepts that should be described (please
+post on ecos-discuss if there are areas you think are not covered).
+</para>
+
+<para>
+All pages or sections where the caption ends in [TBD] contain little
+more than key words and/or random thoughts - there has been no work
+done as such on the content. The word FIXME may appear in the text to
+highlight places where information is missing.
+</para>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ HAL Structure -->
+
+<section id="hal-porting-structure">
+<title>HAL Structure</title>
+
+<para>
+In order to write an eCos HAL it's a good idea to have at least a
+passing understanding of how the HAL interacts with the rest of the
+system.
+</para>
+
+<!-- {{{ HAL Classes -->
+
+<section>
+<title>HAL Classes</title>
+
+<para>
+The eCos HAL consists of four HAL sub-classes. This table gives a
+brief description of each class and partly reiterates the description
+in <xref linkend="hal-architecture-variant-and-platform">. The links
+refer to the on-line CVS tree (specifically to the sub-HALs used by
+the PowerPC MBX target).
+</para>
+
+<informaltable frame=all>
+<tgroup cols=3 align=left colsep=1 rowsep=1>
+<thead>
+<row>
+<entry>HAL type</entry>
+<entry>Description</entry>
+<entry>Functionality Overview</entry>
+</row>
+</thead>
+<tbody>
+<row>
+<entry>
+Common HAL <ulink url="http://ecos.sourceware.org/cgi-bin/cvsweb.cgi/ecos/packages/hal/common/current?cvsroot=ecos">(hal/common)</ulink>
+</entry>
+<entry>Configuration options and functionality shared by all HALs.</entry>
+<entry>Generic debugging functionality, driver API, eCos/ROM monitor
+ calling interface, and tests.</entry>
+</row>
+<row>
+ <entry>Architecture HAL <ulink url="http://ecos.sourceware.org/cgi-bin/cvsweb.cgi/ecos/packages/hal/powerpc/arch/current?cvsroot=ecos">(hal/&lt;architecture&gt;/arch)</ulink></entry>
+ <entry>Functionality specific to the given architecture. Also default
+ implementations of some functionality which can be overridden by
+ variant or platform HALs.</entry>
+ <entry>Architecture specific debugger functionality (handles single
+ stepping, exception-to-signal conversion, etc.),
+ exception/interrupt vector definitions and handlers, cache
+ definition and control macros, context switching code, assembler
+ functions for early system initialization, configuration options,
+ and possibly tests. </entry>
+</row>
+<row>
+ <entry>Variant HAL <ulink url="http://ecos.sourceware.org/cgi-bin/cvsweb.cgi/ecos/packages/hal/powerpc/mpc8xx/current?cvsroot=ecos">(hal/&lt;architecture&gt;/&lt;variant&gt;)</ulink></entry>
+ <entry>Some CPU architectures consist of a number variants, for example
+ MIPS CPUs come in both 32 and 64 bit versions, and some variants
+ have embedded features additional to the CPU core.
+</entry>
+ <entry>Variant extensions to the architecture code (cache,
+ exception/interrupt), configuration options, possibly drivers for
+ variant on-core devices, and possibly tests.</entry>
+</row>
+<row>
+ <entry>Platform HAL <ulink url="http://ecos.sourceware.org/cgi-bin/cvsweb.cgi/ecos/packages/hal/powerpc/mbx/current?cvsroot=ecos">(hal/&lt;architecture&gt;/&lt;platform&gt;)</ulink></entry>
+ <entry>Contains functionality and configuration options specific to the
+ platform.
+</entry>
+ <entry>Early platform initialization code, platform memory layout
+ specification, configuration options (processor speed, compiler
+ options), diagnostic IO functions, debugger IO functions,
+ platform specific extensions to architecture or variant code
+ (off-core interrupt controller), and possibly tests.</entry>
+</row>
+<row>
+ <entry>Auxiliary HAL <ulink url="http://ecos.sourceware.org/cgi-bin/cvsweb.cgi/ecos/packages/hal/powerpc/quicc/current?cvsroot=ecos">(hal/&lt;architecture&gt;/&lt;module&gt;)</ulink></entry>
+ <entry>Some variants share common modules on the core. Motorola's PowerPC
+ QUICC is an example of such a module.
+</entry>
+ <entry>Module specific functionality (interrupt controller, simple
+ device drivers), possibly tests.
+</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ File Descriptions -->
+
+<section>
+<title>File Descriptions</title>
+
+<para>
+Listed below are the files found in various HALs, with a short
+description of what each file contains. When looking in existing HALs
+beware that they do not necessarily follow this naming scheme.
+If you are writing a new HAL, please try to follow it as
+closely as possible. Still, no two targets are the same, so sometimes
+it makes sense to use additional files.
+</para>
+
+<!-- {{{ Common HAL -->
+
+<section>
+<title>Common HAL</title>
+
+<informaltable frame=all>
+<tgroup cols=2 align=left colsep=1 rowsep=1>
+<thead>
+<row>
+<entry>File</entry>
+<entry>Description</entry>
+</row>
+</thead>
+<tbody>
+
+<row>
+<entry><filename>include/dbg-thread-syscall.h</filename></entry>
+ <entry>Defines the thread debugging syscall function. This is used by
+ the ROM monitor to access the thread debugging API in the RAM
+ application. <!-- FIXME: link thread debug description -->.</entry>
+</row>
+<row>
+<entry><filename>include/dbg-threads-api.h</filename></entry>
+ <entry>Defines the thread debugging API. <!-- FIXME: link thread
+ debug description -->.</entry>
+</row>
+<row>
+<entry><filename>include/drv_api.h</filename></entry>
+ <entry>Defines the driver API.</entry>
+</row>
+<row>
+<entry><filename>include/generic-stub.h</filename></entry>
+ <entry>Defines the generic stub features.</entry>
+</row>
+<row>
+<entry><filename>include/hal_if.h</filename></entry>
+ <entry>Defines the ROM/RAM calling interface API.</entry>
+</row>
+<row>
+<entry><filename>include/hal_misc.h</filename></entry>
+ <entry>Defines miscellaneous helper functions shared by all HALs.</entry>
+</row>
+<row>
+<entry><filename>include/hal_stub.h</filename></entry>
+ <entry>Defines eCos mappings of GDB stub features.</entry>
+</row>
+<row>
+<entry><filename>src/dbg-threads-syscall.c</filename></entry>
+ <entry>Thread debugging implementation.</entry>
+</row>
+<row>
+<entry><filename>src/drv_api.c</filename></entry>
+ <entry>Driver API implementation. Depending on configuration this
+ provides either wrappers for the kernel API, or a minimal
+ implementation of these features. This allows drivers to be written
+ relying only on HAL features.</entry>
+</row>
+<row>
+<entry><filename>src/dummy.c</filename></entry>
+ <entry>Empty dummy file ensuring creation of libtarget.a.</entry>
+</row>
+<row>
+<entry><filename>src/generic-stub.c</filename></entry>
+ <entry>Generic GDB stub implementation. This provides the
+ communication protocol used to communicate with GDB over a serial
+ device or via the network.</entry>
+</row>
+<row>
+<entry><filename>src/hal_if.c</filename></entry>
+ <entry>ROM/RAM calling interface implementation. Provides wrappers from
+ the calling interface API to the eCos features used for the
+ implementation.</entry>
+</row>
+<row>
+<entry><filename>src/hal_misc.c</filename></entry>
+ <entry>Various helper functions shared by all platforms and
+ architectures.</entry>
+</row>
+<row>
+<entry><filename>src/hal_stub.c</filename></entry>
+ <entry>Wrappers from eCos HAL features to the features required by the
+ generic GDB stub.</entry>
+</row>
+<row>
+<entry><filename>src/stubrom/stubrom.c</filename></entry>
+ <entry>The file used to build eCos GDB stub images. Basically a
+ cyg_start function with a hard coded breakpoint.</entry>
+</row>
+<row>
+<entry><filename>src/thread-packets.c</filename></entry>
+ <entry>More thread debugging related functions.</entry>
+</row>
+<row>
+<entry><filename>src/thread-pkts.h</filename></entry>
+ <entry>Defines more thread debugging related function.</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Architecture HAL -->
+
+<section>
+<title>Architecture HAL</title>
+
+<para>Some architecture HALs may add extra files for architecture
+specific serial drivers, or for handling interrupts and exceptions if it
+makes sense.</para>
+
+<para>Note that many of the definitions in these files are only
+conditionally defined - if the equivalent variant or platform headers
+provide the definitions, those override the generic architecture
+definitions.</para>
+
+<informaltable frame=all>
+<tgroup cols=2 align=left colsep=1 rowsep=1>
+<thead>
+<row>
+<entry>File</entry>
+<entry>Description</entry>
+</row>
+</thead>
+<tbody>
+
+<row>
+<entry><filename>include/arch.inc</filename></entry>
+ <entry>Various assembly macros used during system initialization.</entry>
+</row>
+<row>
+<entry><filename>include/basetype.h</filename></entry>
+ <entry>Endian, label, alignment, and type size definitions. These
+ override common defaults in CYGPKG_INFRA.</entry>
+</row>
+<row>
+<entry><filename>include/hal_arch.h</filename></entry>
+ <entry>Saved register frame format, various thread, register and stack
+ related macros.</entry>
+</row>
+<row>
+<entry><filename>include/hal_cache.h</filename></entry>
+ <entry>Cache definitions and cache control macros.</entry>
+</row>
+<row>
+<entry><filename>include/hal_intr.h</filename></entry>
+ <entry>Exception and interrupt definitions. Macros for configuring and
+ controlling interrupts. eCos real-time clock control macros.</entry>
+</row>
+<row>
+<entry><filename>include/hal_io.h</filename></entry>
+ <entry>Macros for accessing IO devices.</entry>
+</row>
+<row>
+<entry><filename>include/&lt;arch&gt;_regs.h</filename></entry>
+ <entry>Architecture register definitions.</entry>
+</row>
+<row>
+<entry><filename>include/&lt;arch&gt;_stub.h</filename></entry>
+ <entry>Architecture stub definitions. In particular the register frame
+ layout used by GDB. This may differ from the one used by eCos.</entry>
+</row>
+<row>
+<entry><filename>include/&lt;arch&gt;.inc</filename></entry>
+ <entry>Architecture convenience assembly macros.</entry>
+</row>
+<row>
+<entry><filename>src/&lt;arch&gt;.ld</filename></entry>
+ <entry>Linker macros.</entry>
+</row>
+<row>
+<entry><filename>src/context.S</filename></entry>
+ <entry>Functions handling context switching and setjmp/longjmp.</entry>
+</row>
+<row>
+<entry><filename>src/hal_misc.c</filename></entry>
+ <entry>Exception and interrupt handlers in C. Various other utility
+ functions.</entry>
+</row>
+<row>
+<entry><filename>src/hal_mk_defs.c</filename></entry>
+ <entry>Used to export definitions from C header files to assembler
+ header files.</entry>
+</row>
+<row>
+<entry><filename>src/hal_intr.c</filename></entry>
+ <entry>Any necessary interrupt handling functions.</entry>
+</row>
+<row>
+<entry><filename>src/&lt;arch&gt;stub.c</filename></entry>
+ <entry>Architecture stub code. Contains functions for translating eCos
+ exceptions to UNIX signals and functions for single-stepping.</entry>
+</row>
+<row>
+<entry><filename>src/vectors.S</filename></entry>
+ <entry>Exception, interrupt and early initialization code.</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Variant HAL -->
+
+<section>
+<title>Variant HAL</title>
+
+<para>Some variant HALs may add extra files for variant specific serial
+drivers, or for handling interrupts/exceptions if it makes sense.</para>
+
+<para>Note that these files may be mostly empty if the CPU variant can be
+controlled by the generic architecture macros. The definitions present
+are only conditionally defined - if the equivalent platform headers
+provide the definitions, those override the variant definitions.</para>
+
+<informaltable frame=all>
+<tgroup cols=2 align=left colsep=1 rowsep=1>
+<thead>
+<row>
+<entry>File</entry>
+<entry>Description</entry>
+</row>
+</thead>
+<tbody>
+
+<row>
+<entry><filename>include/var_arch.h</filename></entry>
+ <entry>Saved register frame format, various thread, register and stack
+ related macros.</entry>
+</row>
+<row>
+<entry><filename>include/var_cache.h</filename></entry>
+ <entry>Cache related macros.</entry>
+</row>
+<row>
+<entry><filename>include/var_intr.h</filename></entry>
+ <entry>Interrupt related macros.</entry>
+</row>
+<row>
+<entry><filename>include/var_regs.h</filename></entry>
+ <entry>Extra register definitions for the CPU variant.</entry>
+</row>
+<row>
+<entry><filename>include/variant.inc</filename></entry>
+ <entry>Various assembly macros used during system initialization.</entry>
+</row>
+<row>
+<entry><filename>src/var_intr.c</filename></entry>
+ <entry>Interrupt functions if necessary.</entry>
+</row>
+<row>
+<entry><filename>src/var_misc.c</filename></entry>
+ <entry>hal_variant_init function and any necessary extra functions.</entry>
+</row>
+<row>
+<entry><filename>src/variant.S</filename></entry>
+ <entry>Interrupt handler table definition.</entry>
+</row>
+<row>
+<entry><filename>src/&lt;arch&gt;_&lt;variant&gt;.ld</filename></entry>
+ <entry>Linker macros.</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Platform HAL -->
+
+<section>
+<title>Platform HAL</title>
+
+<para>Extras files may be added for platform specific serial
+drivers. Extra files for handling interrupts and exceptions will be
+present if it makes sense.</para>
+
+<informaltable frame=all>
+<tgroup cols=2 align=left colsep=1 rowsep=1>
+<thead>
+<row>
+<entry>File</entry>
+<entry>Description</entry>
+</row>
+</thead>
+<tbody>
+
+<row>
+<entry><filename>include/hal_diag.h</filename></entry>
+ <entry>Defines functions used for HAL diagnostics output. This would
+ normally be the ROM calling interface wrappers, but may also be the
+ low-level IO functions themselves, saving a little overhead.</entry>
+</row>
+<row>
+<entry><filename>include/platform.inc</filename></entry>
+
+ <entry>Platform initialization code. This includes memory controller,
+ vectors, and monitor initialization. Depending on the architecture,
+ other things may need defining here as well: interrupt decoding,
+ status register initialization value, etc.</entry>
+
+</row>
+<row>
+<entry><filename>include/plf_cache.h</filename></entry>
+ <entry>Platform specific cache handling.</entry>
+</row>
+<row>
+<entry><filename>include/plf_intr.h</filename></entry>
+ <entry>Platform specific interrupt handling.</entry>
+</row>
+<row>
+<entry><filename>include/plf_io.h</filename></entry>
+ <entry>PCI IO definitions and macros. May also be used to override
+ generic HAL IO macros if the platform endianness differs from that of
+ the CPU.</entry>
+</row>
+<row>
+<entry><filename>include/plf_stub.h</filename></entry>
+ <entry>Defines stub initializer and board reset details.</entry>
+</row>
+<row>
+<entry><filename>src/hal_diag.c</filename></entry>
+ <entry>May contain the low-level device drivers. But these may also
+ reside in plf_stub.c</entry>
+</row>
+<row>
+<entry><filename>src/platform.S</filename></entry>
+ <entry>Memory controller setup macro, and if necessary interrupt
+ springboard code.</entry>
+</row>
+<row>
+<entry><filename>src/plf_misc.c</filename></entry>
+ <entry>Platform initialization code.</entry>
+</row>
+<row>
+<entry><filename>src/plf_mk_defs.c</filename></entry>
+ <entry>Used to export definitions from C header files to assembler
+ header files.</entry>
+</row>
+<row>
+<entry><filename>src/plf_stub.c</filename></entry>
+ <entry>Platform specific stub initialization and possibly the low-level
+ device driver.</entry>
+</row>
+</tbody>
+</tgroup>
+</informaltable>
+
+<para>The platform HAL also contains files specifying the platform's
+memory layout. These files are located in
+<filename>include/pkgconf</filename>.</para>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Auxiliary HAL -->
+
+<section>
+<title>Auxiliary HAL</title>
+
+<para>Auxiliary HALs contain whatever files are necessary to provide the
+required functionality. There are no predefined set of files required
+in an auxiliary HAL.</para>
+
+</section>
+
+<!-- }}} -->
+
+</section>
+
+<!-- }}} -->
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ ROM Monitor Calling Interface -->
+
+<section id="hal-calling-if">
+<TITLE>Virtual Vectors (eCos/ROM Monitor Calling Interface)</TITLE>
+
+<para>
+Virtually all eCos platforms provide full debugging capabilities
+via RedBoot. This enviroment contains not only debug stubs based
+on GDB, but also rich I/O support which can be exported to loaded
+programs. Such programs can take advantage of the I/O capabilities
+using a special ROM/RAM calling interface
+(also referred to as virtual vector table).
+eCos programs make use of the virtual vector mechanism implicitly.
+Non-eCos programs can access these functions using the support from
+the <emphasis>newlib</emphasis> library.
+</para>
+
+<!-- {{{ Virtual Vectors -->
+
+<section id="hal-porting-virtual-vectors">
+<title>Virtual Vectors</title>
+
+<para>What are virtual vectors, what do they do, and why are they
+needed?
+</para>
+
+<para>
+"Virtual vectors" is the name of a table located at a static
+location in the target address space. This table contains 64 vectors
+that point to <emphasis>service</emphasis> functions or data.
+</para>
+
+<para>The fact that the vectors are always placed at the same location in
+the address space means that both ROM and RAM startup configurations
+can access these and thus the services pointed to.</para>
+
+<para>The primary goal is to allow services to be provided by ROM
+configurations (ROM monitors such as RedBoot in particular) with
+<emphasis>clients</emphasis> in RAM configurations being able to use these
+services.</para>
+
+<para>Without the table of pointers this would be impossible since the
+ROM and RAM applications would be linked separately - in effect having
+separate name spaces - preventing direct references from one to the
+other.</para>
+
+<para>This decoupling of service from client is needed by RedBoot,
+allowing among other things debugging of applications which do not
+contain debugging client code (stubs).</para>
+
+<!-- {{{ Initialization -->
+
+<section>
+<title>Initialization (or Mechanism vs. Policy)</title>
+
+<para>Virtual vectors are a <emphasis>mechanism</emphasis> for decoupling services
+from clients in the address space.</para>
+
+<para>The mechanism allows services to be implemented by a ROM
+monitor, a RAM application, to be switched out at run-time, to be
+disabled by installing pointers to dummy functions, etc.</para>
+
+<para>The appropriate use of the mechanism is specified loosely by a
+<emphasis>policy</emphasis>. The general policy dictates that the vectors are
+initialized in whole by ROM monitors (built for ROM or RAM), or by
+stand-alone applications.</para>
+
+<para>For configurations relying on a ROM monitor environment, the policy
+is to allow initialization on a service by service basis. The default
+is to initialize all services, except COMMS services since these are
+presumed to already be carrying a communication session to the
+debugger / console which was used for launching the application. This
+means that the bulk of the code gets tested in normal builds, and not
+just once in a blue moon when building new stubs or a ROM
+configuration.</para>
+
+<para>The configuration options are written to comply with this policy by
+default, but can be overridden by the user if desired. Defaults
+are:</para>
+
+<itemizedlist>
+<listitem><para>For application development: the ROM monitor provides
+debugging and diagnostic IO services, the RAM application relies
+on these by default.</para>
+</listitem>
+<listitem>
+<para>For production systems: the application contains all the
+necessary services.</para>
+</listitem>
+
+</itemizedlist>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Pros and Cons -->
+
+<section>
+<title>Pros and Cons of Virtual Vectors</title>
+
+<para>
+There are pros and cons associated with the use of virtual
+vectors. We do believe that the pros generally outweigh the cons by a
+great margin, but there may be situations where the opposite is
+true.
+</para>
+
+<para>
+The use of the services are implemented by way of macros, meaning
+that it is possible to circumvent the virtual vectors if
+desired. There is (as yet) no implementation for doing this, but it is
+possible.
+</para>
+
+<para>Here is a list of pros and cons:</para>
+
+<variablelist>
+<varlistentry><term>Pro: Allows debugging without including stubs</term>
+
+ <listitem><para>This is the primary reason for using virtual vectors. It
+ allows the ROM monitor to provide most of the debugging
+ infrastructure, requiring only the application to provide
+ hooks for asynchronous debugger interrupts and for accessing
+ kernel thread information.</para></listitem></varlistentry>
+
+<varlistentry><term>Pro: Allows debugging to be initiated from arbitrary
+ channel</term>
+
+ <listitem><para> While this is only true where the application does not
+ actively override the debugging channel setup, it is a very
+ nice feature during development. In particular it makes it
+ possible to launch (and/or debug) applications via Ethernet
+ even though the application configuration does not contain
+ networking support.</para></listitem></varlistentry>
+
+<varlistentry><term>Pro: Image smaller due to services being provided by ROM
+ monitor</term>
+
+ <listitem><para>All service functions except HAL IO are included in the
+ default configuration. But if these are all disabled the
+ image for download will be a little smaller. Probably
+ doesn't matter much for regular development, but it is a
+ worthwhile saving for the 20000 daily tests run in the Red
+ Hat eCos test farm.</para></listitem></varlistentry>
+
+<varlistentry><term>Con: The vectors add a layer of indirection, increasing application
+ size and reducing performance.</term>
+
+ <listitem><para>The size increase is a fraction of what is required to
+ implement the services. So for RAM configurations there is
+ a net saving, while for ROM configurations there is a small
+ overhead.</para>
+
+ <para>The performance loss means little for most of the
+ services (of which the most commonly used is diagnostic IO
+ which happens via polled routines
+ anyway).</para></listitem>
+</varlistentry>
+
+<varlistentry><term>Con: The layer of indirection is another point of
+ failure.</term>
+
+ <listitem><para> The concern primarily being that of vectors being
+ trashed by rogue writes from bad code, causing a complete
+ loss of the service and possibly a crash. But this does
+ not differ much from a rogue write to anywhere else in the
+ address space which could cause the same amount of
+ mayhem. But it is arguably an additional point of failure
+ for the service in question.</para></listitem></varlistentry>
+
+<varlistentry><term>Con: All the indirection stuff makes it harder to bring a HAL
+ up</term>
+
+ <listitem><para> This is a valid concern. However, seeing as most of the
+ code in question is shared between all HALs and should
+ remain unchanged over time, the risk of it being broken
+ when a new HAL is being worked on should be
+ minimal.</para>
+
+ <para> When starting a new port, be sure to implement the HAL
+ IO drivers according to the scheme used in other drivers,
+ and there should be no problem.</para>
+
+ <para> However, it is still possible to circumvent the vectors
+ if they are suspect of causing problems: simply change the
+ HAL_DIAG_INIT and HAL_DIAG_WRITE_CHAR macros to use the raw
+ IO functions.</para></listitem></varlistentry>
+</variablelist>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Available Services -->
+
+<section>
+<title>Available services</title>
+
+<para>
+The <filename>hal_if.h</filename> file in the common HAL defines the
+complete list of available services. A few worth mentioning in
+particular:</para>
+
+<itemizedlist>
+<listitem> <para>COMMS services. All HAL IO happens via the communication
+ channels.</para>
+</listitem>
+<listitem> <para>uS delay. Fine granularity (busy wait) delay function.</para>
+</listitem>
+<listitem> <para>Reset. Allows a software initiated reset of the board.</para>
+</listitem>
+</itemizedlist>
+
+</section>
+
+<!-- }}} -->
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ The COMMS Channels -->
+
+<section>
+<title>The COMMS channels</title>
+
+<para>As all HAL IO happens via the COMMS channels these deserve to be
+described in a little more detail. In particular the controls of where
+diagnostic output is routed and how it is treated to allow for display
+in debuggers.</para>
+
+<!-- {{{ Console and Debuggers Channels -->
+
+<section>
+<title>Console and Debugging Channels</title>
+
+<para>There are two COMMS channels - one for console IO and one for
+debugging IO. They can be individually configured to use any of the
+actual IO ports (serial or Ethernet) available on the platform.</para>
+
+<para>The console channel is used for any IO initiated by calling the
+<function>diag_*()</function> functions. Note that these should only be used during
+development for debugging, assertion and possibly tracing
+messages. All proper IO should happen via proper devices. This means
+it should be possible to remove the HAL device drivers from production
+configurations where assertions are disabled.</para>
+
+<para>The debugging channel is used for communication between the
+debugger and the stub which remotely controls the target for the
+debugger (the stub runs on the target). This usually happens via some
+protocol, encoding commands and replies in some suitable form.</para>
+
+<para>Having two separate channels allows, e.g., for simple logging
+without conflicts with the debugger or interactive IO which some
+debuggers do not allow.</para>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Mangling -->
+
+<section>
+<title>Mangling</title>
+
+<para>As debuggers usually have a protocol using specialized commands
+when communicating with the stub on the target, sending out text as
+raw ASCII from the target on the same channel will either result in
+protocol errors (with loss of control over the target) or the text may
+just be ignored as junk by the debugger.</para>
+
+<para>To get around this, some debuggers have a special command for text
+output. Mangling is the process of encoding diagnostic ASCII text
+output in the form specified by the debugger protocol.</para>
+
+<para>When it is necessary to use mangling, i.e. when writing console
+output to the same port used for debugging, a mangler function is
+installed on the console channel which mangles the text and passes it
+on to the debugger channel.</para>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Controlling the Console Channel -->
+
+<section>
+<title>Controlling the Console Channel</title>
+
+<para>Console output configuration is either inherited from the ROM
+monitor launching the application, or it is specified by the
+application. This is controlled by the new option
+<literal>CYGSEM_HAL_VIRTUAL_VECTOR_INHERIT_CONSOLE</literal> which
+defaults to enabled when the configuration is set to use a ROM
+monitor.</para>
+
+<para>If the user wants to specify the console configuration in the
+application image, there are two new options that are used for
+this.</para>
+
+<para>Defaults are to direct diagnostic output via a mangler to the
+debugging channel (<literal>CYGDBG_HAL_DIAG_TO_DEBUG_CHAN</literal>
+enabled). The mangler type is controlled by the option
+<literal>CYGSEM_HAL_DIAG_MANGLER</literal>. At present there are only
+two mangler types:</para>
+
+<variablelist>
+<varlistentry><term><acronym>GDB</acronym></term>
+
+ <listitem><para> This causes a mangler appropriate for debugging with GDB to be
+ installed on the console channel.</para></listitem></varlistentry>
+
+<varlistentry><term>None</term>
+
+ <listitem><para> This causes a NULL mangler to be installed on the console
+ channel. It will redirect the IO to/from the debug channel
+ without mangling of the data. This option differs from setting
+ the console channel to the same IO port as the debugging
+ channel in that it will keep redirecting data to the debugging
+ channel even if that is changed to some other port.</para></listitem></varlistentry>
+
+</variablelist>
+
+<para>Finally, by disabling <literal>CYGDBG_HAL_DIAG_TO_DEBUG_CHAN</literal>, the diagnostic
+output is directed in raw form to the specified console IO port.</para>
+
+<para>In summary this results in the following common configuration
+scenarios for RAM startup configurations:</para>
+
+<itemizedlist>
+<listitem><para> For regular debugging with diagnostic output appearing in the
+ debugger, mangling is enabled and stubs disabled.</para>
+
+ <para>Diagnostic output appears via the debugging channel as
+ initiated by the ROM monitor, allowing for correct behavior
+ whether the application was launched via serial or Ethernet, from
+ the RedBoot command line or from a debugger.</para>
+</listitem>
+
+<listitem><para> For debugging with raw diagnostic output, mangling is
+ disabled.</para>
+
+ <para> Debugging session continues as initiated by the ROM monitor,
+ whether the application was launched via serial or
+ Ethernet. Diagnostic output is directed at the IO port configured
+ in the application configuration.</para>
+
+ <note>
+ <title>Note:</title>
+ <para> There is one caveat to be aware of. If the
+ application uses proper devices (be it serial or Ethernet) on
+ the same ports as those used by the ROM monitor, the
+ connections initiated by the ROM monitor will be
+ terminated.</para>
+ </note>
+</listitem>
+
+</itemizedlist>
+
+<para>And for ROM startup configurations:</para>
+
+<itemizedlist>
+<listitem><para> Production configuration with raw output and no debugging
+ features (configured for RAM or ROM), mangling is disabled, no
+ stubs are included.</para>
+
+ <para>Diagnostic output appears (in unmangled form) on the specified
+ IO port.</para>
+</listitem>
+
+<listitem><para> RedBoot configuration, includes debugging features and necessary
+ mangling.</para>
+
+ <para>Diagnostic and debugging output port is auto-selected by the
+ first connection to any of the supported IO ports. Can change
+ from interactive mode to debugging mode when a debugger is
+ detected - when this happens a mangler will be installed as
+ required.</para>
+</listitem>
+
+<listitem><para> GDB stubs configuration (obsoleted by RedBoot configuration),
+ includes debugging features, mangling is hardwired to GDB
+ protocol.</para>
+
+ <para>Diagnostic and debugging output is hardwired to configured IO
+ ports, mangling is hardwired.</para>
+</listitem>
+
+</itemizedlist>
+</section>
+
+<!-- }}} -->
+<!-- {{{ Footnote: Design Reasoning -->
+
+<section>
+<title>Footnote: Design Reasoning for Control of Console Channel</title>
+
+<para>The current code for controlling the console channel is a
+replacement for an older implementation which had some shortcomings
+which addressed by the new implementation.</para>
+
+<para>This is what the old implementation did: on initialization it would
+check if the CDL configured console channel differed from the active
+debug channel - and if so, set the console channel, thereby disabling
+mangling.</para>
+
+<para>The idea was that whatever channel was configured to be used for
+console (i.e., diagnostic output) in the application was what should
+be used. Also, it meant that if debug and console channels were
+normally the same, a changed console channel would imply a request for
+unmangled output.</para>
+
+<para>But this prevented at least two things:</para>
+
+<itemizedlist>
+<listitem><para> It was impossible to inherit the existing connection by which
+ the application was launched (either by RedBoot commands via
+ telnet, or by via a debugger).</para>
+
+ <para>This was mostly a problem on targets supporting Ethernet
+ access since the diagnostic output would not be returned via the
+ Ethernet connection, but on the configured serial port.</para>
+
+ <para>The problem also occurred on any targets with multiple serial
+ ports where the ROM monitor was configured to use a different
+ port than the CDL defaults.</para>
+</listitem>
+
+<listitem><para> Proper control of when to mangle or just write out raw ASCII
+ text.</para>
+
+ <para>Sometimes it's desirable to disable mangling, even if the
+ channel specified is the same as that used for debugging. This
+ usually happens if GDB is used to download the application, but
+ direct interaction with the application on the same channel is
+ desired (GDB protocol only allows output from the target, no
+ input).</para>
+</listitem>
+</itemizedlist>
+
+</section>
+
+<!-- }}} -->
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ The Calling Interface API -->
+
+<section>
+<title>The calling Interface API</title>
+
+<para>The calling interface API is defined by hal_if.h and hal_if.c in
+hal/common.</para>
+
+<para>The API provides a set of services. Different platforms, or
+different versions of the ROM monitor for a single platform, may
+implement fewer or extra service. The table has room for growth, and
+any entries which are not supported map to a NOP-service (when called
+it returns 0 (<literal>false</literal>)).
+</para>
+
+<para>A client of a service should either be selected by configuration,
+or have suitable fall back alternatives in case the feature is not
+implemented by the ROM monitor.
+</para>
+
+<note>
+<title>Note:</title>
+<para>
+Checking for unimplemented service when this may be a data
+field/pointer instead of a function: suggest reserving the last entry
+in the table as the NOP-service pointer. Then clients can compare a
+service entry with this pointer to determine whether it's initialized
+or not.
+</para>
+</note>
+
+<para>The header file <filename>cyg/hal/hal_if.h</filename> defines
+ the table layout and accessor macros (allowing primitive type
+ checking and alternative implementations should it become necessary).
+</para>
+
+<para>The source file <filename>hal_if.c</filename> defines the table
+ initialization function. All HALs should call this during platform
+ initialization - the table will get initialized according to
+ configuration. Also defined here are wrapper functions which map
+ between the calling interface API and the API of the used eCos
+ functions.
+</para>
+
+<!-- {{{ Implemented Services -->
+
+<section>
+<title>Implemented Services</title>
+
+<para>This is a brief description of the services, some of which are
+described in further detail below.</para>
+
+<variablelist>
+<varlistentry><term><literal>VERSION</literal></term>
+ <listitem><para>Version of table. Serves as a way to check for how many
+ features are available in the table. This is the index of the
+ last service in the table.</para></listitem></varlistentry>
+<varlistentry><term><literal>KILL_VECTOR</literal></term>
+ <listitem><para>[Presently unused by the stub code, but initialized] This
+ vector defines a function to execute when the system receives
+ a kill signal from the debugger. It is initialized with the
+ reset function (see below), but the application (or eCos) can
+ override it if necessary.</para></listitem></varlistentry>
+<varlistentry><term><literal>CONSOLE_PROCS</literal></term>
+ <listitem><para>The communication procedure table used for console IO
+ (see <xref linkend="hal-porting-io-channels">.</para></listitem></varlistentry>
+<varlistentry><term><literal>DEBUG_PROCS</literal></term>
+ <listitem><para>The communication procedure table used for debugger IO
+ (see <xref linkend="hal-porting-io-channels">).</para></listitem></varlistentry>
+<varlistentry><term><literal>FLUSH_DCACHE</literal></term>
+ <listitem><para>Flushes the data cache for the specified
+ region. Some implementations may flush the entire data cache.</para></listitem></varlistentry>
+<varlistentry><term><literal>FLUSH_ICACHE</literal></term>
+ <listitem><para>Flushes (invalidates) the instruction cache
+ for the specified region. Some implementations may flush the
+ entire instruction cache.</para></listitem></varlistentry>
+<varlistentry><term><literal>SET_DEBUG_COMM</literal></term>
+ <listitem><para>Change debugging communication channel.</para></listitem></varlistentry>
+<varlistentry><term><literal>SET_CONSOLE_COMM</literal></term>
+ <listitem><para>Change console communication channel.</para></listitem></varlistentry>
+<varlistentry><term><literal>DBG_SYSCALL</literal></term>
+ <listitem><para>Vector used to communication between debugger functions in
+ ROM and in RAM. RAM eCos configurations may install a function
+ pointer here which the ROM monitor uses to get thread
+ information from the kernel running in RAM.</para></listitem></varlistentry>
+<varlistentry><term><literal>RESET</literal></term>
+ <listitem><para>Resets the board on call. If it is not possible to reset
+ the board from software, it will jump to the ROM entry point
+ which will perform a "software" reset of the board.</para></listitem></varlistentry>
+<varlistentry><term><literal>CONSOLE_INTERRUPT_FLAG</literal></term>
+ <listitem><para>Set if a debugger interrupt request was detected while
+ processing console IO. Allows the actual breakpoint action to
+ be handled after return to RAM, ensuring proper backtraces
+ etc.</para></listitem></varlistentry>
+<varlistentry><term><literal>DELAY_US</literal></term>
+ <listitem><para>Will delay the specified number of microseconds. The
+ precision is platform dependent to some extend - a small value
+ (<100us) is likely to cause bigger delays than requested.</para></listitem></varlistentry>
+<varlistentry><term><literal>FLASH_CFG_OP</literal></term>
+ <listitem><para>For accessing configuration settings kept in flash memory.</para></listitem></varlistentry>
+<varlistentry><term><literal>INSTALL_BPT_FN</literal></term>
+ <listitem><para>Installs a breakpoint at the specified address. This is
+ used by the asynchronous breakpoint support
+ (see <!-- <xref linkend="hal-stubs-async-bps"> -->).</para></listitem></varlistentry>
+</variablelist>
+</section>
+
+<!-- }}} -->
+<!-- {{{ Compatibility -->
+
+<section>
+<title>Compatibility</title>
+
+<para>When a platform is changed to support the calling interface,
+applications will use it if so configured. That means that if an
+application is run on a platform with an older ROM monitor, the
+service is almost guaranteed to fail.
+</para>
+
+<para>For this reason, applications should only use Console Comm for HAL
+diagnostics output if explicitly configured to do so
+(<literal>CYGSEM_HAL_VIRTUAL_VECTOR_DIAG</literal>).
+</para>
+
+<para>As for asynchronous GDB interrupts, the service will always be
+used. This is likely to cause a crash under older ROM monitors, but
+this crash may be caught by the debugger. The old workaround still
+applies: if you need asynchronous breakpoints or thread debugging
+under older ROM monitors, you may have to include the debugging
+support when configuring eCos.
+</para>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Implementation Details -->
+
+<section>
+<title>Implementation details</title>
+
+<para>During the startup of a ROM monitor, the calling table will be
+initialized. This also happens if eCos is configured <emphasis>not</emphasis> to rely on
+a ROM monitor.
+</para>
+
+<note>
+<title>Note:</title>
+<para> There is reserved space (256 bytes) for the vector
+table whether it gets used or not. This may be something that we want
+to change if we ever have to shave off every last byte for a given
+target.
+</para>
+</note>
+
+<para>If thread debugging features are enabled, the function for accessing
+the thread information gets registered in the table during startup of
+a RAM startup configuration.
+</para>
+
+<para>Further implementation details are described where the service itself
+is described.</para>
+
+<!--
+FIXME: Need to describe the CYGARC_HAL_SAVE_GP() and
+CYGARC_HAL_RESTORE_GP() macros.
+-->
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ New Platform Ports -->
+
+<section>
+<title>New Platform Ports</title>
+
+<para>The <function>hal_platform_init()</function> function must call
+<function>hal_if_init()</function>.
+</para>
+
+<para>The HAL serial driver must, when called via
+<function>cyg_hal_plf_comms_init()</function> must initialize the
+communication channels.
+</para>
+
+<para>The <function>reset()</function> function defined in
+<filename>hal_if.c</filename> will attempt to do a hardware reset, but
+if this fails it will fall back to simply jumping to the reset
+entry-point. On most platforms the startup initialization will go a
+long way to reset the target to a sane state (there will be
+exceptions, of course). For this reason, make sure to define
+<literal>HAL_STUB_PLATFORM_RESET_ENTRY</literal> in plf_stub.h.
+</para>
+
+<para>All debugging features must be in place in order for the debugging
+services to be functional. See general platform porting notes.
+</para>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ New Architecture Ports -->
+
+<section>
+<title>New architecture ports</title>
+
+<para>There are no specific requirements for a new architecture port in
+order to support the calling interface, but the basic debugging
+features must be in place. See general architecture porting notes.
+</para>
+</section>
+
+<!-- }}} -->
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ IO Channels -->
+
+<section id="hal-porting-io-channels">
+<title>IO channels</title>
+
+
+<para>The calling interface provides procedure tables for all IO channels on
+the platform. These are used for console (diagnostic) and debugger IO,
+allowing a ROM monitor to provided all the needed IO routines. At
+the same time, this makes it easy to switch console/debugger channels
+at run-time (the old implementation had hardwired drivers for console
+and debugger IO, preventing these to change at run-time).
+</para>
+
+<para>The hal_if provides wrappers which interface these services to the
+eCos infrastructure diagnostics routines. This is done in a way which
+ensures proper string mangling of the diagnostics output when required
+(e.g. O-packetization when using a GDB compatible ROM monitor).
+</para>
+
+<!-- {{{ Available Procedures -->
+
+<section>
+<title>Available Procedures</title>
+
+<para>This is a brief description of the procedures</para>
+
+<variablelist>
+<varlistentry><term><literal>CH_DATA</literal></term>
+<listitem><para>Pointer to the controller IO base (or a pointer to a per-device
+ structure if more data than the IO base is required). All the
+ procedures below are called with this data item as the first
+ argument.</para></listitem></varlistentry>
+
+<varlistentry><term><literal>WRITE</literal></term>
+ <listitem><para>Writes the buffer to the device.</para></listitem></varlistentry>
+<varlistentry><term><literal>READ</literal></term>
+ <listitem><para>Fills a buffer from the device.</para></listitem></varlistentry>
+<varlistentry><term><literal>PUTC</literal></term>
+ <listitem><para>Write a character to the device.</para></listitem></varlistentry>
+<varlistentry><term><literal>GETC</literal></term>
+ <listitem><para>Read a character from the device.</para></listitem></varlistentry>
+<varlistentry><term><literal>CONTROL</literal></term>
+ <listitem><para>Device feature control. Second argument specifies function:</para>
+ <variablelist>
+ <varlistentry><term><literal>SETBAUD</literal></term>
+ <listitem><para>Changes baud rate.</para></listitem></varlistentry>
+ <varlistentry><term><literal>GETBAUD</literal></term>
+ <listitem><para>Returns the current baud rate.</para></listitem></varlistentry>
+ <varlistentry><term><literal>INSTALL_DBG_ISR</literal></term>
+ <listitem><para>[Unused]</para></listitem></varlistentry>
+ <varlistentry><term><literal>REMOVE_DBG_ISR</literal></term>
+ <listitem><para>[Unused]</para></listitem></varlistentry>
+ <varlistentry><term><literal>IRQ_DISABLE</literal></term>
+ <listitem><para>Disable debugging receive interrupts on the device.</para></listitem></varlistentry>
+ <varlistentry><term><literal>IRQ_ENABLE</literal></term>
+ <listitem><para>Enable debugging receive interrupts on the device.</para></listitem></varlistentry>
+ <varlistentry><term><literal>DBG_ISR_VECTOR</literal></term>
+ <listitem><para>Returns the ISR vector used by the device for debugging
+ receive interrupts.</para></listitem></varlistentry>
+ <varlistentry><term><literal>SET_TIMEOUT</literal></term>
+ <listitem><para>Set GETC timeout in milliseconds.</para></listitem></varlistentry>
+ <varlistentry><term><literal>FLUSH_OUTPUT</literal></term>
+ <listitem><para>Forces driver to flush data in its buffers. Note
+ that this may not affect hardware buffers
+ (e.g. FIFOs).</para></listitem></varlistentry>
+ </variablelist>
+ </listitem></varlistentry>
+
+<varlistentry><term><literal>DBG_ISR</literal></term>
+ <listitem><para>ISR used to handle receive interrupts from the
+ device (see <!-- <xref linkend="hal-stubs-async-bps"> -->).</para></listitem></varlistentry>
+<varlistentry><term><literal>GETC_TIMEOUT</literal></term>
+ <listitem><para>Read a character from the device with timeout.</para></listitem></varlistentry>
+</variablelist>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Usage -->
+
+<section><title>Usage</title>
+
+<para>The standard eCos diagnostics IO functions use the channel
+procedure table when <literal>CYGSEM_HAL_VIRTUAL_VECTOR_DIAG</literal> is enabled. That
+means that when you use diag_printf (or the libc printf function) the
+stream goes through the selected console procedure table. If you use
+the virtual vector function SET_CONSOLE_COMM you can change the device
+which the diagnostics output goes to at run-time.</para>
+
+<para>You can also use the table functions directly if desired
+(regardless of the <literal>CYGSEM_HAL_VIRTUAL_VECTOR_DIAG</literal> setting - assuming
+the ROM monitor provides the services). Here is a small example which
+changes the console to use channel 2, fetches the comm procs pointer
+and calls the write function from that table, then restores the
+console to the original channel:</para>
+
+<programlisting>
+#define T "Hello World!\n"
+
+int
+main(void)
+{
+ hal_virtual_comm_table_t* comm;
+ int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(2);
+
+ comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+ CYGACC_COMM_IF_WRITE(*comm, T, strlen(T));
+
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+</programlisting>
+
+<para>Beware that if doing something like the above, you should only do
+it to a channel which does not have GDB at the other end: GDB ignores
+raw data, so you would not see the output.</para>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Compatibility -->
+
+<section>
+<title>Compatibility</title>
+
+<para>The use of this service is controlled by the option
+<literal>CYGSEM_HAL_VIRTUAL_VECTOR_DIAG</literal> which is disabled per default on most
+older platforms (thus preserving backwards compatibility with older
+stubs). On newer ports, this option should always be set.
+</para>
+</section>
+
+<!-- }}} -->
+<!-- {{{ Implementation Details -->
+
+<section><title>Implementation Details</title>
+
+<para>There is an array of procedure tables (raw comm channels) for each
+IO device of the platform which get initialized by the ROM monitor, or
+optionally by a RAM startup configuration (allowing the RAM
+configuration to take full control of the target). In addition to
+this, there's a special table which is used to hold mangler
+procedures.</para>
+
+<para>The vector table defines which of these channels are selected for
+console and debugging IO respectively: console entry can be empty,
+point to mangler channel, or point to a raw channel. The debugger
+entry should always point to a raw channel.</para>
+
+<para>During normal console output (i.e., diagnostic output) the console
+table will be used to handle IO if defined. If not defined, the debug
+table will be used.</para>
+
+<para>This means that debuggers (such as GDB) which require text streams
+to be mangled (O-packetized in the case of GDB), can rely on the ROM
+monitor install mangling IO routines in the special mangler table and
+select this for console output. The mangler will pass the mangled data
+on to the selected debugging channel.</para>
+
+<para>If the eCos configuration specifies a different console channel
+from that used by the debugger, the console entry will point to the
+selected raw channel, thus overriding any mangler provided by the ROM
+monitor.</para>
+
+<para>See hal_if_diag_* routines in hal_if.c for more details of the stream
+path of diagnostic output. See <function>cyg_hal_gdb_diag_*()</function> routines in
+<filename>hal_stub.c</filename> for the mangler used for GDB communication.</para>
+
+<!--
+FIXME: Other special channels are reserved for ethernet communication.
+-->
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ New Platform Ports -->
+
+<section>
+<title>New Platform Ports</title>
+
+<para>Define CDL options <literal>CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS</literal>,
+<literal>CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL</literal>, and
+<literal>CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL</literal>.
+</para>
+
+<para>If <literal>CYGSEM_HAL_VIRTUAL_VECTOR_DIAG</literal> is set, make sure the infra diag
+code uses the hal_if diag functions:</para>
+
+<programlisting>
+ #define HAL_DIAG_INIT() hal_if_diag_init()
+ #define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_)
+ #define HAL_DIAG_READ_CHAR(_c_) hal_if_diag_read_char(&_c_)
+</programlisting>
+
+<para>In addition to the above functions, the platform HAL must also
+provide a function cyg_hal_plf_comms_init which initializes the
+drivers and the channel procedure tables.
+</para>
+
+<para>Most of the other functionality in the table is more or less
+possible to copy unchanged from existing ports. Some care is necessary
+though to ensure the proper handling of interrupt vectors and timeouts
+for various devices handled by the same driver. See PowerPC/Cogent
+platform HAL for an example implementation.</para>
+
+<note>
+<title>Note:</title>
+<para> When vector table console code is <emphasis>not</emphasis> used,
+the platform HAL must map the HAL_DIAG_INIT, HAL_DIAG_WRITE_CHAR and
+HAL_DIAG_READ_CHAR macros directly to the low-level IO functions,
+hardwired to use a compile-time configured channel.</para>
+</note>
+
+<note>
+<title>Note:</title>
+<para> On old ports the hardwired <literal>HAL_DIAG_INIT</literal>,
+<literal>HAL_DIAG_WRITE_CHAR</literal> and
+<literal>HAL_DIAG_READ_CHAR</literal> implementations will also
+contain code to O-packetize the output for GDB. This should
+<emphasis>not</emphasis> be adopted for new ports! On new ports the
+ROM monitor is guaranteed to provide the necessary mangling via the
+vector table. The hardwired configuration should be reserved for ROM
+startups where achieving minimal image size is crucial.
+</para>
+</note>
+
+</section>
+
+<!-- }}} -->
+
+</section>
+
+<!-- }}} -->
+
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Coding Conventions -->
+
+<section id="hal-porting-coding-conventions">
+<TITLE>HAL Coding Conventions</TITLE>
+
+
+<para>
+To get changes and larger submissions included into the eCos source
+repository, we ask that you adhere to a set of coding conventions.
+The conventions are defined as an attempt to make a consistent
+tree. Consistency makes it easier for people to read, understand and
+maintain the code, which is important when many people work on the
+same project.
+</para>
+
+<para>
+The below is only a brief, and probably incomplete, summary of the
+rules. Please look through files in the area where you are making
+changes to get a feel for any additional conventions. Also feel free
+to ask on the list if you have specific questions.
+</para>
+
+
+<section>
+<title>Implementation issues</title>
+
+<para>
+There are a few implementation issues that should be kept in mind:
+</para>
+
+<variablelist>
+<varlistentry><term>HALs</term>
+ <listitem><para>HALs must be written in C and assembly only. C++ must not
+ be used. This is in part to keep the HALs simple since this is
+ usually the first part of eCos a newcomer will see, and in
+ part to maintain the existing de facto standard.</para></listitem></varlistentry>
+
+<varlistentry><term>IO access</term>
+ <listitem><para>Use HAL IO access macros for code that might be reused on
+ different platforms than the one you are writing it for.</para></listitem></varlistentry>
+
+<varlistentry><term>MMU</term>
+ <listitem><para>If it is necessary to use the MMU (e.g., to prevent
+ caching of IO areas), use a simple 1-1 mapping of memory if
+ possible. On most platforms where using the MMU is necessary,
+ it will be possible to achieve the 1-1 mapping using the MMU's
+ provision for mapping large continuous areas (hardwired TLBs or
+ BATs). This reduces the footprint (no MMU table) and avoids
+ execution overhead (no MMU-related exceptions).</para></listitem></varlistentry>
+
+<varlistentry><term>Assertions</term>
+ <listitem><para>The code should contain assertions to validate argument
+ values, state information and any assumptions the code may be
+ making. Assertions are not enabled in production builds, so
+ liberally sprinkling assertions throughout the code is
+ good.</para></listitem></varlistentry>
+
+<varlistentry><term>Testing</term>
+ <listitem><para>The ability to test your code is very important. In
+ general, do not add new code to the eCos runtime unless you
+ also add a new test to exercise that code. The test also
+ serves as an example of how to use the new code.</para></listitem></varlistentry>
+
+</variablelist>
+
+</section>
+
+<section>
+<title>Source code details</title>
+
+<variablelist>
+<varlistentry><term>Line length</term>
+ <listitem><para>Keep line length below 78 columns whenever possible.</para></listitem></varlistentry>
+
+<varlistentry><term>Comments</term>
+ <listitem><para>Whenever possible, use // comments instead of /**/.</para></listitem></varlistentry>
+
+<varlistentry><term>Indentation</term>
+ <listitem><para>Use spaces instead of TABs. Indentation level is 4. Braces
+ start on the same line as the expression. See below for emacs
+ mode details.</para>
+
+<programlisting>
+;;=================================================================
+;; eCos C/C++ mode Setup.
+;;
+;; bsd mode: indent = 4
+;; tail comments are at col 40.
+;; uses spaces not tabs in C
+
+(defun ecos-c-mode ()
+ "C mode with adjusted defaults for use with the eCos sources."
+ (interactive)
+ (c++-mode)
+ (c-set-style "bsd")
+ (setq comment-column 40)
+ (setq indent-tabs-mode nil)
+ (show-paren-mode 1)
+ (setq c-basic-offset 4)
+
+ (set-variable 'add-log-full-name "Your Name")
+ (set-variable 'add-log-mailing-address "Your email address"))
+
+(defun ecos-asm-mode ()
+ "ASM mode with adjusted defaults for use with the eCos sources."
+ (interactive)
+ (setq comment-column 40)
+ (setq indent-tabs-mode nil)
+ (asm-mode)
+ (setq c-basic-offset 4)
+
+ (set-variable 'add-log-full-name "Your Name")
+ (set-variable 'add-log-mailing-address "Your email address"))
+
+(setq auto-mode-alist
+ (append '(("/local/ecc/.*\\.C$" . ecos-c-mode)
+ ("/local/ecc/.*\\.cc$" . ecos-c-mode)
+ ("/local/ecc/.*\\.cpp$" . ecos-c-mode)
+ ("/local/ecc/.*\\.inl$" . ecos-c-mode)
+ ("/local/ecc/.*\\.c$" . ecos-c-mode)
+ ("/local/ecc/.*\\.h$" . ecos-c-mode)
+ ("/local/ecc/.*\\.S$" . ecos-asm-mode)
+ ("/local/ecc/.*\\.inc$" . ecos-asm-mode)
+ ("/local/ecc/.*\\.cdl$" . tcl-mode)
+ ) auto-mode-alist))
+</programlisting>
+</listitem>
+</varlistentry>
+</variablelist>
+</section>
+
+<section>
+
+<title>Nested Headers</title>
+
+<para>In order to allow platforms to define all necessary details, while
+still maintaining the ability to share code between common platforms,
+all HAL headers are included in a nested fashion.</para>
+
+<para>The architecture header (usually <filename>hal_XXX.h</filename>) includes the
+variant equivalent of the header (<filename>var_XXX.h</filename>) which in turn
+includes the platform equivalent of the header
+(<filename>plf_XXX.h</filename>).</para>
+
+<para>All definitions that may need to be overridden by a platform are
+then only conditionally defined, depending on whether a lower layer
+has already made the definition:</para>
+
+<programlisting>
+hal_intr.h: #include &lt;var_intr.h&gt;
+
+ #ifndef MACRO_DEFINED
+ # define MACRO ...
+ # define MACRO_DEFINED
+ #endif
+
+
+
+var_intr.h: #include &lt;plf_intr.h&gt;
+
+ #ifndef MACRO_DEFINED
+ # define MACRO ...
+ # define MACRO_DEFINED
+ #endif
+
+
+plf_intr.h:
+
+ # define MACRO ...
+ # define MACRO_DEFINED
+</programlisting>
+
+<para>This means a platform can opt to rely on the variant or
+architecture implementation of a feature, or implement it itself.</para>
+
+</section>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Platform HAL Porting -->
+
+<section id="hal-porting-platform">
+<title>Platform HAL Porting</title>
+
+<para>
+This is the type of port that takes the least effort. It basically
+consists of describing the platform (board) for the HAL: memory
+layout, early platform initialization, interrupt controllers, and a
+simple serial device driver.
+</para>
+
+<para>
+Doing a platform port requires a preexisting architecture and
+possibly a variant HAL port.
+</para>
+
+<!-- {{{ Porting Process -->
+
+<section>
+<TITLE>HAL Platform Porting Process</TITLE>
+
+<!-- {{{ Brief Overview -->
+
+<section>
+<title>Brief overview</title>
+
+<para>The easiest way to make a new platform HAL is simply to copy an
+existing platform HAL of the same architecture/variant and change all
+the files to match the new one. In case this is the first platform for
+the architecture/variant, a platform HAL from another architecture
+should be used as a template.
+</para>
+
+<para>
+The best way to start a platform port is to concentrate on getting
+RedBoot to run. RedBoot is a simpler environment than full eCos, it
+does not use interrupts or threads, but covers most of the
+basic startup requirements.
+</para>
+
+<para>
+RedBoot normally runs out of FLASH or ROM and provides program loading
+and debugging facilities. This allows further HAL development to
+happen using RAM startup configurations, which is desirable for the
+simple reason that downloading an image which you need to test is
+often many times faster than either updating a flash part, or indeed,
+erasing and reprogramming an EPROM.
+</para>
+
+<para>There are two approaches to getting to this first goal:
+</para>
+
+<orderedlist>
+<listitem>
+<para>
+The board is equipped with a ROM monitor which allows "load and go" of
+ELF, binary, S-record or some other image type which can be created
+using <application>objcopy</application>. This allows you to develop
+RedBoot by downloading and running the code (saving time).
+</para>
+
+<para>
+When the stub is running it is a good idea to examine the various
+hardware registers to help you write the platform initialization code.
+</para>
+
+<para>
+Then you may have to fiddle a bit going through step two (getting it
+to run from ROM startup). If at all possible, preserve the original
+ROM monitor so you can revert to it if necessary.
+</para>
+</listitem>
+
+<listitem>
+<para>
+The board has no ROM monitor. You need to get the platform
+initialization and stub working by repeatedly making changes, updating
+flash or EPROM and testing the changes. If you are lucky, you have a
+JTAG or similar CPU debugger to help you. If not, you will probably
+learn to appreciate LEDs. This approach may also be needed during the
+initial phase of moving RedBoot from RAM startup to ROM, since it is
+very unlikely to work first time.
+</para>
+</listitem>
+</orderedlist>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Step-by-step -->
+
+<section>
+<title>Step-by-step</title>
+
+<para>Given that no two platforms are exactly the same, you may have to
+deviate from the below. Also, you should expect a fair amount of
+fiddling - things almost never go right the first time. See the hints
+section below for some suggestions that might help debugging.
+</para>
+
+<para>The description below is based on the HAL layout used in the MIPS,
+PC and MN10300 HALs. Eventually all HALs should be converted to look like
+these - but in a transition period there will be other HALs which look
+substantially different. Please try to adhere to the following as much is
+possible without causing yourself too much grief integrating with a
+HAL which does not follow this layout.
+</para>
+
+<!-- ====================================================================== -->
+
+<section>
+<title>Minimal requirements</title>
+
+<para>
+These are the changes you must make before you attempt to build
+RedBoot. You are advised to read all the sources though.
+</para>
+
+<orderedlist>
+<listitem><para>Copy an existing platform HAL from the same or another
+ architecture. Rename the files as necessary to follow the
+ standard: CDL and memory layout related files should contain the
+ &lt;arch&gt;_&lt;variant&gt;_&lt;platform&gt; triplet.</para>
+</listitem>
+
+<listitem><para>Adjust CDL options. Primarily option naming, real-time
+ clock/counter, and CYGHWR_MEMORY_LAYOUT variables, but also other
+ options may need editing. Look through the architecture/variant
+ CDL files to see if there are any requirements/features which
+ where not used on the platform you copied. If so, add appropriate
+ ones. See <xref linkend="hal-porting-cdl-requirements"> for more
+ details.</para>
+</listitem>
+
+<listitem><para>Add the necessary packages and target descriptions to the
+ top-level <filename>ecos.db</filename> file. See <xref
+ linkend="hal-porting-ecos-database">. Initially, the target entry
+ should only contain the HAL packages. Other hardware support
+ packages will be added later.</para>
+</listitem>
+
+<listitem><para>Adjust the memory layout files in
+ <filename>include/pkgconf</filename> to match the memory layout on
+ the platform. <!-- For initial testing it should be enough to just hand
+ edit .h and .ldi files, but eventually you should generate all
+ files using the memory layout editor in the configuration
+ tool. --> See <xref linkend="hal-porting-platform-memory-layout"> for
+ more details.</para>
+</listitem>
+
+<listitem>
+ <para>
+ Edit the <filename>misc/redboot_&lt;STARTUP&gt;.ecm</filename> for
+ the startup type you have chosen to begin with. Rename any
+ platform specific options and remove any that do not apply. In the
+ <literal>cdl_configuration</literal> section, comment out any
+ extra packages that are added, particularly packages such as
+ <literal>CYGPKG_IO_FLASH</literal> and
+ <literal>CYGPKG_IO_ETH_DRIVERS</literal>. These are not needed for
+ initial porting and will be added back later.
+ </para>
+</listitem>
+
+<listitem><para>If the default IO macros are not correct, override them in
+ plf_io.h. This may be necessary if the platform uses a different
+ endianness from the default for the CPU.</para>
+</listitem>
+
+<listitem><para>Leave out/comment out code that enables caches and/or MMU if
+ possible. Execution speed will not be a concern until the port is
+ feature complete.</para>
+</listitem>
+
+<listitem><para>Implement a simple serial driver (polled mode only). Make sure the
+ initialization function properly hooks the procedures up in the
+ virtual vector IO channel tables. RedBoot will call the serial
+ driver via these tables.</para>
+ <para>
+ By copying an existing platform HAL most of this code will be
+ already done, and will only need the platform specific hardware
+ access code to be written.
+ </para>
+</listitem>
+
+<listitem><para>Adjust/implement necessary platform
+ initialization. This can be found in
+ <filename>platform.inc</filename> and
+ <filename>platform.S</filename> files (ARM:
+ <filename>hal_platform_setup.h</filename> and
+ <filename>&lt;platform&gt;_misc.c</filename>, PowerPC:
+ <filename>&lt;platform&gt;.S</filename>). This step can be
+ postponed if you are doing a RAM startup RedBoot first and the
+ existing ROM monitor handles board initialization.</para>
+</listitem>
+
+<listitem><para>Define <literal>HAL_STUB_PLATFORM_RESET</literal>
+ (optionally empty) and
+ <literal>HAL_STUB_PLATFORM_RESET_ENTRY</literal> so that RedBoot
+ can reset-on-detach - this is very handy, often removing the need
+ for physically resetting the board between downloads.</para>
+</listitem>
+
+</orderedlist>
+
+<para>You should now be able to build RedBoot. For ROM startup:
+</para>
+
+<programlisting width=72>
+% ecosconfig new &lt;target_name&gt; redboot
+% ecosconfig import $(ECOS_REPOSITORY)/hal/&lt;architecture&gt;/&lt;platform&gt;/&lt;version&gt;/misc/redboot_ROM.ecm
+% ecosconfig tree
+% make
+</programlisting>
+
+<para>You may have to make further changes than suggested above to get
+the make command to succeed. But when it does, you should find a
+RedBoot image in install/bin. To program this image into flash or
+EPROM, you may need to convert to some other file type, and possibly
+adjust the start address. When you have the correct
+<application>objcopy</application> command to do this, add it to the
+<literal>CYGBLD_BUILD_GDB_STUBS</literal> custom build rule in the
+platform CDL file.
+</para>
+
+<para>Having updated the flash/EPROM on the board, you should see output
+on the serial port looking like this when powering on the board:
+</para>
+
+<programlisting>
+RedBoot(tm) bootstrap and debug environment [ROMRAM]
+Non-certified release, version UNKNOWN - built 15:42:24, Mar 14 2002
+
+Platform: &lt;PLATFORM&gt; (&lt;ARCHITECTURE&gt; &lt;VARIANT&gt;)
+Copyright (C) 2000, 2001, 2002, Free Software Foundation, Inc.
+
+RAM: 0x00000000-0x01000000, 0x000293e8-0x00ed1000 available
+FLASH: 0x24000000 - 0x26000000, 256 blocks of 0x00020000 bytes each.
+RedBoot>
+</programlisting>
+
+<para>If you do not see this output, you need to go through all your
+changes and figure out what's wrong. If there's a user programmable
+LED or LCD on the board it may help you figure out how far RedBoot
+gets before it hangs. Unfortunately there's no good way to describe
+what to do in this situation - other than that you have to play with
+the code and the board.
+</para>
+
+</section>
+
+<!-- ====================================================================== -->
+
+<section>
+<title>Adding features</title>
+
+<para>Now you should have a basic RedBoot running on the board. This
+means you have a the correct board initialization and a working serial
+driver. It's time to flesh out the remaining HAL features.
+</para>
+
+<orderedlist>
+<listitem><para>Reset. As mentioned above it is desirable to get the board to
+reset when GDB disconnects. When GDB disconnects it sends RedBoot
+a kill-packet, and RedBoot first calls <literal>HAL_STUB_PLATFORM_RESET()</literal>,
+attempting to perform a software-invoked reset. Most embedded
+CPUs/boards have a watchdog which is capable of triggering a reset.
+If your target does not have a watchdog, leave
+<literal>HAL_STUB_PLATFORM_RESET()</literal> empty and rely on the fallback approach.
+</para>
+
+<para>If <literal>HAL_STUB_PLATFORM_RESET()</literal> did not cause a reset, RedBoot will
+jump to <literal>HAL_STUB_PLATFORM_RESET_ENTRY</literal> - this should be the address
+where the CPU will start execution after a reset. Re-initializing the
+board and drivers will <emphasis>usually</emphasis> be good enough to make a
+hardware reset unnecessary.
+</para>
+
+<para>After the reset caused by the kill-packet, the target will be ready
+for GDB to connect again. During a days work, this will save you from
+pressing the reset button many times.
+</para>
+
+<para>Note that it is possible to disconnect from the board without
+causing it to reset by using the GDB command &quot;detach&quot;.</para>
+</listitem>
+
+<listitem>
+<para>Single-stepping is necessary for both instruction-level debugging
+and for breakpoint support. Single-stepping support should already be
+in place as part of the architecture/variant HAL, but you want to give
+it a quick test since you will come to rely on it.</para>
+</listitem>
+
+<listitem>
+<para>Real-time clock interrupts drive the eCos scheduler clock. Many
+embedded CPUs have an on-core timer (e.g. SH) or decrementer
+(e.g. MIPS, PPC) that can be used, and in this case it will already be
+supported by the architecture/variant HAL. You only have to calculate
+and enter the proper <literal>CYGNUM_HAL_RTC_CONSTANTS</literal>
+definitions in the platform CDL file.
+</para>
+
+<para>On some targets it may be necessary to use a platform-specific
+timer source for driving the real-time clock. In this case you also
+have to enter the proper CDL definitions, but must also define
+suitable versions of the <literal>HAL_CLOCK_XXXX</literal> macros.</para>
+</listitem>
+
+<listitem>
+<para>Interrupt decoding usually differs between platforms because the
+number and type of devices on the board differ. In
+<filename>plf_intr.h</filename> (ARM:
+<filename>hal_platform_ints.h</filename>) you must either extend or
+replace the default vector definitions provided by the architecture
+or variant interrupt headers. You may also have to define
+<literal>HAL_INTERRUPT_XXXX</literal> control macros.</para>
+</listitem>
+
+<listitem>
+<para>Caching may also differ from architecture/variant definitions.
+This maybe just the cache sizes, but there can also be bigger
+differences for example if the platform supports 2nd level caches.
+</para>
+
+<para>When cache definitions are in place, enable the caches on
+startup. First verify that the system is stable for RAM startups, then
+build a new RedBoot and install it. This will test if caching, and in
+particular the cache sync/flush operations, also work for ROM startup.</para>
+</listitem>
+
+<listitem>
+<para>Asynchronous breakpoints allow you to stop application execution
+and enter the debugger. Asynchronous breakpoint details are described
+in <!-- <xref linkend="hal-stubs-async-bps"> -->.</para>
+</listitem>
+
+</orderedlist>
+
+<para>You should now have a completed platform HAL port. Verify its
+stability and completeness by running all the eCos tests and fix any
+problems that show up (you have a working RedBoot now, remember! That
+means you can debug the code to see why it fails).
+</para>
+
+<para>Given the many configuration options in eCos, there may be hidden
+bugs or missing features that do not show up even if you run all the
+tests successfully with a default configuration. A comprehensive test
+of the entire system will take many configuration permutations and
+many many thousands of tests executed.
+</para>
+
+</section>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Hints -->
+
+<section>
+<title>Hints</title>
+
+<itemizedlist>
+
+<listitem>
+ <para>JTAG or similar CPU debugging hardware can greatly reduce the time
+ it takes to write a HAL port since you always have full visibility
+ of what the CPU is doing.
+ </para>
+</listitem>
+
+<listitem>
+ <para>LEDs can be your friends if you don't have a JTAG
+ device. Especially in the start of the porting effort if you don't
+ already have a working ROM monitor on the target. Then you have to
+ get a basic RedBoot working while basically being blindfolded. The
+ LED can make it little easier, as you'll be able to do limited
+ tracking of program flow and behavior by switching the LED on and
+ off. If the board has multiple LEDs you can show a number (using
+ binary notation with the LEDs) and sprinkle code which sets
+ different numbers throughout the code.</para>
+</listitem>
+
+<listitem>
+ <para>Debugging the interrupt processing is possible if you are
+ careful with the way you program the very early interrupt entry
+ handling. Write it so that as soon as possible in the interrupt
+ path, taking a trap (exception) does not harm execution. See the
+ SH vectors.S code for an example. Look for
+ <literal>cyg_hal_default_interrupt_vsr</literal> and the label
+ <literal>cyg_hal_default_interrupt_vsr_bp_safe</literal>, which
+ marks the point after which traps/single-stepping is safe.
+ </para>
+
+ <para>Being able to display memory content, CPU registers,
+ interrupt controller details at the time of an interrupt can save
+ a lot of time.</para>
+</listitem>
+
+<listitem>
+ <para>Using assertions is a good idea. They can sometimes reveal subtle
+ bugs or missing features long before you would otherwise have
+ found them, let alone notice them.
+ </para>
+
+ <para>The default eCos configuration does not use assertions, so you
+ have to enable them by switching on the option <literal>CYGPKG_INFRA_DEBUG</literal>
+ in the infra package.</para>
+</listitem>
+
+<listitem>
+ <para>The idle loop can be used to help debug the system.
+ </para>
+
+ <para>Triggering clock from the idle loop is a neat trick for
+ examining system behavior either before interrupts are fully
+ working, or to speed up &quot;the clock&quot;.
+ </para>
+
+ <para>Use the idle loop to monitor and/or print out variables or
+ hardware registers.</para>
+</listitem>
+
+<listitem>
+<para><application>hal_mk_defs</application> is used in some of the
+HALs (ARM, SH) as a way to generate assembler symbol definitions from
+C header files without imposing an assembler/C syntax separation in
+the C header files.</para>
+</listitem>
+
+<!--
+<listitem><para>Tracing using buffers [FIXME:TBD]</para>
+</listitem>
+-->
+
+</itemizedlist>
+
+</section>
+
+<!-- }}} -->
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ CDL Requirements -->
+
+<section id="hal-porting-cdl-requirements">
+<TITLE>HAL Platform CDL</TITLE>
+
+<para>The platform CDL both contains details necessary for the building
+of eCos, and platform-specific configuration options. For this reason
+the options differ between platforms, and the below is just a brief
+description of the most common options.</para>
+
+<para> See <!-- <xref linkend="???"> --> Components Writers Guide
+for more details on CDL. Also have a quick look around in
+existing platform CDL files to get an idea of what is possible and how
+various configuration issues can be represented with CDL.</para>
+
+<!-- {{{ eCos Database -->
+
+<section id="hal-porting-ecos-database">
+<title>eCos Database</title>
+
+<para>
+The eCos configuration system is made aware of a package by
+adding a package description in <filename>ecos.db</filename>. As an
+example we use the <literal>TX39/JMR3904</literal> platform:
+</para>
+
+<programlisting>
+package CYGPKG_HAL_MIPS_TX39_JMR3904 {
+ alias { "Toshiba JMR-TX3904 board" hal_tx39_jmr3904 tx39_jmr3904_hal }
+ directory hal/mips/jmr3904
+ script hal_mips_tx39_jmr3904.cdl
+ hardware
+ description "
+ The JMR3904 HAL package should be used when targeting the
+ actual hardware. The same package can also be used when
+ running on the full simulator, since this provides an
+ accurate simulation of the hardware including I/O devices.
+ To use the simulator in this mode the command
+ `target sim --board=jmr3904' should be used from inside gdb."
+}
+</programlisting>
+
+<para>This contains the title and description presented in the
+Configuration Tool when the package is selected. It also specifies
+where in the tree the package files can be found (<literal>directory</literal>)
+and the name of the CDL file which contains the package details
+(<literal>script</literal>).
+</para>
+
+<para>
+To be able to build and test a configuration for the new target, there
+also needs to be a <literal>target</literal> entry in the
+<filename>ecos.db</filename> file.
+</para>
+
+<programlisting>
+target jmr3904 {
+ alias { "Toshiba JMR-TX3904 board" jmr tx39 }
+ packages { CYGPKG_HAL_MIPS
+ CYGPKG_HAL_MIPS_TX39
+ CYGPKG_HAL_MIPS_TX39_JMR3904
+ }
+ description "
+ The jmr3904 target provides the packages needed to run
+ eCos on a Toshiba JMR-TX3904 board. This target can also
+ be used when running in the full simulator, since the simulator provides an
+ accurate simulation of the hardware including I/O devices.
+ To use the simulator in this mode the command
+ `target sim --board=jmr3904' should be used from inside gdb."
+}
+</programlisting>
+
+
+<para>
+The important part here is the <literal>packages</literal> section
+which defines the various hardware specific packages that contribute
+to support for this target. In this case the MIPS architecture
+package, the TX39 variant package, and the JMR-TX3904 platform
+packages are selected. Other packages, for serial drivers, ethernet
+drivers and FLASH memory drivers may also appear here.
+</para>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ CDL File Layout -->
+
+<section>
+<title>CDL File Layout</title>
+
+<para>
+All the platform options are contained in a CDL package named
+<literal>CYGPKG_HAL_&lt;architecture&gt;_&lt;variant&gt;_&lt;platform&gt;</literal>.
+They all share more or less the same <literal>cdl_package</literal>
+details:
+</para>
+
+<programlisting>
+cdl_package CYGPKG_HAL_MIPS_TX39_JMR3904 {
+ display "JMR3904 evaluation board"
+ parent CYGPKG_HAL_MIPS
+ requires CYGPKG_HAL_MIPS_TX39
+ define_header hal_mips_tx39_jmr3904.h
+ include_dir cyg/hal
+ description "
+ The JMR3904 HAL package should be used when targeting the
+ actual hardware. The same package can also be used when
+ running on the full simulator, since this provides an
+ accurate simulation of the hardware including I/O devices.
+ To use the simulator in this mode the command
+ `target sim --board=jmr3904' should be used from inside gdb."
+
+ compile platform.S plf_misc.c plf_stub.c
+
+ define_proc {
+ puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H &lt;pkgconf/hal_mips_tx39.h&gt;"
+ puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H &lt;pkgconf/hal_mips_tx39_jmr3904.h&gt;"
+ }
+
+ ...
+}
+</programlisting>
+
+<para>This specifies that the platform package should be parented under
+the MIPS packages, requires the TX39 variant HAL and all configuration
+settings should be saved in
+<filename>cyg/hal/hal_mips_tx39_jmt3904.h</filename>.
+</para>
+
+<para>The <literal>compile</literal> line specifies which files should be built
+when this package is enabled, and the <literal>define_proc</literal> defines
+some macros that are used to access the variant or architecture (the
+<literal>_TARGET_</literal> name is a bit of a misnomer) and platform
+configuration options. </para>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Startup Type -->
+
+<section>
+<title>Startup Type</title>
+
+<para>eCos uses an option to select between a set of valid startup
+configurations. These are normally RAM, ROM and possibly ROMRAM. This
+setting is used to select which linker map to use (i.e., where to link
+eCos and the application in the memory space), and how the startup
+code should behave.</para>
+
+<programlisting>
+cdl_component CYG_HAL_STARTUP {
+ display "Startup type"
+ flavor data
+ legal_values {"RAM" "ROM"}
+ default_value {"RAM"}
+ no_define
+ define -file system.h CYG_HAL_STARTUP
+ description "
+ When targeting the JMR3904 board it is possible to build
+ the system for either RAM bootstrap, ROM bootstrap, or STUB
+ bootstrap. RAM bootstrap generally requires that the board
+ is equipped with ROMs containing a suitable ROM monitor or
+ equivalent software that allows GDB to download the eCos
+ application on to the board. The ROM bootstrap typically
+ requires that the eCos application be blown into EPROMs or
+ equivalent technology."
+}
+</programlisting>
+
+<para>The <literal>no_define</literal> and <literal>define</literal>
+pair is used to make the setting of this option appear in the file
+<filename>system.h</filename> instead of the default specified in the
+header.</para>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Build Options -->
+
+<section>
+<title>Build options</title>
+
+<para>
+A set of options under the components
+<literal>CYGBLD_GLOBAL_OPTIONS</literal> and
+<literal>CYGHWR_MEMORY_LAYOUT</literal> specify how eCos should be
+built: what tools and compiler options should be used, and which
+linker fragments should be used.
+</para>
+
+<programlisting>
+
+cdl_component CYGBLD_GLOBAL_OPTIONS {
+ display "Global build options"
+ flavor none
+ parent CYGPKG_NONE
+ description "
+ Global build options including control over
+ compiler flags, linker flags and choice of toolchain."
+
+
+ cdl_option CYGBLD_GLOBAL_COMMAND_PREFIX {
+ display "Global command prefix"
+ flavor data
+ no_define
+ default_value { "mips-tx39-elf" }
+ description "
+ This option specifies the command prefix used when
+ invoking the build tools."
+ }
+
+ cdl_option CYGBLD_GLOBAL_CFLAGS {
+ display "Global compiler flags"
+ flavor data
+ no_define
+ default_value { "-Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" }
+ description "
+ This option controls the global compiler flags which
+ are used to compile all packages by
+ default. Individual packages may define
+ options which override these global flags."
+ }
+
+ cdl_option CYGBLD_GLOBAL_LDFLAGS {
+ display "Global linker flags"
+ flavor data
+ no_define
+ default_value { "-g -nostdlib -Wl,--gc-sections -Wl,-static" }
+ description "
+ This option controls the global linker flags. Individual
+ packages may define options which override these global flags."
+ }
+}
+
+cdl_component CYGHWR_MEMORY_LAYOUT {
+ display "Memory layout"
+ flavor data
+ no_define
+ calculated { CYG_HAL_STARTUP == "RAM" ? "mips_tx39_jmr3904_ram" : \
+ "mips_tx39_jmr3904_rom" }
+
+ cdl_option CYGHWR_MEMORY_LAYOUT_LDI {
+ display "Memory layout linker script fragment"
+ flavor data
+ no_define
+ define -file system.h CYGHWR_MEMORY_LAYOUT_LDI
+ calculated { CYG_HAL_STARTUP == "RAM" ? "&lt;pkgconf/mlt_mips_tx39_jmr3904_ram.ldi&gt;" : \
+ "&lt;pkgconf/mlt_mips_tx39_jmr3904_rom.ldi&gt;" }
+ }
+
+ cdl_option CYGHWR_MEMORY_LAYOUT_H {
+ display "Memory layout header file"
+ flavor data
+ no_define
+ define -file system.h CYGHWR_MEMORY_LAYOUT_H
+ calculated { CYG_HAL_STARTUP == "RAM" ? "&lt;pkgconf/mlt_mips_tx39_jmr3904_ram.h&gt;" : \
+ "&lt;pkgconf/mlt_mips_tx39_jmr3904_rom.h&gt;" }
+ }
+}
+
+</programlisting>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Common Target Options -->
+
+<section>
+<title>Common Target Options</title>
+
+<para>All platforms also specify real-time clock details:</para>
+
+<programlisting>
+# Real-time clock/counter specifics
+cdl_component CYGNUM_HAL_RTC_CONSTANTS {
+ display "Real-time clock constants."
+ flavor none
+
+ cdl_option CYGNUM_HAL_RTC_NUMERATOR {
+ display "Real-time clock numerator"
+ flavor data
+ calculated 1000000000
+ }
+ cdl_option CYGNUM_HAL_RTC_DENOMINATOR {
+ display "Real-time clock denominator"
+ flavor data
+ calculated 100
+ }
+ # Isn't a nice way to handle freq requirement!
+ cdl_option CYGNUM_HAL_RTC_PERIOD {
+ display "Real-time clock period"
+ flavor data
+ legal_values { 15360 20736 }
+ calculated { CYGHWR_HAL_MIPS_CPU_FREQ == 50 ? 15360 : \
+ CYGHWR_HAL_MIPS_CPU_FREQ == 66 ? 20736 : 0 }
+ }
+}
+</programlisting>
+
+<para> The <literal>NUMERATOR</literal> divided by the
+<literal>DENOMINATOR</literal> gives the number of nanoseconds per
+tick. The <literal>PERIOD</literal> is the divider to be programmed
+into a hardware timer that is driven from an appropriate hardware
+clock, such that the timer overflows once per tick (normally
+generating a CPU interrupt to mark the end of a tick). The tick
+default rate is typically 100Hz.</para>
+
+
+<para>Platforms that make use of the virtual vector
+ROM calling interface (see <xref linkend="hal-calling-if">) will also
+specify details necessary to define configuration channels (these
+options are from the SH/EDK7707 HAL) :</para>
+
+<programlisting>
+cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS {
+ display "Number of communication channels on the board"
+ flavor data
+ calculated 1
+}
+
+cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL {
+ display "Debug serial port"
+ flavor data
+ legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+ default_value 0
+ description "
+ The EDK/7708 board has only one serial port. This option
+ chooses which port will be used to connect to a host
+ running GDB."
+}
+
+cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL {
+ display "Diagnostic serial port"
+ flavor data
+ legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1
+ default_value 0
+ description "
+ The EDK/7708 board has only one serial port. This option
+ chooses which port will be used for diagnostic output."
+}
+</programlisting>
+
+<para>The platform usually also specify an option controlling the ability
+ to co-exist with a ROM monitor:</para>
+
+<programlisting>
+cdl_option CYGSEM_HAL_USE_ROM_MONITOR {
+ display "Work with a ROM monitor"
+ flavor booldata
+ legal_values { "Generic" "CygMon" "GDB_stubs" }
+ default_value { CYG_HAL_STARTUP == "RAM" ? "CygMon" : 0 }
+ parent CYGPKG_HAL_ROM_MONITOR
+ requires { CYG_HAL_STARTUP == "RAM" }
+ description "
+ Support can be enabled for three different varieties of ROM monitor.
+ This support changes various eCos semantics such as the encoding
+ of diagnostic output, or the overriding of hardware interrupt
+ vectors.
+ Firstly there is \"Generic\" support which prevents the HAL
+ from overriding the hardware vectors that it does not use, to
+ instead allow an installed ROM monitor to handle them. This is
+ the most basic support which is likely to be common to most
+ implementations of ROM monitor.
+ \"CygMon\" provides support for the Cygnus ROM Monitor.
+ And finally, \"GDB_stubs\" provides support when GDB stubs are
+ included in the ROM monitor or boot ROM."
+}
+</programlisting>
+
+<para>Or the ability to be configured as a ROM monitor:</para>
+
+<programlisting>
+cdl_option CYGSEM_HAL_ROM_MONITOR {
+ display "Behave as a ROM monitor"
+ flavor bool
+ default_value 0
+ parent CYGPKG_HAL_ROM_MONITOR
+ requires { CYG_HAL_STARTUP == "ROM" }
+ description "
+ Enable this option if this program is to be used as a ROM monitor,
+ i.e. applications will be loaded into RAM on the board, and this
+ ROM monitor may process exceptions or interrupts generated from the
+ application. This enables features such as utilizing a separate
+ interrupt stack when exceptions are generated."
+}
+</programlisting>
+
+<para>The latter option is accompanied by a special build rule that
+extends the generic ROM monitor build rule in the common HAL:</para>
+
+<programlisting>
+cdl_option CYGBLD_BUILD_GDB_STUBS {
+ display "Build GDB stub ROM image"
+ default_value 0
+ requires { CYG_HAL_STARTUP == "ROM" }
+ requires CYGSEM_HAL_ROM_MONITOR
+ requires CYGBLD_BUILD_COMMON_GDB_STUBS
+ requires CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+ requires ! CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+ requires ! CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
+ requires ! CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT
+ requires ! CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM
+ no_define
+ description "
+ This option enables the building of the GDB stubs for the
+ board. The common HAL controls takes care of most of the
+ build process, but the final conversion from ELF image to
+ binary data is handled by the platform CDL, allowing
+ relocation of the data if necessary."
+
+ make -priority 320 {
+ &lt;PREFIX&gt;/bin/gdb_module.bin : &lt;PREFIX&gt;/bin/gdb_module.img
+ $(OBJCOPY) -O binary $< $@
+ }
+}
+</programlisting>
+
+<para>
+Most platforms support RedBoot, and some options are needed to
+configure for RedBoot.
+</para>
+
+<programlisting width=72>
+ cdl_component CYGPKG_REDBOOT_HAL_OPTIONS {
+ display "Redboot HAL options"
+ flavor none
+ no_define
+ parent CYGPKG_REDBOOT
+ active_if CYGPKG_REDBOOT
+ description "
+ This option lists the target's requirements for a valid Redboot
+ configuration."
+
+ cdl_option CYGBLD_BUILD_REDBOOT_BIN {
+ display "Build Redboot ROM binary image"
+ active_if CYGBLD_BUILD_REDBOOT
+ default_value 1
+ no_define
+ description "This option enables the conversion of the Redboot ELF
+ image to a binary image suitable for ROM programming."
+
+ make -priority 325 {
+ &lt;PREFIX&gt;/bin/redboot.bin : &lt;PREFIX&gt;/bin/redboot.elf
+ $(OBJCOPY) --strip-debug $< $(@:.bin=.img)
+ $(OBJCOPY) -O srec $< $(@:.bin=.srec)
+ $(OBJCOPY) -O binary $< $@
+ }
+ }
+ }
+</programlisting>
+
+<para>
+The important part here is the <literal>make</literal> command in the
+<literal>CYGBLD_BUILD_REDBOOT_BIN</literal> option which emits
+makefile commands to translate the <filename>.elf</filename> file
+generated by the link phase into both a binary file and an S-Record
+file. If a different format is required by a PROM programmer or ROM
+monitor, then different output formats would need to be generated here.
+</para>
+
+</section>
+
+<!-- }}} -->
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Platform Memory Layout -->
+
+<section id="hal-porting-platform-memory-layout">
+<TITLE>Platform Memory Layout</TITLE>
+
+<para>Historically, the platform memory layout was defined using a Memory
+Configuration window in the eCos Configuration Tool (version 1.x).
+However, the memory layout feature was not ported to the wxWidgets version
+of the tool (version 2.0 and later). Memory layouts are currently manipulated
+using a text editor.</para>
+
+<!--
+<note>
+<para>If you do not have access to a Windows machine, you can
+hand edit the <filename>.h</filename> and <filename>.ldi</filename> files to match the
+properties of your platform. If you want to contribute your port back
+to the eCos community, ask someone on the list to make proper memory
+map files for you.</para>
+</note>
+-->
+
+<section>
+<title>Layout Files</title>
+
+<para>The memory configuration details are specified in two files:</para>
+
+<variablelist>
+<!--
+<varlistentry>
+<term><filename>.mlt</filename></term>
+ <listitem><para>This is the Configuration Tool save-file. It is only used
+ by the Configuration Tool.</para></listitem>
+</varlistentry>
+-->
+<varlistentry>
+<term><filename>.ldi</filename></term>
+ <listitem><para>This is the linker script fragment. It defines the memory
+ and location of sections by way of macros defined in the
+ architecture or variant linker script.</para></listitem>
+</varlistentry>
+<varlistentry>
+<term><filename>.h</filename></term>
+ <listitem><para>This file describes some of the memory region details as C
+ macros, allowing eCos or the application adapt the memory
+ layout of a specific configuration.</para></listitem>
+</varlistentry>
+</variablelist>
+
+<para>These files are generated for each startup-type, since the
+memory details usually differ. The layout and structure of new files
+should match those of existing memory layout files to allow for the
+introduction of a new memory layout editor in the future.
+</para>
+
+</section>
+
+<section>
+<title>Reserved Regions</title>
+
+<para>Some areas of the memory space are reserved for specific
+purposes, making room for exception vectors and various tables. RAM
+startup configurations also need to reserve some space at the bottom
+of the memory map for the ROM monitor.</para>
+
+<para>These reserved areas are named with the prefix "reserved_" <!-- which is
+handled specially by the Configuration Tool: --> instead of referring to a
+linker macro, the start of the area is labeled and a gap left in the
+memory map.</para>
+
+</section>
+
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Platform Serial Device Support -->
+
+<section>
+<title>Platform Serial Device Support</title>
+
+<para>
+The first step is to set up the CDL definitions. The configuration
+options that need to be set are the following:
+</para>
+
+<variablelist>
+ <varlistentry>
+ <term><literal>CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS</literal></term>
+ <listitem><para>The number of channels, usually 0, 1 or 2.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL</literal></term>
+ <listitem><para>The channel to use for GDB.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD</literal></term>
+ <listitem><para>Initial baud rate for debug channel.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL</literal></term>
+ <listitem><para>The channel to use for the
+ console.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD</literal></term>
+ <listitem><para>The initial baud rate for the console
+ channel.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_DEFAULT</literal></term>
+ <listitem><para>The default console channel.</para></listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+The code in <filename>hal_diag.c</filename> need to be converted to
+support the new serial device.
+If this the same as a device already supported, copy that.
+</para>
+
+<para>
+The following functions and types need to be rewritten to support a new serial
+device.
+</para>
+
+<variablelist>
+ <varlistentry>
+ <term><literal>struct channel_data_t;</literal></term>
+ <listitem>
+ <para>
+ Structure containing base address, timeout and ISR vector number
+ for each serial device supported. Extra fields my be added if
+ necessary for the device. For example some devices have
+ write-only control registers, so keeping a shadow of the last
+ value written here can be useful.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>xxxx_ser_channels[];</literal></term>
+ <listitem>
+ <para>
+ Array of <literal>channel_data_t</literal>, initialized with parameters of each
+ channel. The index into this array is the channel number used
+ in the CDL options above and is used by the virtual vector
+ mechanism to refer to each channel.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>void cyg_hal_plf_serial_init_channel(void
+ *__ch_data)</literal></term>
+ <listitem>
+ <para>
+ Initialize the serial device. The parameter is actually a pointer to a
+ <literal>channel_data_t</literal> and should be cast back to
+ this type before use. This function should use the CDL
+ definition for the baud rate for the channel it is initializing.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>void cyg_hal_plf_serial_putc(void * __ch_data,
+ char *c)</literal></term>
+ <listitem>
+ <para>
+ Send a character to the serial device. This function should
+ poll for the device being ready to send and then write the character.
+ Since this is intended to be a diagnostic/debug channel, it is
+ often also a good idea to poll for end of transmission
+ too. This ensures that as much data gets out of the system as
+ possible.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool cyg_hal_plf_serial_getc_nonblock(void*
+ __ch_data, cyg_uint8* ch)</literal></term>
+ <listitem>
+ <para>
+ This function tests the device and if a character is
+ available, places it in <parameter>*ch</parameter> and returns
+ <literal>TRUE</literal>. If no character is available, then
+ the function returns <literal>FALSE</literal> immediately.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int cyg_hal_plf_serial_control(void *__ch_data,
+ __comm_control_cmd_t __func,
+ ...)</literal></term>
+ <listitem>
+ <para>
+ This is an IOCTL-like function for controlling various aspects
+ of the serial device. The only part in which you may need to
+ do some work initially is in the
+ <literal>__COMMCTL_IRQ_ENABLE</literal> and
+ <literal>__COMMCTL_IRQ_DISABLE</literal> cases to
+ enable/disable interrupts.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
+ CYG_ADDRWORD __vector, CYG_ADDRWORD
+ __data)</literal></term>
+ <listitem>
+ <para>
+ This interrupt handler, called from the spurious interrupt
+ vector, is specifically for dealing with
+ <literal>Ctrl-C</literal> interrupts from GDB. When called
+ this function should do the following:
+ <orderedlist>
+ <listitem>
+ <para>Check for an incoming character. The code here is very
+ similar to that in
+ <function>cyg_hal_plf_serial_getc_nonblock()</function>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Read the character and call
+ <function>cyg_hal_is_break()</function>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If result is true, set <parameter>*__ctrlc</parameter> to
+ <literal>1</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Return <literal>CYG_ISR_HANDLED</literal>.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>void cyg_hal_plf_serial_init()</literal></term>
+ <listitem>
+ <para>
+ Initialize each of the serial channels.
+ First call <function>cyg_hal_plf_serial_init_channel()</function> for each channel.
+ Then call the <literal>CYGACC_COMM_IF_*</literal> macros for
+ each channel. This latter set of calls are identical for all
+ channels, so the best way to do this is to copy and edit an
+ existing example.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+</section>
+
+<!-- }}} -->
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Variant HAL Porting -->
+
+<section id="hal-porting-variant">
+<title>Variant HAL Porting</title>
+
+<para>
+A variant port can be a fairly limited job, but can also
+require quite a lot of work. A variant HAL describes how a specific
+CPU variant differs from the generic CPU architecture. The variant HAL
+can re-define cache, MMU, interrupt, and other features which override
+the default implementation provided by the architecture HAL.
+</para>
+
+<para>
+Doing a variant port requires a preexisting architecture HAL port. It
+is also likely that a platform port will have to be done at the same
+time if it is to be tested.
+</para>
+
+<!-- {{{ Porting Process -->
+
+<section>
+<TITLE>HAL Variant Porting Process</TITLE>
+
+<para>The easiest way to make a new variant HAL is simply to copy an
+existing variant HAL and change all the files to match the new
+variant. If this is the first variant for an architecture, it may be
+hard to decide which parts should be put in the variant - knowledge of
+other variants of the architecture is required.</para>
+
+<para>Looking at existing variant HALs (e.g., MIPS tx39, tx49) may be a
+help - usually things such as caching, interrupt and exception
+handling differ between variants. Initialization code, and code for
+handling various core components (FPU, DSP, MMU, etc.) may also differ
+or be missing altogether on some variants. Linker scripts may also require
+specific variant versions.</para>
+
+<note>
+<title>Note</title>
+<para>Some CPU variants may require specific compiler
+support. That support must be in place before you can undertake the
+eCos variant port.</para>
+</note>
+
+
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ CDL Requirements -->
+
+<section>
+<TITLE>HAL Variant CDL</TITLE>
+
+<para>
+The CDL in a variant HAL tends to depend on the exact functionality
+supported by the variant. If it implements some of the devices
+described in the platform HAL, then the CDL for those will be here
+rather than there (for example the real-time clock).
+</para>
+
+<para>
+There may also be CDL to select options in the architecture HAL to
+configure it to a particular architectural variant.
+</para>
+
+<para>
+Each variant needs an entry in the <filename>ecos.db</filename>
+file. This is the one for the SH3:
+</para>
+
+<programlisting width=72>
+package CYGPKG_HAL_SH_SH3 {
+ alias { "SH3 architecture" hal_sh_sh3 }
+ directory hal/sh/sh3
+ script hal_sh_sh3.cdl
+ hardware
+ description "
+ The SH3 (SuperH 3) variant HAL package provides generic
+ support for SH3 variant CPUs."
+}
+</programlisting>
+
+<para>
+As you can see, it is very similar to the platform entry.
+</para>
+
+<para>
+The variant CDL file will contain a package entry named for the
+architecture and variant, matching the package name in the
+<filename>ecos.db</filename> file. Here is the initial part of the
+MIPS VR4300 CDL file:
+</para>
+
+<programlisting width=72>
+cdl_package CYGPKG_HAL_MIPS_VR4300 {
+ display "VR4300 variant"
+ parent CYGPKG_HAL_MIPS
+ implements CYGINT_HAL_MIPS_VARIANT
+ hardware
+ include_dir cyg/hal
+ define_header hal_mips_vr4300.h
+ description "
+ The VR4300 variant HAL package provides generic support
+ for this processor architecture. It is also necessary to
+ select a specific target platform HAL package."
+</programlisting>
+
+<para>
+This defines the package, placing it under the MIPS architecture
+package in the hierarchy. The <literal>implements</literal> line
+indicates that this is a MIPS variant. The architecture package uses
+this to check that exactly one variant is configured in.
+</para>
+
+<para>
+The variant defines some options that cause the architecture HAL to
+configure itself to support this variant.
+</para>
+
+<programlisting width=72>
+ cdl_option CYGHWR_HAL_MIPS_64BIT {
+ display "Variant 64 bit architecture support"
+ calculated 1
+ }
+
+ cdl_option CYGHWR_HAL_MIPS_FPU {
+ display "Variant FPU support"
+ calculated 1
+ }
+
+ cdl_option CYGHWR_HAL_MIPS_FPU_64BIT {
+ display "Variant 64 bit FPU support"
+ calculated 1
+ }
+</programlisting>
+
+<para>
+These tell the architecture that this is a 64 bit MIPS architecture,
+that it has a floating point unit, and that we are going to use it in
+64 bit mode rather than 32 bit mode.
+</para>
+
+<para>
+The CDL file finishes off with some build options.
+</para>
+
+<programlisting width=72>
+ define_proc {
+ puts $::cdl_header "#include &lt;pkgconf/hal_mips.h&gt;"
+ }
+
+ compile var_misc.c
+
+ make {
+ &lt;PREFIX&gt;/lib/target.ld: &lt;PACKAGE&gt;/src/mips_vr4300.ld
+ $(CC) -E -P -Wp,-MD,target.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(CFLAGS) -o $@ $&lt;
+ @echo $@ ": \\" &gt; $(notdir $@).deps
+ @tail +2 target.tmp &gt;&gt; $(notdir $@).deps
+ @echo &gt;&gt; $(notdir $@).deps
+ @rm target.tmp
+ }
+
+ cdl_option CYGBLD_LINKER_SCRIPT {
+ display "Linker script"
+ flavor data
+ no_define
+ calculated { "src/mips_vr4300.ld" }
+ }
+
+}
+</programlisting>
+
+<para>
+The <literal>define_proc</literal> causes the architecture
+configuration file to be included into the configuration file for the
+variant. The <literal>compile</literal> causes the single source file
+for this variant, <filename>var_misc.c</filename> to be compiled. The
+<literal>make</literal> command emits makefile rules to combine the
+linker script with the <filename>.ldi</filename> file to generate
+<literal>target.ld</literal>. Finally, in the MIPS HALs, the main
+linker script is defined in the variant, rather than the architecture,
+so <literal>CYGBLD_LINKER_SCRIPT</literal> is defined here.
+</para>
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Cache Support -->
+
+<section>
+<title>Cache Support</title>
+
+<para>
+The main area where the variant is likely to be involved is in cache
+support. Often the only thing that distinguishes one CPU variant from
+another is the size of its caches.
+</para>
+
+<para>
+In architectures such as the MIPS and PowerPC where cache instructions
+are part of the ISA, most of the actual cache operations are
+implemented in the architecture HAL. In this case the variant HAL only
+needs to define the cache dimensions. The following are the cache
+dimensions defined in the MIPS VR4300 variant
+<filename>var_cache.h</filename>.
+</para>
+
+<programlisting width=72>
+// Data cache
+#define HAL_DCACHE_SIZE (8*1024) // Size of data cache in bytes
+#define HAL_DCACHE_LINE_SIZE 16 // Size of a data cache line
+#define HAL_DCACHE_WAYS 1 // Associativity of the cache
+
+// Instruction cache
+#define HAL_ICACHE_SIZE (16*1024) // Size of cache in bytes
+#define HAL_ICACHE_LINE_SIZE 32 // Size of a cache line
+#define HAL_ICACHE_WAYS 1 // Associativity of the cache
+
+#define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS))
+#define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS))
+</programlisting>
+
+<para>
+Additional cache macros, or overrides for the defaults, may also
+appear in here. While some architectures have instructions for
+managing cache lines, overall enable/disable operations may be handled
+via variant specific registers. If so then
+<filename>var_cache.h</filename> should also define the
+<literal>HAL_XCACHE_ENABLE()</literal> and
+<literal>HAL_XCACHE_DISABLE()</literal> macros.
+</para>
+
+<para>
+If there are any generic features that the variant does not support
+(cache locking is a typical example) then
+<literal>var_cache.h</literal> may need to disable definitions of
+certain operations. It is architecture dependent exactly how this is
+done.
+</para>
+
+
+</section>
+
+<!-- }}} -->
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ Architecture HAL Porting -->
+
+<section id="hal-porting-architecture">
+
+<title>Architecture HAL Porting</title>
+
+<para>
+A new architecture HAL is the most complex HAL to write, and it the
+least easily described. Hence this section is presently nothing more
+than a place holder for the future.
+</para>
+
+<!-- {{{ Porting Process -->
+
+<section>
+<TITLE>HAL Architecture Porting Process</TITLE>
+
+<para>The easiest way to make a new architecture HAL is simply to copy an
+existing architecture HAL of an, if possible, closely matching
+architecture and change all the files to match the new
+architecture. The MIPS architecture HAL should be used if possible, as
+it has the appropriate layout and coding conventions. Other HALs
+may deviate from that norm in various ways.</para>
+
+<note>
+<title>Note</title>
+<para> eCos is written for GCC. It requires C and C++
+compiler support as well as a few compiler features introduced during
+eCos development - so compilers older than eCos may not provide these
+features. Note that there is no C++ support for any 8 or 16 bit
+CPUs. Before you can undertake an eCos port, you need the required
+compiler support.
+</para>
+</note>
+
+<para>
+The following gives a rough outline of the steps needed to create a
+new architecture HAL. The exact order and set of steps needed will
+vary greatly from architecture to architecture, so a lot of
+flexibility is required. And of course, if the architecture HAL is to
+be tested, it is necessary to do variant and platform ports for the
+initial target simultaneously.
+</para>
+
+<orderedlist>
+
+<listitem>
+<para>
+Make a new directory for the new architecture under the
+<filename>hal</filename> directory in the source repository. Make an
+<filename>arch</filename> directory under this and populate this with
+the standard set of package directories.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Copy the CDL file from an example HAL changing its name to match the
+new HAL. Edit the file, changing option names as appropriate. Delete
+any options that are specific to the original HAL, and and any new
+options that are necessary for the new architecture. This is likely to
+be a continuing process during the development of the HAL. See <xref
+linkend="hal-porting-architecture-cdl"> for more details.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Copy the <filename>hal_arch.h</filename> file from an example
+HAL. Within this file you need to change or define the following:
+</para>
+<itemizedlist>
+
+<listitem>
+<para>
+Define the <structname>HAL_SavedRegisters</structname> structure. This
+may need to reflect the save order of any group register save/restore
+instructions, the interrupt and exception save and restore formats,
+and the procedure calling conventions. It may also need to cater for
+optional FPUs and other functional units. It can be quite difficult to
+develop a layout that copes with all requirements.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Define the bit manipulation routines,
+<literal>HAL_LSBIT_INDEX()</literal> and
+<literal>HAL_MSBIT_INDEX()</literal>. If the architecture contains
+instructions to perform these, or related, operations, then these
+should be defined as inline assembler fragments. Otherwise make them
+calls to functions.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Define <literal>HAL_THREAD_INIT_CONTEXT()</literal>. This initializes
+a restorable CPU context onto a stack pointer so that a later call to
+<literal>HAL_THREAD_LOAD_CONTEXT()</literal> or
+<literal>HAL_THREAD_SWITCH_CONTEXT()</literal> will execute it
+correctly. This macro needs to take account of the same optional
+features of the architecture as the definition of
+<structname>HAL_SavedRegisters</structname>.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Define <literal>HAL_THREAD_LOAD_CONTEXT()</literal> and
+<literal>HAL_THREAD_SWITCH_CONTEXT()</literal>. These should just be
+calls to functions in <filename>context.S</filename>.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Define <literal>HAL_REORDER_BARRIER()</literal>. This prevents code
+being moved by the compiler and is necessary in some order-sensitive
+code. This macro is actually defined identically in all architecture,
+so it can just be copied.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Define breakpoint support. The macro
+<literal>HAL_BREAKPOINT(label)</literal> needs to be an inline assembly
+fragment that invokes a breakpoint. The breakpoint instruction should
+be labeled with the <parameter>label</parameter>
+argument. <literal>HAL_BREAKINST</literal> and
+<literal>HAL_BREAKINST_SIZE</literal> define the breakpoint
+instruction for debugging purposes.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Define GDB support. GDB views the registers of the target as a linear
+array, with each register having a well defined offset. This array may
+differ from the ordering defined in
+<structname>HAL_SavedRegisters</structname>. The macros
+<literal>HAL_GET_GDB_REGISTERS()</literal> and
+<literal>HAL_SET_GDB_REGISTERS()</literal> translate between the GDB
+array and the <structname>HAL_SavedRegisters</structname> structure.
+The <literal>HAL_THREAD_GET_SAVED_REGISTERS()</literal> translates a
+stack pointer saved by the context switch macros into a pointer to a
+<structname>HAL_SavedRegisters</structname> structure. Usually this is
+a one-to-one translation, but this macro allows it to differ if
+necessary.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Define long jump support. The type <type>hal_jmp_buf</type> and the
+functions <function>hal_setjmp()</function> and
+<literal>hal_longjmp()</literal> provide the underlying implementation
+of the C library <function>setjmp()</function> and
+<function>longjmp()</function>.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Define idle thread action. Generally the macro
+<literal>HAL_IDLE_THREAD_ACTION()</literal> is defined to call a
+function in <filename>hal_misc.c</filename>.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Define stack sizes. The macros
+<literal>CYGNUM_HAL_STACK_SIZE_MINIMUM</literal> and
+<literal>CYGNUM_HAL_STACK_SIZE_TYPICAL</literal> should be defined to
+the minimum size for any thread stack and a reasonable default for
+most threads respectively. It is usually best to construct these out
+of component sizes for the CPU save state and procedure call stack
+usage. These definitions should not use anything other than numerical
+values since they can be used from assembly code in some HALs.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Define memory access macros. These macros provide translation between
+cached and uncached and physical memory spaces. They usually consist
+of masking out bits of the supplied address and ORing in alternative
+address bits.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Define global pointer save/restore macros. These really only need
+defining if the calling conventions of the architecture require a
+global pointer (as does the MIPS architecture), they may be empty
+otherwise. If it is necessary to define these, then take a look at the
+MIPS implementation for an example.
+</para>
+</listitem>
+
+</itemizedlist>
+
+</listitem>
+
+<listitem>
+<para>
+Copy <filename>hal_intr.h</filename> from an example HAL. Within this
+file you should change or define the following:
+</para>
+
+
+<itemizedlist>
+<listitem>
+<para>
+Define the exception vectors. These should be detailed in the
+architecture specification. Essentially for each exception entry point
+defined by the architecture there should be an entry in the VSR
+table. The offsets of these VSR table entries should be defined here
+by <literal>CYGNUM_HAL_VECTOR_*</literal> definitions. The size of the
+VSR table also needs to be defined here.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Map any hardware exceptions to standard names. There is a group of
+exception vector name of the form
+<literal>CYGNUM_HAL_EXCEPTION_*</literal> that define a wide variety
+of possible exceptions that many architectures raise. Generic code
+detects whether the architecture can raise a given exception by
+testing whether a given <literal>CYGNUM_HAL_EXCEPTION_*</literal>
+definition is present. If it is present then its value is the vector
+that raises that exception. This does not need to be a one-to-one
+correspondence, and several <literal>CYGNUM_HAL_EXCEPTION_*</literal>
+definitions may have the same value.
+</para>
+
+<para>
+Interrupt vectors are usually defined in the variant or platform
+HALs. The interrupt number space may either be continuous with the VSR
+number space, where they share a vector table (as in the i386) or may
+be a separate space where a separate decode stage is used (as in MIPS
+or PowerPC).
+</para>
+
+</listitem>
+
+<listitem>
+<para>
+Declare any static data used by the HAL to handle interrupts and
+exceptions. This is usually three vectors for interrupts:
+<literal>hal_interrupt_handlers[]</literal>,
+<literal>hal_interrupt_data[]</literal> and
+<literal>hal_interrupt_objects[]</literal>, which are sized according
+to the interrupt vector definitions. In addition a definition for the
+VSR table, <literal>hal_vsr_table[]</literal> should be made. These
+vectors are normally defined in either <filename>vectors.S</filename>
+or <filename>hal_misc.c</filename>.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Define interrupt enable/disable macros. These are normally inline
+assembly fragments to execute the instructions, or manipulate the CPU
+register, that contains the CPU interrupt enable bit.
+</para>
+</listitem>
+
+<listitem>
+<para>
+A feature that many HALs support is the ability to execute DSRs on the
+interrupt stack. This is not an essential feature, and is better left
+unimplemented in the initial porting effort. If this is required, then
+the macro <literal>HAL_INTERRUPT_STACK_CALL_PENDING_DSRS()</literal>
+should be defined to call a function in
+<filename>vectors.S</filename>.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Define the interrupt and VSR attachment macros. If the same arrays as
+for other HALs have been used for VSR and interrupt vectors, then
+these macro can be copied across unchanged.
+</para>
+</listitem>
+
+</itemizedlist>
+
+</listitem>
+
+<listitem>
+<para>
+A number of other header files also need to be filled in:
+</para>
+<itemizedlist>
+<listitem>
+<para>
+<filename>basetype.h</filename>. This file defines the basic types
+used by eCos, together with the endianness and some other
+characteristics. This file only really needs to contain definitions
+if the architecture differs significantly from the defaults defined
+in <filename>cyg_type.h</filename>
+</para>
+</listitem>
+
+<listitem>
+<para>
+<filename>hal_io.h</filename>. This file contains macros for accessing
+device IO registers. If the architecture uses memory mapped IO, then
+these can be copied unchanged from an existing HAL such as MIPS. If
+the architecture uses special IO instructions, then these macros must
+be defined as inline assembler fragments. See the I386 HAL for an
+example. PCI bus access macros are usually defined in the variant or
+platform HALs.
+</para>
+</listitem>
+
+<listitem>
+<para>
+<filename>hal_cache.h</filename>. This file contains cache access
+macros. If the architecture defines cache instructions, or control
+registers, then the access macros should be defined here. Otherwise
+they must be defined in the variant or platform HAL. Usually the cache
+dimensions (total size, line size, ways etc.) are defined in the
+variant HAL.
+</para>
+</listitem>
+
+<listitem>
+<para>
+<filename>arch.inc</filename> and
+<filename>&lt;architecture&gt;.inc</filename>. These files are
+assembler headers used by <filename>vectors.S</filename> and
+<filename>context.S</filename>.
+<filename>&lt;architecture&gt;.inc</filename> is a general purpose
+header that should contain things like register aliases, ABI
+definitions and macros useful to general assembly
+code. If there are no such definitions, then this file need not be
+provided. <filename>arch.inc</filename> contains macros for performing
+various eCos related operations such as initializing the CPU, caches,
+FPU etc. The definitions here may often be configured or overridden by
+definitions in the variant or platform HALs. See the MIPS HAL for an
+example of this.
+</para>
+</listitem>
+
+</itemizedlist>
+
+</listitem>
+
+<listitem>
+<para>
+Write <filename>vectors.S</filename>. This is the most important file
+in the HAL. It contains the CPU initialization code, exception and
+interrupt handlers. While other HALs should be consulted for
+structures and techniques, there is very little here that can be
+copied over without major edits.
+</para>
+
+<para>
+The main pieces of code that need to be defined here are:
+</para>
+
+<itemizedlist>
+<listitem>
+<para>
+Reset vector. This usually need to be positioned at the start of the
+ROM or FLASH, so should be in a linker section of its own. It can then be
+placed correctly by the linker script. Normally this code is little
+more than a jump to the label <literal>_start</literal>.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Exception vectors. These are the trampoline routines connected to the
+hardware exception entry points that vector through the VSR table. In
+many architectures these are adjacent to the reset vector, and should
+occupy the same linker section. If the architecture allow the vectors
+to be moved then it may be necessary for these trampolines to be
+position independent so they can be relocated at runtime.
+</para>
+
+<para>
+The trampolines should do the minimum necessary to transfer control
+from the hardware vector to the VSR pointed to by the matching table
+entry. Exactly how this is done depends on the architecture. Usually
+the trampoline needs to get some working registers by either saving
+them to CPU special registers (e.g. PowerPC SPRs), using reserved
+general registers (MIPS K0 and K1), using only memory based
+operations (IA32), or just jumping directly (ARM). The VSR table index
+to be used is either implicit in the entry point taken (PowerPC, IA32,
+ARM), or must be determined from a CPU register (MIPS).
+</para>
+</listitem>
+
+<listitem>
+<para>
+Write kernel startup code. This is the location the reset vector jumps
+to, and can be in the main text section of the executable, rather than
+a special section. The code here should first initialize the CPU and other
+hardware subsystems. The best approach is to use a set of macro
+calls that are defined either in <filename>arch.inc</filename> or
+overridden in the variant or platform HALs. Other jobs that this code
+should do are: initialize stack pointer; copy the data section from
+ROM to RAM if necessary; zero the BSS; call variant and platform
+initializers; call <function>cyg_hal_invoke_constructors()</function>;
+call <function>initialize_stub()</function> if necessary. Finally it
+should call <function>cyg_start()</function>. See <xref
+linkend="hal-startup"> for details.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Write the default exception VSR. This VSR is installed in the VSR
+table for all synchronous exception vectors. See <xref
+linkend="hal-default-synchronous-exception-handling"> for details of
+what this VSR does.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Write the default interrupt VSR. This is installed in all VSR table
+entries that correspond to external interrupts. See <xref
+linkend="hal-default-synchronous-exception-handling"> for details of
+what this VSR does.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Write
+<function>hal_interrupt_stack_call_pending_dsrs()</function>. If this
+function is defined in <filename>hal_arch.h</filename> then it should
+appear here. The purpose of this function is to call DSRs on the
+interrupt stack rather than the current thread's stack. This is not an
+essential feature, and may be left until later. However it interacts
+with the stack switching that goes on in the interrupt VSR, so it may
+make sense to write these pieces of code at the same time to ensure
+consistency.
+</para>
+
+<para>
+When this function is implemented it should do the following:
+</para>
+
+<itemizedlist>
+<listitem>
+<para>
+Take a copy of the current SP and then switch to the interrupt stack.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Save the old SP, together with the CPU status register (or whatever
+register contains the interrupt enable status) and any other
+registers that may be corrupted by a function call (such as any link
+register) to locations in the interrupt stack.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Enable interrupts.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Call <function>cyg_interrupt_call_pending_DSRs()</function>. This is a
+kernel functions that actually calls any pending DSRs.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Retrieve saved registers from the interrupt stack and switch back to
+the current thread stack.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Merge the interrupt enable state recorded in the save CPU status
+register with the current value of the status register to restore the
+previous enable state. If the status register does not contain any
+other persistent state then this can be a simple restore of the
+register. However if the register contains other state bits that might
+have been changed by a DSR, then care must be taken not to disturb
+these.
+</para>
+</listitem>
+
+</itemizedlist>
+
+</listitem>
+
+
+<listitem>
+<para>
+Define any data items needed. Typically <filename>vectors.S</filename>
+may contain definitions for the VSR table, the interrupt tables and the
+interrupt stack. Sometimes these are only default definitions that may
+be overridden by the variant or platform HALs.
+</para>
+</listitem>
+
+</itemizedlist>
+
+</listitem>
+
+<listitem>
+<para>
+Write <filename>context.S</filename>. This file contains the context
+switch code. See <xref linkend="hal-context-switch"> for details of
+how these functions operate. This file may also contain the
+implementation of <function>hal_setjmp()</function> and
+<function>hal_longjmp()</function>.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Write <filename>hal_misc.c</filename>. This file contains any C
+data and functions needed by the HAL. These might include:
+</para>
+
+<itemizedlist>
+<listitem>
+<para>
+<varname>hal_interrupt_*[]</varname>. In some HALs, if these arrays
+are not defined in <filename>vectors.S</filename> then they must be
+defined here.
+</para>
+</listitem>
+
+<listitem>
+<para>
+<function>cyg_hal_exception_handler()</function>. This function is
+called from the exception VSR. It usually does extra decoding of the
+exception and invokes any special handlers for things like FPU traps,
+bus errors or memory exceptions. If there is nothing special to be
+done for an exception, then it either calls into the GDB stubs, by
+calling <function>__handle_exception()</function>, or
+invokes the kernel by calling
+<function>cyg_hal_deliver_exception()</function>.
+</para>
+</listitem>
+
+<listitem>
+<para>
+<function>hal_arch_default_isr()</function>. The
+<varname>hal_interrupt_handlers[]</varname> array is usually
+initialized with pointers to <filename>hal_default_isr()</filename>,
+which is defined in the common HAL. This function handles things like
+Ctrl-C processing, but if that is not relevant, then it will call
+<function>hal_arch_default_isr()</function>. Normally this function
+should just return zero.
+</para>
+</listitem>
+
+<listitem>
+<para>
+<function>cyg_hal_invoke_constructors()</function>. This calls the
+constructors for all static objects before the program starts. eCos
+relies on these being called in the correct order for it to function
+correctly. The exact way in which constructors are handled may differ
+between architectures, although most use a simple table of function
+pointers between labels <literal>__CTOR_LIST__</literal> and
+<literal>__CTOR_END__</literal> which must called in order from the
+top down. Generally, this function can be copied directly from an
+existing architecture HAL.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Bit indexing functions. If the macros
+<literal>HAL_LSBIT_INDEX()</literal> and
+<literal>HAL_MSBIT_INDEX()</literal> are defined as function calls,
+then the functions should appear here. The main reason for doing this
+is that the architecture does not have support for bit indexing and
+these functions must provide the functionality by conventional
+means. While the trivial implementation is a simple for loop, it is
+expensive and non-deterministic. Better, constant time,
+implementations can be found in several HALs (MIPS for example).
+</para>
+</listitem>
+
+<listitem>
+<para>
+<function>hal_delay_us()</function>. If the macro
+<literal>HAL_DELAY_US()</literal> is defined in <filename
+class="headerfile">hal_intr.h</filename> then it should be defined to
+call this function. While most of the time this function is called
+with very small values, occasionally (particularly in some ethernet
+drivers) it is called with values of several seconds. Hence the
+function should take care to avoid overflow in any calculations.
+</para>
+</listitem>
+
+<listitem>
+<para>
+<function>hal_idle_thread_action()</function>. This function is called
+from the idle thread via the
+<literal>HAL_IDLE_THREAD_ACTION()</literal> macro, if so
+defined. While normally this function does nothing, during development
+this is often a good place to report various important system
+parameters on LCDs, LED or other displays. This function can also
+monitor system state and report any anomalies. If the architecture
+supports a <literal>halt</literal> instruction then this is a good
+place to put an inline assembly fragment to execute it. It is also a
+good place to handle any power saving activity.
+</para>
+</listitem>
+
+</itemizedlist>
+</listitem>
+
+<listitem>
+<para>
+Create the <filename>&lt;architecture&gt;.ld</filename> file. While
+this file may need to be moved to the variant HAL in the future, it
+should initially be defined here, and only moved if necessary.
+</para>
+<para>
+This file defines a set of macros that are used by the platform
+<literal>.ldi</literal> files to generate linker scripts. Most GCC
+toolchains are very similar so the correct approach is to copy the
+file from an existing architecture and edit it. The main things that
+will need editing are the <literal>OUTPUT_FORMAT()</literal> directive
+and maybe the creation or allocation of extra sections to various
+macros. Running the target linker with just the
+<literal>--verbose</literal> argument will cause it to output its
+default linker script. This can be compared with the
+<literal>.ld</literal> file and appropriate edits made.
+</para>
+</listitem>
+
+<listitem>
+<para>
+If GDB stubs are to be supported in RedBoot or eCos, then support must
+be included for these. The most important of these are <filename
+class="headerfile">include/&lt;architecture&gt;-stub.h</filename> and
+<filename>src/&lt;architecture&gt;-stub.c</filename>. In all existing
+architecture HALs these files, and any support files they need, have
+been derived from files supplied in <literal>libgloss</literal>, as
+part of the GDB toolchain package. If this is a totally new
+architecture, this may not have been done, and they must be created
+from scratch.
+</para>
+
+<para>
+<filename
+class="headerfile">include/&lt;architecture&gt;-stub.h</filename>
+contains definitions that are used by the GDB stubs to describe the
+size, type, number and names of CPU registers. This information is
+usually found in the GDB support files for the architecture. It also
+contains prototypes for the functions exported by
+<filename>src/&lt;architecture&gt;-stub.c</filename>; however, since
+this is common to all architectures, it can be copied from some other
+HAL.
+</para>
+
+<para>
+<filename>src/&lt;architecture&gt;-stub.c</filename> implements the
+functions exported by the header. Most of this is fairly straight
+forward: the implementation in existing HALs should show exactly what
+needs to be done. The only complex part is the support for
+single-stepping. This is used a lot by GDB, so it cannot be
+avoided. If the architecture has support for a trace or single-step
+trap then that can be used for this purpose. If it does not then this
+must be simulated by planting a breakpoint in the next
+instruction. This can be quite involved since it requires some
+analysis of the current instruction plus the state of the CPU to
+determine where execution is going to go next.
+</para>
+
+</listitem>
+
+</orderedlist>
+
+
+</section>
+
+<!-- }}} -->
+<!-- {{{ CDL Requirements -->
+
+<section id="hal-porting-architecture-cdl">
+<title>CDL Requirements</title>
+
+<para>
+The CDL needed for any particular architecture HAL depends to a large
+extent on the needs of that architecture. This includes issues such as
+support for different variants, use of FPUs, MMUs and caches. The
+exact split between the architecture, variant and platform HALs for
+various features is also somewhat fluid.
+</para>
+
+<para>
+To give a rough idea about how the CDL for an architecture is
+structured, we will take as an example the I386 CDL.
+</para>
+
+<para>
+This first section introduces the CDL package and placed it under the
+main HAL package. Include files from this package will be put in the
+<filename>include/cyg/hal</filename> directory, and definitions from
+this file will be placed in
+<filename>include/pkgconf/hal_i386.h</filename>. The
+<literal>compile</literal> line specifies the files in the
+<filename>src</filename> directory that are to be compiled as part of
+this package.
+</para>
+
+<programlisting width=72>
+cdl_package CYGPKG_HAL_I386 {
+ display "i386 architecture"
+ parent CYGPKG_HAL
+ hardware
+ include_dir cyg/hal
+ define_header hal_i386.h
+ description "
+ The i386 architecture HAL package provides generic
+ support for this processor architecture. It is also
+ necessary to select a specific target platform HAL
+ package."
+
+ compile hal_misc.c context.S i386_stub.c hal_syscall.c
+</programlisting>
+
+<para>
+Next we need to generate some files using non-standard make rules. The
+first is <filename>vectors.S</filename>, which is not put into the
+library, but linked explicitly with all applications. The second is
+the generation of the <filename>target.ld</filename> file from
+<filename>i386.ld</filename> and the startup-selected
+<filename>.ldi</filename> file. Both of these are essentially
+boilerplate code that can be copied and edited.
+</para>
+
+<programlisting width=72>
+
+ make {
+ &lt;PREFIX&gt;/lib/vectors.o : &lt;PACKAGE&gt;/src/vectors.S
+ $(CC) -Wp,-MD,vectors.tmp $(INCLUDE_PATH) $(CFLAGS) -c -o $@ $&lt;
+ @echo $@ ": \\" &gt; $(notdir $@).deps
+ @tail +2 vectors.tmp &gt;&gt; $(notdir $@).deps
+ @echo &gt;&gt; $(notdir $@).deps
+ @rm vectors.tmp
+ }
+
+ make {
+ &lt;PREFIX&gt;/lib/target.ld: &lt;PACKAGE&gt;/src/i386.ld
+ $(CC) -E -P -Wp,-MD,target.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(CFLAGS) -o $@ $&lt;
+ @echo $@ ": \\" &gt; $(notdir $@).deps
+ @tail +2 target.tmp &gt;&gt; $(notdir $@).deps
+ @echo &gt;&gt; $(notdir $@).deps
+ @rm target.tmp
+ }
+</programlisting>
+
+<para>
+The i386 is currently the only architecture that supports SMP. The
+following CDL simply enabled the HAL SMP support if
+required. Generally this will get enabled as a result of a
+<literal>requires</literal> statement in the kernel. The
+<literal>requires</literal> statement here turns off lazy FPU
+switching in the FPU support code, since it is inconsistent with SMP
+operation.
+</para>
+
+<programlisting width=72>
+
+ cdl_component CYGPKG_HAL_SMP_SUPPORT {
+ display "SMP support"
+ default_value 0
+ requires { CYGHWR_HAL_I386_FPU_SWITCH_LAZY == 0 }
+
+ cdl_option CYGPKG_HAL_SMP_CPU_MAX {
+ display "Max number of CPUs supported"
+ flavor data
+ default_value 2
+ }
+ }
+</programlisting>
+
+<para>
+The i386 HAL has optional FPU support, which is enabled by default. It
+can be disabled to improve system performance. There are two FPU
+support options: either to save and restore the FPU state on every
+context switch, or to only switch the FPU state when necessary.
+</para>
+
+<programlisting width=72>
+
+ cdl_component CYGHWR_HAL_I386_FPU {
+ display "Enable I386 FPU support"
+ default_value 1
+ description "This component enables support for the
+ I386 floating point unit."
+
+ cdl_option CYGHWR_HAL_I386_FPU_SWITCH_LAZY {
+ display "Use lazy FPU state switching"
+ flavor bool
+ default_value 1
+
+ description "
+ This option enables lazy FPU state switching.
+ The default behaviour for eCos is to save and
+ restore FPU state on every thread switch, interrupt
+ and exception. While simple and deterministic, this
+ approach can be expensive if the FPU is not used by
+ all threads. The alternative, enabled by this option,
+ is to use hardware features that allow the FPU state
+ of a thread to be left in the FPU after it has been
+ descheduled, and to allow the state to be switched to
+ a new thread only if it actually uses the FPU. Where
+ only one or two threads use the FPU this can avoid a
+ lot of unnecessary state switching."
+ }
+ }
+</programlisting>
+
+<para>
+The i386 HAL also has support for different classes of CPU. In
+particular, Pentium class CPUs have extra functional units, and some
+variants of GDB expect more registers to be reported. These options
+enable these features. Generally these are enabled by
+<literal>requires</literal> statements in variant or platform
+packages, or in <literal>.ecm</literal> files.
+</para>
+
+<programlisting width=72>
+
+ cdl_component CYGHWR_HAL_I386_PENTIUM {
+ display "Enable Pentium class CPU features"
+ default_value 0
+ description "This component enables support for various
+ features of Pentium class CPUs."
+
+ cdl_option CYGHWR_HAL_I386_PENTIUM_SSE {
+ display "Save/Restore SSE registers on context switch"
+ flavor bool
+ default_value 0
+
+ description "
+ This option enables SSE state switching. The default
+ behaviour for eCos is to ignore the SSE registers.
+ Enabling this option adds SSE state information to
+ every thread context."
+ }
+
+ cdl_option CYGHWR_HAL_I386_PENTIUM_GDB_REGS {
+ display "Support extra Pentium registers in GDB stub"
+ flavor bool
+ default_value 0
+
+ description "
+ This option enables support for extra Pentium registers
+ in the GDB stub. These are registers such as CR0-CR4, and
+ all MSRs. Not all GDBs support these registers, so the
+ default behaviour for eCos is to not include them in the
+ GDB stub support code."
+ }
+ }
+</programlisting>
+
+<para>
+In the i386 HALs, the linker script is provided by the architecture
+HAL. In other HALs, for example MIPS, it is provided in the variant
+HAL. The following option provides the name of the linker script to
+other elements in the configuration system.
+</para>
+
+<programlisting width=72>
+ cdl_option CYGBLD_LINKER_SCRIPT {
+ display "Linker script"
+ flavor data
+ no_define
+ calculated { "src/i386.ld" }
+ }
+</programlisting>
+
+<para>
+Finally, this interface indicates whether the platform supplied an
+implementation of the
+<function>hal_i386_mem_real_region_top()</function> function. If it
+does then it will contain a line of the form: <literal>implements
+CYGINT_HAL_I386_MEM_REAL_REGION_TOP</literal>. This allows packages
+such as RedBoot to detect the presence of this function so that they
+may call it.
+</para>
+
+<programlisting width=72>
+
+ cdl_interface CYGINT_HAL_I386_MEM_REAL_REGION_TOP {
+ display "Implementations of hal_i386_mem_real_region_top()"
+ }
+
+}
+</programlisting>
+
+</section>
+
+<!-- }}} -->
+
+<!--
+<para><a href="hal-arch-process.html">Porting process</a>
+<para><a href="hal-cache.html">HAL Cache Controls</a>
+<para><a href="hal-linking.html">Linker Script Macros</a>
+<para><a href="hal-arch-cdl.html">CDL requirements</a>
+
+-->
+
+</section>
+
+<!-- }}} -->
+
+</CHAPTER>
+
+<!--
+
+Notes added by Nickg:
+
+The following are my notes from the HAL Porting course I did at
+Agilent in Feb 2002. It was my intention to incorporate some stuff
+from here into the Platform Porting section and to include some of
+the things I learned while doing the course. The main things I wanted
+to do were: to change the porting process to concentrate on getting
+RedBoot to run rather than the GDB stubs ROM; update the descriptions
+to match current practice - some of it is now quite old; remove all
+the TBDs and FIXMEs; mend the worst of Jesper's danglish :-)
+
+Also the variant and architecture porting guides are still in the
+incomplete state that Jesper left them; and there are some other bits
+and pieces in the original HTML porting guide that I have not yet
+moved over.
+
+The ridiculous demands of management to sacrifice quality to
+expediency mean that this is not now possible and this document has to
+be abandoned in mid-flux. So I'm just dumping this stuff here. Maybe
+one day someone will get around to doing it properly.
+
+
+
+
+Porting Principals
+==================
+
+Copy an existing HAL.
+ - choose a HAL with which you are familiar and/or which is
+ similar to the intended target.
+ - copy the files
+ - rename them appropriately
+ - rename configuration variables
+ - empty/reimplement platform specific code.
+ - old code is a good indicator of what you need to do.
+ - concentrate on getting it all to compile, so just commenting
+ out the platform specific bits is often a good idea.
+
+Follow execution order.
+ - gives a good indication of what to do next.
+
+Concentrate on RedBoot first.
+ - simpler environment - no interrupts, no threads.
+
+
+CDL
+===
+
+CDL changes made as part of the copy/edit above should be done.
+
+Need to add entries to ecos.db for the new packages.
+
+Platform:
+
+package CYGPKG_HAL_ARM_ARM9_XXXXXXXX {
+ alias { "XXXXXXXX unit" hal_arm_arm9_xxxxxxxx xxxxxxxx }
+ directory hal/arm/arm9/xxxxxxxx
+ script hal_arm_arm9_xxxxxxxx.cdl
+ hardware
+ description "
+ The XXXXXXXX HAL package provides the support needed to run
+ eCos on an XXXXXXXX board."
+}
+
+Target:
+
+target xxxxxxxx {
+ alias { "XXXXXXXX unit" aaed }
+ packages { CYGPKG_HAL_ARM
+ CYGPKG_HAL_ARM_ARM9
+ CYGPKG_HAL_ARM_ARM9_XXXXXXXX
+ }
+ description "
+ The XXXXXXXX target provides the packages needed to run
+ eCos on an XXXXXXXX board."
+}
+
+==================================================================
+
+Getting RedBoot Going
+=====================
+
+Startup
+=======
+
+1. Reset entry point. At location 0.
+ Transfer control to ROM entry point: reset_vector.
+
+2. Here we call invoke PLATFORM_SETUP1 macro. This does the following:
+ - disable interrupts
+ - disable and clear caches
+ - Init memory controllers. may involve discovery of what RAM is
+ present.
+ - Set up clock frequencies.
+ - Init MMU table
+ - sets up TTBR and DACR to default values
+ - fills in MMU table to map
+ - DRAM at 0x00000000 cacheable/buffered
+ - Device registers elsewhere uncacheable/unbuffered usually 1-1
+ - DRAM at 0xF0000000 uncacheable/unbuffered (1-1 in aaed2000)
+ - remap ROM at 0 elsewhere
+ - Enable MMU
+ - Relocate image to RAM for ROMRAM startup
+ - Any other CPU setup required
+
+3. Jump to HAL startup.
+ - Plant vector intructions at 0+
+ - copy .data section to RAM
+ - Init CPSR and SPSR
+ - Set SP
+ - Clear .bss
+ - Call hal_hardware_init()
+ - call initialize_stub() if GDB stubs included
+ - call hal_ctrlc_isr_init()
+ - call cyg_hal_invoke_constructors()
+ - call cyg_start()
+
+
+HAL Serial support
+==================
+
+Set up CDL in platform CDL file.
+ CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS
+ number of channels usually 0, 1 or 2
+ CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL
+ channel to use for GDB
+ CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD
+ initial baud rate
+ CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL
+ channel to use for console
+ CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD
+ initial baud rate
+ CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_DEFAULT
+ default console channel
+
+The code in hal_diag.c need to be converted to the new serial device.
+If this the same as a device already supported, copy that.
+
+Things that need to be written:
+
+struct channel_data_t;
+ Structure containing base address, timeout and ISR vector
+ number for each serial device.
+
+xxxx_ser_channels[];
+ Array of channel_data_t, initialized with parameters of each
+ channel.
+
+void cyg_hal_plf_serial_init_channel(void *__ch_data)
+ Initialize the serial device. parameter is a pointer to a
+ channel_data_t.
+
+void cyg_hal_plf_serial_putc(void * __ch_data, char *c)
+ Send a character to the serial device.
+ Poll for ready, write the char.
+ Maybe poll for char sent.
+
+bool cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+ Look for a character and return it if available.
+ If none available, return false.
+
+int cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t
+__func, ...)
+ An IOCTL-like function for controlling various aspects of the
+ serial device.
+ May need to do some work in __COMMCTL_IRQ_ENABLE and
+ __COMMCTL_IRQ_DISABLE cases to enable/disable interrupts.
+
+int cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
+ CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+ Interrupt handler, specifically for dealing with Ctrl-C.
+ - Check for an incoming character.
+ - Read the character and call cyg_hal_is_break().
+ - If result is true, set *__ctrlc to 1.
+ - return CYG_ISR_HANDLED;
+
+void cyg_hal_plf_serial_init()
+ Initialize each of the serial channels.
+ - call cyg_hal_plf_serial_init_channel() for each channel.
+ - call CYGACC_COMM_IF_* macros for each channel -
+ cut/paste/edit these.
+
+
+Interrupt Controller
+====================
+
+ARM platforms have interrupt controller access in functions in variant
+or platform source file.
+
+void hal_interrupt_mask(int vector)
+ Manipulate interrupt controller to mask the interrupt.
+
+void hal_interrupt_unmask(int vector)
+ Manipulate interrupt controller to unmask the interrupt.
+
+void hal_interrupt_acknowledge(int vector)
+ Manipulate interrupt controller to acknowledge the interrupt.
+ May not be needed in some platforms.
+
+void hal_interrupt_configure(int vector, int level, int up)
+ Set interrupt detection: level vs. edge; high/low
+ rising/falling.
+ Leave empty where not implemented.
+
+void hal_interrupt_set_level(int vector, int level)
+ Set interrupt priority level.
+ Leave empty where not implemented.
+
+
+Redboot Configuration
+=====================
+
+Having done all of the above, you should be in a position to get
+RedBoot running.
+
+If the platform you copied has redboot, there should be some .ecm
+files in the misc directory. Named redboot_<startup>.ecm.
+
+Choose a startup and edit the .ecm file.
+ - remove any options that are not relevant
+ - comment out FLASH, ETH and COMPRESS packages
+
+Configure for redboot:
+
+% setenv ECOS_REPOSITORY <path to source repository>
+% ecosconfig new xxxxxxxx redboot
+% ecosconfig import $ECOS_REPOSITORY/hal/arm/arm9/xxxxxxxx/current/misc/redboot_ROM.ecm
+% ecosconfig tree
+% make
+
+Repeat until successful.
+
+Load into hardware by either programming FLASH from existing ROM
+monitor, via JTAG or whatever.
+
+Run. Debug. Edit. Repeat.
+
+==================================================================
+
+Getting eCos Going
+==================
+
+Once RedBoot is up and running, it should be possible to configure and
+build eCos.
+
+Use the kernel template to start with.
+
+
+Clock Support
+=============
+
+We will use the RTC to test that interrupts are working. First step is
+to get RTC working.
+
+void hal_clock_initialize(cyg_uint32 period)
+ Initialize the RTC device to interrupt every period ticks. The
+ CDL should have defined period according to the frequency
+ required.
+ This should start the clock going.
+
+void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
+ Perform any work to cause the clock to start another timing
+ period. On many platforms this can be empty. On others the
+ counter or compare register may need to be reloaded.
+
+void hal_clock_read(cyg_uint32 *pvalue)
+ Returns the number of hardware ticks since the last interrupt.
+ For count-up timers this is just the value of the timer.
+ For count-down timers the result needs to be subtracted from the
+ initial period.
+
+void hal_delay_us(cyg_int32 usecs)
+ Busy delay for the given number of microseconds.
+ Normally this works by polling the timer device until the
+ required number of usecs has passed.
+ Beware of timer wrap-around, resets, and arithmetic overflows.
+ This function does not have to be very accurate - it's used
+ mostly to provide short timing delays during hardware access.
+
+Interrupt Handling
+==================
+
+Quick overview of interrupt handling:
+
+
+1. Hardware interrupts are delivered to either the IRQ or FIQ vectors at
+ 0x18 and 0x1c respectively.
+
+2. These contain single instructions that load the contents of the memory
+ location 0x20 later in memory and jump there.
+
+3. The code called is a VSR - Vector Service Routine. FIQ VSR fakes
+ CPU state to make it look like an IRQ, then drops into IRQ.
+
+4. Switch back to supervisor mode. Save CPU state onto current stack.
+
+5. Switch to interrupt stack if not already there.
+
+6. Lock scheduler.
+
+7. Call hal_IRQ_handler(). This function inspects the interrupt
+ controller and returns the number of the highest priority pending,
+ unmasked interrupt.
+
+8. Use vector number to index hal_interrupt_handlers[] and
+ hal_interrupt_data[] to get ISR and data.
+
+9. Call ISR. keep the return value.
+
+10. Switch back to original stack.
+
+11. Index hal_interrupt_objects[] with vector number to get interrupt
+ object pointer.
+
+12. Call interrupt_end(isr_ret, *object, *save_regs).
+ This will:
+ - post the onterrupt object's DSR if CYG_ISR_CALL_DSR is set in
+ return code.
+ - Unlock scheduler. During this the following may happen:
+ - Any pending DSRs may be called
+ - The current thread may be preempted, either by a higher
+ priority thread scheduled by a DSR, or it may be timesliced.
+
+13. The return from interrupt_end() may occur some time after the
+ call: lots of threads may have run in the meantime.
+
+14. Restore CPU state and resume interrupted code.
+
+
+The only thing that needs doing in a platform port is to write
+hal_IRQ_handler().
+
+
+
+Once the clock and IRQ code is done, eCos should be able to run all of
+the kernel tests. The best all-round test is tm_basic. Other tests
+that should be run are:
+ clocktruth - tests accuracy of timer setup
+ except1 - checks exception handling works
+ timeslice - checks timeslicing works
+
+Run. Debug. Edit. Repeat.
+
+
+
+
+-->
+
+
diff --git a/ecos/packages/hal/common/current/include/dbg-thread-syscall.h b/ecos/packages/hal/common/current/include/dbg-thread-syscall.h
new file mode 100644
index 0000000..f0a62ba
--- /dev/null
+++ b/ecos/packages/hal/common/current/include/dbg-thread-syscall.h
@@ -0,0 +1,110 @@
+//========================================================================
+//
+// dbg-thread-syscall.h
+//
+// Supports thread-aware debugging
+//
+//========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Red Hat, nickg
+// Contributors: Red Hat, nickg
+// Date: 1998-08-25
+// Purpose:
+// Description: Supports thread-aware debugging
+// Usage: This header is not to be included by user code.
+// This file should be included only by
+// thread-syscall-relay.c and dbg-thread-demux.c
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================
+
+
+enum dbg_syscall_ids
+ {
+ dbg_null_func ,
+ dbg_capabilities_func,
+ dbg_currthread_func,
+ dbg_threadlist_func,
+ dbg_threadinfo_func,
+ dbg_getthreadreg_func,
+ dbg_setthreadreg_func,
+ dbg_scheduler_func,
+ } ;
+
+
+union dbg_thread_syscall_parms
+{
+ struct
+ {
+ struct dbg_capabilities * abilities ;
+ } cap_parms ;
+
+ struct
+ {
+ threadref * ref ;
+ } currthread_parms ;
+
+ struct
+ {
+ int startflag ;
+ threadref * lastid ;
+ threadref * nextthreadid ;
+ } threadlist_parms ;
+
+ struct
+ {
+ threadref * ref ;
+ struct cygmon_thread_debug_info * info ;
+ } info_parms ;
+
+ struct
+ {
+ threadref * thread ;
+ int regcount ;
+ void * registers ;
+ } reg_parms ;
+ struct
+ {
+ threadref * thread ; /* 64-bit thread identifier */
+ int lock; /* 0 == unlock, 1 == lock */
+ int mode; /* 0 == short (step), 1 == continue */
+ } scheduler_parms ;
+} ;
+
+
+typedef int (*dbg_syscall_func) (enum dbg_syscall_ids id,
+ union dbg_thread_syscall_parms * p ) ;
diff --git a/ecos/packages/hal/common/current/include/dbg-threads-api.h b/ecos/packages/hal/common/current/include/dbg-threads-api.h
new file mode 100644
index 0000000..777716c
--- /dev/null
+++ b/ecos/packages/hal/common/current/include/dbg-threads-api.h
@@ -0,0 +1,160 @@
+//========================================================================
+//
+// dbg-threads-api.h
+//
+// Supports thread-aware debugging
+//
+//========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Red Hat, nickg
+// Contributors: Red Hat, nickg
+// Date: 1998-08-25
+// Purpose:
+// Description: These are the calls used to extract operating system
+// specific information used in supporting thread aware
+// debugging. The Operating Environment being debugged
+// needs to supply these functions.
+// Usage: This header is not to be included by user code.
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================
+
+#if !defined(DBG_THREADS_API_INCLUDED)
+#define DBG_THREADS_API_INCLUDED 1
+
+#include <cyg/infra/cyg_type.h> /* externC */
+
+#define has_thread_void 0
+#define has_thread_current 1
+#define has_thread_registers 2
+#define has_thread_reg_change 4
+#define has_thread_list 8
+#define has_thread_info 16
+
+typedef unsigned char threadref[8] ;
+
+struct dbg_capabilities
+{
+ unsigned long mask1 ;
+} ;
+
+
+/* fill in the list of thread aware capabilities */
+externC int dbg_thread_capabilities(struct dbg_capabilities * cbp) ;
+
+
+/* Fillin the identifier of the current thread */
+/* return 1 if defined, 0 if not defined */
+externC int dbg_currthread(threadref * varparm) ;
+
+/* Return the unique ID number of a given thread. */
+/* Return 0 if not valid. */
+externC int dbg_thread_id(threadref *threadid);
+
+/* Return the unique ID number of the current thread. */
+externC int dbg_currthread_id(void);
+
+/* get the first or next member of the list of known threads */
+externC int dbg_threadlist(int startflag,
+ threadref * lastthreadid,
+ threadref * next_thread
+ ) ;
+
+/* return 1 if next_threadid has been filled in with a value */
+/* return 0 if there are none or no more */
+
+/* The O.S can fill in the following information about a thread when queried.
+ The structure of thise strings is determined by the O.S.
+ It is display oriented, so figure out what the users need to see.
+ Nulls are OK but GDB will fill some not so meaningful data.
+ These pointers may be in the calles private structures, the info will
+ get copied immediatly after the call to retreive it.
+ */
+struct cygmon_thread_debug_info
+{
+ threadref thread_id ;
+ int context_exists ; /* To the point where examining its state,
+ registers and stack makes sense to GDB */
+ char * thread_display ; /* As shown in thread status window, name, state */
+ char * unique_thread_name ; /* human readable identifier, window label */
+ char * more_display ; /* more detailed info about thread.
+ priority, queuedepth, state, stack usage, statistics */
+} ;
+
+
+
+
+externC int dbg_threadinfo(
+ threadref * threadid,
+ struct cygmon_thread_debug_info * info) ;
+
+/* Return 1 if threadid is defined and info copied, 0 otherwise */
+
+/* The O.S should fillin the array of registers using values from the
+saves context. The array MUST be in GDB register save order even if
+the saved context is different or smaller. Do not alter the values of
+registers which are NOT in the O.S. thread context. Their default values
+have already been assigned.
+*/
+
+externC int dbg_getthreadreg(
+ threadref * osthreadid,
+ int regcount, /* count of registers in the array */
+ void * regval) ; /* fillin this array */
+
+
+/* The O.S. should scan through this list of registers which are in
+GDB order and the O.S. should replace the values of all registers
+which are defined in the saved context of thread or process identified
+by osthreadid. Return 0 if the threadis does not map to a known
+process or other error. Return 1 if the setting is successful. */
+
+externC int dbg_setthreadreg(
+ threadref * osthreadid,
+ int regcount , /* number of registers */
+ void * regval) ;
+
+/* Control over OS scheduler. With the scheduler locked it should not
+ perform any rescheduling in response to interrupts. */
+externC int dbg_scheduler(
+ threadref * osthreadid,
+ int lock, /* 0 == unlock, 1 == lock */
+ int mode); /* 0 == step, 1 == continue */
+
+
+
+#endif /* DBG_THREADS_API_INCLUDED */
diff --git a/ecos/packages/hal/common/current/include/drv_api.h b/ecos/packages/hal/common/current/include/drv_api.h
new file mode 100644
index 0000000..bf697fa
--- /dev/null
+++ b/ecos/packages/hal/common/current/include/drv_api.h
@@ -0,0 +1,250 @@
+#ifndef CYGONCE_HAL_DRV_API_H
+#define CYGONCE_HAL_DRV_API_H
+
+/*==========================================================================
+//
+// drv_api.h
+//
+// Native API for Kernel
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Date: 1999-02-24
+// Purpose: Driver API
+// Description: This file defines the API used by device drivers to access
+// system services. When the kernel is present it maps directly
+// to the Kernel C API. When the kernel is absent, it is provided
+// by a set of HAL functions.
+//
+// Usage: #include <cyg/kernel/kapi.h>
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+#ifdef CYGPKG_KERNEL
+
+/*------------------------------------------------------------------------*/
+/* Kernel co-resident version of API */
+
+#include <pkgconf/kernel.h>
+
+#ifndef CYGFUN_KERNEL_API_C
+#error Driver API requres Kernel API to be present
+#endif
+
+#include <cyg/kernel/kapi.h>
+
+#define cyg_drv_isr_lock cyg_interrupt_disable
+#define cyg_drv_isr_unlock cyg_interrupt_enable
+
+#define cyg_drv_dsr_lock cyg_scheduler_lock
+#define cyg_drv_dsr_unlock cyg_scheduler_unlock
+
+#define cyg_drv_mutex_t cyg_mutex_t
+#define cyg_drv_mutex_init cyg_mutex_init
+#define cyg_drv_mutex_destroy cyg_mutex_destroy
+#define cyg_drv_mutex_lock cyg_mutex_lock
+#define cyg_drv_mutex_trylock cyg_mutex_trylock
+#define cyg_drv_mutex_unlock cyg_mutex_unlock
+#define cyg_drv_mutex_release cyg_mutex_release
+
+#define cyg_drv_cond_t cyg_cond_t
+#define cyg_drv_cond_init cyg_cond_init
+#define cyg_drv_cond_destroy cyg_cond_destroy
+#define cyg_drv_cond_wait cyg_cond_wait
+#define cyg_drv_cond_signal cyg_cond_signal
+#define cyg_drv_cond_broadcast cyg_cond_broadcast
+
+#define cyg_drv_interrupt_create cyg_interrupt_create
+#define cyg_drv_interrupt_delete cyg_interrupt_delete
+#define cyg_drv_interrupt_attach cyg_interrupt_attach
+#define cyg_drv_interrupt_detach cyg_interrupt_detach
+#define cyg_drv_interrupt_mask cyg_interrupt_mask
+#define cyg_drv_interrupt_unmask cyg_interrupt_unmask
+#define cyg_drv_interrupt_mask_intunsafe cyg_interrupt_mask_intunsafe
+#define cyg_drv_interrupt_unmask_intunsafe cyg_interrupt_unmask_intunsafe
+#define cyg_drv_interrupt_acknowledge cyg_interrupt_acknowledge
+#define cyg_drv_interrupt_configure cyg_interrupt_configure
+#define cyg_drv_interrupt_level cyg_interrupt_level
+#define cyg_drv_interrupt_set_cpu cyg_interrupt_set_cpu
+#define cyg_drv_interrupt_get_cpu cyg_interrupt_get_cpu
+
+#define cyg_drv_spinlock_t cyg_spinlock_t
+#define cyg_drv_spinlock_init cyg_spinlock_init
+#define cyg_drv_spinlock_spin cyg_spinlock_spin
+#define cyg_drv_spinlock_clear cyg_spinlock_clear
+#define cyg_drv_spinlock_try cyg_spinlock_try
+#define cyg_drv_spinlock_test cyg_spinlock_test
+#define cyg_drv_spinlock_spin_intsave cyg_spinlock_spin_intsave
+#define cyg_drv_spinlock_clear_intsave cyg_spinlock_clear_intsave
+
+#else /* CYGPKG_KERNEL */
+
+/*------------------------------------------------------------------------*/
+/* Non-kernel version of API */
+
+typedef CYG_ADDRWORD cyg_addrword_t; /* May hold pointer or word */
+typedef cyg_addrword_t cyg_handle_t; /* Object handle */
+typedef cyg_uint32 cyg_priority_t; /* type for priorities */
+typedef cyg_uint32 cyg_vector_t; /* Interrupt vector id */
+typedef cyg_uint32 cyg_cpu_t; /* CPU id */
+typedef int cyg_bool_t;
+typedef cyg_int32 cyg_code_t; /* type for various codes */
+
+typedef cyg_uint32 cyg_ISR_t( cyg_vector_t vector, cyg_addrword_t data);
+typedef void cyg_DSR_t(cyg_vector_t vector,
+ cyg_ucount32 count,
+ cyg_addrword_t data);
+
+
+externC void cyg_drv_isr_lock(void);
+externC void cyg_drv_isr_unlock(void);
+
+externC void cyg_drv_dsr_lock(void);
+externC void cyg_drv_dsr_unlock(void);
+
+typedef struct
+{
+ cyg_atomic lock;
+} cyg_drv_mutex_t;
+
+externC void cyg_drv_mutex_init( cyg_drv_mutex_t *mutex );
+externC void cyg_drv_mutex_destroy( cyg_drv_mutex_t *mutex );
+externC cyg_bool_t cyg_drv_mutex_lock( cyg_drv_mutex_t *mutex );
+externC cyg_bool_t cyg_drv_mutex_trylock( cyg_drv_mutex_t *mutex );
+externC void cyg_drv_mutex_unlock( cyg_drv_mutex_t *mutex );
+externC void cyg_drv_mutex_release( cyg_drv_mutex_t *mutex );
+
+typedef struct
+{
+ cyg_atomic wait;
+ cyg_drv_mutex_t *mutex;
+} cyg_drv_cond_t;
+
+externC void cyg_drv_cond_init( cyg_drv_cond_t *cond, cyg_drv_mutex_t *mutex );
+externC void cyg_drv_cond_destroy( cyg_drv_cond_t *cond );
+externC cyg_bool_t cyg_drv_cond_wait( cyg_drv_cond_t *cond );
+externC void cyg_drv_cond_signal( cyg_drv_cond_t *cond );
+externC void cyg_drv_cond_broadcast( cyg_drv_cond_t *cond );
+
+typedef struct cyg_interrupt
+{
+ cyg_vector_t vector;
+ cyg_priority_t priority;
+ cyg_ISR_t *isr;
+ cyg_DSR_t *dsr;
+ CYG_ADDRWORD data;
+
+ struct cyg_interrupt* volatile next_dsr;
+ volatile cyg_int32 dsr_count;
+
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
+ struct cyg_interrupt *next;
+#endif
+
+} cyg_interrupt;
+
+externC void cyg_drv_interrupt_create(
+ cyg_vector_t vector,
+ cyg_priority_t priority,
+ cyg_addrword_t data,
+ cyg_ISR_t *isr,
+ cyg_DSR_t *dsr,
+ cyg_handle_t *handle,
+ cyg_interrupt *intr
+ );
+externC void cyg_drv_interrupt_delete( cyg_handle_t interrupt );
+externC void cyg_drv_interrupt_attach( cyg_handle_t interrupt );
+externC void cyg_drv_interrupt_detach( cyg_handle_t interrupt );
+
+externC void cyg_drv_interrupt_mask( cyg_vector_t vector );
+externC void cyg_drv_interrupt_mask_intunsafe( cyg_vector_t vector );
+externC void cyg_drv_interrupt_unmask( cyg_vector_t vector );
+externC void cyg_drv_interrupt_unmask_intunsafe( cyg_vector_t vector );
+externC void cyg_drv_interrupt_acknowledge( cyg_vector_t vector );
+externC void cyg_drv_interrupt_configure(
+ cyg_vector_t vector,
+ cyg_bool_t level,
+ cyg_bool_t up
+ );
+externC void cyg_drv_interrupt_level( cyg_vector_t vector, cyg_priority_t level );
+externC void cyg_drv_interrupt_set_cpu( cyg_vector_t vector, cyg_cpu_t cpu );
+externC cyg_cpu_t cyg_drv_interrupt_get_cpu( cyg_vector_t vector );
+
+
+enum cyg_ISR_results
+{
+ CYG_ISR_HANDLED = 1, /* Interrupt was handled */
+ CYG_ISR_CALL_DSR = 2 /* Schedule DSR */
+};
+
+
+typedef struct
+{
+ cyg_atomic lock;
+} cyg_drv_spinlock_t;
+
+void cyg_drv_spinlock_init(
+ cyg_drv_spinlock_t *lock, /* spinlock to initialize */
+ cyg_bool_t locked /* init locked or unlocked */
+);
+
+void cyg_drv_spinlock_destroy( cyg_drv_spinlock_t *lock );
+
+void cyg_drv_spinlock_spin( cyg_drv_spinlock_t *lock );
+
+void cyg_drv_spinlock_clear( cyg_drv_spinlock_t *lock );
+
+cyg_bool_t cyg_drv_spinlock_try( cyg_drv_spinlock_t *lock );
+
+cyg_bool_t cyg_drv_spinlock_test( cyg_drv_spinlock_t *lock );
+
+void cyg_drv_spinlock_spin_intsave( cyg_drv_spinlock_t *lock,
+ cyg_addrword_t *istate );
+
+void cyg_drv_spinlock_clear_intsave( cyg_drv_spinlock_t *lock,
+ cyg_addrword_t istate );
+
+#endif /* CYGPKG_KERNEL */
+
+/*------------------------------------------------------------------------*/
+/* EOF drv_api.h */
+#endif // CYGONCE_HAL_DRV_API_H
diff --git a/ecos/packages/hal/common/current/include/generic-stub.h b/ecos/packages/hal/common/current/include/generic-stub.h
new file mode 100644
index 0000000..ff4cb09
--- /dev/null
+++ b/ecos/packages/hal/common/current/include/generic-stub.h
@@ -0,0 +1,364 @@
+//========================================================================
+//
+// generic-stub.h
+//
+// Definitions for the generic GDB remote stub
+//
+//========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Red Hat, nickg
+// Contributors: Red Hat, nickg, dmoseley
+// Date: 1998-06-08
+// Purpose:
+// Description: Definitions for the generic GDB remote stub
+// Usage: This header is not to be included by user code, and is
+// only placed in a publically accessible directory so
+// that platform stub packages are able to include it
+// if required.
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================
+
+
+#ifndef GENERIC_STUB_H
+#define GENERIC_STUB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Three typedefs must be provided before including this file.
+ target_register_t should correspond to the largest register value on
+ this target processor.
+ regnames_t corresponds to a type representing a register number.
+ uint32 must correspond to at least a 32-bit unsigned integer type
+ (it may be larger). */
+
+#ifndef ASM
+
+#ifndef __ECOS__
+#include "dbg-serial.h"
+#endif // __ECOS__
+
+struct gdb_packet
+{
+ /* The checksum calculated so far. */
+ uint32 checksum;
+ /* The checksum we've received from the remote side. */
+ uint32 xmitcsum;
+ /* Contents of the accumulated packet. */
+ char *contents;
+ /* Number of characters received. */
+ uint32 length;
+ /*
+ * state is the current state:
+ * 0 = looking for start of packet
+ * 1 = got start of packet, looking for # terminator
+ * 2 = looking for first byte of checksum
+ * 3 = looking for second byte of checksum (indicating end of packet)
+ */
+ char state;
+ char err; // This is set if the packet should be tossed because of overflow
+};
+
+/* Return the currently-saved value corresponding to register REG. */
+extern target_register_t get_register (regnames_t reg);
+
+/* Write the contents of register WHICH into VALUE as raw bytes */
+extern int get_register_as_bytes (regnames_t which, char *value);
+
+#ifdef CYGHWR_REGISTER_VALIDITY_CHECKING
+// Return the validity of register REG.
+extern int get_register_valid (regnames_t reg);
+#endif
+
+/* Store VALUE in the register corresponding to WHICH. */
+extern void put_register (regnames_t which, target_register_t value);
+
+extern int put_register_as_bytes (regnames_t which, char *value);
+
+/* Set the next instruction to be executed when the user program resumes
+ execution to PC. */
+#if !defined(SET_PC_PROTOTYPE_EXISTS) && !defined(set_pc)
+#define SET_PC_PROTOTYPE_EXISTS
+extern void set_pc (target_register_t pc);
+#endif
+
+/* Set the return value of the currently-pending syscall to VALUE. */
+extern void set_syscall_value (target_register_t value);
+
+/* Return the Nth argument to the currently-pending syscall (starting from
+ 0). */
+extern target_register_t get_syscall_arg (int n);
+
+/* Initialize the stub. This will also install any trap handlers needed by
+ the stub. */
+extern void initialize_stub (void);
+
+/* Initialize the hardware. */
+extern void initHardware (void);
+
+/* Skip the current instruction. */
+extern void __skipinst (void);
+
+/* If the address in the PC register corresponds to the breakpoint()
+ instruction, return a non-zero value. */
+#ifndef __is_breakpoint_function
+extern int __is_breakpoint_function (void);
+#endif
+
+/* Execute a breakpoint instruction. Restarting will cause the instruction
+ to be skipped. */
+#ifndef breakpoint
+extern void breakpoint (void);
+#endif
+
+/* Return the syscall # corresponding to this system call. */
+extern int __get_syscall_num (void);
+
+/* Transfer exception event processing to the stub. */
+extern void __switch_to_stub (void);
+
+/* Send an exit packet containing the specified status. */
+extern void __send_exit_status (int status);
+
+/* Copy COUNT bytes of memory from ADDR to BUF.
+ ADDR is assumed to live in the user program's space.
+ Returns number of bytes successfully read
+ (caller must check to see if less than requested). */
+extern int __read_mem_safe (void *buf,
+ void *addr,
+ int count);
+
+extern int __read_progmem_safe (void *buf,
+ void *addr,
+ int count);
+
+/* Copy COUNT bytes of memory from BUF to ADDR.
+ ADDR is assumed to live in the user program's space.
+ Returns number of bytes successfully read
+ (caller must check to see if less than requested). */
+#ifndef __write_mem_safe
+extern int __write_mem_safe (void *buf,
+ void *addr,
+ int count);
+#endif
+
+extern int __write_progmem_safe (void *buf,
+ void *addr,
+ int count);
+
+/* Set to a non-zero value if a memory fault occurs while
+ __set_mem_fault_trap () is running. */
+extern volatile int __mem_fault;
+
+#ifndef __ECOS__
+#if 1
+#include "stub-tservice.h" /* target dependent stub services */
+#else
+/* Flush the instruction cache. */
+extern void flush_i_cache (void);
+
+/* Flush the data cache. */
+extern void __flush_d_cache (void);
+
+typedef enum {
+ CACHE_NOOP, CACHE_ENABLE, CACHE_DISABLE, CACHE_FLUSH
+} cache_control_t;
+
+/* Perform the specified operation on the instruction cache.
+ Returns 1 if the cache is enabled, 0 otherwise. */
+extern int __instruction_cache (cache_control_t request);
+/* Perform the specified operation on the data cache.
+ Returns 1 if the cache is enabled, 0 otherwise. */
+extern int __data_cache (cache_control_t request);
+#endif
+#endif // __ECOS__
+
+/* Write the 'T' packet in BUFFER. SIGVAL is the signal the program
+ received. */
+extern void __build_t_packet (int sigval, char *buffer);
+
+/* Return 1 when a complete packet has been received, 0 if the packet
+ is not yet complete, or -1 if an erroneous packet was NAKed. */
+int __add_char_to_packet (unsigned character, struct gdb_packet *packet);
+
+typedef int (*__PFI)(int);
+typedef void (*__PFV)(void);
+
+/* When an exception occurs, __process_exception_vec will be invoked with
+ the signal number corresponding to the trap/exception. The function
+ should return zero if it wishes execution to resume from the saved
+ register values; a non-zero value indicates that the exception handler
+ should be reinvoked. */
+#if !defined(PROCESS_EXCEPTION_VEC_PROTOTYPE_EXISTS)
+#define PROCESS_EXCEPTION_VEC_PROTOTYPE_EXISTS
+extern volatile __PFI __process_exception_vec;
+#endif
+
+/* __process_exit_vec is invoked when a 'k' kill packet is received
+ from GDB. */
+extern volatile __PFV __process_exit_vec;
+
+/* If SIGSYSCALL is defined, and such a signal value is returned from
+ __computeSignal (), the function pointed to by this vector will
+ be invoked.
+
+ If the return value is negative, the user program is assumed to
+ have received the corresponding positive signal value, and an
+ exception will be processed. Otherwise, the user program is
+ restarted from the next instruction. */
+extern volatile __PFI __process_syscall_vec;
+
+/* A continue packet was received from GDB with a signal value. The function
+ pointed to by __process_signal_vec will be invoked with this signal
+ value.
+
+ If a zero value is returned, we will ignore the signal, and proceed
+ with the continue request. Otherwise, the program will be killed
+ with the signal. */
+extern volatile __PFI __process_signal_vec;
+
+/* If non-NULL, __init_vec is called right before the user program is
+ resumed. */
+extern volatile __PFV __init_vec;
+/* if non-NULL, __cleanup_vec is called after the user program takes
+ an exception. */
+extern volatile __PFV __cleanup_vec;
+
+/* Send an 'O' packet to GDB containing STR. */
+extern int __output_gdb_string (target_register_t addr, int string_len);
+
+/* Request MAXLEN bytes of input from GDB to be stored in DEST. If BLOCK
+ is set, GDB should block until MAXLEN bytes are available to be
+ read; otherwise, it will return immediately with whatever data is
+ available.
+ The return value is the number of bytes written into DEST. */
+extern int __get_gdb_input (target_register_t dest, int maxlen, int block);
+
+/* Return the ASCII equivalent of C (C>=0 && C<=15). The result will be
+ lower-case. */
+extern char __tohex (int c);
+
+/* Convert COUNT bytes of the memory region in MEM to a hexadecimal
+ string in DEST.
+ The resulting string will contain 2*COUNT characters.
+ If MAY_FAULT is non-zero, memory faults are trapped; if a fault occurs,
+ a NULL value will be returned.
+ The value returned is one byte past the end of the string written. */
+extern char *__mem2hex (char *mem, char *dest, int count, int may_fault);
+
+/* Given a hexadecimal string in MEM, write the equivalent bytes to DEST.
+ The string is assumed to contain 2*COUNT characters.
+ If MAY_FAULT is non-zero, memory faults are trapped; if a fault occurs,
+ a NULL value will be returned.
+ Otherwise, the value returned is one byte past the last byte written. */
+extern char *__hex2mem (char *buf, char *mem, int count, int may_fault);
+
+#ifdef CYGSEM_ECOS_SUPPORTS_PROGRAM_ARGS
+/* Set the program arguments passed into the user program's main */
+extern void __set_program_args (int argc, char **argv);
+
+/* Return the user program arguments passed in from GDB (via an 'A'
+ packet). argcPtr is a pointer into the user program, which will hold
+ the number of arguments; the strings are returned. */
+extern char **__get_program_args (target_register_t argcPtr);
+#endif
+
+/* Encode PACKET as a remote protocol packet and send it to GDB; this takes
+ care of sending the initial '$' character, as well as the trailing '#'
+ and checksum, and also waits for an ACK from the remote side, resending
+ as necessary. */
+extern void __putpacket (char *packet);
+
+/* Retrieve the next remote protocol packet from GDB, taking care of verifying
+ the checksum and sending an ACK when necessary. */
+extern void __getpacket (char *buffer);
+
+/* Convert the hexadecimal string pointed to by *PTR into an integer,
+ and store it in the value pointed to by INTVALUE. The number of
+ characters read from *PTR will be returned; *PTR will point to the first
+ non-hexadecmial character encountered. */
+extern unsigned int __hexToInt (char **ptr, target_register_t *intValue);
+
+/* Convert the value in INTVALUE into a string of hexadecimal
+ characters stored in PTR. NUMBITS are the number of bits to use
+ in INTVALUE. The number of characters written to PTR will be returned. */
+extern unsigned int __intToHex (char *ptr,
+ target_register_t intValue,
+ int numBits);
+
+/* Handle an exception, usually some sort of hardware or software trap.
+ This is responsible for communicating the exception to GDB. */
+extern void __handle_exception (void);
+
+/* Send a 'X' packet with signal SIGVAL to GDB. */
+extern void __kill_program (int sigval);
+
+/* Given a packet pointed to by PACKETCONTENTS, decode it and respond to
+ GDB appropriately. */
+extern int __process_packet (char *packetContents);
+
+/* Write the C-style string pointed to by STR to the GDB comm port.
+ Used for printing debug messages. */
+extern void __putDebugStr (char *str);
+
+#if defined(NO_MALLOC) && !defined(MAX_BP_NUM)
+#define MAX_BP_NUM 64 /* Maximum allowed # of breakpoints */
+#endif
+
+extern int hal_syscall_handler(void);
+extern int __is_bsp_syscall(void);
+
+extern void __install_breakpoint_list (void);
+extern void __clear_breakpoint_list (void);
+extern int __display_breakpoint_list (void (*print_func)(target_register_t));
+
+/* 'Z' packet types */
+#define ZTYPE_SW_BREAKPOINT 0
+#define ZTYPE_HW_BREAKPOINT 1
+#define ZTYPE_HW_WATCHPOINT_WRITE 2
+#define ZTYPE_HW_WATCHPOINT_READ 3
+#define ZTYPE_HW_WATCHPOINT_ACCESS 4
+
+#endif /* ASM */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* GENERIC_STUB_H */
diff --git a/ecos/packages/hal/common/current/include/hal_arbiter.h b/ecos/packages/hal/common/current/include/hal_arbiter.h
new file mode 100644
index 0000000..b9b75a2
--- /dev/null
+++ b/ecos/packages/hal/common/current/include/hal_arbiter.h
@@ -0,0 +1,139 @@
+#ifndef CYGONCE_HAL_HAL_ARBITER_H
+#define CYGONCE_HAL_HAL_ARBITER_H
+
+//=============================================================================
+//
+// hal_arbiter.h
+//
+// Functionality used by ISR arbiters
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 2001-06-29
+// Purpose: Functionality used by ISR arbiters
+// Usage: #include <cyg/hal/hal_arbiter.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/hal/hal_intr.h> // hal_interrupt_x tables
+#include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED
+
+//=============================================================================
+// Function used to call ISRs from ISR arbiters
+// An arbiter is hooked on the shared interrupt vector and looks like this:
+//
+// cyg_uint32 _arbitration_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
+// {
+// cyg_uint32 isr_ret;
+// // decode interrupt source and for each active source call the ISR
+// if (source_A_active) {
+// isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_SOURCE_A);
+// #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
+// if (isr_ret & CYG_ISR_HANDLED)
+// #endif
+// return isr_ret;
+// }
+// if (source_B_active) {
+// isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_SOURCE_B);
+// #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
+// if (isr_ret & CYG_ISR_HANDLED)
+// #endif
+// return isr_ret;
+// }
+// ...
+// return 0;
+// }
+//
+// Remember to attach and enable the arbiter source:
+// HAL_INTERRUPT_ATTACH(CYGNUM_HAL_INTERRUPT_ARBITER, &_arbitration_isr, 0, 0);
+// HAL_INTERRUPT_SET_LEVEL(CYGNUM_HAL_INTERRUPT_ARBITER, 1);
+// HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_ARBITER);
+//
+
+typedef cyg_uint32 cyg_ISR(cyg_uint32 vector, CYG_ADDRWORD data);
+
+extern void cyg_interrupt_post_dsr( CYG_ADDRWORD intr_obj );
+
+#ifndef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
+
+static inline cyg_uint32
+hal_call_isr (cyg_uint32 vector)
+{
+ cyg_ISR *isr;
+ CYG_ADDRWORD data;
+ cyg_uint32 isr_ret;
+
+ isr = (cyg_ISR*) hal_interrupt_handlers[vector];
+ data = hal_interrupt_data[vector];
+
+ isr_ret = (*isr) (vector, data);
+
+ if (isr_ret & CYG_ISR_CALL_DSR) {
+ cyg_interrupt_post_dsr (hal_interrupt_objects[vector]);
+ }
+
+ return isr_ret & ~CYG_ISR_CALL_DSR;
+}
+
+#else
+
+// In chained mode, assume vector 0 points to the chain
+// handler. Simply call it with the vector number and let it find the
+// ISR to call - it will also post DSRs as required.
+static inline cyg_uint32
+hal_call_isr (cyg_uint32 vector)
+{
+ cyg_ISR *isr;
+ CYG_ADDRWORD data;
+ cyg_uint32 isr_ret;
+
+ isr = (cyg_ISR*) hal_interrupt_handlers[0];
+ data = hal_interrupt_data[0];
+
+ isr_ret = (*isr) (vector, data);
+
+ return isr_ret;
+}
+
+#endif
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_HAL_HAL_ARBITER_H
+// End of hal_arbiter.h
diff --git a/ecos/packages/hal/common/current/include/hal_endian.h b/ecos/packages/hal/common/current/include/hal_endian.h
new file mode 100644
index 0000000..80e59d4
--- /dev/null
+++ b/ecos/packages/hal/common/current/include/hal_endian.h
@@ -0,0 +1,109 @@
+#ifndef CYGONCE_HAL_HAL_ENDIAN_H
+#define CYGONCE_HAL_HAL_ENDIAN_H
+
+//=============================================================================
+//
+// hal_endian.h
+//
+// Endian conversion macros
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 2001-10-04
+// Purpose: Endian conversion macros
+// Usage: #include <cyg/hal/hal_endian.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h> // CYGBLD_HAL_ENDIAN_H
+#include <cyg/infra/cyg_type.h> // endian setting
+
+// Allow HALs to override the generic implementation of swap macros
+#ifdef CYGBLD_HAL_ENDIAN_H
+# include CYGBLD_HAL_ENDIAN_H
+#endif
+
+#ifndef CYG_SWAP16
+# define CYG_SWAP16(_x_) \
+ ({ cyg_uint16 _x = (_x_); (cyg_uint16)((_x << 8) | (_x >> 8)); })
+#endif
+
+#ifndef CYG_SWAP32
+# define CYG_SWAP32(_x_) \
+ ({ cyg_uint32 _x = (_x_); \
+ ((_x << 24) | \
+ ((0x0000FF00UL & _x) << 8) | \
+ ((0x00FF0000UL & _x) >> 8) | \
+ (_x >> 24)); })
+#endif
+
+
+#if (CYG_BYTEORDER == CYG_LSBFIRST)
+# define CYG_CPU_TO_BE16(_x_) CYG_SWAP16((_x_))
+# define CYG_CPU_TO_BE32(_x_) CYG_SWAP32((_x_))
+# define CYG_BE16_TO_CPU(_x_) CYG_SWAP16((_x_))
+# define CYG_BE32_TO_CPU(_x_) CYG_SWAP32((_x_))
+
+# define CYG_CPU_TO_LE16(_x_) (_x_)
+# define CYG_CPU_TO_LE32(_x_) (_x_)
+# define CYG_LE16_TO_CPU(_x_) (_x_)
+# define CYG_LE32_TO_CPU(_x_) (_x_)
+
+#elif (CYG_BYTEORDER == CYG_MSBFIRST)
+
+# define CYG_CPU_TO_BE16(_x_) (_x_)
+# define CYG_CPU_TO_BE32(_x_) (_x_)
+# define CYG_BE16_TO_CPU(_x_) (_x_)
+# define CYG_BE32_TO_CPU(_x_) (_x_)
+
+# define CYG_CPU_TO_LE16(_x_) CYG_SWAP16((_x_))
+# define CYG_CPU_TO_LE32(_x_) CYG_SWAP32((_x_))
+# define CYG_LE16_TO_CPU(_x_) CYG_SWAP16((_x_))
+# define CYG_LE32_TO_CPU(_x_) CYG_SWAP32((_x_))
+
+#else
+
+# error "Endian mode not selected"
+
+#endif
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_HAL_HAL_ENDIAN_H
+// End of hal_endian.h
diff --git a/ecos/packages/hal/common/current/include/hal_if.h b/ecos/packages/hal/common/current/include/hal_if.h
new file mode 100644
index 0000000..ae68100
--- /dev/null
+++ b/ecos/packages/hal/common/current/include/hal_if.h
@@ -0,0 +1,756 @@
+#ifndef CYGONCE_HAL_HAL_IF_H
+#define CYGONCE_HAL_HAL_IF_H
+
+//=============================================================================
+//
+// hal_if.h
+//
+// HAL header for ROM/RAM calling interface.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov, woehler
+// Date: 2000-06-07
+// Purpose: HAL RAM/ROM calling interface
+// Description: ROM/RAM calling interface table definitions. The layout is a
+// combination of libbsp and vectors already in use by some
+// eCos platforms.
+// Usage: #include <cyg/hal/hal_if.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/infra/cyg_type.h> // types & externC
+#include <cyg/hal/dbg-threads-api.h>
+#include <cyg/hal/dbg-thread-syscall.h>
+
+#include <stdarg.h>
+
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+// Architecture/var/platform may override the accessor macros.
+#include <cyg/hal/hal_arch.h>
+
+// Special monitor locking procedures. These are necessary when the monitor
+// and eCos share facilities, e.g. the network hardware.
+#if defined (CYGPKG_NET) || defined (CYGPKG_NET_LWIP)
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h> // cyg_drv_dsr_lock(), etc
+#define _ENTER_MONITOR() \
+ cyg_uint32 ints; \
+ HAL_DISABLE_INTERRUPTS(ints); \
+ cyg_drv_dsr_lock()
+
+#define _EXIT_MONITOR() \
+ cyg_drv_dsr_unlock(); \
+ HAL_RESTORE_INTERRUPTS(ints)
+#else // !CYGPKG_NET && !CYGPKG_NET_LWIP
+#define _ENTER_MONITOR() CYG_EMPTY_STATEMENT
+#define _EXIT_MONITOR() CYG_EMPTY_STATEMENT
+#endif
+
+//--------------------------------------------------------------------------
+#ifndef _BSP_HANDLER_T_DEFINED
+#define _BSP_HANDLER_T_DEFINED
+typedef int (*bsp_handler_t)(int __irq_nr, void *__regs);
+#endif // _BSP_HANDLER_T_DEFINED
+
+//--------------------------------------------------------------------------
+// Communication interface table. CYGNUM_CALL_IF_CONSOLE_PROCS and
+// CYGNUM_CALL_IF_DEBUG_PROCS point to instances (possibly the same)
+// of this table.
+
+typedef enum {
+ /*
+ * For serial ports, the control function may be used to set and get the
+ * current baud rate. Usage:
+ *
+ * err = (*__control)(COMMCTL_SETBAUD, int bits_per_second);
+ * err => Zero if successful, -1 if error.
+ *
+ * baud = (*__control)(COMMCTL_GETBAUD);
+ * baud => -1 if error, current baud otherwise.
+ */
+ __COMMCTL_SETBAUD=0,
+ __COMMCTL_GETBAUD,
+
+ /*
+ * Install and remove debugger interrupt handlers. These are the receiver
+ * interrupt routines which are used to change control from a running
+ * program to the debugger stub.
+ */
+ __COMMCTL_INSTALL_DBG_ISR,
+ __COMMCTL_REMOVE_DBG_ISR,
+
+ /*
+ * Disable comm port interrupt. Returns TRUE if interrupt was enabled,
+ * FALSE otherwise.
+ */
+ __COMMCTL_IRQ_DISABLE,
+
+ /*
+ * Enable comm port interrupt.
+ */
+ __COMMCTL_IRQ_ENABLE,
+
+ /*
+ * Returns the number of the interrupt vector used by the debug
+ * interrupt handler.
+ */
+ __COMMCTL_DBG_ISR_VECTOR,
+
+ /*
+ * Returns the current timeout value and sets a new timeout.
+ * Timeout resolution is in milliseconds.
+ * old_timeout = (*__control)(__COMMCTL_SET_TIMEOUT,
+ * cyg_int32 new_timeout);
+ */
+ __COMMCTL_SET_TIMEOUT,
+
+ /*
+ * Forces driver to send all characters which may be buffered in
+ * the driver. This only flushes the driver buffers, not necessarily
+ * any hardware FIFO, etc.
+ */
+ __COMMCTL_FLUSH_OUTPUT,
+
+ /*
+ * Forces driver to enable or disable flushes when a newline is
+ * seen in the output stream. Flushing at line boundaries occurs
+ * in the driver, not necessarily any hardware FIFO, etc. Line
+ * buffering is optional and may only be available in some drivers.
+ */
+ __COMMCTL_ENABLE_LINE_FLUSH,
+ __COMMCTL_DISABLE_LINE_FLUSH,
+
+} __comm_control_cmd_t;
+
+
+#define CYGNUM_COMM_IF_CH_DATA 0
+#define CYGNUM_COMM_IF_WRITE 1
+#define CYGNUM_COMM_IF_READ 2
+#define CYGNUM_COMM_IF_PUTC 3
+#define CYGNUM_COMM_IF_GETC 4
+#define CYGNUM_COMM_IF_CONTROL 5
+#define CYGNUM_COMM_IF_DBG_ISR 6
+#define CYGNUM_COMM_IF_GETC_TIMEOUT 7
+
+#define CYGNUM_COMM_IF_TABLE_SIZE 8
+
+typedef volatile CYG_ADDRWORD hal_virtual_comm_table_t[CYGNUM_COMM_IF_TABLE_SIZE];
+
+// The below is a (messy) attempt at adding some type safety to the
+// above array. At the same time, the accessors allow the
+// implementation to be easily changed in the future (both tag->data
+// table and structure implementations have been suggested).
+
+typedef void* __comm_if_ch_data_t;
+typedef void (*__comm_if_write_t)(void* __ch_data, const cyg_uint8* __buf,
+ cyg_uint32 __len);
+typedef int (*__comm_if_read_t)(void* __ch_data, cyg_uint8* __buf,
+ cyg_uint32 __len);
+typedef void (*__comm_if_putc_t)(void* __ch_data, cyg_uint8 __ch);
+typedef cyg_uint8 (*__comm_if_getc_t)(void* __ch_data);
+typedef int (*__comm_if_control_t)(void *__ch_data,
+ __comm_control_cmd_t __func, ...);
+typedef int (*__comm_if_dbg_isr_t)(void *__ch_data,
+ int* __ctrlc, CYG_ADDRWORD __vec,
+ CYG_ADDRWORD __data);
+typedef cyg_bool (*__comm_if_getc_timeout_t)(void* __ch_data, cyg_uint8* __ch);
+
+#define __call_COMM0(_n_,_rt_,_t_) \
+static __inline__ _rt_ \
+__call_COMM_##_n_(hal_virtual_comm_table_t t) \
+{ \
+ _rt_ res; \
+ void *dp = (__comm_if_ch_data_t)t[CYGNUM_COMM_IF_CH_DATA]; \
+ _ENTER_MONITOR(); \
+ res = ((_t_)(t[CYGNUM_COMM_##_n_]))(dp); \
+ _EXIT_MONITOR(); \
+ return res; \
+}
+
+#define __call_voidCOMM(_n_,_rt_,_t_) \
+static __inline__ _rt_ \
+__call_COMM_##_n_(hal_virtual_comm_table_t t) \
+{ \
+ void *dp = (__comm_if_ch_data_t)t[CYGNUM_COMM_IF_CH_DATA]; \
+ _ENTER_MONITOR(); \
+ ((_t_)(t[CYGNUM_COMM_##_n_]))(dp); \
+ _EXIT_MONITOR(); \
+}
+
+#define __call_COMM1(_n_,_rt_,_t_,_t1_) \
+static __inline__ _rt_ \
+__call_COMM_##_n_(hal_virtual_comm_table_t t, _t1_ _p1_) \
+{ \
+ _rt_ res; \
+ void *dp = (__comm_if_ch_data_t)t[CYGNUM_COMM_IF_CH_DATA]; \
+ _ENTER_MONITOR(); \
+ res = ((_t_)(t[CYGNUM_COMM_##_n_]))(dp, _p1_); \
+ _EXIT_MONITOR(); \
+ return res; \
+}
+
+#define __call_voidCOMM1(_n_,_rt_,_t_,_t1_) \
+static __inline__ _rt_ \
+__call_COMM_##_n_(hal_virtual_comm_table_t t, _t1_ _p1_) \
+{ \
+ void *dp = (__comm_if_ch_data_t)t[CYGNUM_COMM_IF_CH_DATA]; \
+ _ENTER_MONITOR(); \
+ ((_t_)(t[CYGNUM_COMM_##_n_]))(dp, _p1_); \
+ _EXIT_MONITOR(); \
+}
+
+#define __call_COMM2(_n_,_rt_,_t_,_t1_,_t2_) \
+static __inline__ _rt_ \
+__call_COMM_##_n_(hal_virtual_comm_table_t t, _t1_ _p1_, _t2_ _p2_) \
+{ \
+ _rt_ res; \
+ void *dp = (__comm_if_ch_data_t)t[CYGNUM_COMM_IF_CH_DATA]; \
+ _ENTER_MONITOR(); \
+ res = ((_t_)(t[CYGNUM_COMM_##_n_]))(dp, _p1_, _p2_); \
+ _EXIT_MONITOR(); \
+ return res; \
+}
+
+#define __call_voidCOMM2(_n_,_rt_,_t_,_t1_,_t2_) \
+static __inline__ _rt_ \
+__call_COMM_##_n_(hal_virtual_comm_table_t t, _t1_ _p1_, _t2_ _p2_) \
+{ \
+ void *dp = (__comm_if_ch_data_t)t[CYGNUM_COMM_IF_CH_DATA]; \
+ _ENTER_MONITOR(); \
+ ((_t_)(t[CYGNUM_COMM_##_n_]))(dp, _p1_, _p2_); \
+ _EXIT_MONITOR(); \
+}
+
+#define __call_COMM3(_n_,_rt_,_t_,_t1_,_t2_,_t3_) \
+static __inline__ _rt_ \
+__call_COMM_##_n_(hal_virtual_comm_table_t t, _t1_ _p1_, _t2_ _p2_, _t3_ _p3_) \
+{ \
+ _rt_ res; \
+ void *dp = (__comm_if_ch_data_t)t[CYGNUM_COMM_IF_CH_DATA]; \
+ _ENTER_MONITOR(); \
+ res = ((_t_)(t[CYGNUM_COMM_##_n_]))(dp, _p1_, _p2_, _p3_); \
+ _EXIT_MONITOR(); \
+ return res; \
+}
+
+#define __call_voidCOMM3(_n_,_rt_,_t_,_t1_,_t2_,_t3_) \
+static __inline__ _rt_ \
+__call_COMM_##_n_(hal_virtual_comm_table_t t, _t1_ _p1_, _t2_ _p2_, _t3_ _p3_) \
+{ \
+ void *dp = (__comm_if_ch_data_t)t[CYGNUM_COMM_IF_CH_DATA]; \
+ _ENTER_MONITOR(); \
+ ((_t_)(t[CYGNUM_COMM_##_n_]))(dp, _p1_, _p2_, _p3_); \
+ _EXIT_MONITOR(); \
+}
+
+#ifndef CYGACC_COMM_IF_DEFINED
+
+#define CYGACC_COMM_IF_CH_DATA(_t_) \
+ ((__comm_if_ch_data_t)((_t_)[CYGNUM_COMM_IF_CH_DATA]))
+#define CYGACC_COMM_IF_CH_DATA_SET(_t_, _x_) \
+ (_t_)[CYGNUM_COMM_IF_CH_DATA]=(CYG_ADDRWORD)(_x_)
+
+__call_voidCOMM2(IF_WRITE, void, __comm_if_write_t, const cyg_uint8 *, cyg_uint32)
+#define CYGACC_COMM_IF_WRITE(_t_, _b_, _l_) \
+ __call_COMM_IF_WRITE(_t_, _b_, _l_)
+#define CYGACC_COMM_IF_WRITE_SET(_t_, _x_) \
+ (_t_)[CYGNUM_COMM_IF_WRITE]=(CYG_ADDRWORD)(_x_)
+
+__call_voidCOMM2(IF_READ, void, __comm_if_read_t, cyg_uint8 *, cyg_uint32)
+#define CYGACC_COMM_IF_READ(_t_, _b_, _l_) \
+ __call_COMM_IF_READ(_t_, _b_, _l_)
+#define CYGACC_COMM_IF_READ_SET(_t_, _x_) \
+ (_t_)[CYGNUM_COMM_IF_READ]=(CYG_ADDRWORD)(_x_)
+
+__call_voidCOMM1(IF_PUTC, void, __comm_if_putc_t, cyg_uint8)
+#define CYGACC_COMM_IF_PUTC(_t_, _c_) \
+ __call_COMM_IF_PUTC(_t_,_c_)
+#define CYGACC_COMM_IF_PUTC_SET(_t_, _x_) \
+ (_t_)[CYGNUM_COMM_IF_PUTC]=(CYG_ADDRWORD)(_x_)
+
+__call_COMM0(IF_GETC, cyg_uint8, __comm_if_getc_t)
+#define CYGACC_COMM_IF_GETC(_t_) \
+ __call_COMM_IF_GETC(_t_)
+#define CYGACC_COMM_IF_GETC_SET(_t_, _x_) \
+ (_t_)[CYGNUM_COMM_IF_GETC]=(CYG_ADDRWORD)(_x_)
+
+// This macro has not been changed to use inline functions like the
+// others, simply because it uses variable arguments, and the change
+// would break binary compatibility.
+#define CYGACC_COMM_IF_CONTROL(_t_, args...) \
+ ({ int res; \
+ _ENTER_MONITOR(); \
+ res = ((__comm_if_control_t)((_t_)[CYGNUM_COMM_IF_CONTROL]))(CYGACC_COMM_IF_CH_DATA(_t_), args); \
+ _EXIT_MONITOR(); \
+ res;})
+#define CYGACC_COMM_IF_CONTROL_SET(_t_, _x_) \
+ (_t_)[CYGNUM_COMM_IF_CONTROL]=(CYG_ADDRWORD)(_x_)
+
+__call_COMM3(IF_DBG_ISR, int, __comm_if_dbg_isr_t, int *, CYG_ADDRWORD, CYG_ADDRWORD)
+#define CYGACC_COMM_IF_DBG_ISR(_t_, _c_, _v_, _d_) \
+ __call_COMM_IF_DBG_ISR(_t_, _c_, _v_, _d_)
+#define CYGACC_COMM_IF_DBG_ISR_SET(_t_, _x_) \
+ (_t_)[CYGNUM_COMM_IF_DBG_ISR]=(CYG_ADDRWORD)(_x_)
+
+__call_COMM1(IF_GETC_TIMEOUT, cyg_bool, __comm_if_getc_timeout_t, cyg_uint8 *)
+#define CYGACC_COMM_IF_GETC_TIMEOUT(_t_, _c_) \
+ __call_COMM_IF_GETC_TIMEOUT(_t_, _c_)
+#define CYGACC_COMM_IF_GETC_TIMEOUT_SET(_t_, _x_) \
+ (_t_)[CYGNUM_COMM_IF_GETC_TIMEOUT]=(CYG_ADDRWORD)(_x_)
+
+#endif // CYGACC_COMM_IF_DEFINED
+
+//--------------------------------------------------------------------------
+// Main calling interface table. Will be assigned a location by the
+// linker script. Both ROM and RAM startup applications will know about
+// the location.
+#define CYGNUM_CALL_IF_VERSION 0
+#define CYGNUM_CALL_IF_available_1 1
+#define CYGNUM_CALL_IF_available_2 2
+#define CYGNUM_CALL_IF_available_3 3
+#define CYGNUM_CALL_IF_KILL_VECTOR 4
+#define CYGNUM_CALL_IF_CONSOLE_PROCS 5
+#define CYGNUM_CALL_IF_DEBUG_PROCS 6
+#define CYGNUM_CALL_IF_available_7 7
+#define CYGNUM_CALL_IF_available_8 8
+#define CYGNUM_CALL_IF_available_9 9
+#define CYGNUM_CALL_IF_available_10 10
+#define CYGNUM_CALL_IF_available_11 11
+#define CYGNUM_CALL_IF_SET_DEBUG_COMM 12
+#define CYGNUM_CALL_IF_SET_CONSOLE_COMM 13
+#define CYGNUM_CALL_IF_MONITOR_VERSION 14
+#define CYGNUM_CALL_IF_DBG_SYSCALL 15
+#define CYGNUM_CALL_IF_RESET 16
+#define CYGNUM_CALL_IF_CONSOLE_INTERRUPT_FLAG 17
+#define CYGNUM_CALL_IF_DELAY_US 18
+#define CYGNUM_CALL_IF_DBG_DATA 19
+#define CYGNUM_CALL_IF_FLASH_CFG_OP 20
+#define CYGNUM_CALL_IF_MONITOR_RETURN 21
+#define CYGNUM_CALL_IF_FLASH_FIS_OP 22
+#define CYGNUM_CALL_IF_FLASH_FIS_OP2 23
+
+#define CYGNUM_CALL_IF_LAST_ENTRY CYGNUM_CALL_IF_FLASH_FIS_OP2
+
+#define CYGNUM_CALL_IF_INSTALL_BPT_FN 35
+
+#define CYGNUM_CALL_IF_TABLE_SIZE 64
+
+externC volatile CYG_ADDRWORD hal_virtual_vector_table[CYGNUM_CALL_IF_TABLE_SIZE];
+
+// Table version contains version information for both the CALL table
+// itself (the number of the last active entry in the table), and the
+// COMM table (the size of the table).
+#define CYGNUM_CALL_IF_TABLE_VERSION_CALL CYGNUM_CALL_IF_LAST_ENTRY
+#define CYGNUM_CALL_IF_TABLE_VERSION_CALL_HACK (CYGNUM_CALL_IF_TABLE_SIZE+1)
+#define CYGNUM_CALL_IF_TABLE_VERSION_CALL_MAX CYGNUM_CALL_IF_TABLE_SIZE
+#define CYGNUM_CALL_IF_TABLE_VERSION_COMM CYGNUM_COMM_IF_TABLE_SIZE
+#define CYGNUM_CALL_IF_TABLE_VERSION_CALL_MASK 0x0000ffff
+#define CYGNUM_CALL_IF_TABLE_VERSION_COMM_MASK 0xffff0000
+#define CYGNUM_CALL_IF_TABLE_VERSION_COMM_shift 16
+
+
+// These are special debug/console procs IDs
+// QUERY_CURRENT will cause the ID of the currently selected proc ID to be
+// returned.
+// EMPTY this is the ID used for an empty procs table (i.e, NULL
+// pointer)
+// MANGLER selects the procs space reserved for the console mangler
+// allowing the application to temporarily disable mangling
+// or temporarily switch in different console procs.
+#define CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT -1
+#define CYGNUM_CALL_IF_SET_COMM_ID_EMPTY -2
+#define CYGNUM_CALL_IF_SET_COMM_ID_MANGLER -3
+
+// The below is a (messy) attempt at adding some type safety to the
+// above array. At the same time, the accessors allow the
+// implementation to be easily changed in the future (both tag->data
+// table and structure implementations have been suggested).
+
+typedef int __call_if_version_t;
+typedef void* __call_if_ictrl_table_t;
+typedef void* __call_if_exc_table_t;
+typedef bsp_handler_t *__call_if_dbg_vector_t;
+typedef bsp_handler_t __call_if_kill_vector_t;
+typedef hal_virtual_comm_table_t *__call_if_console_procs_t;
+typedef hal_virtual_comm_table_t *__call_if_debug_procs_t;
+typedef int (__call_if_set_debug_comm_t)(int __comm_id);
+typedef int (__call_if_set_console_comm_t)(int __comm_id);
+typedef void* __call_if_dbg_data_t;
+typedef int (__call_if_dbg_syscall_t) (enum dbg_syscall_ids id,
+ union dbg_thread_syscall_parms *p );
+typedef void (__call_if_reset_t)(void);
+typedef int __call_if_console_interrupt_flag_t;
+typedef void (__call_if_delay_us_t)(cyg_int32 usecs);
+typedef void (__call_if_install_bpt_fn_t)(void *__epc);
+typedef char *__call_if_monitor_version_t;
+typedef void (__call_if_monitor_return_t)(int status);
+typedef cyg_bool (__call_if_flash_fis_op_fn_t)(int __oper, char *__name, void *__val);
+
+//
+// This structure is used to pass parameters to/from the fis routines
+//
+struct fis_table_entry {
+ unsigned char name[16];
+ CYG_ADDRESS flash_base;
+ CYG_ADDRESS mem_base;
+ unsigned long size;
+ CYG_ADDRESS entry_point;
+ unsigned long data_length;
+ unsigned long desc_cksum;
+ unsigned long file_cksum;
+};
+
+typedef int (__call_if_flash_fis_op2_fn_t)(int __oper, unsigned int index, struct fis_table_entry *__fis_entry);
+//
+// This structure is used to pass parameters to/from the fconfig routines.
+// This allows a single virtual vector interface, with widely varying functionality
+//
+struct cyg_fconfig {
+ char *key; // Datum 'key'
+ int keylen; // Length of key
+ void *val; // Pointer to data
+ int type; // Type of datum
+ int offset; // Offset within data (used by _NEXT)
+};
+typedef cyg_bool (__call_if_flash_cfg_op_fn_t)(int __oper, struct cyg_fconfig *__data);
+
+#ifndef CYGACC_CALL_IF_DEFINED
+
+#define __data_VV(_n_,_tt_) \
+static __inline__ _tt_ \
+__call_vv_##_n_(void) \
+{ \
+ return ((_tt_)hal_virtual_vector_table[_n_]); \
+}
+
+#define __call_VV0(_n_,_tt_,_rt_) \
+static __inline__ _rt_ \
+__call_vv_##_n_(void) \
+{ \
+ _rt_ res; \
+ _ENTER_MONITOR(); \
+ res = ((_tt_ *)hal_virtual_vector_table[_n_])(); \
+ _EXIT_MONITOR(); \
+ return res; \
+}
+
+#define __call_voidVV0(_n_,_tt_,_rt_) \
+static __inline__ _rt_ \
+__call_vv_##_n_(void) \
+{ \
+ _ENTER_MONITOR(); \
+ ((_tt_ *)hal_virtual_vector_table[_n_])(); \
+ _EXIT_MONITOR(); \
+}
+
+#define __call_VV1(_n_,_tt_,_rt_,_t1_) \
+static __inline__ _rt_ \
+__call_vv_##_n_(_t1_ _p1_) \
+{ \
+ _rt_ res; \
+ _ENTER_MONITOR(); \
+ res = ((_tt_ *)hal_virtual_vector_table[_n_])(_p1_); \
+ _EXIT_MONITOR(); \
+ return res; \
+}
+
+#define __call_voidVV1(_n_,_tt_,_rt_,_t1_) \
+static __inline__ _rt_ \
+__call_vv_##_n_(_t1_ _p1_) \
+{ \
+ _ENTER_MONITOR(); \
+ ((_tt_ *)hal_virtual_vector_table[_n_])(_p1_); \
+ _EXIT_MONITOR(); \
+}
+
+#define __call_VV2(_n_,_tt_,_rt_,_t1_,_t2_) \
+static __inline__ _rt_ \
+__call_vv_##_n_(_t1_ _p1_, _t2_ _p2_) \
+{ \
+ _rt_ res; \
+ _ENTER_MONITOR(); \
+ res = ((_tt_ *)hal_virtual_vector_table[_n_])(_p1_,_p2_); \
+ _EXIT_MONITOR(); \
+ return res; \
+}
+
+#define __call_voidVV2(_n_,_tt_,_rt_,_t1_,_t2_) \
+static __inline__ _rt_ \
+__call_vv_##_n_(_t1_ _p1_, _t2_ _p2_) \
+{ \
+ _ENTER_MONITOR(); \
+ ((_tt_ *)hal_virtual_vector_table[_n_])(_p1_,_p2_); \
+ _EXIT_MONITOR(); \
+}
+
+#define __call_VV3(_n_,_tt_,_rt_,_t1_,_t2_,_t3_) \
+static __inline__ _rt_ \
+__call_vv_##_n_(_t1_ _p1_, _t2_ _p2_, _t3_ _p3_) \
+{ \
+ _rt_ res; \
+ _ENTER_MONITOR(); \
+ res = ((_tt_ *)hal_virtual_vector_table[_n_])(_p1_,_p2_,_p3_); \
+ _EXIT_MONITOR(); \
+ return res; \
+}
+
+#define __call_voidVV3(_n_,_tt_,_rt_,_t1_,_t2_,_t3_) \
+static __inline__ _rt_ \
+__call_vv_##_n_(_t1_ _p1_, _t2_ _p2_, _t3_ _p3_) \
+{ \
+ _ENTER_MONITOR(); \
+ ((_tt_ *)hal_virtual_vector_table[_n_])(_p1_,_p2_,_p3_); \
+ _EXIT_MONITOR(); \
+}
+
+#define __call_VV4(_n_,_tt_,_rt_,_t1_,_t2_,_t3_,_t4_) \
+static __inline__ _rt_ \
+__call_vv_##_n_(_t1_ _p1_, _t2_ _p2_, _t3_ _p3_, _t4_ _p4_) \
+{ \
+ _rt_ res; \
+ _ENTER_MONITOR(); \
+ res = ((_tt_ *)hal_virtual_vector_table[_n_])(_p1_,_p2_,_p3_,_p4_); \
+ _EXIT_MONITOR(); \
+ return res; \
+}
+
+#define __call_voidVV4(_n_,_tt_,_rt_,_t1_,_t2_,_t3_,_t4_) \
+static __inline__ _rt_ \
+__call_vv_##_n_(_t1_ _p1_, _t2_ _p2_, _t3_ _p3_, _t4_ _p4_) \
+{ \
+ _ENTER_MONITOR(); \
+ ((_tt_ *)hal_virtual_vector_table[_n_])(_p1_,_p2_,_p3_,_p4_); \
+ _EXIT_MONITOR(); \
+}
+
+
+#define CYGACC_DATA_VV(t,e) __call_vv_##e()
+#define CYGACC_CALL_VV0(t,e) __call_vv_##e
+#define CYGACC_CALL_VV1(t,e,p1) __call_vv_##e((p1))
+#define CYGACC_CALL_VV2(t,e,p1,p2) __call_vv_##e((p1),(p2))
+#define CYGACC_CALL_VV3(t,e,p1,p2,p3) __call_vv_##e((p1),(p2),(p3))
+#define CYGACC_CALL_VV4(t,e,p1,p2,p3,p4) __call_vv_##e((p1),(p2),(p3),(p4))
+
+#define CYGACC_CALL_IF_VERSION() \
+ CYGACC_DATA_VV(__call_if_version_t, CYGNUM_CALL_IF_VERSION)
+__data_VV(CYGNUM_CALL_IF_VERSION, __call_if_version_t)
+#define CYGACC_CALL_IF_VERSION_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_VERSION]=(CYG_ADDRWORD)(_x_)
+
+#define CYGACC_CALL_IF_KILL_VECTOR() \
+ CYGACC_DATA_VV(__call_if_kill_vector_t, CYGNUM_CALL_IF_KILL_VECTOR)
+__data_VV(CYGNUM_CALL_IF_KILL_VECTOR, __call_if_kill_vector_t)
+#define CYGACC_CALL_IF_KILL_VECTOR_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_KILL_VECTOR]=(CYG_ADDRWORD)(_x_)
+
+#define CYGACC_CALL_IF_CONSOLE_PROCS() \
+ CYGACC_DATA_VV(__call_if_console_procs_t, CYGNUM_CALL_IF_CONSOLE_PROCS)
+__data_VV(CYGNUM_CALL_IF_CONSOLE_PROCS, __call_if_console_procs_t)
+#define CYGACC_CALL_IF_CONSOLE_PROCS_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_CONSOLE_PROCS]=(CYG_ADDRWORD)(_x_)
+
+#define CYGACC_CALL_IF_DEBUG_PROCS() \
+ CYGACC_DATA_VV(__call_if_debug_procs_t, CYGNUM_CALL_IF_DEBUG_PROCS)
+__data_VV(CYGNUM_CALL_IF_DEBUG_PROCS, __call_if_debug_procs_t)
+#define CYGACC_CALL_IF_DEBUG_PROCS_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_DEBUG_PROCS]=(CYG_ADDRWORD)(_x_)
+
+#define CYGACC_CALL_IF_SET_DEBUG_COMM(_i_) \
+ CYGACC_CALL_VV1(__call_if_set_debug_comm_t*, CYGNUM_CALL_IF_SET_DEBUG_COMM, (_i_))
+__call_VV1(CYGNUM_CALL_IF_SET_DEBUG_COMM, __call_if_set_debug_comm_t, int, int)
+#define CYGACC_CALL_IF_SET_DEBUG_COMM_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_SET_DEBUG_COMM]=(CYG_ADDRWORD)(_x_)
+
+#define CYGACC_CALL_IF_SET_CONSOLE_COMM(_i_) \
+ CYGACC_CALL_VV1(__call_if_set_console_comm_t*, CYGNUM_CALL_IF_SET_CONSOLE_COMM, (_i_))
+__call_VV1(CYGNUM_CALL_IF_SET_CONSOLE_COMM, __call_if_set_console_comm_t, int, int)
+#define CYGACC_CALL_IF_SET_CONSOLE_COMM_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_SET_CONSOLE_COMM]=(CYG_ADDRWORD)(_x_)
+
+#define CYGACC_CALL_IF_DBG_DATA() \
+ CYGACC_DATA_VV(__call_if_dbg_data_t, CYGNUM_CALL_IF_DBG_DATA)
+__data_VV(CYGNUM_CALL_IF_DBG_DATA, __call_if_dbg_data_t)
+#define CYGACC_CALL_IF_DBG_DATA_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_DBG_DATA]=(CYG_ADDRWORD)(_x_)
+
+#define CYGACC_CALL_IF_DBG_SYSCALL(_id_,_p_) \
+ CYGACC_CALL_VV2(__call_if_dbg_syscall_t, CYGNUM_CALL_IF_DBG_SYSCALL, _id_, _p_)
+__call_VV2(CYGNUM_CALL_IF_DBG_SYSCALL, __call_if_dbg_syscall_t, int, enum dbg_syscall_ids , union dbg_thread_syscall_parms *)
+#define CYGACC_CALL_IF_DBG_SYSCALL_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_DBG_SYSCALL]=(CYG_ADDRWORD)(_x_)
+
+#define CYGACC_CALL_IF_RESET() \
+ CYGACC_CALL_VV0(__call_if_reset_t*, CYGNUM_CALL_IF_RESET)()
+__call_voidVV0(CYGNUM_CALL_IF_RESET, __call_if_reset_t, void)
+#define CYGACC_CALL_IF_RESET_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_RESET]=(CYG_ADDRWORD)(_x_)
+#define CYGACC_CALL_IF_RESET_GET() \
+ ((__call_if_reset_t*)hal_virtual_vector_table[CYGNUM_CALL_IF_RESET])
+
+#define CYGACC_CALL_IF_MONITOR_VERSION() \
+ CYGACC_DATA_VV(__call_if_monitor_version_t, CYGNUM_CALL_IF_MONITOR_VERSION)
+__data_VV(CYGNUM_CALL_IF_MONITOR_VERSION, __call_if_monitor_version_t)
+#define CYGACC_CALL_IF_MONITOR_VERSION_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_MONITOR_VERSION]=(CYG_ADDRWORD)(_x_)
+
+#define CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG() \
+ CYGACC_DATA_VV(__call_if_console_interrupt_flag_t, CYGNUM_CALL_IF_CONSOLE_INTERRUPT_FLAG)
+__data_VV(CYGNUM_CALL_IF_CONSOLE_INTERRUPT_FLAG, __call_if_console_interrupt_flag_t)
+#define CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_CONSOLE_INTERRUPT_FLAG]=(CYG_ADDRWORD)(_x_)
+
+#define CYGACC_CALL_IF_DELAY_US(_u_) \
+ CYGACC_CALL_VV1(__call_if_delay_us_t*, CYGNUM_CALL_IF_DELAY_US, (_u_))
+__call_voidVV1(CYGNUM_CALL_IF_DELAY_US, __call_if_delay_us_t, void, cyg_int32)
+#define CYGACC_CALL_IF_DELAY_US_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_DELAY_US]=(CYG_ADDRWORD)(_x_)
+
+#define CYGACC_CALL_IF_INSTALL_BPT_FN(_e_) \
+ CYGACC_CALL_VV1(__call_if_install_bpt_fn_t*, CYGNUM_CALL_IF_INSTALL_BPT_FN, (_e_))
+__call_voidVV1(CYGNUM_CALL_IF_INSTALL_BPT_FN, __call_if_install_bpt_fn_t, void, void *)
+#define CYGACC_CALL_IF_INSTALL_BPT_FN_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_INSTALL_BPT_FN]=(CYG_ADDRWORD)(_x_)
+
+//
+// Access persistent data store - kept in FLASH or EEPROM by RedBoot
+//
+#define CYGNUM_CALL_IF_FLASH_CFG_GET (0) // Get a particular fconfig key
+#define CYGNUM_CALL_IF_FLASH_CFG_NEXT (1) // Enumerate keys (get the next one)
+#define CYGNUM_CALL_IF_FLASH_CFG_SET (2) // Update particular fconfig key
+#define CYGACC_CALL_IF_FLASH_CFG_OP2(_o_,_d_) \
+ CYGACC_CALL_VV2(__call_if_flash_cfg_op_fn_t*, CYGNUM_CALL_IF_FLASH_CFG_OP, (_o_),(_d_))
+__call_VV2(CYGNUM_CALL_IF_FLASH_CFG_OP, __call_if_flash_cfg_op_fn_t, cyg_bool, int, struct cyg_fconfig *)
+
+static __inline__ cyg_bool
+__call_if_flash_cfg_op(int op, char *key, void *data, int type)
+{
+ struct cyg_fconfig info;
+ info.key = key;
+ info.val = data;
+ info.type = type;
+ info.offset = 0;
+ return CYGACC_CALL_IF_FLASH_CFG_OP2(op, &info);
+}
+#define CYGACC_CALL_IF_FLASH_CFG_OP(_o_,_k_,_d_,_t_) \
+ __call_if_flash_cfg_op(_o_,_k_,_d_,_t_)
+#define CYGACC_CALL_IF_FLASH_CFG_OP_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_FLASH_CFG_OP]=(CYG_ADDRWORD)(_x_)
+
+#define CYGACC_CALL_IF_MONITOR_RETURN(_u_) \
+ CYGACC_CALL_VV1(__call_if_monitor_return_t*, CYGNUM_CALL_IF_MONITOR_RETURN, (_u_))
+__call_voidVV1(CYGNUM_CALL_IF_MONITOR_RETURN, __call_if_monitor_return_t, void, int)
+#define CYGACC_CALL_IF_MONITOR_RETURN_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_MONITOR_RETURN]=(CYG_ADDRWORD)(_x_)
+
+#define CYGACC_CALL_IF_FLASH_FIS_OP(_o_,_k_,_d_) \
+ CYGACC_CALL_VV3(__call_if_flash_fis_op_fn_t*, CYGNUM_CALL_IF_FLASH_FIS_OP, (_o_),(_k_),(_d_))
+__call_VV3(CYGNUM_CALL_IF_FLASH_FIS_OP, __call_if_flash_fis_op_fn_t, cyg_bool, int, char *, void *)
+#define CYGACC_CALL_IF_FLASH_FIS_OP_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_FLASH_FIS_OP]=(CYG_ADDRWORD)(_x_)
+#define CYGNUM_CALL_IF_FLASH_FIS_GET_FLASH_BASE (0)
+#define CYGNUM_CALL_IF_FLASH_FIS_GET_SIZE (1)
+#define CYGNUM_CALL_IF_FLASH_FIS_GET_MEM_BASE (2)
+#define CYGNUM_CALL_IF_FLASH_FIS_GET_ENTRY_POINT (3)
+#define CYGNUM_CALL_IF_FLASH_FIS_GET_DATA_LENGTH (4)
+#define CYGNUM_CALL_IF_FLASH_FIS_GET_DESC_CKSUM (5)
+#define CYGNUM_CALL_IF_FLASH_FIS_GET_FILE_CKSUM (6)
+
+#define CYGACC_CALL_IF_FLASH_FIS_OP2(_o_,_k_,_d_) \
+ CYGACC_CALL_VV3(__call_if_flash_fis_op2_fn_t*, CYGNUM_CALL_IF_FLASH_FIS_OP2, (_o_),(_k_),(_d_))
+__call_VV3(CYGNUM_CALL_IF_FLASH_FIS_OP2, __call_if_flash_fis_op2_fn_t, int, int, unsigned int, struct fis_table_entry *)
+#define CYGACC_CALL_IF_FLASH_FIS_OP2_SET(_x_) \
+ hal_virtual_vector_table[CYGNUM_CALL_IF_FLASH_FIS_OP2]=(CYG_ADDRWORD)(_x_)
+#define CYGNUM_CALL_IF_FLASH_FIS_GET_VERSION (0)
+#define CYGNUM_CALL_IF_FLASH_FIS_INIT (1)
+#define CYGNUM_CALL_IF_FLASH_FIS_GET_ENTRY_COUNT (2)
+#define CYGNUM_CALL_IF_FLASH_FIS_GET_ENTRY (3)
+#define CYGNUM_CALL_IF_FLASH_FIS_START_UPDATE (4)
+#define CYGNUM_CALL_IF_FLASH_FIS_FINISH_UPDATE (5)
+#define CYGNUM_CALL_IF_FLASH_FIS_MODIFY_ENTRY (6)
+
+
+
+// These need to be kept uptodate with the (unadorned) masters
+// in RedBoot's flash_config.h:
+#define CYGNUM_FLASH_CFG_TYPE_CONFIG_EMPTY 0
+#define CYGNUM_FLASH_CFG_TYPE_CONFIG_BOOL 1
+#define CYGNUM_FLASH_CFG_TYPE_CONFIG_INT 2
+#define CYGNUM_FLASH_CFG_TYPE_CONFIG_STRING 3
+#define CYGNUM_FLASH_CFG_TYPE_CONFIG_SCRIPT 4
+#define CYGNUM_FLASH_CFG_TYPE_CONFIG_IP 5
+#define CYGNUM_FLASH_CFG_TYPE_CONFIG_ESA 6
+
+#endif // CYGACC_CALL_IF_DEFINED
+
+//--------------------------------------------------------------------------
+// Diag wrappers.
+externC void hal_if_diag_init(void);
+externC void hal_if_diag_write_char(char c);
+externC void hal_if_diag_read_char(char *c);
+
+//--------------------------------------------------------------------------
+// Ctrl-c support.
+externC cyg_uint32 hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
+externC cyg_bool hal_ctrlc_check(CYG_ADDRWORD vector, CYG_ADDRWORD data);
+
+#define HAL_CTRLC_ISR hal_ctrlc_isr
+#define HAL_CTRLC_CHECK hal_ctrlc_check
+
+#else
+
+#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \
+ || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
+// Then other code might invoke this macro
+#define HAL_CTRLC_CHECK(a1,a2) (0) // Nothing, no CTRLC here
+#endif
+
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+//--------------------------------------------------------------------------
+// Functions provided by the HAL interface.
+externC void hal_if_init(void);
+#if 0 != CYGINT_HAL_PLF_IF_INIT
+externC void plf_if_init(void);
+#endif
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_HAL_HAL_IF_H
+// End of hal_if.h
diff --git a/ecos/packages/hal/common/current/include/hal_misc.h b/ecos/packages/hal/common/current/include/hal_misc.h
new file mode 100644
index 0000000..22f0c16
--- /dev/null
+++ b/ecos/packages/hal/common/current/include/hal_misc.h
@@ -0,0 +1,122 @@
+#ifndef CYGONCE_HAL_HAL_MISC_H
+#define CYGONCE_HAL_HAL_MISC_H
+
+//=============================================================================
+//
+// hal_misc.h
+//
+// HAL header for miscellaneous helper routines
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 2000-06-08
+// Purpose: Miscellaneous routines shared between HALs
+// Usage: #include <cyg/hal/hal_misc.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#ifndef __ASSEMBLER__
+#include <cyg/infra/cyg_type.h> // types & externC
+
+//=============================================================================
+externC cyg_bool cyg_hal_is_break(char *buf, int size);
+externC void cyg_hal_user_break( CYG_ADDRWORD *regs );
+#endif
+
+//=============================================================================
+
+#define BIT0 0x00000001
+#define BIT1 0x00000002
+#define BIT2 0x00000004
+#define BIT3 0x00000008
+#define BIT4 0x00000010
+#define BIT5 0x00000020
+#define BIT6 0x00000040
+#define BIT7 0x00000080
+#define BIT8 0x00000100
+#define BIT9 0x00000200
+#define BIT10 0x00000400
+#define BIT11 0x00000800
+#define BIT12 0x00001000
+#define BIT13 0x00002000
+#define BIT14 0x00004000
+#define BIT15 0x00008000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+
+#define SZ_1K 0x00000400
+#define SZ_2K 0x00000800
+#define SZ_4K 0x00001000
+#define SZ_8K 0x00002000
+#define SZ_16K 0x00004000
+#define SZ_32K 0x00008000
+#define SZ_64K 0x00010000
+#define SZ_128K 0x00020000
+#define SZ_256K 0x00040000
+#define SZ_512K 0x00080000
+#define SZ_1M 0x00100000
+#define SZ_2M 0x00200000
+#define SZ_4M 0x00400000
+#define SZ_8M 0x00800000
+#define SZ_16M 0x01000000
+#define SZ_32M 0x02000000
+#define SZ_64M 0x04000000
+#define SZ_128M 0x08000000
+#define SZ_256M 0x10000000
+#define SZ_512M 0x20000000
+#define SZ_1G 0x40000000
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_HAL_HAL_MISC_H
+// End of hal_misc.h
diff --git a/ecos/packages/hal/common/current/include/hal_spd.h b/ecos/packages/hal/common/current/include/hal_spd.h
new file mode 100644
index 0000000..677cff7
--- /dev/null
+++ b/ecos/packages/hal/common/current/include/hal_spd.h
@@ -0,0 +1,77 @@
+#ifndef CYGONCE_HAL_HAL_SPD_H
+#define CYGONCE_HAL_HAL_SPD_H
+
+//=============================================================================
+//
+// hal_spd.h
+//
+// HAL header for SDRAM Serial Presence Detect support.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): msalter
+// Contributors:msalter
+// Date: 2002-01-17
+// Purpose: Generic HAL SPD header.
+// Usage: #include <cyg/hal/hal_spd.h>
+// Description: This header provides byte numbers and bit definitions for
+// serial EEPROM containing SDRAM module information.
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+// Commonly used bytes
+#define SPD_BANKCNT 5 // number of module banks
+#define SPD_CONFIG 11 // DIMM configuration type (Parity or not, EEC)
+#define SPD_REFRESH 12 // Referesh rate
+#define SPD_SDRAM_WIDTH 13 // DRAM width
+#define SPD_MOD_ATTRIB 21 // DRAM module attribute
+#define SPD_BANKSZ 31 // module bank density
+#define SPD_CHECKSUM 63 // checksum for bytes 0-62
+
+// SPD_MOD_ATTRIB bits
+#define SPD_ATTRIB_BUF_CTL 0x01 // Buffered Addr/Control inputs
+#define SPD_ATTRIB_REG_CTL 0x02 // Registered Addr/Control inputs
+#define SPD_ATTRIB_PLL 0x04 // On-card PLL
+#define SPD_ATTRIB_BUF_DQ 0x08 // Buffered DQMB inputs
+#define SPD_ATTRIB_REG_DQ 0x10 // Registered DQMB inputs
+#define SPD_ATTRIB_DIFF 0x20 // Differential clock input
+#define SPD_ATTRIB_RRA 0x40 // Redundant Row Address
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_HAL_HAL_SPD_H
+// End of hal_spd.h
diff --git a/ecos/packages/hal/common/current/include/hal_stub.h b/ecos/packages/hal/common/current/include/hal_stub.h
new file mode 100644
index 0000000..009ebbb
--- /dev/null
+++ b/ecos/packages/hal/common/current/include/hal_stub.h
@@ -0,0 +1,406 @@
+#ifndef CYGONCE_HAL_HAL_STUB_H
+#define CYGONCE_HAL_HAL_STUB_H
+
+//=============================================================================
+//
+// hal_stub.h
+//
+// HAL header for GDB stub support.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 1999-02-12
+// Purpose: Generic HAL stub header.
+// Usage: #include <cyg/hal/hal_stub.h>
+// Description: This header is included by generic-stub.c to provide an
+// interface to the eCos-specific stub implementation. It is
+// not to be included by user code, and is only placed in a
+// publically accessible directory so that platform stub packages
+// are able to include it if required.
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+#define USE_GDBSTUB_PROTOTYPES 0 // avoid stub-tservice.h atm
+#ifndef __ECOS__
+#define __ECOS__ // use to mark eCos hacks
+#endif
+
+#include <cyg/hal/basetype.h> // HAL_LABEL_NAME
+#include <cyg/hal/hal_arch.h> // HAL header
+#include <cyg/infra/cyg_type.h> // cyg_uint32 and CYG_BYTEORDER
+
+#ifndef __CYGMON_TYPES
+#define __CYGMON_TYPES
+typedef cyg_uint32 uint32;
+typedef cyg_int32 int32;
+#endif // __CYGMON_TYPES
+
+#ifdef CYGBLD_HAL_PLATFORM_STUB_H
+#include CYGBLD_HAL_PLATFORM_STUB_H
+#else
+#include <cyg/hal/plf_stub.h>
+#endif
+#include <cyg/hal/generic-stub.h>
+
+// Some architectures use registers of different sizes, so NUMREGS
+// alone is not sufficient to size the register save area. For those
+// architectures, HAL_STUB_REGISTERS_SIZE is defined as the number
+// of target_register_t sized elements in the register save area.
+#ifndef HAL_STUB_REGISTERS_SIZE
+#define HAL_STUB_REGISTERS_SIZE NUMREGS
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if 0
+} // to make below format correctly.
+#endif
+
+//-----------------------------------------------------------------------------
+// Definitions for generic-stub.c
+
+#define __set_mem_fault_trap(x) ({__mem_fault = 0; x(); __mem_fault;})
+
+#if (CYG_BYTEORDER==CYG_LSBFIRST)
+# if !defined(__LITTLE_ENDIAN__)
+# define __LITTLE_ENDIAN__
+# endif
+# if !defined(_LITTLE_ENDIAN)
+# define _LITTLE_ENDIAN
+# endif
+#endif
+
+//-----------------------------------------------------------------------------
+// Dummy definitions for harvard memory support for princeton memory systems.
+#ifndef TARGET_HAS_HARVARD_MEMORY
+typedef target_register_t target_addr_t;
+#define TARGET_ADDR_IS_PROGMEM(x) 0
+#define TARGET_ADDR_TO_PTR(x) ((char *) (x))
+#endif
+
+//----------------------------------------------------------------------------
+// Signal definitions to avoid 'signal.h'/
+#define SIGHUP 1 /* hangup */
+#define SIGINT 2 /* interrupt */
+#define SIGQUIT 3 /* quit */
+#define SIGILL 4 /* illegal instruction (not reset when caught) */
+#define SIGTRAP 5 /* trace trap (not reset when caught) */
+#define SIGIOT 6 /* IOT instruction */
+#define SIGABRT 6 /* used by abort, replace SIGIOT in the future */
+#define SIGEMT 7 /* EMT instruction */
+#define SIGFPE 8 /* floating point exception */
+#define SIGKILL 9 /* kill (cannot be caught or ignored) */
+#define SIGBUS 10 /* bus error */
+#define SIGSEGV 11 /* segmentation violation */
+#define SIGSYS 12 /* bad argument to system call */
+#define SIGPIPE 13 /* write on a pipe with no one to read it */
+#define SIGALRM 14 /* alarm clock */
+#define SIGTERM 15 /* software termination signal from kill */
+
+//----------------------------------------------------------------------------
+// Thread support. This setting is used in thread-pkts.h
+#ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
+#define DEBUG_THREADS 1
+#else
+#define DEBUG_THREADS 0
+#endif
+
+// The function stub_copy_registers() is statically defined in
+// thread-packets.c, but in eCos this external stub is defined as it
+// is used in dbg_gdb.cxx.
+externC void __stub_copy_registers(target_register_t *dest,
+ target_register_t *src);
+
+//----------------------------------------------------------------------------
+// Hardware Watch/Breakpoint support. These are the possible return values
+// of HAL_STUB_IS_STOPPED_BY_HARDWARE().
+#define HAL_STUB_HW_STOP_NONE 0 // target did not stop for hw watch/break
+#define HAL_STUB_HW_STOP_BREAK 1 // target stopped for hw breakpoint
+#define HAL_STUB_HW_STOP_WATCH 2 // target stopped for write-only watchpoint
+#define HAL_STUB_HW_STOP_RWATCH 3 // target stopped for read-only watchpoint
+#define HAL_STUB_HW_STOP_AWATCH 4 // target stopped for access watchpoint
+
+//----------------------------------------------------------------------------
+// Memory accessor functions.
+#define TARGET_HAS_OWN_MEM_FUNCS
+
+//----------------------------------------------------------------------------
+// Memory access checks.
+
+#ifndef CYG_HAL_STUB_PERMIT_DATA_READ
+#define CYG_HAL_STUB_PERMIT_DATA_READ(_addr_, __count_) (1)
+#endif
+
+#ifndef CYG_HAL_STUB_PERMIT_DATA_WRITE
+#define CYG_HAL_STUB_PERMIT_DATA_WRITE(_addr_, __count_) (1)
+#endif
+
+#ifdef TARGET_HAS_HARVARD_MEMORY
+
+#ifndef CYG_HAL_STUB_PERMIT_CODE_READ
+#define CYG_HAL_STUB_PERMIT_CODE_READ(_addr_, __count_) (1)
+#endif
+
+#ifndef CYG_HAL_STUB_PERMIT_CODE_WRITE
+#define CYG_HAL_STUB_PERMIT_CODE_WRITE(_addr_, __count_) (1)
+#endif
+
+#endif
+
+//----------------------------------------------------------------------------
+// Target extras?!
+extern int __process_target_query(char * pkt, char * out, int maxOut);
+extern int __process_target_set(char * pkt, char * out, int maxout);
+extern int __process_target_packet(char * pkt, char * out, int maxout);
+
+//---------------------------------------------------------------------------
+// Declarations to avoid compiler warnings.
+
+// Set the baud rate for the current serial port.
+extern void __set_baud_rate (int baud);
+
+// Write C to the current serial port.
+extern void putDebugChar (int c);
+
+// Read one character from the current serial port.
+extern int getDebugChar (void);
+
+// Push CH back onto the debug stream.
+extern void ungetDebugChar (int ch);
+
+// Reset the board.
+extern void __reset (void);
+
+// Multi-bp support.
+#ifndef __set_breakpoint
+extern int __set_breakpoint (target_register_t addr, target_register_t len);
+#endif
+#ifndef __remove_breakpoint
+extern int __remove_breakpoint (target_register_t addr, target_register_t len);
+#endif
+#ifndef __set_hw_breakpoint
+extern int __set_hw_breakpoint (target_register_t addr, target_register_t len);
+#endif
+#ifndef __remove_hw_breakpoint
+extern int __remove_hw_breakpoint (target_register_t addr, target_register_t len);
+#endif
+#ifndef __set_hw_watchpoint
+extern int __set_hw_watchpoint (target_register_t addr, target_register_t len, int ztype);
+#endif
+#ifndef __remove_hw_watchpoint
+extern int __remove_hw_watchpoint (target_register_t addr, target_register_t len, int ztype);
+#endif
+
+/* Install the standard set of trap handlers for the stub. */
+extern void __install_traps (void);
+
+/* Address in text section of a breakpoint instruction. */
+
+#ifndef BREAKINST_DEFINED
+#define BREAKINST_DEFINED
+extern void _breakinst (void);
+#endif
+
+/* The opcode for a breakpoint instruction. */
+
+extern unsigned long __break_opcode (void);
+
+/* Function to flush output buffers */
+extern void hal_flush_output(void);
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+// This one may assume a valid saved interrupt context on some platforms
+extern void cyg_hal_gdb_interrupt (target_register_t pc);
+// This one does not; use from CRITICAL_IO_REGION macros below.
+extern void cyg_hal_gdb_place_break (target_register_t pc);
+// Remove a break from either above - or not if cyg_hal_gdb_running_step
+extern int cyg_hal_gdb_remove_break (target_register_t pc);
+// Bool: is such a breakpoint set?
+extern int cyg_hal_gdb_break_is_set (void);
+
+/* This is used so that the generic stub can tell
+ * cyg_hal_gdb_remove_break() not to bother when we are avoiding stepping
+ * through a critical region ie. hal_diag_write_char() usually - that
+ * shares the GDB IO device.
+ */
+extern volatile int cyg_hal_gdb_running_step;
+
+// Use these in hal_diag.c when about to write a whole $O packet to GDB.
+// NB they require __builtin_return_address() to work: if your platform
+// does not support this, use HAL_DISABLE_INTERRUPTS &c instead.
+// These are used to ensure the user's GDB cannot step through the critical
+// region, causing everything to go horribly wrong - particularly likely
+// with watching variables. Instead it will magically skip over the region.
+
+#if 1 // Can use the address of a label: this is more portable
+
+// This macro may already have been defined by the architecture HAL
+#ifndef CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION
+#define CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION( _old_ ) \
+do { \
+ HAL_DISABLE_INTERRUPTS(_old_); \
+ cyg_hal_gdb_place_break( (target_register_t)&&cyg_hal_gdb_break_place ); \
+} while ( 0 )
+#endif
+
+// This macro may already have been defined by the architecture HAL
+// Notice the trick to *use* the label - sometimes the tools want to
+// move the label if unused, which is bad.
+#ifndef CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION
+#define CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION( _old_ ) \
+do { \
+ cyg_hal_gdb_remove_break( (target_register_t)&&cyg_hal_gdb_break_place ); \
+ HAL_RESTORE_INTERRUPTS(_old_); \
+ /* The following is solely to provide the label without the compiler \
+ * optimising it away. By referencing an external function, it can't \
+ * remove or reorder it. And because we have just called \
+ * cyg_hal_gdb_remove_break(), we know cyg_hal_gdb_break_is_set() will \
+ * return 0. \
+ */ \
+cyg_hal_gdb_break_place:; \
+ if ( cyg_hal_gdb_break_is_set() ) /* ...or the compiler might move it! */ \
+ goto cyg_hal_gdb_break_place; \
+} while ( 0 )
+#endif
+
+#else // use __builtin_return_address instead.
+
+#define CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION( _old_ ) \
+do { \
+ HAL_DISABLE_INTERRUPTS(_old_); \
+ cyg_hal_gdb_place_break((target_register_t)__builtin_return_address(0)); \
+} while ( 0 )
+
+#define CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION( _old_ ) \
+do { \
+ cyg_hal_gdb_remove_break((target_register_t)__builtin_return_address(0)); \
+ HAL_RESTORE_INTERRUPTS(_old_); \
+} while ( 0 )
+
+#endif
+
+#else // NO debug_gdb_break_support
+
+// so define these just to do interrupts:
+#define CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION( _old_ ) \
+do { \
+ HAL_DISABLE_INTERRUPTS(_old_); \
+} while (0);
+
+#define CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION( _old_ ) \
+do { \
+ HAL_RESTORE_INTERRUPTS(_old_); \
+} while (0);
+
+#endif
+
+//----------------------------------------------------------------------------
+// eCos extensions to the stub
+
+extern void hal_output_gdb_string(target_register_t str, int string_len);
+
+extern target_register_t registers[]; // The current saved registers.
+extern target_register_t * _registers ;
+extern HAL_SavedRegisters *_hal_registers;
+
+extern int cyg_hal_gdb_break;
+
+#ifdef CYGPKG_ISOINFRA
+# include <pkgconf/isoinfra.h>
+#endif
+#ifdef CYGINT_ISO_STRING_STRFUNCS
+# include <string.h>
+#else
+//-----------------------------------------------------------------------------
+// String helpers. These really should come from ISOINFRA
+static inline char *strcpy( char *s, const char *t)
+{
+ char *r = s;
+
+ while( *t ) *s++ = *t++;
+
+ // Terminate the copied string.
+ *s = 0;
+
+ return r;
+}
+
+static inline size_t strlen( const char *s )
+{
+ int r = 0;
+ while( *s++ ) r++;
+ return r;
+}
+#endif
+
+//-----------------------------------------------------------------------------
+// Repeat the cache definitions here to avoid too much hackery in
+// generic-stub.h
+/* Flush the instruction cache. */
+extern void flush_i_cache (void);
+
+/* Flush the data cache. */
+extern void __flush_d_cache (void);
+
+typedef enum {
+ CACHE_NOOP, CACHE_ENABLE, CACHE_DISABLE, CACHE_FLUSH
+} cache_control_t;
+
+/* Perform the specified operation on the instruction cache.
+ Returns 1 if the cache is enabled, 0 otherwise. */
+extern int __instruction_cache (cache_control_t request);
+/* Perform the specified operation on the data cache.
+ Returns 1 if the cache is enabled, 0 otherwise. */
+extern int __data_cache (cache_control_t request);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_HAL_HAL_STUB_H
+// End of hal_stub.h
diff --git a/ecos/packages/hal/common/current/include/hal_tables.h b/ecos/packages/hal/common/current/include/hal_tables.h
new file mode 100644
index 0000000..e385be8
--- /dev/null
+++ b/ecos/packages/hal/common/current/include/hal_tables.h
@@ -0,0 +1,116 @@
+#ifndef CYGONCE_HAL_TABLES_H
+#define CYGONCE_HAL_TABLES_H
+
+/*==========================================================================
+//
+// hal_tables.h
+//
+// Data table management
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Date: 2000-09-04
+// Purpose: Provide HAL tables
+// Description: This file defines a mechanism to include "tables" of objects
+// that are always included in the image no matter what, and are
+// constrained between labels.
+//
+// Usage: #include <cyg/hal/hal_tables.h>
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/hal.h>
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+
+/*------------------------------------------------------------------------*/
+
+#define __string(_x) #_x
+#define __xstring(_x) __string(_x)
+
+#ifndef CYG_HAL_TABLE_BEGIN
+#define CYG_HAL_TABLE_BEGIN( _label, _name ) \
+__asm__(".section \".ecos.table." __xstring(_name) ".begin\",\"aw\"\n" \
+ ".globl " __xstring(CYG_LABEL_DEFN(_label)) "\n" \
+ ".type " __xstring(CYG_LABEL_DEFN(_label)) ",object\n" \
+ ".p2align " __xstring(CYGARC_P2ALIGNMENT) "\n" \
+__xstring(CYG_LABEL_DEFN(_label)) ":\n" \
+ ".previous\n" \
+ )
+#endif
+
+#ifndef CYG_HAL_TABLE_END
+#define CYG_HAL_TABLE_END( _label, _name ) \
+__asm__(".section \".ecos.table." __xstring(_name) ".finish\",\"aw\"\n" \
+ ".globl " __xstring(CYG_LABEL_DEFN(_label)) "\n" \
+ ".type " __xstring(CYG_LABEL_DEFN(_label)) ",object\n" \
+ ".p2align " __xstring(CYGARC_P2ALIGNMENT) "\n" \
+__xstring(CYG_LABEL_DEFN(_label)) ":\n" \
+ ".previous\n" \
+ )
+#endif
+
+// This macro must be applied to any types whose objects are to be placed in
+// tables
+#ifndef CYG_HAL_TABLE_TYPE
+#define CYG_HAL_TABLE_TYPE CYGBLD_ATTRIB_ALIGN( CYGARC_ALIGNMENT )
+#endif
+
+#ifndef CYG_HAL_TABLE_EXTRA
+#define CYG_HAL_TABLE_EXTRA( _name ) \
+ CYGBLD_ATTRIB_SECTION(".ecos.table." __xstring(_name) ".extra")
+#endif
+
+#ifndef CYG_HAL_TABLE_ENTRY
+#define CYG_HAL_TABLE_ENTRY( _name ) \
+ CYGBLD_ATTRIB_SECTION(".ecos.table." __xstring(_name) ".data") \
+ CYGBLD_ATTRIB_USED
+#endif
+
+#ifndef CYG_HAL_TABLE_QUALIFIED_ENTRY
+#define CYG_HAL_TABLE_QUALIFIED_ENTRY( _name, _qual ) \
+ CYGBLD_ATTRIB_SECTION(".ecos.table." __xstring(_name) ".data." \
+ __xstring(_qual)) \
+ CYGBLD_ATTRIB_USED
+#endif
+
+/*------------------------------------------------------------------------*/
+/* EOF hal_tables.h */
+#endif // CYGONCE_HAL_TABLES_H
diff --git a/ecos/packages/hal/common/current/src/board.h b/ecos/packages/hal/common/current/src/board.h
new file mode 100644
index 0000000..15e7c6f
--- /dev/null
+++ b/ecos/packages/hal/common/current/src/board.h
@@ -0,0 +1,69 @@
+#ifndef CYGONCE_HAL_BOARD_H
+#define CYGONCE_HAL_BOARD_H
+
+//=============================================================================
+//
+// board.h
+//
+// libstub board.h file for eCos HAL
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov
+// Date: 1999-02-12
+// Purpose: libstub board.h file for eCos HAL
+// Description: This file simplifies libstub integration. The board.h file
+// for eCos simply includes the hal_stub.h file which defines
+// the necessary architecture and platform information for
+// any of the possible eCos target configurations.
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+// Define __ECOS__; allows all eCos specific additions to be easily identified.
+#define __ECOS__
+
+#include <cyg/hal/hal_stub.h>
+
+#ifdef CYGPKG_REDBOOT
+#include <pkgconf/redboot.h>
+#endif
+
+//-----------------------------------------------------------------------------
+#endif // CYGONCE_HAL_BOARD_H
+// End of board.h
diff --git a/ecos/packages/hal/common/current/src/bplist-dynamic.c b/ecos/packages/hal/common/current/src/bplist-dynamic.c
new file mode 100644
index 0000000..3ce9434
--- /dev/null
+++ b/ecos/packages/hal/common/current/src/bplist-dynamic.c
@@ -0,0 +1,449 @@
+//==========================================================================
+//
+// bplist-dynamic.c
+//
+// Dynamic breakpoint list.
+// Currently only statically allocated. (ie NO_MALLOC is assumed)
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):
+// Contributors: dmoseley
+// Date: 2000-07-11
+// Purpose: Dynamic breakpoint list.
+// Description:
+//
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+
+#if defined(CYGNUM_HAL_BREAKPOINT_LIST_SIZE) && (CYGNUM_HAL_BREAKPOINT_LIST_SIZE > 0) && defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
+
+#define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
+#include <cyg/hal/hal_stub.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+
+#ifdef TARGET_HAS_HARVARD_MEMORY
+#define __read_mem_safe __read_progmem_safe
+#define __write_mem_safe __write_progmem_safe
+#endif
+
+/*
+ * A simple target breakpoint list without using malloc.
+ * To use this package, you must define HAL_BREAKINST_SIZE to be the size
+ * in bytes of a trap instruction (max if there's more than one),
+ * HAL_BREAKINST to the opcode value of the instruction, and
+ * HAL_BREAKINST_TYPE to be the type necessary to hold the opcode value.
+ */
+
+struct breakpoint_list {
+ target_register_t addr;
+ char old_contents [HAL_BREAKINST_SIZE];
+ struct breakpoint_list *next;
+ char in_memory;
+ char length;
+} *breakpoint_list = NULL;
+
+#ifndef HAL_BREAKINST_ADDR
+static HAL_BREAKINST_TYPE break_inst = HAL_BREAKINST;
+#define HAL_BREAKINST_ADDR(x) ((void*)&break_inst)
+#endif
+
+static struct breakpoint_list bp_list [CYGNUM_HAL_BREAKPOINT_LIST_SIZE];
+static struct breakpoint_list *free_bp_list = NULL;
+static int curr_bp_num = 0;
+
+int
+__set_breakpoint (target_register_t addr, target_register_t len)
+{
+ struct breakpoint_list **addent = &breakpoint_list;
+ struct breakpoint_list *l = breakpoint_list;
+ struct breakpoint_list *newent;
+
+ while (l != NULL && l->addr < addr)
+ {
+ addent = &l->next;
+ l = l->next;
+ }
+
+ if (l != NULL && l->addr == addr)
+ return 2;
+
+ if (free_bp_list != NULL)
+ {
+ newent = free_bp_list;
+ free_bp_list = free_bp_list->next;
+ }
+ else
+ {
+ if (curr_bp_num < CYGNUM_HAL_BREAKPOINT_LIST_SIZE)
+ {
+ newent = &bp_list[curr_bp_num++];
+ }
+ else
+ {
+ return 1;
+ }
+ }
+
+ newent->addr = addr;
+ newent->in_memory = 0;
+ newent->next = l;
+ newent->length = len;
+ *addent = newent;
+
+ return 0;
+}
+
+int
+__remove_breakpoint (target_register_t addr, target_register_t len)
+{
+ struct breakpoint_list *l = breakpoint_list;
+ struct breakpoint_list *prev = NULL;
+
+ while (l != NULL && l->addr < addr)
+ {
+ prev = l;
+ l = l->next;
+ }
+
+ if ((l == NULL) || (l->addr != addr))
+ return 1;
+
+ if (l->in_memory)
+ {
+ __write_mem_safe (&l->old_contents[0],
+ (void*)l->addr,
+ sizeof (l->old_contents));
+ }
+
+ if (prev == NULL)
+ breakpoint_list = l->next;
+ else
+ prev->next = l->next;
+
+ l->next = free_bp_list;
+ free_bp_list = l;
+
+ return 0;
+}
+
+#if defined(HAL_STUB_HW_BREAKPOINT_LIST_SIZE) && (HAL_STUB_HW_BREAKPOINT_LIST_SIZE > 0)
+#ifndef HAL_STUB_HW_BREAKPOINT
+#error "Must define HAL_STUB_HW_BREAKPOINT"
+#endif
+struct hw_breakpoint_list {
+ target_register_t addr;
+ target_register_t len;
+ char used;
+ char installed;
+};
+static struct hw_breakpoint_list hw_bp_list [HAL_STUB_HW_BREAKPOINT_LIST_SIZE];
+
+int
+__set_hw_breakpoint (target_register_t addr, target_register_t len)
+{
+ int i;
+
+ for (i = 0; i < HAL_STUB_HW_BREAKPOINT_LIST_SIZE; i++)
+ {
+ if (hw_bp_list[i].used == 0)
+ {
+ hw_bp_list[i].addr = addr;
+ hw_bp_list[i].len = len;
+ hw_bp_list[i].used = 1;
+ hw_bp_list[i].installed = 0;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int
+__remove_hw_breakpoint (target_register_t addr, target_register_t len)
+{
+ int i;
+
+ for (i = 0; i < HAL_STUB_HW_BREAKPOINT_LIST_SIZE; i++)
+ {
+ if (hw_bp_list[i].used && hw_bp_list[i].addr == addr
+ && hw_bp_list[i].len == len)
+ {
+ if (hw_bp_list[i].installed)
+ HAL_STUB_HW_BREAKPOINT(0, (void *)addr, (int)len);
+ hw_bp_list[i].used = 0;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static void
+__install_hw_breakpoint_list (void)
+{
+ int i;
+
+ for (i = 0; i < HAL_STUB_HW_BREAKPOINT_LIST_SIZE; i++)
+ {
+ if (hw_bp_list[i].used && hw_bp_list[i].installed == 0)
+ {
+ HAL_STUB_HW_BREAKPOINT(1, (void *)hw_bp_list[i].addr,
+ (int)hw_bp_list[i].len);
+ hw_bp_list[i].installed = 1;
+ }
+ }
+}
+
+static void
+__clear_hw_breakpoint_list (void)
+{
+ int i;
+
+ for (i = 0; i < HAL_STUB_HW_BREAKPOINT_LIST_SIZE; i++)
+ {
+ if (hw_bp_list[i].used && hw_bp_list[i].installed)
+ {
+ HAL_STUB_HW_BREAKPOINT(0, (void *)hw_bp_list[i].addr,
+ (int)hw_bp_list[i].len);
+ hw_bp_list[i].installed = 0;
+ }
+ }
+}
+#endif // HAL_STUB_HW_BREAKPOINT_LIST_SIZE
+
+#if defined(HAL_STUB_HW_WATCHPOINT_LIST_SIZE) && (HAL_STUB_HW_WATCHPOINT_LIST_SIZE > 0)
+#ifndef HAL_STUB_HW_WATCHPOINT
+#error "Must define HAL_STUB_HW_WATCHPOINT"
+#endif
+struct hw_watchpoint_list {
+ target_register_t addr;
+ target_register_t len;
+ int ztype;
+ char used;
+ char installed;
+};
+static struct hw_watchpoint_list hw_wp_list [HAL_STUB_HW_WATCHPOINT_LIST_SIZE];
+
+int
+__set_hw_watchpoint (target_register_t addr, target_register_t len, int ztype)
+{
+ int i;
+
+ for (i = 0; i < HAL_STUB_HW_WATCHPOINT_LIST_SIZE; i++)
+ {
+ if (hw_wp_list[i].used == 0)
+ {
+ hw_wp_list[i].addr = addr;
+ hw_wp_list[i].len = len;
+ hw_wp_list[i].ztype = ztype;
+ hw_wp_list[i].used = 1;
+ hw_wp_list[i].installed = 0;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int
+__remove_hw_watchpoint (target_register_t addr, target_register_t len, int ztype)
+{
+ int i;
+
+ for (i = 0; i < HAL_STUB_HW_WATCHPOINT_LIST_SIZE; i++)
+ {
+ if (hw_wp_list[i].used && hw_wp_list[i].addr == addr
+ && hw_wp_list[i].len == len && hw_wp_list[i].ztype == ztype )
+ {
+ if (hw_wp_list[i].installed)
+ HAL_STUB_HW_WATCHPOINT(0, (void *)addr, (int)len, ztype);
+ hw_wp_list[i].used = 0;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static void
+__install_hw_watchpoint_list (void)
+{
+ int i;
+
+ for (i = 0; i < HAL_STUB_HW_WATCHPOINT_LIST_SIZE; i++)
+ {
+ if (hw_wp_list[i].used && hw_wp_list[i].installed == 0)
+ {
+ HAL_STUB_HW_WATCHPOINT(1, (void *)hw_wp_list[i].addr,
+ (int)hw_wp_list[i].len, hw_wp_list[i].ztype);
+ hw_wp_list[i].installed = 1;
+ }
+ }
+}
+
+static void
+__clear_hw_watchpoint_list (void)
+{
+ int i;
+
+ for (i = 0; i < HAL_STUB_HW_WATCHPOINT_LIST_SIZE; i++)
+ {
+ if (hw_wp_list[i].used && hw_wp_list[i].installed)
+ {
+ HAL_STUB_HW_WATCHPOINT(0, (void *)hw_wp_list[i].addr,
+ (int)hw_wp_list[i].len, hw_wp_list[i].ztype);
+ hw_wp_list[i].installed = 0;
+ }
+ }
+}
+#endif // HAL_STUB_HW_WATCHPOINT_LIST_SIZE
+
+
+
+void
+__install_breakpoint_list (void)
+{
+ struct breakpoint_list *l = breakpoint_list;
+
+ while (l != NULL)
+ {
+ if (! l->in_memory)
+ {
+ int len = sizeof (l->old_contents);
+ if (__read_mem_safe (&l->old_contents[0], (void*)l->addr, len) == len)
+ {
+ if (__write_mem_safe (HAL_BREAKINST_ADDR(l->length),
+ (void*)l->addr, l->length) == l->length)
+ {
+ l->in_memory = 1;
+ }
+ }
+ }
+ l = l->next;
+ }
+#if defined(HAL_STUB_HW_BREAKPOINT_LIST_SIZE) && (HAL_STUB_HW_BREAKPOINT_LIST_SIZE > 0)
+ __install_hw_breakpoint_list();
+#endif
+#if defined(HAL_STUB_HW_WATCHPOINT_LIST_SIZE) && (HAL_STUB_HW_WATCHPOINT_LIST_SIZE > 0)
+ __install_hw_watchpoint_list();
+#endif
+ HAL_ICACHE_SYNC();
+}
+
+void
+__clear_breakpoint_list (void)
+{
+ struct breakpoint_list *l = breakpoint_list;
+
+ while (l != NULL)
+ {
+ if (l->in_memory)
+ {
+ int len = sizeof (l->old_contents);
+ if (__write_mem_safe (&l->old_contents[0], (void*)l->addr, len) == len)
+ {
+ l->in_memory = 0;
+ }
+ }
+ l = l->next;
+ }
+#if defined(HAL_STUB_HW_BREAKPOINT_LIST_SIZE) && (HAL_STUB_HW_BREAKPOINT_LIST_SIZE > 0)
+ __clear_hw_breakpoint_list();
+#endif
+#if defined(HAL_STUB_HW_WATCHPOINT_LIST_SIZE) && (HAL_STUB_HW_WATCHPOINT_LIST_SIZE > 0)
+ __clear_hw_watchpoint_list();
+#endif
+ HAL_ICACHE_INVALIDATE_ALL();
+}
+
+int
+__display_breakpoint_list (void (*print_func)(target_register_t))
+{
+ struct breakpoint_list *l = breakpoint_list;
+
+ while (l != NULL)
+ {
+ print_func(l->addr);
+ l = l->next;
+ }
+
+ return 0;
+}
+#else // (CYGNUM_HAL_BREAKPOINT_LIST_SIZE == 0) or UNDEFINED
+
+#include <cyg/hal/hal_stub.h> // Our header
+
+#ifndef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+// We don't know that type target_register_t is yet.
+// Let's just pick a type so we can compile. Since
+// these versions of the functions don't actually do
+// anything with the parameters, the actualy types
+// don't matter.
+typedef unsigned long target_register_t;
+#endif
+
+int
+__set_breakpoint (target_register_t addr, target_register_t len)
+{
+ return 1;
+}
+
+int
+__remove_breakpoint (target_register_t addr, target_register_t len)
+{
+ return 1;
+}
+
+void
+__install_breakpoint_list (void)
+{
+}
+
+void
+__clear_breakpoint_list (void)
+{
+}
+
+int
+__display_breakpoint_list (void (*print_func)(target_register_t))
+{
+ return 0;
+}
+#endif // (CYGNUM_HAL_BREAKPOINT_LIST_SIZE > 0)
+
diff --git a/ecos/packages/hal/common/current/src/dbg-threads-syscall.c b/ecos/packages/hal/common/current/src/dbg-threads-syscall.c
new file mode 100644
index 0000000..58583be
--- /dev/null
+++ b/ecos/packages/hal/common/current/src/dbg-threads-syscall.c
@@ -0,0 +1,216 @@
+//========================================================================
+//
+// dbg-threads-syscall.c
+//
+// Pseudo system calls for multi-threaded debug support
+//
+//========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Red Hat, nickg
+// Contributors: Red Hat, nickg
+// Date: 1998-08-25
+// Purpose:
+// Description: Pseudo system calls to bind system specific multithread
+// debug support with a ROM monitor, cygmon. We call it
+// Cygmon, but the feature lives in libstub.
+// Usage:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+
+#if !defined(CYGPKG_KERNEL) && defined(CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT)
+
+/* Only include this code if we do not have a kernel. Otherwise the kernel
+ * supplies these functions for the app we are linked with.
+ */
+
+#include <cyg/hal/dbg-threads-api.h>
+#include <cyg/hal/dbg-thread-syscall.h>
+
+
+static dbg_syscall_func * dbg_syscall_ptr ;
+
+static union dbg_thread_syscall_parms tcall ;
+
+/* ----- INIT_THREADS_SYSCALL --------------------------------------- */
+/* Some external bing and configuration logic knows how to setup
+ the ststem calls. In the first implementation, we have used a vector
+ in the secondary vector table. This functions allows us to isolate that
+ sort of system specific detail. Similarly, we do not export the
+ specific detail of a dbg_syscall_func.
+ */
+
+
+void init_threads_syscall(void * vector)
+{
+ dbg_syscall_ptr = vector ; /* AH, the easy compatability of the
+ void pointer*/
+} /* init_threads_syscall */
+
+/* All forms of failure return 0 */
+/* Whether non support, incomplete initialization, unknown thread */
+static __inline__ int dbg_thread_syscall(
+ enum dbg_syscall_ids id)
+{
+ dbg_syscall_func f ; /* double indirect via */
+ if (0 == dbg_syscall_ptr) return 0; /* dbg_syscall_ptr never init'd */
+ if (0 ==(f = *dbg_syscall_ptr)) return 0 ; /* vector not initialized */
+ return (*f)(id,&tcall);
+}
+
+
+
+
+/* ------- INIT_THREAD_SYSCALL ------------------------------------------- */
+/* Received the address of the entry in the secondary interrupt vector table */
+/* This table is the interchange between the O.S. and Cygmon/libstub */
+/* This could get more complex so, I am doing it with a function
+ rather than exposing the internals.
+ */
+void init_thread_syscall(void * vector)
+{
+ dbg_syscall_ptr = vector ;
+}
+
+int dbg_thread_capabilities(struct dbg_capabilities * cbp)
+{
+#if 0
+ tcall.cap_parms.abilities = cbp ;
+ return dbg_thread_syscall(dbg_capabilities_func) ;
+#else
+ cbp->mask1 = has_thread_current |
+ has_thread_registers |
+ has_thread_reg_change |
+ has_thread_list |
+ has_thread_info ;
+ return 1 ;
+#endif
+}
+
+int dbg_currthread(threadref * varparm)
+{
+ tcall.currthread_parms.ref = varparm ;
+ return dbg_thread_syscall(dbg_currthread_func) ;
+}
+
+
+int dbg_threadlist(
+ int startflag,
+ threadref * lastthreadid,
+ threadref * next_thread
+ )
+{
+ tcall.threadlist_parms.startflag = startflag ;
+ tcall.threadlist_parms.lastid = lastthreadid ;
+ tcall.threadlist_parms.nextthreadid = next_thread ;
+ return dbg_thread_syscall(dbg_threadlist_func) ;
+}
+
+int dbg_threadinfo(
+ threadref * threadid,
+ struct cygmon_thread_debug_info * info)
+{
+ tcall.info_parms.ref = threadid ;
+ tcall.info_parms.info = info ;
+ return dbg_thread_syscall(dbg_threadinfo_func) ;
+}
+
+int dbg_getthreadreg(
+ threadref * osthreadid,
+ int regcount, /* count of registers in the array */
+ void * regval) /* fillin this array */
+{
+ tcall.reg_parms.thread = osthreadid ;
+ tcall.reg_parms.regcount = regcount ;
+ tcall.reg_parms.registers = regval ;
+ return dbg_thread_syscall(dbg_getthreadreg_func) ;
+}
+
+int dbg_setthreadreg(
+ threadref * osthreadid,
+ int regcount , /* number of registers */
+ void * regval)
+{
+ tcall.reg_parms.thread = osthreadid ;
+ tcall.reg_parms.regcount = regcount ;
+ tcall.reg_parms.registers = regval ;
+ return dbg_thread_syscall(dbg_setthreadreg_func) ;
+} /* dbg_setthreadreg */
+
+int dbg_scheduler(threadref *thread_id, int lock, int mode)
+{
+ tcall.scheduler_parms.thread = thread_id;
+ tcall.scheduler_parms.lock = lock ;
+ tcall.scheduler_parms.mode = mode ;
+
+ return dbg_thread_syscall(dbg_scheduler_func) ;
+}
+
+
+
+#if (CYG_BYTEORDER == CYG_LSBFIRST)
+
+unsigned long swap32(unsigned long x)
+{
+ unsigned long r = 0;
+
+ r |= (x>>24)&0xFF;
+ r |= ((x>>16)&0xFF)<<8;
+ r |= ((x>>8)&0xFF)<<16;
+ r |= ((x)&0xFF)<<24;
+
+ return r;
+}
+
+#else
+
+#define swap32(x) ((unsigned long)(x))
+
+#endif
+
+int dbg_currthread_id(void)
+{
+ threadref ref;
+ if( dbg_currthread( &ref ) )
+ return (cyg_uint16)swap32(((unsigned long *)ref)[1]);
+ else return 0;
+}
+
+#endif
diff --git a/ecos/packages/hal/common/current/src/drv_api.c b/ecos/packages/hal/common/current/src/drv_api.c
new file mode 100644
index 0000000..a9c751a
--- /dev/null
+++ b/ecos/packages/hal/common/current/src/drv_api.c
@@ -0,0 +1,943 @@
+//==========================================================================
+//
+// drv_api.c
+//
+// Driver API for non-kernel configurations
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Nick Garnett
+// Date: 1999-02-24
+// Purpose: Driver API for non-kernel configurations
+// Description: These functions are used to support drivers when the kernel
+// is not present.
+//
+//
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+
+#ifndef CYGPKG_KERNEL
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_trac.h>
+#include <cyg/infra/cyg_ass.h>
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/drv_api.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+
+//--------------------------------------------------------------------------
+// Statics
+
+static volatile cyg_int32 isr_disable_counter = 1; // ISR disable counter
+
+static CYG_INTERRUPT_STATE isr_disable_state;
+
+volatile cyg_int32 dsr_disable_counter // DSR disable counter
+ CYGBLD_ATTRIB_ASM_ALIAS( cyg_scheduler_sched_lock );
+
+static cyg_interrupt* volatile dsr_list; // List of pending DSRs
+
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
+
+cyg_interrupt *chain_list[CYGNUM_HAL_ISR_COUNT];
+
+#endif
+
+//--------------------------------------------------------------------------
+// DSR handling functions.
+// post_dsr() places a DSR on the list of DSRs to be called.
+// call_dsrs() calls the DSRs.
+
+static void post_dsr( cyg_interrupt *intr )
+{
+ CYG_INTERRUPT_STATE old_intr;
+
+ CYG_REPORT_FUNCTION();
+
+ HAL_DISABLE_INTERRUPTS(old_intr);
+
+ if( intr->dsr_count++ == 0 )
+ {
+ intr->next_dsr = dsr_list;
+ dsr_list = intr;
+ }
+
+ HAL_RESTORE_INTERRUPTS(old_intr);
+
+ CYG_REPORT_RETURN();
+}
+
+static void call_dsrs(void)
+{
+ CYG_REPORT_FUNCTION();
+
+ while( dsr_list != NULL )
+ {
+ cyg_interrupt *intr;
+ cyg_int32 count;
+ CYG_INTERRUPT_STATE old_intr;
+
+ HAL_DISABLE_INTERRUPTS(old_intr);
+
+ intr = dsr_list;
+ dsr_list = intr->next_dsr;
+ count = intr->dsr_count;
+ intr->dsr_count = 0;
+
+ HAL_RESTORE_INTERRUPTS(old_intr);
+
+ intr->dsr( intr->vector, count, (CYG_ADDRWORD)intr->data );
+ }
+
+ CYG_REPORT_RETURN();
+
+}
+
+//--------------------------------------------------------------------------
+// This is referenced from the HAL, although it does not actually get called.
+
+externC void
+cyg_interrupt_call_pending_DSRs(void)
+{
+ call_dsrs();
+}
+
+//--------------------------------------------------------------------------
+// This is called from springboard ISRs in some HALs.
+
+externC void
+cyg_interrupt_post_dsr(CYG_ADDRWORD data)
+{
+ cyg_interrupt * intr = (cyg_interrupt *)data;
+ post_dsr(intr);
+}
+
+//--------------------------------------------------------------------------
+// Interrupt end function called from HAL VSR to tidy up. This is where
+// DSRs will be called if necessary.
+
+externC void
+interrupt_end(
+ cyg_uint32 isr_ret,
+ cyg_interrupt *intr,
+ HAL_SavedRegisters *regs
+ )
+{
+ CYG_REPORT_FUNCTION();
+
+#ifndef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
+
+ // Only do this if we are in a non-chained configuration.
+ // If we are chained, then chain_isr will do the DSR
+ // posting.
+
+ if( isr_ret & CYG_ISR_CALL_DSR && intr != NULL ) post_dsr(intr);
+
+#endif
+
+ if( dsr_disable_counter == 0 ) call_dsrs();
+
+ CYG_REPORT_RETURN();
+}
+
+//--------------------------------------------------------------------------
+// ISR for handling chained interrupts.
+
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
+
+cyg_uint32 chain_isr(cyg_vector_t vector, CYG_ADDRWORD data)
+{
+ cyg_interrupt *p = *(cyg_interrupt **)data;
+ register cyg_uint32 isr_ret = 0;
+ register cyg_uint32 isr_chain_ret = 0;
+
+ CYG_REPORT_FUNCTION();
+
+ while( p != NULL )
+ {
+ if( p->vector == vector )
+ {
+ isr_ret = p->isr(vector, p->data);
+
+ isr_chain_ret |= isr_ret;
+
+ if( isr_ret & CYG_ISR_CALL_DSR ) post_dsr(p);
+
+ if( isr_ret & CYG_ISR_HANDLED ) break;
+ }
+
+ p = p->next;
+ }
+
+#ifdef HAL_DEFAULT_ISR
+ if( (isr_chain_ret & (CYG_ISR_CALL_DSR|CYG_ISR_HANDLED)) == 0 )
+ {
+ // If we finished the loop for some reason other than that an
+ // ISR has handled the interrupt, call any default ISR to either
+ // report the spurious interrupt, or do some other HAL level processing
+ // such as GDB interrupt detection etc.
+
+ HAL_DEFAULT_ISR( vector, 0 );
+ }
+#endif
+
+ CYG_REPORT_RETURN();
+
+ return isr_ret & CYG_ISR_CALL_DSR;
+}
+
+#endif
+
+//--------------------------------------------------------------------------
+// ISR lock. This disables interrupts and keeps a count of the number
+// times it has been called.
+
+externC void cyg_drv_isr_lock()
+{
+ CYG_REPORT_FUNCTION();
+
+ if( isr_disable_counter == 0 )
+ HAL_DISABLE_INTERRUPTS(isr_disable_state);
+
+ CYG_ASSERT( isr_disable_counter >= 0 , "Disable counter negative");
+
+ isr_disable_counter++;
+
+ CYG_REPORT_RETURN();
+}
+
+//--------------------------------------------------------------------------
+// Unlock ISRs. This decrements the count and re-enables interrupts if it
+// goes zero.
+
+externC void cyg_drv_isr_unlock()
+{
+ CYG_REPORT_FUNCTION();
+
+ CYG_ASSERT( isr_disable_counter > 0 , "Disable counter not greater than zero");
+
+ isr_disable_counter--;
+
+ if ( isr_disable_counter == 0 )
+ {
+ HAL_RESTORE_INTERRUPTS(isr_disable_state);
+ }
+
+ CYG_REPORT_RETURN();
+}
+
+//--------------------------------------------------------------------------
+// Lock DSR lock. Simply increment the counter.
+
+externC void cyg_drv_dsr_lock()
+{
+ CYG_REPORT_FUNCTION();
+
+ dsr_disable_counter++;
+
+ CYG_REPORT_RETURN();
+}
+
+//--------------------------------------------------------------------------
+// Unlock DSR lock. If the counter is about to go zero, call any pending
+// DSRs and then zero the counter.
+
+externC void cyg_drv_dsr_unlock()
+{
+ CYG_REPORT_FUNCTION();
+
+ do
+ {
+ if( dsr_disable_counter == 1 )
+ {
+ call_dsrs();
+ }
+
+ HAL_REORDER_BARRIER();
+
+ dsr_disable_counter = 0;
+
+ HAL_REORDER_BARRIER();
+
+ // Check that no DSRs have been posted between calling
+ // call_dsrs() and zeroing dsr_disable_counter. If so,
+ // loop back and call them.
+
+ if( dsr_list != NULL )
+ {
+ dsr_disable_counter = 1;
+ continue;
+ }
+
+ CYG_REPORT_RETURN();
+
+ return;
+
+ } while(1);
+
+ CYG_FAIL( "Should not be executed" );
+}
+
+//--------------------------------------------------------------------------
+// Initialize a mutex.
+
+externC void cyg_drv_mutex_init( cyg_drv_mutex_t *mutex )
+{
+ CYG_REPORT_FUNCTION();
+
+ mutex->lock = 0;
+
+ CYG_REPORT_RETURN();
+}
+
+//--------------------------------------------------------------------------
+// Destroy a mutex.
+
+externC void cyg_drv_mutex_destroy( cyg_drv_mutex_t *mutex )
+{
+ CYG_REPORT_FUNCTION();
+
+ mutex->lock = -1;
+
+ CYG_REPORT_RETURN();
+}
+
+//--------------------------------------------------------------------------
+// Lock a mutex. We check that we are not trying to lock a locked or
+// destroyed mutex and if not, set it locked.
+
+externC cyg_bool_t cyg_drv_mutex_lock( cyg_drv_mutex_t *mutex )
+{
+ CYG_REPORT_FUNCTION();
+
+ CYG_ASSERT( mutex->lock == 0 , "Trying to lock locked mutex");
+
+ mutex->lock = 1;
+
+ CYG_REPORT_RETURN();
+
+ return true;
+}
+
+//--------------------------------------------------------------------------
+// Attempt to claim a mutex, and return if it cannot be.
+
+externC cyg_bool_t cyg_drv_mutex_trylock( cyg_drv_mutex_t *mutex )
+{
+ cyg_bool_t result = true;
+
+ CYG_REPORT_FUNCTION();
+
+ if( mutex->lock == 1 ) result = false;
+
+ mutex->lock = 1;
+
+ CYG_REPORT_RETURN();
+
+ return result;
+}
+
+//--------------------------------------------------------------------------
+// Unlock a mutex. We check that the mutex is actually locked before doing
+// this.
+
+externC void cyg_drv_mutex_unlock( cyg_drv_mutex_t *mutex )
+{
+ CYG_REPORT_FUNCTION();
+
+ CYG_ASSERT( mutex->lock == 1 , "Trying to unlock unlocked mutex");
+
+ mutex->lock = 0;
+
+ CYG_REPORT_RETURN();
+}
+
+//--------------------------------------------------------------------------
+// Release all threads waiting for the mutex.
+// This is really for threads, so we do nothing here.
+
+externC void cyg_drv_mutex_release( cyg_drv_mutex_t *mutex )
+{
+ CYG_REPORT_FUNCTION();
+
+
+
+ CYG_REPORT_RETURN();
+}
+
+
+//--------------------------------------------------------------------------
+// Initialized a condition variable.
+
+externC void cyg_drv_cond_init( cyg_drv_cond_t *cond, cyg_drv_mutex_t *mutex )
+{
+ CYG_REPORT_FUNCTION();
+
+ cond->wait = 0;
+ cond->mutex = mutex;
+
+ CYG_REPORT_RETURN();
+}
+
+
+//--------------------------------------------------------------------------
+// Destroy a condition variable.
+
+externC void cyg_drv_cond_destroy( cyg_drv_cond_t *cond )
+{
+ CYG_REPORT_FUNCTION();
+
+ cond->wait = -1;
+ cond->mutex = NULL;
+
+ CYG_REPORT_RETURN();
+}
+
+// -------------------------------------------------------------------------
+// Wait for a condition variable to be signalled. We simply busy wait
+// polling the condition variable's wait member until a DSR sets it to
+// 0. Note that the semantics of condition variables means that the
+// wakeup only happens if there is a thread actually waiting on the CV
+// when the signal is sent.
+
+externC cyg_bool cyg_drv_cond_wait( cyg_drv_cond_t *cond )
+{
+ CYG_REPORT_FUNCTION();
+
+ CYG_ASSERT( cond->mutex != NULL, "Uninitialized condition variable");
+ CYG_ASSERT( cond->mutex->lock, "Mutex not locked");
+
+ cyg_drv_dsr_lock();
+
+ cond->wait = 1;
+
+ while( cond->wait == 1 )
+ {
+ // While looping we call call_dsrs() to service any DSRs that
+ // get posted. One of these will make the call to cond_signal
+ // to break us out of this loop. If we do not have the DSR
+ // lock claimed, then a race condition could occur and keep us
+ // stuck here forever.
+
+ call_dsrs();
+ }
+
+ cyg_drv_dsr_unlock();
+
+ CYG_REPORT_RETURN();
+
+ return true;
+}
+
+//--------------------------------------------------------------------------
+// Signal a condition variable. This sets the wait member to zero, which
+// has no effect when there is no waiter, but will wake up any waiting
+// thread.
+
+externC void cyg_drv_cond_signal( cyg_drv_cond_t *cond )
+{
+ CYG_REPORT_FUNCTION();
+
+ cond->wait = 0;
+
+ CYG_REPORT_RETURN();
+}
+
+
+//--------------------------------------------------------------------------
+// Broadcast to condition variable. This is exactly the same a signal since
+// there can only be one waiter.
+
+externC void cyg_drv_cond_broadcast( cyg_drv_cond_t *cond )
+{
+ CYG_REPORT_FUNCTION();
+
+ cond->wait = 0;
+
+ CYG_REPORT_RETURN();
+}
+
+//--------------------------------------------------------------------------
+// Spinlock support.
+// Since we can only support a single CPU in this version of the API, we only
+// set and clear the lock variable to keep track of what's happening.
+
+void cyg_drv_spinlock_init(
+ cyg_drv_spinlock_t *lock, /* spinlock to initialize */
+ cyg_bool_t locked /* init locked or unlocked */
+)
+{
+ CYG_REPORT_FUNCTION();
+
+ lock->lock = locked;
+
+ CYG_REPORT_RETURN();
+}
+
+void cyg_drv_spinlock_destroy( cyg_drv_spinlock_t *lock )
+{
+ CYG_REPORT_FUNCTION();
+
+ lock->lock = -1;
+
+ CYG_REPORT_RETURN();
+}
+
+void cyg_drv_spinlock_spin( cyg_drv_spinlock_t *lock )
+{
+ CYG_REPORT_FUNCTION();
+
+ CYG_ASSERT( lock->lock == 0 , "Trying to lock locked spinlock");
+
+ lock->lock = 1;
+
+ CYG_REPORT_RETURN();
+}
+
+void cyg_drv_spinlock_clear( cyg_drv_spinlock_t *lock )
+{
+ CYG_REPORT_FUNCTION();
+
+ CYG_ASSERT( lock->lock == 1 , "Trying to clear cleared spinlock");
+
+ lock->lock = 0;
+
+ CYG_REPORT_RETURN();
+}
+
+cyg_bool_t cyg_drv_spinlock_try( cyg_drv_spinlock_t *lock )
+{
+ cyg_bool_t result = true;
+
+ CYG_REPORT_FUNCTION();
+
+ if( lock->lock == 1 ) result = false;
+
+ lock->lock = 1;
+
+ CYG_REPORT_RETURN();
+
+ return result;
+}
+
+cyg_bool_t cyg_drv_spinlock_test( cyg_drv_spinlock_t *lock )
+{
+ cyg_bool_t result = true;
+
+ CYG_REPORT_FUNCTION();
+
+ if( lock->lock == 1 ) result = false;
+
+ CYG_REPORT_RETURN();
+
+ return result;
+}
+
+void cyg_drv_spinlock_spin_intsave( cyg_drv_spinlock_t *lock,
+ cyg_addrword_t *istate )
+{
+ CYG_REPORT_FUNCTION();
+
+ HAL_DISABLE_INTERRUPTS( *istate );
+
+ lock->lock = 1;
+
+ CYG_REPORT_RETURN();
+}
+
+
+void cyg_drv_spinlock_clear_intsave( cyg_drv_spinlock_t *lock,
+ cyg_addrword_t istate )
+{
+ CYG_REPORT_FUNCTION();
+
+ lock->lock = 0;
+
+ HAL_RESTORE_INTERRUPTS( istate );
+
+ CYG_REPORT_RETURN();
+}
+
+//--------------------------------------------------------------------------
+// Create an interrupt object.
+
+externC void cyg_drv_interrupt_create(
+ cyg_vector_t vector,
+ cyg_priority_t priority,
+ cyg_addrword_t data,
+ cyg_ISR_t *isr,
+ cyg_DSR_t *dsr,
+ cyg_handle_t *handle,
+ cyg_interrupt *intr
+ )
+{
+ CYG_REPORT_FUNCTION();
+
+ intr->vector = vector;
+ intr->priority = priority;
+ intr->isr = isr;
+ intr->dsr = dsr;
+ intr->data = data;
+ intr->next_dsr = NULL;
+ intr->dsr_count = 0;
+
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
+
+ intr->next = NULL;
+
+#endif
+
+ *handle = (cyg_handle_t)intr;
+
+ CYG_REPORT_RETURN();
+}
+
+//--------------------------------------------------------------------------
+// Delete an interrupt object. This merely ensures that it is detached from
+// the vector.
+
+externC void cyg_drv_interrupt_delete( cyg_handle_t interrupt )
+{
+ CYG_REPORT_FUNCTION();
+
+ cyg_drv_interrupt_detach( interrupt );
+
+ CYG_REPORT_RETURN();
+}
+
+//--------------------------------------------------------------------------
+//
+
+externC void cyg_drv_interrupt_attach( cyg_handle_t interrupt )
+{
+ cyg_interrupt *intr = (cyg_interrupt *)interrupt;
+
+ CYG_REPORT_FUNCTION();
+
+ CYG_ASSERT( intr->vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
+ CYG_ASSERT( intr->vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
+
+ HAL_INTERRUPT_SET_LEVEL( intr->vector, intr->priority );
+
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
+
+ CYG_ASSERT( intr->next == NULL , "cyg_interrupt already on a list");
+
+ {
+ cyg_uint32 index;
+
+ HAL_TRANSLATE_VECTOR( intr->vector, index );
+
+ if( chain_list[index] == NULL )
+ {
+ // First Interrupt on this chain, just assign it and
+ // register the chain_isr with the HAL.
+
+ chain_list[index] = intr;
+
+ HAL_INTERRUPT_ATTACH( intr->vector, chain_isr,
+ &chain_list[index], NULL );
+ }
+ else
+ {
+ // There are already interrupts chained, add this one into
+ // the chain in priority order.
+
+ cyg_interrupt **p = &chain_list[index];
+
+ while( *p != NULL )
+ {
+ cyg_interrupt *n = *p;
+
+ if( n->priority < intr->priority ) break;
+
+ p = &n->next;
+ }
+ intr->next = *p;
+ *p = intr;
+ }
+ }
+
+#else
+
+ HAL_INTERRUPT_ATTACH( intr->vector, intr->isr, intr->data, intr );
+
+#endif
+
+ CYG_REPORT_RETURN();
+}
+
+
+//--------------------------------------------------------------------------
+// Detach an interrupt from its vector.
+
+externC void cyg_drv_interrupt_detach( cyg_handle_t interrupt )
+{
+ cyg_interrupt *intr = (cyg_interrupt *)interrupt;
+
+ CYG_REPORT_FUNCTION();
+
+ CYG_ASSERT( intr->vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
+ CYG_ASSERT( intr->vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
+
+#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
+
+ // Remove the interrupt object from the vector chain.
+
+ {
+ cyg_uint32 index;
+ cyg_interrupt **p;
+
+ HAL_TRANSLATE_VECTOR( intr->vector, index );
+
+ p = &chain_list[index];
+
+ while( *p != NULL )
+ {
+ cyg_interrupt *n = *p;
+
+ if( n == intr )
+ {
+ *p = intr->next;
+ break;
+ }
+
+ p = &n->next;
+ }
+
+ // If this was the last one, detach the vector.
+
+ if( chain_list[index] == NULL )
+ HAL_INTERRUPT_DETACH( intr->vector, chain_isr );
+ }
+
+#else
+
+ HAL_INTERRUPT_DETACH( intr->vector, intr->isr );
+
+#endif
+
+ CYG_REPORT_RETURN();
+}
+
+
+//--------------------------------------------------------------------------
+// Mask delivery of an interrupt at the interrupt controller.
+// (Interrupt safe)
+
+externC void cyg_drv_interrupt_mask( cyg_vector_t vector )
+{
+ CYG_INTERRUPT_STATE old_ints;
+
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARG1("vector=%d", vector);
+
+ CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
+ CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
+
+ HAL_DISABLE_INTERRUPTS(old_ints);
+ HAL_INTERRUPT_MASK( vector );
+ HAL_RESTORE_INTERRUPTS(old_ints);
+
+ CYG_REPORT_RETURN();
+}
+
+//--------------------------------------------------------------------------
+// Mask delivery of an interrupt at the interrupt controller.
+// (Not interrupt safe)
+
+externC void cyg_drv_interrupt_mask_intunsafe( cyg_vector_t vector )
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARG1("vector=%d", vector);
+
+ CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
+ CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
+
+ HAL_INTERRUPT_MASK( vector );
+
+ CYG_REPORT_RETURN();
+}
+
+//--------------------------------------------------------------------------
+// Unmask delivery of an interrupt at the interrupt controller.
+// (Interrupt safe)
+
+externC void cyg_drv_interrupt_unmask( cyg_vector_t vector )
+{
+ CYG_INTERRUPT_STATE old_ints;
+
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARG1("vector=%d", vector);
+
+ CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
+ CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
+
+ HAL_DISABLE_INTERRUPTS(old_ints);
+ HAL_INTERRUPT_UNMASK( vector );
+ HAL_RESTORE_INTERRUPTS(old_ints);
+
+ CYG_REPORT_RETURN();
+}
+
+//--------------------------------------------------------------------------
+// Unmask delivery of an interrupt at the interrupt controller.
+// (Not interrupt safe)
+
+externC void cyg_drv_interrupt_unmask_intunsafe( cyg_vector_t vector )
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARG1("vector=%d", vector);
+
+ CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
+ CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
+
+ HAL_INTERRUPT_UNMASK( vector );
+
+ CYG_REPORT_RETURN();
+}
+
+//--------------------------------------------------------------------------
+// Acknowledge an interrupt at the controller to allow another interrupt
+// to be delivered.
+
+externC void cyg_drv_interrupt_acknowledge( cyg_vector_t vector )
+{
+// CYG_REPORT_FUNCTION();
+
+ CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
+ CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
+
+ HAL_INTERRUPT_ACKNOWLEDGE( vector );
+
+// CYG_REPORT_RETURN();
+}
+
+//--------------------------------------------------------------------------
+// Configure interrupt detection parameters.
+
+externC void cyg_drv_interrupt_configure(
+ cyg_vector_t vector,
+ cyg_bool_t level,
+ cyg_bool_t up
+ )
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARG3("vector = %d, level = %d, up = %d", vector, level,
+ up);
+
+ CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
+ CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
+
+ HAL_INTERRUPT_CONFIGURE( vector, level, up );
+
+ CYG_REPORT_RETURN();
+}
+
+//--------------------------------------------------------------------------
+// Configure interrupt priority level.
+
+externC void cyg_drv_interrupt_level( cyg_vector_t vector, cyg_priority_t level )
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARG2("vector = %d, level = %d", vector, level);
+
+ CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
+ CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
+
+ HAL_INTERRUPT_SET_LEVEL( vector, level );
+
+ CYG_REPORT_RETURN();
+}
+
+// -------------------------------------------------------------------------
+// CPU interrupt routing
+
+externC void cyg_drv_interrupt_set_cpu( cyg_vector_t vector, cyg_cpu_t cpu )
+{
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARG2("vector = %d, cpu = %d", vector, cpu);
+
+ CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
+ CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
+
+#ifdef CYGPKG_HAL_SMP_SUPPORT
+ HAL_INTERRUPT_SET_CPU( vector, cpu );
+#endif
+
+ CYG_REPORT_RETURN();
+}
+
+externC cyg_cpu_t cyg_drv_interrupt_get_cpu( cyg_vector_t vector )
+{
+ cyg_cpu_t cpu = 0;
+
+ CYG_REPORT_FUNCTION();
+ CYG_REPORT_FUNCARG1("vector = %d", vector);
+
+ CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
+ CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
+
+#ifdef CYGPKG_HAL_SMP_SUPPORT
+ HAL_INTERRUPT_GET_CPU( vector, cpu );
+#endif
+
+ CYG_REPORT_RETURN();
+
+ return cpu;
+}
+
+// -------------------------------------------------------------------------
+// Exception delivery function called from the HAL as a result of a
+// hardware exception being raised.
+
+externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data )
+{
+ CYG_FAIL(" !!! Exception !!! ");
+}
+
+
+#endif
+
+//--------------------------------------------------------------------------
+// EOF drv_api.c
diff --git a/ecos/packages/hal/common/current/src/dummy.c b/ecos/packages/hal/common/current/src/dummy.c
new file mode 100644
index 0000000..c645be6
--- /dev/null
+++ b/ecos/packages/hal/common/current/src/dummy.c
@@ -0,0 +1,53 @@
+//==========================================================================
+//
+// dummy.c
+//
+// Guarantee the existence of libextras.a
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): bartv
+// Contributors: bartv
+// Date: 1999-04-16
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+
+// This file should contain no code or data. Its sole purpose is to
+// be compiled to an empty object file and placed into libtarget.a,
+// thus ensuring that that file actually exists. This simplifies
+// life elsewhere.
diff --git a/ecos/packages/hal/common/current/src/gdb-fileio.c b/ecos/packages/hal/common/current/src/gdb-fileio.c
new file mode 100644
index 0000000..ef0945a
--- /dev/null
+++ b/ecos/packages/hal/common/current/src/gdb-fileio.c
@@ -0,0 +1,728 @@
+/*==========================================================================
+//
+// gdb-fileio.c
+//
+// Implementation of File I/O using the GDB remote protocol
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jlarmour
+// Contributors:
+// Date: 2002-04-09
+// Purpose: Implementation of File I/O using the GDB remote
+// protocol
+// Description: 'F' packet requests are of the form:
+// F<name>[,<parameter>]...
+// where name is the ASCII syscall name, and the
+// parameters are generally included as hex ints,
+// in ASCII.
+//
+//####DESCRIPTIONEND####
+//========================================================================*/
+
+/* CONFIGURATION */
+
+#include <pkgconf/hal.h>
+
+/* HEADERS */
+
+#include <stddef.h> // size_t
+#include <cyg/infra/cyg_type.h>
+#ifdef CYGPKG_ISOINFRA
+# include <pkgconf/isoinfra.h>
+# include <string.h>
+#endif
+#include "board.h" // sets correct definitions for generic stub header
+#include <cyg/hal/generic-stub.h>
+#include "gdb-fileio.h"
+
+/* TYPES */
+
+// this is used by newlib's mode_t so we should match it
+#ifdef __GNUC__
+#define _ST_INT32 __attribute__ ((__mode__ (__SI__)))
+#else
+#define _ST_INT32
+#endif
+
+typedef int newlib_int_t;
+typedef unsigned int newlib_uint_t;
+typedef long newlib_long_t;
+typedef long newlib_time_t;
+typedef unsigned int newlib_mode_t _ST_INT32;
+typedef short newlib_dev_t;
+typedef unsigned short newlib_uid_t;
+typedef unsigned short newlib_gid_t;
+typedef unsigned short newlib_ino_t;
+typedef unsigned short newlib_nlink_t;
+typedef long newlib_off_t;
+
+struct newlib_timeval {
+ newlib_time_t tv_sec;
+ newlib_long_t tv_usec;
+};
+
+struct newlib_stat
+{
+ newlib_dev_t st_dev;
+ newlib_ino_t st_ino;
+ newlib_mode_t st_mode;
+ newlib_nlink_t st_nlink;
+ newlib_uid_t st_uid;
+ newlib_gid_t st_gid;
+ newlib_dev_t st_rdev;
+ newlib_off_t st_size;
+ // We assume we've been compiled with the same flags as newlib here
+#if defined(__svr4__) && !defined(__PPC__) && !defined(__sun__)
+ newlib_time_t st_atime;
+ newlib_time_t st_mtime;
+ newlib_time_t st_ctime;
+#else
+ newlib_time_t st_atime;
+ newlib_long_t st_spare1;
+ newlib_time_t st_mtime;
+ newlib_long_t st_spare2;
+ newlib_time_t st_ctime;
+ newlib_long_t st_spare3;
+ newlib_long_t st_blksize;
+ newlib_long_t st_blocks;
+ newlib_long_t st_spare4[2];
+#endif
+};
+
+/* EXTERNS */
+
+__externC char __remcomInBuffer[]; // from generic-stub.c, for packet data
+__externC char __remcomOutBuffer[]; // ditto
+
+/* STATICS/GLOBALS */
+
+static int __fileio_retcode, __fileio_errno;
+static cyg_bool __fileio_retcode_set, __fileio_errno_set, __fileio_ctrlc_set;
+
+/* MACROS */
+
+// endian independent conversion functions from big endian protocol types
+// to newlib types
+
+#define GDBFILEIO_FIO_TO_NEWLIB( _f, _n, _ftype ) \
+CYG_MACRO_START \
+ char *_cf = (char *)(_f); \
+ int _i; \
+ char _sign = 0; \
+ if (*_cf == '-') { \
+ _sign = 1; \
+ _cf++; \
+ } \
+ (_n) = 0; \
+ for (_i=0; _i<sizeof(_ftype); _i++) { \
+ (_n) = ((_n) << 8) | _cf[_i]; \
+ } \
+ if (_sign) \
+ (_n) = -(_n); \
+CYG_MACRO_END
+
+#define GDBABS(_x_) (((_x_) < 0) ? (-(_x_)) : (_x_))
+
+#define GDBFILEIO_NEWLIB_TO_FIO( _f, _n, _ftype ) \
+CYG_MACRO_START \
+ char *_cf = (char *)(_f); \
+ int _i = 0; \
+ if ((_n) < 0) \
+ _cf[_i++] = '-'; \
+ for (; _i<sizeof(_ftype); _i++) { \
+ _cf[_i] = ((GDBABS(_n)) >> 8*(sizeof(_ftype)-_i-1)) & 0xff; \
+ } \
+CYG_MACRO_END
+
+
+/* FUNCTIONS */
+
+#ifndef CYGINT_ISO_STRING_STRFUNCS
+static size_t strlen( const char *s )
+{
+ size_t retval;
+ const char *start = s;
+ while (*s)
+ s++;
+ retval = s - start;
+ return retval;
+}
+#endif
+
+static int
+chars_to_hex( char *charsin, char *hexout, int bytes )
+{
+ int numChars = 0;
+ int allzero = true;
+
+ while (bytes--) {
+ if (0 != *charsin)
+ allzero = false;
+ *hexout++ = __tohex( (*charsin / 16) & 15 );
+ *hexout++ = __tohex( (*charsin++) & 15 );
+ numChars += 2;
+ }
+ if (allzero) // doesn't matter if we actually set more than needed above
+ return (numChars > 2 ? 2 : numChars);
+ return numChars;
+}
+
+static void
+gdbfileio_fio_to_newlib_time_t( fio_time_t *f, newlib_time_t *n )
+{
+ GDBFILEIO_FIO_TO_NEWLIB( f, *n, fio_time_t );
+} // gdbfileio_fio_to_newlib_time_t()
+
+static void
+gdbfileio_newlib_to_fio_int_t( newlib_int_t *n, fio_int_t *f )
+{
+ GDBFILEIO_NEWLIB_TO_FIO( f, *n, fio_int_t );
+} // gdbfileio_newlib_to_fio_int_t()
+
+static void
+gdbfileio_newlib_to_fio_uint_t( newlib_uint_t *n, fio_uint_t *f )
+{
+ GDBFILEIO_NEWLIB_TO_FIO( f, *n, fio_uint_t );
+} // gdbfileio_newlib_to_fio_uint_t()
+
+static void
+gdbfileio_fio_to_newlib_long_t( fio_long_t *f, newlib_long_t *n )
+{
+ GDBFILEIO_FIO_TO_NEWLIB( f, *n, fio_long_t );
+} // gdbfileio_fio_to_newlib_long_t()
+
+static void
+gdbfileio_newlib_to_fio_long_t( newlib_long_t *n, fio_long_t *f )
+{
+ GDBFILEIO_NEWLIB_TO_FIO( f, *n, fio_long_t );
+} // gdbfileio_newlib_to_fio_long_t()
+
+static void
+gdbfileio_fio_to_newlib_mode_t( fio_mode_t *f, newlib_mode_t *n )
+{
+ GDBFILEIO_FIO_TO_NEWLIB( f, *n, fio_mode_t );
+} // gdbfileio_fio_to_newlib_mode_t()
+
+static void
+gdbfileio_newlib_to_fio_mode_t( newlib_mode_t *n, fio_mode_t *f )
+{
+ GDBFILEIO_NEWLIB_TO_FIO( f, *n, fio_mode_t );
+} // gdbfileio_newlib_to_fio_mode_t()
+
+static void
+gdbfileio_fio_to_newlib_dev_t( fio_uint_t *f, newlib_dev_t *n )
+{
+ GDBFILEIO_FIO_TO_NEWLIB( f, *n, fio_uint_t );
+} // gdbfileio_fio_to_newlib_dev_t()
+
+static void
+gdbfileio_fio_to_newlib_ino_t( fio_uint_t *f, newlib_ino_t *n )
+{
+ GDBFILEIO_FIO_TO_NEWLIB( f, *n, fio_uint_t );
+} // gdbfileio_fio_to_newlib_ino_t()
+
+// these defines are good enough for now (to save code size) as they
+// are the same functions in practice
+#define gdbfileio_fio_to_newlib_nlink_t gdbfileio_fio_to_newlib_ino_t
+#define gdbfileio_fio_to_newlib_uid_t gdbfileio_fio_to_newlib_ino_t
+#define gdbfileio_fio_to_newlib_gid_t gdbfileio_fio_to_newlib_ino_t
+#define gdbfileio_fio_to_newlib_off_t gdbfileio_fio_to_newlib_long_t
+
+
+// this function is commonly used by most functions to handle everything
+// once the packet has been constructed. It doesn't have to be used - it's
+// just nice to keep this in one place for maintenance reasons.
+static int
+gdbfileio_common_sendpkt( char *buf, int *sig )
+{
+ int status;
+
+ __putpacket( buf );
+
+ do {
+ __getpacket( __remcomInBuffer );
+ status = __process_packet( __remcomInBuffer );
+ } while ( status == 0 );
+
+ if ( __fileio_ctrlc_set )
+ *sig = SIGINT;
+ if ( !__fileio_retcode_set ) // deal with protocol failure
+ return -FILEIO_EINVAL;
+ if ( __fileio_retcode < 0 && __fileio_errno_set )
+ return -__fileio_errno;
+ else
+ return __fileio_retcode;
+} // gdbfileio_common_sendpkt()
+
+// deal with a received F packet. This is called from __process_packet in
+// generic-stub.c
+__externC void
+cyg_hal_gdbfileio_process_F_packet( char *packet,
+ char *__remcomOutBuffer )
+{
+ // Reply packet structure:
+ // F<retcode>[,<errno>[,<Ctrl-C flag>]][;<call specific attachment>]
+
+ char *p = &packet[1];
+ cyg_bool minus = false;
+ target_register_t temptrt;
+
+ __fileio_retcode_set = __fileio_errno_set = __fileio_ctrlc_set = false;
+
+ if (*p == '-') {
+ minus = true;
+ p++;
+ }
+
+ __hexToInt( &p, &temptrt );
+ __fileio_retcode = minus ? -(int)temptrt : (int)temptrt;
+ __fileio_retcode_set = true;
+
+ if ( *p++ == ',' ) {
+ // get errno
+ __hexToInt( &p, &temptrt );
+ __fileio_errno = (int)temptrt;
+ __fileio_errno_set = true;
+ if ( *p++ == ',' ) {
+ if ( *p == 'C' ) {
+ __fileio_ctrlc_set = true;
+ }
+ }
+ }
+ // ignore anything afterwards (e.g. call specific attachment) for now
+
+} // cyg_hal_gdbfileio_process_F_packet()
+
+__externC int
+cyg_hal_gdbfileio_open( const char *name, int flags, int mode, int *sig )
+{
+ size_t namelen;
+ unsigned int i=0;
+ fio_mode_t fmode;
+ fio_int_t fflags;
+
+ // clear out unsupported flags/modes, as per the spec
+ flags &= FILEIO_O_SUPPORTED;
+ mode &= FILEIO_S_SUPPORTED;
+
+ gdbfileio_newlib_to_fio_int_t( &flags, &fflags );
+ gdbfileio_newlib_to_fio_mode_t( &mode, &fmode );
+
+ __remcomOutBuffer[i++] = 'F';
+ __remcomOutBuffer[i++] = 'o';
+ __remcomOutBuffer[i++] = 'p';
+ __remcomOutBuffer[i++] = 'e';
+ __remcomOutBuffer[i++] = 'n';
+ __remcomOutBuffer[i++] = ',';
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)name,
+ sizeof(name)*8 );
+ // i now points after the parameter
+ __remcomOutBuffer[i++] = '/';
+ namelen = strlen( name )+1; // includes '\0'
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)namelen,
+ sizeof(namelen)*8 );
+ __remcomOutBuffer[i++] = ',';
+ i += chars_to_hex( (char *)&fflags, &__remcomOutBuffer[i], sizeof(fflags) );
+ __remcomOutBuffer[i++] = ',';
+ i += chars_to_hex( (char *)&fmode, &__remcomOutBuffer[i], sizeof(fmode) );
+ __remcomOutBuffer[i] = 0;
+
+ return gdbfileio_common_sendpkt( __remcomOutBuffer, sig );
+} // cyg_hal_gdbfileio_open()
+
+__externC int
+cyg_hal_gdbfileio_close( int fd, int *sig )
+{
+ unsigned int i=0;
+ fio_int_t ffd;
+
+ gdbfileio_newlib_to_fio_int_t( &fd, &ffd );
+ __remcomOutBuffer[i++] = 'F';
+ __remcomOutBuffer[i++] = 'c';
+ __remcomOutBuffer[i++] = 'l';
+ __remcomOutBuffer[i++] = 'o';
+ __remcomOutBuffer[i++] = 's';
+ __remcomOutBuffer[i++] = 'e';
+ __remcomOutBuffer[i++] = ',';
+ i += chars_to_hex( (char *)&ffd, &__remcomOutBuffer[i], sizeof(ffd) );
+ // i now points after the parameter
+ __remcomOutBuffer[i] = 0;
+
+ return gdbfileio_common_sendpkt( __remcomOutBuffer, sig );
+} // cyg_hal_gdbfileio_close()
+
+__externC int
+cyg_hal_gdbfileio_read( int fd, void *buf, size_t count, int *sig )
+{
+ unsigned int i=0;
+ fio_int_t ffd;
+ fio_uint_t fcount;
+ unsigned int uicount = (unsigned int)count;
+
+ gdbfileio_newlib_to_fio_int_t( &fd, &ffd );
+ gdbfileio_newlib_to_fio_uint_t( &uicount, &fcount );
+
+ __remcomOutBuffer[i++] = 'F';
+ __remcomOutBuffer[i++] = 'r';
+ __remcomOutBuffer[i++] = 'e';
+ __remcomOutBuffer[i++] = 'a';
+ __remcomOutBuffer[i++] = 'd';
+ __remcomOutBuffer[i++] = ',';
+ i += chars_to_hex( (char *)&ffd, &__remcomOutBuffer[i], sizeof(ffd) );
+ // i now points after the parameter
+ __remcomOutBuffer[i++] = ',';
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)buf,
+ sizeof(buf)*8 );
+ __remcomOutBuffer[i++] = ',';
+ i += chars_to_hex( (char *)&fcount, &__remcomOutBuffer[i], sizeof(fcount) );
+ __remcomOutBuffer[i] = 0;
+
+ return gdbfileio_common_sendpkt( __remcomOutBuffer, sig );
+} // cyg_hal_gdbfileio_read()
+
+__externC int
+cyg_hal_gdbfileio_write( int fd, const void *buf, size_t count, int *sig )
+{
+ unsigned int i=0;
+ fio_int_t ffd;
+ fio_uint_t fcount;
+ unsigned int uicount = (unsigned int)count;
+
+ gdbfileio_newlib_to_fio_int_t( &fd, &ffd );
+ gdbfileio_newlib_to_fio_uint_t( &uicount, &fcount );
+
+ __remcomOutBuffer[i++] = 'F';
+ __remcomOutBuffer[i++] = 'w';
+ __remcomOutBuffer[i++] = 'r';
+ __remcomOutBuffer[i++] = 'i';
+ __remcomOutBuffer[i++] = 't';
+ __remcomOutBuffer[i++] = 'e';
+ __remcomOutBuffer[i++] = ',';
+ i += chars_to_hex( (char *)&ffd, &__remcomOutBuffer[i], sizeof(ffd) );
+ // i now points after the parameter
+ __remcomOutBuffer[i++] = ',';
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)buf,
+ sizeof(buf)*8 );
+ __remcomOutBuffer[i++] = ',';
+ i += chars_to_hex( (char *)&fcount, &__remcomOutBuffer[i], sizeof(fcount) );
+ __remcomOutBuffer[i] = 0;
+
+ return gdbfileio_common_sendpkt( __remcomOutBuffer, sig );
+} // cyg_hal_gdbfileio_write()
+
+__externC int
+cyg_hal_gdbfileio_lseek( int fd, /* off_t */ long offset, int whence, int *sig )
+{
+ unsigned int i=0;
+ fio_int_t ffd;
+ fio_long_t foffset;
+ fio_int_t fwhence;
+
+ gdbfileio_newlib_to_fio_int_t( &fd, &ffd );
+ gdbfileio_newlib_to_fio_long_t( &offset, &foffset );
+ gdbfileio_newlib_to_fio_int_t( &whence, &fwhence );
+
+ __remcomOutBuffer[i++] = 'F';
+ __remcomOutBuffer[i++] = 'l';
+ __remcomOutBuffer[i++] = 's';
+ __remcomOutBuffer[i++] = 'e';
+ __remcomOutBuffer[i++] = 'e';
+ __remcomOutBuffer[i++] = 'k';
+ __remcomOutBuffer[i++] = ',';
+ i += chars_to_hex( (char *)&ffd, &__remcomOutBuffer[i], sizeof(ffd) );
+ // i now points after the parameter
+ __remcomOutBuffer[i++] = ',';
+ i += chars_to_hex( (char *)&foffset, &__remcomOutBuffer[i],
+ sizeof(foffset) );
+ __remcomOutBuffer[i++] = ',';
+ i += chars_to_hex( (char *)&fwhence, &__remcomOutBuffer[i],
+ sizeof(fwhence) );
+ __remcomOutBuffer[i] = 0;
+
+ return gdbfileio_common_sendpkt( __remcomOutBuffer, sig );
+} // cyg_hal_gdbfileio_lseek()
+
+__externC int
+cyg_hal_gdbfileio_rename( const char *oldpath, const char *newpath, int *sig )
+{
+ unsigned int i=0;
+ size_t namelen;
+
+ __remcomOutBuffer[i++] = 'F';
+ __remcomOutBuffer[i++] = 'r';
+ __remcomOutBuffer[i++] = 'e';
+ __remcomOutBuffer[i++] = 'n';
+ __remcomOutBuffer[i++] = 'a';
+ __remcomOutBuffer[i++] = 'm';
+ __remcomOutBuffer[i++] = 'e';
+ __remcomOutBuffer[i++] = ',';
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)oldpath,
+ sizeof(oldpath)*8 );
+ // i now points after the parameter
+ __remcomOutBuffer[i++] = '/';
+ namelen = strlen( oldpath )+1; // includes '\0'
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)namelen,
+ sizeof(namelen)*8 );
+ __remcomOutBuffer[i++] = ',';
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)newpath,
+ sizeof(newpath)*8 );
+ // i now points after the parameter
+ __remcomOutBuffer[i++] = '/';
+ namelen = strlen( newpath )+1; // includes '\0'
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)namelen,
+ sizeof(namelen)*8 );
+ __remcomOutBuffer[i] = 0;
+
+ return gdbfileio_common_sendpkt( __remcomOutBuffer, sig );
+} // cyg_hal_gdbfileio_rename()
+
+__externC int
+cyg_hal_gdbfileio_unlink( const char *pathname, int *sig )
+{
+ unsigned int i=0;
+ size_t namelen;
+
+ __remcomOutBuffer[i++] = 'F';
+ __remcomOutBuffer[i++] = 'u';
+ __remcomOutBuffer[i++] = 'n';
+ __remcomOutBuffer[i++] = 'l';
+ __remcomOutBuffer[i++] = 'i';
+ __remcomOutBuffer[i++] = 'n';
+ __remcomOutBuffer[i++] = 'k';
+ __remcomOutBuffer[i++] = ',';
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)pathname,
+ sizeof(pathname)*8 );
+ // i now points after the parameter
+ __remcomOutBuffer[i++] = '/';
+ namelen = strlen( pathname )+1; // includes '\0'
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)namelen,
+ sizeof(namelen)*8 );
+ __remcomOutBuffer[i] = 0;
+
+ return gdbfileio_common_sendpkt( __remcomOutBuffer, sig );
+} // cyg_hal_gdbfileio_unlink()
+
+__externC int
+cyg_hal_gdbfileio_isatty( int fd, int *sig )
+{
+ unsigned int i=0;
+ fio_int_t ffd;
+
+ gdbfileio_newlib_to_fio_int_t( &fd, &ffd );
+
+ __remcomOutBuffer[i++] = 'F';
+ __remcomOutBuffer[i++] = 'i';
+ __remcomOutBuffer[i++] = 's';
+ __remcomOutBuffer[i++] = 'a';
+ __remcomOutBuffer[i++] = 't';
+ __remcomOutBuffer[i++] = 't';
+ __remcomOutBuffer[i++] = 'y';
+ __remcomOutBuffer[i++] = ',';
+ i += chars_to_hex( (char *)&ffd, &__remcomOutBuffer[i], sizeof(ffd) );
+ // i now points after the parameter
+ __remcomOutBuffer[i] = 0;
+
+ return gdbfileio_common_sendpkt( __remcomOutBuffer, sig );
+} // cyg_hal_gdbfileio_isatty()
+
+__externC int
+cyg_hal_gdbfileio_system( const char *command, int *sig )
+{
+ unsigned int i=0;
+ size_t namelen;
+
+ __remcomOutBuffer[i++] = 'F';
+ __remcomOutBuffer[i++] = 's';
+ __remcomOutBuffer[i++] = 'y';
+ __remcomOutBuffer[i++] = 's';
+ __remcomOutBuffer[i++] = 't';
+ __remcomOutBuffer[i++] = 'e';
+ __remcomOutBuffer[i++] = 'm';
+ __remcomOutBuffer[i++] = ',';
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)command,
+ sizeof(command)*8 );
+ // i now points after the parameter
+ __remcomOutBuffer[i++] = '/';
+ namelen = strlen( command )+1; // includes '\0'
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)namelen,
+ sizeof(namelen)*8 );
+ __remcomOutBuffer[i] = 0;
+
+ return gdbfileio_common_sendpkt( __remcomOutBuffer, sig );
+} // cyg_hal_gdbfileio_system()
+
+__externC int
+cyg_hal_gdbfileio_gettimeofday( void *tv, void *tz, int *sig )
+{
+ unsigned int i=0;
+ struct newlib_timeval *ntv = (struct newlib_timeval *)tv;
+ struct fio_timeval ftv;
+ int rc;
+
+ // protocol doesn't support non-null timezone. Just enforce it here.
+ if (NULL != tz)
+ return -FILEIO_EINVAL;
+
+ __remcomOutBuffer[i++] = 'F';
+ __remcomOutBuffer[i++] = 'g';
+ __remcomOutBuffer[i++] = 'e';
+ __remcomOutBuffer[i++] = 't';
+ __remcomOutBuffer[i++] = 't';
+ __remcomOutBuffer[i++] = 'i';
+ __remcomOutBuffer[i++] = 'm';
+ __remcomOutBuffer[i++] = 'e';
+ __remcomOutBuffer[i++] = 'o';
+ __remcomOutBuffer[i++] = 'f';
+ __remcomOutBuffer[i++] = 'd';
+ __remcomOutBuffer[i++] = 'a';
+ __remcomOutBuffer[i++] = 'y';
+ __remcomOutBuffer[i++] = ',';
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)&ftv,
+ sizeof(&ftv)*8 );
+ __remcomOutBuffer[i++] = ',';
+ __remcomOutBuffer[i++] = '0'; // tzptr
+ __remcomOutBuffer[i] = 0;
+
+ rc = gdbfileio_common_sendpkt( __remcomOutBuffer, sig );
+
+ // now ftv should have its contents filled
+ gdbfileio_fio_to_newlib_time_t( &ftv.tv_sec, &ntv->tv_sec );
+ gdbfileio_fio_to_newlib_long_t( &ftv.tv_usec, &ntv->tv_usec );
+
+ return rc;
+} // cyg_hal_gdbfileio_gettimeofday()
+
+__externC int
+cyg_hal_gdbfileio_stat( const char *pathname, struct newlib_stat *buf,
+ int *sig )
+{
+ unsigned int i=0;
+ int rc;
+ size_t namelen;
+ struct fio_stat fbuf;
+
+ __remcomOutBuffer[i++] = 'F';
+ __remcomOutBuffer[i++] = 's';
+ __remcomOutBuffer[i++] = 't';
+ __remcomOutBuffer[i++] = 'a';
+ __remcomOutBuffer[i++] = 't';
+ __remcomOutBuffer[i++] = ',';
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)pathname,
+ sizeof(pathname)*8 );
+ // i now points after the parameter
+ __remcomOutBuffer[i++] = '/';
+ namelen = strlen( pathname )+1; // includes '\0'
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)namelen,
+ sizeof(namelen)*8 );
+ __remcomOutBuffer[i++] = ',';
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)&fbuf,
+ sizeof(&fbuf)*8 );
+ __remcomOutBuffer[i] = 0;
+
+ rc = gdbfileio_common_sendpkt( __remcomOutBuffer, sig );
+
+ // now fbuf should have its contents filled
+ gdbfileio_fio_to_newlib_dev_t( &fbuf.st_dev, &buf->st_dev );
+ gdbfileio_fio_to_newlib_ino_t( &fbuf.st_ino, &buf->st_ino );
+ gdbfileio_fio_to_newlib_mode_t( &fbuf.st_mode, &buf->st_mode );
+ gdbfileio_fio_to_newlib_nlink_t( &fbuf.st_nlink, &buf->st_nlink );
+ gdbfileio_fio_to_newlib_uid_t( &fbuf.st_uid, &buf->st_uid );
+ gdbfileio_fio_to_newlib_gid_t( &fbuf.st_gid, &buf->st_gid );
+ gdbfileio_fio_to_newlib_dev_t( &fbuf.st_rdev, &buf->st_rdev );
+ gdbfileio_fio_to_newlib_off_t( &fbuf.st_size, &buf->st_size );
+ gdbfileio_fio_to_newlib_off_t( &fbuf.st_size, &buf->st_size );
+ gdbfileio_fio_to_newlib_off_t( &fbuf.st_size, &buf->st_size );
+ gdbfileio_fio_to_newlib_off_t( &fbuf.st_size, &buf->st_size );
+#if !defined(__svr4__) || defined(__PPC__) || defined(__sun__)
+ gdbfileio_fio_to_newlib_long_t( &fbuf.st_blksize, &buf->st_blksize );
+ gdbfileio_fio_to_newlib_long_t( &fbuf.st_blocks, &buf->st_blocks );
+#endif
+ gdbfileio_fio_to_newlib_time_t( &fbuf.st_atime, &buf->st_atime );
+ gdbfileio_fio_to_newlib_time_t( &fbuf.st_mtime, &buf->st_mtime );
+ gdbfileio_fio_to_newlib_time_t( &fbuf.st_ctime, &buf->st_ctime );
+
+ return rc;
+} // cyg_hal_gdbfileio_stat()
+
+__externC int
+cyg_hal_gdbfileio_fstat( int fd, struct newlib_stat *buf, int *sig )
+{
+ unsigned int i=0;
+ int rc;
+ struct fio_stat fbuf;
+
+ __remcomOutBuffer[i++] = 'F';
+ __remcomOutBuffer[i++] = 'f';
+ __remcomOutBuffer[i++] = 's';
+ __remcomOutBuffer[i++] = 't';
+ __remcomOutBuffer[i++] = 'a';
+ __remcomOutBuffer[i++] = 't';
+ __remcomOutBuffer[i++] = ',';
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)fd,
+ sizeof(fd)*8 );
+ // i now points after the parameter
+ __remcomOutBuffer[i++] = ',';
+ i += __intToHex( &__remcomOutBuffer[i], (target_register_t)&fbuf,
+ sizeof(&fbuf)*8 );
+ __remcomOutBuffer[i] = 0;
+
+ rc = gdbfileio_common_sendpkt( __remcomOutBuffer, sig );
+
+ // now fbuf should have its contents filled
+ gdbfileio_fio_to_newlib_dev_t( &fbuf.st_dev, &buf->st_dev );
+ gdbfileio_fio_to_newlib_ino_t( &fbuf.st_ino, &buf->st_ino );
+ gdbfileio_fio_to_newlib_mode_t( &fbuf.st_mode, &buf->st_mode );
+ gdbfileio_fio_to_newlib_nlink_t( &fbuf.st_nlink, &buf->st_nlink );
+ gdbfileio_fio_to_newlib_uid_t( &fbuf.st_uid, &buf->st_uid );
+ gdbfileio_fio_to_newlib_gid_t( &fbuf.st_gid, &buf->st_gid );
+ gdbfileio_fio_to_newlib_dev_t( &fbuf.st_rdev, &buf->st_rdev );
+ gdbfileio_fio_to_newlib_off_t( &fbuf.st_size, &buf->st_size );
+ gdbfileio_fio_to_newlib_off_t( &fbuf.st_size, &buf->st_size );
+ gdbfileio_fio_to_newlib_off_t( &fbuf.st_size, &buf->st_size );
+ gdbfileio_fio_to_newlib_off_t( &fbuf.st_size, &buf->st_size );
+#if !defined(__svr4__) || defined(__PPC__) || defined(__sun__)
+ gdbfileio_fio_to_newlib_long_t( &fbuf.st_blksize, &buf->st_blksize );
+ gdbfileio_fio_to_newlib_long_t( &fbuf.st_blocks, &buf->st_blocks );
+#endif
+ gdbfileio_fio_to_newlib_time_t( &fbuf.st_atime, &buf->st_atime );
+ gdbfileio_fio_to_newlib_time_t( &fbuf.st_mtime, &buf->st_mtime );
+ gdbfileio_fio_to_newlib_time_t( &fbuf.st_ctime, &buf->st_ctime );
+
+ return rc;
+} // cyg_hal_gdbfileio_fstat()
+
+/* EOF gdb-fileio.c */
diff --git a/ecos/packages/hal/common/current/src/gdb-fileio.h b/ecos/packages/hal/common/current/src/gdb-fileio.h
new file mode 100644
index 0000000..8e22d98
--- /dev/null
+++ b/ecos/packages/hal/common/current/src/gdb-fileio.h
@@ -0,0 +1,139 @@
+/* gdb-fileio.h.
+ Contains definitions used inside of the File I/O facility.
+
+ Copyright 2002 Free Software Foundation, Inc.
+
+*/
+
+#ifndef _GDB_FILEIO_H_
+#define _GDB_FILEIO_H_
+
+#include <sys/types.h>
+
+/* The following flags are defined to be independent of the host
+ as well as the target side implementation of these constants.
+ All constants are defined with a leading FILEIO_ in the name
+ to allow the usage of these constants together with the
+ corresponding implementation dependent constants in one module. */
+
+/* open(2) flags */
+#define FILEIO_O_RDONLY 0x0
+#define FILEIO_O_WRONLY 0x1
+#define FILEIO_O_RDWR 0x2
+#define FILEIO_O_APPEND 0x8
+#define FILEIO_O_CREAT 0x200
+#define FILEIO_O_TRUNC 0x400
+#define FILEIO_O_EXCL 0x800
+#define FILEIO_O_BINARY 0x10000
+#define FILEIO_O_TEXT 0x20000
+#define FILEIO_O_SUPPORTED (FILEIO_O_RDONLY | FILEIO_O_WRONLY| \
+ FILEIO_O_RDWR | FILEIO_O_APPEND| \
+ FILEIO_O_CREAT | FILEIO_O_TRUNC| \
+ FILEIO_O_EXCL | FILEIO_O_BINARY | \
+ FILEIO_O_TEXT )
+
+/* mode_t bits */
+#define FILEIO_S_IFREG 0100000
+#define FILEIO_S_IFDIR 040000
+#define FILEIO_S_IFCHR 020000
+#define FILEIO_S_IRUSR 0400
+#define FILEIO_S_IWUSR 0200
+#define FILEIO_S_IXUSR 0100
+#define FILEIO_S_IRWXU 0700
+#define FILEIO_S_IRGRP 040
+#define FILEIO_S_IWGRP 020
+#define FILEIO_S_IXGRP 010
+#define FILEIO_S_IRWXG 070
+#define FILEIO_S_IROTH 04
+#define FILEIO_S_IWOTH 02
+#define FILEIO_S_IXOTH 01
+#define FILEIO_S_IRWXO 07
+#define FILEIO_S_SUPPORTED (FILEIO_S_IFREG|FILEIO_S_IFDIR| \
+ FILEIO_S_IRWXU|FILEIO_S_IRWXG| \
+ FILEIO_S_IRWXO)
+
+/* lseek(2) flags */
+#define FILEIO_SEEK_SET 0
+#define FILEIO_SEEK_CUR 1
+#define FILEIO_SEEK_END 2
+
+/* errno values */
+#define FILEIO_EPERM 1
+#define FILEIO_ENOENT 2
+#define FILEIO_EINTR 4
+#define FILEIO_EIO 5
+#define FILEIO_EBADF 9
+#define FILEIO_EACCES 13
+#define FILEIO_EFAULT 14
+#define FILEIO_EBUSY 16
+#define FILEIO_EEXIST 17
+#define FILEIO_ENODEV 19
+#define FILEIO_ENOTDIR 20
+#define FILEIO_EISDIR 21
+#define FILEIO_EINVAL 22
+#define FILEIO_ENFILE 23
+#define FILEIO_EMFILE 24
+#define FILEIO_EFBIG 27
+#define FILEIO_ENOSPC 28
+#define FILEIO_ESPIPE 29
+#define FILEIO_EROFS 30
+#define FILEIO_ENOSYS 88
+#define FILEIO_ENAMETOOLONG 91
+#define FILEIO_EUNKNOWN 9999
+
+/* limits */
+#define FILEIO_INT_MIN -2147483648L
+#define FILEIO_INT_MAX 2147483647L
+#define FILEIO_UINT_MAX 4294967295UL
+#define FILEIO_LONG_MIN -9223372036854775808LL
+#define FILEIO_LONG_MAX 9223372036854775807LL
+#define FILEIO_ULONG_MAX 18446744073709551615ULL
+
+/* Integral types as used in protocol. */
+#if 0
+typedef __int32_t fio_int_t;
+typedef __uint32_t fio_uint_t, fio_mode_t, fio_time_t;
+typedef __int64_t fio_long_t;
+typedef __uint64_t fio_ulong_t;
+#endif
+
+#define FIO_INT_LEN 4
+#define FIO_UINT_LEN 4
+#define FIO_MODE_LEN 4
+#define FIO_TIME_LEN 4
+#define FIO_LONG_LEN 8
+#define FIO_ULONG_LEN 8
+
+typedef char fio_int_t[FIO_INT_LEN];
+typedef char fio_uint_t[FIO_UINT_LEN];
+typedef char fio_mode_t[FIO_MODE_LEN];
+typedef char fio_time_t[FIO_TIME_LEN];
+typedef char fio_long_t[FIO_LONG_LEN];
+typedef char fio_ulong_t[FIO_ULONG_LEN];
+
+/* Struct stat as used in protocol. For complete independence
+ of host/target systems, it's defined as an array with offsets
+ to the members. */
+
+struct fio_stat {
+ fio_uint_t st_dev;
+ fio_uint_t st_ino;
+ fio_mode_t st_mode;
+ fio_uint_t st_nlink;
+ fio_uint_t st_uid;
+ fio_uint_t st_gid;
+ fio_uint_t st_rdev;
+ fio_ulong_t st_size;
+ fio_ulong_t st_blksize;
+ fio_ulong_t st_blocks;
+ fio_time_t st_atime;
+ fio_time_t st_mtime;
+ fio_time_t st_ctime;
+};
+
+struct fio_timeval {
+ fio_time_t tv_sec;
+ fio_long_t tv_usec;
+};
+
+#endif /* _GDB_FILEIO_H_ */
diff --git a/ecos/packages/hal/common/current/src/generic-stub.c b/ecos/packages/hal/common/current/src/generic-stub.c
new file mode 100644
index 0000000..724cc4d
--- /dev/null
+++ b/ecos/packages/hal/common/current/src/generic-stub.c
@@ -0,0 +1,2057 @@
+#include "board.h"
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+/* Eventually, this should default to ON */
+#if USE_GDBSTUB_PROTOTYPES
+#include "stub-tservice.h"
+#include "generic-stub.h"
+#else
+// Function declarations (prevents compiler warnings)
+int stubhex (unsigned char ch);
+static void unlock_thread_scheduler (void);
+static uint32 crc32 (target_addr_t mem, int len, uint32 crc);
+#endif
+
+#include "thread-pkts.h"
+ /* Defines function macros if thread support is not selected in board.h */
+
+#ifdef __ECOS__
+char GDB_stubs_version[] CYGBLD_ATTRIB_WEAK =
+ "eCos GDB stubs - built " __DATE__ " / " __TIME__;
+#endif
+
+/****************************************************************************
+
+ THIS SOFTWARE IS NOT COPYRIGHTED
+
+ HP offers the following for use in the public domain. HP makes no
+ warranty with regard to the software or it's performance and the
+ user accepts the software "AS IS" with all faults.
+
+ HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+ TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ * Module name: remcom.c $
+ * Revision: 1.34 $
+ * Date: 91/03/09 12:29:49 $
+ * Contributor: Lake Stevens Instrument Division$
+ *
+ * Description: low level support for gdb debugger. $
+ *
+ * Considerations: only works on target hardware $
+ *
+ * Written by: Glenn Engel $
+ * ModuleState: Experimental $
+ *
+ * NOTES: See Below $
+ *
+ * Modified for SPARC by Stu Grossman, Red Hat.
+ * Modified for generic CygMON stub support by Bob Manson, Red Hat.
+ *
+ * To enable debugger support, two things need to happen. One, a
+ * call to set_debug_traps () is necessary in order to allow any breakpoints
+ * or error conditions to be properly intercepted and reported to gdb.
+ * Two, a breakpoint needs to be generated to begin communication. This
+ * is most easily accomplished by a call to breakpoint (). Breakpoint ()
+ * simulates a breakpoint by executing a trap #1.
+ *
+ *************
+ *
+ * The following gdb commands are supported:
+ *
+ * command function Return value
+ *
+ * g return the value of the CPU registers hex data or ENN
+ * G set the value of the CPU registers OK or ENN
+ *
+ * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
+ * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
+ *
+ * c Resume at current address SNN ( signal NN)
+ * cAA..AA Continue at address AA..AA SNN
+ *
+ * s Step one instruction SNN
+ * sAA..AA Step one instruction from AA..AA SNN
+ *
+ * k kill
+ *
+ * ? What was the last sigval ? SNN (signal NN)
+ *
+ * bBB..BB Set baud rate to BB..BB OK or BNN, then sets
+ * baud rate
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum. A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer. '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host: Reply:
+ * $m0,10#2a +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+#ifdef __ECOS__
+
+// We cannot share memcpy and memset with the rest of the system since
+// the user may want to step through it.
+static inline void*
+_memcpy(void* dest, void* src, int size)
+{
+ unsigned char* __d = (unsigned char*) dest;
+ unsigned char* __s = (unsigned char*) src;
+
+ while(size--)
+ *__d++ = *__s++;
+
+ return dest;
+}
+
+static inline void*
+_memset(void* s, int c, int size)
+{
+ unsigned char* __s = (unsigned char*) s;
+ unsigned char __c = (unsigned char) c;
+
+ while(size--)
+ *__s++ = __c;
+
+ return s;
+}
+
+#else
+#include <string.h>
+#include <signal.h>
+#define _memcpy memcpy
+#define _memset memset
+#endif // __ECOS__
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+#ifdef __ECOS__
+#ifdef NUMREGBYTES
+#define BUFMAX (32 + (NUMREGBYTES*2))
+#else
+#define BUFMAX 2048
+#endif
+#else
+#define BUFMAX 2048
+#endif
+
+static int initialized = 0; /* !0 means we've been initialized */
+
+static int process_exception (int sigval);
+static void do_nothing (void); /* and do it gracefully */
+static int syscall_do_nothing (int);
+
+#ifdef CYGSEM_ECOS_SUPPORTS_PROGRAM_ARGS
+void __free_program_args (void);
+static char *__add_program_arg (int argnum, uint32 arglen);
+#endif
+
+volatile __PFI __process_exception_vec = process_exception;
+volatile __PFV __process_exit_vec = do_nothing;
+volatile __PFI __process_syscall_vec = syscall_do_nothing;
+volatile __PFI __process_signal_vec = NULL;
+volatile __PFV __init_vec = NULL;
+volatile __PFV __cleanup_vec = NULL;
+
+static const char hexchars[] = "0123456789abcdef";
+
+static void process_query (char *pkt);
+static void process_set (char *pkt);
+
+char
+__tohex (int c)
+{
+ return hexchars [c & 15];
+}
+
+#define __tohex(c) hexchars[(c) & 15]
+
+#ifndef NUMREGS_GDB
+#define NUMREGS_GDB NUMREGS
+#endif
+
+/* One pushback character. */
+int ungot_char = -1;
+
+static int
+readDebugChar (void)
+{
+ if (ungot_char > 0)
+ {
+ int result = ungot_char;
+ ungot_char = -1;
+ return result;
+ }
+ else
+ return getDebugChar ();
+}
+
+/* Convert ch from a hex digit to an int. */
+
+int
+stubhex (ch)
+ unsigned char ch;
+{
+ if (ch >= 'a' && ch <= 'f')
+ return ch-'a'+10;
+ if (ch >= '0' && ch <= '9')
+ return ch-'0';
+ if (ch >= 'A' && ch <= 'F')
+ return ch-'A'+10;
+ return -1;
+}
+
+void
+__getpacket (buffer)
+ char *buffer;
+{
+ struct gdb_packet packet;
+ int res;
+
+ packet.state = 0;
+ packet.contents = buffer;
+ packet.err = 0;
+ while ((res = __add_char_to_packet (readDebugChar () & 0xff, &packet)) != 1) {
+ if (res == -2) {
+ putDebugChar ('-'); // Tell host packet was not processed
+ // Reset for the next packet
+ packet.state = 0;
+ packet.err = 0;
+ }
+ }
+}
+
+int
+__add_char_to_packet (ch, packet)
+ unsigned int ch;
+ struct gdb_packet *packet;
+{
+ if (packet->state == 0)
+ {
+ if (ch == '$')
+ {
+ packet->state = 1;
+ packet->length = 0;
+ packet->checksum = 0;
+ packet->xmitcsum = -1;
+ }
+ return 0;
+ }
+
+ if (packet->state == 1)
+ {
+ if (packet->length == BUFMAX)
+ {
+ packet->state = 0;
+ packet->err = 1;
+ }
+ else if (ch == '#')
+ {
+ packet->contents[packet->length] = 0;
+ packet->state = 2;
+ }
+ else
+ {
+ packet->checksum += ch;
+ packet->contents[packet->length++] = ch;
+ }
+ return 0;
+ }
+
+ if (packet->state == 2)
+ {
+ packet->xmitcsum = stubhex (ch) << 4;
+ packet->state = 3;
+ return 0;
+ }
+
+ if (packet->state == 3)
+ {
+ packet->xmitcsum |= stubhex (ch);
+ if (packet->err) {
+ // Packet was too long - just tell the consumer
+ return -2;
+ }
+ if ((packet->checksum & 255) != packet->xmitcsum)
+ {
+ putDebugChar ('-'); /* failed checksum */
+ packet->state = 0;
+ return -1;
+ }
+ else
+ {
+ putDebugChar ('+'); /* successful transfer */
+ /* if a sequence char is present, reply the sequence ID */
+ if (packet->contents[2] == ':')
+ {
+ uint32 count = packet->length;
+ uint32 i;
+ putDebugChar (packet->contents[0]);
+ putDebugChar (packet->contents[1]);
+ /* remove sequence chars from buffer */
+ for (i=3; i <= count; i++)
+ packet->contents[i-3] = packet->contents[i];
+ }
+ return 1;
+ }
+ }
+ /* We should never get here. */
+ packet->state = 0;
+ return -1;
+}
+
+/* send the packet in buffer. */
+
+void
+__putpacket (buffer)
+ char *buffer;
+{
+ unsigned char checksum;
+ uint32 count;
+ unsigned char ch;
+
+ /* $<packet info>#<checksum>. */
+ do
+ {
+ putDebugChar ('$');
+ checksum = 0;
+ count = 0;
+
+ while ((ch = buffer[count]))
+ {
+ putDebugChar (ch);
+ checksum += ch;
+ count += 1;
+ }
+
+ putDebugChar ('#');
+ putDebugChar (hexchars[(checksum >> 4) & 0xf]);
+ putDebugChar (hexchars[checksum & 0xf]);
+
+ }
+ while ((readDebugChar () & 0x7f) != '+');
+}
+
+char __remcomInBuffer[BUFMAX];
+char __remcomOutBuffer[BUFMAX];
+
+/* Indicate to caller of mem2hex or hex2mem that there has been an
+ error. */
+volatile int __mem_fault = 0;
+
+
+#ifndef TARGET_HAS_OWN_MEM_FUNCS
+/*
+ * _target_readmem_hook / _target_writemem_hook:
+ * Allow target to get involved in reading/writing memory.
+ *
+ * If these hooks are defined by the target, they will be
+ * called for each user program memory access. Otherwise, the stub
+ * will simply dereference a pointer to access user program memory.
+ */
+
+unsigned char (*_target_readmem_hook) (unsigned char* addr);
+void (*_target_writemem_hook) (unsigned char* addr,
+ unsigned char value);
+
+static unsigned char
+get_target_byte (volatile unsigned char *address)
+{
+ if (_target_readmem_hook) /* target needs to control memory access */
+ return _target_readmem_hook ((unsigned char *) address);
+ else
+ return *address;
+}
+
+static void
+put_target_byte (volatile unsigned char *address, unsigned char value)
+{
+ if (_target_writemem_hook) /* target needs to control memory access */
+ _target_writemem_hook ((unsigned char *) address, value);
+ else
+ *address = value;
+}
+
+/* These are the "arguments" to __do_read_mem and __do_write_mem,
+ which are passed as globals to avoid squeezing them thru
+ __set_mem_fault_trap. */
+
+static volatile target_register_t memCount;
+static volatile unsigned char *memSrc, *memDst;
+
+/*
+ * __do_read_mem:
+ * Copy from target memory to trusted memory.
+ */
+
+static void
+__do_read_mem (void)
+{
+ __mem_fault = 0;
+ while (memCount)
+ {
+ unsigned char ch = get_target_byte (memSrc++);
+
+ if (__mem_fault)
+ return;
+ *memDst++ = ch;
+ memCount--;
+ }
+}
+
+/*
+ * __do_write_mem:
+ * Copy from trusted memory to target memory.
+ */
+
+static void
+__do_write_mem (void)
+{
+ __mem_fault = 0;
+ while (memCount)
+ {
+ unsigned char ch = *memSrc++;
+
+ put_target_byte (memDst++, ch);
+ if (__mem_fault)
+ return;
+ memCount--;
+ }
+}
+
+/*
+ * __read_mem_safe:
+ * Get contents of target memory, abort on error.
+ */
+
+int
+__read_mem_safe (void *dst, target_register_t src, int count)
+{
+ memCount = count;
+ memSrc = (unsigned char *) src;
+ memDst = (unsigned char *) dst;
+ __set_mem_fault_trap (__do_read_mem);
+ return count - memCount; /* return number of bytes successfully read */
+}
+
+/*
+ * __write_mem_safe:
+ * Set contents of target memory, abort on error.
+ */
+
+int
+__write_mem_safe (unsigned char *src, target_register_t dst, int count)
+{
+ memCount = count;
+ memSrc = (unsigned char *) src;
+ memDst = (unsigned char *) dst;
+ __set_mem_fault_trap (__do_write_mem);
+ return count - memCount; /* return number of bytes successfully read */
+}
+
+#endif /* TARGET_HAS_OWN_MEM_FUNCS */
+
+/* These are the "arguments" to __mem2hex_helper and __hex2mem_helper,
+ which are passed as globals to avoid squeezing them thru
+ __set_mem_fault_trap. */
+
+static int hexMemCount;
+static char *hexMemSrc, *hexMemDst;
+static int may_fault_mode;
+#ifdef TARGET_HAS_HARVARD_MEMORY
+static int progMem;
+#endif
+
+/* Hamburger helper? */
+static void
+__mem2hex_helper (void)
+{
+ union {
+ unsigned long long_val;
+ unsigned char bytes[sizeof(long)];
+ } val;
+ int len, i;
+ unsigned char ch;
+ __mem_fault = 0;
+ while (hexMemCount > 0) {
+ if (may_fault_mode) {
+ if ((hexMemCount >= sizeof(long)) &&
+ (((target_register_t)hexMemSrc & (sizeof(long)-1)) == 0)) {
+ // Should be safe to access via a long
+ len = sizeof(long);
+ } else if ((hexMemCount >= sizeof(short)) &&
+ (((target_register_t)hexMemSrc & (sizeof(short)-1)) == 0)) {
+ // Should be safe to access via a short
+ len = sizeof(short);
+ } else {
+ len = 1;
+ }
+#ifdef TARGET_HAS_HARVARD_MEMORY
+ if (progMem)
+ __read_progmem_safe(&val.bytes[0], hexMemSrc, len);
+ else
+#endif
+ __read_mem_safe(&val.bytes[0], hexMemSrc, len);
+ } else {
+ len = 1;
+ val.bytes[0] = *hexMemSrc;
+ }
+ if (__mem_fault)
+ return;
+
+ for (i = 0; i < len; i++) {
+ ch = val.bytes[i];
+ *(hexMemDst++) = hexchars[(ch >> 4) & 0xf];
+ if (__mem_fault)
+ return;
+ *(hexMemDst++) = hexchars[ch & 0xf];
+ if (__mem_fault)
+ return;
+ }
+ hexMemCount -= len;
+ hexMemSrc += len;
+ }
+}
+
+/* Convert the memory pointed to by MEM into HEX, placing result in BUF.
+ * Return a pointer to the last char put in buf (NUL). In case of a memory
+ * fault, return 0.
+ * If MAY_FAULT is non-zero, then we will handle memory faults by returning
+ * a 0 (and assume that MEM is a pointer into the user program), else we
+ * treat a fault like any other fault in the stub (and assume that MEM is
+ * a pointer into the stub's memory).
+ */
+
+char *
+__mem2hex (mem, buf, count, may_fault)
+ char *mem;
+ char *buf;
+ int count;
+ int may_fault;
+{
+ hexMemDst = (char *) buf;
+ hexMemSrc = (char *) mem;
+ hexMemCount = count;
+ may_fault_mode = may_fault;
+#ifdef TARGET_HAS_HARVARD_MEMORY
+ progMem = 0;
+#endif
+
+ if (may_fault)
+ {
+ if (__set_mem_fault_trap (__mem2hex_helper))
+ return 0;
+ }
+ else
+ __mem2hex_helper ();
+
+ *hexMemDst = 0;
+
+ return (char *) hexMemDst;
+}
+
+/* Convert the target memory identified by MEM into HEX, placing result in BUF.
+ * Return a pointer to the last char put in buf (NUL). In case of a memory
+ * fault, return 0.
+ */
+
+static char *
+__mem2hex_safe (target_addr_t mem, char *buf, int count)
+{
+ hexMemDst = (char *) buf;
+ hexMemSrc = (char *) TARGET_ADDR_TO_PTR(mem);
+ hexMemCount = count;
+ may_fault_mode = 1;
+#ifdef TARGET_HAS_HARVARD_MEMORY
+ progMem = TARGET_ADDR_IS_PROGMEM(mem);
+#endif
+
+ if (__set_mem_fault_trap (__mem2hex_helper))
+ return 0;
+
+ *hexMemDst = 0;
+
+ return (char *) hexMemDst;
+}
+
+
+
+static void
+__hex2mem_helper (void)
+{
+ union {
+ unsigned long long_val;
+ unsigned char bytes[sizeof(long)];
+ } val;
+ int len, i;
+ unsigned char ch = '\0';
+
+ __mem_fault = 0;
+ while (hexMemCount > 0 && *hexMemSrc) {
+ if (may_fault_mode) {
+ if ((hexMemCount >= sizeof(long)) &&
+ (((target_register_t)hexMemDst & (sizeof(long)-1)) == 0)) {
+ len = sizeof(long);
+ } else if ((hexMemCount >= sizeof(short)) &&
+ (((target_register_t)hexMemDst & (sizeof(short)-1)) == 0)) {
+ len = sizeof(short);
+ } else {
+ len = 1;
+ }
+ } else {
+ len = 1;
+ }
+
+ for (i = 0; i < len; i++) {
+ // Check for short data?
+ ch = stubhex (*(hexMemSrc++)) << 4;
+ if (__mem_fault)
+ return;
+ ch |= stubhex (*(hexMemSrc++));
+ if (__mem_fault)
+ return;
+ val.bytes[i] = ch;
+ }
+
+ if (may_fault_mode) {
+#ifdef TARGET_HAS_HARVARD_MEMORY
+ if (progMem)
+ __write_progmem_safe (&val.bytes[0], hexMemDst, len);
+ else
+#endif
+ __write_mem_safe (&val.bytes[0], hexMemDst, len);
+ } else
+ *hexMemDst = ch;
+
+ if (__mem_fault)
+ return;
+ hexMemCount -= len;
+ hexMemDst += len;
+ }
+}
+
+/* Convert COUNT bytes of the hex array pointed to by BUF into binary
+ to be placed in MEM. Return a pointer to the character AFTER the
+ last byte written.
+
+ If MAY_FAULT is set, we will return a non-zero value if a memory
+ fault occurs (and we assume that MEM is a pointer into the user
+ program). Otherwise, we will take a trap just like any other memory
+ fault (and assume that MEM points into the stub's memory). */
+
+char *
+__hex2mem (buf, mem, count, may_fault)
+ char *buf;
+ char *mem;
+ int count;
+ int may_fault;
+{
+ hexMemSrc = (char *) buf;
+ hexMemDst = (char *) mem;
+ hexMemCount = count;
+ may_fault_mode = may_fault;
+#ifdef TARGET_HAS_HARVARD_MEMORY
+ progMem = 0;
+#endif
+
+ if (may_fault)
+ {
+ if (__set_mem_fault_trap (__hex2mem_helper))
+ return 0;
+ }
+ else
+ __hex2mem_helper ();
+
+ return (char *) hexMemDst;
+}
+
+/* Convert COUNT bytes of the hex array pointed to by BUF into binary
+ to be placed in target MEM. Return a pointer to the character AFTER
+ the last byte written.
+*/
+char *
+__hex2mem_safe (char *buf, target_addr_t mem, int count)
+{
+ hexMemSrc = (char *) buf;
+ hexMemDst = (char *) TARGET_ADDR_TO_PTR(mem);
+ hexMemCount = count;
+ may_fault_mode = 1;
+#ifdef TARGET_HAS_HARVARD_MEMORY
+ progMem = TARGET_ADDR_IS_PROGMEM(mem);
+#endif
+
+ if (__set_mem_fault_trap (__hex2mem_helper))
+ return 0;
+
+ return (char *) hexMemDst;
+}
+
+
+void
+set_debug_traps (void)
+{
+ __install_traps ();
+ initialized = 1; /* FIXME: Change this to dbg_stub_initialized */
+}
+
+/*
+ * While we find nice hex chars, build an int.
+ * Return number of chars processed.
+ */
+
+unsigned int
+__hexToInt (char **ptr, target_register_t *intValue)
+{
+ int numChars = 0;
+ int hexValue;
+
+ *intValue = 0;
+
+ while (**ptr)
+ {
+ hexValue = stubhex (**ptr);
+ if (hexValue < 0)
+ break;
+
+ *intValue = (*intValue << 4) | hexValue;
+ numChars ++;
+
+ (*ptr)++;
+ }
+
+ return (numChars);
+}
+
+/*
+ * While we find nice hex chars, build a target memory address.
+ * Return number of chars processed.
+ */
+
+unsigned int
+__hexToAddr (char **ptr, target_addr_t *val)
+{
+ int numChars = 0;
+ int hexValue;
+
+ *val = 0;
+
+ while (**ptr)
+ {
+ hexValue = stubhex (**ptr);
+ if (hexValue < 0)
+ break;
+
+ *val = (*val << 4) | hexValue;
+ numChars ++;
+
+ (*ptr)++;
+ }
+
+ return (numChars);
+}
+
+
+/*
+ * Complement of __hexToInt: take an int of size "numBits",
+ * convert it to a hex string. Return length of (unterminated) output.
+ */
+
+unsigned int
+__intToHex (char *ptr, target_register_t intValue, int numBits)
+{
+ int numChars = 0;
+
+ if (intValue == 0)
+ {
+ *(ptr++) = '0';
+ *(ptr++) = '0';
+ return 2;
+ }
+
+ numBits = (numBits + 7) / 8;
+ while (numBits)
+ {
+ int v = (intValue >> ((numBits - 1) * 8));
+ if (v || (numBits == 1))
+ {
+ v = v & 255;
+ *(ptr++) = __tohex ((v / 16) & 15);
+ *(ptr++) = __tohex (v & 15);
+ numChars += 2;
+ }
+ numBits--;
+ }
+
+ return (numChars);
+}
+
+#if DEBUG_THREADS
+/*
+ * Kernel Thread Control
+ *
+ * If the current thread is set to other than zero (or minus one),
+ * then ask the kernel to lock it's scheduler so that only that thread
+ * can run.
+ */
+
+static unsigned char did_lock_scheduler = 0;
+static unsigned char did_disable_interrupts = 0;
+
+/* Pointer to "kernel call" for scheduler control */
+static int (*schedlock_fn) (int, int, long) = stub_lock_scheduler;
+
+/* Pointer to target stub call for disabling interrupts.
+ Target stub will initialize this if it can. */
+int (*__disable_interrupts_hook) (int); /* don't initialize here! */
+#endif
+
+static void
+lock_thread_scheduler (int kind) /* "step" or "continue" */
+{
+#if DEBUG_THREADS
+ int ret = 0;
+
+ /* GDB will signal its desire to run a single thread
+ by setting _gdb_cont_thread to non-zero / non-negative. */
+ if (_gdb_cont_thread <= 0)
+ return;
+
+ if (schedlock_fn) /* kernel call */
+ ret = (*schedlock_fn) (1, kind, _gdb_cont_thread);
+
+ if (ret == 1)
+ {
+ did_lock_scheduler = 1;
+ return;
+ }
+
+ if (schedlock_fn == 0 || /* no kernel scheduler call */
+ ret == -1) /* kernel asks stub to handle it */
+ if (__disable_interrupts_hook) /* target stub has capability */
+ if ((*__disable_interrupts_hook) (1))
+ {
+ did_disable_interrupts = 1;
+ return;
+ }
+#endif /* DEBUG_THREADS */
+}
+
+static void
+unlock_thread_scheduler ()
+{
+#if DEBUG_THREADS
+ if (did_lock_scheduler)
+ if (schedlock_fn) /* kernel call */
+ {
+ (*schedlock_fn) (0, 0, _gdb_cont_thread);
+ /* I could check the return value, but
+ what would I do if it failed??? */
+ did_lock_scheduler = 0;
+ }
+ if (did_disable_interrupts)
+ if (__disable_interrupts_hook) /* target stub call */
+ {
+ (*__disable_interrupts_hook) (0);
+ /* Again, I could check the return value, but
+ what would I do if it failed??? */
+ did_disable_interrupts = 0;
+ }
+#endif /* DEBUG_THREADS */
+}
+
+#ifdef CYGPKG_CYGMON
+int processing_breakpoint_function = 0;
+#endif
+
+void
+__handle_exception (void)
+{
+ int sigval = 0;
+
+#ifdef TARGET_HAS_NEXT_STEP
+ if (! __next_step_done ())
+ {
+ __clear_breakpoints ();
+ __install_breakpoints ();
+ __single_step ();
+ return;
+ }
+#endif
+
+#ifdef __ECOS__
+ // We need to unpack the registers before they are accessed.
+ if (__cleanup_vec != NULL)
+ __cleanup_vec ();
+
+#if defined(CYGSEM_REDBOOT_BSP_SYSCALLS)
+ // Temporary support for gnupro bsp SWIs
+ if (__is_bsp_syscall())
+ {
+ sigval = hal_syscall_handler();
+ if (sigval <= 0)
+ {
+ if (sigval < 0)
+ __process_exit_vec ();
+
+ if (__init_vec != NULL)
+ __init_vec ();
+ return;
+ }
+ }
+#endif
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+ // Special case for GDB BREAKs. This flag is set by cyg_stub_cleanup.
+ if (cyg_hal_gdb_break) {
+ cyg_hal_gdb_break = 0;
+ sigval = SIGINT;
+ }
+#endif
+
+ // Only compute sigval if it wasn't already computed (in
+ // hal_syscall_handler or as a result of a GDB async break)
+ if (0 == sigval)
+ sigval = __computeSignal (__get_trap_number ());
+
+#else // __ECOS__
+ /* reply to host that an exception has occurred */
+ sigval = __computeSignal (__get_trap_number ());
+#endif // __ECOS__
+
+ if (__is_breakpoint_function ())
+ {
+#ifdef CYGPKG_CYGMON
+ processing_breakpoint_function = 1;
+#endif
+ __skipinst ();
+ } else {
+#ifdef CYGPKG_CYGMON
+ processing_breakpoint_function = 0;
+#endif
+ }
+
+#ifndef __ECOS__
+ if (__cleanup_vec != NULL)
+ __cleanup_vec ();
+#endif // !__ECOS__
+
+ __clear_breakpoints ();
+
+ /* Undo effect of previous single step. */
+ unlock_thread_scheduler ();
+ __clear_single_step ();
+
+#ifdef __ECOS__
+ /* Need to flush the data and instruction cache here, as we may have
+ removed a breakpoint in __single_step - and we may be sharing
+ some code with the application! */
+
+ __data_cache (CACHE_FLUSH) ;
+ __instruction_cache (CACHE_FLUSH) ;
+#endif
+
+#ifdef SIGSYSCALL
+ if (sigval == SIGSYSCALL)
+ {
+ int val;
+ /* Do the skipinst FIRST. */
+#ifndef SYSCALL_PC_AFTER_INST
+ __skipinst ();
+#endif
+ val = __process_syscall_vec (__get_syscall_num ());
+ if (val < 0)
+ sigval = -val;
+ else
+ sigval = 0;
+ }
+
+#endif
+
+ /* Indirect function call to stub, cygmon monitor or other */
+ if (sigval != 0)
+ {
+ while (__process_exception_vec (sigval))
+ {
+ /* Empty! */
+ }
+ }
+
+ __install_breakpoints ();
+
+ if (__init_vec != NULL)
+ __init_vec ();
+}
+
+/*
+ * _get_trace_register_hook:
+ * This function pointer will be non-zero if the trace component
+ * wants to intercept requests for register values.
+ *
+ * FIXME: evidently I need a new hook for large registers...
+ */
+
+int (*_get_trace_register_hook) (regnames_t, target_register_t *);
+
+void
+stub_format_registers(char *packet, char *ptr)
+{
+ int regnum;
+ int sr = 0, er = NUMREGS_GDB;
+
+ if (packet[0] == 'p')
+ {
+ target_register_t regno;
+ char *p = &packet[1];
+ if (__hexToInt (&p, &regno))
+ {
+ sr = regno;
+ er = regno + 1;
+ }
+ else
+ {
+ strcpy (ptr, "INVALID");
+ return;
+ }
+ }
+
+ for (regnum = sr; regnum < er; regnum++)
+ {
+ /* We need to compensate for the value offset within the
+ register. */
+ char dummyDat[32];
+ target_register_t addr;
+ char *vptr;
+ int reg_valid = 1;
+
+#ifdef TARGET_HAS_LARGE_REGISTERS
+ if (sizeof (target_register_t) < REGSIZE (regnum)) {
+ get_register_as_bytes (regnum, dummyDat);
+ vptr = dummyDat;
+ } else
+#endif
+ {
+ if (_get_trace_register_hook)
+ reg_valid = _get_trace_register_hook (regnum, &addr);
+ else
+ {
+ addr = get_register (regnum);
+#ifdef CYGHWR_REGISTER_VALIDITY_CHECKING
+ reg_valid = get_register_valid (regnum);
+#endif
+ }
+ vptr = ((char *) &addr);
+ if (sizeof (addr) > REGSIZE(regnum)) {
+ /* May need to cope with endian-ness */
+
+#if !defined(__LITTLE_ENDIAN__) && !defined(_LITTLE_ENDIAN)
+ vptr += sizeof (addr) - REGSIZE (regnum);
+#endif
+ } else if (sizeof (addr) < REGSIZE (regnum)) {
+ int off = REGSIZE (regnum) - sizeof (addr);
+ int x;
+ char extend_val = 0;
+
+#ifdef CYGARC_SIGN_EXTEND_REGISTERS
+ {
+ unsigned long bits_in_addr = (sizeof(addr) << 3); // ie Size in bytes * 8
+ target_register_t sign_bit_mask = (1 << (bits_in_addr - 1));
+ if ((addr & sign_bit_mask) == sign_bit_mask)
+ extend_val = ~0;
+ }
+#endif
+
+#if defined(__LITTLE_ENDIAN__) || defined(_LITTLE_ENDIAN)
+ for (x = 0; x < off; x++)
+ dummyDat[x + sizeof(addr)] = extend_val;
+ _memcpy (dummyDat, &addr, sizeof (addr));
+#else
+ for (x = 0; x < off; x++)
+ dummyDat[x] = extend_val;
+ _memcpy (dummyDat + off, &addr, sizeof (addr));
+#endif
+ vptr = dummyDat;
+ }
+ }
+ if (reg_valid) { /* we have a valid reg value */
+ ptr = __mem2hex (vptr, ptr, REGSIZE (regnum), 0);
+ } else {
+ /* Trace component returned a failure code.
+ This means that the register value is not available.
+ We'll fill it with 'x's, and GDB will understand. */
+ _memset (ptr, 'x', 2 * REGSIZE (regnum));
+ ptr += 2 * REGSIZE (regnum);
+ }
+ }
+}
+
+void
+stub_update_registers(char *in_ptr, char *out_ptr)
+{
+ char *ptr = &in_ptr[1];
+ int x;
+ int sr = 0, er = NUMREGS_GDB;
+
+ if (*in_ptr == 'P') {
+ target_register_t regno;
+
+ if (__hexToInt (&ptr, &regno) && (*ptr++ == '=')) {
+
+ sr = regno;
+ er = regno + 1;
+ } else {
+ strcpy (out_ptr, "P01");
+ return;
+ }
+ }
+
+ for (x = sr; x < er; x++) {
+ target_register_t value = 0;
+ char *vptr;
+
+#ifdef TARGET_HAS_LARGE_REGISTERS
+ if (sizeof (target_register_t) < REGSIZE (x)) {
+ char dummyDat [32];
+
+ __hex2mem (ptr, dummyDat, REGSIZE (x), 0);
+ put_register_as_bytes (x, dummyDat);
+ } else
+#endif
+ {
+ vptr = ((char *) &value);
+#if !defined(__LITTLE_ENDIAN__) && !defined(_LITTLE_ENDIAN)
+ vptr += sizeof (value) - REGSIZE (x);
+#endif
+ __hex2mem (ptr, vptr, REGSIZE (x), 0);
+ put_register (x, value);
+ }
+ ptr += REGSIZE (x) * 2;
+ }
+
+ strcpy (out_ptr, "OK");
+}
+
+int
+__process_packet (char *packet)
+{
+ int is_binary = 0;
+#if defined(CYGNUM_HAL_BREAKPOINT_LIST_SIZE)
+ int is_Z = 0;
+#endif
+
+ __remcomOutBuffer[0] = 0;
+ switch (packet[0])
+ {
+ case '?':
+ {
+ int sigval = __computeSignal (__get_trap_number ());
+ __remcomOutBuffer[0] = 'S';
+ __remcomOutBuffer[1] = hexchars[(sigval >> 4) & 0xf];
+ __remcomOutBuffer[2] = hexchars[sigval & 0xf];
+ __remcomOutBuffer[3] = 0;
+ break;
+ }
+
+#ifdef __ECOS__
+#if !defined(CYG_HAL_STARTUP_RAM) // Only for ROM based stubs
+#if 0 // Disable to avoid conflict with stub-breakpoint z/Z-packets
+ case 'z':
+ /* report IO buffer sizes so download can achieve optimal
+ download speed */
+ {
+ int i;
+ i = __intToHex (__remcomOutBuffer, BUFMAX, 32);
+ __remcomOutBuffer[i] = 0;
+ break;
+ }
+#endif
+ case 'd':
+ /* toggle debug flag */
+ strcpy(__remcomOutBuffer, GDB_stubs_version);
+ break;
+#endif
+#endif // __ECOS__
+
+ case 'q':
+ /* general query packet */
+ process_query (&packet[1]);
+ break;
+
+ case 'Q':
+ /* general set packet */
+ process_set (&packet[1]);
+ break;
+
+ case 'p': /* return the value of a single CPU register */
+ case 'g': /* return the value of the CPU registers */
+ {
+ stub_format_registers(&packet[0], __remcomOutBuffer);
+ break;
+ }
+
+ case 'A': /* set program arguments */
+ {
+#ifdef CYGSEM_ECOS_SUPPORTS_PROGRAM_ARGS
+ if (packet[1] == '\0')
+ {
+ __free_program_args ();
+ strcpy (__remcomOutBuffer, "OK");
+ }
+ else
+ {
+ target_register_t arglen, argnum;
+ char *ptr = &packet[1];
+
+ while (1)
+ {
+ if (__hexToInt (&ptr, &arglen)
+ && (*ptr++ == ',')
+ && __hexToInt (&ptr, &argnum)
+ && (*ptr++ == ','))
+ {
+ if (arglen > 0)
+ {
+ char *s = __add_program_arg (argnum, arglen);
+ if (s != NULL)
+ {
+ __hex2mem (ptr, s, arglen, 0);
+ }
+ ptr += arglen * 2;
+ }
+
+ if (*ptr == ',')
+ ptr++;
+ else
+ break;
+ }
+ else
+ break;
+ }
+ if (*ptr == '\0')
+ strcpy (__remcomOutBuffer, "OK");
+ else
+ strcpy (__remcomOutBuffer, "E01");
+ }
+#else
+ strcpy (__remcomOutBuffer, "E01");
+#endif
+ }
+ break;
+
+ case 'P':
+ case 'G': /* set the value of the CPU registers - return OK */
+ {
+ char *in_ptr = &packet[0];
+ char *out_ptr = __remcomOutBuffer;
+ stub_update_registers(in_ptr, out_ptr);
+ break;
+ }
+
+ case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
+ /* Try to read %x,%x. */
+ {
+ target_register_t length;
+ char *ptr = &packet[1];
+ target_addr_t addr;
+
+ if (__hexToAddr (&ptr, &addr)
+ && *ptr++ == ','
+ && __hexToInt (&ptr, &length))
+ {
+ if (__mem2hex_safe (addr, __remcomOutBuffer, length))
+ break;
+
+ strcpy (__remcomOutBuffer, "E03");
+ }
+ else
+ strcpy (__remcomOutBuffer, "E01");
+ break;
+ }
+
+ case 'X':
+ /* XAA..AA,LLLL: Write LLLL escaped binary bytes at address AA.AA */
+ is_binary = 1;
+ /* fall through */
+ case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+ /* Try to read '%x,%x:'. */
+ {
+ target_register_t length;
+ char *ptr = &packet[1], buf[128];
+ int i;
+ target_addr_t addr;
+
+ if (__hexToAddr (&ptr, &addr)
+ && *ptr++ == ','
+ && __hexToInt (&ptr, &length)
+ && *ptr++ == ':')
+ {
+ /* GDB sometimes sends an impossible length */
+ if (length < 0 || length >= BUFMAX)
+ strcpy (__remcomOutBuffer, "E01");
+
+ else if (is_binary)
+ {
+ while (length > 0)
+ {
+ for (i = 0; i < sizeof(buf) && i < length; i++)
+ if ((buf[i] = *ptr++) == 0x7d)
+ buf[i] = 0x20 | (*ptr++ & 0xff);
+
+#ifdef TARGET_HAS_HARVARD_MEMORY
+ if (TARGET_ADDR_IS_PROGMEM(addr)) {
+ if (__write_progmem_safe (buf, (void *)TARGET_ADDR_TO_PTR(addr), i) != i)
+ break;
+ } else
+#endif
+ if (__write_mem_safe (buf, (void *)TARGET_ADDR_TO_PTR(addr), i) != i)
+ break;
+
+
+ length -= i;
+ addr += i;
+ }
+ if (length <= 0)
+ strcpy (__remcomOutBuffer, "OK");
+ else
+ strcpy (__remcomOutBuffer, "E03");
+ }
+ else
+ {
+ if (__hex2mem_safe (ptr, addr, length) != NULL)
+ strcpy (__remcomOutBuffer, "OK");
+ else
+ strcpy (__remcomOutBuffer, "E03");
+ }
+ }
+ else
+ strcpy (__remcomOutBuffer, "E02");
+ break;
+ }
+
+ case 'S':
+ case 's': /* sAA..AA Step from address AA..AA (optional) */
+ case 'C':
+ case 'c': /* cAA..AA Continue at address AA..AA (optional) */
+ /* try to read optional parameter, pc unchanged if no parm */
+
+ {
+ char *ptr = &packet[1];
+ target_addr_t addr;
+ target_register_t sigval = 0;
+
+ if (packet[0] == 'C' || packet[0] == 'S')
+ {
+ __hexToInt (&ptr, &sigval);
+ if (*ptr == ';')
+ ptr++;
+ }
+
+ if (__hexToAddr (&ptr, &addr))
+ set_pc ((target_register_t)TARGET_ADDR_TO_PTR(addr));
+
+ /* Need to flush the instruction cache here, as we may have
+ deposited a breakpoint, and the icache probably has no way of
+ knowing that a data ref to some location may have changed
+ something that is in the instruction cache. */
+
+#ifdef __ECOS__
+ __data_cache (CACHE_FLUSH) ;
+#endif
+ __instruction_cache (CACHE_FLUSH) ;
+
+ /* If we have a function to handle signals, call it. */
+ if (sigval != 0 && __process_signal_vec != NULL)
+ {
+ /* If 0 is returned, we either ignored the signal or invoked a user
+ handler. Otherwise, the user program should die. */
+ if (! __process_signal_vec (sigval))
+ sigval = 0;
+ }
+
+ if (sigval != 0)
+ {
+ sigval = SIGKILL; /* Always nuke the program */
+ __kill_program (sigval);
+ return 0;
+ }
+
+#ifdef __ECOS__
+ // CASE 102327 - watchpoints fight with output, so do not step
+ // through $O packet output routines.
+#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+ if ( cyg_hal_gdb_break_is_set() ) {
+ packet[0] = 'c'; // Force it to be a "continue" instead of step.
+ cyg_hal_gdb_running_step = 1; // And tell the hal_stub...
+ }
+#endif
+#endif
+
+ /* Set machine state to force a single step. */
+ if (packet[0] == 's' || packet[0] == 'S')
+ {
+ lock_thread_scheduler (0); /* 0 == single-step */
+#ifdef __ECOS__
+ // PR 19845 workaround:
+ // Make sure the single-step magic affects the correct registers.
+ _registers = &registers[0];
+#endif
+ __single_step ();
+ }
+ else
+ {
+ lock_thread_scheduler (1); /* 1 == continue */
+ }
+
+#ifdef __ECOS__
+ /* Need to flush the data and instruction cache here, as we may have
+ deposited a breakpoint in __single_step. */
+
+ __data_cache (CACHE_FLUSH) ;
+ __instruction_cache (CACHE_FLUSH) ;
+ hal_flush_output();
+#endif
+
+ return -1;
+ }
+
+ case 'D' : /* detach */
+ __putpacket (__remcomOutBuffer);
+ /* fall through */
+ case 'k' : /* kill the program */
+#ifdef __ECOS__
+ hal_flush_output();
+#endif
+ __process_exit_vec ();
+ return -1;
+
+ case 'r': /* Reset */
+ /* With the next 'k' packet, reset the board */
+ __process_exit_vec = &__reset;
+ break;
+
+ case 'H':
+ STUB_PKT_CHANGETHREAD (packet+1, __remcomOutBuffer, 300) ;
+ break ;
+ case 'T' :
+ STUB_PKT_THREAD_ALIVE (packet+1, __remcomOutBuffer, 300) ;
+ break ;
+ case 'B':
+ /* breakpoint */
+ {
+ target_register_t addr;
+ char mode;
+ char *ptr = &packet[1];
+ if (__hexToInt (&ptr, &addr) && *(ptr++) == ',')
+ {
+ mode = *(ptr++);
+ if (mode == 'C')
+ __remove_breakpoint (addr,0);
+ else
+ __set_breakpoint (addr,0);
+ strcpy (__remcomOutBuffer, "OK");
+ }
+ else
+ {
+ strcpy (__remcomOutBuffer, "E01");
+ }
+ break;
+ }
+
+ case 'b': /* bBB... Set baud rate to BB... */
+ {
+ target_register_t baudrate;
+
+ char *ptr = &packet[1];
+ if (!__hexToInt (&ptr, &baudrate))
+ {
+ strcpy (__remcomOutBuffer, "B01");
+ break;
+ }
+
+ __putpacket ("OK"); /* Ack before changing speed */
+ __set_baud_rate (baudrate);
+ break;
+ }
+
+#if defined(CYGNUM_HAL_BREAKPOINT_LIST_SIZE) && (CYGNUM_HAL_BREAKPOINT_LIST_SIZE > 0)
+ case 'Z':
+ is_Z = 1;
+ case 'z':
+ {
+ char *ptr = &packet[1];
+ target_register_t ztype, addr, length;
+ int err;
+ target_addr_t taddr;
+
+ if (__hexToInt (&ptr, &ztype) && *(ptr++) == ',')
+ {
+ if (__hexToAddr (&ptr, &taddr))
+ {
+ if (*(ptr++) == ',')
+ {
+ /* When there is a comma, there must be a length */
+ if (!__hexToInt (&ptr, &length))
+ {
+ strcpy (__remcomOutBuffer, "E02");
+ break;
+ }
+ }
+ else
+ length = 0;
+
+ addr = (target_register_t)TARGET_ADDR_TO_PTR(taddr);
+
+ switch (ztype)
+ {
+ case ZTYPE_SW_BREAKPOINT:
+ /* sw breakpoint */
+ if (is_Z)
+ err = __set_breakpoint(addr,length);
+ else
+ err = __remove_breakpoint(addr,length);
+ if (!err)
+ strcpy (__remcomOutBuffer, "OK");
+ else
+ strcpy (__remcomOutBuffer, "E02");
+ break;
+ case ZTYPE_HW_BREAKPOINT:
+#if defined(HAL_STUB_HW_BREAKPOINT_LIST_SIZE) && (HAL_STUB_HW_BREAKPOINT_LIST_SIZE > 0)
+ if (is_Z)
+ err = __set_hw_breakpoint(addr, length);
+ else
+ err = __remove_hw_breakpoint(addr, length);
+ if (!err)
+ strcpy (__remcomOutBuffer, "OK");
+ else
+#endif
+ strcpy (__remcomOutBuffer, "E02");
+ break;
+ case ZTYPE_HW_WATCHPOINT_WRITE:
+ case ZTYPE_HW_WATCHPOINT_READ:
+ case ZTYPE_HW_WATCHPOINT_ACCESS:
+#if defined(HAL_STUB_HW_WATCHPOINT_LIST_SIZE) && (HAL_STUB_HW_WATCHPOINT_LIST_SIZE > 0)
+ if (is_Z)
+ err = __set_hw_watchpoint(addr, length, ztype);
+ else
+ err = __remove_hw_watchpoint(addr, length, ztype);
+ if (!err)
+ strcpy (__remcomOutBuffer, "OK");
+ else
+#endif
+ strcpy (__remcomOutBuffer, "E02");
+ break;
+ }
+ }
+ }
+ break;
+ }
+#endif // Z packet support
+#ifdef CYGPKG_HAL_GDB_FILEIO // File I/O over the GDB remote protocol
+ case 'F':
+ {
+ extern void cyg_hal_gdbfileio_process_F_packet( char *, char *);
+ cyg_hal_gdbfileio_process_F_packet( packet, __remcomOutBuffer );
+ return -1;
+ }
+#endif
+ default:
+ __process_target_packet (packet, __remcomOutBuffer, 300);
+ break;
+ }
+
+ /* reply to the request */
+ __putpacket (__remcomOutBuffer);
+ return 0;
+}
+
+static void
+send_t_packet (int sigval)
+{
+ __build_t_packet (sigval, __remcomOutBuffer);
+ __putpacket (__remcomOutBuffer);
+}
+
+/*
+ * This function does all command procesing for interfacing to gdb.
+ */
+
+static int
+process_exception (int sigval)
+{
+ int status;
+
+ /* Nasty. */
+ if (ungot_char < 0)
+ send_t_packet (sigval);
+
+ do {
+ __getpacket (__remcomInBuffer);
+ status = __process_packet (__remcomInBuffer);
+ } while (status == 0);
+
+ if (status < 0)
+ return 0;
+ else
+ return 1;
+}
+
+void
+__send_exit_status (int status)
+{
+ __remcomOutBuffer[0] = 'W';
+ __remcomOutBuffer[1] = hexchars[(status >> 4) & 0xf];
+ __remcomOutBuffer[2] = hexchars[status & 0xf];
+ __remcomOutBuffer[3] = 0;
+ __putpacket (__remcomOutBuffer);
+}
+
+/* Read up to MAXLEN bytes from the remote GDB client, and store in DEST
+ (which is a pointer in the user program). BLOCK indicates what mode
+ is being used; if it is set, we will wait for MAXLEN bytes to be
+ entered. Otherwise, the function will return immediately with whatever
+ bytes are waiting to be read.
+
+ The value returned is the number of bytes read. A -1 indicates that an
+ error of some sort occurred. */
+
+int
+__get_gdb_input (target_register_t dest, int maxlen, int block)
+{
+ char buf[4];
+ int len, i;
+ char d;
+
+ buf[0] = 'I';
+ buf[1] = '0';
+ buf[2] = block ? '0' : '1';
+ buf[3] = 0;
+ __putpacket (buf);
+ __getpacket (__remcomInBuffer);
+ if (__remcomInBuffer[0] != 'I')
+ return -1;
+ len = stubhex (__remcomInBuffer[1]) * 16 + stubhex (__remcomInBuffer[2]);
+ for (i = 0; i < len; i++)
+ {
+ d = stubhex (__remcomInBuffer[3 + i * 2]) * 16;
+ d |= stubhex (__remcomInBuffer[3 + i * 2 + 1]);
+ __write_mem_safe (&d, (void *)(dest + i), 1);
+ }
+ /* Write the trailing \0. */
+ d = '\0';
+ __write_mem_safe (&d, (void *)(dest + i), 1);
+ return len;
+}
+
+void
+__output_hex_value (target_register_t i)
+{
+ char buf[32], *ptr=buf+31;
+ unsigned int x;
+
+ *ptr = 0;
+ for (x = 0; x < (sizeof (i) * 2); x++)
+ {
+ *(--ptr) = hexchars[i & 15];
+ i = i >> 4;
+ }
+ while (*ptr)
+ {
+ putDebugChar (*(ptr++));
+ }
+}
+
+/* Write the C-style string pointed to by STR to the GDB comm port. */
+void
+__putDebugStr (char *str)
+{
+ while (*str)
+ {
+ putDebugChar (*str);
+ str++;
+ }
+}
+
+/* Send STRING_LEN bytes of STR to GDB, using 'O' packets.
+ STR is assumed to be in the program being debugged. */
+
+int
+__output_gdb_string (target_register_t str, int string_len)
+{
+ /* We will arbitrarily limit output packets to less than 400 bytes. */
+ static char buf[400];
+ int x;
+ int len;
+
+ if (string_len == 0)
+ {
+ /* We can't do strlen on a user pointer. */
+ return -1;
+ }
+
+ len = string_len;
+ while (len > 0)
+ {
+ int packetlen = ((len < 175) ? len : 175);
+ buf[0] = 'O';
+ for (x = 0; x < packetlen; x++)
+ {
+ char c;
+
+ __read_mem_safe (&c, (void *)(str + x), 1);
+ buf[x*2+1] = hexchars[(c >> 4) & 0xf];
+ buf[x*2+2] = hexchars[c % 16];
+ }
+ str += x;
+ len -= x;
+ buf[x*2+1] = 0;
+ __putpacket (buf);
+ }
+ return string_len;
+}
+
+static void
+do_nothing (void)
+{
+ /* mmmm */
+}
+
+static int
+syscall_do_nothing (int junk)
+{
+ return 0;
+}
+
+/* Start the stub running. */
+void
+__switch_to_stub (void)
+{
+ __process_exception_vec = process_exception;
+#ifdef CYGPKG_CYGMON
+ // Cygmon will have consumed the '$' character for this packet.
+ // Let's put one in the unget buffer.
+ // Actually, Cygmon does an unget, but since it uses different
+ // unget handling, we need to do this here.
+ ungetDebugChar('$');
+#endif
+}
+
+#if ! defined(BOARD_SPECIFIC_STUB_INIT)
+void
+initialize_stub (void)
+{
+ set_debug_traps ();
+ /* FIXME: This function should be renamed to specifically init the
+ hardware required by debug operations. If initHardware is implemented at
+ all, it should be called before main ().
+ */
+ initHardware () ;
+ /* This acks any stale packets , NOT an effective solution */
+ putDebugChar ('+');
+}
+#endif
+
+void
+ungetDebugChar (int c)
+{
+ ungot_char = c;
+}
+
+void
+__kill_program (int sigval)
+{
+ __remcomOutBuffer[0] = 'X';
+ __remcomOutBuffer[1] = hexchars[(sigval >> 4) & 15];
+ __remcomOutBuffer[2] = hexchars[sigval & 15];
+ __remcomOutBuffer[3] = 0;
+ __putpacket (__remcomOutBuffer);
+}
+
+#ifdef CYGSEM_ECOS_SUPPORTS_PROGRAM_ARGS
+#define MAX_ARG_COUNT 20
+#define MAX_ARGDATA 128
+
+static char *program_argv [MAX_ARG_COUNT];
+static int program_argc;
+static int last_program_arg;
+static char program_argstr [MAX_ARGDATA], *argptr;
+static int args_initted = 0;
+
+void
+__free_program_args (void)
+{
+ last_program_arg = -1;
+ program_argc = 0;
+ program_argv [0] = NULL;
+ argptr = program_argstr;
+ args_initted = 1;
+}
+
+static char *
+__add_program_arg (int argc, uint32 len)
+{
+ char *res;
+
+ if (! args_initted)
+ {
+ __free_program_args ();
+ }
+
+ if ((argc >= (MAX_ARG_COUNT - 1))
+ || ((argptr - program_argstr + len) > MAX_ARGDATA))
+ {
+ return NULL;
+ }
+
+ if (argc != last_program_arg)
+ {
+ if (argc >= program_argc)
+ {
+ program_argc = argc + 1;
+ program_argv [program_argc] = NULL;
+ }
+ program_argv [argc] = argptr;
+ last_program_arg = argc;
+ }
+
+ res = argptr;
+ argptr += len;
+
+ return res;
+}
+
+void
+__set_program_args (int argc, char **argv)
+{
+ int x;
+
+ __free_program_args ();
+ if (argc)
+ {
+ for (x = 0; x < argc; x++)
+ {
+ uint32 len = strlen (argv[x])+1;
+ char *s = __add_program_arg (x, len);
+
+ if (s == NULL)
+ return;
+
+ _memcpy (s, argv[x], len);
+ }
+ }
+}
+
+char **
+__get_program_args (target_register_t argcPtr)
+{
+ if (!args_initted)
+ {
+ __free_program_args ();
+ }
+ __write_mem_safe ((char *) &program_argc, (void *)argcPtr, sizeof (program_argc));
+ return program_argv;
+}
+#endif
+
+/* Table used by the crc32 function to calcuate the checksum. */
+#ifdef CYGDBG_HAL_CRCTABLE_LOCATION_RAM
+static uint32 crc32_table[256];
+static int tableInit = 0;
+#else
+static const uint32 crc32_table[256]={
+ 0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
+ 0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
+ 0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
+ 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
+ 0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
+ 0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
+ 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
+ 0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
+ 0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
+ 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
+ 0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
+ 0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
+ 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
+ 0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
+ 0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
+ 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
+ 0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
+ 0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
+ 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
+ 0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
+ 0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
+ 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
+ 0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
+ 0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
+ 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
+ 0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
+ 0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
+ 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
+ 0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
+ 0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
+ 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
+ 0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4,
+};
+#endif
+
+/*
+ Calculate a CRC-32 using LEN bytes of PTR. CRC is the initial CRC
+ value.
+ PTR is assumed to be a pointer in the user program. */
+
+static uint32
+crc32 (target_addr_t mem, int len, uint32 crc)
+{
+ unsigned char *ptr = (unsigned char *)TARGET_ADDR_TO_PTR(mem);
+#ifdef TARGET_HAS_HARVARD_MEMORY
+ int is_progmem = TARGET_ADDR_IS_PROGMEM(mem);
+#endif
+
+#ifdef CYGDBG_HAL_CRCTABLE_LOCATION_RAM
+ if (! tableInit)
+ {
+ /* Initialize the CRC table and the decoding table. */
+ uint32 i, j;
+ uint32 c;
+
+ tableInit = 1;
+ for (i = 0; i < 256; i++)
+ {
+ for (c = i << 24, j = 8; j > 0; --j)
+ c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
+ crc32_table[i] = c;
+ }
+ }
+#endif
+
+ __mem_fault = 0;
+ while (len--)
+ {
+ unsigned char ch;
+
+#ifdef TARGET_HAS_HARVARD_MEMORY
+ if (is_progmem)
+ __read_progmem_safe (&ch, (void *)ptr, 1);
+ else
+#endif
+ __read_mem_safe (&ch, (void *)ptr, 1);
+ if (__mem_fault)
+ {
+ break;
+ }
+ crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ ch) & 255];
+ ptr++;
+ }
+ return crc;
+}
+
+/* Handle the 'q' request */
+
+static void
+process_query (char *pkt)
+{
+ __remcomOutBuffer[0] = '\0';
+#ifdef __ECOS__
+ if ('C' == pkt[0] &&
+ 'R' == pkt[1] &&
+ 'C' == pkt[2] &&
+ ':' == pkt[3])
+#else // __ECOS__
+ if (strncmp (pkt, "CRC:", 4) == 0)
+#endif // __ECOS__
+ {
+ target_addr_t startmem;
+ target_register_t length;
+ uint32 our_crc;
+
+ pkt += 4;
+ if (__hexToAddr (&pkt, &startmem)
+ && *(pkt++) == ','
+ && __hexToInt (&pkt, &length))
+ {
+ our_crc = crc32 (startmem, length, 0xffffffff);
+ if (__mem_fault)
+ {
+ strcpy (__remcomOutBuffer, "E01");
+ }
+ else
+ {
+ int numb = __intToHex (__remcomOutBuffer + 1, our_crc, 32);
+ __remcomOutBuffer[0] = 'C';
+ __remcomOutBuffer[numb + 1] = 0;
+ }
+ }
+ return;
+ }
+#ifdef CYG_HAL_STUB_PROCESS_QUERY
+ else if (CYG_HAL_STUB_PROCESS_QUERY (pkt, __remcomOutBuffer, sizeof(__remcomOutBuffer)))
+ return;
+#endif
+ else
+ {
+ char ch ;
+ char *subpkt CYGBLD_ATTRIB_UNUSED;
+ ch = *pkt ;
+ subpkt = pkt + 1 ;
+ switch (ch)
+ {
+ case 'L' : /* threadlistquery */
+ STUB_PKT_GETTHREADLIST (subpkt, __remcomOutBuffer, 300);
+ break ;
+ case 'P' : /* Thread or process information request */
+ STUB_PKT_GETTHREADINFO (subpkt, __remcomOutBuffer, 300);
+ break ;
+ case 'C' : /* current thread query */
+ STUB_PKT_CURRTHREAD(subpkt, __remcomOutBuffer, sizeof(__remcomOutBuffer));
+ break;
+ default:
+ __process_target_query (pkt, __remcomOutBuffer, 300);
+ break ;
+ }
+ }
+}
+
+/* Handle the 'Q' request */
+
+static void
+process_set (char *pkt)
+{
+ char ch ;
+
+#ifdef CYG_HAL_STUB_PROCESS_SET
+ if (CYG_HAL_STUB_PROCESS_SET (pkt, __remcomOutBuffer, sizeof(__remcomOutBuffer)))
+ return;
+#endif
+
+ ch = *pkt ;
+ switch (ch)
+ {
+ case 'p' : /* Set current process or thread */
+ /* reserve the packet id even if support is not present */
+ /* Dont strip the 'p' off the header, there are several variations of
+ this packet */
+ STUB_PKT_CHANGETHREAD (pkt, __remcomOutBuffer, 300) ;
+ break ;
+ default:
+ __process_target_set (pkt, __remcomOutBuffer, 300);
+ break ;
+ }
+}
+#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
diff --git a/ecos/packages/hal/common/current/src/hal_if.c b/ecos/packages/hal/common/current/src/hal_if.c
new file mode 100644
index 0000000..d46fbdb
--- /dev/null
+++ b/ecos/packages/hal/common/current/src/hal_if.c
@@ -0,0 +1,1116 @@
+//=============================================================================
+//
+// hal_if.c
+//
+// ROM/RAM interfacing functions
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2011 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors:jskov, woehler, jld
+// Date: 2000-06-07
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+
+#ifdef CYGPKG_KERNEL
+# include <pkgconf/kernel.h>
+#endif
+
+#include <cyg/infra/cyg_ass.h> // assertions
+
+#include <cyg/hal/hal_arch.h> // set/restore GP
+
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_if.h> // our interface
+
+#include <cyg/hal/hal_diag.h> // Diag IO
+#include <cyg/hal/hal_misc.h> // User break
+
+#include <cyg/hal/hal_stub.h> // stub functionality
+
+#include <cyg/hal/hal_intr.h> // hal_vsr_table and others
+
+#ifdef CYGPKG_REDBOOT
+#include <pkgconf/redboot.h>
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+#include <redboot.h>
+#include <flash_config.h>
+#endif
+#ifdef CYGOPT_REDBOOT_FIS
+#include <fis.h>
+#endif
+#endif
+
+//--------------------------------------------------------------------------
+
+externC void patch_dbg_syscalls(void * vector);
+externC void init_thread_syscall(void * vector);
+
+//--------------------------------------------------------------------------
+// Implementations and function wrappers for monitor services
+
+// flash config state queries
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+
+static __call_if_flash_cfg_op_fn_t flash_config_op;
+
+static cyg_bool
+flash_config_op(int op, struct cyg_fconfig *fc)
+{
+ cyg_bool res = false;
+
+ CYGARC_HAL_SAVE_GP();
+
+ switch (op) {
+ case CYGNUM_CALL_IF_FLASH_CFG_GET:
+ res = flash_get_config(fc->key, fc->val, fc->type);
+ break;
+ case CYGNUM_CALL_IF_FLASH_CFG_NEXT:
+ res = flash_next_key(fc->key, fc->keylen, &fc->type, &fc->offset);
+ break;
+ case CYGNUM_CALL_IF_FLASH_CFG_SET:
+ res = flash_set_config(fc->key, fc->val, fc->type);
+ break;
+ default:
+ // nothing else supported yet - though it is expected that "set"
+ // will fit the same set of arguments, potentially.
+ break;
+ }
+
+ CYGARC_HAL_RESTORE_GP();
+ return res;
+}
+#endif
+
+#ifdef CYGOPT_REDBOOT_FIS
+
+static __call_if_flash_fis_op_fn_t flash_fis_op;
+
+static cyg_bool
+flash_fis_op( int op, char *name, void *val)
+{
+ cyg_bool res = false;
+ struct fis_image_desc *fis;
+ int num;
+
+ CYGARC_HAL_SAVE_GP();
+ fis = fis_lookup(name, &num);
+ if(fis != NULL)
+ {
+ switch ( op ) {
+ case CYGNUM_CALL_IF_FLASH_FIS_GET_FLASH_BASE:
+ *(CYG_ADDRESS *)val = fis->flash_base;
+ res = true;
+ break;
+ case CYGNUM_CALL_IF_FLASH_FIS_GET_SIZE:
+ *(unsigned long *)val = fis->size;
+ res = true;
+ break;
+ case CYGNUM_CALL_IF_FLASH_FIS_GET_MEM_BASE:
+ *(CYG_ADDRESS *)val = fis->mem_base;
+ res = true;
+ break;
+ case CYGNUM_CALL_IF_FLASH_FIS_GET_ENTRY_POINT:
+ *(CYG_ADDRESS *)val = fis->entry_point;
+ res = true;
+ break;
+ case CYGNUM_CALL_IF_FLASH_FIS_GET_DATA_LENGTH:
+ *(unsigned long *)val = fis->data_length;
+ res = true;
+ break;
+ case CYGNUM_CALL_IF_FLASH_FIS_GET_DESC_CKSUM:
+ *(unsigned long *)val = fis->desc_cksum;
+ res = true;
+ break;
+ case CYGNUM_CALL_IF_FLASH_FIS_GET_FILE_CKSUM:
+ *(unsigned long *)val = fis->file_cksum;
+ res = true;
+ break;
+ default:
+ break;
+ }
+ }
+ CYGARC_HAL_RESTORE_GP();
+ return res;
+}
+
+#include <cyg/io/flash.h>
+
+extern int __flash_init;
+extern int fisdir_size;
+extern int flash_block_size;
+extern void* fis_addr;
+#ifdef CYGOPT_REDBOOT_REDUNDANT_FIS
+extern void* redundant_fis_addr;
+#endif
+extern void* fis_work_block;
+extern int do_flash_init(void);
+extern int fis_start_update_directory(int autolock);
+extern int fis_update_directory(int autolock, int error);
+
+static __call_if_flash_fis_op2_fn_t flash_fis_op2;
+
+static int
+flash_fis_op2( int op, unsigned int index, struct fis_table_entry *entry)
+{
+ int res=0;
+ CYGARC_HAL_SAVE_GP();
+ switch ( op ) {
+ case CYGNUM_CALL_IF_FLASH_FIS_GET_VERSION:
+ res=CYG_REDBOOT_FIS_VERSION;
+ break;
+ case CYGNUM_CALL_IF_FLASH_FIS_INIT:
+ __flash_init=0; //force reinitialization
+ res=do_flash_init();
+ break;
+ case CYGNUM_CALL_IF_FLASH_FIS_GET_ENTRY_COUNT:
+ res=fisdir_size / sizeof(struct fis_image_desc);
+ break;
+ case CYGNUM_CALL_IF_FLASH_FIS_GET_ENTRY:
+ {
+ struct fis_image_desc* img = (struct fis_image_desc *)fis_work_block;
+ CYG_ASSERT(entry!=0, "fis_table_entry == 0 !");
+ memcpy(entry->name, img[index].u.name, 16);
+ entry->flash_base=img[index].flash_base;
+ entry->mem_base=img[index].mem_base;
+ entry->size=img[index].size;
+ entry->entry_point=img[index].entry_point;
+ entry->data_length=img[index].data_length;
+ entry->desc_cksum=img[index].desc_cksum;
+ entry->file_cksum=img[index].file_cksum;
+ res=0;
+ }
+ break;
+ case CYGNUM_CALL_IF_FLASH_FIS_START_UPDATE:
+ fis_start_update_directory(1);
+ break;
+ case CYGNUM_CALL_IF_FLASH_FIS_FINISH_UPDATE:
+ fis_update_directory(1, index);
+ break;
+ case CYGNUM_CALL_IF_FLASH_FIS_MODIFY_ENTRY:
+ {
+ res=0;
+ if (entry->name[0]!=0xff)
+ {
+ if ((entry->size==0)
+ || ((entry->size % flash_block_size) !=0)
+ || (flash_verify_addr((void*)entry->flash_base)!=0)
+ || (flash_verify_addr((void*)(entry->flash_base+entry->size-1))!=0)
+ || (entry->size < entry->data_length))
+ res=-1;
+ }
+
+ if (res==0)
+ {
+ struct fis_image_desc* img = (struct fis_image_desc *)fis_work_block;
+ memcpy(img[index].u.name, entry->name, 16);
+ img[index].flash_base=entry->flash_base;
+ img[index].mem_base=entry->mem_base;
+ img[index].size=entry->size;
+ img[index].entry_point=entry->entry_point;
+ img[index].data_length=entry->data_length;
+ img[index].desc_cksum=entry->desc_cksum;
+ img[index].file_cksum=entry->file_cksum;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ CYGARC_HAL_RESTORE_GP();
+ return res;
+}
+
+#endif
+
+//----------------------------
+// Delay uS
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_DELAY_US
+
+static __call_if_delay_us_t delay_us;
+
+static void
+delay_us(cyg_int32 usecs)
+{
+ CYGARC_HAL_SAVE_GP();
+#if defined(CYGPKG_KERNEL) && defined(HAL_CLOCK_READ)
+ {
+ cyg_uint32 start, elapsed_hal;
+ cyg_int32 elapsed, elapsed_usec;
+ cyg_int32 slice;
+ cyg_int32 usec_per_period = CYGNUM_HAL_RTC_NUMERATOR/CYGNUM_HAL_RTC_DENOMINATOR/1000;
+ cyg_int32 ticks_per_usec = CYGNUM_KERNEL_COUNTERS_RTC_PERIOD/usec_per_period;
+
+ do {
+ // Spin in slices of 1/2 the RTC period. Allows interrupts
+ // time to run without messing up the algorithm. If we
+ // spun for 1 period (or more) of the RTC, there would also
+ // be problems figuring out when the timer wrapped. We
+ // may lose a tick or two for each cycle but it shouldn't
+ // matter much.
+
+ // The tests against CYGNUM_KERNEL_COUNTERS_RTC_PERIOD
+ // check for a value that would cause a 32 bit signed
+ // multiply to overflow. But this also implies that just
+ // multiplying by ticks_per_usec will yield a good
+ // approximation. Otherwise we need to do the full
+ // multiply+divide to get sufficient accuracy. Note that
+ // this test is actually constant, so the compiler will
+ // eliminate it and only compile the branch that is
+ // selected.
+
+ if( usecs > usec_per_period/2 )
+ slice = CYGNUM_KERNEL_COUNTERS_RTC_PERIOD/2;
+ else if( CYGNUM_KERNEL_COUNTERS_RTC_PERIOD/2 >= 0x7FFFFFFF/usec_per_period )
+ slice = usecs * ticks_per_usec;
+ else
+ {
+ slice = usecs*CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
+ slice /= usec_per_period;
+ }
+
+ HAL_CLOCK_READ(&start);
+ do {
+ HAL_CLOCK_READ(&elapsed_hal);
+ elapsed = (elapsed_hal - start); // counts up!
+ if (elapsed < 0)
+ elapsed += CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
+ } while (elapsed < slice);
+
+ // Adjust by elapsed, not slice, since an interrupt may
+ // have been stalling us for some time.
+
+ if( CYGNUM_KERNEL_COUNTERS_RTC_PERIOD >= 0x7FFFFFFF/usec_per_period )
+ elapsed_usec = elapsed / ticks_per_usec;
+ else
+ {
+ elapsed_usec = elapsed * usec_per_period;
+ elapsed_usec = elapsed_usec / CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
+ }
+
+ // It is possible for elapsed_usec to end up zero in some
+ // circumstances and we could end up looping indefinitely.
+ // Avoid that by ensuring that we always decrement usec by
+ // at least 1 each time.
+
+ usecs -= elapsed_usec ? elapsed_usec : 1;
+
+ } while (usecs > 0);
+ }
+#else // CYGPKG_KERNEL
+#ifdef HAL_DELAY_US
+ // Use a HAL feature if defined
+ HAL_DELAY_US(usecs);
+#else
+ // If no accurate delay mechanism, just spin for a while. Having
+ // an inaccurate delay is much better than no delay at all. The
+ // count of 10 should mean the loop takes something resembling
+ // 1us on most CPUs running between 30-100MHz [depends on how many
+ // instructions this compiles to, how many dispatch units can be
+ // used for the simple loop, actual CPU frequency, etc]
+ while (usecs-- > 0) {
+ int i;
+ for (i = 0; i < 10; i++);
+ }
+#endif // HAL_DELAY_US
+#endif // CYGPKG_KERNEL
+ CYGARC_HAL_RESTORE_GP();
+}
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_DELAY_US
+
+// Reset functions
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_RESET
+
+static __call_if_reset_t reset;
+
+static void
+reset(void)
+{
+ CYGARC_HAL_SAVE_GP();
+ // With luck, the platform defines some magic that will cause a hardware
+ // reset.
+#ifdef HAL_PLATFORM_RESET
+ HAL_PLATFORM_RESET();
+#endif
+
+#ifdef HAL_PLATFORM_RESET_ENTRY
+ // If that's not the case (above is an empty statement) there may
+ // be defined an address we can jump to - and effectively
+ // reinitialize the system. Not quite as good as a reset, but it
+ // is often enough.
+ goto *HAL_PLATFORM_RESET_ENTRY;
+
+#else
+#error " no RESET_ENTRY"
+#endif
+ CYG_FAIL("Reset failed");
+ CYGARC_HAL_RESTORE_GP();
+}
+
+#endif
+
+//------------------------------------
+// NOP service
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_INIT_WHOLE_TABLE) || \
+ defined(CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_COMMS)
+static int
+nop_service(void)
+{
+ // This is the default service. It always returns false (0), and
+ // _does not_ trigger any assertions. Clients must either cope
+ // with the service failure or assert.
+ return 0;
+}
+#endif
+
+//----------------------------------
+// Comm controls
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_COMMS
+
+#ifdef CYGNUM_HAL_VIRTUAL_VECTOR_AUX_CHANNELS
+#define CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS \
+ (CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS+CYGNUM_HAL_VIRTUAL_VECTOR_AUX_CHANNELS)
+#else
+#define CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS \
+ CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS
+#endif
+
+static hal_virtual_comm_table_t comm_channels[CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS+1];
+
+static int
+set_debug_comm(int __comm_id)
+{
+ static int __selected_id = CYGNUM_CALL_IF_SET_COMM_ID_EMPTY;
+ hal_virtual_comm_table_t* __chan;
+ int interrupt_state = 0;
+ int res = 1, update = 0;
+ CYGARC_HAL_SAVE_GP();
+
+ CYG_ASSERT(__comm_id >= CYGNUM_CALL_IF_SET_COMM_ID_MANGLER
+ && __comm_id < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS,
+ "Invalid channel");
+
+ switch (__comm_id) {
+ case CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT:
+ if (__selected_id > 0)
+ res = __selected_id-1;
+ else if (__selected_id == 0)
+ res = CYGNUM_CALL_IF_SET_COMM_ID_MANGLER;
+ else
+ res = __selected_id;
+ break;
+
+ case CYGNUM_CALL_IF_SET_COMM_ID_EMPTY:
+ CYGACC_CALL_IF_DEBUG_PROCS_SET(0);
+ __selected_id = __comm_id;
+ break;
+
+ case CYGNUM_CALL_IF_SET_COMM_ID_MANGLER:
+ __comm_id = 0;
+ update = 1;
+ break;
+
+ default:
+ __comm_id++; // skip mangler entry
+ update = 1;
+ break;
+ }
+
+ if (update) {
+ // Find the interrupt state of the channel.
+ __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+ if (__chan)
+ interrupt_state = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_IRQ_DISABLE);
+
+ __selected_id = __comm_id;
+ CYGACC_CALL_IF_DEBUG_PROCS_SET(comm_channels[__comm_id]);
+
+ // Set interrupt state on the new channel.
+ __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+ if (interrupt_state)
+ CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_IRQ_ENABLE);
+ else
+ CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_IRQ_DISABLE);
+ }
+
+ CYGARC_HAL_RESTORE_GP();
+ return res;
+}
+
+static int
+set_console_comm(int __comm_id)
+{
+ static int __selected_id = CYGNUM_CALL_IF_SET_COMM_ID_EMPTY;
+ int res = 1, update = 0;
+ CYGARC_HAL_SAVE_GP();
+
+ CYG_ASSERT(__comm_id >= CYGNUM_CALL_IF_SET_COMM_ID_MANGLER
+ && __comm_id < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS,
+ "Invalid channel");
+
+ switch (__comm_id) {
+ case CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT:
+ if (__selected_id > 0)
+ res = __selected_id-1;
+ else if (__selected_id == 0)
+ res = CYGNUM_CALL_IF_SET_COMM_ID_MANGLER;
+ else
+ res = __selected_id;
+ break;
+
+ case CYGNUM_CALL_IF_SET_COMM_ID_EMPTY:
+ CYGACC_CALL_IF_CONSOLE_PROCS_SET(0);
+ __selected_id = __comm_id;
+ break;
+
+ case CYGNUM_CALL_IF_SET_COMM_ID_MANGLER:
+ __comm_id = 0;
+ update = 1;
+ break;
+
+ default:
+ __comm_id++; // skip mangler entry
+ update = 1;
+ break;
+ }
+
+ if (update) {
+ __selected_id = __comm_id;
+
+ CYGACC_CALL_IF_CONSOLE_PROCS_SET(comm_channels[__comm_id]);
+ }
+
+ CYGARC_HAL_RESTORE_GP();
+ return res;
+}
+#endif
+
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
+//-----------------------------------------------------------------------------
+// GDB console output mangler (O-packetizer)
+// COMMS init function at end.
+
+// This gets called via the virtual vector console comms entry and
+// handles O-packetization. The debug comms entries are used for the
+// actual device IO.
+static cyg_uint8
+cyg_hal_diag_mangler_gdb_getc(void* __ch_data)
+{
+ cyg_uint8 __ch;
+ hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+ CYGARC_HAL_SAVE_GP();
+
+ __ch = CYGACC_COMM_IF_GETC(*__chan);
+
+ CYGARC_HAL_RESTORE_GP();
+
+ return __ch;
+}
+
+static char __mangler_line[100];
+static int __mangler_pos = 0;
+
+static void
+cyg_hal_diag_mangler_gdb_flush(void* __ch_data)
+{
+ CYG_INTERRUPT_STATE old;
+ hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+#if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0
+ int tries = CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES;
+#endif
+
+
+ // Nothing to do if mangler buffer is empty.
+ if (__mangler_pos == 0)
+ return;
+
+ // Disable interrupts. This prevents GDB trying to interrupt us
+ // while we are in the middle of sending a packet. The serial
+ // receive interrupt will be seen when we re-enable interrupts
+ // later.
+#if defined(CYG_HAL_STARTUP_ROM) \
+ || !defined(CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION)
+ HAL_DISABLE_INTERRUPTS(old);
+#else
+ CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION(old);
+#endif
+
+#if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0
+ // Only wait 500ms for data to arrive - avoid "stuck" connections
+ CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_SET_TIMEOUT, CYGNUM_HAL_DEBUG_GDB_PROTOCOL_TIMEOUT);
+#endif
+
+ while(1)
+ {
+ static const char hex[] = "0123456789ABCDEF";
+ cyg_uint8 csum = 0;
+ char c1;
+ int i;
+
+ CYGACC_COMM_IF_PUTC(*__chan, '$');
+ CYGACC_COMM_IF_PUTC(*__chan, 'O');
+ csum += 'O';
+ for( i = 0; i < __mangler_pos; i++ )
+ {
+ char ch = __mangler_line[i];
+ char h = hex[(ch>>4)&0xF];
+ char l = hex[ch&0xF];
+ CYGACC_COMM_IF_PUTC(*__chan, h);
+ CYGACC_COMM_IF_PUTC(*__chan, l);
+ csum += h;
+ csum += l;
+ }
+ CYGACC_COMM_IF_PUTC(*__chan, '#');
+ CYGACC_COMM_IF_PUTC(*__chan, hex[(csum>>4)&0xF]);
+ CYGACC_COMM_IF_PUTC(*__chan, hex[csum&0xF]);
+
+ nak:
+#if CYGNUM_HAL_DEBUG_GDB_PROTOCOL_RETRIES != 0
+ if (CYGACC_COMM_IF_GETC_TIMEOUT(*__chan, &c1) == 0) {
+ c1 = '-';
+ if (tries && (--tries == 0)) c1 = '+';
+ }
+#else
+ c1 = CYGACC_COMM_IF_GETC(*__chan);
+#endif
+
+ if( c1 == '+' ) break;
+
+ if( cyg_hal_is_break( &c1 , 1 ) ) {
+ // Caller's responsibility to react on this.
+ CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(1);
+ break;
+ }
+ if( c1 != '-' ) goto nak;
+ }
+
+ __mangler_pos = 0;
+ // And re-enable interrupts
+#if defined(CYG_HAL_STARTUP_ROM) \
+ || !defined(CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION)
+ HAL_RESTORE_INTERRUPTS(old);
+#else
+ CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION(old);
+#endif
+}
+
+static void
+cyg_hal_diag_mangler_gdb_putc(void* __ch_data, cyg_uint8 c)
+{
+ // No need to send CRs
+ if( c == '\r' ) return;
+
+ CYGARC_HAL_SAVE_GP();
+
+ __mangler_line[__mangler_pos++] = c;
+
+ if( c == '\n' || __mangler_pos == sizeof(__mangler_line) )
+ cyg_hal_diag_mangler_gdb_flush(__ch_data);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_diag_mangler_gdb_write(void* __ch_data,
+ const cyg_uint8* __buf, cyg_uint32 __len)
+{
+ CYGARC_HAL_SAVE_GP();
+
+ while(__len-- > 0)
+ cyg_hal_diag_mangler_gdb_putc(__ch_data, *__buf++);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_diag_mangler_gdb_read(void* __ch_data,
+ cyg_uint8* __buf, cyg_uint32 __len)
+{
+ CYGARC_HAL_SAVE_GP();
+
+ while(__len-- > 0)
+ *__buf++ = cyg_hal_diag_mangler_gdb_getc(__ch_data);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+static int
+cyg_hal_diag_mangler_gdb_control(void *__ch_data,
+ __comm_control_cmd_t __func, ...)
+{
+ CYGARC_HAL_SAVE_GP();
+
+ if (__func == __COMMCTL_FLUSH_OUTPUT)
+ cyg_hal_diag_mangler_gdb_flush(__ch_data);
+
+ CYGARC_HAL_RESTORE_GP();
+ return 0;
+}
+
+// This is the COMMS init function. It gets called both by the stubs
+// and diag init code to initialize the COMMS mangler channel table -
+// that's all. The callers have to decide whether to actually use this
+// channel.
+void
+cyg_hal_diag_mangler_gdb_init(void)
+{
+ hal_virtual_comm_table_t* comm;
+ int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+ // Initialize mangler procs
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_MANGLER);
+ comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+ CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_diag_mangler_gdb_write);
+ CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_diag_mangler_gdb_read);
+ CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_diag_mangler_gdb_putc);
+ CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_diag_mangler_gdb_getc);
+ CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_diag_mangler_gdb_control);
+
+ // Restore the original console channel.
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+//-----------------------------------------------------------------------------
+// Null console output mangler
+// COMMS init function at end.
+
+// This gets called via the virtual vector console comms entry and
+// just forwards IO to the debug comms entries.
+// This differs from setting the console channel to the same as the
+// debug channel in that console output will go to the debug channel
+// even if the debug channel is changed.
+static cyg_uint8
+cyg_hal_diag_mangler_null_getc(void* __ch_data)
+{
+ cyg_uint8 __ch;
+ hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+ CYGARC_HAL_SAVE_GP();
+
+ __ch = CYGACC_COMM_IF_GETC(*__chan);
+
+ CYGARC_HAL_RESTORE_GP();
+
+ return __ch;
+}
+
+
+static void
+cyg_hal_diag_mangler_null_putc(void* __ch_data, cyg_uint8 c)
+{
+ hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+
+ CYGARC_HAL_SAVE_GP();
+
+ CYGACC_COMM_IF_PUTC(*__chan, c);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_diag_mangler_null_write(void* __ch_data,
+ const cyg_uint8* __buf, cyg_uint32 __len)
+{
+ CYGARC_HAL_SAVE_GP();
+
+ while(__len-- > 0)
+ cyg_hal_diag_mangler_null_putc(__ch_data, *__buf++);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_diag_mangler_null_read(void* __ch_data,
+ cyg_uint8* __buf, cyg_uint32 __len)
+{
+ CYGARC_HAL_SAVE_GP();
+
+ while(__len-- > 0)
+ *__buf++ = cyg_hal_diag_mangler_null_getc(__ch_data);
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+static int
+cyg_hal_diag_mangler_null_control(void *__ch_data,
+ __comm_control_cmd_t __func, ...)
+{
+ // Do nothing (yet).
+ return 0;
+}
+
+// This is the COMMS init function. It gets called both by the stubs
+// and diag init code to initialize the COMMS mangler channel table -
+// that's all. The callers have to decide whether to actually use this
+// channel.
+void
+cyg_hal_diag_mangler_null_init(void)
+{
+ hal_virtual_comm_table_t* comm;
+ int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+ // Initialize mangler procs
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_MANGLER);
+ comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+ CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_diag_mangler_null_write);
+ CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_diag_mangler_null_read);
+ CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_diag_mangler_null_putc);
+ CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_diag_mangler_null_getc);
+ CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_diag_mangler_null_control);
+
+ // Restore the original console channel.
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+//-----------------------------------------------------------------------------
+// Console IO functions that adhere to the virtual vector table semantics in
+// order to ensure proper debug agent mangling when required.
+//
+externC void cyg_hal_plf_comms_init(void);
+
+void
+hal_if_diag_init(void)
+{
+ // This function may be called from various places and the code
+ // should only run once.
+ static cyg_uint8 called = 0;
+ if (called) return;
+ called = 1;
+
+#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_INHERIT_CONSOLE
+
+#if defined(CYGDBG_HAL_DIAG_TO_DEBUG_CHAN)
+ // Use the mangler channel, which in turn uses the debug channel.
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_MANGLER);
+
+ // Initialize the mangler channel.
+#if defined(CYGSEM_HAL_DIAG_MANGLER_GDB)
+ cyg_hal_diag_mangler_gdb_init();
+#elif defined(CYGSEM_HAL_DIAG_MANGLER_None)
+ cyg_hal_diag_mangler_null_init();
+#endif
+
+#else // CYGDBG_HAL_DIAG_TO_DEBUG_CHAN
+
+ // Use an actual (raw) IO channel
+ CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL);
+
+#endif // CYGDBG_HAL_DIAG_TO_DEBUG_CHAN
+
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_INHERIT_CONSOLE
+}
+
+void
+hal_if_diag_write_char(char c)
+{
+ hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
+
+ if (__chan)
+ CYGACC_COMM_IF_PUTC(*__chan, c);
+ else {
+ __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+
+ // FIXME: What should be done if assertions are not enabled?
+ // This is a bad bad situation - we have no means for diag
+ // output; we want to hit a breakpoint to alert the developer
+ // or something like that.
+ CYG_ASSERT(__chan, "No valid channel set");
+
+ CYGACC_COMM_IF_PUTC(*__chan, c);
+ }
+
+ // Check interrupt flag
+ if (CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG()) {
+ CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0);
+ cyg_hal_user_break(0);
+ }
+}
+
+void
+hal_if_diag_read_char(char *c)
+{
+ hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
+
+ if (__chan)
+ *c = CYGACC_COMM_IF_GETC(*__chan);
+ else {
+ __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+
+ // FIXME: What should be done if assertions are not enabled?
+ // This is a bad bad situation - we have no means for diag
+ // output; we want to hit a breakpoint to alert the developer
+ // or something like that.
+ CYG_ASSERT(__chan, "No valid channel set");
+
+ *c = CYGACC_COMM_IF_GETC(*__chan);
+ }
+}
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
+
+//=============================================================================
+// CtrlC support
+//=============================================================================
+
+#if CYGINT_HAL_COMMON_SAVED_INTERRUPT_STATE_REQUIRED > 0
+struct Hal_SavedRegisters *hal_saved_interrupt_state;
+#endif
+
+#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \
+ || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
+
+void
+hal_ctrlc_isr_init(void)
+{
+ // A ROM monitor never enables the interrupt itself. This is left
+ // to the (RAM) application.
+#ifndef CYGSEM_HAL_ROM_MONITOR
+ hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+
+#if 1 // Prevents crash on older stubs
+ int v_m;
+ // Allow only ctrl-c interrupt enabling when version in table is
+ // below legal max and above the necessary service, and _not_
+ // the value we set it to below.
+ v_m = CYGACC_CALL_IF_VERSION() & CYGNUM_CALL_IF_TABLE_VERSION_CALL_MASK;
+ if (v_m >= CYGNUM_CALL_IF_TABLE_VERSION_CALL_MAX
+ || v_m < CYGNUM_CALL_IF_SET_DEBUG_COMM
+ || v_m == CYGNUM_CALL_IF_TABLE_VERSION_CALL_HACK)
+ return;
+
+ // Now trash that value - otherwise downloading an image with
+ // builtin stubs on a board with older stubs (which will cause the
+ // version to be set to VERSION_CALL) may cause all subsequent
+ // runs to (wrongly) fall through to the below code. If there is
+ // a new stub on the board, it will reinitialize the version field
+ // on reset. Yes, this is a gross hack!
+ CYGACC_CALL_IF_VERSION_SET(CYGNUM_CALL_IF_TABLE_VERSION_CALL_HACK);
+#endif
+
+ // We can only enable interrupts on a valid debug channel.
+ if (__chan)
+ CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_IRQ_ENABLE);
+#endif
+}
+
+cyg_uint32
+hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
+{
+ hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+ int isr_ret = 0, ctrlc = 0;
+
+ if (__chan) {
+ isr_ret = CYGACC_COMM_IF_DBG_ISR(*__chan, &ctrlc, vector, data);
+ if (ctrlc)
+ cyg_hal_user_break( (CYG_ADDRWORD *)hal_saved_interrupt_state );
+ }
+ return isr_ret;
+}
+
+cyg_bool
+hal_ctrlc_check(CYG_ADDRWORD vector, CYG_ADDRWORD data)
+{
+ hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+ int gdb_vector = vector-1;
+ int ctrlc = 0;
+
+ // This check only to avoid crash on older stubs in case of unhandled
+ // interrupts. It is a bit messy, but required in a transition period.
+ if (__chan &&
+ (CYGNUM_CALL_IF_TABLE_VERSION_CALL_HACK ==
+ (CYGACC_CALL_IF_VERSION() & CYGNUM_CALL_IF_TABLE_VERSION_CALL_MASK))){
+ gdb_vector = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DBG_ISR_VECTOR);
+ }
+ if (vector == gdb_vector) {
+ CYGACC_COMM_IF_DBG_ISR(*__chan, &ctrlc, vector, data);
+ if (ctrlc) {
+ cyg_hal_user_break( (CYG_ADDRWORD *)hal_saved_interrupt_state );
+ return true;
+ }
+ }
+ return false;
+}
+#endif // CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT || CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT
+
+//--------------------------------------------------------------------------
+// Init function. It should be called from the platform initialization code.
+// For monitor configurations it will initialize the calling interface table,
+// for client configurations it will patch the existing table as per
+// configuration.
+void
+hal_if_init(void)
+{
+ //**********************************************************************
+ //
+ // Note that if your RAM application is configured to initialize
+ // the whole table _or_ the communication channels, you _cannot_
+ // step through this function with the debugger. If your channel
+ // configurations are set to the default, you should be able to
+ // simply step over this function though (or use 'finish' once you
+ // have entered this function if that GDB command works).
+ //
+ // If you really do need to debug this code, the best approach is
+ // to have a working RedBoot / GDB stub in ROM and then change the
+ // hal_virtual_vector_table to reside at some other address in the
+ // RAM configuration than that used by the ROM monitor. Then
+ // you'll be able to use the ROM monitor to debug the below code
+ // and check that it does the right thing.
+ //
+ // Note that if you have a ROM monitor in ROM/flash which does
+ // support virtual vectors, you should be able to disable the
+ // option CYGSEM_HAL_VIRTUAL_VECTOR_INIT_WHOLE_TABLE. On some
+ // targets (which predate the introduction of virtual vectors)
+ // that option is enabled per default and needs to be explicitly
+ // disabled when you have an updated ROM monitor.
+ //
+ //**********************************************************************
+
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_INIT_WHOLE_TABLE
+ {
+ int i;
+
+ // Initialize tables with the NOP service.
+ // This should only be done for service routine entries - data
+ // pointers should be NULLed.
+ for (i = 0; i < CYGNUM_CALL_IF_TABLE_SIZE; i++)
+ hal_virtual_vector_table[i] = (CYG_ADDRWORD) &nop_service;
+
+ // Version number
+ CYGACC_CALL_IF_VERSION_SET(CYGNUM_CALL_IF_TABLE_VERSION_CALL
+ |((CYG_ADDRWORD)CYGNUM_CALL_IF_TABLE_VERSION_COMM<<CYGNUM_CALL_IF_TABLE_VERSION_COMM_shift));
+ }
+#endif
+
+ // Miscellaneous services with wrappers in this file.
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_RESET
+ CYGACC_CALL_IF_RESET_SET(reset);
+#endif
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_DELAY_US
+ CYGACC_CALL_IF_DELAY_US_SET(delay_us);
+#endif
+
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+ CYGACC_CALL_IF_FLASH_CFG_OP_SET(flash_config_op);
+#endif
+
+#ifdef CYGOPT_REDBOOT_FIS
+ CYGACC_CALL_IF_FLASH_FIS_OP_SET(flash_fis_op);
+ CYGACC_CALL_IF_FLASH_FIS_OP2_SET(flash_fis_op2);
+#endif
+
+ // Data entries not currently supported in eCos
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_DATA
+ CYGACC_CALL_IF_DBG_DATA_SET(0);
+#endif
+
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_VERSION
+ CYGACC_CALL_IF_MONITOR_VERSION_SET(0);
+#endif
+
+ // Comm controls
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_CLAIM_COMMS
+ {
+ int i, j;
+
+ // Clear out tables with safe dummy function.
+ for (j = 0; j < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS+1; j++)
+ for (i = 0; i < CYGNUM_COMM_IF_TABLE_SIZE; i++)
+ comm_channels[j][i] = (CYG_ADDRWORD) &nop_service;
+
+ // Set accessor functions
+ CYGACC_CALL_IF_SET_DEBUG_COMM_SET(set_debug_comm);
+ CYGACC_CALL_IF_SET_CONSOLE_COMM_SET(set_console_comm);
+
+ // Initialize console/debug procs. Note that these _must_
+ // be set to empty before the comms init call.
+ set_debug_comm(CYGNUM_CALL_IF_SET_COMM_ID_EMPTY);
+ set_console_comm(CYGNUM_CALL_IF_SET_COMM_ID_EMPTY);
+
+ // Initialize channels. This used to be done in
+ // hal_diag_init() and the stub initHardware() functions, but
+ // it makes more sense to have here.
+ cyg_hal_plf_comms_init();
+
+ // Always set the debug channel. If stubs are included, it is
+ // necessary. If no stubs are included it does not hurt and is
+ // likely to be required by the hal_if_diag_init code anyway
+ // as it may rely on it if using a mangler.
+ set_debug_comm(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL);
+ // Set console channel to a safe default. hal_if_diag_init
+ // will override with console channel or mangler if necessary.
+ set_console_comm(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL);
+ }
+
+ // Reset console interrupt flag.
+ CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0);
+#endif
+
+ // Set up services provided by clients
+#if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \
+ ( defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs) \
+ || defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon))
+
+ patch_dbg_syscalls( (void *)(hal_virtual_vector_table) );
+#endif
+
+ // Init client services
+#if !defined(CYGPKG_KERNEL) && defined(CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT)
+ // Only include this code if we do not have a kernel. Otherwise
+ // the kernel supplies the functionality for the app we are linked
+ // with.
+
+ // Prepare for application installation of thread info function in
+ // vector table.
+ init_thread_syscall( (void *)&hal_virtual_vector_table[CYGNUM_CALL_IF_DBG_SYSCALL] );
+#endif
+
+ // Finally, install async breakpoint handler if it is configured in.
+ // FIXME: this should probably check for STUBS instead (but code is
+ // conditional on BREAK for now)
+#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)
+ // Install async breakpoint handler into vector table.
+ CYGACC_CALL_IF_INSTALL_BPT_FN_SET(&cyg_hal_gdb_interrupt);
+#endif
+
+#if 0 != CYGINT_HAL_PLF_IF_INIT
+ // Call platform specific initializations - should only be used
+ // to augment what has already been set up, etc.
+ plf_if_init();
+#endif
+}
+
diff --git a/ecos/packages/hal/common/current/src/hal_misc.c b/ecos/packages/hal/common/current/src/hal_misc.c
new file mode 100644
index 0000000..cbc7229
--- /dev/null
+++ b/ecos/packages/hal/common/current/src/hal_misc.c
@@ -0,0 +1,200 @@
+//==========================================================================
+//
+// hal_misc.c
+//
+// Common HAL miscellaneous functions
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg, jskov
+// Date: 2000-06-08
+// Purpose: HAL miscellaneous functions
+// Description: This file contains miscellaneous functions provided by the
+// HAL.
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_if.h>
+
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_misc.h> // our header
+
+#include <cyg/infra/cyg_type.h> // Base types
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
+
+//--------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------
+// Macro for finding return address.
+#ifndef CYGARC_HAL_GET_RETURN_ADDRESS
+
+#define CYGARC_HAL_GET_RETURN_ADDRESS(_x_, _dummy_) \
+ CYG_MACRO_START \
+ (_dummy_) = 1; \
+ (_x_) = (CYG_ADDRWORD)&&__backup_return_address; \
+ CYG_MACRO_END
+
+#define CYGARC_HAL_GET_RETURN_ADDRESS_BACKUP(_dummy_) \
+ CYG_MACRO_START \
+__backup_return_address: \
+ if ((_dummy_)-- > 0) \
+ goto __backup_return_address; \
+ CYG_MACRO_END
+#endif
+
+//--------------------------------------------------------------------------
+// Macro for finding PC in saved regs
+#ifndef CYGARC_HAL_GET_PC_REG
+#define CYGARC_HAL_GET_PC_REG(_regs_,_val_) ((_val_) = (_regs_)->pc)
+#endif
+
+//--------------------------------------------------------------------------
+// Macro for matching interrupt vector to GDB comm channel.
+#ifndef CYGHWR_HAL_GDB_PORT_VECTORS_MATCH
+#define CYGHWR_HAL_GDB_PORT_VECTORS_MATCH(_v_,_gv_) ((_v_)==(_gv_))
+#endif
+
+#if defined(CYGPKG_CYGMON)
+unsigned long cygmon_memsize = 0;
+#endif
+
+//--------------------------------------------------------------------------
+// Functions to support the detection and execution of a user provoked
+// program break. These are usually called from interrupt routines.
+
+cyg_bool
+cyg_hal_is_break(char *buf, int size)
+{
+ while( size )
+ if( buf[--size] == 0x03 ) return true;
+
+ return false;
+}
+
+// Keep this variable global, to prevent the compiler removing it (and
+// the goto-reference) due to being local to the function where it is
+// used. Yes, it's ugly.
+int _cyg_hal_compiler_dummy;
+
+void
+cyg_hal_user_break( CYG_ADDRWORD *regs )
+{
+#if defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs) \
+ || defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon) \
+ || defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
+
+ CYG_ADDRWORD __ra;
+ CYG_WORD32 __pc;
+ HAL_SavedRegisters *sreg = (HAL_SavedRegisters *)regs;
+
+ CYGARC_HAL_GET_RETURN_ADDRESS(__ra, _cyg_hal_compiler_dummy);
+
+ if( regs == NULL ) __pc = __ra;
+ else CYGARC_HAL_GET_PC_REG(sreg, __pc);
+
+ CYGACC_CALL_IF_INSTALL_BPT_FN((void *)__pc);
+
+ CYGARC_HAL_GET_RETURN_ADDRESS_BACKUP(_cyg_hal_compiler_dummy);
+
+#else
+
+ HAL_BREAKPOINT(breakinst);
+
+#endif
+}
+
+
+//--------------------------------------------------------------------------
+// The system default interrupt ISR. It calls the architecture default
+// ISR as well if necessary.
+externC cyg_uint32 hal_arch_default_isr(CYG_ADDRWORD vector,
+ CYG_ADDRWORD data);
+
+cyg_uint32
+hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
+{
+ cyg_uint32 result;
+
+#if (defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \
+ || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)) && \
+ (defined(CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT) || \
+ defined(CYGHWR_HAL_GDB_PORT_VECTOR) && \
+ defined(HAL_CTRLC_ISR))
+
+#ifndef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
+#if CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ int gdb_vector = -1;
+ // This check only to avoid crash on older stubs in case of unhandled
+ // interrupts. It is a bit messy, but required in a transition period.
+#ifndef CYGSEM_HAL_ROM_MONITOR
+ if (CYGNUM_CALL_IF_TABLE_VERSION_CALL_HACK ==
+ (CYGACC_CALL_IF_VERSION() & CYGNUM_CALL_IF_TABLE_VERSION_CALL_MASK))
+#endif
+ {
+ hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+ if (__chan)
+ gdb_vector = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DBG_ISR_VECTOR);
+ }
+ if( CYGHWR_HAL_GDB_PORT_VECTORS_MATCH(vector, gdb_vector) )
+#else
+ // Old code using hardwired channels. This should go away eventually.
+ if( vector == CYGHWR_HAL_GDB_PORT_VECTOR )
+#endif
+#endif
+ {
+ result = HAL_CTRLC_ISR( vector, data );
+ if( 0 != result ) return result;
+ }
+#endif
+
+ result = hal_arch_default_isr (vector, data);
+ if( 0 != result) return result;
+
+ CYG_TRACE2(true, "Interrupt: %d, Data: 0x%08x", vector, data);
+ CYG_FAIL("Spurious Interrupt!!!");
+ return 0;
+}
+
+
+//--------------------------------------------------------------------------
+// End of hal_misc.c
diff --git a/ecos/packages/hal/common/current/src/hal_stub.c b/ecos/packages/hal/common/current/src/hal_stub.c
new file mode 100644
index 0000000..d60c79d
--- /dev/null
+++ b/ecos/packages/hal/common/current/src/hal_stub.c
@@ -0,0 +1,1037 @@
+//=============================================================================
+//
+// hal_stub.c
+//
+// Helper functions for stub, specific to eCos HAL
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov (based on powerpc/cogent hal_stub.c)
+// Contributors:jskov, dmoseley
+// Date: 1999-02-12
+// Purpose: Helper functions for stub, specific to eCos HAL
+// Description: Parts of the GDB stub requirements are provided by
+// the eCos HAL, rather than target and/or board specific
+// code.
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#ifdef CYGPKG_CYGMON
+#include <pkgconf/cygmon.h>
+#endif
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+#include <cyg/hal/hal_stub.h> // Our header
+
+#include <cyg/hal/hal_arch.h> // HAL_BREAKINST
+#include <cyg/hal/hal_cache.h> // HAL_xCACHE_x
+#include <cyg/hal/hal_intr.h> // interrupt disable/restore
+
+#include <cyg/hal/hal_if.h> // ROM calling interface
+#include <cyg/hal/hal_misc.h> // Helper functions
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
+#include <cyg/hal/dbg-threads-api.h> // dbg_currthread_id
+#endif
+
+#ifdef USE_LONG_NAMES_FOR_ENUM_REGNAMES
+#ifndef PC
+#define PC REG_PC
+#endif
+#ifndef SP
+#define SP REG_SP
+#endif
+#endif
+
+//-----------------------------------------------------------------------------
+// Extra eCos data.
+
+// Saved registers.
+HAL_SavedRegisters *_hal_registers;
+target_register_t registers[HAL_STUB_REGISTERS_SIZE];
+target_register_t alt_registers[HAL_STUB_REGISTERS_SIZE] ; // Thread or saved process state
+target_register_t * _registers = registers; // Pointer to current set of registers
+#ifndef CYGPKG_REDBOOT
+target_register_t orig_registers[HAL_STUB_REGISTERS_SIZE]; // Registers to get back to original state
+#endif
+
+#if defined(HAL_STUB_HW_WATCHPOINT) || defined(HAL_STUB_HW_BREAKPOINT)
+static int _hw_stop_reason; // Reason we were stopped by hw.
+
+//#define HAL_STUB_HW_SEND_STOP_REASON_TEXT
+#ifdef CYGINT_HAL_ARM_ARCH_XSCALE
+#define HAL_STUB_HW_SEND_STOP_REASON_TEXT
+#endif
+
+#ifdef HAL_STUB_HW_SEND_STOP_REASON_TEXT
+// strings indexed by hw stop reasons defined in hal_stub.h
+
+// Not all GDBs understand this.
+static const char * const _hw_stop_str[] = {
+ "",
+ "hbreak",
+ "watch",
+ "rwatch",
+ "awatch"
+};
+#endif // HAL_STUB_HW_SEND_STOP_REASON_TEXT
+
+static void *_watch_data_addr; // The data address if stopped by watchpoint
+#endif // defined(HAL_STUB_HW_WATCHPOINT) || defined(HAL_STUB_HW_BREAKPOINT)
+
+// Register validity checking
+#ifdef CYGHWR_REGISTER_VALIDITY_CHECKING
+int registers_valid[NUMREGS];
+int *_registers_valid = registers_valid;
+#endif
+
+#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this should go away
+// Interrupt control.
+static volatile __PFI __interruptible_control;
+#endif
+
+// Some architectures need extras regs reported in T packet
+#ifndef HAL_STUB_ARCH_T_PACKET_EXTRAS
+#define HAL_STUB_ARCH_T_PACKET_EXTRAS(x)
+#endif
+
+//-----------------------------------------------------------------------------
+// Register access
+
+#ifndef CYGARC_STUB_REGISTER_ACCESS_DEFINED
+// Return the currently-saved value corresponding to register REG of
+// the exception context.
+target_register_t
+get_register (regnames_t reg)
+{
+ return _registers[reg];
+}
+#endif
+
+#ifdef CYGHWR_REGISTER_VALIDITY_CHECKING
+// Return the validity of register REG.
+int
+get_register_valid (regnames_t reg)
+{
+ return _registers_valid[reg];
+}
+#endif
+
+#ifndef CYGARC_STUB_REGISTER_ACCESS_DEFINED
+// Store VALUE in the register corresponding to WHICH in the exception
+// context.
+void
+put_register (regnames_t which, target_register_t value)
+{
+#ifdef CYGPKG_HAL_MIPS_VR4300
+ // This is a rather nasty kludge to compensate for the fact that
+ // the VR4300 GDB is rather old and does not support proper 64 bit
+ // registers. The only time this really matters is when setting
+ // the PC after loading an executable. So here we detect this case
+ // and artificially sign extend it.
+
+ if( which == PC && (value & 0x0000000080000000ULL ) )
+ {
+ value |= 0xFFFFFFFF00000000ULL;
+ }
+#endif
+ _registers[which] = value;
+}
+#endif // CYGARC_STUB_REGISTER_ACCESS_DEFINED
+
+//-----------------------------------------------------------------------------
+// Serial stuff
+#ifdef CYGPKG_CYGMON
+extern void ecos_bsp_console_putc(char);
+extern char ecos_bsp_console_getc(void);
+#endif
+
+// Write C to the current serial port.
+void
+putDebugChar (int c)
+{
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ __call_if_debug_procs_t __debug_procs = CYGACC_CALL_IF_DEBUG_PROCS();
+ CYGACC_COMM_IF_PUTC(*__debug_procs, c);
+#elif defined(CYGPKG_CYGMON)
+ ecos_bsp_console_putc(c);
+#else
+ HAL_STUB_PLATFORM_PUT_CHAR(c);
+#endif
+}
+
+// Read one character from the current serial port.
+int
+getDebugChar (void)
+{
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ __call_if_debug_procs_t __debug_procs = CYGACC_CALL_IF_DEBUG_PROCS();
+ return CYGACC_COMM_IF_GETC(*__debug_procs);
+#elif defined(CYGPKG_CYGMON)
+ return ecos_bsp_console_getc();
+#else
+ return HAL_STUB_PLATFORM_GET_CHAR();
+#endif
+}
+
+// Flush output channel
+void
+hal_flush_output(void)
+{
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ __call_if_debug_procs_t __debug_procs = CYGACC_CALL_IF_DEBUG_PROCS();
+ CYGACC_COMM_IF_CONTROL(*__debug_procs, __COMMCTL_FLUSH_OUTPUT);
+#endif
+}
+
+
+// Set the baud rate for the current serial port.
+void
+__set_baud_rate (int baud)
+{
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ __call_if_debug_procs_t __debug_procs = CYGACC_CALL_IF_DEBUG_PROCS();
+ CYGACC_COMM_IF_CONTROL(*__debug_procs, __COMMCTL_SETBAUD, baud);
+#elif defined(CYGPKG_CYGMON)
+ // FIXME!
+#else
+ HAL_STUB_PLATFORM_SET_BAUD_RATE(baud);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// GDB interrupt (BREAK) support.
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+
+#ifndef CYGPKG_HAL_ARM
+
+#if (HAL_BREAKINST_SIZE == 1)
+typedef cyg_uint8 t_inst;
+#elif (HAL_BREAKINST_SIZE == 2)
+typedef cyg_uint16 t_inst;
+#elif (HAL_BREAKINST_SIZE == 4)
+typedef cyg_uint32 t_inst;
+#else
+#error "Don't know how to handle that size"
+#endif
+
+typedef struct
+{
+ t_inst *targetAddr;
+ t_inst savedInstr;
+} instrBuffer;
+
+static instrBuffer break_buffer;
+
+volatile int cyg_hal_gdb_running_step = 0;
+
+void
+cyg_hal_gdb_place_break (target_register_t pc)
+{
+ cyg_hal_gdb_interrupt( pc ); // Let's hope this becomes a drop-through:
+}
+
+void
+cyg_hal_gdb_interrupt (target_register_t pc)
+{
+ t_inst break_inst = HAL_BREAKINST;
+
+ CYGARC_HAL_SAVE_GP();
+
+ // Clear flag that we Continued instead of Stepping
+ cyg_hal_gdb_running_step = 0;
+ // and override existing break? So that a ^C takes effect...
+ if (NULL != break_buffer.targetAddr)
+ cyg_hal_gdb_remove_break( (target_register_t)break_buffer.targetAddr );
+
+ if (NULL == break_buffer.targetAddr) {
+ // Not always safe to read/write directly to program
+ // memory due to possibly unaligned instruction, use the
+ // provided memory functions instead.
+ __read_mem_safe(&break_buffer.savedInstr, (t_inst*)pc, HAL_BREAKINST_SIZE);
+ __write_mem_safe(&break_inst, (t_inst*)pc, HAL_BREAKINST_SIZE);
+
+ // Save the PC where we put the break, so we can remove
+ // it after the target takes the break.
+ break_buffer.targetAddr = (t_inst*)pc;
+
+ __data_cache(CACHE_FLUSH);
+ __instruction_cache(CACHE_FLUSH);
+ }
+
+ CYGARC_HAL_RESTORE_GP();
+}
+
+int
+cyg_hal_gdb_remove_break (target_register_t pc)
+{
+ if ( cyg_hal_gdb_running_step )
+ return 0;
+
+ if ((t_inst*)pc == break_buffer.targetAddr) {
+
+ __write_mem_safe(&break_buffer.savedInstr, (t_inst*)pc, HAL_BREAKINST_SIZE);
+ break_buffer.targetAddr = NULL;
+
+ __data_cache(CACHE_FLUSH);
+ __instruction_cache(CACHE_FLUSH);
+ return 1;
+ }
+ return 0;
+}
+
+int
+cyg_hal_gdb_break_is_set (void)
+{
+ if (NULL != break_buffer.targetAddr) {
+ return 1;
+ }
+ return 0;
+}
+
+#endif // CYGPKG_HAL_ARM
+
+#endif // CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+
+// Use this function to disable serial interrupts whenever reply
+// characters are expected from GDB. The reason we want to control
+// whether the target can be interrupted or not is simply that GDB on
+// the host will be sending acknowledge characters/commands while the
+// stub is running - if serial interrupts were still active, the
+// characters would never reach the (polling) getDebugChar.
+static void
+interruptible(int state)
+{
+ static int __interrupts_suspended = 0;
+
+ if (state) {
+ __interrupts_suspended--;
+ if (0 >= __interrupts_suspended) {
+ __interrupts_suspended = 0;
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this _check_ should go away
+ {
+ hal_virtual_comm_table_t* __chan;
+ __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+ CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_IRQ_ENABLE);
+ }
+#else
+ if (__interruptible_control)
+ __interruptible_control(1);
+#endif
+ }
+ } else {
+ __interrupts_suspended++;
+ if (1 == __interrupts_suspended)
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this _check_ should go away
+ {
+ hal_virtual_comm_table_t* __chan;
+ __chan = CYGACC_CALL_IF_DEBUG_PROCS();
+ CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_IRQ_DISABLE);
+ }
+#else
+ if (__interruptible_control)
+ __interruptible_control(0);
+#endif
+ }
+}
+
+//-----------------------------------------------------------------------------
+// eCos stub entry and exit magic.
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+int cyg_hal_gdb_break;
+#endif
+
+#ifdef CYGPKG_REDBOOT
+// Trampoline for returning to RedBoot from exception/stub code
+static void
+return_from_stub(int exit_status)
+{
+ CYGACC_CALL_IF_MONITOR_RETURN(exit_status);
+}
+#endif
+
+// Called at stub *kill*
+static void
+handle_exception_exit( void )
+{
+#ifdef CYGPKG_REDBOOT
+#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
+ { // Reset the timer to default and cancel any callback
+ extern void sys_profile_reset(void);
+ sys_profile_reset();
+ }
+#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
+ set_pc((target_register_t)return_from_stub);
+#else
+ int i;
+
+ for (i = 0; i < (sizeof(registers)/sizeof(registers[0])); i++)
+ registers[i] = orig_registers[i];
+#endif
+}
+
+// Called at stub *entry*
+static void
+handle_exception_cleanup( void )
+{
+#ifndef CYGPKG_REDBOOT
+ static int orig_registers_set = 0;
+#endif
+
+ interruptible(0);
+
+ // Expand the HAL_SavedRegisters structure into the GDB register
+ // array format.
+ HAL_GET_GDB_REGISTERS(&registers[0], _hal_registers);
+ _registers = &registers[0];
+
+#ifndef CYGPKG_REDBOOT
+ if (!orig_registers_set) {
+ int i;
+ for (i = 0; i < (sizeof(registers)/sizeof(registers[0])); i++)
+ orig_registers[i] = registers[i];
+ _registers = &orig_registers[0];
+ if (__is_breakpoint_function ())
+ __skipinst ();
+ _registers = &registers[0];
+ orig_registers_set = 1;
+ }
+#endif
+
+#ifdef HAL_STUB_PLATFORM_STUBS_FIXUP
+ // Some architectures may need to fix the PC in case of a partial
+ // or fully executed trap instruction. GDB only takes correct action
+ // when the PC is pointing to the breakpoint instruction it set.
+ //
+ // Most architectures would leave PC pointing at the trap
+ // instruction itself though, and so do not need to do anything
+ // special.
+ HAL_STUB_PLATFORM_STUBS_FIXUP();
+#endif
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+ // If we continued instead of stepping, when there was a break set
+ // ie. we were stepping within a critical region, clear the break, and
+ // that flag. If we stopped for some other reason, this has no effect.
+ if ( cyg_hal_gdb_running_step ) {
+ cyg_hal_gdb_running_step = 0;
+ cyg_hal_gdb_remove_break(get_register (PC));
+ }
+
+ // FIXME: (there may be a better way to do this)
+ // If we hit a breakpoint set by the gdb interrupt stub, make it
+ // seem like an interrupt rather than having hit a breakpoint.
+ cyg_hal_gdb_break = cyg_hal_gdb_remove_break(get_register (PC));
+#endif
+
+#if defined(HAL_STUB_HW_WATCHPOINT) || defined(HAL_STUB_HW_BREAKPOINT)
+ // For HW watchpoint/breakpoint support, we need to know if we
+ // stopped because of watchpoint or hw break. We do that here
+ // before GDB has a chance to remove the watchpoints and save
+ // the information for later use in building response packets.
+ _hw_stop_reason = HAL_STUB_IS_STOPPED_BY_HARDWARE(_watch_data_addr);
+#endif
+}
+
+// Called at stub *exit*
+static void
+handle_exception_init( void )
+{
+ // Compact register array again.
+ HAL_SET_GDB_REGISTERS(_hal_registers, &registers[0]);
+
+ interruptible(1);
+}
+
+
+//-----------------------------------------------------------------------------
+// Initialization.
+
+// Signal handler.
+int
+cyg_hal_process_signal (int signal)
+{
+ // We don't care about the signal (atm).
+ return 0;
+}
+
+// Install the standard set of trap handlers for the stub.
+void
+__install_traps (void)
+{
+ // Set signal handling vector so we can treat 'C<signum>' as 'c'.
+ __process_signal_vec = &cyg_hal_process_signal;
+ __process_exit_vec = &handle_exception_exit;
+
+ __cleanup_vec = &handle_exception_cleanup;
+ __init_vec = &handle_exception_init;
+
+#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this should go away
+#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+ // Control of GDB interrupts.
+ __interruptible_control = HAL_STUB_PLATFORM_INTERRUPTIBLE;
+#endif
+#endif
+
+ // Nothing further to do, handle_exception will be called when an
+ // exception occurs.
+}
+
+// Initialize the hardware.
+void
+initHardware (void)
+{
+ static int initialized = 0;
+
+ if (initialized)
+ return;
+ initialized = 1;
+
+ // Get serial port initialized.
+ HAL_STUB_PLATFORM_INIT_SERIAL();
+
+#ifdef HAL_STUB_PLATFORM_INIT
+ // If the platform defines any initialization code, call it here.
+ HAL_STUB_PLATFORM_INIT();
+#endif
+
+#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this should go away
+#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+ // Get interrupt handler initialized.
+ HAL_STUB_PLATFORM_INIT_BREAK_IRQ();
+#endif
+#endif // !CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+}
+
+// Reset the board.
+void
+__reset (void)
+{
+#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+ __call_if_reset_t *__rom_reset = CYGACC_CALL_IF_RESET_GET();
+ if (__rom_reset)
+ (*__rom_reset)();
+#else
+ HAL_PLATFORM_RESET();
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Breakpoint support.
+
+#ifndef CYGPKG_HAL_ARM
+// This function will generate a breakpoint exception. It is used at
+// the beginning of a program to sync up with a debugger and can be
+// used otherwise as a quick means to stop program execution and
+// "break" into the debugger.
+void
+breakpoint()
+{
+ HAL_BREAKPOINT(_breakinst);
+}
+
+// This function returns the opcode for a 'trap' instruction.
+unsigned long
+__break_opcode ()
+{
+ return HAL_BREAKINST;
+}
+#endif
+
+//-----------------------------------------------------------------------------
+// Write the 'T' packet in BUFFER. SIGVAL is the signal the program received.
+void
+__build_t_packet (int sigval, char *buf)
+{
+ target_register_t addr;
+ char *ptr = buf;
+ target_register_t extend_val = 0;
+
+ *ptr++ = 'T';
+ *ptr++ = __tohex (sigval >> 4);
+ *ptr++ = __tohex (sigval);
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
+ // Include thread ID if thread manipulation is required.
+ {
+ int id = dbg_currthread_id ();
+
+ if (id != 0) {
+ *ptr++ = 't';
+ *ptr++ = 'h';
+ *ptr++ = 'r';
+ *ptr++ = 'e';
+ *ptr++ = 'a';
+ *ptr++ = 'd';
+ *ptr++ = ':';
+
+#if (CYG_BYTEORDER == CYG_LSBFIRST)
+ // FIXME: Temporary workaround for PR 18903. Thread ID must be
+ // big-endian in the T packet.
+ {
+ unsigned char* bep = (unsigned char*)&id;
+ int be_id;
+
+ be_id = id;
+ *bep++ = (be_id >> 24) & 0xff ;
+ *bep++ = (be_id >> 16) & 0xff ;
+ *bep++ = (be_id >> 8) & 0xff ;
+ *bep++ = (be_id & 0xff) ;
+ }
+#endif
+ ptr = __mem2hex((char *)&id, ptr, sizeof(id), 0);
+ *ptr++ = ';';
+ }
+ }
+#endif
+
+#ifdef HAL_STUB_HW_WATCHPOINT
+ switch(_hw_stop_reason) {
+ case HAL_STUB_HW_STOP_WATCH:
+ case HAL_STUB_HW_STOP_RWATCH:
+ case HAL_STUB_HW_STOP_AWATCH:
+#ifdef HAL_STUB_HW_SEND_STOP_REASON_TEXT
+ // Not all GDBs understand this.
+ strcpy(ptr, _hw_stop_str[_hw_stop_reason]);
+ ptr += strlen(_hw_stop_str[_hw_stop_reason]);
+#endif
+ *ptr++ = ':';
+ // Send address MSB first
+ ptr += __intToHex(ptr, (target_register_t)_watch_data_addr,
+ sizeof(_watch_data_addr) * 8);
+ *ptr++ = ';';
+ break;
+ default:
+ break;
+ }
+#endif
+
+ *ptr++ = __tohex (PC >> 4);
+ *ptr++ = __tohex (PC);
+ *ptr++ = ':';
+ addr = get_register (PC);
+ if (sizeof(addr) < REGSIZE(PC))
+ {
+ // GDB is expecting REGSIZE(PC) number of bytes.
+ // We only have sizeof(addr) number. Let's fill
+ // the appropriate number of bytes intelligently.
+#ifdef CYGARC_SIGN_EXTEND_REGISTERS
+ {
+ unsigned long bits_in_addr = (sizeof(addr) << 3); // ie Size in bytes * 8
+ target_register_t sign_bit_mask = (1 << (bits_in_addr - 1));
+ if ((addr & sign_bit_mask) == sign_bit_mask)
+ extend_val = ~0;
+ }
+#endif
+ }
+#if (CYG_BYTEORDER == CYG_MSBFIRST)
+ ptr = __mem2hex((char *)&extend_val, ptr, REGSIZE(PC) - sizeof(addr), 0);
+#endif
+ ptr = __mem2hex((char *)&addr, ptr, sizeof(addr), 0);
+#if (CYG_BYTEORDER == CYG_LSBFIRST)
+ ptr = __mem2hex((char *)&extend_val, ptr, REGSIZE(PC) - sizeof(addr), 0);
+#endif
+ *ptr++ = ';';
+
+ *ptr++ = __tohex (SP >> 4);
+ *ptr++ = __tohex (SP);
+ *ptr++ = ':';
+ addr = (target_register_t) get_register (SP);
+ if (sizeof(addr) < REGSIZE(SP))
+ {
+ // GDB is expecting REGSIZE(SP) number of bytes.
+ // We only have sizeof(addr) number. Let's fill
+ // the appropriate number of bytes intelligently.
+ extend_val = 0;
+#ifdef CYGARC_SIGN_EXTEND_REGISTERS
+ {
+ unsigned long bits_in_addr = (sizeof(addr) << 3); // ie Size in bytes * 8
+ target_register_t sign_bit_mask = (1 << (bits_in_addr - 1));
+ if ((addr & sign_bit_mask) == sign_bit_mask)
+ extend_val = ~0;
+ }
+#endif
+ ptr = __mem2hex((char *)&extend_val, ptr, REGSIZE(SP) - sizeof(addr), 0);
+ }
+ ptr = __mem2hex((char *)&addr, ptr, sizeof(addr), 0);
+ *ptr++ = ';';
+
+ HAL_STUB_ARCH_T_PACKET_EXTRAS(ptr);
+
+ *ptr++ = 0;
+}
+
+
+//-----------------------------------------------------------------------------
+// Cache functions.
+
+// Perform the specified operation on the instruction cache.
+// Returns 1 if the cache is enabled, 0 otherwise.
+int
+__instruction_cache (cache_control_t request)
+{
+ int state = 1;
+
+ switch (request) {
+ case CACHE_ENABLE:
+ HAL_ICACHE_ENABLE();
+ break;
+ case CACHE_DISABLE:
+ HAL_ICACHE_DISABLE();
+ state = 0;
+ break;
+ case CACHE_FLUSH:
+ HAL_ICACHE_SYNC();
+ break;
+ case CACHE_NOOP:
+ /* fall through */
+ default:
+ break;
+ }
+
+#ifdef HAL_ICACHE_IS_ENABLED
+ HAL_ICACHE_IS_ENABLED(state);
+#endif
+
+ return state;
+}
+
+// Perform the specified operation on the data cache.
+// Returns 1 if the cache is enabled, 0 otherwise.
+int
+__data_cache (cache_control_t request)
+{
+ int state = 1;
+
+ switch (request) {
+ case CACHE_ENABLE:
+ HAL_DCACHE_ENABLE();
+ break;
+ case CACHE_DISABLE:
+ HAL_DCACHE_DISABLE();
+ state = 0;
+ break;
+ case CACHE_FLUSH:
+ HAL_DCACHE_SYNC();
+ break;
+ case CACHE_NOOP:
+ /* fall through */
+ default:
+ break;
+ }
+#ifdef HAL_DCACHE_IS_ENABLED
+ HAL_DCACHE_IS_ENABLED(state);
+#endif
+
+ return state;
+}
+
+//-----------------------------------------------------------------------------
+// Memory accessor functions.
+
+// The __mem_fault_handler pointer is volatile since it is only
+// set/cleared by the function below - which does not rely on any
+// other functions, so the compiler may decide to not bother updating
+// the pointer at all. If any of the memory accesses cause an
+// exception, the pointer must be set to ensure the exception handler
+// can make use of it.
+
+void* volatile __mem_fault_handler = (void *)0;
+
+/* These are the "arguments" to __do_read_mem and __do_write_mem,
+ which are passed as globals to avoid squeezing them thru
+ __set_mem_fault_trap. */
+
+static volatile target_register_t memCount;
+
+static void
+__do_copy_mem (unsigned char* src, unsigned char* dst)
+{
+ unsigned long *long_dst;
+ unsigned long *long_src;
+ unsigned short *short_dst;
+ unsigned short *short_src;
+
+ // Zero memCount is not really an error, but the goto is necessary to
+ // keep some compilers from reordering stuff across the 'err' label.
+ if (memCount == 0) goto err;
+
+ __mem_fault = 1; /* Defaults to 'fail'. Is cleared */
+ /* when the copy loop completes. */
+ __mem_fault_handler = &&err;
+
+ // See if it's safe to do multi-byte, aligned operations
+ while (memCount) {
+ if ((memCount >= sizeof(long)) &&
+ (((target_register_t)dst & (sizeof(long)-1)) == 0) &&
+ (((target_register_t)src & (sizeof(long)-1)) == 0)) {
+
+ long_dst = (unsigned long *)dst;
+ long_src = (unsigned long *)src;
+
+ *long_dst++ = *long_src++;
+ memCount -= sizeof(long);
+
+ dst = (unsigned char *)long_dst;
+ src = (unsigned char *)long_src;
+ } else if ((memCount >= sizeof(short)) &&
+ (((target_register_t)dst & (sizeof(short)-1)) == 0) &&
+ (((target_register_t)src & (sizeof(short)-1)) == 0)) {
+
+ short_dst = (unsigned short *)dst;
+ short_src = (unsigned short *)src;
+
+ *short_dst++ = *short_src++;
+ memCount -= sizeof(short);
+
+ dst = (unsigned char *)short_dst;
+ src = (unsigned char *)short_src;
+ } else {
+ *dst++ = *src++;
+ memCount--;
+ }
+ }
+
+ __mem_fault = 0;
+
+ err:
+ __mem_fault_handler = (void *)0;
+}
+
+/*
+ * __read_mem_safe:
+ * Get contents of target memory, abort on error.
+ */
+
+int
+__read_mem_safe (void *dst, void *src, int count)
+{
+ if( !CYG_HAL_STUB_PERMIT_DATA_READ( src, count ) )
+ return 0;
+
+ memCount = count;
+ __do_copy_mem((unsigned char*) src, (unsigned char*) dst);
+ return count - memCount; // return number of bytes successfully read
+}
+
+/*
+ * __write_mem_safe:
+ * Set contents of target memory, abort on error.
+ */
+
+int
+__write_mem_safe (void *src, void *dst, int count)
+{
+ if( !CYG_HAL_STUB_PERMIT_DATA_READ( dst, count ) )
+ return 0;
+
+ memCount = count;
+ __do_copy_mem((unsigned char*) src, (unsigned char*) dst);
+ return count - memCount; // return number of bytes successfully written
+}
+
+#ifdef TARGET_HAS_HARVARD_MEMORY
+static void
+__do_copy_from_progmem (unsigned char* src, unsigned char* dst)
+{
+ unsigned long *long_dst;
+ unsigned long *long_src;
+ unsigned short *short_dst;
+ unsigned short *short_src;
+
+ // Zero memCount is not really an error, but the goto is necessary to
+ // keep some compilers from reordering stuff across the 'err' label.
+ if (memCount == 0) goto err;
+
+ __mem_fault = 1; /* Defaults to 'fail'. Is cleared */
+ /* when the copy loop completes. */
+ __mem_fault_handler = &&err;
+
+ // See if it's safe to do multi-byte, aligned operations
+ while (memCount) {
+ if ((memCount >= sizeof(long)) &&
+ (((target_register_t)dst & (sizeof(long)-1)) == 0) &&
+ (((target_register_t)src & (sizeof(long)-1)) == 0)) {
+
+ long_dst = (unsigned long *)dst;
+ long_src = (unsigned long *)src;
+
+ *long_dst++ = __read_prog_uint32(long_src++);
+ memCount -= sizeof(long);
+
+ dst = (unsigned char *)long_dst;
+ src = (unsigned char *)long_src;
+ } else if ((memCount >= sizeof(short)) &&
+ (((target_register_t)dst & (sizeof(short)-1)) == 0) &&
+ (((target_register_t)src & (sizeof(short)-1)) == 0)) {
+
+ short_dst = (unsigned short *)dst;
+ short_src = (unsigned short *)src;
+
+ *short_dst++ = __read_prog_uint16(short_src++);
+ memCount -= sizeof(short);
+
+ dst = (unsigned char *)short_dst;
+ src = (unsigned char *)short_src;
+ } else {
+ *dst++ = __read_prog_uint8(src++);
+ memCount--;
+ }
+ }
+
+ __mem_fault = 0;
+
+ err:
+ __mem_fault_handler = (void *)0;
+}
+
+static void
+__do_copy_to_progmem (unsigned char* src, unsigned char* dst)
+{
+ unsigned long *long_dst;
+ unsigned long *long_src;
+ unsigned short *short_dst;
+ unsigned short *short_src;
+
+ // Zero memCount is not really an error, but the goto is necessary to
+ // keep some compilers from reordering stuff across the 'err' label.
+ if (memCount == 0) goto err;
+
+ __mem_fault = 1; /* Defaults to 'fail'. Is cleared */
+ /* when the copy loop completes. */
+ __mem_fault_handler = &&err;
+
+ // See if it's safe to do multi-byte, aligned operations
+ while (memCount) {
+ if ((memCount >= sizeof(long)) &&
+ (((target_register_t)dst & (sizeof(long)-1)) == 0) &&
+ (((target_register_t)src & (sizeof(long)-1)) == 0)) {
+
+ long_dst = (unsigned long *)dst;
+ long_src = (unsigned long *)src;
+
+ __write_prog_uint32(long_dst++, *long_src++);
+ memCount -= sizeof(long);
+
+ dst = (unsigned char *)long_dst;
+ src = (unsigned char *)long_src;
+ } else if ((memCount >= sizeof(short)) &&
+ (((target_register_t)dst & (sizeof(short)-1)) == 0) &&
+ (((target_register_t)src & (sizeof(short)-1)) == 0)) {
+
+ short_dst = (unsigned short *)dst;
+ short_src = (unsigned short *)src;
+
+ __write_prog_uint16(short_dst++, *short_src++);
+ memCount -= sizeof(short);
+
+ dst = (unsigned char *)short_dst;
+ src = (unsigned char *)short_src;
+ } else {
+ __write_prog_uint8(dst++, *src++);
+ memCount--;
+ }
+ }
+
+ __mem_fault = 0;
+
+ err:
+ __mem_fault_handler = (void *)0;
+}
+
+/*
+ * __read_progmem_safe:
+ * Get contents of target memory, abort on error.
+ */
+
+int
+__read_progmem_safe (void *dst, void *src, int count)
+{
+ if( !CYG_HAL_STUB_PERMIT_CODE_READ( src, count ) )
+ return 0;
+
+ memCount = count;
+ __do_copy_from_progmem((unsigned char*) src, (unsigned char*) dst);
+ return count - memCount; // return number of bytes successfully read
+}
+
+/*
+ * __write_progmem_safe:
+ * Set contents of target memory, abort on error.
+ */
+
+int
+__write_progmem_safe (void *src, void *dst, int count)
+{
+ if( !CYG_HAL_STUB_PERMIT_CODE_WRITE( dst, count ) )
+ return 0;
+
+ memCount = count;
+ __do_copy_to_progmem((unsigned char*) src, (unsigned char*) dst);
+ return count - memCount; // return number of bytes successfully written
+}
+#endif
+
+//-----------------------------------------------------------------------------
+// Target extras?!
+int
+__process_target_query(char * pkt, char * out, int maxOut)
+{ return 0 ; }
+int
+__process_target_set(char * pkt, char * out, int maxout)
+{ return 0 ; }
+int
+__process_target_packet(char * pkt, char * out, int maxout)
+{ return 0 ; }
+
+// GDB string output, making sure interrupts are disabled.
+// This function gets used by some diag output functions.
+void
+hal_output_gdb_string(target_register_t str, int string_len)
+{
+ unsigned long __state;
+ HAL_DISABLE_INTERRUPTS(__state);
+ __output_gdb_string(str, string_len);
+ HAL_RESTORE_INTERRUPTS(__state);
+}
+
+#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
diff --git a/ecos/packages/hal/common/current/src/stubrom/stubrom.c b/ecos/packages/hal/common/current/src/stubrom/stubrom.c
new file mode 100644
index 0000000..9beb908
--- /dev/null
+++ b/ecos/packages/hal/common/current/src/stubrom/stubrom.c
@@ -0,0 +1,60 @@
+/*==========================================================================
+//
+// stubrom.c
+//
+// GDB Stub ROM main
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 1998-06-02
+// Purpose: GDB Stub ROM main
+// Description: Main program for GDB stub ROM. It simply set the debug
+// traps and then breakpoints so we can talk to GDB.
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <cyg/hal/hal_stub.h>
+
+void cyg_start (void)
+{
+ for(;;) breakpoint();
+}
+
+// End of stubrom.c
diff --git a/ecos/packages/hal/common/current/src/thread-packets.c b/ecos/packages/hal/common/current/src/thread-packets.c
new file mode 100644
index 0000000..19f80ee
--- /dev/null
+++ b/ecos/packages/hal/common/current/src/thread-packets.c
@@ -0,0 +1,1414 @@
+//========================================================================
+//
+// thread-packets.c
+//
+// Provides multi-threaded debug support
+//
+//========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Red Hat, nickg
+// Contributors: Red Hat, nickg
+// Date: 1998-08-25
+// Purpose:
+// Description: Provides multi-threaded debug support
+// Usage:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================
+
+// Define __ECOS__; allows all eCos specific additions to be easily identified.
+#define __ECOS__
+
+
+// #ifdef __ECOS__
+#include <pkgconf/hal.h>
+
+#if defined(CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT) \
+ && defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
+// #endif // __ECOS__
+
+/* FIXME: Scan this module for correct sizes of fields in packets */
+
+#ifdef __ECOS__
+#include <cyg/hal/dbg-threads-api.h>
+#else // __ECOS__
+#include "dbg-threads-api.h"
+#endif // __ECOS__
+
+/* This file should ALWAYS define debug thread support */
+/* Dont include the object in the link if you dont need the support */
+/* This is NOT the internal unit debug flag, it is a feature control */
+#if defined(DEBUG_THREADS)
+#undef DEBUG_THREADS
+#endif
+
+#define DEBUG_THREADS 1
+#define UNIT_TEST 0
+#define GDB_MOCKUP 0
+
+
+#define STUB_BUF_MAX 300 /* for range checking of packet lengths */
+
+#include "thread-pkts.h"
+
+#ifdef __ECOS__
+// Use HAL rather than board.h in eCos
+#include <cyg/hal/hal_stub.h>
+#else // __ECOS__
+#include "board.h"
+#endif // __ECOS__
+
+/*
+ * Export the continue and "general" (context) thread IDs from GDB.
+ */
+int _gdb_cont_thread ;
+int _gdb_general_thread ;
+
+#if !defined(PKT_DEBUG)
+#define PKT_DEBUG 0
+#endif
+extern void output_string(char * message) ;
+
+#if PKT_DEBUG
+void output_threadid(char * title,threadref * ref) ;
+#warning "PKT_DEBUG macros engaged"
+#define PKT_TRACE(title,packet) \
+{ output_string(title) ; output_string(packet) ; output_string("\n") ;}
+#else
+#define PKT_TRACE(title,packet) {}
+#endif
+
+
+/* This is going to be irregular because the various implementations
+ have adopted different names for registers.
+ It would be nice to fix them to have a common convention
+ _stub_registers
+ stub_registers
+ alt_stub_registers
+ */
+
+extern target_register_t * _registers ;
+ /* A pointer to the current set of registers */
+extern target_register_t registers[]; /* The current saved registers */
+extern target_register_t alt_registers[] ;
+ /* Thread or saved process state */
+
+
+static void stub_copy_registers(
+ target_register_t * dest,
+ target_register_t *src
+ )
+{
+ target_register_t * limit ;
+ limit = dest + HAL_STUB_REGISTERS_SIZE ;
+
+ while (dest < limit) *dest++ = *src++ ;
+}
+
+#ifdef __ECOS__
+void __stub_copy_registers(target_register_t * dest,
+ target_register_t *src)
+{
+ stub_copy_registers(dest, src);
+}
+#endif // __ECOS__
+
+extern int stubhex(char ch) ;
+
+/* ----- STUB_PACK_NAK ----------------------------------- */
+/* Pack an error response into the response packet */
+
+char * stub_pack_nak(char * outbuf)
+{
+ *outbuf++ = 'E' ;
+ *outbuf++ = '0' ;
+ *outbuf++ = '2' ;
+ return outbuf ;
+} /* stub_pack_nak */
+
+/* ----- STUB_PACK_ACK -------------------------- */
+/* Pack an OK achnowledgement */
+char * stub_pack_ack(char * outbuf)
+{
+ *outbuf++ = 'O' ;
+ *outbuf++ = 'K' ;
+ return outbuf ;
+} /* stub_pack_ack */
+
+/* ------- STUB_UNPACK_INT ------------------------------- */
+/* Unpack a few bytes and return its integer value */
+/* This is where I wish functions could return several values
+ I would also advance the buffer pointer */
+
+int stub_unpack_int(char * buff,int fieldlength)
+{
+ int retval = 0 ;
+ int nibble ;
+ while (fieldlength)
+ { nibble = stubhex(*buff++) ;
+ retval |= nibble ;
+ fieldlength-- ;
+ if (fieldlength) retval = retval << 4 ;
+ }
+ return retval ;
+} /* stub_unpack_int */
+
+static char * unpack_byte(char * buf, int * value)
+{
+ *value = stub_unpack_int(buf,2) ;
+ return buf + 2 ;
+}
+
+static char * unpack_int(char * buf, int * value)
+{
+ *value = stub_unpack_int(buf,8) ;
+ return buf + 8 ;
+}
+
+/* We are NOT depending upon extensive libraries */
+static int ishex(char ch,int *val)
+{
+ if ((ch >= 'a') && (ch <= 'f'))
+ { *val =ch - 'a' + 10 ; return 1 ; }
+ if ((ch >= 'A') && (ch <= 'F'))
+ { *val = ch - 'A' + 10 ; return 1 ;}
+ if ((ch >= '0') && (ch <= '9'))
+ { *val = ch - '0' ; return 1 ; }
+ return 0 ;
+} /* ishex */
+
+static char * unpack_nibble(char * buf,int * val)
+{
+ ishex(*buf++,val) ;
+ return buf ;
+}
+
+
+static const char hexchars[] = "0123456789abcdef";
+
+static char * pack_hex_byte(char * pkt, unsigned char byte)
+{
+ *pkt++ = hexchars[(byte >> 4) & 0xf] ;
+ *pkt++ = hexchars[(byte & 0xf)] ;
+ return pkt ;
+} /* pack_hex_byte */
+
+#ifndef __ECOS__
+/* ---- STUB_PACK_VARLEN_HEX ------------------------------------- */
+/* Format a variable length stream of hex bytes */
+
+static char * pack_varlen_hex(
+ char * pkt,
+ unsigned int value)
+{
+ int i ;
+ static unsigned char n[8] ;
+ if (value == 0)
+ {
+ *pkt++ = '0' ;
+ return pkt ;
+ }
+ else
+ {
+ i = 8 ;
+ while (i-- >= 0 ) /* unpack nibbles into a char array */
+ {
+ n[i] = value & 0x0f ;
+ value = value >> 4 ;
+ }
+ i = 0 ; /* we had decrmented it to -1 */
+ while (n[i] == 0 ) i++ ; /* drop leading zeroes */
+ while (i++ < 8) *pkt++ = hexchars[n[i]] ; /* pack the number */
+ }
+ return pkt ;
+} /* pack_varlen_hex */
+#endif // !__ECOS__
+
+
+/* ------ STUB_UNPACK_VARLEN_HEX -------------------------------- */
+/* Parse a stream of hex bytes which may be of variable length */
+/* return the pointer to the next char */
+/* modify a varparm containing the result */
+/* A failure would look like a non-increment of the buffer pointer */
+
+/* This unpacks hex strings that may have been packed using sprintf(%x) */
+/* We assume some non-hex delimits them */
+
+char * unpack_varlen_hex(
+ char * buff, /* packet to parse */
+ int * result)
+{
+ int nibble ;
+ int retval ;
+ retval = 0 ;
+
+ while (ishex(*buff,&nibble))
+ {
+ buff++ ;
+ retval = retval << 4 ;
+ retval |= nibble & 0x0f ;
+ }
+ *result = retval ;
+ return buff ;
+} /* stub_unpack_varlen_int */
+
+
+/* ------ UNPACK_THREADID ------------------------------- */
+/* A threadid is a 64 bit quantity */
+
+#define BUFTHREADIDSIZ 16 /* encode 64 bits in 16 chars of hex */
+
+static char * unpack_threadid(char * inbuf, threadref * id)
+{
+ char * altref ;
+ char * limit = inbuf + BUFTHREADIDSIZ ;
+ int x,y ;
+ altref = (char *) id ;
+
+ while (inbuf < limit)
+ {
+ x = stubhex(*inbuf++) ;
+ y = stubhex(*inbuf++) ;
+ *altref++ = (x << 4) | y ;
+ }
+ return inbuf ;
+} /* unpack_threadid */
+
+
+
+/* Pack an integer use leading zeroes */
+static char * pack_int(char * buf,int value)
+{
+ buf = pack_hex_byte(buf,(value>> 24)& 0xff) ;
+ buf = pack_hex_byte(buf,(value >>16)& 0xff) ;
+ buf = pack_hex_byte(buf,(value >>8) & 0x0ff) ;
+ buf = pack_hex_byte(buf,(value & 0xff)) ;
+ return buf ;
+} /* pack_int */
+
+
+/* -------- PACK_STRING ---------------------------------------------- */
+/* This stupid string better not contain any funny characters */
+/* Also, the GDB protocol will not cope with NULLs in the
+ string or at the end of it.
+ While is is posable to encapsulate the protocol in ays that
+ preclude filtering for # I am assuming this is a constraint.
+*/
+
+static char * pack_raw_string(char * pkt,char * string)
+{
+ char ch ;
+ while (0 != (ch = *string++)) *pkt++ = ch ;
+ return pkt ;
+}
+
+static char * pack_string(
+ char * pkt,
+ char * string)
+{
+ char ch ;
+#ifdef __ECOS__
+ int len = 0;
+ char *s = string;
+ while( *s++ ) len++;
+#else // __ECOS__
+ int len ;
+ len = strlen(string) ;
+#endif // __ECOS
+ if (len > 200 ) len = 200 ; /* Bigger than most GDB packets, junk??? */
+ pkt = pack_hex_byte(pkt,len) ;
+ while (len-- > 0)
+ {
+ ch = *string++ ;
+ if ((ch == '\0') || (ch == '#')) ch = '*' ; /* Protect encapsulation */
+ *pkt++ = ch ;
+ }
+ return pkt ;
+} /* pack_string */
+
+
+/* ----- STUB_PACK_THREADID --------------------------------------------- */
+/* Convert a binary 64 bit threadid and pack it into a xmit buffer */
+/* Return the advanced buffer pointer */
+
+static char * pack_threadid(char * pkt, threadref * id)
+{
+ char * limit ;
+ unsigned char * altid ;
+ altid = (unsigned char *) id ;
+ limit = pkt + BUFTHREADIDSIZ ;
+ while (pkt < limit) pkt = pack_hex_byte(pkt,*altid++) ;
+ return pkt ;
+} /* stub_pack_threadid */
+
+/* UNFORTUNATELY, not all of the extended debugging system has yet been
+ converted to 64 but thread references and process identifiers.
+ These routines do the conversion.
+ An array of bytes is the correct treatment of an opaque identifier.
+ ints have endian issues.
+ */
+
+static void int_to_threadref(threadref * id, int value)
+{
+ unsigned char * scan ;
+ scan = (unsigned char *) id ;
+ {
+ int i = 4 ;
+ while (i--) *scan++ = 0 ;
+ }
+ *scan++ = (value >> 24) & 0xff ;
+ *scan++ = (value >> 16) & 0xff ;
+ *scan++ = (value >> 8) & 0xff ;
+ *scan++ = (value & 0xff) ;
+}
+
+static int threadref_to_int(threadref * ref)
+{
+ int value = 0 ;
+ unsigned char * scan ;
+ int i ;
+
+ scan = (unsigned char *) ref ;
+ scan += 4 ;
+ i = 4 ;
+ while (i-- > 0) value = (value << 8) | ((*scan++) & 0xff) ;
+ return value ;
+} /* threadref_to_int */
+
+void copy_threadref(threadref * dest, threadref * src)
+{
+ int i ;
+ unsigned char * csrc, * cdest ;
+ csrc = (unsigned char *) src ;
+ cdest = (unsigned char *) dest ;
+ i = 8 ;
+ while (i--) *cdest++ = *csrc++ ;
+}
+
+
+int threadmatch(
+ threadref * dest ,
+ threadref * src
+ )
+{
+ unsigned char * srcp, * destp ;
+ int i , result ;
+ srcp = (unsigned char *) src ;
+ destp = (unsigned char *) dest ;
+ i = 8 ;
+ result = 1 ;
+ while (i-- > 0 ) result &= (*srcp++ == *destp++) ? 1 : 0 ;
+ return result ;
+} /* threadmatch */
+
+
+
+static char * Tpkt_threadtag = "thread:" ;
+
+/* ----- STUB_PACK_TPKT_THREADID ------------------------------------ */
+/* retreive, tag and insert a thread identifier into a T packet. */
+/* Insert nothing if the thread identifier is not available */
+
+char * stub_pack_Tpkt_threadid(char * pkt)
+{
+ static threadref thread ;
+ int fmt = 0 ; /* old format */
+ PKT_TRACE("Tpkt-id","---") ;
+ if (dbg_currthread(&thread))
+ {
+ pkt = pack_raw_string(pkt,Tpkt_threadtag) ;
+ if (fmt)
+ pkt = pack_threadid(pkt,&thread) ;
+ else
+ /* Until GDB lengthens its thread ids, we have to MASH
+ the threadid into somthing shorter. PLEASE FIX GDB */
+ pkt = pack_int(pkt,threadref_to_int(&thread)) ;
+ *pkt++ = ';' ; /* terminate variable length int */
+ *pkt = '\0' ; /* Null terminate to allow string to be printed, no++ */
+ }
+ PKT_TRACE("packedTpkt","--") ;
+ return pkt ;
+} /* stub_pack_Tpkt_threadid */
+
+long stub_get_currthread (void)
+{
+ threadref thread ;
+
+ if (dbg_currthread(&thread))
+ return threadref_to_int(&thread) ;
+ else
+ return 0 ;
+}
+
+void stub_pkt_currthread(
+ char * inbuf,
+ char * outbuf,
+ int bufmax)
+{
+ threadref thread ;
+#if PKT_DEBUG
+ char * base_out ;
+ base_out = outbuf ;
+#endif
+ if (dbg_currthread(&thread))
+ {
+ *outbuf++ = 'Q' ;
+ *outbuf++ = 'C' ; /* FIXME: Is this a reasonable code */
+ outbuf = pack_int(outbuf, threadref_to_int(&thread)) ; /* Short form */
+ }
+ else outbuf = stub_pack_nak(outbuf) ;
+ *outbuf = '\0' ; /* terminate response packet */
+ PKT_TRACE("stub_pkt_currthread(resp) ",base_out) ;
+} /* stub_pkt_currthread */
+
+/* ----- STUB_PKT_THREAD_ALIVE --------------------------------- */
+/* Answer the thread alive query */
+
+static int thread_alive (int id)
+{
+ threadref thread ;
+ struct cygmon_thread_debug_info info ;
+
+ int_to_threadref(&thread, id) ;
+ if (dbg_threadinfo(&thread, &info) &&
+ info.context_exists)
+ return 1 ;
+ else
+ return 0 ;
+}
+
+void stub_pkt_thread_alive(char * inbuf,
+ char * outbuf,
+ int bufmax)
+{
+ char * prebuf = inbuf ;
+ int result ;
+
+ if (prebuf != (inbuf = unpack_varlen_hex(inbuf,&result)))
+ {
+ if (thread_alive(result))
+ {
+ outbuf = stub_pack_ack(outbuf) ;
+ *outbuf = '\0' ;
+ return ;
+ }
+ }
+ outbuf = stub_pack_nak(outbuf) ;
+ *outbuf = '\0' ; /* terminate the response message */
+} /* stub_pkt_thread_alive */
+
+
+
+/* ----- STUB_PKT_CHANGETHREAD ------------------------------- */
+/* Switch the display of registers to that of a saved context */
+
+/* Changing the context makes NO sense, although the packets define the
+ capability. Therefore, the option to change the context back does
+ call the function to change registers. Also, there is no
+ forced context switch.
+ 'p' - New format, long long threadid, no special cases
+ 'c' - Old format, id for continue, 32 bit threadid max, possably less
+ -1 means continue all threads
+ 'g' - Old Format, id for general use (other than continue)
+
+ replies:
+ OK for success
+ ENN for error
+ */
+
+void stub_pkt_changethread(
+ char * inbuf,
+ char * outbuf,
+ int bufmax)
+{
+ threadref id ;
+ int idefined = -1 ;
+ char ch ;
+ PKT_TRACE("setthread-pkt ",inbuf) ;
+
+ /* Parse the incoming packet for a thread identifier */
+ switch (ch = *inbuf++ ) /* handle various packet formats */
+ {
+ case 'p' : /* New format: mode:8,threadid:64 */
+ inbuf = unpack_nibble(inbuf,&idefined) ;
+ inbuf = unpack_threadid(inbuf,&id) ; /* even if startflag */
+ break ;
+ case 'c' : /* old format , specify thread for continue */
+ if (inbuf[0] == '-' && inbuf[1] == '1') /* Hc-1 */
+ _gdb_cont_thread = 0 ;
+ else
+ inbuf = unpack_varlen_hex(inbuf, &_gdb_cont_thread) ;
+
+ if (_gdb_cont_thread == 0 || /* revert to any old thread */
+ thread_alive(_gdb_cont_thread)) /* specified thread is alive */
+ outbuf = stub_pack_ack(outbuf) ;
+ else
+ outbuf = stub_pack_nak(outbuf) ;
+ break ;
+ case 'g' : /* old format, specify thread for general operations */
+ /* OLD format: parse a variable length hex string */
+ /* OLD format consider special thread ids */
+ {
+ inbuf = unpack_varlen_hex(inbuf, &_gdb_general_thread) ;
+ int_to_threadref(&id, _gdb_general_thread) ;
+ switch (_gdb_general_thread)
+ {
+ case 0 : /* pick a thread, any thread */
+ idefined = 2 ; /* select original interrupted context */
+ break ;
+ case -1 : /* all threads */
+ idefined = 2 ;
+ break ;
+ default :
+ idefined = 1 ; /* select the specified thread */
+ break ;
+ }
+ }
+ break ;
+ default:
+ outbuf = stub_pack_nak(outbuf) ;
+ break ;
+ } /* handle various packet formats */
+
+ switch (idefined)
+ {
+ case -1 :
+ /* Packet not supported, already NAKed, no further action */
+ break ;
+ case 0 :
+ /* Switch back to interrupted context */
+ _registers = &registers[0] ;
+ break ;
+ case 1 :
+ /* copy the saved registers into the backup registers */
+ stub_copy_registers(alt_registers,registers) ;
+ /* The OS will now update the values it has in a saved process context*/
+ if (dbg_getthreadreg(&id,NUMREGS,&alt_registers[0]))
+ {
+ /* switch the registers pointer */
+ _registers = &alt_registers[0] ;
+ outbuf = stub_pack_ack(outbuf) ;
+ }
+ else
+ outbuf = stub_pack_nak(outbuf) ;
+ break ;
+ case 2 :
+ /* switch to interrupted context */
+ outbuf = stub_pack_ack(outbuf) ;
+ break ;
+ default:
+ outbuf = stub_pack_nak(outbuf) ;
+ break ;
+ }
+ *outbuf = '\0' ; /* Terminate response pkt */
+} /* stub_pkt_changethread */
+
+
+/* ---- STUB_PKT_GETTHREADLIST ------------------------------- */
+/* Get a portion of the threadlist or process list */
+/* This may be part of a multipacket transaction */
+/* It would be hard to tell in the response packet the difference
+ between the end of list and an error in threadid encoding.
+ */
+
+void stub_pkt_getthreadlist(char * inbuf,
+ char * outbuf,
+ int bufmax)
+{
+ char * count_ptr ;
+ char * done_ptr ;
+ char * limit ;
+ int start_flag , batchsize , result , count ;
+ static threadref lastthread, nextthread ;
+
+#if PKT_DEBUG
+ char * r_base = outbuf ;
+#endif
+ PKT_TRACE("pkt_getthreadlist: ",inbuf) ;
+
+ count = 0 ;
+ inbuf = unpack_nibble(inbuf,&start_flag) ;
+ inbuf = unpack_byte(inbuf,&batchsize) ;
+ inbuf = unpack_threadid(inbuf,&lastthread) ; /* even if startflag */
+
+ /* Start building response packet */
+ limit = outbuf + (bufmax - BUFTHREADIDSIZ - 10) ; /* id output packing limit */
+ *outbuf++ = 'Q' ;
+ *outbuf++ = 'M' ;
+
+ /* Default values for count and done fields, save ptr to repatch */
+ count_ptr = outbuf ; /* save to repatch count */
+ outbuf = pack_hex_byte(outbuf,0) ;
+ done_ptr = outbuf ; /* Backpatched later */
+ *outbuf++ = '0' ; /* Done = 0 by default */
+ outbuf = pack_threadid(outbuf,&lastthread) ;
+
+ /* Loop through the threadid packing */
+ while ((outbuf < limit) && (count < batchsize))
+ {
+ result = dbg_threadlist(start_flag,&lastthread,&nextthread) ;
+ start_flag = 0 ; /* redundant but effective */
+ if (!result)
+ { *done_ptr = '1' ; /* pack the done flag */
+ break ;
+ }
+#if 0 /* DEBUG */
+ if (threadmatch(&lastthread,&nextthread))
+ {
+ output_string("FAIL: Threadlist, not incrementing\n") ;
+ *done_ptr = '1' ;
+ break ;
+ }
+#endif
+ count++ ;
+ outbuf = pack_threadid(outbuf,&nextthread) ;
+ copy_threadref(&lastthread,&nextthread) ;
+ }
+ pack_hex_byte(count_ptr,count) ;/* backpatch, Pack the count field */
+ *outbuf = '\0' ;
+ PKT_TRACE("pkt_getthreadlist(resp) ",r_base) ;
+} /* pkt_getthreadlist */
+
+
+
+
+/* ----- STUB_PKT_GETTHREADINFO ---------------------------------------- */
+/* Get the detailed information about a specific thread or process */
+
+/*
+Encoding:
+ 'Q':8,'P':8,mask:16
+
+ Mask Fields
+ threadid:1, # always request threadid
+ context_exists:2,
+ display:4,
+ unique_name:8,
+ more_display:16
+ */
+
+void stub_pkt_getthreadinfo(
+ char * inbuf,
+ char * outbuf,
+ int bufmax)
+{
+ int mask ;
+ int result ;
+ threadref thread ;
+ struct cygmon_thread_debug_info info ;
+
+ info.context_exists = 0 ;
+ info.thread_display = 0 ;
+ info.unique_thread_name = 0 ;
+ info.more_display = 0 ;
+
+ /* Assume the packet identification chars have already been
+ discarded by the packet demultiples routines */
+ PKT_TRACE("PKT getthreadinfo",inbuf) ;
+
+ inbuf = unpack_int(inbuf,&mask) ;
+ inbuf = unpack_threadid(inbuf,&thread) ;
+
+ result = dbg_threadinfo(&thread,&info) ; /* Make system call */
+
+ if (result)
+ {
+ *outbuf++ = 'q' ;
+ *outbuf++ = 'p' ;
+ outbuf = pack_int(outbuf,mask) ;
+ outbuf = pack_threadid(outbuf,&info.thread_id) ; /* echo threadid */
+ if (mask & 2) /* context-exists */
+ {
+ outbuf = pack_int(outbuf,2) ; /* tag */
+ outbuf = pack_hex_byte(outbuf,2) ; /* length */
+ outbuf = pack_hex_byte(outbuf,info.context_exists) ;
+ }
+ if ((mask & 4) && info.thread_display)/* display */
+ {
+ outbuf = pack_int(outbuf,4) ; /* tag */
+ outbuf = pack_string(outbuf,info.thread_display) ;
+ }
+ if ((mask & 8) && info.unique_thread_name) /* unique_name */
+ {
+ outbuf = pack_int(outbuf,8) ;
+ outbuf = pack_string(outbuf,info.unique_thread_name) ;
+ }
+ if ((mask & 16) && info.more_display) /* more display */
+ {
+ outbuf = pack_int(outbuf,16) ; /* tag 16 */
+ outbuf = pack_string(outbuf,info.more_display) ;
+ }
+ }
+ else
+ {
+ PKT_TRACE("FAIL: dbg_threadinfo\n", "") ;
+ outbuf = stub_pack_nak(outbuf) ;
+ }
+ *outbuf = '\0' ;
+} /* stub_pkt_getthreadinfo */
+
+int stub_lock_scheduler(int lock, /* 0 to unlock, 1 to lock */
+ int mode, /* 0 for step, 1 for continue */
+ long id) /* current thread */
+{
+ threadref thread;
+
+ int_to_threadref(&thread, id) ;
+ return dbg_scheduler(&thread, lock, mode) ;
+}
+
+
+#if GDB_MOCKUP
+/* ------ MATCHED GDB SIDE PACKET ENCODING AND PARSING ----------------- */
+
+char * pack_nibble(char * buf, int nibble)
+{
+ *buf++ = hexchars[(nibble & 0x0f)] ;
+ return buf ;
+} /* pack_nibble */
+
+#if 0
+static char * unpack_short(char * buf,int * value)
+{
+ *value = stub_unpack_int(buf,4) ;
+ return buf + 4 ;
+}
+
+static char * pack_short(
+ char * buf,
+ unsigned int value)
+{
+ buf = pack_hex_byte(buf,(value >> 8) & 0xff) ;
+ buf = pack_hex_byte(buf,(value & 0xff)) ;
+ return buf ;
+} /* pack_short */
+#endif
+
+
+/* Generally, I dont bury xmit and receive calls inside packet formatters
+ and parsers
+ */
+
+
+
+
+/* ----- PACK_SETTHREAD_REQUEST ------------------------------------- */
+/* Encoding: ??? decode gdb/remote.c
+ 'Q':8,'p':8,idefined:8,threadid:32 ;
+ */
+
+char * pack_setthread_request(
+ char * buf,
+ char fmt, /* c,g or, p */
+ int idformat ,
+ threadref * threadid )
+{
+ *buf++ = fmt ;
+
+ if (fmt == 'p')
+ { /* pack the long form */
+ buf = pack_nibble(buf,idformat) ;
+ buf = pack_threadid(buf,threadid) ;
+ }
+ else
+ { /* pack the shorter form - Serious truncation */
+ /* There are reserved identifieds 0 , -1 */
+ int quickref = threadref_to_int(threadid) ;
+ buf = pack_varlen_hex(buf,quickref) ;
+ }
+ *buf++ = '\0' ; /* end_of_packet */
+ return buf ;
+} /* pack_setthread_request */
+
+
+
+/* -------- PACK_THREADLIST-REQUEST --------------------------------- */
+/* Format: i'Q':8,i"L":8,initflag:8,batchsize:16,lastthreadid:32 */
+
+
+char * pack_threadlist_request(
+ char * pkt,
+ int startflag,
+ int threadcount,
+ threadref * nextthread
+ )
+{
+ *pkt++ = 'q' ;
+ *pkt++ = 'L' ;
+ pkt = pack_nibble(pkt,startflag) ; /* initflag 1 bytes */
+ pkt = pack_hex_byte(pkt,threadcount) ; /* threadcount 2 bytes */
+ pkt = pack_threadid(pkt,nextthread) ; /* 64 bit thread identifier */
+ *pkt = '\0' ;
+ return pkt ;
+} /* remote_threadlist_request */
+
+
+
+
+/* ---------- PARSE_THREADLIST_RESPONSE ------------------------------------ */
+/* Encoding: 'q':8,'M':8,count:16,done:8,argthreadid:64,(threadid:64)* */
+
+int parse_threadlist_response(
+ char * pkt,
+ threadref * original_echo,
+ threadref * resultlist,
+ int * doneflag)
+{
+ char * limit ;
+ int count, resultcount , done ;
+ resultcount = 0 ;
+
+ /* assume the 'q' and 'M chars have been stripped */
+ PKT_TRACE("parse-threadlist-response ",pkt) ;
+ limit = pkt + (STUB_BUF_MAX - BUFTHREADIDSIZ) ; /* done parse past here */
+ pkt = unpack_byte(pkt,&count) ; /* count field */
+ pkt = unpack_nibble(pkt,&done) ;
+ /* The first threadid is the argument threadid */
+ pkt = unpack_threadid(pkt,original_echo) ; /* should match query packet */
+ while ((count-- > 0) && (pkt < limit))
+ {
+ pkt = unpack_threadid(pkt,resultlist++) ;
+ resultcount++ ;
+ }
+ if (doneflag) *doneflag = done ;
+ return resultcount ; /* successvalue */
+} /* parse_threadlist_response */
+
+struct gdb_ext_thread_info
+{
+ threadref threadid ;
+ int active ;
+ char display[256] ;
+ char shortname[32] ;
+ char more_display[256] ;
+} ;
+
+
+/* ----- PACK_THREAD_INFO_REQUEST -------------------------------- */
+
+/*
+ threadid:1, # always request threadid
+ context_exists:2,
+ display:4,
+ unique_name:8,
+ more_display:16
+ */
+
+/* Encoding: 'Q':8,'P':8,mask:32,threadid:64 */
+
+char * pack_threadinfo_request(char * pkt,
+ int mode,
+ threadref * id
+ )
+{
+ *pkt++ = 'Q' ;
+ *pkt++ = 'P' ;
+ pkt = pack_int(pkt,mode) ; /* mode */
+ pkt = pack_threadid(pkt,id) ; /* threadid */
+ *pkt = '\0' ; /* terminate */
+ return pkt ;
+} /* pack_thread_info_request */
+
+
+
+static char * unpack_string(
+ char * src,
+ char * dest,
+ int length)
+{
+ while (length--) *dest++ = *src++ ;
+ *dest = '\0' ;
+ return src ;
+} /* unpack_string */
+
+
+void output_threadid(char * title,threadref * ref)
+{
+ char hexid[20] ;
+ pack_threadid(&hexid[0],ref) ; /* Convert threead id into hex */
+ hexid[16] = 0 ;
+ output_string(title) ;
+ output_string(&hexid[0]) ;
+ output_string("\n") ;
+}
+
+/* ------ REMOTE_UPK_THREAD_INFO_RESPONSE ------------------------------- */
+/* Unpack the response of a detailed thread info packet */
+/* Encoding: i'Q':8,i'R':8,argmask:16,threadid:64,(tag:8,length:16,data:x)* */
+
+#define TAG_THREADID 1
+#define TAG_EXISTS 2
+#define TAG_DISPLAY 4
+#define TAG_THREADNAME 8
+#define TAG_MOREDISPLAY 16
+
+
+int remote_upk_thread_info_response(
+ char * pkt,
+ threadref * expectedref ,
+ struct gdb_ext_thread_info * info)
+{
+ int mask, length ;
+ unsigned int tag ;
+ threadref ref ;
+ char * limit = pkt + 500 ; /* plausable parsing limit */
+ int retval = 1 ;
+
+ PKT_TRACE("upk-threadinfo ",pkt) ;
+
+ /* info->threadid = 0 ; FIXME: implement zero_threadref */
+ info->active = 0 ;
+ info->display[0] = '\0' ;
+ info->shortname[0] = '\0' ;
+ info->more_display[0] = '\0' ;
+
+ /* Assume the characters indicating the packet type have been stripped */
+ pkt = unpack_int(pkt,&mask) ; /* arg mask */
+ pkt = unpack_threadid(pkt , &ref) ;
+
+ if (! threadmatch(&ref,expectedref))
+ { /* This is an answer to a different request */
+ output_string("FAIL Thread mismatch\n") ;
+ output_threadid("ref ",&ref) ;
+ output_threadid("expected ",expectedref) ;
+ return 0 ;
+ }
+ copy_threadref(&info->threadid,&ref) ;
+
+ /* Loop on tagged fields , try to bail if somthing goes wrong */
+ if (mask==0) output_string("OOPS NO MASK \n") ;
+
+ while ((pkt < limit) && mask && *pkt) /* packets are terminated with nulls */
+ {
+ pkt = unpack_int(pkt,&tag) ; /* tag */
+ pkt = unpack_byte(pkt,&length) ; /* length */
+ if (! (tag & mask)) /* tags out of synch with mask */
+ {
+ output_string("FAIL: threadinfo tag mismatch\n") ;
+ retval = 0 ;
+ break ;
+ }
+ if (tag == TAG_THREADID)
+ {
+ output_string("unpack THREADID\n") ;
+ if (length != 16)
+ {
+ output_string("FAIL: length of threadid is not 16\n") ;
+ retval = 0 ;
+ break ;
+ }
+ pkt = unpack_threadid(pkt,&ref) ;
+ mask = mask & ~ TAG_THREADID ;
+ continue ;
+ }
+ if (tag == TAG_EXISTS)
+ {
+ info->active = stub_unpack_int(pkt,length) ;
+ pkt += length ;
+ mask = mask & ~(TAG_EXISTS) ;
+ if (length > 8)
+ {
+ output_string("FAIL: 'exists' length too long\n") ;
+ retval = 0 ;
+ break ;
+ }
+ continue ;
+ }
+ if (tag == TAG_THREADNAME)
+ {
+ pkt = unpack_string(pkt,&info->shortname[0],length) ;
+ mask = mask & ~TAG_THREADNAME ;
+ continue ;
+ }
+ if (tag == TAG_DISPLAY)
+ {
+ pkt = unpack_string(pkt,&info->display[0],length) ;
+ mask = mask & ~TAG_DISPLAY ;
+ continue ;
+ }
+ if (tag == TAG_MOREDISPLAY)
+ {
+ pkt = unpack_string(pkt,&info->more_display[0],length) ;
+ mask = mask & ~TAG_MOREDISPLAY ;
+ continue ;
+ }
+ output_string("FAIL: unknown info tag\n") ;
+ break ; /* Not a tag we know about */
+ }
+ return retval ;
+} /* parse-thread_info_response */
+
+
+/* ---- REMOTE_PACK_CURRTHREAD_REQUEST ---------------------------- */
+/* This is a request to emit the T packet */
+
+/* FORMAT: 'q':8,'C' */
+
+char * remote_pack_currthread_request(char * pkt )
+{
+ *pkt++ = 'q' ;
+ *pkt++ = 'C' ;
+ *pkt = '\0' ;
+ return pkt ;
+} /* remote_pack_currthread_request */
+
+
+/* ------- REMOTE_UPK_CURTHREAD_RESPONSE ----------------------- */
+/* Unpack the interesting part of a T packet */
+
+
+int remote_upk_currthread_response(
+ char * pkt,
+ int *thr ) /* Parse a T packet */
+{
+ int retval = 0 ;
+ PKT_TRACE("upk-currthreadresp ",pkt) ;
+
+#if 0
+ {
+ static char threadtag[8] = "thread" ;
+ int retval = 0 ;
+ int i , found ;
+ char ch ;
+ int quickid ;
+
+ /* Unpack as a t packet */
+ while (((ch = *pkt++) != ':') /* scan for : thread */
+ && (ch != '\0')) /* stop at end of packet */
+
+ {
+ found = 0 ;
+ i = 0 ;
+ while ((ch = *pkt++) == threadtag[i++]) ;
+ if (i == 8) /* string match "thread" */
+ {
+ pkt = unpack_varlen_hex(pkt,&quickid) ;
+ retval = 1;
+ break ;
+ }
+ retval = 0 ;
+ }
+ }
+#else
+ pkt = unpack_threadid(pkt, thr) ;
+ retval = 1 ;
+#endif
+ return retval ;
+} /* remote_upk_currthread_response */
+
+
+/* -------- REMOTE_UPK-SIMPLE_ACK --------------------------------- */
+/* Decode a response which is eother "OK" or "Enn"
+ fillin error code, fillin pkfag-1== undef, 0==nak, 1 == ack ;
+ return advanced packet pointer */
+
+
+char * remote_upk_simple_ack(
+ char * buf,
+ int * pkflag,
+ int * errcode)
+{
+ int lclerr = 0 ;
+ char ch = *buf++ ;
+ int retval = -1 ; /* Undefined ACK , a protocol error */
+ if (ch == 'E') /* NAK */
+ {
+ buf = unpack_byte(buf,&lclerr) ;
+ retval = 0 ; /* transaction failed, explicitly */
+ }
+ else
+ if ((ch == 'O') && (*buf++ == 'K')) /* ACK */
+ retval = 1 ; /* transaction succeeded */
+ *pkflag = retval ;
+ *errcode = lclerr ;
+ return buf ;
+} /* remote-upk_simple_ack */
+
+
+/* -------- PACK_THREADALIVE_REQUEST ------------------------------- */
+
+char * pack_threadalive_request(
+ char * buf,
+ threadref * threadid)
+{
+ *buf++ = 'T' ;
+ buf = pack_threadid(buf,threadid) ;
+ *buf = '\0' ;
+ return buf ;
+} /* pack_threadalive_request */
+
+#endif /* GDB_MOCKUP */
+
+/* ---------------------------------------------------------------------- */
+/* UNIT_TESTS SUBSECTION */
+/* ---------------------------------------------------------------------- */
+
+
+#if UNIT_TEST
+extern void output_string(char * message) ;
+static char test_req[400] ;
+static char t_response[400] ;
+
+
+
+/* ----- DISPLAY_THREAD_INFO ---------------------------------------------- */
+/* Use local cygmon string output utiities */
+
+void display_thread_info(struct gdb_ext_thread_info * info)
+{
+
+ output_threadid("Threadid: ",&info->threadid) ;
+ /* short name */
+ output_string("Name: ") ; output_string(info->shortname) ; output_string("\n");
+ /* format display state */
+ output_string("State: ") ; output_string(info->display) ; output_string("\n") ;
+ /* additional data */
+ output_string("other: ");output_string(info->more_display);
+ output_string("\n\n");
+} /* display_thread_info */
+
+
+/* --- CURRTHREAD-TEST -------------------------------------------- */
+static int currthread_test(threadref * thread)
+{
+ int result ;
+ int threadid ;
+ output_string("TEST: currthread\n") ;
+ remote_pack_currthread_request(test_req) ;
+ stub_pkt_currthread(test_req+2,t_response,STUB_BUF_MAX) ;
+ result = remote_upk_currthread_response(t_response+2, &threadid) ;
+ if (result)
+ {
+ output_string("PASS getcurthread\n") ;
+ /* FIXME: print the thread */
+ }
+ else
+ output_string("FAIL getcurrthread\n") ;
+ return result ;
+} /* currthread_test */
+
+/* ------ SETTHREAD_TEST ------------------------------------------- */
+ /* use a known thread from previous test */
+
+static int setthread_test(threadref * thread)
+{
+ int result, errcode ;
+ output_string("TEST: setthread\n") ;
+
+ pack_setthread_request(test_req,'p',1,thread) ;
+ stub_pkt_changethread(test_req,t_response,STUB_BUF_MAX) ;
+ remote_upk_simple_ack(t_response,&result,&errcode) ;
+ switch (result)
+ {
+ case 0 :
+ output_string("FAIL setthread\n") ;
+ break ;
+ case 1 :
+ output_string("PASS setthread\n") ;
+ break ;
+ default :
+ output_string("FAIL setthread -unrecognized response\n") ;
+ break ;
+ }
+ return result ;
+} /* setthread_test */
+
+
+/* ------ THREADACTIVE_TEST ---------------------- */
+ /* use known thread */
+ /* pack threadactive packet */
+ /* process threadactive packet */
+ /* parse threadactive response */
+ /* check results */
+
+
+int threadactive_test(threadref * thread)
+{
+ int result ;
+ int errcode ;
+ output_string("TEST: threadactive\n") ;
+ pack_threadalive_request(test_req,thread) ;
+ stub_pkt_thread_alive(test_req+1,t_response,STUB_BUF_MAX);
+ remote_upk_simple_ack(t_response,&result,&errcode) ;
+ switch (result)
+ {
+ case 0 :
+ output_string("FAIL threadalive\n") ;
+ break ;
+ case 1 :
+ output_string("PASS threadalive\n") ;
+ break ;
+ default :
+ output_string("FAIL threadalive -unrecognized response\n") ;
+ break ;
+ }
+ return result ;
+} /* threadactive_test */
+
+/* ------ REMOTE_GET_THREADINFO -------------------------------------- */
+int remote_get_threadinfo(
+ threadref * threadid,
+ int fieldset , /* TAG mask */
+ struct gdb_ext_thread_info * info
+ )
+{
+ int result ;
+ pack_threadinfo_request(test_req,fieldset,threadid) ;
+ stub_pkt_getthreadinfo(test_req+2,t_response,STUB_BUF_MAX) ;
+ result = remote_upk_thread_info_response(t_response+2,threadid,info) ;
+ return result ;
+} /* remote_get-thrreadinfo */
+
+
+static struct gdb_ext_thread_info test_info ;
+
+static int get_and_display_threadinfo(threadref * thread)
+{
+ int mode ;
+ int result ;
+ /* output_string("TEST: get and display threadinfo\n") ; */
+
+ mode = TAG_THREADID | TAG_EXISTS | TAG_THREADNAME
+ | TAG_MOREDISPLAY | TAG_DISPLAY ;
+ result = remote_get_threadinfo(thread,mode,&test_info) ;
+ if (result) display_thread_info(&test_info) ;
+#if 0 /* silent subtest */
+ if (result)
+ output_string("PASS: get_and_display threadinfo\n") ;
+ else
+ output_string("FAIL: get_and_display threadinfo\n") ;
+#endif
+ return result ;
+} /* get-and-display-threadinfo */
+
+
+
+/* ----- THREADLIST_TEST ------------------------------------------ */
+#define TESTLISTSIZE 16
+#define TLRSIZ 2
+static threadref test_threadlist[TESTLISTSIZE] ;
+
+static int threadlist_test(void)
+{
+ int done, i , result_count ;
+ int startflag = 1 ;
+ int result = 1 ;
+ int loopcount = 0 ;
+ static threadref nextthread ;
+ static threadref echo_nextthread ;
+
+ output_string("TEST: threadlist\n") ;
+
+ done = 0 ;
+ while (! done)
+ {
+ if (loopcount++ > 10)
+ {
+ result = 0 ;
+ output_string("FAIL: Threadlist test -infinite loop-\n") ;
+ break ;
+ }
+ pack_threadlist_request(test_req,startflag,TLRSIZ,&nextthread) ;
+ startflag = 0 ; /* clear for later iterations */
+ stub_pkt_getthreadlist(test_req+2,t_response,STUB_BUF_MAX);
+ result_count = parse_threadlist_response(t_response+2,
+ &echo_nextthread,
+ &test_threadlist[0],&done) ;
+ if (! threadmatch(&echo_nextthread,&nextthread))
+ {
+ output_string("FAIL: threadlist did not echo arg thread\n");
+ result = 0 ;
+ break ;
+ }
+ if (result_count <= 0)
+ {
+ if (done != 0)
+ { output_string("FAIL threadlist_test, failed to get list");
+ result = 0 ;
+ }
+ break ;
+ }
+ if (result_count > TLRSIZ)
+ {
+ output_string("FAIL: threadlist response longer than requested\n") ;
+ result = 0 ;
+ break ;
+ }
+ /* Setup to resume next batch of thread references , set nestthread */
+ copy_threadref(&nextthread,&test_threadlist[result_count-1]) ;
+ /* output_threadid("last-of-batch",&nextthread) ; */
+ i = 0 ;
+ while (result_count--)
+ {
+ if (0) /* two display alternatives */
+ output_threadid("truncatedisplay",&test_threadlist[i++]) ;
+ else
+ get_and_display_threadinfo(&test_threadlist[i++]) ;
+ }
+
+ }
+ if (!result)
+ output_string("FAIL: threadlist test\n") ;
+ else output_string("PASS: Threadlist test\n") ;
+ return result ;
+} /* threadlist_test */
+
+
+static threadref testthread ;
+
+
+int test_thread_support(void)
+{
+ int result = 1 ;
+ output_string("TESTING Thread support infrastructure\n") ;
+ stub_pack_Tpkt_threadid(test_req) ;
+ PKT_TRACE("packing the threadid -> ",test_req) ;
+ result &= currthread_test(&testthread) ;
+ result &= get_and_display_threadinfo(&testthread) ;
+ result &= threadlist_test() ;
+ result &= setthread_test(&testthread) ;
+ if (result)
+ output_string("PASS: UNITTEST Thread support\n") ;
+ else
+ output_string("FAIL: UNITTEST Thread support\n") ;
+ return result ;
+} /* test-thread_support */
+#endif /* UNIT_TEST */
+
+// #ifdef __ECOS__
+#endif // ifdef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT...
+// #endif // __ECOS__
diff --git a/ecos/packages/hal/common/current/src/thread-pkts.h b/ecos/packages/hal/common/current/src/thread-pkts.h
new file mode 100644
index 0000000..fbd6076
--- /dev/null
+++ b/ecos/packages/hal/common/current/src/thread-pkts.h
@@ -0,0 +1,105 @@
+//========================================================================
+//
+// thread-pkts.h
+//
+// Optional packet processing for thread aware debugging.
+//
+//========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): Red Hat, nickg
+// Contributors: Red Hat, nickg
+// Date: 1998-08-25
+// Purpose:
+// Description: Optional packet processing for thread aware debugging.
+// Externs as called by central packet switch routine
+// Usage:
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================
+
+
+/* The DEBUG_THREADS flag is usually set in board.h */
+
+#if DEBUG_THREADS /* activate this in board.h */
+
+/* export the thread id's sent by gdb: */
+extern int _gdb_cont_thread, _gdb_general_thread ;
+
+extern char * stub_pack_Tpkt_threadid(char * pkt) ;
+
+extern long stub_get_currthread(void) ;
+extern int stub_lock_scheduler(int lock, int kind, long id) ;
+
+extern void stub_pkt_changethread(char * inbuf,
+ char * outbuf,
+ int bufmax) ;
+
+
+extern void stub_pkt_getthreadlist(char * inbuf,
+ char * outbuf,
+ int bufmax) ;
+
+
+extern void stub_pkt_getthreadinfo(
+ char * inbuf,
+ char * outbuf,
+ int bufmax) ;
+
+extern void stub_pkt_thread_alive(
+ char * inbuf,
+ char * outbuf,
+ int bufmax) ;
+
+extern void stub_pkt_currthread(
+ char * inbuf,
+ char * outbuf,
+ int bufmax) ;
+
+#define STUB_PKT_GETTHREADLIST(A,B,C) { stub_pkt_getthreadlist(A,B,C); }
+#define STUB_PKT_GETTHREADINFO(A,B,C) { stub_pkt_getthreadinfo(A,B,C); }
+#define STUB_PKT_CHANGETHREAD(A,B,C) { stub_pkt_changethread(A,B,C); }
+#define STUB_PKT_THREAD_ALIVE(A,B,C) { stub_pkt_thread_alive(A,B,C); }
+#define STUB_PKT_CURRTHREAD(A,B,C) { stub_pkt_currthread(A,B,C); }
+#define PACK_THREAD_ID(PTR) { PTR = stub_pack_Tpkt_threadid (PTR); }
+#else
+#define STUB_PKT_GETTHREADLIST(A,B,C) {}
+#define STUB_PKT_GETTHREADINFO(A,B,C) {}
+#define STUB_PKT_CHANGETHREAD(A,B,C) {}
+#define STUB_PKT_THREAD_ALIVE(A,B,C) {}
+#define STUB_PKT_CURRTHREAD(A,B,C) {}
+#define PACK_THREAD_ID(PTR) {}
+#endif
diff --git a/ecos/packages/hal/common/current/tests/basic.c b/ecos/packages/hal/common/current/tests/basic.c
new file mode 100644
index 0000000..a229a0f
--- /dev/null
+++ b/ecos/packages/hal/common/current/tests/basic.c
@@ -0,0 +1,109 @@
+//=================================================================
+//
+// basic.c
+//
+// HAL basic functions test
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): gthomas
+// Contributors: gthomas
+// Date: 2001-10-24
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/testcase.h> // test case macros
+#include <cyg/infra/diag.h> // diag_printf
+#include <cyg/infra/cyg_ass.h> // assertions
+
+#include <cyg/hal/hal_arch.h> // context macros
+
+// -------------------------------------------------------------------------
+
+#define BITS(t) (sizeof(t)*8)
+
+void
+entry(void)
+{
+ int res;
+ int i, mask, ndx;
+ hal_jmp_buf jmpbuf;
+
+ res = 1;
+
+ // Check HAL_MSBIT_NDEX() functions
+ mask = 1; // One bits set
+ for (i = 0; i < BITS(int); i++) {
+ HAL_MSBIT_INDEX(ndx, mask);
+ res &= (ndx == i);
+ HAL_LSBIT_INDEX(ndx, mask);
+ res &= (ndx == i);
+ mask <<= 1;
+ }
+
+ mask = 3; // Two bits set
+ for (i = 0; i < BITS(int)-1; i++) {
+ HAL_MSBIT_INDEX(ndx, mask);
+ res &= (ndx == (i+1));
+ HAL_LSBIT_INDEX(ndx, mask);
+ res &= (ndx == i);
+ mask <<= 1;
+ }
+ CYG_TEST_PASS_FAIL(res, "HAL_xSBIT_INDEX() basic functions");
+
+ res = 0;
+ if (hal_setjmp(jmpbuf)) {
+ res = 1;
+ } else {
+ hal_longjmp(jmpbuf, 1);
+ }
+ CYG_TEST_PASS_FAIL(res, "hal_setjmp()/hal_longjmp() basic functions");
+
+ CYG_TEST_FINISH("HAL basic functions test");
+}
+
+// -------------------------------------------------------------------------
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+
+ entry();
+}
+
+// -------------------------------------------------------------------------
+// EOF basic.c
diff --git a/ecos/packages/hal/common/current/tests/cache.c b/ecos/packages/hal/common/current/tests/cache.c
new file mode 100644
index 0000000..1fd4b66
--- /dev/null
+++ b/ecos/packages/hal/common/current/tests/cache.c
@@ -0,0 +1,240 @@
+/*=================================================================
+//
+// cache.c
+//
+// HAL Cache timing test
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): dsm
+// Contributors: dsm, nickg
+// Date: 1998-06-18
+//####DESCRIPTIONEND####
+*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/diag.h>
+
+#if defined(HAL_DCACHE_SIZE) && HAL_DCACHE_SIZE != 0
+
+// -------------------------------------------------------------------------
+// If the HAL does not supply this, we supply our own version
+
+#ifndef HAL_DCACHE_PURGE_ALL
+
+#ifdef HAL_DCACHE_SYNC
+
+# define HAL_DCACHE_PURGE_ALL() HAL_DCACHE_SYNC()
+
+#else
+
+static cyg_uint8 dca[HAL_DCACHE_SIZE + HAL_DCACHE_LINE_SIZE*2];
+
+#define HAL_DCACHE_PURGE_ALL() \
+CYG_MACRO_START \
+ volatile cyg_uint8 *addr = &dca[HAL_DCACHE_LINE_SIZE]; \
+ volatile cyg_uint8 tmp = 0; \
+ int i; \
+ for( i = 0; i < HAL_DCACHE_SIZE; i += HAL_DCACHE_LINE_SIZE ) \
+ { \
+ tmp = addr[i]; \
+ } \
+CYG_MACRO_END
+
+#endif // HAL_DCACHE_SYNC
+
+#endif // HAL_DCACHE_PURGE_ALL
+
+// -------------------------------------------------------------------------
+
+#ifndef MAX_STRIDE
+#define MAX_STRIDE 64
+#endif
+
+volatile char m[(HAL_DCACHE_SIZE/HAL_DCACHE_LINE_SIZE)*MAX_STRIDE];
+
+// -------------------------------------------------------------------------
+
+static void time0(register cyg_uint32 stride)
+{
+ register cyg_uint32 j,k;
+ register char c CYGBLD_ATTRIB_UNUSED;
+
+ diag_printf("stride=%d\n", stride);
+
+ k = 0;
+ if ( cyg_test_is_simulator )
+ k = 3960;
+
+ for(; k<4000;k++) {
+ for(j=0; j<(HAL_DCACHE_SIZE/HAL_DCACHE_LINE_SIZE); j++) {
+ c=m[stride*j];
+ }
+ }
+}
+
+// -------------------------------------------------------------------------
+
+void time1(void)
+{
+ cyg_uint32 i;
+
+ for(i=1; i<=MAX_STRIDE; i+=i) {
+ time0(i);
+ }
+}
+
+// -------------------------------------------------------------------------
+// This test could be improved by counting number of passes possible
+// in a given number of ticks.
+
+static void entry0( void )
+{
+ register CYG_INTERRUPT_STATE oldints;
+
+#ifdef HAL_CACHE_UNIFIED
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL(); // rely on above definition
+ HAL_UCACHE_INVALIDATE_ALL();
+ HAL_UCACHE_DISABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Cache off");
+ time1();
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL(); // rely on above definition
+ HAL_UCACHE_INVALIDATE_ALL();
+ HAL_UCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Cache on");
+ time1();
+
+#else // HAL_CACHE_UNIFIED
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL();
+ HAL_ICACHE_INVALIDATE_ALL();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_ICACHE_DISABLE();
+ HAL_DCACHE_DISABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Dcache off Icache off");
+ time1();
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL();
+ HAL_ICACHE_INVALIDATE_ALL();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_ICACHE_DISABLE();
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Dcache on Icache off");
+ time1();
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL();
+ HAL_ICACHE_INVALIDATE_ALL();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_ICACHE_ENABLE();
+ HAL_DCACHE_DISABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Dcache off Icache on");
+ time1();
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL();
+ HAL_ICACHE_INVALIDATE_ALL();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_ICACHE_ENABLE();
+ HAL_DCACHE_ENABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Dcache on Icache on");
+ time1();
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+ HAL_DCACHE_PURGE_ALL();
+ HAL_ICACHE_INVALIDATE_ALL();
+ HAL_DCACHE_INVALIDATE_ALL();
+ HAL_ICACHE_DISABLE();
+ HAL_DCACHE_DISABLE();
+ HAL_RESTORE_INTERRUPTS(oldints);
+ CYG_TEST_INFO("Dcache off Icache off");
+ time1();
+
+#endif // HAL_CACHE_UNIFIED
+
+ CYG_TEST_PASS_FINISH("End of test");
+}
+
+// -------------------------------------------------------------------------
+
+void cache_main( void )
+{
+ CYG_TEST_INIT();
+
+ entry0();
+
+}
+
+// -------------------------------------------------------------------------
+
+externC void
+cyg_start( void )
+{
+ cache_main();
+}
+
+#else // HAL_DCACHE_SIZE
+#define N_A_MSG "No cache"
+#endif // HAL_DCACHE_SIZE
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG
+
+// -------------------------------------------------------------------------
+/* EOF cache.c */
diff --git a/ecos/packages/hal/common/current/tests/context.c b/ecos/packages/hal/common/current/tests/context.c
new file mode 100644
index 0000000..4e96dd0
--- /dev/null
+++ b/ecos/packages/hal/common/current/tests/context.c
@@ -0,0 +1,120 @@
+/*=================================================================
+//
+// context.c
+//
+// HAL Thread context handling test
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 1998-10-07
+//####DESCRIPTIONEND####
+*/
+
+#include <pkgconf/hal.h>
+
+#include <pkgconf/infra.h>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/infra/cyg_trac.h>
+#include <cyg/hal/hal_arch.h>
+
+#define CYG_TRACE_USER_BOOL 1
+
+// -------------------------------------------------------------------------
+
+#define THREADS 4
+#define STACKSIZE (2*1024)
+
+char stack[THREADS][STACKSIZE];
+
+CYG_ADDRWORD sp[THREADS];
+
+cyg_count32 switches = 0;
+
+// -------------------------------------------------------------------------
+
+void entry0( CYG_ADDRWORD arg )
+{
+ CYG_TRACE1B("Thread %d started\n", arg );
+
+ while( switches < 1000 )
+ {
+ HAL_THREAD_SWITCH_CONTEXT( &sp[arg], &sp[(arg+1) % THREADS] );
+
+ CYG_TRACE1B("Thread %d resumed\n", arg );
+
+ switches++;
+ }
+
+ CYG_TEST_PASS_FINISH("HAL Context test");
+
+}
+
+// -------------------------------------------------------------------------
+
+void context_main(void)
+{
+ int i;
+
+ CYG_TEST_INIT();
+
+ // Init all thread contexts:
+
+ for( i = 0 ; i < THREADS; i++ )
+ {
+ sp[i] = (CYG_ADDRWORD)stack[i]+STACKSIZE;
+
+ HAL_THREAD_INIT_CONTEXT( sp[i], i, entry0, i*0x01010000 );
+ }
+
+ // Load the first thread.
+
+ HAL_THREAD_LOAD_CONTEXT( &sp[0] );
+}
+
+// -------------------------------------------------------------------------
+
+externC void
+cyg_start( void )
+{
+ context_main();
+}
+
+// -------------------------------------------------------------------------
+/* EOF context.c */
diff --git a/ecos/packages/hal/common/current/tests/cpp1.c b/ecos/packages/hal/common/current/tests/cpp1.c
new file mode 100644
index 0000000..9c5eaa3
--- /dev/null
+++ b/ecos/packages/hal/common/current/tests/cpp1.c
@@ -0,0 +1,108 @@
+/*=================================================================
+//
+// cpp1.c
+//
+// cpp arithmetic bug regression test
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): hmt
+// Contributors: hmt
+// Date: 2001-04-30
+//####DESCRIPTIONEND####
+*/
+
+#include <pkgconf/hal.h>
+
+#include <pkgconf/infra.h>
+
+#include <cyg/infra/testcase.h>
+
+// -----------------------------------------------------------------
+// This is smaller than 2048.
+// Unless the parser binds '+' too strongly because it is after a ket, so
+// it is mistaken for unary plus, when (4 * 20 + 2) * 4 * 20 is larger.
+#define CYGNUM_HAL_STACK_SIZE_MINIMUM ((4 * 20) + 2 * 4 * 20)
+
+#define CYGNUM_UITRON_STACK_SIZE (2048)
+
+#ifdef CYGNUM_HAL_STACK_SIZE_MINIMUM
+# ifdef CYGNUM_UITRON_STACK_SIZE
+# if CYGNUM_UITRON_STACK_SIZE < CYGNUM_HAL_STACK_SIZE_MINIMUM
+
+// then override the configured stack size
+# undef CYGNUM_UITRON_STACK_SIZE
+# define CYGNUM_UITRON_STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM
+
+# endif // CYGNUM_UITRON_STACK_SIZE < CYGNUM_HAL_STACK_SIZE_MINIMUM
+# endif // CYGNUM_UITRON_STACK_SIZE
+#endif // CYGNUM_HAL_STACK_SIZE_MINIMUM
+
+
+// This tests for the bug per se:
+int i = CYGNUM_UITRON_STACK_SIZE;
+
+// This tests the workaround independently of more complex context:
+#define MAX(_x_,_y_) ((_x_) > (_y_) ? (_x_) : (_y_))
+
+static char stack1[
+ MAX(
+ CYGNUM_HAL_STACK_SIZE_MINIMUM,
+ 2048)
+ ];
+
+// Better to report a fully-fledged failure and test the workaround than
+// fail early.
+#if 0
+# if CYGNUM_UITRON_STACK_SIZE != 2048
+# error FAIL: CPP '+' binding bug detected
+# endif
+#endif
+
+// -------------------------------------------------------------------------
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+ CYG_TEST_PASS("CPP '+' binding test compiled OK");
+ CYG_TEST_PASS_FAIL( 2048 == i, "initialized i should be 2048" );
+ CYG_TEST_PASS_FAIL( 2048 == sizeof( stack1 ),
+ "workaround: sizeof( stack1 ) should be 2048" );
+ CYG_TEST_EXIT("All done");
+}
+
+// -------------------------------------------------------------------------
+/* EOF cpp1.c */
diff --git a/ecos/packages/hal/common/current/tests/intr.c b/ecos/packages/hal/common/current/tests/intr.c
new file mode 100644
index 0000000..9cf695c
--- /dev/null
+++ b/ecos/packages/hal/common/current/tests/intr.c
@@ -0,0 +1,156 @@
+/*=================================================================
+//
+// intr.c
+//
+// HAL Interrupt API test
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): nickg
+// Contributors: nickg
+// Date: 1998-10-08
+//####DESCRIPTIONEND####
+*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+// Include HAL/Platform specifics
+#include CYGBLD_HAL_PLATFORM_H
+
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h> // Need to look for the RTC config.
+#endif
+
+// Fallback defaults (in case HAL didn't define these)
+#ifndef CYGNUM_HAL_RTC_NUMERATOR
+#define CYGNUM_HAL_RTC_NUMERATOR 1000000000
+#define CYGNUM_HAL_RTC_DENOMINATOR 100
+#define CYGNUM_HAL_RTC_PERIOD 9999
+#endif
+
+// -------------------------------------------------------------------------
+
+#define ISR_DATA 0xAAAA1234
+
+// -------------------------------------------------------------------------
+
+volatile cyg_count32 ticks = 0;
+volatile cyg_count32 dsr_ticks = 0;
+static cyg_interrupt intr;
+static cyg_handle_t intr_handle;
+
+// -------------------------------------------------------------------------
+
+cyg_uint32 isr( cyg_uint32 vector, CYG_ADDRWORD data )
+{
+ CYG_TEST_CHECK( ISR_DATA == data , "Bad data passed to ISR");
+ CYG_TEST_CHECK( CYGNUM_HAL_INTERRUPT_RTC == vector ,
+ "Bad vector passed to ISR");
+
+ HAL_CLOCK_RESET( vector, CYGNUM_HAL_RTC_PERIOD );
+
+ HAL_INTERRUPT_ACKNOWLEDGE( vector );
+
+ ticks++;
+
+ return CYG_ISR_CALL_DSR;
+}
+
+// -------------------------------------------------------------------------
+
+void dsr( cyg_uint32 vector, cyg_ucount32 count, CYG_ADDRWORD data )
+{
+ CYG_TEST_CHECK( ISR_DATA == data , "Bad data passed to DSR");
+ CYG_TEST_CHECK( CYGNUM_HAL_INTERRUPT_RTC == vector ,
+ "Bad vector passed to DSR");
+
+ dsr_ticks += count;
+}
+
+void intr_main( void )
+{
+ CYG_INTERRUPT_STATE oldints;
+
+ cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_RTC, 1,
+ ISR_DATA, isr, dsr, &intr_handle, &intr);
+ cyg_drv_interrupt_attach(intr_handle);
+ HAL_CLOCK_INITIALIZE( CYGNUM_HAL_RTC_PERIOD );
+ cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_RTC);
+
+ HAL_ENABLE_INTERRUPTS();
+
+ while( ticks < 10 )
+ {
+
+ }
+
+
+ CYG_TEST_CHECK( dsr_ticks == 10, "DSR not called sufficient times");
+
+ HAL_DISABLE_INTERRUPTS(oldints);
+
+ CYG_TEST_PASS_FINISH("HAL interrupt test");
+}
+
+
+// -------------------------------------------------------------------------
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+
+ // Attaching the ISR will not succeed if the kernel real-time
+ // clock has been configured in.
+#ifndef CYGVAR_KERNEL_COUNTERS_CLOCK
+
+ intr_main();
+
+#else
+
+ CYG_TEST_NA("Cannot override kernel real-time clock.");
+
+#endif
+}
+
+
+// -------------------------------------------------------------------------
+// EOF intr.c
diff --git a/ecos/packages/hal/common/current/tests/vaargs.c b/ecos/packages/hal/common/current/tests/vaargs.c
new file mode 100644
index 0000000..9bb621d
--- /dev/null
+++ b/ecos/packages/hal/common/current/tests/vaargs.c
@@ -0,0 +1,156 @@
+//=================================================================
+//
+// vaargs.c
+//
+// HAL variable argument calls test
+//
+//==========================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later
+// version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with eCos; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// As a special exception, if other files instantiate templates or use
+// macros or inline functions from this file, or you compile this file
+// and link it with other works to produce a work based on this file,
+// this file does not by itself cause the resulting work to be covered by
+// the GNU General Public License. However the source code for this file
+// must still be made available in accordance with section (3) of the GNU
+// General Public License v2.
+//
+// This exception does not invalidate any other reasons why a work based
+// on this file might be covered by the GNU General Public License.
+// -------------------------------------------
+// ####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): jskov
+// Contributors: jskov
+// Date: 2001-08-03
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/testcase.h> // test case macros
+#include <cyg/infra/diag.h> // diag_printf
+#include <cyg/infra/cyg_ass.h> // assertions
+
+#include <cyg/hal/hal_arch.h> // context macros
+
+#include <stdarg.h> // vaargs magic
+
+// -------------------------------------------------------------------------
+
+int
+function(int n, ...)
+{
+ va_list args;
+ int c = 11 * n;
+ int i = 1;
+ int res = 1;
+
+ CYG_ASSERT(n >= 0 && n < 8, "Invalid count argument");
+
+ va_start(args, n);
+
+ for (i = 1; i <= n; c++, i++) {
+ int v = va_arg(args, int);
+ if (v != c) {
+ diag_printf("FAIL:<Bad argument: index %d expected %d got %d>\n", i, c, v);
+ res = 0;
+ }
+ }
+
+ va_end(args);
+
+ return res;
+}
+
+int
+function_proxy(int n, va_list args)
+{
+ int c = 11 * n;
+ int i = 1;
+ int res = 1;
+
+ CYG_ASSERT(n >= 0 && n < 8, "Invalid count argument");
+
+ for (i = 1; i <= n; c++, i++) {
+ int v = va_arg(args, int);
+ if (v != c) {
+ diag_printf("FAIL:<Bad argument: index %d expected %d got %d>\n", i, c, v);
+ res = 0;
+ }
+ }
+
+ return res;
+}
+
+int
+proxy(int n, ...)
+{
+ int res;
+ va_list args;
+
+ va_start(args, n);
+ res = function_proxy(n, args);
+ va_end(args);
+
+ return res;
+}
+
+
+void
+entry(void)
+{
+ int res;
+
+ res = function(0);
+ res &= function(1, 11);
+ res &= function(2, 22, 23);
+ res &= function(3, 33, 34, 35);
+ res &= function(4, 44, 45, 46, 47);
+ res &= function(5, 55, 56, 57, 58, 59);
+ res &= function(6, 66, 67, 68, 69, 70, 71);
+ res &= function(7, 77, 78, 79, 80, 81, 82, 83);
+ CYG_TEST_PASS_FAIL(res, "Direct vaargs calls");
+
+ res = proxy(0);
+ res &= proxy(1, 11);
+ res &= proxy(2, 22, 23);
+ res &= proxy(3, 33, 34, 35);
+ res &= proxy(4, 44, 45, 46, 47);
+ res &= proxy(5, 55, 56, 57, 58, 59);
+ res &= proxy(6, 66, 67, 68, 69, 70, 71);
+ res &= proxy(7, 77, 78, 79, 80, 81, 82, 83);
+ CYG_TEST_PASS_FAIL(res, "Proxy vaargs calls");
+
+ CYG_TEST_FINISH("HAL vaargs test");
+}
+
+// -------------------------------------------------------------------------
+
+externC void
+cyg_start( void )
+{
+ CYG_TEST_INIT();
+
+ entry();
+}
+
+// -------------------------------------------------------------------------
+// EOF vaargs.c