summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/m68k/ods68302/startup
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1997-07-31 22:13:29 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1997-07-31 22:13:29 +0000
commit0074691a67f857c9b3f880fb581e0af1d5673337 (patch)
treef80fd23129ad62236ee4f64eeaf537f53bbaa0b8 /c/src/lib/libbsp/m68k/ods68302/startup
parentMerged very large and much appreciated patch from Chris Johns (diff)
downloadrtems-0074691a67f857c9b3f880fb581e0af1d5673337.tar.bz2
Merged very large and much appreciated patch from Chris Johns
<cjohns@plessey.com.au>. This patch includes the ods68302 bsp, the RTEMS++ class library, and the rtems++ test.
Diffstat (limited to 'c/src/lib/libbsp/m68k/ods68302/startup')
-rw-r--r--c/src/lib/libbsp/m68k/ods68302/startup/Makefile.in59
-rw-r--r--c/src/lib/libbsp/m68k/ods68302/startup/bspclean.c26
-rw-r--r--c/src/lib/libbsp/m68k/ods68302/startup/bspstart.c263
-rw-r--r--c/src/lib/libbsp/m68k/ods68302/startup/cpuboot.c133
-rw-r--r--c/src/lib/libbsp/m68k/ods68302/startup/crc.c88
-rw-r--r--c/src/lib/libbsp/m68k/ods68302/startup/debugger54
-rw-r--r--c/src/lib/libbsp/m68k/ods68302/startup/debugport.c163
-rw-r--r--c/src/lib/libbsp/m68k/ods68302/startup/gdb-hooks.c76
-rw-r--r--c/src/lib/libbsp/m68k/ods68302/startup/linkcmds55
-rw-r--r--c/src/lib/libbsp/m68k/ods68302/startup/m68302scc.c159
-rw-r--r--c/src/lib/libbsp/m68k/ods68302/startup/m68k-stub.c1084
-rw-r--r--c/src/lib/libbsp/m68k/ods68302/startup/memcheck.c33
-rw-r--r--c/src/lib/libbsp/m68k/ods68302/startup/rom56
-rw-r--r--c/src/lib/libbsp/m68k/ods68302/startup/trace.c175
14 files changed, 2424 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/Makefile.in b/c/src/lib/libbsp/m68k/ods68302/startup/Makefile.in
new file mode 100644
index 0000000000..6db40dbea9
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/ods68302/startup/Makefile.in
@@ -0,0 +1,59 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH=@srcdir@:@srcdir@/../../shared:@srcdir@/../../../shared
+
+PGM=${ARCH}/startup.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=crc debugport gdb-hooks m68302scc m68k-stub memcheck trace \
+ bspstart bspclean sbrk setvec
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+SRCS=$(C_FILES) $(H_FILES) $(srcdir)/rom $(srcdir)/debugger
+OBJS=$(C_O_FILES)
+
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+ $(make-rel)
+
+$(srcdir)/rom:
+
+$(srcdir)/debugger:
+
+all: ${ARCH} $(SRCS) $(PGM)
+ $(INSTALL) $(srcdir)/rom $(srcdir)/debugger ${PROJECT_RELEASE}/lib
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+
diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/bspclean.c b/c/src/lib/libbsp/m68k/ods68302/startup/bspclean.c
new file mode 100644
index 0000000000..90f64272a3
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/ods68302/startup/bspclean.c
@@ -0,0 +1,26 @@
+/* bsp_cleanup()
+ *
+ * This routine normally is part of start.s and usually returns
+ * control to a monitor.
+ *
+ * INPUT: NONE
+ *
+ * OUTPUT: NONE
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+
+void bsp_cleanup( void )
+{
+}
diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/bspstart.c b/c/src/lib/libbsp/m68k/ods68302/startup/bspstart.c
new file mode 100644
index 0000000000..c3c7bd538b
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/ods68302/startup/bspstart.c
@@ -0,0 +1,263 @@
+/* bsp_start()
+ *
+ * This routine starts the application. It includes application,
+ * board, and monitor specific initialization and configuration.
+ * The generic CPU dependent initialization has been performed
+ * before this routine is invoked.
+ *
+ * INPUT: NONE
+ *
+ * OUTPUT: NONE
+ *
+ * COPYRIGHT (c) 1989-1997.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may in
+ * the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <rtems/libio.h>
+
+#include <libcsupport.h>
+
+#include <string.h>
+#include <fcntl.h>
+
+#ifdef STACK_CHECKER_ON
+#include <stackchk.h>
+#endif
+
+/*
+ * The original table from the application and our copy of it with
+ * some changes.
+ */
+
+extern rtems_configuration_table Configuration;
+rtems_configuration_table BSP_Configuration;
+
+rtems_cpu_table Cpu_table;
+rtems_interrupt_level bsp_isr_level;
+
+char *rtems_progname;
+
+/* Initialize whatever libc we are using
+ * called from postdriver hook
+ */
+
+void bsp_libc_init()
+{
+ extern int end;
+ rtems_unsigned32 heap_start;
+
+ heap_start = (rtems_unsigned32) &end;
+ if (heap_start & (CPU_ALIGNMENT-1))
+ heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1);
+
+ /*
+ * The last parameter to RTEMS_Malloc_Initialize is the "chunk"
+ * size which a multiple of will be requested on each sbrk()
+ * call by malloc(). A value of 0 indicates that sbrk() should
+ * not be called to extend the heap.
+ */
+
+ RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0);
+
+ /*
+ * Init the RTEMS libio facility to provide UNIX-like system
+ * calls for use by newlib (ie: provide __rtems_open, __rtems_close, etc)
+ * Uses malloc() to get area for the iops, so must be after malloc init
+ */
+
+ rtems_libio_init();
+
+ /*
+ * Set up for the libc handling.
+ */
+
+ if (BSP_Configuration.ticks_per_timeslice > 0)
+ libc_init(1); /* reentrant if possible */
+ else
+ libc_init(0); /* non-reentrant */
+}
+
+/*
+ * Function: bsp_pretasking_hook
+ * Created: 95/03/10
+ *
+ * Description:
+ * BSP pretasking hook. Called just before drivers are initialized.
+ * Used to setup libc and install any BSP extensions.
+ *
+ * NOTES:
+ * Must not use libc (to do io) from here, since drivers are
+ * not yet initialized.
+ *
+ */
+
+void
+bsp_pretasking_hook(void)
+{
+ bsp_libc_init();
+
+#ifdef STACK_CHECKER_ON
+ /*
+ * Initialize the stack bounds checker
+ * We can either turn it on here or from the app.
+ */
+
+ Stack_check_Initialize();
+#endif
+
+#ifdef RTEMS_DEBUG
+ rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
+#endif
+}
+
+
+/*
+ * After drivers are setup, register some "filenames"
+ * and open stdin, stdout, stderr files
+ *
+ * Newlib will automatically associate the files with these
+ * (it hardcodes the numbers)
+ */
+
+void
+bsp_postdriver_hook(void)
+{
+ int stdin_fd, stdout_fd, stderr_fd;
+ int error_code;
+
+ error_code = 'S' << 24 | 'T' << 16;
+
+ if ((stdin_fd = __rtems_open("/dev/console", O_RDONLY, 0)) == -1)
+ rtems_fatal_error_occurred( error_code | 'D' << 8 | '0' );
+
+ if ((stdout_fd = __rtems_open("/dev/console", O_WRONLY, 0)) == -1)
+ rtems_fatal_error_occurred( error_code | 'D' << 8 | '1' );
+
+ if ((stderr_fd = __rtems_open("/dev/console", O_WRONLY, 0)) == -1)
+ rtems_fatal_error_occurred( error_code | 'D' << 8 | '2' );
+
+ if ((stdin_fd != 0) || (stdout_fd != 1) || (stderr_fd != 2))
+ rtems_fatal_error_occurred( error_code | 'I' << 8 | 'O' );
+}
+
+void bsp_start()
+{
+ /*
+ * Allocate the memory for the RTEMS Work Space. This can come from
+ * a variety of places: hard coded address, malloc'ed from outside
+ * RTEMS world (e.g. simulator or primitive memory manager), or (as
+ * typically done by stock BSPs) by subtracting the required amount
+ * of work space from the last physical address on the CPU board.
+ */
+#if 0
+ Cpu_table.interrupt_vector_table = (mc68000_isr *) 0/*&M68Kvec*/;
+#endif
+
+
+ /*
+ * Copy the Configuration Table .. so we can change it
+ */
+
+ BSP_Configuration = Configuration;
+
+ /*
+ * Add 1 region for the RTEMS Malloc
+ */
+
+ BSP_Configuration.RTEMS_api_configuration->maximum_regions++;
+
+ /*
+ * Add 1 extension for newlib libc
+ */
+
+#ifdef RTEMS_NEWLIB
+ BSP_Configuration.maximum_extensions++;
+#endif
+
+ /*
+ * Add another extension if using the stack checker
+ */
+
+#ifdef STACK_CHECKER_ON
+ BSP_Configuration.maximum_extensions++;
+#endif
+
+ /*
+ * Tell libio how many fd's we want and allow it to tweak config
+ */
+
+ rtems_libio_config(&BSP_Configuration, BSP_LIBIO_MAX_FDS);
+
+ /*
+ * Need to "allocate" the memory for the RTEMS Workspace and
+ * tell the RTEMS configuration where it is. This memory is
+ * not malloc'ed. It is just "pulled from the air".
+ */
+
+ BSP_Configuration.work_space_start = (void *)
+ (RAM_END - BSP_Configuration.work_space_size);
+
+ /*
+ * initialize the CPU table for this BSP
+ */
+
+ /*
+ * we do not use the pretasking_hook
+ */
+
+ Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
+
+ Cpu_table.predriver_hook = NULL;
+
+ Cpu_table.postdriver_hook = bsp_postdriver_hook;
+
+ Cpu_table.idle_task = NULL; /* do not override system IDLE task */
+
+ Cpu_table.do_zero_of_workspace = TRUE;
+
+ Cpu_table.interrupt_stack_size = 4096;
+
+ Cpu_table.extra_mpci_receive_server_stack = 0;
+
+ /*
+ * Don't forget the other CPU Table entries.
+ */
+
+ /*
+ * Start RTEMS
+ */
+
+ bsp_isr_level = rtems_initialize_executive_early( &BSP_Configuration, &Cpu_table );
+}
+
+int main(int argc, char **argv, char **environ)
+{
+ if ((argc > 0) && argv && argv[0])
+ rtems_progname = argv[0];
+ else
+ rtems_progname = "RTEMS";
+
+ rtems_initialize_executive_late( bsp_isr_level );
+
+ bsp_cleanup();
+
+ return 0;
+}
+
+void boot_bsp()
+{
+ /* the atexit hook will be before the static destructor list's entry
+ point */
+ bsp_start();
+
+ exit(main(0, 0, 0));
+}
+
diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/cpuboot.c b/c/src/lib/libbsp/m68k/ods68302/startup/cpuboot.c
new file mode 100644
index 0000000000..1a8f9bd2cf
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/ods68302/startup/cpuboot.c
@@ -0,0 +1,133 @@
+/*****************************************************************************/
+/*
+ Boot the CPU.
+
+ Occurs in 3 phases for a 68302.
+
+ Phase 1.
+
+ Called as soon as able after reset. The BAR has been programed, and
+ a small stack exists in the DPRAM. All interrupts are masked, and
+ the processor is running in supervisor mode. No other hardware or
+ chip selects are active.
+
+ This phase programs the chip select registers, the parallel ports
+ are set into default configurations, and basic registers cleared or
+ reset. The leds are programmed to show the end of phase 1.
+
+ Phase 2.
+
+ This is a piece of code which is copied to DPRAM and executed. It
+ should not do any more thann is currently present. The return to ROM
+ is managed by modifing the return address. Again leds show the status.
+
+ Phase 3.
+
+ This code executes with a valid C environment. That is the data
+ section has been intialised and the bss section set to 0. This phase
+ performs any special card initialisation and then calls boot card.
+
+ $Id$
+
+*/
+/*****************************************************************************/
+
+#include <bsp.h>
+#include <m68302.h>
+#include <debugport.h>
+#include <crc.h>
+
+/*
+ Open the address, reset all registers
+ */
+
+void boot_phase_1()
+{
+ M302_SCR = SCR_DEFAULT;
+
+ WRITE_OR(CSEL_ROM, ROM_SIZE, ROM_WAIT_STATES, OR_MASK_RW, OR_MASK_FC);
+ WRITE_BR(CSEL_ROM, RAM_BASE, BR_READ_ONLY, BR_FC_NULL, BR_ENABLED);
+ WRITE_OR(CSEL_RAM, RAM_SIZE, RAM_WAIT_STATES, OR_MASK_RW, OR_MASK_FC);
+ WRITE_BR(CSEL_RAM, ROM_BASE, BR_READ_WRITE, BR_FC_NULL, BR_ENABLED);
+
+#if defined(CSEL_1)
+ WRITE_OR(CSEL_1, CSEL_1_SIZE, CSEL_1_WAIT_STATES, OR_MASK_RW, OR_MASK_FC);
+ WRITE_BR(CSEL_1, CSEL_1_BASE, BR_READ_WRITE, BR_FC_NULL, BR_ENABLED);
+#endif
+
+#if defined(CSEL_2)
+ WRITE_OR(CSEL_2, CSEL_2_SIZE, CSEL_2_WAIT_STATES, OR_MASK_RW, OR_MASK_FC);
+ WRITE_BR(CSEL_2, CSEL_2_BASE, BR_READ_WRITE, BR_FC_NULL, BR_ENABLED);
+#endif
+
+ m302.reg.gimr = m302.reg.ipr = m302.reg.imr = m302.reg.isr = 0;
+
+ m302.reg.simode = 0;
+
+ m302.reg.pacnt = CARD_PA_CONFIGURATION;
+ m302.reg.paddr = CARD_PA_DEFAULT_DIRECTIONS;
+ m302.reg.padat = CARD_PA_DEFAULT_DATA;
+
+ m302.reg.pbcnt = CARD_PB_CONFIGURATION;
+ m302.reg.pbddr = CARD_PB_DEFAULT_DIRECTIONS;
+ m302.reg.pbdat = CARD_PB_DEFAULT_DATA;
+
+ m302.reg.wrr = WATCHDOG_TIMEOUT_PERIOD | WATCHDOG_ENABLE;
+
+#if defined(LED_CONTROL)
+ LED_CONTROL(LED_1_RED, LED_2_OFF, LED_3_OFF, LED_4_OFF,
+ LED_5_OFF, LED_6_OFF, LED_7_OFF, LED_8_OFF);
+#endif
+}
+
+/*
+ Swap the chip select mapping for ROM and RAM
+ */
+
+void boot_phase_2(void)
+{
+ rtems_unsigned32 stack;
+
+#if defined(LED_CONTROL)
+ LED_CONTROL(LED_1_RED, LED_2_RED, LED_3_OFF, LED_4_OFF,
+ LED_5_OFF, LED_6_OFF, LED_7_OFF, LED_8_OFF);
+#endif
+
+ WRITE_BR(CSEL_ROM, ROM_BASE, BR_READ_ONLY, BR_FC_NULL, BR_ENABLED);
+ WRITE_BR(CSEL_RAM, RAM_BASE, BR_READ_WRITE, BR_FC_NULL, BR_ENABLED);
+
+#if defined(LED_CONTROL)
+ LED_CONTROL(LED_1_GREEN, LED_2_RED, LED_3_OFF, LED_4_OFF,
+ LED_5_OFF, LED_6_OFF, LED_7_OFF, LED_8_OFF);
+#endif
+
+ /* seems to want 2, looked at assember code output */
+ *(&stack + 2) |= ROM_BASE;
+}
+
+/*
+ Any pre-main initialisation, the C environment is setup, how-ever C++
+ static constructors have not been called, and RTEMS is not initialised.
+ */
+
+void boot_bsp();
+void set_debug_traps();
+void breakpoint();
+
+void boot_phase_3(void)
+{
+ if (GDB_RUN_MONITOR())
+ {
+ set_debug_traps();
+ breakpoint();
+ }
+
+ debug_port_banner();
+
+ /* FIXME : add RAM and ROM checks */
+
+ /* boot the bsp, what ever this means */
+ boot_bsp();
+
+ WATCHDOG_TRIGGER();
+}
diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/crc.c b/c/src/lib/libbsp/m68k/ods68302/startup/crc.c
new file mode 100644
index 0000000000..b589ccd2ba
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/ods68302/startup/crc.c
@@ -0,0 +1,88 @@
+/*****************************************************************************/
+/*
+ $Id$
+
+ CRC 16 Calculation
+
+ This module calculates the CRC-16.
+
+ */
+/*****************************************************************************/
+
+#include "bsp.h"
+#include "m68302.h"
+#include "crc.h"
+
+ /* ----
+ C O N S T A N T S
+
+ */
+
+static const rtems_unsigned16 factor[] =
+ {
+ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
+ 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
+ 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
+ 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
+ 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
+ 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
+ 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
+ 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
+ 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
+ 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
+ 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
+ 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
+ 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
+ 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
+ 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
+ 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
+ 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
+ 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
+ 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
+ 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
+ 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
+ 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
+ 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
+ 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
+ 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
+ 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
+ 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
+ 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
+ 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
+ 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
+ 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
+ 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
+ };
+
+/*
+ MACRO : calculates a CRC byte wise
+ */
+
+#define NEW_CRC(byte, crc) factor[(byte) ^ ((crc) & 0xFF)] ^ (((crc) >> 8) & 0xFF)
+
+/* ----
+ CalcCRC
+
+ Calculates the CRC value of a block of memory
+*/
+
+rtems_unsigned16 calc_crc(void* vdata, /* pointer to memory block */
+ rtems_unsigned32 count) /* length of block in bytes */
+{
+ register rtems_unsigned8 *data = vdata;
+ register rtems_unsigned16 crc;
+ register rtems_unsigned32 byte;
+
+ /* initialise to either 0x0 or 0xffff depending on the
+ CRC implementation */
+
+ crc = 0;
+
+ for (byte = count; byte > 0; byte--)
+ {
+ WATCHDOG_TOGGLE();
+ crc = NEW_CRC(*data++, crc);
+ }
+
+ return crc;
+}
diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/debugger b/c/src/lib/libbsp/m68k/ods68302/startup/debugger
new file mode 100644
index 0000000000..6009868468
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/ods68302/startup/debugger
@@ -0,0 +1,54 @@
+/*
+ * $Id$
+ *
+ * MC68302 Linker command file
+ *
+ */
+
+SECTIONS
+{
+ .text . :
+ {
+ text_start = .;
+ *(.text)
+ etext = .;
+ . = ALIGN(4);
+ __CTOR_LIST__ = .;
+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
+ *(.ctors)
+ LONG(0)
+ __CTOR_END__ = .;
+ . = ALIGN(4);
+ __DTOR_LIST__ = .;
+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
+ *(.dtors)
+ LONG(0)
+ __DTOR_END__ = .;
+ }
+
+ .vtable (ADDR(.text) + SIZEOF(.text)) :
+ {
+ vtable_start = .;
+ *(.vtable)
+ evtable = .;
+ }
+ .data (ADDR(.vtable) + SIZEOF(.vtable)) :
+ {
+ data_start = .;
+ *(.data)
+ edata = .;
+ }
+ .bss (ADDR(.data) + SIZEOF(.data)) :
+ {
+ bss_start = .;
+ *(.bss)
+ *(COMMON)
+ end = . ;
+ _end = . ;
+ }
+}
+
+m302 = MC68302_BASE;
+_VBR = 0; /* location of the VBR table (in RAM) */
+
+ENTRY(start);
diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/debugport.c b/c/src/lib/libbsp/m68k/ods68302/startup/debugport.c
new file mode 100644
index 0000000000..b4616152a3
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/ods68302/startup/debugport.c
@@ -0,0 +1,163 @@
+/*****************************************************************************/
+/*
+ High Level Debug Port Functions
+
+ $Id$
+
+ */
+/*****************************************************************************/
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "debugport.h"
+#include "m68302scc.h"
+#include "bsp.h"
+
+static int initialised;
+
+void debug_port_initialise(void)
+{
+ scc_initialise(CONSOLE_PORT, CONSOLE_BAUD, FALSE);
+#if defined(DEBUG_PORT)
+ scc_initialise(DEBUG_PORT, DEBUG_BAUD, FALSE);
+#endif
+}
+
+unsigned char debug_port_status(const unsigned char status)
+{
+ if (!initialised)
+ {
+ initialised = 1;
+ debug_port_initialise();
+ }
+
+ return scc_status(CONSOLE_PORT, status);
+}
+
+unsigned char debug_port_in(void)
+{
+ if (!initialised)
+ {
+ initialised = 1;
+ debug_port_initialise();
+ }
+
+ return scc_in(CONSOLE_PORT);
+}
+
+void debug_port_out(const unsigned char character)
+{
+ if (!initialised)
+ {
+ initialised = 1;
+ debug_port_initialise();
+ }
+
+ scc_out(CONSOLE_PORT, character);
+}
+
+void debug_port_write(const char *buffer)
+{
+ while (*buffer != '\0')
+ {
+ debug_port_out(*buffer++);
+ }
+}
+
+void debug_port_write_buffer(const char *buffer, unsigned int size)
+{
+ unsigned int count;
+ for (count = 0; count < size; count++)
+ {
+ debug_port_out(buffer[count]);
+ }
+}
+
+void debug_port_write_hex_uint(const unsigned int value)
+{
+ unsigned int bits = sizeof(value) * 8;
+ unsigned char c;
+
+ do
+ {
+ bits -= 4;
+ c = (unsigned char) ((value >> bits) & 0x0F);
+ if (c < 10)
+ {
+ c += '0';
+ }
+ else
+ {
+ c += 'a' - 10;
+ }
+ debug_port_out((char) c);
+ }
+ while (bits);
+}
+
+void debug_port_write_hex_ulong(const unsigned long value)
+{
+ unsigned int bits = sizeof(value) * 8;
+ unsigned char c;
+
+ do
+ {
+ bits -= 4;
+ c = (unsigned char) ((value >> bits) & 0x0F);
+ if (c < 10)
+ {
+ c += '0';
+ }
+ else
+ {
+ c += 'a' - 10;
+ }
+ debug_port_out((char) c);
+ }
+ while (bits);
+}
+
+#define BUFFER_SIZE (256)
+static char buffer[BUFFER_SIZE];
+
+void debug_port_printf(const char *format, ...)
+{
+ va_list args;
+ int written;
+
+ /* gain access to the argument list */
+ va_start(args, format);
+
+ /* set the trap */
+ buffer[BUFFER_SIZE - 2] = '\xAA';
+ buffer[BUFFER_SIZE - 1] = '\x55';
+
+ /* format the string and send to stdout */
+ written = vsprintf(buffer, format, args);
+
+ /* try an trap format buffer overflows */
+ if ((buffer[BUFFER_SIZE - 2] != '\xAA') ||
+ (buffer[BUFFER_SIZE - 1] != '\x55'))
+ {
+ debug_port_write("debug port buffer overflow, halting...");
+ DISABLE_WATCHDOG();
+ while (1 == 1);
+ }
+
+ /* see if an error occurred, if not flush the output buffer */
+ if (written != -1)
+ {
+ debug_port_write_buffer(buffer, written);
+ }
+}
+
+void debug_port_banner(void)
+{
+#define CARD_LABEL "ods68302-" #VARIANT
+
+ debug_port_write("\n\n\r");
+ debug_port_write(_Copyright_Notice);
+ debug_port_write("\n\r " CARD_ID "\n\r");
+}
+
diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/gdb-hooks.c b/c/src/lib/libbsp/m68k/ods68302/startup/gdb-hooks.c
new file mode 100644
index 0000000000..64d220219f
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/ods68302/startup/gdb-hooks.c
@@ -0,0 +1,76 @@
+/*****************************************************************************/
+/*
+ $Id$
+
+ Hooks for GDB
+
+ */
+/*****************************************************************************/
+
+
+#include <bsp.h>
+#include <m68302.h>
+#include <m68302scc.h>
+
+static int initialised = 0;
+
+void putDebugChar(char ch)
+{
+ if (!initialised)
+ {
+ scc_initialise(DEBUG_PORT, DEBUG_BAUD, 0);
+ initialised = 1;
+ }
+
+ scc_out(DEBUG_PORT, ch);
+}
+
+char getDebugChar(void)
+{
+ if (!initialised)
+ {
+ scc_initialise(DEBUG_PORT, DEBUG_BAUD, 0);
+ initialised = 1;
+ }
+
+ while (!scc_status(DEBUG_PORT, 0));
+
+ return scc_in(DEBUG_PORT);
+}
+
+/*
+ * Need to create yet another jump table for gdb this time
+ */
+
+void (*exceptionHook)(unsigned int) = 0;
+
+typedef struct {
+ rtems_unsigned16 move_a7; /* move #FORMAT_ID,%a7@- */
+ rtems_unsigned16 format_id;
+ rtems_unsigned16 jmp; /* jmp _ISR_Handlers */
+ rtems_unsigned32 isr_handler;
+} GDB_HANDLER_ENTRY;
+
+#if !defined(M68K_MOVE_A7)
+#define M68K_MOVE_A7 0x3F3C
+#endif
+
+#if !defined(M68K_JMP)
+#define M68K_JMP 0x4EF9
+#endif
+
+/* points to jsr-exception-table in targets wo/ VBR register */
+static GDB_HANDLER_ENTRY gdb_jump_table[256];
+
+void exceptionHandler(unsigned int vector, void *handler)
+{
+ rtems_unsigned32 *interrupt_table = 0;
+
+ gdb_jump_table[vector].move_a7 = M68K_MOVE_A7;
+ gdb_jump_table[vector].format_id = vector;
+ gdb_jump_table[vector].jmp = M68K_JMP;
+ gdb_jump_table[vector].isr_handler = (rtems_unsigned32) handler;
+
+ interrupt_table[vector] = (rtems_unsigned32) &gdb_jump_table[vector];
+}
+
diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/linkcmds b/c/src/lib/libbsp/m68k/ods68302/startup/linkcmds
new file mode 100644
index 0000000000..225cc92f26
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/ods68302/startup/linkcmds
@@ -0,0 +1,55 @@
+/*
+ * $Id$
+ *
+ * MC68302 Linker command file
+ *
+ */
+
+SECTIONS
+{
+ .text . :
+ {
+ text_start = .;
+ *(.text)
+ etext = .;
+ . = ALIGN(4);
+ __CTOR_LIST__ = .;
+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
+ *(.ctors)
+ LONG(0)
+ __CTOR_END__ = .;
+ . = ALIGN(4);
+ __DTOR_LIST__ = .;
+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
+ *(.dtors)
+ LONG(0)
+ __DTOR_END__ = .;
+ }
+
+ .vtable 0 :
+ {
+ vtable_start = .;
+ *(.vtable)
+ evtable = .;
+ }
+
+ .data (ADDR(.vtable) + SIZEOF(.vtable)) :
+ AT (ADDR(.text) + SIZEOF(.text))
+ {
+ data_start = .;
+ *(.data)
+ edata = .;
+ }
+ .bss (ADDR(.data) + SIZEOF(.data)) :
+ {
+ bss_start = .;
+ *(.bss)
+ *(COMMON)
+ end = . ;
+ _end = . ;
+ }
+}
+
+m302 = MC68302_BASE;
+_VBR = ADDR(.vtable); /* location of the VBR table (in RAM) */
+
diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/m68302scc.c b/c/src/lib/libbsp/m68k/ods68302/startup/m68302scc.c
new file mode 100644
index 0000000000..77d7867a21
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/ods68302/startup/m68302scc.c
@@ -0,0 +1,159 @@
+/*****************************************************************************/
+/*
+ $Id$
+
+ M68302 SCC Polled Driver
+
+ */
+/*****************************************************************************/
+
+
+#include <bsp.h>
+#include <m68302.h>
+#include <m68302scc.h>
+
+#define M68302_SCC_COUNT (3)
+
+static volatile m302_SCC_t *scc[M68302_SCC_COUNT] = { 0, 0, 0 };
+static volatile m302_SCC_Registers_t *scc_reg[M68302_SCC_COUNT] = { 0, 0, 0 };
+static int scc_translate[M68302_SCC_COUNT] = { 0, 0, 0 };
+
+static const rtems_unsigned16 baud_clocks[] =
+{
+ (SYSTEM_CLOCK / ( 4800 * 16)),
+ (SYSTEM_CLOCK / ( 9600 * 16)),
+ (SYSTEM_CLOCK / ( 19200 * 16)),
+ (SYSTEM_CLOCK / ( 38400 * 16)),
+ (SYSTEM_CLOCK / ( 57600 * 16)),
+ (SYSTEM_CLOCK / (115700 * 16))
+};
+
+void scc_initialise(int channel, int baud, int translate)
+{
+ rtems_unsigned16 scon;
+
+ if (channel < M68302_SCC_COUNT)
+ {
+ scc[channel] = &m302.scc1 + channel;
+ scc_reg[channel] = &m302.reg.scc[channel];
+ scc_translate[channel] = translate;
+
+ scon = (baud_clocks[baud] & 0xF800) == 0 ? 0 : 1;
+ scon |= (((baud_clocks[baud] / (1 + scon * 3)) - 1) << 1) & 0x0FFE;
+
+ scc_reg[channel]->scon = scon;
+ scc_reg[channel]->scm = 0x0171;
+
+ scc[channel]->bd.tx[0].status = 0x2000;
+ scc[channel]->bd.tx[0].length = 0;
+ scc[channel]->bd.tx[0].buffer =
+ (rtems_unsigned8*) &(scc[channel]->bd.tx[1].buffer);
+
+ scc[channel]->bd.rx[0].status = 0x2000;
+ scc[channel]->bd.rx[0].length = 0;
+ scc[channel]->bd.rx[0].buffer =
+ (rtems_unsigned8*) &(scc[channel]->bd.rx[1].buffer);
+
+ scc[channel]->parm.rfcr = 0x50;
+ scc[channel]->parm.tfcr = 0x50;
+
+ scc[channel]->parm.mrblr = 0x0001;
+ scc[channel]->prot.uart.max_idl = 0x0004;
+ scc[channel]->prot.uart.brkcr = 1;
+ scc[channel]->prot.uart.parec = 0;
+ scc[channel]->prot.uart.frmec = 0;
+ scc[channel]->prot.uart.nosec = 0;
+ scc[channel]->prot.uart.brkec = 0;
+ scc[channel]->prot.uart.uaddr1 = 0;
+ scc[channel]->prot.uart.uaddr2 = 0;
+ scc[channel]->prot.uart.character[0] = 0x0003;
+ scc[channel]->prot.uart.character[1] = 0x8000;
+
+ scc_reg[channel]->scce = 0xFF;
+ scc_reg[channel]->sccm = 0x15;
+
+ scc_reg[channel]->scm = 0x17d;
+ }
+}
+
+unsigned char scc_status(int channel, unsigned char status)
+{
+ rtems_unsigned16 rx_status;
+
+ m302.reg.wcn = 0;
+
+ if ((channel < M68302_SCC_COUNT) && scc[channel])
+ {
+ rx_status = scc[channel]->bd.rx[0].status;
+
+ if ((rx_status & 0x8000) == 0)
+ {
+ if (rx_status & 0x003B)
+ {
+ return 2;
+ }
+ if (status == 0)
+ {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+unsigned char scc_in(int channel)
+{
+ m302.reg.wcn = 0;
+
+ if ((channel < M68302_SCC_COUNT) && scc[channel])
+ {
+ if ((scc[channel]->bd.rx[0].status & 0x8000) == 0)
+ {
+ unsigned char c;
+
+ c = *(scc[channel]->bd.rx[0].buffer);
+
+ scc[channel]->bd.rx[0].status = 0xa000;
+
+ return c;
+ }
+ }
+
+ return 0;
+}
+
+void scc_out(int channel, unsigned char character)
+{
+ if ((channel < M68302_SCC_COUNT) && scc[channel])
+ {
+ do
+ {
+ m302.reg.wcn = 0;
+ }
+ while (scc[channel]->bd.tx[0].status & 0x8000);
+
+ *(scc[channel]->bd.tx[0].buffer) = character;
+
+ scc[channel]->bd.tx[0].length = 1;
+ scc[channel]->bd.tx[0].status = 0xa000;
+
+ if (scc_translate[channel])
+ {
+ if (character == '\n')
+ {
+ scc_out(channel, '\r');
+ }
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/m68k-stub.c b/c/src/lib/libbsp/m68k/ods68302/startup/m68k-stub.c
new file mode 100644
index 0000000000..f9172f4c9f
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/ods68302/startup/m68k-stub.c
@@ -0,0 +1,1084 @@
+/****************************************************************************
+
+ 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 $
+ *
+ * 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 breakpoint instruction
+ * is hardwired to trap #1 because not to do so is a compatibility problem--
+ * there either should be a standard breakpoint instruction, or the protocol
+ * should be extended to provide some means to communicate which breakpoint
+ * instruction is in use (or have the stub insert the breakpoint).
+ *
+ * Some explanation is probably necessary to explain how exceptions are
+ * handled. When an exception is encountered the 68000 pushes the current
+ * program counter and status register onto the supervisor stack and then
+ * transfers execution to a location specified in it's vector table.
+ * The handlers for the exception vectors are hardwired to jmp to an address
+ * given by the relation: (exception - 256) * 6. These are decending
+ * addresses starting from -6, -12, -18, ... By allowing 6 bytes for
+ * each entry, a jsr, jmp, bsr, ... can be used to enter the exception
+ * handler. Using a jsr to handle an exception has an added benefit of
+ * allowing a single handler to service several exceptions and use the
+ * return address as the key differentiation. The vector number can be
+ * computed from the return address by [ exception = (addr + 1530) / 6 ].
+ * The sole purpose of the routine _catchException is to compute the
+ * exception number and push it on the stack in place of the return address.
+ * The external function exceptionHandler() is
+ * used to attach a specific handler to a specific m68k exception.
+ * For 68020 machines, the ability to have a return address around just
+ * so the vector can be determined is not necessary because the '020 pushes an
+ * extra word onto the stack containing the vector offset
+ *
+ * Because gdb will sometimes write to the stack area to execute function
+ * calls, this program cannot rely on using the supervisor stack so it
+ * uses it's own stack area reserved in the int array remcomStack.
+ *
+ *************
+ *
+ * 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)
+ *
+ * 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
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <setjmp.h>
+
+#include <bsp.h>
+#include <debugport.h>
+
+/************************************************************************
+ *
+ * external low-level support routines
+ */
+typedef void (*ExceptionHook)(int); /* pointer to function with int parm */
+typedef void (*Function)(void); /* pointer to a function */
+
+/* assign an exception handler */
+Function exceptionHandler(int vector, Function handler);
+extern ExceptionHook exceptionHook; /* hook variable for errors/exceptions */
+
+int putDebugChar(char ch);
+char getDebugChar(void);
+
+/************************/
+/* FORWARD DECLARATIONS */
+/************************/
+static int hex(char ch);
+static void getpacket(char *buffer);
+static void putpacket(char *buffer);
+static char* mem2hex(char *mem, char *buf, int count);
+static char* hex2mem(char *buf, char *mem, int count);
+static void handle_buserror(void);
+static int computeSignal(int exceptionVector);
+static int hexToInt(char **ptr, int *intValue);
+ void handle_exception(int exceptionVector);
+static void initializeRemcomErrorFrame(void);
+
+void set_debug_traps(void);
+void breakpoint(void);
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+#define BUFMAX 400
+
+static char initialized; /* boolean flag. != 0 means we've been initialized */
+
+int remote_debug;
+/* debug > 0 prints ill-formed commands in valid packets & checksum errors */
+
+static const char hexchars[]="0123456789abcdef";
+
+/* there are 180 bytes of registers on a 68020 w/68881 */
+/* many of the fpa registers are 12 byte (96 bit) registers */
+#define NUMREGBYTES 180
+enum regnames {D0,D1,D2,D3,D4,D5,D6,D7,
+ A0,A1,A2,A3,A4,A5,A6,A7,
+ PS,PC,
+ FP0,FP1,FP2,FP3,FP4,FP5,FP6,FP7,
+ FPCONTROL,FPSTATUS,FPIADDR
+ };
+
+
+/* We keep a whole frame cache here. "Why?", I hear you cry, "doesn't
+ GDB handle that sort of thing?" Well, yes, I believe the only
+ reason for this cache is to save and restore floating point state
+ (fsave/frestore). A cleaner way to do this would be to make the
+ fsave data part of the registers which GDB deals with like any
+ other registers. This should not be a performance problem if the
+ ability to read individual registers is added to the protocol. */
+
+typedef struct FrameStruct
+{
+ struct FrameStruct *previous;
+ int exceptionPC; /* pc value when this frame created */
+ int exceptionVector; /* cpu vector causing exception */
+ short frameSize; /* size of cpu frame in words */
+ short sr; /* for 68000, this not always sr */
+ int pc;
+ short format;
+ int fsaveHeader;
+ int morejunk[0]; /* exception frame, fp save... */
+} Frame;
+
+#define FRAMESIZE 500
+int gdbFrameStack[FRAMESIZE];
+static Frame *lastFrame;
+
+/*
+ * these should not be static cuz they can be used outside this module
+ */
+int registers[NUMREGBYTES/4];
+int superStack;
+
+#define STACKSIZE 10000
+int remcomStack[STACKSIZE/sizeof(int)];
+static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
+
+/*
+ * In many cases, the system will want to continue exception processing
+ * when a continue command is given.
+ * oldExceptionHook is a function to invoke in this case.
+ */
+
+static ExceptionHook oldExceptionHook;
+
+#if defined(__mc68020__)
+/* the size of the exception stack on the 68020 varies with the type of
+ * exception. The following table is the number of WORDS used
+ * for each exception format.
+ */
+const short exceptionSize[] = { 4,4,6,4,4,4,4,4,29,10,16,46,12,4,4,4 };
+#endif
+
+#if defined(__mc68332__)
+static const short exceptionSize[] = { 4,4,6,4,4,4,4,4,4,4,4,4,16,4,4,4 };
+#endif
+
+/************* jump buffer used for setjmp/longjmp **************************/
+jmp_buf remcomEnv;
+
+/*************************** ASSEMBLY CODE MACROS *************************/
+/* */
+
+#if defined(__HAVE_68881__)
+
+/* do an fsave, then remember the address to begin a restore from */
+#define SAVE_FP_REGS() \
+ asm(" fsave %a0@-"); \
+ asm(" fmovemx %fp0-%fp7,registers+72"); \
+ asm(" fmoveml %fpcr/%fpsr/%fpi,registers+168");
+
+#define RESTORE_FP_REGS() \
+asm(" \n\
+ fmoveml registers+168,%fpcr/%fpsr/%fpi \n\
+ fmovemx registers+72,%fp0-%fp7 \n\
+ cmpl #-1,%a0@ | skip frestore flag set ? \n\
+ beq skip_frestore \n\
+ frestore %a0@+ \n\
+skip_frestore: \n\
+");
+
+#else
+
+#define SAVE_FP_REGS()
+#define RESTORE_FP_REGS()
+
+#endif /* __HAVE_68881__ */
+
+void return_to_super(void);
+void return_to_user(void);
+
+asm("
+ .text
+
+ .globl return_to_super
+ .align 4
+return_to_super:
+ movel registers+60,%sp /* get new stack pointer */
+ movel lastFrame,%a0 /* get last frame info */
+ bra return_to_any
+
+ .globl return_to_user
+ .align 4
+
+return_to_user:
+ movel registers+60,%a0 /* get usp */
+ movel %a0,%usp /* set usp */
+ movel superStack,%sp /* get original stack pointer */
+
+return_to_any:
+ movel lastFrame,%a0 /* get last frame info */
+ movel %a0@+,lastFrame /* link in previous frame */
+ addql #8,%a0 /* skip over pc, vector#*/
+ movew %a0@+,%d0 /* get # of words in cpu frame */
+ addw %d0,%a0 /* point to end of data */
+ addw %d0,%a0 /* point to end of data */
+ movel %a0,%a1
+#
+# copy the stack frame
+ subql #1,%d0
+
+copyUserLoop:
+ movew %a1@-,%sp@-
+ dbf %d0,copyUserLoop
+");
+ RESTORE_FP_REGS()
+asm("
+ moveml registers,%d0-%d7/%a0-%a6
+ rte /* pop and go! */
+");
+
+#define DISABLE_INTERRUPTS() asm(" oriw #0x0700,%sr");
+#define BREAKPOINT() asm(" trap #1");
+
+/* this function is called immediately when a level 7 interrupt occurs */
+/* if the previous interrupt level was 7 then we're already servicing */
+/* this interrupt and an rte is in order to return to the debugger. */
+/* For the 68000, the offset for sr is 6 due to the jsr return address */
+asm("
+ .text
+ .globl _debug_level7
+ .align 4
+
+_debug_level7:
+ movew %d0,%sp@-
+");
+
+#if defined(__mc68020__) || defined(__mc68332__)
+asm("
+ movew %sp@(2),%d0
+");
+#else
+asm("
+ movew %sp@(6),%d0
+");
+#endif
+asm("
+ andiw #0x700,%d0
+ cmpiw #0x700,%d0
+ beq _already7
+ movew %sp@+,%d0
+ bra _catchException
+_already7:
+ movew %sp@+,%d0
+");
+#if defined (__m68000__) && !defined(__mc68020__)
+asm("
+ lea %sp@(4),%sp"); /* pull off 68000 return address */
+#endif
+asm("
+ rte
+");
+
+extern void _catchException(void);
+
+#if defined(__mc68020__) || defined(__mc68332__)
+/* This function is called when a 68020 exception occurs. It saves
+ * all the cpu and fpcp regs in the _registers array, creates a frame on a
+ * linked list of frames which has the cpu and fpcp stack frames needed
+ * to properly restore the context of these processors, and invokes
+ * an exception handler (remcom_handler).
+ *
+ * stack on entry: stack on exit:
+ * N bytes of junk exception # MSWord
+ * Exception Format Word exception # MSWord
+ * Program counter LSWord
+ * Program counter MSWord
+ * Status Register
+ *
+ *
+ */
+asm("
+ .text
+
+ .globl _catchException
+ .align 4
+_catchException:
+");
+
+DISABLE_INTERRUPTS();
+
+asm("
+ moveml %d0-%d7/%a0-%a6,registers /* save registers */
+ movel lastFrame,%a0 /* last frame pointer */
+");
+SAVE_FP_REGS();
+asm("
+ lea registers,%a5 /* get address of registers */
+ movew %sp@,%d1 /* get status register */
+ movew %d1,%a5@(66) /* save sr */
+ movel %sp@(2),%a4 /* save pc in %a4 for later use */
+ movel %a4,%a5@(68) /* save pc in _regisers[] */
+
+#
+# figure out how many bytes in the stack frame
+#
+ movew %sp@(6),%d0 /* get '020 exception format */
+ movew %d0,%d2 /* make a copy of format word */
+ andiw #0xf000,%d0 /* mask off format type */
+ rolw #5,%d0 /* rotate into the low byte *2 */
+ lea exceptionSize,%a1
+ addw %d0,%a1 /* index into the table */
+ movew %a1@,%d0 /* get number of words in frame */
+ movew %d0,%d3 /* save it */
+ subw %d0,%a0 /* adjust save pointer */
+ subw %d0,%a0 /* adjust save pointer(bytes) */
+ movel %a0,%a1 /* copy save pointer */
+ subql #1,%d0 /* predecrement loop counter */
+#
+# copy the frame
+#
+saveFrameLoop:
+ movew %sp@+,%a1@+
+ dbf %d0,saveFrameLoop
+#
+# now that the stack has been clenaed,
+# save the %a7 in use at time of exception
+
+ movel %sp,superStack /* save supervisor %sp */
+ andiw #0x2000,%d1 /* were we in supervisor mode ? */
+ beq userMode
+ movel %a7,%a5@(60) /* save %a7 */
+ bra a7saveDone
+userMode:
+ movel %usp,%a1
+ movel %a1,%a5@(60) /* save user stack pointer */
+a7saveDone:
+
+#
+# save size of frame
+ movew %d3,%a0@-
+
+#
+# compute exception number
+ andl #0xfff,%d2 /* mask off vector offset */
+ lsrw #2,%d2 /* divide by 4 to get vect num */
+ movel %d2,%a0@- /* save it */
+#
+# save pc causing exception
+ movel %a4,%a0@-
+#
+# save old frame link and set the new value
+ movel lastFrame,%a1 /* last frame pointer */
+ movel %a1,%a0@- /* save pointer to prev frame */
+ movel %a0,lastFrame
+
+ movel %d2,%sp@- /* push exception num */
+ movel exceptionHook,%a0 /* get address of handler */
+ jbsr %a0@ /* and call it */
+ clrl %sp@ /* replace exception num parm with frame ptr */
+ jbsr _returnFromException /* jbsr, but never returns */
+
+");
+
+#else /* mc68000 */
+
+/* This function is called when an exception occurs. It translates the
+ * return address found on the stack into an exception vector # which
+ * is then handled by either handle_exception or a system handler.
+ * _catchException provides a front end for both.
+ *
+ * stack on entry: stack on exit:
+ * Program counter MSWord exception # MSWord
+ * Program counter LSWord exception # MSWord
+ * Status Register
+ * Return Address MSWord
+ * Return Address LSWord
+ */
+asm("
+ .text
+ .globl _catchException
+ .align 4
+_catchException:
+");
+DISABLE_INTERRUPTS();
+asm("
+ moveml %d0-%d7/%a0-%a6,registers /* save registers */
+ movel lastFrame,%a0 /* last frame pointer */
+");
+
+SAVE_FP_REGS();
+asm("
+ moveq.l #0,%d2
+ movew %sp@+,%d2
+ lea registers,%a5 /* get address of registers */
+
+ moveql #3,%d3 /* assume a three word frame */
+
+ cmpiw #3,%d2 /* bus error or address error ? */
+ bgt normal /* if >3 then normal error */
+ movel %sp@+,%a0@- /* copy error info to frame buff*/
+ movel %sp@+,%a0@- /* these are never used */
+ moveql #7,%d3 /* this is a 7 word frame */
+
+normal:
+ movew %sp@+,%d1 /* pop status register */
+ movel %sp@+,%a4 /* pop program counter */
+
+ cmpiw #33,%d2 /* trap #1, breakpoint ? */
+ bne not_breakpoint
+
+ subql #2,%a4 /* trap leaves the pc after the trap */
+
+not_breakpoint:
+ movew %d1,%a5@(66) /* save sr */
+ movel %a4,%a5@(68) /* save pc in _regisers[] */
+ movel %a4,%a0@- /* copy pc to frame buffer */
+ movew %d1,%a0@- /* copy sr to frame buffer */
+
+ movel %sp,superStack /* save supervisor %sp */
+
+ andiw #0x2000,%d1 /* were we in supervisor mode ? */
+ beq userMode
+ movel %a7,%a5@(60) /* save %a7 */
+ bra saveDone
+userMode:
+ movel %usp,%a1 /* save user stack pointer */
+ movel %a1,%a5@(60) /* save user stack pointer */
+saveDone:
+
+ movew %d3,%a0@- /* push frame size in words */
+ movel %d2,%a0@- /* push vector number */
+ movel %a4,%a0@- /* push exception pc */
+
+#
+# save old frame link and set the new value
+#
+ movel lastFrame,%a1 /* last frame pointer */
+ movel %a1,%a0@- /* save pointer to prev frame */
+ movel %a0,lastFrame
+
+ movel %d2,%sp@- /* push exception num */
+ movel exceptionHook,%a0 /* get address of handler */
+
+ jbsr %a0@ /* and call it */
+ clrl %sp@ /* replace exception num parm with frame ptr */
+ jbsr _returnFromException /* jbsr, but never returns */
+");
+#endif
+
+
+/*
+ * remcomHandler is a front end for handle_exception. It moves the
+ * stack pointer into an area reserved for debugger use in case the
+ * breakpoint happened in supervisor mode.
+ */
+asm("remcomHandler:");
+asm(" addl #4,%sp"); /* pop off return address */
+asm(" movel %sp@+,%d0"); /* get the exception number */
+asm(" movel stackPtr,%sp"); /* move to remcom stack area */
+asm(" movel %d0,%sp@-"); /* push exception onto stack */
+asm(" jbsr handle_exception"); /* this never returns */
+asm(" rts"); /* return */
+
+void _returnFromException(Frame *frame)
+{
+ /* if no passed in frame, use the last one */
+ if (! frame)
+ {
+ frame = lastFrame;
+ frame->frameSize = 4;
+ frame->format = 0;
+ frame->fsaveHeader = -1; /* restore regs, but we dont have fsave info*/
+ }
+
+#if defined(__m68000__) && !defined(__mc68020__)
+ /* a 68000 cannot use the internal info pushed onto a bus error
+ * or address error frame when doing an RTE so don't put this info
+ * onto the stack or the stack will creep every time this happens.
+ */
+ frame->frameSize=3;
+#endif
+
+ /* throw away any frames in the list after this frame */
+ lastFrame = frame;
+
+ frame->sr = registers[(int) PS];
+ frame->pc = registers[(int) PC];
+
+ if (registers[(int) PS] & 0x2000)
+ {
+ /* return to supervisor mode... */
+ return_to_super();
+ }
+ else
+ { /* return to user mode */
+ return_to_user();
+ }
+}
+
+int hex(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);
+}
+
+/* scan for the sequence $<data>#<checksum> */
+void getpacket(char *buffer)
+{
+ unsigned char checksum;
+ unsigned char xmitcsum;
+ int i;
+ int count;
+ char ch;
+
+ do {
+ /* wait around for the start character, ignore all other characters */
+ while ((ch = (getDebugChar() & 0x7f)) != '$');
+ checksum = 0;
+ xmitcsum = -1;
+
+ count = 0;
+
+ /* now, read until a # or end of buffer is found */
+ while (count < BUFMAX) {
+ ch = getDebugChar() & 0x7f;
+ if (ch == '#') break;
+ checksum = checksum + ch;
+ buffer[count] = ch;
+ count = count + 1;
+ }
+ buffer[count] = 0;
+
+ if (ch == '#') {
+ xmitcsum = hex(getDebugChar() & 0x7f) << 4;
+ xmitcsum += hex(getDebugChar() & 0x7f);
+ if ((remote_debug ) && (checksum != xmitcsum)) {
+ debug_port_printf ("bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n",
+ checksum,xmitcsum,buffer);
+ }
+
+ if (checksum != xmitcsum) putDebugChar('-'); /* failed checksum */
+ else {
+ putDebugChar('+'); /* successful transfer */
+ /* if a sequence char is present, reply the sequence ID */
+ if (buffer[2] == ':') {
+ putDebugChar( buffer[0] );
+ putDebugChar( buffer[1] );
+ /* remove sequence chars from buffer */
+ count = strlen(buffer);
+ for (i=3; i <= count; i++) buffer[i-3] = buffer[i];
+ }
+ }
+ }
+ } while (checksum != xmitcsum);
+}
+
+/* send the packet in buffer. The host get's one chance to read it.
+ This routine does not wait for a positive acknowledge. */
+
+
+void
+putpacket(char *buffer)
+{
+ unsigned char checksum;
+ int count;
+ char ch;
+
+ /* $<packet info>#<checksum>. */
+ do {
+ putDebugChar('$');
+ checksum = 0;
+ count = 0;
+
+ while ((ch=buffer[count])) {
+ if (! putDebugChar(ch)) return;
+ checksum += ch;
+ count += 1;
+ }
+
+ putDebugChar('#');
+ putDebugChar(hexchars[checksum >> 4]);
+ putDebugChar(hexchars[checksum % 16]);
+
+ } while (1 == 0); /* (getDebugChar() != '+'); */
+
+}
+
+char remcomInBuffer[BUFMAX];
+char remcomOutBuffer[BUFMAX];
+static short error;
+
+/* convert the memory pointed to by mem into hex, placing result in buf */
+/* return a pointer to the last char put in buf (null) */
+char *mem2hex(char *mem, char *buf, int count)
+{
+ int i;
+ unsigned char ch;
+
+ if (remote_debug)
+ debug_port_printf("mem=0x%x, count=0x%x\n", mem, count);
+
+ for (i=0;i<count;i++) {
+ ch = *mem++;
+ *buf++ = hexchars[ch >> 4];
+ *buf++ = hexchars[ch % 16];
+ }
+ *buf = 0;
+ return(buf);
+}
+
+/* convert 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 */
+char *hex2mem(char *buf, char *mem, int count)
+{
+ int i;
+ unsigned char ch;
+
+ if (remote_debug)
+ debug_port_printf("mem=0x%x, count=0x%x\n", mem, count);
+
+ for (i=0;i<count;i++) {
+ ch = hex(*buf++) << 4;
+ ch = ch + hex(*buf++);
+ *mem++ = ch;
+ }
+ return(mem);
+}
+
+/* a bus error has occurred, perform a longjmp
+ to return execution and allow handling of the error */
+
+void handle_buserror()
+{
+ longjmp(remcomEnv,1);
+}
+
+/* this function takes the 68000 exception number and attempts to
+ translate this number into a unix compatible signal value */
+int computeSignal(int exceptionVector)
+{
+ int sigval;
+ switch (exceptionVector) {
+ case 2 : sigval = 10; break; /* bus error */
+ case 3 : sigval = 10; break; /* address error */
+ case 4 : sigval = 4; break; /* illegal instruction */
+ case 5 : sigval = 8; break; /* zero divide */
+ case 6 : sigval = 8; break; /* chk instruction */
+ case 7 : sigval = 8; break; /* trapv instruction */
+ case 8 : sigval = 11; break; /* privilege violation */
+ case 9 : sigval = 5; break; /* trace trap */
+ case 10: sigval = 4; break; /* line 1010 emulator */
+ case 11: sigval = 4; break; /* line 1111 emulator */
+
+ /* Coprocessor protocol violation. Using a standard MMU or FPU
+ this cannot be triggered by software. Call it a SIGBUS. */
+ case 13: sigval = 10; break;
+
+ case 31: sigval = 2; break; /* interrupt */
+ case 33: sigval = 5; break; /* breakpoint */
+
+ /* This is a trap #8 instruction. Apparently it is someone's software
+ convention for some sort of SIGFPE condition. Whose? How many
+ people are being screwed by having this code the way it is?
+ Is there a clean solution? */
+ case 40: sigval = 8; break; /* floating point err */
+
+ case 48: sigval = 8; break; /* floating point err */
+ case 49: sigval = 8; break; /* floating point err */
+ case 50: sigval = 8; break; /* zero divide */
+ case 51: sigval = 8; break; /* underflow */
+ case 52: sigval = 8; break; /* operand error */
+ case 53: sigval = 8; break; /* overflow */
+ case 54: sigval = 8; break; /* NAN */
+ default:
+ sigval = 7; /* "software generated"*/
+ }
+ return (sigval);
+}
+
+/**********************************************/
+/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
+/* RETURN NUMBER OF CHARS PROCESSED */
+/**********************************************/
+int hexToInt(char **ptr, int *intValue)
+{
+ int numChars = 0;
+ int hexValue;
+
+ *intValue = 0;
+
+ while (**ptr)
+ {
+ hexValue = hex(**ptr);
+ if (hexValue >=0)
+ {
+ *intValue = (*intValue <<4) | hexValue;
+ numChars ++;
+ }
+ else
+ break;
+
+ (*ptr)++;
+ }
+
+ return (numChars);
+}
+
+/*
+ * This function does all command procesing for interfacing to gdb.
+ */
+void handle_exception(int exceptionVector)
+{
+ int sigval;
+ int addr, length;
+ char * ptr;
+ int newPC;
+ Frame *frame;
+
+ if (remote_debug)
+ printf("vector=%d, sr=0x%x, pc=0x%x\n",
+ exceptionVector,
+ registers[ PS ],
+ registers[ PC ]);
+
+ /* reply to host that an exception has occurred */
+ sigval = computeSignal( exceptionVector );
+ remcomOutBuffer[0] = 'S';
+ remcomOutBuffer[1] = hexchars[sigval >> 4];
+ remcomOutBuffer[2] = hexchars[sigval % 16];
+ remcomOutBuffer[3] = 0;
+
+ putpacket(remcomOutBuffer);
+
+ while (1==1) {
+ error = 0;
+ remcomOutBuffer[0] = 0;
+ getpacket(remcomInBuffer);
+ switch (remcomInBuffer[0]) {
+ case '?' : remcomOutBuffer[0] = 'S';
+ remcomOutBuffer[1] = hexchars[sigval >> 4];
+ remcomOutBuffer[2] = hexchars[sigval % 16];
+ remcomOutBuffer[3] = 0;
+ break;
+ case 'd' :
+ remote_debug = !(remote_debug); /* toggle debug flag */
+ debug_port_printf("debug mode ");
+ if (remote_debug)
+ {
+ debug_port_printf("on\n");
+ }
+ else
+ {
+ debug_port_printf("off\n");
+ }
+ break;
+ case 'g' : /* return the value of the CPU registers */
+ mem2hex((char*) registers, remcomOutBuffer, NUMREGBYTES);
+ break;
+ case 'G' : /* set the value of the CPU registers - return OK */
+ hex2mem(&remcomInBuffer[1], (char*) registers, NUMREGBYTES);
+ strcpy(remcomOutBuffer,"OK");
+ break;
+
+ /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
+ case 'm' :
+ if (setjmp(remcomEnv) == 0)
+ {
+ exceptionHandler(2,handle_buserror);
+
+ /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
+ ptr = &remcomInBuffer[1];
+ if (hexToInt(&ptr,&addr))
+ if (*(ptr++) == ',')
+ if (hexToInt(&ptr,&length))
+ {
+ ptr = 0;
+ mem2hex((char*) addr, remcomOutBuffer, length);
+ }
+
+ if (ptr)
+ {
+ strcpy(remcomOutBuffer,"E01");
+ if (remote_debug)
+ printf("malformed read memory command: %s",remcomInBuffer);
+ }
+ }
+ else {
+ exceptionHandler(2,_catchException);
+ strcpy(remcomOutBuffer,"E03");
+ if (remote_debug)
+ printf("bus error");
+ }
+
+ /* restore handler for bus error */
+ exceptionHandler(2,_catchException);
+ break;
+
+ /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+ case 'M' :
+ if (setjmp(remcomEnv) == 0) {
+ exceptionHandler(2,handle_buserror);
+
+ /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
+ ptr = &remcomInBuffer[1];
+ if (hexToInt(&ptr,&addr))
+ if (*(ptr++) == ',')
+ if (hexToInt(&ptr,&length))
+ if (*(ptr++) == ':')
+ {
+ hex2mem(ptr, (char*) addr, length);
+ ptr = 0;
+ strcpy(remcomOutBuffer,"OK");
+ }
+ if (ptr)
+ {
+ strcpy(remcomOutBuffer,"E02");
+ if (remote_debug)
+ printf("malformed write memory command: %s",remcomInBuffer);
+ }
+ }
+ else {
+ exceptionHandler(2,_catchException);
+ strcpy(remcomOutBuffer,"E03");
+ if (remote_debug)
+ printf("bus error");
+ }
+
+ /* restore handler for bus error */
+ exceptionHandler(2,_catchException);
+ break;
+
+ /* cAA..AA Continue at address AA..AA(optional) */
+ /* sAA..AA Step one instruction from AA..AA(optional) */
+ case 'c' :
+ case 's' :
+ /* try to read optional parameter, pc unchanged if no parm */
+ ptr = &remcomInBuffer[1];
+ if (hexToInt(&ptr,&addr))
+ registers[ PC ] = addr;
+
+ newPC = registers[ PC];
+
+ /* clear the trace bit */
+ registers[ PS ] &= 0x7fff;
+
+ /* set the trace bit if we're stepping */
+ if (remcomInBuffer[0] == 's') registers[ PS ] |= 0x8000;
+
+ /*
+ * look for newPC in the linked list of exception frames.
+ * if it is found, use the old frame it. otherwise,
+ * fake up a dummy frame in returnFromException().
+ */
+ if (remote_debug) debug_port_printf("new pc = 0x%x\n",newPC);
+
+ frame = lastFrame;
+ while (frame)
+ {
+ if (remote_debug)
+ debug_port_printf("frame at 0x%x has pc=0x%x, except#=%d\n",
+ frame,frame->exceptionPC,
+ (unsigned int) frame->exceptionVector);
+ if (frame->exceptionPC == newPC) break; /* bingo! a match */
+ /*
+ * for a breakpoint instruction, the saved pc may
+ * be off by two due to re-executing the instruction
+ * replaced by the trap instruction. Check for this.
+ */
+ if ((frame->exceptionVector == 33) &&
+ (frame->exceptionPC == newPC)) break;
+ if (frame == frame->previous)
+ {
+ frame = 0; /* no match found */
+ break;
+ }
+ frame = frame->previous;
+ }
+
+ /*
+ * If we found a match for the PC AND we are not returning
+ * as a result of a breakpoint (33),
+ * trace exception (9), nmi (31), jmp to
+ * the old exception handler as if this code never ran.
+ */
+ if (frame)
+ {
+ if ((frame->exceptionVector != 9) &&
+ (frame->exceptionVector != 31) &&
+ (frame->exceptionVector != 33))
+ {
+ /*
+ * invoke the previous handler.
+ */
+ if (oldExceptionHook)
+ (*oldExceptionHook) (frame->exceptionVector);
+ newPC = registers[ PC ]; /* pc may have changed */
+ if (newPC != frame->exceptionPC)
+ {
+ if (remote_debug)
+ debug_port_printf("frame at 0x%x has pc=0x%x, except#=%d\n",
+ frame,frame->exceptionPC,
+ (unsigned int) frame->exceptionVector);
+ /* re-use the last frame, we're skipping it (longjump?)*/
+ frame = (Frame *) 0;
+ _returnFromException( frame ); /* this is a jump */
+ }
+ }
+ }
+
+ /* if we couldn't find a frame, create one */
+ if (frame == 0)
+ {
+ frame = lastFrame -1 ;
+
+ /* by using a bunch of print commands with breakpoints,
+ it's possible for the frame stack to creep down. If it creeps
+ too far, give up and reset it to the top. Normal use should
+ not see this happen.
+ */
+ if ((unsigned int) (frame-2) < (unsigned int) &gdbFrameStack)
+ {
+ initializeRemcomErrorFrame();
+ frame = lastFrame;
+ }
+ frame->previous = lastFrame;
+ lastFrame = frame;
+ frame = 0; /* null so _return... will properly initialize it */
+ }
+
+ _returnFromException( frame ); /* this is a jump */
+
+ break;
+
+ /* kill the program */
+ case 'k' :
+ /* reset the board */
+ WATCHDOG_TRIGGER();
+ while (1 == 1);
+ break;
+
+ } /* switch */
+
+ /* reply to the request */
+ putpacket(remcomOutBuffer);
+ }
+}
+
+
+void initializeRemcomErrorFrame()
+{
+ lastFrame = ((Frame *) &gdbFrameStack[FRAMESIZE-1]) - 1;
+ lastFrame->previous = lastFrame;
+}
+
+/* this function is used to set up exception handlers for tracing and
+ breakpoints */
+void set_debug_traps()
+{
+ extern void _debug_level7(void);
+ extern void remcomHandler(void);
+
+ int exception;
+
+ initializeRemcomErrorFrame();
+ stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
+
+ registers[ PC ] = 0x400;
+ registers[ PS ] = 0x2700;
+
+ for (exception = 2; exception <= 30; exception++)
+ exceptionHandler(exception,_catchException);
+
+ /* level 7 interrupt */
+ exceptionHandler(31,_debug_level7);
+
+ for (exception = 32; exception <= 47; exception++)
+ exceptionHandler(exception,_catchException);
+
+ /* exclude the unassigned, reserved vector locations */
+
+ for (exception = 64; exception <= 255; exception++)
+ exceptionHandler(exception,_catchException);
+
+ if (oldExceptionHook != (ExceptionHook) remcomHandler)
+ {
+ oldExceptionHook = exceptionHook;
+ exceptionHook = (ExceptionHook) remcomHandler;
+ }
+
+ initialized = 1;
+
+#if defined(UPDATE_DISPLAY)
+ UPDATE_DISPLAY("gdb ");
+#endif
+}
+
+/* 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()
+{
+ if (initialized) BREAKPOINT();
+}
diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/memcheck.c b/c/src/lib/libbsp/m68k/ods68302/startup/memcheck.c
new file mode 100644
index 0000000000..4341a88e37
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/ods68302/startup/memcheck.c
@@ -0,0 +1,33 @@
+/*****************************************************************************/
+/*
+ $Id$
+
+ Memory check routines.
+
+ The production test is a destrucive full test.
+ The boot test is a minimal, non-desctructive.
+ The partial memory test performs a scetion at a time, and gets
+ called in a repeated fashion to completely check the memory,
+
+ */
+/*****************************************************************************/
+
+void
+production_memory_test()
+{
+}
+
+void
+boot_memory_test()
+{
+}
+
+void
+reset_partial_memory_test()
+{
+}
+
+void
+partial_memory_test()
+{
+}
diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/rom b/c/src/lib/libbsp/m68k/ods68302/startup/rom
new file mode 100644
index 0000000000..a8533e08b0
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/ods68302/startup/rom
@@ -0,0 +1,56 @@
+/*
+ * $Id$
+ *
+ * MC68302 Linker command file
+ *
+ */
+
+SECTIONS
+{
+ .text . :
+ {
+ text_start = .;
+ *(.text)
+ etext = .;
+ . = ALIGN(4);
+ __CTOR_LIST__ = .;
+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
+ *(.ctors)
+ LONG(0)
+ __CTOR_END__ = .;
+ . = ALIGN(4);
+ __DTOR_LIST__ = .;
+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
+ *(.dtors)
+ LONG(0)
+ __DTOR_END__ = .;
+ }
+
+ .vtable 0 :
+ {
+ vtable_start = .;
+ *(.vtable)
+ evtable = .;
+ }
+
+ .data (ADDR(.vtable) + SIZEOF(.vtable)) :
+ AT (ADDR(.text) + SIZEOF(.text))
+ {
+ data_start = .;
+ *(.data)
+ edata = .;
+ }
+ .bss (ADDR(.data) + SIZEOF(.data)) :
+ {
+ bss_start = .;
+ *(.bss)
+ *(COMMON)
+ end = . ;
+ _end = . ;
+ }
+}
+
+m302 = MC68302_BASE;
+_VBR = 0; /* location of the VBR table (in RAM) */
+
+
diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/trace.c b/c/src/lib/libbsp/m68k/ods68302/startup/trace.c
new file mode 100644
index 0000000000..bfc2b699e7
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/ods68302/startup/trace.c
@@ -0,0 +1,175 @@
+/*****************************************************************************/
+/*
+ $Id$
+
+ Trace Exception dumps a back trace to the debug serial port
+
+ */
+/*****************************************************************************/
+
+#include <bsp.h>
+#include <debugport.h>
+
+#ifdef 0
+/* FIXME : could get the string to print when in the BSP */
+static const char *exception_names[] =
+{
+ "RESET STACK TOP",
+ "RESET",
+ "BUS ERROR",
+ "ADDRESS ERROR",
+ "ILLEGAL OPCODE",
+ "ZERO DIVIDE",
+ "CHK",
+ "OVERFLOW",
+ "PRIVILEGE",
+ "TRACE",
+ "LINE 1010 EMULATOR",
+ "LINE 1111 EMULATOR",
+ "UNASSIGNED 12",
+ "UNASSIGNED 13",
+ "FORMAT ERROR",
+ "UNINITIALISED INTERRUPT",
+ "UNASSIGNED 16",
+ "NODE ANCHOR",
+ "SYSTEM ANCHOR",
+ "UNASSIGNED 19",
+ "UNASSIGNED 20",
+ "UNASSIGNED 21",
+ "UNASSIGNED 22",
+ "UNASSIGNED 23",
+ "SPURIOUS HANDLER",
+ "LEVEL 1",
+ "LEVEL 2",
+ "LEVEL 3",
+ "LEVEL 4",
+ "LEVEL 5",
+ "LEVEL 6",
+ "LEVEL 7",
+ "TRAP 0",
+ "TRAP 1",
+ "TRAP 2",
+ "TRAP 3",
+ "TRAP 4",
+ "TRAP 5",
+ "TRAP 6",
+ "TRAP 7",
+ "TRAP 8",
+ "TRAP 9",
+ "TRAP 10",
+ "TRAP 11",
+ "TRAP 12",
+ "TRAP 13",
+ "TRAP 14",
+ "TRAP 15"
+};
+#endif
+
+void trace_exception(unsigned long d0,
+ unsigned long d1,
+ unsigned long d2,
+ unsigned long d3,
+ unsigned long d4,
+ unsigned long d5,
+ unsigned long d6,
+ unsigned long d7,
+ unsigned long a0,
+ unsigned long a1,
+ unsigned long a2,
+ unsigned long a3,
+ unsigned long a4,
+ unsigned long a5,
+ unsigned long a6,
+ unsigned long a7,
+ unsigned long sr_pch,
+ unsigned long pcl_format)
+{
+ unsigned int sr = sr_pch >> 16;
+ unsigned long pc = (sr_pch << 16) | (pcl_format >> 16);
+ unsigned int format = pcl_format & 0xFFFF;
+ unsigned int index;
+ unsigned char ch;
+
+ asm volatile(" orw #0x0700,%sr");
+
+ debug_port_banner();
+
+ debug_port_write("unhandled exception=");
+ debug_port_write_hex_uint(format >> 2);
+ debug_port_write("\n");
+
+ debug_port_write("sr=");
+ debug_port_write_hex_uint(sr);
+ debug_port_write(", pc=");
+ debug_port_write_hex_ulong(pc);
+ debug_port_write("\n");
+
+ for (index = 0; index < 16; index++)
+ {
+ if (index == 8)
+ {
+ debug_port_write("\n\r");
+ }
+ if (index < 8)
+ {
+ debug_port_out('d');
+ debug_port_out('0' + index);
+ }
+ else
+ {
+ debug_port_out('a');
+ debug_port_out('0' + index - 8);
+ }
+ debug_port_out('=');
+ debug_port_write_hex_ulong(*(((unsigned long*) &d0) + index));
+ debug_port_out(' ');
+ }
+
+ for (index = 0; index < (16 * 10); index++)
+ {
+ if ((index % 16) == 0)
+ {
+ debug_port_write("\n");
+ debug_port_write_hex_ulong((unsigned long) (((char*) &index) + index));
+ debug_port_write(" : ");
+ }
+ else
+ {
+ debug_port_out(' ');
+ }
+
+ ch = (*(((char*) &index) + index) >> 4) & 0x0F;
+
+ if (ch < 10)
+ {
+ ch += '0';
+ }
+ else
+ {
+ ch += 'a' - 10;
+ }
+
+ debug_port_out((char) ch);
+
+ ch = *(((char*) &index) + index) & 0x0F;
+
+ if (ch < 10)
+ {
+ ch += '0';
+ }
+ else
+ {
+ ch += 'a' - 10;
+ }
+ debug_port_out((char) ch);
+ }
+
+ debug_port_write("\nhalting cpu...");
+
+#if defined(UPDATE_DISPLAY)
+ UPDATE_DISPLAY("HALT");
+#endif
+
+ WATCHDOG_TRIGGER();
+ while (1 == 1);
+}